[web] UI color related improvements (#4759)
Continuation of https://github.com/ente-io/ente/pull/4751. Now that dark theme colors have been (mostly) isolated, next up will be introducing the light one.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { EnteLogo } from "@/base/components/EnteLogo";
|
||||
import { decryptMetadataJSON_New } from "@/base/crypto";
|
||||
import { Box, Button, Stack, Typography } from "@mui/material";
|
||||
import { Box, Button, Stack, Typography, useTheme } from "@mui/material";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
|
||||
interface SharedCode {
|
||||
@@ -19,6 +19,8 @@ const Page: React.FC = () => {
|
||||
progress: 0,
|
||||
});
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const getTimeStatus = (
|
||||
currentTime: number,
|
||||
startTime: number,
|
||||
@@ -65,7 +67,11 @@ const Page: React.FC = () => {
|
||||
useEffect(() => {
|
||||
if (!sharedCode) return;
|
||||
|
||||
let done = false;
|
||||
|
||||
const updateCode = () => {
|
||||
if (done) return;
|
||||
|
||||
const currentTime = Date.now();
|
||||
const codes = sharedCode.codes.split(",");
|
||||
const status = getTimeStatus(
|
||||
@@ -85,15 +91,23 @@ const Page: React.FC = () => {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
requestAnimationFrame(updateCode);
|
||||
};
|
||||
|
||||
const interval = setInterval(updateCode, 100);
|
||||
return () => clearInterval(interval);
|
||||
updateCode();
|
||||
|
||||
return () => {
|
||||
done = true;
|
||||
};
|
||||
}, [sharedCode]);
|
||||
|
||||
const progressBarColor = useMemo(
|
||||
() => (100 - codeDisplay.progress > 40 ? "#8E2DE2" : "#FFC107"),
|
||||
[codeDisplay.progress],
|
||||
() =>
|
||||
100 - codeDisplay.progress > 40
|
||||
? theme.vars.palette.accent.light
|
||||
: theme.vars.palette.warning.main,
|
||||
[theme, codeDisplay.progress],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -128,17 +142,17 @@ const Page: React.FC = () => {
|
||||
{timeStatus === 0 && (
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: "#1C1C1E",
|
||||
backgroundColor: "fixed.gray.A",
|
||||
borderRadius: "10px",
|
||||
paddingBottom: "20px",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "4px",
|
||||
backgroundColor: "#333333",
|
||||
backgroundColor: "fixed.gray.B",
|
||||
borderRadius: "2px",
|
||||
}}
|
||||
>
|
||||
@@ -150,7 +164,7 @@ const Page: React.FC = () => {
|
||||
borderRadius: "2px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Box>
|
||||
<div
|
||||
style={{
|
||||
fontSize: "36px",
|
||||
@@ -191,7 +205,7 @@ const Page: React.FC = () => {
|
||||
<Button
|
||||
color="accent"
|
||||
sx={{
|
||||
backgroundColor: "#8E2DE2",
|
||||
backgroundColor: "accent.light",
|
||||
borderRadius: "25px",
|
||||
padding: "15px 30px",
|
||||
marginBottom: "42px",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { TitledMiniDialog } from "@/base/components/MiniDialog";
|
||||
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
|
||||
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
|
||||
import log from "@/base/log";
|
||||
import type { Collection } from "@/media/collection";
|
||||
import { useSettingsSnapshot } from "@/new/photos/components/utils/use-snapshot";
|
||||
@@ -13,7 +14,7 @@ import { loadCast } from "@/new/photos/utils/chromecast-sender";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
import { Button, Link, Stack, Typography } from "@mui/material";
|
||||
import { Link, Stack, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Trans } from "react-i18next";
|
||||
@@ -143,18 +144,18 @@ export const AlbumCastDialog: React.FC<AlbumCastDialogProps> = ({
|
||||
{t("cast_auto_pair_description")}
|
||||
</Typography>
|
||||
|
||||
<Button onClick={() => setView("auto")}>
|
||||
<FocusVisibleButton onClick={() => setView("auto")}>
|
||||
{t("cast_auto_pair")}
|
||||
</Button>
|
||||
</FocusVisibleButton>
|
||||
</Stack>
|
||||
)}
|
||||
<Stack sx={{ gap: 2 }}>
|
||||
<Typography sx={{ color: "text.muted" }}>
|
||||
{t("pair_with_pin_description")}
|
||||
</Typography>
|
||||
<Button onClick={() => setView("pin")}>
|
||||
<FocusVisibleButton onClick={() => setView("pin")}>
|
||||
{t("pair_with_pin")}
|
||||
</Button>
|
||||
</FocusVisibleButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -164,17 +165,23 @@ export const AlbumCastDialog: React.FC<AlbumCastDialogProps> = ({
|
||||
<ActivityIndicator />
|
||||
</div>
|
||||
<Typography>{t("choose_device_from_browser")}</Typography>
|
||||
<Button color="secondary" onClick={() => setView("choose")}>
|
||||
<FocusVisibleButton
|
||||
color="secondary"
|
||||
onClick={() => setView("choose")}
|
||||
>
|
||||
{t("go_back")}
|
||||
</Button>
|
||||
</FocusVisibleButton>
|
||||
</Stack>
|
||||
)}
|
||||
{view == "auto-cast-error" && (
|
||||
<Stack sx={{ pt: 1, gap: 3, textAlign: "center" }}>
|
||||
<Typography>{t("cast_auto_pair_failed")}</Typography>
|
||||
<Button color="secondary" onClick={() => setView("choose")}>
|
||||
<FocusVisibleButton
|
||||
color="secondary"
|
||||
onClick={() => setView("choose")}
|
||||
>
|
||||
{t("go_back")}
|
||||
</Button>
|
||||
</FocusVisibleButton>
|
||||
</Stack>
|
||||
)}
|
||||
{view == "pin" && (
|
||||
@@ -199,13 +206,13 @@ export const AlbumCastDialog: React.FC<AlbumCastDialogProps> = ({
|
||||
buttonText={t("pair_device_to_tv")}
|
||||
submitButtonProps={{ sx: { mt: 1, mb: 2 } }}
|
||||
/>
|
||||
<Button
|
||||
<FocusVisibleButton
|
||||
variant="text"
|
||||
fullWidth
|
||||
onClick={() => setView("choose")}
|
||||
>
|
||||
{t("go_back")}
|
||||
</Button>
|
||||
</FocusVisibleButton>
|
||||
</>
|
||||
)}
|
||||
</TitledMiniDialog>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { isDesktop } from "@/base/app";
|
||||
import { EnteSwitch } from "@/base/components/EnteSwitch";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import {
|
||||
OverflowMenu,
|
||||
OverflowMenuOption,
|
||||
} from "@/base/components/OverflowMenu";
|
||||
import { EllipsizedTypography } from "@/base/components/Typography";
|
||||
import type { ButtonishProps } from "@/base/components/mui";
|
||||
import type { ModalVisibilityProps } from "@/base/components/utils/modal";
|
||||
import { ensureElectron } from "@/base/electron";
|
||||
@@ -11,11 +13,7 @@ import log from "@/base/log";
|
||||
import { EnteFile } from "@/media/file";
|
||||
import { DialogCloseIconButton } from "@/new/photos/components/mui/Dialog";
|
||||
import { useAppContext } from "@/new/photos/types/context";
|
||||
import {
|
||||
SpaceBetweenFlex,
|
||||
VerticallyCenteredFlex,
|
||||
} from "@ente/shared/components/Container";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { SpaceBetweenFlex } from "@ente/shared/components/Container";
|
||||
import { CustomError } from "@ente/shared/error";
|
||||
import FolderIcon from "@mui/icons-material/Folder";
|
||||
import {
|
||||
@@ -25,9 +23,9 @@ import {
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
Divider,
|
||||
Stack,
|
||||
Tooltip,
|
||||
Typography,
|
||||
styled,
|
||||
} from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -183,15 +181,17 @@ export const Export: React.FC<ExportProps> = ({
|
||||
</SpaceBetweenFlex>
|
||||
|
||||
<DialogContent>
|
||||
<ExportDirectory
|
||||
exportFolder={exportFolder}
|
||||
changeExportDirectory={handleChangeExportDirectoryClick}
|
||||
exportStage={exportStage}
|
||||
/>
|
||||
<ContinuousExport
|
||||
continuousExport={continuousExport}
|
||||
toggleContinuousExport={toggleContinuousExport}
|
||||
/>
|
||||
<Stack>
|
||||
<ExportDirectory
|
||||
exportFolder={exportFolder}
|
||||
changeExportDirectory={handleChangeExportDirectoryClick}
|
||||
exportStage={exportStage}
|
||||
/>
|
||||
<ContinuousExport
|
||||
continuousExport={continuousExport}
|
||||
toggleContinuousExport={toggleContinuousExport}
|
||||
/>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
<Divider />
|
||||
<ExportDynamicContent
|
||||
@@ -210,64 +210,56 @@ export const Export: React.FC<ExportProps> = ({
|
||||
|
||||
function ExportDirectory({ exportFolder, changeExportDirectory, exportStage }) {
|
||||
return (
|
||||
<SpaceBetweenFlex minHeight={"48px"}>
|
||||
<Typography sx={{ color: "text.muted", mr: "16px" }}>
|
||||
<Stack
|
||||
direction="row"
|
||||
sx={{
|
||||
gap: 1,
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{ color: "text.muted", mr: 1 }}>
|
||||
{t("destination")}
|
||||
</Typography>
|
||||
<>
|
||||
{!exportFolder ? (
|
||||
<Button color={"accent"} onClick={changeExportDirectory}>
|
||||
{t("select_folder")}
|
||||
</Button>
|
||||
) : (
|
||||
<VerticallyCenteredFlex>
|
||||
<DirectoryPath width={262} path={exportFolder} />
|
||||
{exportStage === ExportStage.FINISHED ||
|
||||
exportStage === ExportStage.INIT ? (
|
||||
<ChangeDirectoryOption
|
||||
onClick={changeExportDirectory}
|
||||
/>
|
||||
) : (
|
||||
<Box sx={{ width: "16px" }} />
|
||||
)}
|
||||
</VerticallyCenteredFlex>
|
||||
)}
|
||||
</>
|
||||
</SpaceBetweenFlex>
|
||||
{exportFolder ? (
|
||||
<>
|
||||
<DirectoryPath path={exportFolder} />
|
||||
{exportStage === ExportStage.FINISHED ||
|
||||
exportStage === ExportStage.INIT ? (
|
||||
<ChangeDirectoryOption
|
||||
onClick={changeExportDirectory}
|
||||
/>
|
||||
) : (
|
||||
// Prevent layout shift.
|
||||
<Box sx={{ width: "16px", height: "48px" }} />
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Button color={"accent"} onClick={changeExportDirectory}>
|
||||
{t("select_folder")}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const DirectoryPath = ({ width, path }) => {
|
||||
const handleClick = async () => {
|
||||
try {
|
||||
await ensureElectron().openDirectory(path);
|
||||
} catch (e) {
|
||||
log.error("openDirectory failed", e);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<DirectoryPathContainer width={width} onClick={handleClick}>
|
||||
<Tooltip title={path}>
|
||||
<span>{path}</span>
|
||||
</Tooltip>
|
||||
</DirectoryPathContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const DirectoryPathContainer = styled(LinkButton)(
|
||||
({ width }) => `
|
||||
width: ${width}px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* Beginning of string */
|
||||
direction: rtl;
|
||||
text-align: left;
|
||||
`,
|
||||
const DirectoryPath = ({ path }) => (
|
||||
<LinkButton onClick={() => void ensureElectron().openDirectory(path)}>
|
||||
<Tooltip title={path}>
|
||||
<EllipsizedTypography
|
||||
// Haven't found a way to get the path to ellipsize without
|
||||
// providing a maxWidth. Luckily, this is the context of the
|
||||
// desktop app where this width is should not be too off.
|
||||
sx={{ maxWidth: "262px" }}
|
||||
>
|
||||
{path}
|
||||
</EllipsizedTypography>
|
||||
</Tooltip>
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
const ChangeDirectoryOption: React.FC<ButtonishProps> = ({ onClick }) => (
|
||||
<OverflowMenu ariaID="export-option" triggerButtonSxProps={{ ml: 1 }}>
|
||||
<OverflowMenu ariaID="export-option">
|
||||
<OverflowMenuOption onClick={onClick} startIcon={<FolderIcon />}>
|
||||
{t("change_folder")}
|
||||
</OverflowMenuOption>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
|
||||
import { formattedNumber } from "@/base/i18n";
|
||||
import { EnteFile } from "@/media/file";
|
||||
@@ -7,7 +8,6 @@ import { DialogActions, DialogContent, Stack, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useState } from "react";
|
||||
import ExportPendingList from "./ExportPendingList";
|
||||
import LinkButton from "./pages/gallery/LinkButton";
|
||||
|
||||
interface Props {
|
||||
pendingExports: EnteFile[];
|
||||
|
||||
@@ -4,22 +4,15 @@ import {
|
||||
VerticallyCentered,
|
||||
} from "@ente/shared/components/Container";
|
||||
import {
|
||||
Box,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
LinearProgress,
|
||||
styled,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { Trans } from "react-i18next";
|
||||
import { ExportStage, type ExportProgress } from "services/export";
|
||||
|
||||
export const ComfySpan = styled("span")`
|
||||
padding: 0 0.5rem;
|
||||
word-spacing: 1rem;
|
||||
color: #ddd;
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
exportStage: ExportStage;
|
||||
exportProgress: ExportProgress;
|
||||
@@ -41,7 +34,7 @@ export default function ExportInProgress(props: Props) {
|
||||
<>
|
||||
<DialogContent>
|
||||
<VerticallyCentered>
|
||||
<Box sx={{ mb: 1.5 }}>
|
||||
<Typography sx={{ mb: 1.5 }}>
|
||||
{props.exportStage === ExportStage.STARTING ? (
|
||||
t("EXPORT_STARTING")
|
||||
) : props.exportStage === ExportStage.MIGRATION ? (
|
||||
@@ -56,17 +49,31 @@ export default function ExportInProgress(props: Props) {
|
||||
ExportStage.TRASHING_DELETED_COLLECTIONS ? (
|
||||
t("TRASHING_DELETED_COLLECTIONS")
|
||||
) : (
|
||||
<Trans
|
||||
i18nKey={"EXPORT_PROGRESS"}
|
||||
components={{
|
||||
a: <ComfySpan />,
|
||||
}}
|
||||
values={{
|
||||
progress: props.exportProgress,
|
||||
}}
|
||||
/>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{ color: "text.muted" }}
|
||||
>
|
||||
<Trans
|
||||
i18nKey={"EXPORT_PROGRESS"}
|
||||
components={{
|
||||
a: (
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{
|
||||
color: "text.base",
|
||||
pr: "1rem",
|
||||
wordSpacing: "1rem",
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
values={{
|
||||
progress: props.exportProgress,
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
</Typography>
|
||||
<FlexWrapper px={1}>
|
||||
{showIndeterminateProgress() ? (
|
||||
<LinearProgress />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LinkButtonUndecorated } from "@/base/components/LinkButton";
|
||||
import { TitledMiniDialog } from "@/base/components/MiniDialog";
|
||||
import { type ButtonishProps } from "@/base/components/mui";
|
||||
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
|
||||
@@ -68,7 +69,6 @@ import {
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import LinkButton from "components/pages/gallery/LinkButton";
|
||||
import type { DisplayFile } from "components/PhotoFrame";
|
||||
import { Formik } from "formik";
|
||||
import { t } from "i18next";
|
||||
@@ -254,18 +254,13 @@ export const FileInfo: React.FC<FileInfoProps> = ({
|
||||
{t("view_on_map")}
|
||||
</Link>
|
||||
) : (
|
||||
<LinkButton
|
||||
<LinkButtonUndecorated
|
||||
onClick={
|
||||
openDisableMapConfirmationDialog
|
||||
}
|
||||
sx={{
|
||||
textDecoration: "none",
|
||||
color: "text.muted",
|
||||
fontWeight: "medium",
|
||||
}}
|
||||
>
|
||||
{t("disable_map")}
|
||||
</LinkButton>
|
||||
</LinkButtonUndecorated>
|
||||
)
|
||||
}
|
||||
trailingButton={
|
||||
@@ -296,16 +291,9 @@ export const FileInfo: React.FC<FileInfoProps> = ({
|
||||
) : !exif.tags ? (
|
||||
t("no_exif")
|
||||
) : (
|
||||
<LinkButton
|
||||
onClick={showRawExif}
|
||||
sx={{
|
||||
textDecoration: "none",
|
||||
color: "text.muted",
|
||||
fontWeight: "medium",
|
||||
}}
|
||||
>
|
||||
<LinkButtonUndecorated onClick={showRawExif}>
|
||||
{t("view_exif")}
|
||||
</LinkButton>
|
||||
</LinkButtonUndecorated>
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -913,13 +901,15 @@ const MapBoxContainer = styled("div")`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const MapBoxEnableContainer = styled(MapBoxContainer)`
|
||||
const MapBoxEnableContainer = styled(MapBoxContainer)(
|
||||
({ theme }) => `
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
`;
|
||||
background-color: ${theme.vars.palette.fill.fainter};
|
||||
`,
|
||||
);
|
||||
|
||||
interface RawExifProps {
|
||||
open: boolean;
|
||||
|
||||
@@ -304,12 +304,12 @@ const UsageBar: React.FC<UsageBarProps> = ({ used, total, sx }) => (
|
||||
/>
|
||||
);
|
||||
|
||||
const UsageBar_ = styled(LinearProgress)(() => ({
|
||||
const UsageBar_ = styled(LinearProgress)(({ theme }) => ({
|
||||
".MuiLinearProgress-bar": {
|
||||
borderRadius: "2px",
|
||||
},
|
||||
borderRadius: "2px",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
||||
backgroundColor: theme.vars.palette.fixed.storageCardUsageFill,
|
||||
}));
|
||||
|
||||
interface LegendProps {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { RecoveryKey } from "@/accounts/components/RecoveryKey";
|
||||
import { openAccountsManagePasskeysPage } from "@/accounts/services/passkey";
|
||||
import { isDesktop } from "@/base/app";
|
||||
import { EnteLogo } from "@/base/components/EnteLogo";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { SpaceBetweenFlex } from "@/base/components/containers";
|
||||
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
|
||||
import { SidebarDrawer } from "@/base/components/mui/SidebarDrawer";
|
||||
@@ -67,7 +68,6 @@ import {
|
||||
import Typography from "@mui/material/Typography";
|
||||
import DeleteAccountModal from "components/DeleteAccountModal";
|
||||
import { WatchFolder } from "components/WatchFolder";
|
||||
import LinkButton from "components/pages/gallery/LinkButton";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { GalleryContext } from "pages/gallery";
|
||||
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
type UploadPhase,
|
||||
} from "@/new/photos/services/upload/types";
|
||||
import { useAppContext } from "@/new/photos/types/context";
|
||||
import {
|
||||
SpaceBetweenFlex,
|
||||
VerticallyCenteredFlex,
|
||||
} from "@ente/shared/components/Container";
|
||||
import { SpaceBetweenFlex } from "@ente/shared/components/Container";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
|
||||
@@ -433,8 +430,12 @@ const SectionAccordion = styled((props: AccordionProps) => (
|
||||
"&:last-child": { borderBottom: `1px solid ${theme.vars.palette.divider}` },
|
||||
}));
|
||||
|
||||
const SectionAccordionSummary = styled(AccordionSummary)(() => ({
|
||||
backgroundColor: "rgba(255, 255, 255, .05)",
|
||||
const SectionAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||
backgroundColor: theme.vars.palette.fill.fainter,
|
||||
// AccordionSummary is a button, and for a reasons to do with MUI internal
|
||||
// that I didn't explore further, the user agent default font family is
|
||||
// getting applied in this case.
|
||||
fontFamily: "inherit",
|
||||
}));
|
||||
|
||||
const SectionAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
||||
@@ -534,7 +535,12 @@ interface TitleTextProps {
|
||||
}
|
||||
|
||||
const TitleText: React.FC<TitleTextProps> = ({ title, count }) => (
|
||||
<VerticallyCenteredFlex gap={"4px"}>
|
||||
<Stack
|
||||
direction="row"
|
||||
// Need to reset the font weight since it gets reset by the
|
||||
// AccordionSummary (see SectionAccordionSummary).
|
||||
sx={{ gap: 1, fontWeight: "regular", alignItems: "baseline" }}
|
||||
>
|
||||
<Typography>{title}</Typography>
|
||||
<Typography variant="small" sx={{ color: "text.faint" }}>
|
||||
{"•"}
|
||||
@@ -542,7 +548,7 @@ const TitleText: React.FC<TitleTextProps> = ({ title, count }) => (
|
||||
<Typography variant="small" sx={{ color: "text.faint" }}>
|
||||
{count ?? 0}
|
||||
</Typography>
|
||||
</VerticallyCenteredFlex>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const DoneFooter: React.FC = () => {
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { Link, type ButtonProps, type LinkProps } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
export type LinkButtonProps = React.PropsWithChildren<{
|
||||
onClick: () => void;
|
||||
variant?: string;
|
||||
style?: React.CSSProperties;
|
||||
}>;
|
||||
|
||||
const LinkButton: React.FC<
|
||||
LinkProps<"button", { color?: ButtonProps["color"] }>
|
||||
> = ({ children, sx, color, ...props }) => {
|
||||
return (
|
||||
<Link
|
||||
component="button"
|
||||
sx={{
|
||||
color: "text.base",
|
||||
textDecoration: "underline rgba(255, 255, 255, 0.4)",
|
||||
paddingBottom: "2px",
|
||||
"&:hover": {
|
||||
color: `${color}.main`,
|
||||
textDecoration: `underline `,
|
||||
textDecorationColor: `${color}.main`,
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default LinkButton;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LoginContents } from "@/accounts/components/LoginContents";
|
||||
import { SignUpContents } from "@/accounts/components/SignUpContents";
|
||||
import { CenteredFill } from "@/base/components/containers";
|
||||
import { CenteredFill, CenteredFlex } from "@/base/components/containers";
|
||||
import { EnteLogo } from "@/base/components/EnteLogo";
|
||||
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
|
||||
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
|
||||
@@ -286,22 +286,21 @@ const MobileBoxFooter: React.FC<MobileBoxFooterProps> = ({ host }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DesktopBox = styled("div")`
|
||||
const DesktopBox = styled(CenteredFlex)(
|
||||
({ theme }) => `
|
||||
flex-shrink: 0;
|
||||
flex-grow: 2;
|
||||
flex-basis: auto;
|
||||
|
||||
height: 100%;
|
||||
padding-inline: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #242424;
|
||||
background-color: ${theme.vars.palette.fill.faint};
|
||||
|
||||
@media (width <= 1024px) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
`,
|
||||
);
|
||||
|
||||
const Slideshow: React.FC = () => {
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
|
||||
@@ -18,7 +18,7 @@ body {
|
||||
height: 48px;
|
||||
background: none !important;
|
||||
background-image: none !important;
|
||||
color: #fff;
|
||||
color: var(--mui-palette-stroke-base);
|
||||
}
|
||||
|
||||
.pswp__item video {
|
||||
@@ -65,8 +65,8 @@ body {
|
||||
|
||||
.pswp__button--arrow--left,
|
||||
.pswp__button--arrow--right {
|
||||
color: #fff;
|
||||
background-color: #333333 !important;
|
||||
color: var(--mui-palette-stroke-base);
|
||||
background-color: var(--mui-palette-fill-faint) !important;
|
||||
border-radius: 50%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
@@ -4,12 +4,12 @@ import {
|
||||
passkeySessionExpiredErrorMessage,
|
||||
saveCredentialsAndNavigateTo,
|
||||
} from "@/accounts/services/passkey";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import type { MiniDialogAttributes } from "@/base/components/MiniDialog";
|
||||
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
|
||||
import { genericErrorDialogAttributes } from "@/base/components/utils/dialog";
|
||||
import log from "@/base/log";
|
||||
import { customAPIHost } from "@/base/origins";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { CircularProgress, Stack, Typography, styled } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useRouter } from "next/router";
|
||||
@@ -54,7 +54,7 @@ export const AccountsPageFooterWithHost: React.FC<React.PropsWithChildren> = ({
|
||||
useEffect(() => void customAPIHost().then(setHost), []);
|
||||
|
||||
return (
|
||||
<Stack sx={{ gap: 2 }}>
|
||||
<Stack sx={{ gap: 3 }}>
|
||||
<AccountsPageFooter>{children}</AccountsPageFooter>
|
||||
{host && (
|
||||
<Typography
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
import { PAGES } from "@/accounts/constants/pages";
|
||||
import { getSRPAttributes } from "@/accounts/services/srp-remote";
|
||||
import { sendOTT } from "@/accounts/services/user";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { isMuseumHTTPError } from "@/base/http";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
@@ -80,7 +80,7 @@ export const LoginContents: React.FC<LoginContentsProps> = ({
|
||||
}
|
||||
/>
|
||||
<AccountsPageFooter>
|
||||
<Stack sx={{ gap: 4, textAlign: "center" }}>
|
||||
<Stack sx={{ gap: 3, textAlign: "center" }}>
|
||||
<LinkButton onClick={onSignUp}>
|
||||
{t("no_account")}
|
||||
</LinkButton>
|
||||
|
||||
@@ -85,7 +85,9 @@ export const RecoveryKey: React.FC<RecoveryKeyProps> = ({
|
||||
<Stack
|
||||
sx={{
|
||||
border: "1px dashed",
|
||||
borderColor: "gray.A400",
|
||||
borderColor: "stroke.muted",
|
||||
// TODO(LM): Brighter?
|
||||
// borderColor: "gray.A400",
|
||||
borderRadius: 1,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -2,13 +2,13 @@ import { PAGES } from "@/accounts/constants/pages";
|
||||
import { generateKeyAndSRPAttributes } from "@/accounts/services/srp";
|
||||
import { sendOTT } from "@/accounts/services/user";
|
||||
import { isWeakPassword } from "@/accounts/utils/password";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { LoadingButton } from "@/base/components/mui/LoadingButton";
|
||||
import { isMuseumHTTPError } from "@/base/http";
|
||||
import log from "@/base/log";
|
||||
import { LS_KEYS, setLSUser } from "@ente/shared//storage/localStorage";
|
||||
import { VerticallyCentered } from "@ente/shared/components/Container";
|
||||
import ShowHidePassword from "@ente/shared/components/Form/ShowHidePassword";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import {
|
||||
generateAndSaveIntermediateKeyAttributes,
|
||||
saveKeyInSessionStore,
|
||||
@@ -339,16 +339,15 @@ export const SignUpContents: React.FC<SignUpContentsProps> = ({
|
||||
<AccountsPageTitle>{t("sign_up")}</AccountsPageTitle>
|
||||
{form}
|
||||
<AccountsPageFooter>
|
||||
<Stack sx={{ gap: 3, textAlign: "center" }}>
|
||||
<Stack sx={{ gap: 5, textAlign: "center" }}>
|
||||
<LinkButton onClick={onLogin}>
|
||||
{t("existing_account")}
|
||||
</LinkButton>
|
||||
<Typography
|
||||
variant="mini"
|
||||
sx={{ color: "text.faint", minHeight: "16px" }}
|
||||
>
|
||||
{host ?? "" /* prevent layout shift with a minHeight */}
|
||||
</Typography>
|
||||
{host && (
|
||||
<Typography variant="mini" sx={{ color: "text.faint" }}>
|
||||
{host}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</AccountsPageFooter>
|
||||
</>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CodeBlock } from "@/accounts/components/CodeBlock";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { ActivityIndicator } from "@/base/components/mui/ActivityIndicator";
|
||||
import { VerticallyCentered } from "@ente/shared/components/Container";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { Stack, styled, Typography } from "@mui/material";
|
||||
import { t } from "i18next";
|
||||
import { useState } from "react";
|
||||
@@ -99,7 +99,7 @@ const LoadingQRCode = styled(VerticallyCentered)(
|
||||
({ theme }) => `
|
||||
width: 200px;
|
||||
aspect-ratio:1;
|
||||
border: 1px solid ${theme.palette.grey.A200};
|
||||
border: 1px solid ${theme.palette.stroke.muted};
|
||||
margin: ${theme.spacing(2)};
|
||||
`,
|
||||
);
|
||||
|
||||
@@ -5,11 +5,11 @@ import {
|
||||
} from "@/accounts/components/layouts/centered-paper";
|
||||
import { appHomeRoute } from "@/accounts/services/redirect";
|
||||
import { changeEmail, sendOTT } from "@/accounts/services/user";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { LoadingButton } from "@/base/components/mui/LoadingButton";
|
||||
import { isHTTPErrorWithStatus } from "@/base/http";
|
||||
import log from "@/base/log";
|
||||
import { VerticallyCentered } from "@ente/shared/components/Container";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { LS_KEYS, getData, setLSUser } from "@ente/shared/storage/localStorage";
|
||||
import { Alert, Box, TextField } from "@mui/material";
|
||||
import { Formik, type FormikHelpers } from "formik";
|
||||
|
||||
@@ -20,8 +20,8 @@ import {
|
||||
updateSRPAndKeys,
|
||||
} from "@/accounts/services/srp-remote";
|
||||
import type { UpdatedKey } from "@/accounts/services/user";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import {
|
||||
generateAndSaveIntermediateKeyAttributes,
|
||||
generateLoginSubKey,
|
||||
|
||||
@@ -26,12 +26,12 @@ import {
|
||||
import type { SRPAttributes } from "@/accounts/services/srp-remote";
|
||||
import { getSRPAttributes } from "@/accounts/services/srp-remote";
|
||||
import type { PageProps } from "@/accounts/types/page";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { LoadingIndicator } from "@/base/components/loaders";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import type { B64EncryptionResult } from "@/base/crypto/libsodium";
|
||||
import { clearLocalStorage } from "@/base/local-storage";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import VerifyMasterPasswordForm, {
|
||||
type VerifyMasterPasswordFormProps,
|
||||
} from "@ente/shared/components/VerifyMasterPasswordForm";
|
||||
|
||||
@@ -15,9 +15,9 @@ import {
|
||||
} from "@/accounts/services/srp";
|
||||
import { putAttributes } from "@/accounts/services/user";
|
||||
import type { PageProps } from "@/accounts/types/page";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { LoadingIndicator } from "@/base/components/loaders";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import {
|
||||
generateAndSaveIntermediateKeyAttributes,
|
||||
saveKeyInSessionStore,
|
||||
|
||||
@@ -7,9 +7,9 @@ import { PAGES } from "@/accounts/constants/pages";
|
||||
import { appHomeRoute, stashRedirect } from "@/accounts/services/redirect";
|
||||
import { sendOTT } from "@/accounts/services/user";
|
||||
import type { PageProps } from "@/accounts/types/page";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
|
||||
@@ -10,11 +10,11 @@ import {
|
||||
type TwoFactorType,
|
||||
} from "@/accounts/services/user";
|
||||
import type { AccountsContextT } from "@/accounts/types/context";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import type { MiniDialogAttributes } from "@/base/components/MiniDialog";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import type { B64EncryptionResult } from "@/base/crypto/libsodium";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
|
||||
@@ -6,8 +6,8 @@ import { appHomeRoute } from "@/accounts/services/redirect";
|
||||
import type { TwoFactorSecret } from "@/accounts/services/user";
|
||||
import { enableTwoFactor, setupTwoFactor } from "@/accounts/services/user";
|
||||
import { CenteredFill } from "@/base/components/containers";
|
||||
import { FocusVisibleButton } from "@/base/components/mui/FocusVisibleButton";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { encryptWithRecoveryKey } from "@ente/shared/crypto/helpers";
|
||||
import { getData, LS_KEYS, setLSUser } from "@ente/shared/storage/localStorage";
|
||||
import { Paper, Stack, styled, Typography } from "@mui/material";
|
||||
@@ -69,9 +69,14 @@ const Page: React.FC = () => {
|
||||
onSubmit={onSubmit}
|
||||
buttonText={t("enable")}
|
||||
/>
|
||||
<LinkButton sx={{ mt: 1 }} onClick={router.back}>
|
||||
{t("go_back")}
|
||||
</LinkButton>
|
||||
<Stack sx={{ alignItems: "center" }}>
|
||||
<FocusVisibleButton
|
||||
variant="text"
|
||||
onClick={router.back}
|
||||
>
|
||||
{t("go_back")}
|
||||
</FocusVisibleButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</ContentsPaper>
|
||||
</CenteredFill>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PAGES } from "@/accounts/constants/pages";
|
||||
import { verifyTwoFactor } from "@/accounts/services/user";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { ApiError } from "@ente/shared/error";
|
||||
import {
|
||||
LS_KEYS,
|
||||
|
||||
@@ -20,9 +20,9 @@ import type {
|
||||
import { getSRPAttributes } from "@/accounts/services/srp-remote";
|
||||
import { putAttributes, sendOTT, verifyEmail } from "@/accounts/services/user";
|
||||
import type { PageProps } from "@/accounts/types/page";
|
||||
import { LinkButton } from "@/base/components/LinkButton";
|
||||
import { LoadingIndicator } from "@/base/components/loaders";
|
||||
import log from "@/base/log";
|
||||
import LinkButton from "@ente/shared/components/LinkButton";
|
||||
import SingleInputForm, {
|
||||
type SingleInputFormProps,
|
||||
} from "@ente/shared/components/SingleInputForm";
|
||||
|
||||
56
web/packages/base/components/LinkButton.tsx
Normal file
56
web/packages/base/components/LinkButton.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Link, type ButtonProps } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
/**
|
||||
* A button that looks like a link.
|
||||
*
|
||||
* The use of this component is not encouraged. It is only useful in uncommon
|
||||
* cases where we do not have sufficient space to include a proper button.
|
||||
*/
|
||||
export const LinkButton: React.FC<
|
||||
React.PropsWithChildren<Pick<ButtonProps, "onClick">>
|
||||
> = ({ onClick, children }) => (
|
||||
<Link
|
||||
component="button"
|
||||
sx={(theme) => ({
|
||||
color: "text.base",
|
||||
textDecoration: "underline",
|
||||
// The shortcut "text.faint" does not work with textDecorationColor
|
||||
// (as of MUI v6).
|
||||
textDecorationColor: theme.vars.palette.text.faint,
|
||||
"&:hover": {
|
||||
color: "accent.main",
|
||||
textDecoration: "underline",
|
||||
textDecorationColor: "accent.main",
|
||||
},
|
||||
})}
|
||||
{...{ onClick }}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
|
||||
/**
|
||||
* A variant of {@link LinkButton} that does not show an underline, and instead
|
||||
* uses a bolder font weight to indicate clickability.
|
||||
*
|
||||
* Similar caveats as {@link LinkButton} apply.
|
||||
*/
|
||||
export const LinkButtonUndecorated: React.FC<
|
||||
React.PropsWithChildren<Pick<ButtonProps, "onClick">>
|
||||
> = ({ onClick, children }) => (
|
||||
<Link
|
||||
component="button"
|
||||
sx={{
|
||||
textDecoration: "none",
|
||||
color: "text.muted",
|
||||
fontWeight: "medium",
|
||||
"&:hover": {
|
||||
color: "accent.main",
|
||||
},
|
||||
}}
|
||||
{...{ onClick }}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
@@ -85,16 +85,18 @@ declare module "@mui/material/styles" {
|
||||
* These change with the color scheme.
|
||||
*
|
||||
* They come in three strengths which are meant to play nicely with the
|
||||
* corresponding strengths of "text.*" and "stroke.*".
|
||||
* corresponding strengths of "text.*" and "stroke.*", plus extra ones.
|
||||
*
|
||||
* The strength comes with a hover variant, useful to indicate the hover
|
||||
* state of buttons and menu items that use the corresponding fill.
|
||||
* Some strengths also have a hover variant, useful to indicate hover on
|
||||
* buttons and menu items that use the corresponding fill.
|
||||
*/
|
||||
fill: {
|
||||
base: string;
|
||||
baseHover: string;
|
||||
muted: string;
|
||||
faint: string;
|
||||
faintHover: string;
|
||||
fainter: string;
|
||||
};
|
||||
/**
|
||||
* Transparent background fills that serve as the backdrop of modals,
|
||||
@@ -148,6 +150,10 @@ declare module "@mui/material/styles" {
|
||||
* "archived" indicator shown on top of albums.
|
||||
*/
|
||||
overlayIndicatorMuted: string;
|
||||
/**
|
||||
* Color of the total space in the usage bar on the storage card.
|
||||
*/
|
||||
storageCardUsageFill: string;
|
||||
};
|
||||
/**
|
||||
* MUI as of v6 does not allow customizing shadows easily. This is due
|
||||
|
||||
@@ -133,15 +133,16 @@ const _colors = {
|
||||
light: "#01DE4D",
|
||||
},
|
||||
accentAuth: {
|
||||
dark: "rgb(164, 0, 182)",
|
||||
main: "rgb(150, 13, 214)",
|
||||
light: "rgb(152, 77, 244)",
|
||||
dark: "#8e0fcb",
|
||||
main: "#9610d6",
|
||||
light: "#8e2de2",
|
||||
lighter: "#984df4" /* TODO(LM) */,
|
||||
},
|
||||
fixed: {
|
||||
white: "#fff",
|
||||
black: "#000",
|
||||
success: "#1DB954",
|
||||
warning: "#FFC247",
|
||||
golden: "#FFC107",
|
||||
danger: {
|
||||
dark: "#F53434",
|
||||
main: "#EA3F3F",
|
||||
@@ -155,6 +156,7 @@ const _colors = {
|
||||
switchOn: "#2ECA45",
|
||||
croppedAreaOverlay: "rgba(0 0 0 / 0.5)",
|
||||
overlayIndicatorMuted: "rgba(255 255 255 / 0.48)",
|
||||
storageCardUsageFill: "rgba(255 255 255 / 0.2)",
|
||||
},
|
||||
light: {
|
||||
background: {
|
||||
@@ -197,31 +199,32 @@ const _colors = {
|
||||
paper2: "#252525",
|
||||
},
|
||||
backdrop: {
|
||||
base: "rgba(0, 0, 0, 0.90)",
|
||||
muted: "rgba(0, 0, 0, 0.65)",
|
||||
faint: "rgba(0, 0, 0,0.20)",
|
||||
base: "rgba(0 0 0 / 0.90)",
|
||||
muted: "rgba(0 0 0 / 0.65)",
|
||||
faint: "rgba(0 0 0 / 0.20)",
|
||||
},
|
||||
text: {
|
||||
base: "#fff",
|
||||
muted: "rgba(255, 255, 255, 0.70)",
|
||||
faint: "rgba(255, 255, 255, 0.50)",
|
||||
muted: "rgba(255 255 255 / 0.70)",
|
||||
faint: "rgba(255 255 255 / 0.50)",
|
||||
},
|
||||
fill: {
|
||||
base: "#fff",
|
||||
muted: "rgba(255, 255, 255, 0.16)",
|
||||
faint: "rgba(255, 255, 255, 0.12)",
|
||||
baseHover: "rgba(255, 255, 255, 0.90)",
|
||||
faintHover: "rgba(255, 255, 255, 0.06)",
|
||||
baseHover: "rgba(255 255 255 / 0.90)",
|
||||
muted: "rgba(255 255 255 / 0.16)",
|
||||
faint: "rgba(255 255 255 / 0.12)",
|
||||
faintHover: "rgba(255 255 255 / 0.06)",
|
||||
fainter: "rgba(255 255 255 / 0.05)",
|
||||
},
|
||||
stroke: {
|
||||
base: "#fff",
|
||||
muted: "rgba(255,255,255,0.24)",
|
||||
faint: "rgba(255,255,255,0.16)",
|
||||
muted: "rgba(255 255 255 / 0.24)",
|
||||
faint: "rgba(255 255 255 / 0.16)",
|
||||
},
|
||||
boxShadow: {
|
||||
float: "0px 2px 12px rgba(0, 0, 0, 0.75)",
|
||||
menu: "0px 0px 6px rgba(0, 0, 0, 0.50), 0px 3px 6px rgba(0, 0, 0, 0.25)",
|
||||
button: "0px 4px 4px rgba(0, 0, 0, 0.75)",
|
||||
float: "0px 2px 12px rgba(0 0 0 / 0.75)",
|
||||
menu: "0px 0px 6px rgba(0 0 0 / 0.50), 0px 3px 6px rgba(0 0 0 / 0.25)",
|
||||
button: "0px 4px 4px rgba(0 0 0 / 0.75)",
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -251,7 +254,7 @@ const getColorSchemes = (colors: ReturnType<typeof getColors>) => ({
|
||||
contrastText: colors.dark.text.base,
|
||||
},
|
||||
success: { main: colors.fixed.success },
|
||||
warning: { main: colors.fixed.warning },
|
||||
warning: { main: colors.fixed.golden },
|
||||
accent: {
|
||||
main: colors.accent.main,
|
||||
dark: colors.accent.dark,
|
||||
@@ -280,9 +283,11 @@ const getColorSchemes = (colors: ReturnType<typeof getColors>) => ({
|
||||
},
|
||||
fill: {
|
||||
base: colors.dark.fill.base,
|
||||
baseHover: colors.dark.fill.baseHover,
|
||||
muted: colors.dark.fill.muted,
|
||||
faint: colors.dark.fill.faint,
|
||||
faintHover: colors.dark.fill.faintHover,
|
||||
fainter: colors.dark.fill.fainter,
|
||||
},
|
||||
stroke: {
|
||||
base: colors.dark.stroke.base,
|
||||
|
||||
@@ -627,9 +627,6 @@ const FreePlanRow_ = styled(SpaceBetweenFlex)(({ theme }) => ({
|
||||
gap: theme.spacing(1.5),
|
||||
padding: theme.spacing(1.5, 1),
|
||||
cursor: "pointer",
|
||||
"&:hover .endIcon": {
|
||||
backgroundColor: "rgba(255,255,255,0.08)",
|
||||
},
|
||||
}));
|
||||
|
||||
interface AddOnBonusRowsProps {
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { Link, type ButtonProps, type LinkProps } from "@mui/material";
|
||||
import React from "react";
|
||||
|
||||
export type LinkButtonProps = React.PropsWithChildren<{
|
||||
onClick: () => void;
|
||||
variant?: string;
|
||||
style?: React.CSSProperties;
|
||||
}>;
|
||||
|
||||
const LinkButton: React.FC<
|
||||
LinkProps<"button", { color?: ButtonProps["color"] }>
|
||||
> = ({ children, sx, color, ...props }) => {
|
||||
return (
|
||||
<Link
|
||||
component="button"
|
||||
sx={{
|
||||
color: "text.base",
|
||||
textDecoration: "underline rgba(255, 255, 255, 0.4)",
|
||||
paddingBottom: 0.5,
|
||||
"&:hover": {
|
||||
color: `${color}.main`,
|
||||
textDecoration: `underline `,
|
||||
textDecorationColor: `${color}.main`,
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default LinkButton;
|
||||
Reference in New Issue
Block a user