From efabe6766a07b2cbb82701ff95804467a5da9761 Mon Sep 17 00:00:00 2001 From: Pierantonio Zocchi Date: Tue, 13 Jan 2026 16:23:38 +0100 Subject: [PATCH 1/3] Migrate RLSelect, RLTextArea and RlTooltip to Shoelace React components --- src/components/RLSelect/RLSelect.tsx | 135 +++++++++-------------- src/components/RLTextArea/RLTextArea.tsx | 102 +++++++---------- src/components/RLTooltip/RLTooltip.tsx | 37 ++----- 3 files changed, 104 insertions(+), 170 deletions(-) diff --git a/src/components/RLSelect/RLSelect.tsx b/src/components/RLSelect/RLSelect.tsx index 008f7c6..8002968 100644 --- a/src/components/RLSelect/RLSelect.tsx +++ b/src/components/RLSelect/RLSelect.tsx @@ -1,41 +1,12 @@ import { forwardRef, useImperativeHandle, useCallback, useEffect, useMemo } from 'react' +import SlSelect from '@shoelace-style/shoelace/dist/react/select/index.js' +import SlOption from '@shoelace-style/shoelace/dist/react/option/index.js' +import type SlSelectElement from '@shoelace-style/shoelace/dist/components/select/select.js' import type { RLSelectProps, RLSelectRef } from './types' -import type { SlChangeEvent } from '../utils/types' import { ErrorMessage } from '../utils/ErrorMessage' import { useValidation } from '../../hooks/useValidation' import { RLIcon } from '../RLIcon' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-select': React.DetailedHTMLProps, HTMLElement> & { - name?: string - value?: string | string[] - defaultValue?: string | string[] - size?: string - multiple?: boolean - placeholder?: string - maxOptionsVisible?: number - disabled?: boolean - clearable?: boolean - pill?: boolean - filled?: boolean - placement?: string - helpText?: string - label?: string - required?: boolean - form?: string - hoist?: boolean - class?: string - getTag?: (option: { getTextLabel: () => string }) => string - } - 'sl-option': React.DetailedHTMLProps, HTMLElement> & { - value?: string - } - } - } -} - export const RLSelect = forwardRef( ( { @@ -104,9 +75,8 @@ export const RLSelect = forwardRef( })) const handleChange = useCallback( - (event: Event) => { - const evt = event as unknown as SlChangeEvent - const target = evt.target as HTMLSelectElement & { value: string | string[] } + (event: CustomEvent) => { + const target = event.target as SlSelectElement const rawValue = target?.value let newValue: string | string[] | null @@ -118,75 +88,76 @@ export const RLSelect = forwardRef( newValue = null } + validate(newValue) onChange?.(newValue) - onSlChange?.(evt) + onSlChange?.(event) }, - [optionsDict, onChange, onSlChange] + [optionsDict, onChange, onSlChange, validate] ) const handleClear = useCallback( - (event: Event) => { - onClear?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onClear?.(event) }, [onClear] ) const handleBlur = useCallback( - (event: Event) => { - onBlur?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onBlur?.(event) }, [onBlur] ) const handleFocus = useCallback( - (event: Event) => { - onFocus?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onFocus?.(event) }, [onFocus] ) const handleInput = useCallback( - (event: Event) => { - onInput?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInput?.(event) }, [onInput] ) const handleInvalid = useCallback( - (event: Event) => { - onInvalid?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInvalid?.(event) }, [onInvalid] ) const handleShow = useCallback( - (event: Event) => { + (event: CustomEvent) => { event.stopPropagation() - onShow?.(event as unknown as Parameters>[0]) + onShow?.(event) }, [onShow] ) const handleHide = useCallback( - (event: Event) => { + (event: CustomEvent) => { event.stopPropagation() - onHide?.(event as unknown as Parameters>[0]) + onHide?.(event) }, [onHide] ) const handleAfterShow = useCallback( - (event: Event) => { + (event: CustomEvent) => { event.stopPropagation() - onAfterShow?.(event as unknown as Parameters>[0]) + onAfterShow?.(event) }, [onAfterShow] ) const handleAfterHide = useCallback( - (event: Event) => { + (event: CustomEvent) => { event.stopPropagation() - onAfterHide?.(event as unknown as Parameters>[0]) + onAfterHide?.(event) }, [onAfterHide] ) @@ -195,48 +166,50 @@ export const RLSelect = forwardRef( return `${option.getTextLabel()}` }, []) + const combinedClassName = `min-w-full listbox ${errorMessage ? 'error' : ''}` + return (
- {options.map((option) => ( - + {option.icon && ( )} {option.text} - + ))} - + {errorMessage && {errorMessage}}
) diff --git a/src/components/RLTextArea/RLTextArea.tsx b/src/components/RLTextArea/RLTextArea.tsx index 6c1a35e..1ba5061 100644 --- a/src/components/RLTextArea/RLTextArea.tsx +++ b/src/components/RLTextArea/RLTextArea.tsx @@ -1,38 +1,10 @@ import { forwardRef, useImperativeHandle, useCallback, useEffect } from 'react' +import SlTextarea from '@shoelace-style/shoelace/dist/react/textarea/index.js' +import type SlTextareaElement from '@shoelace-style/shoelace/dist/components/textarea/textarea.js' import type { RLTextAreaProps, RLTextAreaRef } from './types' -import type { SlChangeEvent } from '../utils/types' import { ErrorMessage } from '../utils/ErrorMessage' import { useValidation } from '../../hooks/useValidation' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-textarea': React.DetailedHTMLProps, HTMLElement> & { - name?: string - value?: string - defaultValue?: string - size?: string - filled?: boolean - label?: string - 'help-text'?: string - rows?: number - resize?: string - disabled?: boolean - placeholder?: string - readonly?: boolean - form?: string - required?: boolean - autocapitalize?: string - autocorrect?: string - autofocus?: boolean - spellcheck?: boolean - inputmode?: string - class?: string - } - } - } -} - export const RLTextArea = forwardRef( ( { @@ -80,72 +52,74 @@ export const RLTextArea = forwardRef( })) const handleChange = useCallback( - (event: Event) => { - const evt = event as unknown as SlChangeEvent - const target = evt.target as HTMLTextAreaElement + (event: CustomEvent) => { + const target = event.target as SlTextareaElement const newValue = target?.value ?? '' + validate(newValue) onChange?.(newValue) - onSlChange?.(evt) + onSlChange?.(event) }, - [onChange, onSlChange] + [onChange, onSlChange, validate] ) const handleBlur = useCallback( - (event: Event) => { - onBlur?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onBlur?.(event) }, [onBlur] ) const handleFocus = useCallback( - (event: Event) => { - onFocus?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onFocus?.(event) }, [onFocus] ) const handleInput = useCallback( - (event: Event) => { - onInput?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInput?.(event) }, [onInput] ) const handleInvalid = useCallback( - (event: Event) => { - onInvalid?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInvalid?.(event) }, [onInvalid] ) + const combinedClassName = errorMessage ? 'error' : undefined + return (
- {errorMessage && {errorMessage}}
diff --git a/src/components/RLTooltip/RLTooltip.tsx b/src/components/RLTooltip/RLTooltip.tsx index 974919b..29cb328 100644 --- a/src/components/RLTooltip/RLTooltip.tsx +++ b/src/components/RLTooltip/RLTooltip.tsx @@ -1,24 +1,9 @@ -import { forwardRef } from 'react' +import { forwardRef, isValidElement } from 'react' +import SlTooltip from '@shoelace-style/shoelace/dist/react/tooltip/index.js' +import type SlTooltipElement from '@shoelace-style/shoelace/dist/components/tooltip/tooltip.js' import type { RLTooltipProps } from './types' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-tooltip': React.DetailedHTMLProps, HTMLElement> & { - content?: string - placement?: string - disabled?: boolean - distance?: number - open?: boolean - skidding?: number - trigger?: string - hoist?: boolean - } - } - } -} - -export const RLTooltip = forwardRef( +export const RLTooltip = forwardRef( ( { content, @@ -33,20 +18,22 @@ export const RLTooltip = forwardRef( }, ref ) => { + const wrappedChildren = isValidElement(children) ? children : {children} + return ( - - {children} - + {wrappedChildren} + ) } ) From 889ee374c93372a05cf5ac1ae63fc37643171ab6 Mon Sep 17 00:00:00 2001 From: Pierantonio Zocchi Date: Tue, 13 Jan 2026 16:33:59 +0100 Subject: [PATCH 2/3] Migrate RLDailog,RLLIcon and RlLRagioGroup to Shoelace React components --- src/components/RLDialog/RLDialog.tsx | 57 +++++---------- src/components/RLIcon/RLIcon.tsx | 20 ++--- src/components/RLRadioGroup/RLRadioGroup.tsx | 77 ++++++++------------ 3 files changed, 56 insertions(+), 98 deletions(-) diff --git a/src/components/RLDialog/RLDialog.tsx b/src/components/RLDialog/RLDialog.tsx index 2ed5e93..96a0607 100644 --- a/src/components/RLDialog/RLDialog.tsx +++ b/src/components/RLDialog/RLDialog.tsx @@ -1,26 +1,9 @@ import { forwardRef, useImperativeHandle, useCallback, useRef } from 'react' +import SlDialog from '@shoelace-style/shoelace/dist/react/dialog/index.js' +import type SlDialogElement from '@shoelace-style/shoelace/dist/components/dialog/dialog.js' import type { RLDialogProps, RLDialogRef } from './types' import type { SlRequestCloseEvent } from '../utils/types' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-dialog': React.DetailedHTMLProps, HTMLElement> & { - label?: string - open?: boolean - noHeader?: boolean - class?: string - onSlShow?: (event: Event) => void - onSlAfterShow?: (event: Event) => void - onSlHide?: (event: Event) => void - onSlAfterHide?: (event: Event) => void - onSlInitialFocus?: (event: Event) => void - onSlRequestClose?: (event: Event) => void - } - } - } -} - export const RLDialog = forwardRef( ( { @@ -40,7 +23,7 @@ export const RLDialog = forwardRef( }, ref ) => { - const dialogRef = useRef void; hide: () => void }>(null) + const dialogRef = useRef(null) useImperativeHandle(ref, () => ({ open: dialogRef.current?.open, @@ -49,8 +32,8 @@ export const RLDialog = forwardRef( })) const handleRequestClose = useCallback( - (event: Event) => { - const evt = event as unknown as SlRequestCloseEvent + (event: CustomEvent) => { + const evt = event as SlRequestCloseEvent if (noCloseOnOutsideClick && evt.detail.source === 'overlay') { evt.preventDefault() return @@ -63,47 +46,47 @@ export const RLDialog = forwardRef( ) const handleShow = useCallback( - (event: Event) => { - onShow?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onShow?.(event) }, [onShow] ) const handleAfterShow = useCallback( - (event: Event) => { - onAfterShow?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onAfterShow?.(event) }, [onAfterShow] ) const handleHide = useCallback( - (event: Event) => { - onHide?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onHide?.(event) }, [onHide] ) const handleAfterHide = useCallback( - (event: Event) => { - onAfterHide?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onAfterHide?.(event) }, [onAfterHide] ) const handleInitialFocus = useCallback( - (event: Event) => { - onInitialFocus?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInitialFocus?.(event) }, [onInitialFocus] ) return ( - ( onSlRequestClose={handleRequestClose} > {children} - + ) } ) diff --git a/src/components/RLIcon/RLIcon.tsx b/src/components/RLIcon/RLIcon.tsx index c3a2dc3..f9cf9c5 100644 --- a/src/components/RLIcon/RLIcon.tsx +++ b/src/components/RLIcon/RLIcon.tsx @@ -1,24 +1,14 @@ import { forwardRef } from 'react' +import SlIcon from '@shoelace-style/shoelace/dist/react/icon/index.js' +import type SlIconElement from '@shoelace-style/shoelace/dist/components/icon/icon.js' import type { RLIconProps } from './types' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-icon': React.DetailedHTMLProps, HTMLElement> & { - name?: string - library?: string - class?: string - } - } - } -} - -export const RLIcon = forwardRef( +export const RLIcon = forwardRef( ({ name, library = 'default', className, onClick, slot }, ref) => { return ( - , HTMLElement> & { - value?: string - label?: string - helpText?: string - name?: string - size?: string - form?: string - required?: boolean - class?: string - } - 'sl-radio': React.DetailedHTMLProps, HTMLElement> & { - value?: string - disabled?: boolean - class?: string - } - } - } -} - export const RLRadioGroup = forwardRef( ( { @@ -60,55 +41,59 @@ export const RLRadioGroup = forwardRef( })) const handleChange = useCallback( - (event: Event) => { - const target = event.target as HTMLInputElement - onChange?.(target?.value ?? '') - onSlChange?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + const target = event.target as SlRadioGroupElement + const newValue = target?.value ?? '' + validate(newValue) + onChange?.(newValue) + onSlChange?.(event) }, - [onChange, onSlChange] + [onChange, onSlChange, validate] ) const handleInput = useCallback( - (event: Event) => { - onInput?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInput?.(event) }, [onInput] ) const handleInvalid = useCallback( - (event: Event) => { - onInvalid?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInvalid?.(event) }, [onInvalid] ) + const combinedClassName = errorMessage ? 'error' : undefined + return (
- {options.map((radio) => ( - {radio.label} - + ))} {children} - + {errorMessage && {errorMessage}}
) From b8cc16b398d7ac81b7f6985a00936431e7920e2a Mon Sep 17 00:00:00 2001 From: Pierantonio Zocchi Date: Tue, 13 Jan 2026 17:13:59 +0100 Subject: [PATCH 3/3] Migrate RLButton, RLCheckbox, RLColorPicker and RLExpansionCard to Shoelace React component --- src/components/RLButton/RLButton.tsx | 50 +++------- src/components/RLCheckbox/RLCheckbox.tsx | 96 ++++++++----------- .../RLColorPicker/RLColorPicker.tsx | 61 ++++-------- .../RLExpansionCard/RLExpansionCard.tsx | 45 +++------ .../components/RLExpansionCard.stories.tsx | 38 ++++++++ 5 files changed, 128 insertions(+), 162 deletions(-) create mode 100644 src/stories/components/RLExpansionCard.stories.tsx diff --git a/src/components/RLButton/RLButton.tsx b/src/components/RLButton/RLButton.tsx index b801cd4..c715313 100644 --- a/src/components/RLButton/RLButton.tsx +++ b/src/components/RLButton/RLButton.tsx @@ -1,31 +1,9 @@ import { forwardRef } from 'react' +import SlButton from '@shoelace-style/shoelace/dist/react/button/index.js' +import type SlButtonElement from '@shoelace-style/shoelace/dist/components/button/button.js' import type { RLButtonProps } from './types' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-button': React.DetailedHTMLProps, HTMLElement> & { - variant?: string - size?: string - caret?: boolean - disabled?: boolean - loading?: boolean - outline?: boolean - pill?: boolean - circle?: boolean - type?: string - name?: string - value?: string - href?: string - target?: string - form?: string - class?: string - } - } - } -} - -export const RLButton = forwardRef( +export const RLButton = forwardRef( ( { variant = 'default', @@ -51,21 +29,21 @@ export const RLButton = forwardRef( ref ) => { return ( - ( {prefix && {prefix}} {children} {suffix && {suffix}} - + ) } ) diff --git a/src/components/RLCheckbox/RLCheckbox.tsx b/src/components/RLCheckbox/RLCheckbox.tsx index f3f068e..6454abc 100644 --- a/src/components/RLCheckbox/RLCheckbox.tsx +++ b/src/components/RLCheckbox/RLCheckbox.tsx @@ -1,33 +1,10 @@ -import { forwardRef, useImperativeHandle, useCallback, useEffect } from 'react' +import { forwardRef, useImperativeHandle, useCallback, useEffect, useRef } from 'react' +import SlCheckbox from '@shoelace-style/shoelace/dist/react/checkbox/index.js' +import type SlCheckboxElement from '@shoelace-style/shoelace/dist/components/checkbox/checkbox.js' import type { RLCheckboxProps, RLCheckboxRef } from './types' -import type { SlInputEvent } from '../utils/types' import { ErrorMessage } from '../utils/ErrorMessage' import { useValidation } from '../../hooks/useValidation' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-checkbox': React.DetailedHTMLProps, HTMLElement> & { - name?: string - value?: boolean - size?: string - disabled?: boolean - checked?: boolean - indeterminate?: boolean - defaultChecked?: boolean - form?: string - required?: boolean - class?: string - onSlInput?: (event: Event) => void - onSlChange?: (event: Event) => void - onSlBlur?: (event: Event) => void - onSlFocus?: (event: Event) => void - onSlInvalid?: (event: Event) => void - } - } - } -} - export const RLCheckbox = forwardRef( ( { @@ -52,6 +29,13 @@ export const RLCheckbox = forwardRef( ref ) => { const { errorMessage, isValid, validate } = useValidation({ rules, externalError: error }) + const checkboxRef = useRef(null) + + useEffect(() => { + if (checkboxRef.current && checked !== undefined && checkboxRef.current.checked !== checked) { + checkboxRef.current.checked = checked + } + }, [checked]) useEffect(() => { if (checked !== undefined) { @@ -64,59 +48,61 @@ export const RLCheckbox = forwardRef( validate: () => validate(checked) })) - const handleInput = useCallback( - (event: Event) => { - const evt = event as unknown as SlInputEvent - const target = evt.target as HTMLInputElement & { checked: boolean } - onChange?.(target?.checked ?? false) - onInput?.(evt) + const handleChange = useCallback( + (event: CustomEvent) => { + const target = event.target as SlCheckboxElement + const newChecked = target?.checked ?? false + validate(newChecked) + onChange?.(newChecked) + onSlChange?.(event) }, - [onChange, onInput] + [onChange, onSlChange, validate] ) - const handleChange = useCallback( - (event: Event) => { - onSlChange?.(event as unknown as Parameters>[0]) + const handleInput = useCallback( + (event: CustomEvent) => { + onInput?.(event) }, - [onSlChange] + [onInput] ) const handleBlur = useCallback( - (event: Event) => { - onBlur?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onBlur?.(event) }, [onBlur] ) const handleFocus = useCallback( - (event: Event) => { - onFocus?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onFocus?.(event) }, [onFocus] ) const handleInvalid = useCallback( - (event: Event) => { - onInvalid?.(event as unknown as Parameters>[0]) + (event: CustomEvent) => { + onInvalid?.(event) }, [onInvalid] ) + const combinedClassName = `flex items-center ${errorMessage ? 'error' : ''}` + return (
- ( {label} )} - + {errorMessage && {errorMessage}}
) diff --git a/src/components/RLColorPicker/RLColorPicker.tsx b/src/components/RLColorPicker/RLColorPicker.tsx index c589f2a..c854fbe 100644 --- a/src/components/RLColorPicker/RLColorPicker.tsx +++ b/src/components/RLColorPicker/RLColorPicker.tsx @@ -1,29 +1,11 @@ import { forwardRef, useCallback, useRef, useEffect } from 'react' +import SlDropdown from '@shoelace-style/shoelace/dist/react/dropdown/index.js' +import SlColorPicker from '@shoelace-style/shoelace/dist/react/color-picker/index.js' +import SlButton from '@shoelace-style/shoelace/dist/react/button/index.js' +import type SlColorPickerElement from '@shoelace-style/shoelace/dist/components/color-picker/color-picker.js' import type { RLColorPickerProps } from './types' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-dropdown': React.DetailedHTMLProps, HTMLElement> & { - hoist?: boolean - open?: boolean - } - 'sl-color-picker': React.DetailedHTMLProps, HTMLElement> & { - hoist?: boolean - inline?: boolean - noFormatToggle?: boolean - opacity?: boolean - value?: string - name?: string - defaultValue?: string - required?: boolean - disabled?: boolean - } - } - } -} - -export const RLColorPicker = forwardRef( +export const RLColorPicker = forwardRef( ( { value = '#000000', @@ -39,7 +21,6 @@ export const RLColorPicker = forwardRef( ref ) => { const colorPreviewRef = useRef(null) - const slColorPickerRef = useRef(null) useEffect(() => { if (colorPreviewRef.current && value) { @@ -48,46 +29,46 @@ export const RLColorPicker = forwardRef( }, [value]) const handleChange = useCallback( - (event: Event) => { - const target = event.target as HTMLInputElement + (event: CustomEvent) => { + const target = event.target as SlColorPickerElement onChange?.(target?.value ?? '') }, [onChange] ) - const handleShow = useCallback((event: Event) => { + const handleShow = useCallback((event: CustomEvent) => { event.stopPropagation() }, []) - const handleHide = useCallback((event: Event) => { + const handleHide = useCallback((event: CustomEvent) => { event.stopPropagation() }, []) return ( - +
{label}
- +
{value &&
} {value}
- +
- - + ) } ) diff --git a/src/components/RLExpansionCard/RLExpansionCard.tsx b/src/components/RLExpansionCard/RLExpansionCard.tsx index 2716cbb..4e97698 100644 --- a/src/components/RLExpansionCard/RLExpansionCard.tsx +++ b/src/components/RLExpansionCard/RLExpansionCard.tsx @@ -1,22 +1,9 @@ import { forwardRef, useCallback, useImperativeHandle, useRef } from 'react' +import SlDetails from '@shoelace-style/shoelace/dist/react/details/index.js' +import type SlDetailsElement from '@shoelace-style/shoelace/dist/components/details/details.js' import type { RLExpansionCardProps, RLExpansionCardRef } from './types' -import type { SlAfterShowEvent, SlHideEvent, SlShowEvent, SlAfterHideEvent } from '../utils/types' import { RLIcon } from '../RLIcon' -declare global { - namespace JSX { - interface IntrinsicElements { - 'sl-details': React.DetailedHTMLProps, HTMLElement> & { - open?: boolean - onSlShow?: (event: Event) => void - onSlHide?: (event: Event) => void - onSlAfterShow?: (event: Event) => void - onSlAfterHide?: (event: Event) => void - } - } - } -} - export const RLExpansionCard = forwardRef( ( { @@ -36,7 +23,7 @@ export const RLExpansionCard = forwardRef { - const detailsRef = useRef void; hide: () => void }>(null) + const detailsRef = useRef(null) useImperativeHandle(ref, () => ({ show: () => detailsRef.current?.show(), @@ -44,44 +31,40 @@ export const RLExpansionCard = forwardRef { - const evt = event as unknown as SlShowEvent + (event: CustomEvent) => { onOpenChange?.(true) - onShow?.(evt) + onShow?.(event) }, [onOpenChange, onShow] ) const handleHide = useCallback( - (event: Event) => { - const evt = event as unknown as SlHideEvent + (event: CustomEvent) => { onOpenChange?.(false) - onHide?.(evt) + onHide?.(event) }, [onOpenChange, onHide] ) const handleAfterShow = useCallback( - (event: Event) => { - const evt = event as unknown as SlAfterShowEvent - onAfterShow?.(evt) + (event: CustomEvent) => { + onAfterShow?.(event) }, [onAfterShow] ) const handleAfterHide = useCallback( - (event: Event) => { - const evt = event as unknown as SlAfterHideEvent - onAfterHide?.(evt) + (event: CustomEvent) => { + onAfterHide?.(event) }, [onAfterHide] ) return ( - }
{children} - + ) } ) diff --git a/src/stories/components/RLExpansionCard.stories.tsx b/src/stories/components/RLExpansionCard.stories.tsx new file mode 100644 index 0000000..1db351f --- /dev/null +++ b/src/stories/components/RLExpansionCard.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { RLExpansionCard } from '../../components' + +const meta = { + title: 'Components/ExpansionCard', + component: RLExpansionCard, + tags: ['autodocs'], + argTypes: {}, + args: { + title: 'Expansion Card Title', + children: 'This is the content of the expansion card. It can contain any React elements.' + } +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: {} +} + +export const Open: Story = { + args: { + open: true + } +} + +export const CustomTitle: Story = { + args: { + title: 'Custom Expansion Card', + children: ( +
+

This expansion card has custom content.

+

You can add multiple paragraphs or any React components here.

+
+ ) + } +}