@recursica/mui-adapter 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +15 -0
- package/CHANGELOG.md +15 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +74 -1
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +6863 -205
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +43 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
- package/dist/src/components/Avatar/Avatar.d.ts +10 -3
- package/dist/src/components/Badge/Badge.d.ts +10 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +38 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +9 -2
- package/dist/src/components/Container/Container.d.ts +1 -5
- package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
- package/dist/src/components/Label/Label.d.ts +6 -2
- package/dist/src/components/Link/Link.d.ts +2 -6
- package/dist/src/components/Loader/Loader.d.ts +2 -7
- package/dist/src/components/Menu/Menu.d.ts +25 -3
- package/dist/src/components/Modal/Modal.d.ts +37 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
- package/dist/src/components/Pagination/Pagination.d.ts +12 -3
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +52 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
- package/dist/src/components/Slider/Slider.d.ts +18 -2
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +41 -2
- package/dist/src/components/Switch/Switch.d.ts +10 -3
- package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +20 -3
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +12 -2
- package/dist/src/components/TextField/TextField.d.ts +12 -2
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +15 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +20 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
- package/dist/src/components/TransferList/TransferList.d.ts +2 -1
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
- package/dist/src/utils/filterStylingProps.d.ts +1 -11
- package/llms.txt +16 -0
- package/package.json +14 -3
- package/src/components/Accordion/Accordion.module.css +294 -56
- package/src/components/Accordion/Accordion.stories.tsx +131 -21
- package/src/components/Accordion/Accordion.tsx +260 -5
- package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
- package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
- package/src/components/Autocomplete/Autocomplete.module.css +319 -42
- package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
- package/src/components/Autocomplete/Autocomplete.tsx +181 -6
- package/src/components/Avatar/Avatar.module.css +343 -73
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +99 -6
- package/src/components/Badge/Badge.module.css +127 -29
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +67 -6
- package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
- package/src/components/Button/Button.module.css +19 -61
- package/src/components/Button/Button.stories.tsx +24 -23
- package/src/components/Button/Button.tsx +7 -18
- package/src/components/Card/Card.module.css +154 -38
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +181 -5
- package/src/components/Checkbox/Checkbox.module.css +249 -39
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +246 -5
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +246 -43
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +136 -6
- package/src/components/Container/Container.stories.tsx +103 -20
- package/src/components/Container/Container.tsx +1 -13
- package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
- package/src/components/DatePicker/DatePicker.tsx +3 -1
- package/src/components/Dropdown/Dropdown.module.css +291 -41
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +180 -6
- package/src/components/FileInput/FileInput.stories.tsx +2 -19
- package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
- package/src/components/Flex/Flex.stories.tsx +113 -20
- package/src/components/Flex/Flex.tsx +16 -26
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
- package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.module.css +90 -22
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +147 -5
- package/src/components/Label/Label.module.css +140 -35
- package/src/components/Label/Label.stories.tsx +108 -21
- package/src/components/Label/Label.tsx +82 -5
- package/src/components/Link/Link.module.css +4 -3
- package/src/components/Link/Link.stories.tsx +2 -8
- package/src/components/Link/Link.tsx +1 -5
- package/src/components/Loader/Loader.module.css +1 -2
- package/src/components/Loader/Loader.tsx +1 -7
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Menu/Menu.module.css +285 -51
- package/src/components/Menu/Menu.stories.tsx +229 -25
- package/src/components/Menu/Menu.tsx +73 -6
- package/src/components/Modal/Modal.module.css +171 -35
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +215 -5
- package/src/components/NumberInput/NumberInput.module.css +276 -42
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +136 -6
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +234 -20
- package/src/components/Pagination/Pagination.stories.tsx +34 -21
- package/src/components/Pagination/Pagination.tsx +74 -6
- package/src/components/Panel/Panel.module.css +206 -38
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +130 -5
- package/src/components/Radio/Radio.module.css +235 -37
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +210 -5
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +125 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +1 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
- package/src/components/Slider/Slider.module.css +539 -86
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +283 -5
- package/src/components/Stack/Stack.stories.tsx +4 -25
- package/src/components/Stack/Stack.tsx +1 -5
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stepper/Stepper.module.css +410 -71
- package/src/components/Stepper/Stepper.stories.tsx +146 -20
- package/src/components/Stepper/Stepper.tsx +147 -6
- package/src/components/Switch/Switch.module.css +259 -39
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +200 -6
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +120 -0
- package/src/components/Table/Table.stories.tsx +1 -19
- package/src/components/Table/Table.tsx +3 -1
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Tabs/Tabs.module.css +422 -79
- package/src/components/Tabs/Tabs.stories.tsx +156 -20
- package/src/components/Tabs/Tabs.tsx +86 -6
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.module.css +155 -32
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +146 -6
- package/src/components/TextField/TextField.module.css +261 -42
- package/src/components/TextField/TextField.stories.tsx +147 -20
- package/src/components/TextField/TextField.tsx +169 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.module.css +365 -76
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +83 -5
- package/src/components/Timeline/TimelineItem.tsx +90 -0
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.module.css +166 -28
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +124 -5
- package/src/components/Tooltip/Tooltip.module.css +89 -24
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +88 -5
- package/src/components/TransferList/TransferList.stories.tsx +1 -19
- package/src/components/TransferList/TransferList.tsx +3 -1
- package/src/utils/RequireAccessibleLabel.ts +1 -12
- package/src/utils/filterStylingProps.ts +7 -20
|
@@ -1,35 +1,128 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import { Timeline } from "./Timeline";
|
|
3
|
-
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
3
|
|
|
5
4
|
const meta: Meta<typeof Timeline> = {
|
|
6
|
-
title: "UI-Kit
|
|
5
|
+
title: "UI-Kit/Timeline",
|
|
7
6
|
component: Timeline,
|
|
8
7
|
tags: ["autodocs"],
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
},
|
|
8
|
+
argTypes: {
|
|
9
|
+
defaultChecked: { table: { disable: true } },
|
|
27
10
|
},
|
|
28
11
|
};
|
|
29
12
|
|
|
30
13
|
export default meta;
|
|
14
|
+
|
|
31
15
|
type Story = StoryObj<typeof Timeline>;
|
|
32
16
|
|
|
33
17
|
export const Default: Story = {
|
|
34
|
-
|
|
18
|
+
args: {
|
|
19
|
+
active: 1,
|
|
20
|
+
},
|
|
21
|
+
render: (args) => (
|
|
22
|
+
<Timeline {...args}>
|
|
23
|
+
<Timeline.Item
|
|
24
|
+
title="Commit created"
|
|
25
|
+
timestamp="Yesterday"
|
|
26
|
+
bulletVariant="default"
|
|
27
|
+
>
|
|
28
|
+
You pushed 3 new commits to the repository.
|
|
29
|
+
</Timeline.Item>
|
|
30
|
+
<Timeline.Item
|
|
31
|
+
title="Pull request opened"
|
|
32
|
+
timestamp="2 days ago"
|
|
33
|
+
bulletVariant="default"
|
|
34
|
+
>
|
|
35
|
+
You opened a pull request for the feature branch.
|
|
36
|
+
</Timeline.Item>
|
|
37
|
+
<Timeline.Item
|
|
38
|
+
title="Code review completed"
|
|
39
|
+
timestamp="1 week ago"
|
|
40
|
+
bulletVariant="default"
|
|
41
|
+
>
|
|
42
|
+
Your pull request was approved by 2 reviewers.
|
|
43
|
+
</Timeline.Item>
|
|
44
|
+
<Timeline.Item
|
|
45
|
+
title="Branch merged"
|
|
46
|
+
timestamp="2 weeks ago"
|
|
47
|
+
bulletVariant="default"
|
|
48
|
+
>
|
|
49
|
+
Your feature branch was successfully merged into main.
|
|
50
|
+
</Timeline.Item>
|
|
51
|
+
</Timeline>
|
|
52
|
+
),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const BulletVariants: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
active: 1,
|
|
58
|
+
},
|
|
59
|
+
render: (args) => (
|
|
60
|
+
<Timeline {...args}>
|
|
61
|
+
<Timeline.Item
|
|
62
|
+
title="Default Bullet"
|
|
63
|
+
timestamp="Standard configuration"
|
|
64
|
+
bulletVariant="default"
|
|
65
|
+
>
|
|
66
|
+
The default un-configured structural dot.
|
|
67
|
+
</Timeline.Item>
|
|
68
|
+
<Timeline.Item
|
|
69
|
+
title="Icon Bullet"
|
|
70
|
+
timestamp="Standard sized icons"
|
|
71
|
+
bulletVariant="icon"
|
|
72
|
+
bullet={
|
|
73
|
+
<svg
|
|
74
|
+
viewBox="0 0 24 24"
|
|
75
|
+
fill="none"
|
|
76
|
+
stroke="currentColor"
|
|
77
|
+
strokeWidth="2"
|
|
78
|
+
strokeLinecap="round"
|
|
79
|
+
strokeLinejoin="round"
|
|
80
|
+
>
|
|
81
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
82
|
+
</svg>
|
|
83
|
+
}
|
|
84
|
+
>
|
|
85
|
+
A standard structural icon node mapping.
|
|
86
|
+
</Timeline.Item>
|
|
87
|
+
<Timeline.Item
|
|
88
|
+
title="Alternative Icon"
|
|
89
|
+
timestamp="Larger structural bounds"
|
|
90
|
+
bulletVariant="icon-alternative"
|
|
91
|
+
bullet={
|
|
92
|
+
<svg
|
|
93
|
+
viewBox="0 0 24 24"
|
|
94
|
+
fill="none"
|
|
95
|
+
stroke="currentColor"
|
|
96
|
+
strokeWidth="2"
|
|
97
|
+
strokeLinecap="round"
|
|
98
|
+
strokeLinejoin="round"
|
|
99
|
+
>
|
|
100
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
101
|
+
</svg>
|
|
102
|
+
}
|
|
103
|
+
>
|
|
104
|
+
A slightly larger alternative bounding box for specialized icons.
|
|
105
|
+
</Timeline.Item>
|
|
106
|
+
<Timeline.Item
|
|
107
|
+
title="Avatar Bullet"
|
|
108
|
+
timestamp="Profile pictures"
|
|
109
|
+
bulletVariant="avatar"
|
|
110
|
+
bullet={
|
|
111
|
+
<img
|
|
112
|
+
src="https://avatars.githubusercontent.com/u/10353856?s=460&v=4"
|
|
113
|
+
alt="avatar"
|
|
114
|
+
style={{
|
|
115
|
+
width: "100%",
|
|
116
|
+
height: "100%",
|
|
117
|
+
objectFit: "cover",
|
|
118
|
+
borderRadius: "inherit",
|
|
119
|
+
}}
|
|
120
|
+
/>
|
|
121
|
+
}
|
|
122
|
+
>
|
|
123
|
+
Avatar mappings inherently drop borders and leverage specific opacity
|
|
124
|
+
states.
|
|
125
|
+
</Timeline.Item>
|
|
126
|
+
</Timeline>
|
|
127
|
+
),
|
|
35
128
|
};
|
|
@@ -1,8 +1,86 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import MuiTimeline, {
|
|
3
|
+
type TimelineProps as MuiTimelineProps,
|
|
4
|
+
} from "@mui/lab/Timeline";
|
|
5
|
+
import {
|
|
6
|
+
filterStylingProps,
|
|
7
|
+
type RecursicaOverStyled,
|
|
8
|
+
} from "../../utils/filterStylingProps";
|
|
9
|
+
import styles from "./Timeline.module.css";
|
|
10
|
+
import { TimelineItem } from "./TimelineItem";
|
|
3
11
|
|
|
4
|
-
|
|
12
|
+
import { type RecursicaTimelineProps } from "@recursica/adapter-common";
|
|
5
13
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Properties for the strictly-tokenized Timeline component.
|
|
16
|
+
* Native Mui abstract properties like `color`, `radius`, `bulletSize`, and `lineWidth`
|
|
17
|
+
* have been stripped out to strictly enforce the structural mappings of the Recursica UI Kit.
|
|
18
|
+
*/
|
|
19
|
+
export type TimelineProps = RecursicaOverStyled<
|
|
20
|
+
Omit<MuiTimelineProps, "color" | "radius" | "bulletSize" | "lineWidth"> &
|
|
21
|
+
RecursicaTimelineProps
|
|
22
|
+
>;
|
|
23
|
+
|
|
24
|
+
interface TimelineComponent
|
|
25
|
+
extends React.ForwardRefExoticComponent<
|
|
26
|
+
TimelineProps & React.RefAttributes<HTMLDivElement>
|
|
27
|
+
> {
|
|
28
|
+
Item: typeof TimelineItem;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The `Timeline` component displays a list of events in chronological order.
|
|
33
|
+
*
|
|
34
|
+
* **Recursica Abstract:**
|
|
35
|
+
* This component acts as a structural wrapper around Mui's `<Timeline>`.
|
|
36
|
+
* It forces alignment and geometry strictly via the UI Kit's `.itemBullet` and connector definitions.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <Timeline active={1}>
|
|
41
|
+
* <Timeline.Item title="Event 1" timestamp="Yesterday">Description</Timeline.Item>
|
|
42
|
+
* </Timeline>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
const TimelineInner = React.forwardRef<HTMLUListElement, TimelineProps>(
|
|
46
|
+
function Timeline({ overStyled = false, ...rest }, ref) {
|
|
47
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
48
|
+
|
|
49
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
50
|
+
root: styles.root,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const classNamesProp = (sanitizedProps as Record<string, unknown>)
|
|
54
|
+
.classNames;
|
|
55
|
+
if (
|
|
56
|
+
classNamesProp &&
|
|
57
|
+
typeof classNamesProp === "object" &&
|
|
58
|
+
!Array.isArray(classNamesProp)
|
|
59
|
+
) {
|
|
60
|
+
const o = classNamesProp as Record<string, string>;
|
|
61
|
+
Object.keys(o).forEach((key) => {
|
|
62
|
+
if (mergedClassNames[key]) {
|
|
63
|
+
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
64
|
+
} else {
|
|
65
|
+
mergedClassNames[key] = o[key];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<MuiTimeline
|
|
72
|
+
ref={ref}
|
|
73
|
+
classes={mergedClassNames}
|
|
74
|
+
{...(sanitizedProps as unknown as Omit<
|
|
75
|
+
MuiTimelineProps,
|
|
76
|
+
"color" | "radius" | "bulletSize" | "lineWidth"
|
|
77
|
+
>)}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
TimelineInner.displayName = "Timeline";
|
|
84
|
+
|
|
85
|
+
export const Timeline = TimelineInner as TimelineComponent;
|
|
86
|
+
Timeline.Item = TimelineItem;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import MuiTimelineItem, {
|
|
3
|
+
type TimelineItemProps as MuiTimelineItemProps,
|
|
4
|
+
} from "@mui/lab/TimelineItem";
|
|
5
|
+
import {
|
|
6
|
+
filterStylingProps,
|
|
7
|
+
type RecursicaOverStyled,
|
|
8
|
+
} from "../../utils/filterStylingProps";
|
|
9
|
+
import styles from "./Timeline.module.css";
|
|
10
|
+
|
|
11
|
+
import { type RecursicaTimelineItemProps } from "@recursica/adapter-common";
|
|
12
|
+
|
|
13
|
+
export type TimelineItemProps = RecursicaOverStyled<
|
|
14
|
+
Omit<MuiTimelineItemProps, "radius" | "color" | "lineVariant"> &
|
|
15
|
+
RecursicaTimelineItemProps
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The individual item component for the Timeline.
|
|
20
|
+
*
|
|
21
|
+
* **Recursica Abstract:**
|
|
22
|
+
* The `Timeline.Item` has been extended to support a `timestamp` string natively,
|
|
23
|
+
* rendering it below the body content. It also accepts a `bulletVariant` to morph
|
|
24
|
+
* the structural dimensions of the node circle automatically.
|
|
25
|
+
*/
|
|
26
|
+
export const TimelineItem = React.forwardRef<HTMLDivElement, TimelineItemProps>(
|
|
27
|
+
function TimelineItem(
|
|
28
|
+
{
|
|
29
|
+
overStyled = false,
|
|
30
|
+
timestamp,
|
|
31
|
+
bulletVariant = "default",
|
|
32
|
+
children,
|
|
33
|
+
...rest
|
|
34
|
+
},
|
|
35
|
+
ref,
|
|
36
|
+
) {
|
|
37
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
38
|
+
|
|
39
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
40
|
+
item: styles.item,
|
|
41
|
+
itemBody: styles.itemBody,
|
|
42
|
+
itemContent: styles.itemContent,
|
|
43
|
+
itemBullet: styles.itemBullet,
|
|
44
|
+
itemTitle: styles.itemTitle,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const classNamesProp = (sanitizedProps as Record<string, unknown>)
|
|
48
|
+
.classNames;
|
|
49
|
+
if (
|
|
50
|
+
classNamesProp &&
|
|
51
|
+
typeof classNamesProp === "object" &&
|
|
52
|
+
!Array.isArray(classNamesProp)
|
|
53
|
+
) {
|
|
54
|
+
const o = classNamesProp as Record<string, string>;
|
|
55
|
+
Object.keys(o).forEach((key) => {
|
|
56
|
+
if (mergedClassNames[key]) {
|
|
57
|
+
mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
|
|
58
|
+
} else {
|
|
59
|
+
mergedClassNames[key] = o[key];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Embed timestamp inside children if provided, wrapped in a specific class
|
|
65
|
+
const content = timestamp ? (
|
|
66
|
+
<>
|
|
67
|
+
{children && <div className={styles.description}>{children}</div>}
|
|
68
|
+
<div className={styles.timestamp}>{timestamp}</div>
|
|
69
|
+
</>
|
|
70
|
+
) : (
|
|
71
|
+
children
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<MuiTimelineItem
|
|
76
|
+
ref={ref}
|
|
77
|
+
classes={mergedClassNames}
|
|
78
|
+
data-variant={bulletVariant}
|
|
79
|
+
{...(sanitizedProps as unknown as Omit<
|
|
80
|
+
MuiTimelineItemProps,
|
|
81
|
+
"radius" | "color" | "lineVariant"
|
|
82
|
+
>)}
|
|
83
|
+
>
|
|
84
|
+
{content}
|
|
85
|
+
</MuiTimelineItem>
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
TimelineItem.displayName = "TimelineItem";
|
|
@@ -13,24 +13,6 @@ const meta: Meta<typeof Title> = {
|
|
|
13
13
|
"The semantic `<Title>` abstraction intrinsically links pure `h1-h6` tag generation with exact Recursica design boundaries to preserve SEO and screen reader trees uniformly globally.",
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
|
-
controls: {
|
|
17
|
-
include: [
|
|
18
|
-
"layer",
|
|
19
|
-
"withLayer",
|
|
20
|
-
"order",
|
|
21
|
-
"children",
|
|
22
|
-
"component",
|
|
23
|
-
"variant",
|
|
24
|
-
"size",
|
|
25
|
-
"icon",
|
|
26
|
-
"disabled",
|
|
27
|
-
"href",
|
|
28
|
-
"onClick",
|
|
29
|
-
"onChange",
|
|
30
|
-
"value",
|
|
31
|
-
"checked",
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
16
|
},
|
|
35
17
|
argTypes: {
|
|
36
18
|
order: {
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
2
|
import { Typography } from "../Typography/Typography";
|
|
3
3
|
import { type RecursicaOverStyled } from "../../utils/filterStylingProps";
|
|
4
|
-
import { type
|
|
5
|
-
|
|
6
|
-
export type RecursicaTitleProps = Omit<MuiTypographyProps, "variant"> & {
|
|
7
|
-
order?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
8
|
-
children?: React.ReactNode;
|
|
9
|
-
component?: React.ElementType;
|
|
10
|
-
};
|
|
4
|
+
import { type RecursicaTitleProps } from "@recursica/adapter-common";
|
|
11
5
|
|
|
12
6
|
export type TitleProps = RecursicaOverStyled<RecursicaTitleProps>;
|
|
13
7
|
|
|
@@ -1,32 +1,170 @@
|
|
|
1
1
|
/* EXEMPTIONS:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-0 */
|
|
2
|
+
- elevation levels layer-1, layer-2, and layer-3 are ignored because all toasts explicitly use the standard
|
|
3
|
+
layer-0 elevation shadow for styling consistency. */
|
|
6
4
|
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-1 */
|
|
7
5
|
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-2 */
|
|
8
6
|
/* recursica-ignore: --recursica_ui-kit_components_toast_properties_elevation_layer-3 */
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
|
|
8
|
+
/* HARDCODED VALUES:
|
|
9
|
+
- border-style: none. To ensure the notification doesn't render unwanted borders unless specified.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* ======================================
|
|
13
|
+
TOAST / NOTIFICATION ROOT
|
|
14
|
+
====================================== */
|
|
15
|
+
|
|
16
|
+
.root {
|
|
17
|
+
border-style: none; /* HARDCODE: Reset to ensure clean shadow boundaries */
|
|
18
|
+
box-shadow: var(
|
|
19
|
+
--recursica_ui-kit_components_toast_properties_elevation_layer-0
|
|
20
|
+
);
|
|
21
|
+
padding: var(--recursica_ui-kit_components_toast_properties_vertical-padding)
|
|
22
|
+
var(--recursica_ui-kit_components_toast_properties_horizontal-padding);
|
|
23
|
+
min-width: var(--recursica_ui-kit_components_toast_properties_min-width);
|
|
24
|
+
max-width: var(--recursica_ui-kit_components_toast_properties_max-width);
|
|
25
|
+
min-height: var(--recursica_ui-kit_components_toast_properties_min-height);
|
|
26
|
+
|
|
27
|
+
/* Default Variant (Base) */
|
|
28
|
+
background-color: var(
|
|
29
|
+
--recursica_ui-kit_components_toast_variants_styles_default_properties_colors_background
|
|
30
|
+
);
|
|
31
|
+
gap: var(--recursica_ui-kit_components_toast_properties_spacing);
|
|
32
|
+
|
|
33
|
+
/* Hide Mantine's native colored vertical line */
|
|
34
|
+
&::before {
|
|
35
|
+
display: none;
|
|
36
|
+
content: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
& .icon {
|
|
40
|
+
width: var(--recursica_ui-kit_components_toast_properties_icon) !important;
|
|
41
|
+
height: var(--recursica_ui-kit_components_toast_properties_icon) !important;
|
|
42
|
+
margin-right: 0 !important; /* Override Mantine's native spacing in favor of flex gap */
|
|
43
|
+
background-color: transparent !important; /* Remove Mantine's native circle background */
|
|
44
|
+
|
|
45
|
+
color: var(
|
|
46
|
+
--recursica_ui-kit_components_toast_variants_styles_default_properties_colors_text
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
& .loader {
|
|
51
|
+
margin-right: 0 !important; /* Override native spacing */
|
|
52
|
+
}
|
|
53
|
+
& .title,
|
|
54
|
+
& .description {
|
|
55
|
+
color: var(
|
|
56
|
+
--recursica_ui-kit_components_toast_variants_styles_default_properties_colors_text
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
& .closeButton {
|
|
60
|
+
color: var(
|
|
61
|
+
--recursica_ui-kit_components_toast_variants_styles_default_properties_colors_button
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Error Variant styling */
|
|
66
|
+
&[data-variant="error"] {
|
|
67
|
+
background-color: var(
|
|
68
|
+
--recursica_ui-kit_components_toast_variants_styles_error_properties_colors_background
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
& .icon {
|
|
72
|
+
color: var(
|
|
73
|
+
--recursica_ui-kit_components_toast_variants_styles_error_properties_colors_text
|
|
74
|
+
) !important;
|
|
75
|
+
}
|
|
76
|
+
& .title,
|
|
77
|
+
& .description {
|
|
78
|
+
color: var(
|
|
79
|
+
--recursica_ui-kit_components_toast_variants_styles_error_properties_colors_text
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
& .closeButton {
|
|
83
|
+
color: var(
|
|
84
|
+
--recursica_ui-kit_components_toast_variants_styles_error_properties_colors_button
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Success Variant styling */
|
|
90
|
+
&[data-variant="success"] {
|
|
91
|
+
background-color: var(
|
|
92
|
+
--recursica_ui-kit_components_toast_variants_styles_success_properties_colors_background
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
& .icon {
|
|
96
|
+
color: var(
|
|
97
|
+
--recursica_ui-kit_components_toast_variants_styles_success_properties_colors_text
|
|
98
|
+
) !important;
|
|
99
|
+
}
|
|
100
|
+
& .title,
|
|
101
|
+
& .description {
|
|
102
|
+
color: var(
|
|
103
|
+
--recursica_ui-kit_components_toast_variants_styles_success_properties_colors_text
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
& .closeButton {
|
|
107
|
+
color: var(
|
|
108
|
+
--recursica_ui-kit_components_toast_variants_styles_success_properties_colors_button
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* ======================================
|
|
115
|
+
TOAST BODY
|
|
116
|
+
====================================== */
|
|
117
|
+
|
|
118
|
+
.body {
|
|
119
|
+
/* No extra gap here, root handles icon-to-text, body can handle title-to-description if needed */
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.title {
|
|
123
|
+
font-family: var(
|
|
124
|
+
--recursica_ui-kit_components_toast_properties_text_font-family
|
|
125
|
+
);
|
|
126
|
+
font-size: var(--recursica_ui-kit_components_toast_properties_text_font-size);
|
|
127
|
+
font-style: var(
|
|
128
|
+
--recursica_ui-kit_components_toast_properties_text_font-style
|
|
129
|
+
);
|
|
130
|
+
font-weight: var(
|
|
131
|
+
--recursica_ui-kit_components_toast_properties_text_font-weight
|
|
132
|
+
);
|
|
133
|
+
letter-spacing: var(
|
|
134
|
+
--recursica_ui-kit_components_toast_properties_text_letter-spacing
|
|
135
|
+
);
|
|
136
|
+
line-height: var(
|
|
137
|
+
--recursica_ui-kit_components_toast_properties_text_line-height
|
|
138
|
+
);
|
|
139
|
+
text-decoration: var(
|
|
140
|
+
--recursica_ui-kit_components_toast_properties_text_text-decoration
|
|
141
|
+
);
|
|
142
|
+
text-transform: var(
|
|
143
|
+
--recursica_ui-kit_components_toast_properties_text_text-transform
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.description {
|
|
148
|
+
font-family: var(
|
|
149
|
+
--recursica_ui-kit_components_toast_properties_text_font-family
|
|
150
|
+
);
|
|
151
|
+
font-size: var(--recursica_ui-kit_components_toast_properties_text_font-size);
|
|
152
|
+
font-style: var(
|
|
153
|
+
--recursica_ui-kit_components_toast_properties_text_font-style
|
|
154
|
+
);
|
|
155
|
+
font-weight: var(
|
|
156
|
+
--recursica_ui-kit_components_toast_properties_text_font-weight
|
|
157
|
+
);
|
|
158
|
+
letter-spacing: var(
|
|
159
|
+
--recursica_ui-kit_components_toast_properties_text_letter-spacing
|
|
160
|
+
);
|
|
161
|
+
line-height: var(
|
|
162
|
+
--recursica_ui-kit_components_toast_properties_text_line-height
|
|
163
|
+
);
|
|
164
|
+
text-decoration: var(
|
|
165
|
+
--recursica_ui-kit_components_toast_properties_text_text-decoration
|
|
166
|
+
);
|
|
167
|
+
text-transform: var(
|
|
168
|
+
--recursica_ui-kit_components_toast_properties_text_text-transform
|
|
169
|
+
);
|
|
170
|
+
}
|
|
@@ -1,35 +1,67 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import { Toast } from "./Toast";
|
|
3
|
-
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
type ToastStoryArgs = Record<string, any>;
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: "UI-Kit/Toast",
|
|
7
9
|
component: Toast,
|
|
8
10
|
tags: ["autodocs"],
|
|
9
11
|
parameters: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"component",
|
|
16
|
-
"variant",
|
|
17
|
-
"size",
|
|
18
|
-
"icon",
|
|
19
|
-
"disabled",
|
|
20
|
-
"href",
|
|
21
|
-
"onClick",
|
|
22
|
-
"onChange",
|
|
23
|
-
"value",
|
|
24
|
-
"checked",
|
|
25
|
-
],
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
"The `Toast` component is a standalone visual component wrapping Mui's `Alert`. Note that this component is visually decoupled from `@mui/material/Snackbar` and is meant to be used when you need to render a static or manually-controlled notification panel.",
|
|
16
|
+
},
|
|
26
17
|
},
|
|
27
18
|
},
|
|
28
|
-
|
|
19
|
+
argTypes: {
|
|
20
|
+
title: {
|
|
21
|
+
control: "text",
|
|
22
|
+
description: "Title displayed above the message body",
|
|
23
|
+
},
|
|
24
|
+
children: {
|
|
25
|
+
control: "text",
|
|
26
|
+
description: "Main notification message",
|
|
27
|
+
},
|
|
28
|
+
withCloseButton: {
|
|
29
|
+
control: "boolean",
|
|
30
|
+
description: "Whether the close button is visible",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
} satisfies Meta<typeof Toast>;
|
|
29
34
|
|
|
30
35
|
export default meta;
|
|
31
|
-
type Story = StoryObj<typeof
|
|
36
|
+
type Story = StoryObj<typeof meta>;
|
|
32
37
|
|
|
33
38
|
export const Default: Story = {
|
|
34
|
-
|
|
39
|
+
args: {
|
|
40
|
+
variant: "default",
|
|
41
|
+
title: "Update Available",
|
|
42
|
+
children:
|
|
43
|
+
"A new version of the application is available to download. Please restart your browser to apply the latest security patches and feature updates. If you ignore this message, the update will automatically install during your next session.",
|
|
44
|
+
withCloseButton: true,
|
|
45
|
+
},
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
|
+
render: ({ withLayer, layer, ...args }: ToastStoryArgs) => {
|
|
48
|
+
return <Toast {...args} />;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const WithIcon: Story = {
|
|
53
|
+
args: {
|
|
54
|
+
variant: "default",
|
|
55
|
+
title: "Action Required",
|
|
56
|
+
children:
|
|
57
|
+
"You must complete your profile setup before accessing this feature.",
|
|
58
|
+
icon: "⚠️",
|
|
59
|
+
},
|
|
60
|
+
parameters: {
|
|
61
|
+
controls: { disable: true },
|
|
62
|
+
},
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
|
+
render: ({ withLayer, layer, ...args }: ToastStoryArgs) => {
|
|
65
|
+
return <Toast {...args} />;
|
|
66
|
+
},
|
|
35
67
|
};
|