@recursica/adapter-mantine-v8 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 +688 -0
- package/LICENSE +21 -0
- package/OVERSTYLING.md +56 -0
- package/README.md +70 -0
- package/SETUP.md +93 -0
- package/USAGE.md +57 -0
- package/dist/adapter-mantine-v8.cjs +12 -0
- package/dist/adapter-mantine-v8.cjs.map +1 -0
- package/dist/adapter-mantine-v8.css +1 -0
- package/dist/adapter-mantine-v8.js +5759 -0
- package/dist/adapter-mantine-v8.js.map +1 -0
- package/dist/index.d.ts +2095 -0
- package/dist/test.html +1 -0
- package/dist/vite.svg +1 -0
- package/docs/PHILOSOPHY.md +39 -0
- package/llms.txt +74 -0
- package/package.json +131 -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 +154 -0
- package/src/OverStyling.tsx +79 -0
- package/src/Version.tsx +44 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +72 -0
- package/src/components/Accordion/Accordion.module.css +367 -0
- package/src/components/Accordion/Accordion.stories.tsx +189 -0
- package/src/components/Accordion/Accordion.test.tsx +1 -0
- package/src/components/Accordion/Accordion.tsx +220 -0
- package/src/components/Accordion/USAGE.md +51 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -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 +93 -0
- package/src/components/AssistiveElement/USAGE.md +36 -0
- package/src/components/AutoComplete/AUTOCOMPLETE_IMPLEMENTATION_NOTES.md +42 -0
- package/src/components/AutoComplete/AutoComplete.module.css +430 -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 +179 -0
- package/src/components/AutoComplete/USAGE.md +80 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +34 -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 +108 -0
- package/src/components/Avatar/USAGE.md +38 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Badge/Badge.module.css +127 -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 +64 -0
- package/src/components/Badge/USAGE.md +56 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +47 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +48 -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 +85 -0
- package/src/components/Breadcrumb/USAGE.md +55 -0
- package/src/components/Breadcrumb/markCurrentPageItem.test.ts +49 -0
- package/src/components/Button/Button.module.css +446 -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 +184 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +109 -0
- package/src/components/Button/USAGE.md +80 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +17 -0
- package/src/components/Card/Card.module.css +119 -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 +248 -0
- package/src/components/Card/USAGE.md +63 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +267 -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 +151 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +147 -0
- package/src/components/Checkbox/USAGE.md +48 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +110 -0
- package/src/components/Chip/Chip.module.css +288 -0
- package/src/components/Chip/Chip.stories.tsx +128 -0
- package/src/components/Chip/Chip.test.tsx +1 -0
- package/src/components/Chip/Chip.tsx +157 -0
- package/src/components/Chip/USAGE.md +55 -0
- package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Container/Container.module.css +7 -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 +69 -0
- package/src/components/Container/USAGE.md +47 -0
- package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +31 -0
- package/src/components/DatePicker/DatePicker.icons.tsx +27 -0
- package/src/components/DatePicker/DatePicker.module.css +566 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +158 -0
- package/src/components/DatePicker/DatePicker.test.tsx +1 -0
- package/src/components/DatePicker/DatePicker.tsx +218 -0
- package/src/components/DatePicker/USAGE.md +49 -0
- package/src/components/Dropdown/BareDropdown.tsx +97 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Dropdown/Dropdown.module.css +477 -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 +213 -0
- package/src/components/Dropdown/USAGE.md +69 -0
- package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
- package/src/components/FileInput/FileInput.module.css +280 -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 +417 -0
- package/src/components/FileInput/USAGE.md +145 -0
- package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +244 -0
- package/src/components/FileUpload/FileUpload.module.css +205 -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 +354 -0
- package/src/components/FileUpload/USAGE.md +199 -0
- package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Flex/Flex.module.css +7 -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 +75 -0
- package/src/components/Flex/USAGE.md +48 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +90 -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 +74 -0
- package/src/components/FormControlLayout/USAGE.md +40 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +75 -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 +151 -0
- package/src/components/FormControlWrapper/USAGE.md +47 -0
- package/src/components/Grid/GRID_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Grid/Grid.module.css +11 -0
- package/src/components/Grid/Grid.stories.tsx +206 -0
- package/src/components/Grid/Grid.test.tsx +1 -0
- package/src/components/Grid/Grid.tsx +140 -0
- package/src/components/Grid/USAGE.md +47 -0
- package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Group/Group.module.css +7 -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 +60 -0
- package/src/components/Group/USAGE.md +48 -0
- package/src/components/Heading/HEADING_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Heading/Heading.module.css +13 -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 +52 -0
- package/src/components/Heading/USAGE.md +36 -0
- package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/HoverCard/HoverCard.module.css +90 -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 +133 -0
- package/src/components/HoverCard/USAGE.md +52 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +141 -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 +113 -0
- package/src/components/Label/USAGE.md +47 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Layer/USAGE.md +54 -0
- package/src/components/Link/IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/Link/Link.module.css +110 -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 +67 -0
- package/src/components/Link/USAGE.md +56 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Loader/Loader.animate.dom.test.tsx +82 -0
- package/src/components/Loader/Loader.module.css +63 -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 +69 -0
- package/src/components/Loader/USAGE.md +44 -0
- package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +88 -0
- package/src/components/Menu/Menu.module.css +280 -0
- package/src/components/Menu/Menu.stories.tsx +371 -0
- package/src/components/Menu/Menu.test.tsx +1 -0
- package/src/components/Menu/Menu.tsx +373 -0
- package/src/components/Menu/USAGE.md +55 -0
- package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +32 -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 +368 -0
- package/src/components/Modal/USAGE.md +58 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/NumberInput/NumberInput.module.css +302 -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 +157 -0
- package/src/components/NumberInput/USAGE.md +52 -0
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +16 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +188 -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 +265 -0
- package/src/components/Pagination/USAGE.md +36 -0
- package/src/components/Pagination/index.ts +5 -0
- package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +116 -0
- package/src/components/Panel/Panel.module.css +209 -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 +269 -0
- package/src/components/Panel/USAGE.md +56 -0
- package/src/components/Popover/IMPLEMENTATION_NOTES.md +77 -0
- package/src/components/Popover/Popover.module.css +86 -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 +142 -0
- package/src/components/Popover/USAGE.md +61 -0
- package/src/components/Popover/index.ts +1 -0
- package/src/components/Radio/Radio.module.css +231 -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 +168 -0
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +124 -0
- package/src/components/Radio/USAGE.md +36 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -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 +114 -0
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/USAGE.md +44 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +5 -0
- package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
- package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +185 -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 +110 -0
- package/src/components/SegmentedControl/USAGE.md +55 -0
- package/src/components/Slider/IMPLEMENTATION_NOTES.md +92 -0
- package/src/components/Slider/Slider.module.css +588 -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 +391 -0
- package/src/components/Slider/USAGE.md +56 -0
- package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stack/Stack.module.css +7 -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 +62 -0
- package/src/components/Stack/USAGE.md +48 -0
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +28 -0
- package/src/components/Stepper/Stepper.module.css +404 -0
- package/src/components/Stepper/Stepper.stories.tsx +148 -0
- package/src/components/Stepper/Stepper.test.tsx +1 -0
- package/src/components/Stepper/Stepper.tsx +93 -0
- package/src/components/Stepper/USAGE.md +41 -0
- package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +64 -0
- package/src/components/Switch/Switch.module.css +279 -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 +177 -0
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +127 -0
- package/src/components/Switch/USAGE.md +42 -0
- package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +78 -0
- package/src/components/Table/Table.icons.tsx +40 -0
- package/src/components/Table/Table.module.css +444 -0
- package/src/components/Table/Table.stories.tsx +140 -0
- package/src/components/Table/Table.test.tsx +1 -0
- package/src/components/Table/Table.tsx +243 -0
- package/src/components/Table/USAGE.md +78 -0
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +27 -0
- package/src/components/Tabs/Tabs.module.css +591 -0
- package/src/components/Tabs/Tabs.stories.tsx +154 -0
- package/src/components/Tabs/Tabs.test.tsx +1 -0
- package/src/components/Tabs/Tabs.tsx +114 -0
- package/src/components/Tabs/USAGE.md +45 -0
- package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +12 -0
- package/src/components/Text/Text.module.css +13 -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 +53 -0
- package/src/components/Text/USAGE.md +40 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/TextArea/TextArea.module.css +183 -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 +137 -0
- package/src/components/TextArea/USAGE.md +48 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +264 -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 +139 -0
- package/src/components/TextField/USAGE.md +44 -0
- package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +119 -0
- package/src/components/TimePicker/TimePicker.module.css +291 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +141 -0
- package/src/components/TimePicker/TimePicker.test.tsx +1 -0
- package/src/components/TimePicker/TimePicker.tsx +304 -0
- package/src/components/TimePicker/USAGE.md +57 -0
- package/src/components/Timeline/TIMELINE_IMPLEMENTATION_NOTES.md +13 -0
- package/src/components/Timeline/Timeline.module.css +373 -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 +73 -0
- package/src/components/Timeline/TimelineItem.tsx +79 -0
- package/src/components/Timeline/USAGE.md +49 -0
- package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +39 -0
- package/src/components/Toast/Toast.module.css +184 -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 +82 -0
- package/src/components/Toast/USAGE.md +50 -0
- package/src/components/Toast/index.ts +1 -0
- package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
- package/src/components/Tooltip/Tooltip.module.css +91 -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 +117 -0
- package/src/components/Tooltip/USAGE.md +80 -0
- package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +111 -0
- package/src/components/TransferList/TransferList.module.css +182 -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/Tree/IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Tree/Tree.module.css +232 -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 +220 -0
- package/src/components/Tree/USAGE.md +96 -0
- package/src/components/Tree/index.ts +1 -0
- package/src/components/index.ts +52 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +179 -0
- package/src/types/index.ts +9 -0
- package/src/types/mantine.d.ts +7 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +27 -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 +150 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/renderRichOption.tsx +65 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Radio.module.css
|
|
3
|
+
*
|
|
4
|
+
* HARDCODED VALUES:
|
|
5
|
+
* - margin / padding: 0 — Structural resets; consider token if spacing needed.
|
|
6
|
+
* - cursor: pointer / not-allowed — Baseline interactive indications.
|
|
7
|
+
* - appearance / box-sizing / border-style — necessary normalization for inputs.
|
|
8
|
+
* - transition: all 0.2s ease — Animation curve; consider a transition token.
|
|
9
|
+
* - min-width: 0 — Forces text wrap boundary in flex children.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* --- GROUP STYLES --- */
|
|
13
|
+
.groupRoot {
|
|
14
|
+
padding: var(
|
|
15
|
+
--recursica_ui-kit_components_radio-button-group_properties_padding
|
|
16
|
+
);
|
|
17
|
+
margin: 0; /* HARDCODE: structural reset; consider token if layout needs change */
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: var(
|
|
21
|
+
--recursica_ui-kit_components_radio-button-group_properties_item-gap
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* SideBySide Variant */
|
|
26
|
+
.groupRoot[data-layout="side-by-side"] {
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
flex-wrap: wrap;
|
|
29
|
+
gap: var(
|
|
30
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_gutter
|
|
31
|
+
);
|
|
32
|
+
padding-top: var(
|
|
33
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
|
|
34
|
+
);
|
|
35
|
+
padding-bottom: var(
|
|
36
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
|
|
37
|
+
);
|
|
38
|
+
margin-top: var(
|
|
39
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
40
|
+
);
|
|
41
|
+
margin-bottom: var(
|
|
42
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Stacked Variant */
|
|
47
|
+
.groupRoot[data-layout="stacked"] {
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
margin-top: var(
|
|
50
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_label-field-gap
|
|
51
|
+
);
|
|
52
|
+
margin-bottom: var(
|
|
53
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* --- PRIMITIVE RADIO STYLES --- */
|
|
58
|
+
|
|
59
|
+
.root {
|
|
60
|
+
max-width: var(
|
|
61
|
+
--recursica_ui-kit_components_radio-button-item_properties_max-width
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.body {
|
|
66
|
+
display: flex;
|
|
67
|
+
align-items: flex-start;
|
|
68
|
+
gap: var(
|
|
69
|
+
--recursica_ui-kit_components_radio-button-item_properties_label-gap
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.root .inner {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
margin: 0; /* HARDCODE: structural reset */
|
|
78
|
+
width: var(--recursica_ui-kit_components_radio-button_properties_size);
|
|
79
|
+
height: var(--recursica_ui-kit_components_radio-button_properties_size);
|
|
80
|
+
/* Apply font-size to this element so that an 'em' based line-height token evaluates to the correct exact pixel value. */
|
|
81
|
+
font-size: var(
|
|
82
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_font-size
|
|
83
|
+
);
|
|
84
|
+
/* Mathematically syncs the physical input radio bounding block visually with the center of the text's first line.
|
|
85
|
+
NOTE: Since the Figma line-height token resolves to an 'em' length (e.g. 1.05em), we CANNOT multiply it by font-size in CSS.
|
|
86
|
+
Instead, it naturally evaluates to the correct height because we applied the font-size above. */
|
|
87
|
+
margin-top: calc(
|
|
88
|
+
(
|
|
89
|
+
var(
|
|
90
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_line-height
|
|
91
|
+
) -
|
|
92
|
+
var(--recursica_ui-kit_components_radio-button_properties_size)
|
|
93
|
+
) /
|
|
94
|
+
2
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Base explicit reset masking underlying framework defaults */
|
|
99
|
+
.root .radio {
|
|
100
|
+
cursor: pointer; /* HARDCODE: core interaction behavior */
|
|
101
|
+
appearance: none; /* HARDCODE: reset native widget */
|
|
102
|
+
box-sizing: border-box; /* HARDCODE: ensures size includes borders */
|
|
103
|
+
width: var(--recursica_ui-kit_components_radio-button_properties_size);
|
|
104
|
+
height: var(--recursica_ui-kit_components_radio-button_properties_size);
|
|
105
|
+
border-radius: var(
|
|
106
|
+
--recursica_ui-kit_components_radio-button_properties_border-radius
|
|
107
|
+
);
|
|
108
|
+
border-width: var(
|
|
109
|
+
--recursica_ui-kit_components_radio-button_properties_border-size
|
|
110
|
+
);
|
|
111
|
+
border-style: solid; /* HARDCODE: normalize primitive border-style */
|
|
112
|
+
|
|
113
|
+
/* Standard unchecked state */
|
|
114
|
+
background-color: var(
|
|
115
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_unselected_properties_colors_background-color
|
|
116
|
+
);
|
|
117
|
+
border-color: var(
|
|
118
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_unselected_properties_colors_border-color
|
|
119
|
+
);
|
|
120
|
+
transition: all 0.2s ease; /* HARDCODE: consider global transition token */
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Checked State */
|
|
124
|
+
.root .radio:checked {
|
|
125
|
+
background-color: var(
|
|
126
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_background-color
|
|
127
|
+
);
|
|
128
|
+
border-color: var(
|
|
129
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_border-color
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Disabled State (colors now differ per selection state, so each combination is mapped explicitly) */
|
|
134
|
+
.root .radio:disabled {
|
|
135
|
+
cursor: not-allowed; /* HARDCODE: disabled state default */
|
|
136
|
+
}
|
|
137
|
+
.root .radio:disabled:not(:checked) {
|
|
138
|
+
opacity: var(
|
|
139
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_opacity
|
|
140
|
+
);
|
|
141
|
+
background-color: var(
|
|
142
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_colors_background-color
|
|
143
|
+
);
|
|
144
|
+
border-color: var(
|
|
145
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_colors_border-color
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
.root .radio:checked:disabled {
|
|
149
|
+
opacity: var(
|
|
150
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_opacity
|
|
151
|
+
);
|
|
152
|
+
background-color: var(
|
|
153
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_background-color
|
|
154
|
+
);
|
|
155
|
+
border-color: var(
|
|
156
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_border-color
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.root .icon {
|
|
161
|
+
position: absolute;
|
|
162
|
+
inset: 0;
|
|
163
|
+
margin: auto;
|
|
164
|
+
pointer-events: none;
|
|
165
|
+
width: var(--recursica_ui-kit_components_radio-button_properties_icon-size);
|
|
166
|
+
height: var(--recursica_ui-kit_components_radio-button_properties_icon-size);
|
|
167
|
+
}
|
|
168
|
+
/* No icon-color token exists for the unselected state (no icon is visible then) */
|
|
169
|
+
.root .radio:checked + .iconWrapper .icon,
|
|
170
|
+
.root .radio:checked + .icon {
|
|
171
|
+
color: var(
|
|
172
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_icon-color
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
.root .radio:checked:disabled + .iconWrapper .icon,
|
|
176
|
+
.root .radio:checked:disabled + .icon {
|
|
177
|
+
color: var(
|
|
178
|
+
--recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_icon-color
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.root .labelWrapper {
|
|
183
|
+
padding: 0; /* HARDCODE: structural layout reset */
|
|
184
|
+
margin: 0; /* HARDCODE: structural layout reset */
|
|
185
|
+
flex: 1;
|
|
186
|
+
min-width: 0; /* HARDCODE: forces text wrap boundary in flex child */
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.root .label {
|
|
190
|
+
cursor: pointer; /* HARDCODE: interactive affordance */
|
|
191
|
+
padding: 0; /* HARDCODE: reset layout */
|
|
192
|
+
margin: 0; /* HARDCODE: reset layout */
|
|
193
|
+
word-wrap: break-word;
|
|
194
|
+
white-space: normal;
|
|
195
|
+
color: var(
|
|
196
|
+
--recursica_ui-kit_components_radio-button-item_properties_colors_text-color
|
|
197
|
+
);
|
|
198
|
+
font-family: var(
|
|
199
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_font-family
|
|
200
|
+
);
|
|
201
|
+
font-size: var(
|
|
202
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_font-size
|
|
203
|
+
);
|
|
204
|
+
font-weight: var(
|
|
205
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_font-weight
|
|
206
|
+
);
|
|
207
|
+
line-height: var(
|
|
208
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_line-height
|
|
209
|
+
);
|
|
210
|
+
font-style: var(
|
|
211
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_font-style
|
|
212
|
+
);
|
|
213
|
+
letter-spacing: var(
|
|
214
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_letter-spacing
|
|
215
|
+
);
|
|
216
|
+
text-decoration: var(
|
|
217
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_text-decoration
|
|
218
|
+
);
|
|
219
|
+
text-transform: var(
|
|
220
|
+
--recursica_ui-kit_components_radio-button-item_properties_text_text-transform
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
.root:has(input:disabled) .label {
|
|
224
|
+
cursor: not-allowed; /* HARDCODE: disabled interaction */
|
|
225
|
+
color: var(
|
|
226
|
+
--recursica_ui-kit_components_radio-button-item_properties_colors_disabled-text
|
|
227
|
+
);
|
|
228
|
+
opacity: var(
|
|
229
|
+
--recursica_ui-kit_components_radio-button-item_variants_states_disabled_properties_opacity
|
|
230
|
+
);
|
|
231
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Radio } from "./Radio";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Radio> = {
|
|
5
|
+
title: "UI-Kit/Radio",
|
|
6
|
+
component: Radio,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
The \`Radio\` component represents a fundamental standalone boolean selection node mapping to the native HTML \`<input type="radio">\`.
|
|
13
|
+
|
|
14
|
+
> [!WARNING]
|
|
15
|
+
> This component represents the isolated primitive structure. If you need macro form configurations, standard vertical alignments, side-by-side array wrappers, or integrated assistive text and error borders natively, you MUST use the \`<Radio.Group>\` orchestrator instead!
|
|
16
|
+
`,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
argTypes: {
|
|
21
|
+
disabled: {
|
|
22
|
+
control: "boolean",
|
|
23
|
+
},
|
|
24
|
+
checked: {
|
|
25
|
+
control: "boolean",
|
|
26
|
+
},
|
|
27
|
+
readOnly: {
|
|
28
|
+
control: "boolean",
|
|
29
|
+
},
|
|
30
|
+
error: {
|
|
31
|
+
control: "boolean",
|
|
32
|
+
},
|
|
33
|
+
defaultChecked: {
|
|
34
|
+
control: "boolean",
|
|
35
|
+
},
|
|
36
|
+
controlMaxWidth: { table: { disable: true } },
|
|
37
|
+
controlMinWidth: { table: { disable: true } },
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
|
|
43
|
+
type Story = StoryObj<typeof Radio>;
|
|
44
|
+
|
|
45
|
+
export const Default: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
label: "Standard Radio Primitive",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const SideBySideLayout: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
label: "Opt-in form alignment",
|
|
54
|
+
formLayout: "side-by-side",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const CheckedState: Story = {
|
|
59
|
+
args: {
|
|
60
|
+
...Default.args,
|
|
61
|
+
defaultChecked: true,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const DisabledUnchecked: Story = {
|
|
66
|
+
args: {
|
|
67
|
+
...Default.args,
|
|
68
|
+
disabled: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const DisabledChecked: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
...Default.args,
|
|
75
|
+
disabled: true,
|
|
76
|
+
defaultChecked: true,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const ReadOnly: Story = {
|
|
81
|
+
args: {},
|
|
82
|
+
render: () => (
|
|
83
|
+
<div
|
|
84
|
+
style={{
|
|
85
|
+
display: "flex",
|
|
86
|
+
flexDirection: "column",
|
|
87
|
+
gap: "24px",
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<Radio label="Account Type" defaultChecked readOnly />
|
|
91
|
+
</div>
|
|
92
|
+
),
|
|
93
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Radio component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Radio as MantineRadio,
|
|
4
|
+
type RadioProps as MantineRadioProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
7
|
+
import { RadioGroup } from "./RadioGroup";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
11
|
+
withCallerOverride,
|
|
12
|
+
mergeClassNames,
|
|
13
|
+
type RecursicaOverStyled,
|
|
14
|
+
} from "../../utils/filterStylingProps";
|
|
15
|
+
import {
|
|
16
|
+
type RequireAccessibleLabel,
|
|
17
|
+
type RecursicaRadioProps,
|
|
18
|
+
} from "@recursica/adapter-common";
|
|
19
|
+
import {
|
|
20
|
+
FormControlLayout,
|
|
21
|
+
type FormControlLayoutProps,
|
|
22
|
+
} from "../FormControlLayout/FormControlLayout";
|
|
23
|
+
|
|
24
|
+
import styles from "./Radio.module.css";
|
|
25
|
+
|
|
26
|
+
const RadioIcon: React.FC<{
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: React.CSSProperties;
|
|
29
|
+
}> = ({ className, style }) => (
|
|
30
|
+
<svg
|
|
31
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
+
viewBox="0 0 16 16"
|
|
33
|
+
fill="currentColor"
|
|
34
|
+
className={className}
|
|
35
|
+
style={style}
|
|
36
|
+
>
|
|
37
|
+
<circle cx="8" cy="8" r="5" />
|
|
38
|
+
</svg>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export type RadioWrapperProps = Omit<
|
|
42
|
+
MantineRadioProps,
|
|
43
|
+
"size" | "color" | "radius" | "iconColor" | "variant"
|
|
44
|
+
> &
|
|
45
|
+
RecursicaRadioProps &
|
|
46
|
+
ReadOnlyControlProps &
|
|
47
|
+
Pick<
|
|
48
|
+
FormControlLayoutProps,
|
|
49
|
+
"formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
|
|
50
|
+
>;
|
|
51
|
+
|
|
52
|
+
export type RecursicaRadioPropsAlias =
|
|
53
|
+
RequireAccessibleLabel<RadioWrapperProps>;
|
|
54
|
+
|
|
55
|
+
export type RadioProps = RecursicaOverStyled<RecursicaRadioPropsAlias>;
|
|
56
|
+
|
|
57
|
+
type RadioComponent = React.ForwardRefExoticComponent<
|
|
58
|
+
RadioProps & React.RefAttributes<HTMLInputElement>
|
|
59
|
+
> & {
|
|
60
|
+
Group: typeof RadioGroup;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
64
|
+
function Radio(props, ref) {
|
|
65
|
+
const {
|
|
66
|
+
overStyled = false,
|
|
67
|
+
readOnly,
|
|
68
|
+
readOnlyComponent,
|
|
69
|
+
disabled,
|
|
70
|
+
icon,
|
|
71
|
+
formLayout,
|
|
72
|
+
labelSize,
|
|
73
|
+
controlMaxWidth,
|
|
74
|
+
controlMinWidth,
|
|
75
|
+
...rest
|
|
76
|
+
} = props;
|
|
77
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
78
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
79
|
+
const UNSUPPORTED_PROPS = [
|
|
80
|
+
"size", // Recursica controls sizing via Radio.module.css variables, not Mantine's native size scale.
|
|
81
|
+
"color", // Colors are token-driven via Radio.module.css; Mantine's native palette isn't exposed.
|
|
82
|
+
"radius", // Corner radius is fixed by Recursica tokens in Radio.module.css, not caller-configurable.
|
|
83
|
+
"variant", // Radio has a single Recursica-defined visual treatment; Mantine's variant isn't exposed.
|
|
84
|
+
"iconColor", // Icon color is token-driven via Radio.module.css, not a native Mantine override.
|
|
85
|
+
] as const satisfies readonly (keyof MantineRadioProps)[];
|
|
86
|
+
|
|
87
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
88
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
89
|
+
UNSUPPORTED_PROPS,
|
|
90
|
+
) as Partial<typeof rest>;
|
|
91
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
92
|
+
|
|
93
|
+
const mergedClassNames = mergeClassNames(
|
|
94
|
+
{
|
|
95
|
+
root: styles.root,
|
|
96
|
+
body: styles.body,
|
|
97
|
+
inner: styles.inner,
|
|
98
|
+
radio: styles.radio,
|
|
99
|
+
icon: styles.icon,
|
|
100
|
+
labelWrapper: styles.labelWrapper,
|
|
101
|
+
label: styles.label,
|
|
102
|
+
},
|
|
103
|
+
restRecord.classNames as Partial<Record<string, string>> | undefined,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
107
|
+
const finalClass = classNameProp
|
|
108
|
+
? `${styles.root} ${classNameProp}`
|
|
109
|
+
: styles.root;
|
|
110
|
+
|
|
111
|
+
if (readOnly && !!readOnlyComponent) {
|
|
112
|
+
const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
|
|
113
|
+
const ReadOnlyComp = readOnlyComponent;
|
|
114
|
+
const roNode = (
|
|
115
|
+
<ReadOnlyComp
|
|
116
|
+
{...props}
|
|
117
|
+
checked={isChecked}
|
|
118
|
+
label={restRecord.label as React.ReactNode}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (formLayout) {
|
|
123
|
+
return (
|
|
124
|
+
<FormControlLayout
|
|
125
|
+
formLayout={formLayout}
|
|
126
|
+
labelSize={labelSize}
|
|
127
|
+
controlMaxWidth={controlMaxWidth}
|
|
128
|
+
controlMinWidth={controlMinWidth}
|
|
129
|
+
>
|
|
130
|
+
{roNode}
|
|
131
|
+
</FormControlLayout>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return <>{roNode}</>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// We omit Mantine's sizing/coloring so we rely strictly on variables from Radio.module.css
|
|
139
|
+
const radioNode = (
|
|
140
|
+
<MantineRadio
|
|
141
|
+
ref={ref}
|
|
142
|
+
{...(sanitizedProps as unknown as MantineRadioProps)}
|
|
143
|
+
icon={withCallerOverride<MantineRadioProps["icon"]>(RadioIcon, icon)}
|
|
144
|
+
className={finalClass}
|
|
145
|
+
classNames={mergedClassNames}
|
|
146
|
+
disabled={readOnly || disabled}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (formLayout) {
|
|
151
|
+
return (
|
|
152
|
+
<FormControlLayout
|
|
153
|
+
formLayout={formLayout}
|
|
154
|
+
labelSize={labelSize}
|
|
155
|
+
controlMaxWidth={controlMaxWidth}
|
|
156
|
+
controlMinWidth={controlMinWidth}
|
|
157
|
+
>
|
|
158
|
+
{radioNode}
|
|
159
|
+
</FormControlLayout>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return radioNode;
|
|
164
|
+
},
|
|
165
|
+
) as RadioComponent;
|
|
166
|
+
|
|
167
|
+
Radio.displayName = "Radio";
|
|
168
|
+
Radio.Group = RadioGroup;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Radio } from "./Radio";
|
|
3
|
+
import { RadioGroup } from "./RadioGroup";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof RadioGroup> = {
|
|
8
|
+
title: "UI-Kit/RadioGroup",
|
|
9
|
+
component: RadioGroup,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
The \`RadioGroup\` component is the mandatory organizational wrapper aggregating multiple \`Radio\` primitives into structurally bound unified selection arrays. It inherently leverages the \`FormControlWrapper\` granting native access to macroscopic layout structuring, assistive descriptions, and strict flex arrays.
|
|
16
|
+
|
|
17
|
+
We exclusively utilize the \`formLayout\` parameter to control macro-level form flow:
|
|
18
|
+
- **\`formLayout="stacked"\`**: Top-to-bottom layout cascading the Label bounding box down vertically into a standard stacked radio column array.
|
|
19
|
+
- **\`formLayout="side-by-side"\`**: Flow architecture pulling the grouping Label dynamically to the left while structurally organizing the internal radios cleanly alongside it horizontally.
|
|
20
|
+
`,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
argTypes: {
|
|
25
|
+
...formControlArgTypes,
|
|
26
|
+
readOnly: {
|
|
27
|
+
control: "boolean",
|
|
28
|
+
description:
|
|
29
|
+
"Toggles structural read-only data presentation bypassing interaction boundaries completely.",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj<typeof RadioGroup>;
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
formLayout: "stacked",
|
|
41
|
+
label: "Standard Group",
|
|
42
|
+
},
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
44
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
45
|
+
const [value, setValue] = useState<string>("");
|
|
46
|
+
return (
|
|
47
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
48
|
+
<Radio value="1" label="Option 1" />
|
|
49
|
+
<Radio value="2" label="Option 2" />
|
|
50
|
+
</RadioGroup>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const StackedLayout: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
formLayout: "stacked",
|
|
58
|
+
required: true,
|
|
59
|
+
label: "Hosting Provider",
|
|
60
|
+
error: "You must select a deployment provider.",
|
|
61
|
+
},
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
63
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
64
|
+
const [value, setValue] = useState<string>("aws");
|
|
65
|
+
return (
|
|
66
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
67
|
+
<Radio value="aws" label="Amazon Web Services" />
|
|
68
|
+
<Radio
|
|
69
|
+
value="gcp"
|
|
70
|
+
label="Google Cloud Platform (with completely distributed edge computing environments bridging local runtime boundaries seamlessly.)"
|
|
71
|
+
/>
|
|
72
|
+
<Radio value="azure" label="Microsoft Azure" />
|
|
73
|
+
</RadioGroup>
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const SideBySideLayout: Story = {
|
|
79
|
+
args: {
|
|
80
|
+
formLayout: "side-by-side",
|
|
81
|
+
labelOptionalText: "Recommended",
|
|
82
|
+
labelWithEditIcon: true,
|
|
83
|
+
label: "Deployment Region",
|
|
84
|
+
assistiveText: "Select the data center closest to your user base.",
|
|
85
|
+
},
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
87
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
88
|
+
const [value, setValue] = useState<string>("us-east");
|
|
89
|
+
return (
|
|
90
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
91
|
+
<Radio value="us-east" label="US East (N. Virginia)" />
|
|
92
|
+
<Radio value="us-west" label="US West (Oregon)" />
|
|
93
|
+
<Radio value="eu-central" label="EU Central (Frankfurt)" />
|
|
94
|
+
</RadioGroup>
|
|
95
|
+
);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const ReadOnly: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
readOnly: true,
|
|
102
|
+
formLayout: "stacked",
|
|
103
|
+
required: true,
|
|
104
|
+
label: "Selected Framework",
|
|
105
|
+
assistiveText: "This selection cannot be changed after initialization.",
|
|
106
|
+
},
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
108
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
109
|
+
const [value, setValue] = useState<string>("react");
|
|
110
|
+
return (
|
|
111
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
112
|
+
<Radio value="react" label="React" />
|
|
113
|
+
<Radio value="vue" label="Vue" />
|
|
114
|
+
</RadioGroup>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
};
|