@rovula/ui 0.1.7 → 0.1.8

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 (196) hide show
  1. package/dist/cjs/bundle.css +281 -124
  2. package/dist/cjs/bundle.js +1545 -1545
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  5. package/dist/cjs/types/components/Dialog/Dialog.d.ts +7 -1
  6. package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +3 -0
  7. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +2 -0
  8. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  9. package/dist/cjs/types/components/Form/Field.d.ts +26 -0
  10. package/dist/cjs/types/components/Form/FieldMessage.d.ts +7 -0
  11. package/dist/cjs/types/components/Form/Form.d.ts +49 -11
  12. package/dist/cjs/types/components/Form/Form.stories.d.ts +23 -0
  13. package/dist/cjs/types/components/Form/ValidationHintList.d.ts +17 -0
  14. package/dist/cjs/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  15. package/dist/cjs/types/components/Form/index.d.ts +10 -0
  16. package/dist/cjs/types/components/Form/useOptionBridge.d.ts +17 -0
  17. package/dist/cjs/types/components/OtpInput/OtpInput.d.ts +17 -0
  18. package/dist/cjs/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  19. package/dist/cjs/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  20. package/dist/cjs/types/components/OtpInput/index.d.ts +5 -0
  21. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +3 -0
  22. package/dist/cjs/types/index.d.ts +5 -0
  23. package/dist/cjs/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  24. package/dist/cjs/types/utils/colors.d.ts +84 -0
  25. package/dist/components/ActionButton/ActionButton.stories.js +2 -2
  26. package/dist/components/ActionButton/ActionButton.styles.js +1 -1
  27. package/dist/components/AlertDialog/AlertDialog.js +6 -6
  28. package/dist/components/AlertDialog/AlertDialog.stories.js +3 -0
  29. package/dist/components/Avatar/Avatar.stories.js +1 -1
  30. package/dist/components/Avatar/Avatar.styles.js +1 -1
  31. package/dist/components/Avatar/AvatarBase.js +1 -1
  32. package/dist/components/Avatar/AvatarGroup.stories.js +1 -1
  33. package/dist/components/Button/Buttons.stories.js +2 -2
  34. package/dist/components/Calendar/Calendar.js +1 -1
  35. package/dist/components/Checkbox/Checkbox.js +1 -1
  36. package/dist/components/Checkbox/Checkbox.stories.js +17 -7
  37. package/dist/components/Collapsible/Collapsible.styles.js +1 -1
  38. package/dist/components/DataTable/DataTable.js +2 -2
  39. package/dist/components/Dialog/Dialog.js +12 -7
  40. package/dist/components/Dialog/Dialog.stories.js +90 -2
  41. package/dist/components/Dropdown/Dropdown.js +2 -2
  42. package/dist/components/DropdownMenu/DropdownMenu.js +3 -3
  43. package/dist/components/FocusedScrollView/FocusedScrollView.stories.js +6 -6
  44. package/dist/components/Form/Field.js +60 -0
  45. package/dist/components/Form/FieldMessage.js +24 -0
  46. package/dist/components/Form/Form.js +73 -41
  47. package/dist/components/Form/Form.stories.js +221 -0
  48. package/dist/components/Form/ValidationHintList.js +30 -0
  49. package/dist/components/Form/ValidationHintList.stories.js +50 -0
  50. package/dist/components/Form/index.js +5 -0
  51. package/dist/components/Form/useOptionBridge.js +27 -0
  52. package/dist/components/InputFilter/InputFilter.js +5 -4
  53. package/dist/components/InputFilter/InputFilter.stories.js +1 -1
  54. package/dist/components/InputFilter/InputFilter.styles.js +14 -1
  55. package/dist/components/Label/Label.styles.js +1 -1
  56. package/dist/components/Menu/Menu.js +2 -2
  57. package/dist/components/NumberInput/NumberInput.stories.js +1 -1
  58. package/dist/components/OtpInput/OtpInput.js +118 -0
  59. package/dist/components/OtpInput/OtpInput.stories.js +60 -0
  60. package/dist/components/OtpInput/OtpInputGroup.js +23 -0
  61. package/dist/components/OtpInput/index.js +3 -0
  62. package/dist/components/PasswordInput/PasswordInput.stories.js +1 -1
  63. package/dist/components/Popover/Popover.js +1 -1
  64. package/dist/components/RadioGroup/RadioGroup.js +1 -1
  65. package/dist/components/RadioGroup/RadioGroup.stories.js +2 -2
  66. package/dist/components/Search/Search.js +13 -1
  67. package/dist/components/Search/Search.stories.js +1 -1
  68. package/dist/components/Slider/Slider.js +1 -1
  69. package/dist/components/Slider/Slider.stories.js +5 -5
  70. package/dist/components/Switch/Switch.stories.js +2 -2
  71. package/dist/components/Table/Table.js +5 -5
  72. package/dist/components/Tabs/Tabs.js +12 -9
  73. package/dist/components/Tabs/Tabs.stories.js +1 -1
  74. package/dist/components/Text/Text.js +1 -1
  75. package/dist/components/Text/Text.stories.js +1 -1
  76. package/dist/components/TextArea/TextArea.stories.js +1 -1
  77. package/dist/components/TextArea/TextArea.styles.js +3 -3
  78. package/dist/components/TextInput/TextInput.js +3 -2
  79. package/dist/components/TextInput/TextInput.stories.js +3 -3
  80. package/dist/components/TextInput/TextInput.styles.js +41 -19
  81. package/dist/components/Toast/Toast.js +4 -2
  82. package/dist/components/Toast/Toast.stories.js +1 -1
  83. package/dist/components/Toast/Toast.styles.js +4 -4
  84. package/dist/components/Toast/Toaster.js +2 -2
  85. package/dist/components/Tree/Tree.stories.js +1 -1
  86. package/dist/components/Tree/TreeItem.js +1 -1
  87. package/dist/esm/bundle.css +281 -124
  88. package/dist/esm/bundle.js +1545 -1545
  89. package/dist/esm/bundle.js.map +1 -1
  90. package/dist/esm/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  91. package/dist/esm/types/components/Dialog/Dialog.d.ts +7 -1
  92. package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +3 -0
  93. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +2 -0
  94. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  95. package/dist/esm/types/components/Form/Field.d.ts +26 -0
  96. package/dist/esm/types/components/Form/FieldMessage.d.ts +7 -0
  97. package/dist/esm/types/components/Form/Form.d.ts +49 -11
  98. package/dist/esm/types/components/Form/Form.stories.d.ts +23 -0
  99. package/dist/esm/types/components/Form/ValidationHintList.d.ts +17 -0
  100. package/dist/esm/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  101. package/dist/esm/types/components/Form/index.d.ts +10 -0
  102. package/dist/esm/types/components/Form/useOptionBridge.d.ts +17 -0
  103. package/dist/esm/types/components/OtpInput/OtpInput.d.ts +17 -0
  104. package/dist/esm/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  105. package/dist/esm/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  106. package/dist/esm/types/components/OtpInput/index.d.ts +5 -0
  107. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +3 -0
  108. package/dist/esm/types/index.d.ts +5 -0
  109. package/dist/esm/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  110. package/dist/esm/types/utils/colors.d.ts +84 -0
  111. package/dist/index.d.ts +245 -2
  112. package/dist/index.js +3 -0
  113. package/dist/src/theme/global.css +351 -149
  114. package/dist/theme/ThemeColorCoverageRuntime.stories.js +91 -0
  115. package/dist/utils/colors.js +92 -0
  116. package/package.json +4 -2
  117. package/src/components/ActionButton/ActionButton.stories.tsx +6 -6
  118. package/src/components/ActionButton/ActionButton.styles.ts +1 -1
  119. package/src/components/AlertDialog/AlertDialog.stories.tsx +22 -0
  120. package/src/components/AlertDialog/AlertDialog.tsx +6 -6
  121. package/src/components/Avatar/Avatar.stories.tsx +1 -1
  122. package/src/components/Avatar/Avatar.styles.ts +1 -1
  123. package/src/components/Avatar/AvatarBase.tsx +1 -1
  124. package/src/components/Avatar/AvatarGroup.stories.tsx +1 -1
  125. package/src/components/Button/Buttons.stories.tsx +10 -10
  126. package/src/components/Calendar/Calendar.tsx +3 -3
  127. package/src/components/Checkbox/Checkbox.stories.tsx +35 -12
  128. package/src/components/Checkbox/Checkbox.tsx +7 -5
  129. package/src/components/Collapsible/Collapsible.styles.ts +1 -1
  130. package/src/components/DataTable/DataTable.tsx +2 -2
  131. package/src/components/Dialog/Dialog.stories.tsx +173 -0
  132. package/src/components/Dialog/Dialog.tsx +32 -15
  133. package/src/components/Dropdown/Dropdown.styles.ts +1 -1
  134. package/src/components/Dropdown/Dropdown.tsx +16 -14
  135. package/src/components/DropdownMenu/DropdownMenu.tsx +3 -3
  136. package/src/components/FocusedScrollView/FocusedScrollView.stories.tsx +10 -10
  137. package/src/components/Form/Field.tsx +160 -0
  138. package/src/components/Form/FieldMessage.tsx +38 -0
  139. package/src/components/Form/Form.docs.mdx +67 -0
  140. package/src/components/Form/Form.stories.tsx +490 -0
  141. package/src/components/Form/Form.tsx +185 -87
  142. package/src/components/Form/README.md +284 -0
  143. package/src/components/Form/ValidationHintList.stories.tsx +118 -0
  144. package/src/components/Form/ValidationHintList.tsx +82 -0
  145. package/src/components/Form/index.ts +28 -0
  146. package/src/components/Form/useOptionBridge.ts +55 -0
  147. package/src/components/InputFilter/InputFilter.stories.tsx +1 -1
  148. package/src/components/InputFilter/InputFilter.styles.ts +14 -1
  149. package/src/components/InputFilter/InputFilter.tsx +33 -28
  150. package/src/components/Label/Label.styles.ts +2 -2
  151. package/src/components/Label/Label.tsx +1 -1
  152. package/src/components/Menu/Menu.tsx +12 -12
  153. package/src/components/NumberInput/NumberInput.stories.tsx +1 -1
  154. package/src/components/OtpInput/OtpInput.stories.tsx +168 -0
  155. package/src/components/OtpInput/OtpInput.tsx +210 -0
  156. package/src/components/OtpInput/OtpInputGroup.tsx +74 -0
  157. package/src/components/OtpInput/index.ts +5 -0
  158. package/src/components/PasswordInput/PasswordInput.stories.tsx +1 -1
  159. package/src/components/Popover/Popover.tsx +1 -1
  160. package/src/components/RadioGroup/RadioGroup.stories.tsx +4 -4
  161. package/src/components/RadioGroup/RadioGroup.tsx +2 -1
  162. package/src/components/Search/Search.stories.tsx +1 -1
  163. package/src/components/Search/Search.tsx +6 -2
  164. package/src/components/Slider/Slider.stories.tsx +7 -7
  165. package/src/components/Slider/Slider.tsx +1 -1
  166. package/src/components/Switch/Switch.stories.tsx +4 -4
  167. package/src/components/Table/Table.tsx +5 -5
  168. package/src/components/Tabs/Tabs.stories.tsx +1 -1
  169. package/src/components/Tabs/Tabs.tsx +29 -18
  170. package/src/components/Text/Text.stories.tsx +1 -1
  171. package/src/components/Text/Text.tsx +1 -1
  172. package/src/components/TextArea/TextArea.stories.tsx +1 -1
  173. package/src/components/TextArea/TextArea.styles.ts +3 -3
  174. package/src/components/TextInput/TextInput.stories.tsx +7 -7
  175. package/src/components/TextInput/TextInput.styles.ts +42 -19
  176. package/src/components/TextInput/TextInput.tsx +3 -1
  177. package/src/components/Toast/Toast.stories.tsx +1 -1
  178. package/src/components/Toast/Toast.styles.tsx +7 -7
  179. package/src/components/Toast/Toast.tsx +5 -4
  180. package/src/components/Toast/Toaster.tsx +17 -20
  181. package/src/components/Tree/Tree.stories.tsx +1 -1
  182. package/src/components/Tree/TreeItem.tsx +1 -1
  183. package/src/index.ts +5 -0
  184. package/src/theme/ThemeColorCoverageRuntime.stories.tsx +236 -0
  185. package/src/theme/direct-token-migration-plan.md +121 -0
  186. package/src/theme/figma-mcp-check-report.md +225 -0
  187. package/src/theme/figma-mcp-component-checklist.json +1250 -0
  188. package/src/theme/presets/colors.js +155 -44
  189. package/src/theme/themes/xspector/components/loading.css +2 -2
  190. package/src/theme/tokens/color.css +3 -3
  191. package/src/theme/tokens/components/action-button.css +1 -1
  192. package/src/theme/tokens/components/dropdown-menu.css +3 -3
  193. package/src/theme/tokens/components/loading.css +2 -2
  194. package/src/theme/tokens/components/switch.css +1 -1
  195. package/src/theme/utils.js +164 -25
  196. package/src/utils/colors.ts +92 -0
@@ -0,0 +1,160 @@
1
+ import React, { ComponentType, useId } from "react";
2
+ import {
3
+ FieldPath,
4
+ FieldPathValue,
5
+ FieldValues,
6
+ RegisterOptions,
7
+ useController,
8
+ } from "react-hook-form";
9
+
10
+ type ControlledComponentProps = object;
11
+
12
+ export type FieldProps<
13
+ TFieldValues extends FieldValues,
14
+ TName extends FieldPath<TFieldValues>,
15
+ TComponentProps extends ControlledComponentProps = ControlledComponentProps,
16
+ > = {
17
+ name: TName;
18
+ component: ComponentType<TComponentProps>;
19
+ componentProps?: Omit<
20
+ TComponentProps,
21
+ "name" | "value" | "onChange" | "onBlur" | "ref" | "aria-invalid"
22
+ >;
23
+ rules?: Omit<
24
+ RegisterOptions<TFieldValues, TName>,
25
+ "disabled" | "setValueAs" | "valueAsDate" | "valueAsNumber"
26
+ >;
27
+ defaultValue?: FieldPathValue<TFieldValues, TName>;
28
+ disabled?: boolean;
29
+ shouldUnregister?: boolean;
30
+ id?: string;
31
+ describedBy?: string;
32
+ valuePropName?: string;
33
+ changePropName?: string;
34
+ blurPropName?: string | false;
35
+ refPropName?: string | false;
36
+ errorMessagePropName?: string | false;
37
+ invalidPropName?: string | false;
38
+ parseValue?: (
39
+ incomingValue: unknown,
40
+ rawPayload: unknown
41
+ ) => FieldPathValue<TFieldValues, TName>;
42
+ formatValue?: (
43
+ value: FieldPathValue<TFieldValues, TName>
44
+ ) => TComponentProps[keyof TComponentProps];
45
+ onChange?: (
46
+ value: FieldPathValue<TFieldValues, TName>,
47
+ rawPayload: unknown
48
+ ) => void;
49
+ onBlur?: () => void;
50
+ };
51
+
52
+ const extractChangedValue = (payload: unknown) => {
53
+ if (
54
+ payload &&
55
+ typeof payload === "object" &&
56
+ "target" in payload &&
57
+ payload.target &&
58
+ typeof payload.target === "object"
59
+ ) {
60
+ const target = payload.target as {
61
+ value?: unknown;
62
+ checked?: unknown;
63
+ type?: string;
64
+ };
65
+
66
+ if (target.type === "checkbox") {
67
+ return target.checked;
68
+ }
69
+
70
+ return target.value;
71
+ }
72
+
73
+ return payload;
74
+ };
75
+
76
+ export const Field = <
77
+ TFieldValues extends FieldValues,
78
+ TName extends FieldPath<TFieldValues>,
79
+ TComponentProps extends ControlledComponentProps = ControlledComponentProps,
80
+ >({
81
+ name,
82
+ component: Component,
83
+ componentProps,
84
+ rules,
85
+ defaultValue,
86
+ disabled = false,
87
+ shouldUnregister = false,
88
+ id,
89
+ describedBy,
90
+ valuePropName = "value",
91
+ changePropName = "onChange",
92
+ blurPropName = "onBlur",
93
+ refPropName = "ref",
94
+ errorMessagePropName = "errorMessage",
95
+ invalidPropName = "error",
96
+ parseValue,
97
+ formatValue,
98
+ onChange,
99
+ onBlur,
100
+ }: FieldProps<TFieldValues, TName, TComponentProps>) => {
101
+ const fieldId = useId();
102
+ const resolvedId = id || `${name.replace(/\./g, "-")}-${fieldId}`;
103
+ const {
104
+ field,
105
+ fieldState: { error, invalid },
106
+ } = useController<TFieldValues, TName>({
107
+ name,
108
+ rules,
109
+ disabled,
110
+ defaultValue,
111
+ shouldUnregister,
112
+ });
113
+
114
+ const handleChange = (rawPayload: unknown) => {
115
+ const extractedValue = extractChangedValue(rawPayload);
116
+ const parsedValue = parseValue
117
+ ? parseValue(extractedValue, rawPayload)
118
+ : (extractedValue as FieldPathValue<TFieldValues, TName>);
119
+
120
+ field.onChange(parsedValue);
121
+ onChange?.(parsedValue, rawPayload);
122
+ };
123
+
124
+ const handleBlur = () => {
125
+ field.onBlur();
126
+ onBlur?.();
127
+ };
128
+
129
+ const componentValue = formatValue
130
+ ? formatValue(field.value as FieldPathValue<TFieldValues, TName>)
131
+ : field.value;
132
+
133
+ const sharedProps: Record<string, unknown> = {
134
+ ...(componentProps as Record<string, unknown>),
135
+ id: resolvedId,
136
+ name: field.name,
137
+ disabled,
138
+ "aria-invalid": invalid || undefined,
139
+ "aria-describedby": describedBy,
140
+ };
141
+
142
+ sharedProps[valuePropName] = componentValue;
143
+ sharedProps[changePropName] = handleChange;
144
+ if (blurPropName) {
145
+ sharedProps[blurPropName] = handleBlur;
146
+ }
147
+ if (refPropName) {
148
+ sharedProps[refPropName] = field.ref;
149
+ }
150
+ if (errorMessagePropName) {
151
+ sharedProps[errorMessagePropName] = error?.message;
152
+ }
153
+ if (invalidPropName) {
154
+ sharedProps[invalidPropName] = invalid;
155
+ }
156
+
157
+ return <Component {...(sharedProps as TComponentProps)} />;
158
+ };
159
+
160
+ export default Field;
@@ -0,0 +1,38 @@
1
+ import React, { HTMLAttributes } from "react";
2
+ import { FieldPath, FieldValues, useFormContext } from "react-hook-form";
3
+ import { cn } from "@/utils/cn";
4
+
5
+ export type FieldMessageProps<
6
+ TFieldValues extends FieldValues,
7
+ TName extends FieldPath<TFieldValues>,
8
+ > = HTMLAttributes<HTMLParagraphElement> & {
9
+ name: TName;
10
+ };
11
+
12
+ export const FieldMessage = <
13
+ TFieldValues extends FieldValues,
14
+ TName extends FieldPath<TFieldValues>,
15
+ >({
16
+ name,
17
+ className,
18
+ ...props
19
+ }: FieldMessageProps<TFieldValues, TName>) => {
20
+ const { getFieldState, formState } = useFormContext<TFieldValues>();
21
+ const { error } = getFieldState(name, formState);
22
+
23
+ if (!error?.message) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <p
29
+ {...props}
30
+ className={cn("text-sm text-input-error mt-1", className)}
31
+ role="alert"
32
+ >
33
+ {error.message}
34
+ </p>
35
+ );
36
+ };
37
+
38
+ export default FieldMessage;
@@ -0,0 +1,67 @@
1
+ import { Meta, Title, Subtitle, Description, Heading, Unstyled, Canvas, Story, Markdown } from "@storybook/blocks";
2
+ import * as FormStories from "./Form.stories";
3
+ import FormReadme from "./README.md";
4
+
5
+ <Meta title="Components/Form/Guide" of={FormStories} />
6
+
7
+ <Title>Form Guide</Title>
8
+ <Subtitle>How to use Form, Field, and custom input mapping</Subtitle>
9
+ <Description>
10
+ This page summarizes practical usage of the Form system in this package.
11
+ For full examples, open stories under <code>Components/Form</code>.
12
+ </Description>
13
+
14
+ <Heading>Quick Start</Heading>
15
+ <Unstyled>
16
+ <ul>
17
+ <li>Set defaults at <code>Form.defaultValues</code>.</li>
18
+ <li>Use <code>Field</code> to bind UI components to react-hook-form.</li>
19
+ <li>Use <code>validationSchema</code> or <code>resolver</code> for validation.</li>
20
+ <li>For custom components, map prop names and parse/format values as needed.</li>
21
+ <li>
22
+ Use <code>ref</code>/<code>controllerRef</code> for imperative actions:{" "}
23
+ <code>submit</code>, <code>getValues</code>, <code>setValue</code>,{" "}
24
+ <code>trigger</code>, and <code>reset</code>.
25
+ </li>
26
+ </ul>
27
+ </Unstyled>
28
+
29
+ <Heading>Most Used Field Mapping Props</Heading>
30
+ <Unstyled>
31
+ <ul>
32
+ <li><code>valuePropName</code>: form value to component value prop.</li>
33
+ <li><code>changePropName</code>: component change callback prop.</li>
34
+ <li><code>formatValue</code>: form state to component payload.</li>
35
+ <li><code>parseValue</code>: component payload to form state.</li>
36
+ </ul>
37
+ </Unstyled>
38
+
39
+ <Heading>Validation Note</Heading>
40
+ <Description>
41
+ If you use <code>mode=&quot;onTouched&quot;</code>, your input must call
42
+ <code>onBlur</code> correctly when focus leaves the field.
43
+ </Description>
44
+
45
+ <Heading>Examples</Heading>
46
+ <Canvas>
47
+ <Story of={FormStories.BasicYupLogin} />
48
+ </Canvas>
49
+
50
+ <Canvas>
51
+ <Story of={FormStories.MixedUiKitControls} />
52
+ </Canvas>
53
+
54
+ <Canvas>
55
+ <Story of={FormStories.HigherLayerCodeControl} />
56
+ </Canvas>
57
+
58
+ <Heading>Async Dropdown (id in form state)</Heading>
59
+ <Description>
60
+ Prefer storing primitive ids in form state, then map to option objects for UI
61
+ rendering via <code>formatValue</code>/<code>parseValue</code> or
62
+ <code>useOptionBridge</code>.
63
+ </Description>
64
+
65
+ <Heading>Full Markdown Doc</Heading>
66
+ <Markdown>{FormReadme}</Markdown>
67
+