@recursica/adapter-mui-v7 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/dist/adapter-mui-v7.cjs +60 -60
  4. package/dist/adapter-mui-v7.cjs.map +1 -1
  5. package/dist/adapter-mui-v7.css +1 -1
  6. package/dist/adapter-mui-v7.js +3840 -3795
  7. package/dist/adapter-mui-v7.js.map +1 -1
  8. package/dist/index.d.ts +8 -5
  9. package/docs/PHILOSOPHY.md +4 -0
  10. package/package.json +4 -8
  11. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +4 -0
  12. package/src/components/Checkbox/Checkbox.module.css +1 -0
  13. package/src/components/Checkbox/Checkbox.tsx +7 -4
  14. package/src/components/Heading/HEADING_IMPLEMENTATION_NOTES.md +10 -0
  15. package/src/components/Modal/Modal.module.css +9 -2
  16. package/src/components/NativeInputA11y.dom.test.tsx +59 -0
  17. package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +8 -0
  18. package/src/components/Panel/Panel.tsx +51 -9
  19. package/src/components/Radio/RADIO_IMPLEMENTATION_NOTES.md +4 -0
  20. package/src/components/Radio/Radio.module.css +1 -0
  21. package/src/components/Radio/Radio.tsx +7 -4
  22. package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +4 -0
  23. package/src/components/Switch/Switch.tsx +7 -3
  24. package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +12 -0
  25. package/src/components/Text/Text.headings.dom.test.tsx +54 -0
  26. package/src/components/Text/Text.tsx +16 -0
  27. package/src/utils/useNativeInputA11y.ts +43 -0
  28. package/.storybook/commonArgTypes.ts +0 -148
  29. package/recursica_brand.json +0 -2610
  30. package/recursica_tokens.json +0 -769
  31. package/recursica_ui-kit.json +0 -9049
  32. package/recursica_variables_scoped.css +0 -6178
  33. package/src/Introduction.stories.tsx +0 -178
  34. package/src/components/Accordion/Accordion.stories.tsx +0 -198
  35. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +0 -68
  36. package/src/components/AutoComplete/AutoComplete.stories.tsx +0 -336
  37. package/src/components/Avatar/Avatar.stories.tsx +0 -92
  38. package/src/components/Badge/Badge.stories.tsx +0 -78
  39. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -114
  40. package/src/components/Button/Button.stories.tsx +0 -196
  41. package/src/components/Card/Card.stories.tsx +0 -132
  42. package/src/components/Checkbox/Checkbox.stories.tsx +0 -97
  43. package/src/components/Checkbox/CheckboxGroup.stories.tsx +0 -139
  44. package/src/components/Chip/Chip.stories.tsx +0 -154
  45. package/src/components/Container/Container.stories.tsx +0 -118
  46. package/src/components/DatePicker/DatePicker.stories.tsx +0 -163
  47. package/src/components/Dropdown/Dropdown.stories.tsx +0 -252
  48. package/src/components/FileInput/FileInput.stories.tsx +0 -313
  49. package/src/components/FileUpload/FileUpload.stories.tsx +0 -362
  50. package/src/components/Flex/Flex.stories.tsx +0 -128
  51. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +0 -118
  52. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +0 -129
  53. package/src/components/Group/Group.stories.tsx +0 -120
  54. package/src/components/Heading/Heading.stories.tsx +0 -112
  55. package/src/components/HoverCard/HoverCard.stories.tsx +0 -172
  56. package/src/components/Label/Label.stories.tsx +0 -131
  57. package/src/components/LayoutGrid/LayoutGrid.stories.tsx +0 -61
  58. package/src/components/Link/Link.stories.tsx +0 -58
  59. package/src/components/Loader/Loader.stories.tsx +0 -123
  60. package/src/components/Menu/Menu.stories.tsx +0 -402
  61. package/src/components/Modal/Modal.stories.tsx +0 -105
  62. package/src/components/NumberInput/NumberInput.stories.tsx +0 -96
  63. package/src/components/Pagination/Pagination.stories.tsx +0 -48
  64. package/src/components/Panel/Panel.stories.tsx +0 -227
  65. package/src/components/Popover/Popover.stories.tsx +0 -133
  66. package/src/components/Radio/Radio.stories.tsx +0 -93
  67. package/src/components/Radio/RadioGroup.stories.tsx +0 -117
  68. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +0 -163
  69. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -106
  70. package/src/components/Slider/Slider.stories.tsx +0 -282
  71. package/src/components/Stack/Stack.stories.tsx +0 -108
  72. package/src/components/Stepper/Stepper.stories.tsx +0 -157
  73. package/src/components/Switch/Switch.stories.tsx +0 -114
  74. package/src/components/Switch/SwitchGroup.stories.tsx +0 -132
  75. package/src/components/Table/Table.stories.tsx +0 -154
  76. package/src/components/Tabs/Tabs.stories.tsx +0 -174
  77. package/src/components/Text/Text.stories.tsx +0 -123
  78. package/src/components/TextArea/TextArea.stories.tsx +0 -94
  79. package/src/components/TextField/TextField.stories.tsx +0 -162
  80. package/src/components/TimePicker/TimePicker.stories.tsx +0 -155
  81. package/src/components/Timeline/Timeline.stories.tsx +0 -128
  82. package/src/components/Toast/Toast.stories.tsx +0 -67
  83. package/src/components/Tooltip/Tooltip.stories.tsx +0 -165
  84. package/src/components/TransferList/TransferList.stories.tsx +0 -121
  85. package/src/components/Tree/Tree.stories.tsx +0 -104
@@ -1,154 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { Chip } from "./Chip";
4
-
5
- type ChipStoryProps = React.ComponentProps<typeof Chip>;
6
-
7
- const meta: Meta<ChipStoryProps> = {
8
- title: "UI-Kit/Chip",
9
- component: Chip,
10
- tags: ["autodocs"],
11
- parameters: {
12
- docs: {
13
- description: {
14
- component:
15
- "The Chip component is used to represent interactive selections, descriptive tags, or dynamic filters natively bounded to Recursica variables. It can be used as a toggleable input, can render a custom leading `icon`, and handles close constraints automatically via the `onDelete` property.",
16
- },
17
- },
18
- },
19
- argTypes: {
20
- error: {
21
- control: "boolean",
22
- description: "Applies the error state styling dynamically.",
23
- },
24
- disabled: {
25
- control: "boolean",
26
- description: "Applies disabled token states.",
27
- },
28
- checked: {
29
- control: "boolean",
30
- description: "Forces the visual selected state.",
31
- },
32
- },
33
- };
34
-
35
- export default meta;
36
-
37
- type Story = StoryObj<ChipStoryProps>;
38
-
39
- // The Default story exposing native properties for the playground.
40
- export const Default: Story = {
41
- args: {
42
- children: "Default Chip",
43
- error: false,
44
- disabled: false,
45
- checked: false,
46
- },
47
- render: (args: ChipStoryProps) => <Chip {...args} />,
48
- };
49
-
50
- // Static Stories for Regression Snapshots
51
- export const Unselected: Story = {
52
- args: {
53
- children: "Unselected",
54
- checked: false,
55
- },
56
- render: (args: ChipStoryProps) => <Chip {...args} />,
57
- };
58
-
59
- export const Selected: Story = {
60
- args: {
61
- children: "Selected",
62
- checked: true,
63
- },
64
- render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
65
- };
66
-
67
- export const ErrorState: Story = {
68
- args: {
69
- children: "Error",
70
- error: true,
71
- checked: false,
72
- },
73
- render: (args: ChipStoryProps) => <Chip {...args} />,
74
- };
75
-
76
- export const ErrorSelected: Story = {
77
- args: {
78
- children: "Error Selected",
79
- error: true,
80
- checked: true,
81
- },
82
- render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
83
- };
84
-
85
- export const Removable: Story = {
86
- args: {
87
- children: "Dismissible",
88
- checked: false,
89
- onDelete: () => console.log("Removal Action Triggered"),
90
- },
91
- render: (args: ChipStoryProps) => <Chip {...args} />,
92
- };
93
-
94
- export const WithLeadingIcon: Story = {
95
- args: {
96
- children: "Leading Icon",
97
- checked: false,
98
- icon: (
99
- <svg
100
- xmlns="http://www.w3.org/2000/svg"
101
- viewBox="0 0 24 24"
102
- fill="none"
103
- stroke="currentColor"
104
- strokeWidth="2"
105
- strokeLinecap="round"
106
- strokeLinejoin="round"
107
- >
108
- <circle cx="12" cy="12" r="10"></circle>
109
- <path d="M12 8v4"></path>
110
- <path d="M12 16h.01"></path>
111
- </svg>
112
- ),
113
- },
114
- render: (args: ChipStoryProps) => <Chip {...args} />,
115
- };
116
-
117
- // Selecting a chip with a leading icon swaps in the checkmark rather than showing both — this
118
- // was already MUI-adapter's native behavior; the story exists to keep parity with mantine-adapter.
119
- export const WithLeadingIconSelected: Story = {
120
- args: {
121
- ...WithLeadingIcon.args,
122
- children: "Leading Icon Selected",
123
- checked: true,
124
- },
125
- render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
126
- };
127
-
128
- // A label long enough to exceed the chip's own max-width token — should stay a single line and
129
- // truncate with an ellipsis, never wrap, even with both a leading icon and a dismiss button
130
- // competing for space.
131
- export const MaxWidthEllipsis: Story = {
132
- args: {
133
- children:
134
- "A very long chip label that exceeds the maximum width and should truncate with an ellipsis",
135
- checked: false,
136
- icon: (
137
- <svg
138
- xmlns="http://www.w3.org/2000/svg"
139
- viewBox="0 0 24 24"
140
- fill="none"
141
- stroke="currentColor"
142
- strokeWidth="2"
143
- strokeLinecap="round"
144
- strokeLinejoin="round"
145
- >
146
- <circle cx="12" cy="12" r="10"></circle>
147
- <path d="M12 8v4"></path>
148
- <path d="M12 16h.01"></path>
149
- </svg>
150
- ),
151
- onDelete: () => console.log("Removal Action Triggered"),
152
- },
153
- render: (args: ChipStoryProps) => <Chip {...args} />,
154
- };
@@ -1,118 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { Container } from "./Container";
4
- import { Text } from "../Text/Text";
5
-
6
- type ContainerStoryProps = React.ComponentProps<typeof Container>;
7
-
8
- const meta: Meta<ContainerStoryProps> = {
9
- title: "UI-Kit/Container",
10
- component: Container,
11
- tags: ["autodocs"],
12
- parameters: {
13
- docs: {
14
- description: {
15
- component:
16
- "Container is a generic layout wrapper that safely maps to Mantine's Container, standardizing maximum content widths across the application.",
17
- },
18
- },
19
- },
20
- args: {
21
- size: "md",
22
- fluid: false,
23
- },
24
- argTypes: {
25
- size: {
26
- control: "select",
27
- options: [
28
- "xs",
29
- "sm",
30
- "md",
31
- "lg",
32
- "xl",
33
- "rec-sm",
34
- "rec-default",
35
- "rec-md",
36
- "rec-lg",
37
- "rec-xl",
38
- "rec-2xl",
39
- ],
40
- description:
41
- "Maximum width defined by Mantine system sizes or Recursica sizes",
42
- },
43
- fluid: {
44
- control: "boolean",
45
- description: "If true, overrides size and sets max-width to 100%",
46
- },
47
- defaultChecked: {
48
- table: { disable: true },
49
- },
50
- },
51
- };
52
-
53
- export default meta;
54
-
55
- type Story = StoryObj<ContainerStoryProps>;
56
-
57
- export const Default: Story = {
58
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
59
- render: ({ withLayer, layer, ...args }: any) => (
60
- <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
61
- <Container
62
- {...args}
63
- style={{
64
- backgroundColor: "white",
65
- padding: "16px",
66
- border: "1px solid #ccc",
67
- }}
68
- >
69
- <Text>
70
- This is a Container holding centered content. The background and
71
- border are added just to demonstrate the layout bounds visually.
72
- </Text>
73
- </Container>
74
- </div>
75
- ),
76
- };
77
-
78
- export const SmallContainer: Story = {
79
- args: {
80
- size: "sm",
81
- },
82
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
83
- render: ({ withLayer, layer, ...args }: any) => (
84
- <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
85
- <Container
86
- {...args}
87
- style={{
88
- backgroundColor: "white",
89
- padding: "16px",
90
- border: "1px solid #ccc",
91
- }}
92
- >
93
- <Text>Small Container Layout</Text>
94
- </Container>
95
- </div>
96
- ),
97
- };
98
-
99
- export const FluidContainer: Story = {
100
- args: {
101
- fluid: true,
102
- },
103
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
104
- render: ({ withLayer, layer, ...args }: any) => (
105
- <div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
106
- <Container
107
- {...args}
108
- style={{
109
- backgroundColor: "white",
110
- padding: "16px",
111
- border: "1px solid #ccc",
112
- }}
113
- >
114
- <Text>Fluid Container Layout</Text>
115
- </Container>
116
- </div>
117
- ),
118
- };
@@ -1,163 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import { DatePicker } from "./DatePicker";
3
- import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
4
-
5
- const meta: Meta<typeof DatePicker> = {
6
- title: "UI-Kit/DatePicker",
7
- component: DatePicker,
8
- tags: ["autodocs"],
9
- parameters: {
10
- docs: {
11
- description: {
12
- component: `
13
- The \`DatePicker\` primitive provides a unified calendar date selection input integrated directly into the \`FormControlWrapper\` architecture.
14
-
15
- ### Architectural Decoupling
16
- Recursica overrides MUI X's \`DatePicker\` field/popover defaults, safely injecting the date picker into our rigid structural layout systems. State modifiers (e.g. Focus, Errors, ReadOnly) hook seamlessly back onto our native CSS mapping architecture.
17
-
18
- ### Examples
19
- Always structure horizontal architectures via the generic \`formLayout\` parameter.
20
- \`\`\`tsx
21
- <DatePicker
22
- label="Start Date"
23
- assistiveText="Select the deployment kick-off date."
24
- formLayout="stacked"
25
- />
26
- \`\`\`
27
- `,
28
- },
29
- },
30
- },
31
- argTypes: {
32
- ...formControlArgTypes,
33
- disabled: {
34
- control: "boolean",
35
- description:
36
- "Maps the formal disabled variable states structurally to the input core.",
37
- },
38
- error: {
39
- control: "text",
40
- description:
41
- "Applies the strict error string boundary rendering invalid structures seamlessly.",
42
- },
43
- required: {
44
- control: "boolean",
45
- },
46
- label: {
47
- control: "text",
48
- },
49
- assistiveText: {
50
- control: "text",
51
- },
52
- readOnly: {
53
- control: "boolean",
54
- description:
55
- "Toggles structural read-only data presentation explicitly blocking standard component bindings.",
56
- },
57
- },
58
- };
59
-
60
- export default meta;
61
-
62
- type Story = StoryObj<typeof DatePicker>;
63
-
64
- export const Default: Story = {
65
- args: {
66
- disabled: false,
67
- label: "Project Deadline",
68
- assistiveText: "Specify the absolute cutoff for code submission.",
69
- },
70
- };
71
-
72
- export const FormsSideBySide: Story = {
73
- args: {
74
- label: "Incident Start Date",
75
- assistiveText: "When did the incident originally occur?",
76
- formLayout: "side-by-side",
77
- },
78
- };
79
-
80
- function CustomLeadingIcon({ className }: { className?: string }) {
81
- return (
82
- <svg
83
- className={className}
84
- width="24"
85
- height="24"
86
- viewBox="0 0 24 24"
87
- fill="none"
88
- stroke="currentColor"
89
- strokeWidth="2"
90
- strokeLinecap="round"
91
- strokeLinejoin="round"
92
- >
93
- <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
94
- <line x1="16" y1="2" x2="16" y2="6"></line>
95
- <line x1="8" y1="2" x2="8" y2="6"></line>
96
- <line x1="3" y1="10" x2="21" y2="10"></line>
97
- </svg>
98
- );
99
- }
100
-
101
- export const WithLeadingIcon: Story = {
102
- args: {
103
- label: "Launch Date",
104
- slots: { openPickerIcon: CustomLeadingIcon },
105
- },
106
- };
107
-
108
- export const Disabled: Story = {
109
- args: {
110
- label: "Disabled Date Range",
111
- disabled: true,
112
- },
113
- };
114
-
115
- export const ErrorState: Story = {
116
- args: {
117
- label: "Execution Date",
118
- error: "The chosen date conflicts with an existing deployment freeze.",
119
- required: true,
120
- },
121
- };
122
-
123
- export const OpenedCalendar: Story = {
124
- args: {
125
- label: "Meeting Date",
126
- assistiveText: "Calendar rendered open by default for styling review.",
127
- // MUI X's DatePicker supports a controlled `open` prop directly; pairing it with a
128
- // no-op `onClose` keeps the calendar open with no click interaction needed — same
129
- // intent as the mantine-adapter's `OpenedCalendar` story.
130
- open: true,
131
- onClose: () => {},
132
- // Fixed (not computed) so the selected-day fill is visible on load, alongside the
133
- // today marker, for styling review. Local-component constructor, not an ISO date
134
- // string — `new Date("2026-08-26")` parses as UTC midnight, which renders as the
135
- // 25th in any timezone behind UTC.
136
- defaultValue: new Date(2026, 7, 26),
137
- },
138
- parameters: {
139
- docs: {
140
- description: {
141
- story:
142
- "The calendar dropdown renders open by default so its styling can be reviewed without a click interaction.",
143
- },
144
- },
145
- },
146
- };
147
-
148
- export const StaticReadOnly: Story = {
149
- args: {
150
- label: "Static ReadOnly Review",
151
- value: new Date("2026-05-21"),
152
- readOnly: true,
153
- },
154
- };
155
-
156
- export const EditableReadOnly: Story = {
157
- args: {
158
- label: "Editable ReadOnly Review",
159
- defaultValue: new Date("2026-06-01"),
160
- readOnly: true,
161
- labelWithEditIcon: true,
162
- },
163
- };
@@ -1,252 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { Dropdown } from "./Dropdown";
4
- import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
5
- import { renderRichOptionContent } from "../../utils/renderRichOption";
6
- import styles from "./Dropdown.module.css";
7
-
8
- type DropdownStoryProps = React.ComponentProps<typeof Dropdown>;
9
-
10
- const meta: Meta<DropdownStoryProps> = {
11
- title: "UI-Kit/Dropdown",
12
- component: Dropdown,
13
- tags: ["autodocs"],
14
- parameters: {
15
- docs: {
16
- description: {
17
- component:
18
- "Dropdown provides a selectable list of options, mapping natively over Mantine's Select component encapsulated within the standardized FormControlWrapper.",
19
- },
20
- },
21
- },
22
- args: {
23
- label: "Country Selection",
24
- assistiveText: "Select your country of origin.",
25
- placeholder: "Pick value",
26
- data: ["United States", "Canada", "Mexico", "United Kingdom", "France"],
27
- disabled: false,
28
- required: false,
29
- readOnly: false,
30
- clearable: false,
31
- },
32
- argTypes: {
33
- disabled: {
34
- control: "boolean",
35
- },
36
- ...formControlArgTypes,
37
- readOnly: {
38
- control: "boolean",
39
- },
40
- clearable: {
41
- control: "boolean",
42
- },
43
- wrapItemText: {
44
- control: "boolean",
45
- description:
46
- "Wraps option label/supportingText onto additional lines instead of truncating with an ellipsis.",
47
- },
48
- containerWidth: {
49
- table: { disable: true },
50
- },
51
- },
52
- };
53
-
54
- export default meta;
55
-
56
- type Story = StoryObj<DropdownStoryProps>;
57
-
58
- export const Default: Story = {
59
- args: {},
60
- };
61
-
62
- export const Clearable: Story = {
63
- args: {
64
- label: "Clearable Options",
65
- clearable: true,
66
- },
67
- };
68
-
69
- export const WithLeadingIcon: Story = {
70
- args: {
71
- label: "Destination",
72
- startAdornment: (
73
- <svg
74
- width="24"
75
- height="24"
76
- viewBox="0 0 24 24"
77
- fill="none"
78
- stroke="currentColor"
79
- strokeWidth="2"
80
- strokeLinecap="round"
81
- strokeLinejoin="round"
82
- >
83
- <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
84
- <circle cx="12" cy="10" r="3"></circle>
85
- </svg>
86
- ),
87
- },
88
- };
89
-
90
- const UserIcon = (
91
- <svg
92
- width="16"
93
- height="16"
94
- viewBox="0 0 24 24"
95
- fill="none"
96
- stroke="currentColor"
97
- strokeWidth="2"
98
- strokeLinecap="round"
99
- strokeLinejoin="round"
100
- >
101
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
102
- <circle cx="12" cy="7" r="4"></circle>
103
- </svg>
104
- );
105
-
106
- export const WithRichOptions: Story = {
107
- args: {
108
- label: "Assignee",
109
- placeholder: "Pick a team member",
110
- assistiveText:
111
- "Each option can show a leading icon and supporting text — see MANTINE_ADAPTER_RICH_OPTION_DATA.md.",
112
- data: [
113
- {
114
- value: "jdoe",
115
- label: "Jane Doe",
116
- leadingIcon: UserIcon,
117
- supportingText: "jane.doe@example.com",
118
- },
119
- {
120
- value: "asmith",
121
- label: "Alex Smith",
122
- leadingIcon: UserIcon,
123
- supportingText: "alex.smith@example.com",
124
- },
125
- { value: "unassigned", label: "Unassigned" },
126
- ],
127
- },
128
- };
129
-
130
- export const WithRichOptionsWrapped: Story = {
131
- args: {
132
- label: "Assignee",
133
- placeholder: "Pick a team member",
134
- wrapItemText: true,
135
- data: [
136
- {
137
- value: "jdoe",
138
- label: "Jane Doe, Senior Staff Engineer, Platform Infrastructure",
139
- leadingIcon: UserIcon,
140
- supportingText:
141
- "jane.doe@example.com — Platform Infrastructure team, on-call rotation lead",
142
- },
143
- { value: "unassigned", label: "Unassigned" },
144
- ],
145
- assistiveText:
146
- "wrapItemText=true — long label/supportingText wrap instead of truncating.",
147
- },
148
- };
149
-
150
- const optionRowPreviewClassNames = {
151
- optionContent: styles.optionContent,
152
- optionIcon: styles.optionIcon,
153
- optionText: styles.optionText,
154
- optionTextWrap: styles.optionTextWrap,
155
- optionSupportingText: styles.optionSupportingText,
156
- };
157
-
158
- const OPTION_ROW_PREVIEW_ITEMS = [
159
- {
160
- value: "icon-and-supporting",
161
- label: "Jane Doe",
162
- leadingIcon: UserIcon,
163
- supportingText: "jane.doe@example.com",
164
- },
165
- {
166
- value: "no-icon",
167
- label: "Alex Smith",
168
- supportingText:
169
- "No leadingIcon — label/supportingText shift left, no reserved icon space",
170
- },
171
- {
172
- value: "no-supporting-text",
173
- label: "Taylor Rivera",
174
- leadingIcon: UserIcon,
175
- },
176
- {
177
- value: "plain",
178
- label: "Plain option — no leadingIcon, no supportingText",
179
- },
180
- {
181
- value: "long-text",
182
- label:
183
- "A very long option label that, with wrapItemText, wraps onto a second line instead of overflowing the fixed-width dropdown — otherwise it truncates with an ellipsis",
184
- leadingIcon: UserIcon,
185
- supportingText:
186
- "A similarly long supporting text string, to confirm the same wrap-or-truncate behavior applies to it too",
187
- },
188
- ];
189
-
190
- // Renders the option row content directly — outside the MUI Menu portal — inside a container
191
- // sized to Dropdown's own max-width token. Spacing between rows, icon/supportingText presence-
192
- // or-absence alignment, and long-text wrapping/truncation are all much easier to inspect this way
193
- // than by opening the real (portal-rendered) MUI Select menu. See
194
- // MANTINE_ADAPTER_RICH_OPTION_DATA.md.
195
- const renderOptionRowPreview = (wrapItemText: boolean) => (
196
- <div
197
- className={styles.dropdown}
198
- style={{
199
- width:
200
- "var(--recursica_ui-kit_components_dropdown_variants_layouts_stacked_properties_max-width)",
201
- }}
202
- >
203
- {OPTION_ROW_PREVIEW_ITEMS.map((item) => (
204
- <div key={item.value} className={styles.option}>
205
- {renderRichOptionContent(
206
- item,
207
- optionRowPreviewClassNames,
208
- wrapItemText,
209
- )}
210
- </div>
211
- ))}
212
- </div>
213
- );
214
-
215
- // Default: `wrapItemText` is false — label/supportingText truncate to a single line with an
216
- // ellipsis instead of wrapping.
217
- export const RichOptionRowPreview: Story = {
218
- parameters: {
219
- controls: { disable: true },
220
- },
221
- render: () => renderOptionRowPreview(false),
222
- };
223
-
224
- // `wrapItemText: true` — label/supportingText wrap onto additional lines instead of truncating.
225
- export const RichOptionRowPreviewWrapped: Story = {
226
- parameters: {
227
- controls: { disable: true },
228
- },
229
- render: () => renderOptionRowPreview(true),
230
- };
231
-
232
- export const StaticError: Story = {
233
- args: {
234
- error: "You must choose a valid destination.",
235
- value: "Invalid Island",
236
- },
237
- };
238
-
239
- export const StaticDisabled: Story = {
240
- args: {
241
- disabled: true,
242
- value: "United States",
243
- },
244
- };
245
-
246
- export const StaticReadOnly: Story = {
247
- args: {
248
- label: "Read Only View",
249
- readOnly: true,
250
- value: "Canada",
251
- },
252
- };