@recursica/mantine-adapter 0.32.0 → 0.34.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 (70) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/OVERSTYLING.md +56 -0
  3. package/USAGE.md +6 -4
  4. package/dist/mantine-adapter.cjs +2 -2
  5. package/dist/mantine-adapter.cjs.map +1 -1
  6. package/dist/mantine-adapter.js +1765 -1445
  7. package/dist/mantine-adapter.js.map +1 -1
  8. package/dist/src/components/Modal/Modal.d.ts +21 -8
  9. package/dist/src/components/Pagination/Pagination.d.ts +45 -25
  10. package/dist/src/components/Panel/Panel.d.ts +22 -8
  11. package/dist/src/components/Stepper/Stepper.d.ts +4 -2
  12. package/dist/src/components/Table/Table.d.ts +25 -9
  13. package/dist/src/components/Tooltip/Tooltip.d.ts +4 -2
  14. package/llms.txt +57 -2
  15. package/package.json +3 -2
  16. package/src/OverStyling.tsx +10 -226
  17. package/src/components/Accordion/USAGE.md +90 -0
  18. package/src/components/AssistiveElement/USAGE.md +36 -0
  19. package/src/components/AutoComplete/USAGE.md +66 -0
  20. package/src/components/Avatar/USAGE.md +65 -0
  21. package/src/components/Badge/USAGE.md +59 -0
  22. package/src/components/Breadcrumb/USAGE.md +59 -0
  23. package/src/components/Button/USAGE.md +100 -0
  24. package/src/components/Card/USAGE.md +71 -0
  25. package/src/components/Checkbox/USAGE.md +64 -0
  26. package/src/components/Chip/USAGE.md +77 -0
  27. package/src/components/Container/USAGE.md +47 -0
  28. package/src/components/DatePicker/USAGE.md +55 -0
  29. package/src/components/Dropdown/USAGE.md +51 -0
  30. package/src/components/FileInput/USAGE.md +36 -0
  31. package/src/components/FileUpload/USAGE.md +41 -0
  32. package/src/components/Flex/USAGE.md +48 -0
  33. package/src/components/FormControlLayout/USAGE.md +40 -0
  34. package/src/components/FormControlWrapper/USAGE.md +75 -0
  35. package/src/components/Group/USAGE.md +48 -0
  36. package/src/components/HoverCard/USAGE.md +121 -0
  37. package/src/components/Label/USAGE.md +87 -0
  38. package/src/components/Link/USAGE.md +69 -0
  39. package/src/components/Loader/USAGE.md +63 -0
  40. package/src/components/Menu/USAGE.md +124 -0
  41. package/src/components/Modal/Modal.tsx +129 -23
  42. package/src/components/Modal/USAGE.md +58 -0
  43. package/src/components/NumberInput/USAGE.md +55 -0
  44. package/src/components/Pagination/Pagination.tsx +73 -17
  45. package/src/components/Pagination/USAGE.md +55 -0
  46. package/src/components/Panel/Panel.tsx +134 -14
  47. package/src/components/Panel/USAGE.md +145 -0
  48. package/src/components/Popover/USAGE.md +121 -0
  49. package/src/components/Radio/USAGE.md +36 -0
  50. package/src/components/ReadOnlyField/USAGE.md +52 -0
  51. package/src/components/SegmentedControl/USAGE.md +56 -0
  52. package/src/components/Slider/USAGE.md +86 -0
  53. package/src/components/Stack/USAGE.md +48 -0
  54. package/src/components/Stepper/Stepper.tsx +20 -2
  55. package/src/components/Stepper/USAGE.md +41 -0
  56. package/src/components/Switch/USAGE.md +65 -0
  57. package/src/components/Table/Table.tsx +153 -16
  58. package/src/components/Table/USAGE.md +41 -0
  59. package/src/components/Tabs/USAGE.md +45 -0
  60. package/src/components/Text/USAGE.md +40 -0
  61. package/src/components/TextArea/USAGE.md +48 -0
  62. package/src/components/TextField/USAGE.md +60 -0
  63. package/src/components/TimePicker/USAGE.md +36 -0
  64. package/src/components/Timeline/USAGE.md +57 -0
  65. package/src/components/Title/USAGE.md +36 -0
  66. package/src/components/Toast/USAGE.md +80 -0
  67. package/src/components/Tooltip/Tooltip.tsx +26 -2
  68. package/src/components/Tooltip/USAGE.md +124 -0
  69. package/src/components/TransferList/USAGE.md +46 -0
  70. package/src/components/Tree/USAGE.md +46 -0
@@ -0,0 +1,77 @@
1
+ # Chip - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Chip` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Chip } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Chip } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Chip defaultChecked>Clickable Chip</Chip>;
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 3. Design System Integration
29
+
30
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
31
+
32
+ > [!IMPORTANT]
33
+ >
34
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
35
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
36
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
37
+
38
+ ---
39
+
40
+ ## 4. Key Integration Features & Constraints
41
+
42
+ ## Architecture decisions
43
+
44
+ ### Mantine DOM Structure & Label Overrides
45
+
46
+ Mantine's `<Chip>` behaves like an input element (`radio` or `checkbox`). Under the hood, it renders:
47
+
48
+ 1. `.mantine-Chip-root` (wrapper)
49
+ 2. `input` (hidden visual structure)
50
+ 3. `.mantine-Chip-label` (The actual visible button-like pill)
51
+
52
+ Because the `.label` is the primary visual surface and handles Mantine's built-in `:hover` and active states, we direct our Recursica styling natively to `.label`.
53
+
54
+ ### Icon and Remove Implementations
55
+
56
+ To achieve this without breaking Mantine's `Chip` input architecture, we wrapped the internal `children` using a standard `span` DOM strategy:
57
+
58
+ ```tsx
59
+ <span className={styles.innerWrapper}>
60
+ {icon}
61
+ <span className={styles.children}>{children}</span>
62
+ {onRemove}
63
+ </span>
64
+ ```
65
+
66
+ #### Intermediate Children Wrapper Span display fix:
67
+
68
+ Mantine internally wraps the children passed to `Chip` in a default `<span>` which has `display: inline`. This intermediate `span` inherits the `line-height` of the `.label` container, causing the computed height of the Chip to be ~2px taller than expected. To address this, `.label > span:not(.mantineIconWrapper)` is targeted to force `display: inline-flex; align-items: center;` on that intermediate wrapper `span`, allowing it to collapse perfectly to the `16px` height of the `innerWrapper`.
69
+
70
+ ### Accessibility of Remove Action
71
+
72
+ Because the Chip fundamentally functions as a `<label>` linked to an `<input>`, placing a raw interactive element like `<button>` directly inside the standard Chip sub-tree violates nested interactive element ARIA constraints in strict validators.
73
+ To accommodate this, the visual "close" icon uses a `<span>` element configured with `role="button"` and `tabIndex={0}` to hook into standard keyboard activations without triggering generic nested `<form>` conflicts native to Mantine's baseline constraints.
74
+
75
+ ### Removing Sizing Properties
76
+
77
+ During implementation, the parsed Figma design tokens natively exported specific height/padding vectors dynamically (e.g., `--recursica_ui-kit_components_chip_properties_icon-size`) rather than explicit string variants (`sm`, `md`, `lg`). Therefore, we omitted `size` conceptually from the `RecursicaChipProps` wrapper to lock down size evaluation natively against the active layer variables.
@@ -0,0 +1,47 @@
1
+ # Container - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Container` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Container } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Container } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Container size="lg">
24
+ <Text>Centered content container constrained by maximum width.</Text>
25
+ </Container>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ---
31
+
32
+ ## 3. Design System Integration
33
+
34
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
35
+
36
+ > [!IMPORTANT]
37
+ >
38
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
39
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
40
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
41
+
42
+ ---
43
+
44
+ ## 4. Key Integration Features & Constraints
45
+
46
+ The `Container` component is a generic layout wrapper mapped directly to Mantine's `Container`.
47
+ It serves to provide standardized centered max-width bounds around content. Mantine handles the width boundaries inherently based on size properties.
@@ -0,0 +1,55 @@
1
+ # DatePicker - Usage Guide
2
+
3
+ This document describes how to integrate and use the `DatePicker` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { DatePicker } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { DatePicker } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <DatePicker label="Select Date" placeholder="Pick a date" />;
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 3. Design System Integration
29
+
30
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
31
+
32
+ > [!IMPORTANT]
33
+ >
34
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
35
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
36
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
37
+
38
+ ---
39
+
40
+ ## 4. Key Integration Features & Constraints
41
+
42
+ ## Architecture Overview
43
+
44
+ The `DatePicker` component is a wrapper around the `@mantine/dates` `DatePickerInput` component, implementing the `FormControlWrapper` macro structure for Recursica. This ensures that the component visually and structurally aligns with standard Recursica input primitives.
45
+
46
+ ## Structural Constraints
47
+
48
+ 1. **Naked Input Usage**: We intentionally pass `label={undefined}`, `description={undefined}`, and `error={undefined}` to the Mantine `DatePickerInput` component. This suppresses Mantine's internal macro form wrapping and ensures that only our `WithReadOnlyWrapper` > `FormControlWrapper` orchestrates labels, description text, and ARIA state error boundaries.
49
+ 2. **Read-Only Implementation**: Since the value type for `DatePickerInput` can be a date object, string, or array, the `WithReadOnlyWrapper` attempts to safely cast the output value using standard `String(value)`. For production apps utilizing heavy date formatting logic, developers can pass a custom `readOnlyComponent` explicitly to bypass this default cast.
50
+ 3. **Calendar Portal/Dropdown (Figma Token Issue)**: The Recursica UI Kit's `date-picker` component in Figma fails to export any explicit structural or color properties for the calendar popover itself (e.g. elevation, surface background, selected day colors). To solve this organically within the framework without breaking strict token adherence, we manually override the Mantine `.dropdown` and `.day[data-selected]` classes using `--recursica_ui-kit_components_hover-card-popover` tokens for elevation/padding/surfaces, and `--recursica_ui-kit_components_button_variants_styles_solid` tokens for the selected primary blue day. This guarantees strict visual adherence to the system until explicitly mapped tokens are provided in the UI Kit.
51
+
52
+ ## Styling Quirks
53
+
54
+ - The `DatePickerInput` mimics Mantine's `Input` structure natively (`.input`, `.wrapper`, `.section`). We attach our `styles.input` and `styles.root` classes exactly like `TextField`.
55
+ - The global layout margin override (`.layoutOverride`) utilizes `--form-control-margin-bottom` driven by specific stacked/side-by-side design tokens.
@@ -0,0 +1,51 @@
1
+ # Dropdown - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Dropdown` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Dropdown } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Dropdown } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Dropdown placeholder="Select an option">
24
+ <Dropdown.Item value="1">Option 1</Dropdown.Item>
25
+ <Dropdown.Item value="2">Option 2</Dropdown.Item>
26
+ </Dropdown>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 3. Design System Integration
34
+
35
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
36
+
37
+ > [!IMPORTANT]
38
+ >
39
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
40
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
41
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
42
+
43
+ ---
44
+
45
+ ## 4. Key Integration Features & Constraints
46
+
47
+ The `Dropdown` component is mapped explicitly to Mantine's `<Select>` following the exact same strict encapsulation rules as `TextField`.
48
+
49
+ 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`.
50
+ 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.
51
+ 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`.
@@ -0,0 +1,36 @@
1
+ # FileInput - Usage Guide
2
+
3
+ This document describes how to integrate and use the `FileInput` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { FileInput } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { FileInput } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <FileInput label="Upload Resume" placeholder="Choose a file..." />;
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 3. Design System Integration
29
+
30
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
31
+
32
+ > [!IMPORTANT]
33
+ >
34
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
35
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
36
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
@@ -0,0 +1,41 @@
1
+ # FileUpload - Usage Guide
2
+
3
+ This document describes how to integrate and use the `FileUpload` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { FileUpload } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { FileUpload } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <FileUpload
24
+ label="Drop files here"
25
+ onDrop={(files) => console.log(files)}
26
+ />
27
+ );
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 3. Design System Integration
34
+
35
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
36
+
37
+ > [!IMPORTANT]
38
+ >
39
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
40
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
41
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
@@ -0,0 +1,48 @@
1
+ # Flex - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Flex` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Flex } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Flex } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Flex gap="md" justify="space-between" align="center">
24
+ <Text>Item 1</Text>
25
+ <Text>Item 2</Text>
26
+ </Flex>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 3. Design System Integration
34
+
35
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
36
+
37
+ > [!IMPORTANT]
38
+ >
39
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
40
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
41
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
42
+
43
+ ---
44
+
45
+ ## 4. Key Integration Features & Constraints
46
+
47
+ The `Flex` component is a generic unopinionated flex layout wrapper mapped directly to Mantine's `Flex`.
48
+ It currently does not require any custom logical layouts or CSS workarounds since it serves only to provide absolute, raw manipulation of standard CSS flex properties. All spacing props (gap, align, justify, direction, wrap) pass safely through via the `filterStylingProps` layout-property allowance, with `rec-` dimension tokens scaling transparently mapped to standard gap limits.
@@ -0,0 +1,40 @@
1
+ # FormControlLayout - Usage Guide
2
+
3
+ This document describes how to integrate and use the `FormControlLayout` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { FormControlLayout } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { FormControlLayout } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <FormControlLayout label="Input Field" required>
24
+ <input type="text" />
25
+ </FormControlLayout>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ---
31
+
32
+ ## 3. Design System Integration
33
+
34
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
35
+
36
+ > [!IMPORTANT]
37
+ >
38
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
39
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
40
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
@@ -0,0 +1,75 @@
1
+ # FormControlWrapper - Usage Guide
2
+
3
+ This document describes how to integrate and use the `FormControlWrapper` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { FormControlWrapper } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { FormControlWrapper } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <FormControlWrapper label="Email Address" required error="Invalid email">
24
+ <input type="email" />
25
+ </FormControlWrapper>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ---
31
+
32
+ ## 3. Design System Integration
33
+
34
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
35
+
36
+ > [!IMPORTANT]
37
+ >
38
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
39
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
40
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
41
+
42
+ ---
43
+
44
+ ## 4. Key Integration Features & Constraints
45
+
46
+ ## Architectural Philosophy
47
+
48
+ The `FormControlWrapper` is the ultimate structural replacement for Mantine's built-in `Input.Wrapper`. By abandoning Mantine's opinionated wrappers entirely across the design system, we centralize all label tracking, error rendering, ARIA generation, and grid layouts natively inside this single component.
49
+
50
+ ### 1. Bypassing `Input.Wrapper`
51
+
52
+ Under the hood of Mantine, elements like `TextInput` heavily rely on `Input.Wrapper`. We actively discourage their use. The central tenet of Recursica Forms is to strip the UI primitive back to its "naked" form (e.g. `<Input />`, `<Checkbox />`) and encapsulate it manually inside `<FormControlWrapper>`.
53
+
54
+ - **Why?** It enforces complete layout mastery. It natively enables `formLayout="side-by-side"` and completely disables Mantine's margin collisions without requiring messy CSS hacks.
55
+
56
+ ### 2. The `cloneElement` ARIA Map
57
+
58
+ Because we tore out Mantine's `InputContext` provider (which natively glued error strings to `<input>` tags using React Context), we explicitly utilize `React.cloneElement` on the nested children inside this wrapper.
59
+
60
+ - `aria-describedby` and `aria-errormessage` are dynamically generated using `React.useId()` and physically injected back onto the provided child node. Screen readers rely strictly on this mapping to announce the assistive fields correctly.
61
+
62
+ ### 3. Strict `AssistiveElement` Coupling
63
+
64
+ We completely abandoned generic `<Input.Description>` tags. The `FormControlWrapper` directly renders `<AssistiveElement>` primitives, parsing them seamlessly mapping them to `"error"` or `"help"` variants automatically depending on the component's internal state machine.
65
+
66
+ ### 4. Dynamic Geometric Variable Payloads
67
+
68
+ Because `FormControlWrapper` acts as an agnostic grid box encompassing raw primitives (like `TextField`, `Select`), it initially stretches `100%` across horizontal bounds.
69
+
70
+ - **The Bug:** If a child `TextField` carries its own hardcoded `max-width` token, it stops expanding early, but the wrapper and `<Label>` keep expanding, causing right-aligned labels to aggressively float past the field to the screen's edge dynamically.
71
+ - **The Variable Payload Resolution:** Instead of destroying grids with `width: fit-content` arrays, primitive components are required to pass their local `max-width` tokens UP to the wrapper explicitly via React `style`:
72
+ ```tsx
73
+ <FormControlWrapper style={{ "--form-control-max-width": "var(--...)" }}>
74
+ ```
75
+ The wrapper natively respects `max-width: var(--form-control-max-width, 100%)`. This structurally unifies the bounding caps so right-aligned labels flawlessly snap tightly to the explicit boundary edge of the specific primitive it is wrapping.
@@ -0,0 +1,48 @@
1
+ # Group - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Group` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Group } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Group } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Group gap="md" align="center">
24
+ <Button variant="secondary">Cancel</Button>
25
+ <Button variant="primary">Submit</Button>
26
+ </Group>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 3. Design System Integration
34
+
35
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
36
+
37
+ > [!IMPORTANT]
38
+ >
39
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
40
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
41
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
42
+
43
+ ---
44
+
45
+ ## 4. Key Integration Features & Constraints
46
+
47
+ The `Group` component is a generic flex layout wrapper mapped directly to Mantine's `Group`.
48
+ It currently does not require any custom logical layouts or CSS workarounds since it serves only to organize layout structure, and doesn't enforce any strict design-system token styling itself. All gap, align, wrap, and justify properties pass safely through via the `filterStylingProps` layout-property allowance.
@@ -0,0 +1,121 @@
1
+ # HoverCard - Usage Guide
2
+
3
+ This document describes how to integrate and use the `HoverCard` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { HoverCard } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { HoverCard } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <HoverCard>
24
+ <HoverCard.Target>
25
+ <Text>Hover over me</Text>
26
+ </HoverCard.Target>
27
+ <HoverCard.Dropdown>
28
+ <Text size="sm">This is the hover card popup content.</Text>
29
+ </HoverCard.Dropdown>
30
+ </HoverCard>
31
+ );
32
+ }
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 3. Design System Integration
38
+
39
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
40
+
41
+ > [!IMPORTANT]
42
+ >
43
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
44
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
45
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
46
+
47
+ ---
48
+
49
+ ## 4. Key Integration Features & Constraints
50
+
51
+ ## 1. Composable API Preservation (1:1 Mapping)
52
+
53
+ **Decision:** We maintain the exact library composition API structure (`<HoverCard>`, `<HoverCard.Target>`, `<HoverCard.Dropdown>`) as a 1:1 React component mapping.
54
+
55
+ **Implementation:** Mantine's HoverCard internally manages hover detection, open/close delays, Floating UI positioning, and portal rendering. By preserving the exact sub-component tree, Recursica safely inherits all of these behaviors without reimplementation.
56
+
57
+ ---
58
+
59
+ ## 2. HoverCard.Target Pass-Through
60
+
61
+ **Decision:** `HoverCard.Target` is a transparent pass-through with no styling applied.
62
+
63
+ **Implementation:** The target wrapper exists solely to manage Mantine's ref forwarding and hover event binding for the trigger element. No `filterStylingProps` or CSS module classes are applied — the trigger's appearance is entirely controlled by whatever component the integrator places inside it (e.g., `<Button>`). This is identical to the `Menu.Target` pattern.
64
+
65
+ ---
66
+
67
+ ## 3. Token Namespace: `hover-card-popover`
68
+
69
+ **Decision:** The CSS module exclusively uses variables from the `--recursica_ui-kit_components_hover-card-popover_*` namespace.
70
+
71
+ **Implementation:** The Recursica token system defines a single shared namespace (`hover-card-popover`) for this component covering geometry (border-radius, border-size, padding, min/max-width), typography (content-text\_\*), elevation, and layer-aware colors (background, border-color, content). No tokens from other component namespaces are referenced.
72
+
73
+ ---
74
+
75
+ ## 4. Hardcoded Values
76
+
77
+ **Decision:** Two hardcoded values exist in the component.
78
+
79
+ ### `border-style: solid` (CSS module)
80
+
81
+ Mantine renders the dropdown using its `Paper` component, which does not set `border-style` natively. Without this hardcoded value, the border-width and border-color tokens would have no visible effect. This is the same pattern used in the Menu component's dropdown.
82
+
83
+ ### `arrowSize` defaulted to `16` (HoverCard.tsx)
84
+
85
+ Mantine's `arrowSize` prop is a JavaScript number used for inline style calculations: it sets `width`, `height`, and a positioning offset (`-arrowSize/2`) directly on the arrow `<div>` element. These inline styles **cannot** be overridden via CSS without `!important`, and the positioning offset has no CSS equivalent. This means the beak size cannot be fully CSS-driven — it is one of the rare cases where a design token value must be mirrored as a JS prop.
86
+
87
+ The default value `16` matches the Recursica `beak-size` token (`--recursica_ui-kit_components_hover-card-popover_properties_beak-size: 16px`). Developers can override `arrowSize` if needed, but should be aware this is a design system concern. If the token value changes, the default in `HoverCard.tsx` must also be updated.
88
+
89
+ This is documented as an open issue in `docs/COMPONENT_ISSUES.md`.
90
+
91
+ **Note:** Mantine calls this the "arrow"; Recursica calls it the "beak". The Recursica prop `withBeak` (defaulting to `true`) maps to Mantine's `withArrow`. Both `withBeak` and `withArrow` are accepted; `withBeak` takes precedence.
92
+
93
+ ---
94
+
95
+ ## 5. Minimal CSS Override Philosophy
96
+
97
+ **Decision:** The CSS module only overrides visual design tokens (colors, typography, spacing, borders, shadows). All structural layout properties are deferred to Mantine's native behavior.
98
+
99
+ **Implementation:** HoverCard is an overlay component where Mantine's native Floating UI positioning and Paper layout are already correct. We avoid setting:
100
+
101
+ - `overflow` on the dropdown (Mantine handles scroll behavior natively)
102
+ - `display`, `position`, `z-index` (Floating UI controls these)
103
+ - `pointer-events` (Mantine manages hover detection across target and dropdown)
104
+
105
+ **Rationale:** The Menu implementation demonstrated that aggressive structural resets (overflow, box-sizing) on overlay components cause layout breakage. Default to Mantine's native behavior and only override what the Recursica token system explicitly needs to control.
106
+
107
+ ---
108
+
109
+ ## 6. ClassNames Merging on Root
110
+
111
+ **Decision:** The root `HoverCard` component binds CSS module classes via `classNames` on the Mantine root, identical to the Menu pattern.
112
+
113
+ **Implementation:** The root component receives `classNames={{ dropdown: styles.dropdown }}` and merges any consumer-provided `classNames` when `overStyled` is true. This ensures our token-driven styles are applied to the dropdown panel without wrapper divs, and the consumer's classes are additive.
114
+
115
+ ---
116
+
117
+ ## 7. Default Position Override
118
+
119
+ **Decision:** Recursica defaults `position` to `"top"`. Mantine defaults to `"bottom"`.
120
+
121
+ **Implementation:** The `position="top"` default is set on the Mantine root element before the prop spread, so developer-provided `position` values still take precedence. This aligns with Recursica's design intent for overlay components to appear above their trigger by default.