@recursica/mui-adapter 0.6.0 → 0.7.0

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 (164) hide show
  1. package/ARCHITECTURE.md +15 -0
  2. package/CHANGELOG.md +6 -0
  3. package/SETUP.md +77 -0
  4. package/USAGE.md +55 -0
  5. package/dist/mui-adapter.cjs +26 -26
  6. package/dist/mui-adapter.cjs.map +1 -1
  7. package/dist/mui-adapter.css +1 -1
  8. package/dist/mui-adapter.js +3721 -3511
  9. package/dist/mui-adapter.js.map +1 -1
  10. package/dist/src/components/Accordion/Accordion.d.ts +9 -29
  11. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +2 -5
  12. package/dist/src/components/Autocomplete/Autocomplete.d.ts +4 -8
  13. package/dist/src/components/Avatar/Avatar.d.ts +1 -6
  14. package/dist/src/components/Badge/Badge.d.ts +1 -4
  15. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +2 -3
  16. package/dist/src/components/Button/Button.d.ts +2 -17
  17. package/dist/src/components/Card/Card.d.ts +2 -4
  18. package/dist/src/components/Checkbox/Checkbox.d.ts +4 -6
  19. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +8 -6
  20. package/dist/src/components/Chip/Chip.d.ts +2 -11
  21. package/dist/src/components/Container/Container.d.ts +1 -5
  22. package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
  23. package/dist/src/components/Dropdown/Dropdown.d.ts +4 -14
  24. package/dist/src/components/Flex/Flex.d.ts +2 -22
  25. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +2 -7
  26. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +3 -18
  27. package/dist/src/components/Group/Group.d.ts +2 -7
  28. package/dist/src/components/HoverCard/HoverCard.d.ts +13 -39
  29. package/dist/src/components/Label/Label.d.ts +2 -9
  30. package/dist/src/components/Link/Link.d.ts +2 -6
  31. package/dist/src/components/Loader/Loader.d.ts +2 -7
  32. package/dist/src/components/Menu/Menu.d.ts +24 -98
  33. package/dist/src/components/Modal/Modal.d.ts +32 -31
  34. package/dist/src/components/NumberInput/NumberInput.d.ts +3 -5
  35. package/dist/src/components/Pagination/Pagination.d.ts +8 -41
  36. package/dist/src/components/Panel/Panel.d.ts +5 -18
  37. package/dist/src/components/Radio/Radio.d.ts +4 -4
  38. package/dist/src/components/Radio/RadioGroup.d.ts +3 -7
  39. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +2 -5
  40. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +5 -15
  41. package/dist/src/components/Slider/Slider.d.ts +4 -14
  42. package/dist/src/components/Stack/Stack.d.ts +2 -5
  43. package/dist/src/components/Stepper/Stepper.d.ts +36 -16
  44. package/dist/src/components/Switch/Switch.d.ts +4 -4
  45. package/dist/src/components/Switch/SwitchGroup.d.ts +4 -4
  46. package/dist/src/components/Table/Table.d.ts +2 -1
  47. package/dist/src/components/Tabs/Tabs.d.ts +11 -26
  48. package/dist/src/components/Text/Text.d.ts +2 -16
  49. package/dist/src/components/TextArea/TextArea.d.ts +3 -9
  50. package/dist/src/components/TextField/TextField.d.ts +3 -7
  51. package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
  52. package/dist/src/components/Timeline/Timeline.d.ts +2 -1
  53. package/dist/src/components/Timeline/TimelineItem.d.ts +2 -13
  54. package/dist/src/components/Title/Title.d.ts +2 -15
  55. package/dist/src/components/Toast/Toast.d.ts +11 -16
  56. package/dist/src/components/Tooltip/Tooltip.d.ts +7 -21
  57. package/dist/src/components/TransferList/TransferList.d.ts +2 -1
  58. package/dist/src/components/Typography/Typography.d.ts +1 -1
  59. package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
  60. package/dist/src/utils/filterStylingProps.d.ts +1 -11
  61. package/llms.txt +16 -0
  62. package/package.json +6 -2
  63. package/src/components/Accordion/Accordion.module.css +1 -2
  64. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  65. package/src/components/Accordion/Accordion.tsx +19 -23
  66. package/src/components/AssistiveElement/AssistiveElement.module.css +32 -29
  67. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +10 -27
  68. package/src/components/AssistiveElement/AssistiveElement.tsx +11 -15
  69. package/src/components/Autocomplete/Autocomplete.module.css +17 -18
  70. package/src/components/Autocomplete/Autocomplete.stories.tsx +7 -16
  71. package/src/components/Autocomplete/Autocomplete.tsx +27 -45
  72. package/src/components/Avatar/Avatar.tsx +2 -13
  73. package/src/components/Badge/Badge.tsx +2 -5
  74. package/src/components/Breadcrumb/Breadcrumb.tsx +1 -4
  75. package/src/components/Button/Button.module.css +19 -61
  76. package/src/components/Button/Button.stories.tsx +24 -23
  77. package/src/components/Button/Button.tsx +7 -18
  78. package/src/components/Card/Card.module.css +36 -0
  79. package/src/components/Card/Card.tsx +6 -4
  80. package/src/components/Checkbox/Checkbox.module.css +27 -10
  81. package/src/components/Checkbox/Checkbox.tsx +124 -24
  82. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  83. package/src/components/Checkbox/CheckboxGroup.tsx +43 -23
  84. package/src/components/Chip/Chip.module.css +52 -34
  85. package/src/components/Chip/Chip.tsx +45 -47
  86. package/src/components/Container/Container.stories.tsx +103 -20
  87. package/src/components/Container/Container.tsx +1 -13
  88. package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
  89. package/src/components/DatePicker/DatePicker.tsx +3 -1
  90. package/src/components/Dropdown/Dropdown.tsx +7 -9
  91. package/src/components/FileInput/FileInput.stories.tsx +2 -19
  92. package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
  93. package/src/components/Flex/Flex.stories.tsx +113 -20
  94. package/src/components/Flex/Flex.tsx +16 -26
  95. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +0 -8
  96. package/src/components/FormControlLayout/FormControlLayout.tsx +18 -7
  97. package/src/components/FormControlWrapper/FormControlWrapper.module.css +1 -10
  98. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +12 -21
  99. package/src/components/FormControlWrapper/FormControlWrapper.tsx +11 -30
  100. package/src/components/Group/Group.stories.tsx +6 -30
  101. package/src/components/Group/Group.tsx +14 -9
  102. package/src/components/HoverCard/HoverCard.tsx +72 -75
  103. package/src/components/Label/Label.module.css +4 -0
  104. package/src/components/Label/Label.stories.tsx +18 -12
  105. package/src/components/Label/Label.tsx +3 -9
  106. package/src/components/Link/Link.module.css +4 -3
  107. package/src/components/Link/Link.stories.tsx +2 -8
  108. package/src/components/Link/Link.tsx +1 -5
  109. package/src/components/Loader/Loader.module.css +1 -2
  110. package/src/components/Loader/Loader.tsx +1 -7
  111. package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
  112. package/src/components/Menu/Menu.stories.tsx +106 -188
  113. package/src/components/Menu/Menu.tsx +34 -280
  114. package/src/components/Modal/Modal.tsx +158 -160
  115. package/src/components/NumberInput/NumberInput.tsx +6 -18
  116. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
  117. package/src/components/Pagination/Pagination.module.css +12 -24
  118. package/src/components/Pagination/Pagination.stories.tsx +0 -8
  119. package/src/components/Pagination/Pagination.tsx +20 -140
  120. package/src/components/Panel/Panel.tsx +7 -30
  121. package/src/components/Radio/Radio.module.css +25 -10
  122. package/src/components/Radio/Radio.tsx +51 -19
  123. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  124. package/src/components/Radio/RadioGroup.tsx +26 -12
  125. package/src/components/ReadOnlyField/ReadOnlyField.module.css +6 -6
  126. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +5 -36
  127. package/src/components/ReadOnlyField/ReadOnlyField.tsx +9 -13
  128. package/src/components/SegmentedControl/SegmentedControl.module.css +23 -47
  129. package/src/components/SegmentedControl/SegmentedControl.tsx +44 -14
  130. package/src/components/Slider/Slider.module.css +1 -4
  131. package/src/components/Slider/Slider.stories.tsx +3 -3
  132. package/src/components/Slider/Slider.tsx +26 -25
  133. package/src/components/Stack/Stack.stories.tsx +4 -25
  134. package/src/components/Stack/Stack.tsx +1 -5
  135. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
  136. package/src/components/Stepper/Stepper.stories.tsx +56 -43
  137. package/src/components/Stepper/Stepper.tsx +89 -87
  138. package/src/components/Switch/Switch.module.css +21 -0
  139. package/src/components/Switch/Switch.tsx +63 -16
  140. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  141. package/src/components/Switch/SwitchGroup.tsx +27 -18
  142. package/src/components/Table/Table.stories.tsx +1 -19
  143. package/src/components/Table/Table.tsx +3 -1
  144. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
  145. package/src/components/Tabs/Tabs.stories.tsx +41 -24
  146. package/src/components/Tabs/Tabs.tsx +49 -66
  147. package/src/components/Text/Text.stories.tsx +5 -17
  148. package/src/components/Text/Text.tsx +1 -15
  149. package/src/components/TextArea/TextArea.tsx +7 -17
  150. package/src/components/TextField/TextField.stories.tsx +1 -27
  151. package/src/components/TextField/TextField.tsx +4 -6
  152. package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
  153. package/src/components/TimePicker/TimePicker.tsx +3 -1
  154. package/src/components/Timeline/Timeline.tsx +4 -1
  155. package/src/components/Timeline/TimelineItem.tsx +1 -12
  156. package/src/components/Title/Title.stories.tsx +0 -18
  157. package/src/components/Title/Title.tsx +1 -7
  158. package/src/components/Toast/Toast.stories.tsx +1 -1
  159. package/src/components/Toast/Toast.tsx +62 -28
  160. package/src/components/Tooltip/Tooltip.tsx +11 -37
  161. package/src/components/TransferList/TransferList.stories.tsx +1 -19
  162. package/src/components/TransferList/TransferList.tsx +3 -1
  163. package/src/utils/RequireAccessibleLabel.ts +1 -12
  164. package/src/utils/filterStylingProps.ts +7 -20
@@ -1,12 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from "react";
3
2
  import type { Meta, StoryObj } from "@storybook/react";
4
3
  import { ReadOnlyField } from "./ReadOnlyField";
5
4
  import { EmptyValueRenderer } from "@recursica/adapter-common";
6
- import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
7
5
 
8
6
  const meta: Meta<typeof ReadOnlyField> = {
9
- title: "UI-Kit/ReadOnlyField",
7
+ title: "UI Kit/ReadOnlyField",
10
8
  component: ReadOnlyField,
11
9
  tags: ["autodocs"],
12
10
  parameters: {
@@ -16,17 +14,6 @@ const meta: Meta<typeof ReadOnlyField> = {
16
14
  "The ReadOnlyField safely natively wraps data sets bypassing active HTML interaction hooks while natively retaining exact bounding visual layouts defined by internal Design System Tokens. Useful for creating strict data-review profiles or conditional form read-overs.",
17
15
  },
18
16
  },
19
- controls: {
20
- include: [
21
- "type",
22
- "labelWithEditIcon",
23
- "formLayout",
24
- "labelSize",
25
- "labelAlignment",
26
- "labelOptionalText",
27
- "required",
28
- ],
29
- },
30
17
  },
31
18
  args: {
32
19
  label: "Read Only Label",
@@ -35,14 +22,14 @@ const meta: Meta<typeof ReadOnlyField> = {
35
22
  type: "text",
36
23
  },
37
24
  argTypes: {
38
- ...formControlArgTypes,
39
25
  type: {
40
26
  control: "select",
41
- options: ["text", "number", "boolean", "switch", "date"], // Add more as we support them
27
+ options: ["text", "number"], // Add more as we support them
42
28
  },
43
29
  labelWithEditIcon: {
44
30
  control: "boolean",
45
31
  },
32
+ // We cannot natively control a React.ElementType through standard primitive storybook panels.
46
33
  },
47
34
  };
48
35
 
@@ -55,7 +42,6 @@ type Story = StoryObj<typeof ReadOnlyField>;
55
42
  */
56
43
  export const Default: Story = {
57
44
  args: {},
58
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
59
45
  };
60
46
 
61
47
  /**
@@ -66,7 +52,6 @@ export const EmptyValue: Story = {
66
52
  value: "",
67
53
  label: "Empty String Evaluated Automatically (Default 'N/A')",
68
54
  },
69
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
70
55
  };
71
56
 
72
57
  const CustomEmptyTextRenderer: React.FC<{ value?: any }> & {
@@ -83,7 +68,6 @@ export const CustomEmptyText: Story = {
83
68
  label: "Custom Empty Text Default",
84
69
  emptyValueComponent: CustomEmptyTextRenderer,
85
70
  },
86
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
87
71
  };
88
72
 
89
73
  const CustomEmptyCheckRenderer: React.FC<{ value?: any }> & {
@@ -102,7 +86,6 @@ export const CustomEmptyRenderer: Story = {
102
86
  label: "Custom Logic Evaluation Binding",
103
87
  emptyValueComponent: CustomEmptyCheckRenderer,
104
88
  },
105
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
106
89
  };
107
90
 
108
91
  /**
@@ -113,7 +96,6 @@ export const StackedDefault: Story = {
113
96
  formLayout: "stacked",
114
97
  value: "Some fixed readable text",
115
98
  },
116
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
117
99
  };
118
100
 
119
101
  /**
@@ -124,7 +106,6 @@ export const SideBySide: Story = {
124
106
  formLayout: "side-by-side",
125
107
  value: "Some fixed readable text mapping horizontally",
126
108
  },
127
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
128
109
  };
129
110
 
130
111
  /**
@@ -136,7 +117,6 @@ export const WithEditIcon: Story = {
136
117
  required: true,
137
118
  value: "Editable fixed structure",
138
119
  },
139
- render: ({ ...args }: any) => <ReadOnlyField {...args} />,
140
120
  };
141
121
 
142
122
  /**
@@ -145,46 +125,35 @@ export const WithEditIcon: Story = {
145
125
  */
146
126
  export const DataTypes: Story = {
147
127
  args: {},
148
- render: ({ ...args }: any) => (
128
+ render: () => (
149
129
  <div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
150
130
  <ReadOnlyField
151
- {...args}
152
131
  label="Text Mapping"
153
132
  type="text"
154
133
  value="Standard string output"
155
134
  />
135
+ <ReadOnlyField label="Number Mapping" type="number" value={1234567.89} />
156
136
  <ReadOnlyField
157
- {...args}
158
- label="Number Mapping"
159
- type="number"
160
- value={1234567.89}
161
- />
162
- <ReadOnlyField
163
- {...args}
164
137
  label="Date Mapping"
165
138
  type="date"
166
139
  value={new Date("2026-04-28T12:00:00Z").toLocaleDateString()}
167
140
  />
168
141
  <ReadOnlyField
169
- {...args}
170
142
  label="Boolean Mapping (True)"
171
143
  type="boolean"
172
144
  value={true}
173
145
  />
174
146
  <ReadOnlyField
175
- {...args}
176
147
  label="Boolean Mapping (False)"
177
148
  type="boolean"
178
149
  value={false}
179
150
  />
180
151
  <ReadOnlyField
181
- {...args}
182
152
  label="Switch Mapping (True -> On)"
183
153
  type="switch"
184
154
  value={true}
185
155
  />
186
156
  <ReadOnlyField
187
- {...args}
188
157
  label="Switch Mapping (False -> Off)"
189
158
  type="switch"
190
159
  value={false}
@@ -7,14 +7,14 @@ import {
7
7
  } from "../FormControlWrapper/FormControlWrapper";
8
8
  import styles from "./ReadOnlyField.module.css";
9
9
 
10
+ import { type RecursicaReadOnlyFieldProps as BaseRecursicaReadOnlyFieldProps } from "@recursica/adapter-common";
11
+
10
12
  export type ReadOnlyFieldProps = Omit<
11
13
  RecursicaFormControlWrapperProps,
12
- "error" | "focused"
14
+ "error" | "focused" | "controlMaxWidth" | "controlMinWidth"
13
15
  > &
14
- ReadOnlyControlProps & {
15
- value?: any;
16
- type?: "text" | "boolean" | "number" | "switch" | "date";
17
- };
16
+ ReadOnlyControlProps &
17
+ BaseRecursicaReadOnlyFieldProps;
18
18
 
19
19
  export const ReadOnlyField = React.forwardRef<
20
20
  HTMLDivElement,
@@ -61,7 +61,7 @@ export const ReadOnlyField = React.forwardRef<
61
61
  className={`${styles.root} ${className || ""}`}
62
62
  {...wrapperProps}
63
63
  >
64
- <span className={styles.text}>N/A</span>
64
+ <p className={styles.text}>N/A</p>
65
65
  </FormControlWrapper>
66
66
  );
67
67
  }
@@ -88,12 +88,8 @@ export const ReadOnlyField = React.forwardRef<
88
88
  if (type === "switch") {
89
89
  displayValue = value ? "On" : "Off";
90
90
  }
91
- } else if (typeof value === "object") {
92
- try {
93
- displayValue = JSON.stringify(value);
94
- } catch {
95
- displayValue = String(value);
96
- }
91
+ } else if (Array.isArray(value)) {
92
+ displayValue = value.join(", ");
97
93
  } else {
98
94
  displayValue = String(value);
99
95
  }
@@ -104,7 +100,7 @@ export const ReadOnlyField = React.forwardRef<
104
100
  className={`${styles.root} ${className || ""}`}
105
101
  {...wrapperProps}
106
102
  >
107
- <span className={styles.text}>{displayValue}</span>
103
+ <p className={styles.text}>{displayValue}</p>
108
104
  </FormControlWrapper>
109
105
  );
110
106
  });
@@ -25,8 +25,7 @@
25
25
  --recursica_ui-kit_components_segmented-control_properties_padding-horizontal
26
26
  );
27
27
  box-shadow: var(
28
- --recursica_ui-kit_components_segmented-control_properties_elevation,
29
- none
28
+ --recursica_ui-kit_components_segmented-control_properties_elevation
30
29
  );
31
30
  gap: var(--recursica_ui-kit_components_segmented-control_properties_item-gap);
32
31
  }
@@ -42,10 +41,7 @@
42
41
  --recursica_ui-kit_components_segmented-control-item_properties_item_height
43
42
  );
44
43
  border-radius: var(
45
- --recursica_ui-kit_components_segmented-control-item_properties_unselected_border-radius,
46
- var(
47
- --recursica_ui-kit_components_segmented-control-item_properties_item_border-radius
48
- )
44
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected_border-radius
49
45
  );
50
46
 
51
47
  border: var(
@@ -63,41 +59,32 @@
63
59
  );
64
60
 
65
61
  font-family: var(
66
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-family,
67
- inherit
62
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-family
68
63
  );
69
64
  font-size: var(
70
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-size,
71
- inherit
65
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-size
72
66
  );
73
67
  font-style: var(
74
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-style,
75
- inherit
68
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-style
76
69
  );
77
70
  font-weight: var(
78
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-weight,
79
- inherit
71
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_font-weight
80
72
  );
81
73
  letter-spacing: var(
82
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_letter-spacing,
83
- inherit
74
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_letter-spacing
84
75
  );
85
76
  line-height: var(
86
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_line-height,
87
- inherit
77
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_line-height
88
78
  );
89
79
  text-decoration: var(
90
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_text-decoration,
91
- inherit
80
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_text-decoration
92
81
  );
93
82
  text-transform: var(
94
- --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_text-transform,
95
- inherit
83
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected-text_text-transform
96
84
  );
97
85
 
98
86
  color: var(
99
- --recursica_ui-kit_components_segmented-control-item_properties_unselected_colors_text-color,
100
- inherit
87
+ --recursica_ui-kit_components_segmented-control-item_properties_unselected_colors_text-color
101
88
  );
102
89
 
103
90
  display: flex;
@@ -140,8 +127,8 @@
140
127
  );
141
128
  }
142
129
 
143
- /* Indicator (the moving selected block) */
144
- .root .indicator {
130
+ /* Indicator mapping (MUI ToggleButton applies .Mui-selected to the button instead of rendering a sliding indicator) */
131
+ .root .control.Mui-selected {
145
132
  background-color: var(
146
133
  --recursica_ui-kit_components_segmented-control-item_properties_selected_colors_background
147
134
  );
@@ -156,48 +143,37 @@
156
143
  --recursica_ui-kit_components_segmented-control-item_properties_selected_elevation
157
144
  );
158
145
  border-radius: var(
159
- --recursica_ui-kit_components_segmented-control-item_properties_selected_border-radius,
160
- var(
161
- --recursica_ui-kit_components_segmented-control-item_properties_item_border-radius
162
- )
146
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_border-radius
163
147
  );
164
148
  }
165
149
 
166
150
  /* Selected label text color override */
167
- .root .control[data-active] .label {
151
+ .root .control.Mui-selected .label {
168
152
  color: var(
169
153
  --recursica_ui-kit_components_segmented-control-item_properties_selected_colors_text-color
170
154
  );
171
155
  font-family: var(
172
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-family,
173
- inherit
156
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-family
174
157
  );
175
158
  font-size: var(
176
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-size,
177
- inherit
159
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-size
178
160
  );
179
161
  font-style: var(
180
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-style,
181
- inherit
162
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-style
182
163
  );
183
164
  font-weight: var(
184
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-weight,
185
- inherit
165
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_font-weight
186
166
  );
187
167
  letter-spacing: var(
188
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_letter-spacing,
189
- inherit
168
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_letter-spacing
190
169
  );
191
170
  line-height: var(
192
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_line-height,
193
- inherit
171
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_line-height
194
172
  );
195
173
  text-decoration: var(
196
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_text-decoration,
197
- inherit
174
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_text-decoration
198
175
  );
199
176
  text-transform: var(
200
- --recursica_ui-kit_components_segmented-control-item_properties_selected-text_text-transform,
201
- inherit
177
+ --recursica_ui-kit_components_segmented-control-item_properties_selected-text_text-transform
202
178
  );
203
179
  }
@@ -1,6 +1,7 @@
1
1
  import { forwardRef } from "react";
2
2
  import {
3
3
  ToggleButtonGroup as MuiSegmentedControl,
4
+ ToggleButton,
4
5
  type ToggleButtonGroupProps as MuiSegmentedControlProps,
5
6
  } from "@mui/material";
6
7
  import {
@@ -9,17 +10,7 @@ import {
9
10
  } from "../../utils/filterStylingProps";
10
11
  import styles from "./SegmentedControl.module.css";
11
12
 
12
- export interface RecursicaSegmentedControlProps {
13
- /** The orientation of the control */
14
- orientation?: "horizontal" | "vertical";
15
- /** If true, the control will take up the full width of its container */
16
- fullWidth?: boolean;
17
- /**
18
- * SegmentedControl should NOT be allowed to be disabled by design.
19
- * This component explicitly disables the `disabled` prop.
20
- */
21
- disabled?: never;
22
- }
13
+ import { type RecursicaSegmentedControlProps } from "@recursica/adapter-common";
23
14
 
24
15
  export type SegmentedControlProps = RecursicaOverStyled<
25
16
  Omit<
@@ -31,6 +22,8 @@ export type SegmentedControlProps = RecursicaOverStyled<
31
22
  | "classNames"
32
23
  | "className"
33
24
  | "disabled"
25
+ | "value"
26
+ | "onChange"
34
27
  > & {
35
28
  className?: string;
36
29
  classNames?: Partial<Record<string, string>>;
@@ -77,7 +70,15 @@ function useSegmentedControlClassNames(restRecord: Record<string, unknown>): {
77
70
 
78
71
  const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(
79
72
  function SegmentedControl(
80
- { overStyled = false, orientation = "horizontal", fullWidth, ...rest },
73
+ {
74
+ overStyled = false,
75
+ orientation = "horizontal",
76
+ fullWidth,
77
+ data = [],
78
+ value,
79
+ onChange,
80
+ ...rest
81
+ },
81
82
  ref,
82
83
  ) {
83
84
  const sanitizedProps = filterStylingProps(rest, overStyled);
@@ -88,6 +89,15 @@ const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(
88
89
 
89
90
  const stylingParams = useSegmentedControlClassNames(restRecord);
90
91
 
92
+ const handleChange = (
93
+ _event: React.MouseEvent<HTMLElement>,
94
+ newValue: string | null,
95
+ ) => {
96
+ if (newValue !== null && onChange) {
97
+ onChange(newValue);
98
+ }
99
+ };
100
+
91
101
  return (
92
102
  <MuiSegmentedControl
93
103
  ref={ref}
@@ -96,11 +106,31 @@ const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(
96
106
  orientation={orientation}
97
107
  fullWidth={fullWidth}
98
108
  data-orientation={orientation}
109
+ exclusive
110
+ value={value}
111
+ onChange={handleChange as any}
99
112
  {...(sanitizedProps as Omit<
100
113
  MuiSegmentedControlProps,
101
- "variant" | "size"
114
+ "variant" | "size" | "value" | "onChange"
102
115
  >)}
103
- />
116
+ >
117
+ {data.map((item) => {
118
+ const itemValue = typeof item === "string" ? item : item.value;
119
+ const itemLabel = typeof item === "string" ? item : item.label;
120
+ const itemDisabled = typeof item === "string" ? false : item.disabled;
121
+
122
+ return (
123
+ <ToggleButton
124
+ key={itemValue}
125
+ value={itemValue}
126
+ disabled={itemDisabled}
127
+ className={stylingParams.classNames.control}
128
+ >
129
+ <div className={stylingParams.classNames.label}>{itemLabel}</div>
130
+ </ToggleButton>
131
+ );
132
+ })}
133
+ </MuiSegmentedControl>
104
134
  );
105
135
  },
106
136
  );
@@ -233,10 +233,7 @@
233
233
  position: absolute;
234
234
  bottom: calc(
235
235
  100% +
236
- var(
237
- --recursica_ui-kit_globals_form_properties_label-field-gap-vertical,
238
- 8px
239
- )
236
+ var(--recursica_ui-kit_globals_form_properties_label-field-gap-vertical)
240
237
  );
241
238
  right: 0;
242
239
  white-space: nowrap;
@@ -65,8 +65,8 @@ export const Default: Story = {
65
65
  args: {
66
66
  label: "Auditory Threshold",
67
67
  assistiveText: "Specify the maximum decibel frequency boundary.",
68
- defaultValue: 40,
69
- min: 0,
68
+ defaultValue: 60,
69
+ min: 10,
70
70
  max: 100,
71
71
  step: 1,
72
72
  showMinMaxLabels: true,
@@ -92,7 +92,7 @@ export const Disabled: Story = {
92
92
  label: "Decommissioned Server Node",
93
93
  assistiveText: "Modifications to this environment are frozen.",
94
94
  defaultValue: 35,
95
- disabled: true,
95
+ disabled: false,
96
96
  },
97
97
  };
98
98
 
@@ -2,7 +2,6 @@ import React, { forwardRef, useState, useEffect } from "react";
2
2
  import {
3
3
  Slider as MuiSlider,
4
4
  type SliderProps as MuiSliderProps,
5
- type InputWrapperProps,
6
5
  } from "@mui/material";
7
6
  import { type ReadOnlyControlProps } from "@recursica/adapter-common";
8
7
  import {
@@ -14,28 +13,24 @@ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
14
13
 
15
14
  import styles from "./Slider.module.css";
16
15
 
16
+ import { type RecursicaSliderProps as BaseRecursicaSliderProps } from "@recursica/adapter-common";
17
+
17
18
  export interface RecursicaSliderProps
18
19
  extends Omit<
19
- Omit<MuiSliderProps, "size" | "color">,
20
- "variant" | "radius" | "wrapperProps" | "classNames" | "styles" | "label"
20
+ MuiSliderProps,
21
+ "size" | "color" | "classes" | "onChange" | "onChangeCommitted"
21
22
  >,
22
23
  Omit<
23
24
  RecursicaFormControlWrapperProps,
24
- "controlMaxWidth" | "controlMinWidth"
25
+ | "controlMaxWidth"
26
+ | "controlMinWidth"
27
+ | "error"
28
+ | "required"
29
+ | "withAsterisk"
30
+ | keyof MuiSliderProps
25
31
  >,
26
- Pick<InputWrapperProps, "error" | "required" | "withAsterisk">,
27
- ReadOnlyControlProps {
28
- /** The form control label displayed above or beside the slider track. */
29
- label?: React.ReactNode;
30
- /** Floating tooltip shown above the thumb when dragging. Replaces Mui's `label`. */
31
- tooltipLabel?: MuiSliderProps["label"];
32
- /** An optional icon rendered to the left of the slider track. */
33
- icon?: React.ReactNode;
34
- /** Whether to render a numeric input field side-by-side or stacked with the track. Defaults to false. */
35
- showInput?: boolean;
36
- /** Whether to render min and max labels below the track. Defaults to true. */
37
- showMinMaxLabels?: boolean;
38
- }
32
+ ReadOnlyControlProps,
33
+ BaseRecursicaSliderProps {}
39
34
 
40
35
  export type SliderProps = RecursicaOverStyled<RecursicaSliderProps>;
41
36
 
@@ -73,6 +68,7 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
73
68
  assistiveWithIcon,
74
69
  error,
75
70
  required,
71
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
76
72
  withAsterisk,
77
73
  id,
78
74
  className,
@@ -96,12 +92,18 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
96
92
 
97
93
  // Bidirectional state linking the slider track value to the input field string representation
98
94
  const [internalValue, setInternalValue] = useState<number>(() => {
99
- if (value !== undefined) return value;
100
- if (defaultValue !== undefined) return defaultValue;
95
+ if (value !== undefined) return Array.isArray(value) ? value[0] : value;
96
+ if (defaultValue !== undefined)
97
+ return Array.isArray(defaultValue) ? defaultValue[0] : defaultValue;
101
98
  return min;
102
99
  });
103
100
 
104
- const resolvedValue = value !== undefined ? value : internalValue;
101
+ const resolvedValue =
102
+ value !== undefined
103
+ ? Array.isArray(value)
104
+ ? value[0]
105
+ : value
106
+ : internalValue;
105
107
  const [inputValue, setInputValue] = useState<string>(
106
108
  resolvedValue.toString(),
107
109
  );
@@ -111,12 +113,12 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
111
113
  setInputValue(resolvedValue.toString());
112
114
  }, [resolvedValue]);
113
115
 
114
- const handleValueChange = (e: Event, val: number | number[]) => {
116
+ const handleValueChange = (_e: Event, val: number | number[]) => {
115
117
  const singleVal = Array.isArray(val) ? val[0] : val;
116
118
  if (value === undefined) {
117
119
  setInternalValue(singleVal);
118
120
  }
119
- onChange?.(singleVal as any);
121
+ onChange?.(singleVal);
120
122
  };
121
123
 
122
124
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -209,9 +211,8 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
209
211
  label={label}
210
212
  assistiveText={assistiveText}
211
213
  assistiveWithIcon={assistiveWithIcon}
212
- error={error}
214
+ error={error as any}
213
215
  required={required}
214
- withAsterisk={withAsterisk}
215
216
  id={id}
216
217
  readOnly={readOnly}
217
218
  readOnlyComponent={readOnlyComponent || SliderReadOnlyValue}
@@ -270,7 +271,7 @@ export const Slider = forwardRef<HTMLDivElement, SliderProps>(
270
271
  onBlur={handleInputBlur}
271
272
  min={min}
272
273
  max={max}
273
- step={step}
274
+ step={step ?? undefined}
274
275
  disabled={disabled}
275
276
  data-error={error ? "true" : undefined}
276
277
  />
@@ -17,32 +17,11 @@ const meta: Meta<StackStoryProps> = {
17
17
  "Stack is a flex vertical layout container that maps directly to Mantine's Stack component allowing safe layout property passing.",
18
18
  },
19
19
  },
20
- controls: {
21
- include: [
22
- "layer",
23
- "withLayer",
24
- "gap",
25
- "alignItems",
26
- "justifyContent",
27
- "defaultChecked",
28
- "children",
29
- "component",
30
- "variant",
31
- "size",
32
- "icon",
33
- "disabled",
34
- "href",
35
- "onClick",
36
- "onChange",
37
- "value",
38
- "checked",
39
- ],
40
- },
41
20
  },
42
21
  args: {
43
22
  gap: "rec-default",
44
- alignItems: "stretch",
45
- justifyContent: "flex-start",
23
+ align: "stretch",
24
+ justify: "flex-start",
46
25
  },
47
26
  argTypes: {
48
27
  gap: {
@@ -63,12 +42,12 @@ const meta: Meta<StackStoryProps> = {
63
42
  ],
64
43
  description: "Gap between elements",
65
44
  },
66
- alignItems: {
45
+ align: {
67
46
  control: "select",
68
47
  options: ["flex-start", "center", "flex-end", "stretch"],
69
48
  description: "Align-items property",
70
49
  },
71
- justifyContent: {
50
+ justify: {
72
51
  control: "select",
73
52
  options: [
74
53
  "flex-start",
@@ -4,16 +4,12 @@ import {
4
4
  type StackProps as MUIStackProps,
5
5
  } from "@mui/material";
6
6
  import {
7
- type RecursicaSpacing,
8
7
  SPACING_MAP,
9
8
  type OmitSx,
10
9
  filterSxProp,
11
10
  } from "../../utils/filterStylingProps";
12
11
 
13
- export interface RecursicaStackProps {
14
- children?: React.ReactNode;
15
- gap?: MUIStackProps["spacing"] | RecursicaSpacing;
16
- }
12
+ import { type RecursicaStackProps } from "@recursica/adapter-common";
17
13
 
18
14
  export type StackProps = OmitSx<
19
15
  Omit<MUIStackProps, "spacing"> & RecursicaStackProps
@@ -0,0 +1,4 @@
1
+ # Stepper Implementation Notes
2
+
3
+ - **Compositional API Dropped:** Mantine manages stepper state and content via `<Stepper.Step>` and `<Stepper.Completed>`. MUI delegates content rendering to the developer and focuses purely on the stepper visual layout using `<Step>`, `<StepLabel>`, etc.
4
+ - **Monolithic API Adopted:** Following architectural review, we have abandoned the fabricated context wrappers for `mui-adapter`. We now natively export `Stepper`, `Step`, `StepLabel`, `StepButton`, and `StepConnector` wrapping their `@mui/material` counterparts. Developers are expected to manage the active step logic and content rendering outside the `Stepper` component, consistent with MUI patterns. Storybook tests have been updated to reflect this divergence while retaining core visual compatibility.