@nurihaus/web-design-system 3.0.3 → 3.1.0

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 (99) hide show
  1. package/dist/ai/components.md +305 -11
  2. package/dist/ai/tokens.md +38 -13
  3. package/dist/avatar.js +8 -8
  4. package/dist/breadcrumb.js +364 -0
  5. package/dist/check-box.js +16 -35
  6. package/dist/chunk-149.js +4 -4
  7. package/dist/chunk-298.js +1 -1
  8. package/dist/chunk-302.js +4 -4
  9. package/dist/chunk-309.js +1 -1
  10. package/dist/chunk-364.js +2 -2
  11. package/dist/chunk-387.js +23 -4
  12. package/dist/chunk-436.js +33 -0
  13. package/dist/chunk-558.js +6 -6
  14. package/dist/chunk-563.js +7 -7
  15. package/dist/chunk-657.js +143 -0
  16. package/dist/chunk-713.js +38 -0
  17. package/dist/chunk-739.js +6 -6
  18. package/dist/chunk-77.js +34 -0
  19. package/dist/chunk-777.js +2 -2
  20. package/dist/chunk-910.js +64 -0
  21. package/dist/chunk-917.js +1 -1
  22. package/dist/chunk-933.js +4 -4
  23. package/dist/chunk-976.js +2 -2
  24. package/dist/collapsible-menu.js +7 -7
  25. package/dist/components/breadcrumb/base-breadcrumb.d.ts +19 -0
  26. package/dist/components/breadcrumb/breadcrumb-props.d.ts +4 -0
  27. package/dist/components/breadcrumb/breadcrumb-type.d.ts +33 -0
  28. package/dist/components/breadcrumb/breadcrumb.d.ts +4 -0
  29. package/dist/components/breadcrumb/breadcrumb.stories.d.ts +25 -0
  30. package/dist/components/check-box/base-check-box.d.ts +1 -1
  31. package/dist/components/drawer/base-drawer.d.ts +15 -0
  32. package/dist/components/drawer/drawer-props.d.ts +11 -0
  33. package/dist/components/drawer/drawer-type.d.ts +28 -0
  34. package/dist/components/drawer/drawer.d.ts +4 -0
  35. package/dist/components/drawer/drawer.stories.d.ts +34 -0
  36. package/dist/components/drop-down/drop-down-props.d.ts +2 -2
  37. package/dist/components/drop-down/drop-down.stories.d.ts +1 -1
  38. package/dist/components/elements/text/text-props.d.ts +1 -1
  39. package/dist/components/elements/text/text.stories.d.ts +1 -1
  40. package/dist/components/modal/base-modal.d.ts +4 -1
  41. package/dist/components/modal/modal-props.d.ts +3 -0
  42. package/dist/components/modal/modal-type.d.ts +18 -4
  43. package/dist/components/modal/modal-with-double-button.stories.d.ts +22 -0
  44. package/dist/components/modal/modal.d.ts +4 -0
  45. package/dist/components/modal/modal.stories.d.ts +11 -6
  46. package/dist/components/pagination/base-pagination.d.ts +9 -0
  47. package/dist/components/pagination/pagination-props.d.ts +4 -0
  48. package/dist/components/pagination/pagination-type.d.ts +20 -0
  49. package/dist/components/pagination/pagination.d.ts +4 -0
  50. package/dist/components/pagination/pagination.stories.d.ts +25 -0
  51. package/dist/components/skeleton/base-skeleton.d.ts +4 -0
  52. package/dist/components/skeleton/skeleton-props.d.ts +15 -0
  53. package/dist/components/skeleton/skeleton-type.d.ts +12 -0
  54. package/dist/components/skeleton/skeleton.d.ts +4 -0
  55. package/dist/components/skeleton/skeleton.stories.d.ts +327 -0
  56. package/dist/components/switch/base-switch.d.ts +11 -0
  57. package/dist/components/switch/switch-props.d.ts +4 -0
  58. package/dist/components/switch/switch-type.d.ts +19 -0
  59. package/dist/components/switch/switch.d.ts +4 -0
  60. package/dist/components/switch/switch.stories.d.ts +24 -0
  61. package/dist/components/text-area/base-text-area.d.ts +10 -0
  62. package/dist/components/text-area/text-area-props.d.ts +12 -0
  63. package/dist/components/text-area/text-area-type.d.ts +34 -0
  64. package/dist/components/text-area/text-area.d.ts +4 -0
  65. package/dist/components/text-area/text-area.stories.d.ts +32 -0
  66. package/dist/components/text-field/text-field-props.d.ts +2 -2
  67. package/dist/components/text-field/text-field.stories.d.ts +1 -1
  68. package/dist/components/toast/base-toast.d.ts +20 -0
  69. package/dist/components/toast/toast-props.d.ts +18 -0
  70. package/dist/components/toast/toast-type.d.ts +45 -0
  71. package/dist/components/toast/toast.d.ts +5 -0
  72. package/dist/components/toast/toast.stories.d.ts +310 -0
  73. package/dist/components.css +1089 -56
  74. package/dist/cta-button.js +12 -11
  75. package/dist/data-table.js +6 -6
  76. package/dist/drawer.js +390 -0
  77. package/dist/drop-down.js +15 -29
  78. package/dist/helpers/hooks/useExternalState.d.ts +5 -0
  79. package/dist/icon-text-badge.js +11 -11
  80. package/dist/icon-text-option-badge.js +10 -10
  81. package/dist/index.d.ts +16 -0
  82. package/dist/index.js +2090 -475
  83. package/dist/loading.js +8 -8
  84. package/dist/modal-with-double-button.js +60 -255
  85. package/dist/modal.js +288 -0
  86. package/dist/option-badge.js +11 -11
  87. package/dist/pagination.js +412 -0
  88. package/dist/radio.js +10 -10
  89. package/dist/skeleton.js +331 -0
  90. package/dist/styles.css +921 -29
  91. package/dist/switch.js +349 -0
  92. package/dist/tabs.js +6 -6
  93. package/dist/text-area.js +374 -0
  94. package/dist/text-field.js +7 -7
  95. package/dist/text.js +8 -8
  96. package/dist/toast.js +496 -0
  97. package/dist/tokens.css +32 -5
  98. package/dist/tooltip.js +9 -9
  99. package/package.json +33 -1
@@ -43,6 +43,15 @@ import '@nurihaus/web-design-system/components.css';
43
43
  - [TextField](#textfield)
44
44
  - [Radio](#radio)
45
45
  - [Checkbox](#checkbox)
46
+ - [Switch](#switch)
47
+ - [TextArea](#textarea)
48
+ - [Toast](#toast)
49
+ - [ToastProvider](#toastprovider)
50
+ - [Pagination](#pagination)
51
+ - [Modal](#modal)
52
+ - [Drawer](#drawer)
53
+ - [Skeleton](#skeleton)
54
+ - [Breadcrumb](#breadcrumb)
46
55
  - [DropDown](#dropdown)
47
56
  - [CollapsibleMenu](#collapsiblemenu)
48
57
  - [Text](#text)
@@ -282,7 +291,7 @@ import { TextField } from '@nurihaus/web-design-system'; // 루트.
282
291
  | prop | 타입 | 필수 | 기본값 |
283
292
  | --- | --- | --- | --- |
284
293
  | `className` | `string` | | |
285
- | `size` | `'s' \| 'm'` | 예 | `'s'` |
294
+ | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | 예 | `'s'` |
286
295
  | `title` | `ReactNode` | | |
287
296
  | `name` | `string` | 예 | |
288
297
  | `value` | `string` | | |
@@ -358,6 +367,299 @@ import { Checkbox } from '@nurihaus/web-design-system'; // 루트.
358
367
 
359
368
  이 밖에 React·HTML 기본 속성 2개를 받는다.
360
369
 
370
+ ## Switch
371
+
372
+ ```ts
373
+ import { Switch } from '@nurihaus/web-design-system/switch'; // 이 컴포넌트만 싣는다 (권장)
374
+ import { Switch } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
375
+ ```
376
+
377
+ **언제 쓴다.** 알림 켜기처럼 켜고 끄는 설정 하나를 바로 반영할 때 쓴다. `onChange`는 바뀐 켜짐 상태(boolean)를 받는다. `className`·`style`은 루트 버튼에 붙는다. `label`을 주지 않으면 `aria-label`로 이름을 준다.
378
+
379
+ **쓰지 않는다.** 제출 버튼을 눌러야 반영되는 폼 항목이나 동의 여부는 Checkbox를, 여러 선택지 중 하나는 Radio를 쓴다.
380
+
381
+ ```tsx
382
+ <Switch id="push-alarm" label="푸시 알림 받기" checked={true} onChange={() => {}} />
383
+ ```
384
+
385
+ ### props
386
+
387
+ | prop | 타입 | 필수 | 기본값 |
388
+ | --- | --- | --- | --- |
389
+ | `className` | `string` | | |
390
+ | `size` | `'s' \| 'm' \| 'l'` | | `'m'` |
391
+ | `label` | `ReactNode` | | |
392
+ | `disabled` | `boolean` | | |
393
+ | `defaultChecked` | `boolean` | | |
394
+ | `id` | `string` | 예 | |
395
+ | `onChange` | `((checked: boolean) => void)` | | |
396
+ | `checked` | `boolean` | | |
397
+
398
+ 이 밖에 React·HTML 기본 속성 270개를 받는다.
399
+
400
+ ## TextArea
401
+
402
+ ```ts
403
+ import { TextArea } from '@nurihaus/web-design-system/text-area'; // 이 컴포넌트만 싣는다 (권장)
404
+ import { TextArea } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
405
+ ```
406
+
407
+ **언제 쓴다.** 메모·설명처럼 여러 줄 텍스트를 입력받을 때 쓴다. 위 라벨(`title`), 아래 안내 문구(`helperText`)를 함께 붙일 수 있고, `isError`가 true면 `helperText`가 오류 스타일로 바뀐다. 높이는 `rows`가 정하고 `size`는 글자 크기와 안쪽 여백만 바꾼다. `resize`는 `'vertical'`(기본)·`'none'` 중 고른다. `className`·`style`은 textarea를 감싸는 테두리 요소에 붙고, `ref`는 textarea 요소를 가리킨다.
408
+
409
+ **쓰지 않는다.** 한 줄 입력은 TextField를 쓴다. 정해진 값 중에서 고르는 입력은 DropDown이나 Radio를 쓴다.
410
+
411
+ ```tsx
412
+ <TextArea name="memo" title="메모" placeholder="내용을 입력하세요" rows={4} />
413
+ ```
414
+
415
+ ### props
416
+
417
+ | prop | 타입 | 필수 | 기본값 |
418
+ | --- | --- | --- | --- |
419
+ | `className` | `string` | | |
420
+ | `size` | `'s' \| 'm'` | | `'s'` |
421
+ | `title` | `ReactNode` | | |
422
+ | `name` | `string` | 예 | |
423
+ | `value` | `string` | | |
424
+ | `defaultValue` | `string` | | |
425
+ | `width` | `string \| number` | | `'100%'` |
426
+ | `resize` | `'none' \| 'vertical'` | | `'vertical'` |
427
+ | `helperText` | `ReactNode` | | |
428
+ | `isError` | `boolean` | | |
429
+
430
+ 이 밖에 React·HTML 기본 속성 275개를 받는다.
431
+
432
+ ## Toast
433
+
434
+ ```ts
435
+ import { Toast } from '@nurihaus/web-design-system/toast'; // 이 컴포넌트만 싣는다 (권장)
436
+ import { Toast } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
437
+ ```
438
+
439
+ **언제 쓴다.** 저장 완료·삭제 완료처럼 사용자의 행동 결과를 짧게 알리고 스스로 사라져야 할 때 쓴다. `title`은 필수, `description`은 한 줄 보충 설명이다. `variant`(`default · secondary · success · warning · error`)가 바탕색을 정한다. 기본은 Tooltip과 같은 진보라, `secondary`는 CTAButton secondary와 같은 연보라(어두운 글자), `success`는 초록, `warning`은 주황, `error`는 confirm 버튼과 같은 빨강이고 이 셋은 앞에 상태 아이콘(체크·느낌표·X)이 붙는다. secondary 외에는 글자가 흰색이다. `action`을 주면 되돌리기 같은 작은 버튼(CTAButton xs·neutral)이 하나 붙고 누르면 토스트가 닫힌다. `showClose={false}`로 닫기 버튼을 뺄 수 있다. `duration`(ms)은 이 토스트만의 표시 시간이다. `className`·`style`은 토스트 루트(`li`)에 붙는다. 반드시 ToastProvider 안에서 쓴다.
440
+
441
+ **쓰지 않는다.** 사용자의 확인이나 선택이 필요한 내용은 ModalWithDoubleButton을 쓴다. 입력 오류처럼 그 자리에서 고쳐야 하는 안내는 TextField의 helper text를 쓴다.
442
+
443
+ ```tsx
444
+ <Toast open title="저장했습니다" description="변경 사항이 반영됐습니다." variant="success" onOpenChange={() => {}} />
445
+ ```
446
+
447
+ ### props
448
+
449
+ | prop | 타입 | 필수 | 기본값 |
450
+ | --- | --- | --- | --- |
451
+ | `className` | `string` | | |
452
+ | `style` | `CSSProperties` | | |
453
+ | `title` | `ReactNode` | 예 | |
454
+ | `onPause` | `(() => void)` | | |
455
+ | `variant` | `'secondary' \| 'default' \| 'success' \| 'warning' \| 'error'` | | `'default'` |
456
+ | `onResume` | `(() => void)` | | |
457
+ | `open` | `boolean` | | |
458
+ | `defaultOpen` | `boolean` | | |
459
+ | `onOpenChange` | `((open: boolean) => void)` | | |
460
+ | `duration` | `number` | | |
461
+ | `description` | `ReactNode` | | |
462
+ | `action` | `ToastAction` | | |
463
+ | `showClose` | `boolean` | | `true` |
464
+
465
+ 이 밖에 React·HTML 기본 속성 262개를 받는다.
466
+
467
+ ## ToastProvider
468
+
469
+ ```ts
470
+ import { ToastProvider } from '@nurihaus/web-design-system/toast'; // 이 컴포넌트만 싣는다 (권장)
471
+ import { ToastProvider } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
472
+ ```
473
+
474
+ **언제 쓴다.** 앱 루트에 한 번 둔다. 토스트가 쌓이는 자리(Viewport)를 그리고 `position`(`top-right · bottom-right · bottom-center`, 기본 `bottom-right`)으로 화면 어느 모서리에 둘지 고른다. `duration`(ms)은 안의 모든 Toast 에 적용되는 기본 표시 시간이다(기본 5000). Toast 가 `duration`을 주면 그 값이 앞선다. `label`은 스크린 리더가 읽는 이름이고 기본은 `알림`이다. 다른 언어 서비스에서만 바꾼다.
475
+
476
+ **쓰지 않는다.** 화면마다 여러 개 두지 않는다. Provider 가 둘이면 토스트 자리가 둘로 갈린다.
477
+
478
+ ```tsx
479
+ <ToastProvider position="bottom-right" duration={5000}>
480
+ <Toast open title="저장했습니다" onOpenChange={() => {}} />
481
+ </ToastProvider>
482
+ ```
483
+
484
+ ### props
485
+
486
+ | prop | 타입 | 필수 | 기본값 |
487
+ | --- | --- | --- | --- |
488
+ | `children` | `ReactNode` | 예 | |
489
+ | `duration` | `number` | | |
490
+ | `position` | `'top-right' \| 'bottom-right' \| 'bottom-center'` | | `'bottom-right'` |
491
+ | `label` | `string` | | `'알림'` |
492
+
493
+ ## Pagination
494
+
495
+ ```ts
496
+ import { Pagination } from '@nurihaus/web-design-system/pagination'; // 이 컴포넌트만 싣는다 (권장)
497
+ import { Pagination } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
498
+ ```
499
+
500
+ **언제 쓴다.** 목록이나 검색 결과가 여러 페이지로 나뉘어 있고 사용자가 번호로 페이지를 고를 때 쓴다. `totalPages`는 필수다. 현재 페이지는 `page`(controlled)·`defaultPage`(uncontrolled)로 주고, `onPageChange`는 새 페이지 번호(1부터)를 받는다. 1과 마지막 페이지는 항상 보이고, 현재 페이지 양옆 `siblingCount`(기본 1)개를 보이며 사이가 벌어지면 `…`를 넣는다. `className`·`style`은 루트 `nav`에 붙는다. `aria-label`을 주면 nav 이름을 바꾼다(기본 "페이지 탐색").
501
+
502
+ **쓰지 않는다.** 스크롤로 계속 불러오는 목록이나 "더 보기" 버튼으로 이어 붙이는 목록에는 쓰지 않는다. 화면 안의 내용 영역을 바꾸는 탭 전환은 Tabs를 쓴다.
503
+
504
+ ```tsx
505
+ <Pagination totalPages={10} page={3} onPageChange={() => {}} />
506
+ ```
507
+
508
+ ### props
509
+
510
+ | prop | 타입 | 필수 | 기본값 |
511
+ | --- | --- | --- | --- |
512
+ | `size` | `'s' \| 'm'` | | `'m'` |
513
+ | `disabled` | `boolean` | | |
514
+ | `page` | `number` | | |
515
+ | `totalPages` | `number` | 예 | |
516
+ | `defaultPage` | `number` | | |
517
+ | `onPageChange` | `((page: number) => void)` | | |
518
+ | `siblingCount` | `number` | | `1` |
519
+
520
+ 이 밖에 React·HTML 기본 속성 266개를 받는다.
521
+
522
+ ## Modal
523
+
524
+ ```ts
525
+ import { Modal } from '@nurihaus/web-design-system/modal'; // 이 컴포넌트만 싣는다 (권장)
526
+ import { Modal } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
527
+ ```
528
+
529
+ **언제 쓴다.** 제목과 본문, 버튼 영역이 자유로운 일반 대화상자에 쓴다. `open · defaultOpen · onOpenChange`로 열고 닫고, `trigger`를 주면 그 요소를 클릭해 열린다. `title`은 필수이고 dialog의 접근성 이름이 된다. `footer`에는 CTAButton 을 넣는다. `className`·`style`은 dialog 요소(Content)에 붙는다. X 아이콘(`showCloseIcon`, 기본 true)·Escape·오버레이 클릭으로 닫힌다.
530
+
531
+ **쓰지 않는다.** 확인·취소 두 버튼으로 끝나는 확인 대화상자는 ModalWithDoubleButton 을 쓴다.
532
+
533
+ ```tsx
534
+ <Modal
535
+ open
536
+ title="필터 설정"
537
+ description="조건을 고르세요."
538
+ footer={<CTAButton text="적용" onClick={() => {}} />}
539
+ onOpenChange={() => {}}
540
+ >
541
+ 본문
542
+ </Modal>
543
+ ```
544
+
545
+ ### props
546
+
547
+ | prop | 타입 | 필수 | 기본값 |
548
+ | --- | --- | --- | --- |
549
+ | `trigger` | `ReactElement<any, string \| JSXElementConstructor<any>>` | | |
550
+ | `title` | `ReactNode` | 예 | |
551
+ | `description` | `ReactNode` | | |
552
+ | `children` | `ReactNode` | | |
553
+ | `footer` | `ReactNode` | | |
554
+ | `showCloseIcon` | `boolean` | | `true` |
555
+ | `size` | `'s' \| 'm' \| 'l'` | | `'m'` |
556
+ | `open` | `boolean` | | |
557
+ | `defaultOpen` | `boolean` | | |
558
+ | `onOpenChange` | `((open: boolean) => void)` | | |
559
+ | `className` | `string` | | |
560
+ | `style` | `CSSProperties` | | |
561
+
562
+ 이 밖에 React·HTML 기본 속성 2개를 받는다.
563
+
564
+ ## Drawer
565
+
566
+ ```ts
567
+ import { Drawer } from '@nurihaus/web-design-system/drawer'; // 이 컴포넌트만 싣는다 (권장)
568
+ import { Drawer } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
569
+ ```
570
+
571
+ **언제 쓴다.** 상세 정보나 필터처럼 현재 화면을 떠나지 않고 옆이나 아래에서 패널을 꺼내 보여줄 때 쓴다. `trigger`에 넘긴 요소를 클릭하면 열리고, `open`·`defaultOpen`·`onOpenChange`로 제어한다. `title`은 필수이며 dialog 의 접근성 이름이 된다. `side`(`right`·`left`·`bottom`, 기본 `right`)와 `size`(`s`·`m`·`l`, 기본 `m`)로 방향과 폭(bottom 은 높이)을 고른다. Escape·바깥 클릭·X 버튼으로 닫히고, `className`·`style`은 패널에 붙는다.
572
+
573
+ **쓰지 않는다.** 삭제 확인처럼 결정 하나만 받는 짧은 대화상자는 ModalWithDoubleButton 을 쓴다. 페이지 자체 내비게이션이나 항상 보이는 사이드바에는 쓰지 않는다.
574
+
575
+ ```tsx
576
+ <Drawer open title="상세 정보" side="right" onOpenChange={() => {}}>
577
+ 본문
578
+ </Drawer>
579
+ ```
580
+
581
+ ### props
582
+
583
+ | prop | 타입 | 필수 | 기본값 |
584
+ | --- | --- | --- | --- |
585
+ | `trigger` | `ReactElement<any, string \| JSXElementConstructor<any>>` | | |
586
+ | `title` | `ReactNode` | 예 | |
587
+ | `description` | `ReactNode` | | |
588
+ | `children` | `ReactNode` | | |
589
+ | `footer` | `ReactNode` | | |
590
+ | `side` | `'bottom' \| 'left' \| 'right'` | | `'right'` |
591
+ | `size` | `'s' \| 'm' \| 'l'` | | `'m'` |
592
+ | `showCloseIcon` | `boolean` | | `true` |
593
+ | `open` | `boolean` | | |
594
+ | `defaultOpen` | `boolean` | | |
595
+ | `onOpenChange` | `((open: boolean) => void)` | | |
596
+ | `className` | `string` | | |
597
+ | `style` | `CSSProperties` | | |
598
+
599
+ 이 밖에 React·HTML 기본 속성 2개를 받는다.
600
+
601
+ ## Skeleton
602
+
603
+ ```ts
604
+ import { Skeleton } from '@nurihaus/web-design-system/skeleton'; // 이 컴포넌트만 싣는다 (권장)
605
+ import { Skeleton } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
606
+ ```
607
+
608
+ **언제 쓴다.** 데이터를 기다리는 동안 들어올 내용의 자리를 같은 모양으로 비워 둘 때 쓴다. 한 줄 글은 `shape="text"`, 여러 줄은 `lines`, 이미지·카드는 `rect`에 `width`·`height`, 아바타는 `circle`에 `width`를 준다. `className`·`style`은 루트 `span`에 붙고 `width`·`height`는 루트 style 에 들어간다. 보조기기에는 숨기므로(`aria-hidden`) 불러오는 중이라는 알림은 감싸는 영역이 `aria-busy`로 알린다.
609
+
610
+ **쓰지 않는다.** 짧은 처리 중 표시는 InlineLoading, 버튼 로딩은 CTAButton의 `loading`, 화면 전체를 막아야 하면 OverlayLoading을 쓴다. 들어올 내용의 모양을 모를 때는 쓰지 않는다.
611
+
612
+ ```tsx
613
+ <Skeleton shape="text" lines={3} />
614
+ ```
615
+
616
+ ### props
617
+
618
+ | prop | 타입 | 필수 | 기본값 |
619
+ | --- | --- | --- | --- |
620
+ | `width` | `string \| number` | | `'100%'` |
621
+ | `height` | `string \| number` | | |
622
+ | `shape` | `'circle' \| 'rect' \| 'text'` | | `'text'` |
623
+ | `lines` | `number` | | `1` |
624
+ | `animated` | `boolean` | | `true` |
625
+
626
+ 이 밖에 React·HTML 기본 속성 266개를 받는다.
627
+
628
+ ## Breadcrumb
629
+
630
+ ```ts
631
+ import { Breadcrumb } from '@nurihaus/web-design-system/breadcrumb'; // 이 컴포넌트만 싣는다 (권장)
632
+ import { Breadcrumb } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
633
+ ```
634
+
635
+ **언제 쓴다.** 계층이 있는 화면에서 현재 위치와 상위 경로를 한 줄로 보여 줄 때 쓴다. `items`의 마지막 항목이 현재 위치라 링크가 아니고 `aria-current="page"`가 붙는다. `href`가 있는 항목은 `<a>` 링크로, `onItemClick`은 클릭한 항목의 `id`를 받는다. Next.js 나 React Router 안에서는 `linkComponent={Link}`를 넘겨 라우터 링크로 그린다. 넘기지 않으면 일반 `<a>`라 페이지가 새로 고쳐진다. `className`·`style`은 `nav` 루트에 붙는다.
636
+
637
+ **쓰지 않는다.** 같은 깊이의 화면을 오가는 데는 Tabs를, 사이드바 메뉴에는 CollapsibleMenu를 쓴다. 계층이 한 단계뿐이면 쓰지 않는다.
638
+
639
+ ```tsx
640
+ <Breadcrumb
641
+ items={[
642
+ { id: 'home', label: '홈', href: '/' },
643
+ { id: 'list', label: '목록', href: '/list' },
644
+ { id: 'detail', label: '상세' },
645
+ ]}
646
+ />
647
+ ```
648
+
649
+ ### props
650
+
651
+ | prop | 타입 | 필수 | 기본값 |
652
+ | --- | --- | --- | --- |
653
+ | `items` | `BreadcrumbItem[]` | 예 | |
654
+ | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'m'` |
655
+ | `onItemClick` | `((id: string) => void)` | | |
656
+ | `separator` | `ReactNode` | | |
657
+ | `linkComponent` | `ElementType` | | |
658
+ | `className` | `string` | | |
659
+ | `style` | `CSSProperties` | | |
660
+
661
+ 이 밖에 React·HTML 기본 속성 2개를 받는다.
662
+
361
663
  ## DropDown
362
664
 
363
665
  ```ts
@@ -388,7 +690,7 @@ import { DropDown } from '@nurihaus/web-design-system'; // 루트.
388
690
 
389
691
  | prop | 타입 | 필수 | 기본값 |
390
692
  | --- | --- | --- | --- |
391
- | `size` | `'s' \| 'm'` | | `'s'` |
693
+ | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'s'` |
392
694
  | `defaultValue` | `string` | | |
393
695
  | `value` | `string` | | |
394
696
  | `onValueChange` | `((value: string) => void)` | | |
@@ -601,7 +903,7 @@ import { ModalWithDoubleButton } from '@nurihaus/web-design-system';
601
903
 
602
904
  **언제 쓴다.** 삭제 확인처럼 제목, 설명, 버튼 두 개로 된 확인 대화상자에 쓴다. `ModalWithDoubleButton.Row`는 버튼을 가로로, `ModalWithDoubleButton.Column`은 세로로 배치하며, `left`와 `right`는 CTAButton props를 그대로 받는다.
603
905
 
604
- **쓰지 않는다.** `open` prop이 없고 렌더되는 동안 항상 보이므로, 표시 여부는 부모가 조건부 렌더링으로 정하고 버튼 `onClick`에서 언마운트한다. `showCloseIcon`의 X 아이콘은 클릭해도 동작이 없으므로 닫기 수단으로 쓰지 않는다. 버튼이 하나이거나 세 개 이상인 모달은 이 라이브러리에 없다.
906
+ **쓰지 않는다.** `open` prop이 없고 렌더되는 동안 항상 보이므로, 표시 여부는 부모가 조건부 렌더링으로 정하고 버튼 `onClick`에서 언마운트한다. `showCloseIcon`의 X 아이콘은 클릭해도 동작이 없으므로 닫기 수단으로 쓰지 않는다. 일반 모달은 Modal 을 쓴다.
605
907
 
606
908
  ```tsx
607
909
  <ModalWithDoubleButton.Row
@@ -728,15 +1030,7 @@ import { OverlayLoading } from '@nurihaus/web-design-system'; // 루
728
1030
 
729
1031
  | 필요한 것 | 지금 있는 것 |
730
1032
  | --- | --- |
731
- | 페이지네이션 | 없음 |
732
- | 토스트·스낵바 | 없음 |
733
- | 스위치(토글) | 없음. 켜고 끄는 값은 Checkbox |
734
- | 여러 줄 입력(textarea) | 없음. TextField 는 한 줄 `<input>` 이다 |
735
1033
  | 날짜 선택 | 없음 |
736
- | 드로어·사이드 패널 | 없음 |
737
- | 스켈레톤 | 없음. 불러오는 중에는 InlineLoading |
738
- | 브레드크럼 | 없음 |
739
1034
  | 아이콘 세트 | 없음. 패키지 안 아이콘은 컴포넌트 내부용이라 내보내지 않는다 |
740
- | 확인용이 아닌 일반 모달 | 없음. 버튼 두 개짜리 확인 모달 ModalWithDoubleButton 만 있다 |
741
1035
 
742
1036
  없는 것이 필요하면 쓰는 쪽 저장소에서 `tokens.md` 의 변수로 만든다. 그리고 디자인 시스템에 추가할 후보라고 알린다.
package/dist/ai/tokens.md CHANGED
@@ -266,11 +266,11 @@
266
266
 
267
267
  | 변수 | 값 | 용도 |
268
268
  | --- | --- | --- |
269
- | `--control-height-xs` | `30px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
270
- | `--control-height-s` | `40px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
271
- | `--control-height-m` | `50px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
272
- | `--control-height-l` | `54px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
273
- | `--control-height-xl` | `60px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
269
+ | `--control-height-xs` | `28px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
270
+ | `--control-height-s` | `36px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
271
+ | `--control-height-m` | `40px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
272
+ | `--control-height-l` | `44px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
273
+ | `--control-height-xl` | `48px` | 한 줄에 나란히 놓이는 컨트롤: button, drop-down, text-field |
274
274
  | `--label-height-xs` | `28px` | 라벨: badge |
275
275
  | `--label-height-s` | `32px` | 라벨: badge |
276
276
  | `--label-height-m` | `36px` | 라벨: badge |
@@ -284,14 +284,28 @@
284
284
  | `--checkbox-size-l` | `24px` | 정사각 |
285
285
  | `--radio-size` | `18px` | 정사각 |
286
286
  | `--radio-dot-size` | `8px` | 정사각 |
287
- | `--avatar-size-s` | `40px` | 정사각 |
288
- | `--avatar-size-m` | `58px` | 정사각 |
289
- | `--avatar-size-l` | `74px` | 정사각 |
290
- | `--avatar-size-xl` | `124px` | 정사각 |
291
- | `--avatar-badge-size-s` | `18px` | 정사각 |
292
- | `--avatar-badge-size-m` | `24px` | 정사각 |
293
- | `--avatar-badge-size-l` | `30px` | 정사각 |
294
- | `--avatar-badge-size-xl` | `48px` | 정사각 |
287
+ | `--switch-width-s` | `32px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
288
+ | `--switch-width-m` | `40px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
289
+ | `--switch-width-l` | `48px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
290
+ | `--switch-height-s` | `18px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
291
+ | `--switch-height-m` | `22px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
292
+ | `--switch-height-l` | `26px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
293
+ | `--switch-thumb-inset` | `2px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
294
+ | `--avatar-size-s` | `40px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
295
+ | `--avatar-size-m` | `58px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
296
+ | `--avatar-size-l` | `74px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
297
+ | `--avatar-size-xl` | `124px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
298
+ | `--avatar-badge-size-s` | `18px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
299
+ | `--avatar-badge-size-m` | `24px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
300
+ | `--avatar-badge-size-l` | `30px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
301
+ | `--avatar-badge-size-xl` | `48px` | 스위치: 트랙 폭·높이. 손잡이는 트랙 높이에서 inset 을 뺀 정사각이다 |
302
+ | `--drawer-width-s` | `320px` | 폭 |
303
+ | `--drawer-width-m` | `400px` | 폭 |
304
+ | `--drawer-width-l` | `520px` | 폭 |
305
+ | `--drawer-height-s` | `320px` | 폭 |
306
+ | `--drawer-height-m` | `400px` | 폭 |
307
+ | `--drawer-height-l` | `520px` | 폭 |
308
+ | `--toast-width` | `360px` | 폭 |
295
309
  | `--modal-width-s` | `400px` | 폭 |
296
310
  | `--modal-width-m` | `450px` | 폭 |
297
311
  | `--modal-width-l` | `500px` | 폭 |
@@ -300,8 +314,17 @@
300
314
  | `--icon-size-l` | `24px` | 그 밖의 치수 |
301
315
  | `--tooltip-arrow` | `8px` | 그 밖의 치수 |
302
316
  | `--spinner-stroke` | `3px` | 그 밖의 치수 |
317
+ | `--overlay-spinner-size` | `64px` | 그 밖의 치수 |
318
+ | `--overlay-spinner-stroke` | `8px` | 그 밖의 치수 |
303
319
  | `--tab-indicator-thickness` | `3px` | 그 밖의 치수 |
304
320
  | `--checkbox-border` | `1.5px` | 그 밖의 치수 |
321
+ | `--breadcrumb-chevron-xs` | `12px` | 그 밖의 치수 |
322
+ | `--breadcrumb-chevron-s` | `14px` | 그 밖의 치수 |
323
+ | `--breadcrumb-chevron-m` | `16px` | 그 밖의 치수 |
324
+ | `--breadcrumb-chevron-l` | `18px` | 그 밖의 치수 |
325
+ | `--breadcrumb-chevron-xl` | `20px` | 그 밖의 치수 |
326
+ | `--skeleton-text-height` | `16px` | 그 밖의 치수 |
327
+ | `--skeleton-last-line-width` | `60%` | 그 밖의 치수 |
305
328
  | `--hairline` | `1px` | 그 밖의 치수 |
306
329
  | `--shadow-popover` | `0px 4px 6px -2px rgba(0, 0, 0, 0.06), 0px 10px 15px -3px rgba(0, 0, 0, 0.1)` | 그림자 |
307
330
  | `--z-base` | `0` | 레이어. 값이 같아도 역할이 다르면 이름을 따로 둔다 |
@@ -312,8 +335,10 @@
312
335
  | `--z-popover` | `5` | 레이어. 값이 같아도 역할이 다르면 이름을 따로 둔다 |
313
336
  | `--z-overlay` | `9998` | 레이어. 값이 같아도 역할이 다르면 이름을 따로 둔다 |
314
337
  | `--z-modal` | `9999` | 레이어. 값이 같아도 역할이 다르면 이름을 따로 둔다 |
338
+ | `--z-toast` | `10000` | 레이어. 값이 같아도 역할이 다르면 이름을 따로 둔다 |
315
339
  | `--motion-fast` | `160ms` | 모션 |
316
340
  | `--motion-base` | `300ms` | 모션 |
317
341
  | `--motion-ease` | `ease` | 모션 |
318
342
  | `--spinner-duration` | `1.2s` | 모션 |
343
+ | `--skeleton-duration` | `1.5s` | 모션 |
319
344
  | `--spinner-ease` | `cubic-bezier(0.5, 0, 0.5, 1)` | 모션 |
package/dist/avatar.js CHANGED
@@ -4,7 +4,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8__ from "react/jsx-runtime";
5
5
  /******/ var __webpack_modules__ = ({
6
6
 
7
- /***/ 468
7
+ /***/ 5468
8
8
  (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
9
9
 
10
10
 
@@ -16,15 +16,15 @@ __nuri_require__.d(__webpack_exports__, {
16
16
  // EXTERNAL MODULE: external {"root":"jsx-runtime","commonjs2":"react/jsx-runtime","commonjs":"react/jsx-runtime","amd":"react/jsx-runtime","module":"react/jsx-runtime"}
17
17
  var jsx_runtime_ = __nuri_require__(612);
18
18
  // EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react","module":"react"}
19
- var external_root_React_commonjs2_react_commonjs_react_amd_react_module_react_ = __nuri_require__(41);
19
+ var external_root_React_commonjs2_react_commonjs_react_amd_react_module_react_ = __nuri_require__(1041);
20
20
  // EXTERNAL MODULE: ./helpers/utils/classNames.js
21
- var classNames = __nuri_require__(274);
21
+ var classNames = __nuri_require__(3274);
22
22
  // EXTERNAL MODULE: ./helpers/utils/getMergedProps.ts
23
- var getMergedProps = __nuri_require__(335);
23
+ var getMergedProps = __nuri_require__(7335);
24
24
  // EXTERNAL MODULE: ./components/core/composer/index.tsx
25
- var composer = __nuri_require__(777);
25
+ var composer = __nuri_require__(2777);
26
26
  // EXTERNAL MODULE: ./helpers/props/common-props.ts
27
- var common_props = __nuri_require__(298);
27
+ var common_props = __nuri_require__(7298);
28
28
  ;// ./components/avatar/avatar-props.ts
29
29
 
30
30
  var sizes = ['s', 'm', 'l', 'xl'];
@@ -167,7 +167,7 @@ module.exports = x({ ["Avatar"]: () => (__WEBPACK_EXTERNAL_MODULE_radix_ui_3bc96
167
167
 
168
168
  /***/ },
169
169
 
170
- /***/ 41
170
+ /***/ 1041
171
171
  (module, __unused_webpack_exports, __nuri_require__) {
172
172
 
173
173
  var x = (y) => {
@@ -329,7 +329,7 @@ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime
329
329
  /******/ // startup
330
330
  /******/ // Load entry module and return exports
331
331
  /******/ // This entry module depends on other loaded chunks and execution need to be delayed
332
- /******/ var __webpack_exports__ = __nuri_require__.O(undefined, [364,777,298], () => (__nuri_require__(468)))
332
+ /******/ var __webpack_exports__ = __nuri_require__.O(undefined, [364,777,298], () => (__nuri_require__(5468)))
333
333
  /******/ __webpack_exports__ = __nuri_require__.O(__webpack_exports__);
334
334
  /******/ const __webpack_exports__default = __webpack_exports__.A;
335
335
  /******/ export { __webpack_exports__default as default };