@rovula/ui 0.1.20 → 0.1.22

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 (99) hide show
  1. package/dist/cjs/bundle.css +316 -43
  2. package/dist/cjs/bundle.js +675 -675
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/Badge/Badge.d.ts +40 -0
  5. package/dist/cjs/types/components/Badge/Badge.stories.d.ts +295 -0
  6. package/dist/cjs/types/components/Badge/Badge.styles.d.ts +7 -0
  7. package/dist/cjs/types/components/Badge/index.d.ts +2 -0
  8. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +4 -8
  9. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +1 -6
  10. package/dist/cjs/types/components/DropdownMenu/DropdownMenu.d.ts +5 -1
  11. package/dist/cjs/types/components/DropdownMenu/DropdownMenu.stories.d.ts +45 -30
  12. package/dist/cjs/types/components/Form/Form.d.ts +2 -1
  13. package/dist/cjs/types/components/Form/Form.stories.d.ts +4 -0
  14. package/dist/cjs/types/components/ScrollArea/ScrollArea.d.ts +38 -0
  15. package/dist/cjs/types/components/ScrollArea/ScrollArea.stories.d.ts +301 -0
  16. package/dist/cjs/types/index.d.ts +4 -1
  17. package/dist/cjs/types/patterns/menu/Menu.d.ts +70 -0
  18. package/dist/cjs/types/{components/Menu → patterns/menu}/Menu.stories.d.ts +17 -10
  19. package/dist/cjs/types/utils/mergeRefs.d.ts +20 -0
  20. package/dist/components/Avatar/Avatar.styles.js +2 -2
  21. package/dist/components/Badge/Badge.js +36 -0
  22. package/dist/components/Badge/Badge.stories.js +51 -0
  23. package/dist/components/Badge/Badge.styles.js +62 -0
  24. package/dist/components/Badge/index.js +2 -0
  25. package/dist/components/Dropdown/Dropdown.js +54 -163
  26. package/dist/components/Dropdown/Dropdown.stories.js +29 -0
  27. package/dist/components/DropdownMenu/DropdownMenu.js +24 -13
  28. package/dist/components/DropdownMenu/DropdownMenu.stories.js +120 -88
  29. package/dist/components/Form/Form.js +11 -4
  30. package/dist/components/Form/Form.stories.js +27 -0
  31. package/dist/components/ScrollArea/ScrollArea.js +50 -0
  32. package/dist/components/ScrollArea/ScrollArea.stories.js +56 -0
  33. package/dist/components/TextInput/TextInput.js +6 -3
  34. package/dist/esm/bundle.css +316 -43
  35. package/dist/esm/bundle.js +1545 -1545
  36. package/dist/esm/bundle.js.map +1 -1
  37. package/dist/esm/types/components/Badge/Badge.d.ts +40 -0
  38. package/dist/esm/types/components/Badge/Badge.stories.d.ts +295 -0
  39. package/dist/esm/types/components/Badge/Badge.styles.d.ts +7 -0
  40. package/dist/esm/types/components/Badge/index.d.ts +2 -0
  41. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +4 -8
  42. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +1 -6
  43. package/dist/esm/types/components/DropdownMenu/DropdownMenu.d.ts +5 -1
  44. package/dist/esm/types/components/DropdownMenu/DropdownMenu.stories.d.ts +45 -30
  45. package/dist/esm/types/components/Form/Form.d.ts +2 -1
  46. package/dist/esm/types/components/Form/Form.stories.d.ts +4 -0
  47. package/dist/esm/types/components/ScrollArea/ScrollArea.d.ts +38 -0
  48. package/dist/esm/types/components/ScrollArea/ScrollArea.stories.d.ts +301 -0
  49. package/dist/esm/types/index.d.ts +4 -1
  50. package/dist/esm/types/patterns/menu/Menu.d.ts +70 -0
  51. package/dist/esm/types/{components/Menu → patterns/menu}/Menu.stories.d.ts +17 -10
  52. package/dist/esm/types/utils/mergeRefs.d.ts +20 -0
  53. package/dist/index.d.ts +156 -74
  54. package/dist/index.js +3 -1
  55. package/dist/patterns/menu/Menu.js +95 -0
  56. package/dist/patterns/menu/Menu.stories.js +611 -0
  57. package/dist/src/theme/global.css +485 -57
  58. package/dist/utils/mergeRefs.js +42 -0
  59. package/package.json +1 -1
  60. package/src/components/Avatar/Avatar.styles.ts +2 -2
  61. package/src/components/Badge/Badge.stories.tsx +128 -0
  62. package/src/components/Badge/Badge.styles.ts +70 -0
  63. package/src/components/Badge/Badge.tsx +103 -0
  64. package/src/components/Badge/index.ts +3 -0
  65. package/src/components/Dropdown/Dropdown.stories.tsx +170 -1
  66. package/src/components/Dropdown/Dropdown.tsx +186 -276
  67. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +1375 -253
  68. package/src/components/DropdownMenu/DropdownMenu.tsx +118 -55
  69. package/src/components/Form/Form.stories.tsx +70 -0
  70. package/src/components/Form/Form.tsx +23 -0
  71. package/src/components/ScrollArea/ScrollArea.stories.tsx +229 -0
  72. package/src/components/ScrollArea/ScrollArea.tsx +72 -0
  73. package/src/components/TextInput/TextInput.tsx +6 -3
  74. package/src/index.ts +4 -1
  75. package/src/patterns/menu/Menu.stories.tsx +1100 -0
  76. package/src/patterns/menu/Menu.tsx +282 -0
  77. package/src/theme/global.css +84 -11
  78. package/src/theme/themes/xspector/baseline.css +1 -1
  79. package/src/theme/themes/xspector/components/scrollbar.css +12 -0
  80. package/src/theme/tokens/baseline.css +3 -1
  81. package/src/theme/tokens/components/badge.css +54 -0
  82. package/src/theme/tokens/components/dropdown-menu.css +16 -5
  83. package/src/theme/tokens/components/scrollbar.css +18 -0
  84. package/src/utils/mergeRefs.ts +46 -0
  85. package/dist/cjs/types/components/Menu/Menu.d.ts +0 -65
  86. package/dist/cjs/types/components/Menu/helpers.d.ts +0 -19
  87. package/dist/cjs/types/components/Menu/index.d.ts +0 -4
  88. package/dist/components/Menu/Menu.js +0 -64
  89. package/dist/components/Menu/Menu.stories.js +0 -406
  90. package/dist/components/Menu/helpers.js +0 -28
  91. package/dist/components/Menu/index.js +0 -3
  92. package/dist/esm/types/components/Menu/Menu.d.ts +0 -65
  93. package/dist/esm/types/components/Menu/helpers.d.ts +0 -19
  94. package/dist/esm/types/components/Menu/index.d.ts +0 -4
  95. package/src/components/Menu/Menu.stories.tsx +0 -586
  96. package/src/components/Menu/Menu.tsx +0 -235
  97. package/src/components/Menu/helpers.ts +0 -45
  98. package/src/components/Menu/index.ts +0 -7
  99. package/src/theme/themes/xspector/components/dropdown-menu.css +0 -28
@@ -1,235 +0,0 @@
1
- import React, {
2
- CSSProperties,
3
- ReactNode,
4
- forwardRef,
5
- useCallback,
6
- useState,
7
- } from "react";
8
- import { cn } from "@/utils/cn";
9
- import Icon from "../Icon/Icon";
10
-
11
- // ==================== Types ====================
12
-
13
- export type MenuOption = {
14
- value: string;
15
- label: ReactNode;
16
- /**
17
- * Visual type - กำหนดว่าจะแสดง icon อะไร
18
- * - "default": ไม่มี icon (แค่ highlight background)
19
- * - "checkbox": แสดง ✓ icon
20
- * - "radio": แสดง ● icon
21
- */
22
- type?: "default" | "checkbox" | "radio";
23
- icon?: ReactNode;
24
- disabled?: boolean;
25
- danger?: boolean;
26
- checked?: boolean; // สำหรับ type="checkbox" หรือ "radio"
27
- onClick?: () => void;
28
- };
29
-
30
- export type MenuItemType =
31
- | { type: "item"; item: MenuOption }
32
- | { type: "separator" }
33
- | { type: "label"; label: string }
34
- | { type: "custom"; render: () => ReactNode };
35
-
36
- export type MenuProps = {
37
- items: MenuItemType[];
38
- /**
39
- * Selected values - ใช้กับ type="item"
40
- */
41
- selectedValues?: string[];
42
- /**
43
- * Callback เมื่อเลือก item
44
- * - ถ้า item.type="checkbox" → toggle checked state
45
- * - ถ้า item.type="radio" → single select (clear others)
46
- * - ถ้า item.type="default" หรือไม่ระบุ → ตาม selectedValues
47
- */
48
- onSelect?: (value: string, item: MenuOption) => void;
49
- className?: string;
50
- style?: CSSProperties;
51
- isAbove?: boolean;
52
- };
53
-
54
- // ==================== Menu Container ====================
55
-
56
- export const Menu = forwardRef<HTMLDivElement, MenuProps>(
57
- (
58
- { items, selectedValues = [], onSelect, className, style, isAbove = false },
59
- ref,
60
- ) => {
61
- return (
62
- <div
63
- ref={ref}
64
- className={cn(
65
- "z-50 min-w-[154px] overflow-hidden rounded-md bg-modal-surface text-text-g-contrast-high",
66
- "border border-modal-surface",
67
- className,
68
- )}
69
- style={{
70
- boxShadow: "var(--dropdown-menu-shadow)",
71
- ...style,
72
- }}
73
- >
74
- {items.map((item, index) => {
75
- if (item.type === "separator") {
76
- return <MenuSeparator key={`separator-${index}`} />;
77
- }
78
-
79
- if (item.type === "label") {
80
- return <MenuLabel key={`label-${index}`}>{item.label}</MenuLabel>;
81
- }
82
-
83
- if (item.type === "custom") {
84
- return (
85
- <React.Fragment key={`custom-${index}`}>
86
- {item.render()}
87
- </React.Fragment>
88
- );
89
- }
90
-
91
- const itemOption = item.item;
92
- const visualType = itemOption.type || "default";
93
-
94
- // Determine checked/selected state
95
- let isChecked = false;
96
- if (visualType === "checkbox" || visualType === "radio") {
97
- isChecked =
98
- itemOption.checked ?? selectedValues.includes(itemOption.value);
99
- } else {
100
- isChecked = selectedValues.includes(itemOption.value);
101
- }
102
-
103
- return (
104
- <MenuItem
105
- key={itemOption.value}
106
- option={itemOption}
107
- visualType={visualType}
108
- isChecked={isChecked}
109
- onSelect={() => {
110
- onSelect?.(itemOption.value, itemOption);
111
- itemOption.onClick?.();
112
- }}
113
- />
114
- );
115
- })}
116
- </div>
117
- );
118
- },
119
- );
120
-
121
- Menu.displayName = "Menu";
122
-
123
- // ==================== Menu Item ====================
124
-
125
- type MenuItemProps = {
126
- option: MenuOption;
127
- visualType: "default" | "checkbox" | "radio";
128
- isChecked: boolean;
129
- onSelect: () => void;
130
- className?: string;
131
- };
132
-
133
- export const MenuItem = forwardRef<HTMLDivElement, MenuItemProps>(
134
- ({ option, visualType, isChecked, onSelect, className }, ref) => {
135
- // Render indicator based on visual type
136
- const renderIndicator = () => {
137
- if (visualType === "checkbox" && isChecked) {
138
- return (
139
- <span className="absolute left-4 flex items-center justify-center">
140
- <Icon type="heroicons" name="check" className="size-4" />
141
- </span>
142
- );
143
- }
144
- if (visualType === "radio" && isChecked) {
145
- return (
146
- <span className="absolute left-4 flex items-center justify-center">
147
- <Icon
148
- type="heroicons"
149
- name="circle"
150
- className="h-2 w-2 fill-current"
151
- />
152
- </span>
153
- );
154
- }
155
- return null;
156
- };
157
-
158
- return (
159
- <div
160
- ref={ref}
161
- className={cn(
162
- "relative flex gap-3 cursor-pointer select-none box-border items-center py-4 pl-9 pr-4 typography-subtitle4 outline-none transition-colors",
163
- "bg-[var(--dropdown-menu-default-bg)] text-[var(--dropdown-menu-default-text)]",
164
- "active:opacity-75",
165
- "hover:bg-[var(--dropdown-menu-hover-bg)] hover:text-[var(--dropdown-menu-hover-text)]",
166
- {
167
- "bg-[var(--dropdown-menu-selected-bg)] text-[var(--dropdown-menu-selected-text)] typography-subtitle5":
168
- isChecked,
169
- "pointer-events-none opacity-50": option.disabled,
170
- "text-red-500": option.danger,
171
- },
172
- className,
173
- )}
174
- onMouseDown={option.disabled ? undefined : onSelect}
175
- >
176
- {renderIndicator()}
177
- {option.icon && <span className="flex-shrink-0">{option.icon}</span>}
178
- {option.label}
179
- </div>
180
- );
181
- },
182
- );
183
-
184
- MenuItem.displayName = "MenuItem";
185
-
186
- // ==================== Menu Separator ====================
187
-
188
- type MenuSeparatorProps = {
189
- className?: string;
190
- };
191
-
192
- export const MenuSeparator = forwardRef<HTMLDivElement, MenuSeparatorProps>(
193
- ({ className }, ref) => {
194
- return (
195
- <div
196
- ref={ref}
197
- className={cn(
198
- "-mx-2 my-2 h-px bg-[var(--dropdown-menu-seperator-bg)]",
199
- className,
200
- )}
201
- />
202
- );
203
- },
204
- );
205
-
206
- MenuSeparator.displayName = "MenuSeparator";
207
-
208
- // ==================== Menu Label ====================
209
-
210
- type MenuLabelProps = {
211
- children: ReactNode;
212
- className?: string;
213
- };
214
-
215
- export const MenuLabel = forwardRef<HTMLDivElement, MenuLabelProps>(
216
- ({ children, className }, ref) => {
217
- return (
218
- <div
219
- ref={ref}
220
- className={cn(
221
- "px-3 py-2 typography-small4 text-text-g-contrast-medium",
222
- className,
223
- )}
224
- >
225
- {children}
226
- </div>
227
- );
228
- },
229
- );
230
-
231
- MenuLabel.displayName = "MenuLabel";
232
-
233
- // ==================== Exports ====================
234
-
235
- export default Menu;
@@ -1,45 +0,0 @@
1
- import { MenuItemType, MenuOption } from "./Menu";
2
-
3
- /**
4
- * Helper function to convert simple options to MenuItemType
5
- * Useful for integrating with Dropdown component
6
- */
7
- export function optionsToMenuItems(
8
- options: Array<{
9
- value: string;
10
- label: string | React.ReactNode;
11
- disabled?: boolean;
12
- renderLabel?: any;
13
- }>
14
- ): MenuItemType[] {
15
- return options.map((option) => ({
16
- type: "item" as const,
17
- item: {
18
- value: option.value,
19
- label: option.label,
20
- disabled: option.disabled,
21
- },
22
- }));
23
- }
24
-
25
- /**
26
- * Helper to add separator between menu items
27
- */
28
- export function withSeparator(
29
- items: MenuItemType[],
30
- atIndex: number
31
- ): MenuItemType[] {
32
- const result = [...items];
33
- result.splice(atIndex, 0, { type: "separator" });
34
- return result;
35
- }
36
-
37
- /**
38
- * Helper to add label/header to menu items
39
- */
40
- export function withLabel(
41
- label: string,
42
- items: MenuItemType[]
43
- ): MenuItemType[] {
44
- return [{ type: "label", label }, ...items];
45
- }
@@ -1,7 +0,0 @@
1
- export { Menu, MenuItem, MenuSeparator, MenuLabel } from "./Menu";
2
-
3
- export type { MenuOption, MenuItemType, MenuProps } from "./Menu";
4
-
5
- export { optionsToMenuItems, withSeparator, withLabel } from "./helpers";
6
-
7
- export { default } from "./Menu";
@@ -1,28 +0,0 @@
1
- :root[data-theme="xspector"] {
2
- /* ------------------------------------------------------------------ */
3
- /* DropdownMenu Component Tokens */
4
- /* ------------------------------------------------------------------ */
5
- /* Naming Convention: --[component]-[state]-[property] */
6
- /* Element: [default, hover, selected, disabled] */
7
- /* ------------------------------------------------------------------ */
8
-
9
- --dropdown-menu-seperator-bg: var(--transparent-white-8);
10
- --dropdown-menu-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.12);
11
-
12
- /* Default State */
13
- --dropdown-menu-default-bg: transparent;
14
- --dropdown-menu-default-text: inherit;
15
-
16
- /* Hover State */
17
- --dropdown-menu-hover-bg: var(--transparent-white-8);
18
- --dropdown-menu-hover-text: inherit;
19
-
20
- /* Selected State */
21
- --dropdown-menu-selected-bg: var(--ramps-grey-150);
22
- --dropdown-menu-selected-text: inherit;
23
-
24
- /* Disabled State */
25
- --dropdown-menu-disabled-bg: transparent;
26
- --dropdown-menu-disabled-text: var(--ramps-grey-140);
27
-
28
- }