From 0cd7ec50bfba33183e654d6911490c31d6208dc9 Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Mon, 2 Dec 2024 12:44:29 +0100 Subject: [PATCH 01/11] Tests added, fixes on component --- .../FormFieldCheckbox.scss | 2 +- .../form-field-checkbox/FormFieldCheckbox.tsx | 38 ++++++++++---- .../test/form-field-checkbox.spec.tsx | 50 +++++++++++++++++++ .../form-field-textbox/FormFieldTextbox.tsx | 10 +--- packages/components-react/src/utils/object.ts | 17 +++++++ .../form-field-checkbox.stories.tsx | 8 +++ 6 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 packages/components-react/src/form-field-checkbox/test/form-field-checkbox.spec.tsx create mode 100644 packages/components-react/src/utils/object.ts diff --git a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.scss b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.scss index bc6ac3730..50c83a1aa 100644 --- a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.scss +++ b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.scss @@ -82,7 +82,7 @@ outline: none; } - &:not(#{&}--disabled):has(.utrecht-form-field__input .utrecht-checkbox:hover)::before { + &--with-target:not(#{&}--disabled):has(.utrecht-form-field__input .utrecht-checkbox:hover)::before { border-color: var(--lux-form-field-checkbox-hover-inner-border-color); background-color: var(--lux-form-field-checkbox-hover-inner-background-color); color: var(--lux-form-field-checkbox-hover-inner-color); diff --git a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx index 7c7fc442a..44216510b 100644 --- a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx +++ b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; import { useId } from 'react'; -import { LuxCheckbox } from '../checkbox/Checkbox'; +import { LuxCheckbox, LuxCheckboxProps } from '../checkbox/Checkbox'; import { LuxFormField, LuxFormFieldProps } from '../form-field/FormField'; import { LuxFormFieldDescription, @@ -9,14 +9,16 @@ import { import { LuxFormFieldErrorMessage } from '../form-field-error-message/FormFieldErrorMessage'; import { LuxFormFieldLabel } from '../form-field-label/FormFieldLabel'; import './FormFieldCheckbox.scss'; +import { pick } from '../utils/object'; -export type LuxFormFieldCheckboxProps = LuxFormFieldProps & { - checked?: boolean; - disabled?: boolean; - appearance?: LuxFormFieldDescriptionAppearance; - withTarget?: boolean; - distanced?: boolean; -}; +export type LuxFormFieldCheckboxProps = LuxFormFieldProps & + LuxCheckboxProps & { + checked?: boolean; + disabled?: boolean; + appearance?: LuxFormFieldDescriptionAppearance; + withTarget?: boolean; + distanced?: boolean; + }; export const LuxFormFieldCheckbox = ({ label, @@ -73,6 +75,17 @@ export const LuxFormFieldCheckbox = ({ errorMessage ); + const checkBoxAttrs = pick(restProps, [ + 'required', + 'inputRequired', + 'value', + 'defaultValue', + 'onFocus', + 'onBlur', + 'onInput', + 'onChange', + ]); + return ( + } className={clsx('lux-form-field-checkbox', { 'lux-form-field-checkbox--invalid': invalid, diff --git a/packages/components-react/src/form-field-checkbox/test/form-field-checkbox.spec.tsx b/packages/components-react/src/form-field-checkbox/test/form-field-checkbox.spec.tsx new file mode 100644 index 000000000..34c14f162 --- /dev/null +++ b/packages/components-react/src/form-field-checkbox/test/form-field-checkbox.spec.tsx @@ -0,0 +1,50 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen } from '@testing-library/react'; +import { LuxFormFieldCheckbox } from '../FormFieldCheckbox'; + +describe('Form Field Checkbox', () => { + it('renders a basic form field checkbox with label and input', () => { + render(); + + expect(screen.getByText('Name')).toBeInTheDocument(); + expect(screen.getByRole('checkbox')).toBeInTheDocument(); + }); + + it('applies the base class', () => { + render(); + + const formField = screen.getByText('Name').closest('.utrecht-form-field'); + expect(formField).toHaveClass('utrecht-form-field'); + }); + + it('can have an additional class name', () => { + render(); + + const formField = screen.getByText('Name').closest('.utrecht-form-field'); + expect(formField).toHaveClass('utrecht-form-field'); + expect(formField).toHaveClass('custom-class'); + }); + + it('renders description when provided', () => { + render(); + + expect(screen.getByText('Enter your full name')).toBeInTheDocument(); + }); + + it('renders error message when invalid and error message provided', () => { + render(); + + expect(screen.getByText('Name is required')).toBeInTheDocument(); + }); + + it('adds the correct attributes to the Checkbox', () => { + render(); + + const checkbox = screen.getByRole('checkbox'); + + expect(checkbox).toBeInTheDocument(); + expect(checkbox).toBeChecked(); + expect(checkbox).toHaveAttribute('aria-required', 'true'); + expect(checkbox).not.toHaveAttribute('required'); + }); +}); diff --git a/packages/components-react/src/form-field-textbox/FormFieldTextbox.tsx b/packages/components-react/src/form-field-textbox/FormFieldTextbox.tsx index b7e55d392..5f5526d71 100644 --- a/packages/components-react/src/form-field-textbox/FormFieldTextbox.tsx +++ b/packages/components-react/src/form-field-textbox/FormFieldTextbox.tsx @@ -10,6 +10,7 @@ import { import { LuxFormFieldErrorMessage } from '../form-field-error-message/FormFieldErrorMessage'; import { LuxFormFieldLabel } from '../form-field-label/FormFieldLabel'; import { type Direction, LuxTextbox } from '../textbox/Textbox'; +import { pick } from '../utils/object'; export type LuxFormFieldTextboxProps = UtrechtFormFieldTextboxProps & { appearance?: LuxFormFieldDescriptionAppearance; @@ -60,15 +61,6 @@ export const LuxFormFieldTextbox = ({ errorMessage ); - // TODO: naar utils - function pick(obj: T, paths: Array): Pick { - const ret = {} as Pick; - for (const k of paths) { - ret[k] = obj[k]; - } - return ret; - } - const textBoxAttrs = pick(restProps, [ 'autoComplete', 'min', diff --git a/packages/components-react/src/utils/object.ts b/packages/components-react/src/utils/object.ts new file mode 100644 index 000000000..4f57d08b2 --- /dev/null +++ b/packages/components-react/src/utils/object.ts @@ -0,0 +1,17 @@ +/** + * Pick only certain keys form object. + * + * @export + * @template {object} T + * @template {keyof T} U + * @param {T} obj Object to pick from + * @param {Array} keys Keys to pick + * @returns {Pick} Object containing only picked keys + */ +export function pick(obj: T, keys: Array): Pick { + const ret = {} as Pick; + for (const k of keys) { + ret[k] = obj[k]; + } + return ret; +} diff --git a/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx b/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx index 76161cd1c..7e60f5cb5 100644 --- a/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx +++ b/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx @@ -91,6 +91,14 @@ export const WithTarget: Story = { ...Playground.args, withTarget: true, }, + parameters: { + docs: { + description: { + story: + 'Met `withTarget` wordt het hele component (behalve de foutmelding) een klikdoel. _Let op:_ dit kan voor gebruikers onverwacht zijn.', + }, + }, + }, }; export const withLongTexts: Story = { From 4d22752c94a5c10dbcf9c2e48531929a565a4533 Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Fri, 6 Dec 2024 16:04:21 +0100 Subject: [PATCH 02/11] First set of Vis reg tests --- .../src/form-field-select/FormFieldSelect.tsx | 2 + .../form-field-checkbox.stories.tsx | 48 +++++++++++ .../form-field-select.stories.tsx | 46 ++++++++++ .../form-field-textbox.stories.tsx | 44 ++++++++++ .../form-field/form-field.stories.tsx | 48 +++++++++++ .../form-field/visual/FormFieldTypes.tsx | 84 +++++++++++++++++++ 6 files changed, 272 insertions(+) create mode 100644 packages/storybook/src/react-components/form-field/visual/FormFieldTypes.tsx diff --git a/packages/components-react/src/form-field-select/FormFieldSelect.tsx b/packages/components-react/src/form-field-select/FormFieldSelect.tsx index 3c123bed6..de69f06e3 100644 --- a/packages/components-react/src/form-field-select/FormFieldSelect.tsx +++ b/packages/components-react/src/form-field-select/FormFieldSelect.tsx @@ -96,6 +96,8 @@ export const LuxFormFieldSelect = ({ const formFieldAttrs = pick(restProps, ['children']); + // TODO: Options + return ( ( + <> +

Light

+ + + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + + +
+

Dark

+ + + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + + +
+ +)); diff --git a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx index 192f3659f..2f300f5c6 100644 --- a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx +++ b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx @@ -2,10 +2,13 @@ import { LuxFormFieldSelect, type LuxFormFieldSelectProps } from '@lux-design-sy import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; import FormFieldDescriptionMeta from '../form-field-description/form-field-description.stories'; import FormFieldErrorMessageMeta from '../form-field-error-message/form-field-error-message.stories'; import SelectMeta from '../select/select.stories'; +// TODO: Options + const meta = { title: 'React Components/Form Field/Form Field Select', id: 'react-components-form-field-form-field-select', @@ -54,3 +57,46 @@ export const Playground: Story = { }, tags: ['!autodocs'], }; + +export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( + <> +

Light

+ + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + +
+

Dark

+ + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + +
+ +)); diff --git a/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx b/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx index 47b26387c..4dc9ab61b 100644 --- a/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx +++ b/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx @@ -2,6 +2,7 @@ import { LuxFormFieldTextbox, type LuxFormFieldTextboxProps } from '@lux-design- import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; import FormFieldDescriptionMeta from '../form-field-description/form-field-description.stories'; import FormFieldErrorMessageMeta from '../form-field-error-message/form-field-error-message.stories'; import TextboxMeta from '../textbox/textbox.stories'; @@ -54,3 +55,46 @@ export const Playground: Story = { }, tags: ['!autodocs'], }; + +export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( + <> +

Light

+ + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + +
+

Dark

+ + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + +
+ +)); diff --git a/packages/storybook/src/react-components/form-field/form-field.stories.tsx b/packages/storybook/src/react-components/form-field/form-field.stories.tsx index 9cdc137e0..6953d4b5f 100644 --- a/packages/storybook/src/react-components/form-field/form-field.stories.tsx +++ b/packages/storybook/src/react-components/form-field/form-field.stories.tsx @@ -8,7 +8,9 @@ import { } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { FormFieldType } from './visual/FormFieldTypes'; import { BADGES } from '../../../config/preview'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; const meta = { title: 'React Components/Form Field', @@ -141,3 +143,49 @@ export const FormFieldError: Story = { invalid: true, }, }; + +export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( + <> + + Note: Dit is alleen een test voor het FormField, de verschillende inputs hebben hun eigen tests. + +

Light

+ +
Type: text
+ + + + +
Type: checkbox
+ + + + +
Type: radio
+ + + + +
+

Dark

+ +
Type: text
+ + + + +
Type: checkbox
+ + + + +
Type: radio
+ + + + +
+ +)); diff --git a/packages/storybook/src/react-components/form-field/visual/FormFieldTypes.tsx b/packages/storybook/src/react-components/form-field/visual/FormFieldTypes.tsx new file mode 100644 index 000000000..401fab6a8 --- /dev/null +++ b/packages/storybook/src/react-components/form-field/visual/FormFieldTypes.tsx @@ -0,0 +1,84 @@ +import { + LuxFormField, + LuxFormFieldDescription, + LuxFormFieldErrorMessage, + LuxFormFieldLabel, + type LuxFormFieldLabelProps, + LuxParagraph, +} from '@lux-design-system/components-react'; + +type FormFieldTypeProps = { + type?: 'text' | 'checkbox' | 'radio'; + invalid?: boolean; + show?: { + description?: boolean; + extra?: boolean; + }; +}; + +export const FormFieldType = ({ + type = 'text', + invalid = false, + show = { description: true, extra: false }, +}: FormFieldTypeProps) => { + const Input = ({ type }: any) => { + switch (type) { + case 'checkbox': + return ( + + ); + + case 'radio': + return ( + + ); + + default: + return ( + + ); + } + }; + + return ( + {`Label`}} + description={ + show.description ? ( + + {`Description`} + + ) : null + } + errorMessage={invalid ? {`Error Message`} : null} + input={} + invalid={invalid} + > + {show.extra ? {`Extra content`} : null} + + ); +}; From 83aa6a80610fcc4500f1e7f5a815ab4086e3f91c Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Mon, 9 Dec 2024 13:24:45 +0100 Subject: [PATCH 03/11] Second set of Vis reg tests (WIP) --- .../form-field-description.mdx | 5 ++ .../form-field-description.stories.tsx | 82 +++++++++++++++++++ .../form-field-error-message.stories.tsx | 16 ++++ .../form-field-label.stories.tsx | 16 ++++ 4 files changed, 119 insertions(+) diff --git a/packages/storybook/src/react-components/form-field-description/form-field-description.mdx b/packages/storybook/src/react-components/form-field-description/form-field-description.mdx index 124ea418e..8243a5b20 100644 --- a/packages/storybook/src/react-components/form-field-description/form-field-description.mdx +++ b/packages/storybook/src/react-components/form-field-description/form-field-description.mdx @@ -43,6 +43,11 @@ import { CitationDocumentation } from "../../utils/CitationDocumentation"; +### Appearance vormgegeven met tokens + + + + ### Lange Beschrijving diff --git a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx index f5cad3598..d2d140e41 100644 --- a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx +++ b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx @@ -2,6 +2,18 @@ import { LuxFormFieldDescription } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; + +const CustomStyleBlock = () => ( + +); const meta = { title: 'React Components/Form Field/Form Field Description', @@ -94,6 +106,35 @@ export const Invalid: Story = { }, }; +export const CustomAppearance: Story = { + args: {}, + render: () => ( + <> + + + Valid Form Field Description + + + Invalid Form Field Description + + + ), + parameters: { + controls: { + disable: true, + }, + docs: { + source: { + code: null, + }, + description: { + story: + 'Om de `valid` en `invalid` _appearance_ een styling te geven kan dit met de `...valid.color`- en `...invalid.color`-tokens.', + }, + }, + }, +}; + export const LongDescription: Story = { args: { children: @@ -107,3 +148,44 @@ export const LongDescription: Story = { }, }, }; + +export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( + <> +

Light

+ + Form Field Description + Valid Form Field Description + Invalid Form Field Description + + Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, + aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus + nostra varius efficitur lobortis aliquam lectus bibendum. + + +

Dark

+ + Form Field Description + Valid Form Field Description + Invalid Form Field Description + + Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, + aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus + nostra varius efficitur lobortis aliquam lectus bibendum. + + +

Custom

+ + + Form Field Description + Valid Form Field Description + Invalid Form Field Description + + Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, + aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus + nostra varius efficitur lobortis aliquam lectus bibendum. + + + +)); diff --git a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx index 12f84b2e8..0d50762c9 100644 --- a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx +++ b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx @@ -3,6 +3,7 @@ import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { forwardRef, PropsWithChildren } from 'react'; import { BADGES } from '../../../config/preview'; +import { /*createDesignTokensStory,*/ createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; const WrappedLuxFormFieldErrorMessage = forwardRef< HTMLParagraphElement, @@ -72,3 +73,18 @@ export const Distanced: Story = { distanced: true, }, }; + +// export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( + <> +

Light

+ + Error Message + +

Dark

+ + Error Message + + +)); diff --git a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx index b597e13c6..f850fdf9b 100644 --- a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx +++ b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx @@ -3,6 +3,7 @@ import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { type LabelHTMLAttributes, type PropsWithChildren } from 'react'; import { BADGES } from '../../../config/preview'; +import { /*createDesignTokensStory,*/ createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; const LuxFormFieldLabel = ( props: PropsWithChildren & LabelHTMLAttributes, @@ -110,3 +111,18 @@ export const CheckedLabel: Story = { type: 'checkbox', }, }; + +// export const DesignTokens = createDesignTokensStory(meta); + +export const Visual = createVisualRegressionStory(() => ( +
+

Light

+ + Label + +

Dark

+ + Label + +
+)); From cf23e7f327009731e79006d2adc911c2d73fa8c3 Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Thu, 12 Dec 2024 15:08:22 +0100 Subject: [PATCH 04/11] Third set of Vis reg tests (WIP) --- .../FormFieldRadioGroup.tsx | 2 +- .../form-field-description.stories.tsx | 2 +- .../form-field-error-message.stories.tsx | 6 +- .../form-field-label.stories.tsx | 14 +++- .../form-field-radio-group.stories.tsx | 82 +++++++++++++++++++ .../form-field-radio-option.stories.tsx | 34 ++++++++ 6 files changed, 132 insertions(+), 8 deletions(-) diff --git a/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx b/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx index 0d90bfdc8..edbcd4d1b 100644 --- a/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx +++ b/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx @@ -4,7 +4,7 @@ import './FormFieldRadioGroup.css'; import { LuxFormFieldRadioOption } from '../form-field-radio-option/FormFieldRadioOption'; interface RadioOption { - value: string; + value: string | number; label: string; disabled?: boolean; description?: React.ReactNode; diff --git a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx index d2d140e41..7edcdb6e1 100644 --- a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx +++ b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx @@ -22,7 +22,7 @@ const meta = { parameters: { badges: [BADGES.WIP, BADGES.CANARY], tokens, - tokensPrefix: 'react-form-field-description', + tokensPrefix: 'utrecht-form-field-description', docs: { description: { component: 'A description component for form fields that provides additional context or validation feedback.', diff --git a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx index 0d50762c9..3367a2b44 100644 --- a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx +++ b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx @@ -3,7 +3,7 @@ import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { forwardRef, PropsWithChildren } from 'react'; import { BADGES } from '../../../config/preview'; -import { /*createDesignTokensStory,*/ createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; const WrappedLuxFormFieldErrorMessage = forwardRef< HTMLParagraphElement, @@ -19,7 +19,7 @@ const meta = { parameters: { badges: [BADGES.WIP, BADGES.CANARY], tokens, - tokensPrefix: 'react-form-field-error-message', + tokensPrefix: 'utrecht-form-field-error-message', }, argTypes: { children: { @@ -74,7 +74,7 @@ export const Distanced: Story = { }, }; -// export const DesignTokens = createDesignTokensStory(meta); +export const DesignTokens = createDesignTokensStory(meta); export const Visual = createVisualRegressionStory(() => ( <> diff --git a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx index f850fdf9b..c10a1d783 100644 --- a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx +++ b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx @@ -3,7 +3,7 @@ import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { type LabelHTMLAttributes, type PropsWithChildren } from 'react'; import { BADGES } from '../../../config/preview'; -import { /*createDesignTokensStory,*/ createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; +import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; const LuxFormFieldLabel = ( props: PropsWithChildren & LabelHTMLAttributes, @@ -19,7 +19,7 @@ const meta = { parameters: { badges: [BADGES.WIP, BADGES.CANARY], tokens, - tokensPrefix: 'react-form-label', + tokensPrefix: 'utrecht-form-label', }, argTypes: { children: { @@ -112,17 +112,25 @@ export const CheckedLabel: Story = { }, }; -// export const DesignTokens = createDesignTokensStory(meta); +export const DesignTokens = createDesignTokensStory(meta); export const Visual = createVisualRegressionStory(() => (

Light

Label + Checkbox Label + Radio Label + Checked Label + Disabled Label

Dark

Label + Checkbox Label + Radio Label + Checked Label + Disabled Label
)); diff --git a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx index b8e2ea9d2..1754fddba 100644 --- a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx +++ b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx @@ -1,6 +1,7 @@ import { LuxFormFieldRadioGroup } from '@lux-design-system/components-react'; import { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; +import { createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; type Story = StoryObj; @@ -208,3 +209,84 @@ export const WithLongLabels: Story = { }, }, }; + +const options = [ + { value: 1, label: 'Radio Option 1' }, + { value: 2, label: 'Radio Option 2' }, + { value: 3, label: 'Radio Option 3' }, +]; + +export const Visual = createVisualRegressionStory(() => ( +
+

Light

+ + + + Object.assign({}, { ...option }, { description: `Option Description ${option.value}` }), + )} + /> +
+ +
+
+ +
+ Object.assign({}, { ...option }, { checked: option.value === 2 }))} + /> + Object.assign({}, { ...option }, { disabled: option.value === 2 }))} + /> + +
+

Dark

+ + + + Object.assign({}, { ...option }, { description: `Option Description ${option.value}` }), + )} + /> +
+ +
+
+ +
+ Object.assign({}, { ...option }, { checked: option.value === 2 }))} + /> + Object.assign({}, { ...option }, { disabled: option.value === 2 }))} + /> + +
+
+)); diff --git a/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx b/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx index 1551896cb..939be1e94 100644 --- a/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx +++ b/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx @@ -2,6 +2,7 @@ import { LuxFormFieldRadioOption } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; +import { createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; type Story = StoryObj; @@ -150,3 +151,36 @@ export const FocusVisible: Story = { pseudo: { focus: true, focusVisible: true }, }, }; + +export const Visual = createVisualRegressionStory(() => ( +
+

Light

+ + + +
+ +
+
+ +
+ + + +
+

Dark

+ + + +
+ +
+
+ +
+ + + +
+
+)); From 46447ea58a9c9ce49a20c40787f417970224523c Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Mon, 16 Dec 2024 12:26:12 +0100 Subject: [PATCH 05/11] Forth set of Vis reg tests --- .../src/form-field-select/FormFieldSelect.tsx | 21 +++- packages/components-react/src/index.ts | 6 +- .../form-field-select/form-field-select.mdx | 26 ++++- .../form-field-select.stories.tsx | 97 +++++++++++++++---- 4 files changed, 121 insertions(+), 29 deletions(-) diff --git a/packages/components-react/src/form-field-select/FormFieldSelect.tsx b/packages/components-react/src/form-field-select/FormFieldSelect.tsx index de69f06e3..e65085f8b 100644 --- a/packages/components-react/src/form-field-select/FormFieldSelect.tsx +++ b/packages/components-react/src/form-field-select/FormFieldSelect.tsx @@ -8,7 +8,11 @@ import { } from '../form-field-description/FormFieldDescription'; import { LuxFormFieldErrorMessage } from '../form-field-error-message/FormFieldErrorMessage'; import { LuxFormFieldLabel } from '../form-field-label/FormFieldLabel'; -import { LuxSelect, type LuxSelectProps } from '../select/Select'; +import { LuxSelect, LuxSelectOption, type LuxSelectOptionProps, type LuxSelectProps } from '../select/Select'; + +export type LuxFormFieldSelectOptionsProps = LuxSelectOptionProps & { + label?: string | number; +}; export interface LuxFormFieldSelectProps extends Omit, @@ -27,6 +31,7 @@ export interface LuxFormFieldSelectProps | 'size' | 'value' > { + options?: LuxFormFieldSelectOptionsProps[]; appearance?: LuxFormFieldDescriptionAppearance; distanced?: boolean; inputRef?: Ref; @@ -34,6 +39,7 @@ export interface LuxFormFieldSelectProps export const LuxFormFieldSelect = ({ label, + options, description, errorMessage, disabled, @@ -96,8 +102,6 @@ export const LuxFormFieldSelect = ({ const formFieldAttrs = pick(restProps, ['children']); - // TODO: Options - return ( + > + {options + ? options.map((option) => ( + + {option.label} + + )) + : formFieldAttrs['children']} + } className={className} - {...formFieldAttrs} /> ); }; diff --git a/packages/components-react/src/index.ts b/packages/components-react/src/index.ts index 4cd4aec5c..fed4f6dc5 100644 --- a/packages/components-react/src/index.ts +++ b/packages/components-react/src/index.ts @@ -24,7 +24,11 @@ export { type LuxFormFieldErrorMessageProps, } from './form-field-error-message/FormFieldErrorMessage'; export { LuxFormFieldLabel, type LuxFormFieldLabelProps } from './form-field-label/FormFieldLabel'; -export { LuxFormFieldSelect, type LuxFormFieldSelectProps } from './form-field-select/FormFieldSelect'; +export { + LuxFormFieldSelect, + type LuxFormFieldSelectProps, + type LuxFormFieldSelectOptionsProps, +} from './form-field-select/FormFieldSelect'; export { LuxFormFieldTextbox, type LuxFormFieldTextboxProps } from './form-field-textbox/FormFieldTextbox'; export { LuxParagraph, type LuxParagraphProps } from './paragraph/Paragraph'; export { diff --git a/packages/storybook/src/react-components/form-field-select/form-field-select.mdx b/packages/storybook/src/react-components/form-field-select/form-field-select.mdx index 811cbd243..e319df632 100644 --- a/packages/storybook/src/react-components/form-field-select/form-field-select.mdx +++ b/packages/storybook/src/react-components/form-field-select/form-field-select.mdx @@ -1,11 +1,33 @@ -import { Canvas, Controls, Meta } from "@storybook/blocks"; +import { Canvas, Controls, Description, Meta } from "@storybook/blocks"; import * as FormFieldSelectStories from "./form-field-select.stories"; -# Lux Form Field Select +# Form Field Select ## Playground + +## States + +### Disabled + + + + +### Invalid + + + + +### Hover + + + + +### Focus + + + diff --git a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx index 2f300f5c6..d3499e1a4 100644 --- a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx +++ b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx @@ -1,4 +1,8 @@ -import { LuxFormFieldSelect, type LuxFormFieldSelectProps } from '@lux-design-system/components-react'; +import { + LuxFormFieldSelect, + type LuxFormFieldSelectOptionsProps, + type LuxFormFieldSelectProps, +} from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { BADGES } from '../../../config/preview'; @@ -7,7 +11,11 @@ import FormFieldDescriptionMeta from '../form-field-description/form-field-descr import FormFieldErrorMessageMeta from '../form-field-error-message/form-field-error-message.stories'; import SelectMeta from '../select/select.stories'; -// TODO: Options +const options: LuxFormFieldSelectOptionsProps[] = [ + { value: '1', label: 'Option 1', disabled: true }, + { value: '2', label: 'Option 2', selected: true }, + { value: '3', label: 'Option 3' }, +]; const meta = { title: 'React Components/Form Field/Form Field Select', @@ -44,9 +52,10 @@ type Story = StoryObj; export const Playground: Story = { name: 'Playground', args: { - label: 'Form Field Select', - description: 'Select in een FormField', - errorMessage: 'Zo kan het ook een ErrorMessage hebben', + label: 'Label', + options, + description: 'Description', + errorMessage: 'Error Message', invalid: false, appearance: undefined, }, @@ -58,45 +67,91 @@ export const Playground: Story = { tags: ['!autodocs'], }; +export const Disabled: Story = { + ...Playground, + name: 'Disabled', + args: { + ...Playground.args, + disabled: true, + }, +}; + +export const Invalid: Story = { + ...Playground, + name: 'Invalid', + args: { + ...Playground.args, + invalid: true, + }, +}; + +export const Hover: Story = { + ...Playground, + name: 'Hover', + parameters: { + pseudo: { hover: true }, + }, +}; + +export const Focus: Story = { + ...Playground, + name: 'Focus', + parameters: { + pseudo: { focus: true, focusVisible: true }, + }, +}; + export const DesignTokens = createDesignTokensStory(meta); export const Visual = createVisualRegressionStory(() => ( <>

Light

- - + +
Hover & Focus
- +
- +
Invalid
- - + +
Disabled
- - + +

Dark

- - + +
Hover & Focus
- +
- +
Invalid
- - + +
Disabled
- - + +
)); From 315d938d499cb78e4534d3e259606b4158c96d00 Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Tue, 31 Dec 2024 10:57:20 +0100 Subject: [PATCH 06/11] RadioOptionValue --- .../src/form-field-radio-group/FormFieldRadioGroup.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx b/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx index edbcd4d1b..615bc5208 100644 --- a/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx +++ b/packages/components-react/src/form-field-radio-group/FormFieldRadioGroup.tsx @@ -3,8 +3,10 @@ import React, { ForwardedRef, forwardRef } from 'react'; import './FormFieldRadioGroup.css'; import { LuxFormFieldRadioOption } from '../form-field-radio-option/FormFieldRadioOption'; +type RadioOptionValue = string | number; + interface RadioOption { - value: string | number; + value: RadioOptionValue; label: string; disabled?: boolean; description?: React.ReactNode; @@ -16,7 +18,7 @@ export interface LuxFormFieldRadioGroupProps { description?: string; errorMessage?: string; options: RadioOption[]; - value?: string; + value?: RadioOptionValue; invalid?: boolean; required?: boolean; className?: string; From ea46d13ff603ebf08d0213eca1d49ea3765f5e3f Mon Sep 17 00:00:00 2001 From: Jaap-Hein Wester Date: Tue, 31 Dec 2024 11:23:31 +0100 Subject: [PATCH 07/11] forwardRef bug fixed --- packages/components-react/src/select/Select.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/components-react/src/select/Select.tsx b/packages/components-react/src/select/Select.tsx index e1f906dd7..43bd53448 100644 --- a/packages/components-react/src/select/Select.tsx +++ b/packages/components-react/src/select/Select.tsx @@ -6,14 +6,15 @@ import { } from '@utrecht/component-library-react/dist/css-module'; import './Select.css'; import clsx from 'clsx'; -import { forwardRef } from 'react'; +import { ForwardedRef, forwardRef } from 'react'; + export type LuxSelectProps = UtrechtSelectProps; export type LuxSelectOptionProps = UtrechtSelectOptionProps; -export const LuxSelect = forwardRef((props: LuxSelectProps) => { +export const LuxSelect = forwardRef((props: LuxSelectProps, ref: ForwardedRef) => { const { className, ...restProps } = props; - return ; + return ; }); export const LuxSelectOption = SelectOption; From 6f0962875e81c025a8f64c3960e588fd67f9473c Mon Sep 17 00:00:00 2001 From: Remy Parzinski Date: Thu, 2 Jan 2025 14:58:24 +0100 Subject: [PATCH 08/11] refactor(components-react): move visreg scenarios to VisualStates components --- packages/storybook/config/components.ts | 33 +++++++++ .../checkbox/visual/States.tsx | 21 ++++++ .../form-field-checkbox.stories.tsx | 37 +--------- .../form-field-checkbox/visual/States.tsx | 23 ++++++ .../form-field-description.stories.tsx | 28 +------ .../form-field-description/visual/States.tsx | 14 ++++ .../form-field-error-message.stories.tsx | 5 +- .../visual/States.tsx | 7 ++ .../form-field-label.stories.tsx | 13 +--- .../form-field-label/visual/States.tsx | 11 +++ .../form-field-radio-group.stories.tsx | 73 +------------------ .../form-field-radio-group/visual/States.tsx | 44 +++++++++++ .../form-field-radio-option.stories.tsx | 25 +------ .../form-field-radio-option/visual/States.tsx | 17 +++++ .../form-field-select.stories.tsx | 45 +----------- .../form-field-select/visual/States.tsx | 27 +++++++ .../form-field-textbox.stories.tsx | 33 +-------- .../form-field-textbox/visual/States.tsx | 21 ++++++ 18 files changed, 243 insertions(+), 234 deletions(-) create mode 100644 packages/storybook/config/components.ts create mode 100644 packages/storybook/src/react-components/checkbox/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-checkbox/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-description/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-error-message/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-label/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-radio-option/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-select/visual/States.tsx create mode 100644 packages/storybook/src/react-components/form-field-textbox/visual/States.tsx diff --git a/packages/storybook/config/components.ts b/packages/storybook/config/components.ts new file mode 100644 index 000000000..63895b0eb --- /dev/null +++ b/packages/storybook/config/components.ts @@ -0,0 +1,33 @@ +import { + LuxButton, + LuxDocument, + LuxHeading1, + LuxHeading2, + LuxHeading3, + LuxHeading4, + LuxHeading5, + LuxHeading6, + LuxHeadingGroup, + LuxLink, + LuxParagraph, + LuxSection, + LuxSelect, + LuxTextbox, +} from '@lux-design-system/components-react'; + +export default { + a: LuxLink, + body: LuxDocument, + button: LuxButton, + h1: LuxHeading1, + h2: LuxHeading2, + h3: LuxHeading3, + h4: LuxHeading4, + h5: LuxHeading5, + h6: LuxHeading6, + hgroup: LuxHeadingGroup, + input: LuxTextbox, + p: LuxParagraph, + section: LuxSection, + select: LuxSelect, +}; diff --git a/packages/storybook/src/react-components/checkbox/visual/States.tsx b/packages/storybook/src/react-components/checkbox/visual/States.tsx new file mode 100644 index 000000000..c4cf19e9f --- /dev/null +++ b/packages/storybook/src/react-components/checkbox/visual/States.tsx @@ -0,0 +1,21 @@ +import { LuxCheckbox } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> +
+ Default +
+
+ Checked +
+
+ Disabled +
+
+ Checked & Disabled +
+
+ With Target +
+ +); diff --git a/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx b/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx index 57c5d9602..c79cf5292 100644 --- a/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx +++ b/packages/storybook/src/react-components/form-field-checkbox/form-field-checkbox.stories.tsx @@ -1,6 +1,7 @@ import { LuxFormFieldCheckbox, type LuxFormFieldCheckboxProps } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; import CheckboxMeta from '../checkbox/checkbox.stories'; @@ -121,43 +122,11 @@ export const Visual = createVisualRegressionStory(() => ( <>

Light

- - - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - - +

Dark

- - - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - - +
)); diff --git a/packages/storybook/src/react-components/form-field-checkbox/visual/States.tsx b/packages/storybook/src/react-components/form-field-checkbox/visual/States.tsx new file mode 100644 index 000000000..69d4b5054 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-checkbox/visual/States.tsx @@ -0,0 +1,23 @@ +import { LuxFormFieldCheckbox } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> + + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + + + +); diff --git a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx index 7edcdb6e1..cdc25ea6e 100644 --- a/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx +++ b/packages/storybook/src/react-components/form-field-description/form-field-description.stories.tsx @@ -1,6 +1,7 @@ import { LuxFormFieldDescription } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; @@ -155,37 +156,16 @@ export const Visual = createVisualRegressionStory(() => ( <>

Light

- Form Field Description - Valid Form Field Description - Invalid Form Field Description - - Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, - aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus - nostra varius efficitur lobortis aliquam lectus bibendum. - +

Dark

- Form Field Description - Valid Form Field Description - Invalid Form Field Description - - Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, - aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus - nostra varius efficitur lobortis aliquam lectus bibendum. - +

Custom

- Form Field Description - Valid Form Field Description - Invalid Form Field Description - - Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, - aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus - nostra varius efficitur lobortis aliquam lectus bibendum. - + )); diff --git a/packages/storybook/src/react-components/form-field-description/visual/States.tsx b/packages/storybook/src/react-components/form-field-description/visual/States.tsx new file mode 100644 index 000000000..1add8ec19 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-description/visual/States.tsx @@ -0,0 +1,14 @@ +import { LuxFormFieldDescription } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> + Form Field Description + Valid Form Field Description + Invalid Form Field Description + + Long Form Field Description. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Dolor ante id varius, + aenean eu faucibus vitae malesuada. Viverra malesuada aliquam et placerat justo porta ipsum parturient. Cursus + nostra varius efficitur lobortis aliquam lectus bibendum. + + +); diff --git a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx index 3367a2b44..f820565d1 100644 --- a/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx +++ b/packages/storybook/src/react-components/form-field-error-message/form-field-error-message.stories.tsx @@ -2,6 +2,7 @@ import { LuxFormFieldErrorMessage, type LuxFormFieldErrorMessageProps } from '@l import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { forwardRef, PropsWithChildren } from 'react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; @@ -80,11 +81,11 @@ export const Visual = createVisualRegressionStory(() => ( <>

Light

- Error Message +

Dark

- Error Message + )); diff --git a/packages/storybook/src/react-components/form-field-error-message/visual/States.tsx b/packages/storybook/src/react-components/form-field-error-message/visual/States.tsx new file mode 100644 index 000000000..d945b5175 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-error-message/visual/States.tsx @@ -0,0 +1,7 @@ +import { LuxFormFieldErrorMessage } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> + Error Message + +); diff --git a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx index c10a1d783..29110e4a1 100644 --- a/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx +++ b/packages/storybook/src/react-components/form-field-label/form-field-label.stories.tsx @@ -2,6 +2,7 @@ import { LuxFormFieldLabel as FormFieldLabel, LuxFormFieldLabelProps } from '@lu import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; import { type LabelHTMLAttributes, type PropsWithChildren } from 'react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; @@ -118,19 +119,11 @@ export const Visual = createVisualRegressionStory(() => (

Light

- Label - Checkbox Label - Radio Label - Checked Label - Disabled Label +

Dark

- Label - Checkbox Label - Radio Label - Checked Label - Disabled Label +
)); diff --git a/packages/storybook/src/react-components/form-field-label/visual/States.tsx b/packages/storybook/src/react-components/form-field-label/visual/States.tsx new file mode 100644 index 000000000..bb2852d59 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-label/visual/States.tsx @@ -0,0 +1,11 @@ +import { LuxFormFieldLabel } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> + Label + Checkbox Label + Radio Label + Checked Label + Disabled Label + +); diff --git a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx index 1754fddba..1d4fdbfb8 100644 --- a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx +++ b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx @@ -1,5 +1,6 @@ import { LuxFormFieldRadioGroup } from '@lux-design-system/components-react'; import { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; @@ -210,83 +211,15 @@ export const WithLongLabels: Story = { }, }; -const options = [ - { value: 1, label: 'Radio Option 1' }, - { value: 2, label: 'Radio Option 2' }, - { value: 3, label: 'Radio Option 3' }, -]; - export const Visual = createVisualRegressionStory(() => (

Light

- - - Object.assign({}, { ...option }, { description: `Option Description ${option.value}` }), - )} - /> -
- -
-
- -
- Object.assign({}, { ...option }, { checked: option.value === 2 }))} - /> - Object.assign({}, { ...option }, { disabled: option.value === 2 }))} - /> - +

Dark

- - - Object.assign({}, { ...option }, { description: `Option Description ${option.value}` }), - )} - /> -
- -
-
- -
- Object.assign({}, { ...option }, { checked: option.value === 2 }))} - /> - Object.assign({}, { ...option }, { disabled: option.value === 2 }))} - /> - +
)); diff --git a/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx b/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx new file mode 100644 index 000000000..6320ed3ca --- /dev/null +++ b/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx @@ -0,0 +1,44 @@ +import { LuxFormFieldRadioGroup } from '@lux-design-system/components-react'; + +const options = [ + { value: '1', label: 'Radio Option 1' }, + { value: '2', label: 'Radio Option 2' }, + { value: '3', label: 'Radio Option 3' }, +]; + +export const VisualStates = () => ( + <> + + + Object.assign({}, { ...option }, { description: `Option Description ${option.value}` }), + )} + /> +
+ +
+
+ +
+ Object.assign({}, { ...option }, { checked: option.value === 2 }))} + /> + Object.assign({}, { ...option }, { disabled: option.value === 2 }))} + /> + + +); diff --git a/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx b/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx index 939be1e94..5def367ea 100644 --- a/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx +++ b/packages/storybook/src/react-components/form-field-radio-option/form-field-radio-option.stories.tsx @@ -1,6 +1,7 @@ import { LuxFormFieldRadioOption } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; @@ -156,31 +157,11 @@ export const Visual = createVisualRegressionStory(() => (

Light

- - -
- -
-
- -
- - - +

Dark

- - -
- -
-
- -
- - - +
)); diff --git a/packages/storybook/src/react-components/form-field-radio-option/visual/States.tsx b/packages/storybook/src/react-components/form-field-radio-option/visual/States.tsx new file mode 100644 index 000000000..8e9353243 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-radio-option/visual/States.tsx @@ -0,0 +1,17 @@ +import { LuxFormFieldRadioOption } from '@lux-design-system/components-react'; + +export const VisualStates = ({ mode }: { mode: 'light' | 'dark' }) => ( + <> + + +
+ +
+
+ +
+ + + + +); diff --git a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx index d3499e1a4..7beee04fe 100644 --- a/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx +++ b/packages/storybook/src/react-components/form-field-select/form-field-select.stories.tsx @@ -5,6 +5,7 @@ import { } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; import FormFieldDescriptionMeta from '../form-field-description/form-field-description.stories'; @@ -107,51 +108,11 @@ export const Visual = createVisualRegressionStory(() => ( <>

Light

- - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - +

Dark

- - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - +
)); diff --git a/packages/storybook/src/react-components/form-field-select/visual/States.tsx b/packages/storybook/src/react-components/form-field-select/visual/States.tsx new file mode 100644 index 000000000..2ca70f0e4 --- /dev/null +++ b/packages/storybook/src/react-components/form-field-select/visual/States.tsx @@ -0,0 +1,27 @@ +import { LuxFormFieldSelect, type LuxFormFieldSelectProps } from '@lux-design-system/components-react'; + +export const VisualStates = ({ options }: Pick) => ( + <> + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + + +); diff --git a/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx b/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx index 4dc9ab61b..e73483589 100644 --- a/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx +++ b/packages/storybook/src/react-components/form-field-textbox/form-field-textbox.stories.tsx @@ -1,6 +1,7 @@ import { LuxFormFieldTextbox, type LuxFormFieldTextboxProps } from '@lux-design-system/components-react'; import tokens from '@lux-design-system/design-tokens/dist/index.json'; import type { Meta, StoryObj } from '@storybook/react'; +import { VisualStates } from './visual/States'; import { BADGES } from '../../../config/preview'; import { createDesignTokensStory, createVisualRegressionStory, VisualRegressionWrapper } from '../../utils'; import FormFieldDescriptionMeta from '../form-field-description/form-field-description.stories'; @@ -62,39 +63,11 @@ export const Visual = createVisualRegressionStory(() => ( <>

Light

- - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - +

Dark

- - -
Hover & Focus
-
- -
-
- -
-
Invalid
- - -
Disabled
- - +
)); diff --git a/packages/storybook/src/react-components/form-field-textbox/visual/States.tsx b/packages/storybook/src/react-components/form-field-textbox/visual/States.tsx new file mode 100644 index 000000000..9c5f9301a --- /dev/null +++ b/packages/storybook/src/react-components/form-field-textbox/visual/States.tsx @@ -0,0 +1,21 @@ +import { LuxFormFieldTextbox } from '@lux-design-system/components-react'; + +export const VisualStates = () => ( + <> + + +
Hover & Focus
+
+ +
+
+ +
+
Invalid
+ + +
Disabled
+ + + +); From 62177def3f2ba74581c7e5a14540ef096fab4ab0 Mon Sep 17 00:00:00 2001 From: Remy Parzinski Date: Thu, 2 Jan 2025 15:57:57 +0100 Subject: [PATCH 09/11] chore: remove tryout files from index --- packages/storybook/config/components.ts | 33 ------------------- .../checkbox/visual/States.tsx | 21 ------------ 2 files changed, 54 deletions(-) delete mode 100644 packages/storybook/config/components.ts delete mode 100644 packages/storybook/src/react-components/checkbox/visual/States.tsx diff --git a/packages/storybook/config/components.ts b/packages/storybook/config/components.ts deleted file mode 100644 index 63895b0eb..000000000 --- a/packages/storybook/config/components.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - LuxButton, - LuxDocument, - LuxHeading1, - LuxHeading2, - LuxHeading3, - LuxHeading4, - LuxHeading5, - LuxHeading6, - LuxHeadingGroup, - LuxLink, - LuxParagraph, - LuxSection, - LuxSelect, - LuxTextbox, -} from '@lux-design-system/components-react'; - -export default { - a: LuxLink, - body: LuxDocument, - button: LuxButton, - h1: LuxHeading1, - h2: LuxHeading2, - h3: LuxHeading3, - h4: LuxHeading4, - h5: LuxHeading5, - h6: LuxHeading6, - hgroup: LuxHeadingGroup, - input: LuxTextbox, - p: LuxParagraph, - section: LuxSection, - select: LuxSelect, -}; diff --git a/packages/storybook/src/react-components/checkbox/visual/States.tsx b/packages/storybook/src/react-components/checkbox/visual/States.tsx deleted file mode 100644 index c4cf19e9f..000000000 --- a/packages/storybook/src/react-components/checkbox/visual/States.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { LuxCheckbox } from '@lux-design-system/components-react'; - -export const VisualStates = () => ( - <> -
- Default -
-
- Checked -
-
- Disabled -
-
- Checked & Disabled -
-
- With Target -
- -); From 0289e0e72003cf34c208a7a2a64adcd5f34fd4e4 Mon Sep 17 00:00:00 2001 From: Remy Parzinski Date: Thu, 2 Jan 2025 15:58:43 +0100 Subject: [PATCH 10/11] refactor(components-react): fix imports --- .../src/form-field-checkbox/FormFieldCheckbox.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx index 44216510b..7d1309305 100644 --- a/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx +++ b/packages/components-react/src/form-field-checkbox/FormFieldCheckbox.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; import { useId } from 'react'; -import { LuxCheckbox, LuxCheckboxProps } from '../checkbox/Checkbox'; -import { LuxFormField, LuxFormFieldProps } from '../form-field/FormField'; +import { LuxCheckbox, type LuxCheckboxProps } from '../checkbox/Checkbox'; +import { LuxFormField, type LuxFormFieldProps } from '../form-field/FormField'; import { LuxFormFieldDescription, type LuxFormFieldDescriptionAppearance, From 834c639c49eb6e30535ec8f6ec8f9d59e9bb9e44 Mon Sep 17 00:00:00 2001 From: Remy Parzinski Date: Fri, 3 Jan 2025 09:47:35 +0100 Subject: [PATCH 11/11] fix: build --- .../form-field-radio-group.stories.tsx | 4 ++-- .../form-field-radio-group/visual/States.tsx | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx index 1d4fdbfb8..6beccab4e 100644 --- a/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx +++ b/packages/storybook/src/react-components/form-field-radio-group/form-field-radio-group.stories.tsx @@ -215,11 +215,11 @@ export const Visual = createVisualRegressionStory(() => (

Light

- +

Dark

- +
)); diff --git a/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx b/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx index 6320ed3ca..5faff29e0 100644 --- a/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx +++ b/packages/storybook/src/react-components/form-field-radio-group/visual/States.tsx @@ -6,11 +6,11 @@ const options = [ { value: '3', label: 'Radio Option 3' }, ]; -export const VisualStates = () => ( +export const VisualStates = ({ mode }: { mode: 'light' | 'dark' }) => ( <> - + @@ -18,23 +18,23 @@ export const VisualStates = () => ( )} />
- +
- +
Object.assign({}, { ...option }, { checked: option.value === 2 }))} + options={options.map((option) => Object.assign({}, { ...option }, { checked: option.value === '2' }))} /> Object.assign({}, { ...option }, { disabled: option.value === 2 }))} + options={options.map((option) => Object.assign({}, { ...option }, { disabled: option.value === '2' }))} />