@bestow-ui/react 0.12.0 → 1.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.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _bestow_ui_tokens from '@bestow-ui/tokens';
2
2
  import { space } from '@bestow-ui/tokens';
3
3
  import * as react from 'react';
4
- import { HTMLAttributes, CSSProperties, ReactNode, ComponentPropsWithoutRef, InputHTMLAttributes, ElementType, ButtonHTMLAttributes, AnchorHTMLAttributes, ReactElement, TdHTMLAttributes, ThHTMLAttributes, TextareaHTMLAttributes } from 'react';
4
+ import { ReactNode, HTMLAttributes, CSSProperties, ComponentPropsWithoutRef, InputHTMLAttributes, ElementType, ButtonHTMLAttributes, AnchorHTMLAttributes, ReactElement, TdHTMLAttributes, ThHTMLAttributes, TextareaHTMLAttributes } from 'react';
5
5
  import * as RadixAccordion from '@radix-ui/react-accordion';
6
6
  import * as Dialog from '@radix-ui/react-dialog';
7
7
  import * as RadixMenu from '@radix-ui/react-dropdown-menu';
@@ -250,7 +250,8 @@ declare function contrastRatio(a: string, b: string): number;
250
250
  type IntentName = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';
251
251
  /**
252
252
  * 대표색 하나로 intent(primary 등)의 라이트·다크 색 세트를 만든다. 결과는 createTheme 에 넘긴다.
253
- * - solid 는 넘긴 색을 그대로 쓴다 (다크모드에서 너무 어두우면 조금 밝힌다).
253
+ * - solid 는 넘긴 색을 그대로 쓴다 (다크모드에서 너무 어두우면 조금 밝힌다). 단 흰 글자·짙은 글자 모두
254
+ * 대비 4.5:1 이 안 나오는 중간 밝기 색이면 4.5 가 나올 만큼만 밝기를 옮긴다.
254
255
  * - text 와 contrast(solid 위 글자색)는 WCAG AA 대비 4.5:1 을 만족하도록 계산한다.
255
256
  * - intent 가 'primary' 면 포커스 링 색(border.focus)도 함께 바꾼다.
256
257
  *
@@ -258,33 +259,6 @@ type IntentName = 'primary' | 'neutral' | 'danger' | 'success' | 'warning';
258
259
  */
259
260
  declare function createIntentColors(intent: IntentName, color: string): ThemeInput;
260
261
 
261
- interface ThemeProviderProps extends HTMLAttributes<HTMLDivElement> {
262
- /** 라이트/다크 모드. 생략하면 바깥 ThemeProvider 의 모드를 이어받는다 (최상위는 light). */
263
- theme?: ThemeName;
264
- /**
265
- * createTheme 으로 만든 브랜드 테마. 모드를 바꿔도 유지되고, 중첩된 ThemeProvider 는 바깥 값을 이어받는다
266
- * (안쪽에서 준 값이 우선).
267
- */
268
- overrides?: BestowTheme;
269
- }
270
- declare const ThemeProvider: react.ForwardRefExoticComponent<ThemeProviderProps & react.RefAttributes<HTMLDivElement>>;
271
- /** 현재 적용 중인 모드(light/dark)를 반환한다. */
272
- declare function useTheme(): ThemeName;
273
- /**
274
- * Portal 로 ThemeProvider 바깥(body)에 렌더링되는 요소에 펼쳐 넣을 props.
275
- * 현재 모드의 CSS 변수, 브랜드 오버라이드, 기본 글꼴을 다시 적용한다.
276
- *
277
- * @example const portal = usePortalProps(); <Content className={cx(portal.className, styles.content)} style={portal.style} />
278
- */
279
- declare function usePortalProps(): {
280
- className: string;
281
- style?: CSSProperties;
282
- };
283
- /**
284
- * @deprecated usePortalProps() 를 쓰세요. className 만으로는 overrides(브랜드 테마)가 portal 에 적용되지 않습니다.
285
- */
286
- declare function usePortalClassName(): string;
287
-
288
262
  /**
289
263
  * 컴포넌트의 기본 문구. 모두 생략할 수 있고, 생략하면 각 컴포넌트의 한국어 기본값을 쓴다.
290
264
  * 우선순위: 컴포넌트에 직접 준 prop > LocaleProvider 의 messages > 한국어 기본값.
@@ -311,6 +285,13 @@ interface BestowMessages {
311
285
  /** Combobox — "결과가 없어요", "목록 열기" */
312
286
  noResults: string;
313
287
  openList: string;
288
+ /**
289
+ * Combobox clearable — "선택 지우기".
290
+ * 1.0 이후에 추가한 키는 선택(?)으로 둔다 — 직접 만든 BestowMessages 객체(다른 언어 묶음)가 타입 오류로 깨지지 않게.
291
+ */
292
+ clearSelection?: string;
293
+ /** SkipLink — "본문 바로가기" (1.0 이후 추가, 선택 키) */
294
+ skipToContent?: string;
314
295
  /** Slider 범위 손잡이 — "최소", "최대" */
315
296
  rangeStart: string;
316
297
  rangeEnd: string;
@@ -388,22 +369,39 @@ declare function useMessages(): Messages;
388
369
  declare const en: BestowMessages;
389
370
 
390
371
  /**
391
- * `type="single"`: 한 번에 하나만 열린다 (`value: string`). `collapsible` 이면 열린 항목을 다시 눌러 닫을 수 있다.
392
- * `type="multiple"`: 여러 개를 함께 열 수 있다 (`value: string[]`).
372
+ * 숫자만 있는 전화번호에 하이픈을 넣는다. 입력 중인 값도 자연스럽게 나눈다.
373
+ * @example formatPhoneNumber('01012345678') // '010-1234-5678'
374
+ * @example formatPhoneNumber('021234567') // '02-123-4567'
375
+ * @example formatPhoneNumber('15881234') // '1588-1234'
393
376
  */
394
- type AccordionProps = ComponentPropsWithoutRef<typeof RadixAccordion.Root>;
395
- declare const Accordion: react.ForwardRefExoticComponent<AccordionProps & react.RefAttributes<HTMLDivElement>>;
396
- interface AccordionItemProps extends Omit<ComponentPropsWithoutRef<typeof RadixAccordion.Item>, 'title'> {
397
- /** 항목 값. Accordion 의 value 와 비교한다 */
398
- value: string;
399
- /** 항목 제목 (펼침 버튼의 이름) */
400
- title: ReactNode;
401
- /** 제목을 감싸는 heading 수준. 페이지의 heading 구조에 맞춘다 (기본 3) */
402
- headingLevel?: 2 | 3 | 4 | 5 | 6;
403
- /** 펼쳤을 때 보이는 내용 */
404
- children?: ReactNode;
405
- }
406
- declare const AccordionItem: react.ForwardRefExoticComponent<AccordionItemProps & react.RefAttributes<HTMLDivElement>>;
377
+ declare function formatPhoneNumber(input: string): string;
378
+ /**
379
+ * 사업자등록번호(10자리)에 하이픈을 넣는다.
380
+ * @example formatBusinessNumber('1234567890') // '123-45-67890'
381
+ */
382
+ declare function formatBusinessNumber(input: string): string;
383
+ /**
384
+ * 사업자등록번호 검증 공식(가중치 1,3,7,1,3,7,1,3,5)으로 확인한다. 실제로 등록된 번호인지는 국세청 조회가 필요하다.
385
+ * @example isValidBusinessNumber('124-81-00998') // true
386
+ */
387
+ declare function isValidBusinessNumber(input: string): boolean;
388
+ /**
389
+ * 금액을 만·억·조 단위로 읽기 쉽게 쓴다.
390
+ * @example formatKoreanAmount(125000) // '12만 5,000원'
391
+ * @example formatKoreanAmount(150000000) // '1억 5,000만원'
392
+ * @example formatKoreanAmount(0) // '0원'
393
+ */
394
+ declare function formatKoreanAmount(amount: number, unit?: string): string;
395
+
396
+ /** Date → 'YYYY-MM-DD' (로컬 기준) */
397
+ declare function toISODate(date: Date): string;
398
+ /** 'YYYY-MM-DD' → Date (로컬 자정). 형식이 틀리거나 없는 날짜(2월 30일 등)면 null */
399
+ declare function parseISODate(value: string | null | undefined): Date | null;
400
+ /**
401
+ * 한국어 날짜. 스크린리더용 날짜 이름 등에 쓴다.
402
+ * @example formatKoreanDate(new Date(2026, 9, 15)) // '2026년 10월 15일 목요일'
403
+ */
404
+ declare function formatKoreanDate(date: Date, withWeekday?: boolean): string;
407
405
 
408
406
  /** 주소 검색 결과 */
409
407
  interface AddressSearchResult {
@@ -437,6 +435,59 @@ declare function composeExtraAddress(data: Pick<KakaoPostcodeData, 'userSelected
437
435
  */
438
436
  declare const kakaoPostcodeProvider: AddressProvider;
439
437
 
438
+ interface AgreementItem {
439
+ value: string;
440
+ /** 약관 이름 (예: "서비스 이용약관 동의") */
441
+ label: ReactNode;
442
+ /** 필수 동의 여부. 이름 앞에 "필수"/"선택" 이 붙는다 */
443
+ required?: boolean;
444
+ /** 펼쳐서 보여 줄 약관 내용. 있으면 "보기" 버튼이 생긴다 */
445
+ content?: ReactNode;
446
+ }
447
+ /** 필수 항목에 모두 동의했는지 */
448
+ declare function hasAllRequiredAgreements(items: AgreementItem[], value: string[]): boolean;
449
+
450
+ interface ThemeProviderProps extends HTMLAttributes<HTMLDivElement> {
451
+ /** 라이트/다크 모드. 생략하면 바깥 ThemeProvider 의 모드를 이어받는다 (최상위는 light). */
452
+ theme?: ThemeName;
453
+ /**
454
+ * createTheme 으로 만든 브랜드 테마. 모드를 바꿔도 유지되고, 중첩된 ThemeProvider 는 바깥 값을 이어받는다
455
+ * (안쪽에서 준 값이 우선).
456
+ */
457
+ overrides?: BestowTheme;
458
+ }
459
+ declare const ThemeProvider: react.ForwardRefExoticComponent<ThemeProviderProps & react.RefAttributes<HTMLDivElement>>;
460
+ /** 현재 적용 중인 모드(light/dark)를 반환한다. */
461
+ declare function useTheme(): ThemeName;
462
+ /**
463
+ * Portal 로 ThemeProvider 바깥(body)에 렌더링되는 요소에 펼쳐 넣을 props.
464
+ * 현재 모드의 CSS 변수, 브랜드 오버라이드, 기본 글꼴을 다시 적용한다.
465
+ *
466
+ * @example const portal = usePortalProps(); <Content className={cx(portal.className, styles.content)} style={portal.style} />
467
+ */
468
+ declare function usePortalProps(): {
469
+ className: string;
470
+ style?: CSSProperties;
471
+ };
472
+
473
+ /**
474
+ * `type="single"`: 한 번에 하나만 열린다 (`value: string`). `collapsible` 이면 열린 항목을 다시 눌러 닫을 수 있다.
475
+ * `type="multiple"`: 여러 개를 함께 열 수 있다 (`value: string[]`).
476
+ */
477
+ type AccordionProps = ComponentPropsWithoutRef<typeof RadixAccordion.Root>;
478
+ declare const Accordion: react.ForwardRefExoticComponent<AccordionProps & react.RefAttributes<HTMLDivElement>>;
479
+ interface AccordionItemProps extends Omit<ComponentPropsWithoutRef<typeof RadixAccordion.Item>, 'title'> {
480
+ /** 항목 값. Accordion 의 value 와 비교한다 */
481
+ value: string;
482
+ /** 항목 제목 (펼침 버튼의 이름) */
483
+ title: ReactNode;
484
+ /** 제목을 감싸는 heading 수준. 페이지의 heading 구조에 맞춘다 (기본 3) */
485
+ headingLevel?: 2 | 3 | 4 | 5 | 6;
486
+ /** 펼쳤을 때 보이는 내용 */
487
+ children?: ReactNode;
488
+ }
489
+ declare const AccordionItem: react.ForwardRefExoticComponent<AccordionItemProps & react.RefAttributes<HTMLDivElement>>;
490
+
440
491
  interface AddressValue {
441
492
  /** 우편번호 */
442
493
  zonecode: string;
@@ -478,15 +529,6 @@ interface AddressInputProps {
478
529
  */
479
530
  declare const AddressInput: react.ForwardRefExoticComponent<AddressInputProps & react.RefAttributes<HTMLFieldSetElement>>;
480
531
 
481
- interface AgreementItem {
482
- value: string;
483
- /** 약관 이름 (예: "서비스 이용약관 동의") */
484
- label: ReactNode;
485
- /** 필수 동의 여부. 이름 앞에 "필수"/"선택" 이 붙는다 */
486
- required?: boolean;
487
- /** 펼쳐서 보여 줄 약관 내용. 있으면 "보기" 버튼이 생긴다 */
488
- content?: ReactNode;
489
- }
490
532
  interface AgreementGroupProps {
491
533
  items: AgreementItem[];
492
534
  /** 동의한 항목의 value 목록 (제어 모드) */
@@ -513,8 +555,6 @@ interface AgreementGroupProps {
513
555
  name?: string;
514
556
  className?: string;
515
557
  }
516
- /** 필수 항목에 모두 동의했는지 */
517
- declare function hasAllRequiredAgreements(items: AgreementItem[], value: string[]): boolean;
518
558
  /**
519
559
  * 약관 동의 묶음. "전체 동의" 와 개별 항목이 서로 맞춰지고(일부만 동의하면 전체 동의는 부분 선택 상태),
520
560
  * 항목마다 필수·선택 표시와 약관 내용 펼쳐 보기를 지원한다.
@@ -568,6 +608,19 @@ interface TextFieldProps extends Omit<InputProps, 'invalid'> {
568
608
  helperText?: ReactNode;
569
609
  /** 에러 상태 */
570
610
  error?: boolean;
611
+ /** 필수 입력 (레이블에 * 표시, required 속성) */
612
+ required?: boolean;
613
+ disabled?: boolean;
614
+ /** 크기 */
615
+ size?: 'sm' | 'md' | 'lg';
616
+ /** 부모 너비를 꽉 채운다 */
617
+ fullWidth?: boolean;
618
+ /** 입력창 앞에 표시할 요소 (아이콘, 단위 등) */
619
+ startAdornment?: ReactNode;
620
+ /** 입력창 뒤에 표시할 요소 */
621
+ endAdornment?: ReactNode;
622
+ placeholder?: string;
623
+ type?: InputHTMLAttributes<HTMLInputElement>['type'];
571
624
  }
572
625
  declare const TextField: react.ForwardRefExoticComponent<TextFieldProps & react.RefAttributes<HTMLInputElement>>;
573
626
 
@@ -587,6 +640,22 @@ interface AmountInputProps extends Omit<TextFieldProps, 'value' | 'defaultValue'
587
640
  * helperText 를 주면 그 아래 줄로 함께 보여 준다.
588
641
  */
589
642
  showKoreanAmount?: boolean;
643
+ /** 입력창 위에 표시할 레이블 */
644
+ label?: ReactNode;
645
+ /** 입력창 아래에 표시할 도움말. error 일 때는 에러 메시지로 표시된다 */
646
+ helperText?: ReactNode;
647
+ /** 에러 상태 */
648
+ error?: boolean;
649
+ /** 필수 입력 (레이블에 * 표시, required 속성) */
650
+ required?: boolean;
651
+ disabled?: boolean;
652
+ /** 크기 */
653
+ size?: 'sm' | 'md' | 'lg';
654
+ /** 부모 너비를 꽉 채운다 */
655
+ fullWidth?: boolean;
656
+ placeholder?: string;
657
+ /** form 제출 시 사용할 이름 */
658
+ name?: string;
590
659
  }
591
660
  /**
592
661
  * 금액 입력. 천 단위 쉼표를 넣고 뒤에 단위("원")를 붙이며, 아래에 "12만 5,000원" 처럼 읽기 쉬운 금액을 보여 준다.
@@ -660,6 +729,22 @@ interface BusinessNumberInputProps extends Omit<TextFieldProps, 'value' | 'defau
660
729
  validate?: boolean;
661
730
  /** 자동 검증 오류 문구 */
662
731
  invalidText?: string;
732
+ /** 입력창 위에 표시할 레이블 */
733
+ label?: ReactNode;
734
+ /** 입력창 아래에 표시할 도움말. error 일 때는 에러 메시지로 표시된다 */
735
+ helperText?: ReactNode;
736
+ /** 에러 상태 */
737
+ error?: boolean;
738
+ /** 필수 입력 (레이블에 * 표시, required 속성) */
739
+ required?: boolean;
740
+ disabled?: boolean;
741
+ /** 크기 */
742
+ size?: 'sm' | 'md' | 'lg';
743
+ /** 부모 너비를 꽉 채운다 */
744
+ fullWidth?: boolean;
745
+ placeholder?: string;
746
+ /** form 제출 시 사용할 이름 */
747
+ name?: string;
663
748
  }
664
749
  /**
665
750
  * 사업자등록번호 입력. 123-45-67890 형식으로 하이픈을 넣고, 10자리를 채우면 검증 공식으로 확인한다.
@@ -703,7 +788,11 @@ interface CalendarProps {
703
788
  isDateDisabled?: (date: Date) => boolean;
704
789
  /** 공휴일. 일요일처럼 빨갛게 표시하고 스크린리더에 "공휴일" 을 덧붙인다 */
705
790
  isHoliday?: (date: Date) => boolean;
706
- /** 오늘 날짜 'YYYY-MM-DD'. 기본은 실제 오늘 — 테스트·스크린샷에서 고정할 때 쓴다 */
791
+ /**
792
+ * 오늘 날짜 'YYYY-MM-DD'. 기본은 브라우저의 오늘 — 테스트·스크린샷에서 고정할 때 쓴다.
793
+ * 서버 렌더링에서는 서버와 브라우저의 날짜(시간대)가 다를 수 있어, 없으면 hydration 이 끝난 뒤에 정한다
794
+ * (선택된 날짜도 없으면 그 전까지 날짜 칸을 비워 둔다).
795
+ */
707
796
  today?: string;
708
797
  /** 처음 그릴 때 날짜(선택된 날짜, 없으면 오늘)로 포커스를 옮긴다 — 팝업 안에서 쓸 때 */
709
798
  initialFocus?: boolean;
@@ -786,6 +875,13 @@ interface ComboboxProps {
786
875
  'aria-label'?: string;
787
876
  /** 목록 열기 버튼의 이름 */
788
877
  toggleLabel?: string;
878
+ /**
879
+ * 값이 있을 때 "선택 지우기" 버튼을 보여 준다. 버튼이 없어도 입력창 글자를 모두 지우고 닫으면(포커스 이동·Esc·Enter) 선택이 지워진다.
880
+ * 지우면 `onValueChange('')` 가 호출된다.
881
+ */
882
+ clearable?: boolean;
883
+ /** "선택 지우기" 버튼의 이름 */
884
+ clearLabel?: string;
789
885
  /** 입력창 래퍼 className */
790
886
  className?: string;
791
887
  }
@@ -908,11 +1004,8 @@ interface DropdownMenuItemProps extends Omit<ComponentPropsWithoutRef<typeof Rad
908
1004
  icon?: ReactNode;
909
1005
  /** 오른쪽에 표시할 단축키 (예: "⌘K"). 표시용이라 항목 이름에는 포함되지 않는다 */
910
1006
  shortcut?: string;
911
- /**
912
- * danger 는 삭제처럼 되돌리기 어려운 동작.
913
- * `default` 는 0.x 의 옛 이름으로 `neutral` 과 같다 — **deprecated, 1.0 에서 제거**.
914
- */
915
- color?: 'neutral' | 'danger' | 'default';
1007
+ /** danger 는 삭제처럼 되돌리기 어려운 동작 */
1008
+ color?: 'neutral' | 'danger';
916
1009
  }
917
1010
  declare const DropdownMenuItem: react.ForwardRefExoticComponent<DropdownMenuItemProps & react.RefAttributes<HTMLDivElement>>;
918
1011
  type DropdownMenuLabelProps = ComponentPropsWithoutRef<typeof RadixMenu.Label>;
@@ -1005,7 +1098,8 @@ declare function Modal({ open, defaultOpen, onOpenChange, trigger, title, descri
1005
1098
  */
1006
1099
  declare const ModalClose: react.ForwardRefExoticComponent<Dialog.DialogCloseProps & react.RefAttributes<HTMLButtonElement>>;
1007
1100
 
1008
- type ItemType = 'previous' | 'next' | 'page';
1101
+ /** getItemLabel 이 이름을 만드는 버튼 종류 */
1102
+ type PaginationItemType = 'previous' | 'next' | 'page';
1009
1103
  interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
1010
1104
  /** 전체 페이지 수. 1 미만이면 아무것도 렌더링하지 않는다 */
1011
1105
  totalPages: number;
@@ -1022,7 +1116,7 @@ interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'>
1022
1116
  /** 크기 */
1023
1117
  size?: 'sm' | 'md';
1024
1118
  /** 버튼의 스크린리더용 이름 (다국어 대응). 기본: "이전 페이지", "다음 페이지", "3 페이지" */
1025
- getItemLabel?: (type: ItemType, page: number) => string;
1119
+ getItemLabel?: (type: PaginationItemType, page: number) => string;
1026
1120
  }
1027
1121
  declare const Pagination: react.ForwardRefExoticComponent<PaginationProps & react.RefAttributes<HTMLElement>>;
1028
1122
 
@@ -1033,6 +1127,22 @@ interface PhoneNumberInputProps extends Omit<TextFieldProps, 'value' | 'defaultV
1033
1127
  defaultValue?: string;
1034
1128
  /** 숫자만 있는 값으로 호출된다 (하이픈 없음) */
1035
1129
  onValueChange?: (digits: string) => void;
1130
+ /** 입력창 위에 표시할 레이블 */
1131
+ label?: ReactNode;
1132
+ /** 입력창 아래에 표시할 도움말. error 일 때는 에러 메시지로 표시된다 */
1133
+ helperText?: ReactNode;
1134
+ /** 에러 상태 */
1135
+ error?: boolean;
1136
+ /** 필수 입력 (레이블에 * 표시, required 속성) */
1137
+ required?: boolean;
1138
+ disabled?: boolean;
1139
+ /** 크기 */
1140
+ size?: 'sm' | 'md' | 'lg';
1141
+ /** 부모 너비를 꽉 채운다 */
1142
+ fullWidth?: boolean;
1143
+ placeholder?: string;
1144
+ /** form 제출 시 사용할 이름 */
1145
+ name?: string;
1036
1146
  }
1037
1147
  /**
1038
1148
  * 전화번호 입력. 입력하는 대로 하이픈을 넣고(010-1234-5678, 02-123-4567, 1588-1234), 값은 숫자만 넘긴다.
@@ -1137,6 +1247,47 @@ interface RadioGroupProps {
1137
1247
  }
1138
1248
  declare const RadioGroup: react.ForwardRefExoticComponent<RadioGroupProps & react.RefAttributes<HTMLDivElement>>;
1139
1249
 
1250
+ interface SegmentedControlOption {
1251
+ value: string;
1252
+ /** 칸에 보이는 글자 (접근 가능한 이름이 된다) */
1253
+ label: ReactNode;
1254
+ /** 글자 앞 아이콘 (장식용) */
1255
+ icon?: ReactNode;
1256
+ disabled?: boolean;
1257
+ }
1258
+ interface SegmentedControlProps {
1259
+ /** 선택지 (2~5개 권장 — 많으면 Select 를 쓴다) */
1260
+ options: SegmentedControlOption[];
1261
+ /** 선택된 값 (제어 모드) */
1262
+ value?: string;
1263
+ /** 처음 선택된 값 (비제어 모드) */
1264
+ defaultValue?: string;
1265
+ /** 값이 바뀔 때 호출된다 */
1266
+ onValueChange?: (value: string) => void;
1267
+ /** 위에 보이는 레이블. 없으면 aria-label 로 이름을 준다 */
1268
+ label?: ReactNode;
1269
+ /** label 이 없을 때 스크린리더용 이름 (예: "기간") */
1270
+ 'aria-label'?: string;
1271
+ /** 크기 — 전체 높이가 Button·Input 과 같다 (sm 32 / md 40 / lg 48) */
1272
+ size?: 'sm' | 'md' | 'lg';
1273
+ /** 부모 너비를 꽉 채우고 칸을 같은 너비로 나눈다 */
1274
+ fullWidth?: boolean;
1275
+ disabled?: boolean;
1276
+ /** form 제출 시 사용할 이름 */
1277
+ name?: string;
1278
+ id?: string;
1279
+ className?: string;
1280
+ }
1281
+ /**
1282
+ * 여러 값 중 하나를 고르는 칸 묶음 (기간 일/주/월, 보기 방식 등).
1283
+ * 의미는 라디오 그룹과 같다(WAI-ARIA radiogroup): Tab 으로 그룹에 들어가면 선택된 칸, 화살표로 옮기면 바로 선택된다.
1284
+ * 선택에 따라 아래 내용이 바뀌는 "패널" 이 있으면 Tabs 를 쓴다.
1285
+ *
1286
+ * Radix RadioGroup 을 쓰지 않고 직접 구현한다 — Radix 는 "포커스가 옮겨질 때 화살표 키가 아직 눌려 있는지" 로 선택을 정해서
1287
+ * 키를 아주 빨리 떼는 입력(자동화·일부 보조기기)에서는 포커스만 옮겨지고 선택이 안 되는 경우가 있었다(E2E 에서 약 20%).
1288
+ */
1289
+ declare const SegmentedControl: react.ForwardRefExoticComponent<SegmentedControlProps & react.RefAttributes<HTMLDivElement>>;
1290
+
1140
1291
  interface SelectOption {
1141
1292
  value: string;
1142
1293
  label: ReactNode;
@@ -1191,6 +1342,23 @@ interface SkeletonProps extends HTMLAttributes<HTMLSpanElement> {
1191
1342
  */
1192
1343
  declare const Skeleton: react.ForwardRefExoticComponent<SkeletonProps & react.RefAttributes<HTMLSpanElement>>;
1193
1344
 
1345
+ interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
1346
+ /** 건너뛸 곳(본문)의 id 를 가리키는 주소. 기본 "#main" — 본문 요소에 id="main" 을 준다 */
1347
+ href?: string;
1348
+ }
1349
+ /**
1350
+ * 본문 바로가기 (KWCAG 2.2 6.4.1 반복 영역 건너뛰기 / WCAG 2.4.1).
1351
+ * 페이지 맨 앞(머리글·메뉴보다 먼저)에 둔다. 평소에는 보이지 않고, 첫 Tab 에 왼쪽 위에 나타난다.
1352
+ * 누르면 본문으로 포커스를 옮긴다 — 본문 요소가 원래 포커스를 받지 못하면 tabindex="-1" 을 붙여 옮긴다
1353
+ * (주소의 #만 바꾸면 일부 브라우저·SPA 라우터에서 포커스가 그대로 남는다).
1354
+ *
1355
+ * @example
1356
+ * <SkipLink /> // "본문 바로가기" → #main
1357
+ * <Header />
1358
+ * <main id="main">…</main>
1359
+ */
1360
+ declare const SkipLink: react.ForwardRefExoticComponent<SkipLinkProps & react.RefAttributes<HTMLAnchorElement>>;
1361
+
1194
1362
  interface SliderProps {
1195
1363
  /** 값 (제어 모드). 손잡이 하나면 `[50]`, 범위면 `[20, 80]` */
1196
1364
  value?: number[];
@@ -1236,11 +1404,8 @@ declare const Slider: react.ForwardRefExoticComponent<SliderProps & react.RefAtt
1236
1404
  interface SpinnerProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'color'> {
1237
1405
  /** 크기 (sm 16px, md 20px, lg 28px) */
1238
1406
  size?: 'sm' | 'md' | 'lg';
1239
- /**
1240
- * 색상. `inherit`(기본)는 부모 글자색을 그대로 쓴다.
1241
- * `current` 는 0.x 의 옛 이름으로 `inherit` 와 같다 — **deprecated, 1.0 에서 제거**.
1242
- */
1243
- color?: 'inherit' | 'primary' | 'neutral' | 'danger' | 'current';
1407
+ /** 색상. `inherit`(기본)는 부모 글자색을 그대로 쓴다 */
1408
+ color?: 'inherit' | 'primary' | 'neutral' | 'danger';
1244
1409
  /**
1245
1410
  * 스크린리더가 읽을 텍스트 (기본 "로딩 중").
1246
1411
  * 빈 문자열이면 장식용으로 보고 `aria-hidden` 처리한다 — 버튼처럼 바깥 요소가 이미 상태를 알릴 때 쓴다.
@@ -1399,10 +1564,6 @@ interface ToastOptions {
1399
1564
  description?: ReactNode;
1400
1565
  /** 의미 색상 (기본 neutral) — Alert·Badge 의 `color` 와 같은 이름 */
1401
1566
  color?: ToastColor;
1402
- /**
1403
- * @deprecated `color` 를 쓰세요 (`'default'` → `'neutral'`). 1.0 에서 제거.
1404
- */
1405
- variant?: 'default' | 'success' | 'warning' | 'danger';
1406
1567
  /** 자동으로 닫히기까지 시간(ms). Infinity 면 자동으로 닫히지 않는다 */
1407
1568
  duration?: number;
1408
1569
  /** 실행 버튼 */
@@ -1510,39 +1671,4 @@ interface VerificationCodeInputProps {
1510
1671
  */
1511
1672
  declare const VerificationCodeInput: react.ForwardRefExoticComponent<VerificationCodeInputProps & react.RefAttributes<HTMLInputElement>>;
1512
1673
 
1513
- /**
1514
- * 숫자만 있는 전화번호에 하이픈을 넣는다. 입력 중인 값도 자연스럽게 나눈다.
1515
- * @example formatPhoneNumber('01012345678') // '010-1234-5678'
1516
- * @example formatPhoneNumber('021234567') // '02-123-4567'
1517
- * @example formatPhoneNumber('15881234') // '1588-1234'
1518
- */
1519
- declare function formatPhoneNumber(input: string): string;
1520
- /**
1521
- * 사업자등록번호(10자리)에 하이픈을 넣는다.
1522
- * @example formatBusinessNumber('1234567890') // '123-45-67890'
1523
- */
1524
- declare function formatBusinessNumber(input: string): string;
1525
- /**
1526
- * 사업자등록번호 검증 공식(가중치 1,3,7,1,3,7,1,3,5)으로 확인한다. 실제로 등록된 번호인지는 국세청 조회가 필요하다.
1527
- * @example isValidBusinessNumber('124-81-00998') // true
1528
- */
1529
- declare function isValidBusinessNumber(input: string): boolean;
1530
- /**
1531
- * 금액을 만·억·조 단위로 읽기 쉽게 쓴다.
1532
- * @example formatKoreanAmount(125000) // '12만 5,000원'
1533
- * @example formatKoreanAmount(150000000) // '1억 5,000만원'
1534
- * @example formatKoreanAmount(0) // '0원'
1535
- */
1536
- declare function formatKoreanAmount(amount: number, unit?: string): string;
1537
-
1538
- /** Date → 'YYYY-MM-DD' (로컬 기준) */
1539
- declare function toISODate(date: Date): string;
1540
- /** 'YYYY-MM-DD' → Date (로컬 자정). 형식이 틀리거나 없는 날짜(2월 30일 등)면 null */
1541
- declare function parseISODate(value: string | null | undefined): Date | null;
1542
- /**
1543
- * 한국어 날짜. 스크린리더용 날짜 이름 등에 쓴다.
1544
- * @example formatKoreanDate(new Date(2026, 9, 15)) // '2026년 10월 15일 목요일'
1545
- */
1546
- declare function formatKoreanDate(date: Date, withWeekday?: boolean): string;
1547
-
1548
- export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, AddressInput, type AddressInputProps, type AddressProvider, type AddressSearchResult, type AddressValue, AgreementGroup, type AgreementGroupProps, type AgreementItem, Alert, type AlertColor, type AlertProps, AmountInput, type AmountInputProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BestowMessages, type BestowTheme, Breadcrumb, type BreadcrumbItemData, type BreadcrumbProps, BusinessNumberInput, type BusinessNumberInputProps, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardBody, CardFooter, CardHeader, type CardProps, type CardSectionProps, Checkbox, type CheckboxProps, Combobox, type ComboboxOption, type ComboboxProps, DatePicker, type DatePickerProps, type DeepPartial, Divider, type DividerProps, Drawer, DrawerClose, type DrawerProps, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, type DropdownMenuProps, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuTrigger, type DropdownMenuTriggerProps, IconButton, type IconButtonProps, Input, type InputProps, type IntentName, Link, type LinkProps, LocaleProvider, type LocaleProviderProps, type Messages, Modal, ModalClose, type ModalProps, Pagination, type PaginationProps, PhoneNumberInput, type PhoneNumberInputProps, Popover, PopoverClose, type PopoverProps, Progress, type ProgressProps, RadioGroup, type RadioGroupProps, type RadioOption, Select, type SelectOption, type SelectProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Spinner, type SpinnerProps, Stack, type StackProps, Switch, type SwitchProps, Table, type TableAlign, TableBody, TableCell, type TableCellProps, TableFooter, TableHead, type TableHeadProps, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSize, Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsTriggerProps, TextField, type TextFieldProps, Textarea, type TextareaProps, type ThemeInput, type ThemeName, type ThemeOverrides, ThemeProvider, type ThemeProviderProps, type ThemeTokens, type ToastColor, type ToastContextValue, type ToastOptions, ToastProvider, type ToastProviderProps, Tooltip, type TooltipProps, Typography, type TypographyProps, type TypographyVariant, VerificationCodeInput, type VerificationCodeInputProps, composeExtraAddress, contrastRatio, createIntentColors, createTheme, en, formatBusinessNumber, formatKoreanAmount, formatKoreanDate, formatPhoneNumber, hasAllRequiredAgreements, isValidBusinessNumber, kakaoPostcodeProvider, parseISODate, themeClass, toISODate, useMessages, usePortalClassName, usePortalProps, useTheme, useToast, vars };
1674
+ export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps, AddressInput, type AddressInputProps, type AddressProvider, type AddressSearchResult, type AddressValue, AgreementGroup, type AgreementGroupProps, type AgreementItem, Alert, type AlertColor, type AlertProps, AmountInput, type AmountInputProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BestowMessages, type BestowTheme, Breadcrumb, type BreadcrumbItemData, type BreadcrumbProps, BusinessNumberInput, type BusinessNumberInputProps, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardBody, CardFooter, CardHeader, type CardProps, type CardSectionProps, Checkbox, type CheckboxProps, Combobox, type ComboboxOption, type ComboboxProps, DatePicker, type DatePickerProps, type DeepPartial, Divider, type DividerProps, Drawer, DrawerClose, type DrawerProps, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, type DropdownMenuProps, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuTrigger, type DropdownMenuTriggerProps, IconButton, type IconButtonProps, Input, type InputProps, type IntentName, Link, type LinkProps, LocaleProvider, type LocaleProviderProps, type Messages, Modal, ModalClose, type ModalProps, Pagination, type PaginationItemType, type PaginationProps, PhoneNumberInput, type PhoneNumberInputProps, Popover, PopoverClose, type PopoverProps, Progress, type ProgressProps, RadioGroup, type RadioGroupProps, type RadioOption, SegmentedControl, type SegmentedControlOption, type SegmentedControlProps, Select, type SelectOption, type SelectProps, Skeleton, type SkeletonProps, SkipLink, type SkipLinkProps, Slider, type SliderProps, Spinner, type SpinnerProps, Stack, type StackProps, Switch, type SwitchProps, Table, type TableAlign, TableBody, TableCell, type TableCellProps, TableFooter, TableHead, type TableHeadProps, TableHeader, type TableProps, TableRow, type TableRowProps, type TableSize, Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsTriggerProps, TextField, type TextFieldProps, Textarea, type TextareaProps, type ThemeInput, type ThemeName, type ThemeOverrides, ThemeProvider, type ThemeProviderProps, type ThemeTokens, type ToastColor, type ToastContextValue, type ToastOptions, ToastProvider, type ToastProviderProps, Tooltip, type TooltipProps, Typography, type TypographyProps, type TypographyVariant, VerificationCodeInput, type VerificationCodeInputProps, composeExtraAddress, contrastRatio, createIntentColors, createTheme, en, formatBusinessNumber, formatKoreanAmount, formatKoreanDate, formatPhoneNumber, hasAllRequiredAgreements, isValidBusinessNumber, kakaoPostcodeProvider, parseISODate, themeClass, toISODate, useMessages, usePortalProps, useTheme, useToast, vars };