@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,133 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Card } from "./Card";
3
- import { ComingSoon } from "@recursica/storybook-template";
3
+ import { Layer } from "@recursica/adapter-common";
4
+ import { Button } from "../Button/Button";
5
+ import { Group } from "../Group/Group";
6
+ import { Text } from "../Text/Text";
4
7
 
5
8
  const meta: Meta<typeof Card> = {
6
- title: "UI-Kit/🚧 Card",
9
+ title: "UI-Kit/Card",
7
10
  component: Card,
11
+ subcomponents: {
12
+ "Card.Header": Card.Header,
13
+ "Card.Content": Card.Content,
14
+ "Card.Footer": Card.Footer,
15
+ "Card.Section": Card.Section,
16
+ } as Record<string, React.ComponentType<unknown>>,
8
17
  tags: ["autodocs"],
9
18
  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
- ],
19
+ docs: {
20
+ description: {
21
+ component:
22
+ "The Card component acts as the foundational padded surface for grouping related information. It relies on standard internal compositional nodes (`Card.Header`, `Card.Content`, `Card.Footer`) mapped directly to the active Recursica design tokens to enforce layout gaps and margins seamlessly. Use the provided dot-notation wrappers rather than building ad-hoc generic sections.",
23
+ },
26
24
  },
27
25
  },
26
+ argTypes: {},
28
27
  };
29
28
 
30
29
  export default meta;
30
+
31
31
  type Story = StoryObj<typeof Card>;
32
32
 
33
33
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="Card" />,
34
+ args: {},
35
+ render: ({ ...args }) => {
36
+ return (
37
+ <div
38
+ style={{
39
+ padding: "48px",
40
+ backgroundColor:
41
+ "var(--recursica_brand_palettes_neutral_050_color_tone)",
42
+ }}
43
+ >
44
+ <Layer layer={0}>
45
+ <Card {...args}>
46
+ <Card.Header>Customer Activity Report</Card.Header>
47
+ <Card.Content>
48
+ <Text>
49
+ Card inner section content body. Notice how this acts as padded
50
+ content natively based on the overarching properties.
51
+ Recursica's vertical gutter governs vertical spacing between
52
+ siblings in the flex container.
53
+ </Text>
54
+ <Text>Another section showing the vertical gutter spacing.</Text>
55
+ </Card.Content>
56
+ <Card.Footer>
57
+ <Group justify="space-between" align="center">
58
+ <Text variant="caption">Generated today</Text>
59
+ <Button variant="solid">View Details</Button>
60
+ </Group>
61
+ </Card.Footer>
62
+ </Card>
63
+ </Layer>
64
+ </div>
65
+ );
66
+ },
67
+ };
68
+
69
+ export const HeaderlessAndFooterless: Story = {
70
+ args: {},
71
+ render: ({ ...args }) => {
72
+ return (
73
+ <div
74
+ style={{
75
+ padding: "48px",
76
+ backgroundColor:
77
+ "var(--recursica_brand_palettes_neutral_050_color_tone)",
78
+ }}
79
+ >
80
+ <Layer layer={0}>
81
+ <Card {...args}>
82
+ <Card.Content>
83
+ <Text variant="subtitle">Notice</Text>
84
+ <Text>
85
+ This is a completely generic card payload dropping the Header
86
+ and Footer specific elements, simply acting as a padded
87
+ elevation boundary box directly mirroring native composability!
88
+ </Text>
89
+ <Button variant="solid">Acknowledge</Button>
90
+ </Card.Content>
91
+ </Card>
92
+ </Layer>
93
+ </div>
94
+ );
95
+ },
96
+ };
97
+
98
+ export const LayerDemonstration: Story = {
99
+ args: {},
100
+ render: ({ ...args }) => {
101
+ return (
102
+ <div
103
+ style={{
104
+ display: "flex",
105
+ gap: "32px",
106
+ backgroundColor: "#e9ecef",
107
+ padding: "32px",
108
+ }}
109
+ >
110
+ <Layer layer={1}>
111
+ <Card {...args}>
112
+ <Card.Header>Layer 1 Wrapper</Card.Header>
113
+ <Card.Content>
114
+ <Text>Content inside layer 1 card.</Text>
115
+ </Card.Content>
116
+ </Card>
117
+ </Layer>
118
+
119
+ <Layer layer={2}>
120
+ <Card {...args}>
121
+ <Card.Header>Layer 2 Wrapper</Card.Header>
122
+ <Card.Content>
123
+ <Text>
124
+ Content inside layer 2 card exposing a higher elevation drop
125
+ shadow inherently cascaded.
126
+ </Text>
127
+ </Card.Content>
128
+ </Card>
129
+ </Layer>
130
+ </div>
131
+ );
132
+ },
35
133
  };
@@ -1,8 +1,184 @@
1
- import React from "react";
2
- import "./Card.module.css";
1
+ import { forwardRef } from "react";
2
+ import { Card as MuiCard, type CardProps as MuiCardProps } from "@mui/material";
3
+ import {
4
+ filterStylingProps,
5
+ type RecursicaOverStyled,
6
+ } from "../../utils/filterStylingProps";
7
+ import styles from "./Card.module.css";
3
8
 
4
- export type CardProps = React.HTMLAttributes<HTMLDivElement>;
9
+ import {
10
+ type RecursicaCardProps,
11
+ type RecursicaCardSectionProps,
12
+ } from "@recursica/adapter-common";
5
13
 
6
- export const Card: React.FC<CardProps> = (props) => {
7
- return <div {...props}>Card</div>;
14
+ // ==== CARD CONTAINER ====
15
+ export type CardProps = RecursicaOverStyled<MuiCardProps & RecursicaCardProps>;
16
+
17
+ /**
18
+ * The root Card elevation box. It establishes the global background color, border radius, nested component gap, and outer shadow governed by the current `Layer` context.
19
+ */
20
+ const CardBase = forwardRef<HTMLDivElement, CardProps>(function Card(
21
+ { overStyled = false, ...rest },
22
+ ref,
23
+ ) {
24
+ const sanitizedProps = filterStylingProps(rest, overStyled);
25
+
26
+ const mergedClassNames: Partial<Record<string, string>> = {
27
+ root: styles.root,
28
+ };
29
+
30
+ const classNamesProp = (sanitizedProps as Record<string, unknown>).classNames;
31
+ if (
32
+ classNamesProp &&
33
+ typeof classNamesProp === "object" &&
34
+ !Array.isArray(classNamesProp)
35
+ ) {
36
+ const o = classNamesProp as Record<string, string>;
37
+ Object.keys(o).forEach((key) => {
38
+ if (mergedClassNames[key]) {
39
+ mergedClassNames[key] = `${mergedClassNames[key]} ${o[key]}`;
40
+ } else {
41
+ mergedClassNames[key] = o[key];
42
+ }
43
+ });
44
+ }
45
+
46
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
47
+ .className as string | undefined;
48
+
49
+ return (
50
+ <MuiCard
51
+ ref={ref}
52
+ className={classNameProp}
53
+ classes={mergedClassNames}
54
+ {...(sanitizedProps as unknown as MuiCardProps)}
55
+ />
56
+ );
57
+ });
58
+ CardBase.displayName = "Card";
59
+
60
+ // ==== NATIVE MANTINE CARD.SECTION ====
61
+ export type CardSectionProps = RecursicaOverStyled<RecursicaCardSectionProps>;
62
+
63
+ /**
64
+ * A generalized edge-to-edge structural wrapper native to Mui. Strips typical boundary padding via negative margins to allow content (like maps or header images) to touch the border seamlessly.
65
+ */
66
+ export const CardSection = forwardRef<HTMLDivElement, CardSectionProps>(
67
+ function CardSection({ overStyled = false, ...rest }, ref) {
68
+ const sanitizedProps = filterStylingProps(rest, overStyled);
69
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
70
+ .className as string | undefined;
71
+
72
+ return (
73
+ <div
74
+ ref={ref}
75
+ className={
76
+ classNameProp ? `${styles.section} ${classNameProp}` : styles.section
77
+ }
78
+ {...(sanitizedProps as unknown as React.HTMLAttributes<HTMLDivElement>)}
79
+ />
80
+ );
81
+ },
82
+ );
83
+ CardSection.displayName = "CardSection";
84
+
85
+ // ==== EXPLICIT CARD.HEADER ====
86
+ export type CardHeaderProps = RecursicaOverStyled<RecursicaCardSectionProps>;
87
+
88
+ /**
89
+ * Replaces standard generic Mui `<Card.Section>` wrappers by directly injecting the strict Recursica design tokens for header sizing, background drops, and intrinsic padding limits.
90
+ */
91
+ export const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(
92
+ function CardHeader({ overStyled = false, ...rest }, ref) {
93
+ const sanitizedProps = filterStylingProps(rest, overStyled);
94
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
95
+ .className as string | undefined;
96
+
97
+ return (
98
+ <div
99
+ ref={ref}
100
+ className={
101
+ classNameProp ? `${styles.header} ${classNameProp}` : styles.header
102
+ }
103
+ {...(sanitizedProps as unknown as React.HTMLAttributes<HTMLDivElement>)}
104
+ />
105
+ );
106
+ },
107
+ );
108
+ CardHeader.displayName = "CardHeader";
109
+
110
+ // ==== EXPLICIT CARD.FOOTER ====
111
+ export type CardFooterProps = RecursicaOverStyled<RecursicaCardSectionProps>;
112
+
113
+ /**
114
+ * Counterpart to `Card.Header`, applying specific footer elevation margins, sizes, and padding natively.
115
+ */
116
+ export const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(
117
+ function CardFooter({ overStyled = false, ...rest }, ref) {
118
+ const sanitizedProps = filterStylingProps(rest, overStyled);
119
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
120
+ .className as string | undefined;
121
+
122
+ return (
123
+ <div
124
+ ref={ref}
125
+ className={
126
+ classNameProp ? `${styles.footer} ${classNameProp}` : styles.footer
127
+ }
128
+ {...(sanitizedProps as unknown as React.HTMLAttributes<HTMLDivElement>)}
129
+ />
130
+ );
131
+ },
132
+ );
133
+ CardFooter.displayName = "CardFooter";
134
+
135
+ // ==== EXPLICIT CARD.CONTENT ====
136
+ export type CardContentProps = RecursicaOverStyled<
137
+ React.HTMLAttributes<HTMLDivElement>
138
+ >;
139
+
140
+ /**
141
+ * Internal container that safely binds typography and structural flex gaps driven by the active UI kit tokens natively, preserving correct padding blocks compared to rigid `Card.Section` edges.
142
+ */
143
+ export const CardContent = forwardRef<HTMLDivElement, CardContentProps>(
144
+ function CardContent({ overStyled = false, ...rest }, ref) {
145
+ const sanitizedProps = filterStylingProps(rest, overStyled);
146
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
147
+ .className as string | undefined;
148
+
149
+ return (
150
+ <div
151
+ ref={ref}
152
+ className={
153
+ classNameProp ? `${styles.content} ${classNameProp}` : styles.content
154
+ }
155
+ {...sanitizedProps}
156
+ />
157
+ );
158
+ },
159
+ );
160
+ CardContent.displayName = "CardContent";
161
+
162
+ // ==== DOT NOTATION EXPORT ====
163
+
164
+ /**
165
+ * Recursica Card component wrapping Mui's Card (Paper).
166
+ *
167
+ * Supports polymorphism via the `component` prop or `renderRoot` for custom element rendering.
168
+ * Use dot-notation sub-components for structured card layouts.
169
+ */
170
+ const PolymorphicCard = CardBase as any;
171
+
172
+ // Attach static components for dot-notation access
173
+ const _card = PolymorphicCard as unknown as Record<string, unknown>;
174
+ _card.Section = CardSection;
175
+ _card.Header = CardHeader;
176
+ _card.Footer = CardFooter;
177
+ _card.Content = CardContent;
178
+
179
+ export const Card = PolymorphicCard as typeof PolymorphicCard & {
180
+ Section: typeof CardSection;
181
+ Header: typeof CardHeader;
182
+ Footer: typeof CardFooter;
183
+ Content: typeof CardContent;
8
184
  };
@@ -1,39 +1,249 @@
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_checkbox-group_properties_item-gap */
6
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_properties_padding */
7
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_gutter */
8
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_top-bottom-margin */
9
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_vertical-padding */
10
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_variants_layouts_stacked_properties_label-field-gap */
11
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-group_variants_layouts_stacked_properties_top-bottom-margin */
12
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_colors_disabled-text */
13
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_colors_text */
14
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_disabled-opacity */
15
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_label-gap */
16
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_max-width */
17
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_font-family */
18
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_font-size */
19
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_font-style */
20
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_font-weight */
21
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_letter-spacing */
22
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_line-height */
23
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_text-decoration */
24
- /* recursica-ignore: --recursica_ui-kit_components_checkbox-item_properties_text_text-transform */
25
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_border-radius */
26
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_border-size */
27
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_background-checked */
28
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_background-indeterminate */
29
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_background-unchecked */
30
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_border-checked */
31
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_border-indeterminate */
32
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_border-unchecked */
33
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_disabled-background */
34
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_disabled-border */
35
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_disabled-icon */
36
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_colors_icon-color */
37
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_disabled-opacity */
38
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_icon-size */
39
- /* recursica-ignore: --recursica_ui-kit_components_checkbox_properties_size */
1
+ /**
2
+ * Checkbox.module.css
3
+ *
4
+ * HARDCODED VALUES:
5
+ * - margin / padding: 0 — Structural resets; consider token if spacing needed.
6
+ * - cursor: pointer / not-allowed — Baseline interactive indications.
7
+ * - appearance / box-sizing / border-style — necessary normalization for inputs.
8
+ * - transition: all 0.2s ease — Animation curve; consider a transition token.
9
+ * - min-width: 0 — Forces text wrap boundary in flex children.
10
+ */
11
+
12
+ /* --- GROUP STYLES --- */
13
+ .groupRoot {
14
+ padding: var(--recursica_ui-kit_components_checkbox-group_properties_padding);
15
+ margin: 0; /* HARDCODE: structural reset; consider token if layout needs change */
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--recursica_ui-kit_components_checkbox-group_properties_item-gap);
19
+ }
20
+
21
+ /* SideBySide Variant */
22
+ .groupRoot[data-layout="side-by-side"] {
23
+ flex-direction: column;
24
+ flex-wrap: wrap;
25
+ padding-top: var(
26
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_vertical-padding
27
+ );
28
+ padding-bottom: var(
29
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_vertical-padding
30
+ );
31
+ margin-top: var(
32
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_top-bottom-margin
33
+ );
34
+ margin-bottom: var(
35
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_top-bottom-margin
36
+ );
37
+ }
38
+
39
+ /* Stacked Variant */
40
+ .groupRoot[data-layout="stacked"] {
41
+ flex-direction: column;
42
+ margin-top: var(
43
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_stacked_properties_top-bottom-margin
44
+ );
45
+ margin-bottom: var(
46
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_stacked_properties_top-bottom-margin
47
+ );
48
+ }
49
+
50
+ /* --- PRIMITIVE CHECKBOX STYLES --- */
51
+
52
+ .root {
53
+ max-width: var(
54
+ --recursica_ui-kit_components_checkbox-item_properties_max-width
55
+ );
56
+ }
57
+
58
+ .body {
59
+ display: flex;
60
+ align-items: flex-start;
61
+ gap: var(--recursica_ui-kit_components_checkbox-item_properties_label-gap);
62
+ }
63
+
64
+ .inner {
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ margin: 0; /* HARDCODE: structural reset */
69
+ width: var(--recursica_ui-kit_components_checkbox_properties_size);
70
+ height: var(--recursica_ui-kit_components_checkbox_properties_size);
71
+ /* Apply font-size to this element so that an 'em' based line-height token evaluates to the correct exact pixel value. */
72
+ font-size: var(
73
+ --recursica_ui-kit_components_checkbox-item_properties_text_font-size
74
+ );
75
+ /* Mathematically syncs the physical input checkbox bounding block visually with the center of the text's first line.
76
+ NOTE: Since the Figma line-height token resolves to an 'em' length (e.g. 1.05em), we CANNOT multiply it by font-size in CSS.
77
+ Instead, it naturally evaluates to the correct height because we applied the font-size above. */
78
+ margin-top: calc(
79
+ (
80
+ var(
81
+ --recursica_ui-kit_components_checkbox-item_properties_text_line-height
82
+ ) -
83
+ var(--recursica_ui-kit_components_checkbox_properties_size)
84
+ ) /
85
+ 2
86
+ );
87
+ }
88
+
89
+ /* Base explicit reset masking underlying framework defaults */
90
+ .input {
91
+ cursor: pointer; /* HARDCODE: core interaction behavior */
92
+ appearance: none; /* HARDCODE: reset native widget */
93
+ box-sizing: border-box; /* HARDCODE: ensures size includes borders */
94
+ width: var(--recursica_ui-kit_components_checkbox_properties_size);
95
+ height: var(--recursica_ui-kit_components_checkbox_properties_size);
96
+ border-radius: var(
97
+ --recursica_ui-kit_components_checkbox_properties_border-radius
98
+ );
99
+ border-width: var(
100
+ --recursica_ui-kit_components_checkbox_properties_border-size
101
+ );
102
+ border-style: solid; /* HARDCODE: normalize primitive border-style */
103
+
104
+ /* Standard unchecked state */
105
+ background-color: var(
106
+ --recursica_ui-kit_components_checkbox_properties_colors_background-unchecked
107
+ );
108
+ border-color: var(
109
+ --recursica_ui-kit_components_checkbox_properties_colors_border-unchecked
110
+ );
111
+ transition: all 0.2s ease; /* HARDCODE: consider global transition token */
112
+ }
113
+
114
+ /* Checked/Indeterminate State */
115
+ .input:checked,
116
+ .inputChecked {
117
+ background-color: var(
118
+ --recursica_ui-kit_components_checkbox_properties_colors_background-checked
119
+ );
120
+ border-color: var(
121
+ --recursica_ui-kit_components_checkbox_properties_colors_border-checked
122
+ );
123
+ }
124
+ .input[data-indeterminate],
125
+ .inputIndeterminate {
126
+ background-color: var(
127
+ --recursica_ui-kit_components_checkbox_properties_colors_background-indeterminate
128
+ );
129
+ border-color: var(
130
+ --recursica_ui-kit_components_checkbox_properties_colors_border-indeterminate
131
+ );
132
+ }
133
+
134
+ /* Disabled State */
135
+ .input:disabled {
136
+ cursor: not-allowed; /* HARDCODE: disabled state default */
137
+ opacity: var(
138
+ --recursica_ui-kit_components_checkbox_properties_disabled-opacity
139
+ );
140
+ background-color: var(
141
+ --recursica_ui-kit_components_checkbox_properties_colors_disabled-background
142
+ );
143
+ border-color: var(
144
+ --recursica_ui-kit_components_checkbox_properties_colors_disabled-border
145
+ );
146
+ }
147
+
148
+ .icon {
149
+ width: var(--recursica_ui-kit_components_checkbox_properties_icon-size);
150
+ height: var(--recursica_ui-kit_components_checkbox_properties_icon-size);
151
+ color: var(
152
+ --recursica_ui-kit_components_checkbox_properties_colors_icon-color
153
+ );
154
+ }
155
+ .input:disabled + .icon {
156
+ color: var(
157
+ --recursica_ui-kit_components_checkbox_properties_colors_disabled-icon
158
+ );
159
+ }
160
+
161
+ .labelWrapper {
162
+ padding: 0; /* HARDCODE: structural layout reset */
163
+ margin: 0; /* HARDCODE: structural layout reset */
164
+ flex: 1;
165
+ min-width: 0; /* HARDCODE: forces text wrap boundary in flex child */
166
+ }
167
+
168
+ .label {
169
+ cursor: pointer; /* HARDCODE: interactive affordance */
170
+ padding: 0; /* HARDCODE: reset layout */
171
+ margin: 0; /* HARDCODE: reset layout */
172
+ word-wrap: break-word;
173
+ white-space: normal;
174
+ color: var(
175
+ --recursica_ui-kit_components_checkbox-item_properties_colors_text
176
+ );
177
+ font-family: var(
178
+ --recursica_ui-kit_components_checkbox-item_properties_text_font-family
179
+ );
180
+ font-size: var(
181
+ --recursica_ui-kit_components_checkbox-item_properties_text_font-size
182
+ );
183
+ font-weight: var(
184
+ --recursica_ui-kit_components_checkbox-item_properties_text_font-weight
185
+ );
186
+ line-height: var(
187
+ --recursica_ui-kit_components_checkbox-item_properties_text_line-height
188
+ );
189
+ font-style: var(
190
+ --recursica_ui-kit_components_checkbox-item_properties_text_font-style
191
+ );
192
+ letter-spacing: var(
193
+ --recursica_ui-kit_components_checkbox-item_properties_text_letter-spacing
194
+ );
195
+ text-decoration: var(
196
+ --recursica_ui-kit_components_checkbox-item_properties_text_text-decoration
197
+ );
198
+ text-transform: var(
199
+ --recursica_ui-kit_components_checkbox-item_properties_text_text-transform
200
+ );
201
+ }
202
+ .root:has(input:disabled) .label {
203
+ cursor: not-allowed; /* HARDCODE: disabled interaction */
204
+ opacity: var(
205
+ --recursica_ui-kit_components_checkbox-item_properties_disabled-opacity
206
+ );
207
+ color: var(
208
+ --recursica_ui-kit_components_checkbox-item_properties_colors_disabled-text
209
+ );
210
+ }
211
+
212
+ .description {
213
+ margin-top: 5px; /* HARDCODE: mantine default */
214
+ color: #868e96; /* HARDCODE: mantine default dimmed */
215
+ font-size: 12px; /* HARDCODE: mantine default xs */
216
+ line-height: 1.2;
217
+ }
218
+
219
+ .error {
220
+ margin-top: 5px; /* HARDCODE: mantine default */
221
+ color: #fa5252; /* HARDCODE: mantine default error */
222
+ font-size: 12px; /* HARDCODE: mantine default xs */
223
+ line-height: 1.2;
224
+ }
225
+
226
+ .description[data-disabled="true"],
227
+ .error[data-disabled="true"] {
228
+ opacity: var(
229
+ --recursica_ui-kit_components_checkbox-item_properties_disabled-opacity
230
+ );
231
+ }
232
+
233
+ /* CheckboxGroup Layouts */
234
+ .groupRoot {
235
+ display: flex;
236
+ }
237
+ .groupRoot[data-layout="stacked"] {
238
+ flex-direction: column;
239
+ gap: var(
240
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_stacked_properties_label-field-gap
241
+ );
242
+ }
243
+ .groupRoot[data-layout="side-by-side"] {
244
+ flex-direction: row;
245
+ flex-wrap: wrap;
246
+ gap: var(
247
+ --recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_gutter
248
+ );
249
+ }