@arkyn/components 1.3.156 → 1.3.158

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. package/base-variables.css +6 -5
  2. package/dist/bundle.js +108521 -72803
  3. package/dist/bundle.umd.cjs +1937 -1157
  4. package/dist/components/MultiSelect/components/MultiSelectChevron/index.d.ts +11 -0
  5. package/dist/components/MultiSelect/components/MultiSelectChevron/index.d.ts.map +1 -0
  6. package/dist/components/MultiSelect/components/MultiSelectChevron/index.js +13 -0
  7. package/dist/components/MultiSelect/components/MultiSelectContainer/index.d.ts +19 -0
  8. package/dist/components/MultiSelect/components/MultiSelectContainer/index.d.ts.map +1 -0
  9. package/dist/components/MultiSelect/components/MultiSelectContainer/index.js +11 -0
  10. package/dist/components/MultiSelect/components/MultiSelectContent/index.d.ts +9 -0
  11. package/dist/components/MultiSelect/components/MultiSelectContent/index.d.ts.map +1 -0
  12. package/dist/components/MultiSelect/components/MultiSelectContent/index.js +8 -0
  13. package/dist/components/MultiSelect/components/MultiSelectMark/index.d.ts +9 -0
  14. package/dist/components/MultiSelect/components/MultiSelectMark/index.d.ts.map +1 -0
  15. package/dist/components/MultiSelect/components/MultiSelectMark/index.js +11 -0
  16. package/dist/components/MultiSelect/components/MultiSelectOption/index.d.ts +11 -0
  17. package/dist/components/MultiSelect/components/MultiSelectOption/index.d.ts.map +1 -0
  18. package/dist/components/MultiSelect/components/MultiSelectOption/index.js +10 -0
  19. package/dist/components/MultiSelect/components/MultiSelectOptionsContainer/index.d.ts +11 -0
  20. package/dist/components/MultiSelect/components/MultiSelectOptionsContainer/index.d.ts.map +1 -0
  21. package/dist/components/MultiSelect/components/MultiSelectOptionsContainer/index.js +16 -0
  22. package/dist/components/MultiSelect/components/MultiSelectOverlay/index.d.ts +8 -0
  23. package/dist/components/MultiSelect/components/MultiSelectOverlay/index.d.ts.map +1 -0
  24. package/dist/components/MultiSelect/components/MultiSelectOverlay/index.js +9 -0
  25. package/dist/components/MultiSelect/components/MultiSelectSpinner/index.d.ts +8 -0
  26. package/dist/components/MultiSelect/components/MultiSelectSpinner/index.d.ts.map +1 -0
  27. package/dist/components/MultiSelect/components/MultiSelectSpinner/index.js +10 -0
  28. package/dist/components/MultiSelect/index.d.ts +4 -0
  29. package/dist/components/MultiSelect/index.d.ts.map +1 -0
  30. package/dist/components/MultiSelect/index.js +73 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -0
  34. package/dist/style.css +1 -1
  35. package/package.json +1 -1
  36. package/src/components/MultiSelect/components/MultiSelectChevron/index.tsx +26 -0
  37. package/src/components/MultiSelect/components/MultiSelectChevron/styles.css +7 -0
  38. package/src/components/MultiSelect/components/MultiSelectContainer/index.tsx +51 -0
  39. package/src/components/MultiSelect/components/MultiSelectContainer/styles.css +134 -0
  40. package/src/components/MultiSelect/components/MultiSelectContent/index.tsx +15 -0
  41. package/src/components/MultiSelect/components/MultiSelectContent/styles.css +24 -0
  42. package/src/components/MultiSelect/components/MultiSelectMark/index.tsx +30 -0
  43. package/src/components/MultiSelect/components/MultiSelectMark/styles.css +40 -0
  44. package/src/components/MultiSelect/components/MultiSelectOption/index.tsx +25 -0
  45. package/src/components/MultiSelect/components/MultiSelectOption/styles.css +37 -0
  46. package/src/components/MultiSelect/components/MultiSelectOptionsContainer/index.tsx +41 -0
  47. package/src/components/MultiSelect/components/MultiSelectOptionsContainer/styles.css +36 -0
  48. package/src/components/MultiSelect/components/MultiSelectOverlay/index.tsx +14 -0
  49. package/src/components/MultiSelect/components/MultiSelectOverlay/styles.css +8 -0
  50. package/src/components/MultiSelect/components/MultiSelectSpinner/index.tsx +22 -0
  51. package/src/components/MultiSelect/components/MultiSelectSpinner/styles.css +12 -0
  52. package/src/components/MultiSelect/index.tsx +171 -0
  53. package/src/index.ts +4 -0
@@ -0,0 +1,51 @@
1
+ import { ReactNode } from "react";
2
+ import "./styles.css";
3
+
4
+ type MultiSelectContainerProps = {
5
+ children: ReactNode;
6
+ handleContainerFocus: () => void;
7
+ prefixExists: boolean;
8
+ isError: boolean;
9
+ disabled: boolean;
10
+ readOnly: boolean;
11
+ isLoading: boolean;
12
+ isFocused: boolean;
13
+ className?: string;
14
+ id: string;
15
+ variant: "solid" | "outline" | "underline";
16
+ size: "md" | "lg";
17
+ };
18
+
19
+ function MultiSelectContainer(props: MultiSelectContainerProps) {
20
+ const {
21
+ children,
22
+ handleContainerFocus,
23
+ disabled,
24
+ isError,
25
+ isLoading,
26
+ isFocused,
27
+ className,
28
+ readOnly,
29
+ variant,
30
+ size,
31
+ id,
32
+ prefixExists,
33
+ } = props;
34
+
35
+ const hasPrefix = prefixExists ? "hasPrefix" : "";
36
+ const errored = isError ? "errored" : "";
37
+ const opacity = disabled || readOnly || isLoading ? "opacity" : "";
38
+ const focused = isFocused ? "focused" : "";
39
+
40
+ return (
41
+ <section
42
+ onClick={handleContainerFocus}
43
+ id={id}
44
+ className={`arkynMultiSelectContainer ${hasPrefix} ${variant} ${size} ${opacity} ${errored} ${focused} ${className}`}
45
+ >
46
+ {children}
47
+ </section>
48
+ );
49
+ }
50
+
51
+ export { MultiSelectContainer };
@@ -0,0 +1,134 @@
1
+ /* BASE CSS */
2
+ .arkynMultiSelectContainer {
3
+ flex: 1;
4
+ position: relative;
5
+ display: flex;
6
+ align-items: center;
7
+
8
+ padding: 0 16px;
9
+ gap: 8px;
10
+ border-radius: 6px;
11
+
12
+ border: 1px solid transparent;
13
+ outline: 1px solid transparent;
14
+ }
15
+ .arkynMultiSelectContainer:hover {
16
+ cursor: pointer;
17
+ }
18
+ .arkynMultiSelectContainer.opacity {
19
+ opacity: 0.5;
20
+ }
21
+
22
+ /* PREFIX */
23
+ .arkynMultiSelectContainer .prefix {
24
+ color: var(--text-body);
25
+ background: var(--border);
26
+ font-weight: 400;
27
+
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+
32
+ position: absolute;
33
+ }
34
+ .arkynMultiSelectContainer .prefix {
35
+ left: 0;
36
+ top: 0;
37
+ bottom: 0;
38
+ border-radius: 5px 0 0 5px;
39
+ border-right: 1px solid var(--border);
40
+ }
41
+
42
+ /* LEFT ICON */
43
+ .arkynMultiSelectContainer > svg {
44
+ color: var(--text-muted);
45
+ }
46
+ .arkynMultiSelectContainer.errored > svg {
47
+ color: rgba(var(--spotlight-danger), 1);
48
+ }
49
+ .arkynMultiSelectContainer:not(.opacity).focused > svg {
50
+ color: rgba(var(--spotlight-primary), 1);
51
+ }
52
+
53
+ /* VARIANTS */
54
+ .arkynMultiSelectContainer.solid {
55
+ border-color: var(--border);
56
+ background-color: rgba(var(--input-background), 1);
57
+ }
58
+ .arkynMultiSelectContainer.solid.errored {
59
+ border-color: rgba(var(--spotlight-danger), 1);
60
+ outline-color: rgba(var(--spotlight-danger), 1);
61
+ }
62
+ .arkynMultiSelectContainer:not(.opacity).solid.focused {
63
+ border-color: rgba(var(--spotlight-primary), 1);
64
+ outline-color: rgba(var(--spotlight-primary), 1);
65
+ }
66
+ .arkynMultiSelectContainer.outline {
67
+ border-color: var(--border);
68
+ }
69
+ .arkynMultiSelectContainer.outline.errored {
70
+ border-color: rgba(var(--spotlight-danger), 1);
71
+ outline-color: rgba(var(--spotlight-danger), 1);
72
+ }
73
+ .arkynMultiSelectContainer:not(.opacity).outline.focused {
74
+ border-color: rgba(var(--spotlight-primary), 1);
75
+ outline-color: rgba(var(--spotlight-primary), 1);
76
+ }
77
+ .arkynMultiSelectContainer.underline {
78
+ border-radius: 0;
79
+ border-top: none;
80
+ border-left: none;
81
+ border-right: none;
82
+ outline: none;
83
+ border-color: var(--border);
84
+ }
85
+ .arkynMultiSelectContainer.underline .prefix {
86
+ display: none;
87
+ }
88
+ .arkynMultiSelectContainer.underline::before {
89
+ content: " ";
90
+ position: absolute;
91
+ height: 1px;
92
+ left: 0;
93
+ right: 0;
94
+ bottom: -2px;
95
+ background: transparent;
96
+ }
97
+ .arkynMultiSelectContainer.underline.errored {
98
+ border-color: rgba(var(--spotlight-danger), 1);
99
+ }
100
+ .arkynMultiSelectContainer.underline.errored::before {
101
+ background: rgba(var(--spotlight-danger), 1);
102
+ }
103
+ .arkynMultiSelectContainer:not(.opacity).underline.focused {
104
+ border-color: rgba(var(--spotlight-primary), 1);
105
+ }
106
+ .arkynMultiSelectContainer:not(.opacity).underline.focused::before {
107
+ background: rgba(var(--spotlight-primary), 1);
108
+ }
109
+
110
+ /* SIZE */
111
+ .arkynMultiSelectContainer.md {
112
+ min-height: 40px;
113
+ max-height: 40px;
114
+ }
115
+ .arkynMultiSelectContainer.md.hasPrefix {
116
+ padding-left: 60px;
117
+ }
118
+ .arkynMultiSelectContainer.md .prefix {
119
+ height: 40px;
120
+ width: 44px;
121
+ font-size: 14px;
122
+ }
123
+ .arkynMultiSelectContainer.lg {
124
+ min-height: 44px;
125
+ max-height: 44px;
126
+ }
127
+ .arkynMultiSelectContainer.lg .prefix {
128
+ height: 44px;
129
+ width: 48px;
130
+ font-size: 16px;
131
+ }
132
+ .arkynMultiSelectContainer.lg.hasPrefix {
133
+ padding-left: 64px;
134
+ }
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+ import "./styles.css";
3
+
4
+ type MultiSelectContentProps = {
5
+ children: ReactNode;
6
+ size: "md" | "lg";
7
+ };
8
+
9
+ function MultiSelectContent(props: MultiSelectContentProps) {
10
+ const { children, size } = props;
11
+ const className = `arkynMultiSelectContent ${size}`;
12
+ return <div className={className}>{children}</div>;
13
+ }
14
+
15
+ export { MultiSelectContent };
@@ -0,0 +1,24 @@
1
+ .arkynMultiSelectContent {
2
+ display: flex;
3
+ align-items: start;
4
+ gap: 4px;
5
+ flex-wrap: wrap;
6
+
7
+ flex: 1;
8
+ }
9
+
10
+ .arkynMultiSelectContent > p {
11
+ font-weight: 400;
12
+ color: var(--text-muted);
13
+ user-select: none;
14
+ }
15
+
16
+ .arkynMultiSelectContent.md > p {
17
+ font-size: 14px;
18
+ line-height: 14px;
19
+ }
20
+
21
+ .arkynMultiSelectContent.lg > p {
22
+ font-size: 16px;
23
+ line-height: 16px;
24
+ }
@@ -0,0 +1,30 @@
1
+ import { X } from "lucide-react";
2
+ import "./styles.css";
3
+
4
+ type MultiSelectMarkProps = {
5
+ label: string;
6
+ value: string;
7
+ handleChangeValue: (value: string) => void;
8
+ };
9
+
10
+ function MultiSelectMark(props: MultiSelectMarkProps) {
11
+ const { label, value, handleChangeValue } = props;
12
+
13
+ return (
14
+ <div className="arkynMultiSelectMark">
15
+ {label}
16
+
17
+ <button
18
+ type="button"
19
+ onClick={(e) => {
20
+ e.stopPropagation();
21
+ handleChangeValue(value);
22
+ }}
23
+ >
24
+ <X />
25
+ </button>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ export { MultiSelectMark };
@@ -0,0 +1,40 @@
1
+ .arkynMultiSelectMark {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 4px;
5
+
6
+ border-radius: 4px;
7
+ background: var(--card-foreground-terceary);
8
+
9
+ padding: 2px 6px;
10
+
11
+ font-size: 14px;
12
+ font-weight: 400;
13
+ line-height: 19.07px;
14
+ text-align: left;
15
+ z-index: 6;
16
+ user-select: none;
17
+ }
18
+
19
+ .arkynMultiSelectMark button {
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+
24
+ border: none;
25
+ background: inherit;
26
+
27
+ width: 15px;
28
+ height: 15px;
29
+ }
30
+
31
+ .arkynMultiSelectMark button:hover {
32
+ cursor: pointer;
33
+ filter: brightness(0.9);
34
+ }
35
+
36
+ .arkynMultiSelectMark button svg {
37
+ min-width: 10px;
38
+ min-height: 10px;
39
+ color: var(--text-muted);
40
+ }
@@ -0,0 +1,25 @@
1
+ import { Check } from "lucide-react";
2
+ import "./styles.css";
3
+
4
+ type MultiSelectOptionProps = {
5
+ value: string;
6
+ label: string;
7
+ size: "md" | "lg";
8
+ optionHasSelected: (value: string) => boolean;
9
+ handleChangeValue: (value: string) => void;
10
+ };
11
+
12
+ function MultiSelectOption(props: MultiSelectOptionProps) {
13
+ const { label, optionHasSelected, handleChangeValue, value, size } = props;
14
+
15
+ const hasActive = optionHasSelected(value) ? "active" : "";
16
+ const className = `arkynMultiSelectOption ${size} ${hasActive}`;
17
+
18
+ return (
19
+ <div onClick={() => handleChangeValue(value)} className={className}>
20
+ {label} <Check />
21
+ </div>
22
+ );
23
+ }
24
+
25
+ export { MultiSelectOption };
@@ -0,0 +1,37 @@
1
+ .arkynMultiSelectOption {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: space-between;
5
+
6
+ font-weight: 400;
7
+ line-height: 21.79px;
8
+
9
+ color: var(--text-body);
10
+ user-select: none;
11
+ }
12
+ .arkynMultiSelectOption.md {
13
+ font-size: 14px;
14
+ padding: 8px 16px;
15
+ }
16
+ .arkynMultiSelectOption.lg {
17
+ font-size: 16px;
18
+ padding: 8px 16px;
19
+ }
20
+ .arkynMultiSelectOption svg {
21
+ display: none;
22
+ height: 20px;
23
+ width: 20px;
24
+ color: rgba(var(--spotlight-primary), 1);
25
+ }
26
+ .arkynMultiSelectOption:hover {
27
+ cursor: pointer;
28
+ background-color: var(--card-foreground-primary);
29
+ }
30
+ .arkynMultiSelectOption.active {
31
+ font-weight: 600;
32
+ color: var(--text-heading);
33
+ background-color: var(--card-foreground-primary);
34
+ }
35
+ .arkynMultiSelectOption.active svg {
36
+ display: unset;
37
+ }
@@ -0,0 +1,41 @@
1
+ import { Input } from "@arkyn/components";
2
+ import { Search } from "lucide-react";
3
+ import { ChangeEvent, ReactNode } from "react";
4
+
5
+ import "./styles.css";
6
+
7
+ type MultiSelectOptionsContainerProps = {
8
+ isFocused: boolean;
9
+ isSearchable: boolean;
10
+ children: ReactNode;
11
+ onSearch: (value: string) => void;
12
+ };
13
+
14
+ function MultiSelectOptionsContainer(props: MultiSelectOptionsContainerProps) {
15
+ const { children, isFocused, isSearchable, onSearch } = props;
16
+
17
+ function handleSearch(e: ChangeEvent<HTMLInputElement>) {
18
+ if (!isSearchable) return;
19
+ onSearch(e.target.value);
20
+ }
21
+
22
+ if (!isFocused) return <></>;
23
+
24
+ return (
25
+ <div className="arkynMultiSelectOptionsContainer">
26
+ {isSearchable && (
27
+ <Input
28
+ type="search"
29
+ name="search-select"
30
+ variant="underline"
31
+ leftIcon={Search}
32
+ onChange={handleSearch}
33
+ />
34
+ )}
35
+
36
+ {children}
37
+ </div>
38
+ );
39
+ }
40
+
41
+ export { MultiSelectOptionsContainer };
@@ -0,0 +1,36 @@
1
+ /* BASE CSS */
2
+ .arkynMultiSelectOptionsContainer {
3
+ position: absolute;
4
+ z-index: 6;
5
+
6
+ top: calc(100% + 5px);
7
+ left: -2px;
8
+ right: -2px;
9
+
10
+ border-radius: 6px;
11
+ list-style: none;
12
+
13
+ display: flex;
14
+ flex-direction: column;
15
+
16
+ flex: 1;
17
+ overflow: hidden;
18
+ height: max-content;
19
+
20
+ border: 1px solid var(--border);
21
+ background-color: var(--card);
22
+
23
+ max-height: 300px;
24
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
25
+ }
26
+
27
+ /* NOT FOUND TEXT */
28
+ .arkynMultiSelectOptionsContainer > p {
29
+ font-weight: 400;
30
+ font-size: 14px;
31
+ padding: 16px;
32
+ text-align: center;
33
+ line-height: 21.79px;
34
+
35
+ color: var(--text-body);
36
+ }
@@ -0,0 +1,14 @@
1
+ import "./styles.css";
2
+
3
+ type MultiSelectOverlayProps = {
4
+ isFocused: boolean;
5
+ handleBlur: () => void;
6
+ };
7
+
8
+ function MultiSelectOverlay(props: MultiSelectOverlayProps) {
9
+ const { isFocused, handleBlur } = props;
10
+ if (!isFocused) return <></>;
11
+ return <aside className="arkynMultiSelectOverlay" onClick={handleBlur} />;
12
+ }
13
+
14
+ export { MultiSelectOverlay };
@@ -0,0 +1,8 @@
1
+ .arkynMultiSelectOverlay {
2
+ position: fixed;
3
+ top: 0;
4
+ bottom: 0;
5
+ left: 0;
6
+ right: 0;
7
+ z-index: 5;
8
+ }
@@ -0,0 +1,22 @@
1
+ import { Loader2 } from "lucide-react";
2
+ import "./styles.css";
3
+
4
+ type MultiSelectSpinnerProps = {
5
+ iconSize: number;
6
+ isLoading: boolean;
7
+ };
8
+
9
+ function MultiSelectSpinner(props: MultiSelectSpinnerProps) {
10
+ const { iconSize, isLoading } = props;
11
+
12
+ if (!isLoading) return <></>;
13
+ return (
14
+ <Loader2
15
+ className="arkynMultiSelectSpinner"
16
+ size={iconSize}
17
+ strokeWidth={2.5}
18
+ />
19
+ );
20
+ }
21
+
22
+ export { MultiSelectSpinner };
@@ -0,0 +1,12 @@
1
+ .arkynMultiSelectSpinner {
2
+ animation: spin 2s linear infinite;
3
+ }
4
+
5
+ @keyframes spin {
6
+ from {
7
+ transform: rotate(0deg);
8
+ }
9
+ to {
10
+ transform: rotate(360deg);
11
+ }
12
+ }
@@ -0,0 +1,171 @@
1
+ import { MultiSelectProps } from "@arkyn/types";
2
+ import { useRef, useState } from "react";
3
+
4
+ import { morpheme } from "../../services";
5
+ import { useFormController } from "../Form/FormController";
6
+
7
+ import { MultiSelectChevron } from "./components/MultiSelectChevron";
8
+ import { MultiSelectContainer } from "./components/MultiSelectContainer";
9
+ import { MultiSelectContent } from "./components/MultiSelectContent";
10
+ import { MultiSelectMark } from "./components/MultiSelectMark";
11
+ import { MultiSelectOption } from "./components/MultiSelectOption";
12
+ import { MultiSelectOptionsContainer } from "./components/MultiSelectOptionsContainer";
13
+ import { MultiSelectOverlay } from "./components/MultiSelectOverlay";
14
+ import { MultiSelectSpinner } from "./components/MultiSelectSpinner";
15
+
16
+ function MultiSelect(props: MultiSelectProps) {
17
+ const {
18
+ name,
19
+ options,
20
+ className = "",
21
+ placeholder = "Selecione...",
22
+ closeOnSelect = false,
23
+ defaultValue = [],
24
+ isError: baseIsError,
25
+ isLoading = false,
26
+ readOnly = false,
27
+ isSearchable = false,
28
+ leftIcon: LeftIcon,
29
+ onSearch,
30
+ onSelect,
31
+ onBlur,
32
+ notFoundText = "Sem opções disponíveis",
33
+ onFocus,
34
+ disabled = false,
35
+ prefix: basePrefix,
36
+ size = "md",
37
+ value,
38
+ variant = "solid",
39
+ } = props;
40
+
41
+ const formController = useFormController();
42
+ const baseRef = useRef<HTMLInputElement>(null);
43
+
44
+ const multiSelectRef = formController.inputRef || baseRef;
45
+ const multiSelectId = formController.id;
46
+
47
+ const isError = baseIsError || !!formController.error;
48
+
49
+ const iconSizes = { md: 20, lg: 20 };
50
+ const iconSize = iconSizes[size];
51
+ const prefix = morpheme(basePrefix, iconSize, "prefix");
52
+
53
+ const [search, setSearch] = useState("");
54
+ const [isFocused, setIsFocused] = useState(false);
55
+ const [selectedOptions, setSelectedOptions] = useState(defaultValue);
56
+
57
+ const forceSelectedOptions = value || selectedOptions;
58
+
59
+ function optionHasSelected(value: string) {
60
+ return forceSelectedOptions.includes(value);
61
+ }
62
+
63
+ function getOptionLabel(value: string) {
64
+ const option = options.find((option) => option.value === value);
65
+ return option?.label || "";
66
+ }
67
+
68
+ function handleContainerFocus() {
69
+ if (disabled || !multiSelectRef?.current || isFocused) return;
70
+ setIsFocused(true);
71
+ multiSelectRef.current.focus();
72
+ onFocus && onFocus();
73
+ }
74
+
75
+ function handleBlur() {
76
+ setIsFocused(false);
77
+ if (onBlur && multiSelectRef.current) multiSelectRef.current.blur();
78
+ }
79
+
80
+ function handleSearch(value: string) {
81
+ setSearch(value);
82
+ if (onSearch) onSearch(value);
83
+ }
84
+
85
+ function handleChangeValue(value: string) {
86
+ if (optionHasSelected(value)) {
87
+ setSelectedOptions(selectedOptions.filter((v) => v !== value));
88
+ } else setSelectedOptions([...selectedOptions, value]);
89
+
90
+ if (onSelect) onSelect(selectedOptions);
91
+ if (closeOnSelect) handleBlur();
92
+ }
93
+
94
+ const mappedOptions = options.filter((option) => {
95
+ if (props.onSearch) return true;
96
+ if (!props.isSearchable) return true;
97
+ if (option.label.toLowerCase().includes(search.toLowerCase())) return true;
98
+ return false;
99
+ });
100
+
101
+ return (
102
+ <MultiSelectContainer
103
+ handleContainerFocus={handleContainerFocus}
104
+ disabled={disabled}
105
+ isError={isError}
106
+ isFocused={isFocused}
107
+ isLoading={isLoading}
108
+ readOnly={readOnly}
109
+ size={size}
110
+ variant={variant}
111
+ className={className}
112
+ prefixExists={!!basePrefix}
113
+ id={multiSelectId}
114
+ >
115
+ <input
116
+ ref={multiSelectRef}
117
+ name={name}
118
+ value={JSON.stringify(forceSelectedOptions)}
119
+ type="hidden"
120
+ />
121
+
122
+ {prefix}
123
+ {LeftIcon && <LeftIcon size={iconSize} strokeWidth={2.5} />}
124
+
125
+ <MultiSelectContent size={size}>
126
+ {forceSelectedOptions.map((value) => (
127
+ <MultiSelectMark
128
+ key={value}
129
+ label={getOptionLabel(value)}
130
+ value={value}
131
+ handleChangeValue={handleChangeValue}
132
+ />
133
+ ))}
134
+
135
+ {forceSelectedOptions.length <= 0 && <p>{placeholder}</p>}
136
+ </MultiSelectContent>
137
+
138
+ <MultiSelectOptionsContainer
139
+ isFocused={isFocused}
140
+ isSearchable={isSearchable}
141
+ onSearch={handleSearch}
142
+ >
143
+ {mappedOptions.map(({ label, value }) => (
144
+ <MultiSelectOption
145
+ key={value}
146
+ label={label}
147
+ value={value}
148
+ size={size}
149
+ handleChangeValue={handleChangeValue}
150
+ optionHasSelected={optionHasSelected}
151
+ />
152
+ ))}
153
+
154
+ {mappedOptions.length <= 0 && <p>{notFoundText}</p>}
155
+ </MultiSelectOptionsContainer>
156
+
157
+ <MultiSelectChevron
158
+ disabled={disabled}
159
+ isFocused={isFocused}
160
+ readOnly={readOnly}
161
+ iconSize={iconSize}
162
+ isLoading={isLoading}
163
+ />
164
+
165
+ <MultiSelectSpinner iconSize={iconSize} isLoading={isLoading} />
166
+ <MultiSelectOverlay handleBlur={handleBlur} isFocused={isFocused} />
167
+ </MultiSelectContainer>
168
+ );
169
+ }
170
+
171
+ export { MultiSelect };
package/src/index.ts CHANGED
@@ -25,6 +25,7 @@ export { FormController, FormError, FormLabel } from "./components/Form";
25
25
  export { IconButton } from "./components/IconButton";
26
26
  export { ImageUpload } from "./components/ImageUpload";
27
27
  export { Input } from "./components/Input";
28
+ export { MultiSelect } from "./components/MultiSelect";
28
29
  export { RadioBox, RadioGroup } from "./components/Radio";
29
30
  export { RichText } from "./components/RichText";
30
31
  export { Select } from "./components/Select";
@@ -64,3 +65,6 @@ export { ClientOnly } from "./components/ClientOnly";
64
65
  export { GoogleMap } from "./components/GoogleMap";
65
66
  export { GoogleSearchPlaces } from "./components/GoogleSearchPlaces";
66
67
  export { GoogleTagManager } from "./components/GoogleTagManager";
68
+
69
+ // Services
70
+ export { morpheme } from "./services/morpheme";