@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,120 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Group } from "./Group";
|
|
4
|
+
import { Button } from "../Button";
|
|
5
|
+
import { Text } from "../Text/Text";
|
|
6
|
+
|
|
7
|
+
type GroupStoryProps = React.ComponentProps<typeof Group>;
|
|
8
|
+
|
|
9
|
+
const meta: Meta<GroupStoryProps> = {
|
|
10
|
+
title: "UI-Kit/Group",
|
|
11
|
+
component: Group,
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component:
|
|
17
|
+
"Group is a flex horizontal layout container that maps directly to Mantine's Group component allowing safe layout property passing.",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
args: {
|
|
22
|
+
gap: "rec-default",
|
|
23
|
+
align: "center",
|
|
24
|
+
justify: "flex-start",
|
|
25
|
+
wrap: "wrap",
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
gap: {
|
|
29
|
+
control: "select",
|
|
30
|
+
options: [
|
|
31
|
+
"rec-none",
|
|
32
|
+
"rec-sm",
|
|
33
|
+
"rec-default",
|
|
34
|
+
"rec-md",
|
|
35
|
+
"rec-lg",
|
|
36
|
+
"rec-xl",
|
|
37
|
+
"rec-2xl",
|
|
38
|
+
"xs",
|
|
39
|
+
"sm",
|
|
40
|
+
"md",
|
|
41
|
+
"lg",
|
|
42
|
+
"xl",
|
|
43
|
+
],
|
|
44
|
+
description: "Gap between elements",
|
|
45
|
+
},
|
|
46
|
+
align: {
|
|
47
|
+
control: "select",
|
|
48
|
+
options: ["flex-start", "center", "flex-end", "stretch"],
|
|
49
|
+
description: "Align-items property",
|
|
50
|
+
},
|
|
51
|
+
justify: {
|
|
52
|
+
control: "select",
|
|
53
|
+
options: [
|
|
54
|
+
"flex-start",
|
|
55
|
+
"center",
|
|
56
|
+
"flex-end",
|
|
57
|
+
"space-between",
|
|
58
|
+
"space-around",
|
|
59
|
+
],
|
|
60
|
+
description: "Justify-content property",
|
|
61
|
+
},
|
|
62
|
+
wrap: {
|
|
63
|
+
control: "select",
|
|
64
|
+
options: ["wrap", "nowrap", "wrap-reverse"],
|
|
65
|
+
description: "Flex-wrap property",
|
|
66
|
+
},
|
|
67
|
+
defaultChecked: {
|
|
68
|
+
table: { disable: true },
|
|
69
|
+
},
|
|
70
|
+
rowGap: {
|
|
71
|
+
table: { disable: true },
|
|
72
|
+
},
|
|
73
|
+
columnGap: {
|
|
74
|
+
table: { disable: true },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default meta;
|
|
80
|
+
|
|
81
|
+
type Story = StoryObj<GroupStoryProps>;
|
|
82
|
+
|
|
83
|
+
export const Default: Story = {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
85
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
86
|
+
<Group {...args}>
|
|
87
|
+
<Button variant="solid">Primary</Button>
|
|
88
|
+
<Button variant="outline">Secondary</Button>
|
|
89
|
+
<Text>Text element within Group</Text>
|
|
90
|
+
</Group>
|
|
91
|
+
),
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const StaticGapSmall: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
gap: "rec-sm",
|
|
97
|
+
},
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
99
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
100
|
+
<Group {...args}>
|
|
101
|
+
<Button variant="solid">Item 1</Button>
|
|
102
|
+
<Button variant="solid">Item 2</Button>
|
|
103
|
+
<Button variant="solid">Item 3</Button>
|
|
104
|
+
</Group>
|
|
105
|
+
),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const StaticGapLarge: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
gap: "rec-xl",
|
|
111
|
+
},
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
113
|
+
render: ({ withLayer, layer, ...args }: any) => (
|
|
114
|
+
<Group {...args}>
|
|
115
|
+
<Button variant="solid">Item 1</Button>
|
|
116
|
+
<Button variant="solid">Item 2</Button>
|
|
117
|
+
<Button variant="solid">Item 3</Button>
|
|
118
|
+
</Group>
|
|
119
|
+
),
|
|
120
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Group component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Group as MantineGroup,
|
|
4
|
+
type GroupProps as MantineGroupProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import {
|
|
7
|
+
mapLayoutProps,
|
|
8
|
+
type WithRecursicaSpacing,
|
|
9
|
+
} from "../../utils/filterStylingProps";
|
|
10
|
+
import styles from "./Group.module.css";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Group flex layout wrapper.
|
|
14
|
+
*
|
|
15
|
+
* Note: Unlike complex UI components, primitive layout components (Flex, Stack, Group, Container)
|
|
16
|
+
* DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
|
|
17
|
+
* width, height, padding, margins, and flexbox alignment props to construct structural layouts.
|
|
18
|
+
*
|
|
19
|
+
* No formal Recursica prop contract here: this simply passes through Mantine's own
|
|
20
|
+
* `GroupProps` (gap/rowGap/columnGap/justify/align/wrap are all native to Mantine),
|
|
21
|
+
* layered only with rec- spacing token support via `WithRecursicaSpacing`.
|
|
22
|
+
*/
|
|
23
|
+
export type GroupProps = WithRecursicaSpacing<MantineGroupProps>;
|
|
24
|
+
|
|
25
|
+
export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
|
|
26
|
+
{ children, gap = "rec-default", ...rest },
|
|
27
|
+
ref,
|
|
28
|
+
) {
|
|
29
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
30
|
+
root: styles.root,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const classNamesProp = rest.classNames;
|
|
34
|
+
if (
|
|
35
|
+
classNamesProp &&
|
|
36
|
+
typeof classNamesProp === "object" &&
|
|
37
|
+
!Array.isArray(classNamesProp)
|
|
38
|
+
) {
|
|
39
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
40
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const classNameProp = rest.className as string | undefined;
|
|
44
|
+
const finalClass = classNameProp
|
|
45
|
+
? `${styles.root} ${classNameProp}`
|
|
46
|
+
: styles.root;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<MantineGroup
|
|
50
|
+
ref={ref}
|
|
51
|
+
className={finalClass}
|
|
52
|
+
classNames={mergedClassNames}
|
|
53
|
+
{...mapLayoutProps({ gap, ...rest } as Record<string, unknown>)}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
</MantineGroup>
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
Group.displayName = "Group";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Group - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Group` component in your projects using `@recursica/adapter-mantine-v8`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Group } from "@recursica/adapter-mantine-v8";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Group } from "@recursica/adapter-mantine-v8";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<Group gap="md" align="center">
|
|
24
|
+
<Button variant="secondary">Cancel</Button>
|
|
25
|
+
<Button variant="primary">Submit</Button>
|
|
26
|
+
</Group>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Design System Integration
|
|
34
|
+
|
|
35
|
+
All Recursica components in the `@recursica/adapter-mantine-v8` package adhere strictly to design system spacing, scaling, and behavior patterns.
|
|
36
|
+
|
|
37
|
+
> [!IMPORTANT]
|
|
38
|
+
>
|
|
39
|
+
> - **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.
|
|
40
|
+
> - **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.
|
|
41
|
+
> - **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.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 4. Key Integration Features & Constraints
|
|
46
|
+
|
|
47
|
+
The `Group` component is a generic flex layout wrapper mapped directly to Mantine's `Group`.
|
|
48
|
+
`gap`, `align`, `wrap`, and `justify` all pass through as normal.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Heading – Implementation Notes
|
|
2
|
+
|
|
3
|
+
## Renamed from `Title` (Matt Massey, 2026-08-28)
|
|
4
|
+
|
|
5
|
+
**Decision:** Renamed the component from `Title` to `Heading` — designers refer to semantic tags
|
|
6
|
+
(`h1`-`h6`, `span`, `p`), and "Title" wasn't part of that vocabulary. `Heading` + `Text` are now
|
|
7
|
+
Recursica's common typography component names across all adapters. No behavior change.
|
|
8
|
+
|
|
9
|
+
## `.root` `text-wrap: balance` (Matt Massey, 2026-08-28)
|
|
10
|
+
|
|
11
|
+
**Decision:** Added `text-wrap: balance` via a new `Heading.module.css` `.root` class, merged onto
|
|
12
|
+
the typography class for every `order` (h1–h6), alongside the caller's own `className`.
|
|
13
|
+
|
|
14
|
+
**Implementation:** UX asked for more evenly balanced multi-line wrapping instead of a ragged last
|
|
15
|
+
line — headings are the primary intended use case for this property. Not a design token — it's a
|
|
16
|
+
layout algorithm choice, so it's hardcoded rather than pulled from `recursica_variables_scoped.css`.
|
|
17
|
+
Chromium/Firefox only balance up to ~6 lines, which comfortably covers heading text. No fallback
|
|
18
|
+
needed — browsers that don't support the value just ignore the declaration.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* HARDCODED VALUES
|
|
3
|
+
* - `.root` `text-wrap: balance` — not a design token; a layout algorithm choice requested by
|
|
4
|
+
* UX (Matt Massey, 2026-08-28) to even out wrapped line lengths. See HEADING_IMPLEMENTATION_NOTES.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.root {
|
|
8
|
+
/* HARDCODE: balances wrapped line lengths instead of leaving a ragged short last line. Most
|
|
9
|
+
effective on short text; browsers cap balancing at ~6 lines, so long paragraphs silently
|
|
10
|
+
fall back to normal wrapping past that point — no fallback needed, unsupported browsers
|
|
11
|
+
just ignore the declaration. */
|
|
12
|
+
text-wrap: balance;
|
|
13
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Heading } from "./Heading";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Heading> = {
|
|
5
|
+
title: "UI-Kit/Heading",
|
|
6
|
+
component: Heading,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
"The semantic `<Heading>` abstraction intrinsically links pure `h1-h6` tag generation with exact Recursica design boundaries to preserve SEO and screen reader trees uniformly globally.",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
order: {
|
|
18
|
+
control: "select",
|
|
19
|
+
options: [1, 2, 3, 4, 5, 6],
|
|
20
|
+
description:
|
|
21
|
+
"Controls the `h` tag and the resultant typographical weighting natively mapped to Recursica.",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default meta;
|
|
27
|
+
|
|
28
|
+
type Story = StoryObj<typeof Heading>;
|
|
29
|
+
|
|
30
|
+
export const Default: Story = {
|
|
31
|
+
args: {
|
|
32
|
+
order: 1,
|
|
33
|
+
children: "Semantic H1 Document Boundary",
|
|
34
|
+
},
|
|
35
|
+
render: ({ ...args }) => <Heading {...args} />,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const StaticVariations: Story = {
|
|
39
|
+
args: {},
|
|
40
|
+
render: () => (
|
|
41
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
|
|
42
|
+
<Heading order={1}>H1 Heading</Heading>
|
|
43
|
+
<Heading order={2}>H2 Heading</Heading>
|
|
44
|
+
<Heading order={3}>H3 Heading</Heading>
|
|
45
|
+
<Heading order={4}>H4 Heading</Heading>
|
|
46
|
+
<Heading order={5}>H5 Heading</Heading>
|
|
47
|
+
<Heading order={6}>H6 Heading</Heading>
|
|
48
|
+
</div>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Placeholder for future Heading component tests. Add tests here if/when needed.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Title as MantineTitle,
|
|
4
|
+
type TitleProps as MantineTitleProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import {
|
|
7
|
+
filterStylingProps,
|
|
8
|
+
omitUnsupportedProps,
|
|
9
|
+
type RecursicaOverStyled,
|
|
10
|
+
} from "../../utils/filterStylingProps";
|
|
11
|
+
|
|
12
|
+
import { type RecursicaHeadingProps } from "@recursica/adapter-common";
|
|
13
|
+
import styles from "./Heading.module.css";
|
|
14
|
+
|
|
15
|
+
export type HeadingProps = RecursicaOverStyled<
|
|
16
|
+
Omit<MantineTitleProps, "size"> & RecursicaHeadingProps
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Enforces highly accessible structural markup utilizing semantic `<h1>` through `<h6>` tags securely bound directly to Recursica typographic scales.
|
|
21
|
+
*/
|
|
22
|
+
export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
|
|
23
|
+
function Heading({ overStyled = false, order = 1, ...rest }, ref) {
|
|
24
|
+
// Props this component intentionally doesn't support — deleted at runtime so they can't leak
|
|
25
|
+
// through even if a caller forces them via plain JavaScript, bypassing the `Omit<>` above.
|
|
26
|
+
const UNSUPPORTED_PROPS = [
|
|
27
|
+
"size", // Recursica controls Heading sizing via the `order` prop + typography tokens, not Mantine's native `size`.
|
|
28
|
+
] as const satisfies readonly (keyof MantineTitleProps)[];
|
|
29
|
+
|
|
30
|
+
const sanitizedProps = omitUnsupportedProps(
|
|
31
|
+
filterStylingProps(rest, overStyled),
|
|
32
|
+
UNSUPPORTED_PROPS,
|
|
33
|
+
);
|
|
34
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
35
|
+
.className as string | undefined;
|
|
36
|
+
|
|
37
|
+
const typographyClass = `recursica_brand_typography_h${order}`;
|
|
38
|
+
const mergedClassName = [typographyClass, styles.root, classNameProp]
|
|
39
|
+
.filter(Boolean)
|
|
40
|
+
.join(" ");
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<MantineTitle
|
|
44
|
+
ref={ref}
|
|
45
|
+
{...(sanitizedProps as unknown as MantineTitleProps)}
|
|
46
|
+
order={order}
|
|
47
|
+
className={mergedClassName}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
Heading.displayName = "Heading";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Heading - Usage Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate and use the `Heading` component in your projects using `@recursica/adapter-mantine-v8`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Import Reference
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Heading } from "@recursica/adapter-mantine-v8";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Basic Example
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import React from "react";
|
|
19
|
+
import { Heading } from "@recursica/adapter-mantine-v8";
|
|
20
|
+
|
|
21
|
+
export default function Demo() {
|
|
22
|
+
return <Heading order={1}>This is a Heading 1</Heading>;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. Design System Integration
|
|
29
|
+
|
|
30
|
+
All Recursica components in the `@recursica/adapter-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.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# HoverCard – Implementation Notes
|
|
2
|
+
|
|
3
|
+
Decisions and design tweaks strictly tailored for the UI Kit's HoverCard wrapped against `@mantine/core`. This is a living document that tracks _why_ specific logic decisions exist.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Composable API Preservation (1:1 Mapping)
|
|
8
|
+
|
|
9
|
+
**Decision:** We maintain the exact library composition API structure (`<HoverCard>`, `<HoverCard.Target>`, `<HoverCard.Dropdown>`) as a 1:1 React component mapping.
|
|
10
|
+
|
|
11
|
+
**Implementation:** Mantine's HoverCard internally manages hover detection, open/close delays, Floating UI positioning, and portal rendering. By preserving the exact sub-component tree, Recursica safely inherits all of these behaviors without reimplementation.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. HoverCard.Target Pass-Through
|
|
16
|
+
|
|
17
|
+
**Decision:** `HoverCard.Target` is a transparent pass-through with no styling applied.
|
|
18
|
+
|
|
19
|
+
**Implementation:** The target wrapper exists solely to manage Mantine's ref forwarding and hover event binding for the trigger element. No `filterStylingProps` or CSS module classes are applied — the trigger's appearance is entirely controlled by whatever component the integrator places inside it (e.g., `<Button>`). This is identical to the `Menu.Target` pattern.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 3. Token Namespace: `hover-card-popover`
|
|
24
|
+
|
|
25
|
+
**Decision:** The CSS module exclusively uses variables from the `--recursica_ui-kit_components_hover-card-popover_*` namespace.
|
|
26
|
+
|
|
27
|
+
**Implementation:** The Recursica token system defines a single shared namespace (`hover-card-popover`) for this component covering geometry (border-radius, border-size, padding, min/max-width), typography (content-text\_\*), elevation, and layer-aware colors (background, border-color, content). No tokens from other component namespaces are referenced.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 4. Hardcoded Values
|
|
32
|
+
|
|
33
|
+
**Decision:** Two hardcoded values exist in the component.
|
|
34
|
+
|
|
35
|
+
### `border-style: solid` (CSS module)
|
|
36
|
+
|
|
37
|
+
Mantine renders the dropdown using its `Paper` component, which does not set `border-style` natively. Without this hardcoded value, the border-width and border-color tokens would have no visible effect. This is the same pattern used in the Menu component's dropdown.
|
|
38
|
+
|
|
39
|
+
### `arrowSize` defaulted to `16` (HoverCard.tsx)
|
|
40
|
+
|
|
41
|
+
Mantine's `arrowSize` prop is a JavaScript number used for inline style calculations: it sets `width`, `height`, and a positioning offset (`-arrowSize/2`) directly on the arrow `<div>` element. These inline styles **cannot** be overridden via CSS without `!important`, and the positioning offset has no CSS equivalent. This means the beak size cannot be fully CSS-driven — it is one of the rare cases where a design token value must be mirrored as a JS prop.
|
|
42
|
+
|
|
43
|
+
The default value `16` matches the Recursica `beak-size` token (`--recursica_ui-kit_components_hover-card-popover_properties_beak-size: 16px`). Developers can override `arrowSize` if needed, but should be aware this is a design system concern. If the token value changes, the default in `HoverCard.tsx` must also be updated.
|
|
44
|
+
|
|
45
|
+
This is documented as an open issue in `docs/COMPONENT_ISSUES.md`.
|
|
46
|
+
|
|
47
|
+
**Note:** Mantine calls this the "arrow"; Recursica calls it the "beak". The Recursica prop `withBeak` (defaulting to `true`) maps to Mantine's `withArrow`. Both `withBeak` and `withArrow` are accepted; `withBeak` takes precedence.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 5. Minimal CSS Override Philosophy
|
|
52
|
+
|
|
53
|
+
**Decision:** The CSS module only overrides visual design tokens (colors, typography, spacing, borders, shadows). All structural layout properties are deferred to Mantine's native behavior.
|
|
54
|
+
|
|
55
|
+
**Implementation:** HoverCard is an overlay component where Mantine's native Floating UI positioning and Paper layout are already correct. We avoid setting:
|
|
56
|
+
|
|
57
|
+
- `overflow` on the dropdown (Mantine handles scroll behavior natively)
|
|
58
|
+
- `display`, `position`, `z-index` (Floating UI controls these)
|
|
59
|
+
- `pointer-events` (Mantine manages hover detection across target and dropdown)
|
|
60
|
+
|
|
61
|
+
**Rationale:** The Menu implementation demonstrated that aggressive structural resets (overflow, box-sizing) on overlay components cause layout breakage. Default to Mantine's native behavior and only override what the Recursica token system explicitly needs to control.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 6. ClassNames Merging on Root
|
|
66
|
+
|
|
67
|
+
**Decision:** The root `HoverCard` component binds CSS module classes via `classNames` on the Mantine root, identical to the Menu pattern.
|
|
68
|
+
|
|
69
|
+
**Implementation:** The root component receives `classNames={{ dropdown: styles.dropdown }}` and merges any consumer-provided `classNames` when `overStyled` is true. This ensures our token-driven styles are applied to the dropdown panel without wrapper divs, and the consumer's classes are additive.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 7. Default Position Override
|
|
74
|
+
|
|
75
|
+
**Decision:** Recursica defaults `position` to `"top"`. Mantine defaults to `"bottom"`.
|
|
76
|
+
|
|
77
|
+
**Implementation:** The `position="top"` default is set on the Mantine root element before the prop spread, so developer-provided `position` values still take precedence. This aligns with Recursica's design intent for overlay components to appear above their trigger by default.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* HARDCODED VALUES:
|
|
2
|
+
- border-style: solid. Structural rendering rule for the dropdown border (Mantine uses Paper
|
|
3
|
+
which may not set border-style natively). Same pattern as Menu.
|
|
4
|
+
- arrowSize defaults to 16 in HoverCard.tsx. Mantine uses arrowSize for inline width/height
|
|
5
|
+
and positioning (-arrowSize/2) calculations that cannot be CSS-driven. The default matches
|
|
6
|
+
the Recursica beak-size token (16px).
|
|
7
|
+
- All structural layout (display, position, overflow) is deferred to Mantine's native
|
|
8
|
+
behavior. We only override visual design tokens (colors, typography, spacing, borders). */
|
|
9
|
+
|
|
10
|
+
/* EXEMPTIONS:
|
|
11
|
+
- beak-size is ignored: the arrow's size is Mantine's own `arrowSize` JS prop, not CSS-driven —
|
|
12
|
+
see HARDCODED VALUES above. */
|
|
13
|
+
/* recursica-ignore: --recursica_ui-kit_components_hover-card-popover_properties_beak-size */
|
|
14
|
+
|
|
15
|
+
/* ======================================
|
|
16
|
+
DROPDOWN CONTAINER
|
|
17
|
+
====================================== */
|
|
18
|
+
|
|
19
|
+
.dropdown {
|
|
20
|
+
background-color: var(
|
|
21
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_background-color
|
|
22
|
+
);
|
|
23
|
+
border-style: solid; /* HARDCODE: Mantine Paper does not set border-style natively */
|
|
24
|
+
border-width: var(
|
|
25
|
+
--recursica_ui-kit_components_hover-card-popover_properties_border-size
|
|
26
|
+
);
|
|
27
|
+
border-color: var(
|
|
28
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_border-color
|
|
29
|
+
);
|
|
30
|
+
border-radius: var(
|
|
31
|
+
--recursica_ui-kit_components_hover-card-popover_properties_border-radius
|
|
32
|
+
);
|
|
33
|
+
box-shadow: var(
|
|
34
|
+
--recursica_ui-kit_components_hover-card-popover_properties_elevation
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
min-width: var(
|
|
38
|
+
--recursica_ui-kit_components_hover-card-popover_properties_min-width
|
|
39
|
+
);
|
|
40
|
+
max-width: var(
|
|
41
|
+
--recursica_ui-kit_components_hover-card-popover_properties_max-width
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
padding: var(
|
|
45
|
+
--recursica_ui-kit_components_hover-card-popover_properties_vertical-padding
|
|
46
|
+
)
|
|
47
|
+
var(
|
|
48
|
+
--recursica_ui-kit_components_hover-card-popover_properties_horizontal-padding
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/* Typography */
|
|
52
|
+
font-family: var(
|
|
53
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-family
|
|
54
|
+
);
|
|
55
|
+
font-size: var(
|
|
56
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-size
|
|
57
|
+
);
|
|
58
|
+
font-style: var(
|
|
59
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-style
|
|
60
|
+
);
|
|
61
|
+
font-weight: var(
|
|
62
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_font-weight
|
|
63
|
+
);
|
|
64
|
+
letter-spacing: var(
|
|
65
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_letter-spacing
|
|
66
|
+
);
|
|
67
|
+
line-height: var(
|
|
68
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_line-height
|
|
69
|
+
);
|
|
70
|
+
text-decoration: var(
|
|
71
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_text-decoration
|
|
72
|
+
);
|
|
73
|
+
text-transform: var(
|
|
74
|
+
--recursica_ui-kit_components_hover-card-popover_properties_content-text_text-transform
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
color: var(
|
|
78
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_content
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ======================================
|
|
83
|
+
ARROW / BEAK
|
|
84
|
+
====================================== */
|
|
85
|
+
|
|
86
|
+
.arrow {
|
|
87
|
+
border-color: var(
|
|
88
|
+
--recursica_ui-kit_components_hover-card-popover_properties_colors_border-color
|
|
89
|
+
);
|
|
90
|
+
}
|