@recursica/mantine-adapter 0.32.0 → 0.33.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 (50) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/src/components/Accordion/USAGE.md +90 -0
  4. package/src/components/AssistiveElement/USAGE.md +36 -0
  5. package/src/components/AutoComplete/USAGE.md +66 -0
  6. package/src/components/Avatar/USAGE.md +65 -0
  7. package/src/components/Badge/USAGE.md +59 -0
  8. package/src/components/Breadcrumb/USAGE.md +59 -0
  9. package/src/components/Button/USAGE.md +100 -0
  10. package/src/components/Card/USAGE.md +71 -0
  11. package/src/components/Checkbox/USAGE.md +64 -0
  12. package/src/components/Chip/USAGE.md +77 -0
  13. package/src/components/Container/USAGE.md +47 -0
  14. package/src/components/DatePicker/USAGE.md +55 -0
  15. package/src/components/Dropdown/USAGE.md +51 -0
  16. package/src/components/FileInput/USAGE.md +36 -0
  17. package/src/components/FileUpload/USAGE.md +41 -0
  18. package/src/components/Flex/USAGE.md +48 -0
  19. package/src/components/FormControlLayout/USAGE.md +40 -0
  20. package/src/components/FormControlWrapper/USAGE.md +75 -0
  21. package/src/components/Group/USAGE.md +48 -0
  22. package/src/components/HoverCard/USAGE.md +121 -0
  23. package/src/components/Label/USAGE.md +87 -0
  24. package/src/components/Link/USAGE.md +69 -0
  25. package/src/components/Loader/USAGE.md +63 -0
  26. package/src/components/Menu/USAGE.md +124 -0
  27. package/src/components/Modal/USAGE.md +58 -0
  28. package/src/components/NumberInput/USAGE.md +55 -0
  29. package/src/components/Pagination/USAGE.md +55 -0
  30. package/src/components/Panel/USAGE.md +145 -0
  31. package/src/components/Popover/USAGE.md +121 -0
  32. package/src/components/Radio/USAGE.md +36 -0
  33. package/src/components/ReadOnlyField/USAGE.md +52 -0
  34. package/src/components/SegmentedControl/USAGE.md +56 -0
  35. package/src/components/Slider/USAGE.md +86 -0
  36. package/src/components/Stack/USAGE.md +48 -0
  37. package/src/components/Stepper/USAGE.md +41 -0
  38. package/src/components/Switch/USAGE.md +65 -0
  39. package/src/components/Table/USAGE.md +51 -0
  40. package/src/components/Tabs/USAGE.md +45 -0
  41. package/src/components/Text/USAGE.md +40 -0
  42. package/src/components/TextArea/USAGE.md +48 -0
  43. package/src/components/TextField/USAGE.md +60 -0
  44. package/src/components/TimePicker/USAGE.md +36 -0
  45. package/src/components/Timeline/USAGE.md +57 -0
  46. package/src/components/Title/USAGE.md +36 -0
  47. package/src/components/Toast/USAGE.md +80 -0
  48. package/src/components/Tooltip/USAGE.md +124 -0
  49. package/src/components/TransferList/USAGE.md +46 -0
  50. package/src/components/Tree/USAGE.md +46 -0
@@ -0,0 +1,87 @@
1
+ # Label - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Label` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Label } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Label } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Label required>Field Label</Label>;
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 `Label` component is fundamentally built as a strict, localized wrapper around Mantine's native `Input.Label`. The core goal is to preserve context, ref-forwarding, and native accessibility links, while completely overriding visual behaviors via Recursica design variables in scoped CSS.
45
+
46
+ ## Key Design Decisions
47
+
48
+ ### **Layout Architecture**
49
+
50
+ - Because Recursica dictates complex alignments between primary label text, asterisks, edit icons, and optional strings, Mantine's rigid form label flow could not be used out-of-the-box.
51
+ - Implemented `display: flex; flex-wrap: wrap;` directly on `.root`.
52
+ - Injected strict integer-based flex `order` properties (e.g. `order: 1` for text, `order: 2` for `required`, `order: 5` for `optionalText`) to physically decouple DOM rendering from markup flow.
53
+ - Because `optionalText` often acts as secondary contextual detail, it forces `flex-basis: 100%`, securely wrapping to a secondary line underneath the primary label properties and transforming the horizontal gap spacing seamlessly into a `margin-top` vector.
54
+
55
+ ### **Optional Text & Required Mutually Exclusive Parsing**
56
+
57
+ - By design standards, a component cannot logically be both "Required" and mapped as "Optional".
58
+ - To bulletproof implementations natively, the adapter forcibly suppresses rendering of the `resolvedOptionalText` strings if the parent wrapper invokes `required={true}`.
59
+ - `optionalText` can operate as dynamic data or specifically as a boolean `true`, which forces the adapter to natively render the formal `(Optional)` string map.
60
+
61
+ ### **The "Edit Icon" Replacer Logic**
62
+
63
+ - Passing `withEditIcon={true}` evaluates it as fundamentally mutually exclusive to the standard required indicator asterisk.
64
+ - `required={required && !withEditIcon}` is passed to the underlying Mantine structure so the native `*` is entirely suppressed.
65
+ - Added localized styling via `data-replaces-asterisk={required ? "true" : undefined}` onto the `.editIconWrapper` element. If an editable instance is simultaneously designated as required, the edit icon functionally assumes the indicator role natively, overriding its default icon metrics explicitly to match `--recursica_ui-kit_components_label_properties_colors_asterisk`.
66
+
67
+ ### **Bypassing `Input.Wrapper` Integrations**
68
+
69
+ - By decoupling from Mantine's standard `Input.Wrapper`, the `Label` component is exclusively mapped manually through `FormControlWrapper`. This grants us exact visual sync regarding where the label renders based on `formLayout="stacked"` or `formLayout="side-by-side"`, without fighting internal Mantine positional hooks that assume vertical stacking by default.
70
+
71
+ ### **Label Size Container Constraints**
72
+
73
+ - The `labelSize` parameter (mapping values like `"small"`) internally **does not scale typographic font metrics**. Instead, it dynamically defines the explicit horizontal bounding width limit of the block container itself.
74
+ - **Architectural Rule:** `labelSize` modifications are strictly designed to execute exclusively when `formLayout="side-by-side"` is active. It acts as an optical grid threshold ensuring left-aligned string wrappers constrain correctly uniformly down a column without bleeding into the physical input arrays alongside them.
75
+
76
+ ## Outstanding Technical Debt / Issues
77
+
78
+ ### **Description Property Omission**
79
+
80
+ - **Issue:** Currently, the adapter `Label` does not natively parse or support a structured `description` node directly attached beneath it.
81
+ - **Context:** Standard forms often attach subtext beneath inputs, but mapping a description purely within the `<Label>` (distinct from an overall form-control description) is omitted structurally until subsequent UI Kit requirements mandate dedicated `description` styles locally on the label component itself.
82
+
83
+ ### **Global Interactive Hover Mappings**
84
+
85
+ - **Issue:** Currently, the `editIconWrapper` lacks a dedicated hover background layer.
86
+ - **Context:** While the global theme abstracts interactive hover environments deeply using layered variable syntax (e.g., `--recursica_brand_layer_1_elements_interactive_hover-color`), Recursica's token generation framework natively fails to expose a universally generic placeholder token (e.g., `--recursica_elements_interactive_hover-color`) which downstream wrappers can map their `<Layer>` injections directly into safely.
87
+ - **Resolution Path:** We are explicitly ignoring the `.editIconWrapper:hover` background color assignment until the raw Figma token exports directly scaffold a generic token placeholder that we can interface cleanly with across arbitrary `<Layer>` contexts, avoiding manually mapping statically hardcoded depths (`layer-0`, `layer-1`).
@@ -0,0 +1,69 @@
1
+ # Link - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Link` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Link } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Link } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Link href="/dashboard" variant="inline">
24
+ Go to Dashboard
25
+ </Link>
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
+ ## Missing States in Design Tokens
47
+
48
+ Currently, the design tokens (`recursica_variables_scoped.css`) only provide states for:
49
+
50
+ - `default`
51
+ - `hover`
52
+ - `visited`
53
+ - `visited-hover`
54
+
55
+ There are no tokens for the `active` or `focus` states. If these are needed, they must be added to the Figma variables and exported via the token pipeline. The component relies on the browser's default focus outline for accessibility unless overriden by a global reset.
56
+
57
+ ## Overriding Mantine's underline Prop
58
+
59
+ Mantine's `Anchor` component uses `underline="hover"` by default. Because our design system specifies exact `text-decoration` styles via CSS tokens, we explicitly pass `underline="never"` to the underlying Mantine component. This prevents Mantine from injecting its own text-decoration inline or via generic classnames, ensuring our scoped CSS remains the single source of truth.
60
+
61
+ ## Base Layout
62
+
63
+ Mantine's `Anchor` renders an inline element by default and does not natively support `leftSection` like the `Button` component. To support an optional `icon` alongside the text, we enforce a baseline layout of `display: inline-flex` and `align-items: center` in `Link.module.css`.
64
+
65
+ When an icon is present, the component conditionally passes a `data-has-icon` attribute to the root element. The CSS module uses this attribute to apply the `icon-text-gap` token via the CSS `gap` property.
66
+
67
+ ## Inner Wrappers
68
+
69
+ The icon and children are wrapped in internal `<span>` tags (`.iconWrapper` and `.labelText` respectively). This follows the component development guide for structural robustness, allowing us to enforce specific sizing on the icon and intrinsic text truncation behavior if the link is placed in a bounded container.
@@ -0,0 +1,63 @@
1
+ # Loader - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Loader` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Loader } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Loader } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Loader size="md" />;
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 & Integration
43
+
44
+ The `Loader` component acts as a strictly tokenized wrapper bridging the Recursica UI-Kit `loader` variables to the generic Mantine `@mantine/core` `Loader` primitive.
45
+
46
+ ### Key Decisions:
47
+
48
+ - **Variant Mapping:** Recursica's `variant` directly proxies to Mantine's `type` prop for `"oval" | "bars" | "dots"`.
49
+ - **Property Overrides Disabled:** Natively overriding specific structural variants directly on the JSX interface like `thickness` and `borderRadius` has been intentionally omitted. Component rendering relies entirely on variables exposed by the underlying UI Kit mappings tied to the size prop.
50
+
51
+ ### Token Mapping:
52
+
53
+ Sizes are bound through `data-size` attributes (`sm`, `md`, `lg` parsing to target `<div data-size="small">`, etc.).
54
+
55
+ Mantine natively sets sizing dynamically at the component root and parses thickness/variants differently natively (e.g., `oval` styles its geometry strictly via CSS `border`, while `bars` and `dots` utilize specific DOM inner spans `span.dot` / `span.bar`).
56
+
57
+ #### Specific CSS Targeting Hacks Used
58
+
59
+ - `border-width` and `border-radius` structurally style the `thickness` and `border-radius` configuration of the `oval` variant on the `::after` pseudo-element by resolving `--recursica_ui-kit_components_loader_variants_sizes_..._properties_thickness` and `_border-radius`.
60
+
61
+ ### Unsupported Properties
62
+
63
+ - **xs and xl Sizing:** These sizes are explicitly unsupported in the Recursica standard logic (as surfaced in `filterStylingProps` and UI Kit mappings). Attempting to use them will safely default back or fallthrough statically unless defined later. See `COMPONENT_ISSUES.md`.
@@ -0,0 +1,124 @@
1
+ # Menu - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Menu` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Menu } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Menu } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Menu>
24
+ <Menu.Target>
25
+ <Button>Toggle Menu</Button>
26
+ </Menu.Target>
27
+ <Menu.Dropdown>
28
+ <Menu.Item>Profile</Menu.Item>
29
+ <Menu.Item>Settings</Menu.Item>
30
+ <Menu.Item color="red">Logout</Menu.Item>
31
+ </Menu.Dropdown>
32
+ </Menu>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 3. Design System Integration
40
+
41
+ All Recursica components in the `@recursica/mantine-adapter` package adhere strictly to design system spacing, scaling, and behavior patterns.
42
+
43
+ > [!IMPORTANT]
44
+ >
45
+ > - **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.
46
+ > - **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.
47
+ > - **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.
48
+
49
+ ---
50
+
51
+ ## 4. Key Integration Features & Constraints
52
+
53
+ ## 1. Composable API Preservation (1:1 Mapping)
54
+
55
+ **Decision:** We maintain the exact library composition API structure (`<Menu>`, `<Menu.Target>`, `<Menu.Dropdown>`, `<Menu.Item>`, `<Menu.Divider>`, `<Menu.Label>`, `<Menu.Sub>`, `<Menu.Sub.Target>`, `<Menu.Sub.Item>`, `<Menu.Sub.Dropdown>`) as a 1:1 React component mapping.
56
+
57
+ **Implementation:** Mantine's Menu internally manages WAI-ARIA role assignments (`role="menu"`, `role="menuitem"`, `aria-haspopup`, `aria-expanded`, `aria-controls`), keyboard navigation (arrow keys, Enter, Escape), and focus trapping natively across its composable hierarchy. By preserving the exact sub-component tree, Recursica safely adopts all of these accessibility behaviors without reimplementation.
58
+
59
+ ---
60
+
61
+ ## 2. Hover State Overlay Technique
62
+
63
+ **Decision:** We nullify Mantine's native hover background on `Menu.Item` and exclusively utilize Recursica's hover structure via a `::after` pseudo-element overlay.
64
+
65
+ **Implementation:** The `.item::after` pseudo-object dynamically pulls `hover-color` & `hover-opacity` bindings from the Recursica token system. Mantine natively changes `background-color` on item hover which would override our token-driven colors. We enforce `background-color` to remain the unselected-item background on hover, then layer our pseudo-overlay on top. This is the same technique used in the Accordion component.
66
+
67
+ ---
68
+
69
+ ## 3. Selected vs Unselected Item States
70
+
71
+ **Decision:** Menu items map to Recursica's `selected-item` and `unselected-item` color token groups.
72
+
73
+ **Implementation:** The CSS module defaults all items to `unselected-item_*` tokens (background, text, opacity). Items with `[data-selected]` switch to `selected-item_*` tokens. This mapping is natively driven by Mantine's internal state tracking without React state hooks.
74
+
75
+ ---
76
+
77
+ ## 4. `color` Prop Stripping
78
+
79
+ **Decision:** Mantine's `color` prop on `Menu.Item` (used for semantics like "danger/red") is explicitly stripped in strict mode.
80
+
81
+ **Implementation:** The `color` prop is deleted from the sanitized props when `overStyled` is `false`. This enforces strict design token adherence — all item colors come from the CSS module referencing Recursica variables. Developers requiring custom color semantics must either:
82
+
83
+ 1. Use `overStyled={true}` as an explicit escape hatch
84
+ 2. Contribute a proper Recursica variant to the token system
85
+
86
+ **Rationale:** The Recursica token set does not currently include danger-specific or semantic-color variants for menu items. Allowing arbitrary `color` values would break design system consistency.
87
+
88
+ ---
89
+
90
+ ## 5. Menu.Target Pass-Through
91
+
92
+ **Decision:** `Menu.Target` is a transparent pass-through with no styling applied.
93
+
94
+ **Implementation:** The target wrapper exists solely to manage Mantine's ref forwarding and 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>`).
95
+
96
+ ---
97
+
98
+ ## 6. Sub-Menu Support
99
+
100
+ **Decision:** We wrap the full Mantine sub-menu hierarchy (`Menu.Sub`, `Menu.Sub.Target`, `Menu.Sub.Item`, `Menu.Sub.Dropdown`).
101
+
102
+ **Implementation:** Sub-menu components inherit the same CSS module classes as their top-level counterparts since the Recursica token set does not distinguish sub-menu-specific styling. `Menu.Sub.Item` also strips the `color` prop in strict mode, consistent with `Menu.Item`. The sub-menu dropdown portal inherits the same `classNames` from the root Menu's `classNames` mapping.
103
+
104
+ ---
105
+
106
+ ## 7. Dropdown Container Padding
107
+
108
+ **Decision:** The dropdown container uses `divider-item-gap` as its internal padding.
109
+
110
+ **Implementation:** This ensures consistent spacing between the dropdown border and its content items. The gap token (`4px` by default) creates a subtle inset that visually separates items from the container edge, matching the Figma design specifications.
111
+
112
+ ---
113
+
114
+ ## 8. Minimal CSS Override Philosophy
115
+
116
+ **Decision:** The CSS module only overrides visual design tokens (colors, typography, spacing, borders, shadows). All structural layout properties (flex, cursor, pointer-events, box-sizing, etc.) are deferred to Mantine's native behavior.
117
+
118
+ **Implementation:** Unlike form-field components (e.g., Dropdown/TextField) which require deep structural overrides to strip Mantine's macro wrappers, the Menu is an overlay component where Mantine's native layout is already correct. We avoid setting:
119
+
120
+ - `overflow` on the dropdown (Mantine renders sub-menu dropdowns inside the parent DOM tree using Floating UI absolute positioning — setting overflow clips them)
121
+ - `display`, `align-items`, `width`, `cursor` on items (Mantine's button-based items already handle this)
122
+ - `pointer-events` on disabled items (Mantine handles disabled natively)
123
+
124
+ **Rationale:** Early iterations included aggressive structural resets (like `overflow: hidden`, `box-sizing: border-box`, `margin: 0`) cargo-culted from the Dropdown component. These caused sub-menus to render clipped inside the parent dropdown with scrollbars. The lesson: default to Mantine's native behavior and only override what the Recursica token system explicitly needs to control.
@@ -0,0 +1,58 @@
1
+ # Modal - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Modal` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Modal } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Modal } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Modal opened={isOpen} onClose={close} title="Modal Title">
24
+ <Text>This is a styled Modal wrapping the native primitive.</Text>
25
+ </Modal>
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
+ ## Architecture
47
+
48
+ The `Modal` component strictly wraps Mantine's `<Modal>` primitive. We strip Mantine's abstract native styling props (`size`, `radius`, `shadow`) via the `overStyled` interface and strictly inject CSS variable definitions onto the internal node abstractions (`.content`, `.header`, `.body`, `.title`).
49
+
50
+ ## Limitations & Structural Decisions
51
+
52
+ ### 1. Stripped `size` Prop
53
+
54
+ Mantine natively exposes an abstract `size` prop (`"sm" | "md" | "lg" | "xl"`) that scales the Modal geometry. The Recursica UI Kit explicitly dictates strict geometric bounding boxes: `max-width: 960px` and `min-width: 304px`. To enforce absolute parity with the design system, the `size` prop has been intentionally omitted from the component's interface. The width of the Modal will scale fluidly strictly between these Figma-driven pixel limits.
55
+
56
+ ### 2. Scroll Dividers behavior
57
+
58
+ Mantine internally handles scroll state natively, dynamically showing/hiding a divider line when content overflows in `.body`. This logic is tightly coupled to React DOM measurements internally. Our component inherits this dynamic behavior rather than statically rendering a permanent divider, matching Mantine's robust overflow UX. However, we aggressively override the generated `border-bottom` via CSS modules to ensure that when it _does_ appear, it correctly utilizes the `--recursica_ui-kit_components_modal_colors_scroll-divider` variable and `--recursica_ui-kit_components_modal_properties_scroll-divider-thickness` token.
@@ -0,0 +1,55 @@
1
+ # NumberInput - Usage Guide
2
+
3
+ This document describes how to integrate and use the `NumberInput` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { NumberInput } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { NumberInput } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <NumberInput label="Quantity" min={1} max={10} defaultValue={1} />;
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
+ ## 1. Native Macro Wrapper Bypass
43
+
44
+ **Decision:** The `<NumberInput>` component explicitly bypasses Mantine's native `Input.Wrapper` DOM injections.
45
+ **Implementation:** We pass `label={undefined}`, `description={undefined}`, and `error={undefined}` directly into the primitive `<MantineNumberInput>`. All visual form control geometry is delegated exclusively to our unified `<FormControlWrapper>`, ensuring 100% token adherence for label spacing and assistive text styling without duplicate DOM rendering.
46
+
47
+ ## 2. Right Section & Controls Override
48
+
49
+ **Decision:** Passing a `rightSection` element will natively remove the increment/decrement arrow controls.
50
+ **Implementation:** Mantine inherently renders its stepper controls inside the `rightSection` DOM slot. Providing a custom right-aligned icon or text element intentionally overwrites this slot. If a layout strictly requires both a custom right-aligned element and the stepper controls simultaneously, the integrator must manually rebuild the arrows using Mantine's `handlersRef` within a custom right-section wrapper.
51
+
52
+ ## 3. Controls Styling
53
+
54
+ **Decision:** The increment/decrement control arrows rely partially on native Mantine CSS inheritance.
55
+ **Implementation:** The current Recursica design system tokens do not provide explicit UI styling parameters (`background`, `border`, `hover` states) for the inner number-input arrows. We have explicitly removed Mantine's default borders to cleanly nest them inside the unified input box, and mapped the icon colors to the generic `trailing-icon` token variable, but further visual configurations currently fall back to Mantine defaults.
@@ -0,0 +1,55 @@
1
+ # Pagination - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Pagination` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Pagination } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Pagination } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Pagination total={10} value={activePage} onChange={setPage} />;
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 Decision: CSS Inheritance vs. Composition
43
+
44
+ The Figma design tokens for the `Pagination` component dictate that pagination pages perfectly mimic `Button` variants (e.g. `active-pages_style: "solid"`, `inactive-pages_style: "outline"`, `navigation-controls_style: "text"`).
45
+
46
+ As of the `1.2.0` scoped CSS update, the Figma exporter automatically handles these variants. It flattens and aliases the referenced Button properties directly into the `Pagination` component's variable namespace.
47
+
48
+ We opted to use Mantine's native `PaginationControl` components to ensure all DOM structure, focus management, and accessibility attributes are preserved natively without us needing to carefully rebuild `Pagination.Items` mappings.
49
+
50
+ To honor the Figma design intents while using Mantine's raw `<button>` elements:
51
+
52
+ 1. We inherit and map all natively scoped `Pagination` variant styles (small typography, outline/solid/text colors, and hover overlays) directly into `.control` and `.control[data-active]` within `Pagination.module.css`. We do not need to manually reference `Button` variables cross-component.
53
+ 2. We inject `data-variant="text"` via `getControlProps` onto the navigation buttons so that they inherit the explicitly aliased text style variables (`navigation-controls`) defined by the UI Kit for pagination.
54
+
55
+ This achieves exact optical alignment with the tokens while maintaining Mantine's robust internal event handling for pagination.
@@ -0,0 +1,145 @@
1
+ # Panel - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Panel` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Panel } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Panel } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Panel>
24
+ <Text>This is a clean, structured visual container.</Text>
25
+ </Panel>
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
+ ## 1. Mapping to Mantine Drawer
47
+
48
+ **Decision:** Panel maps to Mantine's `Drawer` component, not `Paper` or `Card`.
49
+
50
+ **Implementation:** Per the Recursica design system specification, "Panels slide in or expand from the edge of the screen to reveal additional content or functionality." This is the exact behavior of Mantine's `Drawer` component, which provides:
51
+
52
+ - Slide-in animation from any screen edge
53
+ - Overlay/backdrop
54
+ - Portal rendering
55
+ - Focus trapping
56
+ - Scroll locking
57
+ - Close button and title in header
58
+
59
+ Paper and Card are static containers; Drawer is an overlay that matches Panel's defined behavior.
60
+
61
+ ---
62
+
63
+ ## 2. Token Namespace: `panel`
64
+
65
+ **Decision:** The CSS module exclusively uses variables from the `--recursica_ui-kit_components_panel_*` namespace.
66
+
67
+ **Implementation:** The Recursica token system defines the `panel` namespace covering:
68
+
69
+ - Geometry: border-radius, border-size, min-width (200px), max-width (960px)
70
+ - Content padding: content-horizontal-padding (xl), content-vertical-padding (lg)
71
+ - Header/Footer padding: header-footer-horizontal-padding (xl), header-footer-vertical-padding (md)
72
+ - Spacing: header-close-gap (md), footer-button-gap (md)
73
+ - Divider: divider-size (1px), divider-color
74
+ - Elevation: elevation-3
75
+ - Colors (layer-aware): background, border-color, content, divider-color, header-footer-background, title
76
+ - Non-CSS: header-style ("h3") — see §7
77
+
78
+ No tokens from other component namespaces are referenced.
79
+
80
+ ---
81
+
82
+ ## 3. ClassNames Mapping to Drawer
83
+
84
+ **Decision:** Panel maps CSS module classes to Mantine Drawer's stylesNames.
85
+
86
+ **Implementation:** The Drawer stylesNames used are:
87
+
88
+ - `content` — Outer container (background, border, elevation)
89
+ - `header` — Title bar with close button (padding, divider, gap)
90
+ - `title` — Title text color
91
+ - `body` — Scrollable content area (padding)
92
+
93
+ Other stylesNames (`overlay`, `root`, `inner`, `close`) are left to Mantine defaults.
94
+
95
+ ---
96
+
97
+ ## 4. Default Placement Override
98
+
99
+ **Decision:** Use `placement` instead of `position` for configuring slide-out direction, and default it to `"right"`.
100
+
101
+ **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.
102
+
103
+ ---
104
+
105
+ ## 5. Custom Panel.Footer
106
+
107
+ **Decision:** A custom `Panel.Footer` sub-component is provided. Mantine's Drawer does not have a native footer.
108
+
109
+ **Implementation:** `Panel.Footer` is a `<div>` with inline styles referencing Recursica CSS variables for:
110
+
111
+ - `header-footer-background` and `header-footer-padding` tokens
112
+ - Top divider using `divider-size` and `divider-color`
113
+ - `footer-button-gap` for action button spacing
114
+ - `margin-top: auto` to push the footer to the bottom
115
+
116
+ Inline styles are used instead of a CSS module class because the footer is rendered inside the Drawer's `<body>` element, and the CSS variables are applied to the body's parent container. The inline styles ensure the footer correctly references the panel tokens regardless of DOM position.
117
+
118
+ ---
119
+
120
+ ## 6. Hardcoded Values
121
+
122
+ ### `border-style: solid` (CSS module, `.content`)
123
+
124
+ Mantine's Drawer content does not set `border-style` natively. Without this, the border-width and border-color tokens have no visible effect. Same pattern as Card, Menu, HoverCard, Tooltip.
125
+
126
+ ---
127
+
128
+ ## 7. `header-style` Typography Utility Class
129
+
130
+ **Decision:** The `header-style` token exports as the string `"h3"`, so we use the generated global utility class `.recursica_brand_typography_h3`.
131
+
132
+ **Implementation:** The PostCSS compiler generates `.recursica_brand_typography_<typeName>` classes at the bottom of the scoped variables file to apply full typography definitions without assigning variables inline. We apply this to the `.title` class via `composes: recursica_brand_typography_h3 from global;`.
133
+
134
+ ---
135
+
136
+ ## 8. Panel Types: Standard vs Scrollable
137
+
138
+ **Decision:** Both standard and scrollable types are supported natively.
139
+
140
+ **Implementation:** Per the Recursica specification:
141
+
142
+ - **Standard** — All content visible without scrolling. The default behavior when content fits.
143
+ - **Scrollable** — Internal scrollbar enabled when content exceeds the panel height. Header and footer CTAs remain pinned.
144
+
145
+ Mantine's Drawer handles this automatically — the `body` section scrolls when content overflows, while the `header` remains fixed. The `Panel.Footer` uses `margin-top: auto` to stay at the bottom.