@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,147 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { forwardRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
Checkbox as MantineCheckbox,
|
|
5
|
+
type CheckboxGroupProps as MantineCheckboxGroupProps,
|
|
6
|
+
} from "@mantine/core";
|
|
7
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
omitUnsupportedProps,
|
|
11
|
+
type RecursicaOverStyled,
|
|
12
|
+
} from "../../utils/filterStylingProps";
|
|
13
|
+
import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
|
|
14
|
+
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
15
|
+
import styles from "./Checkbox.module.css";
|
|
16
|
+
|
|
17
|
+
import { type RecursicaCheckboxGroupProps as BaseRecursicaCheckboxGroupProps } from "@recursica/adapter-common";
|
|
18
|
+
|
|
19
|
+
export interface RecursicaCheckboxGroupProps
|
|
20
|
+
extends Omit<
|
|
21
|
+
MantineCheckboxGroupProps,
|
|
22
|
+
"size" | "labelProps" | "defaultValue" | "value"
|
|
23
|
+
>,
|
|
24
|
+
Omit<
|
|
25
|
+
RecursicaFormControlWrapperProps,
|
|
26
|
+
"controlMaxWidth" | "controlMinWidth"
|
|
27
|
+
>,
|
|
28
|
+
ReadOnlyControlProps,
|
|
29
|
+
BaseRecursicaCheckboxGroupProps {}
|
|
30
|
+
|
|
31
|
+
export type CheckboxGroupProps =
|
|
32
|
+
RecursicaOverStyled<RecursicaCheckboxGroupProps>;
|
|
33
|
+
|
|
34
|
+
export const CheckboxGroup = forwardRef<HTMLDivElement, CheckboxGroupProps>(
|
|
35
|
+
function CheckboxGroup(props, ref) {
|
|
36
|
+
const {
|
|
37
|
+
overStyled = false,
|
|
38
|
+
formLayout = "stacked",
|
|
39
|
+
|
|
40
|
+
// Label Wrappers
|
|
41
|
+
labelSize,
|
|
42
|
+
labelAlignment,
|
|
43
|
+
labelOptionalText,
|
|
44
|
+
labelWithEditIcon,
|
|
45
|
+
onLabelEditClick,
|
|
46
|
+
|
|
47
|
+
// Base Mantine Extracted Attributes
|
|
48
|
+
label,
|
|
49
|
+
description,
|
|
50
|
+
assistiveText,
|
|
51
|
+
assistiveWithIcon,
|
|
52
|
+
error,
|
|
53
|
+
required,
|
|
54
|
+
withAsterisk,
|
|
55
|
+
id,
|
|
56
|
+
className,
|
|
57
|
+
style,
|
|
58
|
+
children,
|
|
59
|
+
readOnly,
|
|
60
|
+
readOnlyComponent,
|
|
61
|
+
emptyValueComponent,
|
|
62
|
+
value,
|
|
63
|
+
defaultValue,
|
|
64
|
+
...rest
|
|
65
|
+
} = props;
|
|
66
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
67
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
68
|
+
const UNSUPPORTED_PROPS = [
|
|
69
|
+
"size", // Recursica controls sizing via Checkbox.module.css variables, not Mantine's native size scale.
|
|
70
|
+
] as const satisfies readonly (keyof MantineCheckboxGroupProps)[];
|
|
71
|
+
|
|
72
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
73
|
+
filterStylingProps(rest, overStyled) as Record<string, unknown>,
|
|
74
|
+
UNSUPPORTED_PROPS,
|
|
75
|
+
) as Partial<typeof rest>;
|
|
76
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
77
|
+
|
|
78
|
+
// Mantine's own `Checkbox.Group` always establishes a context whose `value` defaults to
|
|
79
|
+
// `[]` (see @mantine/core's `useUncontrolled({ finalValue: [] })`), and its `Checkbox` spreads
|
|
80
|
+
// that context-derived `checked` *after* the individually-passed `checked` prop — so any
|
|
81
|
+
// `Checkbox` nested in a real `Checkbox.Group`, even one given neither `value` nor
|
|
82
|
+
// `defaultValue`, has its own `checked` prop silently forced to `false`. Callers who only want
|
|
83
|
+
// this component for its layout (item-gap spacing), not array-tracked selection — e.g.
|
|
84
|
+
// `TransferList`'s ungrouped rows, which pass each `Checkbox` its own controlled `checked` —
|
|
85
|
+
// must skip Mantine's real group primitive entirely rather than hand it an empty value.
|
|
86
|
+
const isArrayControlled = value !== undefined || defaultValue !== undefined;
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<WithReadOnlyWrapper
|
|
90
|
+
className={className}
|
|
91
|
+
style={style as React.CSSProperties}
|
|
92
|
+
controlMaxWidth="var(--recursica_ui-kit_components_checkbox-item_properties_max-width)"
|
|
93
|
+
controlMinWidth={undefined}
|
|
94
|
+
overStyled={overStyled as true}
|
|
95
|
+
labelElement="div" // Strictly override. ARIA grouping prohibits interactive checkboxes nested natively inside <label>.
|
|
96
|
+
formLayout={formLayout}
|
|
97
|
+
labelSize={labelSize}
|
|
98
|
+
labelAlignment={labelAlignment}
|
|
99
|
+
labelOptionalText={labelOptionalText}
|
|
100
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
101
|
+
onLabelEditClick={onLabelEditClick}
|
|
102
|
+
label={label}
|
|
103
|
+
description={description}
|
|
104
|
+
assistiveText={assistiveText}
|
|
105
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
106
|
+
error={error}
|
|
107
|
+
required={required}
|
|
108
|
+
withAsterisk={withAsterisk}
|
|
109
|
+
id={id}
|
|
110
|
+
readOnly={readOnly && !!readOnlyComponent}
|
|
111
|
+
readOnlyComponent={readOnlyComponent}
|
|
112
|
+
emptyValueComponent={emptyValueComponent}
|
|
113
|
+
readOnlyType="text"
|
|
114
|
+
readOnlyValue={value !== undefined ? value : defaultValue}
|
|
115
|
+
readOnlyNativeProps={props}
|
|
116
|
+
activeComponent={
|
|
117
|
+
isArrayControlled ? (
|
|
118
|
+
<MantineCheckbox.Group
|
|
119
|
+
ref={ref}
|
|
120
|
+
/* Natively bind local disabled lock dynamically */
|
|
121
|
+
{...(sanitizedProps as unknown as MantineCheckboxGroupProps)}
|
|
122
|
+
disabled={readOnly || (restRecord as any).disabled}
|
|
123
|
+
value={value as any}
|
|
124
|
+
defaultValue={defaultValue as any}
|
|
125
|
+
>
|
|
126
|
+
<div className={styles.groupRoot} data-layout={formLayout}>
|
|
127
|
+
{children}
|
|
128
|
+
</div>
|
|
129
|
+
</MantineCheckbox.Group>
|
|
130
|
+
) : (
|
|
131
|
+
<div
|
|
132
|
+
ref={ref}
|
|
133
|
+
{...(sanitizedProps as Record<string, unknown>)}
|
|
134
|
+
role="group"
|
|
135
|
+
className={styles.groupRoot}
|
|
136
|
+
data-layout={formLayout}
|
|
137
|
+
>
|
|
138
|
+
{children}
|
|
139
|
+
</div>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
CheckboxGroup.displayName = "CheckboxGroup";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Checkbox - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Checkbox` component in your projects using `@recursica/adapter-mantine-v8`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Checkbox } from "@recursica/adapter-mantine-v8";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Checkbox } from "@recursica/adapter-mantine-v8";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return <Checkbox label="Accept terms and conditions" defaultChecked />;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Design System Integration
|
|
29
|
+
|
|
30
|
+
All Recursica components in the `@recursica/adapter-mantine-v8` 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.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 4. Key Integration Features & Constraints
|
|
41
|
+
|
|
42
|
+
### Checkbox Alignment with Multi-line Labels
|
|
43
|
+
|
|
44
|
+
Checkbox visually aligns to the first line of a wrapping, multi-line label.
|
|
45
|
+
|
|
46
|
+
### Checkbox.Group
|
|
47
|
+
|
|
48
|
+
`Checkbox.Group` integrates with the same label, description, and error props as other Recursica form components.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Chip Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Architecture decisions
|
|
4
|
+
|
|
5
|
+
### Mantine DOM Structure & Label Overrides
|
|
6
|
+
|
|
7
|
+
Mantine's `<Chip>` behaves like an input element (`radio` or `checkbox`). Under the hood, it renders:
|
|
8
|
+
|
|
9
|
+
1. `.mantine-Chip-root` (wrapper)
|
|
10
|
+
2. `input` (hidden visual structure)
|
|
11
|
+
3. `.mantine-Chip-label` (The actual visible button-like pill)
|
|
12
|
+
|
|
13
|
+
Because the `.label` is the primary visual surface and handles Mantine's built-in `:hover` and active states, we direct our Recursica styling natively to `.label`.
|
|
14
|
+
|
|
15
|
+
### Icon and Remove Implementations
|
|
16
|
+
|
|
17
|
+
To achieve this without breaking Mantine's `Chip` input architecture, we wrapped the internal `children` using a standard `span` DOM strategy:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<span className={styles.innerWrapper}>
|
|
21
|
+
{icon}
|
|
22
|
+
<span className={styles.children}>{children}</span>
|
|
23
|
+
{onDelete}
|
|
24
|
+
</span>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
#### Intermediate Children Wrapper Span display fix:
|
|
28
|
+
|
|
29
|
+
Mantine internally wraps the children passed to `Chip` in a default `<span>` which has `display: inline`. This intermediate `span` inherits the `line-height` of the `.label` container, causing the computed height of the Chip to be ~2px taller than expected. To address this, `.label > span:not(.mantineIconWrapper)` is targeted to force `display: inline-flex; align-items: center;` on that intermediate wrapper `span`, allowing it to collapse perfectly to the `16px` height of the `innerWrapper`.
|
|
30
|
+
|
|
31
|
+
### Accessibility of Remove Action
|
|
32
|
+
|
|
33
|
+
Because the Chip fundamentally functions as a `<label>` linked to an `<input>`, placing a raw interactive element like `<button>` directly inside the standard Chip sub-tree violates nested interactive element ARIA constraints in strict validators.
|
|
34
|
+
To accommodate this, the visual "close" icon uses a `<span>` element configured with `role="button"` and `tabIndex={0}` to hook into standard keyboard activations without triggering generic nested `<form>` conflicts native to Mantine's baseline constraints.
|
|
35
|
+
|
|
36
|
+
### Removing Sizing Properties
|
|
37
|
+
|
|
38
|
+
During implementation, the parsed Figma design tokens natively exported specific height/padding vectors dynamically (e.g., `--recursica_ui-kit_components_chip_properties_icon-size`) rather than explicit string variants (`sm`, `md`, `lg`). Therefore, we omitted `size` conceptually from the `RecursicaChipProps` wrapper to lock down size evaluation natively against the active layer variables.
|
|
39
|
+
|
|
40
|
+
### Long-label truncation was hiding the remove icon (Matt Massey, 2026-08-17)
|
|
41
|
+
|
|
42
|
+
`.children` already had `text-overflow: ellipsis; overflow: hidden; white-space: nowrap;`, but
|
|
43
|
+
neither it nor its parent `.innerWrapper` had `min-width: 0` — a flex child without that refuses
|
|
44
|
+
to shrink below its intrinsic (full, unwrapped) content width, so `text-overflow: ellipsis` never
|
|
45
|
+
actually engaged. A long label overflowed the flex row instead, and since `.deleteIcon` had no
|
|
46
|
+
`flex-shrink: 0`, it got squeezed out of the clipped (`max-width`-bounded) chip entirely. Fixed by
|
|
47
|
+
adding `min-width: 0` to `.innerWrapper`/`.children` and `flex-shrink: 0` to `.leadingIcon`/
|
|
48
|
+
`.deleteIcon`. Reproduces easily with `FileUpload`'s file list, since its chip `max-width`
|
|
49
|
+
(`--recursica_ui-kit_components_chip_properties_max-width`, 200px) is small enough that most real
|
|
50
|
+
filenames overflow it.
|
|
51
|
+
|
|
52
|
+
### Descenders were being clipped on `.children` and `.root` (Matt Massey, 2026-08-18)
|
|
53
|
+
|
|
54
|
+
A label with a descender (e.g. the "g" in "image.png") had its bottom clipped off. Both `.children`
|
|
55
|
+
and `.root.root` set plain `overflow: hidden` — needed on the x-axis so `.children`'s
|
|
56
|
+
`text-overflow: ellipsis` (and `.root`'s `max-width`) actually clip long labels, but clipping the
|
|
57
|
+
y-axis too cuts off any glyph ink that extends past the line box, which happens whenever the
|
|
58
|
+
`text_line-height` token is tighter than the font's natural ascent+descent. Fixed by splitting both
|
|
59
|
+
into `overflow-x: hidden; overflow-y: visible;` — ellipsis/max-width truncation is unaffected (still
|
|
60
|
+
x-axis only), but descenders can now paint outside a too-tight line box instead of being clipped.
|
|
61
|
+
`.root` has no background/border-radius of its own to protect (that's `.label`), so opening its
|
|
62
|
+
y-axis has no visual side effect.
|
|
63
|
+
|
|
64
|
+
### Roving tabindex support for chip groups (Matt Massey, 2026-08-17)
|
|
65
|
+
|
|
66
|
+
Added two optional pass-through props — `deleteTabIndex` and `deleteIconRef` — purely so a parent
|
|
67
|
+
managing a _group_ of chips (e.g. `FileUpload`'s file list, see its own `IMPLEMENTATION_NOTES.md`)
|
|
68
|
+
can implement roving-tabindex/arrow-key navigation across them: set `deleteTabIndex={-1}` on every
|
|
69
|
+
chip but the currently-active one, and use `deleteIconRef` to move real DOM focus there
|
|
70
|
+
imperatively on arrow-key press. Both are no-ops for a standalone `Chip` (defaults: `tabIndex={0}`,
|
|
71
|
+
no ref) — this doesn't change any existing single-chip behavior.
|
|
72
|
+
|
|
73
|
+
### `isInteractive` was measuring the wrong signal, and leaked a pointer cursor + phantom Tab stop (Matt Massey, 2026-08-18)
|
|
74
|
+
|
|
75
|
+
A `Chip` rendered with `checked` but no real handler (e.g. `FileUpload`'s `readOnly` file list —
|
|
76
|
+
`<Chip checked={false} tabIndex={-1}>`, no `onDelete`) still looked and behaved clickable, from two
|
|
77
|
+
separate bugs:
|
|
78
|
+
|
|
79
|
+
- `isInteractive` treated `checked !== undefined` (even `false`) as proof of interactivity. That's
|
|
80
|
+
the wrong signal — a `checked`-controlled chip with no `onChange` can't actually be toggled by a
|
|
81
|
+
click (Mantine's `useUncontrolled` discards the click when `value` is externally controlled), so
|
|
82
|
+
clicking it does nothing observable regardless. `isInteractive` now only looks at whether
|
|
83
|
+
something actually responds: `onDelete`, `onClick`, or `onChange`.
|
|
84
|
+
- `.label.label` never set its own `cursor`, so Mantine's base style (`cursor: pointer`, hardcoded
|
|
85
|
+
on the underlying `mantine-Chip-label` class) always leaked through, independent of whether the
|
|
86
|
+
chip was actually interactive. Reset it to `cursor: default` and added a `data-interactive`
|
|
87
|
+
attribute (driven by the fixed `isInteractive` above, set via `wrapperProps` on `MantineChip` so
|
|
88
|
+
it lands on `.root`) that re-enables `pointer` via `.root[data-interactive] .label.label` only
|
|
89
|
+
when there's a real handler.
|
|
90
|
+
|
|
91
|
+
Separately, `.children`'s `overflow-x: hidden` (added for ellipsis truncation) made it a scroll
|
|
92
|
+
container, and Chromium auto-adds scroll containers with actually-overflowing content to the Tab
|
|
93
|
+
order — with no `tabindex` attribute at all — so a solo Tab press could land on a chip's plain
|
|
94
|
+
filename text before ever reaching a real control. Switched to `overflow-x: clip`, which doesn't
|
|
95
|
+
establish a scrollport (same visual clipping, still x-axis only per the descender fix above), so
|
|
96
|
+
it's no longer a focus candidate. This affected every chip with long enough content, not just
|
|
97
|
+
read-only ones — see `FileUpload`'s own `IMPLEMENTATION_NOTES.md` for how it surfaced there.
|
|
98
|
+
|
|
99
|
+
### Selected check icon sat to the left of the leading icon instead of replacing it (Matt Massey, 2026-08-28)
|
|
100
|
+
|
|
101
|
+
A checked `Chip` with a custom `icon` (leading icon) rendered both: Mantine's own default check
|
|
102
|
+
icon (via its native `iconWrapper`/`checkIcon` slot, always shown whenever `checked` and its own
|
|
103
|
+
`icon` prop — a different, unrelated slot — is left `undefined`) came first in the DOM, immediately
|
|
104
|
+
followed by this adapter's own `.leadingIcon` span, which we always rendered regardless of checked
|
|
105
|
+
state. mui-adapter's `Chip` never had this problem, since its `icon={checked ? checkIcon : icon}`
|
|
106
|
+
was already a straight swap. Fixed adapter-mantine-v8 to match: the custom `.leadingIcon` span now
|
|
107
|
+
only renders when `!checked`, so Mantine's native checkmark overlays/replaces it instead of sitting
|
|
108
|
+
to its left. Required destructuring `checked` explicitly (previously left in `...rest` and passed
|
|
109
|
+
through opaquely) so the render condition and the explicit `checked` prop on `<MantineChip>` stay
|
|
110
|
+
in sync.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
|
|
2
|
+
* Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
|
|
3
|
+
* recursica-allow-brand: --recursica_brand_states_disabled
|
|
4
|
+
* recursica-allow-brand: --recursica_brand_states_focus_blur
|
|
5
|
+
* recursica-allow-brand: --recursica_brand_states_focus_border-size
|
|
6
|
+
* recursica-allow-brand: --recursica_brand_states_focus_color
|
|
7
|
+
* recursica-allow-brand: --recursica_brand_states_focus_margin
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* HARDCODED VALUES
|
|
11
|
+
border-style: solid; (Baseline reset)
|
|
12
|
+
box-sizing: border-box; (Baseline reset)
|
|
13
|
+
display: inline-flex; (Baseline reset)
|
|
14
|
+
align-items: center; (Baseline reset)
|
|
15
|
+
outline: none; (Accessible fallback)
|
|
16
|
+
padding: 0; (Override mantine default)
|
|
17
|
+
background: transparent; (Override mantine default)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/* EXEMPTIONS:
|
|
21
|
+
- The leading icon and the selected/check icon are mutually exclusive (Chip.tsx only renders
|
|
22
|
+
the leading icon when `!checked`; Mantine's own check icon takes over when checked) — so for
|
|
23
|
+
any given state, exactly one of `leading-icon-color`/`selected-icon-color` ever applies. The
|
|
24
|
+
other one, and the non-state-specific base `properties_leading-icon-color`/
|
|
25
|
+
`properties_close-icon-color` (superseded by the per-selection-state values actually used),
|
|
26
|
+
are never referenced by design, not missing. Same for the generic (non-leading/selected)
|
|
27
|
+
`colors_icon-color` on the error variants — the more specific leading/selected token already
|
|
28
|
+
covers it. */
|
|
29
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_properties_close-icon-color */
|
|
30
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_properties_leading-icon-color */
|
|
31
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_leading-icon-color */
|
|
32
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_icon-color */
|
|
33
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_leading-icon-color */
|
|
34
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_selected-icon-color */
|
|
35
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_icon-color */
|
|
36
|
+
/* recursica-ignore: --recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_selected-icon-color */
|
|
37
|
+
|
|
38
|
+
.root.root {
|
|
39
|
+
/* Set preset layout variables to override mantine defaults safely */
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
|
|
43
|
+
/* Token properties */
|
|
44
|
+
--chip-height: max-content; /* Sizing is driven by padding and line height */
|
|
45
|
+
--chip-bg: var(
|
|
46
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_background-color
|
|
47
|
+
);
|
|
48
|
+
--chip-border: var(
|
|
49
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_border-color
|
|
50
|
+
);
|
|
51
|
+
--chip-text: var(
|
|
52
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_text-color
|
|
53
|
+
);
|
|
54
|
+
--chip-icon: var(
|
|
55
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_leading-icon-color
|
|
56
|
+
);
|
|
57
|
+
--chip-close: var(
|
|
58
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_properties_colors_close-icon-color
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/* Override Mantine's internal variables */
|
|
62
|
+
--chip-size: max-content;
|
|
63
|
+
--chip-radius: var(
|
|
64
|
+
--recursica_ui-kit_components_chip_properties_border-radius
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
user-select: none;
|
|
68
|
+
overflow-x: hidden; /* HARDCODE: horizontal-only, same descender reasoning as .children below —
|
|
69
|
+
.root has no visible background of its own (that's .label), so there's nothing here that
|
|
70
|
+
needs vertical clipping */
|
|
71
|
+
overflow-y: visible;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* We target the mantine label directly because that is the visible container in Mantine's Chip */
|
|
75
|
+
.label.label {
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
|
|
81
|
+
/* Reset mantine styles */
|
|
82
|
+
background: transparent; /* HARDCODE: Mantine forces background styling on label */
|
|
83
|
+
cursor: default; /* HARDCODE: Mantine's own base styles hardcode cursor: pointer on this class —
|
|
84
|
+
override it to plain default, then only re-enable it below for a chip with a real handler
|
|
85
|
+
(onDelete/onClick/onChange — see Chip.tsx's `isInteractive`). A display-only chip (e.g. a
|
|
86
|
+
read-only FileUpload file list) has nothing for a click to do, so it shouldn't look clickable. */
|
|
87
|
+
border-style: solid;
|
|
88
|
+
border-width: var(--recursica_ui-kit_components_chip_properties_border-size);
|
|
89
|
+
padding: var(--recursica_ui-kit_components_chip_properties_vertical-padding)
|
|
90
|
+
var(--recursica_ui-kit_components_chip_properties_horizontal-padding);
|
|
91
|
+
|
|
92
|
+
/* Typography */
|
|
93
|
+
font-family: var(
|
|
94
|
+
--recursica_ui-kit_components_chip_properties_text_font-family
|
|
95
|
+
);
|
|
96
|
+
font-size: var(--recursica_ui-kit_components_chip_properties_text_font-size);
|
|
97
|
+
font-weight: var(
|
|
98
|
+
--recursica_ui-kit_components_chip_properties_text_font-weight
|
|
99
|
+
);
|
|
100
|
+
font-style: var(
|
|
101
|
+
--recursica_ui-kit_components_chip_properties_text_font-style
|
|
102
|
+
);
|
|
103
|
+
letter-spacing: var(
|
|
104
|
+
--recursica_ui-kit_components_chip_properties_text_letter-spacing
|
|
105
|
+
);
|
|
106
|
+
line-height: var(
|
|
107
|
+
--recursica_ui-kit_components_chip_properties_text_line-height
|
|
108
|
+
);
|
|
109
|
+
text-decoration: var(
|
|
110
|
+
--recursica_ui-kit_components_chip_properties_text_text-decoration
|
|
111
|
+
);
|
|
112
|
+
text-transform: var(
|
|
113
|
+
--recursica_ui-kit_components_chip_properties_text_text-transform
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
/* Token evaluation */
|
|
117
|
+
background-color: var(--chip-bg);
|
|
118
|
+
border-color: var(--chip-border);
|
|
119
|
+
color: var(--chip-text);
|
|
120
|
+
min-width: var(--recursica_ui-kit_components_chip_properties_min-width);
|
|
121
|
+
max-width: var(--recursica_ui-kit_components_chip_properties_max-width);
|
|
122
|
+
box-shadow: var(--recursica_ui-kit_components_chip_properties_elevation);
|
|
123
|
+
|
|
124
|
+
transition: all 0.2s ease;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.label.label > span:not(.mantineIconWrapper) {
|
|
128
|
+
display: inline-flex;
|
|
129
|
+
align-items: center;
|
|
130
|
+
flex: 1 1 auto; /* HARDCODE: let this anonymous wrapper actually fill/shrink to .label's real
|
|
131
|
+
width instead of sizing to its content — otherwise a long .children label overflows this
|
|
132
|
+
span well past .label's 200px max-width, and .children's own text-overflow: ellipsis never
|
|
133
|
+
engages because ITS box is still as wide as the unwrapped text (see CHIP_IMPLEMENTATION_NOTES.md) */
|
|
134
|
+
min-width: 0; /* HARDCODE: flex items default to min-width: auto (their content's min-content
|
|
135
|
+
size) — without this override, flex-shrink is a no-op and the span never shrinks below that */
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.label.label:hover {
|
|
139
|
+
background-color: var(--chip-bg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.root[data-interactive] .label.label {
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Default (Unselected) hover/active interactions (Mantine overrides) */
|
|
147
|
+
.label.label[data-checked] {
|
|
148
|
+
--chip-bg: var(
|
|
149
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_background-color
|
|
150
|
+
);
|
|
151
|
+
--chip-border: var(
|
|
152
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_border-color
|
|
153
|
+
);
|
|
154
|
+
--chip-text: var(
|
|
155
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_text-color
|
|
156
|
+
);
|
|
157
|
+
--chip-icon: var(
|
|
158
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_selected-icon-color
|
|
159
|
+
);
|
|
160
|
+
--chip-close: var(
|
|
161
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_properties_colors_close-icon-color
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.root[data-error] .label.label {
|
|
166
|
+
--chip-bg: var(
|
|
167
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_background-color
|
|
168
|
+
);
|
|
169
|
+
--chip-border: var(
|
|
170
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_border-color
|
|
171
|
+
);
|
|
172
|
+
--chip-text: var(
|
|
173
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_text-color
|
|
174
|
+
);
|
|
175
|
+
--chip-icon: var(
|
|
176
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_leading-icon-color
|
|
177
|
+
);
|
|
178
|
+
--chip-close: var(
|
|
179
|
+
--recursica_ui-kit_components_chip_variants_selection-states_unselected_variants_states_error_properties_colors_close-icon-color
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.root[data-error] .label.label[data-checked] {
|
|
184
|
+
--chip-bg: var(
|
|
185
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_background-color
|
|
186
|
+
);
|
|
187
|
+
--chip-border: var(
|
|
188
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_border-color
|
|
189
|
+
);
|
|
190
|
+
--chip-text: var(
|
|
191
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_text-color
|
|
192
|
+
);
|
|
193
|
+
--chip-icon: var(
|
|
194
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_selected-icon-color
|
|
195
|
+
);
|
|
196
|
+
--chip-close: var(
|
|
197
|
+
--recursica_ui-kit_components_chip_variants_selection-states_selected_variants_states_error_properties_colors_close-icon-color
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.root[data-disabled] .label.label {
|
|
202
|
+
opacity: var(--recursica_brand_states_disabled);
|
|
203
|
+
cursor: not-allowed;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* Override Mantine's built-in check icon colors and size if we keep it */
|
|
207
|
+
.mantineIconWrapper.mantineIconWrapper {
|
|
208
|
+
color: var(--chip-icon);
|
|
209
|
+
width: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
210
|
+
height: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
211
|
+
margin-right: var(
|
|
212
|
+
--recursica_ui-kit_components_chip_properties_icon-text-gap
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.innerWrapper {
|
|
217
|
+
display: inline-flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
gap: var(--recursica_ui-kit_components_chip_properties_icon-text-gap);
|
|
220
|
+
width: 100%;
|
|
221
|
+
min-width: 0; /* HARDCODE: lets .children actually shrink and ellipsize instead of overflowing */
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.children {
|
|
225
|
+
flex-grow: 1;
|
|
226
|
+
min-width: 0; /* HARDCODE: a flex child needs this for text-overflow: ellipsis to engage at all */
|
|
227
|
+
text-overflow: ellipsis;
|
|
228
|
+
overflow-x: clip; /* HARDCODE: text-overflow: ellipsis only needs the x-axis clipped — clipping
|
|
229
|
+
y too (plain `overflow: hidden`) cut off descenders (e.g. the "g" in "image.png") whenever the
|
|
230
|
+
line-height token is tighter than the font's natural glyph extent (Matt Massey, 2026-08-18).
|
|
231
|
+
`clip` rather than `hidden` because `hidden` makes this a scroll container, and Chromium
|
|
232
|
+
auto-adds scroll containers with overflowing content to the Tab order (so a browser user can
|
|
233
|
+
arrow-key-scroll them) — `clip` doesn't create a scrollport, so long/truncated chip labels
|
|
234
|
+
(e.g. a read-only FileUpload file list) don't pick up a phantom, un-styled tab stop. */
|
|
235
|
+
overflow-y: visible;
|
|
236
|
+
white-space: nowrap;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.leadingIcon {
|
|
240
|
+
display: inline-flex;
|
|
241
|
+
align-items: center;
|
|
242
|
+
justify-content: center;
|
|
243
|
+
flex-shrink: 0; /* HARDCODE: keep the icon from being squeezed by a long, truncating label */
|
|
244
|
+
color: var(--chip-icon);
|
|
245
|
+
width: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
246
|
+
height: var(--recursica_ui-kit_components_chip_properties_icon-size);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.leadingIcon svg {
|
|
250
|
+
width: 100%;
|
|
251
|
+
height: 100%;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.deleteIcon {
|
|
255
|
+
display: inline-flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
justify-content: center;
|
|
258
|
+
flex-shrink: 0; /* HARDCODE: keep the delete icon visible when the label truncates instead */
|
|
259
|
+
color: var(--chip-close);
|
|
260
|
+
width: var(--recursica_ui-kit_components_chip_properties_close-icon-size);
|
|
261
|
+
height: var(--recursica_ui-kit_components_chip_properties_close-icon-size);
|
|
262
|
+
cursor: pointer;
|
|
263
|
+
border-radius: 50%; /* HARDCODE: Make focus ring rounded */
|
|
264
|
+
outline: none;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.deleteIcon:focus-visible {
|
|
268
|
+
box-shadow:
|
|
269
|
+
0 0 0 var(--recursica_brand_states_focus_border-size)
|
|
270
|
+
var(--recursica_brand_states_focus_color),
|
|
271
|
+
0 0 var(--recursica_brand_states_focus_blur)
|
|
272
|
+
var(--recursica_brand_states_focus_margin)
|
|
273
|
+
var(--recursica_brand_states_focus_color);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.deleteIcon svg {
|
|
277
|
+
width: 100%;
|
|
278
|
+
height: 100%;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.root[data-icon-only] .label.label {
|
|
282
|
+
padding-left: var(
|
|
283
|
+
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
284
|
+
);
|
|
285
|
+
padding-right: var(
|
|
286
|
+
--recursica_ui-kit_components_chip_properties_vertical-padding
|
|
287
|
+
);
|
|
288
|
+
}
|