From 45af7db4d4e93f6af4a244dda2f62ac7a6a697d8 Mon Sep 17 00:00:00 2001 From: Jules Belveze <32683010+JulesBelveze@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:44:15 +0100 Subject: [PATCH] [sparkle] - refacto: Checkbox / RadioGroup (#8752) * [sparkle/src/components] - refactor: centralize Checkbox size styles - Extract size variant mapping from the Checkbox component into a separate constant for better maintainability - Replace inlined size variant definitions in the component with the new centralized `checkboxSizeVariant` mapping [sparkle/src/stories] - feature: update Checkbox stories with enhanced controls and structure - Introduce controls for size, checked state, and disabled state with descriptions and default values in the Checkbox story - Add `text` and `description` properties with conditional rendering logic for more comprehensive story examples - Implement action handlers for onChange events in Checkbox stories to better demonstrate component interaction * [sparkle] - feature: integrate labels directly into RadioGroupItems - Implemented direct label support within the RadioGroupItem component for better encapsulation - Updated RadioGroupItem usage in stories to leverage the new label prop, simplifying layout - Enhanced RadioGroupItem styling to accommodate label inclusion - Adjusted RadioGroupChoice to a flex-column layout to align with new item structure * [sparkle] - refactor: improve readability and syntax conformity in RadioGroup components - Reorder imports to maintain consistent structure across files - Add missing semicolons for code consistency - Reformat props spreading for better readability - Simplify JSX structure by removing redundant divs and merging classNames - Adjust stories for RadioGroup to provide clearer examples with proper htmlFor attributes * [sparkle] - refactor: simplify label prop usage in RadioGroup components - Refactor RadioGroup stories to use string labels directly instead of wrapping them with a Label component * [sparkle] - refactor: update `RadioGroup` to support ReactNode labels - Removed `Label` component import, allowing more flexible `label` prop types in `RadioGroupItem` - Replaced static text labels with JSX labels in `RadioGroup.stories` - Simplified the wrapper div class logic for RadioGroupItem components - Enhanced `RadioGroupWithChildrenExample` with additional icon and style adjustments * [sparkle] - fix: ensure RadioGroup items use full width - Added a class to make RadioGroup items use the full available width for better layout control * [sparkle] - feature: bump package version to 0.2.322 - Increment package version for a new release with latest changes and fixes --- sparkle/package-lock.json | 4 +- sparkle/package.json | 2 +- sparkle/src/components/Checkbox.tsx | 13 +- sparkle/src/components/RadioGroup.tsx | 25 +++- sparkle/src/stories/Checkbox.stories.tsx | 144 +++++++++++++-------- sparkle/src/stories/RadioGroup.stories.tsx | 47 +++++-- 6 files changed, 152 insertions(+), 83 deletions(-) diff --git a/sparkle/package-lock.json b/sparkle/package-lock.json index e6defe726daf..c79a5af5ba6b 100644 --- a/sparkle/package-lock.json +++ b/sparkle/package-lock.json @@ -1,12 +1,12 @@ { "name": "@dust-tt/sparkle", - "version": "0.2.321", + "version": "0.2.322", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@dust-tt/sparkle", - "version": "0.2.321", + "version": "0.2.322", "license": "ISC", "dependencies": { "@emoji-mart/data": "^1.1.2", diff --git a/sparkle/package.json b/sparkle/package.json index 1c255aa971a2..4fb419a2ee86 100644 --- a/sparkle/package.json +++ b/sparkle/package.json @@ -1,6 +1,6 @@ { "name": "@dust-tt/sparkle", - "version": "0.2.321", + "version": "0.2.322", "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/Checkbox.tsx b/sparkle/src/components/Checkbox.tsx index d82e996d0a6e..75eb1ae59ae7 100644 --- a/sparkle/src/components/Checkbox.tsx +++ b/sparkle/src/components/Checkbox.tsx @@ -8,6 +8,14 @@ import { cn } from "@sparkle/lib/utils"; import { Icon } from "./Icon"; import { Label } from "./Label"; +export const CHECKBOX_SIZES = ["xs", "sm"] as const; +type CheckboxSizeType = (typeof CHECKBOX_SIZES)[number]; + +const checkboxSizeVariant: Record = { + xs: "s-h-4 s-w-4 s-rounded", + sm: "s-h-5 s-w-5 s-rounded-md", +}; + const checkboxStyles = cva( cn( "s-shrink-0 s-peer s-border s-text-foreground s-border-border-darker", @@ -22,10 +30,7 @@ const checkboxStyles = cva( partial: "data-[state=checked]:s-bg-muted-foreground", false: "", }, - size: { - xs: "s-h-4 s-w-4 s-rounded", - sm: "s-h-5 s-w-5 s-rounded-md", - }, + size: checkboxSizeVariant, }, defaultVariants: { size: "sm", diff --git a/sparkle/src/components/RadioGroup.tsx b/sparkle/src/components/RadioGroup.tsx index f2d1512b85d8..23edb9702fd4 100644 --- a/sparkle/src/components/RadioGroup.tsx +++ b/sparkle/src/components/RadioGroup.tsx @@ -60,6 +60,7 @@ interface RadioGroupItemProps VariantProps { tooltipMessage?: string; tooltipAsChild?: boolean; + label?: React.ReactNode; } const RadioGroupItem = React.forwardRef< @@ -67,7 +68,14 @@ const RadioGroupItem = React.forwardRef< RadioGroupItemProps >( ( - { tooltipMessage, className, size, tooltipAsChild = false, ...props }, + { + tooltipMessage, + className, + size, + tooltipAsChild = false, + label, + ...props + }, ref ) => { const item = ( @@ -81,10 +89,9 @@ const RadioGroupItem = React.forwardRef< /> ); - return ( -
+ + const wrappedItem = ( +
{tooltipMessage ? ( ); + + return
{wrappedItem}
; } ); -RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName; type IconPosition = "start" | "center" | "end"; @@ -111,7 +120,9 @@ const RadioGroupChoice = React.forwardRef< RadioGroupChoiceProps >(({ className, size, iconPosition = "center", children, ...props }, ref) => { return ( -
+
; + // We need to cast here as the component expects stricter props + component: Checkbox as React.ComponentType, + parameters: { + layout: "centered", + }, + argTypes: { + size: { + description: "The size of the checkbox", + options: CHECKBOX_SIZES, + control: { type: "select" }, + table: { + defaultValue: { summary: "sm" }, + }, + }, + checked: { + description: "The checked state of the checkbox", + options: Object.keys(CHECKED_STATES), + mapping: CHECKED_STATES, + control: { type: "select" }, + table: { + type: { summary: "boolean | 'partial'" }, + defaultValue: { summary: "false" }, + }, + }, + disabled: { + description: "Whether the checkbox is disabled", + control: "boolean", + table: { + defaultValue: { summary: false }, + }, + }, + className: { + description: "Additional CSS classes to apply", + control: "text", + }, + text: { + description: "Optional text label to display next to the checkbox", + control: "text", + }, + description: { + description: + "Optional description text (only shown when text is provided)", + control: "text", + if: { arg: "text" }, + }, + onChange: { + description: "Callback when checkbox state changes", + action: "changed", + }, + }, +} satisfies Meta; export default meta; +type Story = StoryObj; -const handleChange = () => { - // This function intentionally left blank -}; - -export const CheckBoxSizesExample = () => { - return ( -
-
- SM - - - - - - -
-
- XS - - - - - - { + if (text && description) { + return ( + -
-
- ); -}; - -export const CheckBoxWithTextExample = () => { - return ( -
- -
- ); -}; - -export const CheckBoxWithTextAndDescriptionExample = () => { - return ( -
- - -
- ); + ); + } + if (text) { + return ; + } + return ; + }, }; diff --git a/sparkle/src/stories/RadioGroup.stories.tsx b/sparkle/src/stories/RadioGroup.stories.tsx index 6b48026d6b90..8808892acd38 100644 --- a/sparkle/src/stories/RadioGroup.stories.tsx +++ b/sparkle/src/stories/RadioGroup.stories.tsx @@ -3,6 +3,7 @@ import React from "react"; import { Button, + FolderIcon, Icon, Label, LockIcon, @@ -21,16 +22,25 @@ export const RadioGroupExample = () => {
- - + Option One} + />
- - + Option Two} + />
- - + Option Three} + />
@@ -40,8 +50,8 @@ export const RadioGroupExample = () => { id="option-four" size="sm" tooltipMessage="This is a nice tooltip message" + label={} /> -
{ id="option-five" size="sm" disabled + label={} /> -
- - + Option Three} + />
@@ -77,9 +91,18 @@ export const RadioGroupWithChildrenExample = () => { onValueChange={(value) => setSelectedChoice(value)} > {choices.map((choice) => ( - + + + +
+ } + >
- +