@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,165 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Tooltip, type TooltipProps } from "./Tooltip";
|
|
3
|
+
import { Button } from "../Button";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tooltip story axes:
|
|
7
|
+
* - position: tooltip alignment relative to target
|
|
8
|
+
* - withBeak: beak (arrow) indicator on the tooltip
|
|
9
|
+
* - openDelay / closeDelay: hover timing controls
|
|
10
|
+
* - multiline: text wrapping behavior
|
|
11
|
+
* - disabled: suppress the tooltip entirely
|
|
12
|
+
* - layer: tested via the global Layer decorator (withLayer/layer args)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
type TooltipStoryArgs = Record<string, any>;
|
|
17
|
+
|
|
18
|
+
const meta: Meta = {
|
|
19
|
+
title: "UI-Kit/Tooltip",
|
|
20
|
+
component: Tooltip,
|
|
21
|
+
tags: ["autodocs"],
|
|
22
|
+
argTypes: {
|
|
23
|
+
label: {
|
|
24
|
+
control: "text",
|
|
25
|
+
description: "Content displayed inside the tooltip.",
|
|
26
|
+
},
|
|
27
|
+
position: {
|
|
28
|
+
control: "select",
|
|
29
|
+
options: [
|
|
30
|
+
"bottom",
|
|
31
|
+
"bottom-start",
|
|
32
|
+
"bottom-end",
|
|
33
|
+
"top",
|
|
34
|
+
"top-start",
|
|
35
|
+
"top-end",
|
|
36
|
+
"left",
|
|
37
|
+
"left-start",
|
|
38
|
+
"left-end",
|
|
39
|
+
"right",
|
|
40
|
+
"right-start",
|
|
41
|
+
"right-end",
|
|
42
|
+
],
|
|
43
|
+
description: "The position of the tooltip relative to the target.",
|
|
44
|
+
},
|
|
45
|
+
withBeak: {
|
|
46
|
+
control: "boolean",
|
|
47
|
+
description:
|
|
48
|
+
"Whether to display a beak (arrow) pointing to the target. Recursica equivalent of Mantine's withArrow.",
|
|
49
|
+
},
|
|
50
|
+
offset: {
|
|
51
|
+
control: "number",
|
|
52
|
+
description: "Distance in px between the tooltip and the target element.",
|
|
53
|
+
},
|
|
54
|
+
openDelay: {
|
|
55
|
+
control: "number",
|
|
56
|
+
description: "Delay in ms before the tooltip opens on hover.",
|
|
57
|
+
},
|
|
58
|
+
closeDelay: {
|
|
59
|
+
control: "number",
|
|
60
|
+
description: "Delay in ms before the tooltip closes when hover ends.",
|
|
61
|
+
},
|
|
62
|
+
disabled: {
|
|
63
|
+
control: "boolean",
|
|
64
|
+
description: "If set, the tooltip will not be rendered.",
|
|
65
|
+
},
|
|
66
|
+
opened: {
|
|
67
|
+
control: "boolean",
|
|
68
|
+
description:
|
|
69
|
+
"Force the tooltip to stay open. Useful for inspecting styling.",
|
|
70
|
+
},
|
|
71
|
+
// Hide auto-detected HTML attributes that leak from ElementProps<'div'>
|
|
72
|
+
defaultChecked: { table: { disable: true } },
|
|
73
|
+
defaultValue: { table: { disable: true } },
|
|
74
|
+
suppressContentEditableWarning: { table: { disable: true } },
|
|
75
|
+
suppressHydrationWarning: { table: { disable: true } },
|
|
76
|
+
},
|
|
77
|
+
parameters: {
|
|
78
|
+
layout: "centered",
|
|
79
|
+
docs: {
|
|
80
|
+
description: {
|
|
81
|
+
component: `
|
|
82
|
+
The \`Tooltip\` component displays a floating label when the user hovers over or focuses a target element. It wraps Mantine's \`Tooltip\` while enforcing strict Recursica design token styling.
|
|
83
|
+
|
|
84
|
+
### API
|
|
85
|
+
|
|
86
|
+
Unlike \`HoverCard\`, Tooltip is a single component — content is passed via the \`label\` prop:
|
|
87
|
+
\`\`\`tsx
|
|
88
|
+
<Tooltip label="Helpful text" withBeak>
|
|
89
|
+
<Button>Hover me</Button>
|
|
90
|
+
</Tooltip>
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
### Static Sub-Components
|
|
94
|
+
- \`Tooltip.Floating\` — A tooltip that follows the cursor position
|
|
95
|
+
- \`Tooltip.Group\` — Groups multiple tooltips to share hover delay
|
|
96
|
+
|
|
97
|
+
### Key Behaviors
|
|
98
|
+
- The beak (arrow) is shown by default (\`withBeak={true}\`)
|
|
99
|
+
- Supports \`openDelay\` and \`closeDelay\` for timing control
|
|
100
|
+
- Set \`multiline\` to allow text wrapping within max-width
|
|
101
|
+
`,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export default meta;
|
|
108
|
+
|
|
109
|
+
type Story = StoryObj<TooltipStoryArgs>;
|
|
110
|
+
|
|
111
|
+
export const Default: Story = {
|
|
112
|
+
args: {
|
|
113
|
+
label: "This is a helpful tooltip",
|
|
114
|
+
position: "top",
|
|
115
|
+
withBeak: true,
|
|
116
|
+
offset: 5,
|
|
117
|
+
openDelay: 0,
|
|
118
|
+
closeDelay: 0,
|
|
119
|
+
disabled: false,
|
|
120
|
+
},
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
122
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
123
|
+
return (
|
|
124
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
125
|
+
<Button variant="solid">Hover me</Button>
|
|
126
|
+
</Tooltip>
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const WithoutBeak: Story = {
|
|
132
|
+
args: {
|
|
133
|
+
label: "Tooltip without a beak indicator",
|
|
134
|
+
position: "top",
|
|
135
|
+
withBeak: false,
|
|
136
|
+
offset: 5,
|
|
137
|
+
},
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
139
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
140
|
+
return (
|
|
141
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
142
|
+
<Button variant="outline">Without Beak</Button>
|
|
143
|
+
</Tooltip>
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const LongContent: Story = {
|
|
149
|
+
args: {
|
|
150
|
+
label:
|
|
151
|
+
"This is a longer tooltip message that demonstrates how text wraps within the maximum width defined by the design system.",
|
|
152
|
+
position: "top",
|
|
153
|
+
withBeak: true,
|
|
154
|
+
opened: true,
|
|
155
|
+
offset: 5,
|
|
156
|
+
},
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
159
|
+
return (
|
|
160
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
161
|
+
<Button variant="solid">Long Content</Button>
|
|
162
|
+
</Tooltip>
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Tooltip component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Tooltip as MuiTooltip,
|
|
3
|
+
type TooltipProps as MuiTooltipProps,
|
|
4
|
+
} from "@mui/material";
|
|
5
|
+
import {
|
|
6
|
+
filterStylingProps,
|
|
7
|
+
mergeClassNames,
|
|
8
|
+
type RecursicaOverStyled,
|
|
9
|
+
} from "../../utils/filterStylingProps";
|
|
10
|
+
import styles from "./Tooltip.module.css";
|
|
11
|
+
|
|
12
|
+
// ============================================================
|
|
13
|
+
// TOOLTIP
|
|
14
|
+
// ============================================================
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Recursica-specific props for Tooltip.
|
|
18
|
+
*/
|
|
19
|
+
import { type RecursicaTooltipProps } from "@recursica/adapter-common";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Recursica Tooltip component wrapping Mui's Tooltip.
|
|
23
|
+
*
|
|
24
|
+
* Displays a floating label when the user hovers over or focuses a target element.
|
|
25
|
+
* Unlike HoverCard, Tooltip is a single component (not composable) — content is
|
|
26
|
+
* passed via the `label` prop, and the trigger is passed as `children`.
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* <Tooltip label="Helpful information" withBeak>
|
|
30
|
+
* <Button>Hover me</Button>
|
|
31
|
+
* </Tooltip>
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Static sub-components available via dot-notation:
|
|
35
|
+
* - `// Tooltip.Floating` — Tooltip that follows the cursor
|
|
36
|
+
* - `// Tooltip.Group` — Shared hover delay group for multiple tooltips
|
|
37
|
+
*/
|
|
38
|
+
export type TooltipProps = RecursicaOverStyled<
|
|
39
|
+
MuiTooltipProps & RecursicaTooltipProps
|
|
40
|
+
>;
|
|
41
|
+
|
|
42
|
+
const TooltipBase = function Tooltip({
|
|
43
|
+
overStyled = false,
|
|
44
|
+
withBeak = true,
|
|
45
|
+
label,
|
|
46
|
+
opened,
|
|
47
|
+
...rest
|
|
48
|
+
}: TooltipProps & { label?: React.ReactNode; opened?: boolean }) {
|
|
49
|
+
const { title, ...restProps } = rest;
|
|
50
|
+
const sanitizedProps = filterStylingProps(restProps, overStyled);
|
|
51
|
+
|
|
52
|
+
// Bind CSS module classes to Mui's internal classNames API. Note MUI's actual prop is
|
|
53
|
+
// "classes", not "classNames" (that's Mantine's naming) — this used to read the wrong key,
|
|
54
|
+
// silently no-op-ing any caller-supplied classes.
|
|
55
|
+
const mergedClassNames = mergeClassNames(
|
|
56
|
+
{
|
|
57
|
+
tooltip: styles.tooltip,
|
|
58
|
+
arrow: styles.arrow,
|
|
59
|
+
},
|
|
60
|
+
(sanitizedProps as Record<string, unknown>).classes as
|
|
61
|
+
| Partial<Record<string, string>>
|
|
62
|
+
| undefined,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<MuiTooltip
|
|
67
|
+
{...(sanitizedProps as unknown as Omit<MuiTooltipProps, "title">)}
|
|
68
|
+
title={label || title || ""}
|
|
69
|
+
open={opened}
|
|
70
|
+
placement="top" /* Recursica default; Mui defaults to "bottom" */
|
|
71
|
+
arrow={withBeak}
|
|
72
|
+
classes={mergedClassNames}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
TooltipBase.displayName = "Tooltip";
|
|
77
|
+
|
|
78
|
+
export const Tooltip = TooltipBase;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Tooltip - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Tooltip` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Tooltip } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Tooltip } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<Tooltip label="This is a helpful tooltip">
|
|
24
|
+
<Button variant="primary">Hover Me</Button>
|
|
25
|
+
</Tooltip>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 3. Design System Integration
|
|
33
|
+
|
|
34
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
35
|
+
|
|
36
|
+
> [!IMPORTANT]
|
|
37
|
+
>
|
|
38
|
+
> - **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.
|
|
39
|
+
> - **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.
|
|
40
|
+
> - **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 "./Tooltip";
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# TransferList Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture overview
|
|
4
|
+
|
|
5
|
+
`TransferList` replaces the "coming soon" stub with a fully custom composite — neither
|
|
6
|
+
`@mantine/core` nor `@mui/material` ships a real dual-listbox component (MUI's docs "Transfer
|
|
7
|
+
List" is a List+Checkbox recipe, not a package export), so it's built from Recursica's own
|
|
8
|
+
primitives, the same situation `FileUpload`/`FileInput` were in.
|
|
9
|
+
|
|
10
|
+
Follows Matt's reference implementation (Forge's fallback `TransferList.tsx`) fairly closely:
|
|
11
|
+
|
|
12
|
+
- Two side-by-side panes (source/target), each: a header row (pane label + `Badge` count,
|
|
13
|
+
`"selected / total"` once something's checked), a search `TextField`, then a scrollable list of
|
|
14
|
+
`Checkbox` rows (`CheckboxGroup` for items carrying a `group` field).
|
|
15
|
+
- A column of four transfer `Button`s between the panes: single/double chevron, each direction —
|
|
16
|
+
single moves only the checked items in that pane, double moves everything in that pane.
|
|
17
|
+
- Data model: `data`/`defaultData` as a `[sourceItems, targetItems]` tuple + `onChange`, matching
|
|
18
|
+
Forge's controlled/uncontrolled pattern (same shape as `FileUpload`'s `files`/`onFilesAdded`).
|
|
19
|
+
|
|
20
|
+
## Routed through `FormControlWrapper` directly, not Forge's hand-rolled label/assistive
|
|
21
|
+
|
|
22
|
+
Forge's reference renders its own `Label`/`AssistiveElement` directly instead of going through
|
|
23
|
+
`FormControlWrapper`. Per direction, this build uses `FormControlWrapper` instead — consistent
|
|
24
|
+
with every other form control in this codebase (and with `FileUpload`, which was reverted to
|
|
25
|
+
`FormControlWrapper` rather than hand-rolling that same thing). `formLayout`
|
|
26
|
+
(`stacked`/`side-by-side`), `label`, `required`, `assistiveText`/`description`/`helperText`, and
|
|
27
|
+
`error` all come from the standard wrapper; only the two panes + transfer buttons are the
|
|
28
|
+
component's own content.
|
|
29
|
+
|
|
30
|
+
## `state` axis: `disabled`/`error` props, not Forge's `state` string
|
|
31
|
+
|
|
32
|
+
Forge's reference takes a single `state="default"|"disabled"|"error"` prop. This build instead
|
|
33
|
+
uses the same convention as every other Recursica control: a boolean `disabled` prop plus
|
|
34
|
+
`FormControlWrapper`'s own `error` (message) prop — `error`'s mere presence is what triggers the
|
|
35
|
+
error visuals, exactly like `TextArea`/`CheckboxGroup`. The token export only defines
|
|
36
|
+
`disabled`/`error` state variants (no `focus`), matching Matt's direction to "follow the tokens."
|
|
37
|
+
|
|
38
|
+
## `readOnly` mode (added 2026-08-19)
|
|
39
|
+
|
|
40
|
+
Forge's reference has no read-only concept, but Matt asked for a `ReadOnly` story demonstrating
|
|
41
|
+
the selected items as a read-only list. Switched from calling `FormControlWrapper` directly to
|
|
42
|
+
routing through `WithReadOnlyWrapper` (the follow-up flagged in the original version of this note),
|
|
43
|
+
matching `TextArea`'s shape: `readOnly`/`readOnlyComponent`/`emptyValueComponent` added to the prop
|
|
44
|
+
surface via `ReadOnlyControlProps`, `readOnlyType="text"`, and `readOnlyValue` set to the target
|
|
45
|
+
pane's item labels (`effectiveData[1].map(item => item.label)`). Renders as a comma-joined text
|
|
46
|
+
list via the shared `ReadOnlyTextField`, same convention `CheckboxGroup`'s own read-only mode
|
|
47
|
+
already uses for an array of values — no new read-only renderer needed. The two panes + transfer
|
|
48
|
+
buttons (`activeComponent`) are skipped entirely when `readOnly` is set, same as every other
|
|
49
|
+
control.
|
|
50
|
+
|
|
51
|
+
## Height/gap/padding token audit (2026-08-19)
|
|
52
|
+
|
|
53
|
+
Matt flagged the pane height as "too short" and asked that gap/padding be tied to recursica
|
|
54
|
+
variables. Re-verified against `recursica_variables_scoped.css`: `properties_height` (200px),
|
|
55
|
+
`properties_width`, `properties_vertical-padding`/`properties_horizontal-padding`, and
|
|
56
|
+
`properties_gap` were already wired to their tokens (see "Token interpretation" above) — the 200px
|
|
57
|
+
pane height is the design token's own value, not a hardcoded fallback. Two spacing values genuinely
|
|
58
|
+
have no covering token in the 31-variable schema and are intentionally left as hardcoded pixels
|
|
59
|
+
(see `TransferList.module.css` comments) rather than reusing another component's token: the gap
|
|
60
|
+
between stacked `CheckboxGroup` blocks in `.paneList` (ungrouped row + each named group), and the
|
|
61
|
+
gap between the four transfer buttons in `.transferColumn`. If a token is added to the schema for
|
|
62
|
+
either, wire it in directly; until then this matches the established precedent (e.g. `FileUpload`'s
|
|
63
|
+
untokened icon size) of leaving a truly uncovered value hardcoded with a documented reason instead
|
|
64
|
+
of borrowing a sibling component's namespace.
|
|
65
|
+
|
|
66
|
+
## Fixed: checkboxes inside `CheckboxGroup` ignored their own `checked`/`onChange` (2026-08-19)
|
|
67
|
+
|
|
68
|
+
Matt's discrepancy report against the mantine source of truth: clicking an ungrouped checkbox in
|
|
69
|
+
the `Grouped` story showed no checkmark and never toggled selection, though the pane's `Badge`
|
|
70
|
+
count also never changed — meaning it silently did nothing, not "count going up" as literally
|
|
71
|
+
worded, confirmed live via Playwright against both Storybooks (`isChecked()` stayed `false`, badge
|
|
72
|
+
text stayed `5` across repeated clicks in mui; mantine correctly showed `1 / 5`, `2 / 5`).
|
|
73
|
+
|
|
74
|
+
Root cause was in `Checkbox.tsx`, not `TransferList.tsx`: `TransferList` wraps its ungrouped items
|
|
75
|
+
in a bare `<CheckboxGroup>` purely so they pick up the `item-gap` layout token (see the
|
|
76
|
+
`RECURSICA_COMPONENTS`/gap fix from 2026-08-18), without ever passing that group a `value`/
|
|
77
|
+
`onChange`. But `Checkbox.tsx` derived `isGrouped` from `groupContext !== null` alone — any
|
|
78
|
+
`CheckboxGroup` ancestor forced grouped-array semantics (`isChecked = groupContext.value.includes(...)`,
|
|
79
|
+
`handleChange` dispatching to `groupContext.onChange` instead of the checkbox's own `onChange`),
|
|
80
|
+
even though the group had no `value` array and no `onChange` to dispatch to. `TransferList`'s own
|
|
81
|
+
`checked={selected.has(item.value)}`/`onChange={() => onToggle(item.value)}` props were present but
|
|
82
|
+
silently overridden/ignored. Mantine's `Checkbox.tsx` never had this bug — it doesn't consult any
|
|
83
|
+
group context at all and always passes `checked`/`onChange` straight through to
|
|
84
|
+
`@mantine/core`'s `Checkbox`.
|
|
85
|
+
|
|
86
|
+
Fixed by only treating a `Checkbox` as group-controlled when it _doesn't_ already have its own
|
|
87
|
+
explicit `checked` prop: `isGrouped = groupContext !== null && restRecord.checked === undefined`.
|
|
88
|
+
A checkbox with its own `checked` (like `TransferList`'s rows) now always owns its source of truth;
|
|
89
|
+
only checkboxes relying on `Checkbox.Group`'s array-tracking (no individual `checked`, matched by
|
|
90
|
+
`value` — `CheckboxGroup.stories.tsx`'s usage) still defer to the group. Audited every
|
|
91
|
+
`CheckboxGroup`/`Checkbox` pairing in adapter-mui-v7 (`CheckboxGroup.stories.tsx` and `TransferList`) —
|
|
92
|
+
no existing usage combines both an individual `checked` and group-array `value`, so this is a
|
|
93
|
+
straight bug fix with no regression risk.
|
|
94
|
+
|
|
95
|
+
## Token interpretation: unlabeled tokens with more than one plausible layout target
|
|
96
|
+
|
|
97
|
+
The 31-variable schema (`properties_*` + two `layouts.*` + `states.{disabled,error}`) has a few
|
|
98
|
+
names that don't pin down a single location by themselves:
|
|
99
|
+
|
|
100
|
+
- **`properties_gap`** — applied to the row holding `[source pane, transfer column, target pane]`.
|
|
101
|
+
It's the only _unnested_ gap the schema defines at the component's own level (not under
|
|
102
|
+
`header-style`, a state, or a layout), so it reads as the component's top-level layout gap.
|
|
103
|
+
- **`properties_title-filter-gap`** — between each pane's header row (label + count `Badge`) and
|
|
104
|
+
its search field.
|
|
105
|
+
- **`properties_filter-items-gap`** — between each pane's search field and its item list.
|
|
106
|
+
- **`properties_header-style_*` / `properties_colors_header-color`** — typography/color for each
|
|
107
|
+
pane's own header text, not the overall `FormControlWrapper` label (which has its own type
|
|
108
|
+
styling already).
|
|
109
|
+
- **`properties_width` (300px) / `properties_height` (200px)** — taken as each pane's own fixed
|
|
110
|
+
box size (`flex: 1 1 <width>`, so panes still stretch evenly in a wider container; `height` is
|
|
111
|
+
literal since a dual-listbox needs a bounded, independently-scrollable list).
|
|
112
|
+
|
|
113
|
+
No exemptions needed beyond `border-size` (see below) — all 31 variables are referenced; verified
|
|
114
|
+
zero broken/unused via `recursica-token-analyzer`.
|
|
115
|
+
|
|
116
|
+
## Border-size intentionally unused
|
|
117
|
+
|
|
118
|
+
Same house policy `TextField`/`TextArea`/`FileInput` already follow: `border-size` (base,
|
|
119
|
+
`disabled`, `error`) is `recursica-ignore`d and a flat 1px border is applied uniformly instead, so
|
|
120
|
+
switching states doesn't shift layout.
|
|
121
|
+
|
|
122
|
+
## No forge-defined focus state
|
|
123
|
+
|
|
124
|
+
`transfer-list` has no `states.focus` axis in the export — same as `FileInput`/`TextField`. Focus
|
|
125
|
+
is handled per-control (each `Checkbox`/`TextField`/`Button` already has its own focus ring); the
|
|
126
|
+
pane box itself has no focus state to render.
|
|
127
|
+
|
|
128
|
+
## Grouping and search are local, not per-item persisted state
|
|
129
|
+
|
|
130
|
+
Search filters each pane independently (`sourceSearch`/`targetSearch`); grouped items render under
|
|
131
|
+
a `CheckboxGroup` keyed by `item.group`, ungrouped items render as plain `Checkbox` rows above the
|
|
132
|
+
groups (alphabetized by group name) — same two-bucket split Forge's reference uses. Selection
|
|
133
|
+
(`sourceSelected`/`targetSelected`) is cleared on every transfer, matching Forge's behavior.
|
|
134
|
+
|
|
135
|
+
## Chevron icons are inline, not a shared icon set entry
|
|
136
|
+
|
|
137
|
+
Same precedent as `Tree`'s `ExpandGlyph`/`FileInput`'s `ClearIcon`: a single-chevron and a
|
|
138
|
+
double-chevron SVG are defined locally and flipped via `transform: scaleX(-1)` for the "left"
|
|
139
|
+
direction, rather than maintaining four separate paths or adding new shared icon-set entries for a
|
|
140
|
+
single component.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* TOKEN INTERPRETATION NOTES (see TRANSFERLIST_IMPLEMENTATION_NOTES.md):
|
|
2
|
+
- `properties_gap` is applied to the row that holds [source pane, transfer buttons, target pane] —
|
|
3
|
+
it's the only unnested gap the schema defines at the component's own level.
|
|
4
|
+
- `properties_title-filter-gap` sits between each pane's header row and its search field.
|
|
5
|
+
- `properties_filter-items-gap` sits between each pane's search field and its item list. */
|
|
6
|
+
|
|
7
|
+
.layoutOverride {
|
|
8
|
+
--form-control-margin-bottom: var(
|
|
9
|
+
--recursica_ui-kit_components_transfer-list_variants_layouts_stacked_properties_top-bottom-margin
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.layoutOverride[data-form-layout="side-by-side"] {
|
|
14
|
+
--form-control-margin-bottom: var(
|
|
15
|
+
--recursica_ui-kit_components_transfer-list_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.root {
|
|
20
|
+
display: flex;
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.panes {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: stretch;
|
|
27
|
+
gap: var(--recursica_ui-kit_components_transfer-list_properties_gap);
|
|
28
|
+
width: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.pane {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
min-width: 0;
|
|
36
|
+
flex: 1 1 var(--recursica_ui-kit_components_transfer-list_properties_width);
|
|
37
|
+
height: var(--recursica_ui-kit_components_transfer-list_properties_height);
|
|
38
|
+
padding: var(
|
|
39
|
+
--recursica_ui-kit_components_transfer-list_properties_vertical-padding
|
|
40
|
+
)
|
|
41
|
+
var(
|
|
42
|
+
--recursica_ui-kit_components_transfer-list_properties_horizontal-padding
|
|
43
|
+
);
|
|
44
|
+
border-width: 1px;
|
|
45
|
+
border-style: solid;
|
|
46
|
+
border-radius: var(
|
|
47
|
+
--recursica_ui-kit_components_transfer-list_properties_border-radius
|
|
48
|
+
);
|
|
49
|
+
border-color: var(
|
|
50
|
+
--recursica_ui-kit_components_transfer-list_properties_colors_border-color
|
|
51
|
+
);
|
|
52
|
+
background-color: var(
|
|
53
|
+
--recursica_ui-kit_components_transfer-list_properties_colors_background-color
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.paneHeader {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: space-between;
|
|
61
|
+
margin-bottom: var(
|
|
62
|
+
--recursica_ui-kit_components_transfer-list_properties_title-filter-gap
|
|
63
|
+
);
|
|
64
|
+
font-family: var(
|
|
65
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_fontFamily
|
|
66
|
+
);
|
|
67
|
+
font-size: var(
|
|
68
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_fontSize
|
|
69
|
+
);
|
|
70
|
+
font-style: var(
|
|
71
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_fontStyle
|
|
72
|
+
);
|
|
73
|
+
font-weight: var(
|
|
74
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_fontWeight
|
|
75
|
+
);
|
|
76
|
+
letter-spacing: var(
|
|
77
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_letterSpacing
|
|
78
|
+
);
|
|
79
|
+
line-height: var(
|
|
80
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_lineHeight
|
|
81
|
+
);
|
|
82
|
+
text-decoration: var(
|
|
83
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_textDecoration
|
|
84
|
+
);
|
|
85
|
+
text-transform: var(
|
|
86
|
+
--recursica_ui-kit_components_transfer-list_properties_header-style_textCase
|
|
87
|
+
);
|
|
88
|
+
color: var(
|
|
89
|
+
--recursica_ui-kit_components_transfer-list_properties_colors_header-color
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.paneSearch {
|
|
94
|
+
margin-bottom: var(
|
|
95
|
+
--recursica_ui-kit_components_transfer-list_properties_filter-items-gap
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.paneList {
|
|
100
|
+
flex: 1;
|
|
101
|
+
overflow-y: auto;
|
|
102
|
+
display: flex;
|
|
103
|
+
flex-direction: column;
|
|
104
|
+
/* No token exists for the gap between stacked CheckboxGroup blocks (ungrouped row +
|
|
105
|
+
each named group) — the 31-variable transfer-list schema only defines gaps at the
|
|
106
|
+
header/search/pane level (see TRANSFERLIST_IMPLEMENTATION_NOTES.md). Left as an
|
|
107
|
+
intentional hardcoded value rather than borrowing another component's token, same
|
|
108
|
+
as FileUpload's untokened icon size. */
|
|
109
|
+
gap: 2px;
|
|
110
|
+
min-height: 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.emptyState {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
flex: 1;
|
|
118
|
+
opacity: 0.6;
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
padding: 16px;
|
|
121
|
+
text-align: center;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.transferColumn {
|
|
125
|
+
display: flex;
|
|
126
|
+
flex-direction: column;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
/* No token exists for spacing between the four transfer buttons — not part of the
|
|
130
|
+
31-variable schema. Left as an intentional hardcoded value (see TRANSFERLIST_IMPLEMENTATION_NOTES.md). */
|
|
131
|
+
gap: 4px;
|
|
132
|
+
flex-shrink: 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.chevron[data-direction="left"] {
|
|
136
|
+
transform: scaleX(-1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* -------------------------------------
|
|
140
|
+
STATE CASCADE
|
|
141
|
+
-------------------------------------- */
|
|
142
|
+
|
|
143
|
+
.root[data-error] .pane {
|
|
144
|
+
border-color: var(
|
|
145
|
+
--recursica_ui-kit_components_transfer-list_variants_states_error_properties_colors_border-color
|
|
146
|
+
) !important;
|
|
147
|
+
background-color: var(
|
|
148
|
+
--recursica_ui-kit_components_transfer-list_variants_states_error_properties_colors_background-color
|
|
149
|
+
) !important;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.root[data-error] .paneHeader {
|
|
153
|
+
color: var(
|
|
154
|
+
--recursica_ui-kit_components_transfer-list_variants_states_error_properties_colors_header-color
|
|
155
|
+
) !important;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.root[data-disabled] .pane {
|
|
159
|
+
border-color: var(
|
|
160
|
+
--recursica_ui-kit_components_transfer-list_variants_states_disabled_properties_colors_border-color
|
|
161
|
+
) !important;
|
|
162
|
+
background-color: var(
|
|
163
|
+
--recursica_ui-kit_components_transfer-list_variants_states_disabled_properties_colors_background-color
|
|
164
|
+
) !important;
|
|
165
|
+
opacity: var(
|
|
166
|
+
--recursica_ui-kit_components_transfer-list_variants_states_disabled_properties_opacity
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.root[data-disabled] .paneHeader {
|
|
171
|
+
color: var(
|
|
172
|
+
--recursica_ui-kit_components_transfer-list_variants_states_disabled_properties_colors_header-color
|
|
173
|
+
) !important;
|
|
174
|
+
}
|