@recursica/mantine-adapter 0.5.0 → 0.7.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 (160) hide show
  1. package/.storybook/commonArgTypes.ts +148 -0
  2. package/CHANGELOG.md +69 -0
  3. package/dist/mantine-adapter.cjs +1 -1
  4. package/dist/mantine-adapter.cjs.map +1 -1
  5. package/dist/mantine-adapter.css +1 -1
  6. package/dist/mantine-adapter.js +1076 -266
  7. package/dist/mantine-adapter.js.map +1 -1
  8. package/dist/src/components/Accordion/Accordion.d.ts +13 -28
  9. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +10 -0
  10. package/dist/src/components/Avatar/Avatar.d.ts +1 -1
  11. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +6 -3
  12. package/dist/src/components/Button/Button.d.ts +1 -1
  13. package/dist/src/components/Card/Card.d.ts +38 -3
  14. package/dist/src/components/Checkbox/Checkbox.d.ts +11 -3
  15. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +9 -0
  16. package/dist/src/components/Chip/Chip.d.ts +14 -2
  17. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +18 -0
  18. package/dist/src/components/Label/Label.d.ts +21 -0
  19. package/dist/src/components/Label/index.d.ts +1 -0
  20. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +19 -2
  21. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  22. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +22 -0
  23. package/dist/src/components/ReadOnlyField/index.d.ts +3 -0
  24. package/dist/src/components/Text/Text.d.ts +17 -0
  25. package/dist/src/components/TextField/TextField.d.ts +8 -2
  26. package/dist/src/components/Title/Title.d.ts +13 -0
  27. package/dist/src/components/index.d.ts +3 -1
  28. package/dist/src/utils/ColorSchemeWrapper.d.ts +3 -0
  29. package/dist/src/utils/filterStylingProps.d.ts +6 -2
  30. package/package.json +9 -5
  31. package/src/OverStyling.stories.tsx +174 -0
  32. package/src/Version.stories.tsx +56 -0
  33. package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
  34. package/src/components/Accordion/Accordion.module.css +261 -0
  35. package/src/components/Accordion/Accordion.stories.tsx +145 -0
  36. package/src/components/Accordion/Accordion.tsx +200 -0
  37. package/src/components/Accordion/index.ts +1 -0
  38. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  39. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +73 -0
  40. package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
  41. package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
  42. package/src/components/Avatar/Avatar.module.css +340 -0
  43. package/src/components/Avatar/Avatar.stories.tsx +102 -0
  44. package/src/components/Avatar/Avatar.tsx +100 -0
  45. package/src/components/Avatar/index.ts +1 -0
  46. package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
  47. package/src/components/Badge/Badge.module.css +124 -0
  48. package/src/components/Badge/Badge.stories.tsx +77 -0
  49. package/src/components/Badge/Badge.tsx +66 -0
  50. package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
  51. package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
  52. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
  53. package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
  54. package/src/components/Button/Button.module.css +275 -0
  55. package/src/components/Button/Button.stories.tsx +105 -0
  56. package/src/components/Button/Button.tsx +122 -0
  57. package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
  58. package/src/components/Button/index.ts +1 -0
  59. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
  60. package/src/components/Card/Card.module.css +60 -0
  61. package/src/components/Card/Card.stories.tsx +141 -0
  62. package/src/components/Card/Card.tsx +176 -0
  63. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
  64. package/src/components/Checkbox/Checkbox.module.css +204 -0
  65. package/src/components/Checkbox/Checkbox.stories.tsx +73 -0
  66. package/src/components/Checkbox/Checkbox.tsx +111 -0
  67. package/src/components/Checkbox/CheckboxGroup.stories.tsx +138 -0
  68. package/src/components/Checkbox/CheckboxGroup.tsx +140 -0
  69. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
  70. package/src/components/Chip/Chip.module.css +218 -0
  71. package/src/components/Chip/Chip.stories.tsx +115 -0
  72. package/src/components/Chip/Chip.tsx +143 -0
  73. package/src/components/DatePicker/DatePicker.stories.tsx +22 -0
  74. package/src/components/DatePicker/DatePicker.tsx +7 -0
  75. package/src/components/Dropdown/Dropdown.stories.tsx +22 -0
  76. package/src/components/Dropdown/Dropdown.tsx +7 -0
  77. package/src/components/FileInput/FileInput.stories.tsx +22 -0
  78. package/src/components/FileInput/FileInput.tsx +7 -0
  79. package/src/components/FileUpload/FileUpload.stories.tsx +22 -0
  80. package/src/components/FileUpload/FileUpload.tsx +7 -0
  81. package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
  82. package/src/components/FormControlWrapper/FormControlWrapper.module.css +46 -0
  83. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -0
  84. package/src/components/FormControlWrapper/FormControlWrapper.tsx +170 -0
  85. package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
  86. package/src/components/HoverCard/HoverCard.tsx +7 -0
  87. package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
  88. package/src/components/Label/Label.module.css +177 -0
  89. package/src/components/Label/Label.stories.tsx +123 -0
  90. package/src/components/Label/Label.tsx +132 -0
  91. package/src/components/Label/index.ts +1 -0
  92. package/src/components/Link/Link.stories.tsx +17 -0
  93. package/src/components/Link/Link.tsx +7 -0
  94. package/src/components/Loader/Loader.stories.tsx +17 -0
  95. package/src/components/Loader/Loader.tsx +7 -0
  96. package/src/components/Menu/Menu.stories.tsx +17 -0
  97. package/src/components/Menu/Menu.tsx +7 -0
  98. package/src/components/Modal/Modal.stories.tsx +17 -0
  99. package/src/components/Modal/Modal.tsx +7 -0
  100. package/src/components/NumberInput/NumberInput.stories.tsx +22 -0
  101. package/src/components/NumberInput/NumberInput.tsx +7 -0
  102. package/src/components/Pagination/Pagination.stories.tsx +17 -0
  103. package/src/components/Pagination/Pagination.tsx +7 -0
  104. package/src/components/Panel/Panel.stories.tsx +17 -0
  105. package/src/components/Panel/Panel.tsx +7 -0
  106. package/src/components/Popover/Popover.stories.tsx +17 -0
  107. package/src/components/Popover/Popover.tsx +7 -0
  108. package/src/components/Radio/Radio.stories.tsx +22 -0
  109. package/src/components/Radio/Radio.tsx +7 -0
  110. package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
  111. package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
  112. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +120 -0
  113. package/src/components/ReadOnlyField/ReadOnlyField.tsx +75 -0
  114. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +46 -0
  115. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +85 -0
  116. package/src/components/ReadOnlyField/index.ts +3 -0
  117. package/src/components/Search/Search.stories.tsx +17 -0
  118. package/src/components/Search/Search.tsx +7 -0
  119. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +22 -0
  120. package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
  121. package/src/components/Slider/Slider.stories.tsx +22 -0
  122. package/src/components/Slider/Slider.tsx +7 -0
  123. package/src/components/Stepper/Stepper.stories.tsx +17 -0
  124. package/src/components/Stepper/Stepper.tsx +7 -0
  125. package/src/components/Switch/Switch.stories.tsx +22 -0
  126. package/src/components/Switch/Switch.tsx +7 -0
  127. package/src/components/Table/Table.stories.tsx +17 -0
  128. package/src/components/Table/Table.tsx +7 -0
  129. package/src/components/Tabs/Tabs.stories.tsx +17 -0
  130. package/src/components/Tabs/Tabs.tsx +7 -0
  131. package/src/components/Text/Text.stories.tsx +88 -0
  132. package/src/components/Text/Text.tsx +54 -0
  133. package/src/components/TextArea/TextArea.stories.tsx +22 -0
  134. package/src/components/TextArea/TextArea.tsx +7 -0
  135. package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
  136. package/src/components/TextField/TextField.module.css +225 -0
  137. package/src/components/TextField/TextField.stories.tsx +162 -0
  138. package/src/components/TextField/TextField.tsx +138 -0
  139. package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
  140. package/src/components/TimePicker/TimePicker.tsx +7 -0
  141. package/src/components/Timeline/Timeline.stories.tsx +17 -0
  142. package/src/components/Timeline/Timeline.tsx +7 -0
  143. package/src/components/Title/Title.stories.tsx +63 -0
  144. package/src/components/Title/Title.tsx +45 -0
  145. package/src/components/Toast/Toast.stories.tsx +17 -0
  146. package/src/components/Toast/Toast.tsx +7 -0
  147. package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
  148. package/src/components/Tooltip/Tooltip.tsx +7 -0
  149. package/src/components/TransferList/TransferList.stories.tsx +17 -0
  150. package/src/components/TransferList/TransferList.tsx +7 -0
  151. package/src/components/index.ts +39 -0
  152. package/src/env.d.ts +7 -0
  153. package/src/index.ts +3 -0
  154. package/src/types/index.ts +9 -0
  155. package/src/types/mantine.d.ts +7 -0
  156. package/src/types/scss-modules.d.ts +9 -0
  157. package/src/utils/ColorSchemeWrapper.tsx +27 -0
  158. package/src/utils/copyToClipboard.ts +36 -0
  159. package/src/utils/filterStylingProps.ts +139 -0
  160. package/src/utils/index.ts +1 -0
@@ -1,3 +1,20 @@
1
1
  import { default as React } from 'react';
2
- export type ReadOnlyFieldProps = React.HTMLAttributes<HTMLDivElement>;
3
- export declare const ReadOnlyField: React.FC<ReadOnlyFieldProps>;
2
+ import { ReadOnlyFieldType } from '@recursica/adapter-common';
3
+ import { RecursicaOverStyled } from '../../utils/filterStylingProps';
4
+ import { FormControlWrapperProps } from '../FormControlWrapper/FormControlWrapper';
5
+ export interface RecursicaReadOnlyFieldProps extends Omit<FormControlWrapperProps, "children" | "overStyled"> {
6
+ /** The specific value to be rendered in read-only mode explicitly matching the original field input */
7
+ value?: any;
8
+ /** The data type formatting rules bounding how the string is presented to the user */
9
+ type?: ReadOnlyFieldType;
10
+ /** Custom renderer explicitly responsible for formatting missing/empty value mappings (overriding default 'N/A') */
11
+ emptyValueComponent?: React.ElementType<{
12
+ value?: any;
13
+ }>;
14
+ }
15
+ export type ReadOnlyFieldProps = RecursicaOverStyled<RecursicaReadOnlyFieldProps>;
16
+ /**
17
+ * A native generic form control wrapper exclusively responsible for displaying fixed data.
18
+ * Internally maps to structural ReadOnly primitive blocks bridging standard `FormControlWrapper` layouts natively.
19
+ */
20
+ export declare const ReadOnlyField: React.ForwardRefExoticComponent<ReadOnlyFieldProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ import { RecursicaOverStyled } from '../../utils/filterStylingProps';
3
+ export interface RecursicaReadOnlyTextFieldProps {
4
+ /** The value strictly rendered as text output */
5
+ value?: any;
6
+ }
7
+ export type ReadOnlyTextFieldProps = RecursicaOverStyled<RecursicaReadOnlyTextFieldProps>;
8
+ export declare const ReadOnlyTextField: React.FC<ReadOnlyTextFieldProps>;
@@ -0,0 +1,22 @@
1
+ import { default as React } from 'react';
2
+ import { ReadOnlyFieldType } from '@recursica/adapter-common';
3
+ import { FormControlWrapperProps } from '../FormControlWrapper/FormControlWrapper';
4
+ export interface WithReadOnlyWrapperProps extends Omit<FormControlWrapperProps, "children" | "overStyled"> {
5
+ /** Injects whether the field defaults to reading mode natively */
6
+ readOnly?: boolean;
7
+ /** Explicit React component directly overtaking the baseline text renderer when read-only mode is active */
8
+ readOnlyComponent?: React.ReactNode;
9
+ /** Instructs the underlying generic ReadOnlyField which raw visual structure to bridge automatically */
10
+ readOnlyType?: ReadOnlyFieldType;
11
+ /** The isolated raw data value intercepted explicitly into the ReadOnly formatters */
12
+ readOnlyValue?: any;
13
+ /** Safely enables deep Mantine overrides transparently bypassing block filters */
14
+ overStyled?: boolean;
15
+ /** The nested active node dynamically exposed exclusively when read-only bounds are disabled */
16
+ activeComponent: React.ReactNode;
17
+ }
18
+ /**
19
+ * Universal execution barrier trapping readOnly states globally.
20
+ * Natively delegates active logic down avoiding duplicative internal component bindings dynamically.
21
+ */
22
+ export declare const WithReadOnlyWrapper: React.ForwardRefExoticComponent<WithReadOnlyWrapperProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,3 @@
1
+ export * from './ReadOnlyField';
2
+ export * from './WithReadOnlyWrapper';
3
+ export * from './ReadOnlyTextField';
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from 'react';
2
+ import { TextProps as MantineTextProps } from '@mantine/core';
3
+ import { RecursicaOverStyled } from '../../utils/filterStylingProps';
4
+ export type TextVariant = "body" | "body-small" | "caption" | "overline" | "subtitle" | "subtitle-small";
5
+ export type RecursicaTextProps = Omit<MantineTextProps, "variant"> & {
6
+ /**
7
+ * The explicit typography hierarchy dictated by Recursica's global design tokens.
8
+ */
9
+ variant?: TextVariant;
10
+ children?: ReactNode;
11
+ };
12
+ export type TextProps = RecursicaOverStyled<RecursicaTextProps>;
13
+ /**
14
+ * A generalized typographical wrapper limiting text properties to bounded Recursica UI-kit tokens inherently.
15
+ * Do not use for semantic headings; use the explicit `<Title>` component for `<h1>` - `<h6>`.
16
+ */
17
+ export declare const Text: import('react').ForwardRefExoticComponent<TextProps & import('react').RefAttributes<HTMLDivElement>>;
@@ -1,3 +1,9 @@
1
1
  import { default as React } from 'react';
2
- export type TextFieldProps = React.HTMLAttributes<HTMLDivElement>;
3
- export declare const TextField: React.FC<TextFieldProps>;
2
+ import { InputProps, InputWrapperProps } from '@mantine/core';
3
+ import { ReadOnlyControlProps } from '@recursica/adapter-common';
4
+ import { RecursicaOverStyled } from '../../utils/filterStylingProps';
5
+ import { RecursicaFormControlWrapperProps } from '../FormControlWrapper/FormControlWrapper';
6
+ export interface RecursicaTextFieldProps extends Omit<InputProps, "size" | "variant" | "radius" | "wrapperProps">, Pick<InputWrapperProps, "label" | "error" | "required" | "withAsterisk" | "id">, Omit<React.ComponentPropsWithoutRef<"input">, "size" | "style" | "className" | "id">, Omit<RecursicaFormControlWrapperProps, "controlMaxWidth" | "controlMinWidth">, ReadOnlyControlProps {
7
+ }
8
+ export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
9
+ export declare const TextField: React.ForwardRefExoticComponent<TextFieldProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,13 @@
1
+ import { TitleProps as MantineTitleProps } from '@mantine/core';
2
+ import { RecursicaOverStyled } from '../../utils/filterStylingProps';
3
+ export type RecursicaTitleProps = Omit<MantineTitleProps, "order"> & {
4
+ /**
5
+ * Enforces semantic HTML headers (h1-h6) cleanly bound to native typographic scaling variables in the design system.
6
+ */
7
+ order?: 1 | 2 | 3 | 4 | 5 | 6;
8
+ };
9
+ export type TitleProps = RecursicaOverStyled<RecursicaTitleProps>;
10
+ /**
11
+ * Enforces highly accessible structural markup utilizing semantic `<h1>` through `<h6>` tags securely bound directly to Recursica typographic scales.
12
+ */
13
+ export declare const Title: import('react').ForwardRefExoticComponent<TitleProps & import('react').RefAttributes<HTMLHeadingElement>>;
@@ -5,6 +5,7 @@ export * from './Breadcrumb/Breadcrumb';
5
5
  export * from './Button';
6
6
  export * from './Card/Card';
7
7
  export * from './Checkbox/Checkbox';
8
+ export * from './Checkbox/CheckboxGroup';
8
9
  export * from './Chip/Chip';
9
10
  export * from './DatePicker/DatePicker';
10
11
  export * from './Dropdown/Dropdown';
@@ -13,6 +14,7 @@ export * from './FileUpload/FileUpload';
13
14
  export * from './HoverCard/HoverCard';
14
15
  export * from './Link/Link';
15
16
  export * from './Loader/Loader';
17
+ export * from './Label';
16
18
  export * from './Menu/Menu';
17
19
  export * from './Modal/Modal';
18
20
  export * from './NumberInput/NumberInput';
@@ -20,7 +22,7 @@ export * from './Pagination/Pagination';
20
22
  export * from './Panel/Panel';
21
23
  export * from './Popover/Popover';
22
24
  export * from './Radio/Radio';
23
- export * from './ReadOnlyField/ReadOnlyField';
25
+ export * from './ReadOnlyField';
24
26
  export * from './Search/Search';
25
27
  export * from './SegmentedControl/SegmentedControl';
26
28
  export * from './Slider/Slider';
@@ -0,0 +1,3 @@
1
+ export declare function ColorSchemeWrapper({ children, }: {
2
+ children: React.ReactNode;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -21,9 +21,13 @@
21
21
  * @param overStyled - Boolean toggle to allow raw external styling. Defaults to false.
22
22
  * @returns Sanitized component props safe for internal styling merging
23
23
  */
24
- export declare const BLOCKED_STYLING_KEYS: readonly ["className", "classNames", "style", "styles", "vars", "p", "px", "py", "pt", "pb", "pl", "pr", "bg", "c", "opacity", "ff", "fz", "fw", "lts", "ta", "lh", "fs", "tt", "td", "bd", "bdw", "bds", "bdc", "bdr", "shadow"];
24
+ export declare const BLOCKED_STYLING_KEYS: readonly ["className", "classNames", "style", "styles", "vars", "p", "px", "py", "pt", "pb", "pl", "pr", "bg", "c", "opacity", "ff", "fz", "fw", "lts", "ta", "lh", "fs", "tt", "td", "bd", "bdw", "bds", "bdc", "bdr", "shadow", "w", "miw", "maw", "h", "mih", "mah"];
25
25
  export type BlockedStylingKeys = (typeof BLOCKED_STYLING_KEYS)[number];
26
- export type RecursicaOverStyled<T> = (Omit<T, BlockedStylingKeys> & {
26
+ export type RecursicaSpacing = "rec-none" | "rec-sm" | "rec-default" | "rec-md" | "rec-lg" | "rec-xl" | "rec-2xl";
27
+ export type ForbiddenStyles = {
28
+ [K in BlockedStylingKeys]?: never;
29
+ };
30
+ export type RecursicaOverStyled<T> = (Omit<T, BlockedStylingKeys> & ForbiddenStyles & {
27
31
  overStyled?: false | undefined;
28
32
  }) | (T & {
29
33
  overStyled: true;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "git+https://github.com/borderux/recursica.git"
13
13
  },
14
- "version": "0.5.0",
14
+ "version": "0.7.0",
15
15
  "type": "module",
16
16
  "main": "./dist/mantine-adapter.cjs",
17
17
  "module": "./dist/mantine-adapter.js",
@@ -25,7 +25,10 @@
25
25
  "./style.css": "./dist/mantine-adapter.css"
26
26
  },
27
27
  "files": [
28
- "dist"
28
+ "dist",
29
+ "src",
30
+ "CHANGELOG.md",
31
+ ".storybook/commonArgTypes.ts"
29
32
  ],
30
33
  "keywords": [
31
34
  "react",
@@ -72,6 +75,7 @@
72
75
  "sass": "^1.89.2",
73
76
  "sirv": "^3.0.2",
74
77
  "storybook": "^10.3.3",
78
+ "storybook-dark-mode": "^5.0.0",
75
79
  "strip-literal": "^3.0.0",
76
80
  "typescript": "~5.8.3",
77
81
  "typescript-eslint": "^8.30.1",
@@ -81,9 +85,9 @@
81
85
  "vitest": "^3.2.4"
82
86
  },
83
87
  "peerDependencies": {
84
- "@mantine/core": ">=8.0.0",
85
- "@mantine/dates": ">=8.0.0",
86
- "@mantine/hooks": ">=8.0.0",
88
+ "@mantine/core": "^8.0.0",
89
+ "@mantine/dates": "^8.0.0",
90
+ "@mantine/hooks": "^8.0.0",
87
91
  "react": ">=16.8.0",
88
92
  "react-dom": ">=16.8.0"
89
93
  }
@@ -0,0 +1,174 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ Container,
4
+ Paper,
5
+ Title,
6
+ Text,
7
+ List,
8
+ Divider,
9
+ Group,
10
+ Code,
11
+ } from "@mantine/core";
12
+ import { Button } from "./components/Button/Button";
13
+
14
+ const OverStylingInfo = () => {
15
+ return (
16
+ <Container size="md" py="xl">
17
+ <Paper withBorder p="xl" radius="md">
18
+ <Title order={1} mb="md">
19
+ Over Styling (<Code>overStyled</Code>)
20
+ </Title>
21
+ <Text mb="md">
22
+ By default, all Recursica components are strictly sandboxed. This
23
+ means they are protected against arbitrary styling configurations
24
+ (like passing generic React <Code>style</Code> objects, custom{" "}
25
+ <Code>classNames</Code> injections, or using deep Mantine layout hooks
26
+ like <Code>bg</Code> and <Code>c</Code>). This strict compile-time and
27
+ run-time enforcement guarantees that your design system tokens remain
28
+ true across your application.
29
+ </Text>
30
+ <Text mb="md">
31
+ However, there may be edge cases where a developer absolutely must
32
+ modify a component beyond what the design tokens natively allow. For
33
+ this, we provide the <strong>escape hatch</strong> property:{" "}
34
+ <Code>overStyled={`{true}`}</Code>.
35
+ </Text>
36
+
37
+ <Title order={3} mb="sm">
38
+ The Core Philosophy
39
+ </Title>
40
+ <Text mb="sm">
41
+ **You should not over-style components.** Using{" "}
42
+ <Code>overStyled</Code> explicitly signifies that you are breaking
43
+ design system rules.
44
+ </Text>
45
+ <List mb="xl" type="ordered">
46
+ <List.Item>
47
+ <strong>Technical Debt:</strong> If over-styling is required, it
48
+ should be treated as a short-term workaround. Ideally, the component
49
+ will be refactored once the required layouts or variants are
50
+ officially integrated into the core Recursica component library.
51
+ </List.Item>
52
+ <List.Item>
53
+ <strong>Auditing & Searching:</strong> Because this pattern creates
54
+ technical debt, we enforce the explicit <Code>overStyled</Code>{" "}
55
+ boolean. This provides a highly auditable, easily searchable string.
56
+ Product managers and engineers can quickly grep the codebase for{" "}
57
+ <Code>overStyled</Code> (or the <Code>RecursicaOverStyled</Code>{" "}
58
+ typings) to hunt down components that don't match standard patterns.
59
+ </List.Item>
60
+ <List.Item>
61
+ <strong>Highly Custom Components:</strong> If your application
62
+ genuinely requires massive custom layouts that the UI kit cannot
63
+ support, <strong>do not hack the Recursica component</strong>.
64
+ Instead, it is highly encouraged that you import the underlying
65
+ primitive component directly from <Code>@mantine/core</Code> and
66
+ construct your independent feature there. While you can utilize raw
67
+ Recursica CSS variables on these custom components, note that they
68
+ are not guaranteed to be accurately maintained as Recursica evolves.
69
+ Keep strict components strict!
70
+ </List.Item>
71
+ </List>
72
+
73
+ <Divider mb="xl" />
74
+
75
+ <Title order={3} mb="sm">
76
+ Permitted Layout Properties
77
+ </Title>
78
+ <Text mb="sm">
79
+ Unlike deep styling bounds (colors, typography, padding, dimensions),
80
+ external <strong>layout spacing properties</strong> like Margins (
81
+ <Code>m</Code>, <Code>mt</Code>, <Code>mb</Code>, <Code>mx</Code>) are
82
+ safely <strong>permitted by default</strong>. This allows integrators
83
+ to structurally compose components alongside siblings without
84
+ breaching internal token boundaries.
85
+ </Text>
86
+ <Text mb="xl">
87
+ When using layout properties, you have the flexibility to use either
88
+ ecosystem seamlessly:
89
+ </Text>
90
+ <List mb="md" type="ordered">
91
+ <List.Item>
92
+ <strong>Mantine Core Values:</strong> Passing standard Mantine sizes
93
+ (like <Code>mt="md"</Code>) passes straight through to Mantine
94
+ natively, allowing you to interface completely normally with a
95
+ parent application's existing Mantine Theme setup that might fall
96
+ outside Recursica's scope.
97
+ </List.Item>
98
+ <List.Item>
99
+ <strong>Recursica Strict Tokens:</strong> Passing our custom
100
+ prefixed tokens (like <Code>mt="rec-md"</Code>) signals our internal
101
+ layout interceptor to securely translate the value directly to our
102
+ native <Code>recursica_brand_dimensions</Code> CSS variables. This
103
+ ensures strict design token measurements while sharing the exact
104
+ same prop interface!
105
+ </List.Item>
106
+ </List>
107
+ <Text mb="sm" fw={500}>
108
+ Available Recursica Layout Tokens:
109
+ </Text>
110
+ <List mb="xl" type="unordered">
111
+ <List.Item>
112
+ <Code>rec-none</Code> (0px limit)
113
+ </List.Item>
114
+ <List.Item>
115
+ <Code>rec-sm</Code> (0.5x scaling)
116
+ </List.Item>
117
+ <List.Item>
118
+ <Code>rec-default</Code> (1.0x scaling)
119
+ </List.Item>
120
+ <List.Item>
121
+ <Code>rec-md</Code> (1.5x scaling)
122
+ </List.Item>
123
+ <List.Item>
124
+ <Code>rec-lg</Code> (2.0x scaling)
125
+ </List.Item>
126
+ <List.Item>
127
+ <Code>rec-xl</Code> (3.0x scaling)
128
+ </List.Item>
129
+ <List.Item>
130
+ <Code>rec-2xl</Code> (4.0x scaling)
131
+ </List.Item>
132
+ </List>
133
+
134
+ <Divider mb="xl" />
135
+
136
+ <Title order={3} mb="md">
137
+ Live Example
138
+ </Title>
139
+ <Text mb="xl">
140
+ Below is a side-by-side comparison. The first is a standard Recursica
141
+ Button protected by the design tokens mapping. The second flagrantly
142
+ forces <Code>overStyled={`{true}`}</Code>, allowing Mantine's native
143
+ styling generics to punch right through the sandbox layout.
144
+ </Text>
145
+
146
+ <Group gap="xl">
147
+ <div>
148
+ <Text size="sm" c="dimmed" mb="xs">
149
+ Strict Baseline (Default)
150
+ </Text>
151
+ <Button variant="solid">Standard UI Kit Button</Button>
152
+ </div>
153
+ <div>
154
+ <Text size="sm" c="dimmed" mb="xs">
155
+ overStyled={`{true}`}
156
+ </Text>
157
+ <Button overStyled={true} bg="pink" c="black" radius="xl">
158
+ Unsafe Pink Marketing Button
159
+ </Button>
160
+ </div>
161
+ </Group>
162
+ </Paper>
163
+ </Container>
164
+ );
165
+ };
166
+
167
+ const meta: Meta<typeof OverStylingInfo> = {
168
+ title: "Introduction/Over Styling",
169
+ component: OverStylingInfo,
170
+ };
171
+
172
+ export default meta;
173
+
174
+ export const Default: StoryObj<typeof OverStylingInfo> = {};
@@ -0,0 +1,56 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import ReactMarkdown from "react-markdown";
3
+ import {
4
+ Container,
5
+ Paper,
6
+ Title,
7
+ TypographyStylesProvider,
8
+ Group,
9
+ Anchor,
10
+ Divider,
11
+ } from "@mantine/core";
12
+ import pkg from "../package.json";
13
+ import changelog from "../CHANGELOG.md?raw";
14
+
15
+ const VersionInfo = () => {
16
+ return (
17
+ <Container size="md" py="xl">
18
+ <Paper withBorder p="xl" radius="md">
19
+ <Title order={1} mb="xs">
20
+ Mantine Adapter v{pkg.version}
21
+ </Title>
22
+ <Group mb="xl" gap="md">
23
+ <Anchor
24
+ href="https://github.com/borderux/recursica"
25
+ target="_blank"
26
+ rel="noopener noreferrer"
27
+ >
28
+ GitHub Repository
29
+ </Anchor>
30
+ <Anchor
31
+ href="https://recursica.com"
32
+ target="_blank"
33
+ rel="noopener noreferrer"
34
+ >
35
+ Documentation & Website
36
+ </Anchor>
37
+ </Group>
38
+ <Divider mb="xl" />
39
+ <TypographyStylesProvider>
40
+ <ReactMarkdown>{changelog}</ReactMarkdown>
41
+ </TypographyStylesProvider>
42
+ </Paper>
43
+ </Container>
44
+ );
45
+ };
46
+
47
+ const meta: Meta<typeof VersionInfo> = {
48
+ title: "Introduction/Version Info",
49
+ component: VersionInfo,
50
+ };
51
+
52
+ export default meta;
53
+
54
+ type Story = StoryObj<typeof VersionInfo>;
55
+
56
+ export const Default: Story = {};
@@ -0,0 +1,48 @@
1
+ # Accordion – implementation notes
2
+
3
+ Decisions and design tweaks strictly tailored for the UI Kit's Accordion wrapped against `@mantine/core`. Use this when managing components possessing deeply nested state logic (e.g., active toggles, nested headers mapping external design properties).
4
+
5
+ ---
6
+
7
+ ## 1. Hybrid Composition API (Smart Rendering Flow)
8
+
9
+ **Decision:** We fundamentally maintain the exact library composition API structure (`<Accordion>`, `<Accordion.Item>`, `<Accordion.Control>`, `<Accordion.Panel>`) while actively supporting an auto-completing flattened prop schema matching the unified Recursica API (`title`, `leftIcon`, `divider`).
10
+ **Implementation:** Avoid rigid raw parameter dumps. Mantine dynamically injects explicit `id` logic, keyboard ARIA mapping, and focus tracking correctly across `Control` to `Panel` DOM connections natively. By exposing the hierarchical mapping 1:1, Recursica safely adopts these capabilities. However, to strictly support Recursica's unified prop mapping interface:
11
+
12
+ - **Auto-Construction:** If integrators natively pass `title` and/or `leftIcon` props into `<AccordionItem>`, the component structurally auto-generates the internal `AccordionControl` sub-wrappers mapping the text and SVG natively, whilst treating `children` implicitly as the Panel contents.
13
+ - **Graceful Falldown:** If `title` is heavily omitted, the node immediately falls backward into raw Mantine composability expecting integrators mapped `<Accordion.Control>` entirely manually.
14
+
15
+ ---
16
+
17
+ ## 2. Default Configuration Reset (`unstyled`)
18
+
19
+ **Decision:** We strip Mantine's inner styles away completely from Accordion mappings by leveraging React's default `variant="unstyled"`.
20
+ **Implementation:** In `Accordion.tsx`, `<MantineAccordion>` binds `variant="unstyled"`. This effectively deletes Mantine's precomputed padding, borders, and shadow mappings allowing our targeted `classNames` inside `Accordion.module.css` to become the exact source of foundational truth without "fighting" `!important` tags or unpredictable flex-layouts inherited globally.
21
+
22
+ ---
23
+
24
+ ## 3. Strict SVG Icons Wrapper (`.iconLeftWrapper`)
25
+
26
+ **Decision:** Identical logic enforced as seen within Buttons: SVG scales dynamically inside `.mantine-leftSection` based on SVGs internal definition boundaries potentially corrupting header gaps.
27
+ **Implementation:** `AccordionControl` captures `<span className={styles.iconLeftWrapper} aria-hidden>` forcing `object-fit: contain` mapped exactly to the `properties_icon-left-size` Recursica dimension token forcing integrator SVG overrides inline perfectly.
28
+
29
+ ---
30
+
31
+ ## 4. Transparent Global Hover Fixes
32
+
33
+ **Decision:** We nullify internal Mantine button hover actions and exclusively utilize Recursica's hover structure natively.
34
+ **Implementation:** We construct `.control::after` pseudo-objects dynamically pulling our `hover-color` & `hover-opacity` bindings. Mantine's native action sets `.control:hover { background-color: var(...) }` dynamically causing internal layer overlaps. We enforce `background-color: transparent` strictly overriding it, preserving our pseudo-overlay layer-cascade cleanly.
35
+
36
+ ---
37
+
38
+ ## 5. Active Target Hooks (`[data-active]`)
39
+
40
+ **Decision:** Collapsed and expanded state tracking requires separate background maps across `AccordionItem`.
41
+ **Implementation:** Rather than syncing React `useState` hooks matching `Accordion.value`, we defer to Mantine's inherent DOM mapping: `.item[data-active]` implicitly triggers exactly when Mantine registers an expansion state swap changing values down dynamically on the element layer, perfectly binding to `--recursica_..._background-expanded`.
42
+
43
+ ---
44
+
45
+ ## 6. Nullifying Isolated State Bounds (`open` boolean)
46
+
47
+ **Decision:** We do not bind isolated `open={true}` state properties natively on individual `<AccordionItem>` configurations.
48
+ **Implementation:** Recursica natively dictates an item-level `open` tracking mapping. However, internally mapping boolean flags structurally across specific tree nodes heavily corrupts Mantine's DOM layout algorithms mapping parent-driven transition listeners. Mantine forces all expanded-height logic to run symmetrically off the `<Accordion value="...">` string matching array to accurately bind ARIA transitions. We explicitly ignore isolated item `<AccordionItem open={...}>` booleans to shield the rendering sequence cleanly.