@tipp/ui 1.4.21 → 1.4.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,350 @@
1
+ import {
2
+ ScrollArea
3
+ } from "./chunk-ZKZDVS7G.js";
4
+ import {
5
+ Popover
6
+ } from "./chunk-5AVBYDPB.js";
7
+ import {
8
+ Typo
9
+ } from "./chunk-52MVZ6AN.js";
10
+ import {
11
+ Flex
12
+ } from "./chunk-25HMMI7R.js";
13
+ import {
14
+ Grid
15
+ } from "./chunk-EGEQY3KT.js";
16
+ import {
17
+ Badge
18
+ } from "./chunk-EWD4AO5N.js";
19
+ import {
20
+ Button
21
+ } from "./chunk-U7JPP7WJ.js";
22
+ import {
23
+ CheckIcon
24
+ } from "./chunk-F77ES5Y3.js";
25
+ import {
26
+ AutoSizingInput
27
+ } from "./chunk-YJCCE5WP.js";
28
+
29
+ // src/molecules/tag-selector.tsx
30
+ import {
31
+ useCallback,
32
+ useEffect,
33
+ useMemo,
34
+ useRef,
35
+ useState
36
+ } from "react";
37
+ import {
38
+ ChevronRightIcon,
39
+ Cross1Icon,
40
+ MagnifyingGlassIcon
41
+ } from "@radix-ui/react-icons";
42
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
43
+ var OPTION_HEIGHT = 32;
44
+ var DefaultDropdownContainer = (props) => {
45
+ return props.children;
46
+ };
47
+ function TagSelector(props) {
48
+ const {
49
+ options = [],
50
+ tagRender,
51
+ placeholder,
52
+ maxCount = 0,
53
+ DropdownContainer = DefaultDropdownContainer,
54
+ size = "medium",
55
+ readOnly,
56
+ error
57
+ } = props;
58
+ const [_selected, _setSelected] = useState(props.selected || []);
59
+ const selected = props.selected || _selected;
60
+ const setSelected = props.onChange || _setSelected;
61
+ const [value, setValue] = useState("");
62
+ const [focusIndex, setFocusIndex] = useState(null);
63
+ const [open, setOpen] = useState(false);
64
+ const [focus, setFocus] = useState(false);
65
+ const fieldRef = useRef(null);
66
+ const scrollRef = useRef(null);
67
+ const closeRef = useRef();
68
+ const onFocus = useCallback(() => {
69
+ clearTimeout(closeRef.current);
70
+ setFocus(true);
71
+ setOpen(true);
72
+ }, []);
73
+ const onBlur = useCallback(() => {
74
+ closeRef.current = setTimeout(() => {
75
+ setFocus(false);
76
+ setOpen(false);
77
+ setTimeout(() => {
78
+ setValue("");
79
+ }, 100);
80
+ }, 300);
81
+ }, []);
82
+ const onChangeValue = useCallback(
83
+ (e) => {
84
+ setValue(e.target.value);
85
+ },
86
+ []
87
+ );
88
+ const filteredOptions = useMemo(() => {
89
+ return options.filter((option) => {
90
+ return option.name.includes(value);
91
+ });
92
+ }, [options, value]);
93
+ const selectedItem = useMemo(() => {
94
+ const result = [];
95
+ selected.forEach((id) => {
96
+ const maybeItem = options.find((option) => option.id === id);
97
+ if (maybeItem)
98
+ result.push(maybeItem);
99
+ });
100
+ return result;
101
+ }, [options, selected]);
102
+ const onDelete = useCallback(
103
+ (id) => {
104
+ setSelected(selected.filter((el) => el !== id));
105
+ },
106
+ [selected, setSelected]
107
+ );
108
+ const onSelect = useCallback(
109
+ (id) => {
110
+ if (maxCount && selected.length + 1 > maxCount)
111
+ return;
112
+ setSelected([...selected, id]);
113
+ },
114
+ [maxCount, selected, setSelected]
115
+ );
116
+ const toggleItem = useCallback(
117
+ (id) => {
118
+ if (selected.includes(id)) {
119
+ onDelete(id);
120
+ } else {
121
+ onSelect(id);
122
+ }
123
+ },
124
+ [onDelete, onSelect, selected]
125
+ );
126
+ const setScroll = useCallback((index) => {
127
+ if (scrollRef.current) {
128
+ const scrollTop = scrollRef.current.scrollTop;
129
+ const clientHeight = scrollRef.current.clientHeight;
130
+ const focusTop = index * OPTION_HEIGHT;
131
+ if (focusTop < scrollTop) {
132
+ scrollRef.current.scrollTop = focusTop;
133
+ } else if (focusTop + OPTION_HEIGHT > scrollTop + clientHeight) {
134
+ scrollRef.current.scrollTop = focusTop + OPTION_HEIGHT - clientHeight;
135
+ }
136
+ }
137
+ }, []);
138
+ const handleKeyDown = useCallback(
139
+ (e) => {
140
+ var _a;
141
+ const key = e.key;
142
+ switch (key) {
143
+ case "ArrowDown": {
144
+ e.preventDefault();
145
+ let newFocus = 0;
146
+ if (typeof focusIndex === "number") {
147
+ newFocus = focusIndex + 1 >= options.length ? 0 : focusIndex + 1;
148
+ }
149
+ setFocusIndex(newFocus);
150
+ setScroll(newFocus);
151
+ break;
152
+ }
153
+ case "ArrowUp": {
154
+ e.preventDefault();
155
+ let newFocus = 0;
156
+ if (typeof focusIndex === "number") {
157
+ newFocus = focusIndex - 1 < 0 ? options.length - 1 : focusIndex - 1;
158
+ }
159
+ setFocusIndex(newFocus);
160
+ setScroll(newFocus);
161
+ break;
162
+ }
163
+ case "Enter":
164
+ setValue("");
165
+ if (focusIndex !== null) {
166
+ toggleItem((_a = filteredOptions[focusIndex]) == null ? void 0 : _a.id);
167
+ }
168
+ break;
169
+ case "Backspace":
170
+ if (value.length === 0) {
171
+ setSelected(selected.slice(0, -1));
172
+ }
173
+ break;
174
+ case "Escape":
175
+ setOpen(false);
176
+ break;
177
+ }
178
+ },
179
+ [
180
+ focusIndex,
181
+ value.length,
182
+ setScroll,
183
+ options.length,
184
+ toggleItem,
185
+ filteredOptions,
186
+ setSelected,
187
+ selected
188
+ ]
189
+ );
190
+ const placeholderVisible = useMemo(() => {
191
+ if (selectedItem.length)
192
+ return false;
193
+ if (value)
194
+ return false;
195
+ if (focus)
196
+ return false;
197
+ return true;
198
+ }, [focus, selectedItem.length, value]);
199
+ useEffect(() => {
200
+ setFocusIndex(null);
201
+ }, [open]);
202
+ useEffect(() => {
203
+ setFocusIndex(0);
204
+ }, [filteredOptions]);
205
+ const badgeSize = useMemo(() => {
206
+ switch (size) {
207
+ case "large":
208
+ return "large";
209
+ case "medium":
210
+ case "small":
211
+ default:
212
+ return "small";
213
+ }
214
+ }, [size]);
215
+ const placeholderVariant = useMemo(() => {
216
+ switch (size) {
217
+ case "large":
218
+ return "subtitle";
219
+ case "medium":
220
+ default:
221
+ return "body";
222
+ }
223
+ }, [size]);
224
+ const focusClassName = focus ? " focused" : "";
225
+ const readOnlyClassName = readOnly ? " read-only" : "";
226
+ const errorClassName = error ? " error" : "";
227
+ const readonlyContent = /* @__PURE__ */ jsx(Flex, { gap: "1", children: selectedItem.map((item) => {
228
+ return tagRender ? tagRender(item) : /* @__PURE__ */ jsx(Badge, { size: badgeSize, children: item.name }, item.id);
229
+ }) });
230
+ const editContent = /* @__PURE__ */ jsxs(Fragment, { children: [
231
+ /* @__PURE__ */ jsxs(
232
+ Flex,
233
+ {
234
+ align: "center",
235
+ gap: "1",
236
+ maxWidth: "100%",
237
+ overflow: "hidden",
238
+ wrap: "wrap",
239
+ children: [
240
+ selectedItem.map((item) => {
241
+ return tagRender ? tagRender(item) : /* @__PURE__ */ jsxs(Badge, { size: badgeSize, children: [
242
+ item.name,
243
+ /* @__PURE__ */ jsx(
244
+ Button,
245
+ {
246
+ onClick: () => {
247
+ onDelete(item.id);
248
+ },
249
+ variant: "transparent",
250
+ children: /* @__PURE__ */ jsx(Cross1Icon, {})
251
+ }
252
+ )
253
+ ] }, item.id);
254
+ }),
255
+ placeholderVisible ? /* @__PURE__ */ jsx(Typo, { color: "gray", variant: placeholderVariant, children: placeholder }) : null,
256
+ /* @__PURE__ */ jsx(
257
+ AutoSizingInput,
258
+ {
259
+ onBlur,
260
+ onChange: onChangeValue,
261
+ onFocus,
262
+ onKeyDown: handleKeyDown,
263
+ ref: fieldRef,
264
+ value
265
+ }
266
+ )
267
+ ]
268
+ }
269
+ ),
270
+ focus ? /* @__PURE__ */ jsx(MagnifyingGlassIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {})
271
+ ] });
272
+ return /* @__PURE__ */ jsxs(Popover.Root, { open: Boolean(filteredOptions.length) && open, children: [
273
+ /* @__PURE__ */ jsx(Popover.Trigger, { style: { position: "relative" }, children: /* @__PURE__ */ jsx(
274
+ Grid,
275
+ {
276
+ align: "center",
277
+ className: `tag-selector ${size} ${focusClassName}${readOnlyClassName}${errorClassName}`,
278
+ columns: "1fr auto",
279
+ gap: "1",
280
+ onClick: () => {
281
+ var _a;
282
+ return !readOnly && ((_a = fieldRef.current) == null ? void 0 : _a.focus());
283
+ },
284
+ children: readOnly ? readonlyContent : editContent
285
+ }
286
+ ) }),
287
+ /* @__PURE__ */ jsx(
288
+ Popover.Content,
289
+ {
290
+ onOpenAutoFocus: (e) => {
291
+ e.preventDefault();
292
+ },
293
+ children: /* @__PURE__ */ jsx(
294
+ DropdownContainer,
295
+ {
296
+ currentItem: filteredOptions[focusIndex || 0],
297
+ items: filteredOptions,
298
+ children: /* @__PURE__ */ jsx(
299
+ ScrollArea,
300
+ {
301
+ ref: scrollRef,
302
+ scrollbars: "vertical",
303
+ style: { height: OPTION_HEIGHT * 8 },
304
+ type: "auto",
305
+ children: /* @__PURE__ */ jsx(Flex, { direction: "column", children: filteredOptions.map((item, i) => {
306
+ const isSelected = Boolean(
307
+ selected.find((el) => el === item.id)
308
+ );
309
+ const isFocus = i === focusIndex;
310
+ return /* @__PURE__ */ jsx(
311
+ Button,
312
+ {
313
+ className: `tag-selector-button ${isFocus ? "focus" : ""}`,
314
+ onClick: () => {
315
+ var _a;
316
+ toggleItem(item.id);
317
+ (_a = fieldRef.current) == null ? void 0 : _a.focus();
318
+ },
319
+ onMouseEnter: () => {
320
+ setFocusIndex(i);
321
+ },
322
+ style: {
323
+ width: "100%",
324
+ background: isFocus ? "var(--accent-a3)" : void 0,
325
+ color: "var(--gray-12)",
326
+ fontWeight: 400,
327
+ boxShadow: "none"
328
+ },
329
+ variant: isSelected ? "soft" : "outline",
330
+ children: /* @__PURE__ */ jsxs(Flex, { justify: "between", width: "100%", children: [
331
+ item.name,
332
+ isSelected ? /* @__PURE__ */ jsx(CheckIcon, {}) : null
333
+ ] })
334
+ },
335
+ item.id
336
+ );
337
+ }) })
338
+ }
339
+ )
340
+ }
341
+ )
342
+ }
343
+ )
344
+ ] });
345
+ }
346
+
347
+ export {
348
+ TagSelector
349
+ };
350
+ //# sourceMappingURL=chunk-WNYDAKKK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/molecules/tag-selector.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n ChevronRightIcon,\n Cross1Icon,\n MagnifyingGlassIcon,\n} from '@radix-ui/react-icons';\nimport { Popover } from '../atoms/popover';\nimport { Flex } from '../atoms/flex';\nimport { Button } from '../atoms/button';\nimport type { BadgeProps } from '../atoms/badge';\nimport { Badge } from '../atoms/badge';\nimport { CheckIcon } from '../icon';\nimport { ScrollArea } from '../atoms/scroll-area';\nimport { Grid } from '../atoms/grid';\nimport type { TypoProps } from '../atoms';\nimport { AutoSizingInput, Typo } from '../atoms';\n\ntype ID = string;\ninterface Item {\n name: string;\n id: ID;\n}\n\nconst OPTION_HEIGHT = 32;\n\nexport interface TagSelectorProps<T extends Item> {\n options?: T[];\n selected?: ID[];\n placeholder?: string;\n disabled?: boolean;\n maxCount?: number;\n style?: React.CSSProperties;\n size?: 'large' | 'medium' | 'small';\n readOnly?: boolean;\n error?: boolean;\n\n onChange?: (selected: ID[]) => void;\n tagRender?: (item: T) => React.ReactElement;\n DropdownContainer?: DropdownContainer<T>;\n}\ntype DropdownContainer<T> = (props: {\n items: T[];\n children: React.ReactElement;\n currentItem?: T;\n}) => React.ReactElement;\n\nconst DefaultDropdownContainer = (props: {\n children: React.ReactElement;\n}): React.ReactElement => {\n return props.children;\n};\n\nexport function TagSelector<T extends Item>(\n props: TagSelectorProps<T>\n): React.ReactElement {\n const {\n options = [],\n tagRender,\n placeholder,\n maxCount = 0,\n DropdownContainer = DefaultDropdownContainer,\n size = 'medium',\n readOnly,\n error,\n } = props;\n // eslint-disable-next-line react/hook-use-state -- props에 따라 미사용 상태가 될 수 있음\n const [_selected, _setSelected] = useState<string[]>(props.selected || []);\n const selected = props.selected || _selected;\n const setSelected: (v: ID[]) => void = props.onChange || _setSelected;\n const [value, setValue] = useState<string>('');\n const [focusIndex, setFocusIndex] = useState<number | null>(null);\n const [open, setOpen] = useState(false);\n const [focus, setFocus] = useState(false);\n const fieldRef = useRef<HTMLInputElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const closeRef = useRef<ReturnType<typeof setTimeout>>();\n\n const onFocus = useCallback(() => {\n clearTimeout(closeRef.current);\n setFocus(true);\n setOpen(true);\n }, []);\n\n const onBlur = useCallback(() => {\n closeRef.current = setTimeout(() => {\n setFocus(false);\n setOpen(false);\n setTimeout(() => {\n setValue('');\n }, 100);\n }, 300);\n }, []);\n\n const onChangeValue = useCallback<React.ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n setValue(e.target.value);\n },\n []\n );\n\n const filteredOptions = useMemo<T[]>(() => {\n return options.filter((option) => {\n return option.name.includes(value);\n });\n }, [options, value]);\n\n const selectedItem = useMemo<T[]>(() => {\n const result = [] as T[];\n selected.forEach((id) => {\n const maybeItem = options.find((option) => option.id === id);\n if (maybeItem) result.push(maybeItem);\n });\n return result;\n }, [options, selected]);\n\n const onDelete = useCallback(\n (id: string) => {\n setSelected(selected.filter((el) => el !== id));\n },\n [selected, setSelected]\n );\n\n const onSelect = useCallback(\n (id: string) => {\n if (maxCount && selected.length + 1 > maxCount) return;\n setSelected([...selected, id]);\n },\n [maxCount, selected, setSelected]\n );\n\n const toggleItem = useCallback(\n (id: string) => {\n if (selected.includes(id)) {\n onDelete(id);\n } else {\n onSelect(id);\n }\n },\n [onDelete, onSelect, selected]\n );\n\n const setScroll = useCallback((index: number): void => {\n if (scrollRef.current) {\n const scrollTop = scrollRef.current.scrollTop;\n const clientHeight = scrollRef.current.clientHeight;\n const focusTop = index * OPTION_HEIGHT;\n if (focusTop < scrollTop) {\n scrollRef.current.scrollTop = focusTop;\n } else if (focusTop + OPTION_HEIGHT > scrollTop + clientHeight) {\n scrollRef.current.scrollTop = focusTop + OPTION_HEIGHT - clientHeight;\n }\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n const key = e.key;\n\n switch (key) {\n case 'ArrowDown': {\n e.preventDefault();\n let newFocus = 0;\n if (typeof focusIndex === 'number') {\n newFocus = focusIndex + 1 >= options.length ? 0 : focusIndex + 1;\n }\n setFocusIndex(newFocus);\n setScroll(newFocus);\n break;\n }\n\n case 'ArrowUp': {\n e.preventDefault();\n let newFocus = 0;\n if (typeof focusIndex === 'number') {\n newFocus = focusIndex - 1 < 0 ? options.length - 1 : focusIndex - 1;\n }\n setFocusIndex(newFocus);\n setScroll(newFocus);\n break;\n }\n\n case 'Enter':\n setValue('');\n if (focusIndex !== null) {\n toggleItem(filteredOptions[focusIndex]?.id);\n }\n break;\n\n case 'Backspace':\n if (value.length === 0) {\n setSelected(selected.slice(0, -1));\n }\n break;\n\n case 'Escape':\n setOpen(false);\n break;\n }\n },\n [\n focusIndex,\n value.length,\n setScroll,\n options.length,\n toggleItem,\n filteredOptions,\n setSelected,\n selected,\n ]\n );\n\n const placeholderVisible = useMemo(() => {\n if (selectedItem.length) return false;\n if (value) return false;\n if (focus) return false;\n return true;\n }, [focus, selectedItem.length, value]);\n\n useEffect(() => {\n setFocusIndex(null);\n }, [open]);\n\n useEffect(() => {\n setFocusIndex(0);\n }, [filteredOptions]);\n\n const badgeSize = useMemo<BadgeProps['size']>(() => {\n switch (size) {\n case 'large':\n return 'large';\n case 'medium':\n case 'small':\n default:\n return 'small';\n }\n }, [size]);\n\n const placeholderVariant = useMemo<TypoProps['variant']>(() => {\n switch (size) {\n case 'large':\n return 'subtitle';\n case 'medium':\n default:\n return 'body';\n }\n }, [size]);\n\n const focusClassName = focus ? ' focused' : '';\n const readOnlyClassName = readOnly ? ' read-only' : '';\n const errorClassName = error ? ' error' : '';\n\n const readonlyContent = (\n <Flex gap=\"1\">\n {selectedItem.map((item) => {\n return tagRender ? (\n tagRender(item)\n ) : (\n <Badge key={item.id} size={badgeSize}>\n {item.name}\n </Badge>\n );\n })}\n </Flex>\n );\n\n const editContent = (\n <>\n <Flex\n align=\"center\"\n gap=\"1\"\n maxWidth=\"100%\"\n overflow=\"hidden\"\n wrap=\"wrap\"\n >\n {selectedItem.map((item) => {\n return tagRender ? (\n tagRender(item)\n ) : (\n <Badge key={item.id} size={badgeSize}>\n {item.name}\n <Button\n onClick={() => {\n onDelete(item.id);\n }}\n variant=\"transparent\"\n >\n <Cross1Icon />\n </Button>\n </Badge>\n );\n })}\n {placeholderVisible ? (\n <Typo color=\"gray\" variant={placeholderVariant}>\n {placeholder}\n </Typo>\n ) : null}\n <AutoSizingInput\n onBlur={onBlur}\n onChange={onChangeValue}\n onFocus={onFocus}\n onKeyDown={handleKeyDown}\n ref={fieldRef}\n value={value}\n />\n </Flex>\n {focus ? <MagnifyingGlassIcon /> : <ChevronRightIcon />}\n </>\n );\n return (\n <Popover.Root open={Boolean(filteredOptions.length) && open}>\n <Popover.Trigger style={{ position: 'relative' }}>\n <Grid\n align=\"center\"\n className={`tag-selector ${size} ${focusClassName}${readOnlyClassName}${errorClassName}`}\n columns=\"1fr auto\"\n gap=\"1\"\n onClick={() => !readOnly && fieldRef.current?.focus()}\n >\n {readOnly ? readonlyContent : editContent}\n </Grid>\n </Popover.Trigger>\n\n <Popover.Content\n onOpenAutoFocus={(e) => {\n e.preventDefault();\n }}\n >\n <DropdownContainer\n currentItem={filteredOptions[focusIndex || 0]}\n items={filteredOptions}\n >\n <ScrollArea\n ref={scrollRef}\n scrollbars=\"vertical\"\n style={{ height: OPTION_HEIGHT * 8 }}\n type=\"auto\"\n >\n <Flex direction=\"column\">\n {filteredOptions.map((item, i) => {\n const isSelected = Boolean(\n selected.find((el) => el === item.id)\n );\n const isFocus = i === focusIndex;\n\n return (\n <Button\n className={`tag-selector-button ${isFocus ? 'focus' : ''}`}\n key={item.id}\n onClick={() => {\n toggleItem(item.id);\n fieldRef.current?.focus();\n }}\n onMouseEnter={() => {\n setFocusIndex(i);\n }}\n style={{\n width: '100%',\n background: isFocus ? 'var(--accent-a3)' : undefined,\n color: 'var(--gray-12)',\n fontWeight: 400,\n boxShadow: 'none',\n }}\n variant={isSelected ? 'soft' : 'outline'}\n >\n <Flex justify=\"between\" width=\"100%\">\n {item.name}\n {isSelected ? <CheckIcon /> : null}\n </Flex>\n </Button>\n );\n })}\n </Flex>\n </ScrollArea>\n </DropdownContainer>\n </Popover.Content>\n </Popover.Root>\n );\n}\n"],"mappings":"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","names":[]}