@recursica/mui-adapter 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +15 -0
- package/CHANGELOG.md +15 -0
- package/SETUP.md +77 -0
- package/USAGE.md +55 -0
- package/dist/mui-adapter.cjs +74 -1
- package/dist/mui-adapter.cjs.map +1 -1
- package/dist/mui-adapter.css +1 -1
- package/dist/mui-adapter.js +6863 -205
- package/dist/mui-adapter.js.map +1 -1
- package/dist/src/components/Accordion/Accordion.d.ts +43 -2
- package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
- package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
- package/dist/src/components/Avatar/Avatar.d.ts +10 -3
- package/dist/src/components/Badge/Badge.d.ts +10 -3
- package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
- package/dist/src/components/Button/Button.d.ts +2 -17
- package/dist/src/components/Card/Card.d.ts +38 -3
- package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
- package/dist/src/components/Checkbox/index.d.ts +5 -1
- package/dist/src/components/Chip/Chip.d.ts +9 -2
- package/dist/src/components/Container/Container.d.ts +1 -5
- package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/src/components/Flex/Flex.d.ts +2 -22
- package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
- package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
- package/dist/src/components/Group/Group.d.ts +2 -7
- package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
- package/dist/src/components/Label/Label.d.ts +6 -2
- package/dist/src/components/Link/Link.d.ts +2 -6
- package/dist/src/components/Loader/Loader.d.ts +2 -7
- package/dist/src/components/Menu/Menu.d.ts +25 -3
- package/dist/src/components/Modal/Modal.d.ts +37 -2
- package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
- package/dist/src/components/Pagination/Pagination.d.ts +12 -3
- package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
- package/dist/src/components/Panel/Panel.d.ts +52 -3
- package/dist/src/components/Radio/Radio.d.ts +13 -3
- package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
- package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
- package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
- package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
- package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
- package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
- package/dist/src/components/Slider/Slider.d.ts +18 -2
- package/dist/src/components/Stack/Stack.d.ts +2 -5
- package/dist/src/components/Stepper/Stepper.d.ts +41 -2
- package/dist/src/components/Switch/Switch.d.ts +10 -3
- package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
- package/dist/src/components/Table/Table.d.ts +2 -1
- package/dist/src/components/Tabs/Tabs.d.ts +20 -3
- package/dist/src/components/Text/Text.d.ts +2 -16
- package/dist/src/components/TextArea/TextArea.d.ts +12 -2
- package/dist/src/components/TextField/TextField.d.ts +12 -2
- package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
- package/dist/src/components/Timeline/Timeline.d.ts +15 -2
- package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
- package/dist/src/components/Title/Title.d.ts +2 -15
- package/dist/src/components/Toast/Toast.d.ts +20 -2
- package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
- package/dist/src/components/TransferList/TransferList.d.ts +2 -1
- package/dist/src/components/Typography/Typography.d.ts +1 -1
- package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
- package/dist/src/utils/filterStylingProps.d.ts +1 -11
- package/llms.txt +16 -0
- package/package.json +14 -3
- package/src/components/Accordion/Accordion.module.css +294 -56
- package/src/components/Accordion/Accordion.stories.tsx +131 -21
- package/src/components/Accordion/Accordion.tsx +260 -5
- package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
- package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
- package/src/components/Autocomplete/Autocomplete.module.css +319 -42
- package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
- package/src/components/Autocomplete/Autocomplete.tsx +181 -6
- package/src/components/Avatar/Avatar.module.css +343 -73
- package/src/components/Avatar/Avatar.stories.tsx +94 -22
- package/src/components/Avatar/Avatar.tsx +99 -6
- package/src/components/Badge/Badge.module.css +127 -29
- package/src/components/Badge/Badge.stories.tsx +65 -22
- package/src/components/Badge/Badge.tsx +67 -6
- package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
- package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
- package/src/components/Button/Button.module.css +19 -61
- package/src/components/Button/Button.stories.tsx +24 -23
- package/src/components/Button/Button.tsx +7 -18
- package/src/components/Card/Card.module.css +154 -38
- package/src/components/Card/Card.stories.tsx +117 -19
- package/src/components/Card/Card.tsx +181 -5
- package/src/components/Checkbox/Checkbox.module.css +249 -39
- package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
- package/src/components/Checkbox/Checkbox.tsx +246 -5
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
- package/src/components/Checkbox/index.ts +6 -1
- package/src/components/Chip/Chip.module.css +246 -43
- package/src/components/Chip/Chip.stories.tsx +101 -21
- package/src/components/Chip/Chip.tsx +136 -6
- package/src/components/Container/Container.stories.tsx +103 -20
- package/src/components/Container/Container.tsx +1 -13
- package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
- package/src/components/DatePicker/DatePicker.tsx +3 -1
- package/src/components/Dropdown/Dropdown.module.css +291 -41
- package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
- package/src/components/Dropdown/Dropdown.tsx +180 -6
- package/src/components/FileInput/FileInput.stories.tsx +2 -19
- package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
- package/src/components/Flex/Flex.stories.tsx +113 -20
- package/src/components/Flex/Flex.tsx +16 -26
- package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
- package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
- package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
- package/src/components/Group/Group.stories.tsx +6 -30
- package/src/components/Group/Group.tsx +14 -9
- package/src/components/HoverCard/HoverCard.module.css +90 -22
- package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
- package/src/components/HoverCard/HoverCard.tsx +147 -5
- package/src/components/Label/Label.module.css +140 -35
- package/src/components/Label/Label.stories.tsx +108 -21
- package/src/components/Label/Label.tsx +82 -5
- package/src/components/Link/Link.module.css +4 -3
- package/src/components/Link/Link.stories.tsx +2 -8
- package/src/components/Link/Link.tsx +1 -5
- package/src/components/Loader/Loader.module.css +1 -2
- package/src/components/Loader/Loader.tsx +1 -7
- package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Menu/Menu.module.css +285 -51
- package/src/components/Menu/Menu.stories.tsx +229 -25
- package/src/components/Menu/Menu.tsx +73 -6
- package/src/components/Modal/Modal.module.css +171 -35
- package/src/components/Modal/Modal.stories.tsx +66 -22
- package/src/components/Modal/Modal.tsx +215 -5
- package/src/components/NumberInput/NumberInput.module.css +276 -42
- package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
- package/src/components/NumberInput/NumberInput.tsx +136 -6
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
- package/src/components/Pagination/Pagination.icons.tsx +66 -0
- package/src/components/Pagination/Pagination.module.css +234 -20
- package/src/components/Pagination/Pagination.stories.tsx +34 -21
- package/src/components/Pagination/Pagination.tsx +74 -6
- package/src/components/Panel/Panel.module.css +206 -38
- package/src/components/Panel/Panel.stories.tsx +214 -22
- package/src/components/Panel/Panel.tsx +130 -5
- package/src/components/Radio/Radio.module.css +235 -37
- package/src/components/Radio/Radio.stories.tsx +77 -19
- package/src/components/Radio/Radio.tsx +210 -5
- package/src/components/Radio/RadioGroup.stories.tsx +117 -0
- package/src/components/Radio/RadioGroup.tsx +125 -0
- package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
- package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
- package/src/components/ReadOnlyField/index.ts +1 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
- package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
- package/src/components/Slider/Slider.module.css +539 -86
- package/src/components/Slider/Slider.stories.tsx +157 -19
- package/src/components/Slider/Slider.tsx +283 -5
- package/src/components/Stack/Stack.stories.tsx +4 -25
- package/src/components/Stack/Stack.tsx +1 -5
- package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stepper/Stepper.module.css +410 -71
- package/src/components/Stepper/Stepper.stories.tsx +146 -20
- package/src/components/Stepper/Stepper.tsx +147 -6
- package/src/components/Switch/Switch.module.css +259 -39
- package/src/components/Switch/Switch.stories.tsx +98 -19
- package/src/components/Switch/Switch.tsx +200 -6
- package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
- package/src/components/Switch/SwitchGroup.tsx +120 -0
- package/src/components/Table/Table.stories.tsx +1 -19
- package/src/components/Table/Table.tsx +3 -1
- package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Tabs/Tabs.module.css +422 -79
- package/src/components/Tabs/Tabs.stories.tsx +156 -20
- package/src/components/Tabs/Tabs.tsx +86 -6
- package/src/components/Text/Text.stories.tsx +5 -17
- package/src/components/Text/Text.tsx +1 -15
- package/src/components/TextArea/TextArea.module.css +155 -32
- package/src/components/TextArea/TextArea.stories.tsx +80 -21
- package/src/components/TextArea/TextArea.tsx +146 -6
- package/src/components/TextField/TextField.module.css +261 -42
- package/src/components/TextField/TextField.stories.tsx +147 -20
- package/src/components/TextField/TextField.tsx +169 -6
- package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
- package/src/components/TimePicker/TimePicker.tsx +3 -1
- package/src/components/Timeline/Timeline.module.css +365 -76
- package/src/components/Timeline/Timeline.stories.tsx +114 -21
- package/src/components/Timeline/Timeline.tsx +83 -5
- package/src/components/Timeline/TimelineItem.tsx +90 -0
- package/src/components/Title/Title.stories.tsx +0 -18
- package/src/components/Title/Title.tsx +1 -7
- package/src/components/Toast/Toast.module.css +166 -28
- package/src/components/Toast/Toast.stories.tsx +54 -22
- package/src/components/Toast/Toast.tsx +124 -5
- package/src/components/Tooltip/Tooltip.module.css +89 -24
- package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
- package/src/components/Tooltip/Tooltip.tsx +88 -5
- package/src/components/TransferList/TransferList.stories.tsx +1 -19
- package/src/components/TransferList/TransferList.tsx +3 -1
- package/src/utils/RequireAccessibleLabel.ts +1 -12
- package/src/utils/filterStylingProps.ts +7 -20
|
@@ -1,35 +1,133 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import { Card } from "./Card";
|
|
3
|
-
import {
|
|
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
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"component",
|
|
16
|
-
"variant",
|
|
17
|
-
"size",
|
|
18
|
-
"icon",
|
|
19
|
-
"disabled",
|
|
20
|
-
"href",
|
|
21
|
-
"onClick",
|
|
22
|
-
"onChange",
|
|
23
|
-
"value",
|
|
24
|
-
"checked",
|
|
25
|
-
],
|
|
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
|
-
|
|
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
|
|
2
|
-
import
|
|
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
|
-
|
|
9
|
+
import {
|
|
10
|
+
type RecursicaCardProps,
|
|
11
|
+
type RecursicaCardSectionProps,
|
|
12
|
+
} from "@recursica/adapter-common";
|
|
5
13
|
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/*
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/*
|
|
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
|
+
}
|