@exem-ui/react 0.3.4-next.20260727012122 → 0.3.4-next.20260728024650

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.
@@ -4,10 +4,11 @@ var chunk57QR33TR_js = require('./chunk-57QR33TR.js');
4
4
  var utils = require('@exem-ui/core/utils');
5
5
  var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
- var TabsPrimitive2 = require('@radix-ui/react-tabs');
7
+ var combobox = require('@base-ui/react/combobox');
8
8
  var React = require('react');
9
- var SelectPrimitive = require('@radix-ui/react-select');
10
9
  var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
10
+ var TabsPrimitive2 = require('@radix-ui/react-tabs');
11
+ var SelectPrimitive = require('@radix-ui/react-select');
11
12
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
12
13
 
13
14
  function _interopNamespace(e) {
@@ -29,10 +30,10 @@ function _interopNamespace(e) {
29
30
  }
30
31
 
31
32
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
32
- var TabsPrimitive2__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive2);
33
33
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
- var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
35
34
  var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
35
+ var TabsPrimitive2__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive2);
36
+ var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
36
37
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
37
38
 
38
39
  var colorPaletteColorClasses = {
@@ -147,166 +148,6 @@ function FlatColorPalette({
147
148
  return /* @__PURE__ */ jsxRuntime.jsx(ColorPalette, { ...rootProps, children: palette.map((color) => /* @__PURE__ */ jsxRuntime.jsx(ColorPalette.Swatch, { color }, color)) });
148
149
  }
149
150
  FlatColorPalette.displayName = "FlatColorPalette";
150
- var segmentListVariants = utils.cva(
151
- "inline-flex items-center overflow-hidden rounded-medium bg-elevation-elevation-2",
152
- {
153
- variants: {
154
- size: {
155
- small: "h-7 gap-0 p-0.5",
156
- medium: "h-8 gap-0 p-0.5",
157
- large: "h-10 gap-0 p-0.5"
158
- }
159
- },
160
- defaultVariants: {
161
- size: "medium"
162
- }
163
- }
164
- );
165
- var segmentItemVariants = utils.cva(
166
- [
167
- "flex flex-1 items-center justify-center rounded-weak",
168
- "focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-ring",
169
- "disabled:cursor-not-allowed",
170
- "data-[state=active]:bg-component-segmentedOption data-[state=active]:text-text-primary data-[state=active]:shadow-weak",
171
- "data-[state=inactive]:text-text-tertiary data-[state=inactive]:disabled:text-text-disabled",
172
- "transition-colors duration-200 ease-in-out"
173
- ],
174
- {
175
- variants: {
176
- size: {
177
- small: "h-6 gap-0.5 text-body-3 font-medium",
178
- medium: "h-7 gap-1 text-body-2 font-medium",
179
- large: "h-9 gap-1.5 text-body-2 font-medium"
180
- }
181
- },
182
- defaultVariants: {
183
- size: "medium"
184
- }
185
- }
186
- );
187
- var segmentIconVariants = utils.cva("flex items-center justify-center", {
188
- variants: {
189
- size: {
190
- small: "size-4",
191
- medium: "size-4",
192
- large: "size-5"
193
- }
194
- },
195
- defaultVariants: {
196
- size: "medium"
197
- }
198
- });
199
- var SegmentContext = React.createContext(void 0);
200
- var useSegmentContext = () => {
201
- const context = React.useContext(SegmentContext);
202
- if (!context) {
203
- throw new Error("Segment components must be used within a Segment");
204
- }
205
- return context;
206
- };
207
- var Segment = React.forwardRef(
208
- ({ size = "medium", children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SegmentContext.Provider, { value: { size }, children: /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive2__namespace.Root, { ref, ...props, children }) })
209
- );
210
- Segment.List = React.forwardRef(
211
- ({ className, ...props }, ref) => {
212
- const { size } = useSegmentContext();
213
- return /* @__PURE__ */ jsxRuntime.jsx(
214
- TabsPrimitive2__namespace.List,
215
- {
216
- ref,
217
- className: utils.cn(segmentListVariants({ size }), className),
218
- ...props
219
- }
220
- );
221
- }
222
- );
223
- Segment.Item = React.forwardRef(
224
- ({ className, leftIcon, children, ...props }, ref) => {
225
- const { size } = useSegmentContext();
226
- return /* @__PURE__ */ jsxRuntime.jsxs(
227
- TabsPrimitive2__namespace.Trigger,
228
- {
229
- ref,
230
- className: utils.cn(segmentItemVariants({ size }), className),
231
- ...props,
232
- children: [
233
- leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn(segmentIconVariants({ size })), children: leftIcon }),
234
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center", children })
235
- ]
236
- }
237
- );
238
- }
239
- );
240
- Segment.Content = React.forwardRef(
241
- ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
242
- TabsPrimitive2__namespace.Content,
243
- {
244
- ref,
245
- className: utils.cn(
246
- "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
247
- className
248
- ),
249
- ...props
250
- }
251
- )
252
- );
253
- Segment.displayName = "Segment";
254
- Segment.List.displayName = "Segment.List";
255
- Segment.Content.displayName = "Segment.Content";
256
- Segment.Item.displayName = "Segment.Item";
257
- function FlatSegment({
258
- items,
259
- disabled,
260
- className,
261
- ...props
262
- }) {
263
- const rootProps = props;
264
- return /* @__PURE__ */ jsxRuntime.jsx(Segment, { ...rootProps, children: /* @__PURE__ */ jsxRuntime.jsx(Segment.List, { className, children: items.map((item) => /* @__PURE__ */ React.createElement(Segment.Item, { ...item, key: item.value, disabled: disabled || item.disabled })) }) });
265
- }
266
- FlatSegment.displayName = "FlatSegment";
267
- var overlayListVariants = {
268
- content: utils.cn(
269
- "relative z-50 min-w-[8rem] overflow-hidden rounded-medium border border-border-primary bg-background-overlay shadow-weak",
270
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
271
- ),
272
- viewport: utils.cn("flex flex-col gap-0.5 p-1"),
273
- item: utils.cva(
274
- "relative flex w-full gap-0.5 cursor-pointer select-none items-center rounded-weak px-2 text-body-2 text-text-primary outline-none hover:bg-elevation-elevation-2 data-[disabled]:pointer-events-none data-[disabled]:text-text-disabled",
275
- {
276
- defaultVariants: { size: "medium" },
277
- variants: {
278
- size: {
279
- xsmall: "h-6",
280
- small: "h-7",
281
- medium: "h-8",
282
- large: "h-10"
283
- }
284
- }
285
- }
286
- ),
287
- itemText: utils.cva("truncate flex items-center flex-1 min-w-0", {
288
- defaultVariants: { size: "medium" },
289
- variants: {
290
- size: {
291
- xsmall: "h-6",
292
- small: "h-7",
293
- medium: "h-8",
294
- large: "h-10"
295
- }
296
- }
297
- }),
298
- slotSize: utils.cva("shrink-0 flex items-center justify-center text-icon-primary", {
299
- defaultVariants: { size: "medium" },
300
- variants: {
301
- size: {
302
- xsmall: "size-4",
303
- small: "size-4",
304
- medium: "size-4",
305
- large: "size-5"
306
- }
307
- }
308
- })
309
- };
310
151
  function ScrollBar({
311
152
  className,
312
153
  orientation = "vertical",
@@ -377,6 +218,49 @@ function ScrollArea({
377
218
  }
378
219
  );
379
220
  }
221
+ var overlayListVariants = {
222
+ content: utils.cn(
223
+ "relative z-50 min-w-[8rem] overflow-hidden rounded-medium border border-border-primary bg-background-overlay shadow-weak",
224
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
225
+ ),
226
+ viewport: utils.cn("flex flex-col gap-0.5 p-1"),
227
+ item: utils.cva(
228
+ "relative flex w-full gap-0.5 cursor-pointer select-none items-center rounded-weak px-2 text-body-2 text-text-primary outline-none hover:bg-elevation-elevation-2 data-[disabled]:pointer-events-none data-[disabled]:text-text-disabled",
229
+ {
230
+ defaultVariants: { size: "medium" },
231
+ variants: {
232
+ size: {
233
+ xsmall: "h-6",
234
+ small: "h-7",
235
+ medium: "h-8",
236
+ large: "h-10"
237
+ }
238
+ }
239
+ }
240
+ ),
241
+ itemText: utils.cva("truncate flex items-center flex-1 min-w-0", {
242
+ defaultVariants: { size: "medium" },
243
+ variants: {
244
+ size: {
245
+ xsmall: "h-6",
246
+ small: "h-7",
247
+ medium: "h-8",
248
+ large: "h-10"
249
+ }
250
+ }
251
+ }),
252
+ slotSize: utils.cva("shrink-0 flex items-center justify-center text-icon-primary", {
253
+ defaultVariants: { size: "medium" },
254
+ variants: {
255
+ size: {
256
+ xsmall: "size-4",
257
+ small: "size-4",
258
+ medium: "size-4",
259
+ large: "size-5"
260
+ }
261
+ }
262
+ })
263
+ };
380
264
  var commonInputVariants = {
381
265
  // Container variants - 전체 컴포넌트 래퍼
382
266
  container: utils.cva("flex flex-col"),
@@ -536,6 +420,593 @@ var selectVariants = {
536
420
  }),
537
421
  viewport: overlayListVariants.viewport
538
422
  };
423
+ var textFieldVariants = {
424
+ container: commonInputVariants.container,
425
+ label: commonInputVariants.label,
426
+ wrapper: utils.cva(
427
+ "flex w-full flex-row items-center rounded-medium border transition-colors focus-within:border-border-focused focus-within:outline-none",
428
+ {
429
+ variants: {
430
+ variant: {
431
+ fill: "border-transparent bg-elevation-elevation-2",
432
+ line: "border-border-primary",
433
+ lineBackground: "border-border-primary bg-background-primary"
434
+ },
435
+ size: {
436
+ xsmall: "h-6 gap-0 px-1",
437
+ small: "h-7 gap-0.5 px-1.5",
438
+ medium: "h-8 gap-0.5 px-2",
439
+ large: "h-10 gap-1 px-2.5"
440
+ },
441
+ state: {
442
+ default: "text-text-primary",
443
+ error: "text-text-primary",
444
+ disabled: "cursor-not-allowed text-text-disabled"
445
+ }
446
+ },
447
+ compoundVariants: [
448
+ { variant: "fill", state: "error", class: "border-border-critical" },
449
+ {
450
+ variant: "fill",
451
+ state: "disabled",
452
+ class: "bg-elevation-elevation-2 border-transparent"
453
+ },
454
+ { variant: "line", state: "error", class: "border-border-critical" },
455
+ { variant: "line", state: "disabled", class: "border-border-primary" },
456
+ { variant: "lineBackground", state: "error", class: "border-border-critical" },
457
+ { variant: "lineBackground", state: "disabled", class: "border-border-primary" }
458
+ ],
459
+ defaultVariants: { variant: "fill", size: "medium", state: "default" }
460
+ }
461
+ ),
462
+ input: utils.cva(
463
+ "w-full border-none bg-transparent p-0 focus:outline-none focus:ring-0 disabled:cursor-not-allowed",
464
+ {
465
+ variants: {
466
+ size: {
467
+ xsmall: "text-body-3 placeholder:text-body-3",
468
+ small: "text-body-2 placeholder:text-body-2",
469
+ medium: "text-body-2 placeholder:text-body-2",
470
+ large: "text-body-1 placeholder:text-body-1"
471
+ },
472
+ state: {
473
+ default: "text-text-primary placeholder:text-text-tertiary",
474
+ error: "text-text-primary placeholder:text-text-tertiary",
475
+ disabled: "text-text-disabled placeholder:text-text-disabled"
476
+ }
477
+ },
478
+ defaultVariants: { size: "medium", state: "default" }
479
+ }
480
+ ),
481
+ description: utils.cva("mt-0.5 font-regular text-text-tertiary", {
482
+ variants: {
483
+ size: {
484
+ xsmall: "text-caption",
485
+ small: "text-body-3",
486
+ medium: "text-body-3",
487
+ large: "text-body-2"
488
+ },
489
+ error: {
490
+ true: "text-text-critical",
491
+ false: ""
492
+ },
493
+ disabled: {
494
+ true: "text-text-disabled",
495
+ false: ""
496
+ }
497
+ },
498
+ compoundVariants: [
499
+ {
500
+ disabled: true,
501
+ error: true,
502
+ class: "text-text-disabled"
503
+ // disabled가 error보다 우선
504
+ }
505
+ ],
506
+ defaultVariants: { size: "medium", error: false, disabled: false }
507
+ }),
508
+ subText: utils.cva("ml-1 shrink-0 font-regular", {
509
+ variants: {
510
+ size: {
511
+ xsmall: "text-body-3",
512
+ small: "text-body-2",
513
+ medium: "text-body-2",
514
+ large: "text-body-1"
515
+ },
516
+ disabled: {
517
+ true: "text-text-disabled",
518
+ false: "text-text-tertiary"
519
+ }
520
+ },
521
+ defaultVariants: { size: "medium", disabled: false }
522
+ }),
523
+ icon: utils.cva("shrink-0 text-icon-tertiary", {
524
+ variants: {
525
+ size: {
526
+ xsmall: "size-4",
527
+ small: "size-4",
528
+ medium: "size-4",
529
+ large: "size-5"
530
+ }
531
+ },
532
+ defaultVariants: { size: "medium" }
533
+ })
534
+ };
535
+
536
+ // src/combobox/comboboxVariants.ts
537
+ var comboboxVariants = {
538
+ container: selectVariants.container,
539
+ description: selectVariants.description,
540
+ iconSize: overlayListVariants.slotSize,
541
+ label: selectVariants.label,
542
+ // 단독(anchored) 입력형 - Select 트리거와 같은 fill 박스 형태
543
+ input: utils.cva(
544
+ "w-full rounded-medium bg-elevation-elevation-2 text-text-primary outline-none placeholder:text-text-tertiary focus:ring-1 focus:ring-inset focus:ring-border-focused disabled:cursor-not-allowed disabled:bg-elevation-elevation-2 disabled:text-text-disabled",
545
+ {
546
+ defaultVariants: { size: "medium" },
547
+ variants: {
548
+ size: {
549
+ xsmall: "h-6 px-[4px] text-body-3",
550
+ small: "h-7 px-[6px] text-body-2",
551
+ medium: "h-8 px-[8px] text-body-2",
552
+ large: "h-10 px-[10px] text-body-1"
553
+ }
554
+ }
555
+ }
556
+ ),
557
+ item: (props) => utils.cn(
558
+ overlayListVariants.item(props),
559
+ // group/option: 표시 전용 체크박스가 아이템의 data-selected 상태를 CSS로 읽기 위함
560
+ "group/option data-[highlighted]:bg-elevation-elevation-2 data-[selected]:bg-elevation-accent-0"
561
+ ),
562
+ // 다중 선택 아이템의 표시 전용 체크박스 (Figma: 16px, gap 6px — item gap 2px + mr 4px)
563
+ // 시각은 Checkbox 컴포넌트의 상태 토큰과 동일하게 유지한다
564
+ itemCheckbox: utils.cn(
565
+ "mr-1 flex size-4 shrink-0 items-center justify-center rounded-weak border border-border-secondary bg-background-primary transition-colors duration-200",
566
+ "group-data-[selected]/option:border-transparent group-data-[selected]/option:bg-solid-accent-default",
567
+ "group-data-[disabled]/option:bg-elevation-elevation-3"
568
+ ),
569
+ list: utils.cn(overlayListVariants.viewport, "p-0 empty:hidden"),
570
+ // Positioner는 transform으로 자체 스타킹 컨텍스트를 만들므로 z-index를 여기(루트 레벨)에 줘야
571
+ // Modal/Sheet(z-50) 위에 팝업이 올라온다. popup의 z-50은 컨텍스트 내부라 루트에선 무효.
572
+ // pointer-events-auto: radix modal이 body에 pointer-events:none을 걸어도 팝업 클릭이 동작하도록.
573
+ // TODO(#305): radix 제거(Base UI 이관) 시 pointer-events-auto는 불필요 (z-50은 유지)
574
+ positioner: "z-50 pointer-events-auto",
575
+ popup: utils.cn(
576
+ "relative z-50 flex max-h-[var(--available-height)] w-[var(--anchor-width)] min-w-[8rem] max-w-[var(--available-width)] origin-[var(--transform-origin)] flex-col gap-0.5 overflow-hidden rounded-medium border border-border-primary bg-background-overlay p-1 shadow-weak",
577
+ "transition-[transform,scale,opacity] duration-150 data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0"
578
+ ),
579
+ // 팝업 상단 검색바 - TextField(fill)와 동일한 디자인
580
+ searchIcon: textFieldVariants.icon,
581
+ searchInput: textFieldVariants.input,
582
+ searchWrapper: textFieldVariants.wrapper,
583
+ trigger: (props) => utils.cn(
584
+ // selectVariants.trigger의 radix용 data-[state=open] 클래스는 Base UI에서 매칭되지 않는
585
+ // dead class로 남는다(무해). 아래는 동일한 open 스타일의 Base UI attribute 버전.
586
+ selectVariants.trigger(props),
587
+ "data-[popup-open]:border data-[popup-open]:border-border-focused"
588
+ )
589
+ };
590
+ var ComboboxContext = React.createContext(null);
591
+ var useComboboxContext = () => React.useContext(ComboboxContext);
592
+ function ComboboxRoot({
593
+ size = "medium",
594
+ error = false,
595
+ disabled = false,
596
+ className,
597
+ ...props
598
+ }) {
599
+ return /* @__PURE__ */ jsxRuntime.jsx(ComboboxContext.Provider, { value: { disabled, error, multiple: Boolean(props.multiple), size }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn(comboboxVariants.container(), className), children: /* @__PURE__ */ jsxRuntime.jsx(combobox.Combobox.Root, { disabled, ...props }) }) });
600
+ }
601
+ function ComboboxLabel({
602
+ className,
603
+ size: sizeProp,
604
+ required = false,
605
+ ...props
606
+ }) {
607
+ const context = useComboboxContext();
608
+ const size = sizeProp ?? context?.size;
609
+ const disabled = context?.disabled ?? false;
610
+ return /* @__PURE__ */ jsxRuntime.jsx(
611
+ combobox.Combobox.Label,
612
+ {
613
+ "data-slot": "combobox-label",
614
+ className: utils.cn(comboboxVariants.label({ disabled, required, size }), className),
615
+ ...props
616
+ }
617
+ );
618
+ }
619
+ function ComboboxDescription({ children, size: sizeProp, className }) {
620
+ const context = useComboboxContext();
621
+ const size = sizeProp ?? context?.size;
622
+ if (!children) {
623
+ return null;
624
+ }
625
+ return /* @__PURE__ */ jsxRuntime.jsx(
626
+ "div",
627
+ {
628
+ "data-slot": "combobox-description",
629
+ className: utils.cn(
630
+ comboboxVariants.description({
631
+ disabled: context?.disabled ?? false,
632
+ error: context?.error ?? false,
633
+ size
634
+ }),
635
+ className
636
+ ),
637
+ children: /* @__PURE__ */ jsxRuntime.jsx("p", { children })
638
+ }
639
+ );
640
+ }
641
+ function ComboboxValue(props) {
642
+ return /* @__PURE__ */ jsxRuntime.jsx(combobox.Combobox.Value, { "data-slot": "combobox-value", ...props });
643
+ }
644
+ function ComboboxTrigger({
645
+ className,
646
+ children,
647
+ size: sizeProp,
648
+ variant = "fill",
649
+ error: errorProp,
650
+ ...props
651
+ }) {
652
+ const context = useComboboxContext();
653
+ const size = sizeProp ?? context?.size ?? "medium";
654
+ const error = errorProp ?? context?.error ?? false;
655
+ return /* @__PURE__ */ jsxRuntime.jsxs(
656
+ combobox.Combobox.Trigger,
657
+ {
658
+ "data-slot": "combobox-trigger",
659
+ className: utils.cn(comboboxVariants.trigger({ error, size, variant }), className),
660
+ ...props,
661
+ children: [
662
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1 truncate text-left", children }),
663
+ /* @__PURE__ */ jsxRuntime.jsx(
664
+ chunk57QR33TR_js.ChevronDown,
665
+ {
666
+ type: "regular",
667
+ className: utils.cn(
668
+ comboboxVariants.iconSize({ size }),
669
+ "transition-transform duration-200 group-data-[popup-open]:rotate-180 group-disabled:text-icon-disabled"
670
+ )
671
+ }
672
+ )
673
+ ]
674
+ }
675
+ );
676
+ }
677
+ function ComboboxInput({ className, size: sizeProp, ...props }) {
678
+ const context = useComboboxContext();
679
+ const size = sizeProp ?? context?.size ?? "medium";
680
+ return /* @__PURE__ */ jsxRuntime.jsx(
681
+ combobox.Combobox.Input,
682
+ {
683
+ "data-slot": "combobox-input",
684
+ className: utils.cn(comboboxVariants.input({ size }), className),
685
+ ...props
686
+ }
687
+ );
688
+ }
689
+ function ComboboxSearch({ className, size: sizeProp, ...props }) {
690
+ const context = useComboboxContext();
691
+ const size = sizeProp ?? context?.size ?? "medium";
692
+ return (
693
+ // Figma Select List 스펙: 팝업 p-1(4px) 안에 Search 래퍼 p-1이 중첩되어 검색바 인셋은 8px
694
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "combobox-search", className: "w-full shrink-0 p-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn(comboboxVariants.searchWrapper({ size, variant: "fill" }), className), children: [
695
+ /* @__PURE__ */ jsxRuntime.jsx(
696
+ chunk57QR33TR_js.Search,
697
+ {
698
+ type: "regular",
699
+ className: utils.cn("flex items-center justify-center", comboboxVariants.searchIcon({ size }))
700
+ }
701
+ ),
702
+ /* @__PURE__ */ jsxRuntime.jsx(
703
+ combobox.Combobox.Input,
704
+ {
705
+ "data-slot": "combobox-search-input",
706
+ className: utils.cn("px-0.5", comboboxVariants.searchInput({ size })),
707
+ ...props
708
+ }
709
+ )
710
+ ] }) })
711
+ );
712
+ }
713
+ function ComboboxContent({
714
+ className,
715
+ children,
716
+ sideOffset = 4,
717
+ align = "start",
718
+ side,
719
+ ...props
720
+ }) {
721
+ return /* @__PURE__ */ jsxRuntime.jsx(combobox.Combobox.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
722
+ combobox.Combobox.Positioner,
723
+ {
724
+ className: comboboxVariants.positioner,
725
+ align,
726
+ side,
727
+ sideOffset,
728
+ children: /* @__PURE__ */ jsxRuntime.jsx(
729
+ combobox.Combobox.Popup,
730
+ {
731
+ "data-slot": "combobox-content",
732
+ className: utils.cn(comboboxVariants.popup, className),
733
+ ...props,
734
+ children
735
+ }
736
+ )
737
+ }
738
+ ) });
739
+ }
740
+ function ComboboxList({ className, ...props }) {
741
+ return (
742
+ // min-h-0: 팝업(max-h: --available-height)이 좁을 때 flex 자식인 ScrollArea가 줄어들도록
743
+ /* @__PURE__ */ jsxRuntime.jsx(
744
+ ScrollArea,
745
+ {
746
+ className: "min-h-0 max-h-60 [&_[data-slot=scroll-area-viewport]]:max-h-[inherit]",
747
+ disableHorizontalScroll: true,
748
+ children: /* @__PURE__ */ jsxRuntime.jsx(
749
+ combobox.Combobox.List,
750
+ {
751
+ "data-slot": "combobox-list",
752
+ className: utils.cn(comboboxVariants.list, className),
753
+ ...props
754
+ }
755
+ )
756
+ }
757
+ )
758
+ );
759
+ }
760
+ function ComboboxItem({
761
+ className,
762
+ children,
763
+ size: sizeProp,
764
+ checkbox,
765
+ leftIcon,
766
+ rightIcon,
767
+ rightSlot,
768
+ ...props
769
+ }) {
770
+ const context = useComboboxContext();
771
+ const size = sizeProp ?? context?.size ?? "medium";
772
+ const showCheckbox = checkbox ?? context?.multiple ?? false;
773
+ return /* @__PURE__ */ jsxRuntime.jsxs(
774
+ combobox.Combobox.Item,
775
+ {
776
+ "data-slot": "combobox-item",
777
+ className: utils.cn(comboboxVariants.item({ size }), className),
778
+ ...props,
779
+ children: [
780
+ showCheckbox && // 표시 전용 체크박스 — 선택 상태는 아이템의 data-selected가 CSS로 구동 (Figma 14009-5969)
781
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: comboboxVariants.itemCheckbox, children: /* @__PURE__ */ jsxRuntime.jsx(
782
+ chunk57QR33TR_js.Check,
783
+ {
784
+ type: "regular",
785
+ className: "hidden size-4 text-icon-static-light group-data-[selected]/option:block"
786
+ }
787
+ ) }),
788
+ leftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: comboboxVariants.iconSize({ size }), children: leftIcon }),
789
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1 overflow-hidden", children: [
790
+ /* @__PURE__ */ jsxRuntime.jsx(
791
+ "span",
792
+ {
793
+ className: "min-w-0 flex-1 truncate",
794
+ title: typeof children === "string" ? children : void 0,
795
+ children
796
+ }
797
+ ),
798
+ rightSlot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: rightSlot })
799
+ ] }),
800
+ rightIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: comboboxVariants.iconSize({ size }), children: rightIcon })
801
+ ]
802
+ }
803
+ );
804
+ }
805
+ function ComboboxEmpty({ className, children = "No data", ...props }) {
806
+ return /* @__PURE__ */ jsxRuntime.jsx(
807
+ combobox.Combobox.Empty,
808
+ {
809
+ "data-slot": "combobox-empty",
810
+ className: utils.cn(
811
+ // Base UI Empty는 live region이라 display:none으로 숨기면 안 됨 → 결과가 있을 땐 크기만 0으로 수축
812
+ // Figma 스펙: empty 팝업 높이 80px 고정 (팝업 패딩 4px*2 포함이므로 72px)
813
+ "flex items-center justify-center text-body-2 text-text-disabled",
814
+ "[&:not(:empty)]:min-h-[72px] [&:not(:empty)]:p-2",
815
+ className
816
+ ),
817
+ ...props,
818
+ children
819
+ }
820
+ );
821
+ }
822
+ var Combobox = Object.assign(ComboboxRoot, {
823
+ Content: ComboboxContent,
824
+ Description: ComboboxDescription,
825
+ Empty: ComboboxEmpty,
826
+ Input: ComboboxInput,
827
+ Item: ComboboxItem,
828
+ Label: ComboboxLabel,
829
+ List: ComboboxList,
830
+ Search: ComboboxSearch,
831
+ Trigger: ComboboxTrigger,
832
+ Value: ComboboxValue
833
+ });
834
+ function FlatCombobox({
835
+ options,
836
+ placeholder,
837
+ searchPlaceholder,
838
+ emptyText,
839
+ label,
840
+ required,
841
+ description,
842
+ size,
843
+ variant,
844
+ error,
845
+ disabled,
846
+ value,
847
+ defaultValue,
848
+ onValueChange,
849
+ onOpenChange,
850
+ className,
851
+ listClassName
852
+ }) {
853
+ const resolveOption = (v) => options.find((option) => option.value === v) ?? null;
854
+ return /* @__PURE__ */ jsxRuntime.jsxs(
855
+ Combobox,
856
+ {
857
+ items: options,
858
+ itemToStringLabel: (option) => option.label,
859
+ isItemEqualToValue: (a, b) => a?.value === b?.value,
860
+ value: value !== void 0 ? resolveOption(value) : void 0,
861
+ defaultValue: defaultValue !== void 0 ? resolveOption(defaultValue) : void 0,
862
+ onValueChange: (option) => onValueChange?.(option?.value ?? null),
863
+ onOpenChange,
864
+ size,
865
+ error,
866
+ disabled,
867
+ className,
868
+ children: [
869
+ label && /* @__PURE__ */ jsxRuntime.jsx(Combobox.Label, { required, children: label }),
870
+ /* @__PURE__ */ jsxRuntime.jsx(Combobox.Trigger, { variant, children: /* @__PURE__ */ jsxRuntime.jsx(Combobox.Value, { placeholder }) }),
871
+ /* @__PURE__ */ jsxRuntime.jsxs(Combobox.Content, { children: [
872
+ /* @__PURE__ */ jsxRuntime.jsx(Combobox.Search, { placeholder: searchPlaceholder }),
873
+ /* @__PURE__ */ jsxRuntime.jsx(Combobox.Empty, { children: emptyText }),
874
+ /* @__PURE__ */ jsxRuntime.jsx(Combobox.List, { className: listClassName, children: (option) => /* @__PURE__ */ jsxRuntime.jsx(
875
+ Combobox.Item,
876
+ {
877
+ value: option,
878
+ disabled: option.disabled,
879
+ leftIcon: option.leftIcon,
880
+ rightIcon: option.rightIcon,
881
+ rightSlot: option.rightSlot,
882
+ children: option.label
883
+ },
884
+ option.value
885
+ ) })
886
+ ] }),
887
+ description && /* @__PURE__ */ jsxRuntime.jsx(Combobox.Description, { children: description })
888
+ ]
889
+ }
890
+ );
891
+ }
892
+ FlatCombobox.displayName = "FlatCombobox";
893
+ var segmentListVariants = utils.cva(
894
+ "inline-flex items-center overflow-hidden rounded-medium bg-elevation-elevation-2",
895
+ {
896
+ variants: {
897
+ size: {
898
+ small: "h-7 gap-0 p-0.5",
899
+ medium: "h-8 gap-0 p-0.5",
900
+ large: "h-10 gap-0 p-0.5"
901
+ }
902
+ },
903
+ defaultVariants: {
904
+ size: "medium"
905
+ }
906
+ }
907
+ );
908
+ var segmentItemVariants = utils.cva(
909
+ [
910
+ "flex flex-1 items-center justify-center rounded-weak",
911
+ "focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-ring",
912
+ "disabled:cursor-not-allowed",
913
+ "data-[state=active]:bg-component-segmentedOption data-[state=active]:text-text-primary data-[state=active]:shadow-weak",
914
+ "data-[state=inactive]:text-text-tertiary data-[state=inactive]:disabled:text-text-disabled",
915
+ "transition-colors duration-200 ease-in-out"
916
+ ],
917
+ {
918
+ variants: {
919
+ size: {
920
+ small: "h-6 gap-0.5 text-body-3 font-medium",
921
+ medium: "h-7 gap-1 text-body-2 font-medium",
922
+ large: "h-9 gap-1.5 text-body-2 font-medium"
923
+ }
924
+ },
925
+ defaultVariants: {
926
+ size: "medium"
927
+ }
928
+ }
929
+ );
930
+ var segmentIconVariants = utils.cva("flex items-center justify-center", {
931
+ variants: {
932
+ size: {
933
+ small: "size-4",
934
+ medium: "size-4",
935
+ large: "size-5"
936
+ }
937
+ },
938
+ defaultVariants: {
939
+ size: "medium"
940
+ }
941
+ });
942
+ var SegmentContext = React.createContext(void 0);
943
+ var useSegmentContext = () => {
944
+ const context = React.useContext(SegmentContext);
945
+ if (!context) {
946
+ throw new Error("Segment components must be used within a Segment");
947
+ }
948
+ return context;
949
+ };
950
+ var Segment = React.forwardRef(
951
+ ({ size = "medium", children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SegmentContext.Provider, { value: { size }, children: /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive2__namespace.Root, { ref, ...props, children }) })
952
+ );
953
+ Segment.List = React.forwardRef(
954
+ ({ className, ...props }, ref) => {
955
+ const { size } = useSegmentContext();
956
+ return /* @__PURE__ */ jsxRuntime.jsx(
957
+ TabsPrimitive2__namespace.List,
958
+ {
959
+ ref,
960
+ className: utils.cn(segmentListVariants({ size }), className),
961
+ ...props
962
+ }
963
+ );
964
+ }
965
+ );
966
+ Segment.Item = React.forwardRef(
967
+ ({ className, leftIcon, children, ...props }, ref) => {
968
+ const { size } = useSegmentContext();
969
+ return /* @__PURE__ */ jsxRuntime.jsxs(
970
+ TabsPrimitive2__namespace.Trigger,
971
+ {
972
+ ref,
973
+ className: utils.cn(segmentItemVariants({ size }), className),
974
+ ...props,
975
+ children: [
976
+ leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn(segmentIconVariants({ size })), children: leftIcon }),
977
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center", children })
978
+ ]
979
+ }
980
+ );
981
+ }
982
+ );
983
+ Segment.Content = React.forwardRef(
984
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
985
+ TabsPrimitive2__namespace.Content,
986
+ {
987
+ ref,
988
+ className: utils.cn(
989
+ "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
990
+ className
991
+ ),
992
+ ...props
993
+ }
994
+ )
995
+ );
996
+ Segment.displayName = "Segment";
997
+ Segment.List.displayName = "Segment.List";
998
+ Segment.Content.displayName = "Segment.Content";
999
+ Segment.Item.displayName = "Segment.Item";
1000
+ function FlatSegment({
1001
+ items,
1002
+ disabled,
1003
+ className,
1004
+ ...props
1005
+ }) {
1006
+ const rootProps = props;
1007
+ return /* @__PURE__ */ jsxRuntime.jsx(Segment, { ...rootProps, children: /* @__PURE__ */ jsxRuntime.jsx(Segment.List, { className, children: items.map((item) => /* @__PURE__ */ React.createElement(Segment.Item, { ...item, key: item.value, disabled: disabled || item.disabled })) }) });
1008
+ }
1009
+ FlatSegment.displayName = "FlatSegment";
539
1010
  var SelectContext = React.createContext(null);
540
1011
  var useSelectContext = () => {
541
1012
  const context = React.useContext(SelectContext);
@@ -1010,9 +1481,21 @@ ConditionalTooltip.displayName = "ConditionalTooltip";
1010
1481
 
1011
1482
  exports.ColorPalette = ColorPalette;
1012
1483
  exports.ColorPaletteColors = ColorPaletteColors;
1484
+ exports.Combobox = Combobox;
1485
+ exports.ComboboxContent = ComboboxContent;
1486
+ exports.ComboboxDescription = ComboboxDescription;
1487
+ exports.ComboboxEmpty = ComboboxEmpty;
1488
+ exports.ComboboxInput = ComboboxInput;
1489
+ exports.ComboboxItem = ComboboxItem;
1490
+ exports.ComboboxLabel = ComboboxLabel;
1491
+ exports.ComboboxList = ComboboxList;
1492
+ exports.ComboboxSearch = ComboboxSearch;
1493
+ exports.ComboboxTrigger = ComboboxTrigger;
1494
+ exports.ComboboxValue = ComboboxValue;
1013
1495
  exports.ConditionalTooltip = ConditionalTooltip;
1014
1496
  exports.DEFAULT_COLOR = DEFAULT_COLOR;
1015
1497
  exports.FlatColorPalette = FlatColorPalette;
1498
+ exports.FlatCombobox = FlatCombobox;
1016
1499
  exports.FlatSegment = FlatSegment;
1017
1500
  exports.FlatSelect = FlatSelect;
1018
1501
  exports.FlatTabs = FlatTabs;
@@ -1028,3 +1511,4 @@ exports.commonInputVariants = commonInputVariants;
1028
1511
  exports.getColorPaletteColor = getColorPaletteColor;
1029
1512
  exports.isInPalette = isInPalette;
1030
1513
  exports.overlayListVariants = overlayListVariants;
1514
+ exports.textFieldVariants = textFieldVariants;