@recursica/adapter-mantine-v8 1.0.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.
- package/.storybook/commonArgTypes.ts +148 -0
- package/ARCHITECTURE.md +18 -0
- package/CHANGELOG.md +688 -0
- package/LICENSE +21 -0
- package/OVERSTYLING.md +56 -0
- package/README.md +70 -0
- package/SETUP.md +93 -0
- package/USAGE.md +57 -0
- package/dist/adapter-mantine-v8.cjs +12 -0
- package/dist/adapter-mantine-v8.cjs.map +1 -0
- package/dist/adapter-mantine-v8.css +1 -0
- package/dist/adapter-mantine-v8.js +5759 -0
- package/dist/adapter-mantine-v8.js.map +1 -0
- package/dist/index.d.ts +2095 -0
- package/dist/test.html +1 -0
- package/dist/vite.svg +1 -0
- package/docs/PHILOSOPHY.md +39 -0
- package/llms.txt +74 -0
- package/package.json +131 -0
- package/recursica_brand.json +2677 -0
- package/recursica_tokens.json +799 -0
- package/recursica_ui-kit.json +14981 -0
- package/recursica_variables_scoped.css +30489 -0
- package/src/GlobalExemptions.modules.css +7 -0
- package/src/Introduction.stories.tsx +154 -0
- package/src/OverStyling.tsx +79 -0
- package/src/Version.tsx +44 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +72 -0
- package/src/components/Accordion/Accordion.module.css +367 -0
- package/src/components/Accordion/Accordion.stories.tsx +189 -0
- package/src/components/Accordion/Accordion.test.tsx +1 -0
- package/src/components/Accordion/Accordion.tsx +220 -0
- package/src/components/Accordion/USAGE.md +51 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +68 -0
- package/src/components/AssistiveElement/AssistiveElement.test.tsx +1 -0
- package/src/components/AssistiveElement/AssistiveElement.tsx +93 -0
- package/src/components/AssistiveElement/USAGE.md +36 -0
- package/src/components/AutoComplete/AUTOCOMPLETE_IMPLEMENTATION_NOTES.md +42 -0
- package/src/components/AutoComplete/AutoComplete.module.css +430 -0
- package/src/components/AutoComplete/AutoComplete.stories.tsx +336 -0
- package/src/components/AutoComplete/AutoComplete.test.tsx +1 -0
- package/src/components/AutoComplete/AutoComplete.tsx +179 -0
- package/src/components/AutoComplete/USAGE.md +80 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +34 -0
- package/src/components/Avatar/Avatar.module.css +336 -0
- package/src/components/Avatar/Avatar.stories.tsx +92 -0
- package/src/components/Avatar/Avatar.test.tsx +1 -0
- package/src/components/Avatar/Avatar.tsx +108 -0
- package/src/components/Avatar/USAGE.md +38 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Badge/Badge.module.css +127 -0
- package/src/components/Badge/Badge.stories.tsx +78 -0
- package/src/components/Badge/Badge.test.tsx +1 -0
- package/src/components/Badge/Badge.tsx +64 -0
- package/src/components/Badge/USAGE.md +56 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +47 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +48 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +114 -0
- package/src/components/Breadcrumb/Breadcrumb.test.tsx +1 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +85 -0
- package/src/components/Breadcrumb/USAGE.md +55 -0
- package/src/components/Breadcrumb/markCurrentPageItem.test.ts +49 -0
- package/src/components/Button/Button.module.css +446 -0
- package/src/components/Button/Button.stories.tsx +196 -0
- package/src/components/Button/Button.styleIsolation.dom.test.tsx +98 -0
- package/src/components/Button/Button.tsx +184 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +109 -0
- package/src/components/Button/USAGE.md +80 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +17 -0
- package/src/components/Card/Card.module.css +119 -0
- package/src/components/Card/Card.stories.tsx +131 -0
- package/src/components/Card/Card.test.tsx +1 -0
- package/src/components/Card/Card.tsx +248 -0
- package/src/components/Card/USAGE.md +63 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +267 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +97 -0
- package/src/components/Checkbox/Checkbox.test.tsx +1 -0
- package/src/components/Checkbox/Checkbox.tsx +151 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +147 -0
- package/src/components/Checkbox/USAGE.md +48 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +110 -0
- package/src/components/Chip/Chip.module.css +288 -0
- package/src/components/Chip/Chip.stories.tsx +128 -0
- package/src/components/Chip/Chip.test.tsx +1 -0
- package/src/components/Chip/Chip.tsx +157 -0
- package/src/components/Chip/USAGE.md +55 -0
- package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Container/Container.module.css +7 -0
- package/src/components/Container/Container.stories.tsx +118 -0
- package/src/components/Container/Container.test.tsx +1 -0
- package/src/components/Container/Container.tsx +69 -0
- package/src/components/Container/USAGE.md +47 -0
- package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +31 -0
- package/src/components/DatePicker/DatePicker.icons.tsx +27 -0
- package/src/components/DatePicker/DatePicker.module.css +566 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +158 -0
- package/src/components/DatePicker/DatePicker.test.tsx +1 -0
- package/src/components/DatePicker/DatePicker.tsx +218 -0
- package/src/components/DatePicker/USAGE.md +49 -0
- package/src/components/Dropdown/BareDropdown.tsx +97 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Dropdown/Dropdown.module.css +477 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +252 -0
- package/src/components/Dropdown/Dropdown.test.tsx +1 -0
- package/src/components/Dropdown/Dropdown.tsx +213 -0
- package/src/components/Dropdown/USAGE.md +69 -0
- package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
- package/src/components/FileInput/FileInput.module.css +280 -0
- package/src/components/FileInput/FileInput.stories.tsx +313 -0
- package/src/components/FileInput/FileInput.test.tsx +1 -0
- package/src/components/FileInput/FileInput.tsx +417 -0
- package/src/components/FileInput/USAGE.md +145 -0
- package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +244 -0
- package/src/components/FileUpload/FileUpload.module.css +205 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +362 -0
- package/src/components/FileUpload/FileUpload.test.tsx +1 -0
- package/src/components/FileUpload/FileUpload.tsx +354 -0
- package/src/components/FileUpload/USAGE.md +199 -0
- package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Flex/Flex.module.css +7 -0
- package/src/components/Flex/Flex.stories.tsx +128 -0
- package/src/components/Flex/Flex.test.tsx +1 -0
- package/src/components/Flex/Flex.tsx +75 -0
- package/src/components/Flex/USAGE.md +48 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +90 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +118 -0
- package/src/components/FormControlLayout/FormControlLayout.test.tsx +1 -0
- package/src/components/FormControlLayout/FormControlLayout.tsx +74 -0
- package/src/components/FormControlLayout/USAGE.md +40 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +75 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
- package/src/components/FormControlWrapper/FormControlWrapper.test.tsx +1 -0
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +151 -0
- package/src/components/FormControlWrapper/USAGE.md +47 -0
- package/src/components/Grid/GRID_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Grid/Grid.module.css +11 -0
- package/src/components/Grid/Grid.stories.tsx +206 -0
- package/src/components/Grid/Grid.test.tsx +1 -0
- package/src/components/Grid/Grid.tsx +140 -0
- package/src/components/Grid/USAGE.md +47 -0
- package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Group/Group.module.css +7 -0
- package/src/components/Group/Group.stories.tsx +120 -0
- package/src/components/Group/Group.test.tsx +1 -0
- package/src/components/Group/Group.tsx +60 -0
- package/src/components/Group/USAGE.md +48 -0
- package/src/components/Heading/HEADING_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Heading/Heading.module.css +13 -0
- package/src/components/Heading/Heading.stories.tsx +50 -0
- package/src/components/Heading/Heading.test.tsx +1 -0
- package/src/components/Heading/Heading.tsx +52 -0
- package/src/components/Heading/USAGE.md +36 -0
- package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/HoverCard/HoverCard.module.css +90 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +172 -0
- package/src/components/HoverCard/HoverCard.test.tsx +1 -0
- package/src/components/HoverCard/HoverCard.tsx +133 -0
- package/src/components/HoverCard/USAGE.md +52 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +141 -0
- package/src/components/Label/Label.stories.tsx +131 -0
- package/src/components/Label/Label.test.tsx +1 -0
- package/src/components/Label/Label.tsx +113 -0
- package/src/components/Label/USAGE.md +47 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Layer/USAGE.md +54 -0
- package/src/components/Link/IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/Link/Link.module.css +110 -0
- package/src/components/Link/Link.stories.tsx +58 -0
- package/src/components/Link/Link.test.tsx +1 -0
- package/src/components/Link/Link.tsx +67 -0
- package/src/components/Link/USAGE.md +56 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Loader/Loader.animate.dom.test.tsx +82 -0
- package/src/components/Loader/Loader.module.css +63 -0
- package/src/components/Loader/Loader.stories.tsx +123 -0
- package/src/components/Loader/Loader.test.tsx +1 -0
- package/src/components/Loader/Loader.tsx +69 -0
- package/src/components/Loader/USAGE.md +44 -0
- package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +88 -0
- package/src/components/Menu/Menu.module.css +280 -0
- package/src/components/Menu/Menu.stories.tsx +371 -0
- package/src/components/Menu/Menu.test.tsx +1 -0
- package/src/components/Menu/Menu.tsx +373 -0
- package/src/components/Menu/USAGE.md +55 -0
- package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/Modal/Modal.module.css +302 -0
- package/src/components/Modal/Modal.stories.tsx +105 -0
- package/src/components/Modal/Modal.test.tsx +1 -0
- package/src/components/Modal/Modal.tsx +368 -0
- package/src/components/Modal/USAGE.md +58 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/NumberInput/NumberInput.module.css +302 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +96 -0
- package/src/components/NumberInput/NumberInput.test.tsx +1 -0
- package/src/components/NumberInput/NumberInput.tsx +157 -0
- package/src/components/NumberInput/USAGE.md +52 -0
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +16 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +188 -0
- package/src/components/Pagination/Pagination.stories.tsx +48 -0
- package/src/components/Pagination/Pagination.test.tsx +1 -0
- package/src/components/Pagination/Pagination.tsx +265 -0
- package/src/components/Pagination/USAGE.md +36 -0
- package/src/components/Pagination/index.ts +5 -0
- package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +116 -0
- package/src/components/Panel/Panel.module.css +209 -0
- package/src/components/Panel/Panel.stories.tsx +227 -0
- package/src/components/Panel/Panel.test.tsx +1 -0
- package/src/components/Panel/Panel.tsx +269 -0
- package/src/components/Panel/USAGE.md +56 -0
- package/src/components/Popover/IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/Popover/Popover.module.css +86 -0
- package/src/components/Popover/Popover.stories.tsx +133 -0
- package/src/components/Popover/Popover.test.tsx +1 -0
- package/src/components/Popover/Popover.tsx +142 -0
- package/src/components/Popover/USAGE.md +61 -0
- package/src/components/Popover/index.ts +1 -0
- package/src/components/Radio/Radio.module.css +231 -0
- package/src/components/Radio/Radio.stories.tsx +93 -0
- package/src/components/Radio/Radio.test.tsx +1 -0
- package/src/components/Radio/Radio.tsx +168 -0
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +124 -0
- package/src/components/Radio/USAGE.md +36 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
- package/src/components/ReadOnlyField/ReadOnlyField.test.tsx +1 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +114 -0
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/USAGE.md +44 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +5 -0
- package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
- package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +185 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +106 -0
- package/src/components/SegmentedControl/SegmentedControl.test.tsx +1 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +110 -0
- package/src/components/SegmentedControl/USAGE.md +55 -0
- package/src/components/Slider/IMPLEMENTATION_NOTES.md +92 -0
- package/src/components/Slider/Slider.module.css +588 -0
- package/src/components/Slider/Slider.stories.tsx +282 -0
- package/src/components/Slider/Slider.test.tsx +1 -0
- package/src/components/Slider/Slider.tsx +391 -0
- package/src/components/Slider/USAGE.md +56 -0
- package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stack/Stack.module.css +7 -0
- package/src/components/Stack/Stack.stories.tsx +108 -0
- package/src/components/Stack/Stack.test.tsx +1 -0
- package/src/components/Stack/Stack.tsx +62 -0
- package/src/components/Stack/USAGE.md +48 -0
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +28 -0
- package/src/components/Stepper/Stepper.module.css +404 -0
- package/src/components/Stepper/Stepper.stories.tsx +148 -0
- package/src/components/Stepper/Stepper.test.tsx +1 -0
- package/src/components/Stepper/Stepper.tsx +93 -0
- package/src/components/Stepper/USAGE.md +41 -0
- package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +64 -0
- package/src/components/Switch/Switch.module.css +279 -0
- package/src/components/Switch/Switch.stories.tsx +114 -0
- package/src/components/Switch/Switch.test.tsx +1 -0
- package/src/components/Switch/Switch.tsx +177 -0
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +127 -0
- package/src/components/Switch/USAGE.md +42 -0
- package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +78 -0
- package/src/components/Table/Table.icons.tsx +40 -0
- package/src/components/Table/Table.module.css +444 -0
- package/src/components/Table/Table.stories.tsx +140 -0
- package/src/components/Table/Table.test.tsx +1 -0
- package/src/components/Table/Table.tsx +243 -0
- package/src/components/Table/USAGE.md +78 -0
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +27 -0
- package/src/components/Tabs/Tabs.module.css +591 -0
- package/src/components/Tabs/Tabs.stories.tsx +154 -0
- package/src/components/Tabs/Tabs.test.tsx +1 -0
- package/src/components/Tabs/Tabs.tsx +114 -0
- package/src/components/Tabs/USAGE.md +45 -0
- package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Text/Text.module.css +13 -0
- package/src/components/Text/Text.stories.tsx +75 -0
- package/src/components/Text/Text.test.tsx +1 -0
- package/src/components/Text/Text.tsx +53 -0
- package/src/components/Text/USAGE.md +40 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/TextArea/TextArea.module.css +183 -0
- package/src/components/TextArea/TextArea.stories.tsx +94 -0
- package/src/components/TextArea/TextArea.test.tsx +1 -0
- package/src/components/TextArea/TextArea.tsx +137 -0
- package/src/components/TextArea/USAGE.md +48 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +264 -0
- package/src/components/TextField/TextField.stories.tsx +162 -0
- package/src/components/TextField/TextField.test.tsx +1 -0
- package/src/components/TextField/TextField.tsx +139 -0
- package/src/components/TextField/USAGE.md +44 -0
- package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +119 -0
- package/src/components/TimePicker/TimePicker.module.css +291 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +141 -0
- package/src/components/TimePicker/TimePicker.test.tsx +1 -0
- package/src/components/TimePicker/TimePicker.tsx +304 -0
- package/src/components/TimePicker/USAGE.md +57 -0
- package/src/components/Timeline/TIMELINE_IMPLEMENTATION_NOTES.md +13 -0
- package/src/components/Timeline/Timeline.module.css +373 -0
- package/src/components/Timeline/Timeline.stories.tsx +128 -0
- package/src/components/Timeline/Timeline.test.tsx +1 -0
- package/src/components/Timeline/Timeline.tsx +73 -0
- package/src/components/Timeline/TimelineItem.tsx +79 -0
- package/src/components/Timeline/USAGE.md +49 -0
- package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +39 -0
- package/src/components/Toast/Toast.module.css +184 -0
- package/src/components/Toast/Toast.stories.tsx +67 -0
- package/src/components/Toast/Toast.test.tsx +1 -0
- package/src/components/Toast/Toast.tsx +82 -0
- package/src/components/Toast/USAGE.md +50 -0
- package/src/components/Toast/index.ts +1 -0
- package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
- package/src/components/Tooltip/Tooltip.module.css +91 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +165 -0
- package/src/components/Tooltip/Tooltip.test.tsx +1 -0
- package/src/components/Tooltip/Tooltip.tsx +117 -0
- package/src/components/Tooltip/USAGE.md +80 -0
- package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +111 -0
- package/src/components/TransferList/TransferList.module.css +182 -0
- package/src/components/TransferList/TransferList.stories.tsx +121 -0
- package/src/components/TransferList/TransferList.test.tsx +1 -0
- package/src/components/TransferList/TransferList.tsx +419 -0
- package/src/components/TransferList/USAGE.md +77 -0
- package/src/components/Tree/IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Tree/Tree.module.css +232 -0
- package/src/components/Tree/Tree.stories.tsx +104 -0
- package/src/components/Tree/Tree.test.tsx +1 -0
- package/src/components/Tree/Tree.tsx +220 -0
- package/src/components/Tree/USAGE.md +96 -0
- package/src/components/Tree/index.ts +1 -0
- package/src/components/index.ts +52 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +179 -0
- package/src/types/index.ts +9 -0
- package/src/types/mantine.d.ts +7 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +27 -0
- package/src/utils/RequireAccessibleLabel.ts +1 -0
- package/src/utils/copyToClipboard.ts +36 -0
- package/src/utils/filterStylingProps.test.ts +85 -0
- package/src/utils/filterStylingProps.ts +150 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/renderRichOption.tsx +65 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* LAYOUT SPACING OVERRIDES:
|
|
10
|
+
- Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens.
|
|
11
|
+
- Also sets the --number-input-control-{max,min}-width hooks consumed inline in NumberInput.tsx,
|
|
12
|
+
since the token schema no longer provides a single layout-agnostic min/max width. */
|
|
13
|
+
.layoutOverride {
|
|
14
|
+
--form-control-margin-bottom: var(
|
|
15
|
+
--recursica_ui-kit_components_number-input_variants_layouts_stacked_properties_top-bottom-margin
|
|
16
|
+
);
|
|
17
|
+
--number-input-control-max-width: var(
|
|
18
|
+
--recursica_ui-kit_components_number-input_variants_layouts_stacked_properties_max-width
|
|
19
|
+
);
|
|
20
|
+
--number-input-control-min-width: var(
|
|
21
|
+
--recursica_ui-kit_components_number-input_variants_layouts_stacked_properties_min-width
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.layoutOverride[data-form-layout="side-by-side"] {
|
|
26
|
+
--form-control-margin-bottom: var(
|
|
27
|
+
--recursica_ui-kit_components_number-input_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
28
|
+
);
|
|
29
|
+
--number-input-control-max-width: var(
|
|
30
|
+
--recursica_ui-kit_components_number-input_variants_layouts_side-by-side_properties_max-width
|
|
31
|
+
);
|
|
32
|
+
--number-input-control-min-width: var(
|
|
33
|
+
--recursica_ui-kit_components_number-input_variants_layouts_side-by-side_properties_min-width
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* HARDCODED VALUES:
|
|
38
|
+
- border-style: solid. Native structural rendering rule.
|
|
39
|
+
- outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
|
|
40
|
+
- flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
|
|
41
|
+
- Controls: Hardcoded to bypass Mantine's default borders and backgrounds on the increment/decrement arrows.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/* EXEMPTIONS:
|
|
45
|
+
- border-size is constant across disabled/error states — only border-color changes; the
|
|
46
|
+
disabled/error border-size tokens are never applied by design. */
|
|
47
|
+
/* recursica-ignore: --recursica_ui-kit_components_number-input_variants_states_disabled_properties_border-size */
|
|
48
|
+
/* recursica-ignore: --recursica_ui-kit_components_number-input_variants_states_error_properties_border-size */
|
|
49
|
+
|
|
50
|
+
.root {
|
|
51
|
+
display: flex;
|
|
52
|
+
position: relative;
|
|
53
|
+
width: 100%;
|
|
54
|
+
min-height: var(
|
|
55
|
+
--recursica_ui-kit_components_number-input_properties_min-height
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
/* Override Mantine native Input variables governing section spacing padding mathematics safely */
|
|
59
|
+
--input-left-section-size: calc(
|
|
60
|
+
var(
|
|
61
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
62
|
+
) +
|
|
63
|
+
var(--recursica_ui-kit_components_number-input_properties_icon-size) +
|
|
64
|
+
var(--recursica_ui-kit_components_number-input_properties_icon-text-gap)
|
|
65
|
+
);
|
|
66
|
+
--input-right-section-size: calc(
|
|
67
|
+
var(
|
|
68
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
69
|
+
) +
|
|
70
|
+
var(--recursica_ui-kit_components_number-input_properties_icon-size) +
|
|
71
|
+
var(--recursica_ui-kit_components_number-input_properties_icon-text-gap)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.input {
|
|
76
|
+
/* Structural Overrides */
|
|
77
|
+
width: 100%;
|
|
78
|
+
box-sizing: border-box;
|
|
79
|
+
margin: 0;
|
|
80
|
+
|
|
81
|
+
/* Box Geometry */
|
|
82
|
+
min-height: var(
|
|
83
|
+
--recursica_ui-kit_components_number-input_properties_min-height
|
|
84
|
+
);
|
|
85
|
+
padding-top: var(
|
|
86
|
+
--recursica_ui-kit_components_number-input_properties_vertical-padding
|
|
87
|
+
);
|
|
88
|
+
padding-bottom: var(
|
|
89
|
+
--recursica_ui-kit_components_number-input_properties_vertical-padding
|
|
90
|
+
);
|
|
91
|
+
padding-left: var(
|
|
92
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
93
|
+
);
|
|
94
|
+
padding-right: var(
|
|
95
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
96
|
+
);
|
|
97
|
+
border-radius: var(
|
|
98
|
+
--recursica_ui-kit_components_number-input_properties_border-radius
|
|
99
|
+
);
|
|
100
|
+
border-width: var(
|
|
101
|
+
--recursica_ui-kit_components_number-input_properties_border-size
|
|
102
|
+
);
|
|
103
|
+
border-style: solid;
|
|
104
|
+
|
|
105
|
+
/* Strict Typography Unification */
|
|
106
|
+
font-family: var(
|
|
107
|
+
--recursica_ui-kit_components_number-input_properties_text_font-family
|
|
108
|
+
);
|
|
109
|
+
font-size: var(
|
|
110
|
+
--recursica_ui-kit_components_number-input_properties_text_font-size
|
|
111
|
+
);
|
|
112
|
+
font-style: var(
|
|
113
|
+
--recursica_ui-kit_components_number-input_properties_text_font-style
|
|
114
|
+
);
|
|
115
|
+
font-weight: var(
|
|
116
|
+
--recursica_ui-kit_components_number-input_properties_text_font-weight
|
|
117
|
+
);
|
|
118
|
+
letter-spacing: var(
|
|
119
|
+
--recursica_ui-kit_components_number-input_properties_text_letter-spacing
|
|
120
|
+
);
|
|
121
|
+
line-height: var(
|
|
122
|
+
--recursica_ui-kit_components_number-input_properties_text_line-height
|
|
123
|
+
);
|
|
124
|
+
text-decoration: var(
|
|
125
|
+
--recursica_ui-kit_components_number-input_properties_text_text-decoration
|
|
126
|
+
);
|
|
127
|
+
text-transform: var(
|
|
128
|
+
--recursica_ui-kit_components_number-input_properties_text_text-transform
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
/* Base State Default Execution */
|
|
132
|
+
background-color: var(
|
|
133
|
+
--recursica_ui-kit_components_number-input_properties_colors_background-color
|
|
134
|
+
);
|
|
135
|
+
border-color: var(
|
|
136
|
+
--recursica_ui-kit_components_number-input_properties_colors_border-color
|
|
137
|
+
);
|
|
138
|
+
color: var(
|
|
139
|
+
--recursica_ui-kit_components_number-input_properties_colors_text-color
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
outline: none;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.input::placeholder {
|
|
146
|
+
opacity: var(
|
|
147
|
+
--recursica_ui-kit_components_number-input_properties_placeholder-opacity
|
|
148
|
+
);
|
|
149
|
+
color: inherit;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Dynamic Padding Overrides */
|
|
153
|
+
.root[data-with-left-section] .input {
|
|
154
|
+
padding-left: var(--input-left-section-size);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.root[data-with-right-section] .input {
|
|
158
|
+
padding-right: var(--input-right-section-size);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Flexible End-Caps (Icons, actions) */
|
|
162
|
+
.section {
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
height: 100%;
|
|
166
|
+
/* Mantine's own Input.Section rule falls back to --mantine-color-dimmed via
|
|
167
|
+
--input-section-color when nothing else sets it, which leaks a library gray onto
|
|
168
|
+
plain (non-svg) section content like text stand-ins. Feed the real Recursica token
|
|
169
|
+
into the same variable Mantine already reads so text content is token-colored too,
|
|
170
|
+
not just the svg-specific override below. */
|
|
171
|
+
--input-section-color: var(
|
|
172
|
+
--recursica_ui-kit_components_number-input_properties_colors_leading-icon
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.section[data-position="left"] {
|
|
177
|
+
justify-content: flex-start;
|
|
178
|
+
padding-left: var(
|
|
179
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.section[data-position="right"] {
|
|
184
|
+
justify-content: flex-end;
|
|
185
|
+
padding-right: var(
|
|
186
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
187
|
+
);
|
|
188
|
+
--input-section-color: var(
|
|
189
|
+
--recursica_ui-kit_components_number-input_properties_colors_trailing-icon
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.section :global(svg) {
|
|
194
|
+
width: var(--recursica_ui-kit_components_number-input_properties_icon-size);
|
|
195
|
+
height: var(--recursica_ui-kit_components_number-input_properties_icon-size);
|
|
196
|
+
color: var(
|
|
197
|
+
--recursica_ui-kit_components_number-input_properties_colors_leading-icon
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.section[data-position="right"] :global(svg) {
|
|
202
|
+
color: var(
|
|
203
|
+
--recursica_ui-kit_components_number-input_properties_colors_trailing-icon
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* -------------------------------------
|
|
208
|
+
CONTROLS (Mantine Specific Up/Down Arrows)
|
|
209
|
+
-------------------------------------- */
|
|
210
|
+
|
|
211
|
+
.controls {
|
|
212
|
+
/* Adjust right padding so controls do not overlap borders */
|
|
213
|
+
padding-right: var(
|
|
214
|
+
--recursica_ui-kit_components_number-input_properties_horizontal-padding
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.control {
|
|
219
|
+
/* Override Mantine borders for the inner controls */
|
|
220
|
+
border: none;
|
|
221
|
+
background: transparent;
|
|
222
|
+
color: var(
|
|
223
|
+
--recursica_ui-kit_components_number-input_properties_colors_trailing-icon
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.control:hover {
|
|
228
|
+
background: transparent;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* -------------------------------------
|
|
232
|
+
STATE CASCADE ARCHITECTURE
|
|
233
|
+
-------------------------------------- */
|
|
234
|
+
|
|
235
|
+
/* Focus State Mapping (Triggered internally via browser pseudo-pseudo-class) */
|
|
236
|
+
/* The token schema no longer provides per-component focus colors; apply the generic focus ring
|
|
237
|
+
tokens as a box-shadow ring instead of a color swap. */
|
|
238
|
+
.input:focus-within,
|
|
239
|
+
.input:focus {
|
|
240
|
+
box-shadow:
|
|
241
|
+
0 0 0 var(--recursica_brand_states_focus_border-size)
|
|
242
|
+
var(--recursica_brand_states_focus_color),
|
|
243
|
+
0 0 var(--recursica_brand_states_focus_blur)
|
|
244
|
+
var(--recursica_brand_states_focus_margin)
|
|
245
|
+
var(--recursica_brand_states_focus_color);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
|
|
249
|
+
.root[data-error] .input {
|
|
250
|
+
border-color: var(
|
|
251
|
+
--recursica_ui-kit_components_number-input_variants_states_error_properties_colors_border-color
|
|
252
|
+
) !important;
|
|
253
|
+
background-color: var(
|
|
254
|
+
--recursica_ui-kit_components_number-input_variants_states_error_properties_colors_background-color
|
|
255
|
+
) !important;
|
|
256
|
+
color: var(
|
|
257
|
+
--recursica_ui-kit_components_number-input_variants_states_error_properties_colors_text-color
|
|
258
|
+
) !important;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.root[data-error] .section[data-position="left"] :global(svg) {
|
|
262
|
+
color: var(
|
|
263
|
+
--recursica_ui-kit_components_number-input_variants_states_error_properties_colors_leading-icon
|
|
264
|
+
) !important;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.root[data-error] .section[data-position="right"] :global(svg),
|
|
268
|
+
.root[data-error] .control {
|
|
269
|
+
color: var(
|
|
270
|
+
--recursica_ui-kit_components_number-input_variants_states_error_properties_colors_trailing-icon
|
|
271
|
+
) !important;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
|
|
275
|
+
.root[data-disabled] .input {
|
|
276
|
+
border-color: var(
|
|
277
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_border-color
|
|
278
|
+
) !important;
|
|
279
|
+
background-color: var(
|
|
280
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_background-color
|
|
281
|
+
) !important;
|
|
282
|
+
color: var(
|
|
283
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_text-color
|
|
284
|
+
) !important;
|
|
285
|
+
opacity: var(
|
|
286
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_opacity
|
|
287
|
+
) !important;
|
|
288
|
+
cursor: not-allowed;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.root[data-disabled] .section[data-position="left"] :global(svg) {
|
|
292
|
+
color: var(
|
|
293
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_leading-icon
|
|
294
|
+
) !important;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.root[data-disabled] .section[data-position="right"] :global(svg),
|
|
298
|
+
.root[data-disabled] .control {
|
|
299
|
+
color: var(
|
|
300
|
+
--recursica_ui-kit_components_number-input_variants_states_disabled_properties_colors_trailing-icon
|
|
301
|
+
) !important;
|
|
302
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { NumberInput } from "./NumberInput";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof NumberInput> = {
|
|
5
|
+
title: "UI-Kit/NumberInput",
|
|
6
|
+
component: NumberInput,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
argTypes: {
|
|
9
|
+
label: { control: "text" },
|
|
10
|
+
assistiveText: { control: "text" },
|
|
11
|
+
disabled: { control: "boolean" },
|
|
12
|
+
error: { control: "boolean" },
|
|
13
|
+
readOnly: { control: "boolean" },
|
|
14
|
+
required: { control: "boolean" },
|
|
15
|
+
hideControls: { control: "boolean" },
|
|
16
|
+
formLayout: {
|
|
17
|
+
control: "select",
|
|
18
|
+
options: ["stacked", "side-by-side"],
|
|
19
|
+
},
|
|
20
|
+
labelSize: {
|
|
21
|
+
control: "select",
|
|
22
|
+
options: ["small", "default", "large"],
|
|
23
|
+
},
|
|
24
|
+
assistiveWithIcon: { table: { disable: true } },
|
|
25
|
+
labelOptionalText: { table: { disable: true } },
|
|
26
|
+
labelWithEditIcon: { table: { disable: true } },
|
|
27
|
+
onLabelEditClick: { table: { disable: true } },
|
|
28
|
+
emptyValueComponent: { table: { disable: true } },
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default meta;
|
|
33
|
+
|
|
34
|
+
type Story = StoryObj<typeof NumberInput>;
|
|
35
|
+
|
|
36
|
+
export const Default: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
label: "Amount",
|
|
39
|
+
placeholder: "Enter an amount",
|
|
40
|
+
assistiveText: "Must be greater than 0",
|
|
41
|
+
defaultValue: 10,
|
|
42
|
+
min: 0,
|
|
43
|
+
max: 100,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const SideBySideLayout: Story = {
|
|
48
|
+
args: {
|
|
49
|
+
...Default.args,
|
|
50
|
+
formLayout: "side-by-side",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const States: Story = {
|
|
55
|
+
render: () => (
|
|
56
|
+
<div
|
|
57
|
+
style={{
|
|
58
|
+
display: "flex",
|
|
59
|
+
flexDirection: "column",
|
|
60
|
+
gap: "1rem",
|
|
61
|
+
maxWidth: 400,
|
|
62
|
+
}}
|
|
63
|
+
>
|
|
64
|
+
<NumberInput label="Default" placeholder="Enter a number" />
|
|
65
|
+
<NumberInput label="Disabled" placeholder="Disabled input" disabled />
|
|
66
|
+
<NumberInput label="Error" placeholder="Error state" error />
|
|
67
|
+
<NumberInput label="Read Only" value={42} readOnly />
|
|
68
|
+
<NumberInput label="Required" required />
|
|
69
|
+
</div>
|
|
70
|
+
),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const WithLeftIcon: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
label: "Price",
|
|
76
|
+
placeholder: "0.00",
|
|
77
|
+
leftSection: <span>$</span>,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const WithRightIcon: Story = {
|
|
82
|
+
args: {
|
|
83
|
+
label: "Percentage",
|
|
84
|
+
placeholder: "0",
|
|
85
|
+
rightSection: <span>%</span>,
|
|
86
|
+
hideControls: true, // Typically hiding controls if rightSection is occupied
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const HiddenControls: Story = {
|
|
91
|
+
args: {
|
|
92
|
+
label: "Zip Code",
|
|
93
|
+
placeholder: "Enter zip code",
|
|
94
|
+
hideControls: true,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future NumberInput component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
NumberInput as MantineNumberInput,
|
|
4
|
+
type NumberInputProps as MantineNumberInputProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
7
|
+
import {
|
|
8
|
+
filterStylingProps,
|
|
9
|
+
omitUnsupportedProps,
|
|
10
|
+
type RecursicaOverStyled,
|
|
11
|
+
} from "../../utils/filterStylingProps";
|
|
12
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
13
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
14
|
+
import styles from "./NumberInput.module.css";
|
|
15
|
+
|
|
16
|
+
import { type RecursicaNumberInputProps as BaseRecursicaNumberInputProps } from "@recursica/adapter-common";
|
|
17
|
+
|
|
18
|
+
export interface RecursicaNumberInputProps
|
|
19
|
+
extends Omit<
|
|
20
|
+
MantineNumberInputProps,
|
|
21
|
+
"size" | "variant" | "radius" | "wrapperProps" | "classNames" | "styles"
|
|
22
|
+
>,
|
|
23
|
+
Pick<
|
|
24
|
+
RecursicaFormControlWrapperProps,
|
|
25
|
+
| "assistiveText"
|
|
26
|
+
| "assistiveWithIcon"
|
|
27
|
+
| "formLayout"
|
|
28
|
+
| "labelSize"
|
|
29
|
+
| "labelAlignment"
|
|
30
|
+
| "labelOptionalText"
|
|
31
|
+
| "labelWithEditIcon"
|
|
32
|
+
| "onLabelEditClick"
|
|
33
|
+
>,
|
|
34
|
+
ReadOnlyControlProps,
|
|
35
|
+
BaseRecursicaNumberInputProps {}
|
|
36
|
+
|
|
37
|
+
export type NumberInputProps = RecursicaOverStyled<RecursicaNumberInputProps>;
|
|
38
|
+
|
|
39
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
40
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
41
|
+
const UNSUPPORTED_PROPS = [
|
|
42
|
+
"size", // Recursica controls sizing via the `size` variant + design tokens, not raw dimensions.
|
|
43
|
+
"variant", // Colors/variants are token-driven; the library's native palette isn't exposed.
|
|
44
|
+
"radius", // Recursica does not expose the library's native corner-radius system.
|
|
45
|
+
] as const satisfies readonly (keyof MantineNumberInputProps)[];
|
|
46
|
+
|
|
47
|
+
export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(
|
|
48
|
+
function NumberInput(props, ref) {
|
|
49
|
+
const {
|
|
50
|
+
overStyled = false,
|
|
51
|
+
formLayout = "stacked",
|
|
52
|
+
|
|
53
|
+
// Label & Wrapper Maps
|
|
54
|
+
labelSize,
|
|
55
|
+
labelAlignment,
|
|
56
|
+
labelOptionalText,
|
|
57
|
+
labelWithEditIcon,
|
|
58
|
+
onLabelEditClick,
|
|
59
|
+
|
|
60
|
+
label,
|
|
61
|
+
assistiveText,
|
|
62
|
+
assistiveWithIcon,
|
|
63
|
+
error,
|
|
64
|
+
required,
|
|
65
|
+
withAsterisk,
|
|
66
|
+
id,
|
|
67
|
+
className,
|
|
68
|
+
style,
|
|
69
|
+
disabled,
|
|
70
|
+
readOnly,
|
|
71
|
+
readOnlyComponent,
|
|
72
|
+
emptyValueComponent,
|
|
73
|
+
value,
|
|
74
|
+
defaultValue,
|
|
75
|
+
hideControls = false,
|
|
76
|
+
...rest
|
|
77
|
+
} = props;
|
|
78
|
+
|
|
79
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
80
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
81
|
+
UNSUPPORTED_PROPS,
|
|
82
|
+
);
|
|
83
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
84
|
+
|
|
85
|
+
// Securely map core native blocks down ensuring nested CSS modules map precisely
|
|
86
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
87
|
+
wrapper: styles.root, // The nested Input internal relative wrapper bounding box
|
|
88
|
+
input: styles.input,
|
|
89
|
+
section: styles.section,
|
|
90
|
+
controls: styles.controls,
|
|
91
|
+
control: styles.control,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const wrapperClass = className
|
|
95
|
+
? `${styles.layoutOverride} ${className}`
|
|
96
|
+
: styles.layoutOverride;
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<WithReadOnlyWrapper
|
|
100
|
+
className={wrapperClass}
|
|
101
|
+
style={style as React.CSSProperties}
|
|
102
|
+
controlMaxWidth="var(--number-input-control-max-width)"
|
|
103
|
+
controlMinWidth="var(--number-input-control-min-width)"
|
|
104
|
+
overStyled={overStyled as true}
|
|
105
|
+
formLayout={formLayout}
|
|
106
|
+
labelSize={labelSize}
|
|
107
|
+
labelAlignment={labelAlignment}
|
|
108
|
+
labelOptionalText={labelOptionalText}
|
|
109
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
110
|
+
onLabelEditClick={onLabelEditClick}
|
|
111
|
+
label={label}
|
|
112
|
+
assistiveText={assistiveText}
|
|
113
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
114
|
+
error={error}
|
|
115
|
+
required={required}
|
|
116
|
+
withAsterisk={withAsterisk}
|
|
117
|
+
id={id}
|
|
118
|
+
readOnly={readOnly}
|
|
119
|
+
readOnlyComponent={readOnlyComponent}
|
|
120
|
+
emptyValueComponent={emptyValueComponent}
|
|
121
|
+
readOnlyType="text"
|
|
122
|
+
readOnlyValue={
|
|
123
|
+
value !== undefined ? value?.toString() : defaultValue?.toString()
|
|
124
|
+
}
|
|
125
|
+
readOnlyNativeProps={props}
|
|
126
|
+
activeComponent={
|
|
127
|
+
/* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
|
|
128
|
+
<MantineNumberInput
|
|
129
|
+
ref={ref}
|
|
130
|
+
{...(sanitizedProps as unknown as MantineNumberInputProps)}
|
|
131
|
+
classNames={mergedClassNames}
|
|
132
|
+
disabled={disabled}
|
|
133
|
+
value={value}
|
|
134
|
+
defaultValue={defaultValue}
|
|
135
|
+
hideControls={hideControls}
|
|
136
|
+
label={undefined}
|
|
137
|
+
description={undefined}
|
|
138
|
+
error={undefined}
|
|
139
|
+
required={undefined}
|
|
140
|
+
withAsterisk={undefined}
|
|
141
|
+
wrapperProps={{
|
|
142
|
+
"data-disabled": disabled ? "true" : undefined,
|
|
143
|
+
"data-error": error ? "true" : undefined,
|
|
144
|
+
"data-with-left-section": restRecord.leftSection
|
|
145
|
+
? "true"
|
|
146
|
+
: undefined,
|
|
147
|
+
"data-with-right-section":
|
|
148
|
+
restRecord.rightSection || !hideControls ? "true" : undefined,
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
151
|
+
}
|
|
152
|
+
/>
|
|
153
|
+
);
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
NumberInput.displayName = "NumberInput";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# NumberInput - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `NumberInput` component in your projects using `@recursica/adapter-mantine-v8`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { NumberInput } from "@recursica/adapter-mantine-v8";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { NumberInput } from "@recursica/adapter-mantine-v8";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return <NumberInput label="Quantity" min={1} max={10} defaultValue={1} />;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Design System Integration
|
|
29
|
+
|
|
30
|
+
All Recursica components in the `@recursica/adapter-mantine-v8` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
31
|
+
|
|
32
|
+
> [!IMPORTANT]
|
|
33
|
+
>
|
|
34
|
+
> - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
35
|
+
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
36
|
+
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 4. Key Integration Features & Constraints
|
|
41
|
+
|
|
42
|
+
## 1. Label, Description, and Error Rendering
|
|
43
|
+
|
|
44
|
+
Label, description, and error text are rendered using Recursica's standard form-control layout rather than Mantine's native label/description/error rendering, so spacing and styling stay consistent with other form fields.
|
|
45
|
+
|
|
46
|
+
## 2. Right Section & Controls
|
|
47
|
+
|
|
48
|
+
Providing a custom `rightSection` element replaces the built-in increment/decrement controls. To use both together, rebuild the controls manually using Mantine's `handlersRef` API within your custom right section.
|
|
49
|
+
|
|
50
|
+
## 3. Controls Styling
|
|
51
|
+
|
|
52
|
+
The increment/decrement control icons currently fall back to Mantine's default styling beyond their color, as design tokens for their background, border, and hover states are not yet defined.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Pagination Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture Decision: CSS Inheritance vs. Composition
|
|
4
|
+
|
|
5
|
+
The Figma design tokens for the `Pagination` component dictate that pagination pages perfectly mimic `Button` variants (e.g. `active-pages_style: "solid"`, `inactive-pages_style: "outline"`, `navigation-controls_style: "text"`).
|
|
6
|
+
|
|
7
|
+
As of the `1.2.0` scoped CSS update, the Figma exporter automatically handles these variants. It flattens and aliases the referenced Button properties directly into the `Pagination` component's variable namespace.
|
|
8
|
+
|
|
9
|
+
We opted to use Mantine's native `PaginationControl` components to ensure all DOM structure, focus management, and accessibility attributes are preserved natively without us needing to carefully rebuild `Pagination.Items` mappings.
|
|
10
|
+
|
|
11
|
+
To honor the Figma design intents while using Mantine's raw `<button>` elements:
|
|
12
|
+
|
|
13
|
+
1. We inherit and map all natively scoped `Pagination` variant styles (small typography, outline/solid/text colors, and hover overlays) directly into `.control` and `.control[data-active]` within `Pagination.module.css`. We do not need to manually reference `Button` variables cross-component.
|
|
14
|
+
2. We inject `data-variant="text"` via `getControlProps` onto the navigation buttons so that they inherit the explicitly aliased text style variables (`navigation-controls`) defined by the UI Kit for pagination.
|
|
15
|
+
|
|
16
|
+
This achieves exact optical alignment with the tokens while maintaining Mantine's robust internal event handling for pagination.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import styles from "./Pagination.module.css";
|
|
2
|
+
|
|
3
|
+
const NextPath =
|
|
4
|
+
"M8.781 8l-3.3-3.3.943-.943L10.667 8l-4.243 4.243-.943-.943 3.3-3.3z";
|
|
5
|
+
const PrevPath =
|
|
6
|
+
"M7.219 8l3.3 3.3-.943.943L5.333 8l4.243-4.243.943.943-3.3 3.3z";
|
|
7
|
+
const FirstPath =
|
|
8
|
+
"M6.85355 3.85355C7.04882 3.65829 7.04882 3.34171 6.85355 3.14645C6.65829 2.95118 6.34171 2.95118 6.14645 3.14645L2.14645 7.14645C1.95118 7.34171 1.95118 7.65829 2.14645 7.85355L6.14645 11.8536C6.34171 12.0488 6.65829 12.0488 6.85355 11.8536C7.04882 11.6583 7.04882 11.3417 6.85355 11.1464L3.20711 7.5L6.85355 3.85355ZM12.8536 3.85355C13.0488 3.65829 13.0488 3.34171 12.8536 3.14645C12.6583 2.95118 12.3417 2.95118 12.1464 3.14645L8.14645 7.14645C7.95118 7.34171 7.95118 7.65829 8.14645 7.85355L12.1464 11.8536C12.3417 12.0488 12.6583 12.0488 12.8536 11.8536C13.0488 11.6583 13.0488 11.3417 12.8536 11.1464L9.20711 7.5L12.8536 3.85355Z";
|
|
9
|
+
const LastPath =
|
|
10
|
+
"M2.14645 11.1464C1.95118 11.3417 1.95118 11.6583 2.14645 11.8536C2.34171 12.0488 2.65829 12.0488 2.85355 11.8536L6.85355 7.85355C7.04882 7.65829 7.04882 7.34171 6.85355 7.14645L2.85355 3.14645C2.65829 2.95118 2.34171 2.95118 2.14645 3.14645C1.95118 3.34171 1.95118 3.65829 2.14645 3.85355L5.79289 7.5L2.14645 11.1464ZM8.14645 11.1464C7.95118 11.3417 7.95118 11.6583 8.14645 11.8536C8.34171 12.0488 8.65829 12.0488 8.85355 11.8536L12.8536 7.85355C13.0488 7.65829 13.0488 7.34171 12.8536 7.14645L8.85355 3.14645C8.65829 2.95118 8.34171 2.95118 8.14645 3.14645C7.95118 3.34171 7.95118 3.65829 8.14645 3.85355L11.7929 7.5L8.14645 11.1464Z";
|
|
11
|
+
|
|
12
|
+
export type PaginationIconType = "next" | "prev" | "first" | "last";
|
|
13
|
+
|
|
14
|
+
const paths: Record<PaginationIconType, string> = {
|
|
15
|
+
next: NextPath,
|
|
16
|
+
prev: PrevPath,
|
|
17
|
+
first: FirstPath,
|
|
18
|
+
last: LastPath,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const PaginationIcon = ({
|
|
22
|
+
type,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<"svg"> & { type: PaginationIconType }) => (
|
|
26
|
+
<svg
|
|
27
|
+
viewBox="0 0 16 16"
|
|
28
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
29
|
+
className={`${styles.baseIcon} ${className || ""}`.trim()}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
<path d={paths[type as PaginationIconType]} fill="currentColor" />
|
|
33
|
+
</svg>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
export const NextWithLabel = (props: any) => (
|
|
38
|
+
<div className={styles.iconWithLabel}>
|
|
39
|
+
<span>Next</span>
|
|
40
|
+
<PaginationIcon type="next" {...props} />
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
export const PrevWithLabel = (props: any) => (
|
|
46
|
+
<div className={styles.iconWithLabel}>
|
|
47
|
+
<PaginationIcon type="prev" {...props} />
|
|
48
|
+
<span>Prev</span>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
export const FirstWithLabel = (props: any) => (
|
|
54
|
+
<div className={styles.iconWithLabel}>
|
|
55
|
+
<PaginationIcon type="first" {...props} />
|
|
56
|
+
<span>First</span>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
export const LastWithLabel = (props: any) => (
|
|
62
|
+
<div className={styles.iconWithLabel}>
|
|
63
|
+
<span>Last</span>
|
|
64
|
+
<PaginationIcon type="last" {...props} />
|
|
65
|
+
</div>
|
|
66
|
+
);
|