@recursica/mantine-adapter 0.22.0 → 0.24.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 (137) hide show
  1. package/ARCHITECTURE.md +15 -0
  2. package/CHANGELOG.md +18 -0
  3. package/SETUP.md +78 -0
  4. package/USAGE.md +55 -0
  5. package/dist/mantine-adapter.cjs +1 -1
  6. package/dist/mantine-adapter.cjs.map +1 -1
  7. package/dist/mantine-adapter.css +1 -1
  8. package/dist/mantine-adapter.js +1897 -1575
  9. package/dist/mantine-adapter.js.map +1 -1
  10. package/dist/src/components/Accordion/Accordion.d.ts +4 -24
  11. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +1 -6
  12. package/dist/src/components/AutoComplete/AutoComplete.d.ts +7 -3
  13. package/dist/src/components/Avatar/Avatar.d.ts +2 -6
  14. package/dist/src/components/Badge/Badge.d.ts +2 -5
  15. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +1 -2
  16. package/dist/src/components/Button/Button.d.ts +2 -16
  17. package/dist/src/components/Card/Card.d.ts +4 -6
  18. package/dist/src/components/Checkbox/Checkbox.d.ts +4 -4
  19. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +7 -3
  20. package/dist/src/components/Chip/Chip.d.ts +1 -10
  21. package/dist/src/components/Container/Container.d.ts +1 -11
  22. package/dist/src/components/DatePicker/DatePicker.d.ts +12 -2
  23. package/dist/src/components/Dropdown/Dropdown.d.ts +2 -4
  24. package/dist/src/components/Flex/Flex.d.ts +2 -11
  25. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +2 -7
  26. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +1 -15
  27. package/dist/src/components/Group/Group.d.ts +1 -10
  28. package/dist/src/components/HoverCard/HoverCard.d.ts +1 -11
  29. package/dist/src/components/Label/Label.d.ts +1 -14
  30. package/dist/src/components/Link/Link.d.ts +2 -11
  31. package/dist/src/components/Loader/Loader.d.ts +2 -7
  32. package/dist/src/components/Menu/Menu.d.ts +4 -3
  33. package/dist/src/components/Modal/Modal.d.ts +2 -1
  34. package/dist/src/components/NumberInput/NumberInput.d.ts +2 -4
  35. package/dist/src/components/Pagination/Pagination.d.ts +2 -4
  36. package/dist/src/components/Panel/Panel.d.ts +2 -9
  37. package/dist/src/components/Popover/Popover.d.ts +1 -11
  38. package/dist/src/components/Radio/Radio.d.ts +4 -4
  39. package/dist/src/components/Radio/RadioGroup.d.ts +7 -3
  40. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +2 -10
  41. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +1 -11
  42. package/dist/src/components/Slider/Slider.d.ts +18 -2
  43. package/dist/src/components/Stack/Stack.d.ts +2 -9
  44. package/dist/src/components/Stepper/Stepper.d.ts +2 -4
  45. package/dist/src/components/Switch/Switch.d.ts +4 -4
  46. package/dist/src/components/Switch/SwitchGroup.d.ts +7 -3
  47. package/dist/src/components/Table/Table.d.ts +2 -1
  48. package/dist/src/components/Tabs/Tabs.d.ts +2 -4
  49. package/dist/src/components/Text/Text.d.ts +2 -11
  50. package/dist/src/components/TextArea/TextArea.d.ts +2 -8
  51. package/dist/src/components/TextField/TextField.d.ts +7 -3
  52. package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
  53. package/dist/src/components/Timeline/Timeline.d.ts +2 -1
  54. package/dist/src/components/Timeline/TimelineItem.d.ts +1 -12
  55. package/dist/src/components/Title/Title.d.ts +1 -7
  56. package/dist/src/components/Toast/Toast.d.ts +1 -12
  57. package/dist/src/components/Tooltip/Tooltip.d.ts +1 -12
  58. package/dist/src/components/TransferList/TransferList.d.ts +2 -1
  59. package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
  60. package/dist/src/utils/filterStylingProps.d.ts +1 -11
  61. package/dist/test.html +1 -0
  62. package/llms.txt +16 -0
  63. package/package.json +7 -3
  64. package/src/components/Accordion/Accordion.module.css +1 -2
  65. package/src/components/Accordion/Accordion.tsx +15 -28
  66. package/src/components/AssistiveElement/AssistiveElement.tsx +1 -6
  67. package/src/components/AutoComplete/AutoComplete.tsx +4 -1
  68. package/src/components/Avatar/Avatar.tsx +1 -5
  69. package/src/components/Badge/Badge.tsx +1 -4
  70. package/src/components/Breadcrumb/Breadcrumb.tsx +1 -2
  71. package/src/components/Button/Button.module.css +18 -45
  72. package/src/components/Button/Button.tsx +2 -16
  73. package/src/components/Card/Card.tsx +11 -6
  74. package/src/components/Checkbox/Checkbox.module.css +6 -10
  75. package/src/components/Checkbox/Checkbox.tsx +19 -14
  76. package/src/components/Checkbox/CheckboxGroup.tsx +4 -1
  77. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +4 -1
  78. package/src/components/Chip/Chip.module.css +36 -28
  79. package/src/components/Chip/Chip.tsx +8 -15
  80. package/src/components/Container/Container.tsx +1 -19
  81. package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +16 -0
  82. package/src/components/DatePicker/DatePicker.module.css +282 -41
  83. package/src/components/DatePicker/DatePicker.stories.tsx +127 -4
  84. package/src/components/DatePicker/DatePicker.tsx +169 -5
  85. package/src/components/Dropdown/Dropdown.tsx +4 -4
  86. package/src/components/Flex/Flex.tsx +2 -13
  87. package/src/components/FormControlLayout/FormControlLayout.module.css +6 -18
  88. package/src/components/FormControlLayout/FormControlLayout.tsx +4 -8
  89. package/src/components/FormControlWrapper/FormControlWrapper.module.css +1 -0
  90. package/src/components/FormControlWrapper/FormControlWrapper.tsx +2 -15
  91. package/src/components/Group/Group.tsx +2 -13
  92. package/src/components/HoverCard/HoverCard.tsx +1 -8
  93. package/src/components/Label/Label.module.css +5 -10
  94. package/src/components/Label/Label.tsx +1 -14
  95. package/src/components/Link/Link.module.css +4 -3
  96. package/src/components/Link/Link.stories.tsx +2 -3
  97. package/src/components/Link/Link.tsx +1 -10
  98. package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +1 -2
  99. package/src/components/Loader/Loader.module.css +4 -11
  100. package/src/components/Loader/Loader.tsx +1 -7
  101. package/src/components/Menu/Menu.tsx +5 -1
  102. package/src/components/Modal/Modal.tsx +3 -1
  103. package/src/components/NumberInput/NumberInput.tsx +4 -4
  104. package/src/components/Pagination/Pagination.module.css +12 -24
  105. package/src/components/Pagination/Pagination.stories.tsx +0 -8
  106. package/src/components/Pagination/Pagination.tsx +5 -4
  107. package/src/components/Panel/Panel.tsx +1 -8
  108. package/src/components/Popover/Popover.tsx +1 -8
  109. package/src/components/Radio/Radio.module.css +4 -10
  110. package/src/components/Radio/Radio.tsx +19 -14
  111. package/src/components/Radio/RadioGroup.tsx +4 -1
  112. package/src/components/ReadOnlyField/ReadOnlyField.module.css +9 -18
  113. package/src/components/ReadOnlyField/ReadOnlyField.tsx +4 -11
  114. package/src/components/SegmentedControl/SegmentedControl.module.css +20 -44
  115. package/src/components/SegmentedControl/SegmentedControl.tsx +1 -11
  116. package/src/components/Slider/IMPLEMENTATION_NOTES.md +49 -0
  117. package/src/components/Slider/Slider.module.css +492 -86
  118. package/src/components/Slider/Slider.stories.tsx +159 -4
  119. package/src/components/Slider/Slider.tsx +275 -4
  120. package/src/components/Stack/Stack.tsx +2 -11
  121. package/src/components/Stepper/Stepper.tsx +1 -7
  122. package/src/components/Switch/Switch.tsx +19 -11
  123. package/src/components/Switch/SwitchGroup.tsx +4 -1
  124. package/src/components/Table/Table.tsx +3 -1
  125. package/src/components/Tabs/Tabs.tsx +1 -7
  126. package/src/components/Text/Text.tsx +2 -16
  127. package/src/components/TextArea/TextArea.tsx +4 -8
  128. package/src/components/TextField/TextField.tsx +4 -1
  129. package/src/components/TimePicker/TimePicker.tsx +3 -1
  130. package/src/components/Timeline/Timeline.tsx +4 -1
  131. package/src/components/Timeline/TimelineItem.tsx +1 -12
  132. package/src/components/Title/Title.tsx +1 -6
  133. package/src/components/Toast/Toast.tsx +1 -13
  134. package/src/components/Tooltip/Tooltip.tsx +1 -9
  135. package/src/components/TransferList/TransferList.tsx +3 -1
  136. package/src/utils/RequireAccessibleLabel.ts +1 -12
  137. package/src/utils/filterStylingProps.ts +7 -20
@@ -0,0 +1,16 @@
1
+ # DatePicker Implementation Notes
2
+
3
+ ## Architecture Overview
4
+
5
+ The `DatePicker` component is a wrapper around the `@mantine/dates` `DatePickerInput` component, implementing the `FormControlWrapper` macro structure for Recursica. This ensures that the component visually and structurally aligns with standard Recursica input primitives.
6
+
7
+ ## Structural Constraints
8
+
9
+ 1. **Naked Input Usage**: We intentionally pass `label={undefined}`, `description={undefined}`, and `error={undefined}` to the Mantine `DatePickerInput` component. This suppresses Mantine's internal macro form wrapping and ensures that only our `WithReadOnlyWrapper` > `FormControlWrapper` orchestrates labels, description text, and ARIA state error boundaries.
10
+ 2. **Read-Only Implementation**: Since the value type for `DatePickerInput` can be a date object, string, or array, the `WithReadOnlyWrapper` attempts to safely cast the output value using standard `String(value)`. For production apps utilizing heavy date formatting logic, developers can pass a custom `readOnlyComponent` explicitly to bypass this default cast.
11
+ 3. **Calendar Portal/Dropdown (Figma Token Issue)**: The Recursica UI Kit's `date-picker` component in Figma fails to export any explicit structural or color properties for the calendar popover itself (e.g. elevation, surface background, selected day colors). To solve this organically within the framework without breaking strict token adherence, we manually override the Mantine `.dropdown` and `.day[data-selected]` classes using `--recursica_ui-kit_components_hover-card-popover` tokens for elevation/padding/surfaces, and `--recursica_ui-kit_components_button_variants_styles_solid` tokens for the selected primary blue day. This guarantees strict visual adherence to the system until explicitly mapped tokens are provided in the UI Kit.
12
+
13
+ ## Styling Quirks
14
+
15
+ - The `DatePickerInput` mimics Mantine's `Input` structure natively (`.input`, `.wrapper`, `.section`). We attach our `styles.input` and `styles.root` classes exactly like `TextField`.
16
+ - The global layout margin override (`.layoutOverride`) utilizes `--form-control-margin-bottom` driven by specific stacked/side-by-side design tokens.
@@ -1,45 +1,286 @@
1
- /*
2
- * EXEMPTIONS:
3
- * - DatePicker is a "Coming Soon" stub component.
4
- * - It renders a placeholder and has no active implementation or CSS stylesheet yet.
5
- * - The following tokens generated by Figma are ignored until the component is fully built.
6
- */
7
-
8
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_border-radius */
9
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_horizontal-padding */
10
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_icon-size */
11
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_icon-text-gap */
12
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_min-height */
13
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_placeholder-opacity */
14
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_font-family */
15
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_font-size */
16
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_font-style */
17
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_font-weight */
18
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_letter-spacing */
19
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_line-height */
20
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_text-decoration */
21
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_text_text-transform */
22
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_vertical-padding */
23
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_properties_width */
24
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_layouts_side-by-side_properties_top-bottom-margin */
25
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_layouts_stacked_properties_top-bottom-margin */
1
+ /* EXEMPTIONS:
2
+ - state-specific border-size variables are ignored because a uniform 1px border is applied globally to prevent
3
+ unexpected layout shift or flickering during focus, disabled, or error state transitions. */
26
4
  /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_default_properties_border-size */
27
5
  /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_border-size */
28
6
  /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_error_properties_border-size */
29
7
  /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_focus_properties_border-size */
30
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_background */
31
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_border-color */
32
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_leading-icon */
33
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_text */
34
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_background */
35
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_border-color */
36
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_leading-icon */
37
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_text */
38
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_background */
39
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_border-color */
40
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_leading-icon */
41
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_text */
42
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_background */
43
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_border-color */
44
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_leading-icon */
45
- /* recursica-ignore: --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_text */
8
+
9
+ /* LAYOUT SPACING OVERRIDES:
10
+ - Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens. */
11
+ .layoutOverride {
12
+ --form-control-margin-bottom: var(
13
+ --recursica_ui-kit_components_date-picker_variants_layouts_stacked_properties_top-bottom-margin
14
+ );
15
+ }
16
+
17
+ .layoutOverride[data-form-layout="side-by-side"] {
18
+ --form-control-margin-bottom: var(
19
+ --recursica_ui-kit_components_date-picker_variants_layouts_side-by-side_properties_top-bottom-margin
20
+ );
21
+ }
22
+
23
+ /* HARDCODED VALUES:
24
+ - border-width: 1px. Native geometric boundary for the input box.
25
+ - border-style: solid. Native structural rendering rule.
26
+ - outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
27
+ - flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
28
+ */
29
+
30
+ .root {
31
+ display: flex;
32
+ position: relative;
33
+ width: var(--recursica_ui-kit_components_date-picker_properties_width);
34
+ min-height: var(
35
+ --recursica_ui-kit_components_date-picker_properties_min-height
36
+ );
37
+
38
+ /* Override Mantine native Input variables governing section spacing padding mathematics safely */
39
+ --input-left-section-size: calc(
40
+ var(
41
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
42
+ ) +
43
+ var(--recursica_ui-kit_components_date-picker_properties_icon-size) +
44
+ var(--recursica_ui-kit_components_date-picker_properties_icon-text-gap)
45
+ );
46
+ --input-right-section-size: calc(
47
+ var(
48
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
49
+ ) +
50
+ var(--recursica_ui-kit_components_date-picker_properties_icon-size) +
51
+ var(--recursica_ui-kit_components_date-picker_properties_icon-text-gap)
52
+ );
53
+ }
54
+
55
+ .input {
56
+ /* Structural Overrides */
57
+ width: 100%;
58
+ box-sizing: border-box;
59
+ margin: 0;
60
+
61
+ /* Box Geometry */
62
+ min-height: var(
63
+ --recursica_ui-kit_components_date-picker_properties_min-height
64
+ );
65
+ padding-top: var(
66
+ --recursica_ui-kit_components_date-picker_properties_vertical-padding
67
+ );
68
+ padding-bottom: var(
69
+ --recursica_ui-kit_components_date-picker_properties_vertical-padding
70
+ );
71
+ padding-left: var(
72
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
73
+ );
74
+ padding-right: var(
75
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
76
+ );
77
+ border-radius: var(
78
+ --recursica_ui-kit_components_date-picker_properties_border-radius
79
+ );
80
+ border-width: 1px;
81
+ border-style: solid;
82
+
83
+ /* Strict Typography Unification */
84
+ font-family: var(
85
+ --recursica_ui-kit_components_date-picker_properties_text_font-family
86
+ );
87
+ font-size: var(
88
+ --recursica_ui-kit_components_date-picker_properties_text_font-size
89
+ );
90
+ font-style: var(
91
+ --recursica_ui-kit_components_date-picker_properties_text_font-style
92
+ );
93
+ font-weight: var(
94
+ --recursica_ui-kit_components_date-picker_properties_text_font-weight
95
+ );
96
+ letter-spacing: var(
97
+ --recursica_ui-kit_components_date-picker_properties_text_letter-spacing
98
+ );
99
+ line-height: var(
100
+ --recursica_ui-kit_components_date-picker_properties_text_line-height
101
+ );
102
+ text-decoration: var(
103
+ --recursica_ui-kit_components_date-picker_properties_text_text-decoration
104
+ );
105
+ text-transform: var(
106
+ --recursica_ui-kit_components_date-picker_properties_text_text-transform
107
+ );
108
+
109
+ /* Base State Default Execution */
110
+ background-color: var(
111
+ --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_background
112
+ );
113
+ border-color: var(
114
+ --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_border-color
115
+ );
116
+ color: var(
117
+ --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_text
118
+ );
119
+
120
+ outline: none;
121
+ }
122
+
123
+ .input::placeholder {
124
+ opacity: var(
125
+ --recursica_ui-kit_components_date-picker_properties_placeholder-opacity
126
+ );
127
+ color: inherit;
128
+ }
129
+
130
+ /* Dynamic Padding Overrides */
131
+ .root[data-with-left-section] .input {
132
+ padding-left: var(--input-left-section-size);
133
+ }
134
+
135
+ .root[data-with-right-section] .input {
136
+ padding-right: var(--input-right-section-size);
137
+ }
138
+
139
+ /* Flexible End-Caps (Icons, actions) */
140
+ .section {
141
+ display: flex;
142
+ align-items: center;
143
+ height: 100%;
144
+ }
145
+
146
+ .section[data-position="left"] {
147
+ justify-content: flex-start;
148
+ padding-left: var(
149
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
150
+ );
151
+ }
152
+
153
+ .section[data-position="right"] {
154
+ justify-content: flex-end;
155
+ padding-right: var(
156
+ --recursica_ui-kit_components_date-picker_properties_horizontal-padding
157
+ );
158
+ }
159
+
160
+ .section :global(svg) {
161
+ width: var(--recursica_ui-kit_components_date-picker_properties_icon-size);
162
+ height: var(--recursica_ui-kit_components_date-picker_properties_icon-size);
163
+ color: var(
164
+ --recursica_ui-kit_components_date-picker_variants_states_default_properties_colors_leading-icon
165
+ );
166
+ }
167
+
168
+ /* -------------------------------------
169
+ STATE CASCADE ARCHITECTURE
170
+ -------------------------------------- */
171
+
172
+ /* Focus State Mapping (Triggered internally via browser pseudo-pseudo-class) */
173
+ .input:focus-within,
174
+ .input:focus {
175
+ border-color: var(
176
+ --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_border-color
177
+ );
178
+ background-color: var(
179
+ --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_background
180
+ );
181
+ color: var(
182
+ --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_text
183
+ );
184
+ }
185
+
186
+ .root:focus-within .section[data-position="left"] :global(svg) {
187
+ color: var(
188
+ --recursica_ui-kit_components_date-picker_variants_states_focus_properties_colors_leading-icon
189
+ );
190
+ }
191
+
192
+ /* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
193
+ .root[data-error] .input {
194
+ border-color: var(
195
+ --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_border-color
196
+ ) !important;
197
+ background-color: var(
198
+ --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_background
199
+ ) !important;
200
+ color: var(
201
+ --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_text
202
+ ) !important;
203
+ }
204
+
205
+ .root[data-error] .section[data-position="left"] :global(svg) {
206
+ color: var(
207
+ --recursica_ui-kit_components_date-picker_variants_states_error_properties_colors_leading-icon
208
+ ) !important;
209
+ }
210
+
211
+ /* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
212
+ .root[data-disabled] .input {
213
+ border-color: var(
214
+ --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_border-color
215
+ ) !important;
216
+ background-color: var(
217
+ --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_background
218
+ ) !important;
219
+ color: var(
220
+ --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_text
221
+ ) !important;
222
+ cursor: not-allowed;
223
+ }
224
+
225
+ .root[data-disabled] .section[data-position="left"] :global(svg) {
226
+ color: var(
227
+ --recursica_ui-kit_components_date-picker_variants_states_disabled_properties_colors_leading-icon
228
+ ) !important;
229
+ }
230
+
231
+ /* =========================================
232
+ CALENDAR POPOVER OVERRIDES
233
+ Maps generic popover & solid button tokens
234
+ to enforce Recursica's global styling.
235
+ ========================================= */
236
+
237
+ .dropdown {
238
+ background-color: var(
239
+ --recursica_ui-kit_components_hover-card-popover_properties_colors_background
240
+ );
241
+ border: var(
242
+ --recursica_ui-kit_components_hover-card-popover_properties_border-size
243
+ )
244
+ solid
245
+ var(
246
+ --recursica_ui-kit_components_hover-card-popover_properties_colors_border-color
247
+ );
248
+ border-radius: var(
249
+ --recursica_ui-kit_components_hover-card-popover_properties_border-radius
250
+ );
251
+ box-shadow: var(
252
+ --recursica_ui-kit_components_hover-card-popover_properties_elevation
253
+ );
254
+ padding: var(
255
+ --recursica_ui-kit_components_hover-card-popover_properties_vertical-padding
256
+ )
257
+ var(
258
+ --recursica_ui-kit_components_hover-card-popover_properties_horizontal-padding
259
+ );
260
+ font-family: var(
261
+ --recursica_ui-kit_components_hover-card-popover_properties_content-text_font-family
262
+ );
263
+ }
264
+
265
+ .calendarHeader {
266
+ color: var(
267
+ --recursica_ui-kit_components_hover-card-popover_properties_colors_content
268
+ );
269
+ }
270
+
271
+ .day {
272
+ color: var(
273
+ --recursica_ui-kit_components_hover-card-popover_properties_colors_content
274
+ );
275
+ border-radius: var(--recursica_brand_dimensions_border-radii_default);
276
+ }
277
+
278
+ .day[data-selected],
279
+ .day[data-selected]:hover {
280
+ background-color: var(
281
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_background
282
+ );
283
+ color: var(
284
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text
285
+ );
286
+ }
@@ -1,12 +1,61 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { DatePicker } from "./DatePicker";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
4
5
 
5
6
  const meta: Meta<typeof DatePicker> = {
6
- title: "UI-Kit/🚧 DatePicker",
7
+ title: "UI-Kit/DatePicker",
7
8
  component: DatePicker,
8
9
  tags: ["autodocs"],
9
- argTypes: {},
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component: `
14
+ The \`DatePicker\` primitive provides a unified calendar date selection input integrated directly into the \`FormControlWrapper\` architecture.
15
+
16
+ ### Architectural Decoupling
17
+ Recursica overrides the internal Mantine \`DatePickerInput\` wrapper 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.
18
+
19
+ ### Examples
20
+ Always structure horizontal architectures via the generic \`formLayout\` parameter.
21
+ \`\`\`tsx
22
+ <DatePicker
23
+ label="Start Date"
24
+ assistiveText="Select the deployment kick-off date."
25
+ formLayout="stacked"
26
+ />
27
+ \`\`\`
28
+ `,
29
+ },
30
+ },
31
+ },
32
+ argTypes: {
33
+ ...formControlArgTypes,
34
+ disabled: {
35
+ control: "boolean",
36
+ description:
37
+ "Maps the formal disabled variable states structurally to the input core.",
38
+ },
39
+ error: {
40
+ control: "text",
41
+ description:
42
+ "Applies the strict error string boundary rendering invalid structures seamlessly.",
43
+ },
44
+ required: {
45
+ control: "boolean",
46
+ },
47
+ label: {
48
+ control: "text",
49
+ },
50
+ assistiveText: {
51
+ control: "text",
52
+ },
53
+ readOnly: {
54
+ control: "boolean",
55
+ description:
56
+ "Toggles structural read-only data presentation explicitly blocking standard component bindings.",
57
+ },
58
+ },
10
59
  };
11
60
 
12
61
  export default meta;
@@ -14,5 +63,79 @@ export default meta;
14
63
  type Story = StoryObj<typeof DatePicker>;
15
64
 
16
65
  export const Default: Story = {
17
- render: () => <ComingSoon componentName="DatePicker" />,
66
+ args: {
67
+ disabled: false,
68
+ label: "Project Deadline",
69
+ placeholder: "Select a deadline...",
70
+ assistiveText: "Specify the absolute cutoff for code submission.",
71
+ },
72
+ };
73
+
74
+ export const FormsSideBySide: Story = {
75
+ args: {
76
+ label: "Incident Start Date",
77
+ placeholder: "Pick date...",
78
+ assistiveText: "When did the incident originally occur?",
79
+ formLayout: "side-by-side",
80
+ },
81
+ };
82
+
83
+ export const WithLeadingIcon: Story = {
84
+ args: {
85
+ label: "Launch Date",
86
+ placeholder: "Select launch date...",
87
+ leftSection: (
88
+ <svg
89
+ width="24"
90
+ height="24"
91
+ viewBox="0 0 24 24"
92
+ fill="none"
93
+ stroke="currentColor"
94
+ strokeWidth="2"
95
+ strokeLinecap="round"
96
+ strokeLinejoin="round"
97
+ >
98
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
99
+ <line x1="16" y1="2" x2="16" y2="6"></line>
100
+ <line x1="8" y1="2" x2="8" y2="6"></line>
101
+ <line x1="3" y1="10" x2="21" y2="10"></line>
102
+ </svg>
103
+ ),
104
+ },
105
+ };
106
+
107
+ export const Disabled: Story = {
108
+ args: {
109
+ label: "Disabled Date Range",
110
+ placeholder: "Disabled selection...",
111
+ disabled: true,
112
+ },
113
+ };
114
+
115
+ export const ErrorState: Story = {
116
+ args: {
117
+ label: "Execution Date",
118
+ placeholder: "Pick a valid date...",
119
+ error: "The chosen date conflicts with an existing deployment freeze.",
120
+ required: true,
121
+ },
122
+ };
123
+
124
+ export const StaticReadOnly: Story = {
125
+ args: {
126
+ label: "Static ReadOnly Review",
127
+ placeholder: "Ignored...",
128
+ value: new Date("2026-05-21"),
129
+ readOnly: true,
130
+ },
131
+ };
132
+
133
+ export const EditableReadOnly: Story = {
134
+ args: {
135
+ label: "Editable ReadOnly Review",
136
+ placeholder: "Ignored until active...",
137
+ defaultValue: new Date("2026-06-01"),
138
+ readOnly: true,
139
+ labelWithEditIcon: true,
140
+ },
18
141
  };
@@ -1,7 +1,171 @@
1
- import React from "react";
1
+ import React, { forwardRef } from "react";
2
+ import { DatePickerInput, type DatePickerInputProps } from "@mantine/dates";
3
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
4
+ import {
5
+ filterStylingProps,
6
+ type RecursicaOverStyled,
7
+ } from "../../utils/filterStylingProps";
8
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
9
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
10
+ import styles from "./DatePicker.module.css";
2
11
 
3
- export type DatePickerProps = React.HTMLAttributes<HTMLDivElement>;
12
+ import { type RecursicaDatePickerProps as BaseRecursicaDatePickerProps } from "@recursica/adapter-common";
4
13
 
5
- export const DatePicker: React.FC<DatePickerProps> = (props) => {
6
- return <div {...props}>DatePicker</div>;
7
- };
14
+ export interface RecursicaDatePickerProps
15
+ extends Omit<
16
+ DatePickerInputProps,
17
+ | "size"
18
+ | "variant"
19
+ | "radius"
20
+ | "wrapperProps"
21
+ | "label"
22
+ | "error"
23
+ | "required"
24
+ | "withAsterisk"
25
+ | "id"
26
+ | "description"
27
+ >,
28
+ Pick<
29
+ DatePickerInputProps,
30
+ "label" | "error" | "required" | "withAsterisk" | "id"
31
+ >,
32
+ Omit<
33
+ RecursicaFormControlWrapperProps,
34
+ "controlMaxWidth" | "controlMinWidth"
35
+ >,
36
+ ReadOnlyControlProps,
37
+ BaseRecursicaDatePickerProps {}
38
+
39
+ export type DatePickerProps = RecursicaOverStyled<RecursicaDatePickerProps>;
40
+
41
+ export const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(
42
+ function DatePicker(props, ref) {
43
+ const {
44
+ overStyled = false,
45
+ formLayout = "stacked",
46
+
47
+ // Label & Wrapper Maps
48
+ labelSize,
49
+ labelAlignment,
50
+ labelOptionalText,
51
+ labelWithEditIcon,
52
+ onLabelEditClick,
53
+
54
+ label,
55
+ assistiveText,
56
+ assistiveWithIcon,
57
+ error,
58
+ required,
59
+ withAsterisk,
60
+ id,
61
+ className,
62
+ style,
63
+ disabled,
64
+ readOnly,
65
+ readOnlyComponent,
66
+ emptyValueComponent,
67
+ value,
68
+ defaultValue,
69
+ ...rest
70
+ } = props;
71
+
72
+ const sanitizedProps = filterStylingProps(rest, overStyled);
73
+ const restRecord = sanitizedProps as Record<string, unknown>;
74
+
75
+ // Delete prohibited sizing hooks from bypassing variables natively
76
+ delete restRecord["size"];
77
+ delete restRecord["variant"];
78
+ delete restRecord["radius"];
79
+ delete restRecord["description"]; // Managed by FormControlWrapper via assistiveText
80
+
81
+ // Securely map core native blocks down ensuring nested CSS modules map precisely
82
+ const mergedClassNames: Partial<Record<string, string>> = {
83
+ wrapper: styles.root, // The nested Input internal relative wrapper bounding box
84
+ input: styles.input,
85
+ section: styles.section,
86
+ dropdown: styles.dropdown,
87
+ day: styles.day,
88
+ calendarHeader: styles.calendarHeader,
89
+ };
90
+
91
+ const classNamesProp = restRecord.classNames;
92
+ if (
93
+ classNamesProp &&
94
+ typeof classNamesProp === "object" &&
95
+ !Array.isArray(classNamesProp)
96
+ ) {
97
+ const o = classNamesProp as Partial<Record<string, string>>;
98
+ mergedClassNames.wrapper = o.wrapper
99
+ ? `${styles.root} ${o.wrapper}`
100
+ : styles.root;
101
+ mergedClassNames.input = o.input
102
+ ? `${styles.input} ${o.input}`
103
+ : styles.input;
104
+ mergedClassNames.section = o.section
105
+ ? `${styles.section} ${o.section}`
106
+ : styles.section;
107
+ }
108
+
109
+ const wrapperClass = className
110
+ ? `${styles.layoutOverride} ${className}`
111
+ : styles.layoutOverride;
112
+
113
+ return (
114
+ <WithReadOnlyWrapper
115
+ className={wrapperClass}
116
+ style={style as React.CSSProperties}
117
+ controlMaxWidth={undefined}
118
+ controlMinWidth={undefined}
119
+ overStyled={overStyled as true}
120
+ formLayout={formLayout}
121
+ labelSize={labelSize}
122
+ labelAlignment={labelAlignment}
123
+ labelOptionalText={labelOptionalText}
124
+ labelWithEditIcon={labelWithEditIcon}
125
+ onLabelEditClick={onLabelEditClick}
126
+ label={label}
127
+ assistiveText={assistiveText}
128
+ assistiveWithIcon={assistiveWithIcon}
129
+ error={error}
130
+ required={required}
131
+ withAsterisk={withAsterisk}
132
+ id={id}
133
+ readOnly={readOnly}
134
+ readOnlyComponent={readOnlyComponent}
135
+ emptyValueComponent={emptyValueComponent}
136
+ readOnlyType="text"
137
+ readOnlyValue={
138
+ value !== undefined
139
+ ? String(value)
140
+ : defaultValue
141
+ ? String(defaultValue)
142
+ : undefined
143
+ }
144
+ readOnlyNativeProps={props}
145
+ activeComponent={
146
+ /* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
147
+ <DatePickerInput
148
+ ref={ref}
149
+ classNames={mergedClassNames}
150
+ disabled={disabled}
151
+ // @ts-expect-error Mantine 8 DatePickerInput types are overly complex for unified wrappers
152
+ value={value}
153
+ // @ts-expect-error Mantine 8 DatePickerInput types are overly complex for unified wrappers
154
+ defaultValue={defaultValue}
155
+ label={undefined} // Disable Mantine's native label
156
+ description={undefined} // Disable Mantine's native description
157
+ error={undefined} // Disable Mantine's native error text (handled by wrapper)
158
+ withAsterisk={false} // Handled by wrapper
159
+ wrapperProps={{
160
+ "data-disabled": disabled ? "true" : undefined,
161
+ "data-error": error ? "true" : undefined,
162
+ }}
163
+ {...(sanitizedProps as unknown as DatePickerInputProps)}
164
+ />
165
+ }
166
+ />
167
+ );
168
+ },
169
+ );
170
+
171
+ DatePicker.displayName = "DatePicker";
@@ -12,6 +12,8 @@ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/For
12
12
  import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
13
13
  import styles from "./Dropdown.module.css";
14
14
 
15
+ import { type RecursicaDropdownProps as BaseRecursicaDropdownProps } from "@recursica/adapter-common";
16
+
15
17
  export interface RecursicaDropdownProps
16
18
  extends Omit<
17
19
  MantineSelectProps,
@@ -28,10 +30,8 @@ export interface RecursicaDropdownProps
28
30
  | "labelWithEditIcon"
29
31
  | "onLabelEditClick"
30
32
  >,
31
- ReadOnlyControlProps {
32
- /** Internal hook for Selects to override raw layout width properties when necessary */
33
- containerWidth?: React.CSSProperties["width"];
34
- }
33
+ ReadOnlyControlProps,
34
+ BaseRecursicaDropdownProps {}
35
35
 
36
36
  export type DropdownProps = RecursicaOverStyled<RecursicaDropdownProps>;
37
37