@recursica/mantine-adapter 0.6.0 → 0.8.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/.storybook/commonArgTypes.ts +148 -0
- package/CHANGELOG.md +75 -0
- package/dist/mantine-adapter.cjs +1 -1
- package/dist/mantine-adapter.cjs.map +1 -1
- package/dist/mantine-adapter.css +1 -1
- package/dist/mantine-adapter.js +1085 -687
- package/dist/mantine-adapter.js.map +1 -1
- package/dist/src/components/Checkbox/CheckboxGroup.d.ts +1 -1
- package/dist/src/components/Chip/Chip.d.ts +14 -2
- package/dist/src/components/Container/Container.d.ts +14 -0
- package/dist/src/components/Dropdown/Dropdown.d.ts +10 -2
- package/dist/src/components/Flex/Flex.d.ts +17 -0
- package/dist/src/components/Group/Group.d.ts +17 -0
- package/dist/src/components/Stack/Stack.d.ts +15 -0
- package/dist/src/components/TextArea/TextArea.d.ts +14 -2
- package/dist/src/components/index.d.ts +6 -0
- package/package.json +5 -2
- package/src/OverStyling.stories.tsx +174 -0
- package/src/Version.stories.tsx +56 -0
- package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Accordion/Accordion.module.css +261 -0
- package/src/components/Accordion/Accordion.stories.tsx +145 -0
- package/src/components/Accordion/Accordion.tsx +200 -0
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
- package/src/components/AssistiveElement/AssistiveElement.stories.tsx +73 -0
- package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
- package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
- package/src/components/Avatar/Avatar.module.css +340 -0
- package/src/components/Avatar/Avatar.stories.tsx +102 -0
- package/src/components/Avatar/Avatar.tsx +100 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
- package/src/components/Badge/Badge.module.css +124 -0
- package/src/components/Badge/Badge.stories.tsx +77 -0
- package/src/components/Badge/Badge.tsx +66 -0
- package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
- package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
- package/src/components/Button/Button.module.css +275 -0
- package/src/components/Button/Button.stories.tsx +105 -0
- package/src/components/Button/Button.tsx +122 -0
- package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
- package/src/components/Card/Card.module.css +60 -0
- package/src/components/Card/Card.stories.tsx +141 -0
- package/src/components/Card/Card.tsx +176 -0
- package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
- package/src/components/Checkbox/Checkbox.module.css +204 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +73 -0
- package/src/components/Checkbox/Checkbox.tsx +111 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +138 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +140 -0
- package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
- package/src/components/Chip/Chip.module.css +218 -0
- package/src/components/Chip/Chip.stories.tsx +115 -0
- package/src/components/Chip/Chip.tsx +143 -0
- package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Container/Container.module.css +7 -0
- package/src/components/Container/Container.stories.tsx +102 -0
- package/src/components/Container/Container.tsx +63 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +22 -0
- package/src/components/DatePicker/DatePicker.tsx +7 -0
- package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/Dropdown/Dropdown.module.css +272 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +94 -0
- package/src/components/Dropdown/Dropdown.tsx +186 -0
- package/src/components/FileInput/FileInput.stories.tsx +22 -0
- package/src/components/FileInput/FileInput.tsx +7 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +22 -0
- package/src/components/FileUpload/FileUpload.tsx +7 -0
- package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Flex/Flex.module.css +7 -0
- package/src/components/Flex/Flex.stories.tsx +125 -0
- package/src/components/Flex/Flex.tsx +68 -0
- package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
- package/src/components/FormControlWrapper/FormControlWrapper.module.css +46 -0
- package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -0
- package/src/components/FormControlWrapper/FormControlWrapper.tsx +170 -0
- package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Group/Group.module.css +7 -0
- package/src/components/Group/Group.stories.tsx +117 -0
- package/src/components/Group/Group.tsx +68 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
- package/src/components/HoverCard/HoverCard.tsx +7 -0
- package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
- package/src/components/Label/Label.module.css +177 -0
- package/src/components/Label/Label.stories.tsx +123 -0
- package/src/components/Label/Label.tsx +132 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/Link/Link.stories.tsx +17 -0
- package/src/components/Link/Link.tsx +7 -0
- package/src/components/Loader/Loader.stories.tsx +17 -0
- package/src/components/Loader/Loader.tsx +7 -0
- package/src/components/Menu/Menu.stories.tsx +17 -0
- package/src/components/Menu/Menu.tsx +7 -0
- package/src/components/Modal/Modal.stories.tsx +17 -0
- package/src/components/Modal/Modal.tsx +7 -0
- package/src/components/NumberInput/NumberInput.stories.tsx +22 -0
- package/src/components/NumberInput/NumberInput.tsx +7 -0
- package/src/components/Pagination/Pagination.stories.tsx +17 -0
- package/src/components/Pagination/Pagination.tsx +7 -0
- package/src/components/Panel/Panel.stories.tsx +17 -0
- package/src/components/Panel/Panel.tsx +7 -0
- package/src/components/Popover/Popover.stories.tsx +17 -0
- package/src/components/Popover/Popover.tsx +7 -0
- package/src/components/Radio/Radio.stories.tsx +22 -0
- package/src/components/Radio/Radio.tsx +7 -0
- package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
- package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
- package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +120 -0
- package/src/components/ReadOnlyField/ReadOnlyField.tsx +75 -0
- package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +46 -0
- package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +85 -0
- package/src/components/ReadOnlyField/index.ts +3 -0
- package/src/components/Search/Search.stories.tsx +17 -0
- package/src/components/Search/Search.tsx +7 -0
- package/src/components/SegmentedControl/SegmentedControl.stories.tsx +22 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
- package/src/components/Slider/Slider.stories.tsx +22 -0
- package/src/components/Slider/Slider.tsx +7 -0
- package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
- package/src/components/Stack/Stack.module.css +7 -0
- package/src/components/Stack/Stack.stories.tsx +105 -0
- package/src/components/Stack/Stack.tsx +66 -0
- package/src/components/Stepper/Stepper.stories.tsx +17 -0
- package/src/components/Stepper/Stepper.tsx +7 -0
- package/src/components/Switch/Switch.stories.tsx +22 -0
- package/src/components/Switch/Switch.tsx +7 -0
- package/src/components/Table/Table.stories.tsx +17 -0
- package/src/components/Table/Table.tsx +7 -0
- package/src/components/Tabs/Tabs.stories.tsx +17 -0
- package/src/components/Tabs/Tabs.tsx +7 -0
- package/src/components/Text/Text.stories.tsx +88 -0
- package/src/components/Text/Text.tsx +54 -0
- package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
- package/src/components/TextArea/TextArea.module.css +225 -0
- package/src/components/TextArea/TextArea.stories.tsx +94 -0
- package/src/components/TextArea/TextArea.tsx +164 -0
- package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
- package/src/components/TextField/TextField.module.css +225 -0
- package/src/components/TextField/TextField.stories.tsx +162 -0
- package/src/components/TextField/TextField.tsx +138 -0
- package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
- package/src/components/TimePicker/TimePicker.tsx +7 -0
- package/src/components/Timeline/Timeline.stories.tsx +17 -0
- package/src/components/Timeline/Timeline.tsx +7 -0
- package/src/components/Title/Title.stories.tsx +63 -0
- package/src/components/Title/Title.tsx +45 -0
- package/src/components/Toast/Toast.stories.tsx +17 -0
- package/src/components/Toast/Toast.tsx +7 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
- package/src/components/Tooltip/Tooltip.tsx +7 -0
- package/src/components/TransferList/TransferList.stories.tsx +17 -0
- package/src/components/TransferList/TransferList.tsx +7 -0
- package/src/components/index.ts +45 -0
- package/src/env.d.ts +7 -0
- package/src/index.ts +3 -0
- package/src/types/index.ts +9 -0
- package/src/types/mantine.d.ts +7 -0
- package/src/types/scss-modules.d.ts +9 -0
- package/src/utils/ColorSchemeWrapper.tsx +27 -0
- package/src/utils/copyToClipboard.ts +36 -0
- package/src/utils/filterStylingProps.ts +139 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Chip } from "./Chip";
|
|
4
|
+
|
|
5
|
+
type ChipStoryProps = React.ComponentProps<typeof Chip>;
|
|
6
|
+
|
|
7
|
+
const meta: Meta<ChipStoryProps> = {
|
|
8
|
+
title: "UI-Kit/Chip",
|
|
9
|
+
component: Chip,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
description: {
|
|
14
|
+
component:
|
|
15
|
+
"The Chip component is used to represent interactive selections, descriptive tags, or dynamic filters natively bounded to Recursica variables. It can be used as a toggleable input, can render a custom leading `icon`, and handles close constraints automatically via the `onRemove` property.",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
error: {
|
|
21
|
+
control: "boolean",
|
|
22
|
+
description: "Applies the error state styling dynamically.",
|
|
23
|
+
},
|
|
24
|
+
disabled: {
|
|
25
|
+
control: "boolean",
|
|
26
|
+
description: "Applies disabled token states.",
|
|
27
|
+
},
|
|
28
|
+
checked: {
|
|
29
|
+
control: "boolean",
|
|
30
|
+
description: "Forces the visual selected state.",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default meta;
|
|
36
|
+
|
|
37
|
+
type Story = StoryObj<ChipStoryProps>;
|
|
38
|
+
|
|
39
|
+
// The Default story exposing native properties for the playground.
|
|
40
|
+
export const Default: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
children: "Default Chip",
|
|
43
|
+
error: false,
|
|
44
|
+
disabled: false,
|
|
45
|
+
checked: false,
|
|
46
|
+
},
|
|
47
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Static Stories for Regression Snapshots
|
|
51
|
+
export const Unselected: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
children: "Unselected",
|
|
54
|
+
checked: false,
|
|
55
|
+
},
|
|
56
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const Selected: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
children: "Selected",
|
|
62
|
+
checked: true,
|
|
63
|
+
},
|
|
64
|
+
render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const ErrorState: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
children: "Error",
|
|
70
|
+
error: true,
|
|
71
|
+
checked: false,
|
|
72
|
+
},
|
|
73
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const ErrorSelected: Story = {
|
|
77
|
+
args: {
|
|
78
|
+
children: "Error Selected",
|
|
79
|
+
error: true,
|
|
80
|
+
checked: true,
|
|
81
|
+
},
|
|
82
|
+
render: (args: ChipStoryProps) => <Chip {...args} onChange={() => {}} />,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const Removable: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
children: "Dismissible",
|
|
88
|
+
checked: false,
|
|
89
|
+
onRemove: () => console.log("Removal Action Triggered"),
|
|
90
|
+
},
|
|
91
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export const WithLeadingIcon: Story = {
|
|
95
|
+
args: {
|
|
96
|
+
children: "Leading Icon",
|
|
97
|
+
checked: false,
|
|
98
|
+
icon: (
|
|
99
|
+
<svg
|
|
100
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
101
|
+
viewBox="0 0 24 24"
|
|
102
|
+
fill="none"
|
|
103
|
+
stroke="currentColor"
|
|
104
|
+
strokeWidth="2"
|
|
105
|
+
strokeLinecap="round"
|
|
106
|
+
strokeLinejoin="round"
|
|
107
|
+
>
|
|
108
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
109
|
+
<path d="M12 8v4"></path>
|
|
110
|
+
<path d="M12 16h.01"></path>
|
|
111
|
+
</svg>
|
|
112
|
+
),
|
|
113
|
+
},
|
|
114
|
+
render: (args: ChipStoryProps) => <Chip {...args} />,
|
|
115
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Chip as MantineChip,
|
|
4
|
+
type ChipProps as MantineChipProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import {
|
|
7
|
+
filterStylingProps,
|
|
8
|
+
type RecursicaOverStyled,
|
|
9
|
+
} from "../../utils/filterStylingProps";
|
|
10
|
+
import styles from "./Chip.module.css";
|
|
11
|
+
|
|
12
|
+
export interface RecursicaChipProps {
|
|
13
|
+
/** Enables the error state styling */
|
|
14
|
+
error?: boolean;
|
|
15
|
+
|
|
16
|
+
/** Leading icon content */
|
|
17
|
+
icon?: React.ReactNode;
|
|
18
|
+
|
|
19
|
+
/** Called when the remove (X) icon is clicked. If provided, the remove icon will be displayed. */
|
|
20
|
+
onRemove?: (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => void;
|
|
21
|
+
|
|
22
|
+
/** Screen reader label for the remove button. Defaults to 'Remove' */
|
|
23
|
+
removeLabel?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type ChipProps = RecursicaOverStyled<
|
|
27
|
+
Omit<MantineChipProps, "variant" | "size" | "color" | "radius"> &
|
|
28
|
+
RecursicaChipProps
|
|
29
|
+
>;
|
|
30
|
+
|
|
31
|
+
function CloseIcon(props: React.ComponentPropsWithoutRef<"svg">) {
|
|
32
|
+
return (
|
|
33
|
+
<svg
|
|
34
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
35
|
+
width="24"
|
|
36
|
+
height="24"
|
|
37
|
+
viewBox="0 0 24 24"
|
|
38
|
+
fill="none"
|
|
39
|
+
stroke="currentColor"
|
|
40
|
+
strokeWidth="2"
|
|
41
|
+
strokeLinecap="round"
|
|
42
|
+
strokeLinejoin="round"
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
46
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
47
|
+
</svg>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const Chip = forwardRef<HTMLInputElement, ChipProps>(function Chip(
|
|
52
|
+
{
|
|
53
|
+
error = false,
|
|
54
|
+
icon,
|
|
55
|
+
onRemove,
|
|
56
|
+
removeLabel = "Remove",
|
|
57
|
+
children,
|
|
58
|
+
overStyled = false,
|
|
59
|
+
...rest
|
|
60
|
+
},
|
|
61
|
+
ref,
|
|
62
|
+
) {
|
|
63
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
64
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
65
|
+
|
|
66
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
67
|
+
root: styles.root,
|
|
68
|
+
label: styles.label,
|
|
69
|
+
input: styles.input,
|
|
70
|
+
iconWrapper: styles.mantineIconWrapper,
|
|
71
|
+
checkIcon: styles.checkIcon,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const classNamesProp = restRecord.classNames;
|
|
75
|
+
if (
|
|
76
|
+
classNamesProp &&
|
|
77
|
+
typeof classNamesProp === "object" &&
|
|
78
|
+
!Array.isArray(classNamesProp)
|
|
79
|
+
) {
|
|
80
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
81
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
82
|
+
mergedClassNames.label = o.label
|
|
83
|
+
? `${styles.label} ${o.label}`
|
|
84
|
+
: styles.label;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
88
|
+
const finalClass = classNameProp
|
|
89
|
+
? `${styles.root} ${classNameProp}`
|
|
90
|
+
: styles.root;
|
|
91
|
+
|
|
92
|
+
// Determine state
|
|
93
|
+
const dataError = error ? "" : undefined;
|
|
94
|
+
const isIconOnly = !children && (!!icon || !!onRemove);
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<MantineChip
|
|
98
|
+
ref={ref}
|
|
99
|
+
className={finalClass}
|
|
100
|
+
classNames={mergedClassNames}
|
|
101
|
+
{...(dataError !== undefined ? { "data-error": "" } : {})}
|
|
102
|
+
{...(isIconOnly ? { "data-icon-only": "" } : {})}
|
|
103
|
+
{...sanitizedProps}
|
|
104
|
+
>
|
|
105
|
+
<span className={styles.innerWrapper}>
|
|
106
|
+
{icon && (
|
|
107
|
+
<span className={styles.leadingIcon} aria-hidden>
|
|
108
|
+
{icon}
|
|
109
|
+
</span>
|
|
110
|
+
)}
|
|
111
|
+
|
|
112
|
+
<span className={styles.children}>{children}</span>
|
|
113
|
+
|
|
114
|
+
{onRemove && (
|
|
115
|
+
<span
|
|
116
|
+
role="button"
|
|
117
|
+
className={styles.removeIcon}
|
|
118
|
+
onClick={(e) => {
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
onRemove(e);
|
|
122
|
+
}}
|
|
123
|
+
aria-label={removeLabel}
|
|
124
|
+
onKeyDown={(e) => {
|
|
125
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
e.stopPropagation();
|
|
128
|
+
onRemove(
|
|
129
|
+
e as unknown as React.MouseEvent<HTMLSpanElement, MouseEvent>,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}}
|
|
133
|
+
tabIndex={0}
|
|
134
|
+
>
|
|
135
|
+
<CloseIcon />
|
|
136
|
+
</span>
|
|
137
|
+
)}
|
|
138
|
+
</span>
|
|
139
|
+
</MantineChip>
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
Chip.displayName = "Chip";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Container Implementation Notes
|
|
2
|
+
|
|
3
|
+
The `Container` component is a generic layout wrapper mapped directly to Mantine's `Container`.
|
|
4
|
+
It serves to provide standardized centered max-width bounds around content. Mantine handles the width boundaries inherently based on size properties.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { Container } from "./Container";
|
|
4
|
+
import { Text } from "../Text/Text";
|
|
5
|
+
|
|
6
|
+
type ContainerStoryProps = React.ComponentProps<typeof Container>;
|
|
7
|
+
|
|
8
|
+
const meta: Meta<ContainerStoryProps> = {
|
|
9
|
+
title: "UI-Kit/Container",
|
|
10
|
+
component: Container,
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
parameters: {
|
|
13
|
+
docs: {
|
|
14
|
+
description: {
|
|
15
|
+
component:
|
|
16
|
+
"Container is a generic layout wrapper that safely maps to Mantine's Container, standardizing maximum content widths across the application.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
args: {
|
|
21
|
+
size: "md",
|
|
22
|
+
fluid: false,
|
|
23
|
+
},
|
|
24
|
+
argTypes: {
|
|
25
|
+
size: {
|
|
26
|
+
control: "select",
|
|
27
|
+
options: ["xs", "sm", "md", "lg", "xl"],
|
|
28
|
+
description: "Maximum width defined by Mantine system sizes",
|
|
29
|
+
},
|
|
30
|
+
fluid: {
|
|
31
|
+
control: "boolean",
|
|
32
|
+
description: "If true, overrides size and sets max-width to 100%",
|
|
33
|
+
},
|
|
34
|
+
defaultChecked: {
|
|
35
|
+
table: { disable: true },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default meta;
|
|
41
|
+
|
|
42
|
+
type Story = StoryObj<ContainerStoryProps>;
|
|
43
|
+
|
|
44
|
+
export const Default: Story = {
|
|
45
|
+
render: (args) => (
|
|
46
|
+
<div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
|
|
47
|
+
<Container
|
|
48
|
+
{...args}
|
|
49
|
+
style={{
|
|
50
|
+
backgroundColor: "white",
|
|
51
|
+
padding: "16px",
|
|
52
|
+
border: "1px solid #ccc",
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<Text>
|
|
56
|
+
This is a Container holding centered content. The background and
|
|
57
|
+
border are added just to demonstrate the layout bounds visually.
|
|
58
|
+
</Text>
|
|
59
|
+
</Container>
|
|
60
|
+
</div>
|
|
61
|
+
),
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const SmallContainer: Story = {
|
|
65
|
+
args: {
|
|
66
|
+
size: "sm",
|
|
67
|
+
},
|
|
68
|
+
render: (args) => (
|
|
69
|
+
<div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
|
|
70
|
+
<Container
|
|
71
|
+
{...args}
|
|
72
|
+
style={{
|
|
73
|
+
backgroundColor: "white",
|
|
74
|
+
padding: "16px",
|
|
75
|
+
border: "1px solid #ccc",
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<Text>Small Container Layout</Text>
|
|
79
|
+
</Container>
|
|
80
|
+
</div>
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const FluidContainer: Story = {
|
|
85
|
+
args: {
|
|
86
|
+
fluid: true,
|
|
87
|
+
},
|
|
88
|
+
render: (args) => (
|
|
89
|
+
<div style={{ backgroundColor: "#f0f0f0", padding: "16px" }}>
|
|
90
|
+
<Container
|
|
91
|
+
{...args}
|
|
92
|
+
style={{
|
|
93
|
+
backgroundColor: "white",
|
|
94
|
+
padding: "16px",
|
|
95
|
+
border: "1px solid #ccc",
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<Text>Fluid Container Layout</Text>
|
|
99
|
+
</Container>
|
|
100
|
+
</div>
|
|
101
|
+
),
|
|
102
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Container as MantineContainer,
|
|
4
|
+
type ContainerProps as MantineContainerProps,
|
|
5
|
+
} from "@mantine/core";
|
|
6
|
+
import {
|
|
7
|
+
filterStylingProps,
|
|
8
|
+
type RecursicaOverStyled,
|
|
9
|
+
} from "../../utils/filterStylingProps";
|
|
10
|
+
import styles from "./Container.module.css";
|
|
11
|
+
|
|
12
|
+
export interface RecursicaContainerProps {
|
|
13
|
+
/**
|
|
14
|
+
* Children components inside the layout container
|
|
15
|
+
*/
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Container layout wrapper
|
|
21
|
+
*/
|
|
22
|
+
export type ContainerProps = RecursicaOverStyled<
|
|
23
|
+
MantineContainerProps & RecursicaContainerProps
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export const Container = forwardRef<HTMLDivElement, ContainerProps>(
|
|
27
|
+
function Container({ children, overStyled = false, ...rest }, ref) {
|
|
28
|
+
const sanitizedProps = filterStylingProps(rest, overStyled);
|
|
29
|
+
const restRecord = sanitizedProps as Record<string, unknown>;
|
|
30
|
+
|
|
31
|
+
const mergedClassNames: Partial<Record<string, string>> = {
|
|
32
|
+
root: styles.root,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const classNamesProp = restRecord.classNames;
|
|
36
|
+
if (
|
|
37
|
+
classNamesProp &&
|
|
38
|
+
typeof classNamesProp === "object" &&
|
|
39
|
+
!Array.isArray(classNamesProp)
|
|
40
|
+
) {
|
|
41
|
+
const o = classNamesProp as Partial<Record<string, string>>;
|
|
42
|
+
mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const classNameProp = restRecord.className as string | undefined;
|
|
46
|
+
const finalClass = classNameProp
|
|
47
|
+
? `${styles.root} ${classNameProp}`
|
|
48
|
+
: styles.root;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<MantineContainer
|
|
52
|
+
ref={ref}
|
|
53
|
+
className={finalClass}
|
|
54
|
+
classNames={mergedClassNames}
|
|
55
|
+
{...sanitizedProps}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
</MantineContainer>
|
|
59
|
+
);
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
Container.displayName = "Container";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { DatePicker } from "./DatePicker";
|
|
3
|
+
import { ComingSoon } from "@recursica/storybook-template";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof DatePicker> = {
|
|
6
|
+
title: "UI-Kit/🚧 DatePicker",
|
|
7
|
+
component: DatePicker,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
disabled: {
|
|
11
|
+
control: "boolean",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
18
|
+
type Story = StoryObj<typeof DatePicker>;
|
|
19
|
+
|
|
20
|
+
export const Default: Story = {
|
|
21
|
+
render: () => <ComingSoon componentName="DatePicker" />,
|
|
22
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Dropdown Implementation Notes
|
|
2
|
+
|
|
3
|
+
The `Dropdown` component is mapped explicitly to Mantine's `<Select>` following the exact same strict encapsulation rules as `TextField`.
|
|
4
|
+
|
|
5
|
+
1. **Naked Primitive Mapping:** Mantine's `Select` natively executes macro-label generation. To decouple it, we explicitly disable internal labels (`label={undefined}`) and inject it purely inside our generic `FormControlWrapper`.
|
|
6
|
+
2. **Strict Dropdown Design Tokens:** The adapter implements strictly sandboxed styling utilizing only `--recursica_ui-kit_components_dropdown_...` variables. It explicitly does NOT inherit general `text-field` tokens despite geometric similarities, ensuring dropdown menus can be themed independently.
|
|
7
|
+
3. **Dropdown Appendages:** To correctly map Mantine's detached Popover `.dropdown` and list `.option` items, we targeted focus and geometric bindings appending standard padding structures matched to the dropdown height overrides dynamically into our `Dropdown.module.css`.
|