FIX: Add "Apply" button to color picker

This commit is contained in:
Nicolás Hatcher
2025-02-23 11:55:13 +01:00
committed by Nicolás Hatcher Andrés
parent 1ff0c38aa5
commit c0fa55c5f7
5 changed files with 53 additions and 31 deletions

View File

@@ -1,12 +1,13 @@
import styled from "@emotion/styled"; import styled from "@emotion/styled";
import Popover, { type PopoverOrigin } from "@mui/material/Popover"; import Popover, { type PopoverOrigin } from "@mui/material/Popover";
import { Check } from "lucide-react";
import type React from "react"; import type React from "react";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { HexColorInput, HexColorPicker } from "react-colorful"; import { HexColorInput, HexColorPicker } from "react-colorful";
import { useTranslation } from "react-i18next";
import { theme } from "../theme"; import { theme } from "../theme";
type ColorPickerProps = { type ColorPickerProps = {
className?: string;
color: string; color: string;
onChange: (color: string) => void; onChange: (color: string) => void;
onClose: () => void; onClose: () => void;
@@ -17,17 +18,19 @@ type ColorPickerProps = {
}; };
const colorPickerWidth = 240; const colorPickerWidth = 240;
const colorfulHeight = 185; // 150 + 15 + 20 const colorfulHeight = 240;
const ColorPicker = (properties: ColorPickerProps) => { const ColorPicker = (properties: ColorPickerProps) => {
const [color, setColor] = useState<string>(properties.color); const [color, setColor] = useState<string>(properties.color);
const recentColors = useRef<string[]>([]); const recentColors = useRef<string[]>([]);
const { t } = useTranslation();
const closePicker = (newColor: string): void => { const closePicker = (newColor: string): void => {
const maxRecentColors = 14; const maxRecentColors = 14;
properties.onChange(newColor);
const colors = recentColors.current.filter((c) => c !== newColor); const colors = recentColors.current.filter((c) => c !== newColor);
recentColors.current = [newColor, ...colors].slice(0, maxRecentColors); recentColors.current = [newColor, ...colors].slice(0, maxRecentColors);
properties.onChange(newColor);
}; };
const handleClose = (): void => { const handleClose = (): void => {
@@ -85,21 +88,16 @@ const ColorPicker = (properties: ColorPickerProps) => {
/> />
</HexColorInputBox> </HexColorInputBox>
</HexWrapper> </HexWrapper>
<Swatch <Swatch $color={color} />
$color={color}
onClick={(): void => {
closePicker(color);
}}
/>
</ColorPickerInput> </ColorPickerInput>
<HorizontalDivider /> <HorizontalDivider />
<ColorList> <ColorList>
{presetColors.map((presetColor) => ( {presetColors.map((presetColor) => (
<Button <RecentColorButton
key={presetColor} key={presetColor}
$color={presetColor} $color={presetColor}
onClick={(): void => { onClick={(): void => {
closePicker(presetColor); setColor(presetColor);
}} }}
/> />
))} ))}
@@ -111,11 +109,11 @@ const ColorPicker = (properties: ColorPickerProps) => {
<RecentLabel>{"Recent"}</RecentLabel> <RecentLabel>{"Recent"}</RecentLabel>
<ColorList> <ColorList>
{recentColors.current.map((recentColor) => ( {recentColors.current.map((recentColor) => (
<Button <RecentColorButton
key={recentColor} key={recentColor}
$color={recentColor} $color={recentColor}
onClick={(): void => { onClick={(): void => {
closePicker(recentColor); setColor(recentColor);
}} }}
/> />
))} ))}
@@ -124,11 +122,46 @@ const ColorPicker = (properties: ColorPickerProps) => {
) : ( ) : (
<div /> <div />
)} )}
<Buttons>
<StyledButton
onClick={(): void => {
closePicker(color);
}}
>
<Check
style={{ width: "16px", height: "16px", marginRight: "8px" }}
/>
{t("color_picker.apply")}
</StyledButton>
</Buttons>
</ColorPickerDialog> </ColorPickerDialog>
</Popover> </Popover>
); );
}; };
const Buttons = styled.div`
display: flex;
justify-content: flex-end;
margin: 8px;
`;
const StyledButton = styled("div")`
cursor: pointer;
color: #ffffff;
background: #f2994a;
padding: 0px 10px;
height: 36px;
line-height: 36px;
border-radius: 4px;
display: flex;
align-items: center;
font-family: "Inter";
font-size: 14px;
&:hover {
background: #d68742;
}
`;
const RecentLabel = styled.div` const RecentLabel = styled.div`
font-family: "Inter"; font-family: "Inter";
font-size: 12px; font-size: 12px;
@@ -146,7 +179,7 @@ const ColorList = styled.div`
gap: 4.7px; gap: 4.7px;
`; `;
const Button = styled.button<{ $color: string }>` const RecentColorButton = styled.button<{ $color: string }>`
width: 16px; width: 16px;
height: 16px; height: 16px;
${({ $color }): string => { ${({ $color }): string => {
@@ -174,20 +207,6 @@ const HorizontalDivider = styled.div`
border-top: 1px solid ${theme.palette.grey["200"]}; border-top: 1px solid ${theme.palette.grey["200"]};
`; `;
// const StyledPopover = styled(Popover)`
// .MuiPopover-paper {
// border-radius: 10px;
// border: 0px solid ${theme.palette.background.default};
// box-shadow: 1px 2px 8px rgba(139, 143, 173, 0.5);
// }
// .MuiPopover-padding {
// padding: 0px;
// }
// .MuiList-padding {
// padding: 0px;
// }
// `;
const ColorPickerDialog = styled.div` const ColorPickerDialog = styled.div`
background: ${theme.palette.background.default}; background: ${theme.palette.background.default};
width: ${colorPickerWidth}px; width: ${colorPickerWidth}px;

View File

@@ -3,7 +3,7 @@ import type { MenuItemProps } from "@mui/material";
import { ChevronDown } from "lucide-react"; import { ChevronDown } from "lucide-react";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { theme } from "../../theme"; import { theme } from "../../theme";
import ColorPicker from "../colorPicker"; import ColorPicker from "../ColorPicker";
import { isInReferenceMode } from "../editor/util"; import { isInReferenceMode } from "../editor/util";
import type { WorkbookState } from "../workbookState"; import type { WorkbookState } from "../workbookState";
import SheetDeleteDialog from "./SheetDeleteDialog"; import SheetDeleteDialog from "./SheetDeleteDialog";

View File

@@ -22,7 +22,7 @@ import {
BorderTopIcon, BorderTopIcon,
} from "../icons"; } from "../icons";
import { theme } from "../theme"; import { theme } from "../theme";
import ColorPicker from "./colorPicker"; import ColorPicker from "./ColorPicker";
type BorderPickerProps = { type BorderPickerProps = {
className?: string; className?: string;

View File

@@ -38,10 +38,10 @@ import {
DecimalPlacesIncreaseIcon, DecimalPlacesIncreaseIcon,
} from "../icons"; } from "../icons";
import { theme } from "../theme"; import { theme } from "../theme";
import ColorPicker from "./ColorPicker";
import NameManagerDialog from "./NameManagerDialog"; import NameManagerDialog from "./NameManagerDialog";
import type { NameManagerProperties } from "./NameManagerDialog/NameManagerDialog"; import type { NameManagerProperties } from "./NameManagerDialog/NameManagerDialog";
import BorderPicker from "./borderPicker"; import BorderPicker from "./borderPicker";
import ColorPicker from "./colorPicker";
import { TOOLBAR_HEIGHT } from "./constants"; import { TOOLBAR_HEIGHT } from "./constants";
import FormatMenu from "./formatMenu"; import FormatMenu from "./formatMenu";
import { import {

View File

@@ -115,5 +115,8 @@
"freeze": "Freeze", "freeze": "Freeze",
"insert_row": "Insert row", "insert_row": "Insert row",
"insert_column": "Insert column" "insert_column": "Insert column"
},
"color_picker": {
"apply": "Apply"
} }
} }