@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.
Files changed (212) hide show
  1. package/ARCHITECTURE.md +15 -0
  2. package/CHANGELOG.md +15 -0
  3. package/SETUP.md +77 -0
  4. package/USAGE.md +55 -0
  5. package/dist/mui-adapter.cjs +74 -1
  6. package/dist/mui-adapter.cjs.map +1 -1
  7. package/dist/mui-adapter.css +1 -1
  8. package/dist/mui-adapter.js +6863 -205
  9. package/dist/mui-adapter.js.map +1 -1
  10. package/dist/src/components/Accordion/Accordion.d.ts +43 -2
  11. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
  12. package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
  13. package/dist/src/components/Avatar/Avatar.d.ts +10 -3
  14. package/dist/src/components/Badge/Badge.d.ts +10 -3
  15. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
  16. package/dist/src/components/Button/Button.d.ts +2 -17
  17. package/dist/src/components/Card/Card.d.ts +38 -3
  18. package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
  19. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
  20. package/dist/src/components/Checkbox/index.d.ts +5 -1
  21. package/dist/src/components/Chip/Chip.d.ts +9 -2
  22. package/dist/src/components/Container/Container.d.ts +1 -5
  23. package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
  24. package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
  25. package/dist/src/components/Flex/Flex.d.ts +2 -22
  26. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
  27. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
  28. package/dist/src/components/Group/Group.d.ts +2 -7
  29. package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
  30. package/dist/src/components/Label/Label.d.ts +6 -2
  31. package/dist/src/components/Link/Link.d.ts +2 -6
  32. package/dist/src/components/Loader/Loader.d.ts +2 -7
  33. package/dist/src/components/Menu/Menu.d.ts +25 -3
  34. package/dist/src/components/Modal/Modal.d.ts +37 -2
  35. package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
  36. package/dist/src/components/Pagination/Pagination.d.ts +12 -3
  37. package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
  38. package/dist/src/components/Panel/Panel.d.ts +52 -3
  39. package/dist/src/components/Radio/Radio.d.ts +13 -3
  40. package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
  41. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  42. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
  43. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  44. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  45. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
  46. package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
  47. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
  48. package/dist/src/components/Slider/Slider.d.ts +18 -2
  49. package/dist/src/components/Stack/Stack.d.ts +2 -5
  50. package/dist/src/components/Stepper/Stepper.d.ts +41 -2
  51. package/dist/src/components/Switch/Switch.d.ts +10 -3
  52. package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
  53. package/dist/src/components/Table/Table.d.ts +2 -1
  54. package/dist/src/components/Tabs/Tabs.d.ts +20 -3
  55. package/dist/src/components/Text/Text.d.ts +2 -16
  56. package/dist/src/components/TextArea/TextArea.d.ts +12 -2
  57. package/dist/src/components/TextField/TextField.d.ts +12 -2
  58. package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
  59. package/dist/src/components/Timeline/Timeline.d.ts +15 -2
  60. package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
  61. package/dist/src/components/Title/Title.d.ts +2 -15
  62. package/dist/src/components/Toast/Toast.d.ts +20 -2
  63. package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
  64. package/dist/src/components/TransferList/TransferList.d.ts +2 -1
  65. package/dist/src/components/Typography/Typography.d.ts +1 -1
  66. package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
  67. package/dist/src/utils/filterStylingProps.d.ts +1 -11
  68. package/llms.txt +16 -0
  69. package/package.json +14 -3
  70. package/src/components/Accordion/Accordion.module.css +294 -56
  71. package/src/components/Accordion/Accordion.stories.tsx +131 -21
  72. package/src/components/Accordion/Accordion.tsx +260 -5
  73. package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
  74. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
  75. package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
  76. package/src/components/Autocomplete/Autocomplete.module.css +319 -42
  77. package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
  78. package/src/components/Autocomplete/Autocomplete.tsx +181 -6
  79. package/src/components/Avatar/Avatar.module.css +343 -73
  80. package/src/components/Avatar/Avatar.stories.tsx +94 -22
  81. package/src/components/Avatar/Avatar.tsx +99 -6
  82. package/src/components/Badge/Badge.module.css +127 -29
  83. package/src/components/Badge/Badge.stories.tsx +65 -22
  84. package/src/components/Badge/Badge.tsx +67 -6
  85. package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
  86. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
  87. package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
  88. package/src/components/Button/Button.module.css +19 -61
  89. package/src/components/Button/Button.stories.tsx +24 -23
  90. package/src/components/Button/Button.tsx +7 -18
  91. package/src/components/Card/Card.module.css +154 -38
  92. package/src/components/Card/Card.stories.tsx +117 -19
  93. package/src/components/Card/Card.tsx +181 -5
  94. package/src/components/Checkbox/Checkbox.module.css +249 -39
  95. package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
  96. package/src/components/Checkbox/Checkbox.tsx +246 -5
  97. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  98. package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
  99. package/src/components/Checkbox/index.ts +6 -1
  100. package/src/components/Chip/Chip.module.css +246 -43
  101. package/src/components/Chip/Chip.stories.tsx +101 -21
  102. package/src/components/Chip/Chip.tsx +136 -6
  103. package/src/components/Container/Container.stories.tsx +103 -20
  104. package/src/components/Container/Container.tsx +1 -13
  105. package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
  106. package/src/components/DatePicker/DatePicker.tsx +3 -1
  107. package/src/components/Dropdown/Dropdown.module.css +291 -41
  108. package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
  109. package/src/components/Dropdown/Dropdown.tsx +180 -6
  110. package/src/components/FileInput/FileInput.stories.tsx +2 -19
  111. package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
  112. package/src/components/Flex/Flex.stories.tsx +113 -20
  113. package/src/components/Flex/Flex.tsx +16 -26
  114. package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
  115. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
  116. package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
  117. package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
  118. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
  119. package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
  120. package/src/components/Group/Group.stories.tsx +6 -30
  121. package/src/components/Group/Group.tsx +14 -9
  122. package/src/components/HoverCard/HoverCard.module.css +90 -22
  123. package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
  124. package/src/components/HoverCard/HoverCard.tsx +147 -5
  125. package/src/components/Label/Label.module.css +140 -35
  126. package/src/components/Label/Label.stories.tsx +108 -21
  127. package/src/components/Label/Label.tsx +82 -5
  128. package/src/components/Link/Link.module.css +4 -3
  129. package/src/components/Link/Link.stories.tsx +2 -8
  130. package/src/components/Link/Link.tsx +1 -5
  131. package/src/components/Loader/Loader.module.css +1 -2
  132. package/src/components/Loader/Loader.tsx +1 -7
  133. package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
  134. package/src/components/Menu/Menu.module.css +285 -51
  135. package/src/components/Menu/Menu.stories.tsx +229 -25
  136. package/src/components/Menu/Menu.tsx +73 -6
  137. package/src/components/Modal/Modal.module.css +171 -35
  138. package/src/components/Modal/Modal.stories.tsx +66 -22
  139. package/src/components/Modal/Modal.tsx +215 -5
  140. package/src/components/NumberInput/NumberInput.module.css +276 -42
  141. package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
  142. package/src/components/NumberInput/NumberInput.tsx +136 -6
  143. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
  144. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  145. package/src/components/Pagination/Pagination.module.css +234 -20
  146. package/src/components/Pagination/Pagination.stories.tsx +34 -21
  147. package/src/components/Pagination/Pagination.tsx +74 -6
  148. package/src/components/Panel/Panel.module.css +206 -38
  149. package/src/components/Panel/Panel.stories.tsx +214 -22
  150. package/src/components/Panel/Panel.tsx +130 -5
  151. package/src/components/Radio/Radio.module.css +235 -37
  152. package/src/components/Radio/Radio.stories.tsx +77 -19
  153. package/src/components/Radio/Radio.tsx +210 -5
  154. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  155. package/src/components/Radio/RadioGroup.tsx +125 -0
  156. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  157. package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
  158. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
  159. package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
  160. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  161. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  162. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  163. package/src/components/ReadOnlyField/index.ts +1 -0
  164. package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
  165. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
  166. package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
  167. package/src/components/Slider/Slider.module.css +539 -86
  168. package/src/components/Slider/Slider.stories.tsx +157 -19
  169. package/src/components/Slider/Slider.tsx +283 -5
  170. package/src/components/Stack/Stack.stories.tsx +4 -25
  171. package/src/components/Stack/Stack.tsx +1 -5
  172. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
  173. package/src/components/Stepper/Stepper.module.css +410 -71
  174. package/src/components/Stepper/Stepper.stories.tsx +146 -20
  175. package/src/components/Stepper/Stepper.tsx +147 -6
  176. package/src/components/Switch/Switch.module.css +259 -39
  177. package/src/components/Switch/Switch.stories.tsx +98 -19
  178. package/src/components/Switch/Switch.tsx +200 -6
  179. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  180. package/src/components/Switch/SwitchGroup.tsx +120 -0
  181. package/src/components/Table/Table.stories.tsx +1 -19
  182. package/src/components/Table/Table.tsx +3 -1
  183. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
  184. package/src/components/Tabs/Tabs.module.css +422 -79
  185. package/src/components/Tabs/Tabs.stories.tsx +156 -20
  186. package/src/components/Tabs/Tabs.tsx +86 -6
  187. package/src/components/Text/Text.stories.tsx +5 -17
  188. package/src/components/Text/Text.tsx +1 -15
  189. package/src/components/TextArea/TextArea.module.css +155 -32
  190. package/src/components/TextArea/TextArea.stories.tsx +80 -21
  191. package/src/components/TextArea/TextArea.tsx +146 -6
  192. package/src/components/TextField/TextField.module.css +261 -42
  193. package/src/components/TextField/TextField.stories.tsx +147 -20
  194. package/src/components/TextField/TextField.tsx +169 -6
  195. package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
  196. package/src/components/TimePicker/TimePicker.tsx +3 -1
  197. package/src/components/Timeline/Timeline.module.css +365 -76
  198. package/src/components/Timeline/Timeline.stories.tsx +114 -21
  199. package/src/components/Timeline/Timeline.tsx +83 -5
  200. package/src/components/Timeline/TimelineItem.tsx +90 -0
  201. package/src/components/Title/Title.stories.tsx +0 -18
  202. package/src/components/Title/Title.tsx +1 -7
  203. package/src/components/Toast/Toast.module.css +166 -28
  204. package/src/components/Toast/Toast.stories.tsx +54 -22
  205. package/src/components/Toast/Toast.tsx +124 -5
  206. package/src/components/Tooltip/Tooltip.module.css +89 -24
  207. package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
  208. package/src/components/Tooltip/Tooltip.tsx +88 -5
  209. package/src/components/TransferList/TransferList.stories.tsx +1 -19
  210. package/src/components/TransferList/TransferList.tsx +3 -1
  211. package/src/utils/RequireAccessibleLabel.ts +1 -12
  212. 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/🚧 Timeline",
5
+ title: "UI-Kit/Timeline",
7
6
  component: Timeline,
8
7
  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
- },
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
- render: () => <ComingSoon componentName="Timeline" />,
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 "./Timeline.module.css";
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
- export type TimelineProps = React.HTMLAttributes<HTMLDivElement>;
12
+ import { type RecursicaTimelineProps } from "@recursica/adapter-common";
5
13
 
6
- export const Timeline: React.FC<TimelineProps> = (props) => {
7
- return <div {...props}>Timeline</div>;
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 TypographyProps as MuiTypographyProps } from "@mui/material";
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
- This component is a placeholder stub. Once fully implemented, its specific
3
- tokens will be fully wired up to direct styles. */
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
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_horizontal-padding */
10
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_icon */
11
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_max-width */
12
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_min-height */
13
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_min-width */
14
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_spacing */
15
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_font-family */
16
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_font-size */
17
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_font-style */
18
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_font-weight */
19
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_letter-spacing */
20
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_line-height */
21
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_text-decoration */
22
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_text_text-transform */
23
- /* recursica-ignore: --recursica_ui-kit_components_toast_properties_vertical-padding */
24
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_default_properties_colors_background */
25
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_default_properties_colors_button */
26
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_default_properties_colors_text */
27
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_error_properties_colors_background */
28
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_error_properties_colors_button */
29
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_error_properties_colors_text */
30
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_success_properties_colors_background */
31
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_success_properties_colors_button */
32
- /* recursica-ignore: --recursica_ui-kit_components_toast_variants_styles_success_properties_colors_text */
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
- const meta: Meta<typeof Toast> = {
6
- title: "UI-Kit/🚧 Toast",
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
- 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
- ],
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 Toast>;
36
+ type Story = StoryObj<typeof meta>;
32
37
 
33
38
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Toast" />,
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
  };