@recursica/adapter-mantine-v8 1.3.3 → 1.3.4

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 (61) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/docs/PHILOSOPHY.md +4 -0
  3. package/package.json +4 -8
  4. package/.storybook/commonArgTypes.ts +0 -148
  5. package/recursica_brand.json +0 -2610
  6. package/recursica_tokens.json +0 -769
  7. package/recursica_ui-kit.json +0 -9049
  8. package/recursica_variables_scoped.css +0 -6178
  9. package/src/Introduction.stories.tsx +0 -149
  10. package/src/components/Accordion/Accordion.stories.tsx +0 -189
  11. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +0 -68
  12. package/src/components/AutoComplete/AutoComplete.stories.tsx +0 -336
  13. package/src/components/Avatar/Avatar.stories.tsx +0 -92
  14. package/src/components/Badge/Badge.stories.tsx +0 -78
  15. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -114
  16. package/src/components/Button/Button.stories.tsx +0 -192
  17. package/src/components/Card/Card.stories.tsx +0 -76
  18. package/src/components/Checkbox/Checkbox.stories.tsx +0 -97
  19. package/src/components/Checkbox/CheckboxGroup.stories.tsx +0 -139
  20. package/src/components/Chip/Chip.stories.tsx +0 -128
  21. package/src/components/Container/Container.stories.tsx +0 -118
  22. package/src/components/DatePicker/DatePicker.stories.tsx +0 -158
  23. package/src/components/Dropdown/Dropdown.stories.tsx +0 -252
  24. package/src/components/FileInput/FileInput.stories.tsx +0 -313
  25. package/src/components/FileUpload/FileUpload.stories.tsx +0 -362
  26. package/src/components/Flex/Flex.stories.tsx +0 -128
  27. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +0 -118
  28. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +0 -129
  29. package/src/components/Group/Group.stories.tsx +0 -120
  30. package/src/components/Heading/Heading.stories.tsx +0 -112
  31. package/src/components/HoverCard/HoverCard.stories.tsx +0 -172
  32. package/src/components/Label/Label.stories.tsx +0 -131
  33. package/src/components/LayoutGrid/LayoutGrid.stories.tsx +0 -61
  34. package/src/components/Link/Link.stories.tsx +0 -58
  35. package/src/components/Loader/Loader.stories.tsx +0 -123
  36. package/src/components/Menu/Menu.stories.tsx +0 -370
  37. package/src/components/Modal/Modal.stories.tsx +0 -105
  38. package/src/components/NumberInput/NumberInput.stories.tsx +0 -96
  39. package/src/components/Pagination/Pagination.stories.tsx +0 -48
  40. package/src/components/Panel/Panel.stories.tsx +0 -219
  41. package/src/components/Popover/Popover.stories.tsx +0 -133
  42. package/src/components/Radio/Radio.stories.tsx +0 -93
  43. package/src/components/Radio/RadioGroup.stories.tsx +0 -117
  44. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +0 -163
  45. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -106
  46. package/src/components/Slider/Slider.stories.tsx +0 -282
  47. package/src/components/Stack/Stack.stories.tsx +0 -108
  48. package/src/components/Stepper/Stepper.stories.tsx +0 -148
  49. package/src/components/Switch/Switch.stories.tsx +0 -114
  50. package/src/components/Switch/SwitchGroup.stories.tsx +0 -132
  51. package/src/components/Table/Table.stories.tsx +0 -140
  52. package/src/components/Tabs/Tabs.stories.tsx +0 -154
  53. package/src/components/Text/Text.stories.tsx +0 -148
  54. package/src/components/TextArea/TextArea.stories.tsx +0 -94
  55. package/src/components/TextField/TextField.stories.tsx +0 -162
  56. package/src/components/TimePicker/TimePicker.stories.tsx +0 -141
  57. package/src/components/Timeline/Timeline.stories.tsx +0 -128
  58. package/src/components/Toast/Toast.stories.tsx +0 -67
  59. package/src/components/Tooltip/Tooltip.stories.tsx +0 -165
  60. package/src/components/TransferList/TransferList.stories.tsx +0 -121
  61. package/src/components/Tree/Tree.stories.tsx +0 -104
@@ -1,172 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
2
- import { HoverCard } from "./HoverCard";
3
- import { Button } from "../Button";
4
- import { Text } from "../Text/Text";
5
- import { Group } from "../Group/Group";
6
- import { Stack } from "../Stack/Stack";
7
- import { Avatar } from "../Avatar";
8
-
9
- /**
10
- * HoverCard story axes:
11
- * - position: dropdown alignment relative to target
12
- * - withArrow: arrow indicator on the dropdown
13
- * - openDelay / closeDelay: hover timing controls
14
- * - content variations: plain text, rich content (avatar + text + actions)
15
- * - layer: tested via the global Layer decorator (withLayer/layer args)
16
- */
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- type HoverCardStoryArgs = Record<string, any>;
20
-
21
- const meta: Meta = {
22
- title: "UI-Kit/HoverCard",
23
- component: HoverCard,
24
- tags: ["autodocs"],
25
- argTypes: {
26
- position: {
27
- control: "select",
28
- options: [
29
- "bottom",
30
- "bottom-start",
31
- "bottom-end",
32
- "top",
33
- "top-start",
34
- "top-end",
35
- "left",
36
- "left-start",
37
- "left-end",
38
- "right",
39
- "right-start",
40
- "right-end",
41
- ],
42
- description: "The position of the dropdown relative to the target.",
43
- },
44
- withBeak: {
45
- control: "boolean",
46
- description:
47
- "Whether to display a beak (arrow) pointing to the target. Recursica equivalent of Mantine's withArrow.",
48
- },
49
- offset: {
50
- control: "number",
51
- description:
52
- "Distance in px between the dropdown and the target element.",
53
- },
54
- openDelay: {
55
- control: "number",
56
- description: "Delay in ms before the dropdown opens on hover.",
57
- },
58
- closeDelay: {
59
- control: "number",
60
- description: "Delay in ms before the dropdown closes when hover ends.",
61
- },
62
- disabled: {
63
- control: "boolean",
64
- description: "If set, the hover card dropdown will not be rendered.",
65
- },
66
- },
67
- parameters: {
68
- layout: "centered",
69
- docs: {
70
- description: {
71
- component: `
72
- The \`HoverCard\` component displays a popover-style dropdown when the user hovers over a target element. It wraps Mantine's composable \`HoverCard\` while enforcing strict Recursica design token styling.
73
-
74
- ### Composable API
75
-
76
- HoverCard uses a dot-notation composition pattern:
77
- - \`<HoverCard>\` — Root container managing open/close state on hover
78
- - \`<HoverCard.Target>\` — Wrapper for the trigger element (must be a single element supporting ref)
79
- - \`<HoverCard.Dropdown>\` — The popup panel displaying content on hover
80
-
81
- ### Key Behaviors
82
- - The dropdown opens when the user hovers over the target and closes when they move away
83
- - \`openDelay\` and \`closeDelay\` control the timing of open/close transitions
84
- - The dropdown stays open while the user hovers over it, allowing interaction with its content
85
- `,
86
- },
87
- },
88
- },
89
- };
90
-
91
- export default meta;
92
-
93
- type Story = StoryObj<HoverCardStoryArgs>;
94
-
95
- export const Default: Story = {
96
- args: {
97
- position: "top",
98
- withBeak: true,
99
- offset: 5,
100
- openDelay: 0,
101
- closeDelay: 150,
102
- },
103
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
104
- render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
105
- return (
106
- <HoverCard {...args}>
107
- <HoverCard.Target>
108
- <Button variant="solid">Hover me</Button>
109
- </HoverCard.Target>
110
-
111
- <HoverCard.Dropdown>
112
- <Text>
113
- This is a hover card with informational content that appears when
114
- you hover over the target element.
115
- </Text>
116
- </HoverCard.Dropdown>
117
- </HoverCard>
118
- );
119
- },
120
- };
121
-
122
- export const WithoutBeak: Story = {
123
- args: {
124
- position: "top",
125
- withBeak: false,
126
- offset: 5,
127
- },
128
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
129
- render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
130
- return (
131
- <HoverCard {...args}>
132
- <HoverCard.Target>
133
- <Button variant="outline">Without Beak</Button>
134
- </HoverCard.Target>
135
-
136
- <HoverCard.Dropdown>
137
- <Text>
138
- This hover card has the beak disabled, showing a clean dropdown
139
- without the pointing indicator.
140
- </Text>
141
- </HoverCard.Dropdown>
142
- </HoverCard>
143
- );
144
- },
145
- };
146
-
147
- export const RichContent: Story = {
148
- args: {
149
- position: "top",
150
- offset: 5,
151
- },
152
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
153
- render: ({ withLayer, layer, ...args }: HoverCardStoryArgs) => {
154
- return (
155
- <HoverCard {...args}>
156
- <HoverCard.Target>
157
- <Button variant="solid">User Profile</Button>
158
- </HoverCard.Target>
159
-
160
- <HoverCard.Dropdown>
161
- <Group>
162
- <Avatar src={null} alt="User avatar" />
163
- <Stack>
164
- <Text>Jane Doe</Text>
165
- <Text>Software Engineer at Recursica</Text>
166
- </Stack>
167
- </Group>
168
- </HoverCard.Dropdown>
169
- </HoverCard>
170
- );
171
- },
172
- };
@@ -1,131 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { Label } from "./Label";
4
- import { Button } from "../Button/Button";
5
-
6
- type LabelStoryProps = React.ComponentProps<typeof Label>;
7
-
8
- const meta: Meta<LabelStoryProps> = {
9
- title: "UI-Kit/Label",
10
- component: Label,
11
- tags: ["autodocs"],
12
- parameters: {
13
- docs: {
14
- description: {
15
- component:
16
- "The `Label` component is a strict Recursica-styled wrapper around Mantine's native `Input.Label`. It serves as the primary compositional primitive for all form fields, preserving Mantine's accessibility associations and context while strictly enforcing the Recursica atomic design system.\n\n### Usage with Form Inputs\nThis component only renders the label itself — layout concerns like `stacked` vs `side-by-side` positioning relative to an input live on `FormControlLayout`/`FormControlWrapper`, not here. Render this `Label` in isolation to verify its own states, or see `UI-Kit/FormControlLayout` for how it composes into a full form field.",
17
- },
18
- },
19
- },
20
- argTypes: {
21
- labelSize: {
22
- control: "inline-radio",
23
- options: ["default", "small"],
24
- description:
25
- "Sizing metrics for the Label. Only visually distinguishable once composed inside a `side-by-side` FormControlLayout, which is where the resulting width constraint applies.",
26
- },
27
- labelAlignment: {
28
- control: "inline-radio",
29
- options: ["left", "right"],
30
- description: "Text alignment of the label content.",
31
- },
32
- required: {
33
- control: "boolean",
34
- description:
35
- "Renders the required asterisk (suppressed automatically when `labelWithEditIcon` is set, and mutually exclusive with `labelOptionalText`).",
36
- },
37
- labelOptionalText: {
38
- control: "text",
39
- description:
40
- "Secondary text rendered beneath the label. Pass `true` for the default '(Optional)' string, or a custom node/string. Suppressed when `required` is true.",
41
- },
42
- labelWithEditIcon: {
43
- control: "boolean",
44
- description:
45
- "Replaces the default edit icon slot with an interactive edit affordance; replaces the required asterisk visually when both are set.",
46
- },
47
- labelActionArea: {
48
- table: { disable: true },
49
- },
50
- onLabelEditClick: {
51
- table: { disable: true },
52
- },
53
- },
54
- };
55
-
56
- export default meta;
57
-
58
- type Story = StoryObj<LabelStoryProps>;
59
-
60
- export const Default: Story = {
61
- args: {
62
- children: "Label",
63
- labelSize: "default",
64
- labelAlignment: "left",
65
- required: false,
66
- labelOptionalText: "",
67
- labelWithEditIcon: false,
68
- },
69
- };
70
-
71
- export const Required: Story = {
72
- args: {
73
- children: "Required Field",
74
- required: true,
75
- },
76
- };
77
-
78
- export const RequiredSuppressesOptionalText: Story = {
79
- args: {
80
- children: "Full Name",
81
- required: true,
82
- labelOptionalText: "This should not render",
83
- },
84
- };
85
-
86
- export const WithOptionalText: Story = {
87
- args: {
88
- children: "Bio",
89
- labelOptionalText: "Max 100 characters",
90
- },
91
- };
92
-
93
- export const BooleanOptionalText: Story = {
94
- args: {
95
- children: "Middle Initial",
96
- labelOptionalText: true,
97
- },
98
- };
99
-
100
- export const WithEditIcon: Story = {
101
- args: {
102
- children: "Shipping Address",
103
- labelWithEditIcon: true,
104
- },
105
- };
106
-
107
- export const RequiredWithEditIcon: Story = {
108
- args: {
109
- children: "Primary Network Node",
110
- required: true,
111
- labelWithEditIcon: true,
112
- },
113
- };
114
-
115
- export const RightAligned: Story = {
116
- args: {
117
- children: "Status",
118
- labelAlignment: "right",
119
- },
120
- };
121
-
122
- export const WithActionArea: Story = {
123
- args: {
124
- children: "Configuration",
125
- labelActionArea: (
126
- <Button variant="text" size="small">
127
- Edit
128
- </Button>
129
- ),
130
- },
131
- };
@@ -1,61 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { useRecursicaManifest } from "@recursica/adapter-common";
4
- import { LayoutGrid } from "./LayoutGrid";
5
-
6
- type LayoutGridStoryProps = React.ComponentProps<typeof LayoutGrid>;
7
-
8
- const meta: Meta<LayoutGridStoryProps> = {
9
- title: "UI-Kit/LayoutGrid",
10
- component: LayoutGrid,
11
- tags: ["autodocs"],
12
- parameters: {
13
- docs: {
14
- description: {
15
- component:
16
- "LayoutGrid is the Recursica layout grid. Its column count, column-gutter, row-gutter and margin come from the design system's layout-grid tokens, which Forge defines per breakpoint, so they respond to the viewport and are not integrator-configurable.",
17
- },
18
- },
19
- },
20
- };
21
-
22
- export default meta;
23
-
24
- type Story = StoryObj<LayoutGridStoryProps>;
25
-
26
- // Plain bordered cell: Card has a token min-width wider than one column, which would overflow it.
27
- const Swatch = ({ children }: { children: React.ReactNode }) => (
28
- <div
29
- style={{
30
- border: "1px dashed currentColor",
31
- padding: "8px",
32
- textAlign: "center",
33
- }}
34
- >
35
- {children}
36
- </div>
37
- );
38
-
39
- // Reads the default layout grid from the manifest (brand.layout-grids.default) and fills two full
40
- // rows of single-column cells, so the story shows exactly the design system's column count.
41
- const DefaultGrid = () => {
42
- const manifest = useRecursicaManifest() as {
43
- brand: {
44
- "layout-grids": { default: { columns: { $value: number } } };
45
- };
46
- };
47
- const columns = manifest.brand["layout-grids"].default.columns.$value;
48
- return (
49
- <LayoutGrid>
50
- {Array.from({ length: columns * 2 }, (_, i) => (
51
- <LayoutGrid.Col key={i} span={1}>
52
- <Swatch>{(i % columns) + 1}</Swatch>
53
- </LayoutGrid.Col>
54
- ))}
55
- </LayoutGrid>
56
- );
57
- };
58
-
59
- export const Default: Story = {
60
- render: () => <DefaultGrid />,
61
- };
@@ -1,58 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- /* eslint-disable @typescript-eslint/no-unused-vars */
3
- import type { Meta, StoryObj } from "@storybook/react";
4
- import { Link } from "./Link";
5
-
6
- const meta: Meta<typeof Link> = {
7
- title: "UI-Kit/Link",
8
- component: Link,
9
- tags: ["autodocs"],
10
- args: {
11
- children: "Link text",
12
- href: "#",
13
- },
14
- render: ({ withLayer, layer, ...args }: any) => <Link {...args} />,
15
- };
16
-
17
- export default meta;
18
-
19
- type Story = StoryObj<typeof Link>;
20
-
21
- export const Default: Story = {};
22
-
23
- export const WithIcon: Story = {
24
- args: {
25
- icon: (
26
- <svg
27
- width="24"
28
- height="24"
29
- viewBox="0 0 24 24"
30
- fill="none"
31
- stroke="currentColor"
32
- strokeWidth="2"
33
- strokeLinecap="round"
34
- strokeLinejoin="round"
35
- >
36
- <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
37
- <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
38
- </svg>
39
- ),
40
- children: "Link with Icon",
41
- },
42
- };
43
-
44
- export const Polymorphic: Story = {
45
- args: {
46
- component: "button",
47
- onClick: () => alert("Button clicked!"),
48
- children: "Rendered as <button>",
49
- },
50
- };
51
-
52
- export const InlineText: Story = {
53
- render: () => (
54
- <p>
55
- Here is some text with an <Link href="#">inline link</Link> inside it.
56
- </p>
57
- ),
58
- };
@@ -1,123 +0,0 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import { Loader } from "./Loader";
4
- import { Layer } from "@recursica/adapter-common";
5
-
6
- type LoaderStoryArgs = React.ComponentProps<typeof Loader> & {
7
- layer?: 0 | 1 | 2 | 3;
8
- };
9
-
10
- const meta: Meta<LoaderStoryArgs> = {
11
- title: "UI-Kit/Loader",
12
- component: Loader as React.ComponentType<LoaderStoryArgs>,
13
- tags: ["autodocs"],
14
- parameters: {
15
- docs: {
16
- description: {
17
- component:
18
- "The Loader bridges the Recursica UI-Kit `loader` variables to the generic primitive, rendering deterministic sizes and variants visually mapped strictly from the explicit design boundary tokens.",
19
- },
20
- },
21
- },
22
- argTypes: {
23
- variant: {
24
- control: "select",
25
- options: ["oval", "bars", "dots"],
26
- description: "The structural layout variant of the loading indicator",
27
- },
28
- size: {
29
- control: "select",
30
- options: ["sm", "md", "lg", "small", "default", "large"],
31
- description:
32
- "Scales the dimensional and thickness layout constrained to the explicit UI variables",
33
- },
34
- color: {
35
- control: "color",
36
- description:
37
- "Optional inline dynamic color override spanning the token defaults",
38
- },
39
- layer: {
40
- control: { type: "range", min: 0, max: 3, step: 1 },
41
- description:
42
- "Applies a wrapping context to observe rendering logic externally",
43
- },
44
- animate: {
45
- control: "boolean",
46
- description:
47
- "Freezes the CSS animation when false — deterministic, for visual regression",
48
- },
49
- },
50
- };
51
-
52
- export default meta;
53
-
54
- type Story = StoryObj<LoaderStoryArgs>;
55
-
56
- /**
57
- * Animated — excluded from visual regression (`adapter-tester.config.json`),
58
- * since a moving animation diffs differently every run. See the `Static*`
59
- * stories below for the deterministic, visual-regression-covered equivalents.
60
- */
61
- export const Default: Story = {
62
- args: {
63
- variant: "oval",
64
- size: "default",
65
- layer: 0,
66
- },
67
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
68
- render: ({ withLayer, layer, ...args }: any) => (
69
- <Layer layer={layer ?? 0} style={{ padding: "24px" }}>
70
- <Loader {...args} />
71
- </Layer>
72
- ),
73
- };
74
-
75
- /** `animate: false` freezes the spin — deterministic for visual regression. */
76
- export const StaticOvalDefault: Story = {
77
- args: {
78
- variant: "oval",
79
- size: "default",
80
- animate: false,
81
- },
82
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
83
- render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
84
- };
85
-
86
- /** `animate: false` freezes the bars — deterministic for visual regression. */
87
- export const StaticBarsLarge: Story = {
88
- args: {
89
- variant: "bars",
90
- size: "large",
91
- animate: false,
92
- },
93
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
94
- render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
95
- };
96
-
97
- /** `animate: false` freezes the dots — deterministic for visual regression. */
98
- export const StaticDotsSmall: Story = {
99
- args: {
100
- variant: "dots",
101
- size: "sm",
102
- animate: false,
103
- },
104
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
105
- render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
106
- };
107
-
108
- /**
109
- * Animated — excluded from visual regression, same as `Default`; this one
110
- * additionally demonstrates rendering inside a `layer={2}` context.
111
- */
112
- export const LayerTwoOval: Story = {
113
- args: {
114
- variant: "oval",
115
- size: "default",
116
- },
117
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
118
- render: ({ withLayer, layer, ...args }: any) => (
119
- <Layer layer={2} style={{ padding: "24px" }}>
120
- <Loader {...args} />
121
- </Layer>
122
- ),
123
- };