@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,107 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { Avatar } from "./Avatar";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { Layer } from "@recursica/adapter-common";
4
5
 
5
- const meta: Meta<typeof Avatar> = {
6
- title: "UI-Kit/🚧 Avatar",
6
+ type AvatarStoryProps = React.ComponentProps<typeof Avatar>;
7
+
8
+ const meta: Meta<AvatarStoryProps> = {
9
+ title: "UI-Kit/Avatar",
7
10
  component: Avatar,
8
11
  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
- ],
12
+ argTypes: {
13
+ variant: {
14
+ control: "select",
15
+ options: ["solid", "outline", "ghost"],
16
+ description:
17
+ "The visual variant of the avatar (applies to icon/text styles)",
18
+ },
19
+ size: {
20
+ control: "radio",
21
+ options: ["default", "small", "large"],
22
+ description: "The size of the avatar",
23
+ },
24
+ src: {
25
+ control: "text",
26
+ description: "Image URL for the image style avatar",
27
+ },
28
+ icon: {
29
+ table: {
30
+ disable: true,
31
+ },
26
32
  },
27
33
  },
28
34
  };
29
35
 
30
36
  export default meta;
31
- type Story = StoryObj<typeof Avatar>;
37
+
38
+ type Story = StoryObj<AvatarStoryProps>;
32
39
 
33
40
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Avatar" />,
41
+ args: {
42
+ size: "default",
43
+ variant: "solid",
44
+ },
45
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
46
+ render: ({ withLayer, layer, ...args }: any) => {
47
+ return <Avatar {...args} />;
48
+ },
49
+ };
50
+
51
+ export const TextSolidDefault: Story = {
52
+ args: {
53
+ children: "JD",
54
+ variant: "solid",
55
+ size: "default",
56
+ },
57
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
58
+ render: ({ withLayer, layer, ...args }: any) => <Avatar {...args} />,
59
+ };
60
+
61
+ export const ImageLarge: Story = {
62
+ args: {
63
+ src: "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=250&q=80",
64
+ size: "large",
65
+ },
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
67
+ render: ({ withLayer, layer, ...args }: any) => <Avatar {...args} />,
68
+ };
69
+
70
+ export const IconSmallGhost: Story = {
71
+ args: {
72
+ size: "small",
73
+ variant: "ghost",
74
+ icon: (
75
+ <svg
76
+ xmlns="http://www.w3.org/2000/svg"
77
+ width="16"
78
+ height="16"
79
+ viewBox="0 0 24 24"
80
+ fill="none"
81
+ stroke="currentColor"
82
+ strokeWidth="2"
83
+ strokeLinecap="round"
84
+ strokeLinejoin="round"
85
+ >
86
+ <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
87
+ <circle cx="12" cy="7" r="4"></circle>
88
+ </svg>
89
+ ),
90
+ },
91
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
92
+ render: ({ withLayer, layer, ...args }: any) => <Avatar {...args} />,
93
+ };
94
+
95
+ export const LayerOneOutline: Story = {
96
+ args: {
97
+ children: "L1",
98
+ variant: "outline",
99
+ size: "default",
100
+ },
101
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
102
+ render: ({ withLayer, layer, ...args }: any) => (
103
+ <Layer layer={1} style={{ padding: "24px", display: "inline-block" }}>
104
+ <Avatar {...args} />
105
+ </Layer>
106
+ ),
35
107
  };
@@ -1,8 +1,101 @@
1
- import React from "react";
2
- import "./Avatar.module.css";
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ Avatar as MuiAvatar,
4
+ type AvatarProps as MuiAvatarProps,
5
+ } from "@mui/material";
6
+ import {
7
+ filterStylingProps,
8
+ type RecursicaOverStyled,
9
+ } from "../../utils/filterStylingProps";
10
+ import styles from "./Avatar.module.css";
3
11
 
4
- export type AvatarProps = React.HTMLAttributes<HTMLDivElement>;
12
+ import { type RecursicaAvatarProps } from "@recursica/adapter-common";
5
13
 
6
- export const Avatar: React.FC<AvatarProps> = (props) => {
7
- return <div {...props}>Avatar</div>;
8
- };
14
+ export type AvatarProps = RecursicaOverStyled<
15
+ Omit<MuiAvatarProps, "variant" | "size" | "color" | "radius"> &
16
+ RecursicaAvatarProps
17
+ >;
18
+
19
+ const _Avatar = forwardRef<HTMLDivElement, AvatarProps>(function Avatar(
20
+ {
21
+ size = "default",
22
+ variant = "solid",
23
+ icon,
24
+ children,
25
+ src,
26
+ overStyled = false,
27
+ ...rest
28
+ },
29
+ ref,
30
+ ) {
31
+ const mapVariant = {
32
+ solid: "filled",
33
+ outline: "outline",
34
+ ghost: "transparent",
35
+ } as const;
36
+
37
+ const sanitizedProps = filterStylingProps(rest, overStyled);
38
+ const restRecord = sanitizedProps as Record<string, unknown>;
39
+
40
+ // Determine semantic style based on provided props
41
+ let computedStyle = "text";
42
+ if (src) {
43
+ computedStyle = "image";
44
+ } else if (icon) {
45
+ computedStyle = "icon";
46
+ }
47
+
48
+ const mergedClassNames: Partial<Record<string, string>> = {
49
+ root: styles.root,
50
+ image: styles.image,
51
+ placeholder: styles.placeholder,
52
+ };
53
+
54
+ const classNamesProp = restRecord.classNames;
55
+ if (
56
+ classNamesProp &&
57
+ typeof classNamesProp === "object" &&
58
+ !Array.isArray(classNamesProp)
59
+ ) {
60
+ const o = classNamesProp as Partial<Record<string, string>>;
61
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
62
+ mergedClassNames.image = o.image
63
+ ? `${styles.image} ${o.image}`
64
+ : styles.image;
65
+ mergedClassNames.placeholder = o.placeholder
66
+ ? `${styles.placeholder} ${o.placeholder}`
67
+ : styles.placeholder;
68
+ }
69
+
70
+ const classNameProp = restRecord.className as string | undefined;
71
+
72
+ return (
73
+ <MuiAvatar
74
+ ref={ref}
75
+ className={classNameProp}
76
+ classes={mergedClassNames}
77
+ variant={mapVariant[variant] as any}
78
+ src={src}
79
+ data-variant={variant}
80
+ data-size={size}
81
+ data-style={computedStyle}
82
+ {...sanitizedProps}
83
+ >
84
+ {icon != null ? (
85
+ <span className={styles.iconWrapper} aria-hidden>
86
+ {icon}
87
+ </span>
88
+ ) : children != null ? (
89
+ <span className={styles.textWrapper}>{children}</span>
90
+ ) : undefined}
91
+ </MuiAvatar>
92
+ );
93
+ });
94
+ _Avatar.displayName = "Avatar";
95
+
96
+ /**
97
+ * Recursica Avatar component wrapping Mui's Avatar.
98
+ *
99
+ * Supports polymorphism via the `component` prop or `renderRoot` for custom element rendering.
100
+ */
101
+ export const Avatar = _Avatar as any;
@@ -1,29 +1,127 @@
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_badge_properties_border-radius */
6
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_border-size */
7
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_elevation */
8
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_padding-horizontal */
9
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_padding-vertical */
10
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_font-family */
11
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_font-size */
12
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_font-style */
13
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_font-weight */
14
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_letter-spacing */
15
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_line-height */
16
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_text-decoration */
17
- /* recursica-ignore: --recursica_ui-kit_components_badge_properties_text_text-transform */
18
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_background */
19
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_border-color */
20
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_text */
21
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_background */
22
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_border-color */
23
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_text */
24
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_background */
25
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_border-color */
26
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_text */
27
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_background */
28
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_border-color */
29
- /* recursica-ignore: --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_text */
1
+ /* HARDCODED VALUES:
2
+ - border-style: solid (needs a token if we support other border styles)
3
+ - box-sizing: border-box
4
+ - display: inline-flex
5
+ - align-items: center
6
+ - justify-content: center
7
+ - text-transform: uppercase (Mantine does this, but our tokens also specify it so we map it)
8
+ */
9
+
10
+ .root {
11
+ /* HARDCODE: Basic structural assumptions */
12
+ box-sizing: border-box;
13
+ display: inline-flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ border-style: solid;
17
+
18
+ /* Base style resets to fully clear Mantine's defaults before applying ours */
19
+ background-color: transparent;
20
+ color: inherit;
21
+ border-color: transparent;
22
+
23
+ /* Apply global badge properties */
24
+ border-radius: var(
25
+ --recursica_ui-kit_components_badge_properties_border-radius
26
+ );
27
+ border-width: var(--recursica_ui-kit_components_badge_properties_border-size);
28
+ box-shadow: var(--recursica_ui-kit_components_badge_properties_elevation);
29
+
30
+ padding-left: var(
31
+ --recursica_ui-kit_components_badge_properties_padding-horizontal
32
+ );
33
+ padding-right: var(
34
+ --recursica_ui-kit_components_badge_properties_padding-horizontal
35
+ );
36
+ padding-top: var(
37
+ --recursica_ui-kit_components_badge_properties_padding-vertical
38
+ );
39
+ padding-bottom: var(
40
+ --recursica_ui-kit_components_badge_properties_padding-vertical
41
+ );
42
+
43
+ font-family: var(
44
+ --recursica_ui-kit_components_badge_properties_text_font-family
45
+ );
46
+ font-size: var(--recursica_ui-kit_components_badge_properties_text_font-size);
47
+ font-weight: var(
48
+ --recursica_ui-kit_components_badge_properties_text_font-weight
49
+ );
50
+ font-style: var(
51
+ --recursica_ui-kit_components_badge_properties_text_font-style
52
+ );
53
+ letter-spacing: var(
54
+ --recursica_ui-kit_components_badge_properties_text_letter-spacing
55
+ );
56
+ line-height: var(
57
+ --recursica_ui-kit_components_badge_properties_text_line-height
58
+ );
59
+ text-decoration: var(
60
+ --recursica_ui-kit_components_badge_properties_text_text-decoration
61
+ );
62
+ text-transform: var(
63
+ --recursica_ui-kit_components_badge_properties_text_text-transform
64
+ );
65
+ }
66
+
67
+ /* Variant Definitions */
68
+
69
+ .root[data-variant="alert"] {
70
+ background-color: var(
71
+ --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_background
72
+ );
73
+ border-color: var(
74
+ --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_border-color
75
+ );
76
+ color: var(
77
+ --recursica_ui-kit_components_badge_variants_styles_alert_properties_colors_text
78
+ );
79
+ }
80
+
81
+ .root[data-variant="primary-color"] {
82
+ background-color: var(
83
+ --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_background
84
+ );
85
+ border-color: var(
86
+ --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_border-color
87
+ );
88
+ color: var(
89
+ --recursica_ui-kit_components_badge_variants_styles_primary-color_properties_colors_text
90
+ );
91
+ }
92
+
93
+ .root[data-variant="success"] {
94
+ background-color: var(
95
+ --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_background
96
+ );
97
+ border-color: var(
98
+ --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_border-color
99
+ );
100
+ color: var(
101
+ --recursica_ui-kit_components_badge_variants_styles_success_properties_colors_text
102
+ );
103
+ }
104
+
105
+ .root[data-variant="warning"] {
106
+ background-color: var(
107
+ --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_background
108
+ );
109
+ border-color: var(
110
+ --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_border-color
111
+ );
112
+ color: var(
113
+ --recursica_ui-kit_components_badge_variants_styles_warning_properties_colors_text
114
+ );
115
+ }
116
+
117
+ /* Target Mantine internal children if needed for typography constraints */
118
+ .root :global(.mantine-Badge-label),
119
+ .root :global(.mantine-Badge-section) {
120
+ /* HARDCODE: Prevent Mantine from overriding our typography setup inside inner wrappers */
121
+ font-size: inherit;
122
+ font-weight: inherit;
123
+ line-height: inherit;
124
+ font-family: inherit;
125
+ letter-spacing: inherit;
126
+ text-transform: inherit;
127
+ }
@@ -1,35 +1,78 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { Badge } from "./Badge";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { Layer } from "@recursica/adapter-common";
4
5
 
5
- const meta: Meta<typeof Badge> = {
6
- title: "UI-Kit/🚧 Badge",
6
+ type BadgeStoryProps = React.ComponentProps<typeof Badge>;
7
+
8
+ const meta: Meta<BadgeStoryProps> = {
9
+ title: "UI-Kit/Badge",
7
10
  component: Badge,
8
11
  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
- ],
12
+ argTypes: {
13
+ variant: {
14
+ control: "select",
15
+ options: ["alert", "primary-color", "success", "warning"],
16
+ description: "The style / intent mapping for the badge",
26
17
  },
27
18
  },
28
19
  };
29
20
 
30
21
  export default meta;
31
- type Story = StoryObj<typeof Badge>;
22
+
23
+ type Story = StoryObj<BadgeStoryProps>;
32
24
 
33
25
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Badge" />,
26
+ args: {
27
+ children: "Badge Label",
28
+ variant: "primary-color",
29
+ },
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
31
+ render: ({ withLayer, layer, ...args }: any) => {
32
+ return <Badge {...args} />;
33
+ },
34
+ };
35
+
36
+ export const StaticAlert: Story = {
37
+ args: {
38
+ children: "Alert Badge",
39
+ variant: "alert",
40
+ },
41
+ render: (args: BadgeStoryProps) => <Badge {...args} />,
42
+ };
43
+
44
+ export const StaticPrimary: Story = {
45
+ args: {
46
+ children: "Primary Badge",
47
+ variant: "primary-color",
48
+ },
49
+ render: (args: BadgeStoryProps) => <Badge {...args} />,
50
+ };
51
+
52
+ export const StaticSuccess: Story = {
53
+ args: {
54
+ children: "Success Badge",
55
+ variant: "success",
56
+ },
57
+ render: (args: BadgeStoryProps) => <Badge {...args} />,
58
+ };
59
+
60
+ export const StaticWarning: Story = {
61
+ args: {
62
+ children: "Warning Badge",
63
+ variant: "warning",
64
+ },
65
+ render: (args: BadgeStoryProps) => <Badge {...args} />,
66
+ };
67
+
68
+ export const LayerOneAlert: Story = {
69
+ args: {
70
+ children: "Layer 1 Alert",
71
+ variant: "alert",
72
+ },
73
+ render: (args: BadgeStoryProps) => (
74
+ <Layer layer={1} style={{ padding: "24px" }}>
75
+ <Badge {...args} />
76
+ </Layer>
77
+ ),
35
78
  };
@@ -1,8 +1,69 @@
1
- import React from "react";
2
- import "./Badge.module.css";
1
+ import { forwardRef } from "react";
2
+ import {
3
+ Badge as MuiBadge,
4
+ type BadgeProps as MuiBadgeProps,
5
+ } from "@mui/material";
6
+ import {
7
+ filterStylingProps,
8
+ type RecursicaOverStyled,
9
+ } from "../../utils/filterStylingProps";
10
+ import styles from "./Badge.module.css";
3
11
 
4
- export type BadgeProps = React.HTMLAttributes<HTMLDivElement>;
12
+ import { type RecursicaBadgeProps } from "@recursica/adapter-common";
5
13
 
6
- export const Badge: React.FC<BadgeProps> = (props) => {
7
- return <div {...props}>Badge</div>;
8
- };
14
+ export type BadgeProps = RecursicaOverStyled<
15
+ Omit<MuiBadgeProps, "variant" | "size" | "color" | "radius"> &
16
+ RecursicaBadgeProps
17
+ >;
18
+
19
+ const _Badge = forwardRef<HTMLDivElement, BadgeProps>(function Badge(
20
+ { variant = "primary-color", overStyled = false, ...rest },
21
+ ref,
22
+ ) {
23
+ // Strip all visual override injections unless developer has specifically opted into overStyling.
24
+ // External layout props like margins are safely preserved.
25
+ const sanitizedProps = filterStylingProps(rest, overStyled);
26
+
27
+ const mergedClassNames: Partial<Record<string, string>> = {
28
+ root: styles.root,
29
+ section: styles.section,
30
+ label: styles.label,
31
+ };
32
+
33
+ const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
34
+ if (
35
+ classNamesProp &&
36
+ typeof classNamesProp === "object" &&
37
+ !Array.isArray(classNamesProp)
38
+ ) {
39
+ const o = classNamesProp as Partial<Record<string, string>>;
40
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
41
+ mergedClassNames.section = o.section ?? styles.section;
42
+ mergedClassNames.label = o.label ?? styles.label;
43
+ }
44
+
45
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
46
+ .className as string | undefined;
47
+ const finalClass = classNameProp
48
+ ? `${styles.root} ${classNameProp}`
49
+ : styles.root;
50
+
51
+ return (
52
+ <MuiBadge
53
+ ref={ref}
54
+ variant="standard" // We manage visual style purely through our CSS variables mapping
55
+ data-variant={variant}
56
+ {...sanitizedProps}
57
+ className={finalClass}
58
+ classes={mergedClassNames}
59
+ />
60
+ );
61
+ });
62
+ _Badge.displayName = "Badge";
63
+
64
+ /**
65
+ * Recursica Badge component wrapping Mui's Badge.
66
+ *
67
+ * Supports polymorphism via the `component` prop or `renderRoot` for custom element rendering.
68
+ */
69
+ export const Badge = _Badge as any;
@@ -1,6 +1,26 @@
1
- /* EXEMPTIONS:
2
- This component is a placeholder stub. Once fully implemented, its specific
3
- tokens will be fully wired up to direct styles. */
1
+ /* HARDCODED VALUES:
2
+ - align-items: center
3
+ */
4
4
 
5
- /* recursica-ignore: --recursica_ui-kit_components_breadcrumb_properties_item-gap */
6
- /* recursica-ignore: --recursica_ui-kit_components_breadcrumb_properties_padding */
5
+ .root {
6
+ /* HARDCODE: Basic structural flex layout for breadcrumbs */
7
+ display: flex;
8
+ align-items: center;
9
+
10
+ /* Base style resets */
11
+ background-color: transparent;
12
+ color: inherit;
13
+
14
+ /* Apply global breadcrumb properties */
15
+ padding: var(--recursica_ui-kit_components_breadcrumb_properties_padding);
16
+
17
+ /* Mantine's breadcrumbs uses gap on the root or pseudo classes, but standard gap is safest since flex is used */
18
+ gap: var(--recursica_ui-kit_components_breadcrumb_properties_item-gap);
19
+ }
20
+
21
+ .separator {
22
+ /* Separator base resets if needed */
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ }