@recursica/mantine-adapter 0.6.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 (140) 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 +660 -586
  7. package/dist/mantine-adapter.js.map +1 -1
  8. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +1 -1
  9. package/dist/src/components/Chip/Chip.d.ts +14 -2
  10. package/package.json +5 -2
  11. package/src/OverStyling.stories.tsx +174 -0
  12. package/src/Version.stories.tsx +56 -0
  13. package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
  14. package/src/components/Accordion/Accordion.module.css +261 -0
  15. package/src/components/Accordion/Accordion.stories.tsx +145 -0
  16. package/src/components/Accordion/Accordion.tsx +200 -0
  17. package/src/components/Accordion/index.ts +1 -0
  18. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  19. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +73 -0
  20. package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
  21. package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
  22. package/src/components/Avatar/Avatar.module.css +340 -0
  23. package/src/components/Avatar/Avatar.stories.tsx +102 -0
  24. package/src/components/Avatar/Avatar.tsx +100 -0
  25. package/src/components/Avatar/index.ts +1 -0
  26. package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
  27. package/src/components/Badge/Badge.module.css +124 -0
  28. package/src/components/Badge/Badge.stories.tsx +77 -0
  29. package/src/components/Badge/Badge.tsx +66 -0
  30. package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
  31. package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
  32. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
  33. package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
  34. package/src/components/Button/Button.module.css +275 -0
  35. package/src/components/Button/Button.stories.tsx +105 -0
  36. package/src/components/Button/Button.tsx +122 -0
  37. package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
  38. package/src/components/Button/index.ts +1 -0
  39. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
  40. package/src/components/Card/Card.module.css +60 -0
  41. package/src/components/Card/Card.stories.tsx +141 -0
  42. package/src/components/Card/Card.tsx +176 -0
  43. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
  44. package/src/components/Checkbox/Checkbox.module.css +204 -0
  45. package/src/components/Checkbox/Checkbox.stories.tsx +73 -0
  46. package/src/components/Checkbox/Checkbox.tsx +111 -0
  47. package/src/components/Checkbox/CheckboxGroup.stories.tsx +138 -0
  48. package/src/components/Checkbox/CheckboxGroup.tsx +140 -0
  49. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
  50. package/src/components/Chip/Chip.module.css +218 -0
  51. package/src/components/Chip/Chip.stories.tsx +115 -0
  52. package/src/components/Chip/Chip.tsx +143 -0
  53. package/src/components/DatePicker/DatePicker.stories.tsx +22 -0
  54. package/src/components/DatePicker/DatePicker.tsx +7 -0
  55. package/src/components/Dropdown/Dropdown.stories.tsx +22 -0
  56. package/src/components/Dropdown/Dropdown.tsx +7 -0
  57. package/src/components/FileInput/FileInput.stories.tsx +22 -0
  58. package/src/components/FileInput/FileInput.tsx +7 -0
  59. package/src/components/FileUpload/FileUpload.stories.tsx +22 -0
  60. package/src/components/FileUpload/FileUpload.tsx +7 -0
  61. package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
  62. package/src/components/FormControlWrapper/FormControlWrapper.module.css +46 -0
  63. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -0
  64. package/src/components/FormControlWrapper/FormControlWrapper.tsx +170 -0
  65. package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
  66. package/src/components/HoverCard/HoverCard.tsx +7 -0
  67. package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
  68. package/src/components/Label/Label.module.css +177 -0
  69. package/src/components/Label/Label.stories.tsx +123 -0
  70. package/src/components/Label/Label.tsx +132 -0
  71. package/src/components/Label/index.ts +1 -0
  72. package/src/components/Link/Link.stories.tsx +17 -0
  73. package/src/components/Link/Link.tsx +7 -0
  74. package/src/components/Loader/Loader.stories.tsx +17 -0
  75. package/src/components/Loader/Loader.tsx +7 -0
  76. package/src/components/Menu/Menu.stories.tsx +17 -0
  77. package/src/components/Menu/Menu.tsx +7 -0
  78. package/src/components/Modal/Modal.stories.tsx +17 -0
  79. package/src/components/Modal/Modal.tsx +7 -0
  80. package/src/components/NumberInput/NumberInput.stories.tsx +22 -0
  81. package/src/components/NumberInput/NumberInput.tsx +7 -0
  82. package/src/components/Pagination/Pagination.stories.tsx +17 -0
  83. package/src/components/Pagination/Pagination.tsx +7 -0
  84. package/src/components/Panel/Panel.stories.tsx +17 -0
  85. package/src/components/Panel/Panel.tsx +7 -0
  86. package/src/components/Popover/Popover.stories.tsx +17 -0
  87. package/src/components/Popover/Popover.tsx +7 -0
  88. package/src/components/Radio/Radio.stories.tsx +22 -0
  89. package/src/components/Radio/Radio.tsx +7 -0
  90. package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
  91. package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
  92. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +120 -0
  93. package/src/components/ReadOnlyField/ReadOnlyField.tsx +75 -0
  94. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +46 -0
  95. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +85 -0
  96. package/src/components/ReadOnlyField/index.ts +3 -0
  97. package/src/components/Search/Search.stories.tsx +17 -0
  98. package/src/components/Search/Search.tsx +7 -0
  99. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +22 -0
  100. package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
  101. package/src/components/Slider/Slider.stories.tsx +22 -0
  102. package/src/components/Slider/Slider.tsx +7 -0
  103. package/src/components/Stepper/Stepper.stories.tsx +17 -0
  104. package/src/components/Stepper/Stepper.tsx +7 -0
  105. package/src/components/Switch/Switch.stories.tsx +22 -0
  106. package/src/components/Switch/Switch.tsx +7 -0
  107. package/src/components/Table/Table.stories.tsx +17 -0
  108. package/src/components/Table/Table.tsx +7 -0
  109. package/src/components/Tabs/Tabs.stories.tsx +17 -0
  110. package/src/components/Tabs/Tabs.tsx +7 -0
  111. package/src/components/Text/Text.stories.tsx +88 -0
  112. package/src/components/Text/Text.tsx +54 -0
  113. package/src/components/TextArea/TextArea.stories.tsx +22 -0
  114. package/src/components/TextArea/TextArea.tsx +7 -0
  115. package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
  116. package/src/components/TextField/TextField.module.css +225 -0
  117. package/src/components/TextField/TextField.stories.tsx +162 -0
  118. package/src/components/TextField/TextField.tsx +138 -0
  119. package/src/components/TimePicker/TimePicker.stories.tsx +22 -0
  120. package/src/components/TimePicker/TimePicker.tsx +7 -0
  121. package/src/components/Timeline/Timeline.stories.tsx +17 -0
  122. package/src/components/Timeline/Timeline.tsx +7 -0
  123. package/src/components/Title/Title.stories.tsx +63 -0
  124. package/src/components/Title/Title.tsx +45 -0
  125. package/src/components/Toast/Toast.stories.tsx +17 -0
  126. package/src/components/Toast/Toast.tsx +7 -0
  127. package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
  128. package/src/components/Tooltip/Tooltip.tsx +7 -0
  129. package/src/components/TransferList/TransferList.stories.tsx +17 -0
  130. package/src/components/TransferList/TransferList.tsx +7 -0
  131. package/src/components/index.ts +39 -0
  132. package/src/env.d.ts +7 -0
  133. package/src/index.ts +3 -0
  134. package/src/types/index.ts +9 -0
  135. package/src/types/mantine.d.ts +7 -0
  136. package/src/types/scss-modules.d.ts +9 -0
  137. package/src/utils/ColorSchemeWrapper.tsx +27 -0
  138. package/src/utils/copyToClipboard.ts +36 -0
  139. package/src/utils/filterStylingProps.ts +139 -0
  140. package/src/utils/index.ts +1 -0
@@ -0,0 +1,123 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React from "react";
3
+ import type { Meta, StoryObj } from "@storybook/react";
4
+ import { Label } from "./Label";
5
+ import { TextField } from "../TextField/TextField";
6
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
7
+
8
+ type LabelStoryProps = React.ComponentProps<typeof Label>;
9
+
10
+ const meta: Meta<LabelStoryProps> = {
11
+ title: "UI-Kit/Label",
12
+ component: Label,
13
+ tags: ["autodocs"],
14
+ parameters: {
15
+ docs: {
16
+ description: {
17
+ component:
18
+ "The `Label` component is a strict Recursica-styled wrapper around Mantine's native `Input.Label`. It serves as the primary compositional primitive for all form fields, preserving Mantine's accessibility associations and context while strictly enforcing the Recursica atomic design system.\n\n### Usage with Form Inputs\nWhen working with form structures, render this `Label` component directly above your inputs or supply it to a component's overriding properties. The component automatically maps structural layout dimensions, dynamic alignment (`left` vs `right`), custom indicator gaps, and integrates a customized `optionalText` and `withEditIcon` flow that safely bypasses Mantine's native required asterisk mechanisms.",
19
+ },
20
+ },
21
+ },
22
+ argTypes: {
23
+ ...formControlArgTypes,
24
+ },
25
+ };
26
+
27
+ export default meta;
28
+
29
+ type Story = StoryObj<LabelStoryProps>;
30
+
31
+ // Utility mapping to pipe raw Label args structurally into TextField accurately
32
+ const renderWithTextField = ({ children, ...args }: LabelStoryProps) => (
33
+ <TextField
34
+ label={children as React.ReactNode}
35
+ placeholder="Form Control primitive mapped..."
36
+ {...(args as any)}
37
+ />
38
+ );
39
+
40
+ export const Default: Story = {
41
+ args: {
42
+ children: "Dynamic Label (Controls)",
43
+ formLayout: "stacked",
44
+ labelSize: "default",
45
+ labelAlignment: "left",
46
+ required: false,
47
+ labelOptionalText: "",
48
+ labelWithEditIcon: false,
49
+ },
50
+ render: renderWithTextField,
51
+ };
52
+
53
+ export const StackedDefault: Story = {
54
+ args: {
55
+ children: "Email Address",
56
+ formLayout: "stacked",
57
+ },
58
+ render: renderWithTextField,
59
+ };
60
+
61
+ export const StackedRequired: Story = {
62
+ args: {
63
+ children: "Primary Network Node",
64
+ formLayout: "stacked",
65
+ required: true,
66
+ },
67
+ render: renderWithTextField,
68
+ };
69
+
70
+ export const StackedWithEditIcon: Story = {
71
+ args: {
72
+ children: "Environment Variables",
73
+ formLayout: "stacked",
74
+ labelWithEditIcon: true,
75
+ },
76
+ render: renderWithTextField,
77
+ };
78
+
79
+ export const SideBySideDefault: Story = {
80
+ args: {
81
+ children: "Status",
82
+ formLayout: "side-by-side",
83
+ labelSize: "default",
84
+ },
85
+ render: renderWithTextField,
86
+ };
87
+
88
+ export const RequiredSuppressesOptionalText: Story = {
89
+ args: {
90
+ children: "Full Name",
91
+ formLayout: "stacked",
92
+ required: true,
93
+ labelOptionalText: "This should not render",
94
+ },
95
+ render: renderWithTextField,
96
+ };
97
+
98
+ export const BooleanOptionalText: Story = {
99
+ args: {
100
+ children: "Middle Initial",
101
+ formLayout: "side-by-side",
102
+ labelOptionalText: true,
103
+ },
104
+ render: renderWithTextField,
105
+ };
106
+
107
+ export const WithEditIcon: Story = {
108
+ args: {
109
+ children: "Shipping Address",
110
+ formLayout: "side-by-side",
111
+ labelWithEditIcon: true,
112
+ },
113
+ render: renderWithTextField,
114
+ };
115
+
116
+ export const LayerOneSideBySide: Story = {
117
+ args: {
118
+ children: "Configuration",
119
+ formLayout: "side-by-side",
120
+ labelWithEditIcon: true,
121
+ },
122
+ render: renderWithTextField,
123
+ };
@@ -0,0 +1,132 @@
1
+ import React, { forwardRef } from "react";
2
+ import { Input, type InputLabelProps } from "@mantine/core";
3
+ import {
4
+ filterStylingProps,
5
+ type RecursicaOverStyled,
6
+ } from "../../utils/filterStylingProps";
7
+ import styles from "./Label.module.css";
8
+
9
+ export interface RecursicaLabelProps {
10
+ /** Overall structural flow mapping the Form Control natively cascading down to Label and Input logic. */
11
+ formLayout?: "stacked" | "side-by-side";
12
+ /** Specifies the sizing metrics natively mapping the Label boundaries. */
13
+ labelSize?: "default" | "small";
14
+ /** Overall alignment directive for the label strings natively forcing Left/Right justification. */
15
+ labelAlignment?: "left" | "right";
16
+ /** Injects an indicator text block alongside the label. Can be boolean (`true` maps to '(Optional)') or custom React nodes. */
17
+ labelOptionalText?: boolean | React.ReactNode;
18
+ /** When true, forces the native Edit Icon to replace the standard asterisk visually. */
19
+ labelWithEditIcon?: boolean;
20
+ /** Custom action area to render alongside the label instead of the default edit icon. */
21
+ labelActionArea?: React.ReactNode;
22
+ /** Interaction hook invoked whenever a generated edit icon block natively triggers a click event. */
23
+ onLabelEditClick?: React.MouseEventHandler<HTMLButtonElement>;
24
+ }
25
+
26
+ export type LabelProps = RecursicaOverStyled<
27
+ Omit<InputLabelProps, "size"> & RecursicaLabelProps
28
+ >;
29
+
30
+ export const Label = forwardRef<HTMLLabelElement, LabelProps>(function Label(
31
+ {
32
+ formLayout = "stacked",
33
+ labelSize = "default",
34
+ labelAlignment,
35
+ required = false,
36
+ labelOptionalText,
37
+ labelWithEditIcon,
38
+ labelActionArea,
39
+ onLabelEditClick,
40
+ children,
41
+ overStyled = false,
42
+ ...rest
43
+ },
44
+ ref,
45
+ ) {
46
+ const resolvedAlignment =
47
+ labelAlignment || (formLayout === "side-by-side" ? "right" : "left");
48
+
49
+ let resolvedOptionalText: React.ReactNode | undefined;
50
+ if (!required) {
51
+ if (labelOptionalText === true) resolvedOptionalText = "optional";
52
+ else if (labelOptionalText) resolvedOptionalText = labelOptionalText;
53
+ }
54
+
55
+ const sanitizedProps = filterStylingProps(rest, overStyled);
56
+ const restRecord = sanitizedProps as Record<string, unknown>;
57
+
58
+ const mergedClassNames: Partial<Record<string, string>> = {
59
+ label: styles.root,
60
+ required: styles.required,
61
+ };
62
+
63
+ const classNamesProp = restRecord.classNames;
64
+ if (
65
+ classNamesProp &&
66
+ typeof classNamesProp === "object" &&
67
+ !Array.isArray(classNamesProp)
68
+ ) {
69
+ const o = classNamesProp as Partial<Record<string, string>>;
70
+ mergedClassNames.label = o.label
71
+ ? `${styles.root} ${o.label}`
72
+ : styles.root;
73
+ mergedClassNames.required = o.required
74
+ ? `${styles.required} ${o.required}`
75
+ : styles.required;
76
+ }
77
+
78
+ const classNameProp = restRecord.className as string | undefined;
79
+ const finalClass = classNameProp
80
+ ? `${styles.root} ${classNameProp}`
81
+ : styles.root;
82
+
83
+ return (
84
+ <Input.Label
85
+ ref={ref}
86
+ className={finalClass}
87
+ classNames={mergedClassNames}
88
+ data-layout={formLayout}
89
+ data-size={labelSize}
90
+ data-alignment={resolvedAlignment}
91
+ required={required && !labelWithEditIcon}
92
+ {...sanitizedProps}
93
+ >
94
+ <span className={styles.labelText}>{children}</span>
95
+ {resolvedOptionalText && (
96
+ <span className={styles.optionalText}>
97
+ {typeof resolvedOptionalText === "string"
98
+ ? `(${resolvedOptionalText})`
99
+ : resolvedOptionalText}
100
+ </span>
101
+ )}
102
+ {labelActionArea ? (
103
+ <span className={styles.actionAreaWrapper}>{labelActionArea}</span>
104
+ ) : labelWithEditIcon ? (
105
+ <button
106
+ type="button"
107
+ className={styles.editIconWrapper}
108
+ data-replaces-asterisk={required ? "true" : undefined}
109
+ onClick={onLabelEditClick}
110
+ aria-label="Edit"
111
+ >
112
+ <svg
113
+ width="16"
114
+ height="16"
115
+ viewBox="0 0 16 16"
116
+ fill="none"
117
+ xmlns="http://www.w3.org/2000/svg"
118
+ >
119
+ <path
120
+ d="M11.5303 2.46967C11.8232 2.17678 12.2981 2.17678 12.591 2.46967L13.5303 3.40898C13.8232 3.70188 13.8232 4.17675 13.5303 4.46964L5.61288 12.3871C5.45268 12.5473 5.24434 12.6483 5.01809 12.6766L2.39534 13.0044C2.10091 13.0412 1.83856 12.7789 1.87538 12.4845L2.2032 9.86175C2.23147 9.63551 2.3325 9.42716 2.4927 9.26696L11.5303 2.46967Z"
121
+ stroke="currentColor"
122
+ strokeLinecap="round"
123
+ strokeLinejoin="round"
124
+ />
125
+ </svg>
126
+ </button>
127
+ ) : null}
128
+ </Input.Label>
129
+ );
130
+ });
131
+
132
+ Label.displayName = "Label";
@@ -0,0 +1 @@
1
+ export * from "./Label";
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Link } from "./Link";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Link> = {
6
+ title: "UI-Kit/🚧 Link",
7
+ component: Link,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Link>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Link" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type LinkProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Link: React.FC<LinkProps> = (props) => {
6
+ return <div {...props}>Link</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Loader } from "./Loader";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Loader> = {
6
+ title: "UI-Kit/🚧 Loader",
7
+ component: Loader,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Loader>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Loader" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type LoaderProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Loader: React.FC<LoaderProps> = (props) => {
6
+ return <div {...props}>Loader</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Menu } from "./Menu";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Menu> = {
6
+ title: "UI-Kit/🚧 Menu",
7
+ component: Menu,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Menu>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Menu" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type MenuProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Menu: React.FC<MenuProps> = (props) => {
6
+ return <div {...props}>Menu</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Modal } from "./Modal";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Modal> = {
6
+ title: "UI-Kit/🚧 Modal",
7
+ component: Modal,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Modal>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Modal" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type ModalProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Modal: React.FC<ModalProps> = (props) => {
6
+ return <div {...props}>Modal</div>;
7
+ };
@@ -0,0 +1,22 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { NumberInput } from "./NumberInput";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof NumberInput> = {
6
+ title: "UI-Kit/🚧 NumberInput",
7
+ component: NumberInput,
8
+ tags: ["autodocs"],
9
+ argTypes: {
10
+ disabled: {
11
+ control: "boolean",
12
+ },
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+
18
+ type Story = StoryObj<typeof NumberInput>;
19
+
20
+ export const Default: Story = {
21
+ render: () => <ComingSoon componentName="NumberInput" />,
22
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type NumberInputProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const NumberInput: React.FC<NumberInputProps> = (props) => {
6
+ return <div {...props}>NumberInput</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Pagination } from "./Pagination";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Pagination> = {
6
+ title: "UI-Kit/🚧 Pagination",
7
+ component: Pagination,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Pagination>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Pagination" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type PaginationProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Pagination: React.FC<PaginationProps> = (props) => {
6
+ return <div {...props}>Pagination</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Panel } from "./Panel";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Panel> = {
6
+ title: "UI-Kit/🚧 Panel",
7
+ component: Panel,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Panel>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Panel" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type PanelProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Panel: React.FC<PanelProps> = (props) => {
6
+ return <div {...props}>Panel</div>;
7
+ };
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Popover } from "./Popover";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Popover> = {
6
+ title: "UI-Kit/🚧 Popover",
7
+ component: Popover,
8
+ tags: ["autodocs"],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof Popover>;
14
+
15
+ export const Default: Story = {
16
+ render: () => <ComingSoon componentName="Popover" />,
17
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type PopoverProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Popover: React.FC<PopoverProps> = (props) => {
6
+ return <div {...props}>Popover</div>;
7
+ };
@@ -0,0 +1,22 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Radio } from "./Radio";
3
+ import { ComingSoon } from "@recursica/storybook-template";
4
+
5
+ const meta: Meta<typeof Radio> = {
6
+ title: "UI-Kit/🚧 Radio",
7
+ component: Radio,
8
+ tags: ["autodocs"],
9
+ argTypes: {
10
+ disabled: {
11
+ control: "boolean",
12
+ },
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+
18
+ type Story = StoryObj<typeof Radio>;
19
+
20
+ export const Default: Story = {
21
+ render: () => <ComingSoon componentName="Radio" />,
22
+ };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+
3
+ export type RadioProps = React.HTMLAttributes<HTMLDivElement>;
4
+
5
+ export const Radio: React.FC<RadioProps> = (props) => {
6
+ return <div {...props}>Radio</div>;
7
+ };
@@ -0,0 +1,15 @@
1
+ # ReadOnlyField Implementation Notes
2
+
3
+ This document acts as a living record tracking edge cases and architectural choices made specific to the `ReadOnlyField` and its internal blocks (like `ReadOnlyTextField`).
4
+
5
+ ## 1. Stripping Mantine Assumptions
6
+
7
+ 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:
8
+
9
+ - `margin: 0` explicitly strips block flow gap so `FormControlWrapper` handles vertical rhythm.
10
+ - `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.
11
+
12
+ ## 2. Unidirectional Editable Mode
13
+
14
+ 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.
15
+ 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,49 @@
1
+ /* HARDCODED VALUES:
2
+ - margin: 0; padding: overrides native paragraph margins mapping back to form element flows.
3
+ */
4
+ .textField {
5
+ margin: 0; /* HARDCODE: Reset paragraph margin; assume wrapper controls layout */
6
+ display: flex;
7
+ align-items: center;
8
+ word-break: break-word;
9
+ padding: 0; /* HARDCODE: read-only fields have no specific padding defined by tokens, zeroing it. */
10
+ font-family: var(
11
+ --recursica_ui-kit_components_read-only-field_properties_text_font-family,
12
+ inherit
13
+ );
14
+ font-size: var(
15
+ --recursica_ui-kit_components_read-only-field_properties_text_font-size,
16
+ 1rem
17
+ );
18
+ font-weight: var(
19
+ --recursica_ui-kit_components_read-only-field_properties_text_font-weight,
20
+ normal
21
+ );
22
+ letter-spacing: var(
23
+ --recursica_ui-kit_components_read-only-field_properties_text_letter-spacing,
24
+ normal
25
+ );
26
+ line-height: var(
27
+ --recursica_ui-kit_components_read-only-field_properties_text_line-height,
28
+ 1.5
29
+ );
30
+ font-style: var(
31
+ --recursica_ui-kit_components_read-only-field_properties_text_font-style,
32
+ normal
33
+ );
34
+ text-decoration: var(
35
+ --recursica_ui-kit_components_read-only-field_properties_text_text-decoration,
36
+ none
37
+ );
38
+ text-transform: var(
39
+ --recursica_ui-kit_components_read-only-field_properties_text_text-transform,
40
+ none
41
+ );
42
+ color: var(
43
+ --recursica_ui-kit_components_read-only-field_properties_colors_text
44
+ );
45
+ min-height: var(
46
+ --recursica_ui-kit_components_read-only-field_properties_min-height,
47
+ 32px
48
+ );
49
+ }