From 7779c7de92205621b107bfe56584da9fafaa00c8 Mon Sep 17 00:00:00 2001 From: Edouard Wautier <4435185+Duncid@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:07:17 +0100 Subject: [PATCH] Polishing Input, Area, Chip, Dropdown (#8581) * Fixing Dropdown with description style * Polishing Sparkle styles * [sparkle] - refactor: streamline handling of animated text variants - Abstract animated text background and text color variants into separate records for cleaner code structure - Use cva utility from `class-variance-authority` to manage TextArea component styles, introducing a more flexible and scalable approach to variant handling [sparkle] - fix: mark `isBusy` prop in `Chip` component as potentially undefined - Adjust typings for `isBusy` prop to correctly reflect its optional nature in the `Chip` component [sparkle] - refactor: introduce cva to refactor `TextArea` styles and variants - Consolidate `TextArea` styling and variant handling into a single cva call to improve readability and maintainability - Simplify the props destructuring in the `TextArea` component by relying on cva to handle default variants and classes * polishing * Hoverable * Page * [sparkle] - refactor: implement `cva` for className variations in `Hoverable` - Introduced `cva` for more scalable handling of className variations based on component variants - Replaced manual className construction with `cva` utility in `Hoverable` component for maintainability and readability improvements --------- Co-authored-by: JulesBelveze --- front/components/assistant/HelpDrawer.tsx | 27 ++++---- sparkle/package-lock.json | 4 +- sparkle/package.json | 2 +- sparkle/src/components/AnimatedText.tsx | 53 +++++++++++++--- sparkle/src/components/Chip.tsx | 11 +++- sparkle/src/components/Dropdown.tsx | 4 +- sparkle/src/components/Hoverable.tsx | 37 +++++++---- sparkle/src/components/Input.tsx | 9 ++- sparkle/src/components/Item.tsx | 36 ----------- sparkle/src/components/Page.tsx | 2 +- sparkle/src/components/TextArea.tsx | 71 +++++++++++++-------- sparkle/src/stories/Chip.stories.tsx | 2 +- sparkle/src/stories/Dropdown.stories.tsx | 27 ++++++++ sparkle/src/stories/Hoverable.stories.tsx | 10 +++ sparkle/src/stories/Item.stories.tsx | 76 +---------------------- sparkle/src/stories/TextArea.stories.tsx | 32 +++++++++- sparkle/tailwind.config.js | 6 +- 17 files changed, 217 insertions(+), 192 deletions(-) diff --git a/front/components/assistant/HelpDrawer.tsx b/front/components/assistant/HelpDrawer.tsx index d25332bedcb1..8719c8748068 100644 --- a/front/components/assistant/HelpDrawer.tsx +++ b/front/components/assistant/HelpDrawer.tsx @@ -2,7 +2,6 @@ import { Button, ChatBubbleBottomCenterTextIcon, FolderIcon, - Item, LightbulbIcon, Modal, Page, @@ -72,19 +71,23 @@ function LinksList({ title?: string; }) { return ( - - {title && } +
+ {title && ( +
{title}
+ )} {linksList.map((link, index) => ( - +
+
))} - +
); } diff --git a/sparkle/package-lock.json b/sparkle/package-lock.json index 14df0dcc1e6f..6707afa84b9d 100644 --- a/sparkle/package-lock.json +++ b/sparkle/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dust-tt/sparkle", - "version": "0.2.304", + "version": "0.2.305", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dust-tt/sparkle", - "version": "0.2.304", + "version": "0.2.305", "license": "ISC", "dependencies": { "@emoji-mart/data": "^1.1.2", diff --git a/sparkle/package.json b/sparkle/package.json index b84639073918..389191864a3e 100644 --- a/sparkle/package.json +++ b/sparkle/package.json @@ -1,6 +1,6 @@ { "name": "@dust-tt/sparkle", - "version": "0.2.304", + "version": "0.2.305", "scripts": { "build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs", "tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css", diff --git a/sparkle/src/components/AnimatedText.tsx b/sparkle/src/components/AnimatedText.tsx index e70d593b3025..de5c8363b4c4 100644 --- a/sparkle/src/components/AnimatedText.tsx +++ b/sparkle/src/components/AnimatedText.tsx @@ -4,16 +4,39 @@ import React from "react"; import { cn } from "@sparkle/lib/utils"; +const ANIMATED_TEXT_VARIANTS = [ + "muted", + "highlight", + "emerald", + "amber", + "slate", + "purple", + "warning", + "sky", + "pink", + "red", +] as const; + +type AnimatedTextVariantType = (typeof ANIMATED_TEXT_VARIANTS)[number]; + +const animatedVariants: Record = { + muted: "s-from-transparent s-via-primary-950/80 s-via-50% s-to-transparent", + highlight: "s-from-highlight s-via-highlight-800 s-via-50% s-to-highlight", + emerald: "s-from-emerald-800 s-via-emerald-950 s-via-50% s-to-emerald-800", + amber: "s-from-amber-800 s-via-amber-950 s-via-50% s-to-amber-800", + slate: "s-from-slate-600 s-via-slate-950 s-via-50% s-to-slate-600", + purple: "s-from-purple-800 s-via-purple-950 s-via-50% s-to-purple-800", + warning: "s-from-warning-800 s-via-warning-950 s-via-50% s-to-warning-800", + sky: "s-from-sky-800 s-via-sky-950 s-via-50% s-to-sky-800", + pink: "s-from-pink-800 s-via-pink-950 s-via-50% s-to-pink-800", + red: "s-from-red-800 s-via-red-950 s-via-50% s-to-red-800", +}; + const animVariants = cva( "s-relative s-mx-auto s-max-w-md s-text-black/0 s-animate-shiny-text s-bg-clip-text s-bg-no-repeat [background-position:0_0] [background-size:50%_100%] s-bg-gradient-to-r", { variants: { - variant: { - muted: - "s-from-transparent s-via-primary-950/80 s-via-50% s-to-transparent", - highlight: - "s-from-highlight s-via-highlight-800 s-via-50% s-to-highlight", - }, + variant: animatedVariants, }, defaultVariants: { variant: "muted", @@ -21,12 +44,22 @@ const animVariants = cva( } ); +const animatedTextVariants: Record = { + muted: "s-text-muted-foreground", + highlight: "s-text-highlight", + emerald: "s-text-emerald-800", + amber: "s-text-amber-800", + slate: "s-text-slate-600", + purple: "s-text-purple-800-800", + warning: "s-text-warning-800", + sky: "s-text-sky-800", + pink: "s-text-pink-800", + red: "s-text-red-800", +}; + const textVariants = cva("s-absolute s-inset-0", { variants: { - variant: { - muted: "s-text-muted-foreground", - highlight: "s-text-highlight", - }, + variant: animatedTextVariants, }, defaultVariants: { variant: "muted", diff --git a/sparkle/src/components/Chip.tsx b/sparkle/src/components/Chip.tsx index 148fd5eb1afd..46f7c78bd4d0 100644 --- a/sparkle/src/components/Chip.tsx +++ b/sparkle/src/components/Chip.tsx @@ -1,6 +1,7 @@ import { cva } from "class-variance-authority"; import React, { ComponentType, ReactNode } from "react"; +import { AnimatedText } from "@sparkle/components/"; import { cn } from "@sparkle/lib/utils"; import { Icon, IconProps } from "./Icon"; @@ -83,13 +84,13 @@ export function Chip({ label, children, className, - isBusy = false, + isBusy, icon, }: ChipProps) { return (
} {label && ( - {label} + {isBusy ? ( + {label} + ) : ( + label + )} )} {children} diff --git a/sparkle/src/components/Dropdown.tsx b/sparkle/src/components/Dropdown.tsx index d15a33c9a965..4d968686cb28 100644 --- a/sparkle/src/components/Dropdown.tsx +++ b/sparkle/src/components/Dropdown.tsx @@ -40,7 +40,7 @@ export const menuStyleClasses = { }, label: "s-font-semibold s-px-2 s-py-2 s-text-xs s-text-muted-foreground", description: - "s-grow s-truncate s-text-sm s-font-regular s-text-element-700 dark:s-text-element-600-dark", + "s-grow s-truncate s-text-xs s-text-muted-foreground s-font-normal", separator: "-s-mx-1 s-my-1 s-h-px s-bg-separator", shortcut: "s-ml-auto s-text-xs s-tracking-widest s-text-primary-400", }; @@ -85,7 +85,7 @@ const ItemWithLabelIconAndDescription = < return ( <> {label && ( -
+
{icon && (
{ children: ReactNode; className?: string; onClick: (e: SyntheticEvent) => void; - variant?: "primary" | "invisible"; } export function Hoverable({ children, - className = "", + className, onClick, - variant = "invisible", + variant, }: HoverableProps) { - const baseClasses = "s-cursor-pointer s-duration-300"; - - const variantClasses = { - invisible: "hover:s-text-action-500 active:s-text-action-600", - primary: "s-font-bold s-text-blue-500 hover:active:s-text-action-600", - }; - return ( {children} diff --git a/sparkle/src/components/Input.tsx b/sparkle/src/components/Input.tsx index c901d8745931..d31f85223db3 100644 --- a/sparkle/src/components/Input.tsx +++ b/sparkle/src/components/Input.tsx @@ -32,10 +32,9 @@ const messageVariantStyles: Record = { }; const stateVariantStyles: Record = { - default: "focus-visible:s-ring-ring", - disabled: - "disabled:s-cursor-not-allowed disabled:s-opacity-50 disabled:s-text-muted-foreground", - error: "s-border-border-warning focus:s-ring-ring-warning", + default: "", + disabled: "disabled:s-cursor-not-allowed disabled:s-text-muted-foreground", + error: "focus:s-ring-ring-warning", }; const messageVariant = cva("", { @@ -49,7 +48,7 @@ const messageVariant = cva("", { const inputStyleClasses = cva( cn( - "s-text-sm s-bg-background s-rounded-xl s-border s-border-border-dark s-flex s-h-9 s-w-full s-px-3 s-py-1.5 ", + "s-text-sm s-bg-background s-rounded-xl s-border s-border-border-dark/0 s-bg-muted-background s-flex s-h-9 s-w-full s-px-3 s-py-1.5 ", "file:s-border-0 file:s-bg-transparent file:s-text-sm file:s-font-medium file:s-text-foreground", "placeholder:s-text-muted-foreground", "focus-visible:s-outline-none focus-visible:s-ring-2 focus-visible:s-ring-offset-2 focus-visible:s-border-border-dark" diff --git a/sparkle/src/components/Item.tsx b/sparkle/src/components/Item.tsx index b64f0ba6f024..ba678e41075d 100644 --- a/sparkle/src/components/Item.tsx +++ b/sparkle/src/components/Item.tsx @@ -221,42 +221,6 @@ Item.Avatar = function ({ ); }; -type NavigationListItemProps = Pick< - ItemProps, - | "action" - | "className" - | "description" - | "disabled" - | "hasAction" - | "icon" - | "label" - | "link" - | "onClick" - | "selected" ->; - -Item.Navigation = function (props: NavigationListItemProps) { - return ; -}; - -type LinkItemProps = Pick< - ItemProps, - "onClick" | "label" | "description" | "visual" | "icon" | "className" | "link" ->; - -Item.Link = function ({ ...props }: LinkItemProps) { - return ( - - ); -}; - interface DropdownListItemBaseProps { style?: "default" | "warning"; } diff --git a/sparkle/src/components/Page.tsx b/sparkle/src/components/Page.tsx index 7319d8bb609c..3c935145bc12 100644 --- a/sparkle/src/components/Page.tsx +++ b/sparkle/src/components/Page.tsx @@ -40,7 +40,7 @@ interface PageHeaderProps { Page.Header = function ({ title, description, icon }: PageHeaderProps) { return ( - + {title} {description && {description}} diff --git a/sparkle/src/components/TextArea.tsx b/sparkle/src/components/TextArea.tsx index 1db8ae945b93..5c61cd8f0690 100644 --- a/sparkle/src/components/TextArea.tsx +++ b/sparkle/src/components/TextArea.tsx @@ -1,3 +1,4 @@ +import { cva } from "class-variance-authority"; import React from "react"; import { cn } from "@sparkle/lib/utils"; @@ -12,55 +13,71 @@ export interface TextareaProps error?: string | null; showErrorLabel?: boolean; minRows?: number; + isDisplay?: boolean; } -const textAreaStyles = cn( - "s-flex s-w-full s-px-3 s-py-2", - "s-transition s-duration-100", - "s-text-sm placeholder:s-text-muted-foreground s-text-foreground", - "s-ring-offset-background s-border s-border-border-dark s-bg-background s-rounded-xl", - "focus-visible:s-outline-none focus-visible:s-ring-2 focus-visible:s-ring-offset-2 ", - "disabled:s-cursor-not-allowed disabled:s-opacity-50 disabled:s-text-muted-foreground" +const textAreaVariants = cva( + "s-flex s-w-full s-px-3 s-py-2 s-text-sm s-text-foreground s-bg-muted-background s-ring-offset-background s-border s-border-border-dark/0 s-rounded-xl s-transition s-duration-100 focus-visible:s-outline-none focus-visible:s-border-border-dark focus-visible:s-ring-2 focus-visible:s-ring-offset-2", + { + variants: { + resize: { + none: "s-resize-none", + vertical: "s-resize-y", + horizontal: "s-resize-x", + both: "s-resize", + }, + error: { + true: "s-ring-warning-200 focus:s-ring-warning-300 dark:s-ring-warning-200-dark dark:focus:s-ring-warning-300-dark", + false: + "s-ring-structure-200 focus:s-ring-action-300 dark:s-ring-structure-300-dark dark:focus:s-ring-action-300-dark", + }, + disabled: { + true: "disabled:s-cursor-not-allowed disabled:s-text-muted-foreground", + false: "", + }, + isDisplay: { + true: "s-cursor-default", + false: "", + }, + }, + defaultVariants: { + resize: "both", + error: false, + disabled: false, + isDisplay: false, + }, + } ); const TextArea = React.forwardRef( ( { className, - resize = "both", + resize, minRows = 10, error, showErrorLabel, + disabled, + isDisplay, ...props }, ref ) => { - const resizeClass = { - none: "s-resize-none", - vertical: "s-resize-y", - horizontal: "s-resize-x", - both: "s-resize", - }; - return (