@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,36 @@
1
+ # Radio - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Radio` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Radio } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Radio } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Radio label="Option 1" name="radio-group" value="1" defaultChecked />;
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,52 @@
1
+ # ReadOnlyField - Usage Guide
2
+
3
+ This document describes how to integrate and use the `ReadOnlyField` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { ReadOnlyField } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { ReadOnlyField } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <ReadOnlyField label="API Key" value="sk_test_123456789" copyable />;
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. Stripping Mantine Assumptions
43
+
44
+ Unlike standard input variables, standard HTML output `<p>` tags inherently carry margin and spacing assumptions from core browser stylesheets. To correctly map `ReadOnlyTextField` elements gracefully inside the generic `FormControlWrapper` bounded context, we hardcode resets:
45
+
46
+ - `margin: 0` explicitly strips block flow gap so `FormControlWrapper` handles vertical rhythm.
47
+ - `min-height`: Native `Input` boxes typically have baseline padding borders. We map directly to `var(--recursica_ui-kit_components_read-only-field_properties_min-height)` to ensure a side-by-side editable `TextField` and `ReadOnlyField` perfectly share roughly identical visual heights.
48
+
49
+ ## 2. Unidirectional Editable Mode
50
+
51
+ The main wrapper intercepts `readOnly` boolean blocks, maintaining its own `isReadOnly` state. Natively, if a user clicks an exposed 'Edit' action (like our legacy SVG or custom `labelActionArea`), the context permanently switches to active.
52
+ There is intentionally no built-in reverse toggle inside typical field bindings (like input "Blur") to revert state. Parents must pass external controls to `readOnly` forcing the internal hooks to reset via standard `useEffect` propagation.
@@ -0,0 +1,56 @@
1
+ # SegmentedControl - Usage Guide
2
+
3
+ This document describes how to integrate and use the `SegmentedControl` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { SegmentedControl } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { SegmentedControl } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <SegmentedControl data={["Preview", "Code", "Edit"]} />;
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. Stripping Mantine's Native Variants and Sizes
43
+
44
+ The Figma design tokens for the SegmentedControl component do not define nested layers of variants (such as `solid`, `outline`) or specific sizing steps (`xs`, `sm`, etc.). They are defined globally. Therefore, we explicitly `Omit` the standard `variant`, `size`, `radius`, and `color` props from the generic Mantine `SegmentedControlProps` interface.
45
+
46
+ ## 2. Hardcoded Overrides for Figma Strictness
47
+
48
+ Mantine injects inline hover styles on `.label` (specifically, adding a subtle gray background when hovering). Since Recursica defines explicit transparent or specifically-driven hover states, we use `!important` tags within `SegmentedControl.module.css` for background and typography overriding.
49
+
50
+ ## 3. Divider Separators
51
+
52
+ Mantine uses an `::before` pseudo-element on the `.control` block to draw standard visual separators between adjacent elements. Instead of stripping this functionality out, we hook directly into the pseudo-element and override its `background-color` with `--recursica_ui-kit_components_segmented-control_properties_colors_divider-color`.
53
+
54
+ ## 4. Indicator Mapping
55
+
56
+ The moving active background element (`.indicator`) is decoupled from the actual text label. It is styled natively with its own background color, border size, and elevation shadow variables to match the exact visual parity of a "floating active chip" as defined in the Recursica properties map.
@@ -0,0 +1,86 @@
1
+ # Slider - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Slider` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Slider } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Slider } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Slider defaultValue={50} min={0} max={100} label="Volume" />;
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. Bidirectional State Synchronization
43
+
44
+ **Decision:** Maintain a highly responsive, bidirectional connection between the sliding track value and the adjacent numeric text input.
45
+ **Implementation:**
46
+
47
+ - The slider track requires a clean `number` state, whereas the text box requires a `string` state (`inputValue`) to allow typing intermediate characters like decimals (`2.`), negative signs (`-`), or empty text without breaking standard React input binding.
48
+ - A `useEffect` hook continuously feeds the outer numeric state changes back into the text input value as a string representation.
49
+ - Input changes instantly parsed as float clamp bounds securely. On blur (`onBlur`), the input state is automatically sanitized and reset to the clean, clamped string representation of the final track value.
50
+
51
+ ## 2. Outer Form Control Wrapper Integration
52
+
53
+ **Decision:** Bypass Mantine's native `Input.Wrapper` and `label` properties.
54
+ **Implementation:**
55
+
56
+ - Universal form wrappers like `<FormControlWrapper>` and `<WithReadOnlyWrapper>` handle the outer layout architecture, including labels, assistive text, error states, and optional edit-triggering fields.
57
+ - Therefore, we map the outer form label directly to the `label` property of the `Slider` (delegated to the wrapper), and rename Mantine's internal dragging tooltip label property to `tooltipLabel`.
58
+
59
+ ## 3. Custom Min-Max Labels and Step Indicators
60
+
61
+ **Decision:** Enforce rigid typography tokens on lower bounds and custom mark indicators.
62
+ **Implementation:**
63
+
64
+ - Mantine's native mark and step structures are fully styles-mapped back to our scoped variables in `Slider.module.css`.
65
+ - Min and Max numeric guides are rendered directly to the left and right of the slider track, centered vertically and spaced automatically using standard input gaps, while dynamically fetching custom typography tokens for min-max labels to avoid hardcoded formatting constraints.
66
+
67
+ ## 4. Visual Overrides for Stacked and Side-by-Side Spacing
68
+
69
+ **Decision:** Enforce layout margins dynamically based on container orientation parameters.
70
+ **Implementation:**
71
+
72
+ - Using custom layouts (e.g. `stacked` and `side-by-side`), we override the margins by assigning the component-specific Figma spacing variables to the unified `--form-control-margin-bottom` property.
73
+
74
+ ## 5. Right-Aligned Floating Current Value
75
+
76
+ **Decision:** Position the current active value of the slider directly above the max guide (or right-side element) on the right side of the track.
77
+ **Implementation:**
78
+
79
+ - Wrap the max guide element in a relative layout container (`.rightGuideContainer`) to provide a positioning anchor.
80
+ - Place the active value element (`.currentValue`) inside `.rightGuideContainer` and position it absolutely (`bottom: calc(100% + var(--recursica_ui-kit_globals_form_properties_label-field-gap-vertical, 8px))`, `right: 0`).
81
+ - This absolute positioning strategy guarantees that the active value floats cleanly above the track's right side, while aligning it vertically on the Y-axis to sit in perfect baseline alignment with the component's left-aligned form label.
82
+ - Set typography using the Figma-aligned component-specific read-only value variables (`--recursica_ui-kit_components_slider_properties_read-only-value_...`).
83
+ - Allow the text color of both the floating current value (`.currentValue`) and the component's read-only value (`.readOnlyValue`) to naturally inherit from their parent states/form globals, automatically supporting default (`--form-field-text-valued`), disabled (`--form-field-disabled-text`), and error colors without explicit color overrides, matching the min/max guides.
84
+ - If `showInput` is enabled, the floating `.currentValue` is hidden since the active value is already displayed and editable within the adjacent numeric text input, avoiding visual redundancy.
85
+ - In `side-by-side` form layouts, the `.currentValue` is positioned inline (static positioning) to the right of the max label rather than floating above it, centered vertically with the max label and aligned right to the container. This uses CSS flexbox ordering (`order: 2` for `.currentValue` and `order: 1` for `.minMaxGuide`) to visually swap their positions while preserving clean, semantic DOM ordering.
86
+ - To ensure perfect, pixel-perfect vertical track alignment between sliders that show numeric text inputs (`showInput={true}`) and sliders that display the active inline value (`showInput={false}`), the `.currentValue` element is globally given a width equal to the input width (`var(--recursica_ui-kit_components_slider_properties_input-width)`) and right-aligned (`text-align: right`). In `side-by-side` layouts, `.rightGuideContainer`'s flex gap is also matched to the horizontal input-to-track gap (`var(--recursica_ui-kit_components_slider_properties_input-gap)`), making the horizontal space occupied by the rightmost elements exactly identical in both component modes.
@@ -0,0 +1,48 @@
1
+ # Stack - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Stack` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Stack } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Stack } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Stack gap="md" align="stretch">
24
+ <Text>Item 1</Text>
25
+ <Text>Item 2</Text>
26
+ </Stack>
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 `Stack` component is a generic flex layout wrapper mapped directly to Mantine's `Stack`.
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, and justify properties pass safely through via the `filterStylingProps` layout-property allowance.
@@ -2,6 +2,7 @@ import React, { forwardRef } from "react";
2
2
  import {
3
3
  Stepper as MantineStepper,
4
4
  type StepperProps as MantineStepperProps,
5
+ type StepperStepProps as MantineStepperStepProps,
5
6
  } from "@mantine/core";
6
7
  import {
7
8
  filterStylingProps,
@@ -56,12 +57,29 @@ const _Stepper = forwardRef<HTMLDivElement, StepperProps>(
56
57
  },
57
58
  );
58
59
 
60
+ export type StepperStepProps = RecursicaOverStyled<MantineStepperStepProps>;
61
+
62
+ const _StepperStep = forwardRef<HTMLButtonElement, StepperStepProps>(
63
+ function StepperStep({ overStyled = false, ...rest }, ref) {
64
+ const sanitizedProps = filterStylingProps(rest, overStyled);
65
+ return (
66
+ <MantineStepper.Step
67
+ ref={ref}
68
+ {...(sanitizedProps as unknown as MantineStepperStepProps)}
69
+ />
70
+ );
71
+ },
72
+ );
73
+ _StepperStep.displayName = "Stepper.Step";
74
+
59
75
  // We need to re-export the static components Step and Completed
60
76
  export const Stepper: typeof _Stepper & {
61
- Step: typeof MantineStepper.Step;
77
+ Step: typeof _StepperStep;
62
78
  Completed: typeof MantineStepper.Completed;
63
79
  } = Object.assign(_Stepper, {
64
- Step: MantineStepper.Step,
80
+ Step: _StepperStep,
81
+ // Stepper.Completed only accepts `children` — no styling props to strip,
82
+ // so re-exporting Mantine's implementation directly is not a gap.
65
83
  Completed: MantineStepper.Completed,
66
84
  });
67
85
 
@@ -0,0 +1,41 @@
1
+ # Stepper - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Stepper` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Stepper } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Stepper } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Stepper active={1}>
24
+ <Stepper.Step label="First step" description="Create account" />
25
+ <Stepper.Step label="Second step" description="Verify email" />
26
+ </Stepper>
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,65 @@
1
+ # Switch - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Switch` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Switch } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Switch } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return <Switch label="Enable notifications" defaultChecked />;
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. Stripping Mantine's Size Engine
43
+
44
+ Mantine uses properties like `size`, `color`, and `radius` to dynamically map CSS layout values across its `.track` and `.thumb` nodes. We proactively strip and delete these properties using `filterStylingProps` to entirely neutralize this native behavior.
45
+
46
+ ## 2. Hardcoded Values & Transitions
47
+
48
+ Mantine injects dynamic width/height attributes into its switch through inline CSS variables (e.g. `--switch-height`). To strictly enforce the UI Kit tokens without breaking Mantine's internal math, our `Switch.module.css` structurally remaps Mantine's internal variables explicitly:
49
+
50
+ ```css
51
+ --switch-width: var(--switch-track-width);
52
+ --switch-height: calc(
53
+ var(--switch-thumb-height) + (var(--switch-track-padding) * 2)
54
+ );
55
+ ```
56
+
57
+ We also hardcode `border: none` since the UI kit designs rely purely on box-shadow elevations and background color tracking. Mantine’s default border logic is entirely disabled.
58
+
59
+ ## 3. ReadOnly Behavior
60
+
61
+ Similar to `Checkbox`, the `Switch` component handles `readOnly` presentation by dropping the entire underlying node tree and falling back structurally onto `<FormControlWrapper>` when `readOnly: true`. This strictly preserves exact baseline alignment across all primitives without trying to hack disabled CSS to look like read-only text.
62
+
63
+ ## 4. Hover State Reset
64
+
65
+ Mantine forcefully triggers track hover color states globally. Since Recursica currently does not map specific hover states to switch backgrounds across themes (falling back to standard unselected tokens or simply providing a cursor), we structurally wipe out Mantine's `.track:hover` class block inside `Switch.module.css`.
@@ -2,6 +2,14 @@ import { forwardRef } from "react";
2
2
  import {
3
3
  Table as MantineTable,
4
4
  type TableProps as MantineTableProps,
5
+ type TableTheadProps as MantineTableTheadProps,
6
+ type TableTbodyProps as MantineTableTbodyProps,
7
+ type TableTrProps as MantineTableTrProps,
8
+ type TableThProps as MantineTableThProps,
9
+ type TableTdProps as MantineTableTdProps,
10
+ type TableTfootProps as MantineTableTfootProps,
11
+ type TableCaptionProps as MantineTableCaptionProps,
12
+ type TableScrollContainerProps as MantineTableScrollContainerProps,
5
13
  } from "@mantine/core";
6
14
  import {
7
15
  filterStylingProps,
@@ -38,23 +46,152 @@ const TableBase = forwardRef<HTMLTableElement, TableProps>(function Table(
38
46
 
39
47
  TableBase.displayName = "Table";
40
48
 
49
+ // ==== EXPLICIT DOT-NOTATION SUB-COMPONENTS ====
50
+ // Each sub-component is wrapped independently so it goes through
51
+ // filterStylingProps/overStyled the same way the root Table does.
52
+
53
+ export type TableTheadProps = RecursicaOverStyled<MantineTableTheadProps>;
54
+
55
+ export const TableThead = forwardRef<HTMLTableSectionElement, TableTheadProps>(
56
+ function TableThead({ overStyled = false, ...rest }, ref) {
57
+ const sanitizedProps = filterStylingProps(rest, overStyled);
58
+ return (
59
+ <MantineTable.Thead
60
+ ref={ref}
61
+ {...(sanitizedProps as unknown as MantineTableTheadProps)}
62
+ />
63
+ );
64
+ },
65
+ );
66
+ TableThead.displayName = "TableThead";
67
+
68
+ export type TableTbodyProps = RecursicaOverStyled<MantineTableTbodyProps>;
69
+
70
+ export const TableTbody = forwardRef<HTMLTableSectionElement, TableTbodyProps>(
71
+ function TableTbody({ overStyled = false, ...rest }, ref) {
72
+ const sanitizedProps = filterStylingProps(rest, overStyled);
73
+ return (
74
+ <MantineTable.Tbody
75
+ ref={ref}
76
+ {...(sanitizedProps as unknown as MantineTableTbodyProps)}
77
+ />
78
+ );
79
+ },
80
+ );
81
+ TableTbody.displayName = "TableTbody";
82
+
83
+ export type TableTrProps = RecursicaOverStyled<MantineTableTrProps>;
84
+
85
+ export const TableTr = forwardRef<HTMLTableRowElement, TableTrProps>(
86
+ function TableTr({ overStyled = false, ...rest }, ref) {
87
+ const sanitizedProps = filterStylingProps(rest, overStyled);
88
+ return (
89
+ <MantineTable.Tr
90
+ ref={ref}
91
+ {...(sanitizedProps as unknown as MantineTableTrProps)}
92
+ />
93
+ );
94
+ },
95
+ );
96
+ TableTr.displayName = "TableTr";
97
+
98
+ export type TableThProps = RecursicaOverStyled<MantineTableThProps>;
99
+
100
+ export const TableTh = forwardRef<HTMLTableCellElement, TableThProps>(
101
+ function TableTh({ overStyled = false, ...rest }, ref) {
102
+ const sanitizedProps = filterStylingProps(rest, overStyled);
103
+ return (
104
+ <MantineTable.Th
105
+ ref={ref}
106
+ {...(sanitizedProps as unknown as MantineTableThProps)}
107
+ />
108
+ );
109
+ },
110
+ );
111
+ TableTh.displayName = "TableTh";
112
+
113
+ export type TableTdProps = RecursicaOverStyled<MantineTableTdProps>;
114
+
115
+ export const TableTd = forwardRef<HTMLTableCellElement, TableTdProps>(
116
+ function TableTd({ overStyled = false, ...rest }, ref) {
117
+ const sanitizedProps = filterStylingProps(rest, overStyled);
118
+ return (
119
+ <MantineTable.Td
120
+ ref={ref}
121
+ {...(sanitizedProps as unknown as MantineTableTdProps)}
122
+ />
123
+ );
124
+ },
125
+ );
126
+ TableTd.displayName = "TableTd";
127
+
128
+ export type TableTfootProps = RecursicaOverStyled<MantineTableTfootProps>;
129
+
130
+ export const TableTfoot = forwardRef<HTMLTableSectionElement, TableTfootProps>(
131
+ function TableTfoot({ overStyled = false, ...rest }, ref) {
132
+ const sanitizedProps = filterStylingProps(rest, overStyled);
133
+ return (
134
+ <MantineTable.Tfoot
135
+ ref={ref}
136
+ {...(sanitizedProps as unknown as MantineTableTfootProps)}
137
+ />
138
+ );
139
+ },
140
+ );
141
+ TableTfoot.displayName = "TableTfoot";
142
+
143
+ export type TableCaptionProps = RecursicaOverStyled<MantineTableCaptionProps>;
144
+
145
+ export const TableCaption = forwardRef<
146
+ HTMLTableCaptionElement,
147
+ TableCaptionProps
148
+ >(function TableCaption({ overStyled = false, ...rest }, ref) {
149
+ const sanitizedProps = filterStylingProps(rest, overStyled);
150
+ return (
151
+ <MantineTable.Caption
152
+ ref={ref}
153
+ {...(sanitizedProps as unknown as MantineTableCaptionProps)}
154
+ />
155
+ );
156
+ });
157
+ TableCaption.displayName = "TableCaption";
158
+
159
+ export type TableScrollContainerProps =
160
+ RecursicaOverStyled<MantineTableScrollContainerProps>;
161
+
162
+ export const TableScrollContainer = forwardRef<
163
+ HTMLDivElement,
164
+ TableScrollContainerProps
165
+ >(function TableScrollContainer({ overStyled = false, ...rest }, ref) {
166
+ const sanitizedProps = filterStylingProps(rest, overStyled);
167
+ return (
168
+ <MantineTable.ScrollContainer
169
+ ref={ref}
170
+ {...(sanitizedProps as unknown as MantineTableScrollContainerProps)}
171
+ />
172
+ );
173
+ });
174
+ TableScrollContainer.displayName = "TableScrollContainer";
175
+
176
+ // ==== DOT NOTATION EXPORT ====
177
+
41
178
  type TableComponent = typeof TableBase & {
42
- Thead: typeof MantineTable.Thead;
43
- Tbody: typeof MantineTable.Tbody;
44
- Tr: typeof MantineTable.Tr;
45
- Th: typeof MantineTable.Th;
46
- Td: typeof MantineTable.Td;
47
- Tfoot: typeof MantineTable.Tfoot;
48
- Caption: typeof MantineTable.Caption;
49
- ScrollContainer: typeof MantineTable.ScrollContainer;
179
+ Thead: typeof TableThead;
180
+ Tbody: typeof TableTbody;
181
+ Tr: typeof TableTr;
182
+ Th: typeof TableTh;
183
+ Td: typeof TableTd;
184
+ Tfoot: typeof TableTfoot;
185
+ Caption: typeof TableCaption;
186
+ ScrollContainer: typeof TableScrollContainer;
50
187
  };
51
188
 
52
189
  export const Table = TableBase as TableComponent;
53
- Table.Thead = MantineTable.Thead;
54
- Table.Tbody = MantineTable.Tbody;
55
- Table.Tr = MantineTable.Tr;
56
- Table.Th = MantineTable.Th;
57
- Table.Td = MantineTable.Td;
58
- Table.Tfoot = MantineTable.Tfoot;
59
- Table.Caption = MantineTable.Caption;
60
- Table.ScrollContainer = MantineTable.ScrollContainer;
190
+ Table.Thead = TableThead;
191
+ Table.Tbody = TableTbody;
192
+ Table.Tr = TableTr;
193
+ Table.Th = TableTh;
194
+ Table.Td = TableTd;
195
+ Table.Tfoot = TableTfoot;
196
+ Table.Caption = TableCaption;
197
+ Table.ScrollContainer = TableScrollContainer;
@@ -0,0 +1,41 @@
1
+ # Table - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Table` component in your projects using `@recursica/mantine-adapter`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Table } from "@recursica/mantine-adapter";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from 'react';
19
+ import { Table } from "@recursica/mantine-adapter";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Table>
24
+ <Table.Thead>
25
+ <Table.Tr>
26
+ <Table.Th>Name</Table.Th>
27
+ <Table.Th>Email</Table.Tr>
28
+ </Table.Tr>
29
+ </Table.Thead>
30
+ <Table.Tbody>
31
+ <Table.Tr>
32
+ <Table.Td>Jane Doe</Table.Tr>
33
+ <Table.Td>jane@example.com</Table.Tr>
34
+ </Table.Tr>
35
+ </Table.Tbody>
36
+ </Table>
37
+ );
38
+ }
39
+ ```
40
+
41
+ ---