@recursica/mantine-adapter 0.10.0 → 0.12.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 (79) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +6 -28
  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 +1650 -1344
  7. package/dist/mantine-adapter.js.map +1 -1
  8. package/dist/src/components/Checkbox/Checkbox.d.ts +3 -1
  9. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +21 -0
  10. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +2 -0
  11. package/dist/src/components/Label/Label.d.ts +1 -3
  12. package/dist/src/components/Menu/Menu.d.ts +85 -3
  13. package/dist/src/components/Radio/Radio.d.ts +3 -1
  14. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  15. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +6 -6
  16. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  17. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +7 -1
  18. package/dist/src/components/ReadOnlyField/index.d.ts +2 -0
  19. package/dist/src/components/Switch/Switch.d.ts +3 -1
  20. package/dist/src/components/index.d.ts +1 -0
  21. package/dist/src/utils/RequireAccessibleLabel.d.ts +18 -0
  22. package/package.json +1 -1
  23. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +6 -4
  24. package/src/components/Avatar/Avatar.stories.tsx +10 -5
  25. package/src/components/Badge/Badge.stories.tsx +2 -1
  26. package/src/components/Button/Button.stories.tsx +2 -4
  27. package/src/components/Checkbox/Checkbox.module.css +1 -1
  28. package/src/components/Checkbox/Checkbox.stories.tsx +24 -3
  29. package/src/components/Checkbox/Checkbox.tsx +72 -15
  30. package/src/components/Checkbox/CheckboxGroup.stories.tsx +26 -25
  31. package/src/components/Checkbox/CheckboxGroup.tsx +38 -58
  32. package/src/components/Container/Container.stories.tsx +6 -3
  33. package/src/components/DatePicker/DatePicker.stories.tsx +1 -5
  34. package/src/components/Dropdown/Dropdown.stories.tsx +0 -3
  35. package/src/components/Dropdown/Dropdown.tsx +6 -5
  36. package/src/components/FileInput/FileInput.stories.tsx +1 -5
  37. package/src/components/FileUpload/FileUpload.stories.tsx +1 -5
  38. package/src/components/Flex/Flex.stories.tsx +6 -3
  39. package/src/components/FormControlLayout/FormControlLayout.module.css +80 -0
  40. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +82 -0
  41. package/src/components/FormControlLayout/FormControlLayout.tsx +78 -0
  42. package/src/components/FormControlWrapper/FormControlWrapper.module.css +3 -41
  43. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +18 -5
  44. package/src/components/FormControlWrapper/FormControlWrapper.tsx +28 -41
  45. package/src/components/Group/Group.stories.tsx +6 -3
  46. package/src/components/Label/Label.module.css +0 -37
  47. package/src/components/Label/Label.stories.tsx +8 -9
  48. package/src/components/Label/Label.tsx +2 -7
  49. package/src/components/Loader/Loader.stories.tsx +10 -5
  50. package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +78 -0
  51. package/src/components/Menu/Menu.module.css +244 -0
  52. package/src/components/Menu/Menu.stories.tsx +309 -5
  53. package/src/components/Menu/Menu.tsx +317 -4
  54. package/src/components/NumberInput/NumberInput.stories.tsx +1 -5
  55. package/src/components/Radio/Radio.stories.tsx +22 -8
  56. package/src/components/Radio/Radio.tsx +134 -75
  57. package/src/components/Radio/RadioGroup.stories.tsx +26 -7
  58. package/src/components/Radio/RadioGroup.tsx +37 -57
  59. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  60. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +43 -0
  61. package/src/components/ReadOnlyField/ReadOnlyField.tsx +30 -3
  62. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  63. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +3 -1
  64. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +10 -2
  65. package/src/components/ReadOnlyField/index.ts +2 -0
  66. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +1 -5
  67. package/src/components/Slider/Slider.stories.tsx +1 -5
  68. package/src/components/Stack/Stack.stories.tsx +6 -3
  69. package/src/components/Switch/Switch.module.css +2 -10
  70. package/src/components/Switch/Switch.stories.tsx +42 -27
  71. package/src/components/Switch/Switch.tsx +138 -89
  72. package/src/components/Switch/SwitchGroup.stories.tsx +28 -8
  73. package/src/components/Switch/SwitchGroup.tsx +37 -57
  74. package/src/components/TextArea/TextArea.stories.tsx +0 -3
  75. package/src/components/TextArea/TextArea.tsx +6 -5
  76. package/src/components/TextField/TextField.tsx +6 -5
  77. package/src/components/TimePicker/TimePicker.stories.tsx +1 -5
  78. package/src/components/index.ts +1 -0
  79. package/src/utils/RequireAccessibleLabel.ts +12 -0
@@ -11,15 +11,23 @@ import {
11
11
  filterStylingProps,
12
12
  type RecursicaOverStyled,
13
13
  } from "../../utils/filterStylingProps";
14
+ import { type RequireAccessibleLabel } from "../../utils/RequireAccessibleLabel";
15
+ import {
16
+ FormControlLayout,
17
+ type FormControlLayoutProps,
18
+ } from "../FormControlLayout/FormControlLayout";
14
19
  import styles from "./Switch.module.css";
15
20
 
16
21
  import { SwitchGroup } from "./SwitchGroup";
17
22
 
18
- export type RecursicaSwitchProps = Omit<
19
- MantineSwitchProps,
20
- "size" | "color" | "radius" | "variant"
21
- > &
22
- ReadOnlyControlProps;
23
+ export type RecursicaSwitchProps = RequireAccessibleLabel<
24
+ Omit<MantineSwitchProps, "size" | "color" | "radius" | "variant"> &
25
+ ReadOnlyControlProps &
26
+ Pick<
27
+ FormControlLayoutProps,
28
+ "formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
29
+ >
30
+ >;
23
31
 
24
32
  export type SwitchProps = RecursicaOverStyled<RecursicaSwitchProps>;
25
33
 
@@ -29,91 +37,132 @@ type SwitchComponent = React.ForwardRefExoticComponent<
29
37
  Group: typeof SwitchGroup;
30
38
  };
31
39
 
32
- export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
33
- {
34
- overStyled = false,
35
- readOnly,
36
- readOnlyComponent,
37
- disabled,
38
- thumbIcon,
39
- ...rest
40
+ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
41
+ function Switch(props, ref) {
42
+ const {
43
+ overStyled = false,
44
+ readOnly,
45
+ readOnlyComponent,
46
+ disabled,
47
+ thumbIcon,
48
+ formLayout,
49
+ labelSize,
50
+ controlMaxWidth,
51
+ controlMinWidth,
52
+ ...rest
53
+ } = props;
54
+ const sanitizedProps = filterStylingProps(rest, overStyled);
55
+ const restRecord = sanitizedProps as Record<string, unknown>;
56
+
57
+ // Actively delete dimension bindings that bypass the abstraction
58
+ delete restRecord["size"];
59
+ delete restRecord["color"];
60
+ delete restRecord["radius"];
61
+ delete restRecord["variant"];
62
+
63
+ const mergedClassNames: Partial<Record<string, string>> = {
64
+ root: styles.root,
65
+ body: styles.body,
66
+ track: styles.track,
67
+ thumb: styles.thumb,
68
+ trackLabel: styles.trackLabel,
69
+ labelWrapper: styles.labelWrapper,
70
+ label: styles.label,
71
+ };
72
+
73
+ const classNamesProp = restRecord.classNames;
74
+ if (
75
+ classNamesProp &&
76
+ typeof classNamesProp === "object" &&
77
+ !Array.isArray(classNamesProp)
78
+ ) {
79
+ const o = classNamesProp as Partial<Record<string, string>>;
80
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
81
+ mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
82
+ mergedClassNames.track = o.track
83
+ ? `${styles.track} ${o.track}`
84
+ : styles.track;
85
+ mergedClassNames.thumb = o.thumb
86
+ ? `${styles.thumb} ${o.thumb}`
87
+ : styles.thumb;
88
+ mergedClassNames.trackLabel = o.trackLabel
89
+ ? `${styles.trackLabel} ${o.trackLabel}`
90
+ : styles.trackLabel;
91
+ mergedClassNames.labelWrapper = o.labelWrapper
92
+ ? `${styles.labelWrapper} ${o.labelWrapper}`
93
+ : styles.labelWrapper;
94
+ mergedClassNames.label = o.label
95
+ ? `${styles.label} ${o.label}`
96
+ : styles.label;
97
+ }
98
+
99
+ const classNameProp = restRecord.className as string | undefined;
100
+ const finalClass = classNameProp
101
+ ? `${styles.root} ${classNameProp}`
102
+ : styles.root;
103
+
104
+ if (readOnly && !!readOnlyComponent) {
105
+ const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
106
+ const ReadOnlyComp = readOnlyComponent;
107
+ const roNode = (
108
+ <ReadOnlyComp
109
+ {...props}
110
+ checked={isChecked}
111
+ label={restRecord.label as React.ReactNode}
112
+ />
113
+ );
114
+
115
+ if (formLayout) {
116
+ return (
117
+ <FormControlLayout
118
+ formLayout={formLayout}
119
+ labelSize={labelSize}
120
+ controlMaxWidth={controlMaxWidth}
121
+ controlMinWidth={controlMinWidth}
122
+ >
123
+ {roNode}
124
+ </FormControlLayout>
125
+ );
126
+ }
127
+
128
+ return <>{roNode}</>;
129
+ }
130
+
131
+ const FinalThumbIcon = (
132
+ <div className={styles.thumbIconWrapper}>
133
+ <CheckIcon className={styles.checkIcon} />
134
+ <CloseIcon className={styles.closeIcon} />
135
+ </div>
136
+ );
137
+
138
+ // We omit Mantine's sizing/coloring so we rely strictly on variables from Switch.module.css
139
+ const switchNode = (
140
+ <MantineSwitch
141
+ ref={ref}
142
+ className={finalClass}
143
+ classNames={mergedClassNames}
144
+ disabled={readOnly || disabled}
145
+ thumbIcon={thumbIcon ?? FinalThumbIcon}
146
+ {...(sanitizedProps as unknown as MantineSwitchProps)}
147
+ />
148
+ );
149
+
150
+ if (formLayout) {
151
+ return (
152
+ <FormControlLayout
153
+ formLayout={formLayout}
154
+ labelSize={labelSize}
155
+ controlMaxWidth={controlMaxWidth}
156
+ controlMinWidth={controlMinWidth}
157
+ >
158
+ {switchNode}
159
+ </FormControlLayout>
160
+ );
161
+ }
162
+
163
+ return switchNode;
40
164
  },
41
- ref,
42
- ) {
43
- const sanitizedProps = filterStylingProps(rest, overStyled);
44
- const restRecord = sanitizedProps as Record<string, unknown>;
45
-
46
- // Actively delete dimension bindings that bypass the abstraction
47
- delete restRecord["size"];
48
- delete restRecord["color"];
49
- delete restRecord["radius"];
50
- delete restRecord["variant"];
51
-
52
- if (readOnly && readOnlyComponent) {
53
- // Safely fallback explicitly returning mapped elements natively without macro wrappers
54
- return <>{readOnlyComponent}</>;
55
- }
56
-
57
- const mergedClassNames: Partial<Record<string, string>> = {
58
- root: styles.root,
59
- body: styles.body,
60
- track: styles.track,
61
- thumb: styles.thumb,
62
- trackLabel: styles.trackLabel,
63
- labelWrapper: styles.labelWrapper,
64
- label: styles.label,
65
- };
66
-
67
- const classNamesProp = restRecord.classNames;
68
- if (
69
- classNamesProp &&
70
- typeof classNamesProp === "object" &&
71
- !Array.isArray(classNamesProp)
72
- ) {
73
- const o = classNamesProp as Partial<Record<string, string>>;
74
- mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
75
- mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
76
- mergedClassNames.track = o.track
77
- ? `${styles.track} ${o.track}`
78
- : styles.track;
79
- mergedClassNames.thumb = o.thumb
80
- ? `${styles.thumb} ${o.thumb}`
81
- : styles.thumb;
82
- mergedClassNames.trackLabel = o.trackLabel
83
- ? `${styles.trackLabel} ${o.trackLabel}`
84
- : styles.trackLabel;
85
- mergedClassNames.labelWrapper = o.labelWrapper
86
- ? `${styles.labelWrapper} ${o.labelWrapper}`
87
- : styles.labelWrapper;
88
- mergedClassNames.label = o.label
89
- ? `${styles.label} ${o.label}`
90
- : styles.label;
91
- }
92
-
93
- const classNameProp = restRecord.className as string | undefined;
94
- const finalClass = classNameProp
95
- ? `${styles.root} ${classNameProp}`
96
- : styles.root;
97
-
98
- const FinalThumbIcon = (
99
- <div className={styles.thumbIconWrapper}>
100
- <CheckIcon className={styles.checkIcon} />
101
- <CloseIcon className={styles.closeIcon} />
102
- </div>
103
- );
104
-
105
- // We omit Mantine's sizing/coloring so we rely strictly on variables from Switch.module.css
106
- return (
107
- <MantineSwitch
108
- ref={ref}
109
- className={finalClass}
110
- classNames={mergedClassNames}
111
- disabled={readOnly || disabled}
112
- thumbIcon={thumbIcon ?? FinalThumbIcon}
113
- {...(sanitizedProps as unknown as MantineSwitchProps)}
114
- />
115
- );
116
- }) as SwitchComponent;
165
+ ) as SwitchComponent;
117
166
 
118
167
  Switch.displayName = "Switch";
119
168
  Switch.Group = SwitchGroup;
@@ -39,6 +39,23 @@ export default meta;
39
39
  type Story = StoryObj<typeof SwitchGroup>;
40
40
 
41
41
  export const Default: Story = {
42
+ args: {
43
+ formLayout: "stacked",
44
+ label: "Standard Group",
45
+ },
46
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
47
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
48
+ const [value, setValue] = useState<string[]>([]);
49
+ return (
50
+ <SwitchGroup {...args} value={value} onChange={setValue}>
51
+ <Switch value="1" label="Option 1" />
52
+ <Switch value="2" label="Option 2" />
53
+ </SwitchGroup>
54
+ );
55
+ },
56
+ };
57
+
58
+ export const StackedLayout: Story = {
42
59
  args: {
43
60
  formLayout: "stacked",
44
61
  label: "Notification Settings",
@@ -47,7 +64,8 @@ export const Default: Story = {
47
64
  error: "",
48
65
  required: true,
49
66
  },
50
- render: function DefaultRender(args) {
67
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
68
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
51
69
  const [value, setValue] = useState<string[]>(["email"]);
52
70
  return (
53
71
  <SwitchGroup {...args} value={value} onChange={setValue}>
@@ -61,12 +79,13 @@ export const Default: Story = {
61
79
 
62
80
  export const SideBySideLayout: Story = {
63
81
  args: {
64
- ...Default.args,
82
+ ...StackedLayout.args,
65
83
  formLayout: "side-by-side",
66
84
  labelSize: "default",
67
85
  labelAlignment: "left",
68
86
  },
69
- render: function SideBySideRender(args) {
87
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
88
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
70
89
  const [value, setValue] = useState<string[]>([]);
71
90
  return (
72
91
  <SwitchGroup {...args} value={value} onChange={setValue}>
@@ -83,7 +102,8 @@ export const SolitaryFormControl: Story = {
83
102
  label: "Enable Backups",
84
103
  description: "Automatically back up your data nightly.",
85
104
  },
86
- render: function SolitaryRender(args) {
105
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
106
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
87
107
  const [value, setValue] = useState<string[]>(["auto"]);
88
108
  return (
89
109
  <SwitchGroup {...args} value={value} onChange={setValue}>
@@ -93,13 +113,13 @@ export const SolitaryFormControl: Story = {
93
113
  },
94
114
  };
95
115
 
96
- export const GroupReadOnly: Story = {
116
+ export const ReadOnly: Story = {
97
117
  args: {
98
- ...Default.args,
118
+ ...StackedLayout.args,
99
119
  readOnly: true,
100
- readOnlyComponent: <span>2 Notifications Enabled</span>,
101
120
  },
102
- render: function ReadOnlyRender(args) {
121
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
122
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
103
123
  const [value, setValue] = useState<string[]>(["email", "sms"]);
104
124
  return (
105
125
  <SwitchGroup {...args} value={value} onChange={setValue}>
@@ -9,10 +9,8 @@ import {
9
9
  filterStylingProps,
10
10
  type RecursicaOverStyled,
11
11
  } from "../../utils/filterStylingProps";
12
- import {
13
- FormControlWrapper,
14
- type RecursicaFormControlWrapperProps,
15
- } from "../FormControlWrapper/FormControlWrapper";
12
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
13
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
16
14
  import styles from "./Switch.module.css";
17
15
 
18
16
  export interface RecursicaSwitchGroupProps
@@ -26,8 +24,8 @@ export interface RecursicaSwitchGroupProps
26
24
  export type SwitchGroupProps = RecursicaOverStyled<RecursicaSwitchGroupProps>;
27
25
 
28
26
  export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
29
- function SwitchGroup(
30
- {
27
+ function SwitchGroup(props, ref) {
28
+ const {
31
29
  overStyled = false,
32
30
  formLayout = "stacked",
33
31
 
@@ -52,47 +50,19 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
52
50
  children,
53
51
  readOnly,
54
52
  readOnlyComponent,
53
+ emptyValueComponent,
54
+ value,
55
+ defaultValue,
55
56
  ...rest
56
- },
57
- ref,
58
- ) {
57
+ } = props;
59
58
  const sanitizedProps = filterStylingProps(rest, overStyled);
60
59
  const restRecord = sanitizedProps as Record<string, unknown>;
61
60
 
62
61
  // Delete prohibited sizing hooks from bypassing the variables
63
62
  delete restRecord["size"];
64
63
 
65
- if (readOnly && readOnlyComponent) {
66
- return (
67
- <FormControlWrapper
68
- className={className}
69
- style={style as React.CSSProperties}
70
- controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
71
- controlMinWidth={undefined}
72
- overStyled={overStyled as true}
73
- labelElement="div"
74
- formLayout={formLayout}
75
- labelSize={labelSize}
76
- labelAlignment={labelAlignment}
77
- labelOptionalText={labelOptionalText}
78
- labelWithEditIcon={labelWithEditIcon}
79
- onLabelEditClick={onLabelEditClick}
80
- label={label}
81
- description={description}
82
- assistiveText={assistiveText}
83
- assistiveWithIcon={assistiveWithIcon}
84
- error={error}
85
- required={required}
86
- withAsterisk={withAsterisk}
87
- id={id}
88
- >
89
- {readOnlyComponent}
90
- </FormControlWrapper>
91
- );
92
- }
93
-
94
64
  return (
95
- <FormControlWrapper
65
+ <WithReadOnlyWrapper
96
66
  className={className}
97
67
  style={style as React.CSSProperties}
98
68
  controlMaxWidth="var(--recursica_ui-kit_components_switch_properties_max-width)"
@@ -113,24 +83,34 @@ export const SwitchGroup = forwardRef<HTMLDivElement, SwitchGroupProps>(
113
83
  required={required}
114
84
  withAsterisk={withAsterisk}
115
85
  id={id}
116
- >
117
- <MantineSwitch.Group
118
- ref={ref}
119
- /* Natively bind local disabled lock dynamically */
120
- {...(sanitizedProps as unknown as MantineSwitchGroupProps)}
121
- >
122
- <div className={styles.groupRoot} data-layout={formLayout}>
123
- {React.Children.map(children, (child) => {
124
- if (React.isValidElement(child)) {
125
- return React.cloneElement(child as React.ReactElement<any>, {
126
- disabled: readOnly || (child.props as any).disabled,
127
- });
128
- }
129
- return child;
130
- })}
131
- </div>
132
- </MantineSwitch.Group>
133
- </FormControlWrapper>
86
+ readOnly={readOnly && !!readOnlyComponent}
87
+ readOnlyComponent={readOnlyComponent}
88
+ emptyValueComponent={emptyValueComponent}
89
+ readOnlyType="text"
90
+ readOnlyValue={value !== undefined ? value : defaultValue}
91
+ readOnlyNativeProps={props}
92
+ activeComponent={
93
+ <MantineSwitch.Group
94
+ ref={ref}
95
+ /* Natively bind local disabled lock dynamically */
96
+ {...(sanitizedProps as unknown as MantineSwitchGroupProps)}
97
+ disabled={readOnly || (restRecord as any).disabled}
98
+ value={value}
99
+ defaultValue={defaultValue}
100
+ >
101
+ <div className={styles.groupRoot}>
102
+ {React.Children.map(children, (child) => {
103
+ if (React.isValidElement(child)) {
104
+ return React.cloneElement(child as React.ReactElement<any>, {
105
+ disabled: readOnly || (child.props as any).disabled,
106
+ });
107
+ }
108
+ return child;
109
+ })}
110
+ </div>
111
+ </MantineSwitch.Group>
112
+ }
113
+ />
134
114
  );
135
115
  },
136
116
  );
@@ -27,9 +27,6 @@ const meta: Meta<TextAreaStoryProps> = {
27
27
  },
28
28
  argTypes: {
29
29
  ...formControlArgTypes,
30
- disabled: {
31
- control: "boolean",
32
- },
33
30
  readOnly: {
34
31
  control: "boolean",
35
32
  },
@@ -40,8 +40,8 @@ export interface RecursicaTextAreaProps
40
40
  export type TextAreaProps = RecursicaOverStyled<RecursicaTextAreaProps>;
41
41
 
42
42
  export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
43
- function TextArea(
44
- {
43
+ function TextArea(props, ref) {
44
+ const {
45
45
  overStyled = false,
46
46
  formLayout = "stacked",
47
47
 
@@ -64,12 +64,11 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
64
64
  disabled,
65
65
  readOnly,
66
66
  readOnlyComponent,
67
+ emptyValueComponent,
67
68
  value,
68
69
  defaultValue,
69
70
  ...rest
70
- },
71
- ref,
72
- ) {
71
+ } = props;
73
72
  const sanitizedProps = filterStylingProps(rest, overStyled);
74
73
  const restRecord = sanitizedProps as Record<string, unknown>;
75
74
 
@@ -121,8 +120,10 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
121
120
  id={id}
122
121
  readOnly={readOnly}
123
122
  readOnlyComponent={readOnlyComponent}
123
+ emptyValueComponent={emptyValueComponent}
124
124
  readOnlyType="text"
125
125
  readOnlyValue={value !== undefined ? value : defaultValue}
126
+ readOnlyNativeProps={props}
126
127
  activeComponent={
127
128
  /* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
128
129
  <MantineTextarea
@@ -28,8 +28,8 @@ export interface RecursicaTextFieldProps
28
28
  export type TextFieldProps = RecursicaOverStyled<RecursicaTextFieldProps>;
29
29
 
30
30
  export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
31
- function TextField(
32
- {
31
+ function TextField(props, ref) {
32
+ const {
33
33
  overStyled = false,
34
34
  formLayout = "stacked",
35
35
 
@@ -52,12 +52,11 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
52
52
  disabled,
53
53
  readOnly,
54
54
  readOnlyComponent,
55
+ emptyValueComponent,
55
56
  value,
56
57
  defaultValue,
57
58
  ...rest
58
- },
59
- ref,
60
- ) {
59
+ } = props;
61
60
  const sanitizedProps = filterStylingProps(rest, overStyled);
62
61
  const restRecord = sanitizedProps as Record<string, unknown>;
63
62
 
@@ -113,8 +112,10 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
113
112
  id={id}
114
113
  readOnly={readOnly}
115
114
  readOnlyComponent={readOnlyComponent}
115
+ emptyValueComponent={emptyValueComponent}
116
116
  readOnlyType="text"
117
117
  readOnlyValue={value !== undefined ? value : defaultValue}
118
+ readOnlyNativeProps={props}
118
119
  activeComponent={
119
120
  /* Naked Input execution safely decoupled from Mantine's macro Input.Wrapper DOM hooks */
120
121
  <Input
@@ -6,11 +6,7 @@ const meta: Meta<typeof TimePicker> = {
6
6
  title: "UI-Kit/🚧 TimePicker",
7
7
  component: TimePicker,
8
8
  tags: ["autodocs"],
9
- argTypes: {
10
- disabled: {
11
- control: "boolean",
12
- },
13
- },
9
+ argTypes: {},
14
10
  };
15
11
 
16
12
  export default meta;
@@ -13,6 +13,7 @@ export * from "./Dropdown/Dropdown";
13
13
  export * from "./FileInput/FileInput";
14
14
  export * from "./FileUpload/FileUpload";
15
15
  export * from "./Flex/Flex";
16
+ export * from "./FormControlLayout/FormControlLayout";
16
17
  export * from "./Group/Group";
17
18
  export * from "./HoverCard/HoverCard";
18
19
  export * from "./Link/Link";
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from "react";
2
+
3
+ /**
4
+ * Enforces accessibility by strictly requiring at least one form of labeling:
5
+ * either a visual \`label\`, an \`aria-label\`, or an \`aria-labelledby\`.
6
+ */
7
+ export type RequireAccessibleLabel<T> = T &
8
+ (
9
+ | { label: ReactNode; "aria-label"?: string; "aria-labelledby"?: string }
10
+ | { label?: ReactNode; "aria-label": string; "aria-labelledby"?: string }
11
+ | { label?: ReactNode; "aria-label"?: string; "aria-labelledby": string }
12
+ );