@tecsinapse/cortex-react 1.3.0-beta.1 → 1.3.0-beta.2

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 (44) hide show
  1. package/dist/cjs/components/Input.js +16 -16
  2. package/dist/cjs/components/Select/GroupedOptions.js +32 -0
  3. package/dist/cjs/components/Select/Option.js +25 -0
  4. package/dist/cjs/components/Select/Options.js +29 -0
  5. package/dist/cjs/components/Select/Popover.js +13 -0
  6. package/dist/cjs/components/Select/Root.js +31 -0
  7. package/dist/cjs/components/Select/Trigger.js +28 -0
  8. package/dist/cjs/components/Select/context.js +10 -0
  9. package/dist/cjs/components/Select/index.js +19 -0
  10. package/dist/cjs/hooks/useOutsideClickListener.js +22 -0
  11. package/dist/cjs/index.js +26 -20
  12. package/dist/cjs/service/SnackbarSonner.js +7 -1
  13. package/dist/esm/components/Input.js +12 -12
  14. package/dist/esm/components/Select/GroupedOptions.js +30 -0
  15. package/dist/esm/components/Select/Option.js +23 -0
  16. package/dist/esm/components/Select/Options.js +27 -0
  17. package/dist/esm/components/Select/Popover.js +11 -0
  18. package/dist/esm/components/Select/Root.js +29 -0
  19. package/dist/esm/components/Select/Trigger.js +26 -0
  20. package/dist/esm/components/Select/context.js +8 -0
  21. package/dist/esm/components/Select/index.js +17 -0
  22. package/dist/esm/hooks/useOutsideClickListener.js +20 -0
  23. package/dist/esm/index.js +13 -8
  24. package/dist/esm/service/SnackbarSonner.js +7 -1
  25. package/dist/types/components/Input.d.ts +5 -5
  26. package/dist/types/components/SearchInput.d.ts +3 -2
  27. package/dist/types/components/Select/GroupedOptions.d.ts +6 -0
  28. package/dist/types/components/Select/Option.d.ts +5 -0
  29. package/dist/types/components/Select/Options.d.ts +5 -0
  30. package/dist/types/components/Select/Popover.d.ts +5 -0
  31. package/dist/types/components/Select/Root.d.ts +8 -0
  32. package/dist/types/components/Select/Trigger.d.ts +5 -0
  33. package/dist/types/components/Select/context.d.ts +10 -0
  34. package/dist/types/components/Select/index.d.ts +8 -0
  35. package/dist/types/components/index.d.ts +2 -1
  36. package/dist/types/hooks/index.d.ts +1 -0
  37. package/dist/types/hooks/useOutsideClickListener.d.ts +7 -0
  38. package/dist/types/tests/useOutsideClickListener.test.d.ts +1 -0
  39. package/package.json +6 -4
  40. package/dist/cjs/components/SearchInput.js +0 -83
  41. package/dist/cjs/components/Select.js +0 -101
  42. package/dist/esm/components/SearchInput.js +0 -81
  43. package/dist/esm/components/Select.js +0 -96
  44. package/dist/types/components/Select.d.ts +0 -27
@@ -9,7 +9,7 @@ const getValidChildren = (children) => {
9
9
  (el) => React.isValidElement(el)
10
10
  );
11
11
  };
12
- const Box = React.forwardRef(
12
+ const InputBox = React.forwardRef(
13
13
  ({ id, name, variants, label, placeholder, className, ...rest }, ref) => {
14
14
  return /* @__PURE__ */ React.createElement("div", { className: "flex w-full flex-col" }, /* @__PURE__ */ React.createElement(
15
15
  "input",
@@ -33,7 +33,7 @@ const Box = React.forwardRef(
33
33
  ));
34
34
  }
35
35
  );
36
- const Face = React.forwardRef(
36
+ const InputFace = React.forwardRef(
37
37
  ({ children, variants, className, ...rest }, ref) => {
38
38
  const clones = getValidChildren(children).map((el) => {
39
39
  return React.cloneElement(el, { ...el.props, variants });
@@ -50,32 +50,32 @@ const Face = React.forwardRef(
50
50
  );
51
51
  }
52
52
  );
53
- const Root = React.forwardRef(
53
+ const InputRoot = React.forwardRef(
54
54
  ({ variants, className, ...rest }, ref) => {
55
- return /* @__PURE__ */ React.createElement(Face, { variants, className }, /* @__PURE__ */ React.createElement(Box, { ...rest, ref }));
55
+ return /* @__PURE__ */ React.createElement(InputFace, { variants, className }, /* @__PURE__ */ React.createElement(InputBox, { ...rest, ref }));
56
56
  }
57
57
  );
58
- const Left = React.forwardRef(
58
+ const InputLeft = React.forwardRef(
59
59
  ({ children, className, ...rest }, ref) => {
60
60
  return /* @__PURE__ */ React.createElement("div", { className: clsx.clsx(className, "mr-2.5"), ...rest, ref }, children);
61
61
  }
62
62
  );
63
- const Right = React.forwardRef(
63
+ const InputRight = React.forwardRef(
64
64
  ({ children, className, ...rest }, ref) => {
65
65
  return /* @__PURE__ */ React.createElement("div", { className: clsx.clsx(className, "ml-2.5"), ...rest, ref }, children);
66
66
  }
67
67
  );
68
68
  const Input = {
69
- Root,
70
- Face,
71
- Box,
72
- Left,
73
- Right
69
+ Root: InputRoot,
70
+ Face: InputFace,
71
+ Box: InputBox,
72
+ Left: InputLeft,
73
+ Right: InputRight
74
74
  };
75
75
 
76
- exports.Box = Box;
77
- exports.Face = Face;
78
76
  exports.Input = Input;
79
- exports.Left = Left;
80
- exports.Right = Right;
81
- exports.Root = Root;
77
+ exports.InputBox = InputBox;
78
+ exports.InputFace = InputFace;
79
+ exports.InputLeft = InputLeft;
80
+ exports.InputRight = InputRight;
81
+ exports.InputRoot = InputRoot;
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var cortexCore = require('@tecsinapse/cortex-core');
4
+ var React = require('react');
5
+ var index = require('./index.js');
6
+ var context = require('./context.js');
7
+
8
+ const { groupedTitle, containerGrouped } = cortexCore.selectVariants();
9
+ const SelectGroupedOptions = ({
10
+ onSelect,
11
+ groupedLabelExtractor,
12
+ options
13
+ }) => {
14
+ const { setOpen, keyExtractor } = React.useContext(context.SelectContext);
15
+ const handleSelect = React.useCallback(
16
+ (option) => {
17
+ onSelect(option);
18
+ setOpen?.(false);
19
+ },
20
+ [onSelect]
21
+ );
22
+ return /* @__PURE__ */ React.createElement("ul", { role: "select", className: containerGrouped() }, [...options ?? []].map(([key, value]) => /* @__PURE__ */ React.createElement("div", { key }, /* @__PURE__ */ React.createElement("span", { className: groupedTitle() }, groupedLabelExtractor?.(key)), value.map((option) => /* @__PURE__ */ React.createElement(
23
+ index.Select.Option,
24
+ {
25
+ option,
26
+ key: keyExtractor(option),
27
+ onSelectOption: handleSelect
28
+ }
29
+ )))));
30
+ };
31
+
32
+ exports.SelectGroupedOptions = SelectGroupedOptions;
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ var cortexCore = require('@tecsinapse/cortex-core');
4
+ var React = require('react');
5
+ var context = require('./context.js');
6
+
7
+ const SelectOption = ({
8
+ onSelectOption,
9
+ option
10
+ }) => {
11
+ const { keyExtractor, labelExtractor, value } = React.useContext(context.SelectContext);
12
+ return /* @__PURE__ */ React.createElement(
13
+ "li",
14
+ {
15
+ onClick: () => onSelectOption(option),
16
+ className: cortexCore.option({
17
+ selected: value && keyExtractor(value) === keyExtractor(option)
18
+ }),
19
+ role: "option"
20
+ },
21
+ labelExtractor(option)
22
+ );
23
+ };
24
+
25
+ exports.SelectOption = SelectOption;
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var index = require('./index.js');
5
+ var context = require('./context.js');
6
+
7
+ const SelectOptions = ({
8
+ onSelect,
9
+ options
10
+ }) => {
11
+ const { setOpen, keyExtractor } = React.useContext(context.SelectContext);
12
+ const handleSelect = React.useCallback(
13
+ (option) => {
14
+ onSelect(option);
15
+ setOpen?.(false);
16
+ },
17
+ [onSelect]
18
+ );
19
+ return /* @__PURE__ */ React.createElement("ul", { role: "select" }, (options ?? []).map((option) => /* @__PURE__ */ React.createElement(
20
+ index.Select.Option,
21
+ {
22
+ option,
23
+ key: keyExtractor(option),
24
+ onSelectOption: handleSelect
25
+ }
26
+ )));
27
+ };
28
+
29
+ exports.SelectOptions = SelectOptions;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var cortexCore = require('@tecsinapse/cortex-core');
4
+ var React = require('react');
5
+ var context = require('./context.js');
6
+
7
+ const { dropdown } = cortexCore.selectVariants();
8
+ const SelectPopover = ({ children }) => {
9
+ const { open } = React.useContext(context.SelectContext);
10
+ return /* @__PURE__ */ React.createElement("div", { className: dropdown({ open }), "data-testid": "select-popover" }, children);
11
+ };
12
+
13
+ exports.SelectPopover = SelectPopover;
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ require('@internationalized/date');
5
+ require('react-aria');
6
+ require('react-stately');
7
+ var useOutsideClickListener = require('../../hooks/useOutsideClickListener.js');
8
+ var context = require('./context.js');
9
+
10
+ const SelectRoot = ({
11
+ children,
12
+ value,
13
+ keyExtractor,
14
+ labelExtractor
15
+ }) => {
16
+ const [open, setOpen] = React.useState(false);
17
+ const ref = React.useRef(null);
18
+ useOutsideClickListener.useOutsideClickListener({
19
+ ref,
20
+ onClickOutside: () => setOpen?.(false)
21
+ });
22
+ return /* @__PURE__ */ React.createElement(
23
+ context.SelectContext.Provider,
24
+ {
25
+ value: { value, open, setOpen, keyExtractor, labelExtractor }
26
+ },
27
+ /* @__PURE__ */ React.createElement("div", { className: "w-full relative bg-white", ref }, children)
28
+ );
29
+ };
30
+
31
+ exports.SelectRoot = SelectRoot;
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var cortexCore = require('@tecsinapse/cortex-core');
4
+ var React = require('react');
5
+ var io5 = require('react-icons/io5');
6
+ var context = require('./context.js');
7
+
8
+ const { button } = cortexCore.selectVariants();
9
+ const SelectTrigger = ({ label, disabled }) => {
10
+ const { value, setOpen, labelExtractor, open } = React.useContext(context.SelectContext);
11
+ const placeholder = React.useMemo(
12
+ () => value ? labelExtractor(value) : label,
13
+ [label, value]
14
+ );
15
+ return /* @__PURE__ */ React.createElement(
16
+ "button",
17
+ {
18
+ className: button({ disabled }),
19
+ onClick: () => setOpen?.(!open),
20
+ disabled,
21
+ role: "button"
22
+ },
23
+ /* @__PURE__ */ React.createElement("span", { "data-testid": "select-placeholder" }, placeholder),
24
+ /* @__PURE__ */ React.createElement(io5.IoChevronDownOutline, null)
25
+ );
26
+ };
27
+
28
+ exports.SelectTrigger = SelectTrigger;
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ const SelectContext = React.createContext({
6
+ keyExtractor: () => "",
7
+ labelExtractor: () => ""
8
+ });
9
+
10
+ exports.SelectContext = SelectContext;
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ var GroupedOptions = require('./GroupedOptions.js');
4
+ var Option = require('./Option.js');
5
+ var Options = require('./Options.js');
6
+ var Popover = require('./Popover.js');
7
+ var Root = require('./Root.js');
8
+ var Trigger = require('./Trigger.js');
9
+
10
+ const Select = {
11
+ Root: Root.SelectRoot,
12
+ Trigger: Trigger.SelectTrigger,
13
+ Popover: Popover.SelectPopover,
14
+ Options: Options.SelectOptions,
15
+ GroupedOptions: GroupedOptions.SelectGroupedOptions,
16
+ Option: Option.SelectOption
17
+ };
18
+
19
+ exports.Select = Select;
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ const useOutsideClickListener = ({
6
+ ref,
7
+ onClickOutside
8
+ }) => {
9
+ const handleClickOutside = React.useCallback((event) => {
10
+ if (ref.current && !ref.current.contains(event.target)) {
11
+ onClickOutside?.();
12
+ }
13
+ }, []);
14
+ React.useEffect(() => {
15
+ document.addEventListener("click", handleClickOutside, true);
16
+ return () => {
17
+ document.removeEventListener("click", handleClickOutside, true);
18
+ };
19
+ }, [handleClickOutside]);
20
+ };
21
+
22
+ exports.useOutsideClickListener = useOutsideClickListener;
package/dist/cjs/index.js CHANGED
@@ -17,20 +17,25 @@ var Input = require('./components/Input.js');
17
17
  var Modal = require('./components/Modal.js');
18
18
  var ProgressBar = require('./components/ProgressBar.js');
19
19
  var RangeCalendar = require('./components/RangeCalendar.js');
20
- var Select = require('./components/Select.js');
21
- var Skeleton = require('./components/Skeleton.js');
22
- var Table = require('./components/Table.js');
23
- var Tag = require('./components/Tag.js');
24
- var TextArea = require('./components/TextArea.js');
25
- var TimeFieldInput = require('./components/TimeFieldInput.js');
26
- var Toggle = require('./components/Toggle.js');
20
+ require('react');
21
+ require('react-icons/ai');
22
+ require('react-icons/io5');
23
+ require('tailwind-merge');
27
24
  var useCalendar = require('./hooks/useCalendar.js');
28
25
  var useCalendarCell = require('./hooks/useCalendarCell.js');
29
26
  var useCalendarGrid = require('./hooks/useCalendarGrid.js');
30
27
  var useDatePickerInput = require('./hooks/useDatePickerInput.js');
31
28
  var useDateRangePickerInput = require('./hooks/useDateRangePickerInput.js');
32
29
  var useDebouncedState = require('./hooks/useDebouncedState.js');
30
+ var useOutsideClickListener = require('./hooks/useOutsideClickListener.js');
33
31
  var useRangeCalendar = require('./hooks/useRangeCalendar.js');
32
+ var index = require('./components/Select/index.js');
33
+ var Skeleton = require('./components/Skeleton.js');
34
+ var Table = require('./components/Table.js');
35
+ var Tag = require('./components/Tag.js');
36
+ var TextArea = require('./components/TextArea.js');
37
+ var TimeFieldInput = require('./components/TimeFieldInput.js');
38
+ var Toggle = require('./components/Toggle.js');
34
39
  var SnackbarSonner = require('./service/SnackbarSonner.js');
35
40
 
36
41
 
@@ -49,16 +54,24 @@ exports.DefaultSnack = DefaultSnack.DefaultSnack;
49
54
  exports.Drawer = Drawer.Drawer;
50
55
  exports.GroupButton = GroupButton.GroupButton;
51
56
  exports.Hint = Hint.Hint;
52
- exports.Box = Input.Box;
53
- exports.Face = Input.Face;
54
57
  exports.Input = Input.Input;
55
- exports.Left = Input.Left;
56
- exports.Right = Input.Right;
57
- exports.Root = Input.Root;
58
+ exports.InputBox = Input.InputBox;
59
+ exports.InputFace = Input.InputFace;
60
+ exports.InputLeft = Input.InputLeft;
61
+ exports.InputRight = Input.InputRight;
62
+ exports.InputRoot = Input.InputRoot;
58
63
  exports.Modal = Modal.Modal;
59
64
  exports.ProgressBar = ProgressBar.ProgressBar;
60
65
  exports.RangeCalendar = RangeCalendar.RangeCalendar;
61
- exports.Select = Select.Select;
66
+ exports.useCalendar = useCalendar.useCalendar;
67
+ exports.useCalendarCell = useCalendarCell.useCalendarCell;
68
+ exports.useCalendarGrid = useCalendarGrid.useCalendarGrid;
69
+ exports.useDatePickerInput = useDatePickerInput.useDatePickerInput;
70
+ exports.useDateRangePickerInput = useDateRangePickerInput.useDateRangePickerInput;
71
+ exports.useDebouncedState = useDebouncedState.useDebouncedState;
72
+ exports.useOutsideClickListener = useOutsideClickListener.useOutsideClickListener;
73
+ exports.useRangeCalendar = useRangeCalendar.useRangeCalendar;
74
+ exports.Select = index.Select;
62
75
  exports.Skeleton = Skeleton.Skeleton;
63
76
  exports.TCell = Table.TCell;
64
77
  exports.TFoot = Table.TFoot;
@@ -72,11 +85,4 @@ exports.Tag = Tag.Tag;
72
85
  exports.TextArea = TextArea.TextArea;
73
86
  exports.TimeFieldInput = TimeFieldInput.TimeFieldInput;
74
87
  exports.Toggle = Toggle.Toggle;
75
- exports.useCalendar = useCalendar.useCalendar;
76
- exports.useCalendarCell = useCalendarCell.useCalendarCell;
77
- exports.useCalendarGrid = useCalendarGrid.useCalendarGrid;
78
- exports.useDatePickerInput = useDatePickerInput.useDatePickerInput;
79
- exports.useDateRangePickerInput = useDateRangePickerInput.useDateRangePickerInput;
80
- exports.useDebouncedState = useDebouncedState.useDebouncedState;
81
- exports.useRangeCalendar = useRangeCalendar.useRangeCalendar;
82
88
  exports.SnackbarSonner = SnackbarSonner.SnackbarSonner;
@@ -23,7 +23,13 @@ require('../components/Modal.js');
23
23
  require('../styles/calendar-cell.js');
24
24
  require('../styles/groupButton.js');
25
25
  require('../styles/progressBar.js');
26
- require('../components/Select.js');
26
+ require('react-icons/ai');
27
+ require('react-icons/io5');
28
+ require('tailwind-merge');
29
+ require('../components/Select/GroupedOptions.js');
30
+ require('../components/Select/context.js');
31
+ require('../components/Select/Popover.js');
32
+ require('../components/Select/Trigger.js');
27
33
  require('../components/Tag.js');
28
34
  require('../components/TextArea.js');
29
35
  require('../components/Toggle.js');
@@ -7,7 +7,7 @@ const getValidChildren = (children) => {
7
7
  (el) => React.isValidElement(el)
8
8
  );
9
9
  };
10
- const Box = React.forwardRef(
10
+ const InputBox = React.forwardRef(
11
11
  ({ id, name, variants, label, placeholder, className, ...rest }, ref) => {
12
12
  return /* @__PURE__ */ React.createElement("div", { className: "flex w-full flex-col" }, /* @__PURE__ */ React.createElement(
13
13
  "input",
@@ -31,7 +31,7 @@ const Box = React.forwardRef(
31
31
  ));
32
32
  }
33
33
  );
34
- const Face = React.forwardRef(
34
+ const InputFace = React.forwardRef(
35
35
  ({ children, variants, className, ...rest }, ref) => {
36
36
  const clones = getValidChildren(children).map((el) => {
37
37
  return React.cloneElement(el, { ...el.props, variants });
@@ -48,27 +48,27 @@ const Face = React.forwardRef(
48
48
  );
49
49
  }
50
50
  );
51
- const Root = React.forwardRef(
51
+ const InputRoot = React.forwardRef(
52
52
  ({ variants, className, ...rest }, ref) => {
53
- return /* @__PURE__ */ React.createElement(Face, { variants, className }, /* @__PURE__ */ React.createElement(Box, { ...rest, ref }));
53
+ return /* @__PURE__ */ React.createElement(InputFace, { variants, className }, /* @__PURE__ */ React.createElement(InputBox, { ...rest, ref }));
54
54
  }
55
55
  );
56
- const Left = React.forwardRef(
56
+ const InputLeft = React.forwardRef(
57
57
  ({ children, className, ...rest }, ref) => {
58
58
  return /* @__PURE__ */ React.createElement("div", { className: clsx(className, "mr-2.5"), ...rest, ref }, children);
59
59
  }
60
60
  );
61
- const Right = React.forwardRef(
61
+ const InputRight = React.forwardRef(
62
62
  ({ children, className, ...rest }, ref) => {
63
63
  return /* @__PURE__ */ React.createElement("div", { className: clsx(className, "ml-2.5"), ...rest, ref }, children);
64
64
  }
65
65
  );
66
66
  const Input = {
67
- Root,
68
- Face,
69
- Box,
70
- Left,
71
- Right
67
+ Root: InputRoot,
68
+ Face: InputFace,
69
+ Box: InputBox,
70
+ Left: InputLeft,
71
+ Right: InputRight
72
72
  };
73
73
 
74
- export { Box, Face, Input, Left, Right, Root };
74
+ export { Input, InputBox, InputFace, InputLeft, InputRight, InputRoot };
@@ -0,0 +1,30 @@
1
+ import { selectVariants } from '@tecsinapse/cortex-core';
2
+ import React, { useContext, useCallback } from 'react';
3
+ import { Select } from './index.js';
4
+ import { SelectContext } from './context.js';
5
+
6
+ const { groupedTitle, containerGrouped } = selectVariants();
7
+ const SelectGroupedOptions = ({
8
+ onSelect,
9
+ groupedLabelExtractor,
10
+ options
11
+ }) => {
12
+ const { setOpen, keyExtractor } = useContext(SelectContext);
13
+ const handleSelect = useCallback(
14
+ (option) => {
15
+ onSelect(option);
16
+ setOpen?.(false);
17
+ },
18
+ [onSelect]
19
+ );
20
+ return /* @__PURE__ */ React.createElement("ul", { role: "select", className: containerGrouped() }, [...options ?? []].map(([key, value]) => /* @__PURE__ */ React.createElement("div", { key }, /* @__PURE__ */ React.createElement("span", { className: groupedTitle() }, groupedLabelExtractor?.(key)), value.map((option) => /* @__PURE__ */ React.createElement(
21
+ Select.Option,
22
+ {
23
+ option,
24
+ key: keyExtractor(option),
25
+ onSelectOption: handleSelect
26
+ }
27
+ )))));
28
+ };
29
+
30
+ export { SelectGroupedOptions };
@@ -0,0 +1,23 @@
1
+ import { option } from '@tecsinapse/cortex-core';
2
+ import React, { useContext } from 'react';
3
+ import { SelectContext } from './context.js';
4
+
5
+ const SelectOption = ({
6
+ onSelectOption,
7
+ option: option$1
8
+ }) => {
9
+ const { keyExtractor, labelExtractor, value } = useContext(SelectContext);
10
+ return /* @__PURE__ */ React.createElement(
11
+ "li",
12
+ {
13
+ onClick: () => onSelectOption(option$1),
14
+ className: option({
15
+ selected: value && keyExtractor(value) === keyExtractor(option$1)
16
+ }),
17
+ role: "option"
18
+ },
19
+ labelExtractor(option$1)
20
+ );
21
+ };
22
+
23
+ export { SelectOption };
@@ -0,0 +1,27 @@
1
+ import React, { useContext, useCallback } from 'react';
2
+ import { Select } from './index.js';
3
+ import { SelectContext } from './context.js';
4
+
5
+ const SelectOptions = ({
6
+ onSelect,
7
+ options
8
+ }) => {
9
+ const { setOpen, keyExtractor } = useContext(SelectContext);
10
+ const handleSelect = useCallback(
11
+ (option) => {
12
+ onSelect(option);
13
+ setOpen?.(false);
14
+ },
15
+ [onSelect]
16
+ );
17
+ return /* @__PURE__ */ React.createElement("ul", { role: "select" }, (options ?? []).map((option) => /* @__PURE__ */ React.createElement(
18
+ Select.Option,
19
+ {
20
+ option,
21
+ key: keyExtractor(option),
22
+ onSelectOption: handleSelect
23
+ }
24
+ )));
25
+ };
26
+
27
+ export { SelectOptions };
@@ -0,0 +1,11 @@
1
+ import { selectVariants } from '@tecsinapse/cortex-core';
2
+ import React, { useContext } from 'react';
3
+ import { SelectContext } from './context.js';
4
+
5
+ const { dropdown } = selectVariants();
6
+ const SelectPopover = ({ children }) => {
7
+ const { open } = useContext(SelectContext);
8
+ return /* @__PURE__ */ React.createElement("div", { className: dropdown({ open }), "data-testid": "select-popover" }, children);
9
+ };
10
+
11
+ export { SelectPopover };
@@ -0,0 +1,29 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import '@internationalized/date';
3
+ import 'react-aria';
4
+ import 'react-stately';
5
+ import { useOutsideClickListener } from '../../hooks/useOutsideClickListener.js';
6
+ import { SelectContext } from './context.js';
7
+
8
+ const SelectRoot = ({
9
+ children,
10
+ value,
11
+ keyExtractor,
12
+ labelExtractor
13
+ }) => {
14
+ const [open, setOpen] = useState(false);
15
+ const ref = useRef(null);
16
+ useOutsideClickListener({
17
+ ref,
18
+ onClickOutside: () => setOpen?.(false)
19
+ });
20
+ return /* @__PURE__ */ React.createElement(
21
+ SelectContext.Provider,
22
+ {
23
+ value: { value, open, setOpen, keyExtractor, labelExtractor }
24
+ },
25
+ /* @__PURE__ */ React.createElement("div", { className: "w-full relative bg-white", ref }, children)
26
+ );
27
+ };
28
+
29
+ export { SelectRoot };
@@ -0,0 +1,26 @@
1
+ import { selectVariants } from '@tecsinapse/cortex-core';
2
+ import React, { useContext, useMemo } from 'react';
3
+ import { IoChevronDownOutline } from 'react-icons/io5';
4
+ import { SelectContext } from './context.js';
5
+
6
+ const { button } = selectVariants();
7
+ const SelectTrigger = ({ label, disabled }) => {
8
+ const { value, setOpen, labelExtractor, open } = useContext(SelectContext);
9
+ const placeholder = useMemo(
10
+ () => value ? labelExtractor(value) : label,
11
+ [label, value]
12
+ );
13
+ return /* @__PURE__ */ React.createElement(
14
+ "button",
15
+ {
16
+ className: button({ disabled }),
17
+ onClick: () => setOpen?.(!open),
18
+ disabled,
19
+ role: "button"
20
+ },
21
+ /* @__PURE__ */ React.createElement("span", { "data-testid": "select-placeholder" }, placeholder),
22
+ /* @__PURE__ */ React.createElement(IoChevronDownOutline, null)
23
+ );
24
+ };
25
+
26
+ export { SelectTrigger };
@@ -0,0 +1,8 @@
1
+ import { createContext } from 'react';
2
+
3
+ const SelectContext = createContext({
4
+ keyExtractor: () => "",
5
+ labelExtractor: () => ""
6
+ });
7
+
8
+ export { SelectContext };
@@ -0,0 +1,17 @@
1
+ import { SelectGroupedOptions } from './GroupedOptions.js';
2
+ import { SelectOption } from './Option.js';
3
+ import { SelectOptions } from './Options.js';
4
+ import { SelectPopover } from './Popover.js';
5
+ import { SelectRoot } from './Root.js';
6
+ import { SelectTrigger } from './Trigger.js';
7
+
8
+ const Select = {
9
+ Root: SelectRoot,
10
+ Trigger: SelectTrigger,
11
+ Popover: SelectPopover,
12
+ Options: SelectOptions,
13
+ GroupedOptions: SelectGroupedOptions,
14
+ Option: SelectOption
15
+ };
16
+
17
+ export { Select };
@@ -0,0 +1,20 @@
1
+ import { useCallback, useEffect } from 'react';
2
+
3
+ const useOutsideClickListener = ({
4
+ ref,
5
+ onClickOutside
6
+ }) => {
7
+ const handleClickOutside = useCallback((event) => {
8
+ if (ref.current && !ref.current.contains(event.target)) {
9
+ onClickOutside?.();
10
+ }
11
+ }, []);
12
+ useEffect(() => {
13
+ document.addEventListener("click", handleClickOutside, true);
14
+ return () => {
15
+ document.removeEventListener("click", handleClickOutside, true);
16
+ };
17
+ }, [handleClickOutside]);
18
+ };
19
+
20
+ export { useOutsideClickListener };
package/dist/esm/index.js CHANGED
@@ -11,22 +11,27 @@ export { DefaultSnack } from './components/DefaultSnack.js';
11
11
  export { Drawer } from './components/Drawer.js';
12
12
  export { GroupButton } from './components/GroupButton.js';
13
13
  export { Hint } from './components/Hint.js';
14
- export { Box, Face, Input, Left, Right, Root } from './components/Input.js';
14
+ export { Input, InputBox, InputFace, InputLeft, InputRight, InputRoot } from './components/Input.js';
15
15
  export { Modal } from './components/Modal.js';
16
16
  export { ProgressBar } from './components/ProgressBar.js';
17
17
  export { RangeCalendar } from './components/RangeCalendar.js';
18
- export { Select } from './components/Select.js';
19
- export { Skeleton } from './components/Skeleton.js';
20
- export { TCell, TFoot, THead, THeadCell, TRow, TRowHeader, Table, Td } from './components/Table.js';
21
- export { Tag } from './components/Tag.js';
22
- export { TextArea } from './components/TextArea.js';
23
- export { TimeFieldInput } from './components/TimeFieldInput.js';
24
- export { Toggle } from './components/Toggle.js';
18
+ import 'react';
19
+ import 'react-icons/ai';
20
+ import 'react-icons/io5';
21
+ import 'tailwind-merge';
25
22
  export { useCalendar } from './hooks/useCalendar.js';
26
23
  export { useCalendarCell } from './hooks/useCalendarCell.js';
27
24
  export { useCalendarGrid } from './hooks/useCalendarGrid.js';
28
25
  export { useDatePickerInput } from './hooks/useDatePickerInput.js';
29
26
  export { useDateRangePickerInput } from './hooks/useDateRangePickerInput.js';
30
27
  export { useDebouncedState } from './hooks/useDebouncedState.js';
28
+ export { useOutsideClickListener } from './hooks/useOutsideClickListener.js';
31
29
  export { useRangeCalendar } from './hooks/useRangeCalendar.js';
30
+ export { Select } from './components/Select/index.js';
31
+ export { Skeleton } from './components/Skeleton.js';
32
+ export { TCell, TFoot, THead, THeadCell, TRow, TRowHeader, Table, Td } from './components/Table.js';
33
+ export { Tag } from './components/Tag.js';
34
+ export { TextArea } from './components/TextArea.js';
35
+ export { TimeFieldInput } from './components/TimeFieldInput.js';
36
+ export { Toggle } from './components/Toggle.js';
32
37
  export { SnackbarSonner } from './service/SnackbarSonner.js';
@@ -21,7 +21,13 @@ import '../components/Modal.js';
21
21
  import '../styles/calendar-cell.js';
22
22
  import '../styles/groupButton.js';
23
23
  import '../styles/progressBar.js';
24
- import '../components/Select.js';
24
+ import 'react-icons/ai';
25
+ import 'react-icons/io5';
26
+ import 'tailwind-merge';
27
+ import '../components/Select/GroupedOptions.js';
28
+ import '../components/Select/context.js';
29
+ import '../components/Select/Popover.js';
30
+ import '../components/Select/Trigger.js';
25
31
  import '../components/Tag.js';
26
32
  import '../components/TextArea.js';
27
33
  import '../components/Toggle.js';
@@ -6,15 +6,15 @@ export interface InputPropsBase {
6
6
  }
7
7
  export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement>, InputPropsBase {
8
8
  }
9
- export declare const Box: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
9
+ export declare const InputBox: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
10
10
  type DivBaseProps = React.HTMLAttributes<HTMLDivElement>;
11
- export declare const Face: React.ForwardRefExoticComponent<DivBaseProps & Pick<InputPropsBase, "variants"> & React.RefAttributes<HTMLDivElement>>;
12
- export declare const Root: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
13
- export declare const Left: React.ForwardRefExoticComponent<DivBaseProps & {
11
+ export declare const InputFace: React.ForwardRefExoticComponent<DivBaseProps & Pick<InputPropsBase, "variants"> & React.RefAttributes<HTMLDivElement>>;
12
+ export declare const InputRoot: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
13
+ export declare const InputLeft: React.ForwardRefExoticComponent<DivBaseProps & {
14
14
  children: React.ReactNode;
15
15
  className?: string | undefined;
16
16
  } & React.RefAttributes<HTMLDivElement>>;
17
- export declare const Right: React.ForwardRefExoticComponent<DivBaseProps & {
17
+ export declare const InputRight: React.ForwardRefExoticComponent<DivBaseProps & {
18
18
  children: React.ReactNode;
19
19
  className?: string | undefined;
20
20
  } & React.RefAttributes<HTMLDivElement>>;
@@ -1,4 +1,5 @@
1
- interface SearchInputProps {
1
+ import { HTMLAttributes } from 'react';
2
+ interface SearchInputProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'onChange'> {
2
3
  label?: string;
3
4
  placeholder?: string;
4
5
  isSubmitting?: boolean;
@@ -6,5 +7,5 @@ interface SearchInputProps {
6
7
  onClick?: (value: string) => void;
7
8
  BOUNCE_TIMEOUT?: number;
8
9
  }
9
- declare const SearchInput: ({ label, placeholder, isSubmitting, onChange, onClick, BOUNCE_TIMEOUT, }: SearchInputProps) => JSX.Element;
10
+ declare const SearchInput: ({ label, placeholder, isSubmitting, onChange, onClick, BOUNCE_TIMEOUT, className, ...rest }: SearchInputProps) => JSX.Element;
10
11
  export default SearchInput;
@@ -0,0 +1,6 @@
1
+ export interface SelectGroupedOptionsProps<T> {
2
+ onSelect: (value: T) => void;
3
+ options?: Map<string, T[]>;
4
+ groupedLabelExtractor: (value: string) => string;
5
+ }
6
+ export declare const SelectGroupedOptions: <T>({ onSelect, groupedLabelExtractor, options, }: SelectGroupedOptionsProps<T>) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ export interface SelectOptionProps<T> {
2
+ option: T;
3
+ onSelectOption: (option: T) => void;
4
+ }
5
+ export declare const SelectOption: <T>({ onSelectOption, option, }: SelectOptionProps<T>) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ export interface SelectOptionsProps<T> {
2
+ options?: T[];
3
+ onSelect: (value: T) => void;
4
+ }
5
+ export declare const SelectOptions: <T>({ onSelect, options, }: SelectOptionsProps<T>) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SelectPopoverProps {
3
+ children: ReactNode;
4
+ }
5
+ export declare const SelectPopover: ({ children }: SelectPopoverProps) => JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SelectRootProps<T> {
3
+ children: ReactNode;
4
+ value?: T;
5
+ keyExtractor: (value: T) => string;
6
+ labelExtractor: (value: T) => string;
7
+ }
8
+ export declare const SelectRoot: <T>({ children, value, keyExtractor, labelExtractor, }: SelectRootProps<T>) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ export interface SelectTriggerProps {
2
+ label: string;
3
+ disabled?: boolean;
4
+ }
5
+ export declare const SelectTrigger: ({ label, disabled }: SelectTriggerProps) => JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { Dispatch, SetStateAction } from 'react';
2
+ interface SelectContextProps<T> {
3
+ value?: T;
4
+ open?: boolean;
5
+ setOpen?: Dispatch<SetStateAction<boolean>>;
6
+ keyExtractor: (value: T) => string;
7
+ labelExtractor: (value: T) => string;
8
+ }
9
+ export declare const SelectContext: import("react").Context<SelectContextProps<any>>;
10
+ export {};
@@ -0,0 +1,8 @@
1
+ export declare const Select: {
2
+ Root: <T>({ children, value, keyExtractor, labelExtractor, }: import("./Root").SelectRootProps<T>) => JSX.Element;
3
+ Trigger: ({ label, disabled }: import("./Trigger").SelectTriggerProps) => JSX.Element;
4
+ Popover: ({ children }: import("./Popover").SelectPopoverProps) => JSX.Element;
5
+ Options: <T_1>({ onSelect, options, }: import("./Options").SelectOptionsProps<T_1>) => JSX.Element;
6
+ GroupedOptions: <T_2>({ onSelect, groupedLabelExtractor, options, }: import("./GroupedOptions").SelectGroupedOptionsProps<T_2>) => JSX.Element;
7
+ Option: <T_3>({ onSelectOption, option, }: import("./Option").SelectOptionProps<T_3>) => JSX.Element;
8
+ };
@@ -15,7 +15,8 @@ export * from './Input';
15
15
  export * from './Modal';
16
16
  export * from './ProgressBar';
17
17
  export * from './RangeCalendar';
18
- export { default as Select } from './Select';
18
+ export * from './SearchInput';
19
+ export * from './Select';
19
20
  export * from './Skeleton';
20
21
  export * from './Table';
21
22
  export * from './Tag';
@@ -4,4 +4,5 @@ export * from './useCalendarGrid';
4
4
  export * from './useDatePickerInput';
5
5
  export * from './useDateRangePickerInput';
6
6
  export * from './useDebouncedState';
7
+ export * from './useOutsideClickListener';
7
8
  export * from './useRangeCalendar';
@@ -0,0 +1,7 @@
1
+ import { MutableRefObject } from 'react';
2
+ interface useOutsideClickListenerProps {
3
+ ref: MutableRefObject<any>;
4
+ onClickOutside?: () => void;
5
+ }
6
+ export declare const useOutsideClickListener: ({ ref, onClickOutside, }: useOutsideClickListenerProps) => void;
7
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tecsinapse/cortex-react",
3
- "version": "1.3.0-beta.1",
3
+ "version": "1.3.0-beta.2",
4
4
  "description": "React components based in @tecsinapse/cortex-core",
5
5
  "license": "MIT",
6
6
  "main": "dist/esm/index.js",
@@ -18,12 +18,14 @@
18
18
  "test:watch": "jest --watch"
19
19
  },
20
20
  "dependencies": {
21
- "@tecsinapse/cortex-core": "0.2.2-beta.2",
21
+ "@internationalized/date": "*",
22
+ "@tecsinapse/cortex-core": "0.3.0-beta.0",
22
23
  "clsx": "*",
23
24
  "react-aria": "^3.33.1",
24
25
  "react-icons": "^5.2.1",
25
26
  "react-stately": "^3.31.1",
26
- "sonner": "^1.5.0"
27
+ "sonner": "^1.5.0",
28
+ "tailwind-merge": "*"
27
29
  },
28
30
  "repository": {
29
31
  "type": "git",
@@ -39,5 +41,5 @@
39
41
  "react-dom": ">=18.0.0",
40
42
  "tailwind": ">=3.3.0"
41
43
  },
42
- "gitHead": "db686bfbca61f00d03a355fbb00cfa88646b68ed"
44
+ "gitHead": "cc8903eb4c3ec693fa6dbd384bfc407f39e144ae"
43
45
  }
@@ -1,83 +0,0 @@
1
- 'use strict';
2
-
3
- var React = require('react');
4
- require('clsx');
5
- require('@internationalized/date');
6
- require('./Badge.js');
7
- require('./BaseSnackbar.js');
8
- require('react-icons/md');
9
- require('./Card.js');
10
- var Button = require('./Button.js');
11
- require('react-aria');
12
- require('react-stately');
13
- var useDebouncedState = require('../hooks/useDebouncedState.js');
14
- require('./CalendarCell.js');
15
- require('@tecsinapse/cortex-core');
16
- require('react-icons/fa');
17
- require('react-icons/lia');
18
- var Input = require('./Input.js');
19
- require('react-icons/io');
20
- require('./GroupButton.js');
21
- require('./Hint.js');
22
- require('./Modal.js');
23
- require('../styles/calendar-cell.js');
24
- require('../styles/groupButton.js');
25
- require('../styles/progressBar.js');
26
- require('./Select.js');
27
- require('./Tag.js');
28
- require('./TextArea.js');
29
- require('./Toggle.js');
30
- var ai = require('react-icons/ai');
31
- var io5 = require('react-icons/io5');
32
-
33
- const inputFace = "bg-white w-full";
34
- const inputLeft = "flex items-center";
35
- const SearchInput = ({
36
- label,
37
- placeholder,
38
- isSubmitting = false,
39
- onChange,
40
- onClick,
41
- BOUNCE_TIMEOUT = 1e3
42
- }) => {
43
- const [bouncedText, setBouncedText] = React.useState("");
44
- const [searchInput, setSearchInput] = useDebouncedState.useDebouncedState(
45
- "",
46
- setBouncedText,
47
- BOUNCE_TIMEOUT
48
- );
49
- React.useEffect(() => {
50
- if (onChange) {
51
- onChange(bouncedText);
52
- }
53
- }, [bouncedText]);
54
- const handleEnterKey = (e) => {
55
- if (e.key === "Enter" && onClick && searchInput) {
56
- onClick(searchInput);
57
- }
58
- };
59
- return /* @__PURE__ */ React.createElement("div", { className: "flex flex-row w-full space-x-mili" }, /* @__PURE__ */ React.createElement(Input.Input.Face, { variants: { className: inputFace } }, !onClick && /* @__PURE__ */ React.createElement(Input.Input.Left, { className: inputLeft }, /* @__PURE__ */ React.createElement(io5.IoSearchOutline, { "data-testid": "icon-search-left" })), /* @__PURE__ */ React.createElement(
60
- Input.Input.Box,
61
- {
62
- placeholder,
63
- label,
64
- onChange: (e) => setSearchInput(e.target.value),
65
- onKeyDown: handleEnterKey,
66
- disabled: isSubmitting
67
- }
68
- )), onClick && /* @__PURE__ */ React.createElement(
69
- Button.Button,
70
- {
71
- variants: {
72
- intent: "primary",
73
- size: "square",
74
- className: "h-11"
75
- },
76
- onClick: () => onClick(searchInput),
77
- disabled: !searchInput || isSubmitting
78
- },
79
- isSubmitting ? /* @__PURE__ */ React.createElement("div", { className: "animate-spin" }, /* @__PURE__ */ React.createElement(ai.AiOutlineLoading, { "data-testid": "icon-loading" })) : /* @__PURE__ */ React.createElement(io5.IoSearchOutline, { "data-testid": "icon-search-button" })
80
- ));
81
- };
82
-
83
- module.exports = SearchInput;
@@ -1,101 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var cortexCore = require('@tecsinapse/cortex-core');
6
- var React = require('react');
7
- var io = require('react-icons/io');
8
- var io5 = require('react-icons/io5');
9
- var Hint = require('./Hint.js');
10
- var SearchInput = require('./SearchInput.js');
11
-
12
- const { button, dropdown, groupedTitle, containerGrouped, hintBody } = cortexCore.selectVariants();
13
- const Select = (props) => {
14
- const {
15
- label,
16
- keyExtractor,
17
- labelExtractor,
18
- options,
19
- value,
20
- onSelect,
21
- onSearch,
22
- disabled,
23
- grouped,
24
- groupedLabelExtractor,
25
- hint,
26
- placeholderSearchInput,
27
- variant = "default"
28
- } = props;
29
- const [open, setOpen] = React.useState(false);
30
- const placeholder = React.useMemo(
31
- () => value ? labelExtractor(value) : label,
32
- [label, labelExtractor, value]
33
- );
34
- const ref = React.useRef(null);
35
- const handleClickOutside = React.useCallback((event) => {
36
- if (ref.current && !ref.current.contains(event.target)) {
37
- setOpen(false);
38
- }
39
- }, []);
40
- const handleSelect = React.useCallback(
41
- (option) => {
42
- onSelect(option);
43
- setOpen(false);
44
- },
45
- [onSelect]
46
- );
47
- React.useEffect(() => {
48
- document.addEventListener("click", handleClickOutside, true);
49
- return () => {
50
- document.removeEventListener("click", handleClickOutside, true);
51
- };
52
- }, [handleClickOutside]);
53
- const Option = ({ option }) => /* @__PURE__ */ React.createElement(
54
- "li",
55
- {
56
- onClick: () => handleSelect(option),
57
- className: cortexCore.option(),
58
- role: "option"
59
- },
60
- labelExtractor(option)
61
- );
62
- const GroupedOptions = ({ options: options2 }) => /* @__PURE__ */ React.createElement(React.Fragment, null, [...options2 ?? []].map(([key, value2]) => /* @__PURE__ */ React.createElement("div", { key, className: containerGrouped() }, /* @__PURE__ */ React.createElement("span", { className: groupedTitle() }, groupedLabelExtractor?.(key)), value2.map((option) => /* @__PURE__ */ React.createElement(Option, { option, key: keyExtractor(option) })))));
63
- const DefaultOptions = ({ options: options2 }) => /* @__PURE__ */ React.createElement(React.Fragment, null, (options2 ?? []).map((option) => /* @__PURE__ */ React.createElement(Option, { option, key: keyExtractor(option) })));
64
- return /* @__PURE__ */ React.createElement("div", { className: "w-full relative bg-white", ref }, /* @__PURE__ */ React.createElement(
65
- "button",
66
- {
67
- className: button({ disabled, intent: variant }),
68
- onClick: () => setOpen((prevState) => !prevState),
69
- disabled
70
- },
71
- /* @__PURE__ */ React.createElement("span", { "data-testid": "select-placeholder" }, placeholder),
72
- /* @__PURE__ */ React.createElement(io5.IoChevronDownOutline, null)
73
- ), /* @__PURE__ */ React.createElement(
74
- "ul",
75
- {
76
- role: "select",
77
- className: dropdown({
78
- open
79
- })
80
- },
81
- onSearch ? /* @__PURE__ */ React.createElement("div", { className: "m-mili" }, /* @__PURE__ */ React.createElement(
82
- SearchInput,
83
- {
84
- placeholder: placeholderSearchInput,
85
- onChange: onSearch
86
- }
87
- )) : /* @__PURE__ */ React.createElement(React.Fragment, null),
88
- grouped ? /* @__PURE__ */ React.createElement(GroupedOptions, { options }) : /* @__PURE__ */ React.createElement(DefaultOptions, { options })
89
- ), hint && /* @__PURE__ */ React.createElement(
90
- Hint.Hint,
91
- {
92
- variants: {
93
- intent: variant
94
- }
95
- },
96
- /* @__PURE__ */ React.createElement("div", { className: hintBody() }, variant === "error" ? /* @__PURE__ */ React.createElement(io.IoIosCloseCircleOutline, { "data-testid": "select-hint-error-icon" }) : /* @__PURE__ */ React.createElement(React.Fragment, null), /* @__PURE__ */ React.createElement("span", null, hint))
97
- ));
98
- };
99
-
100
- exports.Select = Select;
101
- exports.default = Select;
@@ -1,81 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import 'clsx';
3
- import '@internationalized/date';
4
- import './Badge.js';
5
- import './BaseSnackbar.js';
6
- import 'react-icons/md';
7
- import './Card.js';
8
- import { Button } from './Button.js';
9
- import 'react-aria';
10
- import 'react-stately';
11
- import { useDebouncedState } from '../hooks/useDebouncedState.js';
12
- import './CalendarCell.js';
13
- import '@tecsinapse/cortex-core';
14
- import 'react-icons/fa';
15
- import 'react-icons/lia';
16
- import { Input } from './Input.js';
17
- import 'react-icons/io';
18
- import './GroupButton.js';
19
- import './Hint.js';
20
- import './Modal.js';
21
- import '../styles/calendar-cell.js';
22
- import '../styles/groupButton.js';
23
- import '../styles/progressBar.js';
24
- import './Select.js';
25
- import './Tag.js';
26
- import './TextArea.js';
27
- import './Toggle.js';
28
- import { AiOutlineLoading } from 'react-icons/ai';
29
- import { IoSearchOutline } from 'react-icons/io5';
30
-
31
- const inputFace = "bg-white w-full";
32
- const inputLeft = "flex items-center";
33
- const SearchInput = ({
34
- label,
35
- placeholder,
36
- isSubmitting = false,
37
- onChange,
38
- onClick,
39
- BOUNCE_TIMEOUT = 1e3
40
- }) => {
41
- const [bouncedText, setBouncedText] = useState("");
42
- const [searchInput, setSearchInput] = useDebouncedState(
43
- "",
44
- setBouncedText,
45
- BOUNCE_TIMEOUT
46
- );
47
- useEffect(() => {
48
- if (onChange) {
49
- onChange(bouncedText);
50
- }
51
- }, [bouncedText]);
52
- const handleEnterKey = (e) => {
53
- if (e.key === "Enter" && onClick && searchInput) {
54
- onClick(searchInput);
55
- }
56
- };
57
- return /* @__PURE__ */ React.createElement("div", { className: "flex flex-row w-full space-x-mili" }, /* @__PURE__ */ React.createElement(Input.Face, { variants: { className: inputFace } }, !onClick && /* @__PURE__ */ React.createElement(Input.Left, { className: inputLeft }, /* @__PURE__ */ React.createElement(IoSearchOutline, { "data-testid": "icon-search-left" })), /* @__PURE__ */ React.createElement(
58
- Input.Box,
59
- {
60
- placeholder,
61
- label,
62
- onChange: (e) => setSearchInput(e.target.value),
63
- onKeyDown: handleEnterKey,
64
- disabled: isSubmitting
65
- }
66
- )), onClick && /* @__PURE__ */ React.createElement(
67
- Button,
68
- {
69
- variants: {
70
- intent: "primary",
71
- size: "square",
72
- className: "h-11"
73
- },
74
- onClick: () => onClick(searchInput),
75
- disabled: !searchInput || isSubmitting
76
- },
77
- isSubmitting ? /* @__PURE__ */ React.createElement("div", { className: "animate-spin" }, /* @__PURE__ */ React.createElement(AiOutlineLoading, { "data-testid": "icon-loading" })) : /* @__PURE__ */ React.createElement(IoSearchOutline, { "data-testid": "icon-search-button" })
78
- ));
79
- };
80
-
81
- export { SearchInput as default };
@@ -1,96 +0,0 @@
1
- import { selectVariants, option } from '@tecsinapse/cortex-core';
2
- import React, { useState, useMemo, useRef, useCallback, useEffect } from 'react';
3
- import { IoIosCloseCircleOutline } from 'react-icons/io';
4
- import { IoChevronDownOutline } from 'react-icons/io5';
5
- import { Hint } from './Hint.js';
6
- import SearchInput from './SearchInput.js';
7
-
8
- const { button, dropdown, groupedTitle, containerGrouped, hintBody } = selectVariants();
9
- const Select = (props) => {
10
- const {
11
- label,
12
- keyExtractor,
13
- labelExtractor,
14
- options,
15
- value,
16
- onSelect,
17
- onSearch,
18
- disabled,
19
- grouped,
20
- groupedLabelExtractor,
21
- hint,
22
- placeholderSearchInput,
23
- variant = "default"
24
- } = props;
25
- const [open, setOpen] = useState(false);
26
- const placeholder = useMemo(
27
- () => value ? labelExtractor(value) : label,
28
- [label, labelExtractor, value]
29
- );
30
- const ref = useRef(null);
31
- const handleClickOutside = useCallback((event) => {
32
- if (ref.current && !ref.current.contains(event.target)) {
33
- setOpen(false);
34
- }
35
- }, []);
36
- const handleSelect = useCallback(
37
- (option) => {
38
- onSelect(option);
39
- setOpen(false);
40
- },
41
- [onSelect]
42
- );
43
- useEffect(() => {
44
- document.addEventListener("click", handleClickOutside, true);
45
- return () => {
46
- document.removeEventListener("click", handleClickOutside, true);
47
- };
48
- }, [handleClickOutside]);
49
- const Option = ({ option: option$1 }) => /* @__PURE__ */ React.createElement(
50
- "li",
51
- {
52
- onClick: () => handleSelect(option$1),
53
- className: option(),
54
- role: "option"
55
- },
56
- labelExtractor(option$1)
57
- );
58
- const GroupedOptions = ({ options: options2 }) => /* @__PURE__ */ React.createElement(React.Fragment, null, [...options2 ?? []].map(([key, value2]) => /* @__PURE__ */ React.createElement("div", { key, className: containerGrouped() }, /* @__PURE__ */ React.createElement("span", { className: groupedTitle() }, groupedLabelExtractor?.(key)), value2.map((option) => /* @__PURE__ */ React.createElement(Option, { option, key: keyExtractor(option) })))));
59
- const DefaultOptions = ({ options: options2 }) => /* @__PURE__ */ React.createElement(React.Fragment, null, (options2 ?? []).map((option) => /* @__PURE__ */ React.createElement(Option, { option, key: keyExtractor(option) })));
60
- return /* @__PURE__ */ React.createElement("div", { className: "w-full relative bg-white", ref }, /* @__PURE__ */ React.createElement(
61
- "button",
62
- {
63
- className: button({ disabled, intent: variant }),
64
- onClick: () => setOpen((prevState) => !prevState),
65
- disabled
66
- },
67
- /* @__PURE__ */ React.createElement("span", { "data-testid": "select-placeholder" }, placeholder),
68
- /* @__PURE__ */ React.createElement(IoChevronDownOutline, null)
69
- ), /* @__PURE__ */ React.createElement(
70
- "ul",
71
- {
72
- role: "select",
73
- className: dropdown({
74
- open
75
- })
76
- },
77
- onSearch ? /* @__PURE__ */ React.createElement("div", { className: "m-mili" }, /* @__PURE__ */ React.createElement(
78
- SearchInput,
79
- {
80
- placeholder: placeholderSearchInput,
81
- onChange: onSearch
82
- }
83
- )) : /* @__PURE__ */ React.createElement(React.Fragment, null),
84
- grouped ? /* @__PURE__ */ React.createElement(GroupedOptions, { options }) : /* @__PURE__ */ React.createElement(DefaultOptions, { options })
85
- ), hint && /* @__PURE__ */ React.createElement(
86
- Hint,
87
- {
88
- variants: {
89
- intent: variant
90
- }
91
- },
92
- /* @__PURE__ */ React.createElement("div", { className: hintBody() }, variant === "error" ? /* @__PURE__ */ React.createElement(IoIosCloseCircleOutline, { "data-testid": "select-hint-error-icon" }) : /* @__PURE__ */ React.createElement(React.Fragment, null), /* @__PURE__ */ React.createElement("span", null, hint))
93
- ));
94
- };
95
-
96
- export { Select, Select as default };
@@ -1,27 +0,0 @@
1
- interface CommonProps<T> {
2
- label: string;
3
- value: T | undefined;
4
- onSelect: (value: T) => void;
5
- keyExtractor: (value: T) => string;
6
- labelExtractor: (value: T) => string;
7
- onSearch?: (search: string) => void;
8
- disabled?: boolean;
9
- grouped?: boolean;
10
- variant?: 'error' | 'default';
11
- hint?: string;
12
- placeholderSearchInput?: string;
13
- }
14
- interface GroupedProps<T> {
15
- options?: Map<string, T[]>;
16
- groupedLabelExtractor: (value: string) => string;
17
- grouped: true;
18
- }
19
- interface DefaultProps<T> {
20
- options?: T[];
21
- groupedLabelExtractor?: never;
22
- grouped?: never;
23
- }
24
- type ConditionalProps<T> = GroupedProps<T> | DefaultProps<T>;
25
- type SelectProps<T> = CommonProps<T> & ConditionalProps<T>;
26
- export declare const Select: <T>(props: SelectProps<T>) => JSX.Element;
27
- export default Select;