@recursica/mantine-adapter 0.9.4 → 0.10.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/CHANGELOG.md +88 -0
- package/README.md +48 -332
- package/dist/index.d.ts +2 -8
- package/dist/mantine-adapter.cjs +2 -0
- package/dist/mantine-adapter.cjs.map +1 -0
- package/dist/mantine-adapter.css +1 -0
- package/dist/mantine-adapter.js +1797 -0
- package/dist/mantine-adapter.js.map +1 -0
- package/dist/src/components/Accordion/Accordion.d.ts +42 -0
- package/dist/src/components/Accordion/index.d.ts +1 -0
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +10 -0
- package/dist/src/components/Avatar/Avatar.d.ts +9 -0
- package/dist/src/components/Avatar/index.d.ts +1 -0
- package/dist/src/components/Badge/Badge.d.ts +8 -0
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +6 -0
- package/dist/src/components/Button/Button.d.ts +10 -0
- package/dist/src/components/Button/index.d.ts +1 -0
- package/dist/src/components/Card/Card.d.ts +38 -0
- package/dist/src/components/Checkbox/Checkbox.d.ts +11 -0
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +9 -0
- package/dist/src/components/Chip/Chip.d.ts +15 -0
- package/dist/src/components/Container/Container.d.ts +18 -0
- package/dist/src/components/DatePicker/DatePicker.d.ts +3 -0
- package/dist/src/components/Dropdown/Dropdown.d.ts +11 -0
- package/dist/src/components/FileInput/FileInput.d.ts +3 -0
- package/dist/src/components/FileUpload/FileUpload.d.ts +3 -0
- package/dist/src/components/Flex/Flex.d.ts +17 -0
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +18 -0
- package/dist/src/components/Group/Group.d.ts +17 -0
- package/dist/src/components/HoverCard/HoverCard.d.ts +3 -0
- package/dist/src/components/Label/Label.d.ts +21 -0
- package/dist/src/components/Label/index.d.ts +1 -0
- package/dist/src/components/Link/Link.d.ts +3 -0
- package/dist/src/components/Loader/Loader.d.ts +10 -0
- package/dist/src/components/Menu/Menu.d.ts +3 -0
- package/dist/src/components/Modal/Modal.d.ts +3 -0
- package/dist/src/components/NumberInput/NumberInput.d.ts +3 -0
- package/dist/src/components/Pagination/Pagination.d.ts +3 -0
- package/dist/src/components/Panel/Panel.d.ts +3 -0
- package/dist/src/components/Popover/Popover.d.ts +3 -0
- package/dist/src/components/Radio/Radio.d.ts +11 -0
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +20 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +22 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +3 -0
- package/dist/src/components/Search/Search.d.ts +3 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +3 -0
- package/dist/src/components/Slider/Slider.d.ts +3 -0
- package/dist/src/components/Stack/Stack.d.ts +15 -0
- package/dist/src/components/Stepper/Stepper.d.ts +3 -0
- package/dist/src/components/Switch/Switch.d.ts +11 -0
- package/dist/src/components/Switch/SwitchGroup.d.ts +9 -0
- package/dist/src/components/Table/Table.d.ts +3 -0
- package/dist/src/components/Tabs/Tabs.d.ts +3 -0
- package/dist/src/components/Text/Text.d.ts +17 -0
- package/dist/src/components/TextArea/TextArea.d.ts +15 -0
- package/dist/src/components/TextField/TextField.d.ts +9 -0
- package/dist/src/components/TimePicker/TimePicker.d.ts +3 -0
- package/dist/src/components/Timeline/Timeline.d.ts +3 -0
- package/dist/src/components/Title/Title.d.ts +13 -0
- package/dist/src/components/Toast/Toast.d.ts +3 -0
- package/dist/src/components/Tooltip/Tooltip.d.ts +3 -0
- package/dist/src/components/TransferList/TransferList.d.ts +3 -0
- package/dist/src/components/index.d.ts +47 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/utils/ColorSchemeWrapper.d.ts +3 -0
- package/dist/src/utils/copyToClipboard.d.ts +8 -0
- package/dist/src/utils/filterStylingProps.d.ts +36 -0
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/vite.config.d.ts +2 -0
- package/dist/vite.svg +1 -0
- package/dist/vitest.workspace.d.ts +2 -0
- package/package.json +74 -35
- package/src/OverStyling.stories.tsx +174 -0
- package/src/Version.stories.tsx +56 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Accordion/Accordion.module.css +282 -0
- package/src/components/Accordion/Accordion.stories.tsx +145 -0
- package/src/components/Accordion/Accordion.tsx +200 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +73 -0
- package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Avatar/Avatar.module.css +340 -0
- package/src/components/Avatar/Avatar.stories.tsx +102 -0
- package/src/components/Avatar/Avatar.tsx +100 -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 +124 -0
- package/src/components/Badge/Badge.stories.tsx +77 -0
- package/src/components/Badge/Badge.tsx +66 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
- package/src/components/Button/Button.module.css +275 -0
- package/src/components/Button/Button.stories.tsx +105 -0
- package/src/components/Button/Button.tsx +122 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
- package/src/components/Card/Card.module.css +60 -0
- package/src/components/Card/Card.stories.tsx +141 -0
- package/src/components/Card/Card.tsx +176 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +204 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +73 -0
- package/src/components/Checkbox/Checkbox.tsx +102 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +138 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +140 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
- package/src/components/Chip/Chip.module.css +218 -0
- package/src/components/Chip/Chip.stories.tsx +115 -0
- package/src/components/Chip/Chip.tsx +143 -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 +115 -0
- package/src/components/Container/Container.tsx +89 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +22 -0
- package/src/components/DatePicker/DatePicker.tsx +7 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/Dropdown/Dropdown.module.css +272 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +94 -0
- package/src/components/Dropdown/Dropdown.tsx +173 -0
- package/src/components/FileInput/FileInput.stories.tsx +22 -0
- package/src/components/FileInput/FileInput.tsx +7 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +22 -0
- package/src/components/FileUpload/FileUpload.tsx +7 -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 +125 -0
- package/src/components/Flex/Flex.tsx +68 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +46 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -0
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +170 -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 +117 -0
- package/src/components/Group/Group.tsx +68 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
- package/src/components/HoverCard/HoverCard.tsx +7 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +177 -0
- package/src/components/Label/Label.stories.tsx +123 -0
- package/src/components/Label/Label.tsx +132 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Link/Link.stories.tsx +17 -0
- package/src/components/Link/Link.tsx +7 -0
- package/src/components/Loader/Loader.module.css +60 -0
- package/src/components/Loader/Loader.stories.tsx +98 -0
- package/src/components/Loader/Loader.tsx +76 -0
- package/src/components/Menu/Menu.stories.tsx +17 -0
- package/src/components/Menu/Menu.tsx +7 -0
- package/src/components/Modal/Modal.stories.tsx +17 -0
- package/src/components/Modal/Modal.tsx +7 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +22 -0
- package/src/components/NumberInput/NumberInput.tsx +7 -0
- package/src/components/Pagination/Pagination.stories.tsx +17 -0
- package/src/components/Pagination/Pagination.tsx +7 -0
- package/src/components/Panel/Panel.stories.tsx +17 -0
- package/src/components/Panel/Panel.tsx +7 -0
- package/src/components/Popover/Popover.stories.tsx +17 -0
- package/src/components/Popover/Popover.tsx +7 -0
- package/src/components/Radio/Radio.module.css +207 -0
- package/src/components/Radio/Radio.stories.tsx +76 -0
- package/src/components/Radio/Radio.tsx +115 -0
- package/src/components/Radio/RadioGroup.stories.tsx +98 -0
- package/src/components/Radio/RadioGroup.tsx +138 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +120 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +75 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +46 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +85 -0
- package/src/components/ReadOnlyField/index.ts +3 -0
- package/src/components/Search/Search.stories.tsx +17 -0
- package/src/components/Search/Search.tsx +7 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +22 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
- package/src/components/Slider/Slider.stories.tsx +22 -0
- package/src/components/Slider/Slider.tsx +7 -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 +105 -0
- package/src/components/Stack/Stack.tsx +66 -0
- package/src/components/Stepper/Stepper.stories.tsx +17 -0
- package/src/components/Stepper/Stepper.tsx +7 -0
- package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +28 -0
- package/src/components/Switch/Switch.module.css +207 -0
- package/src/components/Switch/Switch.stories.tsx +96 -0
- package/src/components/Switch/Switch.tsx +119 -0
- package/src/components/Switch/SwitchGroup.stories.tsx +112 -0
- package/src/components/Switch/SwitchGroup.tsx +138 -0
- package/src/components/Table/Table.stories.tsx +17 -0
- package/src/components/Table/Table.tsx +7 -0
- package/src/components/Tabs/Tabs.stories.tsx +17 -0
- package/src/components/Tabs/Tabs.tsx +7 -0
- package/src/components/Text/Text.stories.tsx +88 -0
- package/src/components/Text/Text.tsx +54 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/TextArea/TextArea.module.css +225 -0
- package/src/components/TextArea/TextArea.stories.tsx +94 -0
- package/src/components/TextArea/TextArea.tsx +151 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +225 -0
- package/src/components/TextField/TextField.stories.tsx +162 -0
- package/src/components/TextField/TextField.tsx +138 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
- package/src/components/TimePicker/TimePicker.tsx +7 -0
- package/src/components/Timeline/Timeline.stories.tsx +17 -0
- package/src/components/Timeline/Timeline.tsx +7 -0
- package/src/components/Title/Title.stories.tsx +63 -0
- package/src/components/Title/Title.tsx +45 -0
- package/src/components/Toast/Toast.stories.tsx +17 -0
- package/src/components/Toast/Toast.tsx +7 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
- package/src/components/Tooltip/Tooltip.tsx +7 -0
- package/src/components/TransferList/TransferList.stories.tsx +17 -0
- package/src/components/TransferList/TransferList.tsx +7 -0
- package/src/components/index.ts +47 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +3 -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/copyToClipboard.ts +36 -0
- package/src/utils/filterStylingProps.ts +141 -0
- package/src/utils/index.ts +1 -0
- package/dist/adapter/generateBorderRadiusType.d.ts +0 -3
- package/dist/adapter/generateBorderRadiusType.d.ts.map +0 -1
- package/dist/adapter/generateColorTypes.d.ts +0 -6
- package/dist/adapter/generateColorTypes.d.ts.map +0 -1
- package/dist/adapter/generateIcons.d.ts +0 -8
- package/dist/adapter/generateIcons.d.ts.map +0 -1
- package/dist/adapter/generateMantineTheme.d.ts +0 -19
- package/dist/adapter/generateMantineTheme.d.ts.map +0 -1
- package/dist/adapter/generatePrettierignore.d.ts +0 -3
- package/dist/adapter/generatePrettierignore.d.ts.map +0 -1
- package/dist/adapter/generateRecursicaObject.d.ts +0 -7
- package/dist/adapter/generateRecursicaObject.d.ts.map +0 -1
- package/dist/adapter/generateRecursicaThemes.d.ts +0 -12
- package/dist/adapter/generateRecursicaThemes.d.ts.map +0 -1
- package/dist/adapter/generateRecursicaTokens.d.ts +0 -3
- package/dist/adapter/generateRecursicaTokens.d.ts.map +0 -1
- package/dist/adapter/generateSpacersType.d.ts +0 -3
- package/dist/adapter/generateSpacersType.d.ts.map +0 -1
- package/dist/adapter/generateUiKit.d.ts +0 -8
- package/dist/adapter/generateUiKit.d.ts.map +0 -1
- package/dist/adapter/generateVanillaExtractThemes.d.ts +0 -12
- package/dist/adapter/generateVanillaExtractThemes.d.ts.map +0 -1
- package/dist/adapter/index.d.ts +0 -44
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/cli.d.ts +0 -6
- package/dist/cli.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -921
- package/dist/index.js.map +0 -1
- package/dist/main.cjs +0 -928
- package/dist/main.cjs.map +0 -1
- package/dist/main.d.ts +0 -2
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js +0 -926
- package/dist/main.js.map +0 -1
- package/dist/shared/processTokens.d.ts +0 -22
- package/dist/shared/processTokens.d.ts.map +0 -1
- package/dist/types.d.ts +0 -62
- package/dist/types.d.ts.map +0 -1
- package/dist/utils/fileCheck.d.ts +0 -8
- package/dist/utils/fileCheck.d.ts.map +0 -1
- package/dist/utils/loadConfig.d.ts +0 -24
- package/dist/utils/loadConfig.d.ts.map +0 -1
- package/dist/webworker.d.ts +0 -2
- package/dist/webworker.d.ts.map +0 -1
- package/dist/webworker.js +0 -791
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Switch } from "./Switch";
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Switch> = {
|
|
5
|
+
title: "UI-Kit/Switch",
|
|
6
|
+
component: Switch,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `
|
|
12
|
+
The \`Switch\` component is an atomic form primitive representing boolean states, natively aligned to the Recursica design system.
|
|
13
|
+
|
|
14
|
+
> [!IMPORTANT]
|
|
15
|
+
> Unlike \`Checkbox\`, the \`Switch\` is typically used for standalone settings toggles. It fully supports the universal \`ReadOnlyField\` boundaries when passed the \`readOnly\` attribute.
|
|
16
|
+
|
|
17
|
+
### Usage
|
|
18
|
+
To render a standard switch:
|
|
19
|
+
\`\`\`tsx
|
|
20
|
+
<Switch label="Enable Notifications" defaultChecked />
|
|
21
|
+
\`\`\`
|
|
22
|
+
`,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
argTypes: {
|
|
27
|
+
disabled: {
|
|
28
|
+
control: "boolean",
|
|
29
|
+
},
|
|
30
|
+
checked: {
|
|
31
|
+
control: "boolean",
|
|
32
|
+
},
|
|
33
|
+
required: {
|
|
34
|
+
control: "boolean",
|
|
35
|
+
},
|
|
36
|
+
error: {
|
|
37
|
+
control: "boolean",
|
|
38
|
+
},
|
|
39
|
+
defaultChecked: {
|
|
40
|
+
control: "boolean",
|
|
41
|
+
},
|
|
42
|
+
readOnly: {
|
|
43
|
+
control: "boolean",
|
|
44
|
+
description:
|
|
45
|
+
"Toggles structural read-only data presentation bypassing interaction boundaries completely.",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default meta;
|
|
51
|
+
|
|
52
|
+
type Story = StoryObj<typeof Switch>;
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
disabled: false,
|
|
57
|
+
label: "Standard Switch",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const StaticVariations: Story = {
|
|
62
|
+
args: {},
|
|
63
|
+
render: () => (
|
|
64
|
+
<div
|
|
65
|
+
style={{
|
|
66
|
+
display: "flex",
|
|
67
|
+
flexDirection: "column",
|
|
68
|
+
gap: "24px",
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<Switch label="Default Unchecked State" />
|
|
72
|
+
<Switch label="Checked State" defaultChecked />
|
|
73
|
+
<Switch label="Disabled Unchecked" disabled />
|
|
74
|
+
<Switch label="Disabled Checked" defaultChecked disabled />
|
|
75
|
+
</div>
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const StaticReadOnly: Story = {
|
|
80
|
+
args: {},
|
|
81
|
+
render: () => (
|
|
82
|
+
<div
|
|
83
|
+
style={{
|
|
84
|
+
display: "flex",
|
|
85
|
+
flexDirection: "column",
|
|
86
|
+
gap: "24px",
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<Switch
|
|
90
|
+
label="Read Only Switch"
|
|
91
|
+
readOnly
|
|
92
|
+
readOnlyComponent={<span>Enabled</span>}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
),
|
|
96
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Switch as MantineSwitch,
|
|
4
|
+
type SwitchProps as MantineSwitchProps,
|
|
5
|
+
CheckIcon,
|
|
6
|
+
CloseIcon,
|
|
7
|
+
} from "@mantine/core";
|
|
8
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
filterStylingProps,
|
|
12
|
+
type RecursicaOverStyled,
|
|
13
|
+
} from "../../utils/filterStylingProps";
|
|
14
|
+
import styles from "./Switch.module.css";
|
|
15
|
+
|
|
16
|
+
import { SwitchGroup } from "./SwitchGroup";
|
|
17
|
+
|
|
18
|
+
export type RecursicaSwitchProps = Omit<
|
|
19
|
+
MantineSwitchProps,
|
|
20
|
+
"size" | "color" | "radius" | "variant"
|
|
21
|
+
> &
|
|
22
|
+
ReadOnlyControlProps;
|
|
23
|
+
|
|
24
|
+
export type SwitchProps = RecursicaOverStyled<RecursicaSwitchProps>;
|
|
25
|
+
|
|
26
|
+
type SwitchComponent = React.ForwardRefExoticComponent<
|
|
27
|
+
SwitchProps & React.RefAttributes<HTMLInputElement>
|
|
28
|
+
> & {
|
|
29
|
+
Group: typeof SwitchGroup;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
33
|
+
{
|
|
34
|
+
overStyled = false,
|
|
35
|
+
readOnly,
|
|
36
|
+
readOnlyComponent,
|
|
37
|
+
disabled,
|
|
38
|
+
thumbIcon,
|
|
39
|
+
...rest
|
|
40
|
+
},
|
|
41
|
+
ref,
|
|
42
|
+
) {
|
|
43
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
44
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
45
|
+
|
|
46
|
+
// Actively delete dimension bindings that bypass the abstraction
|
|
47
|
+
delete restRecord["size"];
|
|
48
|
+
delete restRecord["color"];
|
|
49
|
+
delete restRecord["radius"];
|
|
50
|
+
delete restRecord["variant"];
|
|
51
|
+
|
|
52
|
+
if (readOnly && readOnlyComponent) {
|
|
53
|
+
// Safely fallback explicitly returning mapped elements natively without macro wrappers
|
|
54
|
+
return <>{readOnlyComponent}</>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
58
|
+
root: styles.root,
|
|
59
|
+
body: styles.body,
|
|
60
|
+
track: styles.track,
|
|
61
|
+
thumb: styles.thumb,
|
|
62
|
+
trackLabel: styles.trackLabel,
|
|
63
|
+
labelWrapper: styles.labelWrapper,
|
|
64
|
+
label: styles.label,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const classNamesProp = restRecord.classNames;
|
|
68
|
+
if (
|
|
69
|
+
classNamesProp &&
|
|
70
|
+
typeof classNamesProp === "object" &&
|
|
71
|
+
!Array.isArray(classNamesProp)
|
|
72
|
+
) {
|
|
73
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
74
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
75
|
+
mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
|
|
76
|
+
mergedClassNames.track = o.track
|
|
77
|
+
? `${styles.track} ${o.track}`
|
|
78
|
+
: styles.track;
|
|
79
|
+
mergedClassNames.thumb = o.thumb
|
|
80
|
+
? `${styles.thumb} ${o.thumb}`
|
|
81
|
+
: styles.thumb;
|
|
82
|
+
mergedClassNames.trackLabel = o.trackLabel
|
|
83
|
+
? `${styles.trackLabel} ${o.trackLabel}`
|
|
84
|
+
: styles.trackLabel;
|
|
85
|
+
mergedClassNames.labelWrapper = o.labelWrapper
|
|
86
|
+
? `${styles.labelWrapper} ${o.labelWrapper}`
|
|
87
|
+
: styles.labelWrapper;
|
|
88
|
+
mergedClassNames.label = o.label
|
|
89
|
+
? `${styles.label} ${o.label}`
|
|
90
|
+
: styles.label;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
94
|
+
const finalClass = classNameProp
|
|
95
|
+
? `${styles.root} ${classNameProp}`
|
|
96
|
+
: styles.root;
|
|
97
|
+
|
|
98
|
+
const FinalThumbIcon = (
|
|
99
|
+
<div className={styles.thumbIconWrapper}>
|
|
100
|
+
<CheckIcon className={styles.checkIcon} />
|
|
101
|
+
<CloseIcon className={styles.closeIcon} />
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// We omit Mantine's sizing/coloring so we rely strictly on variables from Switch.module.css
|
|
106
|
+
return (
|
|
107
|
+
<MantineSwitch
|
|
108
|
+
ref={ref}
|
|
109
|
+
className={finalClass}
|
|
110
|
+
classNames={mergedClassNames}
|
|
111
|
+
disabled={readOnly || disabled}
|
|
112
|
+
thumbIcon={thumbIcon ?? FinalThumbIcon}
|
|
113
|
+
{...(sanitizedProps as unknown as MantineSwitchProps)}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
}) as SwitchComponent;
|
|
117
|
+
|
|
118
|
+
Switch.displayName = "Switch";
|
|
119
|
+
Switch.Group = SwitchGroup;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Switch } from "./Switch";
|
|
3
|
+
import { SwitchGroup } from "./SwitchGroup";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof SwitchGroup> = {
|
|
8
|
+
title: "UI-Kit/SwitchGroup",
|
|
9
|
+
component: SwitchGroup,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
The \`SwitchGroup\` component is the mandatory organizational wrapper for orchestrating \`Switch\` primitives into macro form layouts. It inherently leverages the \`FormControlWrapper\`, granting native access to structural alignments, assistive descriptions, and strict flex arrays.
|
|
16
|
+
|
|
17
|
+
### Supported Layout Vectors
|
|
18
|
+
- **\`formLayout="stacked"\`**: Top-to-bottom layout cascading the Label bounding box down vertically into a standard stacked switch array.
|
|
19
|
+
- **\`formLayout="side-by-side"\`**: Flow architecture pulling the grouping Label dynamically to the left while structurally organizing the internal switches cleanly alongside it horizontally.
|
|
20
|
+
|
|
21
|
+
> [!IMPORTANT]
|
|
22
|
+
> If you require a solitary \`Switch\` field to natively accept an overarching form label, assistive text, or align with other side-by-side components in a form column, you must wrap it inside a \`Switch.Group\` to trigger the \`FormControlWrapper\` mapping.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
argTypes: {
|
|
28
|
+
...formControlArgTypes,
|
|
29
|
+
readOnly: {
|
|
30
|
+
control: "boolean",
|
|
31
|
+
description:
|
|
32
|
+
"Passes read-only lock natively down mapping inner switches into explicitly disabled states.",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
|
|
39
|
+
type Story = StoryObj<typeof SwitchGroup>;
|
|
40
|
+
|
|
41
|
+
export const Default: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
formLayout: "stacked",
|
|
44
|
+
label: "Notification Settings",
|
|
45
|
+
description: "Manage your preferences.",
|
|
46
|
+
assistiveText: "We recommend turning these on.",
|
|
47
|
+
error: "",
|
|
48
|
+
required: true,
|
|
49
|
+
},
|
|
50
|
+
render: function DefaultRender(args) {
|
|
51
|
+
const [value, setValue] = useState<string[]>(["email"]);
|
|
52
|
+
return (
|
|
53
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
54
|
+
<Switch value="email" label="Email Alerts" />
|
|
55
|
+
<Switch value="push" label="Push Notifications" />
|
|
56
|
+
<Switch value="sms" label="SMS Messages" />
|
|
57
|
+
</SwitchGroup>
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const SideBySideLayout: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
...Default.args,
|
|
65
|
+
formLayout: "side-by-side",
|
|
66
|
+
labelSize: "default",
|
|
67
|
+
labelAlignment: "left",
|
|
68
|
+
},
|
|
69
|
+
render: function SideBySideRender(args) {
|
|
70
|
+
const [value, setValue] = useState<string[]>([]);
|
|
71
|
+
return (
|
|
72
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
73
|
+
<Switch value="weekly" label="Weekly Digest" />
|
|
74
|
+
<Switch value="marketing" label="Marketing Emails" />
|
|
75
|
+
</SwitchGroup>
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const SolitaryFormControl: Story = {
|
|
81
|
+
args: {
|
|
82
|
+
formLayout: "side-by-side",
|
|
83
|
+
label: "Enable Backups",
|
|
84
|
+
description: "Automatically back up your data nightly.",
|
|
85
|
+
},
|
|
86
|
+
render: function SolitaryRender(args) {
|
|
87
|
+
const [value, setValue] = useState<string[]>(["auto"]);
|
|
88
|
+
return (
|
|
89
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
90
|
+
<Switch value="auto" label="Auto-backup" />
|
|
91
|
+
</SwitchGroup>
|
|
92
|
+
);
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const GroupReadOnly: Story = {
|
|
97
|
+
args: {
|
|
98
|
+
...Default.args,
|
|
99
|
+
readOnly: true,
|
|
100
|
+
readOnlyComponent: <span>2 Notifications Enabled</span>,
|
|
101
|
+
},
|
|
102
|
+
render: function ReadOnlyRender(args) {
|
|
103
|
+
const [value, setValue] = useState<string[]>(["email", "sms"]);
|
|
104
|
+
return (
|
|
105
|
+
<SwitchGroup {...args} value={value} onChange={setValue}>
|
|
106
|
+
<Switch value="email" label="Email Alerts" />
|
|
107
|
+
<Switch value="push" label="Push Notifications" />
|
|
108
|
+
<Switch value="sms" label="SMS Messages" />
|
|
109
|
+
</SwitchGroup>
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { forwardRef } from "react";
|
|
3
|
+
import {
|
|
4
|
+
Switch as MantineSwitch,
|
|
5
|
+
type SwitchGroupProps as MantineSwitchGroupProps,
|
|
6
|
+
} from "@mantine/core";
|
|
7
|
+
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
type RecursicaOverStyled,
|
|
11
|
+
} from "../../utils/filterStylingProps";
|
|
12
|
+
import {
|
|
13
|
+
FormControlWrapper,
|
|
14
|
+
type RecursicaFormControlWrapperProps,
|
|
15
|
+
} from "../FormControlWrapper/FormControlWrapper";
|
|
16
|
+
import styles from "./Switch.module.css";
|
|
17
|
+
|
|
18
|
+
export interface RecursicaSwitchGroupProps
|
|
19
|
+
extends Omit<MantineSwitchGroupProps, "size" | "labelProps">,
|
|
20
|
+
Omit<
|
|
21
|
+
RecursicaFormControlWrapperProps,
|
|
22
|
+
"controlMaxWidth" | "controlMinWidth"
|
|
23
|
+
>,
|
|
24
|
+
ReadOnlyControlProps {}
|
|
25
|
+
|
|
26
|
+
export type SwitchGroupProps = RecursicaOverStyled<RecursicaSwitchGroupProps>;
|
|
27
|
+
|
|
28
|
+
export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
|
|
29
|
+
function SwitchGroup(
|
|
30
|
+
{
|
|
31
|
+
overStyled = false,
|
|
32
|
+
formLayout = "stacked",
|
|
33
|
+
|
|
34
|
+
// Label Wrappers
|
|
35
|
+
labelSize,
|
|
36
|
+
labelAlignment,
|
|
37
|
+
labelOptionalText,
|
|
38
|
+
labelWithEditIcon,
|
|
39
|
+
onLabelEditClick,
|
|
40
|
+
|
|
41
|
+
// Base Mantine Extracted Attributes
|
|
42
|
+
label,
|
|
43
|
+
description,
|
|
44
|
+
assistiveText,
|
|
45
|
+
assistiveWithIcon,
|
|
46
|
+
error,
|
|
47
|
+
required,
|
|
48
|
+
withAsterisk,
|
|
49
|
+
id,
|
|
50
|
+
className,
|
|
51
|
+
style,
|
|
52
|
+
children,
|
|
53
|
+
readOnly,
|
|
54
|
+
readOnlyComponent,
|
|
55
|
+
...rest
|
|
56
|
+
},
|
|
57
|
+
ref,
|
|
58
|
+
) {
|
|
59
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
60
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
61
|
+
|
|
62
|
+
// Delete prohibited sizing hooks from bypassing the variables
|
|
63
|
+
delete restRecord["size"];
|
|
64
|
+
|
|
65
|
+
if (readOnly && readOnlyComponent) {
|
|
66
|
+
return (
|
|
67
|
+
<FormControlWrapper
|
|
68
|
+
className={className}
|
|
69
|
+
style={style as React.CSSProperties}
|
|
70
|
+
controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
|
|
71
|
+
controlMinWidth={undefined}
|
|
72
|
+
overStyled={overStyled as true}
|
|
73
|
+
labelElement="div"
|
|
74
|
+
formLayout={formLayout}
|
|
75
|
+
labelSize={labelSize}
|
|
76
|
+
labelAlignment={labelAlignment}
|
|
77
|
+
labelOptionalText={labelOptionalText}
|
|
78
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
79
|
+
onLabelEditClick={onLabelEditClick}
|
|
80
|
+
label={label}
|
|
81
|
+
description={description}
|
|
82
|
+
assistiveText={assistiveText}
|
|
83
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
84
|
+
error={error}
|
|
85
|
+
required={required}
|
|
86
|
+
withAsterisk={withAsterisk}
|
|
87
|
+
id={id}
|
|
88
|
+
>
|
|
89
|
+
{readOnlyComponent}
|
|
90
|
+
</FormControlWrapper>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<FormControlWrapper
|
|
96
|
+
className={className}
|
|
97
|
+
style={style as React.CSSProperties}
|
|
98
|
+
controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
|
|
99
|
+
controlMinWidth={undefined}
|
|
100
|
+
overStyled={overStyled as true}
|
|
101
|
+
labelElement="div" // Strictly override. ARIA grouping prohibits interactive switches nested natively inside <label>.
|
|
102
|
+
formLayout={formLayout}
|
|
103
|
+
labelSize={labelSize}
|
|
104
|
+
labelAlignment={labelAlignment}
|
|
105
|
+
labelOptionalText={labelOptionalText}
|
|
106
|
+
labelWithEditIcon={labelWithEditIcon}
|
|
107
|
+
onLabelEditClick={onLabelEditClick}
|
|
108
|
+
label={label}
|
|
109
|
+
description={description}
|
|
110
|
+
assistiveText={assistiveText}
|
|
111
|
+
assistiveWithIcon={assistiveWithIcon}
|
|
112
|
+
error={error}
|
|
113
|
+
required={required}
|
|
114
|
+
withAsterisk={withAsterisk}
|
|
115
|
+
id={id}
|
|
116
|
+
>
|
|
117
|
+
<MantineSwitch.Group
|
|
118
|
+
ref={ref}
|
|
119
|
+
/* Natively bind local disabled lock dynamically */
|
|
120
|
+
{...(sanitizedProps as unknown as MantineSwitchGroupProps)}
|
|
121
|
+
>
|
|
122
|
+
<div className={styles.groupRoot} data-layout={formLayout}>
|
|
123
|
+
{React.Children.map(children, (child) => {
|
|
124
|
+
if (React.isValidElement(child)) {
|
|
125
|
+
return React.cloneElement(child as React.ReactElement<any>, {
|
|
126
|
+
disabled: readOnly || (child.props as any).disabled,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return child;
|
|
130
|
+
})}
|
|
131
|
+
</div>
|
|
132
|
+
</MantineSwitch.Group>
|
|
133
|
+
</FormControlWrapper>
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
SwitchGroup.displayName = "SwitchGroup";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Table } from "./Table";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Table> = {
|
|
6
|
+
title: "UI-Kit/🚧 Table",
|
|
7
|
+
component: Table,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Table>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
render: () => <ComingSoon componentName="Table" />,
|
|
17
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Tabs } from "./Tabs";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Tabs> = {
|
|
6
|
+
title: "UI-Kit/🚧 Tabs",
|
|
7
|
+
component: Tabs,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Tabs>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
render: () => <ComingSoon componentName="Tabs" />,
|
|
17
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Text } from "./Text";
|
|
3
|
+
import { Layer } from "@recursica/adapter-common";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Text> = {
|
|
6
|
+
title: "UI-Kit/Text",
|
|
7
|
+
component: Text,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component:
|
|
13
|
+
"The standard `<Text>` component controls common body sizing scales and implicit paragraphs governed by the active theme layer. For semantic headings (`h1` through `h6`), use `<Title>` instead.",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
argTypes: {
|
|
18
|
+
variant: {
|
|
19
|
+
control: "select",
|
|
20
|
+
options: [
|
|
21
|
+
"body",
|
|
22
|
+
"body-small",
|
|
23
|
+
"caption",
|
|
24
|
+
"overline",
|
|
25
|
+
"subtitle",
|
|
26
|
+
"subtitle-small",
|
|
27
|
+
],
|
|
28
|
+
description:
|
|
29
|
+
"Controls the standard logical boundary definitions natively extracted from Figma.",
|
|
30
|
+
},
|
|
31
|
+
c: {
|
|
32
|
+
control: "text",
|
|
33
|
+
description:
|
|
34
|
+
"Standard Mantine color string mapped via internal boundaries. Example: `dimmed`",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default meta;
|
|
40
|
+
|
|
41
|
+
type Story = StoryObj<typeof Text>;
|
|
42
|
+
|
|
43
|
+
export const Default: Story = {
|
|
44
|
+
args: {
|
|
45
|
+
variant: "body",
|
|
46
|
+
children:
|
|
47
|
+
"This is standard body typography controlled by the central UI-kit boundaries exclusively.",
|
|
48
|
+
},
|
|
49
|
+
render: ({ ...args }) => (
|
|
50
|
+
<Layer layer={0} style={{ padding: "48px" }}>
|
|
51
|
+
<Text {...args} />
|
|
52
|
+
</Layer>
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const StaticVariations: Story = {
|
|
57
|
+
args: {},
|
|
58
|
+
render: () => (
|
|
59
|
+
<Layer
|
|
60
|
+
layer={0}
|
|
61
|
+
style={{
|
|
62
|
+
padding: "48px",
|
|
63
|
+
display: "flex",
|
|
64
|
+
flexDirection: "column",
|
|
65
|
+
gap: "16px",
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<Text variant="body">
|
|
69
|
+
Body (Base paragraph and generic information flow)
|
|
70
|
+
</Text>
|
|
71
|
+
<Text variant="body-small">
|
|
72
|
+
Body Small (Compacted list items and helper blocks)
|
|
73
|
+
</Text>
|
|
74
|
+
<Text variant="caption">
|
|
75
|
+
Caption (Data table descriptions or micro-labels)
|
|
76
|
+
</Text>
|
|
77
|
+
<Text variant="overline">
|
|
78
|
+
Overline (Card contextual pre-headers and categorical tags)
|
|
79
|
+
</Text>
|
|
80
|
+
<Text variant="subtitle">
|
|
81
|
+
Subtitle (Minor sub-headers avoiding heavy display weights)
|
|
82
|
+
</Text>
|
|
83
|
+
<Text variant="subtitle-small">
|
|
84
|
+
Subtitle Small (Section anchors deep in hierarchy)
|
|
85
|
+
</Text>
|
|
86
|
+
</Layer>
|
|
87
|
+
),
|
|
88
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { forwardRef, type ReactNode } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Text as MantineText,
|
|
4
|
+
type TextProps as MantineTextProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import {
|
|
7
|
+
filterStylingProps,
|
|
8
|
+
type RecursicaOverStyled,
|
|
9
|
+
} from "../../utils/filterStylingProps";
|
|
10
|
+
|
|
11
|
+
export type TextVariant =
|
|
12
|
+
| "body"
|
|
13
|
+
| "body-small"
|
|
14
|
+
| "caption"
|
|
15
|
+
| "overline"
|
|
16
|
+
| "subtitle"
|
|
17
|
+
| "subtitle-small";
|
|
18
|
+
|
|
19
|
+
export type RecursicaTextProps = Omit<MantineTextProps, "variant"> & {
|
|
20
|
+
/**
|
|
21
|
+
* The explicit typography hierarchy dictated by Recursica's global design tokens.
|
|
22
|
+
*/
|
|
23
|
+
variant?: TextVariant;
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type TextProps = RecursicaOverStyled<RecursicaTextProps>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A generalized typographical wrapper limiting text properties to bounded Recursica UI-kit tokens inherently.
|
|
31
|
+
* Do not use for semantic headings; use the explicit `<Title>` component for `<h1>` - `<h6>`.
|
|
32
|
+
*/
|
|
33
|
+
export const Text = forwardRef<HTMLDivElement, TextProps>(function Text(
|
|
34
|
+
{ overStyled = false, variant = "body", ...rest },
|
|
35
|
+
ref,
|
|
36
|
+
) {
|
|
37
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
38
|
+
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
39
|
+
.className as string | undefined;
|
|
40
|
+
|
|
41
|
+
const typographyClass = `recursica_brand_typography_${variant}`;
|
|
42
|
+
const mergedClassName = classNameProp
|
|
43
|
+
? `${typographyClass} ${classNameProp}`
|
|
44
|
+
: typographyClass;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<MantineText
|
|
48
|
+
ref={ref}
|
|
49
|
+
className={mergedClassName}
|
|
50
|
+
{...(sanitizedProps as unknown as MantineTextProps)}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
Text.displayName = "Text";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# TextArea Implementation Notes
|
|
2
|
+
|
|
3
|
+
The `TextArea` component is mapped explicitly to Mantine's `<Textarea>` following the same strict encapsulation rules as `TextField`.
|
|
4
|
+
|
|
5
|
+
1. **Naked Primitive Mapping:** Mantine's `Textarea` natively executes macro-label generation. To decouple it, we explicitly disable internal labels (`label={undefined}`) and inject it purely inside our generic `FormControlWrapper`.
|
|
6
|
+
2. **Text Field Token Re-Use:** Because text areas fundamentally share the same box-geometry, text, and state definitions as single-line inputs, it strictly implements the `--recursica_ui-kit_components_text-field_...` variables natively.
|
|
7
|
+
3. **Autosize Handling:** The component supports Mantine's raw `autosize`, `minRows`, and `maxRows` parameters out of the box dynamically via property passthrough.
|