@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,250 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Table as MuiTable,
|
|
4
|
+
type TableProps as MuiTableProps,
|
|
5
|
+
TableBody as MuiTableBody,
|
|
6
|
+
type TableBodyProps as MuiTableBodyProps,
|
|
7
|
+
TableCell as MuiTableCell,
|
|
8
|
+
type TableCellProps as MuiTableCellProps,
|
|
9
|
+
TableContainer as MuiTableContainer,
|
|
10
|
+
type TableContainerProps as MuiTableContainerProps,
|
|
11
|
+
TableHead as MuiTableHead,
|
|
12
|
+
type TableHeadProps as MuiTableHeadProps,
|
|
13
|
+
TableRow as MuiTableRow,
|
|
14
|
+
type TableRowProps as MuiTableRowProps,
|
|
15
|
+
TableFooter as MuiTableFooter,
|
|
16
|
+
type TableFooterProps as MuiTableFooterProps,
|
|
17
|
+
TableSortLabel as MuiTableSortLabel,
|
|
18
|
+
type TableSortLabelProps as MuiTableSortLabelProps,
|
|
19
|
+
} from "@mui/material";
|
|
20
|
+
import {
|
|
21
|
+
filterStylingProps,
|
|
22
|
+
type RecursicaOverStyled,
|
|
23
|
+
} from "../../utils/filterStylingProps";
|
|
24
|
+
import {
|
|
25
|
+
type RecursicaTableProps,
|
|
26
|
+
type RecursicaTableRowProps,
|
|
27
|
+
type RecursicaTableHeaderCellProps,
|
|
28
|
+
type RecursicaTableCellProps,
|
|
29
|
+
} from "@recursica/adapter-common";
|
|
30
|
+
import styles from "./Table.module.css";
|
|
31
|
+
|
|
32
|
+
/** Merges a Recursica-controlled `className` with a caller-supplied one, same idiom as `TableBase`. */
|
|
33
|
+
function withRootClass(rootClass: string, classNameProp: string | undefined) {
|
|
34
|
+
return classNameProp ? `${rootClass} ${classNameProp}` : rootClass;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type TableProps = RecursicaOverStyled<
|
|
38
|
+
MuiTableProps & RecursicaTableProps
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
const TableBase = forwardRef<HTMLTableElement, TableProps>(function Table(
|
|
42
|
+
{ overStyled = false, ...rest },
|
|
43
|
+
ref,
|
|
44
|
+
) {
|
|
45
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
46
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
47
|
+
.className as string | undefined;
|
|
48
|
+
|
|
49
|
+
const rootClass = styles.root;
|
|
50
|
+
const finalClass = classNameProp
|
|
51
|
+
? `${rootClass} ${classNameProp}`
|
|
52
|
+
: rootClass;
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<MuiTable
|
|
56
|
+
ref={ref}
|
|
57
|
+
{...(sanitizedProps as unknown as MuiTableProps)}
|
|
58
|
+
className={finalClass}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
TableBase.displayName = "Table";
|
|
64
|
+
|
|
65
|
+
// ==== EXPLICIT DOT-NOTATION SUB-COMPONENTS ====
|
|
66
|
+
// Each sub-component is wrapped independently so it goes through
|
|
67
|
+
// filterStylingProps/overStyled the same way the root Table does.
|
|
68
|
+
|
|
69
|
+
export type TableBodyPropsRecursica = RecursicaOverStyled<MuiTableBodyProps>;
|
|
70
|
+
|
|
71
|
+
export const TableBodyComponent = forwardRef<
|
|
72
|
+
HTMLTableSectionElement,
|
|
73
|
+
TableBodyPropsRecursica
|
|
74
|
+
>(function TableBody({ overStyled = false, ...rest }, ref) {
|
|
75
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
76
|
+
return (
|
|
77
|
+
<MuiTableBody
|
|
78
|
+
ref={ref}
|
|
79
|
+
{...(sanitizedProps as unknown as MuiTableBodyProps)}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
TableBodyComponent.displayName = "TableBody";
|
|
84
|
+
|
|
85
|
+
// MUI's `TableCell` is the single primitive used for header, body, and footer cells alike — it
|
|
86
|
+
// auto-detects which one it is (and whether to render a `<th>` or `<td>`) from its ancestor
|
|
87
|
+
// (`Table.Head`/`Table.Body`/`Table.Footer`). Recursica mirrors that: one cell component whose
|
|
88
|
+
// props cover both the header-only concern (`sorted`) and the body/footer concern (`variant`).
|
|
89
|
+
export type TableCellPropsRecursica = RecursicaOverStyled<
|
|
90
|
+
// MUI's own `variant` ('head' | 'body' | 'footer') is superseded by Recursica's `variant`
|
|
91
|
+
// ('default' | 'currency') — MUI still auto-detects head/body/footer from ancestor context
|
|
92
|
+
// when its native `variant` prop is omitted, so nothing is lost by dropping it here.
|
|
93
|
+
Omit<MuiTableCellProps, "children" | "variant"> &
|
|
94
|
+
RecursicaTableHeaderCellProps &
|
|
95
|
+
RecursicaTableCellProps
|
|
96
|
+
>;
|
|
97
|
+
|
|
98
|
+
export const TableCellComponent = forwardRef<
|
|
99
|
+
HTMLTableCellElement,
|
|
100
|
+
TableCellPropsRecursica
|
|
101
|
+
>(function TableCell(
|
|
102
|
+
{
|
|
103
|
+
overStyled = false,
|
|
104
|
+
sorted = false,
|
|
105
|
+
disabled = false,
|
|
106
|
+
variant = "default",
|
|
107
|
+
...rest
|
|
108
|
+
},
|
|
109
|
+
ref,
|
|
110
|
+
) {
|
|
111
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
112
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
113
|
+
.className as string | undefined;
|
|
114
|
+
return (
|
|
115
|
+
<MuiTableCell
|
|
116
|
+
ref={ref}
|
|
117
|
+
{...(sanitizedProps as unknown as MuiTableCellProps)}
|
|
118
|
+
className={withRootClass(styles.cell, classNameProp)}
|
|
119
|
+
data-sorted={sorted ? "true" : undefined}
|
|
120
|
+
data-disabled={disabled ? "true" : undefined}
|
|
121
|
+
data-currency={variant === "currency" ? "true" : undefined}
|
|
122
|
+
aria-sort={
|
|
123
|
+
sorted === "asc"
|
|
124
|
+
? "ascending"
|
|
125
|
+
: sorted === "desc"
|
|
126
|
+
? "descending"
|
|
127
|
+
: undefined
|
|
128
|
+
}
|
|
129
|
+
/>
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
TableCellComponent.displayName = "TableCell";
|
|
133
|
+
|
|
134
|
+
export type TableContainerPropsRecursica =
|
|
135
|
+
RecursicaOverStyled<MuiTableContainerProps>;
|
|
136
|
+
|
|
137
|
+
export const TableContainerComponent = forwardRef<
|
|
138
|
+
HTMLDivElement,
|
|
139
|
+
TableContainerPropsRecursica
|
|
140
|
+
>(function TableContainer({ overStyled = false, ...rest }, ref) {
|
|
141
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
142
|
+
return (
|
|
143
|
+
<MuiTableContainer
|
|
144
|
+
ref={ref}
|
|
145
|
+
{...(sanitizedProps as unknown as MuiTableContainerProps)}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
TableContainerComponent.displayName = "TableContainer";
|
|
150
|
+
|
|
151
|
+
export type TableHeadPropsRecursica = RecursicaOverStyled<MuiTableHeadProps>;
|
|
152
|
+
|
|
153
|
+
export const TableHeadComponent = forwardRef<
|
|
154
|
+
HTMLTableSectionElement,
|
|
155
|
+
TableHeadPropsRecursica
|
|
156
|
+
>(function TableHead({ overStyled = false, ...rest }, ref) {
|
|
157
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
158
|
+
return (
|
|
159
|
+
<MuiTableHead
|
|
160
|
+
ref={ref}
|
|
161
|
+
{...(sanitizedProps as unknown as MuiTableHeadProps)}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
TableHeadComponent.displayName = "TableHead";
|
|
166
|
+
|
|
167
|
+
export type TableRowPropsRecursica = RecursicaOverStyled<
|
|
168
|
+
Omit<MuiTableRowProps, "children"> & RecursicaTableRowProps
|
|
169
|
+
>;
|
|
170
|
+
|
|
171
|
+
export const TableRowComponent = forwardRef<
|
|
172
|
+
HTMLTableRowElement,
|
|
173
|
+
TableRowPropsRecursica
|
|
174
|
+
>(function TableRow(
|
|
175
|
+
{ overStyled = false, selected = false, disabled = false, ...rest },
|
|
176
|
+
ref,
|
|
177
|
+
) {
|
|
178
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
179
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
180
|
+
.className as string | undefined;
|
|
181
|
+
return (
|
|
182
|
+
<MuiTableRow
|
|
183
|
+
ref={ref}
|
|
184
|
+
{...(sanitizedProps as unknown as MuiTableRowProps)}
|
|
185
|
+
className={withRootClass(styles.row, classNameProp)}
|
|
186
|
+
selected={selected}
|
|
187
|
+
data-selected={selected ? "true" : undefined}
|
|
188
|
+
data-disabled={disabled ? "true" : undefined}
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
TableRowComponent.displayName = "TableRow";
|
|
193
|
+
|
|
194
|
+
export type TableFooterPropsRecursica =
|
|
195
|
+
RecursicaOverStyled<MuiTableFooterProps>;
|
|
196
|
+
|
|
197
|
+
export const TableFooterComponent = forwardRef<
|
|
198
|
+
HTMLTableSectionElement,
|
|
199
|
+
TableFooterPropsRecursica
|
|
200
|
+
>(function TableFooter({ overStyled = false, ...rest }, ref) {
|
|
201
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
202
|
+
return (
|
|
203
|
+
<MuiTableFooter
|
|
204
|
+
ref={ref}
|
|
205
|
+
{...(sanitizedProps as unknown as MuiTableFooterProps)}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
TableFooterComponent.displayName = "TableFooter";
|
|
210
|
+
|
|
211
|
+
export type TableSortLabelPropsRecursica =
|
|
212
|
+
RecursicaOverStyled<MuiTableSortLabelProps>;
|
|
213
|
+
|
|
214
|
+
export const TableSortLabelComponent = forwardRef<
|
|
215
|
+
HTMLSpanElement,
|
|
216
|
+
TableSortLabelPropsRecursica
|
|
217
|
+
>(function TableSortLabel({ overStyled = false, ...rest }, ref) {
|
|
218
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
219
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
220
|
+
.className as string | undefined;
|
|
221
|
+
return (
|
|
222
|
+
<MuiTableSortLabel
|
|
223
|
+
ref={ref}
|
|
224
|
+
{...(sanitizedProps as unknown as MuiTableSortLabelProps)}
|
|
225
|
+
className={withRootClass(styles.sortLabel, classNameProp)}
|
|
226
|
+
/>
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
TableSortLabelComponent.displayName = "TableSortLabel";
|
|
230
|
+
|
|
231
|
+
// ==== DOT NOTATION EXPORT ====
|
|
232
|
+
|
|
233
|
+
type TableComponent = typeof TableBase & {
|
|
234
|
+
Body: typeof TableBodyComponent;
|
|
235
|
+
Cell: typeof TableCellComponent;
|
|
236
|
+
Container: typeof TableContainerComponent;
|
|
237
|
+
Head: typeof TableHeadComponent;
|
|
238
|
+
Row: typeof TableRowComponent;
|
|
239
|
+
Footer: typeof TableFooterComponent;
|
|
240
|
+
SortLabel: typeof TableSortLabelComponent;
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export const Table = TableBase as TableComponent;
|
|
244
|
+
Table.Body = TableBodyComponent;
|
|
245
|
+
Table.Cell = TableCellComponent;
|
|
246
|
+
Table.Container = TableContainerComponent;
|
|
247
|
+
Table.Head = TableHeadComponent;
|
|
248
|
+
Table.Row = TableRowComponent;
|
|
249
|
+
Table.Footer = TableFooterComponent;
|
|
250
|
+
Table.SortLabel = TableSortLabelComponent;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Table - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Table` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Table } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Table } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<Table.Container>
|
|
24
|
+
<Table>
|
|
25
|
+
<Table.Head>
|
|
26
|
+
<Table.Row>
|
|
27
|
+
<Table.Cell>Name</Table.Cell>
|
|
28
|
+
<Table.Cell>Email</Table.Cell>
|
|
29
|
+
</Table.Row>
|
|
30
|
+
</Table.Head>
|
|
31
|
+
<Table.Body>
|
|
32
|
+
<Table.Row>
|
|
33
|
+
<Table.Cell>Jane Doe</Table.Cell>
|
|
34
|
+
<Table.Cell>jane@example.com</Table.Cell>
|
|
35
|
+
</Table.Row>
|
|
36
|
+
</Table.Body>
|
|
37
|
+
</Table>
|
|
38
|
+
</Table.Container>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. Row and Cell States
|
|
46
|
+
|
|
47
|
+
- **`Table.Row`**: `selected` applies the selected-row background (and MUI's own `selected`/`aria-selected`); `disabled` dims the row and applies the disabled cell colors to every cell in it.
|
|
48
|
+
- **`Table.Cell`**: `sorted="asc" | "desc"` applies the sorted header style (pair with `Table.SortLabel` for the actual sort icon — see below); `variant="currency"` applies the currency text style, right-aligning it in any context (header, body, or footer); `disabled` dims the cell.
|
|
49
|
+
- **`Table.SortLabel`** (wraps MUI's `TableSortLabel`): renders the actual sort arrow. Compose it inside a `Table.Cell` the same way MUI's own docs do.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<Table.Head>
|
|
53
|
+
<Table.Row>
|
|
54
|
+
<Table.Cell>Name</Table.Cell>
|
|
55
|
+
<Table.Cell sorted="asc" variant="currency">
|
|
56
|
+
<Table.SortLabel active direction="asc">
|
|
57
|
+
Balance
|
|
58
|
+
</Table.SortLabel>
|
|
59
|
+
</Table.Cell>
|
|
60
|
+
</Table.Row>
|
|
61
|
+
</Table.Head>
|
|
62
|
+
<Table.Body>
|
|
63
|
+
<Table.Row selected>
|
|
64
|
+
<Table.Cell>Jane Doe</Table.Cell>
|
|
65
|
+
<Table.Cell variant="currency">$1,204.50</Table.Cell>
|
|
66
|
+
</Table.Row>
|
|
67
|
+
<Table.Row disabled>
|
|
68
|
+
<Table.Cell>Inactive Account</Table.Cell>
|
|
69
|
+
<Table.Cell variant="currency">$0.00</Table.Cell>
|
|
70
|
+
</Table.Row>
|
|
71
|
+
</Table.Body>
|
|
72
|
+
<Table.Footer>
|
|
73
|
+
<Table.Row>
|
|
74
|
+
<Table.Cell>Total</Table.Cell>
|
|
75
|
+
<Table.Cell variant="currency">$1,204.50</Table.Cell>
|
|
76
|
+
</Table.Row>
|
|
77
|
+
</Table.Footer>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 4. Design System Integration
|
|
83
|
+
|
|
84
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
85
|
+
|
|
86
|
+
> [!IMPORTANT]
|
|
87
|
+
>
|
|
88
|
+
> - **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.
|
|
89
|
+
> - **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.
|
|
90
|
+
> - **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 "./Table";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Tabs Implementation Notes
|
|
2
|
+
|
|
3
|
+
- **Compositional API Dropped:** Mantine uses `<Tabs.List>`, `<Tabs.Tab>`, and `<Tabs.Panel>` natively with implicit context from `<Tabs>`. MUI relies on `@mui/lab/TabContext` and separates `Tabs` and `TabPanel`.
|
|
4
|
+
- **Monolithic API Adopted:** Following architectural review, we have opted to drop the broken dot-notation wrappers for `adapter-mui-v7`. We now natively export `Tabs` (MUI List), `Tab` (MUI Item), and `TabPanel` (from `@mui/lab`). Developers must use `TabContext` (from `@mui/lab`) to manage state, just like native MUI. Storybook and visual regression tests have been updated to reflect this divergence while retaining core property mapping compatibility.
|
|
5
|
+
|
|
6
|
+
## Traps found via adapter-tester parity fixing (2026-08-15)
|
|
7
|
+
|
|
8
|
+
- **`Tabs` doesn't read `TabContext`:** only `TabPanel` (from `@mui/lab`) consumes it. `Tabs` (from `@mui/material`) needs its own explicit `value` prop or every tab renders permanently unselected (no error, just silently inert). See USAGE.md's warning callout.
|
|
9
|
+
- **`TabPanel` is a DOM sibling of `Tabs`, not nested inside it:** any `.root .panel`-style descendant selector in this file silently never matches. Scope panel rules off the bare class instead. Consumers must also wrap both in their own column-direction container (Storybook does this via `Flex`) — otherwise the panel renders beside the tab list, not below it, because there's nothing else establishing the block stacking.
|
|
10
|
+
- **`.Mui-selected` needs `:global(...)`:** written bare in a `.module.css` file, CSS Modules locally scopes it to something like `.Tabs-module__Mui-selected___xxx`, which never matches the real MUI-applied class. Every reference to a native MUI state class in this file must be `:global(.Mui-selected)`, not `.Mui-selected`. (SegmentedControl's `.control.Mui-selected` has this exact same latent bug — not fixed as part of this pass, flagged separately.)
|
|
11
|
+
- **MUI's Tab defaults to `min-height: 72px`** for icon+label tabs (48px otherwise); Mantine's tab height is purely padding/content-driven. Reset to `min-height: auto` or the whole row renders visibly taller than Mantine's.
|
|
12
|
+
- **MUI's `TabPanel` defaults to `padding: theme.spacing(3)` (24px)**; Mantine's `Tabs.Panel` has none — the gap is already carried by `.list`'s own margin. Reset to `padding: 0`.
|
|
13
|
+
- **The indicator (`classes.indicator`) is absolutely positioned against `.MuiTabs-root`, not `.list`:** `.list`'s own `margin-bottom` (the tabs-content-gap) collapses into that root's auto height instead of stopping at `.list`'s border edge, so the indicator's default `bottom: 0` lands one content-gap below the baseline. Offset it by the same content-gap token to bring it flush again.
|
|
14
|
+
- **All of the above needed `!important`** to reliably beat MUI's own emotion-injected styles for the same property — plain specificity/cascade order wasn't sufficient in this build.
|
|
15
|
+
|
|
16
|
+
## Follow-up parity fixes (2026-08-18)
|
|
17
|
+
|
|
18
|
+
- **`MuiTouchRipple-root` gets caught by `.root .tab > *`:** that rule exists to lift real content (icon/label) above the hover overlay's `z-index`, but it also matches the ripple span MUI injects into the tab on first click. Forcing that span from its native `position: absolute` to `position: relative` turns it into a real flex item, inserting one extra `--tabs-element-gap` into the tab's flex row and permanently growing the tab's width (it never gets removed from the DOM after the ripple animation ends) — this was the cause of a layout shift where selecting a tab pushed later siblings sideways. Excluded via `:not(:global(.MuiTouchRipple-root))`.
|
|
19
|
+
- **Outline's selected-tab border can't be "erased" with a same-element pseudo-element:** the open edge (0 border-width on the side touching the list's baseline) leaves the list's own `border-bottom`/`border-right` showing through, because that border is a real CSS border appended outside the tab's box, not an inset overlay sharing the tab's own bottom edge (unlike Mantine, where the list-baseline wrapper and the tab share the same reference edge, so the tab's own border naturally paints over it). A `::after` patch on the tab itself can't fix this either: MUI gives `Tab` (`ButtonBase`) `overflow: hidden` natively (to contain the ripple), which clips away anything extending past the tab's own box before it ever reaches the list's border. Fixed by repurposing the indicator element (`classes.indicator`) instead — it already lives in the scroller (a sibling of `.list`, not clipped) and MUI already keeps its position/size in sync with whichever tab is selected, so it just needed restyling into a small opaque patch instead of being `display: none`.
|
|
20
|
+
- **That patch needs a real opaque color, not the tab's own token:** outline's active background-color token is `transparent` by design (it's meant to let the ambient Layer surface show through), so it can't double as the eraser — painting "transparent over transparent" does nothing. Used `--recursica_brand_layer_0_properties_surface` (the default/outermost Layer surface) instead, since that's what a Tabs instance sits on absent an explicit wrapping `<Layer>`. This is an inherent approximation, same category as Mantine's own equivalent trick (which hardcodes `--mantine-color-body`): if a consumer nests outline Tabs inside a `<Layer layer={1|2|3}>`, the patch will mismatch that surface's color. No generic "current ambient layer" token exists in the schema to fix this properly — flagged for whoever owns the token schema.
|
|
21
|
+
- **Vertical `.list` doesn't stretch to the root's full height:** Mantine's vertical `.list` stretches via flex `align-items`, so its `border-right` divider runs the whole rail. MUI's scroller (the `.list`'s parent) is a plain block for vertical, not a flex container, so `.list` sizes to just its stacked tab content and the divider stopped at the last tab. Fixed with an explicit `height: 100%` on `.list` for vertical orientation.
|
|
22
|
+
- **Vertical indicator needs the same content-gap offset as horizontal, rotated 90°:** the list's `margin-right` (vertical's tabs-content-gap) inflates the root's auto width past the list's own border-right edge, same mechanism as the existing horizontal `bottom` offset trick — without a matching `right` offset, the indicator renders content-gap pixels to the right of the divider instead of on it.
|
|
23
|
+
|
|
24
|
+
## `inverted` never actually moved the tab list below the content (2026-08-30, source-of-truth audit)
|
|
25
|
+
|
|
26
|
+
**Reported symptom:** in the `Inverted` story, content should render above the tab list (tabs
|
|
27
|
+
below), with padding between them — the padding looked missing "when content is on top".
|
|
28
|
+
|
|
29
|
+
**What was actually happening (both adapters):** `inverted` already worked for its _documented_
|
|
30
|
+
scope — flipping the active-indicator line and border-radius direction (top vs bottom) via
|
|
31
|
+
`data-inverted` selectors already in this file — but neither adapter actually repositioned the
|
|
32
|
+
tab list below the panel content. The story always renders `<Tabs>` before `<TabPanel>` in JSX
|
|
33
|
+
regardless of `inverted`, so "padding missing when content is on top" wasn't reproducible as
|
|
34
|
+
such: content was never on top to begin with, in either adapter, before this fix.
|
|
35
|
+
|
|
36
|
+
**Fix:** per USAGE.md, consumers already wrap `Tabs`+`TabPanel` in their own column-direction
|
|
37
|
+
`Flex` — meaning this component's own root and each `TabPanel` are real flex siblings under that
|
|
38
|
+
consumer container. Added `.root[data-orientation="horizontal"][data-inverted] { order: 1; }`
|
|
39
|
+
(scoped to horizontal only — vertical's "instead of left" flip isn't exercised by any story) so
|
|
40
|
+
the tab list visually moves after every `TabPanel` (which stay default `order: 0`) with zero DOM
|
|
41
|
+
changes. Also introduced a shared `--tabs-content-gap` custom property per variant (previously
|
|
42
|
+
each variant inlined its own long token reference directly into `.list`'s `margin-bottom`) so the
|
|
43
|
+
same gap can be redirected: `margin-bottom: 0; margin-top: var(--tabs-content-gap);` when
|
|
44
|
+
inverted, since the gap now needs to land above the now-trailing tab list instead of below it.
|
|
45
|
+
The existing indicator `bottom`/`top` offset math elsewhere in this file needed no changes — it
|
|
46
|
+
positions the indicator within `.root`'s own local box, which is unaffected by where flex `order`
|
|
47
|
+
places that whole box among its siblings. Verified live against mantine-adapter's identical fix
|
|
48
|
+
(see its own `Tabs/IMPLEMENTATION_NOTES.md`) — pixel-equivalent stacking order and gap.
|
|
49
|
+
|
|
50
|
+
## Vertical `inverted` — "instead of left" flip (Matt Massey, ROUND 2 2026-08-31)
|
|
51
|
+
|
|
52
|
+
**Reported symptom:** no story exercises `orientation="vertical"` + `inverted` in either adapter
|
|
53
|
+
(flagged as an open question, unimplemented, in the prior round). After toggling it live, MUI's
|
|
54
|
+
red active-indicator line floated disconnected from the grey divider below it.
|
|
55
|
+
|
|
56
|
+
**Root cause:** the horizontal `inverted` fix above was explicitly scoped to
|
|
57
|
+
`[data-orientation="horizontal"]` only — none of its `order`/margin/indicator/border/radius rules
|
|
58
|
+
applied to vertical, so `inverted` on a vertical Tabs silently did nothing: the list stayed on the
|
|
59
|
+
left, but the divider/indicator's `right`-side offsets stayed anchored to a content-gap margin
|
|
60
|
+
that no longer existed once toggled (`.list`'s margin-right token expects the panel to still be
|
|
61
|
+
on its right), producing the disconnected look.
|
|
62
|
+
|
|
63
|
+
**Fix:** mirrored the horizontal flip rotated 90°, for `[data-orientation="vertical"][data-inverted]`:
|
|
64
|
+
`order: 1` on `.root` (list moves after the panel in the consumer's row `Flex`), `.list`'s
|
|
65
|
+
content-gap margin flips from `margin-right` to `margin-left`, the divider flips from
|
|
66
|
+
`border-right` to `border-left`, the indicator's offset flips from `right` to `left` (both the
|
|
67
|
+
default variant's underline and outline's baseline patch), and tab border-radius/outline
|
|
68
|
+
open-edge geometry flip from left-rounded/right-open to right-rounded/left-open. Verified live via
|
|
69
|
+
DOM attribute injection (no story exists yet to exercise this combo automatically) — divider and
|
|
70
|
+
indicator render flush on the list's new left edge, list correctly moves to the right of the
|
|
71
|
+
panel. mantine-adapter has the same "vertical inverted unimplemented" gap and wasn't touched here
|
|
72
|
+
(out of scope — only the MUI symptom was reported); flagged in `OPEN_QUESTIONS.txt` for parity.
|
|
73
|
+
|
|
74
|
+
## Ripple removal (2026-08-19)
|
|
75
|
+
|
|
76
|
+
- **MUI `Tab` shows a click ripple; Mantine's has none.** `Tab` extends `ButtonBase`, which renders a `TouchRipple` on click by default. Fixed by passing `disableRipple` on `MuiTab` in `Tab` (the same official escape hatch already used by `Button`/`Switch`/`Radio`/`Checkbox`). With `disableRipple`, the `MuiTouchRipple-root` span is never rendered at all, which also makes the `.root .tab > *:not(:global(.MuiTouchRipple-root))` layout-shift workaround above moot going forward (left in place defensively).
|