@recursica/mui-adapter 0.4.0 → 0.6.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 (177) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/mui-adapter.cjs +74 -1
  3. package/dist/mui-adapter.cjs.map +1 -1
  4. package/dist/mui-adapter.css +1 -1
  5. package/dist/mui-adapter.js +6651 -201
  6. package/dist/mui-adapter.js.map +1 -1
  7. package/dist/src/components/Accordion/Accordion.d.ts +63 -2
  8. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +9 -2
  9. package/dist/src/components/Autocomplete/Autocomplete.d.ts +17 -0
  10. package/dist/src/components/Autocomplete/index.d.ts +1 -0
  11. package/dist/src/components/Avatar/Avatar.d.ts +14 -2
  12. package/dist/src/components/Badge/Badge.d.ts +13 -3
  13. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +10 -3
  14. package/dist/src/components/Button/Button.d.ts +1 -1
  15. package/dist/src/components/Card/Card.d.ts +40 -3
  16. package/dist/src/components/Checkbox/Checkbox.d.ts +15 -2
  17. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +16 -0
  18. package/dist/src/components/Checkbox/index.d.ts +5 -1
  19. package/dist/src/components/Chip/Chip.d.ts +18 -2
  20. package/dist/src/components/Dropdown/Dropdown.d.ts +23 -3
  21. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +10 -2
  22. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +24 -2
  23. package/dist/src/components/HoverCard/HoverCard.d.ts +55 -3
  24. package/dist/src/components/Label/Label.d.ts +13 -2
  25. package/dist/src/components/Link/Link.d.ts +1 -1
  26. package/dist/src/components/Menu/Menu.d.ts +99 -3
  27. package/dist/src/components/Modal/Modal.d.ts +36 -2
  28. package/dist/src/components/NumberInput/NumberInput.d.ts +14 -2
  29. package/dist/src/components/Pagination/Pagination.d.ts +44 -2
  30. package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
  31. package/dist/src/components/Panel/Panel.d.ts +65 -3
  32. package/dist/src/components/Radio/Radio.d.ts +13 -3
  33. package/dist/src/components/Radio/RadioGroup.d.ts +13 -0
  34. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  35. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +7 -2
  36. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  37. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  38. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
  39. package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
  40. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +31 -3
  41. package/dist/src/components/Slider/Slider.d.ts +28 -2
  42. package/dist/src/components/Stepper/Stepper.d.ts +21 -2
  43. package/dist/src/components/Switch/Switch.d.ts +10 -3
  44. package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
  45. package/dist/src/components/Tabs/Tabs.d.ts +35 -3
  46. package/dist/src/components/Text/Text.d.ts +1 -1
  47. package/dist/src/components/TextArea/TextArea.d.ts +18 -2
  48. package/dist/src/components/TextField/TextField.d.ts +16 -2
  49. package/dist/src/components/Timeline/Timeline.d.ts +14 -2
  50. package/dist/src/components/Timeline/TimelineItem.d.ts +29 -0
  51. package/dist/src/components/Title/Title.d.ts +1 -1
  52. package/dist/src/components/Toast/Toast.d.ts +25 -2
  53. package/dist/src/components/Tooltip/Tooltip.d.ts +42 -3
  54. package/dist/src/components/Typography/Typography.d.ts +1 -1
  55. package/dist/src/components/index.d.ts +1 -0
  56. package/package.json +12 -2
  57. package/src/GlobalExemptions.modules.css +13 -0
  58. package/src/components/Accordion/Accordion.module.css +295 -0
  59. package/src/components/Accordion/Accordion.stories.tsx +149 -21
  60. package/src/components/Accordion/Accordion.tsx +264 -4
  61. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  62. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +76 -19
  63. package/src/components/AssistiveElement/AssistiveElement.tsx +85 -4
  64. package/src/components/Autocomplete/Autocomplete.module.css +325 -0
  65. package/src/components/Autocomplete/Autocomplete.stories.tsx +196 -0
  66. package/src/components/Autocomplete/Autocomplete.tsx +201 -0
  67. package/src/components/Autocomplete/index.ts +1 -0
  68. package/src/components/Avatar/Avatar.module.css +344 -0
  69. package/src/components/Avatar/Avatar.stories.tsx +94 -22
  70. package/src/components/Avatar/Avatar.tsx +110 -5
  71. package/src/components/Badge/Badge.module.css +127 -0
  72. package/src/components/Badge/Badge.stories.tsx +65 -22
  73. package/src/components/Badge/Badge.tsx +70 -5
  74. package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
  75. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
  76. package/src/components/Breadcrumb/Breadcrumb.tsx +62 -5
  77. package/src/components/Button/Button.module.css +113 -20
  78. package/src/components/Button/Button.stories.tsx +3 -0
  79. package/src/components/Button/Button.tsx +10 -3
  80. package/src/components/Card/Card.module.css +118 -0
  81. package/src/components/Card/Card.stories.tsx +117 -19
  82. package/src/components/Card/Card.tsx +179 -4
  83. package/src/components/Checkbox/Checkbox.module.css +232 -0
  84. package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
  85. package/src/components/Checkbox/Checkbox.tsx +146 -4
  86. package/src/components/Checkbox/CheckboxGroup.tsx +117 -0
  87. package/src/components/Checkbox/index.ts +6 -1
  88. package/src/components/Chip/Chip.module.css +236 -0
  89. package/src/components/Chip/Chip.stories.tsx +101 -21
  90. package/src/components/Chip/Chip.tsx +138 -5
  91. package/src/components/DatePicker/DatePicker.module.css +42 -0
  92. package/src/components/DatePicker/DatePicker.tsx +1 -0
  93. package/src/components/Dropdown/Dropdown.module.css +296 -0
  94. package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
  95. package/src/components/Dropdown/Dropdown.tsx +182 -5
  96. package/src/components/FileInput/FileInput.module.css +47 -0
  97. package/src/components/FileInput/FileInput.tsx +1 -0
  98. package/src/components/FileUpload/FileUpload.module.css +40 -0
  99. package/src/components/FileUpload/FileUpload.tsx +1 -0
  100. package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
  101. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +74 -19
  102. package/src/components/FormControlLayout/FormControlLayout.tsx +58 -4
  103. package/src/components/FormControlWrapper/FormControlWrapper.module.css +96 -0
  104. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +122 -19
  105. package/src/components/FormControlWrapper/FormControlWrapper.tsx +145 -6
  106. package/src/components/HoverCard/HoverCard.module.css +91 -0
  107. package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
  108. package/src/components/HoverCard/HoverCard.tsx +150 -4
  109. package/src/components/Label/Label.module.css +136 -0
  110. package/src/components/Label/Label.stories.tsx +98 -17
  111. package/src/components/Label/Label.tsx +88 -4
  112. package/src/components/Link/Link.module.css +8 -0
  113. package/src/components/Menu/Menu.module.css +287 -0
  114. package/src/components/Menu/Menu.stories.tsx +307 -21
  115. package/src/components/Menu/Menu.tsx +318 -4
  116. package/src/components/Modal/Modal.module.css +172 -0
  117. package/src/components/Modal/Modal.stories.tsx +66 -22
  118. package/src/components/Modal/Modal.tsx +216 -3
  119. package/src/components/NumberInput/NumberInput.module.css +281 -0
  120. package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
  121. package/src/components/NumberInput/NumberInput.tsx +148 -5
  122. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  123. package/src/components/Pagination/Pagination.module.css +307 -0
  124. package/src/components/Pagination/Pagination.stories.tsx +42 -21
  125. package/src/components/Pagination/Pagination.tsx +193 -4
  126. package/src/components/Panel/Panel.module.css +206 -0
  127. package/src/components/Panel/Panel.stories.tsx +214 -22
  128. package/src/components/Panel/Panel.tsx +153 -4
  129. package/src/components/Radio/Radio.module.css +220 -0
  130. package/src/components/Radio/Radio.stories.tsx +77 -19
  131. package/src/components/Radio/Radio.tsx +178 -4
  132. package/src/components/Radio/RadioGroup.tsx +111 -0
  133. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  134. package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
  135. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +175 -16
  136. package/src/components/ReadOnlyField/ReadOnlyField.tsx +109 -4
  137. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  138. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  139. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  140. package/src/components/ReadOnlyField/index.ts +1 -0
  141. package/src/components/SegmentedControl/SegmentedControl.module.css +203 -0
  142. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
  143. package/src/components/SegmentedControl/SegmentedControl.tsx +110 -5
  144. package/src/components/Slider/Slider.module.css +542 -0
  145. package/src/components/Slider/Slider.stories.tsx +157 -19
  146. package/src/components/Slider/Slider.tsx +282 -4
  147. package/src/components/Stepper/Stepper.module.css +410 -0
  148. package/src/components/Stepper/Stepper.stories.tsx +132 -19
  149. package/src/components/Stepper/Stepper.tsx +145 -5
  150. package/src/components/Switch/Switch.module.css +238 -0
  151. package/src/components/Switch/Switch.stories.tsx +98 -19
  152. package/src/components/Switch/Switch.tsx +153 -5
  153. package/src/components/Switch/SwitchGroup.tsx +111 -0
  154. package/src/components/Tabs/Tabs.module.css +422 -0
  155. package/src/components/Tabs/Tabs.stories.tsx +138 -19
  156. package/src/components/Tabs/Tabs.tsx +103 -5
  157. package/src/components/TextArea/TextArea.module.css +160 -0
  158. package/src/components/TextArea/TextArea.stories.tsx +80 -21
  159. package/src/components/TextArea/TextArea.tsx +156 -5
  160. package/src/components/TextField/TextField.module.css +266 -0
  161. package/src/components/TextField/TextField.stories.tsx +168 -15
  162. package/src/components/TextField/TextField.tsx +171 -5
  163. package/src/components/TimePicker/TimePicker.module.css +41 -0
  164. package/src/components/TimePicker/TimePicker.tsx +1 -0
  165. package/src/components/Timeline/Timeline.module.css +367 -0
  166. package/src/components/Timeline/Timeline.stories.tsx +114 -21
  167. package/src/components/Timeline/Timeline.tsx +80 -4
  168. package/src/components/Timeline/TimelineItem.tsx +101 -0
  169. package/src/components/Toast/Toast.module.css +170 -0
  170. package/src/components/Toast/Toast.stories.tsx +54 -22
  171. package/src/components/Toast/Toast.tsx +90 -4
  172. package/src/components/Tooltip/Tooltip.module.css +90 -0
  173. package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
  174. package/src/components/Tooltip/Tooltip.tsx +114 -4
  175. package/src/components/TransferList/TransferList.module.css +38 -0
  176. package/src/components/TransferList/TransferList.tsx +1 -0
  177. package/src/components/index.ts +1 -0
@@ -1,7 +1,105 @@
1
- import React from "react";
1
+ import { forwardRef } from "react";
2
+ import {
3
+ Tabs as MuiTabs,
4
+ type TabsProps as MuiTabsProps,
5
+ type ListProps as MuiTabsListProps,
6
+ type TabsProps as MuiTabsTabProps,
7
+ } from "@mui/material";
8
+ import {
9
+ filterStylingProps,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import styles from "./Tabs.module.css";
2
13
 
3
- export type TabsProps = React.HTMLAttributes<HTMLDivElement>;
14
+ export interface RecursicaTabsProps
15
+ extends Omit<MuiTabsProps, "variant" | "classNames" | "color" | "radius"> {
16
+ variant?: "default" | "outline" | "pills";
17
+ }
4
18
 
5
- export const Tabs: React.FC<TabsProps> = (props) => {
6
- return <div {...props}>Tabs</div>;
7
- };
19
+ export type TabsProps = RecursicaOverStyled<RecursicaTabsProps>;
20
+
21
+ const _Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(props, ref) {
22
+ const {
23
+ variant = "default",
24
+ orientation = "horizontal",
25
+ overStyled = false,
26
+ className,
27
+ ...rest
28
+ } = props;
29
+
30
+ const sanitizedProps = filterStylingProps(rest, overStyled);
31
+
32
+ return (
33
+ <MuiTabs
34
+ ref={ref}
35
+ variant={variant}
36
+ orientation={orientation}
37
+ className={`${styles.root} ${className || ""}`}
38
+ data-variant={variant}
39
+ data-orientation={orientation}
40
+ classes={{
41
+ list: styles.list,
42
+ tab: styles.tab,
43
+ panel: styles.panel,
44
+ }}
45
+ {...(sanitizedProps as MuiTabsProps)}
46
+ />
47
+ );
48
+ });
49
+
50
+ _Tabs.displayName = "Tabs";
51
+
52
+ export type TabsListProps = RecursicaOverStyled<MuiTabsListProps>;
53
+
54
+ const _TabsList = forwardRef<HTMLDivElement, TabsListProps>(
55
+ function TabsList(props, ref) {
56
+ const { overStyled = false, ...rest } = props;
57
+ return (
58
+ <div
59
+ ref={ref}
60
+ {...(filterStylingProps(rest, overStyled) as MuiTabsListProps)}
61
+ />
62
+ );
63
+ },
64
+ );
65
+ _TabsList.displayName = "Tabs.List";
66
+
67
+ export type TabsTabProps = RecursicaOverStyled<MuiTabsTabProps>;
68
+
69
+ const _TabsTab = forwardRef<HTMLButtonElement, TabsTabProps>(
70
+ function TabsTab(props, ref) {
71
+ const { overStyled = false, ...rest } = props;
72
+ return (
73
+ <div
74
+ ref={ref}
75
+ {...(filterStylingProps(rest, overStyled) as MuiTabsTabProps)}
76
+ />
77
+ );
78
+ },
79
+ );
80
+ _TabsTab.displayName = "Tabs.Tab";
81
+
82
+ export type TabsPanelProps = RecursicaOverStyled<MuiTabsPanelProps>;
83
+
84
+ const _TabsPanel = forwardRef<HTMLDivElement, TabsPanelProps>(
85
+ function TabsPanel(props, ref) {
86
+ const { overStyled = false, ...rest } = props;
87
+ return (
88
+ <div
89
+ ref={ref}
90
+ {...(filterStylingProps(rest, overStyled) as MuiTabsPanelProps)}
91
+ />
92
+ );
93
+ },
94
+ );
95
+ _TabsPanel.displayName = "Tabs.Panel";
96
+
97
+ export const Tabs: typeof _Tabs & {
98
+ List: typeof _TabsList;
99
+ Tab: typeof _TabsTab;
100
+ Panel: typeof _TabsPanel;
101
+ } = Object.assign(_Tabs, {
102
+ List: _TabsList,
103
+ Tab: _TabsTab,
104
+ Panel: _TabsPanel,
105
+ });
@@ -0,0 +1,160 @@
1
+ /* EXEMPTIONS:
2
+ - state-specific border-size variables are ignored because a uniform 1px border is applied globally to prevent
3
+ unexpected layout shift or flickering during focus, disabled, or error state transitions. */
4
+ /* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_default_properties_border-size */
5
+ /* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_disabled_properties_border-size */
6
+ /* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_error_properties_border-size */
7
+ /* recursica-ignore: --recursica_ui-kit_components_textarea_variants_states_focus_properties_border-size */
8
+
9
+ /* LAYOUT SPACING OVERRIDES:
10
+ - Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens. */
11
+ .layoutOverride {
12
+ --form-control-margin-bottom: var(
13
+ --recursica_ui-kit_components_textarea_variants_layouts_stacked_properties_top-bottom-margin
14
+ );
15
+ }
16
+
17
+ .layoutOverride[data-form-layout="side-by-side"] {
18
+ --form-control-margin-bottom: var(
19
+ --recursica_ui-kit_components_textarea_variants_layouts_side-by-side_properties_top-bottom-margin
20
+ );
21
+ }
22
+
23
+ /* HARDCODED VALUES:
24
+ - border-width: 1px. Native geometric boundary for the input box.
25
+ - border-style: solid. Native structural rendering rule.
26
+ - outline: none. Bypassing browser focus rings to rely strictly on Recursica focus states natively.
27
+ - flex/layout: display: flex on the root wrapper safely encapsulating internal section rendering.
28
+ */
29
+
30
+ .root {
31
+ display: flex;
32
+ position: relative;
33
+ width: 100%;
34
+ }
35
+
36
+ .input {
37
+ /* Structural Overrides */
38
+ width: 100%;
39
+ box-sizing: border-box;
40
+ margin: 0;
41
+
42
+ /* Sizing driven by rows token */
43
+ min-height: calc(
44
+ var(--recursica_ui-kit_components_textarea_properties_rows) *
45
+ var(--recursica_ui-kit_components_textarea_properties_text_line-height) +
46
+ 2 *
47
+ var(--recursica_ui-kit_components_textarea_properties_vertical-padding) +
48
+ 2px
49
+ );
50
+
51
+ /* Box Geometry */
52
+ padding-top: var(
53
+ --recursica_ui-kit_components_textarea_properties_vertical-padding
54
+ );
55
+ padding-bottom: var(
56
+ --recursica_ui-kit_components_textarea_properties_vertical-padding
57
+ );
58
+ padding-left: var(
59
+ --recursica_ui-kit_components_textarea_properties_horizontal-padding
60
+ );
61
+ padding-right: var(
62
+ --recursica_ui-kit_components_textarea_properties_horizontal-padding
63
+ );
64
+ border-radius: var(
65
+ --recursica_ui-kit_components_textarea_properties_border-radius
66
+ );
67
+ border-width: 1px;
68
+ border-style: solid;
69
+
70
+ /* Strict Typography Unification */
71
+ font-family: var(
72
+ --recursica_ui-kit_components_textarea_properties_text_font-family
73
+ );
74
+ font-size: var(
75
+ --recursica_ui-kit_components_textarea_properties_text_font-size
76
+ );
77
+ font-style: var(
78
+ --recursica_ui-kit_components_textarea_properties_text_font-style
79
+ );
80
+ font-weight: var(
81
+ --recursica_ui-kit_components_textarea_properties_text_font-weight
82
+ );
83
+ letter-spacing: var(
84
+ --recursica_ui-kit_components_textarea_properties_text_letter-spacing
85
+ );
86
+ line-height: var(
87
+ --recursica_ui-kit_components_textarea_properties_text_line-height
88
+ );
89
+ text-decoration: var(
90
+ --recursica_ui-kit_components_textarea_properties_text_text-decoration
91
+ );
92
+ text-transform: var(
93
+ --recursica_ui-kit_components_textarea_properties_text_text-transform
94
+ );
95
+
96
+ /* Base State Default Execution */
97
+ background-color: var(
98
+ --recursica_ui-kit_components_textarea_variants_states_default_properties_colors_background
99
+ );
100
+ border-color: var(
101
+ --recursica_ui-kit_components_textarea_variants_states_default_properties_colors_border-color
102
+ );
103
+ color: var(
104
+ --recursica_ui-kit_components_textarea_variants_states_default_properties_colors_text
105
+ );
106
+
107
+ outline: none;
108
+ }
109
+
110
+ .input::placeholder {
111
+ opacity: var(
112
+ --recursica_ui-kit_components_textarea_properties_placeholder-opacity
113
+ );
114
+ color: inherit;
115
+ }
116
+
117
+ /* -------------------------------------
118
+ STATE CASCADE ARCHITECTURE
119
+ -------------------------------------- */
120
+
121
+ /* Focus State Mapping (Triggered internally via browser focus rules) */
122
+ .input:focus-within,
123
+ .input:focus {
124
+ border-color: var(
125
+ --recursica_ui-kit_components_textarea_variants_states_focus_properties_colors_border-color
126
+ );
127
+ background-color: var(
128
+ --recursica_ui-kit_components_textarea_variants_states_focus_properties_colors_background
129
+ );
130
+ color: var(
131
+ --recursica_ui-kit_components_textarea_variants_states_focus_properties_colors_text
132
+ );
133
+ }
134
+
135
+ /* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
136
+ .root[data-error] .input {
137
+ border-color: var(
138
+ --recursica_ui-kit_components_textarea_variants_states_error_properties_colors_border-color
139
+ ) !important;
140
+ background-color: var(
141
+ --recursica_ui-kit_components_textarea_variants_states_error_properties_colors_background
142
+ ) !important;
143
+ color: var(
144
+ --recursica_ui-kit_components_textarea_variants_states_error_properties_colors_text
145
+ ) !important;
146
+ }
147
+
148
+ /* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
149
+ .root[data-disabled] .input {
150
+ border-color: var(
151
+ --recursica_ui-kit_components_textarea_variants_states_disabled_properties_colors_border-color
152
+ ) !important;
153
+ background-color: var(
154
+ --recursica_ui-kit_components_textarea_variants_states_disabled_properties_colors_background
155
+ ) !important;
156
+ color: var(
157
+ --recursica_ui-kit_components_textarea_variants_states_disabled_properties_colors_text
158
+ ) !important;
159
+ cursor: not-allowed;
160
+ }
@@ -1,35 +1,94 @@
1
+ import React from "react";
1
2
  import type { Meta, StoryObj } from "@storybook/react";
2
3
  import { TextArea } from "./TextArea";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
4
5
 
5
- const meta: Meta<typeof TextArea> = {
6
- title: "UI-Kit/🚧 TextArea",
6
+ type TextAreaStoryProps = React.ComponentProps<typeof TextArea>;
7
+
8
+ const meta: Meta<TextAreaStoryProps> = {
9
+ title: "UI-Kit/TextArea",
7
10
  component: TextArea,
8
11
  tags: ["autodocs"],
9
12
  parameters: {
10
- controls: {
11
- include: [
12
- "layer",
13
- "withLayer",
14
- "children",
15
- "component",
16
- "variant",
17
- "size",
18
- "icon",
19
- "disabled",
20
- "href",
21
- "onClick",
22
- "onChange",
23
- "value",
24
- "checked",
25
- ],
13
+ docs: {
14
+ description: {
15
+ component:
16
+ "TextArea provides a multi-line input field, mapping layout explicitly over the standardized FormControlWrapper.",
17
+ },
18
+ },
19
+ },
20
+ args: {
21
+ label: "Description",
22
+ assistiveText: "Enter your full description here.",
23
+ disabled: false,
24
+ required: false,
25
+ readOnly: false,
26
+ autosize: false,
27
+ },
28
+ argTypes: {
29
+ disabled: {
30
+ control: "boolean",
31
+ },
32
+ ...formControlArgTypes,
33
+ readOnly: {
34
+ control: "boolean",
35
+ },
36
+ autosize: {
37
+ control: "boolean",
38
+ },
39
+ minRows: {
40
+ control: "number",
41
+ },
42
+ maxRows: {
43
+ control: "number",
44
+ },
45
+ value: {
46
+ control: "text",
47
+ },
48
+ placeholder: {
49
+ control: "text",
26
50
  },
27
51
  },
28
52
  };
29
53
 
30
54
  export default meta;
31
- type Story = StoryObj<typeof TextArea>;
55
+
56
+ type Story = StoryObj<TextAreaStoryProps>;
32
57
 
33
58
  export const Default: Story = {
34
- render: () => <ComingSoon componentName="TextArea" />,
59
+ args: {
60
+ placeholder: "Type something long...",
61
+ },
62
+ };
63
+
64
+ export const Autosize: Story = {
65
+ args: {
66
+ label: "Auto-sizing TextArea",
67
+ autosize: true,
68
+ minRows: 2,
69
+ maxRows: 6,
70
+ placeholder: "Type multiple lines here. Watch it grow!",
71
+ },
72
+ };
73
+
74
+ export const StaticError: Story = {
75
+ args: {
76
+ error: "This field requires a detailed explanation.",
77
+ value: "Some bad input.",
78
+ },
79
+ };
80
+
81
+ export const StaticDisabled: Story = {
82
+ args: {
83
+ disabled: true,
84
+ value: "This content is locked.",
85
+ },
86
+ };
87
+
88
+ export const StaticReadOnly: Story = {
89
+ args: {
90
+ label: "Read Only View",
91
+ readOnly: true,
92
+ value: "This text is safely frozen in read-only form.",
93
+ },
35
94
  };
@@ -1,7 +1,158 @@
1
- import React from "react";
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ TextField as MuiTextarea,
4
+ type TextFieldProps as MuiTextareaProps,
5
+ } from "@mui/material";
6
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
7
+ import { TextField } from "@mui/material";
8
+ import {
9
+ filterStylingProps,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
13
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
14
+ import styles from "./TextArea.module.css";
2
15
 
3
- export type TextAreaProps = React.HTMLAttributes<HTMLDivElement>;
16
+ export interface RecursicaTextAreaProps
17
+ extends Omit<
18
+ MuiTextareaProps,
19
+ "size" | "variant" | "radius" | "wrapperProps"
20
+ >,
21
+ Pick<
22
+ RecursicaFormControlWrapperProps,
23
+ | "assistiveText"
24
+ | "assistiveWithIcon"
25
+ | "formLayout"
26
+ | "labelSize"
27
+ | "labelAlignment"
28
+ | "labelOptionalText"
29
+ | "labelWithEditIcon"
30
+ | "onLabelEditClick"
31
+ >,
32
+ ReadOnlyControlProps {
33
+ /** Maximum rows for autosize textarea to grow */
34
+ maxRows?: number;
35
+ /** Minimum rows of autosize textarea */
36
+ minRows?: number;
37
+ /** If set, enables textarea height growing with its content */
38
+ autosize?: boolean;
39
+ }
4
40
 
5
- export const TextArea: React.FC<TextAreaProps> = (props) => {
6
- return <div {...props}>TextArea</div>;
7
- };
41
+ export type TextAreaProps = RecursicaOverStyled<RecursicaTextAreaProps>;
42
+
43
+ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
44
+ function TextArea(props, ref) {
45
+ const {
46
+ overStyled = false,
47
+ formLayout = "stacked",
48
+
49
+ // Label & Wrapper Maps
50
+ labelSize,
51
+ labelAlignment,
52
+ labelOptionalText,
53
+ labelWithEditIcon,
54
+ onLabelEditClick,
55
+
56
+ label,
57
+ assistiveText,
58
+ assistiveWithIcon,
59
+ error,
60
+ required,
61
+ withAsterisk,
62
+ id,
63
+ className,
64
+ style,
65
+ disabled,
66
+ readOnly,
67
+ readOnlyComponent,
68
+ emptyValueComponent,
69
+ value,
70
+ defaultValue,
71
+ ...rest
72
+ } = props;
73
+ const sanitizedProps = filterStylingProps(rest, overStyled);
74
+ const restRecord = sanitizedProps as Record<string, unknown>;
75
+
76
+ // Delete prohibited sizing hooks from bypassing variables natively
77
+ delete restRecord["size"];
78
+ delete restRecord["variant"];
79
+ delete restRecord["radius"];
80
+
81
+ // Securely map core native blocks down ensuring nested CSS modules map precisely
82
+ const mergedClassNames: Partial<Record<string, string>> = {
83
+ wrapper: styles.root, // The nested Input internal relative wrapper bounding box
84
+ input: styles.input,
85
+ };
86
+
87
+ const classNamesProp = restRecord.classNames;
88
+ if (
89
+ classNamesProp &&
90
+ typeof classNamesProp === "object" &&
91
+ !Array.isArray(classNamesProp)
92
+ ) {
93
+ const o = classNamesProp as Partial<Record<string, string>>;
94
+ mergedClassNames.wrapper = o.wrapper
95
+ ? `${styles.root} ${o.wrapper}`
96
+ : styles.root;
97
+ mergedClassNames.input = o.input
98
+ ? `${styles.input} ${o.input}`
99
+ : styles.input;
100
+ }
101
+
102
+ const wrapperClass = className
103
+ ? `${styles.layoutOverride} ${className}`
104
+ : styles.layoutOverride;
105
+
106
+ return (
107
+ <WithReadOnlyWrapper
108
+ className={wrapperClass}
109
+ style={style as React.CSSProperties}
110
+ controlMaxWidth="var(--recursica_ui-kit_components_textarea_properties_max-width)"
111
+ controlMinWidth="var(--recursica_ui-kit_components_textarea_properties_min-width)"
112
+ overStyled={overStyled as true}
113
+ formLayout={formLayout}
114
+ labelSize={labelSize}
115
+ labelAlignment={labelAlignment}
116
+ labelOptionalText={labelOptionalText}
117
+ labelWithEditIcon={labelWithEditIcon}
118
+ onLabelEditClick={onLabelEditClick}
119
+ label={label}
120
+ assistiveText={assistiveText}
121
+ assistiveWithIcon={assistiveWithIcon}
122
+ error={error}
123
+ required={required}
124
+ withAsterisk={withAsterisk}
125
+ id={id}
126
+ readOnly={readOnly}
127
+ readOnlyComponent={readOnlyComponent}
128
+ emptyValueComponent={emptyValueComponent}
129
+ readOnlyType="text"
130
+ readOnlyValue={value !== undefined ? value : defaultValue}
131
+ readOnlyNativeProps={props}
132
+ activeComponent={
133
+ /* Naked Input execution safely decoupled from Mui's macro Input.Wrapper DOM hooks */
134
+ <MuiTextarea
135
+ multiline
136
+ ref={ref}
137
+ classes={mergedClassNames}
138
+ disabled={disabled}
139
+ value={value}
140
+ defaultValue={defaultValue}
141
+ label={undefined}
142
+ description={undefined}
143
+ error={undefined}
144
+ required={undefined}
145
+ withAsterisk={undefined}
146
+ wrapperProps={{
147
+ "data-disabled": disabled ? "true" : undefined,
148
+ "data-error": error ? "true" : undefined,
149
+ }}
150
+ {...(sanitizedProps as unknown as MuiTextareaProps)}
151
+ />
152
+ }
153
+ />
154
+ );
155
+ },
156
+ );
157
+
158
+ TextArea.displayName = "TextArea";