@recursica/mui-adapter 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +15 -0
- package/CHANGELOG.md +15 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +74 -1
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +6863 -205
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +43 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
- package/dist/src/components/Avatar/Avatar.d.ts +10 -3
- package/dist/src/components/Badge/Badge.d.ts +10 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +38 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +9 -2
- package/dist/src/components/Container/Container.d.ts +1 -5
- package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
- package/dist/src/components/Label/Label.d.ts +6 -2
- package/dist/src/components/Link/Link.d.ts +2 -6
- package/dist/src/components/Loader/Loader.d.ts +2 -7
- package/dist/src/components/Menu/Menu.d.ts +25 -3
- package/dist/src/components/Modal/Modal.d.ts +37 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
- package/dist/src/components/Pagination/Pagination.d.ts +12 -3
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +52 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
- package/dist/src/components/Slider/Slider.d.ts +18 -2
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +41 -2
- package/dist/src/components/Switch/Switch.d.ts +10 -3
- package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +20 -3
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +12 -2
- package/dist/src/components/TextField/TextField.d.ts +12 -2
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +15 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +20 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
- package/dist/src/components/TransferList/TransferList.d.ts +2 -1
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
- package/dist/src/utils/filterStylingProps.d.ts +1 -11
- package/llms.txt +16 -0
- package/package.json +14 -3
- package/src/components/Accordion/Accordion.module.css +294 -56
- package/src/components/Accordion/Accordion.stories.tsx +131 -21
- package/src/components/Accordion/Accordion.tsx +260 -5
- package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
- package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
- package/src/components/Autocomplete/Autocomplete.module.css +319 -42
- package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
- package/src/components/Autocomplete/Autocomplete.tsx +181 -6
- package/src/components/Avatar/Avatar.module.css +343 -73
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +99 -6
- package/src/components/Badge/Badge.module.css +127 -29
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +67 -6
- package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
- package/src/components/Button/Button.module.css +19 -61
- package/src/components/Button/Button.stories.tsx +24 -23
- package/src/components/Button/Button.tsx +7 -18
- package/src/components/Card/Card.module.css +154 -38
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +181 -5
- package/src/components/Checkbox/Checkbox.module.css +249 -39
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +246 -5
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +246 -43
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +136 -6
- package/src/components/Container/Container.stories.tsx +103 -20
- package/src/components/Container/Container.tsx +1 -13
- package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
- package/src/components/DatePicker/DatePicker.tsx +3 -1
- package/src/components/Dropdown/Dropdown.module.css +291 -41
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +180 -6
- package/src/components/FileInput/FileInput.stories.tsx +2 -19
- package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
- package/src/components/Flex/Flex.stories.tsx +113 -20
- package/src/components/Flex/Flex.tsx +16 -26
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
- package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.module.css +90 -22
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +147 -5
- package/src/components/Label/Label.module.css +140 -35
- package/src/components/Label/Label.stories.tsx +108 -21
- package/src/components/Label/Label.tsx +82 -5
- package/src/components/Link/Link.module.css +4 -3
- package/src/components/Link/Link.stories.tsx +2 -8
- package/src/components/Link/Link.tsx +1 -5
- package/src/components/Loader/Loader.module.css +1 -2
- package/src/components/Loader/Loader.tsx +1 -7
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Menu/Menu.module.css +285 -51
- package/src/components/Menu/Menu.stories.tsx +229 -25
- package/src/components/Menu/Menu.tsx +73 -6
- package/src/components/Modal/Modal.module.css +171 -35
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +215 -5
- package/src/components/NumberInput/NumberInput.module.css +276 -42
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +136 -6
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +234 -20
- package/src/components/Pagination/Pagination.stories.tsx +34 -21
- package/src/components/Pagination/Pagination.tsx +74 -6
- package/src/components/Panel/Panel.module.css +206 -38
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +130 -5
- package/src/components/Radio/Radio.module.css +235 -37
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +210 -5
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +125 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +1 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
- package/src/components/Slider/Slider.module.css +539 -86
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +283 -5
- package/src/components/Stack/Stack.stories.tsx +4 -25
- package/src/components/Stack/Stack.tsx +1 -5
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stepper/Stepper.module.css +410 -71
- package/src/components/Stepper/Stepper.stories.tsx +146 -20
- package/src/components/Stepper/Stepper.tsx +147 -6
- package/src/components/Switch/Switch.module.css +259 -39
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +200 -6
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +120 -0
- package/src/components/Table/Table.stories.tsx +1 -19
- package/src/components/Table/Table.tsx +3 -1
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Tabs/Tabs.module.css +422 -79
- package/src/components/Tabs/Tabs.stories.tsx +156 -20
- package/src/components/Tabs/Tabs.tsx +86 -6
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.module.css +155 -32
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +146 -6
- package/src/components/TextField/TextField.module.css +261 -42
- package/src/components/TextField/TextField.stories.tsx +147 -20
- package/src/components/TextField/TextField.tsx +169 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.module.css +365 -76
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +83 -5
- package/src/components/Timeline/TimelineItem.tsx +90 -0
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.module.css +166 -28
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +124 -5
- package/src/components/Tooltip/Tooltip.module.css +89 -24
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +88 -5
- package/src/components/TransferList/TransferList.stories.tsx +1 -19
- package/src/components/TransferList/TransferList.tsx +3 -1
- package/src/utils/RequireAccessibleLabel.ts +1 -12
- package/src/utils/filterStylingProps.ts +7 -20
|
@@ -1,8 +1,127 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
Alert as MuiAlert,
|
|
4
|
+
AlertTitle as MuiAlertTitle,
|
|
5
|
+
IconButton as MuiIconButton,
|
|
6
|
+
type AlertProps as MuiAlertProps,
|
|
7
|
+
} from "@mui/material";
|
|
8
|
+
import {
|
|
9
|
+
filterStylingProps,
|
|
10
|
+
type RecursicaOverStyled,
|
|
11
|
+
} from "../../utils/filterStylingProps";
|
|
12
|
+
import styles from "./Toast.module.css";
|
|
3
13
|
|
|
4
|
-
|
|
14
|
+
import { type RecursicaToastProps as BaseRecursicaToastProps } from "@recursica/adapter-common";
|
|
5
15
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
export interface RecursicaToastProps extends BaseRecursicaToastProps {
|
|
17
|
+
withCloseButton?: boolean;
|
|
18
|
+
title?: React.ReactNode;
|
|
19
|
+
icon?: React.ReactNode;
|
|
20
|
+
onClose?: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Toast component wrapping Mui's Alert.
|
|
25
|
+
*
|
|
26
|
+
* Can be used as a standalone visual component to display a notification or message.
|
|
27
|
+
*/
|
|
28
|
+
export type ToastProps = RecursicaOverStyled<
|
|
29
|
+
Omit<MuiAlertProps, "color" | "radius" | "variant" | "onClose"> &
|
|
30
|
+
RecursicaToastProps
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
const CloseIcon = () => (
|
|
34
|
+
<svg
|
|
35
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
36
|
+
width="20"
|
|
37
|
+
height="20"
|
|
38
|
+
viewBox="0 0 24 24"
|
|
39
|
+
fill="none"
|
|
40
|
+
stroke="currentColor"
|
|
41
|
+
strokeWidth="2"
|
|
42
|
+
strokeLinecap="round"
|
|
43
|
+
strokeLinejoin="round"
|
|
44
|
+
>
|
|
45
|
+
<path d="M18 6L6 18M6 6l12 12" />
|
|
46
|
+
</svg>
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
|
|
50
|
+
function Toast(
|
|
51
|
+
{
|
|
52
|
+
overStyled = false,
|
|
53
|
+
variant = "default",
|
|
54
|
+
withCloseButton = true,
|
|
55
|
+
title,
|
|
56
|
+
icon,
|
|
57
|
+
children,
|
|
58
|
+
onClose,
|
|
59
|
+
className,
|
|
60
|
+
...rest
|
|
61
|
+
},
|
|
62
|
+
ref,
|
|
63
|
+
) {
|
|
64
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
65
|
+
|
|
66
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
67
|
+
root: styles.root,
|
|
68
|
+
message: styles.body,
|
|
69
|
+
icon: styles.icon,
|
|
70
|
+
action: styles.closeButton,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const classNamesProp = (sanitizedProps as Record<string, unknown>)
|
|
74
|
+
.classNames;
|
|
75
|
+
if (
|
|
76
|
+
classNamesProp &&
|
|
77
|
+
typeof classNamesProp === "object" &&
|
|
78
|
+
!Array.isArray(classNamesProp)
|
|
79
|
+
) {
|
|
80
|
+
const o = classNamesProp as Record<string, string>;
|
|
81
|
+
Object.keys(o).forEach((key) => {
|
|
82
|
+
if (mergedClassNames[key]) {
|
|
83
|
+
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
84
|
+
} else {
|
|
85
|
+
mergedClassNames[key] = o[key];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const handleClose = () => {
|
|
91
|
+
if (onClose) onClose();
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<MuiAlert
|
|
96
|
+
ref={ref}
|
|
97
|
+
icon={icon}
|
|
98
|
+
data-variant={variant}
|
|
99
|
+
className={`${className || ""}`}
|
|
100
|
+
classes={mergedClassNames}
|
|
101
|
+
action={
|
|
102
|
+
withCloseButton ? (
|
|
103
|
+
<MuiIconButton
|
|
104
|
+
size="small"
|
|
105
|
+
aria-label="close"
|
|
106
|
+
color="inherit"
|
|
107
|
+
onClick={handleClose}
|
|
108
|
+
>
|
|
109
|
+
<CloseIcon />
|
|
110
|
+
</MuiIconButton>
|
|
111
|
+
) : undefined
|
|
112
|
+
}
|
|
113
|
+
{...(sanitizedProps as unknown as Omit<
|
|
114
|
+
MuiAlertProps,
|
|
115
|
+
"color" | "radius" | "variant" | "onClose"
|
|
116
|
+
>)}
|
|
117
|
+
>
|
|
118
|
+
{title && (
|
|
119
|
+
<MuiAlertTitle className={styles.title}>{title}</MuiAlertTitle>
|
|
120
|
+
)}
|
|
121
|
+
<div className={styles.description}>{children}</div>
|
|
122
|
+
</MuiAlert>
|
|
123
|
+
);
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
Toast.displayName = "Toast";
|
|
@@ -1,25 +1,90 @@
|
|
|
1
1
|
/* EXEMPTIONS:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/* recursica-ignore: --recursica_ui-
|
|
8
|
-
/* recursica-ignore: --recursica_ui-
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
- beak-inset is ignored because Tooltip positioning calculations are handled dynamically by Mantine/Floating UI at the React runtime.
|
|
3
|
+
- beak-size is ignored because Mantine's tooltip arrows compute their sizing and positional offsets
|
|
4
|
+
dynamically within the React rendering engine (requires inline pixel number rather than standard CSS variables).
|
|
5
|
+
The beak size is checked in JS against a fixed value of 16px. If this variable changes, the TSX components
|
|
6
|
+
need to be reviewed/re-compiled. */
|
|
7
|
+
/* recursica-ignore: --recursica_ui-kit_components_tooltip_properties_beak-inset = 8px */
|
|
8
|
+
/* recursica-ignore: --recursica_ui-kit_components_tooltip_properties_beak-size = 16px */
|
|
9
|
+
|
|
10
|
+
/* HARDCODED VALUES:
|
|
11
|
+
- border-style: solid. Structural rendering rule for the tooltip border (Mantine uses Box
|
|
12
|
+
which may not set border-style natively). Same pattern as Menu / HoverCard.
|
|
13
|
+
- arrowSize defaults to 16 in Tooltip.tsx. Mantine uses arrowSize for inline width/height
|
|
14
|
+
and positioning (-arrowSize/2) calculations that cannot be CSS-driven. The default matches
|
|
15
|
+
the Recursica beak-size token (16px). See COMPONENT_ISSUES.md for details.
|
|
16
|
+
- All structural layout (display, position, overflow) is deferred to Mantine's native
|
|
17
|
+
behavior. We only override visual design tokens (colors, typography, spacing, borders).
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/* ======================================
|
|
21
|
+
TOOLTIP CONTAINER
|
|
22
|
+
====================================== */
|
|
23
|
+
|
|
24
|
+
.tooltip {
|
|
25
|
+
background-color: var(
|
|
26
|
+
--recursica_ui-kit_components_tooltip_properties_colors_background
|
|
27
|
+
);
|
|
28
|
+
border-style: solid; /* HARDCODE: Mantine Box does not set border-style natively */
|
|
29
|
+
border-width: var(
|
|
30
|
+
--recursica_ui-kit_components_tooltip_properties_border-size
|
|
31
|
+
);
|
|
32
|
+
border-color: var(
|
|
33
|
+
--recursica_ui-kit_components_tooltip_properties_colors_border-color
|
|
34
|
+
);
|
|
35
|
+
border-radius: var(
|
|
36
|
+
--recursica_ui-kit_components_tooltip_properties_border-radius
|
|
37
|
+
);
|
|
38
|
+
box-shadow: var(--recursica_ui-kit_components_tooltip_properties_elevation);
|
|
39
|
+
|
|
40
|
+
min-width: var(--recursica_ui-kit_components_tooltip_properties_min-width);
|
|
41
|
+
min-height: var(--recursica_ui-kit_components_tooltip_properties_min-height);
|
|
42
|
+
max-width: var(--recursica_ui-kit_components_tooltip_properties_max-width);
|
|
43
|
+
|
|
44
|
+
padding: var(
|
|
45
|
+
--recursica_ui-kit_components_tooltip_properties_vertical-padding
|
|
46
|
+
)
|
|
47
|
+
var(--recursica_ui-kit_components_tooltip_properties_horizontal-padding);
|
|
48
|
+
|
|
49
|
+
/* Vertically center text within min-height container */
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
|
|
53
|
+
/* Typography */
|
|
54
|
+
font-family: var(
|
|
55
|
+
--recursica_ui-kit_components_tooltip_properties_text_font-family
|
|
56
|
+
);
|
|
57
|
+
font-size: var(
|
|
58
|
+
--recursica_ui-kit_components_tooltip_properties_text_font-size
|
|
59
|
+
);
|
|
60
|
+
font-style: var(
|
|
61
|
+
--recursica_ui-kit_components_tooltip_properties_text_font-style
|
|
62
|
+
);
|
|
63
|
+
font-weight: var(
|
|
64
|
+
--recursica_ui-kit_components_tooltip_properties_text_font-weight
|
|
65
|
+
);
|
|
66
|
+
letter-spacing: var(
|
|
67
|
+
--recursica_ui-kit_components_tooltip_properties_text_letter-spacing
|
|
68
|
+
);
|
|
69
|
+
line-height: var(
|
|
70
|
+
--recursica_ui-kit_components_tooltip_properties_text_line-height
|
|
71
|
+
);
|
|
72
|
+
text-decoration: var(
|
|
73
|
+
--recursica_ui-kit_components_tooltip_properties_text_text-decoration
|
|
74
|
+
);
|
|
75
|
+
text-transform: var(
|
|
76
|
+
--recursica_ui-kit_components_tooltip_properties_text_text-transform
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
color: var(--recursica_ui-kit_components_tooltip_properties_colors_text);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ======================================
|
|
83
|
+
ARROW / BEAK
|
|
84
|
+
====================================== */
|
|
85
|
+
|
|
86
|
+
.arrow {
|
|
87
|
+
border-color: var(
|
|
88
|
+
--recursica_ui-kit_components_tooltip_properties_colors_border-color
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -1,35 +1,165 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { Tooltip } from "./Tooltip";
|
|
3
|
-
import {
|
|
2
|
+
import { Tooltip, type TooltipProps } from "./Tooltip";
|
|
3
|
+
import { Button } from "../Button";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Tooltip story axes:
|
|
7
|
+
* - position: tooltip alignment relative to target
|
|
8
|
+
* - withBeak: beak (arrow) indicator on the tooltip
|
|
9
|
+
* - openDelay / closeDelay: hover timing controls
|
|
10
|
+
* - multiline: text wrapping behavior
|
|
11
|
+
* - disabled: suppress the tooltip entirely
|
|
12
|
+
* - layer: tested via the global Layer decorator (withLayer/layer args)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
type TooltipStoryArgs = Record<string, any>;
|
|
17
|
+
|
|
18
|
+
const meta: Meta = {
|
|
19
|
+
title: "UI-Kit/Tooltip",
|
|
7
20
|
component: Tooltip,
|
|
8
21
|
tags: ["autodocs"],
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
22
|
+
argTypes: {
|
|
23
|
+
label: {
|
|
24
|
+
control: "text",
|
|
25
|
+
description: "Content displayed inside the tooltip.",
|
|
26
|
+
},
|
|
27
|
+
position: {
|
|
28
|
+
control: "select",
|
|
29
|
+
options: [
|
|
30
|
+
"bottom",
|
|
31
|
+
"bottom-start",
|
|
32
|
+
"bottom-end",
|
|
33
|
+
"top",
|
|
34
|
+
"top-start",
|
|
35
|
+
"top-end",
|
|
36
|
+
"left",
|
|
37
|
+
"left-start",
|
|
38
|
+
"left-end",
|
|
39
|
+
"right",
|
|
40
|
+
"right-start",
|
|
41
|
+
"right-end",
|
|
25
42
|
],
|
|
43
|
+
description: "The position of the tooltip relative to the target.",
|
|
44
|
+
},
|
|
45
|
+
withBeak: {
|
|
46
|
+
control: "boolean",
|
|
47
|
+
description:
|
|
48
|
+
"Whether to display a beak (arrow) pointing to the target. Recursica equivalent of Mantine's withArrow.",
|
|
49
|
+
},
|
|
50
|
+
offset: {
|
|
51
|
+
control: "number",
|
|
52
|
+
description: "Distance in px between the tooltip and the target element.",
|
|
53
|
+
},
|
|
54
|
+
openDelay: {
|
|
55
|
+
control: "number",
|
|
56
|
+
description: "Delay in ms before the tooltip opens on hover.",
|
|
57
|
+
},
|
|
58
|
+
closeDelay: {
|
|
59
|
+
control: "number",
|
|
60
|
+
description: "Delay in ms before the tooltip closes when hover ends.",
|
|
61
|
+
},
|
|
62
|
+
disabled: {
|
|
63
|
+
control: "boolean",
|
|
64
|
+
description: "If set, the tooltip will not be rendered.",
|
|
65
|
+
},
|
|
66
|
+
opened: {
|
|
67
|
+
control: "boolean",
|
|
68
|
+
description:
|
|
69
|
+
"Force the tooltip to stay open. Useful for inspecting styling.",
|
|
70
|
+
},
|
|
71
|
+
// Hide auto-detected HTML attributes that leak from ElementProps<'div'>
|
|
72
|
+
defaultChecked: { table: { disable: true } },
|
|
73
|
+
defaultValue: { table: { disable: true } },
|
|
74
|
+
suppressContentEditableWarning: { table: { disable: true } },
|
|
75
|
+
suppressHydrationWarning: { table: { disable: true } },
|
|
76
|
+
},
|
|
77
|
+
parameters: {
|
|
78
|
+
layout: "centered",
|
|
79
|
+
docs: {
|
|
80
|
+
description: {
|
|
81
|
+
component: `
|
|
82
|
+
The \`Tooltip\` component displays a floating label when the user hovers over or focuses a target element. It wraps Mantine's \`Tooltip\` while enforcing strict Recursica design token styling.
|
|
83
|
+
|
|
84
|
+
### API
|
|
85
|
+
|
|
86
|
+
Unlike \`HoverCard\`, Tooltip is a single component — content is passed via the \`label\` prop:
|
|
87
|
+
\`\`\`tsx
|
|
88
|
+
<Tooltip label="Helpful text" withBeak>
|
|
89
|
+
<Button>Hover me</Button>
|
|
90
|
+
</Tooltip>
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
### Static Sub-Components
|
|
94
|
+
- \`Tooltip.Floating\` — A tooltip that follows the cursor position
|
|
95
|
+
- \`Tooltip.Group\` — Groups multiple tooltips to share hover delay
|
|
96
|
+
|
|
97
|
+
### Key Behaviors
|
|
98
|
+
- The beak (arrow) is shown by default (\`withBeak={true}\`)
|
|
99
|
+
- Supports \`openDelay\` and \`closeDelay\` for timing control
|
|
100
|
+
- Set \`multiline\` to allow text wrapping within max-width
|
|
101
|
+
`,
|
|
102
|
+
},
|
|
26
103
|
},
|
|
27
104
|
},
|
|
28
105
|
};
|
|
29
106
|
|
|
30
107
|
export default meta;
|
|
31
|
-
|
|
108
|
+
|
|
109
|
+
type Story = StoryObj<TooltipStoryArgs>;
|
|
32
110
|
|
|
33
111
|
export const Default: Story = {
|
|
34
|
-
|
|
112
|
+
args: {
|
|
113
|
+
label: "This is a helpful tooltip",
|
|
114
|
+
position: "top",
|
|
115
|
+
withBeak: true,
|
|
116
|
+
offset: 5,
|
|
117
|
+
openDelay: 0,
|
|
118
|
+
closeDelay: 0,
|
|
119
|
+
disabled: false,
|
|
120
|
+
},
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
122
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
123
|
+
return (
|
|
124
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
125
|
+
<Button variant="solid">Hover me</Button>
|
|
126
|
+
</Tooltip>
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const WithoutBeak: Story = {
|
|
132
|
+
args: {
|
|
133
|
+
label: "Tooltip without a beak indicator",
|
|
134
|
+
position: "top",
|
|
135
|
+
withBeak: false,
|
|
136
|
+
offset: 5,
|
|
137
|
+
},
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
139
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
140
|
+
return (
|
|
141
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
142
|
+
<Button variant="outline">Without Beak</Button>
|
|
143
|
+
</Tooltip>
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const LongContent: Story = {
|
|
149
|
+
args: {
|
|
150
|
+
label:
|
|
151
|
+
"This is a longer tooltip message that demonstrates how text wraps within the maximum width defined by the design system.",
|
|
152
|
+
position: "top",
|
|
153
|
+
withBeak: true,
|
|
154
|
+
opened: true,
|
|
155
|
+
offset: 5,
|
|
156
|
+
},
|
|
157
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
|
+
render: ({ withLayer, layer, ...args }: TooltipStoryArgs) => {
|
|
159
|
+
return (
|
|
160
|
+
<Tooltip {...(args as TooltipProps)}>
|
|
161
|
+
<Button variant="solid">Long Content</Button>
|
|
162
|
+
</Tooltip>
|
|
163
|
+
);
|
|
164
|
+
},
|
|
35
165
|
};
|
|
@@ -1,8 +1,91 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Tooltip as MuiTooltip,
|
|
3
|
+
type TooltipProps as MuiTooltipProps,
|
|
4
|
+
} from "@mui/material";
|
|
5
|
+
import {
|
|
6
|
+
filterStylingProps,
|
|
7
|
+
type RecursicaOverStyled,
|
|
8
|
+
} from "../../utils/filterStylingProps";
|
|
9
|
+
import styles from "./Tooltip.module.css";
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
// ============================================================
|
|
12
|
+
// TOOLTIP
|
|
13
|
+
// ============================================================
|
|
5
14
|
|
|
6
|
-
|
|
7
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Recursica-specific props for Tooltip.
|
|
17
|
+
*/
|
|
18
|
+
import { type RecursicaTooltipProps } from "@recursica/adapter-common";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Recursica Tooltip component wrapping Mui's Tooltip.
|
|
22
|
+
*
|
|
23
|
+
* Displays a floating label when the user hovers over or focuses a target element.
|
|
24
|
+
* Unlike HoverCard, Tooltip is a single component (not composable) — content is
|
|
25
|
+
* passed via the `label` prop, and the trigger is passed as `children`.
|
|
26
|
+
*
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <Tooltip label="Helpful information" withBeak>
|
|
29
|
+
* <Button>Hover me</Button>
|
|
30
|
+
* </Tooltip>
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Static sub-components available via dot-notation:
|
|
34
|
+
* - `// Tooltip.Floating` — Tooltip that follows the cursor
|
|
35
|
+
* - `// Tooltip.Group` — Shared hover delay group for multiple tooltips
|
|
36
|
+
*/
|
|
37
|
+
export type TooltipProps = RecursicaOverStyled<
|
|
38
|
+
MuiTooltipProps & RecursicaTooltipProps
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
const TooltipBase = function Tooltip({
|
|
42
|
+
overStyled = false,
|
|
43
|
+
withBeak = true,
|
|
44
|
+
label,
|
|
45
|
+
opened,
|
|
46
|
+
...rest
|
|
47
|
+
}: TooltipProps & { label?: React.ReactNode; opened?: boolean }) {
|
|
48
|
+
const { title, ...restProps } = rest;
|
|
49
|
+
const sanitizedProps = filterStylingProps(restProps, overStyled);
|
|
50
|
+
|
|
51
|
+
// Bind CSS module classes to Mui's internal classNames API
|
|
52
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
53
|
+
tooltip: styles.tooltip,
|
|
54
|
+
arrow: styles.arrow,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
|
|
58
|
+
if (
|
|
59
|
+
classNamesProp &&
|
|
60
|
+
typeof classNamesProp === "object" &&
|
|
61
|
+
!Array.isArray(classNamesProp)
|
|
62
|
+
) {
|
|
63
|
+
const o = classNamesProp as Record<string, string>;
|
|
64
|
+
Object.keys(o).forEach((key) => {
|
|
65
|
+
if (mergedClassNames[key]) {
|
|
66
|
+
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
67
|
+
} else {
|
|
68
|
+
mergedClassNames[key] = o[key];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const withArrow = (sanitizedProps as Record<string, unknown>).withArrow as
|
|
74
|
+
| boolean
|
|
75
|
+
| undefined;
|
|
76
|
+
const resolvedWithArrow = withBeak ?? withArrow;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<MuiTooltip
|
|
80
|
+
title={label || title || ""}
|
|
81
|
+
open={opened}
|
|
82
|
+
placement="top" /* Recursica default; Mui defaults to "bottom" */
|
|
83
|
+
arrow={resolvedWithArrow}
|
|
84
|
+
classes={mergedClassNames}
|
|
85
|
+
{...(sanitizedProps as unknown as Omit<MuiTooltipProps, "title">)}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
8
88
|
};
|
|
89
|
+
TooltipBase.displayName = "Tooltip";
|
|
90
|
+
|
|
91
|
+
export const Tooltip = TooltipBase;
|
|
@@ -6,28 +6,10 @@ const meta: Meta<typeof TransferList> = {
|
|
|
6
6
|
title: "UI-Kit/🚧 TransferList",
|
|
7
7
|
component: TransferList,
|
|
8
8
|
tags: ["autodocs"],
|
|
9
|
-
parameters: {
|
|
10
|
-
controls: {
|
|
11
|
-
include: [
|
|
12
|
-
"layer",
|
|
13
|
-
"withLayer",
|
|
14
|
-
"children",
|
|
15
|
-
"component",
|
|
16
|
-
"variant",
|
|
17
|
-
"size",
|
|
18
|
-
"icon",
|
|
19
|
-
"disabled",
|
|
20
|
-
"href",
|
|
21
|
-
"onClick",
|
|
22
|
-
"onChange",
|
|
23
|
-
"value",
|
|
24
|
-
"checked",
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
9
|
};
|
|
29
10
|
|
|
30
11
|
export default meta;
|
|
12
|
+
|
|
31
13
|
type Story = StoryObj<typeof TransferList>;
|
|
32
14
|
|
|
33
15
|
export const Default: Story = {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import "./TransferList.module.css";
|
|
3
|
+
import { type RecursicaTransferListProps } from "@recursica/adapter-common";
|
|
3
4
|
|
|
4
|
-
export type TransferListProps = React.HTMLAttributes<HTMLDivElement
|
|
5
|
+
export type TransferListProps = React.HTMLAttributes<HTMLDivElement> &
|
|
6
|
+
RecursicaTransferListProps;
|
|
5
7
|
|
|
6
8
|
export const TransferList: React.FC<TransferListProps> = (props) => {
|
|
7
9
|
return <div {...props}>TransferList</div>;
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Enforces accessibility by strictly requiring at least one form of labeling:
|
|
5
|
-
* either a visual \`label\`, an \`aria-label\`, or an \`aria-labelledby\`.
|
|
6
|
-
*/
|
|
7
|
-
export type RequireAccessibleLabel<T> = T &
|
|
8
|
-
(
|
|
9
|
-
| { label: ReactNode; "aria-label"?: string; "aria-labelledby"?: string }
|
|
10
|
-
| { label?: ReactNode; "aria-label": string; "aria-labelledby"?: string }
|
|
11
|
-
| { label?: ReactNode; "aria-label"?: string; "aria-labelledby": string }
|
|
12
|
-
);
|
|
1
|
+
export { type RequireAccessibleLabel } from "@recursica/adapter-common";
|
|
@@ -51,19 +51,13 @@ export const BLOCKED_STYLING_KEYS = [
|
|
|
51
51
|
"position",
|
|
52
52
|
"zIndex",
|
|
53
53
|
] as const;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
| "rec-md"
|
|
62
|
-
| "rec-lg"
|
|
63
|
-
| "rec-xl"
|
|
64
|
-
| "rec-2xl";
|
|
65
|
-
|
|
66
|
-
export type RecursicaSize = "small" | "default" | "large";
|
|
54
|
+
export {
|
|
55
|
+
type RecursicaSpacing,
|
|
56
|
+
type RecursicaSize,
|
|
57
|
+
type RecursicaOverStyled,
|
|
58
|
+
type BlockedStylingKeys,
|
|
59
|
+
type ForbiddenStyles,
|
|
60
|
+
} from "@recursica/adapter-common";
|
|
67
61
|
|
|
68
62
|
const LAYOUT_PROPS = new Set([
|
|
69
63
|
"m",
|
|
@@ -99,8 +93,6 @@ export const SPACING_MAP: Record<string, string> = {
|
|
|
99
93
|
"rec-2xl": "var(--recursica_brand_dimensions_general_2xl)",
|
|
100
94
|
};
|
|
101
95
|
|
|
102
|
-
export type ForbiddenStyles = { [K in BlockedStylingKeys]?: never };
|
|
103
|
-
|
|
104
96
|
export type OmitSx<T> = Omit<T, "sx">;
|
|
105
97
|
|
|
106
98
|
export function filterSxProp<T extends Record<string, unknown>>(
|
|
@@ -113,11 +105,6 @@ export function filterSxProp<T extends Record<string, unknown>>(
|
|
|
113
105
|
return sanitized as Omit<T, "sx">;
|
|
114
106
|
}
|
|
115
107
|
|
|
116
|
-
export type RecursicaOverStyled<T> =
|
|
117
|
-
| (Omit<T, BlockedStylingKeys> &
|
|
118
|
-
ForbiddenStyles & { overStyled?: false | undefined })
|
|
119
|
-
| (T & { overStyled: true });
|
|
120
|
-
|
|
121
108
|
export function filterStylingProps<T extends Record<string, unknown>>(
|
|
122
109
|
props: T,
|
|
123
110
|
overStyled?: boolean,
|