@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
|
@@ -1,36 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
import React, { forwardRef } from "react";
|
|
1
|
+
import { forwardRef } from "react";
|
|
3
2
|
import {
|
|
4
3
|
Pagination as MuiPagination,
|
|
5
4
|
type PaginationProps as MuiPaginationProps,
|
|
6
|
-
type PaginationRootProps as MuiPaginationRootProps,
|
|
7
5
|
} from "@mui/material";
|
|
8
6
|
import {
|
|
9
7
|
filterStylingProps,
|
|
10
8
|
type RecursicaOverStyled,
|
|
11
9
|
} from "../../utils/filterStylingProps";
|
|
12
10
|
import styles from "./Pagination.module.css";
|
|
13
|
-
import {
|
|
14
|
-
NextWithLabel,
|
|
15
|
-
PrevWithLabel,
|
|
16
|
-
FirstWithLabel,
|
|
17
|
-
LastWithLabel,
|
|
18
|
-
PaginationIcon,
|
|
19
|
-
} from "./Pagination.icons";
|
|
20
|
-
|
|
21
|
-
export type PaginationProps = RecursicaOverStyled<MuiPaginationProps> & {
|
|
22
|
-
/** If set to true, displays text labels alongside the icons for next/previous/first/last edges. */
|
|
23
|
-
withLabels?: boolean;
|
|
24
|
-
};
|
|
25
11
|
|
|
26
|
-
|
|
12
|
+
import { type RecursicaPaginationProps } from "@recursica/adapter-common";
|
|
27
13
|
|
|
28
|
-
export type
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
withLabel?: boolean;
|
|
32
|
-
icon?: any;
|
|
33
|
-
};
|
|
14
|
+
export type PaginationProps = RecursicaOverStyled<
|
|
15
|
+
MuiPaginationProps & RecursicaPaginationProps
|
|
16
|
+
>;
|
|
34
17
|
|
|
35
18
|
function usePaginationClassNames(restRecord: Record<string, unknown>): {
|
|
36
19
|
className: string;
|
|
@@ -38,8 +21,7 @@ function usePaginationClassNames(restRecord: Record<string, unknown>): {
|
|
|
38
21
|
} {
|
|
39
22
|
const mergedClassNames: Partial<Record<string, string>> = {
|
|
40
23
|
root: styles.root,
|
|
41
|
-
|
|
42
|
-
dots: styles.dots,
|
|
24
|
+
ul: styles.ul,
|
|
43
25
|
};
|
|
44
26
|
|
|
45
27
|
const classNamesProp = restRecord.classNames;
|
|
@@ -50,10 +32,7 @@ function usePaginationClassNames(restRecord: Record<string, unknown>): {
|
|
|
50
32
|
) {
|
|
51
33
|
const o = classNamesProp as Partial<Record<string, string>>;
|
|
52
34
|
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
53
|
-
mergedClassNames.
|
|
54
|
-
? `${styles.control} ${o.control}`
|
|
55
|
-
: styles.control;
|
|
56
|
-
mergedClassNames.dots = o.dots ? `${styles.dots} ${o.dots}` : styles.dots;
|
|
35
|
+
mergedClassNames.ul = o.ul ? `${styles.ul} ${o.ul}` : styles.ul;
|
|
57
36
|
}
|
|
58
37
|
|
|
59
38
|
const classNameProp = restRecord.className as string | undefined;
|
|
@@ -64,72 +43,14 @@ function usePaginationClassNames(restRecord: Record<string, unknown>): {
|
|
|
64
43
|
return { className: finalClass, classNames: mergedClassNames };
|
|
65
44
|
}
|
|
66
45
|
|
|
67
|
-
const _PaginationRoot = forwardRef<HTMLDivElement, PaginationRootProps>(
|
|
68
|
-
function PaginationRoot({ overStyled = false, ...rest }, ref) {
|
|
69
|
-
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
70
|
-
const stylingParams = usePaginationClassNames(
|
|
71
|
-
sanitizedProps as Record<string, unknown>,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<div
|
|
76
|
-
ref={ref}
|
|
77
|
-
className={stylingParams.className}
|
|
78
|
-
classes={stylingParams.classNames}
|
|
79
|
-
{...(sanitizedProps as MuiPaginationRootProps)}
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
},
|
|
83
|
-
);
|
|
84
|
-
_PaginationRoot.displayName = "Pagination.Root";
|
|
85
|
-
|
|
86
|
-
const _PaginationNext = forwardRef<
|
|
87
|
-
HTMLButtonElement,
|
|
88
|
-
PaginationEdgeProps<typeof MuiPagination.Next>
|
|
89
|
-
>(function PaginationNext({ withLabel, icon, ...props }, ref) {
|
|
90
|
-
const renderIcon = icon || (withLabel ? NextWithLabel : undefined);
|
|
91
|
-
return (
|
|
92
|
-
<div ref={ref} data-variant="text" icon={renderIcon as any} {...props} />
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
_PaginationNext.displayName = "Pagination.Next";
|
|
96
|
-
|
|
97
|
-
const _PaginationPrevious = forwardRef<
|
|
98
|
-
HTMLButtonElement,
|
|
99
|
-
PaginationEdgeProps<typeof MuiPagination.Previous>
|
|
100
|
-
>(function PaginationPrevious({ withLabel, icon, ...props }, ref) {
|
|
101
|
-
const renderIcon = icon || (withLabel ? PrevWithLabel : undefined);
|
|
102
|
-
return (
|
|
103
|
-
<div ref={ref} data-variant="text" icon={renderIcon as any} {...props} />
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
_PaginationPrevious.displayName = "Pagination.Previous";
|
|
107
|
-
|
|
108
|
-
const _PaginationFirst = forwardRef<
|
|
109
|
-
HTMLButtonElement,
|
|
110
|
-
PaginationEdgeProps<typeof MuiPagination.First>
|
|
111
|
-
>(function PaginationFirst({ withLabel, icon, ...props }, ref) {
|
|
112
|
-
const renderIcon = icon || (withLabel ? FirstWithLabel : undefined);
|
|
113
|
-
return (
|
|
114
|
-
<div ref={ref} data-variant="text" icon={renderIcon as any} {...props} />
|
|
115
|
-
);
|
|
116
|
-
});
|
|
117
|
-
_PaginationFirst.displayName = "Pagination.First";
|
|
118
|
-
|
|
119
|
-
const _PaginationLast = forwardRef<
|
|
120
|
-
HTMLButtonElement,
|
|
121
|
-
PaginationEdgeProps<typeof MuiPagination.Last>
|
|
122
|
-
>(function PaginationLast({ withLabel, icon, ...props }, ref) {
|
|
123
|
-
const renderIcon = icon || (withLabel ? LastWithLabel : undefined);
|
|
124
|
-
return (
|
|
125
|
-
<div ref={ref} data-variant="text" icon={renderIcon as any} {...props} />
|
|
126
|
-
);
|
|
127
|
-
});
|
|
128
|
-
_PaginationLast.displayName = "Pagination.Last";
|
|
129
|
-
|
|
130
46
|
const _Pagination = forwardRef<HTMLDivElement, PaginationProps>(
|
|
131
47
|
function Pagination(
|
|
132
|
-
{
|
|
48
|
+
{
|
|
49
|
+
overStyled = false,
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
+
withLabels,
|
|
52
|
+
...rest
|
|
53
|
+
},
|
|
133
54
|
ref,
|
|
134
55
|
) {
|
|
135
56
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
@@ -137,34 +58,13 @@ const _Pagination = forwardRef<HTMLDivElement, PaginationProps>(
|
|
|
137
58
|
sanitizedProps as Record<string, unknown>,
|
|
138
59
|
);
|
|
139
60
|
|
|
140
|
-
const mergedGetControlProps = (
|
|
141
|
-
control: "first" | "previous" | "last" | "next",
|
|
142
|
-
) => {
|
|
143
|
-
const baseProps = { "data-variant": "text" };
|
|
144
|
-
if (getControlProps) {
|
|
145
|
-
return { ...baseProps, ...getControlProps(control) };
|
|
146
|
-
}
|
|
147
|
-
return baseProps;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const labelsIcons = withLabels
|
|
151
|
-
? {
|
|
152
|
-
nextIcon: NextWithLabel,
|
|
153
|
-
previousIcon: PrevWithLabel,
|
|
154
|
-
firstIcon: FirstWithLabel,
|
|
155
|
-
lastIcon: LastWithLabel,
|
|
156
|
-
}
|
|
157
|
-
: {};
|
|
158
|
-
|
|
159
61
|
return (
|
|
160
|
-
<
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{...(sanitizedProps as MuiPaginationProps)}
|
|
167
|
-
/>
|
|
62
|
+
<div ref={ref} className={stylingParams.className}>
|
|
63
|
+
<MuiPagination
|
|
64
|
+
classes={stylingParams.classNames}
|
|
65
|
+
{...(sanitizedProps as MuiPaginationProps)}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
168
68
|
);
|
|
169
69
|
},
|
|
170
70
|
);
|
|
@@ -173,24 +73,4 @@ _Pagination.displayName = "Pagination";
|
|
|
173
73
|
/**
|
|
174
74
|
* Recursica Pagination component wrapping Mui's Pagination.
|
|
175
75
|
*/
|
|
176
|
-
export const Pagination = _Pagination
|
|
177
|
-
Root: typeof _PaginationRoot;
|
|
178
|
-
Items: typeof MuiPagination.Items;
|
|
179
|
-
Control: typeof MuiPagination.Control;
|
|
180
|
-
Dots: typeof MuiPagination.Dots;
|
|
181
|
-
Next: typeof _PaginationNext;
|
|
182
|
-
Previous: typeof _PaginationPrevious;
|
|
183
|
-
First: typeof _PaginationFirst;
|
|
184
|
-
Last: typeof _PaginationLast;
|
|
185
|
-
Icon: typeof PaginationIcon;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
Pagination.Root = _PaginationRoot;
|
|
189
|
-
Pagination.Items = MuiPagination.Items;
|
|
190
|
-
Pagination.Control = MuiPagination.Control;
|
|
191
|
-
Pagination.Dots = MuiPagination.Dots;
|
|
192
|
-
Pagination.Next = _PaginationNext;
|
|
193
|
-
Pagination.Previous = _PaginationPrevious;
|
|
194
|
-
Pagination.First = _PaginationFirst;
|
|
195
|
-
Pagination.Last = _PaginationLast;
|
|
196
|
-
Pagination.Icon = PaginationIcon;
|
|
76
|
+
export const Pagination = _Pagination;
|
|
@@ -13,14 +13,7 @@ import styles from "./Panel.module.css";
|
|
|
13
13
|
// PANEL (Drawer)
|
|
14
14
|
// ============================================================
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* If true, forces the header text to a single line and truncates with an ellipsis.
|
|
19
|
-
* Note: While the prop is named `wrapHeaderText` for backward compatibility,
|
|
20
|
-
* setting it to `true` actually PREVENTS wrapping (it forces truncation).
|
|
21
|
-
*/
|
|
22
|
-
wrapHeaderText?: boolean;
|
|
23
|
-
}
|
|
16
|
+
import { type RecursicaPanelProps } from "@recursica/adapter-common";
|
|
24
17
|
|
|
25
18
|
/**
|
|
26
19
|
* Recursica Panel root props. Extends Mui Drawer.
|
|
@@ -59,7 +52,10 @@ const PanelBase = function Panel({
|
|
|
59
52
|
keepMounted = true,
|
|
60
53
|
wrapHeaderText = false,
|
|
61
54
|
...rest
|
|
62
|
-
}: PanelProps
|
|
55
|
+
}: PanelProps & {
|
|
56
|
+
position?: "left" | "right" | "top" | "bottom";
|
|
57
|
+
opened?: boolean;
|
|
58
|
+
}) {
|
|
63
59
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
64
60
|
|
|
65
61
|
// Bind CSS module classes to Mui's internal classNames API
|
|
@@ -89,9 +85,9 @@ const PanelBase = function Panel({
|
|
|
89
85
|
|
|
90
86
|
return (
|
|
91
87
|
<MuiDrawer
|
|
92
|
-
|
|
88
|
+
anchor={position} /* Recursica default: right; Mui default: left */
|
|
93
89
|
keepMounted={keepMounted}
|
|
94
|
-
|
|
90
|
+
open={Boolean(rest.opened)}
|
|
95
91
|
{...(sanitizedProps as unknown as MuiDrawerProps)}
|
|
96
92
|
classes={mergedClassNames}
|
|
97
93
|
/>
|
|
@@ -129,28 +125,9 @@ export const PanelFooter = forwardRef<HTMLDivElement, PanelFooterProps>(
|
|
|
129
125
|
PanelFooter.displayName = "PanelFooter";
|
|
130
126
|
|
|
131
127
|
// ============================================================
|
|
132
|
-
// DOT NOTATION EXPORT
|
|
133
|
-
// ============================================================
|
|
134
|
-
|
|
135
128
|
type PanelComponent = typeof PanelBase & {
|
|
136
|
-
Root: typeof MuiDrawer.Root;
|
|
137
|
-
Overlay: typeof MuiDrawer.Overlay;
|
|
138
|
-
Content: typeof MuiDrawer.Content;
|
|
139
|
-
Header: typeof MuiDrawer.Header;
|
|
140
|
-
Title: typeof MuiDrawer.Title;
|
|
141
|
-
CloseButton: typeof MuiDrawer.CloseButton;
|
|
142
|
-
Body: typeof MuiDrawer.Body;
|
|
143
|
-
Stack: typeof MuiDrawer.Stack;
|
|
144
129
|
Footer: typeof PanelFooter;
|
|
145
130
|
};
|
|
146
131
|
|
|
147
132
|
export const Panel = PanelBase as PanelComponent;
|
|
148
|
-
Panel.Root = MuiDrawer.Root;
|
|
149
|
-
Panel.Overlay = MuiDrawer.Overlay;
|
|
150
|
-
Panel.Content = MuiDrawer.Content;
|
|
151
|
-
Panel.Header = MuiDrawer.Header;
|
|
152
|
-
Panel.Title = MuiDrawer.Title;
|
|
153
|
-
Panel.CloseButton = MuiDrawer.CloseButton;
|
|
154
|
-
Panel.Body = MuiDrawer.Body;
|
|
155
|
-
Panel.Stack = MuiDrawer.Stack;
|
|
156
133
|
Panel.Footer = PanelFooter;
|
|
@@ -12,15 +12,13 @@
|
|
|
12
12
|
/* --- GROUP STYLES --- */
|
|
13
13
|
.groupRoot {
|
|
14
14
|
padding: var(
|
|
15
|
-
--recursica_ui-kit_components_radio-button-group_properties_padding
|
|
16
|
-
0
|
|
15
|
+
--recursica_ui-kit_components_radio-button-group_properties_padding
|
|
17
16
|
);
|
|
18
17
|
margin: 0; /* HARDCODE: structural reset; consider token if layout needs change */
|
|
19
18
|
display: flex;
|
|
20
19
|
flex-direction: column;
|
|
21
20
|
gap: var(
|
|
22
|
-
--recursica_ui-kit_components_radio-button-group_properties_item-gap
|
|
23
|
-
16px
|
|
21
|
+
--recursica_ui-kit_components_radio-button-group_properties_item-gap
|
|
24
22
|
);
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -49,10 +47,7 @@
|
|
|
49
47
|
.groupRoot[data-layout="stacked"] {
|
|
50
48
|
flex-direction: column;
|
|
51
49
|
margin-top: var(
|
|
52
|
-
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_label-field-gap
|
|
53
|
-
var(
|
|
54
|
-
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
|
|
55
|
-
)
|
|
50
|
+
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_label-field-gap
|
|
56
51
|
);
|
|
57
52
|
margin-bottom: var(
|
|
58
53
|
--recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
|
|
@@ -214,7 +209,27 @@
|
|
|
214
209
|
--recursica_ui-kit_components_radio-button-item_properties_colors_disabled-text
|
|
215
210
|
);
|
|
216
211
|
opacity: var(
|
|
217
|
-
--recursica_ui-kit_components_radio-button-item_properties_disabled-opacity
|
|
218
|
-
|
|
212
|
+
--recursica_ui-kit_components_radio-button-item_properties_disabled-opacity
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.root .description {
|
|
217
|
+
margin-top: 5px; /* HARDCODE: mantine default */
|
|
218
|
+
color: #868e96; /* HARDCODE: mantine default dimmed */
|
|
219
|
+
font-size: 12px; /* HARDCODE: mantine default xs */
|
|
220
|
+
line-height: 1.2;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.root .error {
|
|
224
|
+
margin-top: 5px; /* HARDCODE: mantine default */
|
|
225
|
+
color: #fa5252; /* HARDCODE: mantine default error */
|
|
226
|
+
font-size: 12px; /* HARDCODE: mantine default xs */
|
|
227
|
+
line-height: 1.2;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.root .description[data-disabled="true"],
|
|
231
|
+
.root .error[data-disabled="true"] {
|
|
232
|
+
opacity: var(
|
|
233
|
+
--recursica_ui-kit_components_radio-button-item_properties_disabled-opacity
|
|
219
234
|
);
|
|
220
235
|
}
|
|
@@ -2,7 +2,6 @@ import { forwardRef } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
Radio as MuiRadio,
|
|
4
4
|
type RadioProps as MuiRadioProps,
|
|
5
|
-
FormControlLabel,
|
|
6
5
|
} from "@mui/material";
|
|
7
6
|
import { type ReadOnlyControlProps } from "@recursica/adapter-common";
|
|
8
7
|
import { RadioGroup } from "./RadioGroup";
|
|
@@ -10,7 +9,10 @@ import {
|
|
|
10
9
|
filterStylingProps,
|
|
11
10
|
type RecursicaOverStyled,
|
|
12
11
|
} from "../../utils/filterStylingProps";
|
|
13
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
type RequireAccessibleLabel,
|
|
14
|
+
type RecursicaRadioProps,
|
|
15
|
+
} from "@recursica/adapter-common";
|
|
14
16
|
import {
|
|
15
17
|
FormControlLayout,
|
|
16
18
|
type FormControlLayoutProps,
|
|
@@ -33,16 +35,18 @@ const RadioIcon: React.FC<{
|
|
|
33
35
|
</svg>
|
|
34
36
|
);
|
|
35
37
|
|
|
36
|
-
export type
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
export type RadioWrapperProps = Omit<MuiRadioProps, "size" | "color"> &
|
|
39
|
+
RecursicaRadioProps &
|
|
40
|
+
ReadOnlyControlProps &
|
|
41
|
+
Pick<
|
|
42
|
+
FormControlLayoutProps,
|
|
43
|
+
"formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
|
|
44
|
+
>;
|
|
45
|
+
|
|
46
|
+
export type RecursicaRadioPropsAlias =
|
|
47
|
+
RequireAccessibleLabel<RadioWrapperProps>;
|
|
44
48
|
|
|
45
|
-
export type RadioProps = RecursicaOverStyled<
|
|
49
|
+
export type RadioProps = RecursicaOverStyled<RecursicaRadioPropsAlias>;
|
|
46
50
|
|
|
47
51
|
type RadioComponent = React.ForwardRefExoticComponent<
|
|
48
52
|
RadioProps & React.RefAttributes<HTMLInputElement>
|
|
@@ -61,6 +65,10 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
|
61
65
|
labelSize,
|
|
62
66
|
controlMaxWidth,
|
|
63
67
|
controlMinWidth,
|
|
68
|
+
label,
|
|
69
|
+
description,
|
|
70
|
+
error,
|
|
71
|
+
style,
|
|
64
72
|
...rest
|
|
65
73
|
} = props;
|
|
66
74
|
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
@@ -139,7 +147,7 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
|
139
147
|
// We omit Mui's sizing/coloring so we rely strictly on variables from Radio.module.css
|
|
140
148
|
const radioNode = (
|
|
141
149
|
<MuiRadio
|
|
142
|
-
ref={ref}
|
|
150
|
+
ref={ref as any}
|
|
143
151
|
icon={<RadioIcon />}
|
|
144
152
|
checkedIcon={<RadioIcon className={styles.checked} />}
|
|
145
153
|
className={finalClass}
|
|
@@ -149,13 +157,37 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
|
|
|
149
157
|
/>
|
|
150
158
|
);
|
|
151
159
|
|
|
152
|
-
const finalNode =
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
const finalNode = label ? (
|
|
161
|
+
<div className={finalClass} style={style as React.CSSProperties}>
|
|
162
|
+
<div className={styles.body}>
|
|
163
|
+
{radioNode}
|
|
164
|
+
<div className={styles.labelWrapper}>
|
|
165
|
+
<label
|
|
166
|
+
className={styles.label}
|
|
167
|
+
htmlFor={restRecord.id as string}
|
|
168
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
169
|
+
>
|
|
170
|
+
{label as React.ReactNode}
|
|
171
|
+
</label>
|
|
172
|
+
{description && (
|
|
173
|
+
<div
|
|
174
|
+
className={styles.description}
|
|
175
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
176
|
+
>
|
|
177
|
+
{description}
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
{error && (
|
|
181
|
+
<div
|
|
182
|
+
className={styles.error}
|
|
183
|
+
data-disabled={readOnly || disabled ? true : undefined}
|
|
184
|
+
>
|
|
185
|
+
{error}
|
|
186
|
+
</div>
|
|
187
|
+
)}
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
159
191
|
) : (
|
|
160
192
|
radioNode
|
|
161
193
|
);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Radio } from "./Radio";
|
|
3
|
+
import { RadioGroup } from "./RadioGroup";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof RadioGroup> = {
|
|
8
|
+
title: "UI-Kit/RadioGroup",
|
|
9
|
+
component: RadioGroup,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component: `
|
|
15
|
+
The \`RadioGroup\` component is the mandatory organizational wrapper aggregating multiple \`Radio\` primitives into structurally bound unified selection arrays. It inherently leverages the \`FormControlWrapper\` granting native access to macroscopic layout structuring, assistive descriptions, and strict flex arrays.
|
|
16
|
+
|
|
17
|
+
We exclusively utilize the \`formLayout\` parameter to control macro-level form flow:
|
|
18
|
+
- **\`formLayout="stacked"\`**: Top-to-bottom layout cascading the Label bounding box down vertically into a standard stacked radio column array.
|
|
19
|
+
- **\`formLayout="side-by-side"\`**: Flow architecture pulling the grouping Label dynamically to the left while structurally organizing the internal radios cleanly alongside it horizontally.
|
|
20
|
+
`,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
argTypes: {
|
|
25
|
+
...formControlArgTypes,
|
|
26
|
+
readOnly: {
|
|
27
|
+
control: "boolean",
|
|
28
|
+
description:
|
|
29
|
+
"Toggles structural read-only data presentation bypassing interaction boundaries completely.",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj<typeof RadioGroup>;
|
|
37
|
+
|
|
38
|
+
export const Default: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
formLayout: "stacked",
|
|
41
|
+
label: "Standard Group",
|
|
42
|
+
},
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
44
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
45
|
+
const [value, setValue] = useState<string>("");
|
|
46
|
+
return (
|
|
47
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
48
|
+
<Radio value="1" label="Option 1" />
|
|
49
|
+
<Radio value="2" label="Option 2" />
|
|
50
|
+
</RadioGroup>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const StackedLayout: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
formLayout: "stacked",
|
|
58
|
+
required: true,
|
|
59
|
+
label: "Hosting Provider",
|
|
60
|
+
error: "You must select a deployment provider.",
|
|
61
|
+
},
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
63
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
64
|
+
const [value, setValue] = useState<string>("aws");
|
|
65
|
+
return (
|
|
66
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
67
|
+
<Radio value="aws" label="Amazon Web Services" />
|
|
68
|
+
<Radio
|
|
69
|
+
value="gcp"
|
|
70
|
+
label="Google Cloud Platform (with completely distributed edge computing environments bridging local runtime boundaries seamlessly.)"
|
|
71
|
+
/>
|
|
72
|
+
<Radio value="azure" label="Microsoft Azure" />
|
|
73
|
+
</RadioGroup>
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const SideBySideLayout: Story = {
|
|
79
|
+
args: {
|
|
80
|
+
formLayout: "side-by-side",
|
|
81
|
+
labelOptionalText: "Recommended",
|
|
82
|
+
labelWithEditIcon: true,
|
|
83
|
+
label: "Deployment Region",
|
|
84
|
+
assistiveText: "Select the data center closest to your user base.",
|
|
85
|
+
},
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
87
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
88
|
+
const [value, setValue] = useState<string>("us-east");
|
|
89
|
+
return (
|
|
90
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
91
|
+
<Radio value="us-east" label="US East (N. Virginia)" />
|
|
92
|
+
<Radio value="us-west" label="US West (Oregon)" />
|
|
93
|
+
<Radio value="eu-central" label="EU Central (Frankfurt)" />
|
|
94
|
+
</RadioGroup>
|
|
95
|
+
);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const ReadOnly: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
readOnly: true,
|
|
102
|
+
formLayout: "stacked",
|
|
103
|
+
required: true,
|
|
104
|
+
label: "Selected Framework",
|
|
105
|
+
assistiveText: "This selection cannot be changed after initialization.",
|
|
106
|
+
},
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
|
108
|
+
render: function StoryRender({ withLayer, layer, ...args }: any) {
|
|
109
|
+
const [value, setValue] = useState<string>("react");
|
|
110
|
+
return (
|
|
111
|
+
<RadioGroup {...args} value={value} onChange={setValue}>
|
|
112
|
+
<Radio value="react" label="React" />
|
|
113
|
+
<Radio value="vue" label="Vue" />
|
|
114
|
+
</RadioGroup>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
import React, { forwardRef } from "react";
|
|
3
2
|
import {
|
|
4
|
-
Radio
|
|
3
|
+
// Removed unused Radio import
|
|
5
4
|
RadioGroup as MuiRadioGroup,
|
|
6
5
|
type RadioGroupProps as MuiRadioGroupProps,
|
|
7
6
|
} from "@mui/material";
|
|
@@ -14,13 +13,29 @@ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/For
|
|
|
14
13
|
import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
|
|
15
14
|
import styles from "./Radio.module.css";
|
|
16
15
|
|
|
16
|
+
import { type RecursicaRadioGroupProps as BaseRecursicaRadioGroupProps } from "@recursica/adapter-common";
|
|
17
|
+
|
|
17
18
|
export interface RecursicaRadioGroupProps
|
|
18
|
-
extends Omit<
|
|
19
|
+
extends Omit<
|
|
20
|
+
MuiRadioGroupProps,
|
|
21
|
+
| "size"
|
|
22
|
+
| "labelProps"
|
|
23
|
+
| "classes"
|
|
24
|
+
| "ref"
|
|
25
|
+
| "onChange"
|
|
26
|
+
| "value"
|
|
27
|
+
| "defaultValue"
|
|
28
|
+
>,
|
|
19
29
|
Omit<
|
|
20
30
|
RecursicaFormControlWrapperProps,
|
|
21
|
-
|
|
31
|
+
| "controlMaxWidth"
|
|
32
|
+
| "controlMinWidth"
|
|
33
|
+
| "classes"
|
|
34
|
+
| "onChange"
|
|
35
|
+
| keyof MuiRadioGroupProps
|
|
22
36
|
>,
|
|
23
|
-
ReadOnlyControlProps
|
|
37
|
+
ReadOnlyControlProps,
|
|
38
|
+
BaseRecursicaRadioGroupProps {}
|
|
24
39
|
|
|
25
40
|
export type RadioGroupProps = RecursicaOverStyled<RecursicaRadioGroupProps>;
|
|
26
41
|
|
|
@@ -43,8 +58,9 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
|
43
58
|
assistiveText,
|
|
44
59
|
assistiveWithIcon,
|
|
45
60
|
error,
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
62
|
required,
|
|
47
|
-
withAsterisk
|
|
63
|
+
// Removed withAsterisk as it is not supported natively in this interface
|
|
48
64
|
id,
|
|
49
65
|
className,
|
|
50
66
|
style,
|
|
@@ -69,7 +85,7 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
|
69
85
|
controlMaxWidth="var(--recursica_ui-kit_components_radio-button-item_properties_max-width)"
|
|
70
86
|
controlMinWidth={undefined}
|
|
71
87
|
overStyled={overStyled as true}
|
|
72
|
-
|
|
88
|
+
// Strictly override. ARIA grouping prohibits interactive radios nested natively inside <label>.
|
|
73
89
|
formLayout={formLayout}
|
|
74
90
|
labelSize={labelSize}
|
|
75
91
|
labelAlignment={labelAlignment}
|
|
@@ -81,8 +97,6 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
|
81
97
|
assistiveText={assistiveText}
|
|
82
98
|
assistiveWithIcon={assistiveWithIcon}
|
|
83
99
|
error={error}
|
|
84
|
-
required={required}
|
|
85
|
-
withAsterisk={withAsterisk}
|
|
86
100
|
id={id}
|
|
87
101
|
readOnly={readOnly && !!readOnlyComponent}
|
|
88
102
|
readOnlyComponent={readOnlyComponent}
|
|
@@ -97,10 +111,10 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
|
|
97
111
|
{...(sanitizedProps as unknown as MuiRadioGroupProps)}
|
|
98
112
|
value={value}
|
|
99
113
|
defaultValue={defaultValue}
|
|
114
|
+
className={styles.groupRoot}
|
|
115
|
+
data-layout={formLayout}
|
|
100
116
|
>
|
|
101
|
-
|
|
102
|
-
{children}
|
|
103
|
-
</div>
|
|
117
|
+
{children}
|
|
104
118
|
</MuiRadioGroup>
|
|
105
119
|
}
|
|
106
120
|
/>
|
|
@@ -3,21 +3,22 @@
|
|
|
3
3
|
.root {
|
|
4
4
|
width: 100%;
|
|
5
5
|
--form-control-margin-bottom: var(
|
|
6
|
-
--recursica_ui-kit_components_read-only-field_variants_layouts_stacked_properties_top-bottom-margin
|
|
7
|
-
0px
|
|
6
|
+
--recursica_ui-kit_components_read-only-field_variants_layouts_stacked_properties_top-bottom-margin
|
|
8
7
|
);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
.root[data-form-layout="side-by-side"] {
|
|
12
11
|
--form-control-margin-bottom: var(
|
|
13
|
-
--recursica_ui-kit_components_read-only-field_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
14
|
-
0px
|
|
12
|
+
--recursica_ui-kit_components_read-only-field_variants_layouts_side-by-side_properties_top-bottom-margin
|
|
15
13
|
);
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
.text {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
19
|
display: flex;
|
|
20
20
|
align-items: center;
|
|
21
|
+
word-break: break-word;
|
|
21
22
|
|
|
22
23
|
font-family: var(
|
|
23
24
|
--recursica_ui-kit_components_read-only-field_properties_text_font-family
|
|
@@ -48,7 +49,6 @@
|
|
|
48
49
|
);
|
|
49
50
|
|
|
50
51
|
min-height: var(
|
|
51
|
-
--recursica_ui-kit_components_read-only-field_properties_min-height
|
|
52
|
-
40px
|
|
52
|
+
--recursica_ui-kit_components_read-only-field_properties_min-height
|
|
53
53
|
);
|
|
54
54
|
}
|