@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,102 @@
|
|
|
1
|
+
# Chip Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture decisions
|
|
4
|
+
|
|
5
|
+
### MUI DOM Structure & Label/Icon Overrides
|
|
6
|
+
|
|
7
|
+
MUI's `<Chip>` renders a plain `<div>` root with an optional leading `icon`, a `label`, and an
|
|
8
|
+
optional `deleteIcon` — no hidden `<input>` involved (unlike Mantine's checkbox/radio-based
|
|
9
|
+
`Chip`). This adapter targets MUI's own style hooks (`classes.root`/`classes.label`/`classes.icon`/
|
|
10
|
+
`classes.deleteIcon`) directly via the `classes` prop, matching the same visual surface the
|
|
11
|
+
mantine-adapter's `Chip` exposes.
|
|
12
|
+
|
|
13
|
+
### Icon and Remove Implementations
|
|
14
|
+
|
|
15
|
+
To match the mantine-adapter's internal `children` wrapper strategy, `label` is always set to a
|
|
16
|
+
`<span className={styles.innerWrapper}><span className={styles.children}>{children}</span></span>`
|
|
17
|
+
— any caller-supplied `label` in `sanitizedProps` is unconditionally overridden, since this
|
|
18
|
+
component's real public API is `children`, not `label` (see the `Chip.tsx` type comment: MUI's own
|
|
19
|
+
`ChipProps.children` is typed `null | undefined`, re-typed here as `React.ReactNode`).
|
|
20
|
+
|
|
21
|
+
`deleteIcon` and `icon` are each wrapped in their own `<span>` (`styles.removeIconWrapper`/
|
|
22
|
+
`styles.leadingIcon`) rather than styled as bare SVGs, so sizing/color/gap tokens have a stable
|
|
23
|
+
element to target — MUI clones whatever element is passed as `deleteIcon`/`icon`, adding only its
|
|
24
|
+
own `className`/`onClick`, so a `ref`/`tabIndex` set directly on that `<span>` survives the clone
|
|
25
|
+
untouched.
|
|
26
|
+
|
|
27
|
+
### Long-label truncation was hiding the remove icon (Matt Massey, 2026-08-17)
|
|
28
|
+
|
|
29
|
+
Same root cause as mantine-adapter's `Chip` (see its `CHIP_IMPLEMENTATION_NOTES.md`): `.children`
|
|
30
|
+
had ellipsis/`overflow: hidden`/`white-space: nowrap` but no `min-width: 0` on it or `.innerWrapper`,
|
|
31
|
+
so a flex child never actually shrank enough to trigger the ellipsis — the label overflowed instead,
|
|
32
|
+
pushing `.removeIconWrapper` outside the chip's clipped `max-width`. Fixed by adding `min-width: 0`
|
|
33
|
+
to `.innerWrapper`/`.children` and `flex-shrink: 0` to `.leadingIcon`/`.removeIconWrapper`.
|
|
34
|
+
|
|
35
|
+
### The remove icon had no accessible label and no real keyboard activation (Matt Massey, 2026-08-17)
|
|
36
|
+
|
|
37
|
+
`removeLabel` was destructured from props and defaulted to `"Remove"`, but was never actually
|
|
38
|
+
applied anywhere — dead code (`// eslint-disable-next-line @typescript-eslint/no-unused-vars`)
|
|
39
|
+
since this component was first built. The `deleteIcon` `<span>` had no `aria-label`, no `role`, and
|
|
40
|
+
no keyboard handler of its own: MUI's own `onDelete` wiring only reacts to `Backspace`/`Delete`,
|
|
41
|
+
and only when the _root_ itself is both the event's `target` and `currentTarget` (see
|
|
42
|
+
`isDeleteKeyboardEvent`/`handleKeyUp` in MUI's own `Chip.js`) — it never fires once focus moves onto
|
|
43
|
+
a child span directly (which is exactly what happens once you `.focus()` the remove icon
|
|
44
|
+
imperatively, as `FileUpload`'s roving-tabindex group does below). A plain `<span>` also gets no
|
|
45
|
+
native Enter/Space-triggers-click behavior the way a real `<button>` would. Fixed by adding
|
|
46
|
+
`role="button"`, `aria-label={removeLabel}`, and an explicit `onKeyDown` for `Enter`/`Space` that
|
|
47
|
+
calls `onDelete` directly — matching the mantine-adapter `Chip`'s remove icon, which already did all
|
|
48
|
+
three.
|
|
49
|
+
|
|
50
|
+
### Roving tabindex support for chip groups (Matt Massey, 2026-08-17)
|
|
51
|
+
|
|
52
|
+
Added two optional pass-through props — `removeTabIndex` and `removeIconRef` — purely so a parent
|
|
53
|
+
managing a _group_ of chips (e.g. `FileUpload`'s file list, see its own `IMPLEMENTATION_NOTES.md`)
|
|
54
|
+
can implement roving-tabindex/arrow-key navigation across them: set `removeTabIndex={-1}` on every
|
|
55
|
+
chip but the currently-active one, and use `removeIconRef` to move real DOM focus there
|
|
56
|
+
imperatively on arrow-key press. Both are set directly on the `<span>` passed as `deleteIcon`,
|
|
57
|
+
which MUI's `Chip` preserves when it clones that element. Both are no-ops for a standalone `Chip`
|
|
58
|
+
(defaults: `tabIndex={0}`, no ref) — this doesn't change any existing single-chip behavior.
|
|
59
|
+
|
|
60
|
+
A group composing multiple chips also needs to pass a plain `tabIndex={-1}` directly on each
|
|
61
|
+
`<Chip>` itself (not just `removeTabIndex` on the remove icon) — MUI's `Chip` silently renders its
|
|
62
|
+
_root_ as a focusable `ButtonBase` (not a plain `<div>`) whenever `onDelete` is set, even with no
|
|
63
|
+
`onClick` (`component = clickable || onDelete ? ButtonBase : ...`), so without this the root is a
|
|
64
|
+
second, unwanted tab stop ahead of the remove icon on every chip. `FileUpload` does this; any other
|
|
65
|
+
consumer building a roving-tabindex chip group needs to as well.
|
|
66
|
+
|
|
67
|
+
### Descenders were being clipped on `.children` and `.root` (Matt Massey, 2026-08-18)
|
|
68
|
+
|
|
69
|
+
Same root cause and fix as mantine-adapter's `Chip` (see its `CHIP_IMPLEMENTATION_NOTES.md`): a
|
|
70
|
+
label with a descender (e.g. the "g" in "image.png") had its bottom clipped off, because both
|
|
71
|
+
`.children` and `.root.root` set plain `overflow: hidden` — needed on the x-axis for
|
|
72
|
+
`text-overflow: ellipsis`/`max-width` truncation, but clipping the y-axis too cuts off glyph ink
|
|
73
|
+
that extends past a `text_line-height` token tighter than the font's natural ascent+descent. Split
|
|
74
|
+
both into `overflow-x: hidden; overflow-y: visible;`; truncation is unaffected (still x-axis only).
|
|
75
|
+
Unlike mantine's `Chip`, MUI's `.root.root` _is_ the visible pill (background-color/border-radius
|
|
76
|
+
live there, not on a separate `.label`), but border-radius rendering doesn't depend on `overflow`,
|
|
77
|
+
so opening the y-axis has no visual side effect on the rounded corners.
|
|
78
|
+
|
|
79
|
+
### Removing Sizing Properties
|
|
80
|
+
|
|
81
|
+
Matching mantine-adapter's `Chip`: Figma tokens export explicit height/padding vectors rather than
|
|
82
|
+
string size variants (`sm`/`md`/`lg`), so `size` is omitted from `RecursicaChipProps` entirely.
|
|
83
|
+
|
|
84
|
+
### A non-interactive chip still looked clickable, and had a phantom Tab stop (Matt Massey, 2026-08-18)
|
|
85
|
+
|
|
86
|
+
A `Chip` with no `onDelete`/`onClick`/`onChange` (e.g. `FileUpload`'s `readOnly` file list) still
|
|
87
|
+
showed a pointer cursor on hover — `.root.root` hardcoded `cursor: pointer` unconditionally, with
|
|
88
|
+
no notion of whether the chip actually did anything. Added an `isInteractive` check (mirroring the
|
|
89
|
+
one added to mantine-adapter's `Chip`, see its `CHIP_IMPLEMENTATION_NOTES.md`) based on
|
|
90
|
+
`onDelete`/`onClick`/`onChange` — this adapter's `Chip` has no `checked`-driven native-input case to
|
|
91
|
+
misread the way Mantine's did, since MUI's `Chip` has no real underlying form control. A new
|
|
92
|
+
`data-interactive` attribute (set from `isInteractive`) gates `cursor: pointer` in CSS; without it,
|
|
93
|
+
the chip falls back to whatever MUI's own non-clickable `Chip` renders as (no cursor override, no
|
|
94
|
+
`ButtonBase`).
|
|
95
|
+
|
|
96
|
+
Separately, `.children`'s `overflow-x: hidden` (added for ellipsis truncation) made it a scroll
|
|
97
|
+
container, and Chromium auto-adds scroll containers with actually-overflowing content to the Tab
|
|
98
|
+
order — with no `tabindex` attribute at all — so a solo Tab press could land on a chip's plain
|
|
99
|
+
filename text before ever reaching a real control. Switched to `overflow-x: clip`, which doesn't
|
|
100
|
+
establish a scrollport (same visual clipping, still x-axis only per the descender fix above), so
|
|
101
|
+
it's no longer a focus candidate. This affected every chip with long enough content, not just
|
|
102
|
+
read-only ones — see `FileUpload`'s own `IMPLEMENTATION_NOTES.md` for how it surfaced there.
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* HARDCODED VALUES
|
|
11
|
+
border-style: solid; (Baseline reset)
|
|
12
|
+
box-sizing: border-box; (Baseline reset)
|
|
13
|
+
display: inline-flex; (Baseline reset)
|
|
14
|
+
align-items: center; (Baseline reset)
|
|
15
|
+
outline: none; (Accessible fallback)
|
|
16
|
+
padding: 0; (Override mantine default)
|
|
17
|
+
background: transparent; (Override mantine default)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
.root.root {
|
|
21
|
+
/* Set preset layout variables to override mantine defaults safely */
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
|
|
27
|
+
/* Token properties */
|
|
28
|
+
--chip-height: max-content; /* Sizing is driven by padding and line height */
|
|
29
|
+
--chip-bg: var(
|
|
30
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_background-color
|
|
31
|
+
);
|
|
32
|
+
--chip-border: var(
|
|
33
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_border-color
|
|
34
|
+
);
|
|
35
|
+
--chip-text: var(
|
|
36
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_text-color
|
|
37
|
+
);
|
|
38
|
+
--chip-icon: var(
|
|
39
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_leading-icon-color
|
|
40
|
+
);
|
|
41
|
+
--chip-close: var(
|
|
42
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_close-icon-color
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/* Container geometry */
|
|
46
|
+
height: var(--chip-height);
|
|
47
|
+
border-radius: var(
|
|
48
|
+
--recursica_ui-kit_components_chip_properties_border-radius
|
|
49
|
+
);
|
|
50
|
+
border-style: solid;
|
|
51
|
+
border-width: var(--recursica_ui-kit_components_chip_properties_border-size);
|
|
52
|
+
padding: var(--recursica_ui-kit_components_chip_properties_vertical-padding)
|
|
53
|
+
var(--recursica_ui-kit_components_chip_properties_horizontal-padding);
|
|
54
|
+
|
|
55
|
+
/* Gap for native MUI icons */
|
|
56
|
+
gap: var(--recursica_ui-kit_components_chip_properties_icon-text-gap);
|
|
57
|
+
|
|
58
|
+
/* Background and colors */
|
|
59
|
+
background-color: var(--chip-bg);
|
|
60
|
+
border-color: var(--chip-border);
|
|
61
|
+
color: var(--chip-text);
|
|
62
|
+
min-width: var(--recursica_ui-kit_components_chip_properties_min-width);
|
|
63
|
+
max-width: var(--recursica_ui-kit_components_chip_properties_max-width);
|
|
64
|
+
box-shadow: var(--recursica_ui-kit_components_chip_properties_elevation);
|
|
65
|
+
|
|
66
|
+
user-select: none;
|
|
67
|
+
overflow-x: hidden; /* HARDCODE: horizontal-only — `overflow: hidden` on both axes was clipping
|
|
68
|
+
descenders (e.g. the "g" in "image.png") whenever the line-height token is tighter than the
|
|
69
|
+
font's natural glyph extent (Matt Massey, 2026-08-18); border-radius still renders correctly
|
|
70
|
+
on this box regardless of overflow, so rounded corners are unaffected */
|
|
71
|
+
overflow-y: visible;
|
|
72
|
+
transition: all 0.2s ease;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Only a chip with a real handler (onDelete/onClick/onChange — see Chip.tsx's `isInteractive`)
|
|
76
|
+
gets the pointer cursor. A display-only chip (e.g. a read-only FileUpload file list) has
|
|
77
|
+
nothing for a click to do, so it shouldn't look clickable. */
|
|
78
|
+
.root.root[data-interactive] {
|
|
79
|
+
cursor: pointer;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* We target the mantine label directly because that is the visible container in Mantine's Chip */
|
|
83
|
+
.label.label {
|
|
84
|
+
box-sizing: border-box;
|
|
85
|
+
display: inline-flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: center;
|
|
88
|
+
|
|
89
|
+
/* Reset MUI styles */
|
|
90
|
+
background: transparent;
|
|
91
|
+
padding: 0;
|
|
92
|
+
border: none;
|
|
93
|
+
border-radius: 0;
|
|
94
|
+
|
|
95
|
+
/* Typography */
|
|
96
|
+
font-family: var(
|
|
97
|
+
--recursica_ui-kit_components_chip_properties_text_font-family
|
|
98
|
+
);
|
|
99
|
+
font-size: var(--recursica_ui-kit_components_chip_properties_text_font-size);
|
|
100
|
+
font-weight: var(
|
|
101
|
+
--recursica_ui-kit_components_chip_properties_text_font-weight
|
|
102
|
+
);
|
|
103
|
+
font-style: var(
|
|
104
|
+
--recursica_ui-kit_components_chip_properties_text_font-style
|
|
105
|
+
);
|
|
106
|
+
letter-spacing: var(
|
|
107
|
+
--recursica_ui-kit_components_chip_properties_text_letter-spacing
|
|
108
|
+
);
|
|
109
|
+
line-height: var(
|
|
110
|
+
--recursica_ui-kit_components_chip_properties_text_line-height
|
|
111
|
+
);
|
|
112
|
+
text-decoration: var(
|
|
113
|
+
--recursica_ui-kit_components_chip_properties_text_text-decoration
|
|
114
|
+
);
|
|
115
|
+
text-transform: var(
|
|
116
|
+
--recursica_ui-kit_components_chip_properties_text_text-transform
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
/* Token evaluation */
|
|
120
|
+
background-color: var(--chip-bg);
|
|
121
|
+
border-color: var(--chip-border);
|
|
122
|
+
color: var(--chip-text);
|
|
123
|
+
box-shadow: var(--recursica_ui-kit_components_chip_properties_elevation);
|
|
124
|
+
|
|
125
|
+
transition: all 0.2s ease;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Default (Unselected) hover/active interactions (Mantine overrides) */
|
|
129
|
+
.root.root[data-checked] {
|
|
130
|
+
--chip-bg: var(
|
|
131
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_background-color
|
|
132
|
+
);
|
|
133
|
+
--chip-border: var(
|
|
134
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_border-color
|
|
135
|
+
);
|
|
136
|
+
--chip-text: var(
|
|
137
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_text-color
|
|
138
|
+
);
|
|
139
|
+
--chip-icon: var(
|
|
140
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_selected-icon-color
|
|
141
|
+
);
|
|
142
|
+
--chip-close: var(
|
|
143
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_close-icon-color
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.root.root[data-error] {
|
|
148
|
+
--chip-bg: var(
|
|
149
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_background-color
|
|
150
|
+
);
|
|
151
|
+
--chip-border: var(
|
|
152
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_border-color
|
|
153
|
+
);
|
|
154
|
+
--chip-text: var(
|
|
155
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_text-color
|
|
156
|
+
);
|
|
157
|
+
--chip-icon: var(
|
|
158
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_leading-icon-color
|
|
159
|
+
);
|
|
160
|
+
--chip-close: var(
|
|
161
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_close-icon-color
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.root.root[data-error][data-checked] {
|
|
166
|
+
--chip-bg: var(
|
|
167
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_background-color
|
|
168
|
+
);
|
|
169
|
+
--chip-border: var(
|
|
170
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_border-color
|
|
171
|
+
);
|
|
172
|
+
--chip-text: var(
|
|
173
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_text-color
|
|
174
|
+
);
|
|
175
|
+
--chip-icon: var(
|
|
176
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_selected-icon-color
|
|
177
|
+
);
|
|
178
|
+
--chip-close: var(
|
|
179
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_close-icon-color
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.root.root[data-disabled] {
|
|
184
|
+
opacity: var(--recursica_brand_states_disabled);
|
|
185
|
+
cursor: not-allowed;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Selected-state check icon colors and size */
|
|
189
|
+
.checkIconWrapper.checkIconWrapper {
|
|
190
|
+
color: var(--chip-icon);
|
|
191
|
+
width: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
192
|
+
height: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
193
|
+
margin-left: 0;
|
|
194
|
+
margin-right: var(
|
|
195
|
+
--recursica_ui-kit_components_chip_properties_icon-text-gap
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.innerWrapper {
|
|
200
|
+
display: inline-flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
gap: var(--recursica_ui-kit_components_chip_properties_icon-text-gap);
|
|
203
|
+
width: 100%;
|
|
204
|
+
min-width: 0; /* HARDCODE: lets .children actually shrink and ellipsize instead of overflowing */
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.children {
|
|
208
|
+
flex-grow: 1;
|
|
209
|
+
min-width: 0; /* HARDCODE: a flex child needs this for text-overflow: ellipsis to engage at all */
|
|
210
|
+
text-overflow: ellipsis;
|
|
211
|
+
overflow-x: clip; /* HARDCODE: text-overflow: ellipsis only needs the x-axis clipped — clipping
|
|
212
|
+
y too (plain `overflow: hidden`) cut off descenders (e.g. the "g" in "image.png") whenever the
|
|
213
|
+
line-height token is tighter than the font's natural glyph extent (Matt Massey, 2026-08-18).
|
|
214
|
+
`clip` rather than `hidden` because `hidden` makes this a scroll container, and Chromium
|
|
215
|
+
auto-adds scroll containers with overflowing content to the Tab order (so a browser user can
|
|
216
|
+
arrow-key-scroll them) — `clip` doesn't create a scrollport, so long/truncated chip labels
|
|
217
|
+
(e.g. a read-only FileUpload file list) don't pick up a phantom, un-styled tab stop. */
|
|
218
|
+
overflow-y: visible;
|
|
219
|
+
white-space: nowrap;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* Doubled selector for specificity parity with MUI's own compound
|
|
223
|
+
`.MuiChip-root .MuiChip-icon` rule, which otherwise wins outright on a
|
|
224
|
+
plain single-class selector and leaks its default margin/color. */
|
|
225
|
+
.leadingIcon.leadingIcon {
|
|
226
|
+
display: inline-flex;
|
|
227
|
+
align-items: center;
|
|
228
|
+
justify-content: center;
|
|
229
|
+
flex-shrink: 0; /* HARDCODE: keep the icon from being squeezed by a long, truncating label */
|
|
230
|
+
color: var(--chip-icon);
|
|
231
|
+
width: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
232
|
+
height: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
233
|
+
/* Reset MUI's default icon margin, keep the icon-text gap */
|
|
234
|
+
margin-left: 0;
|
|
235
|
+
margin-right: var(
|
|
236
|
+
--recursica_ui-kit_components_chip_properties_icon-text-gap
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.leadingIcon svg {
|
|
241
|
+
width: 100%;
|
|
242
|
+
height: 100%;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* Doubled selector for specificity parity with MUI's own compound
|
|
246
|
+
`.MuiChip-root .MuiChip-deleteIcon` rule (same reasoning as .leadingIcon). */
|
|
247
|
+
.deleteIconWrapper.deleteIconWrapper {
|
|
248
|
+
display: inline-flex;
|
|
249
|
+
align-items: center;
|
|
250
|
+
justify-content: center;
|
|
251
|
+
flex-shrink: 0; /* HARDCODE: keep the delete icon visible when the label truncates instead */
|
|
252
|
+
color: var(--chip-close);
|
|
253
|
+
width: var(--recursica_ui-kit_components_chip_properties_close-icon-size);
|
|
254
|
+
height: var(--recursica_ui-kit_components_chip_properties_close-icon-size);
|
|
255
|
+
cursor: pointer;
|
|
256
|
+
border-radius: 50%; /* HARDCODE: Make focus ring rounded */
|
|
257
|
+
outline: none;
|
|
258
|
+
/* Reset MUI icon defaults */
|
|
259
|
+
margin: 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.deleteIconWrapper.deleteIconWrapper:focus-visible {
|
|
263
|
+
box-shadow:
|
|
264
|
+
0 0 0 var(--recursica_brand_states_focus_border-size)
|
|
265
|
+
var(--recursica_brand_states_focus_color),
|
|
266
|
+
0 0 var(--recursica_brand_states_focus_blur)
|
|
267
|
+
var(--recursica_brand_states_focus_margin)
|
|
268
|
+
var(--recursica_brand_states_focus_color);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.deleteIconWrapper svg {
|
|
272
|
+
width: 100%;
|
|
273
|
+
height: 100%;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.root.root[data-icon-only] {
|
|
277
|
+
padding-left: var(
|
|
278
|
+
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
279
|
+
);
|
|
280
|
+
padding-right: var(
|
|
281
|
+
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
282
|
+
);
|
|
283
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Chip } from "./Chip";
|
|
4
|
+
|
|
5
|
+
type ChipStoryProps = React.ComponentProps<typeof Chip>;
|
|
6
|
+
|
|
7
|
+
const meta: Meta<ChipStoryProps> = {
|
|
8
|
+
title: "UI-Kit/Chip",
|
|
9
|
+
component: Chip,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
"The Chip component is used to represent interactive selections, descriptive tags, or dynamic filters natively bounded to Recursica variables. It can be used as a toggleable input, can render a custom leading `icon`, and handles close constraints automatically via the `onDelete` property.",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
error: {
|
|
21
|
+
control: "boolean",
|
|
22
|
+
description: "Applies the error state styling dynamically.",
|
|
23
|
+
},
|
|
24
|
+
disabled: {
|
|
25
|
+
control: "boolean",
|
|
26
|
+
description: "Applies disabled token states.",
|
|
27
|
+
},
|
|
28
|
+
checked: {
|
|
29
|
+
control: "boolean",
|
|
30
|
+
description: "Forces the visual selected state.",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default meta;
|
|
36
|
+
|
|
37
|
+
type Story = StoryObj<ChipStoryProps>;
|
|
38
|
+
|
|
39
|
+
// The Default story exposing native properties for the playground.
|
|
40
|
+
export const Default: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
children: "Default Chip",
|
|
43
|
+
error: false,
|
|
44
|
+
disabled: false,
|
|
45
|
+
checked: false,
|
|
46
|
+
},
|
|
47
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Static Stories for Regression Snapshots
|
|
51
|
+
export const Unselected: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
children: "Unselected",
|
|
54
|
+
checked: false,
|
|
55
|
+
},
|
|
56
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Selected: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
children: "Selected",
|
|
62
|
+
checked: true,
|
|
63
|
+
},
|
|
64
|
+
render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const ErrorState: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
children: "Error",
|
|
70
|
+
error: true,
|
|
71
|
+
checked: false,
|
|
72
|
+
},
|
|
73
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const ErrorSelected: Story = {
|
|
77
|
+
args: {
|
|
78
|
+
children: "Error Selected",
|
|
79
|
+
error: true,
|
|
80
|
+
checked: true,
|
|
81
|
+
},
|
|
82
|
+
render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const Removable: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
children: "Dismissible",
|
|
88
|
+
checked: false,
|
|
89
|
+
onDelete: () => console.log("Removal Action Triggered"),
|
|
90
|
+
},
|
|
91
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const WithLeadingIcon: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
children: "Leading Icon",
|
|
97
|
+
checked: false,
|
|
98
|
+
icon: (
|
|
99
|
+
<svg
|
|
100
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
101
|
+
viewBox="0 0 24 24"
|
|
102
|
+
fill="none"
|
|
103
|
+
stroke="currentColor"
|
|
104
|
+
strokeWidth="2"
|
|
105
|
+
strokeLinecap="round"
|
|
106
|
+
strokeLinejoin="round"
|
|
107
|
+
>
|
|
108
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
109
|
+
<path d="M12 8v4"></path>
|
|
110
|
+
<path d="M12 16h.01"></path>
|
|
111
|
+
</svg>
|
|
112
|
+
),
|
|
113
|
+
},
|
|
114
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// Selecting a chip with a leading icon swaps in the checkmark rather than showing both — this
|
|
118
|
+
// was already MUI-adapter's native behavior; the story exists to keep parity with mantine-adapter.
|
|
119
|
+
export const WithLeadingIconSelected: Story = {
|
|
120
|
+
args: {
|
|
121
|
+
...WithLeadingIcon.args,
|
|
122
|
+
children: "Leading Icon Selected",
|
|
123
|
+
checked: true,
|
|
124
|
+
},
|
|
125
|
+
render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// A label long enough to exceed the chip's own max-width token — should stay a single line and
|
|
129
|
+
// truncate with an ellipsis, never wrap, even with both a leading icon and a dismiss button
|
|
130
|
+
// competing for space.
|
|
131
|
+
export const MaxWidthEllipsis: Story = {
|
|
132
|
+
args: {
|
|
133
|
+
children:
|
|
134
|
+
"A very long chip label that exceeds the maximum width and should truncate with an ellipsis",
|
|
135
|
+
checked: false,
|
|
136
|
+
icon: (
|
|
137
|
+
<svg
|
|
138
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
139
|
+
viewBox="0 0 24 24"
|
|
140
|
+
fill="none"
|
|
141
|
+
stroke="currentColor"
|
|
142
|
+
strokeWidth="2"
|
|
143
|
+
strokeLinecap="round"
|
|
144
|
+
strokeLinejoin="round"
|
|
145
|
+
>
|
|
146
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
147
|
+
<path d="M12 8v4"></path>
|
|
148
|
+
<path d="M12 16h.01"></path>
|
|
149
|
+
</svg>
|
|
150
|
+
),
|
|
151
|
+
onDelete: () => console.log("Removal Action Triggered"),
|
|
152
|
+
},
|
|
153
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
154
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Chip component tests. Add tests here if/when needed.
|