@recursica/mui-adapter 0.6.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 +6 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +26 -26
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +3721 -3511
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +9 -29
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +2 -5
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +4 -8
- package/dist/src/components/Avatar/Avatar.d.ts +1 -6
- package/dist/src/components/Badge/Badge.d.ts +1 -4
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +2 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +2 -4
- package/dist/src/components/Checkbox/Checkbox.d.ts +4 -6
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +8 -6
- package/dist/src/components/Chip/Chip.d.ts +2 -11
- 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 +4 -14
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +2 -7
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +3 -18
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +13 -39
- package/dist/src/components/Label/Label.d.ts +2 -9
- 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 +24 -98
- package/dist/src/components/Modal/Modal.d.ts +32 -31
- package/dist/src/components/NumberInput/NumberInput.d.ts +3 -5
- package/dist/src/components/Pagination/Pagination.d.ts +8 -41
- package/dist/src/components/Panel/Panel.d.ts +5 -18
- package/dist/src/components/Radio/Radio.d.ts +4 -4
- package/dist/src/components/Radio/RadioGroup.d.ts +3 -7
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +2 -5
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +5 -15
- package/dist/src/components/Slider/Slider.d.ts +4 -14
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +36 -16
- package/dist/src/components/Switch/Switch.d.ts +4 -4
- package/dist/src/components/Switch/SwitchGroup.d.ts +4 -4
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +11 -26
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +3 -9
- package/dist/src/components/TextField/TextField.d.ts +3 -7
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +2 -1
- package/dist/src/components/Timeline/TimelineItem.d.ts +2 -13
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +11 -16
- package/dist/src/components/Tooltip/Tooltip.d.ts +7 -21
- 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 +6 -2
- package/src/components/Accordion/Accordion.module.css +1 -2
- package/src/components/Accordion/Accordion.stories.tsx +0 -18
- package/src/components/Accordion/Accordion.tsx +19 -23
- package/src/components/AssistiveElement/AssistiveElement.module.css +32 -29
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +10 -27
- package/src/components/AssistiveElement/AssistiveElement.tsx +11 -15
- package/src/components/Autocomplete/Autocomplete.module.css +17 -18
- package/src/components/Autocomplete/Autocomplete.stories.tsx +7 -16
- package/src/components/Autocomplete/Autocomplete.tsx +27 -45
- package/src/components/Avatar/Avatar.tsx +2 -13
- package/src/components/Badge/Badge.tsx +2 -5
- package/src/components/Breadcrumb/Breadcrumb.tsx +1 -4
- 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 +36 -0
- package/src/components/Card/Card.tsx +6 -4
- package/src/components/Checkbox/Checkbox.module.css +27 -10
- package/src/components/Checkbox/Checkbox.tsx +124 -24
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +43 -23
- package/src/components/Chip/Chip.module.css +52 -34
- package/src/components/Chip/Chip.tsx +45 -47
- 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.tsx +7 -9
- 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.stories.tsx +0 -8
- package/src/components/FormControlLayout/FormControlLayout.tsx +18 -7
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +1 -10
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +12 -21
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +11 -30
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.tsx +72 -75
- package/src/components/Label/Label.module.css +4 -0
- package/src/components/Label/Label.stories.tsx +18 -12
- package/src/components/Label/Label.tsx +3 -9
- 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.stories.tsx +106 -188
- package/src/components/Menu/Menu.tsx +34 -280
- package/src/components/Modal/Modal.tsx +158 -160
- package/src/components/NumberInput/NumberInput.tsx +6 -18
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.module.css +12 -24
- package/src/components/Pagination/Pagination.stories.tsx +0 -8
- package/src/components/Pagination/Pagination.tsx +20 -140
- package/src/components/Panel/Panel.tsx +7 -30
- package/src/components/Radio/Radio.module.css +25 -10
- package/src/components/Radio/Radio.tsx +51 -19
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +26 -12
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +6 -6
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +5 -36
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +9 -13
- package/src/components/SegmentedControl/SegmentedControl.module.css +23 -47
- package/src/components/SegmentedControl/SegmentedControl.tsx +44 -14
- package/src/components/Slider/Slider.module.css +1 -4
- package/src/components/Slider/Slider.stories.tsx +3 -3
- package/src/components/Slider/Slider.tsx +26 -25
- 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.stories.tsx +56 -43
- package/src/components/Stepper/Stepper.tsx +89 -87
- package/src/components/Switch/Switch.module.css +21 -0
- package/src/components/Switch/Switch.tsx +63 -16
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +27 -18
- 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.stories.tsx +41 -24
- package/src/components/Tabs/Tabs.tsx +49 -66
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.tsx +7 -17
- package/src/components/TextField/TextField.stories.tsx +1 -27
- package/src/components/TextField/TextField.tsx +4 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.tsx +4 -1
- package/src/components/Timeline/TimelineItem.tsx +1 -12
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.stories.tsx +1 -1
- package/src/components/Toast/Toast.tsx +62 -28
- package/src/components/Tooltip/Tooltip.tsx +11 -37
- 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
|
@@ -4,25 +4,28 @@ import {
|
|
|
4
4
|
type StackProps as MUIStackProps,
|
|
5
5
|
} from "@mui/material";
|
|
6
6
|
import {
|
|
7
|
-
type RecursicaSpacing,
|
|
8
7
|
SPACING_MAP,
|
|
9
8
|
type OmitSx,
|
|
10
9
|
filterSxProp,
|
|
11
10
|
} from "../../utils/filterStylingProps";
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
children?: React.ReactNode;
|
|
15
|
-
gap?: MUIStackProps["spacing"] | RecursicaSpacing;
|
|
16
|
-
rowGap?: MUIStackProps["spacing"] | RecursicaSpacing;
|
|
17
|
-
columnGap?: MUIStackProps["spacing"] | RecursicaSpacing;
|
|
18
|
-
}
|
|
12
|
+
import { type RecursicaGroupProps } from "@recursica/adapter-common";
|
|
19
13
|
|
|
20
14
|
export type GroupProps = OmitSx<
|
|
21
15
|
Omit<MUIStackProps, "spacing" | "direction"> & RecursicaGroupProps
|
|
22
16
|
>;
|
|
23
17
|
|
|
24
18
|
export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
|
|
25
|
-
{
|
|
19
|
+
{
|
|
20
|
+
children,
|
|
21
|
+
gap = "rec-default",
|
|
22
|
+
rowGap,
|
|
23
|
+
columnGap,
|
|
24
|
+
justify,
|
|
25
|
+
align,
|
|
26
|
+
wrap,
|
|
27
|
+
...rest
|
|
28
|
+
},
|
|
26
29
|
ref,
|
|
27
30
|
) {
|
|
28
31
|
const safeProps = filterSxProp(rest as Record<string, unknown>);
|
|
@@ -43,7 +46,9 @@ export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
|
|
|
43
46
|
<MUIStack
|
|
44
47
|
ref={ref}
|
|
45
48
|
direction="row"
|
|
46
|
-
flexWrap="wrap"
|
|
49
|
+
flexWrap={wrap || "wrap"}
|
|
50
|
+
justifyContent={justify}
|
|
51
|
+
alignItems={align}
|
|
47
52
|
spacing={resolvedGap}
|
|
48
53
|
sx={{
|
|
49
54
|
...(resolvedRowGap ? { rowGap: resolvedRowGap } : {}),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import React, { isValidElement } from "react";
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
type
|
|
3
|
+
Tooltip as MuiTooltip,
|
|
4
|
+
type TooltipProps as MuiTooltipProps,
|
|
4
5
|
} from "@mui/material";
|
|
5
6
|
import {
|
|
6
7
|
filterStylingProps,
|
|
@@ -12,48 +13,31 @@ import styles from "./HoverCard.module.css";
|
|
|
12
13
|
// HOVERCARD ROOT
|
|
13
14
|
// ============================================================
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
export interface RecursicaHoverCardProps {
|
|
19
|
-
/**
|
|
20
|
-
* Whether to display a beak (arrow) pointing from the dropdown to the target.
|
|
21
|
-
* This is the Recursica equivalent of Mui's `withArrow`.
|
|
22
|
-
* When both `withBeak` and `withArrow` are provided, `withBeak` takes precedence.
|
|
23
|
-
*/
|
|
24
|
-
withBeak?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Recursica HoverCard component wrapping Mui's composable HoverCard.
|
|
29
|
-
*
|
|
30
|
-
* Displays a dropdown panel when the user hovers over a target element.
|
|
31
|
-
* Uses the composable dot-notation pattern:
|
|
32
|
-
* ```tsx
|
|
33
|
-
* <HoverCard withBeak>
|
|
34
|
-
* <HoverCard.Target>
|
|
35
|
-
* <Button>Hover me</Button>
|
|
36
|
-
* </HoverCard.Target>
|
|
37
|
-
* <HoverCard.Dropdown>
|
|
38
|
-
* Content displayed on hover
|
|
39
|
-
* </HoverCard.Dropdown>
|
|
40
|
-
* </HoverCard>
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
16
|
+
import { type RecursicaHoverCardProps } from "@recursica/adapter-common";
|
|
17
|
+
|
|
43
18
|
export type HoverCardProps = RecursicaOverStyled<
|
|
44
|
-
|
|
19
|
+
Omit<MuiTooltipProps, "title" | "children"> & RecursicaHoverCardProps
|
|
45
20
|
>;
|
|
46
21
|
|
|
47
22
|
const HoverCardBase = function HoverCard({
|
|
48
23
|
overStyled = false,
|
|
49
24
|
withBeak = true,
|
|
25
|
+
position = "top",
|
|
26
|
+
openDelay = 0,
|
|
27
|
+
closeDelay = 150,
|
|
28
|
+
disabled = false,
|
|
29
|
+
offset = 5,
|
|
30
|
+
children,
|
|
50
31
|
...rest
|
|
51
32
|
}: HoverCardProps) {
|
|
52
|
-
const sanitizedProps = filterStylingProps(
|
|
33
|
+
const sanitizedProps = filterStylingProps(
|
|
34
|
+
rest as Record<string, unknown>,
|
|
35
|
+
overStyled,
|
|
36
|
+
);
|
|
53
37
|
|
|
54
38
|
// Bind CSS module classes to Mui's internal classNames API
|
|
55
39
|
const mergedClassNames: Partial<Record<string, string>> = {
|
|
56
|
-
|
|
40
|
+
tooltip: styles.dropdown,
|
|
57
41
|
arrow: styles.arrow,
|
|
58
42
|
};
|
|
59
43
|
|
|
@@ -73,29 +57,55 @@ const HoverCardBase = function HoverCard({
|
|
|
73
57
|
});
|
|
74
58
|
}
|
|
75
59
|
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
60
|
+
// Find Target and Dropdown children
|
|
61
|
+
let targetNode: React.ReactNode = null;
|
|
62
|
+
let dropdownNode: React.ReactNode = null;
|
|
63
|
+
|
|
64
|
+
React.Children.forEach(children, (child) => {
|
|
65
|
+
if (isValidElement(child)) {
|
|
66
|
+
const childElement = child as any;
|
|
67
|
+
if (childElement.type?.displayName === "HoverCardTarget") {
|
|
68
|
+
targetNode = childElement.props.children;
|
|
69
|
+
} else if (childElement.type?.displayName === "HoverCardDropdown") {
|
|
70
|
+
dropdownNode = childElement.props.children;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!targetNode) {
|
|
76
|
+
// Fallback if structure is wrong
|
|
77
|
+
targetNode = <div />;
|
|
78
|
+
}
|
|
79
|
+
if (!dropdownNode) {
|
|
80
|
+
dropdownNode = <div />;
|
|
81
|
+
}
|
|
90
82
|
|
|
91
83
|
return (
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
{
|
|
98
|
-
|
|
84
|
+
<MuiTooltip
|
|
85
|
+
title={dropdownNode}
|
|
86
|
+
placement={position as any}
|
|
87
|
+
arrow={withBeak}
|
|
88
|
+
enterDelay={openDelay}
|
|
89
|
+
leaveDelay={closeDelay}
|
|
90
|
+
disableHoverListener={disabled}
|
|
91
|
+
slotProps={{
|
|
92
|
+
popper: {
|
|
93
|
+
modifiers: [
|
|
94
|
+
{
|
|
95
|
+
name: "offset",
|
|
96
|
+
options: {
|
|
97
|
+
offset: [0, offset],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
}}
|
|
103
|
+
classes={mergedClassNames as any}
|
|
104
|
+
{...(sanitizedProps as any)}
|
|
105
|
+
>
|
|
106
|
+
{/* Tooltip requires a single valid React element child that accepts a ref */}
|
|
107
|
+
{isValidElement(targetNode) ? targetNode : <span>{targetNode}</span>}
|
|
108
|
+
</MuiTooltip>
|
|
99
109
|
);
|
|
100
110
|
};
|
|
101
111
|
HoverCardBase.displayName = "HoverCard";
|
|
@@ -104,14 +114,12 @@ HoverCardBase.displayName = "HoverCard";
|
|
|
104
114
|
// HOVERCARD TARGET
|
|
105
115
|
// ============================================================
|
|
106
116
|
|
|
107
|
-
|
|
108
|
-
* Wrapper for the element that triggers the hover card.
|
|
109
|
-
* Requires a single child element that supports ref forwarding.
|
|
110
|
-
*/
|
|
111
|
-
export type HoverCardTargetProps = any;
|
|
117
|
+
export type HoverCardTargetProps = { children?: React.ReactNode };
|
|
112
118
|
|
|
113
|
-
const HoverCardTarget = function HoverCardTarget(
|
|
114
|
-
|
|
119
|
+
const HoverCardTarget = function HoverCardTarget({
|
|
120
|
+
children,
|
|
121
|
+
}: HoverCardTargetProps) {
|
|
122
|
+
return <>{children}</>;
|
|
115
123
|
};
|
|
116
124
|
HoverCardTarget.displayName = "HoverCardTarget";
|
|
117
125
|
|
|
@@ -119,23 +127,12 @@ HoverCardTarget.displayName = "HoverCardTarget";
|
|
|
119
127
|
// HOVERCARD DROPDOWN
|
|
120
128
|
// ============================================================
|
|
121
129
|
|
|
122
|
-
|
|
123
|
-
export type HoverCardDropdownProps = RecursicaOverStyled<any>;
|
|
130
|
+
export type HoverCardDropdownProps = { children?: React.ReactNode };
|
|
124
131
|
|
|
125
132
|
const HoverCardDropdown = function HoverCardDropdown({
|
|
126
|
-
|
|
127
|
-
...rest
|
|
133
|
+
children,
|
|
128
134
|
}: HoverCardDropdownProps) {
|
|
129
|
-
|
|
130
|
-
const classNameProp = (sanitizedProps as Record<string, unknown>)
|
|
131
|
-
.className as string | undefined;
|
|
132
|
-
|
|
133
|
-
return (
|
|
134
|
-
<div
|
|
135
|
-
className={classNameProp}
|
|
136
|
-
{...(sanitizedProps as unknown as MuiHoverCardDropdownProps)}
|
|
137
|
-
/>
|
|
138
|
-
);
|
|
135
|
+
return <>{children}</>;
|
|
139
136
|
};
|
|
140
137
|
HoverCardDropdown.displayName = "HoverCardDropdown";
|
|
141
138
|
|
|
@@ -62,6 +62,10 @@
|
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
.root :global(.MuiFormLabel-asterisk) {
|
|
66
|
+
display: none !important;
|
|
67
|
+
}
|
|
68
|
+
|
|
65
69
|
/* MUI propagates .Mui-error to the label automatically on FormControl error.
|
|
66
70
|
We explicitly override this bleed to prevent the main label text from turning red,
|
|
67
71
|
while allowing the asterisk to take the error color! */
|
|
@@ -15,19 +15,9 @@ const meta: Meta<LabelStoryProps> = {
|
|
|
15
15
|
docs: {
|
|
16
16
|
description: {
|
|
17
17
|
component:
|
|
18
|
-
"The `Label` component is a strict Recursica-styled wrapper around
|
|
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
19
|
},
|
|
20
20
|
},
|
|
21
|
-
controls: {
|
|
22
|
-
include: [
|
|
23
|
-
"labelSize",
|
|
24
|
-
"labelAlignment",
|
|
25
|
-
"required",
|
|
26
|
-
"labelOptionalText",
|
|
27
|
-
"labelWithEditIcon",
|
|
28
|
-
"children",
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
21
|
},
|
|
32
22
|
argTypes: {
|
|
33
23
|
...formControlArgTypes,
|
|
@@ -39,7 +29,7 @@ export default meta;
|
|
|
39
29
|
type Story = StoryObj<LabelStoryProps>;
|
|
40
30
|
|
|
41
31
|
// Utility mapping to pipe raw Label args structurally into TextField accurately
|
|
42
|
-
const renderWithTextField = ({ children, ...args }:
|
|
32
|
+
const renderWithTextField = ({ children, ...args }: LabelStoryProps) => (
|
|
43
33
|
<TextField
|
|
44
34
|
label={children as React.ReactNode}
|
|
45
35
|
placeholder="Form Control primitive mapped..."
|
|
@@ -50,6 +40,7 @@ const renderWithTextField = ({ children, ...args }: any) => (
|
|
|
50
40
|
export const Default: Story = {
|
|
51
41
|
args: {
|
|
52
42
|
children: "Dynamic Label (Controls)",
|
|
43
|
+
|
|
53
44
|
labelSize: "default",
|
|
54
45
|
labelAlignment: "left",
|
|
55
46
|
required: false,
|
|
@@ -69,6 +60,7 @@ export const StackedDefault: Story = {
|
|
|
69
60
|
export const StackedRequired: Story = {
|
|
70
61
|
args: {
|
|
71
62
|
children: "Primary Network Node",
|
|
63
|
+
|
|
72
64
|
required: true,
|
|
73
65
|
},
|
|
74
66
|
render: renderWithTextField,
|
|
@@ -77,6 +69,7 @@ export const StackedRequired: Story = {
|
|
|
77
69
|
export const StackedWithEditIcon: Story = {
|
|
78
70
|
args: {
|
|
79
71
|
children: "Environment Variables",
|
|
72
|
+
|
|
80
73
|
labelWithEditIcon: true,
|
|
81
74
|
},
|
|
82
75
|
render: renderWithTextField,
|
|
@@ -85,6 +78,7 @@ export const StackedWithEditIcon: Story = {
|
|
|
85
78
|
export const SideBySideDefault: Story = {
|
|
86
79
|
args: {
|
|
87
80
|
children: "Status",
|
|
81
|
+
|
|
88
82
|
labelSize: "default",
|
|
89
83
|
},
|
|
90
84
|
render: renderWithTextField,
|
|
@@ -93,6 +87,7 @@ export const SideBySideDefault: Story = {
|
|
|
93
87
|
export const RequiredSuppressesOptionalText: Story = {
|
|
94
88
|
args: {
|
|
95
89
|
children: "Full Name",
|
|
90
|
+
|
|
96
91
|
required: true,
|
|
97
92
|
labelOptionalText: "This should not render",
|
|
98
93
|
},
|
|
@@ -102,6 +97,7 @@ export const RequiredSuppressesOptionalText: Story = {
|
|
|
102
97
|
export const BooleanOptionalText: Story = {
|
|
103
98
|
args: {
|
|
104
99
|
children: "Middle Initial",
|
|
100
|
+
|
|
105
101
|
labelOptionalText: true,
|
|
106
102
|
},
|
|
107
103
|
render: renderWithTextField,
|
|
@@ -110,6 +106,16 @@ export const BooleanOptionalText: Story = {
|
|
|
110
106
|
export const WithEditIcon: Story = {
|
|
111
107
|
args: {
|
|
112
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
|
+
|
|
113
119
|
labelWithEditIcon: true,
|
|
114
120
|
},
|
|
115
121
|
render: renderWithTextField,
|
|
@@ -3,16 +3,10 @@ import { InputLabel, type InputLabelProps } from "@mui/material";
|
|
|
3
3
|
import { filterStylingProps } from "../../utils/filterStylingProps";
|
|
4
4
|
import styles from "./Label.module.css";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { type RecursicaLabelProps } from "@recursica/adapter-common";
|
|
7
|
+
|
|
8
|
+
export interface LabelProps extends InputLabelProps, RecursicaLabelProps {
|
|
7
9
|
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
10
|
}
|
|
17
11
|
|
|
18
12
|
export const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
|
@@ -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.
|