@recursica/mui-adapter 0.5.0 → 0.7.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/ARCHITECTURE.md +15 -0
- package/CHANGELOG.md +15 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +74 -1
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +6863 -205
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +43 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
- package/dist/src/components/Avatar/Avatar.d.ts +10 -3
- package/dist/src/components/Badge/Badge.d.ts +10 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +38 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +9 -2
- package/dist/src/components/Container/Container.d.ts +1 -5
- package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
- package/dist/src/components/Label/Label.d.ts +6 -2
- package/dist/src/components/Link/Link.d.ts +2 -6
- package/dist/src/components/Loader/Loader.d.ts +2 -7
- package/dist/src/components/Menu/Menu.d.ts +25 -3
- package/dist/src/components/Modal/Modal.d.ts +37 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
- package/dist/src/components/Pagination/Pagination.d.ts +12 -3
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +52 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
- package/dist/src/components/Slider/Slider.d.ts +18 -2
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +41 -2
- package/dist/src/components/Switch/Switch.d.ts +10 -3
- package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +20 -3
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +12 -2
- package/dist/src/components/TextField/TextField.d.ts +12 -2
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +15 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +20 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
- package/dist/src/components/TransferList/TransferList.d.ts +2 -1
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
- package/dist/src/utils/filterStylingProps.d.ts +1 -11
- package/llms.txt +16 -0
- package/package.json +14 -3
- package/src/components/Accordion/Accordion.module.css +294 -56
- package/src/components/Accordion/Accordion.stories.tsx +131 -21
- package/src/components/Accordion/Accordion.tsx +260 -5
- package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
- package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
- package/src/components/Autocomplete/Autocomplete.module.css +319 -42
- package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
- package/src/components/Autocomplete/Autocomplete.tsx +181 -6
- package/src/components/Avatar/Avatar.module.css +343 -73
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +99 -6
- package/src/components/Badge/Badge.module.css +127 -29
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +67 -6
- package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
- package/src/components/Button/Button.module.css +19 -61
- package/src/components/Button/Button.stories.tsx +24 -23
- package/src/components/Button/Button.tsx +7 -18
- package/src/components/Card/Card.module.css +154 -38
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +181 -5
- package/src/components/Checkbox/Checkbox.module.css +249 -39
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +246 -5
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +246 -43
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +136 -6
- package/src/components/Container/Container.stories.tsx +103 -20
- package/src/components/Container/Container.tsx +1 -13
- package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
- package/src/components/DatePicker/DatePicker.tsx +3 -1
- package/src/components/Dropdown/Dropdown.module.css +291 -41
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +180 -6
- package/src/components/FileInput/FileInput.stories.tsx +2 -19
- package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
- package/src/components/Flex/Flex.stories.tsx +113 -20
- package/src/components/Flex/Flex.tsx +16 -26
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
- package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.module.css +90 -22
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +147 -5
- package/src/components/Label/Label.module.css +140 -35
- package/src/components/Label/Label.stories.tsx +108 -21
- package/src/components/Label/Label.tsx +82 -5
- package/src/components/Link/Link.module.css +4 -3
- package/src/components/Link/Link.stories.tsx +2 -8
- package/src/components/Link/Link.tsx +1 -5
- package/src/components/Loader/Loader.module.css +1 -2
- package/src/components/Loader/Loader.tsx +1 -7
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Menu/Menu.module.css +285 -51
- package/src/components/Menu/Menu.stories.tsx +229 -25
- package/src/components/Menu/Menu.tsx +73 -6
- package/src/components/Modal/Modal.module.css +171 -35
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +215 -5
- package/src/components/NumberInput/NumberInput.module.css +276 -42
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +136 -6
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +234 -20
- package/src/components/Pagination/Pagination.stories.tsx +34 -21
- package/src/components/Pagination/Pagination.tsx +74 -6
- package/src/components/Panel/Panel.module.css +206 -38
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +130 -5
- package/src/components/Radio/Radio.module.css +235 -37
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +210 -5
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +125 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +1 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
- package/src/components/Slider/Slider.module.css +539 -86
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +283 -5
- package/src/components/Stack/Stack.stories.tsx +4 -25
- package/src/components/Stack/Stack.tsx +1 -5
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stepper/Stepper.module.css +410 -71
- package/src/components/Stepper/Stepper.stories.tsx +146 -20
- package/src/components/Stepper/Stepper.tsx +147 -6
- package/src/components/Switch/Switch.module.css +259 -39
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +200 -6
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +120 -0
- package/src/components/Table/Table.stories.tsx +1 -19
- package/src/components/Table/Table.tsx +3 -1
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Tabs/Tabs.module.css +422 -79
- package/src/components/Tabs/Tabs.stories.tsx +156 -20
- package/src/components/Tabs/Tabs.tsx +86 -6
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.module.css +155 -32
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +146 -6
- package/src/components/TextField/TextField.module.css +261 -42
- package/src/components/TextField/TextField.stories.tsx +147 -20
- package/src/components/TextField/TextField.tsx +169 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.module.css +365 -76
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +83 -5
- package/src/components/Timeline/TimelineItem.tsx +90 -0
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.module.css +166 -28
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +124 -5
- package/src/components/Tooltip/Tooltip.module.css +89 -24
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +88 -5
- package/src/components/TransferList/TransferList.stories.tsx +1 -19
- package/src/components/TransferList/TransferList.tsx +3 -1
- package/src/utils/RequireAccessibleLabel.ts +1 -12
- package/src/utils/filterStylingProps.ts +7 -20
|
@@ -1,35 +1,122 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React from "react";
|
|
1
3
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
4
|
import { Label } from "./Label";
|
|
3
|
-
import {
|
|
5
|
+
import { TextField } from "../TextField/TextField";
|
|
6
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
type LabelStoryProps = React.ComponentProps<typeof Label>;
|
|
9
|
+
|
|
10
|
+
const meta: Meta<LabelStoryProps> = {
|
|
11
|
+
title: "UI-Kit/Label",
|
|
7
12
|
component: Label,
|
|
8
13
|
tags: ["autodocs"],
|
|
9
14
|
parameters: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"component",
|
|
16
|
-
"variant",
|
|
17
|
-
"size",
|
|
18
|
-
"icon",
|
|
19
|
-
"disabled",
|
|
20
|
-
"href",
|
|
21
|
-
"onClick",
|
|
22
|
-
"onChange",
|
|
23
|
-
"value",
|
|
24
|
-
"checked",
|
|
25
|
-
],
|
|
15
|
+
docs: {
|
|
16
|
+
description: {
|
|
17
|
+
component:
|
|
18
|
+
"The `Label` component is a strict Recursica-styled wrapper around Mantine's native `Input.Label`. It serves as the primary compositional primitive for all form fields, preserving Mantine's accessibility associations and context while strictly enforcing the Recursica atomic design system.\n\n### Usage with Form Inputs\nWhen working with form structures, render this `Label` component directly above your inputs or supply it to a component's overriding properties. The component automatically maps structural layout dimensions, dynamic alignment (`left` vs `right`), custom indicator gaps, and integrates a customized `optionalText` and `withEditIcon` flow that safely bypasses Mantine's native required asterisk mechanisms.",
|
|
19
|
+
},
|
|
26
20
|
},
|
|
27
21
|
},
|
|
22
|
+
argTypes: {
|
|
23
|
+
...formControlArgTypes,
|
|
24
|
+
},
|
|
28
25
|
};
|
|
29
26
|
|
|
30
27
|
export default meta;
|
|
31
|
-
|
|
28
|
+
|
|
29
|
+
type Story = StoryObj<LabelStoryProps>;
|
|
30
|
+
|
|
31
|
+
// Utility mapping to pipe raw Label args structurally into TextField accurately
|
|
32
|
+
const renderWithTextField = ({ children, ...args }: LabelStoryProps) => (
|
|
33
|
+
<TextField
|
|
34
|
+
label={children as React.ReactNode}
|
|
35
|
+
placeholder="Form Control primitive mapped..."
|
|
36
|
+
{...(args as any)}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
32
39
|
|
|
33
40
|
export const Default: Story = {
|
|
34
|
-
|
|
41
|
+
args: {
|
|
42
|
+
children: "Dynamic Label (Controls)",
|
|
43
|
+
|
|
44
|
+
labelSize: "default",
|
|
45
|
+
labelAlignment: "left",
|
|
46
|
+
required: false,
|
|
47
|
+
labelOptionalText: "",
|
|
48
|
+
labelWithEditIcon: false,
|
|
49
|
+
},
|
|
50
|
+
render: renderWithTextField,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const StackedDefault: Story = {
|
|
54
|
+
args: {
|
|
55
|
+
children: "Email Address",
|
|
56
|
+
},
|
|
57
|
+
render: renderWithTextField,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const StackedRequired: Story = {
|
|
61
|
+
args: {
|
|
62
|
+
children: "Primary Network Node",
|
|
63
|
+
|
|
64
|
+
required: true,
|
|
65
|
+
},
|
|
66
|
+
render: renderWithTextField,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const StackedWithEditIcon: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
children: "Environment Variables",
|
|
72
|
+
|
|
73
|
+
labelWithEditIcon: true,
|
|
74
|
+
},
|
|
75
|
+
render: renderWithTextField,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const SideBySideDefault: Story = {
|
|
79
|
+
args: {
|
|
80
|
+
children: "Status",
|
|
81
|
+
|
|
82
|
+
labelSize: "default",
|
|
83
|
+
},
|
|
84
|
+
render: renderWithTextField,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const RequiredSuppressesOptionalText: Story = {
|
|
88
|
+
args: {
|
|
89
|
+
children: "Full Name",
|
|
90
|
+
|
|
91
|
+
required: true,
|
|
92
|
+
labelOptionalText: "This should not render",
|
|
93
|
+
},
|
|
94
|
+
render: renderWithTextField,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const BooleanOptionalText: Story = {
|
|
98
|
+
args: {
|
|
99
|
+
children: "Middle Initial",
|
|
100
|
+
|
|
101
|
+
labelOptionalText: true,
|
|
102
|
+
},
|
|
103
|
+
render: renderWithTextField,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const WithEditIcon: Story = {
|
|
107
|
+
args: {
|
|
108
|
+
children: "Shipping Address",
|
|
109
|
+
|
|
110
|
+
labelWithEditIcon: true,
|
|
111
|
+
},
|
|
112
|
+
render: renderWithTextField,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const LayerOneSideBySide: Story = {
|
|
116
|
+
args: {
|
|
117
|
+
children: "Configuration",
|
|
118
|
+
|
|
119
|
+
labelWithEditIcon: true,
|
|
120
|
+
},
|
|
121
|
+
render: renderWithTextField,
|
|
35
122
|
};
|
|
@@ -1,8 +1,85 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import "
|
|
2
|
+
import { InputLabel, type InputLabelProps } from "@mui/material";
|
|
3
|
+
import { filterStylingProps } from "../../utils/filterStylingProps";
|
|
4
|
+
import styles from "./Label.module.css";
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
import { type RecursicaLabelProps } from "@recursica/adapter-common";
|
|
5
7
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
}
|
|
8
|
+
export interface LabelProps extends InputLabelProps, RecursicaLabelProps {
|
|
9
|
+
overStyled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
|
13
|
+
function Label(props, ref) {
|
|
14
|
+
const {
|
|
15
|
+
overStyled = false,
|
|
16
|
+
required = false,
|
|
17
|
+
labelOptionalText = "",
|
|
18
|
+
labelWithEditIcon = false,
|
|
19
|
+
onLabelEditClick,
|
|
20
|
+
labelActionArea,
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
...rest
|
|
24
|
+
} = props;
|
|
25
|
+
|
|
26
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
27
|
+
|
|
28
|
+
const PenIcon = () => (
|
|
29
|
+
<svg
|
|
30
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
31
|
+
width="24"
|
|
32
|
+
height="24"
|
|
33
|
+
viewBox="0 0 24 24"
|
|
34
|
+
fill="none"
|
|
35
|
+
stroke="currentColor"
|
|
36
|
+
strokeWidth="2"
|
|
37
|
+
strokeLinecap="round"
|
|
38
|
+
strokeLinejoin="round"
|
|
39
|
+
>
|
|
40
|
+
<path d="M12 20h9"></path>
|
|
41
|
+
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
|
42
|
+
</svg>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Bypassing MUI's floating functionality by forcing shrink=true to static inline positioning.
|
|
46
|
+
return (
|
|
47
|
+
<InputLabel
|
|
48
|
+
ref={ref}
|
|
49
|
+
shrink={true}
|
|
50
|
+
className={className ? `${styles.root} ${className}` : styles.root}
|
|
51
|
+
{...(sanitizedProps as InputLabelProps)}
|
|
52
|
+
>
|
|
53
|
+
<div className={styles.innerLayout}>
|
|
54
|
+
<span className={styles.textWrapper}>
|
|
55
|
+
<span className={styles.text}>{children}</span>
|
|
56
|
+
{required && <span className={styles.required}> *</span>}
|
|
57
|
+
</span>
|
|
58
|
+
|
|
59
|
+
<div className={styles.endNodes}>
|
|
60
|
+
{labelActionArea && (
|
|
61
|
+
<span className={styles.actionArea}>{labelActionArea}</span>
|
|
62
|
+
)}
|
|
63
|
+
{!required && labelOptionalText && !labelActionArea && (
|
|
64
|
+
<span className={styles.optionalText}>
|
|
65
|
+
{labelOptionalText === true ? "Optional" : labelOptionalText}
|
|
66
|
+
</span>
|
|
67
|
+
)}
|
|
68
|
+
{labelWithEditIcon && (
|
|
69
|
+
<button
|
|
70
|
+
type="button"
|
|
71
|
+
className={styles.editIcon}
|
|
72
|
+
onClick={onLabelEditClick}
|
|
73
|
+
aria-label="Edit label"
|
|
74
|
+
>
|
|
75
|
+
<PenIcon />
|
|
76
|
+
</button>
|
|
77
|
+
)}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</InputLabel>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
Label.displayName = "Label";
|
|
@@ -8,9 +8,8 @@ HARDCODED VALUES:
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
.root {
|
|
11
|
-
/* HARDCODE: base layout
|
|
12
|
-
display: inline
|
|
13
|
-
align-items: center;
|
|
11
|
+
/* HARDCODE: base layout */
|
|
12
|
+
display: inline;
|
|
14
13
|
cursor: pointer;
|
|
15
14
|
|
|
16
15
|
/* HARDCODE: Reset underline and color so we can explicitly use our tokens */
|
|
@@ -45,6 +44,8 @@ HARDCODED VALUES:
|
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
.root[data-has-icon] {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
48
49
|
gap: var(--recursica_ui-kit_components_link_properties_icon-text-gap);
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -2,17 +2,11 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
3
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
4
|
import { Link } from "./Link";
|
|
5
|
-
import { Text } from "../Text/Text";
|
|
6
5
|
|
|
7
6
|
const meta: Meta<typeof Link> = {
|
|
8
7
|
title: "UI-Kit/Link",
|
|
9
8
|
component: Link,
|
|
10
9
|
tags: ["autodocs"],
|
|
11
|
-
parameters: {
|
|
12
|
-
controls: {
|
|
13
|
-
include: ["children", "href", "icon", "component", "onClick"],
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
10
|
args: {
|
|
17
11
|
children: "Link text",
|
|
18
12
|
href: "#",
|
|
@@ -57,8 +51,8 @@ export const Polymorphic: Story = {
|
|
|
57
51
|
|
|
58
52
|
export const InlineText: Story = {
|
|
59
53
|
render: () => (
|
|
60
|
-
<
|
|
54
|
+
<p>
|
|
61
55
|
Here is some text with an <Link href="#">inline link</Link> inside it.
|
|
62
|
-
</
|
|
56
|
+
</p>
|
|
63
57
|
),
|
|
64
58
|
};
|
|
@@ -6,11 +6,7 @@ import {
|
|
|
6
6
|
} from "../../utils/filterStylingProps";
|
|
7
7
|
import styles from "./Link.module.css";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
icon?: React.ReactNode;
|
|
11
|
-
children?: React.ReactNode;
|
|
12
|
-
component?: React.ElementType;
|
|
13
|
-
}
|
|
9
|
+
import { type RecursicaLinkProps } from "@recursica/adapter-common";
|
|
14
10
|
|
|
15
11
|
export type LinkProps = RecursicaOverStyled<
|
|
16
12
|
Omit<MUILinkProps, "underline"> & RecursicaLinkProps
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
.root {
|
|
2
2
|
/* Default inheritance mapped from component variables if not explicitly overridden by variants */
|
|
3
3
|
--loader-color: var(
|
|
4
|
-
--recursica_ui-kit_components_loader_properties_indicator-color
|
|
5
|
-
currentColor
|
|
4
|
+
--recursica_ui-kit_components_loader_properties_indicator-color
|
|
6
5
|
);
|
|
7
6
|
box-sizing: border-box;
|
|
8
7
|
}
|
|
@@ -2,16 +2,10 @@ import React, { forwardRef } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
filterStylingProps,
|
|
4
4
|
type RecursicaOverStyled,
|
|
5
|
-
type RecursicaSize,
|
|
6
5
|
} from "../../utils/filterStylingProps";
|
|
7
6
|
import styles from "./Loader.module.css";
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
/** Map to the component styles defined in variables */
|
|
11
|
-
variant?: "oval" | "bars" | "dots";
|
|
12
|
-
/** Map to Recursica sizes */
|
|
13
|
-
size?: "sm" | "md" | "lg" | RecursicaSize;
|
|
14
|
-
}
|
|
8
|
+
import { type RecursicaLoaderProps } from "@recursica/adapter-common";
|
|
15
9
|
|
|
16
10
|
export type LoaderProps = RecursicaOverStyled<
|
|
17
11
|
React.HTMLAttributes<HTMLSpanElement> & RecursicaLoaderProps
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Menu Implementation Notes
|
|
2
|
+
|
|
3
|
+
- **Compositional API Dropped:** Mantine uses `<Menu.Target>`, `<Menu.Dropdown>`, `<Menu.Item>`, etc., and manages state natively via React context within `<Menu>`. MUI's API is fully monolithic.
|
|
4
|
+
- **Monolithic API Adopted:** Following architectural review, we have abandoned the fabricated context wrappers for `mui-adapter`. We now natively export `Menu`, `MenuItem`, and `MenuDivider` wrapping their `@mui/material` counterparts. Developers are expected to manage `anchorEl` state themselves, just like native MUI. Storybook tests have been updated to simulate this open state so visual regressions still cover the dropdown menu visually.
|
|
@@ -1,53 +1,287 @@
|
|
|
1
1
|
/* EXEMPTIONS:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_border-radius */
|
|
6
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_background */
|
|
7
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_hover-color */
|
|
8
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_hover-opacity */
|
|
9
|
-
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_leading-icon-color */
|
|
2
|
+
- colors_selected-item_supporting-text-color is ignored because selected menu items do not render
|
|
3
|
+
supporting secondary text, making selected state overrides for supporting text colors obsolete. */
|
|
10
4
|
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_supporting-text-color */
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/*
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
5
|
+
|
|
6
|
+
/* HARDCODED VALUES:
|
|
7
|
+
- border-style: solid. Structural rendering rule for the dropdown border (Mantine uses Paper which may not set border natively).
|
|
8
|
+
- opacity: 0.5 on disabled items. Recursica has no dedicated disabled-opacity token for menu items.
|
|
9
|
+
- NOTE: overflow is intentionally NOT set on .dropdown. Mantine renders sub-menu dropdowns
|
|
10
|
+
inside the parent dropdown DOM tree using Floating UI absolute positioning. Setting
|
|
11
|
+
overflow: hidden clips sub-menus; overflow-y: auto causes unwanted scrollbars.
|
|
12
|
+
- All structural layout (flex, cursor, pointer-events on disabled) is deferred to Mantine's
|
|
13
|
+
native behavior. We only override visual design tokens (colors, typography, spacing, borders).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/* ======================================
|
|
17
|
+
DROPDOWN CONTAINER
|
|
18
|
+
====================================== */
|
|
19
|
+
|
|
20
|
+
.dropdown {
|
|
21
|
+
background-color: var(
|
|
22
|
+
--recursica_ui-kit_components_menu_properties_colors_background
|
|
23
|
+
);
|
|
24
|
+
border-style: solid; /* HARDCODE: Mantine Paper does not set border-style natively */
|
|
25
|
+
border-width: var(--recursica_ui-kit_components_menu_properties_border-size);
|
|
26
|
+
border-color: var(
|
|
27
|
+
--recursica_ui-kit_components_menu_properties_colors_border-color
|
|
28
|
+
);
|
|
29
|
+
border-radius: var(
|
|
30
|
+
--recursica_ui-kit_components_menu_properties_border-radius
|
|
31
|
+
);
|
|
32
|
+
box-shadow: var(--recursica_ui-kit_components_menu_properties_elevation);
|
|
33
|
+
|
|
34
|
+
min-width: var(--recursica_ui-kit_components_menu_properties_min-width);
|
|
35
|
+
max-height: var(--recursica_ui-kit_components_menu_properties_max-height);
|
|
36
|
+
max-width: var(--recursica_ui-kit_components_menu_properties_max-width);
|
|
37
|
+
|
|
38
|
+
/* HARDCODE: Figma UI Kit does not export padding tokens for the Menu container itself.
|
|
39
|
+
If added in the future, it would be mapped here. */
|
|
40
|
+
padding: 8px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* ======================================
|
|
44
|
+
MENU ITEM
|
|
45
|
+
====================================== */
|
|
46
|
+
|
|
47
|
+
.item {
|
|
48
|
+
position: relative;
|
|
49
|
+
|
|
50
|
+
/* Geometry */
|
|
51
|
+
padding: var(
|
|
52
|
+
--recursica_ui-kit_components_menu-item_properties_vertical-padding
|
|
53
|
+
)
|
|
54
|
+
var(--recursica_ui-kit_components_menu-item_properties_horizontal-padding);
|
|
55
|
+
border-radius: var(
|
|
56
|
+
--recursica_ui-kit_components_menu-item_properties_border-radius
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
/* Typography */
|
|
60
|
+
font-family: var(
|
|
61
|
+
--recursica_ui-kit_components_menu-item_properties_text_font-family
|
|
62
|
+
);
|
|
63
|
+
font-size: var(
|
|
64
|
+
--recursica_ui-kit_components_menu-item_properties_text_font-size
|
|
65
|
+
);
|
|
66
|
+
font-style: var(
|
|
67
|
+
--recursica_ui-kit_components_menu-item_properties_text_font-style
|
|
68
|
+
);
|
|
69
|
+
font-weight: var(
|
|
70
|
+
--recursica_ui-kit_components_menu-item_properties_text_font-weight
|
|
71
|
+
);
|
|
72
|
+
letter-spacing: var(
|
|
73
|
+
--recursica_ui-kit_components_menu-item_properties_text_letter-spacing
|
|
74
|
+
);
|
|
75
|
+
line-height: var(
|
|
76
|
+
--recursica_ui-kit_components_menu-item_properties_text_line-height
|
|
77
|
+
);
|
|
78
|
+
text-decoration: var(
|
|
79
|
+
--recursica_ui-kit_components_menu-item_properties_text_text-decoration
|
|
80
|
+
);
|
|
81
|
+
text-transform: var(
|
|
82
|
+
--recursica_ui-kit_components_menu-item_properties_text_text-transform
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
/* Default State: Unselected */
|
|
86
|
+
background-color: var(
|
|
87
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_background
|
|
88
|
+
);
|
|
89
|
+
color: var(
|
|
90
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_text
|
|
91
|
+
);
|
|
92
|
+
opacity: 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Override Mantine's native hover background to use our overlay technique */
|
|
96
|
+
.item:hover {
|
|
97
|
+
background-color: var(
|
|
98
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_background
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Hover overlay using ::after pseudo-element (same technique as Accordion) */
|
|
103
|
+
.item::after {
|
|
104
|
+
content: "";
|
|
105
|
+
position: absolute;
|
|
106
|
+
inset: 0;
|
|
107
|
+
border-radius: inherit;
|
|
108
|
+
z-index: 0;
|
|
109
|
+
pointer-events: none;
|
|
110
|
+
background-color: var(
|
|
111
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_hover-color
|
|
112
|
+
);
|
|
113
|
+
opacity: 0;
|
|
114
|
+
transition: opacity 150ms ease;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.item:hover:not([data-disabled])::after {
|
|
118
|
+
opacity: var(
|
|
119
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_hover-opacity
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Selected item state */
|
|
124
|
+
.item[data-selected] {
|
|
125
|
+
background-color: var(
|
|
126
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_background
|
|
127
|
+
);
|
|
128
|
+
color: var(
|
|
129
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_text
|
|
130
|
+
);
|
|
131
|
+
opacity: 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.item[data-selected]::after {
|
|
135
|
+
background-color: var(
|
|
136
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_hover-color
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* Hovered item state (keyboard navigation) */
|
|
141
|
+
.item[data-hovered] {
|
|
142
|
+
background-color: var(
|
|
143
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_background
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
.item[data-hovered]::after {
|
|
147
|
+
opacity: var(
|
|
148
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_hover-opacity
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.item[data-hovered][data-selected]::after {
|
|
153
|
+
opacity: var(
|
|
154
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_hover-opacity
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Disabled item */
|
|
159
|
+
.item[data-disabled] {
|
|
160
|
+
opacity: var(
|
|
161
|
+
--recursica_ui-kit_components_menu-item_properties_disabled-opacity
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ======================================
|
|
166
|
+
ITEM LABEL
|
|
167
|
+
====================================== */
|
|
168
|
+
|
|
169
|
+
.itemLabel {
|
|
170
|
+
position: relative;
|
|
171
|
+
z-index: 1;
|
|
172
|
+
color: inherit;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* ======================================
|
|
176
|
+
ITEM SECTION (LEFT / RIGHT ICONS)
|
|
177
|
+
====================================== */
|
|
178
|
+
|
|
179
|
+
.itemSection {
|
|
180
|
+
position: relative;
|
|
181
|
+
z-index: 1;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.itemSection[data-position="left"] {
|
|
185
|
+
width: var(
|
|
186
|
+
--recursica_ui-kit_components_menu-item_properties_icon-leading-size
|
|
187
|
+
);
|
|
188
|
+
height: var(
|
|
189
|
+
--recursica_ui-kit_components_menu-item_properties_icon-leading-size
|
|
190
|
+
);
|
|
191
|
+
margin-right: var(
|
|
192
|
+
--recursica_ui-kit_components_menu-item_properties_icon-text-gap
|
|
193
|
+
);
|
|
194
|
+
color: var(
|
|
195
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_leading-icon-color
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.itemSection[data-position="right"] {
|
|
200
|
+
width: var(
|
|
201
|
+
--recursica_ui-kit_components_menu-item_properties_icon-trailing-size
|
|
202
|
+
);
|
|
203
|
+
height: var(
|
|
204
|
+
--recursica_ui-kit_components_menu-item_properties_icon-trailing-size
|
|
205
|
+
);
|
|
206
|
+
margin-left: var(--recursica_ui-kit_components_menu-item_properties_text-gap);
|
|
207
|
+
color: var(
|
|
208
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_trailing-icon-color
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.item[data-selected] .itemSection[data-position="left"] {
|
|
213
|
+
color: var(
|
|
214
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_leading-icon-color
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.item[data-selected] .itemSection[data-position="right"] {
|
|
219
|
+
color: var(
|
|
220
|
+
--recursica_ui-kit_components_menu-item_properties_colors_selected-item_trailing-icon-color
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* ======================================
|
|
225
|
+
DIVIDER
|
|
226
|
+
====================================== */
|
|
227
|
+
|
|
228
|
+
.divider {
|
|
229
|
+
height: var(--recursica_ui-kit_components_menu_properties_divider-height);
|
|
230
|
+
background-color: var(
|
|
231
|
+
--recursica_ui-kit_components_menu_properties_colors_divider-color
|
|
232
|
+
);
|
|
233
|
+
opacity: var(--recursica_ui-kit_components_menu_properties_divider-opacity);
|
|
234
|
+
margin: 8px 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* ======================================
|
|
238
|
+
SECTION LABEL
|
|
239
|
+
====================================== */
|
|
240
|
+
|
|
241
|
+
.label {
|
|
242
|
+
padding: var(
|
|
243
|
+
--recursica_ui-kit_components_menu-item_properties_vertical-padding
|
|
244
|
+
)
|
|
245
|
+
var(--recursica_ui-kit_components_menu-item_properties_horizontal-padding);
|
|
246
|
+
|
|
247
|
+
/* Supporting Text Typography */
|
|
248
|
+
font-family: var(
|
|
249
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_font-family
|
|
250
|
+
);
|
|
251
|
+
font-size: var(
|
|
252
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_font-size
|
|
253
|
+
);
|
|
254
|
+
font-style: var(
|
|
255
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_font-style
|
|
256
|
+
);
|
|
257
|
+
font-weight: var(
|
|
258
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_font-weight
|
|
259
|
+
);
|
|
260
|
+
letter-spacing: var(
|
|
261
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_letter-spacing
|
|
262
|
+
);
|
|
263
|
+
line-height: var(
|
|
264
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_line-height
|
|
265
|
+
);
|
|
266
|
+
text-decoration: var(
|
|
267
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_text-decoration
|
|
268
|
+
);
|
|
269
|
+
text-transform: var(
|
|
270
|
+
--recursica_ui-kit_components_menu-item_properties_supporting-text_text-transform
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
color: var(
|
|
274
|
+
--recursica_ui-kit_components_menu-item_properties_colors_unselected-item_supporting-text-color
|
|
275
|
+
);
|
|
276
|
+
opacity: 0.7;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* ======================================
|
|
280
|
+
SUB-MENU CHEVRON
|
|
281
|
+
====================================== */
|
|
282
|
+
|
|
283
|
+
.chevron {
|
|
284
|
+
position: relative;
|
|
285
|
+
z-index: 1;
|
|
286
|
+
color: inherit;
|
|
287
|
+
}
|