@rovula/ui 0.0.78 → 0.0.80

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 (42) hide show
  1. package/dist/cjs/bundle.css +15 -3
  2. package/dist/cjs/bundle.js +3 -3
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +3 -0
  5. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +5 -1
  6. package/dist/cjs/types/components/Menu/Menu.d.ts +65 -0
  7. package/dist/cjs/types/components/Menu/Menu.stories.d.ts +31 -0
  8. package/dist/cjs/types/components/Menu/helpers.d.ts +19 -0
  9. package/dist/cjs/types/components/Menu/index.d.ts +4 -0
  10. package/dist/cjs/types/components/Search/Search.d.ts +46 -3
  11. package/dist/cjs/types/components/Search/Search.stories.d.ts +46 -27
  12. package/dist/cjs/types/index.d.ts +1 -0
  13. package/dist/components/Dropdown/Dropdown.js +41 -19
  14. package/dist/components/Dropdown/Dropdown.stories.js +13 -0
  15. package/dist/components/Menu/Menu.js +64 -0
  16. package/dist/components/Menu/Menu.stories.js +406 -0
  17. package/dist/components/Menu/helpers.js +28 -0
  18. package/dist/components/Menu/index.js +3 -0
  19. package/dist/esm/bundle.css +15 -3
  20. package/dist/esm/bundle.js +3 -3
  21. package/dist/esm/bundle.js.map +1 -1
  22. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +3 -0
  23. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +5 -1
  24. package/dist/esm/types/components/Menu/Menu.d.ts +65 -0
  25. package/dist/esm/types/components/Menu/Menu.stories.d.ts +31 -0
  26. package/dist/esm/types/components/Menu/helpers.d.ts +19 -0
  27. package/dist/esm/types/components/Menu/index.d.ts +4 -0
  28. package/dist/esm/types/components/Search/Search.d.ts +46 -3
  29. package/dist/esm/types/components/Search/Search.stories.d.ts +46 -27
  30. package/dist/esm/types/index.d.ts +1 -0
  31. package/dist/index.d.ts +111 -3
  32. package/dist/index.js +1 -0
  33. package/dist/src/theme/global.css +20 -4
  34. package/package.json +1 -1
  35. package/src/components/Dropdown/Dropdown.stories.tsx +31 -0
  36. package/src/components/Dropdown/Dropdown.tsx +73 -54
  37. package/src/components/Menu/Menu.stories.tsx +586 -0
  38. package/src/components/Menu/Menu.tsx +235 -0
  39. package/src/components/Menu/helpers.ts +45 -0
  40. package/src/components/Menu/index.ts +7 -0
  41. package/src/components/Search/Search.tsx +24 -11
  42. package/src/index.ts +1 -0
@@ -1,5 +1,6 @@
1
1
  import React, { CSSProperties, ReactNode } from "react";
2
2
  import { InputProps } from "../TextInput/TextInput";
3
+ import { MenuOption } from "../Menu/Menu";
3
4
  type RenderLabelCallbackArg = {
4
5
  value: string;
5
6
  label: string;
@@ -17,6 +18,7 @@ export type DropdownProps = {
17
18
  size?: "sm" | "md" | "lg";
18
19
  rounded?: "none" | "normal" | "full";
19
20
  variant?: "flat" | "outline" | "underline";
21
+ defaultMenuItemType?: MenuOption["type"];
20
22
  helperText?: string;
21
23
  errorMessage?: string;
22
24
  filterMode?: boolean;
@@ -47,6 +49,7 @@ declare const Dropdown: React.ForwardRefExoticComponent<{
47
49
  size?: "sm" | "md" | "lg";
48
50
  rounded?: "none" | "normal" | "full";
49
51
  variant?: "flat" | "outline" | "underline";
52
+ defaultMenuItemType?: MenuOption["type"];
50
53
  helperText?: string;
51
54
  errorMessage?: string;
52
55
  filterMode?: boolean;
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
- import { Options } from "./Dropdown";
2
+ import type { StoryObj } from "@storybook/react";
3
+ import Dropdown, { Options } from "./Dropdown";
3
4
  declare const meta: {
4
5
  title: string;
5
6
  component: React.ForwardRefExoticComponent<{
@@ -8,6 +9,7 @@ declare const meta: {
8
9
  size?: "sm" | "md" | "lg";
9
10
  rounded?: "none" | "normal" | "full";
10
11
  variant?: "flat" | "outline" | "underline";
12
+ defaultMenuItemType?: import("../Menu/Menu").MenuOption["type"];
11
13
  helperText?: string;
12
14
  errorMessage?: string;
13
15
  filterMode?: boolean;
@@ -42,6 +44,7 @@ declare const meta: {
42
44
  size?: "sm" | "md" | "lg" | undefined;
43
45
  rounded?: "none" | "normal" | "full" | undefined;
44
46
  variant?: "flat" | "outline" | "underline" | undefined;
47
+ defaultMenuItemType?: "checkbox" | "radio" | "default" | undefined;
45
48
  helperText?: string | undefined;
46
49
  errorMessage?: string | undefined;
47
50
  filterMode?: boolean | undefined;
@@ -405,3 +408,4 @@ export declare const CustomOption: {
405
408
  };
406
409
  render: (args: {}) => import("react/jsx-runtime").JSX.Element;
407
410
  };
411
+ export declare const WithIcons: StoryObj<typeof Dropdown>;
@@ -0,0 +1,65 @@
1
+ import React, { CSSProperties, ReactNode } from "react";
2
+ export type MenuOption = {
3
+ value: string;
4
+ label: ReactNode;
5
+ /**
6
+ * Visual type - กำหนดว่าจะแสดง icon อะไร
7
+ * - "default": ไม่มี icon (แค่ highlight background)
8
+ * - "checkbox": แสดง ✓ icon
9
+ * - "radio": แสดง ● icon
10
+ */
11
+ type?: "default" | "checkbox" | "radio";
12
+ icon?: ReactNode;
13
+ disabled?: boolean;
14
+ danger?: boolean;
15
+ checked?: boolean;
16
+ onClick?: () => void;
17
+ };
18
+ export type MenuItemType = {
19
+ type: "item";
20
+ item: MenuOption;
21
+ } | {
22
+ type: "separator";
23
+ } | {
24
+ type: "label";
25
+ label: string;
26
+ } | {
27
+ type: "custom";
28
+ render: () => ReactNode;
29
+ };
30
+ export type MenuProps = {
31
+ items: MenuItemType[];
32
+ /**
33
+ * Selected values - ใช้กับ type="item"
34
+ */
35
+ selectedValues?: string[];
36
+ /**
37
+ * Callback เมื่อเลือก item
38
+ * - ถ้า item.type="checkbox" → toggle checked state
39
+ * - ถ้า item.type="radio" → single select (clear others)
40
+ * - ถ้า item.type="default" หรือไม่ระบุ → ตาม selectedValues
41
+ */
42
+ onSelect?: (value: string, item: MenuOption) => void;
43
+ className?: string;
44
+ style?: CSSProperties;
45
+ isAbove?: boolean;
46
+ };
47
+ export declare const Menu: React.ForwardRefExoticComponent<MenuProps & React.RefAttributes<HTMLDivElement>>;
48
+ type MenuItemProps = {
49
+ option: MenuOption;
50
+ visualType: "default" | "checkbox" | "radio";
51
+ isChecked: boolean;
52
+ onSelect: () => void;
53
+ className?: string;
54
+ };
55
+ export declare const MenuItem: React.ForwardRefExoticComponent<MenuItemProps & React.RefAttributes<HTMLDivElement>>;
56
+ type MenuSeparatorProps = {
57
+ className?: string;
58
+ };
59
+ export declare const MenuSeparator: React.ForwardRefExoticComponent<MenuSeparatorProps & React.RefAttributes<HTMLDivElement>>;
60
+ type MenuLabelProps = {
61
+ children: ReactNode;
62
+ className?: string;
63
+ };
64
+ export declare const MenuLabel: React.ForwardRefExoticComponent<MenuLabelProps & React.RefAttributes<HTMLDivElement>>;
65
+ export default Menu;
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import type { StoryObj } from "@storybook/react";
3
+ import { Menu, MenuItemType } from "./Menu";
4
+ declare const meta: {
5
+ title: string;
6
+ component: React.ForwardRefExoticComponent<import("./Menu").MenuProps & React.RefAttributes<HTMLDivElement>>;
7
+ tags: string[];
8
+ parameters: {
9
+ layout: string;
10
+ };
11
+ decorators: ((Story: import("@storybook/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
12
+ items: MenuItemType[];
13
+ selectedValues?: string[] | undefined;
14
+ onSelect?: ((value: string, item: import("./Menu").MenuOption) => void) | undefined;
15
+ className?: string | undefined;
16
+ style?: React.CSSProperties | undefined;
17
+ isAbove?: boolean | undefined;
18
+ ref?: React.LegacyRef<HTMLDivElement> | undefined;
19
+ key?: React.Key | null | undefined;
20
+ }>) => import("react/jsx-runtime").JSX.Element)[];
21
+ };
22
+ export default meta;
23
+ export declare const Basic: StoryObj<typeof Menu>;
24
+ export declare const WithIcons: StoryObj<typeof Menu>;
25
+ export declare const WithCheckbox: StoryObj<typeof Menu>;
26
+ export declare const WithRadio: StoryObj<typeof Menu>;
27
+ export declare const ComplexMenu: StoryObj<typeof Menu>;
28
+ export declare const WithDropdownTrigger: StoryObj<typeof Menu>;
29
+ export declare const CustomItems: StoryObj<typeof Menu>;
30
+ export declare const DropdownPattern: StoryObj<typeof Menu>;
31
+ export declare const MultiSelectPattern: StoryObj<typeof Menu>;
@@ -0,0 +1,19 @@
1
+ import { MenuItemType } from "./Menu";
2
+ /**
3
+ * Helper function to convert simple options to MenuItemType
4
+ * Useful for integrating with Dropdown component
5
+ */
6
+ export declare function optionsToMenuItems(options: Array<{
7
+ value: string;
8
+ label: string | React.ReactNode;
9
+ disabled?: boolean;
10
+ renderLabel?: any;
11
+ }>): MenuItemType[];
12
+ /**
13
+ * Helper to add separator between menu items
14
+ */
15
+ export declare function withSeparator(items: MenuItemType[], atIndex: number): MenuItemType[];
16
+ /**
17
+ * Helper to add label/header to menu items
18
+ */
19
+ export declare function withLabel(label: string, items: MenuItemType[]): MenuItemType[];
@@ -0,0 +1,4 @@
1
+ export { Menu, MenuItem, MenuSeparator, MenuLabel } from "./Menu";
2
+ export type { MenuOption, MenuItemType, MenuProps } from "./Menu";
3
+ export { optionsToMenuItems, withSeparator, withLabel } from "./helpers";
4
+ export { default } from "./Menu";
@@ -1,5 +1,48 @@
1
1
  import React from "react";
2
- import { DropdownProps } from "../Dropdown/Dropdown";
3
- export type SearchProps = Omit<DropdownProps, "isFloatingLabel" | "keepCloseIconOnValue" | "hasClearIcon" | "hasSearchIcon" | "endIcon" | "filterMode" | "isFloatingLabel">;
4
- declare const Search: React.ForwardRefExoticComponent<SearchProps & React.RefAttributes<HTMLInputElement>>;
2
+ import { Options } from "../Dropdown/Dropdown";
3
+ import { InputProps } from "../TextInput/TextInput";
4
+ export type SearchProps = {
5
+ id?: string;
6
+ label?: string;
7
+ size?: "sm" | "md" | "lg";
8
+ rounded?: "none" | "normal" | "full";
9
+ variant?: "flat" | "outline" | "underline";
10
+ helperText?: string;
11
+ errorMessage?: string;
12
+ fullwidth?: boolean;
13
+ disabled?: boolean;
14
+ error?: boolean;
15
+ required?: boolean;
16
+ modal?: boolean;
17
+ className?: string;
18
+ optionContainerClassName?: string;
19
+ optionItemClassName?: string;
20
+ optionNotFoundItemClassName?: string;
21
+ options: Options[];
22
+ value?: Options;
23
+ onChangeText?: InputProps["onChange"];
24
+ onSelect?: (value: Options) => void;
25
+ } & Omit<InputProps, "value" | "onSelect">;
26
+ declare const Search: React.ForwardRefExoticComponent<{
27
+ id?: string;
28
+ label?: string;
29
+ size?: "sm" | "md" | "lg";
30
+ rounded?: "none" | "normal" | "full";
31
+ variant?: "flat" | "outline" | "underline";
32
+ helperText?: string;
33
+ errorMessage?: string;
34
+ fullwidth?: boolean;
35
+ disabled?: boolean;
36
+ error?: boolean;
37
+ required?: boolean;
38
+ modal?: boolean;
39
+ className?: string;
40
+ optionContainerClassName?: string;
41
+ optionItemClassName?: string;
42
+ optionNotFoundItemClassName?: string;
43
+ options: Options[];
44
+ value?: Options;
45
+ onChangeText?: InputProps["onChange"];
46
+ onSelect?: (value: Options) => void;
47
+ } & Omit<InputProps, "onSelect" | "value"> & React.RefAttributes<HTMLInputElement>>;
5
48
  export { Search };
@@ -2,18 +2,56 @@ import React from "react";
2
2
  import { Options } from "../Dropdown/Dropdown";
3
3
  declare const meta: {
4
4
  title: string;
5
- component: React.ForwardRefExoticComponent<import("./Search").SearchProps & React.RefAttributes<HTMLInputElement>>;
5
+ component: React.ForwardRefExoticComponent<{
6
+ id?: string;
7
+ label?: string;
8
+ size?: "sm" | "md" | "lg";
9
+ rounded?: "none" | "normal" | "full";
10
+ variant?: "flat" | "outline" | "underline";
11
+ helperText?: string;
12
+ errorMessage?: string;
13
+ fullwidth?: boolean;
14
+ disabled?: boolean;
15
+ error?: boolean;
16
+ required?: boolean;
17
+ modal?: boolean;
18
+ className?: string;
19
+ optionContainerClassName?: string;
20
+ optionItemClassName?: string;
21
+ optionNotFoundItemClassName?: string;
22
+ options: Options[];
23
+ value?: Options;
24
+ onChangeText?: import("../..").InputProps["onChange"];
25
+ onSelect?: (value: Options) => void;
26
+ } & Omit<import("../..").InputProps, "onSelect" | "value"> & React.RefAttributes<HTMLInputElement>>;
6
27
  tags: string[];
7
28
  parameters: {
8
29
  layout: string;
9
30
  };
10
31
  decorators: ((Story: import("@storybook/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
32
+ id?: string | undefined;
33
+ label?: string | undefined;
34
+ size?: "sm" | "md" | "lg" | undefined;
35
+ rounded?: "none" | "normal" | "full" | undefined;
11
36
  variant?: "flat" | "outline" | "underline" | undefined;
12
- suppressHydrationWarning?: boolean | undefined | undefined;
37
+ helperText?: string | undefined;
38
+ errorMessage?: string | undefined;
39
+ fullwidth?: boolean | undefined;
40
+ disabled?: boolean | undefined;
41
+ error?: boolean | undefined;
42
+ required?: boolean | undefined;
43
+ modal?: boolean | undefined;
13
44
  className?: string | undefined;
45
+ optionContainerClassName?: string | undefined;
46
+ optionItemClassName?: string | undefined;
47
+ optionNotFoundItemClassName?: string | undefined;
48
+ options: Options[];
49
+ value?: Options | undefined;
50
+ onChangeText?: React.ChangeEventHandler<HTMLInputElement> | undefined;
51
+ onSelect?: ((value: Options) => void) | undefined;
52
+ suppressHydrationWarning?: boolean | undefined | undefined;
14
53
  color?: string | undefined | undefined;
15
54
  height?: number | string | undefined | undefined;
16
- id?: string | undefined;
17
55
  lang?: string | undefined | undefined;
18
56
  max?: number | string | undefined | undefined;
19
57
  min?: number | string | undefined | undefined;
@@ -200,7 +238,6 @@ declare const meta: {
200
238
  onMouseOverCapture?: React.MouseEventHandler<HTMLInputElement> | undefined;
201
239
  onMouseUp?: React.MouseEventHandler<HTMLInputElement> | undefined;
202
240
  onMouseUpCapture?: React.MouseEventHandler<HTMLInputElement> | undefined;
203
- onSelect?: ((value: Options) => void) | undefined;
204
241
  onSelectCapture?: React.ReactEventHandler<HTMLInputElement> | undefined;
205
242
  onTouchCancel?: React.TouchEventHandler<HTMLInputElement> | undefined;
206
243
  onTouchCancelCapture?: React.TouchEventHandler<HTMLInputElement> | undefined;
@@ -243,18 +280,14 @@ declare const meta: {
243
280
  form?: string | undefined | undefined;
244
281
  list?: string | undefined | undefined;
245
282
  step?: number | string | undefined | undefined;
246
- error?: boolean | undefined;
247
- size?: "sm" | "md" | "lg" | undefined;
248
- disabled?: boolean | undefined;
249
- fullwidth?: boolean | undefined;
250
283
  title?: string | undefined | undefined;
251
284
  startIcon?: React.ReactNode;
285
+ endIcon?: React.ReactNode;
252
286
  formAction?: string | undefined;
253
287
  formEncType?: string | undefined | undefined;
254
288
  formMethod?: string | undefined | undefined;
255
289
  formNoValidate?: boolean | undefined | undefined;
256
290
  formTarget?: string | undefined | undefined;
257
- value?: Options | undefined;
258
291
  defaultChecked?: boolean | undefined | undefined;
259
292
  defaultValue?: string | number | readonly string[] | undefined;
260
293
  suppressContentEditableWarning?: boolean | undefined | undefined;
@@ -295,7 +328,9 @@ declare const meta: {
295
328
  unselectable?: "on" | "off" | undefined | undefined;
296
329
  inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
297
330
  is?: string | undefined | undefined;
298
- rounded?: "none" | "normal" | "full" | undefined;
331
+ hasClearIcon?: boolean | undefined;
332
+ hasSearchIcon?: boolean | undefined;
333
+ isFloatingLabel?: boolean | undefined;
299
334
  accept?: string | undefined | undefined;
300
335
  alt?: string | undefined | undefined;
301
336
  autoComplete?: React.HTMLInputAutoCompleteAttribute | undefined;
@@ -307,12 +342,9 @@ declare const meta: {
307
342
  pattern?: string | undefined | undefined;
308
343
  placeholder?: string | undefined | undefined;
309
344
  readOnly?: boolean | undefined | undefined;
310
- required?: boolean | undefined;
311
345
  src?: string | undefined | undefined;
312
- label?: string | undefined;
313
346
  iconMode?: "flat" | "solid" | undefined;
314
- helperText?: string | undefined;
315
- errorMessage?: string | undefined;
347
+ keepCloseIconOnValue?: boolean | undefined;
316
348
  labelClassName?: string | undefined;
317
349
  classes?: {
318
350
  iconWrapper?: string;
@@ -325,19 +357,6 @@ declare const meta: {
325
357
  onClickEndIcon?: (() => void) | undefined;
326
358
  renderStartIcon?: (() => React.ReactNode) | undefined;
327
359
  renderEndIcon?: (() => React.ReactNode) | undefined;
328
- modal?: boolean | undefined;
329
- optionContainerClassName?: string | undefined;
330
- optionItemClassName?: string | undefined;
331
- optionNotFoundItemClassName?: string | undefined;
332
- options: Options[];
333
- onChangeText?: React.ChangeEventHandler<HTMLInputElement> | undefined;
334
- renderOptions?: ((value: {
335
- optionsFiltered: Options[];
336
- selectedOption: Options | null | undefined;
337
- onClick: (option: Options) => void;
338
- style?: React.CSSProperties;
339
- dropdownRef?: React.RefObject<HTMLUListElement>;
340
- }) => React.ReactNode) | undefined;
341
360
  ref?: React.LegacyRef<HTMLInputElement> | undefined;
342
361
  key?: React.Key | null | undefined;
343
362
  }>) => import("react/jsx-runtime").JSX.Element)[];
@@ -30,6 +30,7 @@ export * from "./components/InputFilter/InputFilter";
30
30
  export * from "./components/Slider/Slider";
31
31
  export * from "./components/Switch/Switch";
32
32
  export * from "./components/DropdownMenu/DropdownMenu";
33
+ export * from "./components/Menu/Menu";
33
34
  export * from "./components/Tooltip/Tooltip";
34
35
  export * from "./components/Tooltip/TooltipSimple";
35
36
  export * from "./components/Toast/Toast";
package/dist/index.d.ts CHANGED
@@ -298,6 +298,70 @@ type TabsProps = {
298
298
  };
299
299
  declare const Tabs: React__default.FC<TabsProps>;
300
300
 
301
+ type MenuOption = {
302
+ value: string;
303
+ label: ReactNode;
304
+ /**
305
+ * Visual type - กำหนดว่าจะแสดง icon อะไร
306
+ * - "default": ไม่มี icon (แค่ highlight background)
307
+ * - "checkbox": แสดง ✓ icon
308
+ * - "radio": แสดง ● icon
309
+ */
310
+ type?: "default" | "checkbox" | "radio";
311
+ icon?: ReactNode;
312
+ disabled?: boolean;
313
+ danger?: boolean;
314
+ checked?: boolean;
315
+ onClick?: () => void;
316
+ };
317
+ type MenuItemType = {
318
+ type: "item";
319
+ item: MenuOption;
320
+ } | {
321
+ type: "separator";
322
+ } | {
323
+ type: "label";
324
+ label: string;
325
+ } | {
326
+ type: "custom";
327
+ render: () => ReactNode;
328
+ };
329
+ type MenuProps = {
330
+ items: MenuItemType[];
331
+ /**
332
+ * Selected values - ใช้กับ type="item"
333
+ */
334
+ selectedValues?: string[];
335
+ /**
336
+ * Callback เมื่อเลือก item
337
+ * - ถ้า item.type="checkbox" → toggle checked state
338
+ * - ถ้า item.type="radio" → single select (clear others)
339
+ * - ถ้า item.type="default" หรือไม่ระบุ → ตาม selectedValues
340
+ */
341
+ onSelect?: (value: string, item: MenuOption) => void;
342
+ className?: string;
343
+ style?: CSSProperties;
344
+ isAbove?: boolean;
345
+ };
346
+ declare const Menu: React__default.ForwardRefExoticComponent<MenuProps & React__default.RefAttributes<HTMLDivElement>>;
347
+ type MenuItemProps = {
348
+ option: MenuOption;
349
+ visualType: "default" | "checkbox" | "radio";
350
+ isChecked: boolean;
351
+ onSelect: () => void;
352
+ className?: string;
353
+ };
354
+ declare const MenuItem: React__default.ForwardRefExoticComponent<MenuItemProps & React__default.RefAttributes<HTMLDivElement>>;
355
+ type MenuSeparatorProps = {
356
+ className?: string;
357
+ };
358
+ declare const MenuSeparator: React__default.ForwardRefExoticComponent<MenuSeparatorProps & React__default.RefAttributes<HTMLDivElement>>;
359
+ type MenuLabelProps = {
360
+ children: ReactNode;
361
+ className?: string;
362
+ };
363
+ declare const MenuLabel: React__default.ForwardRefExoticComponent<MenuLabelProps & React__default.RefAttributes<HTMLDivElement>>;
364
+
301
365
  type RenderLabelCallbackArg$1 = {
302
366
  value: string;
303
367
  label: string;
@@ -315,6 +379,7 @@ type DropdownProps = {
315
379
  size?: "sm" | "md" | "lg";
316
380
  rounded?: "none" | "normal" | "full";
317
381
  variant?: "flat" | "outline" | "underline";
382
+ defaultMenuItemType?: MenuOption["type"];
318
383
  helperText?: string;
319
384
  errorMessage?: string;
320
385
  filterMode?: boolean;
@@ -345,6 +410,7 @@ declare const Dropdown: React__default.ForwardRefExoticComponent<{
345
410
  size?: "sm" | "md" | "lg";
346
411
  rounded?: "none" | "normal" | "full";
347
412
  variant?: "flat" | "outline" | "underline";
413
+ defaultMenuItemType?: MenuOption["type"];
348
414
  helperText?: string;
349
415
  errorMessage?: string;
350
416
  filterMode?: boolean;
@@ -588,8 +654,50 @@ declare const AlertDialogDescription: React.ForwardRefExoticComponent<Omit<Alert
588
654
  declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
589
655
  declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
590
656
 
591
- type SearchProps = Omit<DropdownProps, "isFloatingLabel" | "keepCloseIconOnValue" | "hasClearIcon" | "hasSearchIcon" | "endIcon" | "filterMode" | "isFloatingLabel">;
592
- declare const Search: React__default.ForwardRefExoticComponent<SearchProps & React__default.RefAttributes<HTMLInputElement>>;
657
+ type SearchProps = {
658
+ id?: string;
659
+ label?: string;
660
+ size?: "sm" | "md" | "lg";
661
+ rounded?: "none" | "normal" | "full";
662
+ variant?: "flat" | "outline" | "underline";
663
+ helperText?: string;
664
+ errorMessage?: string;
665
+ fullwidth?: boolean;
666
+ disabled?: boolean;
667
+ error?: boolean;
668
+ required?: boolean;
669
+ modal?: boolean;
670
+ className?: string;
671
+ optionContainerClassName?: string;
672
+ optionItemClassName?: string;
673
+ optionNotFoundItemClassName?: string;
674
+ options: Options$1[];
675
+ value?: Options$1;
676
+ onChangeText?: InputProps["onChange"];
677
+ onSelect?: (value: Options$1) => void;
678
+ } & Omit<InputProps, "value" | "onSelect">;
679
+ declare const Search: React__default.ForwardRefExoticComponent<{
680
+ id?: string;
681
+ label?: string;
682
+ size?: "sm" | "md" | "lg";
683
+ rounded?: "none" | "normal" | "full";
684
+ variant?: "flat" | "outline" | "underline";
685
+ helperText?: string;
686
+ errorMessage?: string;
687
+ fullwidth?: boolean;
688
+ disabled?: boolean;
689
+ error?: boolean;
690
+ required?: boolean;
691
+ modal?: boolean;
692
+ className?: string;
693
+ optionContainerClassName?: string;
694
+ optionItemClassName?: string;
695
+ optionNotFoundItemClassName?: string;
696
+ options: Options$1[];
697
+ value?: Options$1;
698
+ onChangeText?: InputProps["onChange"];
699
+ onSelect?: (value: Options$1) => void;
700
+ } & Omit<InputProps, "onSelect" | "value"> & React__default.RefAttributes<HTMLInputElement>>;
593
701
 
594
702
  type RenderLabelCallbackArg = {
595
703
  value: string;
@@ -918,4 +1026,4 @@ declare function usePrevious<T>(value: T): T | undefined;
918
1026
 
919
1027
  declare function cn(...inputs: ClassValue[]): string;
920
1028
 
921
- export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, type CustomSliderProps, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, FocusedScrollView, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, type MaskRule, MaskedTextInput, type MaskedTextInputProps, Navbar, type NavbarProps, NumberInput, type NumberInputProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, RadioGroup, RadioGroupItem, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextArea, type TextAreaProps, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, usePrevious, useToast };
1029
+ export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, type CustomSliderProps, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, FocusedScrollView, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, type MaskRule, MaskedTextInput, type MaskedTextInputProps, Menu, MenuItem, type MenuItemType, MenuLabel, type MenuOption, type MenuProps, MenuSeparator, Navbar, type NavbarProps, NumberInput, type NumberInputProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, RadioGroup, RadioGroupItem, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextArea, type TextAreaProps, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, usePrevious, useToast };
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ export * from "./components/InputFilter/InputFilter";
32
32
  export * from "./components/Slider/Slider";
33
33
  export * from "./components/Switch/Switch";
34
34
  export * from "./components/DropdownMenu/DropdownMenu";
35
+ export * from "./components/Menu/Menu";
35
36
  export * from "./components/Tooltip/Tooltip";
36
37
  export * from "./components/Tooltip/TooltipSimple";
37
38
  export * from "./components/Toast/Toast";
@@ -2344,6 +2344,10 @@ input[type=number] {
2344
2344
  z-index: 10;
2345
2345
  }
2346
2346
 
2347
+ .z-40 {
2348
+ z-index: 40;
2349
+ }
2350
+
2347
2351
  .z-50 {
2348
2352
  z-index: 50;
2349
2353
  }
@@ -2356,10 +2360,6 @@ input[type=number] {
2356
2360
  z-index: 100;
2357
2361
  }
2358
2362
 
2359
- .z-\[9999\] {
2360
- z-index: 9999;
2361
- }
2362
-
2363
2363
  .col-span-3 {
2364
2364
  grid-column: span 3 / span 3;
2365
2365
  }
@@ -2712,6 +2712,10 @@ input[type=number] {
2712
2712
  width: 2rem;
2713
2713
  }
2714
2714
 
2715
+ .w-80 {
2716
+ width: 20rem;
2717
+ }
2718
+
2715
2719
  .w-\[100px\] {
2716
2720
  width: 100px;
2717
2721
  }
@@ -6060,6 +6064,10 @@ input[type=number] {
6060
6064
  caret-color: color-mix(in srgb, var(--state-color-primary-default) calc(100% * 1), transparent);
6061
6065
  }
6062
6066
 
6067
+ .opacity-50 {
6068
+ opacity: 0.5;
6069
+ }
6070
+
6063
6071
  .opacity-60 {
6064
6072
  opacity: 0.6;
6065
6073
  }
@@ -6570,6 +6578,10 @@ input[type=number] {
6570
6578
  border-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
6571
6579
  }
6572
6580
 
6581
+ .hover\:bg-\[var\(--dropdown-menu-hover-bg\)\]:hover {
6582
+ background-color: var(--dropdown-menu-hover-bg);
6583
+ }
6584
+
6573
6585
  .hover\:bg-action-button-icon-active-hover:hover {
6574
6586
  --tw-bg-opacity: 1;
6575
6587
  background-color: color-mix(in srgb, var(--action-button-icon-active-hover-bg) calc(100% * var(--tw-bg-opacity, 1)), transparent);
@@ -6841,6 +6853,10 @@ input[type=number] {
6841
6853
  fill: color-mix(in srgb, var(--input-color-default-text) calc(100% * 1), transparent);
6842
6854
  }
6843
6855
 
6856
+ .hover\:text-\[var\(--dropdown-menu-hover-text\)\]:hover {
6857
+ color: var(--dropdown-menu-hover-text);
6858
+ }
6859
+
6844
6860
  .hover\:text-action-button-icon-active-hover:hover {
6845
6861
  --tw-text-opacity: 1;
6846
6862
  color: color-mix(in srgb, var(--action-button-icon-active-hover-text) calc(100% * var(--tw-text-opacity, 1)), transparent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rovula/ui",
3
- "version": "0.0.78",
3
+ "version": "0.0.80",
4
4
  "main": "dist/cjs/bundle.js",
5
5
  "module": "dist/esm/bundle.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,6 +3,8 @@ import type { Meta, StoryObj } from "@storybook/react";
3
3
  import Dropdown, { Options } from "./Dropdown";
4
4
  import Button from "../Button/Button";
5
5
  import { cn } from "@/utils/cn";
6
+ import { MenuItemType } from "../Menu/Menu";
7
+ import Icon from "../Icon/Icon";
6
8
 
7
9
  // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
8
10
  const meta = {
@@ -167,3 +169,32 @@ export const CustomOption = {
167
169
  );
168
170
  },
169
171
  } satisfies StoryObj;
172
+
173
+ // ==================== Advanced Menu Features ====================
174
+
175
+ export const WithIcons: StoryObj<typeof Dropdown> = {
176
+ render: () => {
177
+ const [selectedValue, setSelectedValue] = useState<Options | undefined>();
178
+
179
+ const optionsWithIcons: Options[] = [
180
+ { value: "apple", label: "🍎 Apple" },
181
+ { value: "banana", label: "🍌 Banana" },
182
+ { value: "carrot", label: "🥕 Carrot" },
183
+ { value: "broccoli", label: "🥦 Broccoli" },
184
+ ];
185
+
186
+ return (
187
+ <div className="flex flex-row gap-4 w-full">
188
+ <Dropdown
189
+ id="with-icons"
190
+ size="lg"
191
+ label="Select Food"
192
+ fullwidth
193
+ options={optionsWithIcons}
194
+ value={selectedValue}
195
+ onSelect={(option) => setSelectedValue(option)}
196
+ />
197
+ </div>
198
+ );
199
+ },
200
+ };