@rovula/ui 0.0.29 → 0.0.31

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 (77) hide show
  1. package/dist/cjs/bundle.css +139 -69
  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 +12 -0
  5. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +18 -0
  6. package/dist/cjs/types/components/InputFilter/InputFilter.d.ts +64 -0
  7. package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +370 -0
  8. package/dist/cjs/types/components/InputFilter/InputFilter.styles.d.ts +8 -0
  9. package/dist/cjs/types/components/Search/Search.d.ts +2 -20
  10. package/dist/cjs/types/components/Search/Search.stories.d.ts +26 -38
  11. package/dist/cjs/types/components/TextInput/TextInput.d.ts +10 -0
  12. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +10 -0
  13. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +1 -0
  14. package/dist/cjs/types/index.d.ts +1 -0
  15. package/dist/components/ActionButton/ActionButton.stories.js +1 -1
  16. package/dist/components/Checkbox/Checkbox.js +3 -3
  17. package/dist/components/Checkbox/Checkbox.stories.js +1 -1
  18. package/dist/components/DatePicker/DatePicker.js +2 -1
  19. package/dist/components/Dropdown/Dropdown.js +34 -19
  20. package/dist/components/Dropdown/Dropdown.stories.js +1 -0
  21. package/dist/components/Dropdown/Dropdown.styles.js +1 -1
  22. package/dist/components/InputFilter/InputFilter.js +124 -0
  23. package/dist/components/InputFilter/InputFilter.stories.js +34 -0
  24. package/dist/components/InputFilter/InputFilter.styles.js +65 -0
  25. package/dist/components/RadioGroup/RadioGroup.js +5 -2
  26. package/dist/components/RadioGroup/RadioGroup.stories.js +1 -1
  27. package/dist/components/Search/Search.js +1 -1
  28. package/dist/components/Search/Search.stories.js +2 -1
  29. package/dist/components/TextInput/TextInput.js +23 -6
  30. package/dist/components/TextInput/TextInput.styles.js +94 -20
  31. package/dist/esm/bundle.css +139 -69
  32. package/dist/esm/bundle.js +3 -3
  33. package/dist/esm/bundle.js.map +1 -1
  34. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +12 -0
  35. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +18 -0
  36. package/dist/esm/types/components/InputFilter/InputFilter.d.ts +64 -0
  37. package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +370 -0
  38. package/dist/esm/types/components/InputFilter/InputFilter.styles.d.ts +8 -0
  39. package/dist/esm/types/components/Search/Search.d.ts +2 -20
  40. package/dist/esm/types/components/Search/Search.stories.d.ts +26 -38
  41. package/dist/esm/types/components/TextInput/TextInput.d.ts +10 -0
  42. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +10 -0
  43. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +1 -0
  44. package/dist/esm/types/index.d.ts +1 -0
  45. package/dist/index.d.ts +82 -16
  46. package/dist/index.js +1 -0
  47. package/dist/src/theme/global.css +278 -161
  48. package/dist/theme/presets/colors.js +21 -0
  49. package/dist/theme/themes/xspector/color.css +13 -0
  50. package/dist/theme/themes/xspector/components/action-button.css +44 -42
  51. package/dist/theme/themes/xspector/state.css +1 -1
  52. package/dist/theme/tokens/color.css +13 -0
  53. package/dist/theme/tokens/components/action-button.css +42 -42
  54. package/package.json +1 -1
  55. package/src/components/ActionButton/ActionButton.stories.tsx +1 -1
  56. package/src/components/Checkbox/Checkbox.stories.tsx +1 -1
  57. package/src/components/Checkbox/Checkbox.tsx +4 -4
  58. package/src/components/DatePicker/DatePicker.tsx +4 -2
  59. package/src/components/Dropdown/Dropdown.stories.tsx +1 -0
  60. package/src/components/Dropdown/Dropdown.styles.ts +1 -1
  61. package/src/components/Dropdown/Dropdown.tsx +69 -38
  62. package/src/components/InputFilter/InputFilter.stories.tsx +72 -0
  63. package/src/components/InputFilter/InputFilter.styles.ts +74 -0
  64. package/src/components/InputFilter/InputFilter.tsx +314 -0
  65. package/src/components/RadioGroup/RadioGroup.stories.tsx +1 -1
  66. package/src/components/RadioGroup/RadioGroup.tsx +7 -9
  67. package/src/components/Search/Search.stories.tsx +3 -2
  68. package/src/components/Search/Search.tsx +13 -2
  69. package/src/components/TextInput/TextInput.styles.ts +94 -20
  70. package/src/components/TextInput/TextInput.tsx +53 -11
  71. package/src/index.ts +1 -0
  72. package/src/theme/presets/colors.js +21 -0
  73. package/src/theme/themes/xspector/color.css +13 -0
  74. package/src/theme/themes/xspector/components/action-button.css +44 -42
  75. package/src/theme/themes/xspector/state.css +1 -1
  76. package/src/theme/tokens/color.css +13 -0
  77. package/src/theme/tokens/components/action-button.css +42 -42
@@ -2,50 +2,18 @@ import React from "react";
2
2
  import { Options } from "../Dropdown/Dropdown";
3
3
  declare const meta: {
4
4
  title: string;
5
- component: React.ForwardRefExoticComponent<{
6
- id?: string | undefined;
7
- label?: string | undefined;
8
- size?: "sm" | "md" | "lg" | undefined;
9
- rounded?: "none" | "normal" | "full" | undefined;
10
- variant?: "outline" | "flat" | "underline" | undefined;
11
- helperText?: string | undefined;
12
- errorMessage?: string | undefined;
13
- filterMode?: boolean | undefined;
14
- fullwidth?: boolean | undefined;
15
- disabled?: boolean | undefined;
16
- error?: boolean | undefined;
17
- required?: boolean | undefined;
18
- className?: string | undefined;
19
- options: Options[];
20
- value?: Options | undefined;
21
- onChangeText?: React.ChangeEventHandler<HTMLInputElement> | undefined;
22
- onSelect?: ((value: Options) => void) | undefined;
23
- } & Omit<import("../..").InputProps, "value"> & React.RefAttributes<HTMLInputElement>>;
5
+ component: React.ForwardRefExoticComponent<import("./Search").SearchProps & React.RefAttributes<HTMLInputElement>>;
24
6
  tags: string[];
25
7
  parameters: {
26
8
  layout: string;
27
9
  };
28
10
  decorators: ((Story: import("@storybook/types").PartialStoryFn<import("@storybook/react").ReactRenderer, {
29
- id?: string | undefined;
30
- label?: string | undefined;
31
- size?: "sm" | "md" | "lg" | undefined;
32
- rounded?: "none" | "normal" | "full" | undefined;
33
11
  variant?: "outline" | "flat" | "underline" | undefined;
34
- helperText?: string | undefined;
35
- errorMessage?: string | undefined;
36
- filterMode?: boolean | undefined;
37
- fullwidth?: boolean | undefined;
38
- disabled?: boolean | undefined;
39
- error?: boolean | undefined;
40
- required?: boolean | undefined;
41
- className?: string | undefined;
42
- options: Options[];
43
- value?: Options | undefined;
44
- onChangeText?: React.ChangeEventHandler<HTMLInputElement> | undefined;
45
- onSelect?: (((value: Options) => void) & React.ReactEventHandler<HTMLInputElement>) | undefined;
46
12
  suppressHydrationWarning?: boolean | undefined;
13
+ className?: string | undefined;
47
14
  color?: string | undefined;
48
15
  height?: string | number | undefined;
16
+ id?: string | undefined;
49
17
  lang?: string | undefined;
50
18
  max?: string | number | undefined;
51
19
  min?: string | number | undefined;
@@ -232,6 +200,7 @@ declare const meta: {
232
200
  onMouseOverCapture?: React.MouseEventHandler<HTMLInputElement> | undefined;
233
201
  onMouseUp?: React.MouseEventHandler<HTMLInputElement> | undefined;
234
202
  onMouseUpCapture?: React.MouseEventHandler<HTMLInputElement> | undefined;
203
+ onSelect?: (((value: Options) => void) & React.ReactEventHandler<HTMLInputElement>) | undefined;
235
204
  onSelectCapture?: React.ReactEventHandler<HTMLInputElement> | undefined;
236
205
  onTouchCancel?: React.TouchEventHandler<HTMLInputElement> | undefined;
237
206
  onTouchCancelCapture?: React.TouchEventHandler<HTMLInputElement> | undefined;
@@ -274,14 +243,18 @@ declare const meta: {
274
243
  form?: string | undefined;
275
244
  list?: string | undefined;
276
245
  step?: string | number | undefined;
246
+ error?: boolean | undefined;
247
+ size?: "sm" | "md" | "lg" | undefined;
248
+ disabled?: boolean | undefined;
249
+ fullwidth?: boolean | undefined;
277
250
  title?: string | undefined;
278
251
  startIcon?: React.ReactNode;
279
- endIcon?: React.ReactNode;
280
252
  formAction?: string | undefined;
281
253
  formEncType?: string | undefined;
282
254
  formMethod?: string | undefined;
283
255
  formNoValidate?: boolean | undefined;
284
256
  formTarget?: string | undefined;
257
+ value?: Options | undefined;
285
258
  defaultChecked?: boolean | undefined;
286
259
  defaultValue?: string | number | readonly string[] | undefined;
287
260
  suppressContentEditableWarning?: boolean | undefined;
@@ -321,8 +294,7 @@ declare const meta: {
321
294
  unselectable?: "off" | "on" | undefined;
322
295
  inputMode?: "none" | "search" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
323
296
  is?: string | undefined;
324
- hasClearIcon?: boolean | undefined;
325
- hasSearchIcon?: boolean | undefined;
297
+ rounded?: "none" | "normal" | "full" | undefined;
326
298
  accept?: string | undefined;
327
299
  alt?: string | undefined;
328
300
  autoComplete?: React.HTMLInputAutoCompleteAttribute | undefined;
@@ -335,8 +307,23 @@ declare const meta: {
335
307
  pattern?: string | undefined;
336
308
  placeholder?: string | undefined;
337
309
  readOnly?: boolean | undefined;
310
+ required?: boolean | undefined;
338
311
  src?: string | undefined;
312
+ label?: string | undefined;
313
+ helperText?: string | undefined;
314
+ errorMessage?: string | undefined;
339
315
  labelClassName?: string | undefined;
316
+ onClickEndIcon?: (() => void) | undefined;
317
+ renderEndIcon?: (() => React.ReactNode) | undefined;
318
+ onClickStartIcon?: (() => void) | undefined;
319
+ options: Options[];
320
+ onChangeText?: React.ChangeEventHandler<HTMLInputElement> | undefined;
321
+ renderOptions?: ((value: {
322
+ optionsFiltered: Options[];
323
+ selectedOption: Options | null | undefined;
324
+ onClick: (option: Options) => void;
325
+ }) => React.ReactNode) | undefined;
326
+ optionContainerClassName?: string | undefined;
340
327
  ref?: React.LegacyRef<HTMLInputElement> | undefined;
341
328
  key?: React.Key | null | undefined;
342
329
  }>) => import("react/jsx-runtime").JSX.Element)[];
@@ -346,6 +333,7 @@ export declare const Default: {
346
333
  args: {
347
334
  label: string;
348
335
  fullwidth: boolean;
336
+ size: string;
349
337
  options: Options[];
350
338
  };
351
339
  render: (args: {}) => import("react/jsx-runtime").JSX.Element;
@@ -12,12 +12,17 @@ export type InputProps = {
12
12
  disabled?: boolean;
13
13
  error?: boolean;
14
14
  required?: boolean;
15
+ isFloatingLabel?: boolean;
16
+ keepCloseIconOnValue?: boolean;
15
17
  hasClearIcon?: boolean;
16
18
  hasSearchIcon?: boolean;
17
19
  startIcon?: ReactNode;
18
20
  endIcon?: ReactNode;
19
21
  className?: string;
20
22
  labelClassName?: string;
23
+ onClickStartIcon?: () => void;
24
+ onClickEndIcon?: () => void;
25
+ renderEndIcon?: () => ReactNode;
21
26
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">;
22
27
  export declare const TextInput: React.ForwardRefExoticComponent<{
23
28
  id?: string | undefined;
@@ -32,11 +37,16 @@ export declare const TextInput: React.ForwardRefExoticComponent<{
32
37
  disabled?: boolean | undefined;
33
38
  error?: boolean | undefined;
34
39
  required?: boolean | undefined;
40
+ isFloatingLabel?: boolean | undefined;
41
+ keepCloseIconOnValue?: boolean | undefined;
35
42
  hasClearIcon?: boolean | undefined;
36
43
  hasSearchIcon?: boolean | undefined;
37
44
  startIcon?: ReactNode;
38
45
  endIcon?: ReactNode;
39
46
  className?: string | undefined;
40
47
  labelClassName?: string | undefined;
48
+ onClickStartIcon?: (() => void) | undefined;
49
+ onClickEndIcon?: (() => void) | undefined;
50
+ renderEndIcon?: (() => ReactNode) | undefined;
41
51
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & React.RefAttributes<HTMLInputElement>>;
42
52
  export default TextInput;
@@ -14,12 +14,17 @@ declare const meta: {
14
14
  disabled?: boolean | undefined;
15
15
  error?: boolean | undefined;
16
16
  required?: boolean | undefined;
17
+ isFloatingLabel?: boolean | undefined;
18
+ keepCloseIconOnValue?: boolean | undefined;
17
19
  hasClearIcon?: boolean | undefined;
18
20
  hasSearchIcon?: boolean | undefined;
19
21
  startIcon?: React.ReactNode;
20
22
  endIcon?: React.ReactNode;
21
23
  className?: string | undefined;
22
24
  labelClassName?: string | undefined;
25
+ onClickStartIcon?: (() => void) | undefined;
26
+ onClickEndIcon?: (() => void) | undefined;
27
+ renderEndIcon?: (() => React.ReactNode) | undefined;
23
28
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & React.RefAttributes<HTMLInputElement>>;
24
29
  tags: string[];
25
30
  parameters: {
@@ -38,12 +43,17 @@ declare const meta: {
38
43
  disabled?: boolean | undefined;
39
44
  error?: boolean | undefined;
40
45
  required?: boolean | undefined;
46
+ isFloatingLabel?: boolean | undefined;
47
+ keepCloseIconOnValue?: boolean | undefined;
41
48
  hasClearIcon?: boolean | undefined;
42
49
  hasSearchIcon?: boolean | undefined;
43
50
  startIcon?: React.ReactNode;
44
51
  endIcon?: React.ReactNode;
45
52
  className?: string | undefined;
46
53
  labelClassName?: string | undefined;
54
+ onClickStartIcon?: (() => void) | undefined;
55
+ onClickEndIcon?: (() => void) | undefined;
56
+ renderEndIcon?: (() => React.ReactNode) | undefined;
47
57
  suppressHydrationWarning?: boolean | undefined;
48
58
  color?: string | undefined;
49
59
  height?: string | number | undefined;
@@ -15,6 +15,7 @@ export declare const labelVariant: (props?: ({
15
15
  disabled?: boolean | null | undefined;
16
16
  error?: boolean | null | undefined;
17
17
  hasSearchIcon?: boolean | null | undefined;
18
+ isFloatingLabel?: boolean | null | undefined;
18
19
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
19
20
  export declare const helperTextVariant: (props?: ({
20
21
  size?: "sm" | "md" | "lg" | null | undefined;
@@ -23,6 +23,7 @@ export * from "./components/DataTable/DataTable";
23
23
  export * from "./components/Dialog/Dialog";
24
24
  export * from "./components/AlertDialog/AlertDialog";
25
25
  export * from "./components/Search/Search";
26
+ export * from "./components/InputFilter/InputFilter";
26
27
  export * from "./components/Slider/Slider";
27
28
  export * from "./components/Switch/Switch";
28
29
  export * from "./components/DropdownMenu/DropdownMenu";
@@ -10,7 +10,7 @@ const meta = {
10
10
  layout: "fullscreen",
11
11
  },
12
12
  decorators: [
13
- (Story) => (_jsx("div", { className: "p-5", children: _jsx(Story, {}) })),
13
+ (Story) => (_jsx("div", { className: "p-5 bg-base-bg2", children: _jsx(Story, {}) })),
14
14
  ],
15
15
  };
16
16
  export default meta;
@@ -17,9 +17,9 @@ import { CheckIcon } from "@heroicons/react/16/solid";
17
17
  import { cn } from "@/utils/cn";
18
18
  const Checkbox = React.forwardRef((_a, ref) => {
19
19
  var { className } = _a, props = __rest(_a, ["className"]);
20
- return (_jsx(CheckboxPrimitive.Root, Object.assign({ ref: ref, className: cn("peer size-4 shrink-0 rounded-[var(--spacing-spacing-xxs,2px)] border border-primary ring-offset-background", "hover:border-primary-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:border-state-disable-solid disabled:text-state-disable-outline", {
21
- "data-[state=checked]:border-secondary data-[state=checked]:bg-secondary data-[state=checked]:text-secondary-foreground": !props.disabled,
22
- "hover:data-[state=checked]:border-secondary-hover hover:data-[state=checked]:bg-secondary-hover": !props.disabled,
20
+ return (_jsx(CheckboxPrimitive.Root, Object.assign({ ref: ref, className: cn("peer size-4 shrink-0 rounded-[var(--spacing-spacing-xxs,2px)] border border-function-default-solid ring-offset-background", "hover:border-function-default-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:border-state-disable-solid disabled:text-state-disable-outline", {
21
+ "data-[state=checked]:border-function-active-solid data-[state=checked]:bg-function-active-solid data-[state=checked]:text-function-active-icon": !props.disabled,
22
+ "hover:data-[state=checked]:border-function-active-hover hover:data-[state=checked]:bg-function-active-hover": !props.disabled,
23
23
  "bg-state-disable-solid": props.checked && props.disabled,
24
24
  }, className) }, props, { children: _jsx(CheckboxPrimitive.Indicator, { className: cn("flex items-center justify-center text-current"), children: _jsx(CheckIcon, { className: "size-4" }) }) })));
25
25
  });
@@ -8,7 +8,7 @@ const meta = {
8
8
  layout: "fullscreen",
9
9
  },
10
10
  decorators: [
11
- (Story) => (_jsx("div", { className: "p-5 flex w-full", children: _jsx(Story, {}) })),
11
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
12
12
  ],
13
13
  };
14
14
  export default meta;
@@ -20,7 +20,8 @@ import { format } from "date-fns/format";
20
20
  const DatePicker = (_a) => {
21
21
  var { date, onSelect, textInputProps } = _a, props = __rest(_a, ["date", "onSelect", "textInputProps"]);
22
22
  const [isOpen, setIsOpen] = useState(false);
23
- return (_jsx("div", { children: _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { className: "flex", children: _jsx(TextInput, Object.assign({ fullwidth: true, id: "2", readOnly: true, label: "Date", size: "md", value: date ? format(date, "dd MMM yyyy") : isOpen ? " " : "", hasClearIcon: false, endIcon: _jsx(CalendarIcon, { fill: "inherit" }) }, textInputProps)) }) }), _jsx(PopoverContent, { className: "w-auto p-0", children: _jsx(Calendar, Object.assign({ defaultMonth: date }, props, { mode: "single", selected: date, onSelect: (...value) => {
23
+ return (_jsx("div", { children: _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { className: "flex", children: _jsx(TextInput, Object.assign({ fullwidth: true, id: "2" // TODO
24
+ , readOnly: true, label: "Date", size: "md", value: date ? format(date, "dd MMM yyyy") : isOpen ? " " : "", hasClearIcon: false, endIcon: _jsx(CalendarIcon, { fill: "inherit", className: "cursor-pointer" }) }, textInputProps)) }) }), _jsx(PopoverContent, { className: "w-auto p-0", children: _jsx(Calendar, Object.assign({ defaultMonth: date }, props, { mode: "single", selected: date, onSelect: (...value) => {
24
25
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(...value);
25
26
  setIsOpen(false);
26
27
  } })) })] }) }));
@@ -14,21 +14,25 @@ import { Fragment, forwardRef, useCallback, useEffect, useMemo, useRef, useState
14
14
  import TextInput from "../TextInput/TextInput";
15
15
  import { customInputVariant, dropdownIconVariant, iconWrapperVariant, } from "./Dropdown.styles";
16
16
  import { ChevronDownIcon } from "@heroicons/react/16/solid";
17
+ import { cn } from "@/utils/cn";
17
18
  const Dropdown = forwardRef((_a, ref) => {
18
- var { id, options = [], value, label, size = "md", rounded = "normal", variant = "outline", helperText, errorMessage, fullwidth = true, disabled = false, error = false, filterMode = false, required = true, onChangeText, onSelect } = _a, props = __rest(_a, ["id", "options", "value", "label", "size", "rounded", "variant", "helperText", "errorMessage", "fullwidth", "disabled", "error", "filterMode", "required", "onChangeText", "onSelect"]);
19
+ var { id, options = [], value, label, size = "md", rounded = "normal", variant = "outline", helperText, errorMessage, fullwidth = true, disabled = false, error = false, filterMode = false, required = true, onChangeText, onSelect, renderOptions: customRenderOptions, optionContainerClassName } = _a, props = __rest(_a, ["id", "options", "value", "label", "size", "rounded", "variant", "helperText", "errorMessage", "fullwidth", "disabled", "error", "filterMode", "required", "onChangeText", "onSelect", "renderOptions", "optionContainerClassName"]);
19
20
  const _id = id || `${label}-select`;
20
21
  const [isFocused, setIsFocused] = useState(false);
21
22
  const [selectedOption, setSelectedOption] = useState(null);
22
23
  const [textValue, setTextValue] = useState("");
23
24
  const keyCode = useRef("");
24
25
  useEffect(() => {
25
- if (value && !selectedOption) {
26
- setSelectedOption(value);
27
- }
28
- }, [value, selectedOption]);
26
+ var _a;
27
+ setSelectedOption(value);
28
+ setTextValue((_a = value === null || value === void 0 ? void 0 : value.label) !== null && _a !== void 0 ? _a : "");
29
+ }, [value]);
29
30
  const handleOnChangeText = useCallback((event) => {
30
31
  onChangeText === null || onChangeText === void 0 ? void 0 : onChangeText(event);
31
32
  setTextValue(event.target.value);
33
+ if (!event.target.value) {
34
+ clearMismatchValue(event);
35
+ }
32
36
  }, [onChangeText]);
33
37
  const handleOptionClick = useCallback((option) => {
34
38
  setSelectedOption(option);
@@ -42,19 +46,30 @@ const Dropdown = forwardRef((_a, ref) => {
42
46
  ((_a = option.label) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(textValue === null || textValue === void 0 ? void 0 : textValue.toLowerCase()));
43
47
  });
44
48
  }, [options, filterMode, textValue]);
45
- const renderOptions = () => (_jsxs("ul", { className: "absolute mt-1 w-full bg-base-popup border border-base-popup text-base-popup-foreground rounded-md shadow-md z-10 max-h-60 overflow-y-auto", children: [optionsFiltered.map((option) => {
46
- if (option.renderLabel) {
47
- return (_jsx(Fragment, { children: option.renderLabel({
48
- value: option.value,
49
- label: option.label,
50
- handleOnClick: () => handleOptionClick(option),
51
- className: `px-4 py-2 hover:bg-gray-100 cursor-pointer ${(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) === option.value ? " bg-gray-200" : ""}`,
52
- }) }, option.value));
53
- }
54
- return (_jsx("li", { onMouseDown: () => handleOptionClick(option), className: `px-4 py-2 hover:bg-primary-hover-bg cursor-pointer ${(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) === option.value
55
- ? "bg-base-popup-highligh"
56
- : ""}`, children: option.label }, option.value));
57
- }), optionsFiltered.length === 0 && (_jsx("li", { className: "px-4 py-14 text-center text-input-text", children: "Not found" }))] }));
49
+ const renderOptions = () => {
50
+ if (customRenderOptions) {
51
+ return customRenderOptions({
52
+ optionsFiltered,
53
+ selectedOption,
54
+ onClick: handleOptionClick,
55
+ });
56
+ }
57
+ return (_jsxs("ul", { className: cn("absolute mt-1 w-full bg-base-popup border border-base-popup text-base-popup-foreground rounded-md shadow-md z-10 max-h-60 overflow-y-auto", optionContainerClassName), children: [optionsFiltered.map((option) => {
58
+ if (option.renderLabel) {
59
+ return (_jsx(Fragment, { children: option.renderLabel({
60
+ value: option.value,
61
+ label: option.label,
62
+ handleOnClick: () => handleOptionClick(option),
63
+ className: `px-4 py-2 hover:bg-gray-100 cursor-pointer ${(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) === option.value
64
+ ? " bg-gray-200"
65
+ : ""}`,
66
+ }) }, option.value));
67
+ }
68
+ return (_jsx("li", { onMouseDown: () => handleOptionClick(option), className: `px-4 py-2 hover:bg-primary-hover-bg cursor-pointer ${(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value) === option.value
69
+ ? "bg-base-popup-highligh"
70
+ : ""}`, children: option.label }, option.value));
71
+ }), optionsFiltered.length === 0 && (_jsx("li", { className: "px-4 py-14 text-center text-input-text", children: "Not found" }))] }));
72
+ };
58
73
  const handleOnFocus = useCallback((e) => {
59
74
  var _a;
60
75
  setIsFocused(true);
@@ -85,7 +100,7 @@ const Dropdown = forwardRef((_a, ref) => {
85
100
  setIsFocused(false);
86
101
  clearMismatchValue(e);
87
102
  (_a = props === null || props === void 0 ? void 0 : props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
88
- }, [props === null || props === void 0 ? void 0 : props.onBlur]);
103
+ }, [props === null || props === void 0 ? void 0 : props.onBlur, clearMismatchValue]);
89
104
  const handleOnKeyDown = useCallback((e) => {
90
105
  var _a;
91
106
  keyCode.current = e.code;
@@ -25,6 +25,7 @@ export const Default = {
25
25
  args: {
26
26
  label: "Choose an option:",
27
27
  fullwidth: true,
28
+ isFloatingLabel: true,
28
29
  options,
29
30
  },
30
31
  render: (args) => {
@@ -38,7 +38,7 @@ export const customInputVariant = cva([], {
38
38
  size: {
39
39
  sm: "pe-[30px]",
40
40
  md: "pe-[40px]",
41
- lg: "pe-[48px]",
41
+ lg: "pe-[68px]",
42
42
  },
43
43
  },
44
44
  defaultVariants: {
@@ -0,0 +1,124 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { Fragment, forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from "react";
14
+ import TextInput from "../TextInput/TextInput";
15
+ import { cn } from "@/utils/cn";
16
+ import { customInputVariant } from "../Dropdown/Dropdown.styles";
17
+ import Icon from "../Icon/Icon";
18
+ import { filterIconVariant } from "./InputFilter.styles";
19
+ import { Checkbox } from "../Checkbox/Checkbox";
20
+ const InputFilter = forwardRef((_a, ref) => {
21
+ var { id, options = [], values = [], label, size = "md", rounded = "normal", variant = "outline", helperText, errorMessage, fullwidth = true, disabled = false, error = false, filterMode = false, required = true, onChangeText, onSelect, renderOptions: customRenderOptions, optionContainerClassName } = _a, props = __rest(_a, ["id", "options", "values", "label", "size", "rounded", "variant", "helperText", "errorMessage", "fullwidth", "disabled", "error", "filterMode", "required", "onChangeText", "onSelect", "renderOptions", "optionContainerClassName"]);
22
+ const _id = id || `${label}-select`;
23
+ const [isFocused, setIsFocused] = useState(false);
24
+ const [selectedOptions, setSelectedOptions] = useState(values);
25
+ const [textValue, setTextValue] = useState("");
26
+ const keyCode = useRef("");
27
+ const containerRef = useRef(null);
28
+ useEffect(() => {
29
+ var _a;
30
+ setSelectedOptions(values !== null && values !== void 0 ? values : []);
31
+ setTextValue((_a = values === null || values === void 0 ? void 0 : values.map((option) => option.label).join(", ")) !== null && _a !== void 0 ? _a : "");
32
+ }, [values]);
33
+ useEffect(() => {
34
+ const handleClickOutside = (event) => {
35
+ if (containerRef.current &&
36
+ !containerRef.current.contains(event.target)) {
37
+ setIsFocused(false);
38
+ }
39
+ };
40
+ document.addEventListener("mousedown", handleClickOutside);
41
+ return () => document.removeEventListener("mousedown", handleClickOutside);
42
+ }, []);
43
+ const handleOnChangeText = useCallback((event) => {
44
+ onChangeText === null || onChangeText === void 0 ? void 0 : onChangeText(event);
45
+ setTextValue(event.target.value);
46
+ if (!event.target.value) {
47
+ clearMismatchValues(event);
48
+ }
49
+ }, [onChangeText]);
50
+ const handleOptionClick = useCallback((option) => {
51
+ const isSelected = selectedOptions.some((selected) => selected.value === option.value);
52
+ let newSelectedOptions = [...selectedOptions];
53
+ if (isSelected) {
54
+ newSelectedOptions = newSelectedOptions.filter((selected) => selected.value !== option.value);
55
+ }
56
+ else {
57
+ newSelectedOptions.push(option);
58
+ }
59
+ setSelectedOptions(newSelectedOptions);
60
+ setTextValue(newSelectedOptions.map((option) => option.label).join(", "));
61
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(newSelectedOptions);
62
+ }, [selectedOptions, onSelect]);
63
+ const optionsFiltered = useMemo(() => {
64
+ const lastText = textValue === null || textValue === void 0 ? void 0 : textValue.split(",").pop();
65
+ const filterText = lastText !== null && lastText !== void 0 ? lastText : "";
66
+ return options.filter((option) => {
67
+ var _a;
68
+ return !filterMode ||
69
+ ((_a = option.label) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(filterText === null || filterText === void 0 ? void 0 : filterText.toLowerCase()));
70
+ });
71
+ }, [options, filterMode, textValue]);
72
+ const renderOptions = () => {
73
+ if (customRenderOptions) {
74
+ return customRenderOptions({
75
+ optionsFiltered,
76
+ selectedOptions,
77
+ onClick: handleOptionClick,
78
+ });
79
+ }
80
+ return (_jsxs("ul", { className: cn("absolute mt-1 w-full bg-base-popup border border-base-popup text-base-popup-foreground rounded-md shadow-md z-10 max-h-60 overflow-y-auto", optionContainerClassName), children: [optionsFiltered.map((option) => {
81
+ if (option.renderLabel) {
82
+ return (_jsx(Fragment, { children: option.renderLabel({
83
+ value: option.value,
84
+ label: option.label,
85
+ handleOnClick: () => handleOptionClick(option),
86
+ className: `p-4 typography-subtitile4 hover:bg-gray-100 cursor-pointer flex items-center gap-3 ${selectedOptions.some((selected) => selected.value === option.value)
87
+ ? "bg-gray-200"
88
+ : ""}`,
89
+ }) }, option.value));
90
+ }
91
+ return (_jsxs("li", { onMouseDown: () => handleOptionClick(option), className: `p-4 typography-subtitile4 hover:bg-primary-hover-bg cursor-pointer flex items-center gap-3 ${selectedOptions.some((selected) => selected.value === option.value)
92
+ ? "bg-base-popup-highlight"
93
+ : ""}`, children: [_jsx(Checkbox, { checked: selectedOptions.some((selected) => selected.value === option.value) }), option.label] }, option.value));
94
+ }), optionsFiltered.length === 0 && (_jsx("li", { className: "px-4 py-14 text-center text-input-text", children: "Not found" }))] }));
95
+ };
96
+ const handleOnFocus = useCallback((e) => {
97
+ var _a;
98
+ setIsFocused(true);
99
+ (_a = props === null || props === void 0 ? void 0 : props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
100
+ }, [props === null || props === void 0 ? void 0 : props.onFocus]);
101
+ const clearMismatchValues = useCallback((e) => {
102
+ const matchSelectedValues = optionsFiltered.filter((opt) => { var _a, _b; return opt.value === ((_a = e.target) === null || _a === void 0 ? void 0 : _a.value) || opt.label === ((_b = e.target) === null || _b === void 0 ? void 0 : _b.value); });
103
+ if (keyCode.current === "Enter") {
104
+ return;
105
+ }
106
+ setSelectedOptions(matchSelectedValues);
107
+ setTextValue(matchSelectedValues.map((option) => option.label).join(", "));
108
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(matchSelectedValues);
109
+ }, [optionsFiltered, textValue]);
110
+ const handleOnKeyDown = useCallback((e) => {
111
+ var _a;
112
+ keyCode.current = e.code;
113
+ (_a = props === null || props === void 0 ? void 0 : props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, e);
114
+ }, [props === null || props === void 0 ? void 0 : props.onKeyDown]);
115
+ const filterIconClassName = filterIconVariant({
116
+ size: size,
117
+ rounded: rounded,
118
+ error: error,
119
+ active: !!values.length,
120
+ disabled,
121
+ });
122
+ return (_jsxs("div", { ref: containerRef, className: `relative ${fullwidth ? "w-full" : ""}`, children: [_jsx(TextInput, Object.assign({ hasClearIcon: false, endIcon: _jsx("div", { className: filterIconClassName, children: _jsx(Icon, { type: "heroicons", name: "adjustments-horizontal", variant: "outline", color: "inherit", stroke: "inherit", fill: "transparent" }) }) }, props, { ref: ref, readOnly: !filterMode, value: textValue, onChange: handleOnChangeText, label: label, placeholder: " ", type: "text", rounded: rounded, variant: variant, helperText: helperText, errorMessage: errorMessage, fullwidth: fullwidth, error: error, required: required, id: _id, disabled: disabled, size: size, className: customInputVariant({ size }), onFocus: handleOnFocus, onKeyDown: handleOnKeyDown })), isFocused && renderOptions()] }));
123
+ });
124
+ export { InputFilter };
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { InputFilter } from "./InputFilter";
4
+ const meta = {
5
+ title: "Components/InputFilter",
6
+ component: InputFilter,
7
+ tags: ["autodocs"],
8
+ parameters: {
9
+ layout: "fullscreen",
10
+ },
11
+ decorators: [
12
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
13
+ ],
14
+ };
15
+ export default meta;
16
+ const options = new Array(100).fill("").map((__, index) => ({
17
+ value: `option${index + 1}`,
18
+ label: `Option ${index + 1}`,
19
+ }));
20
+ export const Default = {
21
+ args: {
22
+ label: "Choose an option:",
23
+ fullwidth: true,
24
+ disabled: true,
25
+ options,
26
+ },
27
+ render: (args) => {
28
+ const [value, setValue] = useState([]);
29
+ const handleOnSelect = (values) => {
30
+ setValue(values);
31
+ };
32
+ return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(InputFilter, Object.assign({ id: "1", size: "lg", options: options, values: value, onSelect: handleOnSelect, optionContainerClassName: "h-[400px]" }, args)), _jsx(InputFilter, Object.assign({ id: "2", size: "md", options: options, values: value, onSelect: handleOnSelect }, args)), _jsx(InputFilter, Object.assign({ id: "3", size: "sm", options: options, values: value, onSelect: handleOnSelect }, args))] }));
33
+ },
34
+ };
@@ -0,0 +1,65 @@
1
+ import { cva } from "class-variance-authority";
2
+ export const filterIconVariant = cva([
3
+ // Base styles
4
+ "absolute contents items-center justify-center cursor-pointer",
5
+ // Border styles
6
+ "border-l border-l-input-default-stroke",
7
+ "peer-hover:border-l-input-active-stroke",
8
+ "peer-focus:border-l-input-active-stroke",
9
+ // Fill styles
10
+ "fill-primary",
11
+ "peer-hover:fill-input-filled-text",
12
+ "peer-focus:fill-input-filled-text",
13
+ // Stroke styles
14
+ "stroke-input-default-stroke",
15
+ "peer-hover:stroke-input-active-stroke",
16
+ "peer-focus:stroke-input-filled-text",
17
+ ], {
18
+ variants: {
19
+ size: {
20
+ sm: "p-1 size-[30px]",
21
+ md: "p-2 size-[38px]",
22
+ lg: "p-3 size-14",
23
+ },
24
+ rounded: {
25
+ none: "rounded-r-none",
26
+ normal: "rounded-r-xl",
27
+ full: "rounded-r-full",
28
+ },
29
+ error: {
30
+ true: "border-l-input-error",
31
+ },
32
+ position: {
33
+ start: "inset-y-0 left-0",
34
+ end: "inset-y-0 right-0",
35
+ },
36
+ active: {
37
+ false: "",
38
+ true: [
39
+ // Fill styles
40
+ "fill-primary-default",
41
+ "peer-hover:fill-primary-default", // TODO wait for refactor color after change function button colors
42
+ "peer-focus:fill-primary-hover", // TODO wait for refactor color after change function button colors
43
+ // Stroke styles
44
+ "stroke-primary-default",
45
+ "peer-hover:stroke-primary-default",
46
+ "peer-focus:stroke-primary-hover",
47
+ ],
48
+ },
49
+ disabled: {
50
+ true: [
51
+ "border-l-input-disable-stroke",
52
+ "fill-input-disable-stroke",
53
+ "stroke-input-disable-stroke",
54
+ ],
55
+ },
56
+ },
57
+ defaultVariants: {
58
+ size: "md",
59
+ rounded: "normal",
60
+ error: false,
61
+ position: "end",
62
+ active: false,
63
+ disabled: false,
64
+ },
65
+ });
@@ -1,4 +1,3 @@
1
- "use client";
2
1
  var __rest = (this && this.__rest) || function (s, e) {
3
2
  var t = {};
4
3
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -21,7 +20,11 @@ const RadioGroup = React.forwardRef((_a, ref) => {
21
20
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
22
21
  const RadioGroupItem = React.forwardRef((_a, ref) => {
23
22
  var { className } = _a, props = __rest(_a, ["className"]);
24
- return (_jsx(RadioGroupPrimitive.Item, Object.assign({ ref: ref, className: cn("aspect-square box-border size-4 rounded-full border border-primary text-primary", "hover:border-primary-hover", "focus:outline-none", "data-[state=checked]:border-secondary data-[state=checked]:text-secondary", "hover:data-[state=checked]:border-secondary-hover hover:data-[state=checked]:text-secondary-hover", "data-[disabled]:border-state-disable-solid data-[disabled]:fill-state-disable-solid data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none data-[disabled]:text-state-disable-solid", className) }, props, { children: _jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "fill-current text-current", children: _jsx("circle", { cx: "5", cy: "5", r: "5", fill: "current" }) }) }) })));
23
+ return (_jsx(RadioGroupPrimitive.Item, Object.assign({ ref: ref, className: cn("aspect-square box-border size-4 rounded-full border border-function-default-solid text-function-default-solid", "hover:border-function-default-hover", "focus:outline-none",
24
+ // Disabled state styles
25
+ "data-[disabled]:!border-state-disable-solid data-[disabled]:!fill-state-disable-solid data-[disabled]:!cursor-not-allowed data-[disabled]:!pointer-events-none data-[disabled]:!text-state-disable-solid",
26
+ // Checked state styles
27
+ "data-[state=checked]:border-function-active-solid data-[state=checked]:text-function-active-solid", "hover:data-[state=checked]:border-function-active-hover hover:data-[state=checked]:text-function-active-hover", className) }, props, { children: _jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "fill-current text-current", children: _jsx("circle", { cx: "5", cy: "5", r: "5", fill: "current" }) }) }) })));
25
28
  });
26
29
  RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
27
30
  export { RadioGroup, RadioGroupItem };
@@ -9,7 +9,7 @@ const meta = {
9
9
  layout: "fullscreen",
10
10
  },
11
11
  decorators: [
12
- (Story) => (_jsx("div", { className: "p-5 flex w-full", children: _jsx(Story, {}) })),
12
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
13
13
  ],
14
14
  };
15
15
  export default meta;
@@ -2,6 +2,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import Dropdown from "../Dropdown/Dropdown";
4
4
  const Search = forwardRef((props, ref) => {
5
- return (_jsx(Dropdown, Object.assign({}, props, { ref: ref, hasClearIcon: true, hasSearchIcon: true, label: "Search", endIcon: null, filterMode: true })));
5
+ return (_jsx(Dropdown, Object.assign({ label: "Search" }, props, { ref: ref, keepCloseIconOnValue: true, hasClearIcon: true, hasSearchIcon: true, endIcon: null, filterMode: true, isFloatingLabel: false })));
6
6
  });
7
7
  export { Search };