@recursica/mantine-adapter 0.16.0 → 0.18.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 (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/mantine-adapter.cjs +1 -1
  3. package/dist/mantine-adapter.cjs.map +1 -1
  4. package/dist/mantine-adapter.css +1 -1
  5. package/dist/mantine-adapter.js +1677 -1505
  6. package/dist/mantine-adapter.js.map +1 -1
  7. package/dist/src/OverStyling.d.ts +1 -0
  8. package/dist/src/Version.d.ts +1 -0
  9. package/dist/src/components/Container/Container.d.ts +8 -5
  10. package/dist/src/components/Flex/Flex.d.ts +10 -7
  11. package/dist/src/components/Group/Group.d.ts +8 -5
  12. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +16 -3
  13. package/dist/src/components/Stack/Stack.d.ts +8 -5
  14. package/dist/src/components/Stepper/Stepper.d.ts +12 -2
  15. package/dist/src/components/Tabs/Tabs.d.ts +19 -3
  16. package/dist/src/components/index.d.ts +0 -2
  17. package/package.json +4 -3
  18. package/src/Introduction.stories.tsx +180 -0
  19. package/src/{OverStyling.stories.tsx → OverStyling.tsx} +23 -11
  20. package/src/{Version.stories.tsx → Version.tsx} +1 -13
  21. package/src/components/Card/Card.tsx +1 -1
  22. package/src/components/Container/Container.tsx +13 -17
  23. package/src/components/Flex/Flex.tsx +13 -17
  24. package/src/components/Group/Group.tsx +13 -17
  25. package/src/components/Pagination/Pagination.stories.tsx +0 -1
  26. package/src/components/Panel/Panel.stories.tsx +1 -1
  27. package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +17 -0
  28. package/src/components/SegmentedControl/SegmentedControl.module.css +138 -0
  29. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +108 -6
  30. package/src/components/SegmentedControl/SegmentedControl.tsx +96 -5
  31. package/src/components/Stack/Stack.tsx +13 -17
  32. package/src/components/Stepper/Stepper.module.css +353 -0
  33. package/src/components/Stepper/Stepper.stories.tsx +135 -4
  34. package/src/components/Stepper/Stepper.tsx +68 -5
  35. package/src/components/Tabs/Tabs.module.css +401 -0
  36. package/src/components/Tabs/Tabs.stories.tsx +141 -4
  37. package/src/components/Tabs/Tabs.tsx +107 -5
  38. package/src/components/index.ts +0 -2
  39. package/dist/src/components/Popover/Popover.d.ts +0 -3
  40. package/dist/src/components/Search/Search.d.ts +0 -3
  41. package/src/components/Popover/Popover.stories.tsx +0 -17
  42. package/src/components/Popover/Popover.tsx +0 -7
  43. package/src/components/Search/Search.stories.tsx +0 -17
  44. package/src/components/Search/Search.tsx +0 -7
@@ -1,14 +1,10 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Flex as MantineFlex,
4
4
  type FlexProps as MantineFlexProps,
5
5
  createPolymorphicComponent,
6
6
  } from "@mantine/core";
7
- import {
8
- filterStylingProps,
9
- type RecursicaOverStyled,
10
- type RecursicaSpacing,
11
- } from "../../utils/filterStylingProps";
7
+ import { type RecursicaSpacing } from "../../utils/filterStylingProps";
12
8
  import styles from "./Flex.module.css";
13
9
 
14
10
  export interface RecursicaFlexProps {
@@ -22,24 +18,23 @@ export interface RecursicaFlexProps {
22
18
  }
23
19
 
24
20
  /**
25
- * Flex layout wrapper
21
+ * Flex layout wrapper.
22
+ *
23
+ * Note: Unlike complex UI components, primitive layout components (Flex, Stack, Group, Container)
24
+ * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
25
+ * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
26
26
  */
27
- export type FlexProps = RecursicaOverStyled<
28
- MantineFlexProps & RecursicaFlexProps
29
- >;
27
+ export type FlexProps = MantineFlexProps & RecursicaFlexProps;
30
28
 
31
29
  const _Flex = forwardRef<HTMLDivElement, FlexProps>(function Flex(
32
- { children, overStyled = false, gap = "rec-default", ...rest },
30
+ { children, gap = "rec-default", ...rest },
33
31
  ref,
34
32
  ) {
35
- const sanitizedProps = filterStylingProps({ ...rest, gap }, overStyled);
36
- const restRecord = sanitizedProps as Record<string, unknown>;
37
-
38
33
  const mergedClassNames: Partial<Record<string, string>> = {
39
34
  root: styles.root,
40
35
  };
41
36
 
42
- const classNamesProp = restRecord.classNames;
37
+ const classNamesProp = rest.classNames;
43
38
  if (
44
39
  classNamesProp &&
45
40
  typeof classNamesProp === "object" &&
@@ -49,7 +44,7 @@ const _Flex = forwardRef<HTMLDivElement, FlexProps>(function Flex(
49
44
  mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
50
45
  }
51
46
 
52
- const classNameProp = restRecord.className as string | undefined;
47
+ const classNameProp = rest.className as string | undefined;
53
48
  const finalClass = classNameProp
54
49
  ? `${styles.root} ${classNameProp}`
55
50
  : styles.root;
@@ -59,7 +54,8 @@ const _Flex = forwardRef<HTMLDivElement, FlexProps>(function Flex(
59
54
  ref={ref}
60
55
  className={finalClass}
61
56
  classNames={mergedClassNames}
62
- {...sanitizedProps}
57
+ gap={gap}
58
+ {...rest}
63
59
  >
64
60
  {children}
65
61
  </MantineFlex>
@@ -1,13 +1,9 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Group as MantineGroup,
4
4
  type GroupProps as MantineGroupProps,
5
5
  } from "@mantine/core";
6
- import {
7
- filterStylingProps,
8
- type RecursicaOverStyled,
9
- type RecursicaSpacing,
10
- } from "../../utils/filterStylingProps";
6
+ import { type RecursicaSpacing } from "../../utils/filterStylingProps";
11
7
  import styles from "./Group.module.css";
12
8
 
13
9
  export interface RecursicaGroupProps {
@@ -21,24 +17,23 @@ export interface RecursicaGroupProps {
21
17
  }
22
18
 
23
19
  /**
24
- * Group flex layout wrapper
20
+ * Group flex layout wrapper.
21
+ *
22
+ * Note: Unlike complex UI components, primitive layout components (Flex, Stack, Group, Container)
23
+ * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
24
+ * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
25
25
  */
26
- export type GroupProps = RecursicaOverStyled<
27
- MantineGroupProps & RecursicaGroupProps
28
- >;
26
+ export type GroupProps = MantineGroupProps & RecursicaGroupProps;
29
27
 
30
28
  export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
31
- { children, overStyled = false, gap = "rec-default", ...rest },
29
+ { children, gap = "rec-default", ...rest },
32
30
  ref,
33
31
  ) {
34
- const sanitizedProps = filterStylingProps({ ...rest, gap }, overStyled);
35
- const restRecord = sanitizedProps as Record<string, unknown>;
36
-
37
32
  const mergedClassNames: Partial<Record<string, string>> = {
38
33
  root: styles.root,
39
34
  };
40
35
 
41
- const classNamesProp = restRecord.classNames;
36
+ const classNamesProp = rest.classNames;
42
37
  if (
43
38
  classNamesProp &&
44
39
  typeof classNamesProp === "object" &&
@@ -48,7 +43,7 @@ export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
48
43
  mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
49
44
  }
50
45
 
51
- const classNameProp = restRecord.className as string | undefined;
46
+ const classNameProp = rest.className as string | undefined;
52
47
  const finalClass = classNameProp
53
48
  ? `${styles.root} ${classNameProp}`
54
49
  : styles.root;
@@ -58,7 +53,8 @@ export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
58
53
  ref={ref}
59
54
  className={finalClass}
60
55
  classNames={mergedClassNames}
61
- {...sanitizedProps}
56
+ gap={gap}
57
+ {...rest}
62
58
  >
63
59
  {children}
64
60
  </MantineGroup>
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import type { Meta, StoryObj } from "@storybook/react";
3
2
  import { Pagination } from "./Pagination";
4
3
 
@@ -94,12 +94,12 @@ export const Default: Story = {
94
94
  Open Panel
95
95
  </Button>
96
96
  <Panel
97
+ {...(args as PanelProps)}
97
98
  opened={opened}
98
99
  onClose={() => setOpened(false)}
99
100
  title="Panel Title"
100
101
  position="right"
101
102
  wrapHeaderText={wrapHeaderText}
102
- {...(args as PanelProps)}
103
103
  >
104
104
  <Text>
105
105
  This is the panel body content area. Panels slide in from the edge
@@ -0,0 +1,17 @@
1
+ # SegmentedControl Implementation Notes
2
+
3
+ ## 1. Stripping Mantine's Native Variants and Sizes
4
+
5
+ The Figma design tokens for the SegmentedControl component do not define nested layers of variants (such as `solid`, `outline`) or specific sizing steps (`xs`, `sm`, etc.). They are defined globally. Therefore, we explicitly `Omit` the standard `variant`, `size`, `radius`, and `color` props from the generic Mantine `SegmentedControlProps` interface.
6
+
7
+ ## 2. Hardcoded Overrides for Figma Strictness
8
+
9
+ Mantine injects inline hover styles on `.label` (specifically, adding a subtle gray background when hovering). Since Recursica defines explicit transparent or specifically-driven hover states, we use `!important` tags within `SegmentedControl.module.css` for background and typography overriding.
10
+
11
+ ## 3. Divider Separators
12
+
13
+ Mantine uses an `::before` pseudo-element on the `.control` block to draw standard visual separators between adjacent elements. Instead of stripping this functionality out, we hook directly into the pseudo-element and override its `background-color` with `--recursica_ui-kit_components_segmented-control_properties_colors_divider-color`.
14
+
15
+ ## 4. Indicator Mapping
16
+
17
+ The moving active background element (`.indicator`) is decoupled from the actual text label. It is styled natively with its own background color, border size, and elevation shadow variables to match the exact visual parity of a "floating active chip" as defined in the Recursica properties map.
@@ -0,0 +1,138 @@
1
+ /* HARDCODED VALUES:
2
+ - border-style: solid; on container and indicator
3
+ - background-color: transparent; on label hover (overriding Mantine)
4
+ - !important usage to strictly enforce Figma tokens over Mantine's inline calculation
5
+ */
6
+
7
+ .root {
8
+ background-color: var(
9
+ --recursica_ui-kit_components_segmented-control_properties_container_colors_background
10
+ ) !important;
11
+ border: var(
12
+ --recursica_ui-kit_components_segmented-control_properties_container_border-size
13
+ )
14
+ solid
15
+ var(
16
+ --recursica_ui-kit_components_segmented-control_properties_container_colors_border-color
17
+ );
18
+ border-radius: var(
19
+ --recursica_ui-kit_components_segmented-control_properties_container_border-radius
20
+ ) !important;
21
+ padding: var(
22
+ --recursica_ui-kit_components_segmented-control_properties_container_padding-vertical
23
+ )
24
+ var(
25
+ --recursica_ui-kit_components_segmented-control_properties_container_padding-horizontal
26
+ ) !important;
27
+ box-shadow: var(
28
+ --recursica_ui-kit_components_segmented-control_properties_container_elevation
29
+ );
30
+ gap: var(--recursica_ui-kit_components_segmented-control_properties_item-gap);
31
+ }
32
+
33
+ .label {
34
+ padding-left: var(
35
+ --recursica_ui-kit_components_segmented-control-item_properties_item_padding-horizontal
36
+ ) !important;
37
+ padding-right: var(
38
+ --recursica_ui-kit_components_segmented-control-item_properties_item_padding-horizontal
39
+ ) !important;
40
+ height: var(
41
+ --recursica_ui-kit_components_segmented-control-item_properties_item_height
42
+ ) !important;
43
+ border-radius: var(
44
+ --recursica_ui-kit_components_segmented-control-item_properties_item_border-radius
45
+ ) !important;
46
+
47
+ font-family: var(
48
+ --recursica_ui-kit_components_segmented-control-item_properties_text_font-family
49
+ );
50
+ font-size: var(
51
+ --recursica_ui-kit_components_segmented-control-item_properties_text_font-size
52
+ );
53
+ font-style: var(
54
+ --recursica_ui-kit_components_segmented-control-item_properties_text_font-style
55
+ );
56
+ font-weight: var(
57
+ --recursica_ui-kit_components_segmented-control-item_properties_text_font-weight
58
+ );
59
+ letter-spacing: var(
60
+ --recursica_ui-kit_components_segmented-control-item_properties_text_letter-spacing
61
+ );
62
+ line-height: var(
63
+ --recursica_ui-kit_components_segmented-control-item_properties_text_line-height
64
+ );
65
+ text-decoration: var(
66
+ --recursica_ui-kit_components_segmented-control-item_properties_text_text-decoration
67
+ );
68
+ text-transform: var(
69
+ --recursica_ui-kit_components_segmented-control-item_properties_text_text-transform
70
+ );
71
+
72
+ color: var(
73
+ --recursica_ui-kit_components_segmented-control_properties_colors_text
74
+ ) !important;
75
+
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ }
80
+
81
+ /* Mantine natively wraps label contents in an innerLabel span */
82
+ .label :global(.mantine-SegmentedControl-innerLabel) {
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: center;
86
+ gap: var(
87
+ --recursica_ui-kit_components_segmented-control-item_properties_item_icon-text-gap
88
+ );
89
+ }
90
+
91
+ .label svg {
92
+ width: var(
93
+ --recursica_ui-kit_components_segmented-control-item_properties_item_icon-size
94
+ );
95
+ height: var(
96
+ --recursica_ui-kit_components_segmented-control-item_properties_item_icon-size
97
+ );
98
+ flex-shrink: 0;
99
+ }
100
+
101
+ /* Mantine adds a background on hover, we must strictly strip it */
102
+ .label:hover {
103
+ background-color: transparent !important;
104
+ }
105
+
106
+ /* Mantine adds separators via ::before on the .control */
107
+ .control::before {
108
+ background-color: var(
109
+ --recursica_ui-kit_components_segmented-control_properties_colors_divider-color
110
+ ) !important;
111
+ }
112
+
113
+ /* Indicator (the moving selected block) */
114
+ .indicator {
115
+ background-color: var(
116
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_colors_background
117
+ ) !important;
118
+ border: var(
119
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_border-size
120
+ )
121
+ solid
122
+ var(
123
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_colors_border-color
124
+ ) !important;
125
+ box-shadow: var(
126
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_elevation
127
+ ) !important;
128
+ border-radius: var(
129
+ --recursica_ui-kit_components_segmented-control-item_properties_item_border-radius
130
+ ) !important;
131
+ }
132
+
133
+ /* Selected label text color override */
134
+ .control[data-active] .label {
135
+ color: var(
136
+ --recursica_ui-kit_components_segmented-control-item_properties_selected_colors_text-color
137
+ ) !important;
138
+ }
@@ -1,18 +1,120 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { SegmentedControl } from "./SegmentedControl";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
3
 
5
4
  const meta: Meta<typeof SegmentedControl> = {
6
- title: "UI-Kit/🚧 SegmentedControl",
5
+ title: "UI-Kit/SegmentedControl",
7
6
  component: SegmentedControl,
8
7
  tags: ["autodocs"],
9
- argTypes: {},
10
- };
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component:
12
+ "SegmentedControl provides a linear set of two or more segments, each of which functions as a mutually exclusive button.",
13
+ },
14
+ },
15
+ },
16
+ argTypes: {
17
+ orientation: {
18
+ control: "radio",
19
+ options: ["horizontal", "vertical"],
20
+ },
21
+ fullWidth: {
22
+ control: "boolean",
23
+ },
24
+ disabled: {
25
+ control: "boolean",
26
+ },
27
+ data: { table: { disable: true } },
28
+ defaultChecked: { table: { disable: true } },
29
+ },
30
+ } satisfies Meta<typeof SegmentedControl>;
11
31
 
12
32
  export default meta;
13
-
14
33
  type Story = StoryObj<typeof SegmentedControl>;
15
34
 
16
35
  export const Default: Story = {
17
- render: () => <ComingSoon componentName="SegmentedControl" />,
36
+ args: {
37
+ data: ["React", "Angular", "Vue", "Svelte"],
38
+ orientation: "horizontal",
39
+ fullWidth: false,
40
+ disabled: false,
41
+ },
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
43
+ render: ({ withLayer, layer, ...args }: any) => {
44
+ return <SegmentedControl {...args} />;
45
+ },
46
+ };
47
+
48
+ export const FullWidth: Story = {
49
+ args: {
50
+ data: ["Daily", "Weekly", "Monthly"],
51
+ fullWidth: true,
52
+ },
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
54
+ render: ({ withLayer, layer, ...args }: any) => {
55
+ return <SegmentedControl {...args} />;
56
+ },
57
+ };
58
+
59
+ export const Vertical: Story = {
60
+ args: {
61
+ data: ["Option 1", "Option 2", "Option 3"],
62
+ orientation: "vertical",
63
+ },
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
65
+ render: ({ withLayer, layer, ...args }: any) => {
66
+ return <SegmentedControl {...args} />;
67
+ },
68
+ };
69
+
70
+ const CheckIcon = () => (
71
+ <svg
72
+ viewBox="0 0 24 24"
73
+ fill="none"
74
+ xmlns="http://www.w3.org/2000/svg"
75
+ stroke="currentColor"
76
+ strokeWidth="2"
77
+ strokeLinecap="round"
78
+ strokeLinejoin="round"
79
+ >
80
+ <polyline points="20 6 9 17 4 12" />
81
+ </svg>
82
+ );
83
+
84
+ export const WithIcons: Story = {
85
+ args: {
86
+ data: [
87
+ {
88
+ value: "daily",
89
+ label: (
90
+ <>
91
+ <CheckIcon />
92
+ <span>Daily</span>
93
+ </>
94
+ ),
95
+ },
96
+ {
97
+ value: "weekly",
98
+ label: (
99
+ <>
100
+ <CheckIcon />
101
+ <span>Weekly</span>
102
+ </>
103
+ ),
104
+ },
105
+ {
106
+ value: "monthly",
107
+ label: (
108
+ <>
109
+ <CheckIcon />
110
+ <span>Monthly</span>
111
+ </>
112
+ ),
113
+ },
114
+ ],
115
+ },
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
117
+ render: ({ withLayer, layer, ...args }: any) => {
118
+ return <SegmentedControl {...args} />;
119
+ },
18
120
  };
@@ -1,7 +1,98 @@
1
- import React from "react";
1
+ import { forwardRef } from "react";
2
+ import {
3
+ SegmentedControl as MantineSegmentedControl,
4
+ type SegmentedControlProps as MantineSegmentedControlProps,
5
+ } from "@mantine/core";
6
+ import {
7
+ filterStylingProps,
8
+ type RecursicaOverStyled,
9
+ } from "../../utils/filterStylingProps";
10
+ import styles from "./SegmentedControl.module.css";
2
11
 
3
- export type SegmentedControlProps = React.HTMLAttributes<HTMLDivElement>;
12
+ export interface RecursicaSegmentedControlProps {
13
+ /** The orientation of the control */
14
+ orientation?: "horizontal" | "vertical";
15
+ /** If true, the control will take up the full width of its container */
16
+ fullWidth?: boolean;
17
+ }
4
18
 
5
- export const SegmentedControl: React.FC<SegmentedControlProps> = (props) => {
6
- return <div {...props}>SegmentedControl</div>;
7
- };
19
+ export type SegmentedControlProps = RecursicaOverStyled<
20
+ Omit<
21
+ MantineSegmentedControlProps,
22
+ "variant" | "size" | "radius" | "color" | "classNames" | "className"
23
+ > & {
24
+ className?: string;
25
+ classNames?: Partial<Record<string, string>>;
26
+ } & RecursicaSegmentedControlProps
27
+ >;
28
+
29
+ function useSegmentedControlClassNames(restRecord: Record<string, unknown>): {
30
+ className: string;
31
+ classNames: Partial<Record<string, string>>;
32
+ } {
33
+ const mergedClassNames: Partial<Record<string, string>> = {
34
+ root: styles.root,
35
+ control: styles.control,
36
+ label: styles.label,
37
+ indicator: styles.indicator,
38
+ };
39
+
40
+ const classNamesProp = restRecord.classNames;
41
+ if (
42
+ classNamesProp &&
43
+ typeof classNamesProp === "object" &&
44
+ !Array.isArray(classNamesProp)
45
+ ) {
46
+ const o = classNamesProp as Partial<Record<string, string>>;
47
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
48
+ mergedClassNames.control = o.control
49
+ ? `${styles.control} ${o.control}`
50
+ : styles.control;
51
+ mergedClassNames.label = o.label
52
+ ? `${styles.label} ${o.label}`
53
+ : styles.label;
54
+ mergedClassNames.indicator = o.indicator
55
+ ? `${styles.indicator} ${o.indicator}`
56
+ : styles.indicator;
57
+ }
58
+
59
+ const classNameProp = restRecord.className as string | undefined;
60
+ const finalClass = classNameProp
61
+ ? `${styles.root} ${classNameProp}`
62
+ : styles.root;
63
+
64
+ return { className: finalClass, classNames: mergedClassNames };
65
+ }
66
+
67
+ const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(
68
+ function SegmentedControl(
69
+ { overStyled = false, orientation = "horizontal", fullWidth, ...rest },
70
+ ref,
71
+ ) {
72
+ const sanitizedProps = filterStylingProps(rest, overStyled);
73
+ const stylingParams = useSegmentedControlClassNames(
74
+ sanitizedProps as Record<string, unknown>,
75
+ );
76
+
77
+ return (
78
+ <MantineSegmentedControl
79
+ ref={ref}
80
+ className={stylingParams.className}
81
+ classNames={stylingParams.classNames}
82
+ orientation={orientation}
83
+ fullWidth={fullWidth}
84
+ data-orientation={orientation}
85
+ {...(sanitizedProps as Omit<
86
+ MantineSegmentedControlProps,
87
+ "variant" | "size"
88
+ >)}
89
+ />
90
+ );
91
+ },
92
+ );
93
+ _SegmentedControl.displayName = "SegmentedControl";
94
+
95
+ /**
96
+ * Recursica SegmentedControl component wrapping Mantine's SegmentedControl.
97
+ */
98
+ export const SegmentedControl = _SegmentedControl;
@@ -1,13 +1,9 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Stack as MantineStack,
4
4
  type StackProps as MantineStackProps,
5
5
  } from "@mantine/core";
6
- import {
7
- filterStylingProps,
8
- type RecursicaOverStyled,
9
- type RecursicaSpacing,
10
- } from "../../utils/filterStylingProps";
6
+ import { type RecursicaSpacing } from "../../utils/filterStylingProps";
11
7
  import styles from "./Stack.module.css";
12
8
 
13
9
  export interface RecursicaStackProps {
@@ -19,24 +15,23 @@ export interface RecursicaStackProps {
19
15
  }
20
16
 
21
17
  /**
22
- * Stack flex layout wrapper
18
+ * Stack flex layout wrapper.
19
+ *
20
+ * Note: Unlike complex UI components, primitive layout components (Flex, Stack, Group, Container)
21
+ * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
22
+ * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
23
23
  */
24
- export type StackProps = RecursicaOverStyled<
25
- MantineStackProps & RecursicaStackProps
26
- >;
24
+ export type StackProps = MantineStackProps & RecursicaStackProps;
27
25
 
28
26
  export const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(
29
- { children, overStyled = false, gap = "rec-default", ...rest },
27
+ { children, gap = "rec-default", ...rest },
30
28
  ref,
31
29
  ) {
32
- const sanitizedProps = filterStylingProps({ ...rest, gap }, overStyled);
33
- const restRecord = sanitizedProps as Record<string, unknown>;
34
-
35
30
  const mergedClassNames: Partial<Record<string, string>> = {
36
31
  root: styles.root,
37
32
  };
38
33
 
39
- const classNamesProp = restRecord.classNames;
34
+ const classNamesProp = rest.classNames;
40
35
  if (
41
36
  classNamesProp &&
42
37
  typeof classNamesProp === "object" &&
@@ -46,7 +41,7 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(
46
41
  mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
47
42
  }
48
43
 
49
- const classNameProp = restRecord.className as string | undefined;
44
+ const classNameProp = rest.className as string | undefined;
50
45
  const finalClass = classNameProp
51
46
  ? `${styles.root} ${classNameProp}`
52
47
  : styles.root;
@@ -56,7 +51,8 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(
56
51
  ref={ref}
57
52
  className={finalClass}
58
53
  classNames={mergedClassNames}
59
- {...sanitizedProps}
54
+ gap={gap}
55
+ {...rest}
60
56
  >
61
57
  {children}
62
58
  </MantineStack>