@recursica/adapter-mui-v7 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 +582 -0
- package/LICENSE +21 -0
- package/OVERSTYLING.md +59 -0
- package/README.md +70 -0
- package/SETUP.md +92 -0
- package/USAGE.md +57 -0
- package/dist/adapter-mui-v7.cjs +292 -0
- package/dist/adapter-mui-v7.cjs.map +1 -0
- package/dist/adapter-mui-v7.css +1 -0
- package/dist/adapter-mui-v7.js +40757 -0
- package/dist/adapter-mui-v7.js.map +1 -0
- package/dist/index.d.ts +2350 -0
- package/dist/vite.svg +1 -0
- package/docs/PHILOSOPHY.md +39 -0
- package/llms.txt +76 -0
- package/package.json +151 -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 +184 -0
- package/src/OverStyling.tsx +87 -0
- package/src/Version.tsx +37 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +107 -0
- package/src/components/Accordion/Accordion.module.css +362 -0
- package/src/components/Accordion/Accordion.stories.tsx +198 -0
- package/src/components/Accordion/Accordion.test.tsx +1 -0
- package/src/components/Accordion/Accordion.tsx +285 -0
- package/src/components/Accordion/USAGE.md +43 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +59 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +121 -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 +94 -0
- package/src/components/AssistiveElement/USAGE.md +36 -0
- package/src/components/AssistiveElement/index.ts +1 -0
- package/src/components/AutoComplete/AutoComplete.module.css +456 -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 +266 -0
- package/src/components/AutoComplete/IMPLEMENTATION_NOTES.md +37 -0
- package/src/components/AutoComplete/USAGE.md +68 -0
- package/src/components/AutoComplete/index.ts +1 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +36 -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 +88 -0
- package/src/components/Avatar/USAGE.md +38 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/Badge.module.css +115 -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 +61 -0
- package/src/components/Badge/USAGE.md +40 -0
- package/src/components/Badge/index.ts +1 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +51 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +51 -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 +70 -0
- package/src/components/Breadcrumb/USAGE.md +42 -0
- package/src/components/Breadcrumb/index.ts +1 -0
- package/src/components/Button/BUTTON_IMPLEMENTATION_NOTES.md +123 -0
- package/src/components/Button/Button.module.css +413 -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 +156 -0
- package/src/components/Button/USAGE.md +46 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/Card/Card.module.css +155 -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 +202 -0
- package/src/components/Card/USAGE.md +57 -0
- package/src/components/Card/index.ts +1 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +14 -0
- package/src/components/Checkbox/Checkbox.module.css +286 -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 +259 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +148 -0
- package/src/components/Checkbox/USAGE.md +36 -0
- package/src/components/Checkbox/index.ts +6 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +102 -0
- package/src/components/Chip/Chip.module.css +283 -0
- package/src/components/Chip/Chip.stories.tsx +154 -0
- package/src/components/Chip/Chip.test.tsx +1 -0
- package/src/components/Chip/Chip.tsx +168 -0
- package/src/components/Chip/USAGE.md +55 -0
- package/src/components/Chip/index.ts +1 -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 +51 -0
- package/src/components/Container/IMPLEMENTATION_NOTES.md +5 -0
- package/src/components/Container/USAGE.md +48 -0
- package/src/components/Container/index.ts +1 -0
- package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +29 -0
- package/src/components/DatePicker/DatePicker.icons.tsx +35 -0
- package/src/components/DatePicker/DatePicker.module.css +464 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +163 -0
- package/src/components/DatePicker/DatePicker.test.tsx +1 -0
- package/src/components/DatePicker/DatePicker.tsx +229 -0
- package/src/components/DatePicker/USAGE.md +49 -0
- package/src/components/DatePicker/index.ts +1 -0
- package/src/components/Dropdown/BareDropdown.tsx +168 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/Dropdown/Dropdown.icons.tsx +33 -0
- package/src/components/Dropdown/Dropdown.module.css +535 -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 +319 -0
- package/src/components/Dropdown/USAGE.md +68 -0
- package/src/components/Dropdown/index.ts +1 -0
- package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
- package/src/components/FileInput/FileInput.module.css +268 -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 +415 -0
- package/src/components/FileInput/USAGE.md +145 -0
- package/src/components/FileInput/index.ts +1 -0
- package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +249 -0
- package/src/components/FileUpload/FileUpload.module.css +200 -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 +352 -0
- package/src/components/FileUpload/USAGE.md +199 -0
- package/src/components/FileUpload/index.ts +1 -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 +89 -0
- package/src/components/Flex/USAGE.md +41 -0
- package/src/components/Flex/index.ts +1 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -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 +72 -0
- package/src/components/FormControlLayout/USAGE.md +40 -0
- package/src/components/FormControlLayout/index.ts +1 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +35 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -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 +149 -0
- package/src/components/FormControlWrapper/USAGE.md +40 -0
- package/src/components/FormControlWrapper/index.ts +1 -0
- package/src/components/Grid/Grid.module.css +72 -0
- package/src/components/Grid/Grid.stories.tsx +161 -0
- package/src/components/Grid/Grid.test.tsx +1 -0
- package/src/components/Grid/Grid.tsx +155 -0
- package/src/components/Grid/IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Grid/USAGE.md +53 -0
- package/src/components/Grid/index.ts +1 -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 +116 -0
- package/src/components/Group/USAGE.md +41 -0
- package/src/components/Group/index.ts +1 -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 +28 -0
- package/src/components/Heading/USAGE.md +36 -0
- package/src/components/Heading/index.ts +1 -0
- package/src/components/HoverCard/HoverCard.module.css +107 -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 +145 -0
- package/src/components/HoverCard/USAGE.md +45 -0
- package/src/components/HoverCard/index.ts +1 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +27 -0
- package/src/components/Label/Label.module.css +169 -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 +96 -0
- package/src/components/Label/USAGE.md +36 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Layer/USAGE.md +50 -0
- package/src/components/Link/LINK_IMPLEMENTATION_NOTES.md +9 -0
- package/src/components/Link/Link.module.css +105 -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 +45 -0
- package/src/components/Link/USAGE.md +40 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Loader/Loader.animate.dom.test.tsx +72 -0
- package/src/components/Loader/Loader.module.css +175 -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 +72 -0
- package/src/components/Loader/USAGE.md +42 -0
- package/src/components/Loader/index.ts +1 -0
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +5 -0
- package/src/components/Menu/Menu.module.css +283 -0
- package/src/components/Menu/Menu.stories.tsx +405 -0
- package/src/components/Menu/Menu.test.tsx +1 -0
- package/src/components/Menu/Menu.tsx +103 -0
- package/src/components/Menu/USAGE.md +53 -0
- package/src/components/Menu/index.ts +1 -0
- package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +31 -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 +231 -0
- package/src/components/Modal/USAGE.md +40 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +93 -0
- package/src/components/NumberInput/NumberInput.module.css +303 -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 +273 -0
- package/src/components/NumberInput/USAGE.md +36 -0
- package/src/components/NumberInput/index.ts +1 -0
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +40 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +197 -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 +123 -0
- package/src/components/Pagination/USAGE.md +36 -0
- package/src/components/Pagination/index.ts +1 -0
- package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +133 -0
- package/src/components/Panel/Panel.module.css +231 -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 +186 -0
- package/src/components/Panel/USAGE.md +46 -0
- package/src/components/Panel/index.ts +1 -0
- package/src/components/Popover/IMPLEMENTATION_NOTES.md +22 -0
- package/src/components/Popover/Popover.module.css +118 -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 +267 -0
- package/src/components/Popover/USAGE.md +69 -0
- package/src/components/Popover/index.ts +1 -0
- package/src/components/Radio/RADIO_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Radio/Radio.module.css +247 -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 +223 -0
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +122 -0
- package/src/components/Radio/USAGE.md +36 -0
- package/src/components/Radio/index.ts +2 -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 +108 -0
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/USAGE.md +36 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +2 -0
- package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
- package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +14 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +201 -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 +149 -0
- package/src/components/SegmentedControl/USAGE.md +49 -0
- package/src/components/SegmentedControl/index.ts +1 -0
- package/src/components/Slider/IMPLEMENTATION_NOTES.md +55 -0
- package/src/components/Slider/Slider.module.css +635 -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 +435 -0
- package/src/components/Slider/USAGE.md +56 -0
- package/src/components/Slider/index.ts +1 -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 +43 -0
- package/src/components/Stack/USAGE.md +41 -0
- package/src/components/Stack/index.ts +1 -0
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +120 -0
- package/src/components/Stepper/Stepper.module.css +474 -0
- package/src/components/Stepper/Stepper.stories.tsx +157 -0
- package/src/components/Stepper/Stepper.test.tsx +1 -0
- package/src/components/Stepper/Stepper.tsx +240 -0
- package/src/components/Stepper/USAGE.md +45 -0
- package/src/components/Stepper/index.ts +1 -0
- package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +147 -0
- package/src/components/Switch/Switch.module.css +346 -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 +294 -0
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +156 -0
- package/src/components/Switch/USAGE.md +36 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +75 -0
- package/src/components/Table/Table.module.css +462 -0
- package/src/components/Table/Table.stories.tsx +154 -0
- package/src/components/Table/Table.test.tsx +1 -0
- package/src/components/Table/Table.tsx +250 -0
- package/src/components/Table/USAGE.md +90 -0
- package/src/components/Table/index.ts +1 -0
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +76 -0
- package/src/components/Tabs/Tabs.module.css +801 -0
- package/src/components/Tabs/Tabs.stories.tsx +174 -0
- package/src/components/Tabs/Tabs.test.tsx +1 -0
- package/src/components/Tabs/Tabs.tsx +103 -0
- package/src/components/Tabs/USAGE.md +61 -0
- package/src/components/Tabs/index.ts +1 -0
- package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +10 -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 +19 -0
- package/src/components/Text/USAGE.md +40 -0
- package/src/components/Text/index.ts +1 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +42 -0
- package/src/components/TextArea/TextArea.module.css +203 -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 +162 -0
- package/src/components/TextArea/USAGE.md +38 -0
- package/src/components/TextArea/index.ts +1 -0
- package/src/components/TextField/TextField.module.css +271 -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 +182 -0
- package/src/components/TextField/USAGE.md +38 -0
- package/src/components/TextField/index.ts +1 -0
- package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +89 -0
- package/src/components/TimePicker/TimePicker.module.css +262 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +155 -0
- package/src/components/TimePicker/TimePicker.test.tsx +1 -0
- package/src/components/TimePicker/TimePicker.tsx +277 -0
- package/src/components/TimePicker/USAGE.md +61 -0
- package/src/components/TimePicker/index.ts +1 -0
- package/src/components/Timeline/IMPLEMENTATION_NOTES.md +42 -0
- package/src/components/Timeline/Timeline.module.css +363 -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 +90 -0
- package/src/components/Timeline/TimelineItem.tsx +95 -0
- package/src/components/Timeline/USAGE.md +41 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +37 -0
- package/src/components/Toast/Toast.module.css +193 -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 +121 -0
- package/src/components/Toast/USAGE.md +42 -0
- package/src/components/Toast/index.ts +1 -0
- package/src/components/Tooltip/Tooltip.module.css +83 -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 +78 -0
- package/src/components/Tooltip/USAGE.md +40 -0
- package/src/components/Tooltip/index.ts +1 -0
- package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +140 -0
- package/src/components/TransferList/TransferList.module.css +174 -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/TransferList/index.ts +1 -0
- package/src/components/Tree/IMPLEMENTATION_NOTES.md +53 -0
- package/src/components/Tree/Tree.module.css +272 -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 +298 -0
- package/src/components/Tree/USAGE.md +99 -0
- package/src/components/Tree/index.ts +1 -0
- package/src/components/Typography/TYPOGRAPHY_IMPLEMENTATION_NOTES.md +17 -0
- package/src/components/Typography/Typography.module.css +13 -0
- package/src/components/Typography/Typography.test.tsx +1 -0
- package/src/components/Typography/Typography.tsx +43 -0
- package/src/components/Typography/USAGE.md +40 -0
- package/src/components/Typography/index.ts +1 -0
- package/src/components/index.ts +50 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +194 -0
- package/src/types/index.ts +9 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +23 -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 +143 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/renderRichOption.tsx +51 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Grid } from "./Grid";
|
|
4
|
+
import { Card } from "../Card/Card";
|
|
5
|
+
import { Text } from "../Text/Text";
|
|
6
|
+
|
|
7
|
+
type GridStoryProps = React.ComponentProps<typeof Grid>;
|
|
8
|
+
|
|
9
|
+
const meta: Meta<GridStoryProps> = {
|
|
10
|
+
title: "UI-Kit/Grid",
|
|
11
|
+
component: Grid,
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component:
|
|
17
|
+
"Grid is a 12-column (by default) responsive grid layout hand-composed from MUI's own Grid, providing column sizing, offsets, ordering, and breakpoint-based visibility using MUI's native prop names.",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
controls: {
|
|
21
|
+
include: ["children", "spacing", "columns", "direction", "wrap"],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
args: {
|
|
25
|
+
spacing: "rec-default",
|
|
26
|
+
columns: 12,
|
|
27
|
+
},
|
|
28
|
+
argTypes: {
|
|
29
|
+
spacing: {
|
|
30
|
+
control: "select",
|
|
31
|
+
options: [
|
|
32
|
+
"rec-none",
|
|
33
|
+
"rec-sm",
|
|
34
|
+
"rec-default",
|
|
35
|
+
"rec-md",
|
|
36
|
+
"rec-lg",
|
|
37
|
+
"rec-xl",
|
|
38
|
+
"rec-2xl",
|
|
39
|
+
],
|
|
40
|
+
description: "Space between columns",
|
|
41
|
+
},
|
|
42
|
+
columns: {
|
|
43
|
+
control: "number",
|
|
44
|
+
description: "Number of columns in each row",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default meta;
|
|
50
|
+
|
|
51
|
+
type Story = StoryObj<GridStoryProps>;
|
|
52
|
+
|
|
53
|
+
const Swatch = ({ children }: { children: React.ReactNode }) => (
|
|
54
|
+
<Card>
|
|
55
|
+
<Card.Content>
|
|
56
|
+
<Text>{children}</Text>
|
|
57
|
+
</Card.Content>
|
|
58
|
+
</Card>
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
export const Default: Story = {
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
63
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
64
|
+
<Grid {...args}>
|
|
65
|
+
<Grid.Col size={4}>
|
|
66
|
+
<Swatch>size 4</Swatch>
|
|
67
|
+
</Grid.Col>
|
|
68
|
+
<Grid.Col size={4}>
|
|
69
|
+
<Swatch>size 4</Swatch>
|
|
70
|
+
</Grid.Col>
|
|
71
|
+
<Grid.Col size={4}>
|
|
72
|
+
<Swatch>size 4</Swatch>
|
|
73
|
+
</Grid.Col>
|
|
74
|
+
</Grid>
|
|
75
|
+
),
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const ResponsiveSizes: Story = {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
80
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
81
|
+
<Grid {...args}>
|
|
82
|
+
<Grid.Col size={{ xs: 12, sm: 6, md: 3 }}>
|
|
83
|
+
<Swatch>xs 12 / sm 6 / md 3</Swatch>
|
|
84
|
+
</Grid.Col>
|
|
85
|
+
<Grid.Col size={{ xs: 12, sm: 6, md: 3 }}>
|
|
86
|
+
<Swatch>xs 12 / sm 6 / md 3</Swatch>
|
|
87
|
+
</Grid.Col>
|
|
88
|
+
<Grid.Col size={{ xs: 12, sm: 6, md: 3 }}>
|
|
89
|
+
<Swatch>xs 12 / sm 6 / md 3</Swatch>
|
|
90
|
+
</Grid.Col>
|
|
91
|
+
<Grid.Col size={{ xs: 12, sm: 6, md: 3 }}>
|
|
92
|
+
<Swatch>xs 12 / sm 6 / md 3</Swatch>
|
|
93
|
+
</Grid.Col>
|
|
94
|
+
</Grid>
|
|
95
|
+
),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const Offset: Story = {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
100
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
101
|
+
<Grid {...args}>
|
|
102
|
+
<Grid.Col size={4} offset={4}>
|
|
103
|
+
<Swatch>size 4, offset 4</Swatch>
|
|
104
|
+
</Grid.Col>
|
|
105
|
+
<Grid.Col size={4}>
|
|
106
|
+
<Swatch>size 4</Swatch>
|
|
107
|
+
</Grid.Col>
|
|
108
|
+
</Grid>
|
|
109
|
+
),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const Grow: Story = {
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
114
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
115
|
+
<Grid {...args}>
|
|
116
|
+
<Grid.Col size={3}>
|
|
117
|
+
<Swatch>size 3</Swatch>
|
|
118
|
+
</Grid.Col>
|
|
119
|
+
<Grid.Col size={3}>
|
|
120
|
+
<Swatch>size 3</Swatch>
|
|
121
|
+
</Grid.Col>
|
|
122
|
+
<Grid.Col size="grow">
|
|
123
|
+
<Swatch>size "grow" (fills remaining space)</Swatch>
|
|
124
|
+
</Grid.Col>
|
|
125
|
+
</Grid>
|
|
126
|
+
),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const CustomColumnCount: Story = {
|
|
130
|
+
args: {
|
|
131
|
+
columns: 6,
|
|
132
|
+
},
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
134
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
135
|
+
<Grid {...args}>
|
|
136
|
+
<Grid.Col size={2}>
|
|
137
|
+
<Swatch>size 2 of 6</Swatch>
|
|
138
|
+
</Grid.Col>
|
|
139
|
+
<Grid.Col size={2}>
|
|
140
|
+
<Swatch>size 2 of 6</Swatch>
|
|
141
|
+
</Grid.Col>
|
|
142
|
+
<Grid.Col size={2}>
|
|
143
|
+
<Swatch>size 2 of 6</Swatch>
|
|
144
|
+
</Grid.Col>
|
|
145
|
+
</Grid>
|
|
146
|
+
),
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const VisibleHiddenFrom: Story = {
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
151
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
152
|
+
<Grid {...args}>
|
|
153
|
+
<Grid.Col size={6} hiddenFrom="sm">
|
|
154
|
+
<Swatch>hidden from sm and up</Swatch>
|
|
155
|
+
</Grid.Col>
|
|
156
|
+
<Grid.Col size={6} visibleFrom="sm">
|
|
157
|
+
<Swatch>visible from sm and up</Swatch>
|
|
158
|
+
</Grid.Col>
|
|
159
|
+
</Grid>
|
|
160
|
+
),
|
|
161
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Grid component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid layout wrapper.
|
|
3
|
+
*
|
|
4
|
+
* MUI merges "container" and "item" into a single `Grid` component (no separate Grid.Col,
|
|
5
|
+
* unlike Mantine). To preserve the Grid/Grid.Col dot-notation shape across adapters, this
|
|
6
|
+
* file splits MUI's single component back into two thin wrappers: Grid always renders MUI's
|
|
7
|
+
* `<Grid container>`, GridCol always renders a plain MUI `<Grid>` (item mode).
|
|
8
|
+
*
|
|
9
|
+
* Per the layout-components rule, both wrappers simply pass through MUI's own Grid props
|
|
10
|
+
* (`size`, `offset`, `spacing`, `columns`, `direction`, `wrap`) with no Recursica renaming.
|
|
11
|
+
* MUI has no per-item "grow to fill remaining space" container flag like Mantine's `grow`;
|
|
12
|
+
* use MUI's own `size="grow"` on individual columns instead. `visibleFrom`/`hiddenFrom`
|
|
13
|
+
* don't exist in MUI at all, so — per the rule that a missing kit feature is built following
|
|
14
|
+
* Mantine's own shape — they're added here via CSS classes, keyed on MUI's own breakpoint
|
|
15
|
+
* scale (`xs`/`sm`/`md`/`lg`/`xl`).
|
|
16
|
+
*
|
|
17
|
+
* `justifyContent`/`alignItems` (container) and `order` (item) are typed on `MuiGridProps`
|
|
18
|
+
* (inherited generically from `SystemProps`) but MUI's Grid style generator — verified by
|
|
19
|
+
* reading `@mui/system`'s `gridGenerator.js`/`createGrid.js` — only wires up `size`, `offset`,
|
|
20
|
+
* `columns`, `spacing`/`rowSpacing`/`columnSpacing`, `direction`, and `wrap`; passing these
|
|
21
|
+
* three straight through would silently no-op. They're pulled out and applied via inline
|
|
22
|
+
* `style` instead, still using MUI's own native names.
|
|
23
|
+
*
|
|
24
|
+
* Like Flex, Stack, Group, and Container, this is a primitive layout component and
|
|
25
|
+
* does not use the `RecursicaOverStyled` gatekeeper — only the `sx` prop is stripped.
|
|
26
|
+
*/
|
|
27
|
+
import { forwardRef, type CSSProperties } from "react";
|
|
28
|
+
import { Grid as MuiGrid, type GridProps as MuiGridProps } from "@mui/material";
|
|
29
|
+
import {
|
|
30
|
+
SPACING_MAP,
|
|
31
|
+
type OmitSx,
|
|
32
|
+
filterSxProp,
|
|
33
|
+
type WithRecursicaSpacing,
|
|
34
|
+
} from "../../utils/filterStylingProps";
|
|
35
|
+
import styles from "./Grid.module.css";
|
|
36
|
+
|
|
37
|
+
type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl";
|
|
38
|
+
|
|
39
|
+
const HIDDEN_FROM_CLASS: Record<Breakpoint, string> = {
|
|
40
|
+
xs: styles.hiddenFromXs,
|
|
41
|
+
sm: styles.hiddenFromSm,
|
|
42
|
+
md: styles.hiddenFromMd,
|
|
43
|
+
lg: styles.hiddenFromLg,
|
|
44
|
+
xl: styles.hiddenFromXl,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// "xs" intentionally absent: visible from the smallest breakpoint means never hidden.
|
|
48
|
+
const VISIBLE_FROM_CLASS: Partial<Record<Breakpoint, string>> = {
|
|
49
|
+
sm: styles.visibleFromSm,
|
|
50
|
+
md: styles.visibleFromMd,
|
|
51
|
+
lg: styles.visibleFromLg,
|
|
52
|
+
xl: styles.visibleFromXl,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// ============================================================
|
|
56
|
+
// GRID
|
|
57
|
+
// ============================================================
|
|
58
|
+
|
|
59
|
+
export type GridProps = WithRecursicaSpacing<
|
|
60
|
+
OmitSx<Omit<MuiGridProps, "container" | "justifyContent" | "alignItems">>
|
|
61
|
+
> & {
|
|
62
|
+
/** Sets `justify-content` on the container. Applied via inline style — see notes above. */
|
|
63
|
+
justifyContent?: CSSProperties["justifyContent"];
|
|
64
|
+
/** Sets `align-items` on the container. Applied via inline style — see notes above. */
|
|
65
|
+
alignItems?: CSSProperties["alignItems"];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const GridBase = forwardRef<HTMLDivElement, GridProps>(function Grid(
|
|
69
|
+
{
|
|
70
|
+
children,
|
|
71
|
+
spacing = "rec-default",
|
|
72
|
+
justifyContent,
|
|
73
|
+
alignItems,
|
|
74
|
+
style,
|
|
75
|
+
...rest
|
|
76
|
+
},
|
|
77
|
+
ref,
|
|
78
|
+
) {
|
|
79
|
+
const safeProps = filterSxProp(rest as Record<string, unknown>);
|
|
80
|
+
const resolvedSpacing =
|
|
81
|
+
typeof spacing === "string" && spacing in SPACING_MAP
|
|
82
|
+
? SPACING_MAP[spacing as keyof typeof SPACING_MAP]
|
|
83
|
+
: spacing;
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<MuiGrid
|
|
87
|
+
ref={ref}
|
|
88
|
+
{...(safeProps as unknown as MuiGridProps)}
|
|
89
|
+
container
|
|
90
|
+
spacing={resolvedSpacing}
|
|
91
|
+
className={styles.root}
|
|
92
|
+
style={{ justifyContent, alignItems, ...(style as CSSProperties) }}
|
|
93
|
+
>
|
|
94
|
+
{children}
|
|
95
|
+
</MuiGrid>
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
GridBase.displayName = "Grid";
|
|
99
|
+
|
|
100
|
+
// ============================================================
|
|
101
|
+
// GRID.COL
|
|
102
|
+
// ============================================================
|
|
103
|
+
|
|
104
|
+
export type GridColProps = WithRecursicaSpacing<
|
|
105
|
+
OmitSx<Omit<MuiGridProps, "container" | "order">>
|
|
106
|
+
> & {
|
|
107
|
+
/** Sets the CSS `order` property. Applied via inline style — see notes above. */
|
|
108
|
+
order?: number;
|
|
109
|
+
/** Hides the column below the given breakpoint. MUI has no native equivalent. */
|
|
110
|
+
visibleFrom?: Breakpoint;
|
|
111
|
+
/** Hides the column above the given breakpoint. MUI has no native equivalent. */
|
|
112
|
+
hiddenFrom?: Breakpoint;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const GridCol = forwardRef<HTMLDivElement, GridColProps>(
|
|
116
|
+
function GridCol(
|
|
117
|
+
{ children, order, visibleFrom, hiddenFrom, style, className, ...rest },
|
|
118
|
+
ref,
|
|
119
|
+
) {
|
|
120
|
+
const safeProps = filterSxProp(rest as Record<string, unknown>);
|
|
121
|
+
|
|
122
|
+
const visibilityClass = visibleFrom
|
|
123
|
+
? VISIBLE_FROM_CLASS[visibleFrom]
|
|
124
|
+
: hiddenFrom
|
|
125
|
+
? HIDDEN_FROM_CLASS[hiddenFrom]
|
|
126
|
+
: undefined;
|
|
127
|
+
|
|
128
|
+
const finalClassName = [styles.col, visibilityClass, className]
|
|
129
|
+
.filter(Boolean)
|
|
130
|
+
.join(" ");
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<MuiGrid
|
|
134
|
+
ref={ref}
|
|
135
|
+
className={finalClassName}
|
|
136
|
+
{...(safeProps as unknown as MuiGridProps)}
|
|
137
|
+
style={{ order, ...(style as CSSProperties) }}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</MuiGrid>
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
GridCol.displayName = "GridCol";
|
|
145
|
+
|
|
146
|
+
// ============================================================
|
|
147
|
+
// DOT NOTATION EXPORT
|
|
148
|
+
// ============================================================
|
|
149
|
+
|
|
150
|
+
type GridComponent = typeof GridBase & {
|
|
151
|
+
Col: typeof GridCol;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const Grid = GridBase as GridComponent;
|
|
155
|
+
Grid.Col = GridCol;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Grid Implementation Notes
|
|
2
|
+
|
|
3
|
+
MUI has no native Grid/Grid.Col split — MUI's own `Grid` component merges "container" and "item" behavior into one component (toggled by the `container` boolean and a `size` prop). To keep the same `Grid` + `Grid.Col` dot-notation shape as the mantine-adapter, this file hand-composes two thin wrappers around that single underlying component: `Grid` always renders `<MuiGrid container>`, `Grid.Col` always renders `<MuiGrid>` in item mode. This is a structural convenience only — the props on each wrapper are MUI's own, not a Recursica-defined contract.
|
|
4
|
+
|
|
5
|
+
Per the layout-components rule (no formal Recursica common props definition — layout components simply pass through the underlying kit's own props), this Grid does **not** attempt prop-name parity with the mantine-adapter's Grid. Its public API is MUI's own vocabulary:
|
|
6
|
+
|
|
7
|
+
- **`spacing`** (not Mantine's `gutter`/the old Recursica `gap` alias) — MUI's own container-spacing prop. Still accepts `rec-*` tokens, resolved through the same `SPACING_MAP` lookup used elsewhere in this adapter.
|
|
8
|
+
- **`size`** (not Mantine's `span`) — MUI's own item-sizing prop on `Grid.Col`: a column count, `"auto"` (size to content), `"grow"` (fill remaining space), or a responsive object keyed by MUI's own breakpoints. No inversion/translation against Mantine's `span` semantics.
|
|
9
|
+
- **`offset`** — MUI's own prop, used as-is.
|
|
10
|
+
- **Breakpoint objects** use MUI's own scale (`xs`/`sm`/`md`/`lg`/`xl`) directly. There is no `"base"` alias — `xs` is MUI's smallest breakpoint, same role Mantine's own smallest breakpoint plays.
|
|
11
|
+
- **`grow` (container-level)**: not implemented. Mantine's container `grow` flag ("last row's columns expand to fill available space") has no MUI equivalent, but MUI's own `size="grow"` on individual `Grid.Col`s already covers the same real-world need — set it per-column instead of on the container.
|
|
12
|
+
- **`order`**: MUI types `order` generically (via `SystemProps`) but its Grid style generator (`gridGenerator.js`/`createGrid.js`, read directly to confirm) never wires it up — passing it straight through silently no-ops. Applied here via inline `style.order` instead, single value only (no per-breakpoint object).
|
|
13
|
+
- **`justifyContent` / `alignItems`** (container only): same issue as `order` — typed but not read by MUI's Grid generator (confirmed by reading `gridGenerator.js`: only `size`, `offset`, `columns`, spacing, `direction`, and `wrap` have generator functions). Applied via inline `style` instead, using MUI's own prop names (not Mantine's `justify`/`align`).
|
|
14
|
+
- **`visibleFrom` / `hiddenFrom`**: no native MUI Grid mechanism at all, so — per the rule that a missing kit feature is built following Mantine's own shape — implemented via `Grid.module.css` media-query classes, hardcoded to MUI's own default `theme.breakpoints` pixel values (`xs:0, sm:600, md:900, lg:1200, xl:1536`). If the consuming app customizes its MUI theme breakpoints, these thresholds won't follow — structural layout mechanics, not a design token.
|
|
15
|
+
|
|
16
|
+
**Cross-adapter parity caveat**: `visibleFrom`/`hiddenFrom` are pinned to MUI's default breakpoints here, while the mantine-adapter's equivalent behavior is driven by Mantine's own default breakpoints (576/768/992/1200/1408). The two adapters' Grid stories may show different columns at the exact same viewport width in the `adapter-tester` visual-regression suite as a result — a real, structural difference between the two underlying libraries' breakpoint scales, not a bug in either adapter. The two adapters' Grid APIs are also no longer prop-name-identical (`spacing`/`size` here vs. `gutter`/`span` in mantine-adapter) — this is intentional per the layout-components rule; each adapter's Grid speaks its own kit's vocabulary.
|
|
17
|
+
|
|
18
|
+
**Story parity exclude**: for the same `size`/`span` reason above, this story is named `ResponsiveSizes` here vs. mantine-adapter's `ResponsiveSpans` — different story ids. `ui-kit-grid--responsive-spans` is marked `exclude: true` in `adapter-tester.config.json`'s `story parity with source of truth` check rather than renamed to match, per developer direction (2026-08-30).
|
|
19
|
+
|
|
20
|
+
**Update (2026-08-30):** mantine-adapter now also has its own `ResponsiveSizes` story (using its
|
|
21
|
+
own `span` prop, same breakpoints/content as this one) purely so this adapter's `responsive-sizes`
|
|
22
|
+
story id has a source-of-truth golden to diff against — see mantine-adapter's own
|
|
23
|
+
`GRID_IMPLEMENTATION_NOTES.md`. The `responsive-spans`/`responsive-sizes` naming split itself is
|
|
24
|
+
unchanged/still intentional; this just closes the one-directional story-parity gap.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Grid - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Grid` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Grid } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Grid } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<Grid spacing="rec-default">
|
|
24
|
+
<Grid.Col size={6}>Half width</Grid.Col>
|
|
25
|
+
<Grid.Col size={{ xs: 12, sm: 6, md: 3 }}>Responsive width</Grid.Col>
|
|
26
|
+
</Grid>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Design System Integration
|
|
34
|
+
|
|
35
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
36
|
+
|
|
37
|
+
> [!IMPORTANT]
|
|
38
|
+
>
|
|
39
|
+
> - **Anti-override protection**: `Grid` is a primitive layout component (see [OVERSTYLING.md](../../../OVERSTYLING.md)) — only the `sx` prop is stripped, everything else passes through freely without needing `overStyled`.
|
|
40
|
+
> - **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.
|
|
41
|
+
> - **Variables and Theming**: Spacing is entirely determined by the `rec-*` token scale, mapped transparently to MUI's `spacing` value.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 4. Key Integration Features & Constraints
|
|
46
|
+
|
|
47
|
+
This Grid uses MUI's own prop vocabulary directly (see [IMPLEMENTATION_NOTES.md](./IMPLEMENTATION_NOTES.md)) — it is not name-for-name identical to the mantine-adapter's Grid.
|
|
48
|
+
|
|
49
|
+
- `spacing` controls the space between grid items (accepts `rec-*` tokens).
|
|
50
|
+
- `size` accepts a column count, `"auto"`, `"grow"`, or a responsive object (`{ xs, sm, md, ... }`).
|
|
51
|
+
- `offset` shifts a column by a number of columns.
|
|
52
|
+
- `order` accepts a fixed number to control a column's visual order (single value only, no responsive object).
|
|
53
|
+
- `visibleFrom`/`hiddenFrom` show or hide a column at the standard breakpoints (600/900/1200/1536px).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Grid";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Group } from "./Group";
|
|
4
|
+
import { Button } from "../Button";
|
|
5
|
+
import { Text } from "../Text/Text";
|
|
6
|
+
|
|
7
|
+
type GroupStoryProps = React.ComponentProps<typeof Group>;
|
|
8
|
+
|
|
9
|
+
const meta: Meta<GroupStoryProps> = {
|
|
10
|
+
title: "UI-Kit/Group",
|
|
11
|
+
component: Group,
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component:
|
|
17
|
+
"Group is a flex horizontal layout container that maps directly to Mantine's Group component allowing safe layout property passing.",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
args: {
|
|
22
|
+
gap: "rec-default",
|
|
23
|
+
align: "center",
|
|
24
|
+
justify: "flex-start",
|
|
25
|
+
wrap: "wrap",
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
gap: {
|
|
29
|
+
control: "select",
|
|
30
|
+
options: [
|
|
31
|
+
"rec-none",
|
|
32
|
+
"rec-sm",
|
|
33
|
+
"rec-default",
|
|
34
|
+
"rec-md",
|
|
35
|
+
"rec-lg",
|
|
36
|
+
"rec-xl",
|
|
37
|
+
"rec-2xl",
|
|
38
|
+
"xs",
|
|
39
|
+
"sm",
|
|
40
|
+
"md",
|
|
41
|
+
"lg",
|
|
42
|
+
"xl",
|
|
43
|
+
],
|
|
44
|
+
description: "Gap between elements",
|
|
45
|
+
},
|
|
46
|
+
align: {
|
|
47
|
+
control: "select",
|
|
48
|
+
options: ["flex-start", "center", "flex-end", "stretch"],
|
|
49
|
+
description: "Align-items property",
|
|
50
|
+
},
|
|
51
|
+
justify: {
|
|
52
|
+
control: "select",
|
|
53
|
+
options: [
|
|
54
|
+
"flex-start",
|
|
55
|
+
"center",
|
|
56
|
+
"flex-end",
|
|
57
|
+
"space-between",
|
|
58
|
+
"space-around",
|
|
59
|
+
],
|
|
60
|
+
description: "Justify-content property",
|
|
61
|
+
},
|
|
62
|
+
wrap: {
|
|
63
|
+
control: "select",
|
|
64
|
+
options: ["wrap", "nowrap", "wrap-reverse"],
|
|
65
|
+
description: "Flex-wrap property",
|
|
66
|
+
},
|
|
67
|
+
defaultChecked: {
|
|
68
|
+
table: { disable: true },
|
|
69
|
+
},
|
|
70
|
+
rowGap: {
|
|
71
|
+
table: { disable: true },
|
|
72
|
+
},
|
|
73
|
+
columnGap: {
|
|
74
|
+
table: { disable: true },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default meta;
|
|
80
|
+
|
|
81
|
+
type Story = StoryObj<GroupStoryProps>;
|
|
82
|
+
|
|
83
|
+
export const Default: Story = {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
85
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
86
|
+
<Group {...args}>
|
|
87
|
+
<Button variant="solid">Primary</Button>
|
|
88
|
+
<Button variant="outline">Secondary</Button>
|
|
89
|
+
<Text>Text element within Group</Text>
|
|
90
|
+
</Group>
|
|
91
|
+
),
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const StaticGapSmall: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
gap: "rec-sm",
|
|
97
|
+
},
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
99
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
100
|
+
<Group {...args}>
|
|
101
|
+
<Button variant="solid">Item 1</Button>
|
|
102
|
+
<Button variant="solid">Item 2</Button>
|
|
103
|
+
<Button variant="solid">Item 3</Button>
|
|
104
|
+
</Group>
|
|
105
|
+
),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const StaticGapLarge: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
gap: "rec-xl",
|
|
111
|
+
},
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
113
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
114
|
+
<Group {...args}>
|
|
115
|
+
<Button variant="solid">Item 1</Button>
|
|
116
|
+
<Button variant="solid">Item 2</Button>
|
|
117
|
+
<Button variant="solid">Item 3</Button>
|
|
118
|
+
</Group>
|
|
119
|
+
),
|
|
120
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Group component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group layout wrapper.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: MUI has no native `<Group>` component. Per the layout-components rule, when a UI kit
|
|
5
|
+
* lacks an equivalent component it's built following a prop definition similar to Mantine's
|
|
6
|
+
* own `Group` (gap/rowGap/columnGap/justify/align/wrap) — this shape is owned locally here,
|
|
7
|
+
* not shared as a formal cross-adapter Recursica contract. It's implemented as a row-direction,
|
|
8
|
+
* wrapping MUI `Stack`.
|
|
9
|
+
*/
|
|
10
|
+
import { forwardRef } from "react";
|
|
11
|
+
import {
|
|
12
|
+
Stack as MUIStack,
|
|
13
|
+
type StackProps as MUIStackProps,
|
|
14
|
+
} from "@mui/material";
|
|
15
|
+
import {
|
|
16
|
+
SPACING_MAP,
|
|
17
|
+
type OmitSx,
|
|
18
|
+
filterSxProp,
|
|
19
|
+
type WithRecursicaSpacing,
|
|
20
|
+
} from "../../utils/filterStylingProps";
|
|
21
|
+
|
|
22
|
+
interface GroupOwnProps {
|
|
23
|
+
/** Gap spacing */
|
|
24
|
+
gap?: string | number;
|
|
25
|
+
/** Row gap spacing */
|
|
26
|
+
rowGap?: string | number;
|
|
27
|
+
/** Column gap spacing */
|
|
28
|
+
columnGap?: string | number;
|
|
29
|
+
/** Align items justify properties */
|
|
30
|
+
justify?: React.CSSProperties["justifyContent"];
|
|
31
|
+
/** Align items vertical alignment */
|
|
32
|
+
align?: React.CSSProperties["alignItems"];
|
|
33
|
+
/** Flex-wrap settings */
|
|
34
|
+
wrap?: React.CSSProperties["flexWrap"];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type GroupProps = WithRecursicaSpacing<
|
|
38
|
+
OmitSx<Omit<MUIStackProps, "spacing" | "direction"> & GroupOwnProps>
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
|
|
42
|
+
{
|
|
43
|
+
children,
|
|
44
|
+
gap = "rec-default",
|
|
45
|
+
rowGap,
|
|
46
|
+
columnGap,
|
|
47
|
+
justify,
|
|
48
|
+
align,
|
|
49
|
+
wrap,
|
|
50
|
+
...rest
|
|
51
|
+
},
|
|
52
|
+
ref,
|
|
53
|
+
) {
|
|
54
|
+
const safeProps = filterSxProp(rest as Record<string, unknown>);
|
|
55
|
+
// MUI's `sx`/system props treat spacing shorthands (`gap`, margin/padding
|
|
56
|
+
// shorthands like `mt`, `p`, ...) as multiples of the theme's 8px unit
|
|
57
|
+
// (e.g. `gap={8}` -> 64px, `mt={24}` -> 192px). Mantine's `Group` takes a
|
|
58
|
+
// raw number as literal pixels, so numeric values must be stringified to
|
|
59
|
+
// `px` here to opt out of that multiplication and keep parity.
|
|
60
|
+
const resolveGap = (value: string | number | undefined) => {
|
|
61
|
+
if (typeof value === "string" && value in SPACING_MAP) {
|
|
62
|
+
return SPACING_MAP[value as keyof typeof SPACING_MAP];
|
|
63
|
+
}
|
|
64
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
65
|
+
};
|
|
66
|
+
const resolvedGap = resolveGap(gap);
|
|
67
|
+
const resolvedRowGap = resolveGap(rowGap);
|
|
68
|
+
const resolvedColumnGap = resolveGap(columnGap);
|
|
69
|
+
|
|
70
|
+
const MARGIN_PADDING_KEYS = [
|
|
71
|
+
"m",
|
|
72
|
+
"mt",
|
|
73
|
+
"mr",
|
|
74
|
+
"mb",
|
|
75
|
+
"ml",
|
|
76
|
+
"mx",
|
|
77
|
+
"my",
|
|
78
|
+
"p",
|
|
79
|
+
"pt",
|
|
80
|
+
"pr",
|
|
81
|
+
"pb",
|
|
82
|
+
"pl",
|
|
83
|
+
"px",
|
|
84
|
+
"py",
|
|
85
|
+
] as const;
|
|
86
|
+
for (const key of MARGIN_PADDING_KEYS) {
|
|
87
|
+
const value = safeProps[key];
|
|
88
|
+
if (typeof value === "number") {
|
|
89
|
+
safeProps[key] = `${value}px`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<MUIStack
|
|
95
|
+
ref={ref}
|
|
96
|
+
{...safeProps}
|
|
97
|
+
direction="row"
|
|
98
|
+
flexWrap={wrap || "wrap"}
|
|
99
|
+
justifyContent={justify}
|
|
100
|
+
alignItems={align}
|
|
101
|
+
sx={{
|
|
102
|
+
// Set gap directly instead of MUI Stack's `spacing` prop: `spacing`
|
|
103
|
+
// multiplies numeric values by the theme's 8px spacing unit (e.g.
|
|
104
|
+
// `gap={8}` -> 64px), while Mantine's `Group` treats a raw number as
|
|
105
|
+
// literal pixels. Using `sx.gap` keeps numeric/px/token values 1:1.
|
|
106
|
+
gap: resolvedGap,
|
|
107
|
+
...(resolvedRowGap ? { rowGap: resolvedRowGap } : {}),
|
|
108
|
+
...(resolvedColumnGap ? { columnGap: resolvedColumnGap } : {}),
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{children}
|
|
112
|
+
</MUIStack>
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
Group.displayName = "Group";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Group - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Group` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Group } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Group } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<Group gap="md" align="center">
|
|
24
|
+
<Button variant="secondary">Cancel</Button>
|
|
25
|
+
<Button variant="primary">Submit</Button>
|
|
26
|
+
</Group>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Design System Integration
|
|
34
|
+
|
|
35
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
36
|
+
|
|
37
|
+
> [!IMPORTANT]
|
|
38
|
+
>
|
|
39
|
+
> - **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.
|
|
40
|
+
> - **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.
|
|
41
|
+
> - **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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Group";
|