refactor: enhance UI components with dark mode support and streamline tooltip usage across toolbar buttons

This commit is contained in:
Anish Sarkar 2026-02-17 02:26:43 +05:30
parent 6af251a108
commit d4ad1dcae4
9 changed files with 21 additions and 26 deletions

View file

@ -74,7 +74,7 @@ function DropdownMenuItem({
data-inset={inset}
data-variant={variant}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"focus:bg-accent focus:text-accent-foreground dark:focus:bg-neutral-700 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
@ -92,7 +92,7 @@ function DropdownMenuCheckboxItem({
<DropdownMenuPrimitive.CheckboxItem
data-slot="dropdown-menu-checkbox-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"focus:bg-accent focus:text-accent-foreground dark:focus:bg-neutral-700 relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
checked={checked}
@ -128,7 +128,7 @@ function DropdownMenuRadioItem({
<DropdownMenuPrimitive.RadioItem
data-slot="dropdown-menu-radio-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"focus:bg-accent focus:text-accent-foreground dark:focus:bg-neutral-700 relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
@ -211,7 +211,7 @@ function DropdownMenuSubTrigger({
data-slot="dropdown-menu-sub-trigger"
data-inset={inset}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"focus:bg-accent focus:text-accent-foreground dark:focus:bg-neutral-700 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground dark:data-[state=open]:bg-neutral-700 [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}

View file

@ -25,35 +25,29 @@ export function FloatingToolbarButtons() {
return (
<>
<ToolbarGroup>
<TurnIntoToolbarButton />
<TurnIntoToolbarButton tooltip={false} />
<MarkToolbarButton nodeType={KEYS.bold} tooltip="Bold (⌘+B)">
<MarkToolbarButton nodeType={KEYS.bold}>
<BoldIcon />
</MarkToolbarButton>
<MarkToolbarButton nodeType={KEYS.italic} tooltip="Italic (⌘+I)">
<MarkToolbarButton nodeType={KEYS.italic}>
<ItalicIcon />
</MarkToolbarButton>
<MarkToolbarButton
nodeType={KEYS.underline}
tooltip="Underline (⌘+U)"
>
<MarkToolbarButton nodeType={KEYS.underline}>
<UnderlineIcon />
</MarkToolbarButton>
<MarkToolbarButton
nodeType={KEYS.strikethrough}
tooltip="Strikethrough (⌘+⇧+M)"
>
<MarkToolbarButton nodeType={KEYS.strikethrough}>
<StrikethroughIcon />
</MarkToolbarButton>
<MarkToolbarButton nodeType={KEYS.code} tooltip="Code (⌘+E)">
<MarkToolbarButton nodeType={KEYS.code}>
<Code2Icon />
</MarkToolbarButton>
<LinkToolbarButton />
<LinkToolbarButton tooltip={false} />
</ToolbarGroup>
</>

View file

@ -74,7 +74,7 @@ export function FloatingToolbar({
{...rootProps}
ref={ref}
className={cn(
'scrollbar-hide absolute z-50 overflow-x-auto whitespace-nowrap rounded-md border bg-popover p-1 opacity-100 shadow-md print:hidden',
'scrollbar-hide absolute z-50 overflow-x-auto whitespace-nowrap rounded-md border bg-popover p-1 opacity-100 shadow-md print:hidden dark:bg-neutral-800 dark:border-neutral-700',
'max-w-[80vw]',
className
)}

View file

@ -328,7 +328,7 @@ const comboboxItemVariants = cva(
variants: {
interactive: {
false: '',
true: 'cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground data-[active-item=true]:bg-accent data-[active-item=true]:text-accent-foreground',
true: 'cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground data-[active-item=true]:bg-accent data-[active-item=true]:text-accent-foreground dark:hover:bg-neutral-700 dark:data-[active-item=true]:bg-neutral-700',
},
},
}

View file

@ -195,7 +195,7 @@ export function InsertToolbarButton(props: DropdownMenuProps) {
</DropdownMenuTrigger>
<DropdownMenuContent
className="flex max-h-[300px] min-w-0 flex-col overflow-y-scroll"
className="flex max-h-[300px] min-w-0 flex-col overflow-y-scroll dark:bg-neutral-800 dark:border dark:border-neutral-700"
align="start"
>
{groups.map(({ group, items }) => (

View file

@ -17,7 +17,7 @@ export function LinkToolbarButton(
const { props: buttonProps } = useLinkToolbarButton(state);
return (
<ToolbarButton {...props} {...buttonProps} data-plate-focus tooltip="Link">
<ToolbarButton tooltip="Link" {...props} {...buttonProps} data-plate-focus>
<Link />
</ToolbarButton>
);

View file

@ -362,7 +362,8 @@ export function ToolbarMenuGroup({
<DropdownMenuSeparator
className={cn(
'hidden',
'mb-0 shrink-0 peer-has-[[role=menuitem]]/menu-group:block peer-has-[[role=menuitemradio]]/menu-group:block peer-has-[[role=option]]/menu-group:block'
'mb-0 mx-2 shrink-0 peer-has-[[role=menuitem]]/menu-group:block peer-has-[[role=menuitemradio]]/menu-group:block peer-has-[[role=option]]/menu-group:block',
'dark:bg-neutral-700'
)}
/>

View file

@ -126,7 +126,7 @@ export const turnIntoItems = [
},
];
export function TurnIntoToolbarButton(props: DropdownMenuProps) {
export function TurnIntoToolbarButton({ tooltip = 'Turn into', ...props }: DropdownMenuProps & { tooltip?: React.ReactNode }) {
const editor = useEditorRef();
const [open, setOpen] = React.useState(false);
@ -147,7 +147,7 @@ export function TurnIntoToolbarButton(props: DropdownMenuProps) {
<ToolbarButton
className="min-w-[125px]"
pressed={open}
tooltip="Turn into"
tooltip={tooltip}
isDropdown
>
{selectedItem.label}
@ -155,7 +155,7 @@ export function TurnIntoToolbarButton(props: DropdownMenuProps) {
</DropdownMenuTrigger>
<DropdownMenuContent
className="ignore-click-outside/toolbar min-w-0 max-h-[350px] overflow-y-scroll"
className="ignore-click-outside/toolbar min-w-0 max-h-[350px] overflow-y-scroll dark:bg-neutral-800 dark:border dark:border-neutral-700"
onCloseAutoFocus={(e) => {
e.preventDefault();
editor.tf.focus();