@nurimedia/react-ui 0.1.0 โ†’ 0.1.2

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 (97) hide show
  1. package/dist/AlertDialog/index.cjs +4 -180
  2. package/dist/AlertDialog/index.cjs.map +1 -1
  3. package/dist/AlertDialog/index.js +5 -144
  4. package/dist/AlertDialog/index.js.map +1 -1
  5. package/dist/Button/index.cjs +4 -131
  6. package/dist/Button/index.cjs.map +1 -1
  7. package/dist/Button/index.js +5 -105
  8. package/dist/Button/index.js.map +1 -1
  9. package/dist/Checkbox/index.cjs +4 -78
  10. package/dist/Checkbox/index.cjs.map +1 -1
  11. package/dist/Checkbox/index.js +5 -42
  12. package/dist/Checkbox/index.js.map +1 -1
  13. package/dist/Input/index.cjs +4 -98
  14. package/dist/Input/index.cjs.map +1 -1
  15. package/dist/Input/index.js +5 -72
  16. package/dist/Input/index.js.map +1 -1
  17. package/dist/Modal/index.cjs +4 -115
  18. package/dist/Modal/index.cjs.map +1 -1
  19. package/dist/Modal/index.js +5 -79
  20. package/dist/Modal/index.js.map +1 -1
  21. package/dist/Radio/index.cjs +6 -81
  22. package/dist/Radio/index.cjs.map +1 -1
  23. package/dist/Radio/index.js +6 -43
  24. package/dist/Radio/index.js.map +1 -1
  25. package/dist/Select/index.cjs +4 -111
  26. package/dist/Select/index.cjs.map +1 -1
  27. package/dist/Select/index.js +5 -75
  28. package/dist/Select/index.js.map +1 -1
  29. package/dist/Switch/index.cjs +4 -66
  30. package/dist/Switch/index.cjs.map +1 -1
  31. package/dist/Switch/index.js +5 -30
  32. package/dist/Switch/index.js.map +1 -1
  33. package/dist/Textarea/index.cjs +4 -122
  34. package/dist/Textarea/index.cjs.map +1 -1
  35. package/dist/Textarea/index.js +5 -96
  36. package/dist/Textarea/index.js.map +1 -1
  37. package/dist/Toast/index.cjs +4 -177
  38. package/dist/Toast/index.cjs.map +1 -1
  39. package/dist/Toast/index.js +6 -141
  40. package/dist/Toast/index.js.map +1 -1
  41. package/dist/Tooltip/index.cjs +6 -100
  42. package/dist/Tooltip/index.cjs.map +1 -1
  43. package/dist/Tooltip/index.js +6 -62
  44. package/dist/Tooltip/index.js.map +1 -1
  45. package/dist/chunk-2LFW4MM6.cjs +47 -0
  46. package/dist/chunk-2LFW4MM6.cjs.map +1 -0
  47. package/dist/chunk-2WKLA5RC.cjs +82 -0
  48. package/dist/chunk-2WKLA5RC.cjs.map +1 -0
  49. package/dist/chunk-2YGYLCCA.js +66 -0
  50. package/dist/chunk-2YGYLCCA.js.map +1 -0
  51. package/dist/chunk-323VGYMK.cjs +147 -0
  52. package/dist/chunk-323VGYMK.cjs.map +1 -0
  53. package/dist/chunk-3H47QMKS.js +47 -0
  54. package/dist/chunk-3H47QMKS.js.map +1 -0
  55. package/dist/chunk-3QSLHLC2.cjs +45 -0
  56. package/dist/chunk-3QSLHLC2.cjs.map +1 -0
  57. package/dist/chunk-4N5JIGIU.js +82 -0
  58. package/dist/chunk-4N5JIGIU.js.map +1 -0
  59. package/dist/chunk-DTGPVOJK.js +99 -0
  60. package/dist/chunk-DTGPVOJK.js.map +1 -0
  61. package/dist/chunk-DTQE42F7.js +33 -0
  62. package/dist/chunk-DTQE42F7.js.map +1 -0
  63. package/dist/chunk-DYO4PIBB.js +75 -0
  64. package/dist/chunk-DYO4PIBB.js.map +1 -0
  65. package/dist/chunk-GBMYANHH.js +149 -0
  66. package/dist/chunk-GBMYANHH.js.map +1 -0
  67. package/dist/chunk-I7KJ7WTN.cjs +149 -0
  68. package/dist/chunk-I7KJ7WTN.cjs.map +1 -0
  69. package/dist/chunk-JM4HDCLU.cjs +110 -0
  70. package/dist/chunk-JM4HDCLU.cjs.map +1 -0
  71. package/dist/chunk-JXJ6G634.cjs +75 -0
  72. package/dist/chunk-JXJ6G634.cjs.map +1 -0
  73. package/dist/chunk-LAPTEQ5N.js +45 -0
  74. package/dist/chunk-LAPTEQ5N.js.map +1 -0
  75. package/dist/chunk-LRATCHCB.cjs +66 -0
  76. package/dist/chunk-LRATCHCB.cjs.map +1 -0
  77. package/dist/chunk-OM4QMC4F.js +110 -0
  78. package/dist/chunk-OM4QMC4F.js.map +1 -0
  79. package/dist/chunk-PAXRFQUJ.cjs +33 -0
  80. package/dist/chunk-PAXRFQUJ.cjs.map +1 -0
  81. package/dist/chunk-PC3B67B4.cjs +78 -0
  82. package/dist/chunk-PC3B67B4.cjs.map +1 -0
  83. package/dist/chunk-PS6QXS5Z.js +11 -0
  84. package/dist/chunk-PS6QXS5Z.js.map +1 -0
  85. package/dist/chunk-Q26BJSLP.cjs +99 -0
  86. package/dist/chunk-Q26BJSLP.cjs.map +1 -0
  87. package/dist/chunk-R4E4BIPC.cjs +11 -0
  88. package/dist/chunk-R4E4BIPC.cjs.map +1 -0
  89. package/dist/chunk-R757N7RU.js +78 -0
  90. package/dist/chunk-R757N7RU.js.map +1 -0
  91. package/dist/chunk-RC773ZEY.js +147 -0
  92. package/dist/chunk-RC773ZEY.js.map +1 -0
  93. package/dist/index.cjs +54 -899
  94. package/dist/index.cjs.map +1 -1
  95. package/dist/index.js +38 -833
  96. package/dist/index.js.map +1 -1
  97. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Button/Button.tsx","../src/Button/Spinner.tsx","../src/utils/cx.ts","../src/Input/Input.tsx","../src/Textarea/Textarea.tsx","../src/Checkbox/Checkbox.tsx","../src/Radio/Radio.tsx","../src/Switch/Switch.tsx","../src/Select/Select.tsx","../src/Modal/Modal.tsx","../src/AlertDialog/AlertDialog.tsx","../src/AlertDialog/icons.tsx","../src/Toast/Toaster.tsx","../src/Toast/store.ts","../src/Toast/icons.tsx","../src/Toast/toast.ts","../src/Tooltip/Tooltip.tsx"],"sourcesContent":["export * from './Button/index.js';\nexport * from './Input/index.js';\nexport * from './Textarea/index.js';\nexport * from './Checkbox/index.js';\nexport * from './Radio/index.js';\nexport * from './Switch/index.js';\nexport * from './Select/index.js';\nexport * from './Modal/index.js';\nexport * from './AlertDialog/index.js';\nexport * from './Toast/index.js';\nexport * from './Tooltip/index.js';\n","'use client';\n\nimport './styles.css';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Children, cloneElement, forwardRef, isValidElement } from 'react';\nimport type { ButtonHTMLAttributes, MouseEvent, ReactElement, ReactNode } from 'react';\nimport { Spinner } from './Spinner.js';\nimport { cx } from '../utils/cx.js';\n\ntype Variant = 'primary' | 'secondary' | 'outline' | 'ghost';\ntype Size = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n /**\n * ์‹œ๊ฐ ์œ ํ˜•.\n * - `primary`: ๋ธŒ๋žœ๋“œ ์ƒ‰ ๋ฐฐ๊ฒฝ (๊ธฐ๋ณธ)\n * - `secondary`: ๋ธŒ๋žœ๋“œ ์˜…์€ ํ†ค ๋ฐฐ๊ฒฝ\n * - `outline`: ํˆฌ๋ช… ๋ฐฐ๊ฒฝ + ํ…Œ๋‘๋ฆฌ\n * - `ghost`: ํˆฌ๋ช… ๋ฐฐ๊ฒฝ, hover ์‹œ์—๋งŒ ๋ฐฐ๊ฒฝ ์ฑ„์›€\n * @default 'primary'\n */\n variant?: Variant;\n\n /**\n * ์‚ฌ์ด์ฆˆ.\n * - `sm`: 36px ๋†’์ด โ€” ๋ฐ€์ง‘๋œ UI, ํ…Œ์ด๋ธ” ์•ก์…˜\n * - `md`: 42px ๋†’์ด โ€” ์ผ๋ฐ˜ ์ฝ˜ํ…์ธ  ์˜์—ญ (๊ธฐ๋ณธ)\n * - `lg`: 48px ๋†’์ด โ€” ์ฃผ์š” CTA, ๋ชจ๋ฐ”์ผ ํ„ฐ์น˜\n * @default 'md'\n */\n size?: Size;\n\n /**\n * ๋ผ๋ฒจ ์ขŒ์ธก์— ํ‘œ์‹œํ•  ์•„์ด์ฝ˜.\n * @example <Button iconLeft={<SearchIcon />}>๊ฒ€์ƒ‰</Button>\n */\n iconLeft?: ReactNode;\n\n /**\n * ๋ผ๋ฒจ ์šฐ์ธก์— ํ‘œ์‹œํ•  ์•„์ด์ฝ˜.\n */\n iconRight?: ReactNode;\n\n /**\n * ์•„์ด์ฝ˜๋งŒ ํ‘œ์‹œํ•˜๋Š” ์ •์‚ฌ๊ฐ ๋ฒ„ํŠผ. **`aria-label` ํ•„์ˆ˜**\n * (icon-only๋Š” ์‹œ๊ฐ์ ์œผ๋กœ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์Šคํฌ๋ฆฐ๋ฆฌ๋”์šฉ ๋ผ๋ฒจ์ด ์—†์œผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์šฉ๋„๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ).\n * children์€ ๋‹จ์ผ ์•„์ด์ฝ˜ ์—˜๋ฆฌ๋จผํŠธ.\n * @example <Button iconOnly aria-label=\"๋‹ซ๊ธฐ\"><CloseIcon /></Button>\n */\n iconOnly?: boolean;\n\n /**\n * ์ปจํ…Œ์ด๋„ˆ ์ „์ฒด ๋„ˆ๋น„๋กœ ํ™•์žฅ.\n */\n block?: boolean;\n\n /**\n * ๋กœ๋”ฉ ์ค‘ ํ‘œ์‹œ. ์Šคํ”ผ๋„ˆ๋ฅผ ์ขŒ์ธก ์•„์ด์ฝ˜ ์ž๋ฆฌ์— ํ‘œ์‹œํ•˜๊ณ , ํด๋ฆญ์„ ์ฐจ๋‹จํ•˜๋ฉฐ `aria-busy=\"true\"`๋ฅผ ๋ถ€์—ฌ.\n */\n loading?: boolean;\n\n /**\n * Radix Slot์œผ๋กœ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ Œ๋” โ€” ์ž์‹์ด Button์˜ classNameยทrefยท์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋ชจ๋‘ ๋ฌผ๋ ค๋ฐ›์Œ.\n * ๋งํฌ๋ฅผ ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•  ๋•Œ ๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉ (next/link, react-router Link ๋“ฑ).\n * @example\n * <Button asChild><Link href=\"/about\">์†Œ๊ฐœ</Link></Button>\n */\n asChild?: boolean;\n\n /**\n * ํผ ๋ฒ„ํŠผ ํƒ€์ž…. ์˜๋„์น˜ ์•Š์€ form submit ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ๊ฐ’ `'button'`.\n * ํผ ์ œ์ถœ ๋ฒ„ํŠผ์ด๋ฉด ๋ช…์‹œ์ ์œผ๋กœ `type=\"submit\"` ์ง€์ •.\n * @default 'button'\n */\n type?: 'button' | 'submit' | 'reset';\n\n children?: ReactNode;\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n variant = 'primary',\n size = 'md',\n iconLeft,\n iconRight,\n iconOnly = false,\n block = false,\n loading = false,\n disabled = false,\n asChild = false,\n type = 'button',\n className,\n children,\n onClick,\n ...rest\n },\n ref,\n) {\n const isBlocked = disabled || loading;\n\n if (\n process.env.NODE_ENV !== 'production' &&\n iconOnly &&\n !rest['aria-label'] &&\n !rest['aria-labelledby']\n ) {\n // iconOnly ๋ฒ„ํŠผ์€ ํ…์ŠคํŠธ๊ฐ€ ์—†์–ด ์Šคํฌ๋ฆฐ๋ฆฌ๋”๊ฐ€ ์šฉ๋„๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ โ†’ ๊ฐœ๋ฐœ ๋ชจ๋“œ ๊ฒฝ๊ณ \n console.warn(\n '[nuri/Button] `iconOnly` ๋ฒ„ํŠผ์€ `aria-label`(๋˜๋Š” `aria-labelledby`)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.',\n );\n }\n\n const hasLeftSlot = !iconOnly && (loading || iconLeft != null);\n const hasRightSlot = !iconOnly && !loading && iconRight != null;\n\n const classes = cx(\n 'nuri-button',\n `nuri-button--${variant}`,\n `nuri-button--${size}`,\n block && 'nuri-button--block',\n iconOnly && 'nuri-button--icon-only',\n isBlocked && 'nuri-button--disabled',\n loading && 'nuri-button--loading',\n hasLeftSlot && 'nuri-button--has-left',\n hasRightSlot && 'nuri-button--has-right',\n className,\n );\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (isBlocked) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n onClick?.(e);\n };\n\n const renderContent = (content: ReactNode) => {\n if (iconOnly) {\n return (\n <span className=\"nuri-button__icon\" aria-hidden=\"true\">\n {loading ? <Spinner /> : content}\n </span>\n );\n }\n return (\n <>\n {loading ? (\n <Spinner />\n ) : (\n iconLeft != null && (\n <span className=\"nuri-button__icon nuri-button__icon--left\" aria-hidden=\"true\">\n {iconLeft}\n </span>\n )\n )}\n {content}\n {hasRightSlot && (\n <span className=\"nuri-button__icon nuri-button__icon--right\" aria-hidden=\"true\">\n {iconRight}\n </span>\n )}\n </>\n );\n };\n\n if (asChild) {\n const child = Children.only(children);\n if (!isValidElement(child)) return null;\n const childElement = child as ReactElement<{ children?: ReactNode }>;\n return (\n <Slot\n ref={ref}\n className={classes}\n aria-disabled={isBlocked || undefined}\n aria-busy={loading || undefined}\n onClick={handleClick}\n {...rest}\n >\n {cloneElement(childElement, undefined, renderContent(childElement.props.children))}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n type={type}\n className={classes}\n // disabled = ์ง„์งœ ๋น„ํ™œ์„ฑ โ†’ native disabled (ํฌ์ปค์Šค ๋ถˆ๊ฐ€, ์˜๋„๋œ ๋™์ž‘)\n // loading = ์ผ์‹œ์  ์ฒ˜๋ฆฌ์ค‘ โ†’ aria-disabled๋กœ ํฌ์ปค์Šค ์œ ์ง€ (ํด๋ฆญ์€ handleClick์ด ๊ฐ€๋“œ)\n disabled={disabled}\n aria-disabled={loading || undefined}\n aria-busy={loading || undefined}\n onClick={handleClick}\n {...rest}\n >\n {renderContent(children)}\n </button>\n );\n});\n","export const Spinner = () => (\n <span className=\"nuri-button__icon\" aria-hidden=\"true\">\n <svg className=\"nuri-button__spinner\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" stroke=\"currentColor\" strokeOpacity=\"0.25\" strokeWidth=\"2\" />\n <path d=\"M14 8a6 6 0 0 0-6-6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </span>\n);\n","/**\n * ์กฐ๊ฑด๋ถ€ className ํ•ฉ์„ฑ ์œ ํ‹ธ. falsy ๊ฐ’(undefined/false/null/'')์€ ์ œ๊ฑฐ.\n * @example cx('btn', isActive && 'btn--active', className)\n */\nexport function cx(...classes: Array<string | false | null | undefined>): string {\n return classes.filter(Boolean).join(' ');\n}\n","'use client';\n\nimport './styles.css';\nimport { forwardRef, useId } from 'react';\nimport type { InputHTMLAttributes, ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\ntype Size = 'sm' | 'md' | 'lg';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /**\n * ์‚ฌ์ด์ฆˆ. sm 36 / md 42 / lg 48 px ๋†’์ด.\n * @default 'md'\n */\n size?: Size;\n /**\n * ๋ผ๋ฒจ (ํ•„๋“œ ์œ„). ์ง€์ • ์‹œ `<label>`๋กœ ๋ Œ๋”๋˜์–ด ์ž๋™ ์—ฐ๊ฒฐ๋จ.\n * ๋ผ๋ฒจ์„ ๋‘์ง€ ์•Š์œผ๋ฉด `aria-label`๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„์„ ์ฃผ์„ธ์š”\n * (placeholder๋Š” ์ด๋ฆ„์„ ๋Œ€์ฒดํ•˜์ง€ ๋ชปํ•จ โ€” ์ž…๋ ฅ ์‹œ ์‚ฌ๋ผ์ง€๊ณ  ๋Œ€๋น„๊ฐ€ ๋‚ฎ์Œ).\n */\n label?: ReactNode;\n /**\n * ๋ผ๋ฒจ์„ ์‹œ๊ฐ์ ์œผ๋กœ๋งŒ ์ˆจ๊น€ (์Šคํฌ๋ฆฐ๋ฆฌ๋”์—๋Š” ๋…ธ์ถœ). ๋””์ž์ธ์ƒ ๋ผ๋ฒจ์„ ์•ˆ ๋ณด์ด๊ฒŒ ํ•˜๋˜\n * ์ ‘๊ทผ์„ฑ ์ด๋ฆ„์€ ์œ ์ง€ํ•  ๋•Œ ์‚ฌ์šฉ.\n * @default false\n */\n hideLabel?: boolean;\n /** ํ‰์ƒ์‹œ ํžŒํŠธ (ํšŒ์ƒ‰, ํ•„๋“œ ์•„๋ž˜). `aria-describedby`๋กœ ์—ฐ๊ฒฐ๋จ. */\n description?: ReactNode;\n /** ์—๋Ÿฌ ์ƒํƒœ โ€” ๋ณด๋”ยทํ…์ŠคํŠธยท๋ฐฐ๊ฒฝ์ด ์—๋Ÿฌ์ƒ‰์œผ๋กœ ๋ฐ”๋€Œ๊ณ  `aria-invalid`๊ฐ€ ์„ค์ •๋จ. */\n invalid?: boolean;\n /** `invalid`์ผ ๋•Œ ํ‘œ์‹œํ•  ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ (๋นจ๊ฐ•). ์žˆ์œผ๋ฉด description์„ ๋Œ€์ฒด. */\n errorMessage?: ReactNode;\n /** ์ขŒ์ธก ์–ด๋„๋จผํŠธ (์•„์ด์ฝ˜ ๋“ฑ). */\n iconLeft?: ReactNode;\n /** ์šฐ์ธก ์–ด๋„๋จผํŠธ (์•„์ด์ฝ˜ยทclearยท๋ฒ„ํŠผ ๋“ฑ). */\n iconRight?: ReactNode;\n /** ์ปจํ…Œ์ด๋„ˆ ์ „์ฒด ๋„ˆ๋น„๋กœ ํ™•์žฅ. @default false */\n block?: boolean;\n}\n\n/**\n * ํ…์ŠคํŠธ ์ž…๋ ฅ ํ•„๋“œ. ์˜ต์…˜์œผ๋กœ ๋ผ๋ฒจ(์œ„)ยทํ—ฌํผ/์—๋Ÿฌ ๋ฉ”์‹œ์ง€(์•„๋ž˜)๋ฅผ ํฌํ•จํ•˜๋Š” ์ž์ฒด ์™„๊ฒฐํ˜•.\n * ์ƒํƒœ(default/focus/invalid/disabled)๋Š” CSS๋กœ, ๊ฐ’ ์ฑ„์›€(filled)์€ ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ์ฒ˜๋ฆฌ.\n *\n * @example ๊ธฐ๋ณธ\n * <Input placeholder=\"๊ฒ€์ƒ‰์–ด\" aria-label=\"๊ฒ€์ƒ‰\" />\n *\n * @example ๋ผ๋ฒจ + ํ—ฌํผ + ์—๋Ÿฌ\n * <Input\n * label=\"๋น„๋ฐ€๋ฒˆํ˜ธ\"\n * description=\"8์ž ์ด์ƒ ์ž…๋ ฅํ•˜์„ธ์š”\"\n * invalid\n * errorMessage=\"๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค\"\n * />\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n size = 'md',\n label,\n hideLabel = false,\n description,\n invalid = false,\n errorMessage,\n iconLeft,\n iconRight,\n block = false,\n disabled = false,\n className,\n id: idProp,\n 'aria-describedby': ariaDescribedby,\n ...rest\n },\n ref,\n) {\n const reactId = useId();\n const id = idProp ?? `nuri-input-${reactId}`;\n const messageId = `${id}-message`;\n\n // invalid + errorMessage โ†’ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ / ์•„๋‹ˆ๋ฉด ํžŒํŠธ. ์‹œ๊ฐ ์Šฌ๋กฏ์€ ํ•ญ์ƒ ํ•œ ์ค„.\n const message = invalid && errorMessage != null ? errorMessage : description;\n const hasMessage = message != null;\n const describedBy =\n cx(hasMessage ? messageId : undefined, ariaDescribedby as string | undefined) || undefined;\n\n return (\n <div className={cx('nuri-input', block && 'nuri-input--block', className)}>\n {label != null && (\n <label htmlFor={id} className={cx('nuri-input__label', hideLabel && 'nuri-sr-only')}>\n {label}\n </label>\n )}\n\n <div\n className={cx(\n 'nuri-input__field',\n `nuri-input__field--${size}`,\n invalid && 'nuri-input__field--invalid',\n disabled && 'nuri-input__field--disabled',\n )}\n >\n {iconLeft != null && (\n <span className=\"nuri-input__icon\" aria-hidden=\"true\">\n {iconLeft}\n </span>\n )}\n <input\n ref={ref}\n id={id}\n className=\"nuri-input__control\"\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n {...rest}\n />\n {iconRight != null && (\n <span className=\"nuri-input__icon\" aria-hidden=\"true\">\n {iconRight}\n </span>\n )}\n </div>\n\n {hasMessage && (\n <p\n id={messageId}\n className={cx('nuri-input__message', invalid && 'nuri-input__message--error')}\n >\n {message}\n </p>\n )}\n </div>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport { forwardRef, useCallback, useId, useLayoutEffect, useRef } from 'react';\nimport type { ChangeEvent, TextareaHTMLAttributes, ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n /**\n * ๋ผ๋ฒจ (ํ•„๋“œ ์œ„). ์ง€์ • ์‹œ `<label>`๋กœ ๋ Œ๋”๋˜์–ด ์ž๋™ ์—ฐ๊ฒฐ๋จ.\n * ๋ผ๋ฒจ์„ ๋‘์ง€ ์•Š์œผ๋ฉด `aria-label`๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„์„ ์ฃผ์„ธ์š”.\n */\n label?: ReactNode;\n /** ๋ผ๋ฒจ์„ ์‹œ๊ฐ์ ์œผ๋กœ๋งŒ ์ˆจ๊น€ (์Šคํฌ๋ฆฐ๋ฆฌ๋”์—๋Š” ๋…ธ์ถœ). @default false */\n hideLabel?: boolean;\n /** ํ‰์ƒ์‹œ ํžŒํŠธ (ํšŒ์ƒ‰, ํ•„๋“œ ์•„๋ž˜). `aria-describedby`๋กœ ์—ฐ๊ฒฐ๋จ. */\n description?: ReactNode;\n /** ์—๋Ÿฌ ์ƒํƒœ โ€” ๋ณด๋”ยทํ…์ŠคํŠธยท๋ฐฐ๊ฒฝ์ด ์—๋Ÿฌ์ƒ‰์œผ๋กœ ๋ฐ”๋€Œ๊ณ  `aria-invalid`๊ฐ€ ์„ค์ •๋จ. */\n invalid?: boolean;\n /** `invalid`์ผ ๋•Œ ํ‘œ์‹œํ•  ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ (๋นจ๊ฐ•). ์žˆ์œผ๋ฉด description์„ ๋Œ€์ฒด. */\n errorMessage?: ReactNode;\n /** ์ปจํ…Œ์ด๋„ˆ ์ „์ฒด ๋„ˆ๋น„๋กœ ํ™•์žฅ. @default false */\n block?: boolean;\n /**\n * ํฌ๊ธฐ ์กฐ์ ˆ ํ•ธ๋“ค. ์„ธ๋กœ ์กฐ์ ˆ ํ—ˆ์šฉ์ด ๊ธฐ๋ณธ โ€” ๊ธด ์ž…๋ ฅ์„ ์‚ฌ์šฉ์ž๊ฐ€ ๋Š˜๋ ค ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ.\n * `autosize`๊ฐ€ ์ผœ์ง€๋ฉด ๋ฌด์‹œ๋œ๋‹ค(์ž๋™ ํฌ๊ธฐ์™€ ์ˆ˜๋™ ํ•ธ๋“ค์€ ์ถฉ๋Œ).\n * @default 'vertical'\n */\n resize?: 'vertical' | 'none';\n /**\n * ๋‚ด์šฉ์— ๋”ฐ๋ผ ๋†’์ด ์ž๋™ ์กฐ์ ˆ. `rows`(์ตœ์†Œ)์—์„œ ์‹œ์ž‘ํ•ด ๋‚ด์šฉ๋งŒํผ ๋Š˜์–ด๋‚˜๊ณ ,\n * `maxRows`์— ๋„๋‹ฌํ•˜๋ฉด ๋ฉˆ์ถ”๊ณ  ์Šคํฌ๋กค์ด ์ƒ๊ธด๋‹ค.\n * @default false\n */\n autosize?: boolean;\n /** `autosize`์ผ ๋•Œ ์ตœ๋Œ€ ์ค„ ์ˆ˜ โ€” ๋„˜์œผ๋ฉด ์Šคํฌ๋กค. ๋ฏธ์ง€์ • ์‹œ ๋ฌด์ œํ•œ ํ™•์žฅ. */\n maxRows?: number;\n}\n\n/**\n * ์—ฌ๋Ÿฌ ์ค„ ํ…์ŠคํŠธ ์ž…๋ ฅ. Input๊ณผ ๋™์ผํ•œ ๋””์ž์ธ ์–ธ์–ด(๋ณด๋”ยท์ƒํƒœยทํƒ€์ดํฌ)์™€\n * ๋ผ๋ฒจ/ํžŒํŠธ/์—๋Ÿฌ ์ž๋™ ์—ฐ๊ฒฐ ํŒจํ„ด์„ ๋”ฐ๋ฅด๋Š” ์ž์ฒด ์™„๊ฒฐํ˜•.\n * ๋†’์ด๋Š” native `rows`(๊ธฐ๋ณธ 3)๋กœ ์ œ์–ดํ•˜๊ณ , `autosize`๋กœ ์ž๋™ ํ™•์žฅ๋„ ์ง€์›ํ•œ๋‹ค.\n *\n * @example\n * <Textarea label=\"๋ฌธ์˜ ๋‚ด์šฉ\" rows={5} block />\n *\n * @example ์ž๋™ ๋†’์ด โ€” 3์ค„์—์„œ ์‹œ์ž‘ํ•ด 8์ค„๊นŒ์ง€ ๋Š˜์–ด๋‚œ ๋’ค ์Šคํฌ๋กค\n * <Textarea label=\"๋Œ“๊ธ€\" autosize rows={3} maxRows={8} />\n */\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n label,\n hideLabel = false,\n description,\n invalid = false,\n errorMessage,\n block = false,\n resize = 'vertical',\n autosize = false,\n maxRows,\n rows = 3,\n disabled = false,\n className,\n id: idProp,\n value,\n onChange,\n 'aria-describedby': ariaDescribedby,\n ...rest\n },\n ref,\n) {\n const reactId = useId();\n const id = idProp ?? `nuri-textarea-${reactId}`;\n const messageId = `${id}-message`;\n\n const innerRef = useRef<HTMLTextAreaElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLTextAreaElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n\n // autosize: height๋ฅผ ๋‚ด์šฉ(scrollHeight)์— ๋งž์ถ”๋˜ maxRows ์ƒํ•œ์—์„œ ํด๋žจํ”„.\n const fitHeight = useCallback(() => {\n const el = innerRef.current;\n if (!el) return;\n const cs = getComputedStyle(el);\n const borders = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth);\n const lineHeight = parseFloat(cs.lineHeight);\n // maxRows โ†’ px ์ƒํ•œ (line-height ๊ณ„์‚ฐ ๋ถˆ๊ฐ€ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฌด์ œํ•œ)\n const maxHeight =\n maxRows != null && !Number.isNaN(lineHeight)\n ? maxRows * lineHeight + parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom) + borders\n : Infinity;\n\n el.style.height = 'auto'; // ์ค„์–ด๋“œ๋Š” ๊ฒฝ์šฐ๋„ ๋ฐ˜์˜๋˜๋„๋ก ์ดˆ๊ธฐํ™” ํ›„ ์ธก์ •\n const contentHeight = el.scrollHeight + borders; // scrollHeight๋Š” border ๋ฏธํฌํ•จ(border-box ๋ณด์ •)\n const next = Math.min(contentHeight, maxHeight);\n if (!Number.isNaN(next)) el.style.height = `${next}px`;\n el.style.overflowY = contentHeight > maxHeight ? 'auto' : 'hidden';\n }, [maxRows]);\n\n // ๋งˆ์šดํŠธยท์ œ์–ดํ˜• value ๋ณ€๊ฒฝยทautosize ํ† ๊ธ€ ์‹œ ์žฌ๊ณ„์‚ฐ\n useLayoutEffect(() => {\n if (autosize) fitHeight();\n }, [autosize, fitHeight, value]);\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(e);\n if (autosize) fitHeight(); // ๋น„์ œ์–ดํ˜• ์ž…๋ ฅ์—๋„ ๋ฐ˜์‘\n };\n\n // invalid + errorMessage โ†’ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ / ์•„๋‹ˆ๋ฉด ํžŒํŠธ. ์‹œ๊ฐ ์Šฌ๋กฏ์€ ํ•ญ์ƒ ํ•œ ์ค„. (Input๊ณผ ๋™์ผ)\n const message = invalid && errorMessage != null ? errorMessage : description;\n const hasMessage = message != null;\n const describedBy =\n cx(hasMessage ? messageId : undefined, ariaDescribedby as string | undefined) || undefined;\n\n return (\n <div className={cx('nuri-textarea', block && 'nuri-textarea--block', className)}>\n {label != null && (\n <label htmlFor={id} className={cx('nuri-textarea__label', hideLabel && 'nuri-sr-only')}>\n {label}\n </label>\n )}\n\n <textarea\n ref={setRefs}\n id={id}\n rows={rows}\n value={value}\n onChange={handleChange}\n className={cx(\n 'nuri-textarea__control',\n invalid && 'nuri-textarea__control--invalid',\n (resize === 'none' || autosize) && 'nuri-textarea__control--resize-none',\n )}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-describedby={describedBy}\n {...rest}\n />\n\n {hasMessage && (\n <p\n id={messageId}\n className={cx('nuri-textarea__message', invalid && 'nuri-textarea__message--error')}\n >\n {message}\n </p>\n )}\n </div>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport * as RadixCheckbox from '@radix-ui/react-checkbox';\nimport { forwardRef, useId } from 'react';\nimport type { ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\ntype Size = 'sm' | 'md';\n\nexport interface CheckboxProps {\n /** ๋ผ๋ฒจ (์ปจํŠธ๋กค ์šฐ์ธก). ์ง€์ • ์‹œ ํด๋ฆญ ์˜์—ญ์— ํฌํ•จ๋˜๊ณ  ์ž๋™ ์—ฐ๊ฒฐ๋จ. ์—†์œผ๋ฉด `aria-label` ํ•„์ˆ˜. */\n label?: ReactNode;\n /**\n * ์‚ฌ์ด์ฆˆ. md 16px(๋””์ž์ธ Large, ๊ธฐ๋ณธ) / sm 12px(๋””์ž์ธ Small).\n * @default 'md'\n */\n size?: Size;\n /** ์ฒดํฌ ์ƒํƒœ (์ œ์–ดํ˜•). `'indeterminate'`๋Š” ๋ถ€๋ถ„ ์„ ํƒ ํ‘œ์‹œ. */\n checked?: boolean | 'indeterminate';\n /** ์ดˆ๊ธฐ ์ฒดํฌ ์ƒํƒœ (๋น„์ œ์–ดํ˜•). */\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean | 'indeterminate') => void;\n disabled?: boolean;\n /** ํผ ์ „์†ก์šฉ name โ€” ๋„ค์ดํ‹ฐ๋ธŒ checkbox์ฒ˜๋Ÿผ ํผ์— ์ฐธ์—ฌ. */\n name?: string;\n /** ํผ ์ „์†ก ์‹œ ๊ฐ’. @default 'on' */\n value?: string;\n required?: boolean;\n id?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** ์ฒดํฌ๋งˆํฌ. TODO(Figma ์‹ค์ธก): ๋””์ž์ด๋„ˆ ์•„์ด์ฝ˜์œผ๋กœ ๊ต์ฒด ์˜ˆ์ • โ€” ์ž ์ • ํ‘œ์ค€ํ˜•. */\nconst CheckIcon = () => (\n <svg viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2.5 6.2l2.4 2.4 4.6-5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n/** ๋ถ€๋ถ„ ์„ ํƒ(indeterminate) ํ‘œ์‹œ โ€” ๊ฐ€๋กœ ๋ง‰๋Œ€. */\nconst IndeterminateIcon = () => (\n <svg viewBox=\"0 0 12 12\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2.8 6h6.4\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" />\n </svg>\n);\n\n/**\n * ์ฒดํฌ๋ฐ•์Šค. Radix Checkbox ๊ธฐ๋ฐ˜ โ€” Space ํ† ๊ธ€ยทaria-checkedยทํผ ์ฐธ์—ฌ ์ž๋™.\n * ๋ผ๋ฒจ์„ ์ง€์ •ํ•˜๋ฉด ๋ผ๋ฒจ ํด๋ฆญ์œผ๋กœ๋„ ํ† ๊ธ€๋œ๋‹ค.\n *\n * @example\n * <Checkbox label=\"์ด์šฉ์•ฝ๊ด€์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค\" checked={agreed} onCheckedChange={setAgreed} />\n *\n * @example ๋ถ€๋ถ„ ์„ ํƒ (์ „์ฒด์„ ํƒ ํ—ค๋” ๋“ฑ)\n * <Checkbox label=\"์ „์ฒด ์„ ํƒ\" checked={someChecked ? 'indeterminate' : allChecked} โ€ฆ />\n */\nexport const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(function Checkbox(\n { label, size = 'md', disabled = false, id: idProp, className, checked, ...rest },\n ref,\n) {\n const reactId = useId();\n const id = idProp ?? `nuri-checkbox-${reactId}`;\n\n return (\n <div className={cx('nuri-checkbox', `nuri-checkbox--${size}`, className)}>\n <RadixCheckbox.Root\n ref={ref}\n id={id}\n className=\"nuri-checkbox__control\"\n disabled={disabled}\n checked={checked}\n {...rest}\n >\n <RadixCheckbox.Indicator className=\"nuri-checkbox__indicator\">\n {checked === 'indeterminate' ? <IndeterminateIcon /> : <CheckIcon />}\n </RadixCheckbox.Indicator>\n </RadixCheckbox.Root>\n {label != null && (\n <label htmlFor={id} className=\"nuri-checkbox__label\">\n {label}\n </label>\n )}\n </div>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport * as RadixRadioGroup from '@radix-ui/react-radio-group';\nimport { forwardRef, useId } from 'react';\nimport type { ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\nexport interface RadioGroupProps {\n children: ReactNode;\n /** ์„ ํƒ๋œ ๊ฐ’ (์ œ์–ดํ˜•). */\n value?: string;\n /** ์ดˆ๊ธฐ ๊ฐ’ (๋น„์ œ์–ดํ˜•). */\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** ๋ฐฐ์น˜ ๋ฐฉํ–ฅ โ€” ํ‚ค๋ณด๋“œ ํ™”์‚ดํ‘œ ํƒ์ƒ‰ ๋ฐฉํ–ฅ์—๋„ ๋ฐ˜์˜๋จ. @default 'vertical' */\n orientation?: 'vertical' | 'horizontal';\n disabled?: boolean;\n /** ํผ ์ „์†ก์šฉ name. */\n name?: string;\n required?: boolean;\n className?: string;\n /** ๊ทธ๋ฃน์˜ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„ (์‹œ๊ฐ ์ œ๋ชฉ์ด ์—†์„ ๋•Œ ํ•„์ˆ˜). */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * ๋ผ๋””์˜ค ๊ทธ๋ฃน. Radix RadioGroup ๊ธฐ๋ฐ˜ โ€” ํ™”์‚ดํ‘œ ํ‚ค ๊ทธ๋ฃน ํƒ์ƒ‰ยท๋‹จ์ผ ์„ ํƒยทํผ ์ฐธ์—ฌ ์ž๋™.\n * ๊ทธ๋ฃน์— `aria-label`(๋˜๋Š” aria-labelledby)์„ ์ง€์ •ํ•œ๋‹ค.\n *\n * @example\n * <RadioGroup aria-label=\"์ •๋ ฌ\" value={sort} onValueChange={setSort}>\n * <Radio value=\"latest\" label=\"์ตœ์‹ ์ˆœ\" />\n * <Radio value=\"edited\" label=\"์ˆ˜์ •์ˆœ\" />\n * </RadioGroup>\n */\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n { children, orientation = 'vertical', className, ...rest },\n ref,\n) {\n return (\n <RadixRadioGroup.Root\n ref={ref}\n orientation={orientation}\n className={cx('nuri-radio-group', `nuri-radio-group--${orientation}`, className)}\n {...rest}\n >\n {children}\n </RadixRadioGroup.Root>\n );\n});\n\nexport interface RadioProps {\n /** ์ด ํ•ญ๋ชฉ์ด ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’. */\n value: string;\n /** ๋ผ๋ฒจ (์ปจํŠธ๋กค ์šฐ์ธก). ์—†์œผ๋ฉด `aria-label` ํ•„์ˆ˜. */\n label?: ReactNode;\n disabled?: boolean;\n id?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** ๋ผ๋””์˜ค ํ•ญ๋ชฉ โ€” ๋ฐ˜๋“œ์‹œ RadioGroup ์•ˆ์—์„œ ์‚ฌ์šฉ. */\nexport const Radio = forwardRef<HTMLButtonElement, RadioProps>(function Radio(\n { value, label, disabled = false, id: idProp, className, ...rest },\n ref,\n) {\n const reactId = useId();\n const id = idProp ?? `nuri-radio-${reactId}`;\n\n return (\n <div className={cx('nuri-radio', className)}>\n <RadixRadioGroup.Item\n ref={ref}\n id={id}\n value={value}\n disabled={disabled}\n className=\"nuri-radio__control\"\n {...rest}\n >\n <RadixRadioGroup.Indicator className=\"nuri-radio__indicator\" />\n </RadixRadioGroup.Item>\n {label != null && (\n <label htmlFor={id} className=\"nuri-radio__label\">\n {label}\n </label>\n )}\n </div>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport * as RadixSwitch from '@radix-ui/react-switch';\nimport { forwardRef, useId } from 'react';\nimport type { ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\nexport interface SwitchProps {\n /**\n * ๋ผ๋ฒจ (์ปจํŠธ๋กค ์šฐ์ธก). ๋””์ž์ธ ์‹œ์Šคํ…œ์˜ Toggle์€ ์ปจํŠธ๋กค ๋‹จ๋… ์ •์˜์ง€๋งŒ,\n * ๋ฒ”์šฉ ์‚ฌ์šฉ์„ ์œ„ํ•ด ๋ผ๋ฒจ์„ ์ง€์›ํ•œ๋‹ค(Checkbox ๋ผ๋ฒจ ์Šคํƒ€์ผ ์ค€์šฉ). ์—†์œผ๋ฉด `aria-label` ํ•„์ˆ˜.\n */\n label?: ReactNode;\n /** ์ผœ์ง ์ƒํƒœ (์ œ์–ดํ˜•). */\n checked?: boolean;\n /** ์ดˆ๊ธฐ ์ƒํƒœ (๋น„์ œ์–ดํ˜•). */\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n /** ํผ ์ „์†ก์šฉ name. */\n name?: string;\n /** ํผ ์ „์†ก ์‹œ ๊ฐ’. @default 'on' */\n value?: string;\n required?: boolean;\n id?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\n/**\n * ์Šค์œ„์น˜(ํ† ๊ธ€). Radix Switch ๊ธฐ๋ฐ˜ โ€” `role=\"switch\"`ยทSpace/Enter ํ† ๊ธ€ยทํผ ์ฐธ์—ฌ ์ž๋™.\n * ์ฆ‰์‹œ ์ ์šฉ๋˜๋Š” ์ผฌ/๋” ์„ค์ •์— ์‚ฌ์šฉํ•œ๋‹ค (์ œ์ถœ์ด ํ•„์š”ํ•œ ์„ ํƒ์€ Checkbox).\n *\n * @example\n * <Switch label=\"์•Œ๋ฆผ ๋ฐ›๊ธฐ\" checked={on} onCheckedChange={setOn} />\n */\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(function Switch(\n { label, disabled = false, id: idProp, className, ...rest },\n ref,\n) {\n const reactId = useId();\n const id = idProp ?? `nuri-switch-${reactId}`;\n\n return (\n <div className={cx('nuri-switch', className)}>\n <RadixSwitch.Root\n ref={ref}\n id={id}\n className=\"nuri-switch__control\"\n disabled={disabled}\n {...rest}\n >\n <RadixSwitch.Thumb className=\"nuri-switch__thumb\" />\n </RadixSwitch.Root>\n {label != null && (\n <label htmlFor={id} className=\"nuri-switch__label\">\n {label}\n </label>\n )}\n </div>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport * as RadixSelect from '@radix-ui/react-select';\nimport { forwardRef } from 'react';\nimport type { ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\ntype Size = 'sm' | 'md';\n\nexport interface SelectOption {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n /** ์„ ํƒ์ง€ ๋ชฉ๋ก. */\n options: SelectOption[];\n /**\n * ์‚ฌ์ด์ฆˆ. sm 36 / md 42 px ๋†’์ด (๋””์ž์ธ ์‹œ์Šคํ…œ์˜ Small/Large).\n * @default 'md'\n */\n size?: Size;\n /** ๊ฐ’์ด ์—†์„ ๋•Œ ํŠธ๋ฆฌ๊ฑฐ์— ํ‘œ์‹œํ•  ๋ฌธ๊ตฌ. */\n placeholder?: ReactNode;\n /** ์„ ํƒ๋œ ๊ฐ’ (์ œ์–ดํ˜•). */\n value?: string;\n /** ์ดˆ๊ธฐ ๊ฐ’ (๋น„์ œ์–ดํ˜•). */\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** ์—ด๋ฆผ ์ƒํƒœ ์ œ์–ด (์„ ํƒ). */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n /** ์ปจํ…Œ์ด๋„ˆ ์ „์ฒด ๋„ˆ๋น„๋กœ ํ™•์žฅ. @default false */\n block?: boolean;\n /** ํผ ์ „์†ก์šฉ name โ€” ๋„ค์ดํ‹ฐ๋ธŒ select์ฒ˜๋Ÿผ ํผ์— ์ฐธ์—ฌ. */\n name?: string;\n required?: boolean;\n /** ํฌํ„ธ ๋ Œ๋” ๋Œ€์ƒ. ๊ธฐ๋ณธ document.body. */\n container?: HTMLElement | null;\n /** ํŠธ๋ฆฌ๊ฑฐ์— ์ถ”๊ฐ€ํ•  className. */\n className?: string;\n /** ์‹œ๊ฐ ๋ผ๋ฒจ์ด ์—†์„ ๋•Œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„. */\n 'aria-label'?: string;\n}\n\n/** ๋””์ž์ธ ์‹œ์Šคํ…œ์˜ 8px ์‚ผ๊ฐ ์บ๋Ÿฟ (์—ด๋ฆผ ์‹œ CSS๋กœ ํšŒ์ „). */\nconst CaretIcon = () => (\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M1.1 2.5h5.8L4 5.9z\" fill=\"currentColor\" />\n </svg>\n);\n\n/**\n * ์…€๋ ‰ํŠธ ๋ฐ•์Šค (๋‹จ์ผ ์„ ํƒ). Radix Select ๊ธฐ๋ฐ˜ โ€” ํ‚ค๋ณด๋“œ ํƒ์ƒ‰ยทํƒ€์ž…์–ดํ—ค๋“œยท\n * ํฌ์ง€์…”๋‹ยทaria ์—ฐ๊ฒฐ์„ ์ž๋™ ์ œ๊ณต. ์˜ต์…˜ ๋ชฉ๋ก์€ `options` ๋ฐฐ์—ด๋กœ ์ „๋‹ฌํ•œ๋‹ค.\n *\n * ๋‹ค์ค‘ ์„ ํƒ(์ฒดํฌ๋ฐ•์Šค ์˜ต์…˜)ยท์„œ๋ธŒ๋ฉ”๋‰ด ๋ณ€ํ˜•์€ ๋ณ„๋„ ์ปดํฌ๋„ŒํŠธ(DropdownMenu) ๋ฒ”์œ„.\n *\n * @example\n * <Select\n * aria-label=\"์ •๋ ฌ\"\n * placeholder=\"์ •๋ ฌ ์„ ํƒ\"\n * options={[\n * { value: 'latest', label: '์ตœ์‹ ์ˆœ' },\n * { value: 'edited', label: '์ˆ˜์ •์ˆœ' },\n * ]}\n * onValueChange={setSort}\n * />\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n size = 'md',\n placeholder,\n value,\n defaultValue,\n onValueChange,\n open,\n defaultOpen,\n onOpenChange,\n disabled = false,\n block = false,\n name,\n required,\n container,\n className,\n 'aria-label': ariaLabel,\n },\n ref,\n) {\n return (\n <RadixSelect.Root\n value={value}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n disabled={disabled}\n name={name}\n required={required}\n >\n <RadixSelect.Trigger\n ref={ref}\n aria-label={ariaLabel}\n className={cx(\n 'nuri-select__trigger',\n `nuri-select__trigger--${size}`,\n block && 'nuri-select__trigger--block',\n className,\n )}\n >\n <span className=\"nuri-select__value\">\n <RadixSelect.Value placeholder={placeholder} />\n </span>\n <RadixSelect.Icon className=\"nuri-select__caret\">\n <CaretIcon />\n </RadixSelect.Icon>\n </RadixSelect.Trigger>\n\n <RadixSelect.Portal container={container}>\n <RadixSelect.Content className=\"nuri-select__content\" position=\"popper\" sideOffset={6}>\n <RadixSelect.Viewport className=\"nuri-select__viewport\">\n {options.map((option) => (\n <RadixSelect.Item\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n className=\"nuri-select__item\"\n >\n <RadixSelect.ItemText>{option.label}</RadixSelect.ItemText>\n </RadixSelect.Item>\n ))}\n </RadixSelect.Viewport>\n </RadixSelect.Content>\n </RadixSelect.Portal>\n </RadixSelect.Root>\n );\n});\n","'use client';\n\nimport './styles.css';\nimport * as Dialog from '@radix-ui/react-dialog';\nimport { forwardRef } from 'react';\nimport type { ComponentPropsWithoutRef, ElementRef, ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\ntype Placement = 'center' | 'bottom';\ntype Size = 'sm' | 'md' | 'lg';\n\n/**\n * ๋ชจ๋‹ฌ ๋ฃจํŠธ. open/onOpenChange๋กœ ์ œ์–ดํ•˜๊ฑฐ๋‚˜, Modal.Trigger์™€ ํ•จ๊ป˜ ๋น„์ œ์–ด๋กœ๋„ ์‚ฌ์šฉ.\n * Radix Dialog ๊ธฐ๋ฐ˜ โ€” ํฌ์ปค์Šค ํŠธ๋žฉยทEscยท์Šคํฌ๋กค ๋ฝยทํฌ์ปค์Šค ๋ณต๊ท€ยทaria ์—ฐ๊ฒฐ์„ ์ž๋™ ์ œ๊ณต.\n *\n * @example ์ œ์–ดํ˜•\n * <Modal open={open} onOpenChange={setOpen}>\n * <Modal.Content>...</Modal.Content>\n * </Modal>\n *\n * @example ๋น„์ œ์–ด (ํŠธ๋ฆฌ๊ฑฐ)\n * <Modal>\n * <Modal.Trigger asChild><Button>์—ด๊ธฐ</Button></Modal.Trigger>\n * <Modal.Content>...</Modal.Content>\n * </Modal>\n */\nconst Root = (props: ComponentPropsWithoutRef<typeof Dialog.Root>) => <Dialog.Root {...props} />;\nRoot.displayName = 'Modal';\n\n/** ๋ชจ๋‹ฌ์„ ์—ฌ๋Š” ํŠธ๋ฆฌ๊ฑฐ. `asChild`๋กœ ์ž„์˜ ์—˜๋ฆฌ๋จผํŠธ(Button ๋“ฑ)์— ์œ„์ž„. */\nconst Trigger = Dialog.Trigger;\n\nexport interface ModalContentProps extends ComponentPropsWithoutRef<typeof Dialog.Content> {\n /**\n * ํ‘œ์‹œ ์œ„์น˜.\n * - `center`: ํ™”๋ฉด ์ค‘์•™ ๋‹ค์ด์–ผ๋กœ๊ทธ (๊ธฐ๋ณธ)\n * - `bottom`: ํ•˜๋‹จ ๋ฐ”ํ…€์‹œํŠธ (๋ชจ๋ฐ”์ผ์—์„œ ์•„๋ž˜์—์„œ ์˜ฌ๋ผ์˜ด)\n * @default 'center'\n */\n placement?: Placement;\n /**\n * ์ตœ๋Œ€ ๋„ˆ๋น„. **`placement=\"center\"`์—์„œ๋งŒ ์ ์šฉ** (bottom ๋ฐ”ํ…€์‹œํŠธ๋Š” ํ•ญ์ƒ ํ’€ width).\n * @default 'md'\n */\n size?: Size;\n /** ๋ฐฑ๋“œ๋กญ(์˜ค๋ฒ„๋ ˆ์ด) ํ‘œ์‹œ ์—ฌ๋ถ€. @default true */\n overlay?: boolean;\n /** ํฌํ„ธ ๋ Œ๋” ๋Œ€์ƒ. ๊ธฐ๋ณธ์€ document.body. ๋‹ค๋ฅธ ์š”์†Œ์— ๋ Œ๋”ํ•˜๋ ค๋ฉด ์ง€์ •. */\n container?: HTMLElement | null;\n}\n\n/**\n * ์˜ค๋ฒ„๋ ˆ์ด + ํฌํ„ธ + ๋‹ค์ด์–ผ๋กœ๊ทธ ํŒจ๋„์„ ํ•œ ๋ฒˆ์— ๋ Œ๋”.\n * ๋‚ด๋ถ€์— Modal.Header / Modal.Body / Modal.Footer๋ฅผ ์ž์œ ๋กญ๊ฒŒ ํ•ฉ์„ฑ.\n */\nconst Content = forwardRef<ElementRef<typeof Dialog.Content>, ModalContentProps>(\n function ModalContent(\n { placement = 'center', size = 'md', overlay = true, container, className, children, ...rest },\n ref,\n ) {\n const classes = cx('nuri-modal', `nuri-modal--${placement}`, `nuri-modal--${size}`, className);\n\n return (\n <Dialog.Portal container={container}>\n {overlay && <Dialog.Overlay className=\"nuri-modal__overlay\" />}\n <Dialog.Content ref={ref} className={classes} {...rest}>\n {children}\n </Dialog.Content>\n </Dialog.Portal>\n );\n },\n);\n\n/** ํ—ค๋” ์˜์—ญ (Title/Description/CloseButton์„ ๋‹ด๋Š” ๋ ˆ์ด์•„์›ƒ ์Šฌ๋กฏ). */\nconst Header = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(function ModalHeader(\n { className, ...rest },\n ref,\n) {\n return <div ref={ref} className={cx('nuri-modal__header', className)} {...rest} />;\n});\n\nexport interface ModalTitleProps extends ComponentPropsWithoutRef<typeof Dialog.Title> {\n /**\n * ์‹œ๊ฐ์ ์œผ๋กœ๋Š” ์ˆจ๊ธฐ๋˜ ์Šคํฌ๋ฆฐ๋ฆฌ๋”์—๋Š” ๋…ธ์ถœ. ์‹œ๊ฐ์  ์ œ๋ชฉ์ด ์—†๋Š” ๋ชจ๋‹ฌ๋„\n * ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•˜๋ฏ€๋กœ(Radix Dialog๋Š” Title ํ•„์ˆ˜), ์ด ์˜ต์…˜์œผ๋กœ ์ฒ˜๋ฆฌ.\n * @example <Modal.Title visuallyHidden>์ด๋ฏธ์ง€ ๋ฏธ๋ฆฌ๋ณด๊ธฐ</Modal.Title>\n */\n visuallyHidden?: boolean;\n}\n\n/** ๋ชจ๋‹ฌ ์ œ๋ชฉ. ๋ Œ๋” ์‹œ ์ž๋™์œผ๋กœ `aria-labelledby`๋กœ ์—ฐ๊ฒฐ๋จ (Radix Dialog.Title). */\nconst Title = forwardRef<ElementRef<typeof Dialog.Title>, ModalTitleProps>(function ModalTitle(\n { visuallyHidden = false, className, ...rest },\n ref,\n) {\n return (\n <Dialog.Title\n ref={ref}\n className={cx('nuri-modal__title', visuallyHidden && 'nuri-sr-only', className)}\n {...rest}\n />\n );\n});\n\n/** ๋ชจ๋‹ฌ ์„ค๋ช…. ๋ Œ๋” ์‹œ ์ž๋™์œผ๋กœ `aria-describedby`๋กœ ์—ฐ๊ฒฐ๋จ (Radix Dialog.Description). */\nconst Description = forwardRef<\n ElementRef<typeof Dialog.Description>,\n ComponentPropsWithoutRef<typeof Dialog.Description>\n>(function ModalDescription({ className, ...rest }, ref) {\n return (\n <Dialog.Description ref={ref} className={cx('nuri-modal__description', className)} {...rest} />\n );\n});\n\n/** ๋ณธ๋ฌธ ์˜์—ญ (์Šคํฌ๋กค ๊ฐ€๋Šฅ). */\nconst Body = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(function ModalBody(\n { className, ...rest },\n ref,\n) {\n return <div ref={ref} className={cx('nuri-modal__body', className)} {...rest} />;\n});\n\nexport interface ModalFooterProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * ์•ก์…˜ ๋ฒ„ํŠผ ์ •๋ ฌ.\n * - `end`: ์šฐ์ธก (๊ธฐ๋ณธ, ๋ฐ์Šคํฌํƒ‘ ๊ด€๋ก€)\n * - `start`: ์ขŒ์ธก\n * - `center`: ๊ฐ€์šด๋ฐ\n * - `between`: ์–‘๋ ๋ถ„์‚ฐ (์˜ˆ: ์ขŒ์ธก ์œ„ํ—˜ ์•ก์…˜ + ์šฐ์ธก ํ™•์ธ)\n * - `full`: ๋ฒ„ํŠผ๋“ค์ด ๊ฐ€๋กœ๋ฅผ ๊ท ๋“ฑํ•˜๊ฒŒ ์ฑ„์›€ (๋ชจ๋ฐ”์ผ ์ „์ฒด๋„ˆ๋น„)\n * @default 'end'\n */\n align?: 'start' | 'center' | 'end' | 'between' | 'full';\n}\n\n/** ํ‘ธํ„ฐ ์˜์—ญ (์•ก์…˜ ๋ฒ„ํŠผ ๋ฐฐ์น˜). ์ •๋ ฌ์€ `align` prop์œผ๋กœ ์ œ์–ด. */\nconst Footer = forwardRef<HTMLDivElement, ModalFooterProps>(function ModalFooter(\n { align = 'end', className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={cx('nuri-modal__footer', `nuri-modal__footer--${align}`, className)}\n {...rest}\n />\n );\n});\n\n/**\n * ๋ชจ๋‹ฌ์„ ๋‹ซ๋Š” ์•ก์…˜. `asChild`๋กœ ์ž„์˜ ์—˜๋ฆฌ๋จผํŠธ์— ์œ„์ž„.\n * @example <Modal.Close asChild><Button variant=\"outline\">์ทจ์†Œ</Button></Modal.Close>\n */\nconst Close = Dialog.Close;\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\n/** ์šฐ์ƒ๋‹จ X ๋‹ซ๊ธฐ ๋ฒ„ํŠผ (๋ฏธ๋ฆฌ ์Šคํƒ€์ผ๋ง๋จ). ๊ธฐ๋ณธ `aria-label=\"๋‹ซ๊ธฐ\"`. */\nconst CloseButton = forwardRef<\n HTMLButtonElement,\n Omit<ComponentPropsWithoutRef<'button'>, 'children'> & { children?: ReactNode }\n>(function ModalCloseButton(\n { className, 'aria-label': ariaLabel = '๋‹ซ๊ธฐ', children, ...rest },\n ref,\n) {\n return (\n <Dialog.Close asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={ariaLabel}\n className={cx('nuri-modal__close', className)}\n {...rest}\n >\n {children ?? <CloseIcon />}\n </button>\n </Dialog.Close>\n );\n});\n\nexport const Modal = Object.assign(Root, {\n Trigger,\n Content,\n Header,\n Title,\n Description,\n Body,\n Footer,\n Close,\n CloseButton,\n});\n","'use client';\n\nimport './styles.css';\nimport * as Alert from '@radix-ui/react-alert-dialog';\nimport { forwardRef } from 'react';\nimport type { ComponentPropsWithoutRef, ElementRef, ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\nimport { defaultToneIcon } from './icons.js';\n\ntype Tone = 'info' | 'success' | 'warning';\n\n/**\n * ํ™•์ธ ๊ฐ•์ œํ˜• ๋‹ค์ด์–ผ๋กœ๊ทธ (alertdialog). Radix AlertDialog ๊ธฐ๋ฐ˜.\n *\n * ์ผ๋ฐ˜ Modal๊ณผ์˜ ์ฐจ์ด:\n * - `role=\"alertdialog\"` โ€” ์Šคํฌ๋ฆฐ๋ฆฌ๋”๊ฐ€ ๋” ๊ฐ•ํ•˜๊ฒŒ ์•ˆ๋‚ด\n * - **๋ฐ”๊นฅ(๋ฐฑ๋“œ๋กญ) ํด๋ฆญ์œผ๋กœ ๋‹ซํžˆ์ง€ ์•Š์Œ** โ€” ์‹ค์ˆ˜๋กœ ๋‹ซํžˆ๋Š” ๊ฒƒ ๋ฐฉ์ง€\n * - ํฌ์ปค์Šค๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ Cancel(์ทจ์†Œ)์— ์œ„์น˜ โ€” ์‹ค์ˆ˜๋กœ ์œ„ํ—˜ ์•ก์…˜ ๋ฐฉ์ง€\n * - **์ค‘์•™ ์ •๋ ฌ + ์ƒ๋‹จ ์•„์ด์ฝ˜** (๋””์ž์ธ ์‹œ์Šคํ…œ ํ‘œ์ค€ ๋ ˆ์ด์•„์›ƒ)\n *\n * Esc ํ‚ค๋Š” ๋‹ซํž˜(ํ‚ค๋ณด๋“œ ํƒˆ์ถœ๊ตฌ โ€” ์ ‘๊ทผ์„ฑ). ๋ง‰์œผ๋ ค๋ฉด Content์— `onEscapeKeyDown` ์ „๋‹ฌ.\n *\n * @example\n * <AlertDialog>\n * <AlertDialog.Trigger asChild><Button>์‚ญ์ œ</Button></AlertDialog.Trigger>\n * <AlertDialog.Content tone=\"warning\">\n * <AlertDialog.Header>\n * <AlertDialog.Title>์ •๋ง ์‚ญ์ œํ• ๊นŒ์š”?</AlertDialog.Title>\n * <AlertDialog.Description>๋˜๋Œ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.</AlertDialog.Description>\n * </AlertDialog.Header>\n * <AlertDialog.Footer>\n * <AlertDialog.Cancel asChild><Button variant=\"outline\">์ทจ์†Œ</Button></AlertDialog.Cancel>\n * <AlertDialog.Action asChild><Button onClick={onDelete}>์‚ญ์ œ</Button></AlertDialog.Action>\n * </AlertDialog.Footer>\n * </AlertDialog.Content>\n * </AlertDialog>\n */\nconst Root = (props: ComponentPropsWithoutRef<typeof Alert.Root>) => <Alert.Root {...props} />;\nRoot.displayName = 'AlertDialog';\n\n/** ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ์—ฌ๋Š” ํŠธ๋ฆฌ๊ฑฐ. `asChild`๋กœ ์ž„์˜ ์—˜๋ฆฌ๋จผํŠธ์— ์œ„์ž„. */\nconst Trigger = Alert.Trigger;\n\nexport interface AlertDialogContentProps extends ComponentPropsWithoutRef<typeof Alert.Content> {\n /**\n * ์ƒํƒœ ํ†ค โ€” ๊ธฐ๋ณธ ์•„์ด์ฝ˜๊ณผ ๊ทธ ์ƒ‰์„ ๊ฒฐ์ •.\n * @default 'info'\n */\n tone?: Tone;\n /**\n * ์ƒ๋‹จ ์•„์ด์ฝ˜.\n * - ๋ฏธ์ง€์ •: `tone`์— ๋งž๋Š” **๊ธฐ๋ณธ ์•„์ด์ฝ˜** ์ž๋™ ๋ Œ๋”\n * - `ReactNode`: ์ปค์Šคํ…€ ์•„์ด์ฝ˜์œผ๋กœ ๊ต์ฒด\n * - `null`: ์•„์ด์ฝ˜ ์ œ๊ฑฐ\n */\n icon?: ReactNode | null;\n /** ๋ฐฑ๋“œ๋กญ(์˜ค๋ฒ„๋ ˆ์ด) ํ‘œ์‹œ ์—ฌ๋ถ€. @default true */\n overlay?: boolean;\n /** ํฌํ„ธ ๋ Œ๋” ๋Œ€์ƒ. ๊ธฐ๋ณธ์€ document.body. ๋‹ค๋ฅธ ์š”์†Œ์— ๋ Œ๋”ํ•˜๋ ค๋ฉด ์ง€์ •. */\n container?: HTMLElement | null;\n}\n\n/** ์˜ค๋ฒ„๋ ˆ์ด + ํฌํ„ธ + ํŒจ๋„์„ ํ•œ ๋ฒˆ์— ๋ Œ๋”. ์ค‘์•™ ์ •๋ ฌ + ์ƒ๋‹จ ์•„์ด์ฝ˜ ๋ ˆ์ด์•„์›ƒ. */\nconst Content = forwardRef<ElementRef<typeof Alert.Content>, AlertDialogContentProps>(\n function AlertDialogContent(\n { tone = 'info', icon, overlay = true, container, className, children, ...rest },\n ref,\n ) {\n // icon ๋ฏธ์ง€์ •(undefined) โ†’ ๊ธฐ๋ณธ tone ์•„์ด์ฝ˜ / null โ†’ ์ œ๊ฑฐ / ReactNode โ†’ ๊ต์ฒด\n const resolvedIcon = icon === undefined ? defaultToneIcon[tone] : icon;\n return (\n <Alert.Portal container={container}>\n {overlay && <Alert.Overlay className=\"nuri-alert__overlay\" />}\n <Alert.Content\n ref={ref}\n className={cx('nuri-alert', `nuri-alert--${tone}`, className)}\n {...rest}\n >\n {resolvedIcon != null && (\n <div className=\"nuri-alert__icon\" aria-hidden=\"true\">\n {resolvedIcon}\n </div>\n )}\n {children}\n </Alert.Content>\n </Alert.Portal>\n );\n },\n);\n\n/** ํ—ค๋” ์Šฌ๋กฏ (Title/Description ๋ฌถ์Œ, ์ค‘์•™ ์ •๋ ฌ). */\nconst Header = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(\n function AlertDialogHeader({ className, ...rest }, ref) {\n return <div ref={ref} className={cx('nuri-alert__header', className)} {...rest} />;\n },\n);\n\n/** ์ œ๋ชฉ. ์ž๋™์œผ๋กœ `aria-labelledby`๋กœ ์—ฐ๊ฒฐ๋จ. */\nconst Title = forwardRef<\n ElementRef<typeof Alert.Title>,\n ComponentPropsWithoutRef<typeof Alert.Title>\n>(function AlertDialogTitle({ className, ...rest }, ref) {\n return <Alert.Title ref={ref} className={cx('nuri-alert__title', className)} {...rest} />;\n});\n\n/** ์„ค๋ช…. ์ž๋™์œผ๋กœ `aria-describedby`๋กœ ์—ฐ๊ฒฐ๋จ. */\nconst Description = forwardRef<\n ElementRef<typeof Alert.Description>,\n ComponentPropsWithoutRef<typeof Alert.Description>\n>(function AlertDialogDescription({ className, ...rest }, ref) {\n return (\n <Alert.Description ref={ref} className={cx('nuri-alert__description', className)} {...rest} />\n );\n});\n\n/** ๋ณธ๋ฌธ ์Šฌ๋กฏ (์ถ”๊ฐ€ ์ฝ˜ํ…์ธ ). */\nconst Body = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'>>(function AlertDialogBody(\n { className, ...rest },\n ref,\n) {\n return <div ref={ref} className={cx('nuri-alert__body', className)} {...rest} />;\n});\n\nexport interface AlertDialogFooterProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * ๋ฒ„ํŠผ ์ •๋ ฌ. ๋””์ž์ธ ํ‘œ์ค€์€ ์ „์ฒด๋„ˆ๋น„ ๋ฒ„ํŠผ์ด๋ผ ๊ธฐ๋ณธ๊ฐ’ `full`.\n * @default 'full'\n */\n align?: 'start' | 'center' | 'end' | 'between' | 'full';\n}\n\n/** ํ‘ธํ„ฐ ์Šฌ๋กฏ (Cancel/Action ๋ฐฐ์น˜). ๊ธฐ๋ณธ ์ „์ฒด๋„ˆ๋น„(`full`). */\nconst Footer = forwardRef<HTMLDivElement, AlertDialogFooterProps>(function AlertDialogFooter(\n { align = 'full', className, ...rest },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={cx('nuri-alert__footer', `nuri-alert__footer--${align}`, className)}\n {...rest}\n />\n );\n});\n\n/**\n * ํ™•์ธ(์ฃผ ์•ก์…˜) ๋ฒ„ํŠผ. ํด๋ฆญ ์‹œ ๋‹ซํž˜. `asChild`๋กœ Button ์œ„์ž„.\n * @example <AlertDialog.Action asChild><Button onClick={onConfirm}>์‚ญ์ œ</Button></AlertDialog.Action>\n */\nconst Action = Alert.Action;\n\n/**\n * ์ทจ์†Œ ๋ฒ„ํŠผ. ํด๋ฆญ ์‹œ ๋‹ซํž˜. ํฌ์ปค์Šค๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์—ฌ๊ธฐ ์œ„์น˜.\n * @example <AlertDialog.Cancel asChild><Button variant=\"outline\">์ทจ์†Œ</Button></AlertDialog.Cancel>\n */\nconst Cancel = Alert.Cancel;\n\nconst CloseIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M5 5l10 10M15 5L5 15\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n);\n\n/**\n * ์šฐ์ƒ๋‹จ X ๋‹ซ๊ธฐ ๋ฒ„ํŠผ (์˜ต์…˜). ๋‚ด๋ถ€์ ์œผ๋กœ Cancel๊ณผ ๋™์ผํ•˜๊ฒŒ ๋‹ซํž˜. ๊ธฐ๋ณธ `aria-label=\"๋‹ซ๊ธฐ\"`.\n * ํ™•์ธ์„ ๊ฐ•์ œํ•˜๋ ค๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŽธ์ด ์ข‹์Šต๋‹ˆ๋‹ค (Cancel/Action์œผ๋กœ ๋ช…์‹œ์  ์„ ํƒ ์œ ๋„).\n */\nconst CloseButton = forwardRef<\n HTMLButtonElement,\n Omit<ComponentPropsWithoutRef<'button'>, 'children'> & { children?: ReactNode }\n>(function AlertDialogCloseButton(\n { className, 'aria-label': ariaLabel = '๋‹ซ๊ธฐ', children, ...rest },\n ref,\n) {\n return (\n <Alert.Cancel asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={ariaLabel}\n className={cx('nuri-alert__close', className)}\n {...rest}\n >\n {children ?? <CloseIcon />}\n </button>\n </Alert.Cancel>\n );\n});\n\nexport const AlertDialog = Object.assign(Root, {\n Trigger,\n Content,\n Header,\n Title,\n Description,\n Body,\n Footer,\n Action,\n Cancel,\n CloseButton,\n});\n","/**\n * tone๋ณ„ ๊ธฐ๋ณธ ์•„์ด์ฝ˜ โ€” ๋””์ž์ด๋„ˆ ์‹œ์Šคํ…œ(Figma) ์—์…‹์„ ๊ทธ๋Œ€๋กœ inline SVG๋กœ ์žฌํ˜„.\n * ๊ตฌ์กฐ: ํ‹ดํŠธ ์› ๋ฐฐ๊ฒฝ + tone ์ƒ‰ ์‹ฌ๋ณผ. ์ƒ‰์€ ํ† ํฐ(`--nuri-alert-tone-*`)์œผ๋กœ ๋ถ„๋ฆฌ.\n * AlertDialog.Content์˜ `icon` ๋ฏธ์ง€์ • ์‹œ tone์— ๋งž์ถฐ ์ž๋™ ๋ Œ๋”.\n * `icon={<Custom/>}`๋กœ ๊ต์ฒด, `icon={null}`๋กœ ์ œ๊ฑฐ ๊ฐ€๋Šฅ.\n */\nimport type { ReactNode } from 'react';\n\nconst SuccessIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"var(--nuri-alert-tone-success-bg)\" />\n <path\n d=\"M15.77 9.58L10.65 14.70L8.90 12.95\"\n stroke=\"var(--nuri-alert-tone-success-fg)\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst WarningIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"var(--nuri-alert-tone-warning-bg)\" />\n <path\n d=\"M12 6.75V12\"\n stroke=\"var(--nuri-alert-tone-warning-fg)\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"12\" cy=\"16.31\" r=\"1.1\" fill=\"var(--nuri-alert-tone-warning-fg)\" />\n </svg>\n);\n\nconst InfoIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"var(--nuri-alert-tone-info-bg)\" />\n <path\n d=\"M12.25 7h0.01\"\n stroke=\"var(--nuri-alert-tone-info-fg)\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M11 12h1.25v5h1.25\"\n stroke=\"var(--nuri-alert-tone-info-fg)\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const defaultToneIcon: Record<'info' | 'success' | 'warning', ReactNode> = {\n info: <InfoIcon />,\n success: <SuccessIcon />,\n warning: <WarningIcon />,\n};\n","'use client';\n\nimport './styles.css';\nimport * as RadixToast from '@radix-ui/react-toast';\nimport { cx } from '../utils/cx.js';\nimport { toastStore, useToasts } from './store.js';\nimport { toneIcon } from './icons.js';\n\nexport interface ToasterProps {\n /**\n * ์Šค์™€์ดํ”„๋กœ ๋‹ซ๋Š” ๋ฐฉํ–ฅ. ํ•˜๋‹จ ํ‘œ์‹œ๋ผ ๊ธฐ๋ณธ `down`(์•„๋ž˜๋กœ ๋ฐ€์–ด ๋‹ซ๊ธฐ โ€” ํ„ฐ์น˜ยท๋“œ๋ž˜๊ทธ ๋ชจ๋‘).\n * @default 'down'\n */\n swipeDirection?: RadixToast.ToastProviderProps['swipeDirection'];\n /** ์Šค์™€์ดํ”„ ์ž„๊ณ„ ๊ฑฐ๋ฆฌ(px). @default 50 */\n swipeThreshold?: number;\n /** ๋ทฐํฌํŠธ์— ์ถ”๊ฐ€ํ•  className (์œ„์น˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ ๋“ฑ). */\n className?: string;\n /** ์Šคํฌ๋ฆฐ๋ฆฌ๋”์šฉ ์ง€์—ญ ๋ผ๋ฒจ. @default '์•Œ๋ฆผ' */\n label?: string;\n}\n\n/**\n * ํ† ์ŠคํŠธ ๋ Œ๋”๋Ÿฌ. **์•ฑ ๋ฃจํŠธ์— 1ํšŒ๋งŒ** ๋งˆ์šดํŠธํ•˜๋ฉด ๋˜๊ณ , ํ‘œ์‹œ๋Š” `toast()` ํ˜ธ์ถœ๋กœ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.\n * (์‚ฌ์šฉ์ฒ˜๋งˆ๋‹ค ๋ Œ๋”ํ•  ํ•„์š” ์—†์Œ โ€” ๋ชจ๋“ˆ store๋ฅผ ๊ตฌ๋…ํ•ด ์ด ์ปดํฌ๋„ŒํŠธ๋งŒ ๋ Œ๋”)\n *\n * Radix Toast ๊ธฐ๋ฐ˜์ด๋ผ ์ž๋™ ๋‹ซํž˜ ํƒ€์ด๋จธยทhover ์‹œ ์ผ์‹œ์ •์ง€ยท์Šค์™€์ดํ”„ ๋‹ซ๊ธฐยท\n * ์Šคํฌ๋ฆฐ๋ฆฌ๋” announce(aria-live)๋ฅผ ํ‘œ์ค€์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.\n *\n * @example\n * // app/layout.tsx\n * <body>{children}<Toaster /></body>\n */\nexport function Toaster({\n swipeDirection = 'down',\n swipeThreshold = 50,\n className,\n label = '์•Œ๋ฆผ',\n}: ToasterProps) {\n const toasts = useToasts();\n\n return (\n <RadixToast.Provider\n swipeDirection={swipeDirection}\n swipeThreshold={swipeThreshold}\n label={label}\n >\n {toasts.map((t) => (\n <RadixToast.Root\n key={t.id}\n duration={t.duration}\n onOpenChange={(open) => {\n if (!open) toastStore.remove(t.id);\n }}\n // error๋Š” foreground(assertive)๋กœ ์ฆ‰์‹œ ์•ˆ๋‚ด, ๊ทธ ์™ธ๋Š” background(polite)\n type={t.tone === 'error' ? 'foreground' : 'background'}\n className={cx('nuri-toast', t.tone !== 'default' && `nuri-toast--${t.tone}`)}\n >\n {t.tone !== 'default' && (\n <span className=\"nuri-toast__icon\" aria-hidden=\"true\">\n {toneIcon[t.tone]}\n </span>\n )}\n <RadixToast.Title className=\"nuri-toast__message\">{t.message}</RadixToast.Title>\n </RadixToast.Root>\n ))}\n {/* ๋žœ๋“œ๋งˆํฌ ์ด๋ฆ„ โ€” ์Šคํฌ๋ฆฐ๋ฆฌ๋” ์˜์—ญ ํƒ์ƒ‰์šฉ. {hotkey}๋Š” Radix๊ฐ€ ์‹ค์ œ ํ‚ค(F8)๋กœ ์น˜ํ™˜ */}\n <RadixToast.Viewport\n className={cx('nuri-toast__viewport', className)}\n label={`${label} ({hotkey})`}\n />\n </RadixToast.Provider>\n );\n}\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport type { ReactNode } from 'react';\n\nexport type ToastTone = 'default' | 'success' | 'error' | 'info';\n\nexport interface ToastOptions {\n /** ํ†ค โ€” ์•„์ด์ฝ˜ยท์ƒ‰ ๊ฒฐ์ •. @default 'default' (์•„์ด์ฝ˜ ์—†์Œ) */\n tone?: ToastTone;\n /** ์ž๋™ ๋‹ซํž˜๊นŒ์ง€ ms. @default 3000 */\n duration?: number;\n /** id ์ง์ ‘ ์ง€์ • (๊ฐ™์€ id๋ฉด ๊ต์ฒด โ€” ์ค‘๋ณต ๋ฐฉ์ง€ยท์ˆ˜๋™ dismiss์šฉ). */\n id?: string;\n}\n\nexport interface ToastRecord {\n id: string;\n message: ReactNode;\n tone: ToastTone;\n duration: number;\n}\n\n// โ”€โ”€ React ๋ฐ– ๋ชจ๋“ˆ ์‹ฑ๊ธ€ํ†ค store (์•„๋ฌด ๋ฐ์„œ๋‚˜ toast() ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ์ด์œ ) โ”€โ”€\nlet toasts: ToastRecord[] = [];\nconst listeners = new Set<() => void>();\nconst EMPTY: ToastRecord[] = []; // ์„œ๋ฒ„ ์Šค๋ƒ…์ƒท์šฉ ์•ˆ์ • ์ฐธ์กฐ\nlet counter = 0;\n\nconst emit = () => {\n for (const l of listeners) l();\n};\n\nfunction add(message: ReactNode, options: ToastOptions = {}): string {\n const id = options.id ?? `nuri-toast-${++counter}`;\n const record: ToastRecord = {\n id,\n message,\n tone: options.tone ?? 'default',\n duration: options.duration ?? 3000,\n };\n const idx = toasts.findIndex((t) => t.id === id);\n toasts = idx >= 0 ? toasts.map((t) => (t.id === id ? record : t)) : [...toasts, record];\n emit();\n return id;\n}\n\nfunction remove(id: string) {\n toasts = toasts.filter((t) => t.id !== id);\n emit();\n}\n\nfunction clear() {\n toasts = [];\n emit();\n}\n\nexport const toastStore = {\n add,\n remove,\n clear,\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot: () => toasts,\n getServerSnapshot: () => EMPTY,\n};\n\n/** ํ˜„์žฌ ํ† ์ŠคํŠธ ๋ชฉ๋ก์„ ๊ตฌ๋… (Toaster ๋‚ด๋ถ€ ์ „์šฉ). */\nexport function useToasts(): ToastRecord[] {\n return useSyncExternalStore(\n toastStore.subscribe,\n toastStore.getSnapshot,\n toastStore.getServerSnapshot,\n );\n}\n","import type { ReactNode } from 'react';\nimport type { ToastTone } from './store.js';\n\n// 16px, currentColor โ€” ์ƒ‰์€ .nuri-toast--{tone}์ด ํ†ค ํ† ํฐ์œผ๋กœ ์ง€์ •.\nconst CheckIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.5 8.5l3 3 6-6.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst ErrorIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 4v4.5\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"11.3\" r=\"0.95\" fill=\"currentColor\" />\n </svg>\n);\n\nconst InfoIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 7.5v4\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" />\n <circle cx=\"8\" cy=\"4.7\" r=\"0.95\" fill=\"currentColor\" />\n </svg>\n);\n\n/** default ํ†ค์€ ์•„์ด์ฝ˜ ์—†์Œ. */\nexport const toneIcon: Record<Exclude<ToastTone, 'default'>, ReactNode> = {\n success: <CheckIcon />,\n error: <ErrorIcon />,\n info: <InfoIcon />,\n};\n","import type { ReactNode } from 'react';\nimport { toastStore } from './store.js';\nimport type { ToastOptions } from './store.js';\n\ntype ToneOptions = Omit<ToastOptions, 'tone'>;\n\n/**\n * ํ† ์ŠคํŠธ๋ฅผ ๋„์šด๋‹ค. React ๋ฐ– ๋ชจ๋“ˆ ํ•จ์ˆ˜๋ผ ์ปดํฌ๋„ŒํŠธยท์ด๋ฒคํŠธ ํ•ธ๋“ค๋ŸฌยทAPI ๋ ˆ์ด์–ด ๋“ฑ\n * **์–ด๋””์„œ๋‚˜** ํ˜ธ์ถœ ๊ฐ€๋Šฅ. ํ™”๋ฉด ๋ Œ๋”๋Š” ์•ฑ ๋ฃจํŠธ์— 1ํšŒ ๋งˆ์šดํŠธํ•œ `<Toaster/>`๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค.\n *\n * @returns ํ† ์ŠคํŠธ id (์ˆ˜๋™ dismiss์— ์‚ฌ์šฉ)\n * @example\n * toast.success('์ €์žฅ๋์Šต๋‹ˆ๋‹ค');\n * const id = toast.error('์˜ค๋ฅ˜', { duration: 5000 });\n * toast.dismiss(id);\n */\nfunction toastFn(message: ReactNode, options?: ToastOptions): string {\n return toastStore.add(message, options);\n}\n\nexport const toast = Object.assign(toastFn, {\n success: (message: ReactNode, options?: ToneOptions) =>\n toastStore.add(message, { ...options, tone: 'success' }),\n error: (message: ReactNode, options?: ToneOptions) =>\n toastStore.add(message, { ...options, tone: 'error' }),\n info: (message: ReactNode, options?: ToneOptions) =>\n toastStore.add(message, { ...options, tone: 'info' }),\n /** id ์ง€์ • ์‹œ ํ•ด๋‹น ํ† ์ŠคํŠธ๋งŒ, ์—†์œผ๋ฉด ์ „์ฒด ์ œ๊ฑฐ. */\n dismiss: (id?: string) => (id ? toastStore.remove(id) : toastStore.clear()),\n});\n","'use client';\n\nimport './styles.css';\nimport * as RadixTooltip from '@radix-ui/react-tooltip';\nimport { createContext, useContext } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\ntype Align = 'start' | 'center' | 'end';\n\nexport interface TooltipProps {\n /** ํˆดํŒ ๋‚ด์šฉ. */\n content: ReactNode;\n /** ํŠธ๋ฆฌ๊ฑฐ โ€” ๋‹จ์ผ ์—˜๋ฆฌ๋จผํŠธ์— asChild๋กœ ์œ„์ž„ (Button, ์•„์ด์ฝ˜ ๋ฒ„ํŠผ ๋“ฑ). */\n children: ReactElement;\n /**\n * ํˆดํŒ์ด ๋œจ๋Š” ๋ฐฉํ–ฅ. (๋””์ž์ธ์˜ Direction์€ ๊ผฌ๋ฆฌ ๋ฐฉํ–ฅ ๊ธฐ์ค€์ด๋ผ ๋ฐ˜๋Œ€ โ€”\n * ์˜ˆ: ๋””์ž์ธ Direction=Bottom โ‡’ side=\"top\")\n * ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ฐ˜๋Œ€์ชฝ์œผ๋กœ ๋ฐ˜์ „๋œ๋‹ค.\n * @default 'top'\n */\n side?: Side;\n /** ํŠธ๋ฆฌ๊ฑฐ ๊ธฐ์ค€ ์ •๋ ฌ. @default 'center' */\n align?: Align;\n /** ๊ผฌ๋ฆฌ(ํ™”์‚ดํ‘œ) ํ‘œ์‹œ ์—ฌ๋ถ€ โ€” ๋””์ž์ธ์˜ showTail. @default true */\n arrow?: boolean;\n /**\n * ์—ด๋ฆผ ์ง€์—ฐ ms. ๋ฏธ์ง€์ • ์‹œ โ€” ๋‹จ๋… ์‚ฌ์šฉ์€ 100ms(๊ฑฐ์˜ ์ฆ‰์‹œ, ์Šค์ณ ์ง€๋‚˜๊ฐˆ ๋•Œ ๊นœ๋นก์ž„๋งŒ ๋ฐฉ์ง€),\n * TooltipProvider ์•ˆ์—์„œ๋Š” ํ”„๋กœ๋ฐ”์ด๋” ์„ค์ •์„ ๋”ฐ๋ฆ„. 0์ด๋ฉด ์ฆ‰์‹œ.\n * ํ‚ค๋ณด๋“œ ํฌ์ปค์Šค๋Š” ์ง€์—ฐ ์—†์ด ํ•ญ์ƒ ์ฆ‰์‹œ ํ‘œ์‹œ๋œ๋‹ค.\n */\n delayDuration?: number;\n /** ์—ด๋ฆผ ์ƒํƒœ ์ œ์–ด โ€” ํ•ญ์ƒ ํ‘œ์‹œ(์ฝ”์น˜๋งˆํฌ๋ฅ˜)๋‚˜ ์ˆ˜๋™ ์ œ์–ด์— ์‚ฌ์šฉ. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** true๋ฉด ํˆดํŒ ์—†์ด ํŠธ๋ฆฌ๊ฑฐ๋งŒ ๋ Œ๋” (์กฐ๊ฑด๋ถ€ ํˆดํŒ). @default false */\n disabled?: boolean;\n /** ํฌํ„ธ ๋ Œ๋” ๋Œ€์ƒ. ๊ธฐ๋ณธ document.body. */\n container?: HTMLElement | null;\n /** ํˆดํŒ ํŒจ๋„์— ์ถ”๊ฐ€ํ•  className. */\n className?: string;\n}\n\n// TooltipProvider ์กด์žฌ ๊ฐ์ง€์šฉ โ€” ์—†์œผ๋ฉด Tooltip์ด ์ž์ฒด Provider๋กœ ๊ฐ์‹ผ๋‹ค(์ œ๋กœ ์…‹์—…).\nconst HasProviderContext = createContext(false);\n\nexport type TooltipProviderProps = RadixTooltip.TooltipProviderProps;\n\n/**\n * ์ง€์—ฐ ์‹œ๊ฐ„์„ ๊ณต์œ ํ•˜๋Š” ํ”„๋กœ๋ฐ”์ด๋” (์„ ํƒ). ์•ฑ ๋ฃจํŠธ์— 1ํšŒ ๋‘๋ฉด ํˆดํŒ ํ•˜๋‚˜๋ฅผ ๋ณธ ์งํ›„\n * ์ธ์ ‘ ํŠธ๋ฆฌ๊ฑฐ๋กœ ์ด๋™ํ•  ๋•Œ ์ง€์—ฐ ์—†์ด ๋ฐ”๋กœ ํ‘œ์‹œ๋œ๋‹ค(skipDelayDuration).\n * ์—†์–ด๋„ Tooltip์€ ๋‹จ๋…์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.\n *\n * @example\n * <TooltipProvider delayDuration={300}><App /></TooltipProvider>\n */\nexport function TooltipProvider({ children, ...props }: TooltipProviderProps) {\n return (\n <HasProviderContext.Provider value={true}>\n <RadixTooltip.Provider {...props}>{children}</RadixTooltip.Provider>\n </HasProviderContext.Provider>\n );\n}\n\n/**\n * ํˆดํŒ. Radix Tooltip ๊ธฐ๋ฐ˜ โ€” hover์™€ **ํ‚ค๋ณด๋“œ ํฌ์ปค์Šค** ๋ชจ๋‘์—์„œ ์—ด๋ฆฌ๊ณ ,\n * Esc๋กœ ๋‹ซํžˆ๋ฉฐ, `aria-describedby`๊ฐ€ ์ž๋™ ์—ฐ๊ฒฐ๋œ๋‹ค. ํฌํ„ธ + ์ถฉ๋Œ ๊ฐ์ง€\n * ํฌ์ง€์…”๋‹์ด๋ผ ๋ถ€๋ชจ overflow์— ์ž˜๋ฆฌ์ง€ ์•Š๊ณ  ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€์ง€ ์•Š๋Š”๋‹ค.\n *\n * ํ„ฐ์น˜ ๊ธฐ๊ธฐ์—์„œ๋Š” ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค(hover ๊ฐœ๋… ๋ถ€์žฌ โ€” Radix ๊ธฐ๋ณธ ๋™์ž‘).\n * ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์ด ์žˆ๋Š” ์ง€์†ํ˜• ์•ˆ๋‚ด(์ฝ”์น˜๋งˆํฌ)๋Š” ํˆดํŒ ๋ฒ”์œ„๊ฐ€ ์•„๋‹ˆ๋‹ค.\n *\n * @example\n * <Tooltip content=\"์ฆ๊ฒจ์ฐพ๊ธฐ์— ์ถ”๊ฐ€\">\n * <Button iconOnly aria-label=\"์ฆ๊ฒจ์ฐพ๊ธฐ\">โ˜…</Button>\n * </Tooltip>\n */\nexport function Tooltip({\n content,\n children,\n side = 'top',\n align = 'center',\n arrow = true,\n delayDuration,\n open,\n defaultOpen,\n onOpenChange,\n disabled = false,\n container,\n className,\n}: TooltipProps) {\n const hasProvider = useContext(HasProviderContext);\n\n if (disabled) return children;\n\n const root = (\n <RadixTooltip.Root\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n delayDuration={delayDuration}\n >\n <RadixTooltip.Trigger asChild>{children}</RadixTooltip.Trigger>\n <RadixTooltip.Portal container={container}>\n <RadixTooltip.Content\n className={cx('nuri-tooltip', className)}\n side={side}\n align={align}\n sideOffset={4}\n collisionPadding={8}\n arrowPadding={6}\n // ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋ทฐํฌํŠธ/์Šคํฌ๋กค ์˜์—ญ์—์„œ ์™„์ „ํžˆ ์‚ฌ๋ผ์ง€๋ฉด ํˆดํŒ๋„ ์ˆจ๊น€\n // (๊ธฐ์ค€ ์š”์†Œ ์—†์ด ํˆดํŒ๋งŒ ๋–  ์žˆ๋Š” ํ˜„์ƒ ๋ฐฉ์ง€)\n hideWhenDetached\n >\n {content}\n {arrow && <RadixTooltip.Arrow className=\"nuri-tooltip__arrow\" width={14} height={7} />}\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n </RadixTooltip.Root>\n );\n\n // ์•ฑ์— TooltipProvider๊ฐ€ ์—†์–ด๋„ ๋™์ž‘ํ•˜๋„๋ก ์ž์ฒด Provider๋กœ ํด๋ฐฑ.\n // ์•ฑ Provider๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ์‹ธ์ง€ ์•Š๋Š”๋‹ค โ€” ์•ˆ์ชฝ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ด๊ธฐ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ๋˜ ๊ฐ์‹ธ๋ฉด\n // ์•ฑ์ด ์„ค์ •ํ•œ delayDurationยทskipDelayDuration์ด ๋ฌด์‹œ๋œ๋‹ค.\n // ํด๋ฐฑ ์ง€์—ฐ 100ms โ€” ๊ฑฐ์˜ ์ฆ‰์‹œ๋กœ ๋А๊ปด์ง€๋˜, ๋งˆ์šฐ์Šค๊ฐ€ ์Šค์ณ ์ง€๋‚˜๊ฐˆ ๋•Œ ์—ฐ์‡„ ๊นœ๋นก์ž„์€ ๋ฐฉ์ง€\n // (๋ฒ„ํŠผ ํ•˜๋‚˜๋ฅผ ๊ฐ€๋กœ์ง€๋ฅด๋Š” ๋ฐ ~30โ€“50ms โ€” ๊ทธ๋ณด๋‹ค ๊ธธ๊ฒŒ ๋จธ๋ฌธ ๊ฒฝ์šฐ๋งŒ ์˜๋„๋กœ ํŒ์ •).\n return hasProvider ? (\n root\n ) : (\n <RadixTooltip.Provider delayDuration={100}>{root}</RadixTooltip.Provider>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","Button","import_styles","import_react","import_jsx_runtime","Input","import_styles","import_react","import_jsx_runtime","Textarea","import_styles","import_react","import_jsx_runtime","Checkbox","import_styles","import_react","import_jsx_runtime","RadioGroup","Radio","import_styles","import_react","import_jsx_runtime","Switch","import_styles","import_react","import_jsx_runtime","Select","import_styles","import_react","import_jsx_runtime","Root","Trigger","Content","Title","Description","Close","import_styles","import_react","import_jsx_runtime","import_jsx_runtime","Root","Trigger","Content","Header","Title","Description","Body","Footer","Action","Cancel","CloseIcon","CloseButton","import_styles","import_react","import_jsx_runtime","CheckIcon","InfoIcon","import_jsx_runtime","toasts","import_styles","import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["/Users/summerhoony/Desktop/projects/nuri-ui/dist/index.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,ioBAAC","file":"/Users/summerhoony/Desktop/projects/nuri-ui/dist/index.cjs"}