@recursica/mantine-adapter 0.26.0 → 0.27.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 (67) hide show
  1. package/CHANGELOG.md +17 -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 +1289 -1254
  6. package/dist/mantine-adapter.js.map +1 -1
  7. package/dist/src/components/Accordion/Accordion.d.ts +3 -4
  8. package/dist/src/components/AutoComplete/AutoComplete.d.ts +4 -6
  9. package/dist/src/components/Avatar/Avatar.d.ts +2 -3
  10. package/dist/src/components/Badge/Badge.d.ts +1 -1
  11. package/dist/src/components/Button/Button.d.ts +1 -1
  12. package/dist/src/components/Card/Card.d.ts +10 -2
  13. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +2 -6
  14. package/dist/src/components/Container/Container.d.ts +14 -2
  15. package/dist/src/components/DatePicker/DatePicker.d.ts +1 -5
  16. package/dist/src/components/Dropdown/Dropdown.d.ts +1 -1
  17. package/dist/src/components/Flex/Flex.d.ts +26 -3
  18. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +1 -0
  19. package/dist/src/components/Group/Group.d.ts +14 -2
  20. package/dist/src/components/Link/Link.d.ts +3 -4
  21. package/dist/src/components/Menu/Menu.d.ts +2 -2
  22. package/dist/src/components/Panel/Panel.d.ts +6 -4
  23. package/dist/src/components/Radio/RadioGroup.d.ts +2 -6
  24. package/dist/src/components/Slider/Slider.d.ts +1 -5
  25. package/dist/src/components/Stack/Stack.d.ts +27 -4
  26. package/dist/src/components/Stepper/Stepper.d.ts +4 -2
  27. package/dist/src/components/Switch/SwitchGroup.d.ts +2 -6
  28. package/dist/src/components/Table/Table.d.ts +16 -3
  29. package/dist/src/components/Tabs/Tabs.d.ts +4 -2
  30. package/dist/src/components/Text/Text.d.ts +3 -2
  31. package/dist/src/components/TextArea/TextArea.d.ts +1 -1
  32. package/dist/src/components/TextField/TextField.d.ts +1 -5
  33. package/dist/src/components/Title/Title.d.ts +2 -1
  34. package/dist/src/index.d.ts +1 -0
  35. package/dist/src/utils/filterStylingProps.d.ts +1 -1
  36. package/package.json +2 -2
  37. package/src/components/Accordion/Accordion.tsx +1 -1
  38. package/src/components/AutoComplete/AutoComplete.tsx +13 -4
  39. package/src/components/Avatar/Avatar.tsx +1 -1
  40. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +7 -0
  41. package/src/components/Card/Card.module.css +1 -0
  42. package/src/components/Card/Card.tsx +25 -1
  43. package/src/components/Checkbox/CheckboxGroup.tsx +6 -3
  44. package/src/components/Container/Container.tsx +4 -2
  45. package/src/components/DatePicker/DatePicker.tsx +1 -3
  46. package/src/components/Dropdown/Dropdown.tsx +4 -11
  47. package/src/components/Flex/Flex.tsx +7 -2
  48. package/src/components/FormControlWrapper/FormControlWrapper.tsx +1 -0
  49. package/src/components/Group/Group.tsx +7 -2
  50. package/src/components/Link/Link.tsx +3 -3
  51. package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +3 -3
  52. package/src/components/Panel/Panel.stories.tsx +8 -8
  53. package/src/components/Panel/Panel.tsx +11 -4
  54. package/src/components/Radio/RadioGroup.tsx +6 -3
  55. package/src/components/ReadOnlyField/ReadOnlyField.tsx +5 -1
  56. package/src/components/Stack/Stack.tsx +7 -2
  57. package/src/components/Stepper/Stepper.tsx +5 -1
  58. package/src/components/Switch/SwitchGroup.tsx +6 -3
  59. package/src/components/Table/Table.module.css +7 -0
  60. package/src/components/Table/Table.stories.tsx +33 -3
  61. package/src/components/Table/Table.tsx +56 -5
  62. package/src/components/Tabs/Tabs.tsx +5 -1
  63. package/src/components/Text/Text.tsx +3 -1
  64. package/src/components/TextArea/TextArea.tsx +2 -9
  65. package/src/components/Title/Title.tsx +3 -1
  66. package/src/index.ts +14 -0
  67. package/src/utils/filterStylingProps.ts +1 -0
@@ -1,6 +1,7 @@
1
+ import { TextProps as MantineTextProps } from '@mantine/core';
1
2
  import { RecursicaOverStyled } from '../../utils/filterStylingProps';
2
3
  import { RecursicaTextProps } from '@recursica/adapter-common';
3
- export type TextProps = RecursicaOverStyled<RecursicaTextProps>;
4
+ export type TextProps = RecursicaOverStyled<Omit<MantineTextProps, "variant"> & RecursicaTextProps>;
4
5
  /**
5
6
  * A generalized typographical wrapper limiting text properties to bounded Recursica UI-kit tokens inherently.
6
7
  * Do not use for semantic headings; use the explicit `<Title>` component for `<h1>` - `<h6>`.
@@ -14,7 +15,7 @@ export type TextProps = RecursicaOverStyled<RecursicaTextProps>;
14
15
  */
15
16
  export declare const Text: (<C = "p">(props: import('@mantine/core').PolymorphicComponentProps<C, TextProps>) => React.ReactElement) & Omit<import('react').FunctionComponent<((TextProps & {
16
17
  component?: any;
17
- }) & Omit<Omit<any, "ref">, "variant" | "children" | "overStyled" | "component"> & {
18
+ }) & Omit<Omit<any, "ref">, "className" | "classNames" | "style" | "styles" | "vars" | "p" | "px" | "py" | "pt" | "pb" | "pl" | "pr" | "bg" | "c" | "opacity" | "ff" | "fz" | "fw" | "lts" | "ta" | "lh" | "fs" | "tt" | "td" | "bd" | "w" | "miw" | "maw" | "h" | "mih" | "mah" | "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap" | "top" | "left" | "bottom" | "right" | "variant" | "span" | "color" | "children" | "__vars" | "__size" | "hiddenFrom" | "visibleFrom" | "lightHidden" | "darkHidden" | "mod" | "ms" | "me" | "ps" | "pe" | "bdrs" | "bgsz" | "bgp" | "bgr" | "bga" | "pos" | "inset" | "display" | "flex" | "unstyled" | "attributes" | "overStyled" | "inherit" | "inline" | "size" | "__staticSelector" | "component" | "gradient" | "lineClamp" | "truncate"> & {
18
19
  ref?: any;
19
20
  renderRoot?: (props: any) => any;
20
21
  }) | (TextProps & {
@@ -3,7 +3,7 @@ import { TextareaProps as MantineTextareaProps } from '@mantine/core';
3
3
  import { ReadOnlyControlProps, RecursicaTextAreaProps as BaseRecursicaTextAreaProps } from '@recursica/adapter-common';
4
4
  import { RecursicaOverStyled } from '../../utils/filterStylingProps';
5
5
  import { RecursicaFormControlWrapperProps } from '../FormControlWrapper/FormControlWrapper';
6
- export interface RecursicaTextAreaProps extends Omit<MantineTextareaProps, "size" | "variant" | "radius" | "wrapperProps">, Pick<RecursicaFormControlWrapperProps, "assistiveText" | "assistiveWithIcon" | "formLayout" | "labelSize" | "labelAlignment" | "labelOptionalText" | "labelWithEditIcon" | "onLabelEditClick">, ReadOnlyControlProps, BaseRecursicaTextAreaProps {
6
+ export interface RecursicaTextAreaProps extends Omit<MantineTextareaProps, "size" | "variant" | "radius" | "wrapperProps">, Omit<RecursicaFormControlWrapperProps, "controlMaxWidth" | "controlMinWidth">, ReadOnlyControlProps, BaseRecursicaTextAreaProps {
7
7
  }
8
8
  export type TextAreaProps = RecursicaOverStyled<RecursicaTextAreaProps>;
9
9
  export declare const TextArea: React.ForwardRefExoticComponent<TextAreaProps & React.RefAttributes<HTMLTextAreaElement>>;
@@ -6,8 +6,4 @@ import { RecursicaFormControlWrapperProps } from '../FormControlWrapper/FormCont
6
6
  export interface RecursicaTextFieldProps extends Omit<InputProps, "size" | "variant" | "radius" | "wrapperProps">, Pick<InputWrapperProps, "label" | "error" | "required" | "withAsterisk" | "id">, Omit<React.ComponentPropsWithoutRef<"input">, "size" | "style" | "className" | "id">, Omit<RecursicaFormControlWrapperProps, "controlMaxWidth" | "controlMinWidth">, ReadOnlyControlProps, BaseRecursicaTextFieldProps {
7
7
  }
8
8
  export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
9
- export declare const TextField: React.ForwardRefExoticComponent<(Omit<Omit<RecursicaTextFieldProps, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
10
- overStyled?: false | undefined;
11
- }, "ref"> | Omit<RecursicaTextFieldProps & {
12
- overStyled: true;
13
- }, "ref">) & React.RefAttributes<HTMLInputElement>>;
9
+ export declare const TextField: React.ForwardRefExoticComponent<TextFieldProps & React.RefAttributes<HTMLInputElement>>;
@@ -1,6 +1,7 @@
1
+ import { TitleProps as MantineTitleProps } from '@mantine/core';
1
2
  import { RecursicaOverStyled } from '../../utils/filterStylingProps';
2
3
  import { RecursicaTitleProps } from '@recursica/adapter-common';
3
- export type TitleProps = RecursicaOverStyled<RecursicaTitleProps>;
4
+ export type TitleProps = RecursicaOverStyled<Omit<MantineTitleProps, "size"> & RecursicaTitleProps>;
4
5
  /**
5
6
  * Enforces highly accessible structural markup utilizing semantic `<h1>` through `<h6>` tags securely bound directly to Recursica typographic scales.
6
7
  */
@@ -1,2 +1,3 @@
1
1
  export * from './components';
2
2
  export * from '@recursica/adapter-common';
3
+ export type { RecursicaCheckboxGroupProps, RecursicaDatePickerProps, RecursicaDropdownProps, RecursicaNumberInputProps, RecursicaRadioGroupProps, RecursicaReadOnlyFieldProps, RecursicaReadOnlyTextFieldProps, RecursicaSliderProps, RecursicaSwitchGroupProps, RecursicaTextAreaProps, RecursicaTextFieldProps, } from './components';
@@ -22,7 +22,7 @@
22
22
  * @returns Sanitized component props safe for internal styling merging
23
23
  */
24
24
  export declare const BLOCKED_STYLING_KEYS: readonly ["className", "classNames", "style", "styles", "vars", "p", "px", "py", "pt", "pb", "pl", "pr", "bg", "c", "opacity", "ff", "fz", "fw", "lts", "ta", "lh", "fs", "tt", "td", "bd", "bdw", "bds", "bdc", "bdr", "shadow", "w", "miw", "maw", "h", "mih", "mah"];
25
- export { type RecursicaSpacing, type RecursicaSize, type RecursicaOverStyled, type BlockedStylingKeys, type ForbiddenStyles, } from '@recursica/adapter-common';
25
+ export { type RecursicaSpacing, type RecursicaSize, type RecursicaOverStyled, type BlockedStylingKeys, type ForbiddenStyles, type WithRecursicaSpacing, } from '@recursica/adapter-common';
26
26
  export declare const SPACING_MAP: Record<string, string>;
27
27
  export declare function mapLayoutProps<T extends Record<string, unknown>>(props: T): T;
28
28
  export declare function filterStylingProps<T extends Record<string, unknown>>(props: T, overStyled?: boolean): Partial<T>;
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "url": "git+https://github.com/borderux/recursica.git",
14
14
  "directory": "packages/mantine-adapter"
15
15
  },
16
- "version": "0.26.0",
16
+ "version": "0.27.0",
17
17
  "type": "module",
18
18
  "main": "./dist/mantine-adapter.cjs",
19
19
  "module": "./dist/mantine-adapter.js",
@@ -58,7 +58,6 @@
58
58
  "devDependencies": {
59
59
  "@chromatic-com/storybook": "^5.1.1",
60
60
  "@eslint/js": "^9.25.0",
61
- "@recursica/adapter-common": "*",
62
61
  "@recursica/recursica-postcss-vars": "*",
63
62
  "@recursica/storybook-template": "*",
64
63
  "@recursica/token-analyzer": "*",
@@ -93,6 +92,7 @@
93
92
  "vitest": "^3.2.4"
94
93
  },
95
94
  "dependencies": {
95
+ "@recursica/adapter-common": "*",
96
96
  "@recursica/official-release": "*"
97
97
  },
98
98
  "peerDependencies": {
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Accordion as MantineAccordion,
4
4
  type AccordionProps as MantineAccordionProps,
@@ -18,7 +18,13 @@ import { type RecursicaAutocompleteProps as BaseRecursicaAutocompleteProps } fro
18
18
  export interface RecursicaAutoCompleteProps
19
19
  extends Omit<
20
20
  MantineAutocompleteProps,
21
- "size" | "variant" | "radius" | "wrapperProps"
21
+ | "size"
22
+ | "variant"
23
+ | "radius"
24
+ | "wrapperProps"
25
+ | "data"
26
+ | "defaultValue"
27
+ | "value"
22
28
  >,
23
29
  Pick<
24
30
  InputWrapperProps,
@@ -29,7 +35,10 @@ export interface RecursicaAutoCompleteProps
29
35
  "controlMaxWidth" | "controlMinWidth"
30
36
  >,
31
37
  ReadOnlyControlProps,
32
- BaseRecursicaAutocompleteProps {}
38
+ BaseRecursicaAutocompleteProps {
39
+ /** Current input value */
40
+ value?: string;
41
+ }
33
42
 
34
43
  export type AutoCompleteProps = RecursicaOverStyled<RecursicaAutoCompleteProps>;
35
44
 
@@ -140,8 +149,8 @@ export const AutoComplete = forwardRef<HTMLInputElement, AutoCompleteProps>(
140
149
  ref={ref}
141
150
  classNames={mergedClassNames}
142
151
  disabled={disabled}
143
- value={value}
144
- defaultValue={defaultValue}
152
+ value={value as any}
153
+ defaultValue={defaultValue as any}
145
154
  wrapperProps={{
146
155
  "data-disabled": disabled ? "true" : undefined,
147
156
  "data-error": error ? "true" : undefined,
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Avatar as MantineAvatar,
4
4
  type AvatarProps as MantineAvatarProps,
@@ -8,3 +8,10 @@ Because Mantine natively constructs `Card` bounding boxes with generic inner `<C
8
8
  - `<Card.Footer>` explicitly hooks `--recursica_ui-kit_components_card_properties_footer-background` and corresponding padding variables.
9
9
 
10
10
  Mantine's generic `<Card.Section>` calculates negative margins implicitly. Because of this, it is crucial that our local CSS module declares `--card-padding: var(--recursica_ui-kit_components_card_properties_padding)` directly on `.root` so that all generic or explicit section wrappers natively stretch across the bounding box properly.
11
+
12
+ ## Layout Alignment Exceptions
13
+
14
+ To allow Cards to fit cleanly inside dynamic/flex layouts (like dashboard panels, grid tracks, or sidebar layout segments), the Card wrapper implements a custom gatekeeper bypass for outer styling properties:
15
+
16
+ - Exposes a safe subset of flexbox/dimensions styling properties (`flex`, `flexGrow`, `flexShrink`, `flexBasis`, `grow`, `h`, `height`) on the root `<Card>` component to allow proper sizing alongside layout siblings.
17
+ - Sets `<Card.Content>` to `flex-grow: 1;` by default via CSS modules. Since the root `<Card>` has `display: flex; flex-direction: column;`, this makes the content area expand to fill all vertical space, pushing `<Card.Footer>` to align at the absolute bottom of the bounding box.
@@ -89,6 +89,7 @@
89
89
  flex-direction: column;
90
90
  gap: var(--recursica_ui-kit_components_card_properties_vertical-gutter);
91
91
  padding: 0;
92
+ flex-grow: 1;
92
93
 
93
94
  /* Direct Figma Typography Mapping */
94
95
  font-family: var(
@@ -19,7 +19,15 @@ import {
19
19
  // ==== CARD CONTAINER ====
20
20
  export type CardProps = RecursicaOverStyled<
21
21
  MantineCardProps & RecursicaCardProps
22
- >;
22
+ > & {
23
+ flex?: string | number;
24
+ flexGrow?: string | number;
25
+ flexShrink?: string | number;
26
+ flexBasis?: string | number;
27
+ grow?: string | number;
28
+ h?: string | number;
29
+ height?: string | number;
30
+ };
23
31
 
24
32
  /**
25
33
  * 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.
@@ -30,6 +38,22 @@ const CardBase = forwardRef<HTMLDivElement, CardProps>(function Card(
30
38
  ) {
31
39
  const sanitizedProps = filterStylingProps(rest, overStyled);
32
40
 
41
+ // Expose outer layout/flexbox properties on Card to allow structuring alongside siblings
42
+ const safeCardLayoutKeys = [
43
+ "flex",
44
+ "flexGrow",
45
+ "flexShrink",
46
+ "flexBasis",
47
+ "grow",
48
+ "h",
49
+ "height",
50
+ ] as const;
51
+ safeCardLayoutKeys.forEach((key) => {
52
+ if (key in rest && !(key in sanitizedProps)) {
53
+ (sanitizedProps as any)[key] = (rest as any)[key];
54
+ }
55
+ });
56
+
33
57
  const mergedClassNames: Partial<Record<string, string>> = {
34
58
  root: styles.root,
35
59
  };
@@ -16,7 +16,10 @@ import styles from "./Checkbox.module.css";
16
16
  import { type RecursicaCheckboxGroupProps as BaseRecursicaCheckboxGroupProps } from "@recursica/adapter-common";
17
17
 
18
18
  export interface RecursicaCheckboxGroupProps
19
- extends Omit<MantineCheckboxGroupProps, "size" | "labelProps">,
19
+ extends Omit<
20
+ MantineCheckboxGroupProps,
21
+ "size" | "labelProps" | "defaultValue" | "value" | "onChange"
22
+ >,
20
23
  Omit<
21
24
  RecursicaFormControlWrapperProps,
22
25
  "controlMaxWidth" | "controlMinWidth"
@@ -99,8 +102,8 @@ export const CheckboxGroup = forwardRef<HTMLDivElement, CheckboxGroupProps>(
99
102
  /* Natively bind local disabled lock dynamically */
100
103
  {...(sanitizedProps as unknown as MantineCheckboxGroupProps)}
101
104
  disabled={readOnly || (restRecord as any).disabled}
102
- value={value}
103
- defaultValue={defaultValue}
105
+ value={value as any}
106
+ defaultValue={defaultValue as any}
104
107
  >
105
108
  <div className={styles.groupRoot} data-layout={formLayout}>
106
109
  {children}
@@ -5,6 +5,7 @@ import {
5
5
  } from "@mantine/core";
6
6
  import styles from "./Container.module.css";
7
7
 
8
+ import { type WithRecursicaSpacing } from "../../utils/filterStylingProps";
8
9
  import { type RecursicaContainerProps } from "@recursica/adapter-common";
9
10
 
10
11
  /**
@@ -14,8 +15,9 @@ import { type RecursicaContainerProps } from "@recursica/adapter-common";
14
15
  * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
15
16
  * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
16
17
  */
17
- export type ContainerProps = Omit<MantineContainerProps, "size"> &
18
- RecursicaContainerProps;
18
+ export type ContainerProps = WithRecursicaSpacing<
19
+ Omit<MantineContainerProps, "size"> & RecursicaContainerProps
20
+ >;
19
21
 
20
22
  export const Container = forwardRef<HTMLDivElement, ContainerProps>(
21
23
  function Container({ children, size, ...rest }, ref) {
@@ -38,7 +38,7 @@ export interface RecursicaDatePickerProps
38
38
 
39
39
  export type DatePickerProps = RecursicaOverStyled<RecursicaDatePickerProps>;
40
40
 
41
- export const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(
41
+ export const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
42
42
  function DatePicker(props, ref) {
43
43
  const {
44
44
  overStyled = false,
@@ -148,9 +148,7 @@ export const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(
148
148
  ref={ref}
149
149
  classNames={mergedClassNames}
150
150
  disabled={disabled}
151
- // @ts-expect-error Mantine 8 DatePickerInput types are overly complex for unified wrappers
152
151
  value={value}
153
- // @ts-expect-error Mantine 8 DatePickerInput types are overly complex for unified wrappers
154
152
  defaultValue={defaultValue}
155
153
  label={undefined} // Disable Mantine's native label
156
154
  description={undefined} // Disable Mantine's native description
@@ -17,18 +17,11 @@ import { type RecursicaDropdownProps as BaseRecursicaDropdownProps } from "@recu
17
17
  export interface RecursicaDropdownProps
18
18
  extends Omit<
19
19
  MantineSelectProps,
20
- "size" | "variant" | "radius" | "wrapperProps"
20
+ "size" | "variant" | "radius" | "wrapperProps" | "data"
21
21
  >,
22
- Pick<
22
+ Omit<
23
23
  RecursicaFormControlWrapperProps,
24
- | "assistiveText"
25
- | "assistiveWithIcon"
26
- | "formLayout"
27
- | "labelSize"
28
- | "labelAlignment"
29
- | "labelOptionalText"
30
- | "labelWithEditIcon"
31
- | "onLabelEditClick"
24
+ "controlMaxWidth" | "controlMinWidth"
32
25
  >,
33
26
  ReadOnlyControlProps,
34
27
  BaseRecursicaDropdownProps {}
@@ -157,7 +150,7 @@ export const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
157
150
  disabled={disabled}
158
151
  value={value}
159
152
  defaultValue={defaultValue}
160
- data={data || []}
153
+ data={(data as any) || []}
161
154
  label={undefined}
162
155
  description={undefined}
163
156
  error={undefined}
@@ -4,7 +4,10 @@ import {
4
4
  type FlexProps as MantineFlexProps,
5
5
  createPolymorphicComponent,
6
6
  } from "@mantine/core";
7
- import { mapLayoutProps } from "../../utils/filterStylingProps";
7
+ import {
8
+ mapLayoutProps,
9
+ type WithRecursicaSpacing,
10
+ } from "../../utils/filterStylingProps";
8
11
  import styles from "./Flex.module.css";
9
12
 
10
13
  import { type RecursicaFlexProps } from "@recursica/adapter-common";
@@ -16,7 +19,9 @@ import { type RecursicaFlexProps } from "@recursica/adapter-common";
16
19
  * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
17
20
  * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
18
21
  */
19
- export type FlexProps = MantineFlexProps & RecursicaFlexProps;
22
+ export type FlexProps = WithRecursicaSpacing<
23
+ MantineFlexProps & RecursicaFlexProps
24
+ >;
20
25
 
21
26
  const _Flex = forwardRef<HTMLDivElement, FlexProps>(function Flex(
22
27
  { children, gap = "rec-default", rowGap, columnGap, ...rest },
@@ -10,6 +10,7 @@ import { AssistiveElement } from "../AssistiveElement/AssistiveElement";
10
10
  import styles from "./FormControlWrapper.module.css";
11
11
 
12
12
  import { type RecursicaFormControlWrapperProps } from "@recursica/adapter-common";
13
+ export type { RecursicaFormControlWrapperProps };
13
14
 
14
15
  export type FormControlWrapperProps = RecursicaOverStyled<
15
16
  Omit<InputWrapperProps, "labelProps" | "inputWrapperOrder"> &
@@ -3,7 +3,10 @@ import {
3
3
  Group as MantineGroup,
4
4
  type GroupProps as MantineGroupProps,
5
5
  } from "@mantine/core";
6
- import { mapLayoutProps } from "../../utils/filterStylingProps";
6
+ import {
7
+ mapLayoutProps,
8
+ type WithRecursicaSpacing,
9
+ } from "../../utils/filterStylingProps";
7
10
  import styles from "./Group.module.css";
8
11
 
9
12
  import { type RecursicaGroupProps } from "@recursica/adapter-common";
@@ -15,7 +18,9 @@ import { type RecursicaGroupProps } from "@recursica/adapter-common";
15
18
  * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
16
19
  * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
17
20
  */
18
- export type GroupProps = MantineGroupProps & RecursicaGroupProps;
21
+ export type GroupProps = WithRecursicaSpacing<
22
+ MantineGroupProps & RecursicaGroupProps
23
+ >;
19
24
 
20
25
  export const Group = forwardRef<HTMLDivElement, GroupProps>(function Group(
21
26
  { children, gap = "rec-default", ...rest },
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from "react";
1
+ import { forwardRef } from "react";
2
2
  import {
3
3
  Anchor as MantineAnchor,
4
4
  type AnchorProps as MantineAnchorProps,
@@ -13,7 +13,7 @@ import styles from "./Link.module.css";
13
13
  import { type RecursicaLinkProps } from "@recursica/adapter-common";
14
14
 
15
15
  export type LinkProps = RecursicaOverStyled<
16
- Omit<MantineAnchorProps, "underline"> & RecursicaLinkProps
16
+ Omit<MantineAnchorProps, "underline"> & Omit<RecursicaLinkProps, "component">
17
17
  >;
18
18
 
19
19
  const _Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
@@ -49,7 +49,7 @@ const _Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
49
49
  classNames={mergedClassNames}
50
50
  underline="never"
51
51
  {...(icon ? { "data-has-icon": "" } : {})}
52
- {...sanitizedProps}
52
+ {...(sanitizedProps as any)}
53
53
  >
54
54
  {icon && (
55
55
  <span className={styles.iconWrapper} aria-hidden>
@@ -55,11 +55,11 @@ Other stylesNames (`overlay`, `root`, `inner`, `close`) are left to Mantine defa
55
55
 
56
56
  ---
57
57
 
58
- ## 4. Default Position Override
58
+ ## 4. Default Placement Override
59
59
 
60
- **Decision:** Recursica defaults `position` to `"right"`. Mantine defaults to `"left"`.
60
+ **Decision:** Use `placement` instead of `position` for configuring slide-out direction, and default it to `"right"`.
61
61
 
62
- **Implementation:** The `position="right"` default is set before the prop spread, so developer-provided `position` values still take precedence. Right-side panels are the most common pattern for supplementary content, settings, and detail views.
62
+ **Implementation:** The prop was renamed from `position` to `placement` to prevent collision with the CSS `position` keyword, which is strictly blocked by the styling gatekeeper (`BLOCKED_STYLING_KEYS`). This allows configuring the drawer direction natively while maintaining strict design-system boundaries. The `placement="right"` default is mapped internally to Mantine Drawer's `position` prop before any other sanitized props are applied. Right-side panels are the most common pattern for supplementary content, settings, and detail views.
63
63
 
64
64
  ---
65
65
 
@@ -12,7 +12,7 @@ const meta: Meta = {
12
12
  component: Panel,
13
13
  tags: ["autodocs"],
14
14
  argTypes: {
15
- position: {
15
+ placement: {
16
16
  control: "select",
17
17
  options: ["left", "right", "top", "bottom"],
18
18
  description: "Side of the screen the panel slides in from.",
@@ -58,7 +58,7 @@ The \`Panel\` component slides in or expands from the edge of the screen to reve
58
58
  const [opened, { open, close }] = useDisclosure(false);
59
59
 
60
60
  <Button onClick={open}>Open Panel</Button>
61
- <Panel opened={opened} onClose={close} title="Settings" position="right">
61
+ <Panel opened={opened} onClose={close} title="Settings" placement="right">
62
62
  Content goes here
63
63
  <Panel.Footer>
64
64
  <Button variant="outline">Cancel</Button>
@@ -78,7 +78,7 @@ type Story = StoryObj<PanelStoryArgs>;
78
78
 
79
79
  export const Default: Story = {
80
80
  args: {
81
- position: "right",
81
+ placement: "right",
82
82
  title: "Panel Title",
83
83
  withOverlay: true,
84
84
  withCloseButton: true,
@@ -98,7 +98,7 @@ export const Default: Story = {
98
98
  opened={opened}
99
99
  onClose={() => setOpened(false)}
100
100
  title="Panel Title"
101
- position="right"
101
+ placement="right"
102
102
  wrapHeaderText={wrapHeaderText}
103
103
  >
104
104
  <Text>
@@ -118,9 +118,9 @@ export const Default: Story = {
118
118
  },
119
119
  };
120
120
 
121
- export const LeftPosition: Story = {
121
+ export const LeftPlacement: Story = {
122
122
  args: {
123
- position: "left",
123
+ placement: "left",
124
124
  title: "Navigation",
125
125
  withOverlay: true,
126
126
  withCloseButton: true,
@@ -153,7 +153,7 @@ export const LeftPosition: Story = {
153
153
 
154
154
  export const ScrollableContent: Story = {
155
155
  args: {
156
- position: "right",
156
+ placement: "right",
157
157
  title: "Scrollable Panel",
158
158
  withOverlay: true,
159
159
  withCloseButton: true,
@@ -195,7 +195,7 @@ export const ScrollableContent: Story = {
195
195
 
196
196
  export const LongTitle: Story = {
197
197
  args: {
198
- position: "right",
198
+ placement: "right",
199
199
  title:
200
200
  "This is a ridiculously long panel title designed to test how the header CSS handles text overflow and whether it truncates correctly or breaks the layout",
201
201
  withOverlay: true,
@@ -13,11 +13,18 @@ import styles from "./Panel.module.css";
13
13
  // PANEL (Drawer)
14
14
  // ============================================================
15
15
 
16
- import { type RecursicaPanelProps } from "@recursica/adapter-common";
16
+ import { type RecursicaPanelProps as BaseRecursicaPanelProps } from "@recursica/adapter-common";
17
17
 
18
18
  /**
19
19
  * Recursica Panel root props. Extends Mantine Drawer.
20
20
  */
21
+ export interface RecursicaPanelProps
22
+ extends Omit<
23
+ MantineDrawerProps,
24
+ "size" | "styles" | "classNames" | "style" | "position"
25
+ >,
26
+ BaseRecursicaPanelProps {}
27
+
21
28
  export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
22
29
 
23
30
  /**
@@ -29,7 +36,7 @@ export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
29
36
  * cluttering the main interface.
30
37
  *
31
38
  * ```tsx
32
- * <Panel opened={opened} onClose={close} title="Panel Title" position="right">
39
+ * <Panel opened={opened} onClose={close} title="Panel Title" placement="right">
33
40
  * <Panel.Body>
34
41
  * Content goes here
35
42
  * </Panel.Body>
@@ -48,7 +55,7 @@ export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
48
55
  */
49
56
  const PanelBase = function Panel({
50
57
  overStyled = false,
51
- position = "right",
58
+ placement = "right",
52
59
  keepMounted = true,
53
60
  wrapHeaderText = false,
54
61
  ...rest
@@ -82,7 +89,7 @@ const PanelBase = function Panel({
82
89
 
83
90
  return (
84
91
  <MantineDrawer
85
- position={position} /* Recursica default: right; Mantine default: left */
92
+ position={placement} /* Recursica default: right; Mantine default: left */
86
93
  keepMounted={keepMounted}
87
94
  closeOnClickOutside={rest.closeOnClickOutside ?? Boolean(rest.opened)}
88
95
  {...(sanitizedProps as unknown as MantineDrawerProps)}
@@ -16,7 +16,10 @@ import styles from "./Radio.module.css";
16
16
  import { type RecursicaRadioGroupProps as BaseRecursicaRadioGroupProps } from "@recursica/adapter-common";
17
17
 
18
18
  export interface RecursicaRadioGroupProps
19
- extends Omit<MantineRadioGroupProps, "size" | "labelProps">,
19
+ extends Omit<
20
+ MantineRadioGroupProps,
21
+ "size" | "labelProps" | "defaultValue" | "value" | "onChange"
22
+ >,
20
23
  Omit<
21
24
  RecursicaFormControlWrapperProps,
22
25
  "controlMaxWidth" | "controlMinWidth"
@@ -98,8 +101,8 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
98
101
  /* Natively bind local disabled lock dynamically */
99
102
  {...(sanitizedProps as unknown as MantineRadioGroupProps)}
100
103
  disabled={readOnly || (restRecord as any).disabled}
101
- value={value}
102
- defaultValue={defaultValue}
104
+ value={value as any}
105
+ defaultValue={defaultValue as any}
103
106
  >
104
107
  <div className={styles.groupRoot} data-layout={formLayout}>
105
108
  {children}
@@ -55,7 +55,11 @@ export const ReadOnlyField = forwardRef<HTMLDivElement, ReadOnlyFieldProps>(
55
55
  ? (Renderer as any).check(value)
56
56
  : EmptyValueRenderer.check(value);
57
57
 
58
- const displayValue = isValueEmpty ? <Renderer value={value} /> : value;
58
+ const displayValue = isValueEmpty ? (
59
+ <Renderer value={value as any} />
60
+ ) : (
61
+ value
62
+ );
59
63
 
60
64
  switch (type) {
61
65
  case "boolean":
@@ -4,7 +4,10 @@ import {
4
4
  type StackProps as MantineStackProps,
5
5
  createPolymorphicComponent,
6
6
  } from "@mantine/core";
7
- import { mapLayoutProps } from "../../utils/filterStylingProps";
7
+ import {
8
+ mapLayoutProps,
9
+ type WithRecursicaSpacing,
10
+ } from "../../utils/filterStylingProps";
8
11
  import styles from "./Stack.module.css";
9
12
 
10
13
  import { type RecursicaStackProps } from "@recursica/adapter-common";
@@ -16,7 +19,9 @@ import { type RecursicaStackProps } from "@recursica/adapter-common";
16
19
  * DO NOT use the `RecursicaOverStyled` gatekeeper. Developers must be able to freely pass
17
20
  * width, height, padding, margins, and flexbox alignment props to construct structural layouts.
18
21
  */
19
- export type StackProps = MantineStackProps & RecursicaStackProps;
22
+ export type StackProps = WithRecursicaSpacing<
23
+ MantineStackProps & RecursicaStackProps
24
+ >;
20
25
 
21
26
  const _Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(
22
27
  { children, gap = "rec-default", ...rest },
@@ -11,7 +11,11 @@ import styles from "./Stepper.module.css";
11
11
 
12
12
  import { type RecursicaStepperProps } from "@recursica/adapter-common";
13
13
 
14
- export type StepperProps = RecursicaOverStyled<RecursicaStepperProps>;
14
+ export interface RecursicaStepperPropsExtended
15
+ extends Omit<MantineStepperProps, "size">,
16
+ RecursicaStepperProps {}
17
+
18
+ export type StepperProps = RecursicaOverStyled<RecursicaStepperPropsExtended>;
15
19
 
16
20
  const _Stepper = forwardRef<HTMLDivElement, StepperProps>(
17
21
  function Stepper(props, ref) {
@@ -16,7 +16,10 @@ import styles from "./Switch.module.css";
16
16
  import { type RecursicaSwitchGroupProps as BaseRecursicaSwitchGroupProps } from "@recursica/adapter-common";
17
17
 
18
18
  export interface RecursicaSwitchGroupProps
19
- extends Omit<MantineSwitchGroupProps, "size" | "labelProps">,
19
+ extends Omit<
20
+ MantineSwitchGroupProps,
21
+ "size" | "labelProps" | "defaultValue" | "value" | "onChange"
22
+ >,
20
23
  Omit<
21
24
  RecursicaFormControlWrapperProps,
22
25
  "controlMaxWidth" | "controlMinWidth"
@@ -98,8 +101,8 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
98
101
  /* Natively bind local disabled lock dynamically */
99
102
  {...(sanitizedProps as unknown as MantineSwitchGroupProps)}
100
103
  disabled={readOnly || (restRecord as any).disabled}
101
- value={value}
102
- defaultValue={defaultValue}
104
+ value={value as any}
105
+ defaultValue={defaultValue as any}
103
106
  >
104
107
  <div className={styles.groupRoot} data-layout={formLayout}>
105
108
  {children}
@@ -0,0 +1,7 @@
1
+ /* HARDCODED VALUES:
2
+ * None. This is a generic layout wrapper.
3
+ */
4
+
5
+ .root {
6
+ /* Mantine Table handles table layout natively. */
7
+ }