@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,50 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Heading } from "./Heading";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Heading> = {
|
|
5
|
+
title: "UI-Kit/Heading",
|
|
6
|
+
component: Heading,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
"The semantic `<Heading>` abstraction intrinsically links pure `h1-h6` tag generation with exact Recursica design boundaries to preserve SEO and screen reader trees uniformly globally.",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
order: {
|
|
18
|
+
control: "select",
|
|
19
|
+
options: [1, 2, 3, 4, 5, 6],
|
|
20
|
+
description:
|
|
21
|
+
"Controls the `h` tag and the resultant typographical weighting natively mapped to Recursica.",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default meta;
|
|
27
|
+
|
|
28
|
+
type Story = StoryObj<typeof Heading>;
|
|
29
|
+
|
|
30
|
+
export const Default: Story = {
|
|
31
|
+
args: {
|
|
32
|
+
order: 1,
|
|
33
|
+
children: "Semantic H1 Document Boundary",
|
|
34
|
+
},
|
|
35
|
+
render: ({ ...args }) => <Heading {...args} />,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const StaticVariations: Story = {
|
|
39
|
+
args: {},
|
|
40
|
+
render: () => (
|
|
41
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
|
|
42
|
+
<Heading order={1}>H1 Heading</Heading>
|
|
43
|
+
<Heading order={2}>H2 Heading</Heading>
|
|
44
|
+
<Heading order={3}>H3 Heading</Heading>
|
|
45
|
+
<Heading order={4}>H4 Heading</Heading>
|
|
46
|
+
<Heading order={5}>H5 Heading</Heading>
|
|
47
|
+
<Heading order={6}>H6 Heading</Heading>
|
|
48
|
+
</div>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Heading component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import { type TypographyProps as MuiTypographyProps } from "@mui/material";
|
|
3
|
+
import { Typography } from "../Typography/Typography";
|
|
4
|
+
import { type RecursicaOverStyled } from "../../utils/filterStylingProps";
|
|
5
|
+
import { type RecursicaHeadingProps } from "@recursica/adapter-common";
|
|
6
|
+
|
|
7
|
+
export type HeadingProps = RecursicaOverStyled<
|
|
8
|
+
Omit<MuiTypographyProps, "variant" | "classes"> & RecursicaHeadingProps
|
|
9
|
+
>;
|
|
10
|
+
|
|
11
|
+
export const Heading = forwardRef<HTMLElement, HeadingProps>(function Heading(
|
|
12
|
+
{ order = 1, component, ...rest },
|
|
13
|
+
ref,
|
|
14
|
+
) {
|
|
15
|
+
const typographyClass = `recursica_brand_typography_h${order}`;
|
|
16
|
+
const defaultComponent = `h${order}` as React.ElementType;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Typography
|
|
20
|
+
ref={ref}
|
|
21
|
+
typographyClass={typographyClass}
|
|
22
|
+
component={component || defaultComponent}
|
|
23
|
+
{...rest}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
Heading.displayName = "Heading";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Heading - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Heading` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Heading } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Heading } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return <Heading order={1}>This is a Heading 1</Heading>;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Design System Integration
|
|
29
|
+
|
|
30
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
31
|
+
|
|
32
|
+
> [!IMPORTANT]
|
|
33
|
+
>
|
|
34
|
+
> - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
35
|
+
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
36
|
+
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Heading";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* HARDCODED VALUES:
|
|
2
|
+
- border-style: solid. Structural rendering rule for the dropdown border (Mantine uses Paper
|
|
3
|
+
which may not set border-style natively). Same pattern as Menu.
|
|
4
|
+
- arrowSize defaults to 16 in HoverCard.tsx. Mantine uses arrowSize for inline width/height
|
|
5
|
+
and positioning (-arrowSize/2) calculations that cannot be CSS-driven. The default matches
|
|
6
|
+
the Recursica beak-size token (16px). See COMPONENT_ISSUES.md for details.
|
|
7
|
+
- All structural layout (display, position, overflow) is deferred to Mantine's native
|
|
8
|
+
behavior. We only override visual design tokens (colors, typography, spacing, borders).
|
|
9
|
+
- margin: 0 !important on .dropdown. Mui's Tooltip hardcodes a per-placement margin
|
|
10
|
+
(14px, reset to 0 only when arrow is enabled) on top of whatever offset the popper
|
|
11
|
+
"offset" modifier applies, so with withBeak=false the trigger-to-dropdown gap was
|
|
12
|
+
offset + 14px instead of just offset. There is no Recursica token for this spacing —
|
|
13
|
+
the gap is driven purely by the `offset` prop (a plain number, same as Mantine's
|
|
14
|
+
HoverCard), so we zero out Mui's extra margin to make offset the only source of gap. */
|
|
15
|
+
|
|
16
|
+
/* ======================================
|
|
17
|
+
DROPDOWN CONTAINER
|
|
18
|
+
====================================== */
|
|
19
|
+
|
|
20
|
+
.dropdown {
|
|
21
|
+
background-color: var(
|
|
22
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_background-color
|
|
23
|
+
);
|
|
24
|
+
border-style: solid; /* HARDCODE: Mantine Paper does not set border-style natively */
|
|
25
|
+
border-width: var(
|
|
26
|
+
--recursica_ui-kit_components_hover-card-popover_properties_border-size
|
|
27
|
+
);
|
|
28
|
+
border-color: var(
|
|
29
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_border-color
|
|
30
|
+
);
|
|
31
|
+
border-radius: var(
|
|
32
|
+
--recursica_ui-kit_components_hover-card-popover_properties_border-radius
|
|
33
|
+
);
|
|
34
|
+
box-shadow: var(
|
|
35
|
+
--recursica_ui-kit_components_hover-card-popover_properties_elevation
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
min-width: var(
|
|
39
|
+
--recursica_ui-kit_components_hover-card-popover_properties_min-width
|
|
40
|
+
);
|
|
41
|
+
max-width: var(
|
|
42
|
+
--recursica_ui-kit_components_hover-card-popover_properties_max-width
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
padding: var(
|
|
46
|
+
--recursica_ui-kit_components_hover-card-popover_properties_vertical-padding
|
|
47
|
+
)
|
|
48
|
+
var(
|
|
49
|
+
--recursica_ui-kit_components_hover-card-popover_properties_horizontal-padding
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
/* Typography */
|
|
53
|
+
font-family: var(
|
|
54
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-family
|
|
55
|
+
);
|
|
56
|
+
font-size: var(
|
|
57
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-size
|
|
58
|
+
);
|
|
59
|
+
font-style: var(
|
|
60
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-style
|
|
61
|
+
);
|
|
62
|
+
font-weight: var(
|
|
63
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-weight
|
|
64
|
+
);
|
|
65
|
+
letter-spacing: var(
|
|
66
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_letter-spacing
|
|
67
|
+
);
|
|
68
|
+
line-height: var(
|
|
69
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_line-height
|
|
70
|
+
);
|
|
71
|
+
text-decoration: var(
|
|
72
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_text-decoration
|
|
73
|
+
);
|
|
74
|
+
text-transform: var(
|
|
75
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_text-transform
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
color: var(
|
|
79
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_content
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
margin: 0 !important; /* HARDCODE: cancel Mui's built-in per-placement margin, see note above */
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* ======================================
|
|
86
|
+
ARROW / BEAK
|
|
87
|
+
====================================== */
|
|
88
|
+
|
|
89
|
+
/* Mui's arrow is a rotated square (via ::before, background-color: currentColor)
|
|
90
|
+
sized in em units off font-size, not a bordered CSS triangle. `color` (not
|
|
91
|
+
border-color) is what actually fills it, which is why setting border-color here
|
|
92
|
+
previously had no visible effect and left it defaulting to the inherited text
|
|
93
|
+
color (solid black). Fill it with the same background-color token the card body
|
|
94
|
+
uses so it blends into the card exactly like Mantine's beak, and size it off the
|
|
95
|
+
beak-size token instead of Mui's default 1em/0.71em (font-size-relative) box. */
|
|
96
|
+
.arrow {
|
|
97
|
+
color: var(
|
|
98
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_background-color
|
|
99
|
+
);
|
|
100
|
+
width: var(
|
|
101
|
+
--recursica_ui-kit_components_hover-card-popover_properties_beak-size
|
|
102
|
+
);
|
|
103
|
+
height: calc(
|
|
104
|
+
var(--recursica_ui-kit_components_hover-card-popover_properties_beak-size) *
|
|
105
|
+
0.7071
|
|
106
|
+
); /* = width / sqrt(2), same ratio Mui's default arrow uses */
|
|
107
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { HoverCard } from "./HoverCard";
|
|
3
|
+
import { Button } from "../Button";
|
|
4
|
+
import { Text } from "../Text/Text";
|
|
5
|
+
import { Group } from "../Group/Group";
|
|
6
|
+
import { Stack } from "../Stack/Stack";
|
|
7
|
+
import { Avatar } from "../Avatar";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* HoverCard story axes:
|
|
11
|
+
* - position: dropdown alignment relative to target
|
|
12
|
+
* - withArrow: arrow indicator on the dropdown
|
|
13
|
+
* - openDelay / closeDelay: hover timing controls
|
|
14
|
+
* - content variations: plain text, rich content (avatar + text + actions)
|
|
15
|
+
* - layer: tested via the global Layer decorator (withLayer/layer args)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
type HoverCardStoryArgs = Record<string, any>;
|
|
20
|
+
|
|
21
|
+
const meta: Meta = {
|
|
22
|
+
title: "UI-Kit/HoverCard",
|
|
23
|
+
component: HoverCard,
|
|
24
|
+
tags: ["autodocs"],
|
|
25
|
+
argTypes: {
|
|
26
|
+
position: {
|
|
27
|
+
control: "select",
|
|
28
|
+
options: [
|
|
29
|
+
"bottom",
|
|
30
|
+
"bottom-start",
|
|
31
|
+
"bottom-end",
|
|
32
|
+
"top",
|
|
33
|
+
"top-start",
|
|
34
|
+
"top-end",
|
|
35
|
+
"left",
|
|
36
|
+
"left-start",
|
|
37
|
+
"left-end",
|
|
38
|
+
"right",
|
|
39
|
+
"right-start",
|
|
40
|
+
"right-end",
|
|
41
|
+
],
|
|
42
|
+
description: "The position of the dropdown relative to the target.",
|
|
43
|
+
},
|
|
44
|
+
withBeak: {
|
|
45
|
+
control: "boolean",
|
|
46
|
+
description:
|
|
47
|
+
"Whether to display a beak (arrow) pointing to the target. Recursica equivalent of Mantine's withArrow.",
|
|
48
|
+
},
|
|
49
|
+
offset: {
|
|
50
|
+
control: "number",
|
|
51
|
+
description:
|
|
52
|
+
"Distance in px between the dropdown and the target element.",
|
|
53
|
+
},
|
|
54
|
+
openDelay: {
|
|
55
|
+
control: "number",
|
|
56
|
+
description: "Delay in ms before the dropdown opens on hover.",
|
|
57
|
+
},
|
|
58
|
+
closeDelay: {
|
|
59
|
+
control: "number",
|
|
60
|
+
description: "Delay in ms before the dropdown closes when hover ends.",
|
|
61
|
+
},
|
|
62
|
+
disabled: {
|
|
63
|
+
control: "boolean",
|
|
64
|
+
description: "If set, the hover card dropdown will not be rendered.",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
parameters: {
|
|
68
|
+
layout: "centered",
|
|
69
|
+
docs: {
|
|
70
|
+
description: {
|
|
71
|
+
component: `
|
|
72
|
+
The \`HoverCard\` component displays a popover-style dropdown when the user hovers over a target element. It wraps Mantine's composable \`HoverCard\` while enforcing strict Recursica design token styling.
|
|
73
|
+
|
|
74
|
+
### Composable API
|
|
75
|
+
|
|
76
|
+
HoverCard uses a dot-notation composition pattern:
|
|
77
|
+
- \`<HoverCard>\` — Root container managing open/close state on hover
|
|
78
|
+
- \`<HoverCard.Target>\` — Wrapper for the trigger element (must be a single element supporting ref)
|
|
79
|
+
- \`<HoverCard.Dropdown>\` — The popup panel displaying content on hover
|
|
80
|
+
|
|
81
|
+
### Key Behaviors
|
|
82
|
+
- The dropdown opens when the user hovers over the target and closes when they move away
|
|
83
|
+
- \`openDelay\` and \`closeDelay\` control the timing of open/close transitions
|
|
84
|
+
- The dropdown stays open while the user hovers over it, allowing interaction with its content
|
|
85
|
+
`,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default meta;
|
|
92
|
+
|
|
93
|
+
type Story = StoryObj<HoverCardStoryArgs>;
|
|
94
|
+
|
|
95
|
+
export const Default: Story = {
|
|
96
|
+
args: {
|
|
97
|
+
position: "top",
|
|
98
|
+
withBeak: true,
|
|
99
|
+
offset: 5,
|
|
100
|
+
openDelay: 0,
|
|
101
|
+
closeDelay: 150,
|
|
102
|
+
},
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
104
|
+
render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
|
|
105
|
+
return (
|
|
106
|
+
<HoverCard {...args}>
|
|
107
|
+
<HoverCard.Target>
|
|
108
|
+
<Button variant="solid">Hover me</Button>
|
|
109
|
+
</HoverCard.Target>
|
|
110
|
+
|
|
111
|
+
<HoverCard.Dropdown>
|
|
112
|
+
<Text>
|
|
113
|
+
This is a hover card with informational content that appears when
|
|
114
|
+
you hover over the target element.
|
|
115
|
+
</Text>
|
|
116
|
+
</HoverCard.Dropdown>
|
|
117
|
+
</HoverCard>
|
|
118
|
+
);
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const WithoutBeak: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
position: "top",
|
|
125
|
+
withBeak: false,
|
|
126
|
+
offset: 5,
|
|
127
|
+
},
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
129
|
+
render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
|
|
130
|
+
return (
|
|
131
|
+
<HoverCard {...args}>
|
|
132
|
+
<HoverCard.Target>
|
|
133
|
+
<Button variant="outline">Without Beak</Button>
|
|
134
|
+
</HoverCard.Target>
|
|
135
|
+
|
|
136
|
+
<HoverCard.Dropdown>
|
|
137
|
+
<Text>
|
|
138
|
+
This hover card has the beak disabled, showing a clean dropdown
|
|
139
|
+
without the pointing indicator.
|
|
140
|
+
</Text>
|
|
141
|
+
</HoverCard.Dropdown>
|
|
142
|
+
</HoverCard>
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const RichContent: Story = {
|
|
148
|
+
args: {
|
|
149
|
+
position: "top",
|
|
150
|
+
offset: 5,
|
|
151
|
+
},
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
153
|
+
render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
|
|
154
|
+
return (
|
|
155
|
+
<HoverCard {...args}>
|
|
156
|
+
<HoverCard.Target>
|
|
157
|
+
<Button variant="solid">User Profile</Button>
|
|
158
|
+
</HoverCard.Target>
|
|
159
|
+
|
|
160
|
+
<HoverCard.Dropdown>
|
|
161
|
+
<Group>
|
|
162
|
+
<Avatar src={undefined} alt="User avatar" />
|
|
163
|
+
<Stack>
|
|
164
|
+
<Text>Jane Doe</Text>
|
|
165
|
+
<Text>Software Engineer at Recursica</Text>
|
|
166
|
+
</Stack>
|
|
167
|
+
</Group>
|
|
168
|
+
</HoverCard.Dropdown>
|
|
169
|
+
</HoverCard>
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future HoverCard component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, { isValidElement } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Tooltip as MuiTooltip,
|
|
4
|
+
type TooltipProps as MuiTooltipProps,
|
|
5
|
+
} from "@mui/material";
|
|
6
|
+
import {
|
|
7
|
+
filterStylingProps,
|
|
8
|
+
mergeClassNames,
|
|
9
|
+
type RecursicaOverStyled,
|
|
10
|
+
} from "../../utils/filterStylingProps";
|
|
11
|
+
import styles from "./HoverCard.module.css";
|
|
12
|
+
|
|
13
|
+
// ============================================================
|
|
14
|
+
// HOVERCARD ROOT
|
|
15
|
+
// ============================================================
|
|
16
|
+
|
|
17
|
+
import { type RecursicaHoverCardProps } from "@recursica/adapter-common";
|
|
18
|
+
|
|
19
|
+
export type HoverCardProps = RecursicaOverStyled<
|
|
20
|
+
Omit<MuiTooltipProps, "title" | "children"> & RecursicaHoverCardProps
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
const HoverCardBase = function HoverCard({
|
|
24
|
+
overStyled = false,
|
|
25
|
+
withBeak = true,
|
|
26
|
+
position = "top",
|
|
27
|
+
openDelay = 0,
|
|
28
|
+
closeDelay = 150,
|
|
29
|
+
disabled = false,
|
|
30
|
+
offset = 5,
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
}: HoverCardProps) {
|
|
34
|
+
const sanitizedProps = filterStylingProps(
|
|
35
|
+
rest as Record<string, unknown>,
|
|
36
|
+
overStyled,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Bind CSS module classes to Mui's internal classNames API. Note MUI's actual prop is
|
|
40
|
+
// "classes", not "classNames" (that's Mantine's naming) — this used to read the wrong key,
|
|
41
|
+
// silently no-op-ing any caller-supplied classes.
|
|
42
|
+
const mergedClassNames = mergeClassNames(
|
|
43
|
+
{
|
|
44
|
+
tooltip: styles.dropdown,
|
|
45
|
+
arrow: styles.arrow,
|
|
46
|
+
},
|
|
47
|
+
(sanitizedProps as Record<string, unknown>).classes as
|
|
48
|
+
| Partial<Record<string, string>>
|
|
49
|
+
| undefined,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Find Target and Dropdown children
|
|
53
|
+
let targetNode: React.ReactNode = null;
|
|
54
|
+
let dropdownNode: React.ReactNode = null;
|
|
55
|
+
|
|
56
|
+
React.Children.forEach(children, (child) => {
|
|
57
|
+
if (isValidElement(child)) {
|
|
58
|
+
const childElement = child as unknown as {
|
|
59
|
+
type?: { displayName?: string };
|
|
60
|
+
props: { children?: React.ReactNode };
|
|
61
|
+
};
|
|
62
|
+
if (childElement.type?.displayName === "HoverCardTarget") {
|
|
63
|
+
targetNode = childElement.props.children;
|
|
64
|
+
} else if (childElement.type?.displayName === "HoverCardDropdown") {
|
|
65
|
+
dropdownNode = childElement.props.children;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!targetNode) {
|
|
71
|
+
// Fallback if structure is wrong
|
|
72
|
+
targetNode = <div />;
|
|
73
|
+
}
|
|
74
|
+
if (!dropdownNode) {
|
|
75
|
+
dropdownNode = <div />;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<MuiTooltip
|
|
80
|
+
{...(sanitizedProps as unknown as Record<string, unknown>)}
|
|
81
|
+
title={dropdownNode}
|
|
82
|
+
placement={position as unknown as MuiTooltipProps["placement"]}
|
|
83
|
+
arrow={withBeak}
|
|
84
|
+
enterDelay={openDelay}
|
|
85
|
+
leaveDelay={closeDelay}
|
|
86
|
+
disableHoverListener={disabled}
|
|
87
|
+
slotProps={{
|
|
88
|
+
popper: {
|
|
89
|
+
modifiers: [
|
|
90
|
+
{
|
|
91
|
+
name: "offset",
|
|
92
|
+
options: {
|
|
93
|
+
offset: [0, offset],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
}}
|
|
99
|
+
classes={mergedClassNames as unknown as MuiTooltipProps["classes"]}
|
|
100
|
+
>
|
|
101
|
+
{/* Tooltip requires a single valid React element child that accepts a ref */}
|
|
102
|
+
{isValidElement(targetNode) ? targetNode : <span>{targetNode}</span>}
|
|
103
|
+
</MuiTooltip>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
HoverCardBase.displayName = "HoverCard";
|
|
107
|
+
|
|
108
|
+
// ============================================================
|
|
109
|
+
// HOVERCARD TARGET
|
|
110
|
+
// ============================================================
|
|
111
|
+
|
|
112
|
+
export type HoverCardTargetProps = { children?: React.ReactNode };
|
|
113
|
+
|
|
114
|
+
const HoverCardTarget = function HoverCardTarget({
|
|
115
|
+
children,
|
|
116
|
+
}: HoverCardTargetProps) {
|
|
117
|
+
return <>{children}</>;
|
|
118
|
+
};
|
|
119
|
+
HoverCardTarget.displayName = "HoverCardTarget";
|
|
120
|
+
|
|
121
|
+
// ============================================================
|
|
122
|
+
// HOVERCARD DROPDOWN
|
|
123
|
+
// ============================================================
|
|
124
|
+
|
|
125
|
+
export type HoverCardDropdownProps = { children?: React.ReactNode };
|
|
126
|
+
|
|
127
|
+
const HoverCardDropdown = function HoverCardDropdown({
|
|
128
|
+
children,
|
|
129
|
+
}: HoverCardDropdownProps) {
|
|
130
|
+
return <>{children}</>;
|
|
131
|
+
};
|
|
132
|
+
HoverCardDropdown.displayName = "HoverCardDropdown";
|
|
133
|
+
|
|
134
|
+
// ============================================================
|
|
135
|
+
// DOT NOTATION EXPORT
|
|
136
|
+
// ============================================================
|
|
137
|
+
|
|
138
|
+
type HoverCardComponent = typeof HoverCardBase & {
|
|
139
|
+
Target: typeof HoverCardTarget;
|
|
140
|
+
Dropdown: typeof HoverCardDropdown;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export const HoverCard = HoverCardBase as HoverCardComponent;
|
|
144
|
+
HoverCard.Target = HoverCardTarget;
|
|
145
|
+
HoverCard.Dropdown = HoverCardDropdown;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# HoverCard - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `HoverCard` component in your projects using `@recursica/adapter-mui-v7`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { HoverCard } from "@recursica/adapter-mui-v7";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { HoverCard } from "@recursica/adapter-mui-v7";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<HoverCard>
|
|
24
|
+
<HoverCard.Target>
|
|
25
|
+
<Text>Hover over me</Text>
|
|
26
|
+
</HoverCard.Target>
|
|
27
|
+
<HoverCard.Dropdown>
|
|
28
|
+
<Text size="sm">This is the hover card popup content.</Text>
|
|
29
|
+
</HoverCard.Dropdown>
|
|
30
|
+
</HoverCard>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. Design System Integration
|
|
38
|
+
|
|
39
|
+
All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
40
|
+
|
|
41
|
+
> [!IMPORTANT]
|
|
42
|
+
>
|
|
43
|
+
> - **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.
|
|
44
|
+
> - **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.
|
|
45
|
+
> - **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 "./HoverCard";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Label Implementation Notes
|
|
2
|
+
|
|
3
|
+
Decisions and gotchas specific to wrapping `@mui/material`'s `InputLabel` for the UI Kit's Label.
|
|
4
|
+
|
|
5
|
+
## `labelAlignment` was completely unimplemented
|
|
6
|
+
|
|
7
|
+
**Found 2026-08-30, source-of-truth audit against mantine.** `ui-kit-label--right-aligned` used
|
|
8
|
+
identical story args on both adapters, but only mantine's rendering was actually right-aligned.
|
|
9
|
+
Root cause: `labelAlignment` isn't part of MUI `InputLabelProps`, and this component never
|
|
10
|
+
destructured or otherwise referenced it — it silently fell into `...rest` and got spread onto
|
|
11
|
+
`<InputLabel>` as an unrecognized prop (no visual effect, MUI drops/ignores it). Fixed by
|
|
12
|
+
destructuring `labelAlignment` (defaulting to `"left"`, matching mantine), exposing it as
|
|
13
|
+
`data-alignment` on the root `<InputLabel>`, and adding
|
|
14
|
+
`.root[data-alignment="right"] .innerLayout { justify-content: flex-end; text-align: right; }`
|
|
15
|
+
in `Label.module.css` — mirroring mantine-adapter's own `[data-alignment]` selector pattern.
|
|
16
|
+
|
|
17
|
+
## `labelOptionalText` custom string wasn't wrapped in parentheses
|
|
18
|
+
|
|
19
|
+
**Found 2026-08-30, source-of-truth audit against mantine.** `ui-kit-label--with-optional-text`
|
|
20
|
+
passes a custom string (`"Max 100 characters"`), not the `true` sentinel. This component only
|
|
21
|
+
special-cased `labelOptionalText === true` (mapping it to the literal `"(optional)"` string) and
|
|
22
|
+
rendered any other value verbatim, with no parentheses — e.g. mantine shows `(Max 100
|
|
23
|
+
characters)`, this adapter showed `Max 100 characters`. Mantine's component wraps ANY resolved
|
|
24
|
+
string value in parentheses, not just its own boolean-default case. Fixed to match: resolve
|
|
25
|
+
`true` to `"optional"` same as before, then wrap the result in parentheses whenever it's a
|
|
26
|
+
string (non-string custom nodes, e.g. a caller-supplied element, pass through unwrapped, same as
|
|
27
|
+
mantine).
|