custom colors in dropdown

This commit is contained in:
Nate Kelley 2025-08-02 16:22:17 -06:00
parent 0778c8db4e
commit 3d726438fb
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 78 additions and 61 deletions

View File

@ -26,7 +26,7 @@ export const useGetMyUserInfo = <TData = UserResponse>(
return useQuery({ return useQuery({
...userQueryKeys.userGetUserMyself, ...userQueryKeys.userGetUserMyself,
queryFn: getMyUserInfo, queryFn: getMyUserInfo,
enabled: false, //This is a server only query, enabled: true, //This is a server only query,
select: props?.select, select: props?.select,
...props ...props
}); });

View File

@ -270,7 +270,29 @@ const value: ReportElements = [
url: '/docs' url: '/docs'
}, },
{ {
text: ' to discover more.' fontSize: '20px',
text: 'to disc',
bold: true,
italic: true,
underline: true,
strikethrough: true
},
{
text: 'asdfsdf',
fontSize: '20px',
bold: true,
italic: true,
underline: true,
strikethrough: true,
code: true
},
{
fontSize: '20px',
bold: true,
italic: true,
underline: true,
strikethrough: true,
text: 'over more'
} }
], ],
type: 'p', type: 'p',

View File

@ -68,10 +68,7 @@ export function DateElement(props: PlateElementProps<TDateElement>) {
<PopoverContent className="w-auto p-0"> <PopoverContent className="w-auto p-0">
<Calendar <Calendar
selected={new Date(element.date as string)} selected={new Date(element.date as string)}
disabled={(date) => { disabled={false}
console.log(date);
return false;
}}
disableNavigation={false} disableNavigation={false}
onSelect={(date) => { onSelect={(date) => {
if (!date) return; if (!date) return;

View File

@ -16,17 +16,13 @@ import {
DropdownMenuItem, DropdownMenuItem,
DropdownMenuTrigger DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'; } from '@/components/ui/dropdown-menu';
import { import { Tooltip } from '@/components/ui/tooltip';
Tooltip,
TooltipBase,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '@/components/ui/tooltip';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { ToolbarButton, ToolbarMenuGroup } from '@/components/ui/toolbar/Toolbar'; import { ToolbarButton, ToolbarMenuGroup } from '@/components/ui/toolbar/Toolbar';
import { THEME_RESET_STYLE } from '@/styles/theme-reset'; import { useGetOrganizationUsers } from '@/api/buster_rest/organizations';
import { useGetPalettes } from '@/context-hooks/usePalettes';
import { isBrightColor } from '@/lib/colors';
export function FontColorToolbarButton({ export function FontColorToolbarButton({
children, children,
@ -37,6 +33,7 @@ export function FontColorToolbarButton({
tooltip?: string; tooltip?: string;
} & DropdownMenuProps) { } & DropdownMenuProps) {
const editor = useEditorRef(); const editor = useEditorRef();
const { organizationPalettes } = useGetPalettes();
const selectionDefined = useEditorSelector((editor) => !!editor.selection, []); const selectionDefined = useEditorSelector((editor) => !!editor.selection, []);
@ -45,6 +42,17 @@ export function FontColorToolbarButton({
const [selectedColor, setSelectedColor] = React.useState<string>(); const [selectedColor, setSelectedColor] = React.useState<string>();
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const customColors: TColor[] = React.useMemo(() => {
const dedupedColors = new Set(organizationPalettes.flatMap((palette) => palette.colors));
return Array.from(dedupedColors).map((color) => {
return {
isBrightColor: isBrightColor(color),
name: color,
value: color
};
});
}, [organizationPalettes]);
const onToggle = React.useCallback( const onToggle = React.useCallback(
(value = !open) => { (value = !open) => {
setOpen(value); setOpen(value);
@ -93,6 +101,8 @@ export function FontColorToolbarButton({
} }
}, [color, selectionDefined]); }, [color, selectionDefined]);
console.log(customColors, organizationPalettes);
return ( return (
<DropdownMenu <DropdownMenu
open={open} open={open}
@ -106,12 +116,12 @@ export function FontColorToolbarButton({
</ToolbarButton> </ToolbarButton>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="start" style={THEME_RESET_STYLE}> <DropdownMenuContent align="start">
<ColorPicker <ColorPicker
color={selectedColor || color} color={selectedColor || color}
clearColor={clearColor} clearColor={clearColor}
colors={DEFAULT_COLORS} colors={DEFAULT_COLORS}
customColors={DEFAULT_CUSTOM_COLORS} customColors={customColors}
updateColor={updateColorAndClose} updateColor={updateColorAndClose}
updateCustomColor={updateColor} updateCustomColor={updateColor}
/> />
@ -131,25 +141,29 @@ function PureColorPicker({
...props ...props
}: React.ComponentProps<'div'> & { }: React.ComponentProps<'div'> & {
colors: TColor[]; colors: TColor[];
customColors: TColor[]; customColors: TColor[] | undefined;
clearColor: () => void; clearColor: () => void;
updateColor: (color: string) => void; updateColor: (color: string) => void;
updateCustomColor: (color: string) => void; updateCustomColor: (color: string) => void;
color?: string; color?: string;
}) { }) {
const hasCustomColors: boolean = !!customColors && customColors?.length > 0;
return ( return (
<div className={cn('flex flex-col', className)} {...props}> <div className={cn('flex flex-col', className)} {...props}>
<ToolbarMenuGroup label="Custom Colors"> {hasCustomColors && (
<ColorCustom <ToolbarMenuGroup label="Organization colors">
color={color} <ColorCustom
className="px-2" color={color}
colors={colors} className="px-2"
customColors={customColors} colors={colors}
updateColor={updateColor} customColors={customColors || []}
updateCustomColor={updateCustomColor} updateColor={updateColor}
/> updateCustomColor={updateCustomColor}
</ToolbarMenuGroup> />
<ToolbarMenuGroup label="Default Colors"> </ToolbarMenuGroup>
)}
<ToolbarMenuGroup label="Default colors">
<ColorDropdownMenuItems <ColorDropdownMenuItems
color={color} color={color}
className="px-2" className="px-2"
@ -232,7 +246,7 @@ function ColorCustom({
return ( return (
<div className={cn('relative flex flex-col gap-4', className)} {...props}> <div className={cn('relative flex flex-col gap-4', className)} {...props}>
<ColorDropdownMenuItems color={color} colors={computedColors} updateColor={updateColor}> <ColorDropdownMenuItems color={color} colors={computedColors} updateColor={updateColor}>
<ColorInput {/* <ColorInput
value={value} value={value}
onChange={(e) => { onChange={(e) => {
setValue(e.target.value); setValue(e.target.value);
@ -254,7 +268,7 @@ function ColorCustom({
<Plus /> <Plus />
</div> </div>
</DropdownMenuItem> </DropdownMenuItem>
</ColorInput> </ColorInput> */}
</ColorDropdownMenuItems> </ColorDropdownMenuItems>
</div> </div>
); );
@ -772,31 +786,3 @@ export const DEFAULT_COLORS = [
value: '#4C1130' value: '#4C1130'
} }
]; ];
const DEFAULT_CUSTOM_COLORS = [
{
isBrightColor: false,
name: 'dark orange 3',
value: '#783F04'
},
{
isBrightColor: false,
name: 'dark grey 3',
value: '#666666'
},
{
isBrightColor: false,
name: 'dark grey 2',
value: '#999999'
},
{
isBrightColor: false,
name: 'light cornflower blue 1',
value: '#6C9EEB'
},
{
isBrightColor: false,
name: 'dark magenta 3',
value: '#4C1130'
}
];

View File

@ -6,12 +6,15 @@ import {
FontBackgroundColorPlugin, FontBackgroundColorPlugin,
FontColorPlugin, FontColorPlugin,
FontFamilyPlugin, FontFamilyPlugin,
FontSizePlugin FontSizePlugin,
FontWeightPlugin
} from '@platejs/basic-styles/react'; } from '@platejs/basic-styles/react';
import { KEYS } from 'platejs'; import { KEYS } from 'platejs';
const options = { const options = {
inject: { targetPlugins: [KEYS.p] } inject: {
targetPlugins: [KEYS.p]
}
} satisfies PlatePluginConfig; } satisfies PlatePluginConfig;
export const FontKit = [ export const FontKit = [
@ -25,5 +28,6 @@ export const FontKit = [
}), }),
FontBackgroundColorPlugin.configure(options), FontBackgroundColorPlugin.configure(options),
FontSizePlugin.configure(options), FontSizePlugin.configure(options),
FontFamilyPlugin.configure(options) FontFamilyPlugin.configure(options),
FontWeightPlugin.configure(options)
]; ];

View File

@ -6,6 +6,10 @@ export const determineFontColorContrast = (color: string, threshold = TEXT_THRES
return fontColorContrast(color, threshold); return fontColorContrast(color, threshold);
}; };
export const isBrightColor = (color: string) => {
return determineFontColorContrast(color) === '#ffffff';
};
export const addOpacityToColor = (color: string, opacity: number): string => { export const addOpacityToColor = (color: string, opacity: number): string => {
if (opacity === 1) { if (opacity === 1) {
return color; return color;

View File

@ -32,6 +32,10 @@ export const TextSchema = z
kbd: z.boolean().optional(), kbd: z.boolean().optional(),
strikethrough: z.boolean().optional(), strikethrough: z.boolean().optional(),
code: z.boolean().optional(), code: z.boolean().optional(),
fontSize: z
.string()
.regex(/^(?:\d+px)$/)
.optional(),
}) })
.merge(AttributesSchema); .merge(AttributesSchema);