@recursica/mui-adapter 0.4.0 → 0.6.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/CHANGELOG.md +15 -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 +6651 -201
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +63 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +9 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +17 -0
- package/dist/src/components/Autocomplete/index.d.ts +1 -0
- package/dist/src/components/Avatar/Avatar.d.ts +14 -2
- package/dist/src/components/Badge/Badge.d.ts +13 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +10 -3
- package/dist/src/components/Button/Button.d.ts +1 -1
- package/dist/src/components/Card/Card.d.ts +40 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +15 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +16 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +18 -2
- package/dist/src/components/Dropdown/Dropdown.d.ts +23 -3
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +10 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +24 -2
- package/dist/src/components/HoverCard/HoverCard.d.ts +55 -3
- package/dist/src/components/Label/Label.d.ts +13 -2
- package/dist/src/components/Link/Link.d.ts +1 -1
- package/dist/src/components/Menu/Menu.d.ts +99 -3
- package/dist/src/components/Modal/Modal.d.ts +36 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +14 -2
- package/dist/src/components/Pagination/Pagination.d.ts +44 -2
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +65 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +13 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +7 -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 +31 -3
- package/dist/src/components/Slider/Slider.d.ts +28 -2
- package/dist/src/components/Stepper/Stepper.d.ts +21 -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/Tabs/Tabs.d.ts +35 -3
- package/dist/src/components/Text/Text.d.ts +1 -1
- package/dist/src/components/TextArea/TextArea.d.ts +18 -2
- package/dist/src/components/TextField/TextField.d.ts +16 -2
- package/dist/src/components/Timeline/Timeline.d.ts +14 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +29 -0
- package/dist/src/components/Title/Title.d.ts +1 -1
- package/dist/src/components/Toast/Toast.d.ts +25 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/components/index.d.ts +1 -0
- package/package.json +12 -2
- package/src/GlobalExemptions.modules.css +13 -0
- package/src/components/Accordion/Accordion.module.css +295 -0
- package/src/components/Accordion/Accordion.stories.tsx +149 -21
- package/src/components/Accordion/Accordion.tsx +264 -4
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +76 -19
- package/src/components/AssistiveElement/AssistiveElement.tsx +85 -4
- package/src/components/Autocomplete/Autocomplete.module.css +325 -0
- package/src/components/Autocomplete/Autocomplete.stories.tsx +196 -0
- package/src/components/Autocomplete/Autocomplete.tsx +201 -0
- package/src/components/Autocomplete/index.ts +1 -0
- package/src/components/Avatar/Avatar.module.css +344 -0
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +110 -5
- package/src/components/Badge/Badge.module.css +127 -0
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +70 -5
- package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +62 -5
- package/src/components/Button/Button.module.css +113 -20
- package/src/components/Button/Button.stories.tsx +3 -0
- package/src/components/Button/Button.tsx +10 -3
- package/src/components/Card/Card.module.css +118 -0
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +179 -4
- package/src/components/Checkbox/Checkbox.module.css +232 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +146 -4
- package/src/components/Checkbox/CheckboxGroup.tsx +117 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +236 -0
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +138 -5
- package/src/components/DatePicker/DatePicker.module.css +42 -0
- package/src/components/DatePicker/DatePicker.tsx +1 -0
- package/src/components/Dropdown/Dropdown.module.css +296 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +182 -5
- package/src/components/FileInput/FileInput.module.css +47 -0
- package/src/components/FileInput/FileInput.tsx +1 -0
- package/src/components/FileUpload/FileUpload.module.css +40 -0
- package/src/components/FileUpload/FileUpload.tsx +1 -0
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +74 -19
- package/src/components/FormControlLayout/FormControlLayout.tsx +58 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +96 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +122 -19
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +145 -6
- package/src/components/HoverCard/HoverCard.module.css +91 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +150 -4
- package/src/components/Label/Label.module.css +136 -0
- package/src/components/Label/Label.stories.tsx +98 -17
- package/src/components/Label/Label.tsx +88 -4
- package/src/components/Link/Link.module.css +8 -0
- package/src/components/Menu/Menu.module.css +287 -0
- package/src/components/Menu/Menu.stories.tsx +307 -21
- package/src/components/Menu/Menu.tsx +318 -4
- package/src/components/Modal/Modal.module.css +172 -0
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +216 -3
- package/src/components/NumberInput/NumberInput.module.css +281 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +148 -5
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +307 -0
- package/src/components/Pagination/Pagination.stories.tsx +42 -21
- package/src/components/Pagination/Pagination.tsx +193 -4
- package/src/components/Panel/Panel.module.css +206 -0
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +153 -4
- package/src/components/Radio/Radio.module.css +220 -0
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +178 -4
- package/src/components/Radio/RadioGroup.tsx +111 -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 +175 -16
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +109 -4
- 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 +203 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +110 -5
- package/src/components/Slider/Slider.module.css +542 -0
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +282 -4
- package/src/components/Stepper/Stepper.module.css +410 -0
- package/src/components/Stepper/Stepper.stories.tsx +132 -19
- package/src/components/Stepper/Stepper.tsx +145 -5
- package/src/components/Switch/Switch.module.css +238 -0
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +153 -5
- package/src/components/Switch/SwitchGroup.tsx +111 -0
- package/src/components/Tabs/Tabs.module.css +422 -0
- package/src/components/Tabs/Tabs.stories.tsx +138 -19
- package/src/components/Tabs/Tabs.tsx +103 -5
- package/src/components/TextArea/TextArea.module.css +160 -0
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +156 -5
- package/src/components/TextField/TextField.module.css +266 -0
- package/src/components/TextField/TextField.stories.tsx +168 -15
- package/src/components/TextField/TextField.tsx +171 -5
- package/src/components/TimePicker/TimePicker.module.css +41 -0
- package/src/components/TimePicker/TimePicker.tsx +1 -0
- package/src/components/Timeline/Timeline.module.css +367 -0
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +80 -4
- package/src/components/Timeline/TimelineItem.tsx +101 -0
- package/src/components/Toast/Toast.module.css +170 -0
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +90 -4
- package/src/components/Tooltip/Tooltip.module.css +90 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +114 -4
- package/src/components/TransferList/TransferList.module.css +38 -0
- package/src/components/TransferList/TransferList.tsx +1 -0
- package/src/components/index.ts +1 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
/* Prevent default MUI absolute positioning logic */
|
|
3
|
+
position: relative;
|
|
4
|
+
transform: none;
|
|
5
|
+
pointer-events: auto;
|
|
6
|
+
white-space: normal;
|
|
7
|
+
|
|
8
|
+
/* Reset MUI structural overrides */
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
display: flex;
|
|
12
|
+
width: 100%;
|
|
13
|
+
|
|
14
|
+
/* Recursica Font Map */
|
|
15
|
+
font-family: var(
|
|
16
|
+
--recursica_ui-kit_components_label_properties_label-text_font-family
|
|
17
|
+
);
|
|
18
|
+
font-size: var(
|
|
19
|
+
--recursica_ui-kit_components_label_properties_label-text_font-size
|
|
20
|
+
);
|
|
21
|
+
font-style: var(
|
|
22
|
+
--recursica_ui-kit_components_label_properties_label-text_font-style
|
|
23
|
+
);
|
|
24
|
+
font-weight: var(
|
|
25
|
+
--recursica_ui-kit_components_label_properties_label-text_font-weight
|
|
26
|
+
);
|
|
27
|
+
letter-spacing: var(
|
|
28
|
+
--recursica_ui-kit_components_label_properties_label-text_letter-spacing
|
|
29
|
+
);
|
|
30
|
+
line-height: var(
|
|
31
|
+
--recursica_ui-kit_components_label_properties_label-text_line-height
|
|
32
|
+
);
|
|
33
|
+
text-decoration: var(
|
|
34
|
+
--recursica_ui-kit_components_label_properties_label-text_text-decoration
|
|
35
|
+
);
|
|
36
|
+
text-transform: var(
|
|
37
|
+
--recursica_ui-kit_components_label_properties_label-text_text-transform
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
color: var(--recursica_ui-kit_components_label_properties_colors_text);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.innerLayout {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: var(
|
|
47
|
+
--recursica_ui-kit_components_label_properties_label-optional-text-gap
|
|
48
|
+
);
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.text {
|
|
53
|
+
/* Natively intercepts MUI asterisk rendering securely wrapping inline with typography */
|
|
54
|
+
display: inline;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.required {
|
|
58
|
+
/* Override the `.MuiInputLabel-asterisk` natively */
|
|
59
|
+
color: var(--recursica_ui-kit_components_label_properties_colors_asterisk);
|
|
60
|
+
margin-left: var(
|
|
61
|
+
--recursica_ui-kit_components_label_properties_required-indicator-gap
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* MUI propagates .Mui-error to the label automatically on FormControl error.
|
|
66
|
+
We explicitly override this bleed to prevent the main label text from turning red,
|
|
67
|
+
while allowing the asterisk to take the error color! */
|
|
68
|
+
.root:global(.Mui-error) {
|
|
69
|
+
color: var(--recursica_ui-kit_components_label_properties_colors_text);
|
|
70
|
+
}
|
|
71
|
+
.root:global(.Mui-error) .required {
|
|
72
|
+
color: var(
|
|
73
|
+
--recursica_ui-kit_components_assistive-element_variants_types_error_properties_colors_text-color
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.endNodes {
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
gap: var(
|
|
81
|
+
--recursica_ui-kit_components_label_properties_label-optional-text-gap
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.optionalText {
|
|
86
|
+
color: inherit;
|
|
87
|
+
font-family: var(
|
|
88
|
+
--recursica_ui-kit_components_label_properties_optional-text_font-family
|
|
89
|
+
);
|
|
90
|
+
font-size: var(
|
|
91
|
+
--recursica_ui-kit_components_label_properties_optional-text_font-size
|
|
92
|
+
);
|
|
93
|
+
font-style: var(
|
|
94
|
+
--recursica_ui-kit_components_label_properties_optional-text_font-style
|
|
95
|
+
);
|
|
96
|
+
font-weight: var(
|
|
97
|
+
--recursica_ui-kit_components_label_properties_optional-text_font-weight
|
|
98
|
+
);
|
|
99
|
+
letter-spacing: var(
|
|
100
|
+
--recursica_ui-kit_components_label_properties_optional-text_letter-spacing
|
|
101
|
+
);
|
|
102
|
+
line-height: var(
|
|
103
|
+
--recursica_ui-kit_components_label_properties_optional-text_line-height
|
|
104
|
+
);
|
|
105
|
+
text-decoration: var(
|
|
106
|
+
--recursica_ui-kit_components_label_properties_optional-text_text-decoration
|
|
107
|
+
);
|
|
108
|
+
text-transform: var(
|
|
109
|
+
--recursica_ui-kit_components_label_properties_optional-text_text-transform
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.actionArea {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.editIcon {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
background: none;
|
|
124
|
+
border: none;
|
|
125
|
+
padding: 0;
|
|
126
|
+
|
|
127
|
+
width: 16px;
|
|
128
|
+
height: 16px;
|
|
129
|
+
color: inherit;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.editIcon :global(svg) {
|
|
133
|
+
width: 100%;
|
|
134
|
+
height: 100%;
|
|
135
|
+
stroke-width: 2px;
|
|
136
|
+
}
|
|
@@ -1,35 +1,116 @@
|
|
|
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: {
|
|
15
|
+
docs: {
|
|
16
|
+
description: {
|
|
17
|
+
component:
|
|
18
|
+
"The `Label` component is a strict Recursica-styled wrapper around MUI's native `InputLabel`. It serves as the primary compositional primitive for all form fields, preserving MUI'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 MUI's native required asterisk mechanisms.",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
10
21
|
controls: {
|
|
11
22
|
include: [
|
|
12
|
-
"
|
|
13
|
-
"
|
|
23
|
+
"labelSize",
|
|
24
|
+
"labelAlignment",
|
|
25
|
+
"required",
|
|
26
|
+
"labelOptionalText",
|
|
27
|
+
"labelWithEditIcon",
|
|
14
28
|
"children",
|
|
15
|
-
"component",
|
|
16
|
-
"variant",
|
|
17
|
-
"size",
|
|
18
|
-
"icon",
|
|
19
|
-
"disabled",
|
|
20
|
-
"href",
|
|
21
|
-
"onClick",
|
|
22
|
-
"onChange",
|
|
23
|
-
"value",
|
|
24
|
-
"checked",
|
|
25
29
|
],
|
|
26
30
|
},
|
|
27
31
|
},
|
|
32
|
+
argTypes: {
|
|
33
|
+
...formControlArgTypes,
|
|
34
|
+
},
|
|
28
35
|
};
|
|
29
36
|
|
|
30
37
|
export default meta;
|
|
31
|
-
|
|
38
|
+
|
|
39
|
+
type Story = StoryObj<LabelStoryProps>;
|
|
40
|
+
|
|
41
|
+
// Utility mapping to pipe raw Label args structurally into TextField accurately
|
|
42
|
+
const renderWithTextField = ({ children, ...args }: any) => (
|
|
43
|
+
<TextField
|
|
44
|
+
label={children as React.ReactNode}
|
|
45
|
+
placeholder="Form Control primitive mapped..."
|
|
46
|
+
{...(args as any)}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
32
49
|
|
|
33
50
|
export const Default: Story = {
|
|
34
|
-
|
|
51
|
+
args: {
|
|
52
|
+
children: "Dynamic Label (Controls)",
|
|
53
|
+
labelSize: "default",
|
|
54
|
+
labelAlignment: "left",
|
|
55
|
+
required: false,
|
|
56
|
+
labelOptionalText: "",
|
|
57
|
+
labelWithEditIcon: false,
|
|
58
|
+
},
|
|
59
|
+
render: renderWithTextField,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const StackedDefault: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
children: "Email Address",
|
|
65
|
+
},
|
|
66
|
+
render: renderWithTextField,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const StackedRequired: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
children: "Primary Network Node",
|
|
72
|
+
required: true,
|
|
73
|
+
},
|
|
74
|
+
render: renderWithTextField,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const StackedWithEditIcon: Story = {
|
|
78
|
+
args: {
|
|
79
|
+
children: "Environment Variables",
|
|
80
|
+
labelWithEditIcon: true,
|
|
81
|
+
},
|
|
82
|
+
render: renderWithTextField,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const SideBySideDefault: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
children: "Status",
|
|
88
|
+
labelSize: "default",
|
|
89
|
+
},
|
|
90
|
+
render: renderWithTextField,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const RequiredSuppressesOptionalText: Story = {
|
|
94
|
+
args: {
|
|
95
|
+
children: "Full Name",
|
|
96
|
+
required: true,
|
|
97
|
+
labelOptionalText: "This should not render",
|
|
98
|
+
},
|
|
99
|
+
render: renderWithTextField,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const BooleanOptionalText: Story = {
|
|
103
|
+
args: {
|
|
104
|
+
children: "Middle Initial",
|
|
105
|
+
labelOptionalText: true,
|
|
106
|
+
},
|
|
107
|
+
render: renderWithTextField,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export const WithEditIcon: Story = {
|
|
111
|
+
args: {
|
|
112
|
+
children: "Shipping Address",
|
|
113
|
+
labelWithEditIcon: true,
|
|
114
|
+
},
|
|
115
|
+
render: renderWithTextField,
|
|
35
116
|
};
|
|
@@ -1,7 +1,91 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { InputLabel, type InputLabelProps } from "@mui/material";
|
|
3
|
+
import { filterStylingProps } from "../../utils/filterStylingProps";
|
|
4
|
+
import styles from "./Label.module.css";
|
|
2
5
|
|
|
3
|
-
export
|
|
6
|
+
export interface LabelProps extends InputLabelProps {
|
|
7
|
+
overStyled?: boolean;
|
|
8
|
+
/** Explicit optional text to render safely mapping alongside the label. Hidden natively if 'required' is flagged true. */
|
|
9
|
+
labelOptionalText?: React.ReactNode | true;
|
|
10
|
+
/** Triggers the inline edit action icon native layout hook beside the label element. */
|
|
11
|
+
labelWithEditIcon?: boolean;
|
|
12
|
+
/** Fires specifically on icon click natively. */
|
|
13
|
+
onLabelEditClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
14
|
+
/** Replaces the right side optional text block natively with any custom React node (e.g. actions, toggles). */
|
|
15
|
+
labelActionArea?: React.ReactNode;
|
|
16
|
+
}
|
|
4
17
|
|
|
5
|
-
export const Label
|
|
6
|
-
|
|
7
|
-
|
|
18
|
+
export const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
|
19
|
+
function Label(props, ref) {
|
|
20
|
+
const {
|
|
21
|
+
overStyled = false,
|
|
22
|
+
required = false,
|
|
23
|
+
labelOptionalText = "",
|
|
24
|
+
labelWithEditIcon = false,
|
|
25
|
+
onLabelEditClick,
|
|
26
|
+
labelActionArea,
|
|
27
|
+
children,
|
|
28
|
+
className,
|
|
29
|
+
...rest
|
|
30
|
+
} = props;
|
|
31
|
+
|
|
32
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
33
|
+
|
|
34
|
+
const PenIcon = () => (
|
|
35
|
+
<svg
|
|
36
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
37
|
+
width="24"
|
|
38
|
+
height="24"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
fill="none"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
strokeWidth="2"
|
|
43
|
+
strokeLinecap="round"
|
|
44
|
+
strokeLinejoin="round"
|
|
45
|
+
>
|
|
46
|
+
<path d="M12 20h9"></path>
|
|
47
|
+
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
|
|
48
|
+
</svg>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Bypassing MUI's floating functionality by forcing shrink=true to static inline positioning.
|
|
52
|
+
return (
|
|
53
|
+
<InputLabel
|
|
54
|
+
ref={ref}
|
|
55
|
+
shrink={true}
|
|
56
|
+
className={className ? `${styles.root} ${className}` : styles.root}
|
|
57
|
+
{...(sanitizedProps as InputLabelProps)}
|
|
58
|
+
>
|
|
59
|
+
<div className={styles.innerLayout}>
|
|
60
|
+
<span className={styles.textWrapper}>
|
|
61
|
+
<span className={styles.text}>{children}</span>
|
|
62
|
+
{required && <span className={styles.required}> *</span>}
|
|
63
|
+
</span>
|
|
64
|
+
|
|
65
|
+
<div className={styles.endNodes}>
|
|
66
|
+
{labelActionArea && (
|
|
67
|
+
<span className={styles.actionArea}>{labelActionArea}</span>
|
|
68
|
+
)}
|
|
69
|
+
{!required && labelOptionalText && !labelActionArea && (
|
|
70
|
+
<span className={styles.optionalText}>
|
|
71
|
+
{labelOptionalText === true ? "Optional" : labelOptionalText}
|
|
72
|
+
</span>
|
|
73
|
+
)}
|
|
74
|
+
{labelWithEditIcon && (
|
|
75
|
+
<button
|
|
76
|
+
type="button"
|
|
77
|
+
className={styles.editIcon}
|
|
78
|
+
onClick={onLabelEditClick}
|
|
79
|
+
aria-label="Edit label"
|
|
80
|
+
>
|
|
81
|
+
<PenIcon />
|
|
82
|
+
</button>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</InputLabel>
|
|
87
|
+
);
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
Label.displayName = "Label";
|
|
@@ -131,3 +131,11 @@ HARDCODED VALUES:
|
|
|
131
131
|
/* HARDCODE: allows text truncation if bounded */
|
|
132
132
|
min-width: 0;
|
|
133
133
|
}
|
|
134
|
+
|
|
135
|
+
/* EXEMPTIONS:
|
|
136
|
+
text_text-transform across multiple link states (default, hover, visited, visited-hover) is ignored
|
|
137
|
+
because links naturally inherit casing directly from text children rather than requiring custom CSS transforms. */
|
|
138
|
+
/* recursica-ignore: --recursica_ui-kit_components_link_variants_states_default_properties_text_text-transform */
|
|
139
|
+
/* recursica-ignore: --recursica_ui-kit_components_link_variants_states_hover_properties_text_text-transform */
|
|
140
|
+
/* recursica-ignore: --recursica_ui-kit_components_link_variants_states_visited_properties_text_text-transform */
|
|
141
|
+
/* recursica-ignore: --recursica_ui-kit_components_link_variants_states_visited-hover_properties_text_text-transform */
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/* EXEMPTIONS:
|
|
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. */
|
|
4
|
+
/* recursica-ignore: --recursica_ui-kit_components_menu-item_properties_colors_selected-item_supporting-text-color */
|
|
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
|
+
}
|