@recursica/mui-adapter 0.4.0 → 0.6.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 (177) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/mui-adapter.cjs +74 -1
  3. package/dist/mui-adapter.cjs.map +1 -1
  4. package/dist/mui-adapter.css +1 -1
  5. package/dist/mui-adapter.js +6651 -201
  6. package/dist/mui-adapter.js.map +1 -1
  7. package/dist/src/components/Accordion/Accordion.d.ts +63 -2
  8. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +9 -2
  9. package/dist/src/components/Autocomplete/Autocomplete.d.ts +17 -0
  10. package/dist/src/components/Autocomplete/index.d.ts +1 -0
  11. package/dist/src/components/Avatar/Avatar.d.ts +14 -2
  12. package/dist/src/components/Badge/Badge.d.ts +13 -3
  13. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +10 -3
  14. package/dist/src/components/Button/Button.d.ts +1 -1
  15. package/dist/src/components/Card/Card.d.ts +40 -3
  16. package/dist/src/components/Checkbox/Checkbox.d.ts +15 -2
  17. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +16 -0
  18. package/dist/src/components/Checkbox/index.d.ts +5 -1
  19. package/dist/src/components/Chip/Chip.d.ts +18 -2
  20. package/dist/src/components/Dropdown/Dropdown.d.ts +23 -3
  21. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +10 -2
  22. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +24 -2
  23. package/dist/src/components/HoverCard/HoverCard.d.ts +55 -3
  24. package/dist/src/components/Label/Label.d.ts +13 -2
  25. package/dist/src/components/Link/Link.d.ts +1 -1
  26. package/dist/src/components/Menu/Menu.d.ts +99 -3
  27. package/dist/src/components/Modal/Modal.d.ts +36 -2
  28. package/dist/src/components/NumberInput/NumberInput.d.ts +14 -2
  29. package/dist/src/components/Pagination/Pagination.d.ts +44 -2
  30. package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
  31. package/dist/src/components/Panel/Panel.d.ts +65 -3
  32. package/dist/src/components/Radio/Radio.d.ts +13 -3
  33. package/dist/src/components/Radio/RadioGroup.d.ts +13 -0
  34. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  35. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +7 -2
  36. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  37. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  38. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
  39. package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
  40. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +31 -3
  41. package/dist/src/components/Slider/Slider.d.ts +28 -2
  42. package/dist/src/components/Stepper/Stepper.d.ts +21 -2
  43. package/dist/src/components/Switch/Switch.d.ts +10 -3
  44. package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
  45. package/dist/src/components/Tabs/Tabs.d.ts +35 -3
  46. package/dist/src/components/Text/Text.d.ts +1 -1
  47. package/dist/src/components/TextArea/TextArea.d.ts +18 -2
  48. package/dist/src/components/TextField/TextField.d.ts +16 -2
  49. package/dist/src/components/Timeline/Timeline.d.ts +14 -2
  50. package/dist/src/components/Timeline/TimelineItem.d.ts +29 -0
  51. package/dist/src/components/Title/Title.d.ts +1 -1
  52. package/dist/src/components/Toast/Toast.d.ts +25 -2
  53. package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
  54. package/dist/src/components/Typography/Typography.d.ts +1 -1
  55. package/dist/src/components/index.d.ts +1 -0
  56. package/package.json +12 -2
  57. package/src/GlobalExemptions.modules.css +13 -0
  58. package/src/components/Accordion/Accordion.module.css +295 -0
  59. package/src/components/Accordion/Accordion.stories.tsx +149 -21
  60. package/src/components/Accordion/Accordion.tsx +264 -4
  61. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  62. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +76 -19
  63. package/src/components/AssistiveElement/AssistiveElement.tsx +85 -4
  64. package/src/components/Autocomplete/Autocomplete.module.css +325 -0
  65. package/src/components/Autocomplete/Autocomplete.stories.tsx +196 -0
  66. package/src/components/Autocomplete/Autocomplete.tsx +201 -0
  67. package/src/components/Autocomplete/index.ts +1 -0
  68. package/src/components/Avatar/Avatar.module.css +344 -0
  69. package/src/components/Avatar/Avatar.stories.tsx +94 -22
  70. package/src/components/Avatar/Avatar.tsx +110 -5
  71. package/src/components/Badge/Badge.module.css +127 -0
  72. package/src/components/Badge/Badge.stories.tsx +65 -22
  73. package/src/components/Badge/Badge.tsx +70 -5
  74. package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
  75. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
  76. package/src/components/Breadcrumb/Breadcrumb.tsx +62 -5
  77. package/src/components/Button/Button.module.css +113 -20
  78. package/src/components/Button/Button.stories.tsx +3 -0
  79. package/src/components/Button/Button.tsx +10 -3
  80. package/src/components/Card/Card.module.css +118 -0
  81. package/src/components/Card/Card.stories.tsx +117 -19
  82. package/src/components/Card/Card.tsx +179 -4
  83. package/src/components/Checkbox/Checkbox.module.css +232 -0
  84. package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
  85. package/src/components/Checkbox/Checkbox.tsx +146 -4
  86. package/src/components/Checkbox/CheckboxGroup.tsx +117 -0
  87. package/src/components/Checkbox/index.ts +6 -1
  88. package/src/components/Chip/Chip.module.css +236 -0
  89. package/src/components/Chip/Chip.stories.tsx +101 -21
  90. package/src/components/Chip/Chip.tsx +138 -5
  91. package/src/components/DatePicker/DatePicker.module.css +42 -0
  92. package/src/components/DatePicker/DatePicker.tsx +1 -0
  93. package/src/components/Dropdown/Dropdown.module.css +296 -0
  94. package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
  95. package/src/components/Dropdown/Dropdown.tsx +182 -5
  96. package/src/components/FileInput/FileInput.module.css +47 -0
  97. package/src/components/FileInput/FileInput.tsx +1 -0
  98. package/src/components/FileUpload/FileUpload.module.css +40 -0
  99. package/src/components/FileUpload/FileUpload.tsx +1 -0
  100. package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
  101. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +74 -19
  102. package/src/components/FormControlLayout/FormControlLayout.tsx +58 -4
  103. package/src/components/FormControlWrapper/FormControlWrapper.module.css +96 -0
  104. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +122 -19
  105. package/src/components/FormControlWrapper/FormControlWrapper.tsx +145 -6
  106. package/src/components/HoverCard/HoverCard.module.css +91 -0
  107. package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
  108. package/src/components/HoverCard/HoverCard.tsx +150 -4
  109. package/src/components/Label/Label.module.css +136 -0
  110. package/src/components/Label/Label.stories.tsx +98 -17
  111. package/src/components/Label/Label.tsx +88 -4
  112. package/src/components/Link/Link.module.css +8 -0
  113. package/src/components/Menu/Menu.module.css +287 -0
  114. package/src/components/Menu/Menu.stories.tsx +307 -21
  115. package/src/components/Menu/Menu.tsx +318 -4
  116. package/src/components/Modal/Modal.module.css +172 -0
  117. package/src/components/Modal/Modal.stories.tsx +66 -22
  118. package/src/components/Modal/Modal.tsx +216 -3
  119. package/src/components/NumberInput/NumberInput.module.css +281 -0
  120. package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
  121. package/src/components/NumberInput/NumberInput.tsx +148 -5
  122. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  123. package/src/components/Pagination/Pagination.module.css +307 -0
  124. package/src/components/Pagination/Pagination.stories.tsx +42 -21
  125. package/src/components/Pagination/Pagination.tsx +193 -4
  126. package/src/components/Panel/Panel.module.css +206 -0
  127. package/src/components/Panel/Panel.stories.tsx +214 -22
  128. package/src/components/Panel/Panel.tsx +153 -4
  129. package/src/components/Radio/Radio.module.css +220 -0
  130. package/src/components/Radio/Radio.stories.tsx +77 -19
  131. package/src/components/Radio/Radio.tsx +178 -4
  132. package/src/components/Radio/RadioGroup.tsx +111 -0
  133. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  134. package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
  135. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +175 -16
  136. package/src/components/ReadOnlyField/ReadOnlyField.tsx +109 -4
  137. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  138. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  139. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  140. package/src/components/ReadOnlyField/index.ts +1 -0
  141. package/src/components/SegmentedControl/SegmentedControl.module.css +203 -0
  142. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
  143. package/src/components/SegmentedControl/SegmentedControl.tsx +110 -5
  144. package/src/components/Slider/Slider.module.css +542 -0
  145. package/src/components/Slider/Slider.stories.tsx +157 -19
  146. package/src/components/Slider/Slider.tsx +282 -4
  147. package/src/components/Stepper/Stepper.module.css +410 -0
  148. package/src/components/Stepper/Stepper.stories.tsx +132 -19
  149. package/src/components/Stepper/Stepper.tsx +145 -5
  150. package/src/components/Switch/Switch.module.css +238 -0
  151. package/src/components/Switch/Switch.stories.tsx +98 -19
  152. package/src/components/Switch/Switch.tsx +153 -5
  153. package/src/components/Switch/SwitchGroup.tsx +111 -0
  154. package/src/components/Tabs/Tabs.module.css +422 -0
  155. package/src/components/Tabs/Tabs.stories.tsx +138 -19
  156. package/src/components/Tabs/Tabs.tsx +103 -5
  157. package/src/components/TextArea/TextArea.module.css +160 -0
  158. package/src/components/TextArea/TextArea.stories.tsx +80 -21
  159. package/src/components/TextArea/TextArea.tsx +156 -5
  160. package/src/components/TextField/TextField.module.css +266 -0
  161. package/src/components/TextField/TextField.stories.tsx +168 -15
  162. package/src/components/TextField/TextField.tsx +171 -5
  163. package/src/components/TimePicker/TimePicker.module.css +41 -0
  164. package/src/components/TimePicker/TimePicker.tsx +1 -0
  165. package/src/components/Timeline/Timeline.module.css +367 -0
  166. package/src/components/Timeline/Timeline.stories.tsx +114 -21
  167. package/src/components/Timeline/Timeline.tsx +80 -4
  168. package/src/components/Timeline/TimelineItem.tsx +101 -0
  169. package/src/components/Toast/Toast.module.css +170 -0
  170. package/src/components/Toast/Toast.stories.tsx +54 -22
  171. package/src/components/Toast/Toast.tsx +90 -4
  172. package/src/components/Tooltip/Tooltip.module.css +90 -0
  173. package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
  174. package/src/components/Tooltip/Tooltip.tsx +114 -4
  175. package/src/components/TransferList/TransferList.module.css +38 -0
  176. package/src/components/TransferList/TransferList.tsx +1 -0
  177. package/src/components/index.ts +1 -0
@@ -0,0 +1,111 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { forwardRef } from "react";
3
+ import {
4
+ Switch as MuiSwitch,
5
+ type SwitchGroupProps as MuiSwitchGroupProps,
6
+ } from "@mui/material";
7
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
8
+ import {
9
+ filterStylingProps,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
13
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
14
+ import styles from "./Switch.module.css";
15
+
16
+ export interface RecursicaSwitchGroupProps
17
+ extends Omit<MuiSwitchGroupProps, "size" | "labelProps">,
18
+ Omit<
19
+ RecursicaFormControlWrapperProps,
20
+ "controlMaxWidth" | "controlMinWidth"
21
+ >,
22
+ ReadOnlyControlProps {}
23
+
24
+ export type SwitchGroupProps = RecursicaOverStyled<RecursicaSwitchGroupProps>;
25
+
26
+ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
27
+ function SwitchGroup(props, ref) {
28
+ const {
29
+ overStyled = false,
30
+ formLayout = "stacked",
31
+
32
+ // Label Wrappers
33
+ labelSize,
34
+ labelAlignment,
35
+ labelOptionalText,
36
+ labelWithEditIcon,
37
+ onLabelEditClick,
38
+
39
+ // Base Mui Extracted Attributes
40
+ label,
41
+ description,
42
+ assistiveText,
43
+ assistiveWithIcon,
44
+ error,
45
+ required,
46
+ withAsterisk,
47
+ id,
48
+ className,
49
+ style,
50
+ children,
51
+ readOnly,
52
+ readOnlyComponent,
53
+ emptyValueComponent,
54
+ value,
55
+ defaultValue,
56
+ ...rest
57
+ } = props;
58
+ const sanitizedProps = filterStylingProps(rest, overStyled);
59
+ const restRecord = sanitizedProps as Record<string, unknown>;
60
+
61
+ // Delete prohibited sizing hooks from bypassing the variables
62
+ delete restRecord["size"];
63
+
64
+ return (
65
+ <WithReadOnlyWrapper
66
+ className={className}
67
+ style={style as React.CSSProperties}
68
+ controlMaxWidth="var(--recursica_ui-kit_components_switch-item_properties_label-max-width)"
69
+ controlMinWidth={undefined}
70
+ overStyled={overStyled as true}
71
+ // Strictly override. ARIA grouping prohibits interactive switches nested natively inside <label>.
72
+ formLayout={formLayout}
73
+ labelSize={labelSize}
74
+ labelAlignment={labelAlignment}
75
+ labelOptionalText={labelOptionalText}
76
+ labelWithEditIcon={labelWithEditIcon}
77
+ onLabelEditClick={onLabelEditClick}
78
+ label={label}
79
+ description={description}
80
+ assistiveText={assistiveText}
81
+ assistiveWithIcon={assistiveWithIcon}
82
+ error={error}
83
+ required={required}
84
+ withAsterisk={withAsterisk}
85
+ id={id}
86
+ readOnly={readOnly && !!readOnlyComponent}
87
+ readOnlyComponent={readOnlyComponent}
88
+ emptyValueComponent={emptyValueComponent}
89
+ readOnlyType="text"
90
+ readOnlyValue={value !== undefined ? value : defaultValue}
91
+ readOnlyNativeProps={props}
92
+ activeComponent={
93
+ <div
94
+ ref={ref}
95
+ /* Natively bind local disabled lock dynamically */
96
+ {...(sanitizedProps as unknown as MuiSwitchGroupProps)}
97
+ disabled={readOnly || (restRecord as any).disabled}
98
+ value={value}
99
+ defaultValue={defaultValue}
100
+ >
101
+ <div className={styles.groupRoot} data-layout={formLayout}>
102
+ {children}
103
+ </div>
104
+ </div>
105
+ }
106
+ />
107
+ );
108
+ },
109
+ );
110
+
111
+ const SwitchGroup = (() => {}) as any; // SwitchGroup.displayName = "SwitchGroup";
@@ -0,0 +1,422 @@
1
+ /*
2
+ Recursica Tabs CSS module natively binding to Figma variables.
3
+ */
4
+
5
+ .root {
6
+ width: 100%;
7
+ }
8
+
9
+ /*
10
+ Mantine Tabs Anatomy:
11
+ .root
12
+ .list (container for tabs)
13
+ .tab (individual tab)
14
+ .panel (content)
15
+ */
16
+
17
+ /* ---------------------------------
18
+ ORIENTATION & SPACING
19
+ --------------------------------- */
20
+
21
+ /* Horizontal Orientation */
22
+ .root[data-orientation="horizontal"] {
23
+ --tabs-element-gap: var(
24
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_element-gap
25
+ );
26
+ --tabs-horizontal-padding: var(
27
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_horizontal-padding
28
+ );
29
+ --tabs-icon-size: var(
30
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_icon-size
31
+ );
32
+ --tabs-space-between-tabs: var(
33
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_space-between-tabs
34
+ );
35
+ --tabs-vertical-padding: var(
36
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_vertical-padding
37
+ );
38
+ --tabs-content-alignment: var(
39
+ --recursica_ui-kit_components_tabs_variants_orientation_horizontal_properties_tab-content-alignment
40
+ );
41
+ }
42
+
43
+ .root[data-orientation="horizontal"] .list {
44
+ gap: var(--tabs-space-between-tabs);
45
+ width: 100%;
46
+ }
47
+
48
+ /* Vertical Orientation */
49
+ .root[data-orientation="vertical"] {
50
+ --tabs-element-gap: var(
51
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_element-gap
52
+ );
53
+ --tabs-horizontal-padding: var(
54
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_horizontal-padding
55
+ );
56
+ --tabs-icon-size: var(
57
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_icon-size
58
+ );
59
+ --tabs-space-between-tabs: var(
60
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_space-between-tabs
61
+ );
62
+ --tabs-vertical-padding: var(
63
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_vertical-padding
64
+ );
65
+ --tabs-content-alignment: var(
66
+ --recursica_ui-kit_components_tabs_variants_orientation_vertical_properties_tab-content-alignment
67
+ );
68
+ }
69
+
70
+ .root[data-orientation="vertical"] .list {
71
+ gap: var(--tabs-space-between-tabs);
72
+ }
73
+
74
+ /* ---------------------------------
75
+ VARIANTS
76
+ --------------------------------- */
77
+
78
+ .root[data-variant="default"][data-orientation] {
79
+ --tabs-active-border-size: var(
80
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_active_border-size
81
+ ) !important;
82
+ --tabs-inactive-border-size: var(
83
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_inactive_border-size
84
+ ) !important;
85
+ --tabs-border-radius: var(
86
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_border-radius
87
+ ) !important;
88
+ --tabs-border-color: var(
89
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_inactive_colors_border-color
90
+ ) !important;
91
+ --tabs-color: var(
92
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_active_colors_border-color
93
+ ) !important;
94
+ --tabs-hover-color: var(
95
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_hover-color
96
+ );
97
+ --tabs-hover-opacity: var(
98
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_hover-opacity
99
+ );
100
+ }
101
+
102
+ .root[data-variant="default"][data-orientation="horizontal"] .list {
103
+ margin-bottom: var(
104
+ --recursica_ui-kit_components_tabs_variants_styles_default_variants_orientation_horizontal_properties_tabs-content-gap
105
+ );
106
+ }
107
+
108
+ .root[data-variant="default"][data-orientation="vertical"] .list {
109
+ margin-right: var(
110
+ --recursica_ui-kit_components_tabs_variants_styles_default_variants_orientation_vertical_properties_tabs-content-gap
111
+ );
112
+ }
113
+
114
+ /* Outline Variant */
115
+ .root[data-variant="outline"][data-orientation] {
116
+ --tabs-active-border-size: var(
117
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_active_border-size
118
+ ) !important;
119
+ --tabs-inactive-border-size: var(
120
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_inactive_border-size
121
+ ) !important;
122
+ --tabs-border-radius: var(
123
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_border-radius
124
+ ) !important;
125
+ --tabs-border-color: var(
126
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_inactive_colors_border-color
127
+ ) !important;
128
+ --tabs-color: var(
129
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_active_colors_border-color
130
+ ) !important;
131
+ --tabs-hover-color: var(
132
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_hover-color
133
+ );
134
+ --tabs-hover-opacity: var(
135
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_hover-opacity
136
+ );
137
+ }
138
+
139
+ .root[data-variant="outline"][data-orientation="horizontal"] .list {
140
+ margin-bottom: var(
141
+ --recursica_ui-kit_components_tabs_variants_styles_outline_variants_orientation_horizontal_properties_tabs-content-gap
142
+ );
143
+ }
144
+
145
+ .root[data-variant="outline"][data-orientation="vertical"] .list {
146
+ margin-right: var(
147
+ --recursica_ui-kit_components_tabs_variants_styles_outline_variants_orientation_vertical_properties_tabs-content-gap
148
+ );
149
+ }
150
+
151
+ /* Pills Variant */
152
+ .root[data-variant="pills"][data-orientation] {
153
+ --tabs-active-border-size: var(
154
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_active_border-size
155
+ );
156
+ --tabs-inactive-border-size: var(
157
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_inactive_border-size
158
+ );
159
+ --tabs-border-radius: var(
160
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_border-radius
161
+ );
162
+ --tabs-hover-color: var(
163
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_hover-color
164
+ );
165
+ --tabs-hover-opacity: var(
166
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_hover-opacity
167
+ );
168
+ }
169
+
170
+ .root[data-variant="pills"][data-orientation="horizontal"] .list {
171
+ margin-bottom: var(
172
+ --recursica_ui-kit_components_tabs_variants_styles_pills_variants_orientation_horizontal_properties_tabs-content-gap
173
+ );
174
+ }
175
+
176
+ .root[data-variant="pills"][data-orientation="vertical"] .list {
177
+ margin-right: var(
178
+ --recursica_ui-kit_components_tabs_variants_styles_pills_variants_orientation_vertical_properties_tabs-content-gap
179
+ );
180
+ }
181
+
182
+ /* ---------------------------------
183
+ TAB ELEMENT
184
+ --------------------------------- */
185
+ .root .tab {
186
+ min-width: var(--recursica_ui-kit_components_tabs_properties_min-width);
187
+ max-width: var(--recursica_ui-kit_components_tabs_properties_max-width);
188
+ padding: var(--tabs-vertical-padding) var(--tabs-horizontal-padding);
189
+ gap: var(--tabs-element-gap);
190
+ display: flex;
191
+ align-items: center;
192
+ justify-content: var(--tabs-content-alignment);
193
+ cursor: pointer;
194
+ position: relative;
195
+
196
+ /* Typography (Inactive by default) */
197
+ font-family: var(
198
+ --recursica_ui-kit_components_tabs_properties_inactive-text_font-family
199
+ );
200
+ font-size: var(
201
+ --recursica_ui-kit_components_tabs_properties_inactive-text_font-size
202
+ );
203
+ font-style: var(
204
+ --recursica_ui-kit_components_tabs_properties_inactive-text_font-style
205
+ );
206
+ font-weight: var(
207
+ --recursica_ui-kit_components_tabs_properties_inactive-text_font-weight
208
+ );
209
+ letter-spacing: var(
210
+ --recursica_ui-kit_components_tabs_properties_inactive-text_letter-spacing
211
+ );
212
+ line-height: var(
213
+ --recursica_ui-kit_components_tabs_properties_inactive-text_line-height
214
+ );
215
+ text-decoration: var(
216
+ --recursica_ui-kit_components_tabs_properties_inactive-text_text-decoration
217
+ );
218
+ text-transform: var(
219
+ --recursica_ui-kit_components_tabs_properties_inactive-text_text-transform
220
+ );
221
+ }
222
+
223
+ /* Hover effect (moved to bottom for specificity, see end of file) */
224
+
225
+ .root .tab[data-active] {
226
+ font-family: var(
227
+ --recursica_ui-kit_components_tabs_properties_active-text_font-family
228
+ );
229
+ font-size: var(
230
+ --recursica_ui-kit_components_tabs_properties_active-text_font-size
231
+ );
232
+ font-style: var(
233
+ --recursica_ui-kit_components_tabs_properties_active-text_font-style
234
+ );
235
+ font-weight: var(
236
+ --recursica_ui-kit_components_tabs_properties_active-text_font-weight
237
+ );
238
+ letter-spacing: var(
239
+ --recursica_ui-kit_components_tabs_properties_active-text_letter-spacing
240
+ );
241
+ line-height: var(
242
+ --recursica_ui-kit_components_tabs_properties_active-text_line-height
243
+ );
244
+ text-decoration: var(
245
+ --recursica_ui-kit_components_tabs_properties_active-text_text-decoration
246
+ );
247
+ text-transform: var(
248
+ --recursica_ui-kit_components_tabs_properties_active-text_text-transform
249
+ );
250
+ }
251
+
252
+ /* Icon support */
253
+ .root .tab svg {
254
+ width: var(--tabs-icon-size);
255
+ height: var(--tabs-icon-size);
256
+ }
257
+
258
+ /* Disabled State */
259
+ .root .tab[data-disabled] {
260
+ opacity: var(--recursica_brand_states_disabled);
261
+ cursor: not-allowed;
262
+ }
263
+
264
+ /* ---------------------------------
265
+ COLORS
266
+ Because colors are defined per-layer and theme via generic variable structures,
267
+ we rely on Mantine injecting the correct data-variant attributes, but we must
268
+ map the colors in our CSS. Recursica handles dark/light automatically via root.
269
+ --------------------------------- */
270
+
271
+ /* ---------------------------------
272
+ BORDER RADIUS GEOMETRY
273
+ --------------------------------- */
274
+
275
+ /* Pills get full radius on all sides */
276
+ .root[data-variant="pills"] .tab {
277
+ border-radius: var(--tabs-border-radius);
278
+ }
279
+
280
+ /* Default & Outline Horizontal get top radius only so they sit flush on the panel */
281
+ .root[data-variant="default"][data-orientation="horizontal"]:not(
282
+ [data-inverted]
283
+ )
284
+ .tab,
285
+ .root[data-variant="outline"][data-orientation="horizontal"]:not(
286
+ [data-inverted]
287
+ )
288
+ .tab {
289
+ border-radius: var(--tabs-border-radius) var(--tabs-border-radius) 0 0;
290
+ }
291
+
292
+ /* Inverted horizontal tabs hang downwards, so bottom corners are rounded */
293
+ .root[data-variant="default"][data-orientation="horizontal"][data-inverted]
294
+ .tab,
295
+ .root[data-variant="outline"][data-orientation="horizontal"][data-inverted]
296
+ .tab {
297
+ border-radius: 0 0 var(--tabs-border-radius) var(--tabs-border-radius);
298
+ }
299
+
300
+ /* Default & Outline Vertical get left radius only so they sit flush against the right-side panel */
301
+ .root[data-variant="default"][data-orientation="vertical"] .tab,
302
+ .root[data-variant="outline"][data-orientation="vertical"] .tab {
303
+ border-radius: var(--tabs-border-radius) 0 0 var(--tabs-border-radius);
304
+ }
305
+
306
+ /* Default Variant Colors */
307
+ .root[data-variant="default"] .tab {
308
+ background-color: var(
309
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_inactive_colors_background
310
+ );
311
+ color: var(
312
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_inactive_colors_text-color
313
+ );
314
+ }
315
+ .root[data-variant="default"] .tab svg {
316
+ color: var(
317
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_inactive_colors_icon-color
318
+ );
319
+ }
320
+
321
+ .root[data-variant="default"] .tab[data-active] {
322
+ background-color: var(
323
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_active_colors_background
324
+ );
325
+ color: var(
326
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_active_colors_text-color
327
+ );
328
+ }
329
+ .root[data-variant="default"] .tab[data-active] svg {
330
+ color: var(
331
+ --recursica_ui-kit_components_tabs_variants_styles_default_properties_active_colors_icon-color
332
+ );
333
+ }
334
+
335
+ /* Outline Variant Colors */
336
+ .root[data-variant="outline"] .tab {
337
+ background-color: var(
338
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_inactive_colors_background
339
+ );
340
+ color: var(
341
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_inactive_colors_text-color
342
+ );
343
+ }
344
+ .root[data-variant="outline"] .tab svg {
345
+ color: var(
346
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_inactive_colors_icon-color
347
+ );
348
+ }
349
+
350
+ .root[data-variant="outline"] .tab[data-active] {
351
+ background-color: var(
352
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_active_colors_background
353
+ );
354
+ color: var(
355
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_active_colors_text-color
356
+ );
357
+ }
358
+ .root[data-variant="outline"] .tab[data-active] svg {
359
+ color: var(
360
+ --recursica_ui-kit_components_tabs_variants_styles_outline_properties_active_colors_icon-color
361
+ );
362
+ }
363
+
364
+ /* Pills Variant Colors */
365
+ .root[data-variant="pills"] .tab {
366
+ background-color: var(
367
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_inactive_colors_background
368
+ );
369
+ color: var(
370
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_inactive_colors_text-color
371
+ );
372
+ border: var(--tabs-inactive-border-size) solid
373
+ var(
374
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_inactive_colors_border-color
375
+ );
376
+ }
377
+ .root[data-variant="pills"] .tab svg {
378
+ color: var(
379
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_inactive_colors_icon-color
380
+ );
381
+ }
382
+
383
+ .root[data-variant="pills"] .tab[data-active] {
384
+ background-color: var(
385
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_active_colors_background
386
+ );
387
+ color: var(
388
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_active_colors_text-color
389
+ );
390
+ border: var(--tabs-active-border-size) solid
391
+ var(
392
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_active_colors_border-color
393
+ );
394
+ }
395
+ .root[data-variant="pills"] .tab[data-active] svg {
396
+ color: var(
397
+ --recursica_ui-kit_components_tabs_variants_styles_pills_properties_active_colors_icon-color
398
+ );
399
+ }
400
+
401
+ /* Content panel */
402
+ .root .panel {
403
+ /* Recursica doesn't define panel colors intrinsically, leaves it to child content */
404
+ }
405
+
406
+ /* Hover state uses a pseudo-element to apply opacity to the background without fading the text */
407
+ .root[data-variant] .tab:not([data-active]):hover::before {
408
+ content: "";
409
+ position: absolute;
410
+ inset: 0;
411
+ border-radius: inherit;
412
+ background-color: var(--tabs-hover-color);
413
+ opacity: var(--tabs-hover-opacity);
414
+ pointer-events: none;
415
+ z-index: 0;
416
+ }
417
+
418
+ /* Ensure tab content sits above the hover background */
419
+ .root .tab > * {
420
+ z-index: 1;
421
+ position: relative;
422
+ }
@@ -1,28 +1,31 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Tabs } from "./Tabs";
3
- import { ComingSoon } from "@recursica/storybook-template";
3
+ import { Flex } from "../Flex/Flex";
4
4
 
5
5
  const meta: Meta<typeof Tabs> = {
6
- title: "UI-Kit/🚧 Tabs",
6
+ title: "UI-Kit/Tabs",
7
7
  component: Tabs,
8
8
  tags: ["autodocs"],
9
9
  parameters: {
10
- controls: {
11
- include: [
12
- "layer",
13
- "withLayer",
14
- "children",
15
- "component",
16
- "variant",
17
- "size",
18
- "icon",
19
- "disabled",
20
- "href",
21
- "onClick",
22
- "onChange",
23
- "value",
24
- "checked",
25
- ],
10
+ layout: "centered",
11
+ },
12
+ argTypes: {
13
+ variant: {
14
+ control: "radio",
15
+ options: ["default", "outline", "pills"],
16
+ },
17
+ orientation: {
18
+ control: "radio",
19
+ options: ["horizontal", "vertical"],
20
+ },
21
+ // @ts-expect-error Custom prop not in native TabsProps
22
+ disabled: {
23
+ control: "boolean",
24
+ },
25
+ defaultChecked: {
26
+ table: {
27
+ disable: true,
28
+ },
26
29
  },
27
30
  },
28
31
  };
@@ -30,6 +33,122 @@ const meta: Meta<typeof Tabs> = {
30
33
  export default meta;
31
34
  type Story = StoryObj<typeof Tabs>;
32
35
 
36
+ const InteractiveTabs = (
37
+ args: React.ComponentProps<typeof Tabs> & { disabled?: boolean },
38
+ ) => {
39
+ return (
40
+ <Flex w={600} h={300}>
41
+ <Tabs defaultValue="gallery" {...args}>
42
+ <Tabs.List>
43
+ <Tabs.Tab
44
+ value="gallery"
45
+ disabled={args.disabled}
46
+ leftSection={
47
+ <svg
48
+ xmlns="http://www.w3.org/2000/svg"
49
+ viewBox="0 0 24 24"
50
+ fill="none"
51
+ stroke="currentColor"
52
+ strokeWidth="2"
53
+ strokeLinecap="round"
54
+ strokeLinejoin="round"
55
+ >
56
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
57
+ <circle cx="8.5" cy="8.5" r="1.5"></circle>
58
+ <polyline points="21 15 16 10 5 21"></polyline>
59
+ </svg>
60
+ }
61
+ >
62
+ Gallery
63
+ </Tabs.Tab>
64
+ <Tabs.Tab
65
+ value="messages"
66
+ disabled={args.disabled}
67
+ leftSection={
68
+ <svg
69
+ xmlns="http://www.w3.org/2000/svg"
70
+ viewBox="0 0 24 24"
71
+ fill="none"
72
+ stroke="currentColor"
73
+ strokeWidth="2"
74
+ strokeLinecap="round"
75
+ strokeLinejoin="round"
76
+ >
77
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
78
+ </svg>
79
+ }
80
+ >
81
+ Messages
82
+ </Tabs.Tab>
83
+ <Tabs.Tab
84
+ value="settings"
85
+ disabled={args.disabled}
86
+ leftSection={
87
+ <svg
88
+ xmlns="http://www.w3.org/2000/svg"
89
+ viewBox="0 0 24 24"
90
+ fill="none"
91
+ stroke="currentColor"
92
+ strokeWidth="2"
93
+ strokeLinecap="round"
94
+ strokeLinejoin="round"
95
+ >
96
+ <circle cx="12" cy="12" r="3"></circle>
97
+ <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
98
+ </svg>
99
+ }
100
+ >
101
+ Settings
102
+ </Tabs.Tab>
103
+ </Tabs.List>
104
+
105
+ <Tabs.Panel value="gallery">Gallery tab content</Tabs.Panel>
106
+
107
+ <Tabs.Panel value="messages">Messages tab content</Tabs.Panel>
108
+
109
+ <Tabs.Panel value="settings">Settings tab content</Tabs.Panel>
110
+ </Tabs>
111
+ </Flex>
112
+ );
113
+ };
114
+
33
115
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Tabs" />,
116
+ render: (args) => <InteractiveTabs {...args} />,
117
+ args: {
118
+ variant: "default",
119
+ orientation: "horizontal",
120
+ },
121
+ };
122
+
123
+ export const Outline: Story = {
124
+ render: (args) => <InteractiveTabs {...args} />,
125
+ args: {
126
+ variant: "outline",
127
+ orientation: "horizontal",
128
+ },
129
+ };
130
+
131
+ export const Pills: Story = {
132
+ render: (args) => <InteractiveTabs {...args} />,
133
+ args: {
134
+ variant: "pills",
135
+ orientation: "horizontal",
136
+ },
137
+ };
138
+
139
+ export const Vertical: Story = {
140
+ render: (args) => <InteractiveTabs {...args} />,
141
+ args: {
142
+ variant: "default",
143
+ orientation: "vertical",
144
+ },
145
+ };
146
+
147
+ export const Inverted: Story = {
148
+ render: (args) => <InteractiveTabs {...args} />,
149
+ args: {
150
+ variant: "default",
151
+ orientation: "horizontal",
152
+ inverted: true,
153
+ },
35
154
  };