@hjmds/design-contracts 1.1.0 → 1.2.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 (198) hide show
  1. package/dist/agreement.d.ts +183 -0
  2. package/dist/agreement.d.ts.map +1 -0
  3. package/dist/agreement.js +137 -0
  4. package/dist/agreement.js.map +1 -0
  5. package/dist/alert-dialog.d.ts +1 -1
  6. package/dist/alert-dialog.d.ts.map +1 -1
  7. package/dist/alert-dialog.js.map +1 -1
  8. package/dist/anchor.d.ts +62 -0
  9. package/dist/anchor.d.ts.map +1 -0
  10. package/dist/anchor.js +43 -0
  11. package/dist/anchor.js.map +1 -0
  12. package/dist/asset.d.ts +94 -0
  13. package/dist/asset.d.ts.map +1 -0
  14. package/dist/asset.js +60 -0
  15. package/dist/asset.js.map +1 -0
  16. package/dist/base-recipes.d.ts +19 -0
  17. package/dist/base-recipes.d.ts.map +1 -1
  18. package/dist/base-recipes.js +17 -0
  19. package/dist/base-recipes.js.map +1 -1
  20. package/dist/behaviors.d.ts +346 -3
  21. package/dist/behaviors.d.ts.map +1 -1
  22. package/dist/behaviors.js +35 -1
  23. package/dist/behaviors.js.map +1 -1
  24. package/dist/bottom-info.d.ts +58 -0
  25. package/dist/bottom-info.d.ts.map +1 -0
  26. package/dist/bottom-info.js +48 -0
  27. package/dist/bottom-info.js.map +1 -0
  28. package/dist/carousel.d.ts +3 -3
  29. package/dist/carousel.js +1 -1
  30. package/dist/carousel.js.map +1 -1
  31. package/dist/catalog.d.ts +1294 -239
  32. package/dist/catalog.d.ts.map +1 -1
  33. package/dist/catalog.js +65 -25
  34. package/dist/catalog.js.map +1 -1
  35. package/dist/collapsible.d.ts +56 -0
  36. package/dist/collapsible.d.ts.map +1 -0
  37. package/dist/collapsible.js +37 -0
  38. package/dist/collapsible.js.map +1 -0
  39. package/dist/component-definitions.d.ts +16 -0
  40. package/dist/component-definitions.d.ts.map +1 -1
  41. package/dist/component-definitions.js +16 -0
  42. package/dist/component-definitions.js.map +1 -1
  43. package/dist/component-recipes.d.ts +76 -4
  44. package/dist/component-recipes.d.ts.map +1 -1
  45. package/dist/component-recipes.js +38 -1
  46. package/dist/component-recipes.js.map +1 -1
  47. package/dist/context-menu.d.ts +53 -0
  48. package/dist/context-menu.d.ts.map +1 -0
  49. package/dist/context-menu.js +44 -0
  50. package/dist/context-menu.js.map +1 -0
  51. package/dist/counter-badge-recipe.d.ts +5 -0
  52. package/dist/counter-badge-recipe.d.ts.map +1 -1
  53. package/dist/counter-badge-recipe.js +5 -0
  54. package/dist/counter-badge-recipe.js.map +1 -1
  55. package/dist/dataviz.d.ts +76 -0
  56. package/dist/dataviz.d.ts.map +1 -0
  57. package/dist/dataviz.js +58 -0
  58. package/dist/dataviz.js.map +1 -0
  59. package/dist/date-range.d.ts +56 -0
  60. package/dist/date-range.d.ts.map +1 -0
  61. package/dist/date-range.js +79 -0
  62. package/dist/date-range.js.map +1 -0
  63. package/dist/design-system-provider.d.ts +24 -0
  64. package/dist/design-system-provider.d.ts.map +1 -1
  65. package/dist/design-system-provider.js +21 -0
  66. package/dist/design-system-provider.js.map +1 -1
  67. package/dist/floating-action-button.d.ts +1 -1
  68. package/dist/floating-action-button.d.ts.map +1 -1
  69. package/dist/floating-action-button.js +3 -1
  70. package/dist/floating-action-button.js.map +1 -1
  71. package/dist/formatters.d.ts +37 -0
  72. package/dist/formatters.d.ts.map +1 -0
  73. package/dist/formatters.js +69 -0
  74. package/dist/formatters.js.map +1 -0
  75. package/dist/heading.d.ts +82 -0
  76. package/dist/heading.d.ts.map +1 -0
  77. package/dist/heading.js +48 -0
  78. package/dist/heading.js.map +1 -0
  79. package/dist/index.d.ts +19 -0
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +19 -0
  82. package/dist/index.js.map +1 -1
  83. package/dist/menubar.d.ts +133 -0
  84. package/dist/menubar.d.ts.map +1 -0
  85. package/dist/menubar.js +80 -0
  86. package/dist/menubar.js.map +1 -0
  87. package/dist/native-platform.d.ts +88 -0
  88. package/dist/native-platform.d.ts.map +1 -0
  89. package/dist/native-platform.js +70 -0
  90. package/dist/native-platform.js.map +1 -0
  91. package/dist/popover.d.ts +19 -4
  92. package/dist/popover.d.ts.map +1 -1
  93. package/dist/popover.js +3 -0
  94. package/dist/popover.js.map +1 -1
  95. package/dist/progress-recipe.d.ts +14 -0
  96. package/dist/progress-recipe.d.ts.map +1 -1
  97. package/dist/progress-recipe.js +14 -1
  98. package/dist/progress-recipe.js.map +1 -1
  99. package/dist/provider-button.d.ts +140 -0
  100. package/dist/provider-button.d.ts.map +1 -0
  101. package/dist/provider-button.js +83 -0
  102. package/dist/provider-button.js.map +1 -0
  103. package/dist/recipes.d.ts +15 -1
  104. package/dist/recipes.d.ts.map +1 -1
  105. package/dist/recipes.js +14 -0
  106. package/dist/recipes.js.map +1 -1
  107. package/dist/sheet.d.ts +16 -0
  108. package/dist/sheet.d.ts.map +1 -1
  109. package/dist/sheet.js +33 -0
  110. package/dist/sheet.js.map +1 -1
  111. package/dist/sidebar.d.ts +168 -0
  112. package/dist/sidebar.d.ts.map +1 -0
  113. package/dist/sidebar.js +98 -0
  114. package/dist/sidebar.js.map +1 -0
  115. package/dist/skip-nav.d.ts +67 -0
  116. package/dist/skip-nav.d.ts.map +1 -0
  117. package/dist/skip-nav.js +47 -0
  118. package/dist/skip-nav.js.map +1 -0
  119. package/dist/tags-input.d.ts +157 -0
  120. package/dist/tags-input.d.ts.map +1 -0
  121. package/dist/tags-input.js +108 -0
  122. package/dist/tags-input.js.map +1 -0
  123. package/dist/text-formats.d.ts +85 -0
  124. package/dist/text-formats.d.ts.map +1 -0
  125. package/dist/text-formats.js +43 -0
  126. package/dist/text-formats.js.map +1 -0
  127. package/dist/toggle-group.d.ts +111 -0
  128. package/dist/toggle-group.d.ts.map +1 -0
  129. package/dist/toggle-group.js +78 -0
  130. package/dist/toggle-group.js.map +1 -0
  131. package/dist/top.d.ts +113 -0
  132. package/dist/top.d.ts.map +1 -0
  133. package/dist/top.js +72 -0
  134. package/dist/top.js.map +1 -0
  135. package/dist/version.d.ts +1 -1
  136. package/dist/version.js +1 -1
  137. package/dist/version.js.map +1 -1
  138. package/docs/agreement.md +33 -0
  139. package/docs/anchor.md +59 -59
  140. package/docs/ant-design-coverage.md +5 -3
  141. package/docs/architecture.md +10 -0
  142. package/docs/asset.md +26 -0
  143. package/docs/bottom-info.md +15 -0
  144. package/docs/breadcrumb.md +15 -15
  145. package/docs/button-label.md +20 -0
  146. package/docs/calendar.md +82 -154
  147. package/docs/carousel.md +27 -2
  148. package/docs/cascader.md +17 -0
  149. package/docs/chart.md +33 -0
  150. package/docs/clipboard.md +13 -0
  151. package/docs/collapsible.md +19 -0
  152. package/docs/command-palette.md +19 -0
  153. package/docs/confirm-popover.md +11 -1
  154. package/docs/context-menu.md +23 -0
  155. package/docs/data-table.md +22 -0
  156. package/docs/date-range.md +31 -0
  157. package/docs/density.md +23 -0
  158. package/docs/expansion-roadmap.md +16 -3
  159. package/docs/floating-action-button.md +35 -3
  160. package/docs/formatters.md +18 -0
  161. package/docs/generated/component-maturity.md +39 -23
  162. package/docs/generated/renderer-evidence.json +2921 -642
  163. package/docs/generated/renderer-evidence.md +53 -6
  164. package/docs/generated/showcase-manifest.json +1087 -64
  165. package/docs/heading.md +25 -0
  166. package/docs/identity.md +5 -0
  167. package/docs/layout.md +1 -1
  168. package/docs/library-gap-analysis.md +29 -9
  169. package/docs/list-row.md +14 -0
  170. package/docs/mentions.md +18 -0
  171. package/docs/menubar.md +22 -0
  172. package/docs/native-platform.md +36 -0
  173. package/docs/overlay-stack.md +24 -0
  174. package/docs/pagination.md +16 -8
  175. package/docs/popover.md +42 -13
  176. package/docs/product-audit-2026-09-15.md +88 -0
  177. package/docs/progress.md +16 -0
  178. package/docs/provider-button.md +33 -0
  179. package/docs/rating.md +19 -0
  180. package/docs/react-native-completion.md +347 -0
  181. package/docs/screen-chrome.md +52 -0
  182. package/docs/side-panel.md +23 -2
  183. package/docs/sidebar.md +30 -0
  184. package/docs/skip-nav.md +20 -0
  185. package/docs/splitter.md +22 -2
  186. package/docs/stable-promotion.md +51 -0
  187. package/docs/tags-input.md +25 -0
  188. package/docs/text-formats.md +15 -0
  189. package/docs/theming.md +84 -0
  190. package/docs/time-picker.md +22 -1
  191. package/docs/toast.md +18 -0
  192. package/docs/toggle-group.md +21 -0
  193. package/docs/top.md +32 -0
  194. package/docs/tour.md +23 -2
  195. package/docs/transfer-list.md +20 -0
  196. package/docs/tree-select.md +18 -0
  197. package/docs/tree.md +21 -0
  198. package/package.json +120 -6
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import { floatingSurfaceContract } from \"./component-contracts.js\";\nimport { motionPreset, spacing } from \"./foundations.js\";\n\n/**\n * Popover is the third corner of a triangle with Tooltip and Menu — all three\n * are \"a floating surface anchored to a trigger.\" Tooltip is explicitly\n * plain-text and never receives focus (docs/tooltip.md: \"interactive\n * Popover로 확장하지 않는다\"). Menu is a collection of actionable items with\n * its own role/keyboard table (behaviorRegistry.menu). Popover is what is left:\n * arbitrary *interactive* content (a small form, rich text with a link, a\n * mixed layout) that is neither a single plain sentence nor an item list.\n * Focus entering the surface is the decisive, testable difference from\n * Tooltip — everything else here (dismiss reasons, non-modal posture) follows\n * from that one fact.\n */\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"start\" | \"end\";\nexport type PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover is non-modal: it does not trap focus like Dialog/Sheet and does not\n * block the rest of the page. So its dismiss vocabulary is deliberately\n * narrower than SheetDismissReason — no \"back\" or \"swipe\" (this is a web-only\n * surface), but it adds \"outside-focus\" because, unlike a modal, Tab can\n * legitimately carry focus out of a non-modal surface and that departure is\n * itself a dismiss signal distinct from a pointer click outside.\n */\nexport type PopoverDismissReason =\n | \"close-action\"\n | \"outside-pointer\"\n | \"outside-focus\"\n | \"escape\"\n | \"programmatic\";\n\n/**\n * 여는 사유는 `\"trigger\"`다. Sheet·SidePanel·CommandPalette가 모두 이 이름을 쓰고,\n * `\"trigger-activation\"`은 `src/tooltip.ts`에서 **닫는** 사유(열려 있는 툴팁의\n * 트리거를 눌러 닫는다)로 이미 쓰이고 있다. 한 문자열이 여는 뜻과 닫는 뜻을 겸하면\n * 렌더러가 조용히 반대로 처리한다 — 컴파일러는 둘 다 유효한 문자열로만 본다.\n */\nexport type PopoverOpenChangeReason = \"trigger\" | PopoverDismissReason;\n\nexport type PopoverOpenChangeDetails = Readonly<{\n reason: PopoverOpenChangeReason;\n}>;\n\nexport type PopoverDescriptor = Readonly<{\n placement?: PopoverPlacement;\n align?: PopoverAlign;\n /**\n * Only needed when the content has no visible heading the platform\n * accessibility tree can already read as the surface's name. Most Popover\n * content should carry its own heading; this is an escape hatch, not the\n * default path.\n */\n accessibilityLabel?: string;\n}>;\n\nexport type ResolvedPopoverDescriptor = Readonly<{\n placement: PopoverPlacement;\n align: PopoverAlign;\n accessibilityLabel?: string;\n}>;\n\nexport const popoverDescriptorDefaults = {\n placement: \"bottom\",\n align: \"start\",\n} as const satisfies Readonly<{ placement: PopoverPlacement; align: PopoverAlign }>;\n\n/**\n * A controlled owner's programmatic close always wins, exactly like\n * SheetDismissPolicy/canDismissSheet. Popover has no `busy` axis: unlike\n * Sheet/AlertDialog it is not modal, so there is no global \"block every\n * dismiss\" state to defend — a form inside the content that wants to ignore\n * Escape while submitting makes that call itself, at the content level.\n */\nexport type PopoverDismissPolicy = Readonly<{\n dismissible: boolean;\n outsideDismiss: boolean;\n escapeDismiss: boolean;\n focusOutDismiss: boolean;\n}>;\n\nexport const popoverBehaviorDefaults = {\n dismissible: true,\n outsideDismiss: true,\n escapeDismiss: true,\n focusOutDismiss: true,\n} as const satisfies PopoverDismissPolicy;\n\nexport type ControlledPopoverOpenState = Readonly<{\n open: boolean;\n defaultOpen?: never;\n onOpenChange(open: boolean, details: PopoverOpenChangeDetails): void;\n}>;\n\nexport type UncontrolledPopoverOpenState = Readonly<{\n open?: never;\n defaultOpen?: boolean;\n onOpenChange?: (\n open: boolean,\n details: PopoverOpenChangeDetails,\n ) => void;\n}>;\n\nexport type PopoverOpenState =\n | ControlledPopoverOpenState\n | UncontrolledPopoverOpenState;\n\n/** Products own what page-change caused this; Popover only needs \"did it happen and how.\" */\nexport type PopoverChangeHandler = PopoverOpenState[\"onOpenChange\"];\n\nconst placements = new Set<PopoverPlacement>([\"top\", \"bottom\", \"start\", \"end\"]);\nconst alignments = new Set<PopoverAlign>([\"start\", \"center\", \"end\"]);\nconst descriptorKeys = new Set([\"placement\", \"align\", \"accessibilityLabel\"]);\nconst openStateKeys = new Set([\"open\", \"defaultOpen\", \"onOpenChange\"]);\n\nfunction isObject(value: unknown): value is Readonly<Record<string, unknown>> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n value: Readonly<Record<string, unknown>>,\n allowed: ReadonlySet<string>,\n field: string,\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) {\n throw new TypeError(`Unsupported Popover ${field} field: ${key}`);\n }\n }\n}\n\nexport function validatePopoverDescriptor(descriptor: PopoverDescriptor): void {\n if (!isObject(descriptor)) {\n throw new TypeError(\"Popover descriptor must be an object\");\n }\n rejectUnknownKeys(descriptor, descriptorKeys, \"descriptor\");\n if (\n descriptor.placement !== undefined &&\n !placements.has(descriptor.placement)\n ) {\n throw new TypeError(\n `Unsupported Popover placement: ${String(descriptor.placement)}`,\n );\n }\n if (descriptor.align !== undefined && !alignments.has(descriptor.align)) {\n throw new TypeError(`Unsupported Popover align: ${String(descriptor.align)}`);\n }\n if (descriptor.accessibilityLabel !== undefined) {\n if (\n typeof descriptor.accessibilityLabel !== \"string\" ||\n descriptor.accessibilityLabel.trim().length === 0\n ) {\n throw new TypeError(\"Popover accessibilityLabel must not be empty\");\n }\n if (descriptor.accessibilityLabel !== descriptor.accessibilityLabel.trim()) {\n throw new TypeError(\n \"Popover accessibilityLabel must not start or end with whitespace\",\n );\n }\n }\n}\n\nexport function resolvePopoverDescriptor(\n descriptor: PopoverDescriptor,\n): ResolvedPopoverDescriptor {\n validatePopoverDescriptor(descriptor);\n return {\n placement: descriptor.placement ?? popoverDescriptorDefaults.placement,\n align: descriptor.align ?? popoverDescriptorDefaults.align,\n ...(descriptor.accessibilityLabel !== undefined\n ? { accessibilityLabel: descriptor.accessibilityLabel }\n : {}),\n };\n}\n\nexport function validatePopoverOpenState(state: PopoverOpenState): void {\n if (!isObject(state)) {\n throw new TypeError(\"Popover open state must be an object\");\n }\n rejectUnknownKeys(state, openStateKeys, \"open state\");\n const runtime = state as Readonly<Record<string, unknown>>;\n const hasOpen = Object.prototype.hasOwnProperty.call(runtime, \"open\");\n const hasDefaultOpen = Object.prototype.hasOwnProperty.call(\n runtime,\n \"defaultOpen\",\n );\n if (hasOpen) {\n if (typeof runtime.open !== \"boolean\") {\n throw new TypeError(\"Popover open must be a boolean\");\n }\n if (hasDefaultOpen) {\n throw new TypeError(\"Controlled Popover must not provide defaultOpen\");\n }\n if (typeof runtime.onOpenChange !== \"function\") {\n throw new TypeError(\"Controlled Popover must provide onOpenChange\");\n }\n return;\n }\n if (hasDefaultOpen && typeof runtime.defaultOpen !== \"boolean\") {\n throw new TypeError(\"Popover defaultOpen must be a boolean\");\n }\n if (\n runtime.onOpenChange !== undefined &&\n typeof runtime.onOpenChange !== \"function\"\n ) {\n throw new TypeError(\"Popover onOpenChange must be a function\");\n }\n}\n\n/**\n * Resolves an attempted close without platform knowledge, mirroring\n * canDismissSheet. Programmatic close is always an owner override.\n */\nexport function canDismissPopover(\n reason: PopoverDismissReason,\n policy: PopoverDismissPolicy = popoverBehaviorDefaults,\n): boolean {\n if (reason === \"programmatic\") return true;\n if (!policy.dismissible) return false;\n if (reason === \"outside-pointer\") return policy.outsideDismiss;\n if (reason === \"outside-focus\") return policy.focusOutDismiss;\n if (reason === \"escape\") return policy.escapeDismiss;\n return true;\n}\n\n/**\n * Positioning boundary is identical to Tooltip's: HJM owns preferred\n * placement, spacing, and motion; DOM measurement, portal, flip/shift, and\n * RTL logical-to-physical translation stay in the product Web renderer's\n * private AnchoredOverlay (see docs/tooltip.md \"Positioning boundary\"). This\n * module never exposes that internal tool, so Popover cannot regress Tooltip's\n * \"no public collision/portal API\" boundary.\n */\nexport const popoverRecipe = {\n slots: [\"trigger\", \"content\", \"arrow\", \"closeAction\"] as const,\n surface: floatingSurfaceContract,\n arrow: { size: spacing.xxs, offset: spacing.xxs },\n sideOffset: spacing.xs,\n collisionPadding: spacing.xs,\n minWidth: 240,\n maxWidth: 360,\n transition: { enter: motionPreset.enter, exit: motionPreset.exit },\n} as const satisfies {\n slots: readonly string[];\n surface: typeof floatingSurfaceContract;\n arrow: { size: number; offset: number };\n sideOffset: number;\n collisionPadding: number;\n minWidth: number;\n maxWidth: number;\n transition: { enter: typeof motionPreset.enter; exit: typeof motionPreset.exit };\n};\n\n/**\n * Literal scenario names for behaviorRegistry.popover (lead wires into\n * src/behaviors.ts). Kept here, not there, so this module stays self-contained\n * per the authoring brief.\n */\nexport const popoverBehaviorScenarios = [\n \"focus-enters-surface-on-open\",\n \"escape-closes-and-restores-trigger-focus\",\n \"outside-pointer-close-does-not-cancel-the-original-interaction\",\n \"tabbing-past-last-focusable-child-closes-without-trapping\",\n \"controlled-owner-programmatic-close-always-wins\",\n \"close-action-inside-content-closes-exactly-once\",\n \"trigger-while-open-does-not-reopen\",\n \"one-visible-popover-per-trigger\",\n] as const;\n"]}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import { floatingSurfaceContract } from \"./component-contracts.js\";\nimport { motionPreset, spacing } from \"./foundations.js\";\n\n/**\n * Popover is the third corner of a triangle with Tooltip and Menu — all three\n * are \"a floating surface anchored to a trigger.\" Tooltip is explicitly\n * plain-text and never receives focus (docs/tooltip.md: \"interactive\n * Popover로 확장하지 않는다\"). Menu is a collection of actionable items with\n * its own role/keyboard table (behaviorRegistry.menu). Popover is what is left:\n * arbitrary *interactive* content (a small form, rich text with a link, a\n * mixed layout) that is neither a single plain sentence nor an item list.\n * Focus entering the surface is the decisive, testable difference from\n * Tooltip — everything else here (dismiss reasons, non-modal posture) follows\n * from that one fact.\n */\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"start\" | \"end\";\nexport type PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover is non-modal: it does not trap focus like Dialog/Sheet and does not\n * block the rest of the page. So its dismiss vocabulary is deliberately\n * narrower than SheetDismissReason — no \"back\" or \"swipe\" (this is a web-only\n * surface), but it adds \"outside-focus\" because, unlike a modal, Tab can\n * legitimately carry focus out of a non-modal surface and that departure is\n * itself a dismiss signal distinct from a pointer click outside.\n */\nexport type PopoverDismissReason =\n | \"close-action\"\n | \"outside-pointer\"\n | \"outside-focus\"\n | \"escape\"\n | \"programmatic\";\n\n/**\n * 여는 사유는 `\"trigger\"`다. Sheet·SidePanel·CommandPalette가 모두 이 이름을 쓰고,\n * `\"trigger-activation\"`은 `src/tooltip.ts`에서 **닫는** 사유(열려 있는 툴팁의\n * 트리거를 눌러 닫는다)로 이미 쓰이고 있다. 한 문자열이 여는 뜻과 닫는 뜻을 겸하면\n * 렌더러가 조용히 반대로 처리한다 — 컴파일러는 둘 다 유효한 문자열로만 본다.\n */\nexport type PopoverOpenChangeReason = \"trigger\" | PopoverDismissReason;\n\nexport type PopoverOpenChangeDetails = Readonly<{\n reason: PopoverOpenChangeReason;\n}>;\n\nexport type PopoverDescriptor = Readonly<{\n placement?: PopoverPlacement;\n align?: PopoverAlign;\n /**\n * Optional explicit accessible name. A renderer must connect its visible\n * heading with aria-labelledby; a heading alone does not name a dialog.\n */\n accessibilityLabel?: string;\n}>;\n\nexport type ResolvedPopoverDescriptor = Readonly<{\n placement: PopoverPlacement;\n align: PopoverAlign;\n accessibilityLabel?: string;\n}>;\n\nexport const popoverDescriptorDefaults = {\n placement: \"bottom\",\n align: \"start\",\n} as const satisfies Readonly<{ placement: PopoverPlacement; align: PopoverAlign }>;\n\n/**\n * A controlled owner's programmatic close always wins, exactly like\n * SheetDismissPolicy/canDismissSheet. Popover has no `busy` axis: unlike\n * Sheet/AlertDialog it is not modal, so there is no global \"block every\n * dismiss\" state to defend — a form inside the content that wants to ignore\n * Escape while submitting makes that call itself, at the content level.\n */\nexport type PopoverDismissPolicy = Readonly<{\n dismissible: boolean;\n outsideDismiss: boolean;\n escapeDismiss: boolean;\n focusOutDismiss: boolean;\n}>;\n\n/**\n * 무엇이 popover를 여는가. `press`가 기본이고 `hover`는 **읽기 전용 미리보기**\n * (다른 시스템의 HoverCard)를 위한 축이다.\n *\n * 별도 컴포넌트를 만들지 않은 이유: 표면·초점·dismiss·충돌 회피가 전부 같고 다른 것은\n * 여는 방법 하나뿐이다. 두 컴포넌트로 나누면 그 네 가지가 두 벌이 된다.\n *\n * 대신 `hover`에는 제약이 붙는다 — hover로만 열리는 내용에 **행동을 두면 안 된다**.\n * 포인터가 없는 사용자는 그 행동에 닿을 수 없기 때문이다. 미리보기는 읽기 전용이다.\n */\nexport type PopoverOpenOn = \"press\" | \"hover\";\n\nexport const popoverBehaviorDefaults = {\n openOn: \"press\" as PopoverOpenOn,\n dismissible: true,\n outsideDismiss: true,\n escapeDismiss: true,\n focusOutDismiss: true,\n} as const satisfies PopoverDismissPolicy & Readonly<{ openOn: PopoverOpenOn }>;\n\n/** hover로 열 때의 지연. 지나가는 포인터마다 열리면 화면이 깜빡인다. */\nexport const popoverHoverDelay = { open: 300, close: 150 } as const;\n\nexport type ControlledPopoverOpenState = Readonly<{\n open: boolean;\n defaultOpen?: never;\n onOpenChange(open: boolean, details: PopoverOpenChangeDetails): void;\n}>;\n\nexport type UncontrolledPopoverOpenState = Readonly<{\n open?: never;\n defaultOpen?: boolean;\n onOpenChange?: (\n open: boolean,\n details: PopoverOpenChangeDetails,\n ) => void;\n}>;\n\nexport type PopoverOpenState =\n | ControlledPopoverOpenState\n | UncontrolledPopoverOpenState;\n\n/** Products own what page-change caused this; Popover only needs \"did it happen and how.\" */\nexport type PopoverChangeHandler = PopoverOpenState[\"onOpenChange\"];\n\nconst placements = new Set<PopoverPlacement>([\"top\", \"bottom\", \"start\", \"end\"]);\nconst alignments = new Set<PopoverAlign>([\"start\", \"center\", \"end\"]);\nconst descriptorKeys = new Set([\"placement\", \"align\", \"accessibilityLabel\"]);\nconst openStateKeys = new Set([\"open\", \"defaultOpen\", \"onOpenChange\"]);\n\nfunction isObject(value: unknown): value is Readonly<Record<string, unknown>> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n value: Readonly<Record<string, unknown>>,\n allowed: ReadonlySet<string>,\n field: string,\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) {\n throw new TypeError(`Unsupported Popover ${field} field: ${key}`);\n }\n }\n}\n\nexport function validatePopoverDescriptor(descriptor: PopoverDescriptor): void {\n if (!isObject(descriptor)) {\n throw new TypeError(\"Popover descriptor must be an object\");\n }\n rejectUnknownKeys(descriptor, descriptorKeys, \"descriptor\");\n if (\n descriptor.placement !== undefined &&\n !placements.has(descriptor.placement)\n ) {\n throw new TypeError(\n `Unsupported Popover placement: ${String(descriptor.placement)}`,\n );\n }\n if (descriptor.align !== undefined && !alignments.has(descriptor.align)) {\n throw new TypeError(`Unsupported Popover align: ${String(descriptor.align)}`);\n }\n if (descriptor.accessibilityLabel !== undefined) {\n if (\n typeof descriptor.accessibilityLabel !== \"string\" ||\n descriptor.accessibilityLabel.trim().length === 0\n ) {\n throw new TypeError(\"Popover accessibilityLabel must not be empty\");\n }\n if (descriptor.accessibilityLabel !== descriptor.accessibilityLabel.trim()) {\n throw new TypeError(\n \"Popover accessibilityLabel must not start or end with whitespace\",\n );\n }\n }\n}\n\nexport function resolvePopoverDescriptor(\n descriptor: PopoverDescriptor,\n): ResolvedPopoverDescriptor {\n validatePopoverDescriptor(descriptor);\n return {\n placement: descriptor.placement ?? popoverDescriptorDefaults.placement,\n align: descriptor.align ?? popoverDescriptorDefaults.align,\n ...(descriptor.accessibilityLabel !== undefined\n ? { accessibilityLabel: descriptor.accessibilityLabel }\n : {}),\n };\n}\n\nexport function validatePopoverOpenState(state: PopoverOpenState): void {\n if (!isObject(state)) {\n throw new TypeError(\"Popover open state must be an object\");\n }\n rejectUnknownKeys(state, openStateKeys, \"open state\");\n const runtime = state as Readonly<Record<string, unknown>>;\n const hasOpen = Object.prototype.hasOwnProperty.call(runtime, \"open\");\n const hasDefaultOpen = Object.prototype.hasOwnProperty.call(\n runtime,\n \"defaultOpen\",\n );\n if (hasOpen) {\n if (typeof runtime.open !== \"boolean\") {\n throw new TypeError(\"Popover open must be a boolean\");\n }\n if (hasDefaultOpen) {\n throw new TypeError(\"Controlled Popover must not provide defaultOpen\");\n }\n if (typeof runtime.onOpenChange !== \"function\") {\n throw new TypeError(\"Controlled Popover must provide onOpenChange\");\n }\n return;\n }\n if (hasDefaultOpen && typeof runtime.defaultOpen !== \"boolean\") {\n throw new TypeError(\"Popover defaultOpen must be a boolean\");\n }\n if (\n runtime.onOpenChange !== undefined &&\n typeof runtime.onOpenChange !== \"function\"\n ) {\n throw new TypeError(\"Popover onOpenChange must be a function\");\n }\n}\n\n/**\n * Resolves an attempted close without platform knowledge, mirroring\n * canDismissSheet. Programmatic close is always an owner override.\n */\nexport function canDismissPopover(\n reason: PopoverDismissReason,\n policy: PopoverDismissPolicy = popoverBehaviorDefaults,\n): boolean {\n if (reason === \"programmatic\") return true;\n if (!policy.dismissible) return false;\n if (reason === \"outside-pointer\") return policy.outsideDismiss;\n if (reason === \"outside-focus\") return policy.focusOutDismiss;\n if (reason === \"escape\") return policy.escapeDismiss;\n return true;\n}\n\n/**\n * Positioning boundary is identical to Tooltip's: HJM owns preferred\n * placement, spacing, and motion; DOM measurement, portal, flip/shift, and\n * RTL logical-to-physical translation stay in the product Web renderer's\n * private AnchoredOverlay (see docs/tooltip.md \"Positioning boundary\"). This\n * module never exposes that internal tool, so Popover cannot regress Tooltip's\n * \"no public collision/portal API\" boundary.\n */\nexport const popoverRecipe = {\n slots: [\"trigger\", \"content\", \"arrow\", \"closeAction\"] as const,\n surface: floatingSurfaceContract,\n arrow: { size: spacing.xxs, offset: spacing.xxs },\n sideOffset: spacing.xs,\n collisionPadding: spacing.xs,\n minWidth: 240,\n maxWidth: 360,\n transition: { enter: motionPreset.enter, exit: motionPreset.exit },\n} as const satisfies {\n slots: readonly string[];\n surface: typeof floatingSurfaceContract;\n arrow: { size: number; offset: number };\n sideOffset: number;\n collisionPadding: number;\n minWidth: number;\n maxWidth: number;\n transition: { enter: typeof motionPreset.enter; exit: typeof motionPreset.exit };\n};\n\n/**\n * Literal scenario names for behaviorRegistry.popover (lead wires into\n * src/behaviors.ts). Kept here, not there, so this module stays self-contained\n * per the authoring brief.\n */\nexport const popoverBehaviorScenarios = [\n \"focus-enters-surface-on-open\",\n \"escape-closes-and-restores-trigger-focus\",\n \"outside-pointer-close-does-not-cancel-the-original-interaction\",\n \"tabbing-past-last-focusable-child-closes-without-trapping\",\n \"controlled-owner-programmatic-close-always-wins\",\n \"close-action-inside-content-closes-exactly-once\",\n \"trigger-while-open-does-not-reopen\",\n \"one-visible-popover-per-trigger\",\n] as const;\n"]}
@@ -3,12 +3,25 @@ export declare const progressRecipe: {
3
3
  readonly defaults: {
4
4
  readonly size: "medium";
5
5
  readonly tone: "brand";
6
+ readonly shape: "linear";
6
7
  };
7
8
  readonly sizes: {
8
9
  readonly small: 4;
9
10
  readonly medium: 8;
10
11
  readonly large: 12;
11
12
  };
13
+ readonly circular: {
14
+ readonly sizes: {
15
+ readonly small: 24;
16
+ readonly medium: 40;
17
+ readonly large: 64;
18
+ };
19
+ readonly strokeWidth: {
20
+ readonly small: 3;
21
+ readonly medium: 4;
22
+ readonly large: 6;
23
+ };
24
+ };
12
25
  readonly tones: {
13
26
  readonly brand: Readonly<{
14
27
  source: "theme";
@@ -40,4 +53,5 @@ export declare const progressRecipe: {
40
53
  };
41
54
  export type ProgressSize = keyof typeof progressRecipe.sizes;
42
55
  export type ProgressTone = keyof typeof progressRecipe.tones;
56
+ export type ProgressShape = "linear" | "circular";
43
57
  //# sourceMappingURL=progress-recipe.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-recipe.d.ts","sourceRoot":"","sources":["../src/progress-recipe.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmB1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC;AAC7D,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC"}
1
+ {"version":3,"file":"progress-recipe.d.ts","sourceRoot":"","sources":["../src/progress-recipe.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwC1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC;AAC7D,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC"}
@@ -2,8 +2,21 @@ import { radius } from "./foundations.js";
2
2
  import { semanticColors } from "./semantic-colors.js";
3
3
  export const progressRecipe = {
4
4
  slots: ["root", "track", "indicator", "label", "value"],
5
- defaults: { size: "medium", tone: "brand" },
5
+ defaults: { size: "medium", tone: "brand", shape: "linear" },
6
6
  sizes: { small: 4, medium: 8, large: 12 },
7
+ /*
8
+ 같은 값을 원으로 그리는 변형이다. 새 컴포넌트가 아닌 이유는 의미가 완전히 같기
9
+ 때문이다 — min/max/now, 값 없는 진행, 발표 문구, tone이 전부 선형과 공유된다.
10
+ 따로 만들면 "어느 쪽이 접근성 계약을 갖는가"가 둘로 갈린다.
11
+
12
+ 지름은 linear의 두께와 다른 축이다: 선형은 굵기만 정하면 되지만 원은 지름과
13
+ 획 두께를 함께 정해야 같은 tone에서 같은 무게로 읽힌다. Diairy가 ProgressRing을
14
+ 직접 만든 자리이고, 그때 필요했던 값이 이 둘이다.
15
+ */
16
+ circular: {
17
+ sizes: { small: 24, medium: 40, large: 64 },
18
+ strokeWidth: { small: 3, medium: 4, large: 6 },
19
+ },
7
20
  tones: {
8
21
  brand: semanticColors.content.brand,
9
22
  success: semanticColors.feedback.success.foreground,
@@ -1 +1 @@
1
- {"version":3,"file":"progress-recipe.js","sourceRoot":"","sources":["../src/progress-recipe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAU;IAChE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;IAC3C,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACzC,KAAK,EAAE;QACL,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK;QACnC,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;QACnD,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;QACnD,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM;KACtC;IACD,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM;IACpC,MAAM,EAAE,MAAM;CAQf,CAAC","sourcesContent":["import type { ColorReference } from \"./color-references.js\";\nimport { radius } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\nexport const progressRecipe = {\n slots: [\"root\", \"track\", \"indicator\", \"label\", \"value\"] as const,\n defaults: { size: \"medium\", tone: \"brand\" },\n sizes: { small: 4, medium: 8, large: 12 },\n tones: {\n brand: semanticColors.content.brand,\n success: semanticColors.feedback.success.foreground,\n warning: semanticColors.feedback.warning.foreground,\n danger: semanticColors.content.danger,\n },\n track: semanticColors.surface.sunken,\n radius: \"full\",\n} as const satisfies {\n radius: keyof typeof radius;\n slots: readonly string[];\n defaults: { size: \"small\" | \"medium\" | \"large\"; tone: \"brand\" | \"success\" | \"warning\" | \"danger\" };\n sizes: Record<\"small\" | \"medium\" | \"large\", number>;\n tones: Record<\"brand\" | \"success\" | \"warning\" | \"danger\", ColorReference>;\n track: ColorReference;\n};\n\nexport type ProgressSize = keyof typeof progressRecipe.sizes;\nexport type ProgressTone = keyof typeof progressRecipe.tones;\n"]}
1
+ {"version":3,"file":"progress-recipe.js","sourceRoot":"","sources":["../src/progress-recipe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAU;IAChE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;IAC5D,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACzC;;;;;;;;MAQE;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3C,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;KAC/C;IACD,KAAK,EAAE;QACL,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK;QACnC,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;QACnD,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;QACnD,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM;KACtC;IACD,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM;IACpC,MAAM,EAAE,MAAM;CAgBf,CAAC","sourcesContent":["import type { ColorReference } from \"./color-references.js\";\nimport { radius } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\nexport const progressRecipe = {\n slots: [\"root\", \"track\", \"indicator\", \"label\", \"value\"] as const,\n defaults: { size: \"medium\", tone: \"brand\", shape: \"linear\" },\n sizes: { small: 4, medium: 8, large: 12 },\n /*\n 같은 값을 원으로 그리는 변형이다. 새 컴포넌트가 아닌 이유는 의미가 완전히 같기\n 때문이다 — min/max/now, 값 없는 진행, 발표 문구, tone이 전부 선형과 공유된다.\n 따로 만들면 \"어느 쪽이 접근성 계약을 갖는가\"가 둘로 갈린다.\n\n 지름은 linear의 두께와 다른 축이다: 선형은 굵기만 정하면 되지만 원은 지름과\n 획 두께를 함께 정해야 같은 tone에서 같은 무게로 읽힌다. Diairy가 ProgressRing을\n 직접 만든 자리이고, 그때 필요했던 값이 이 둘이다.\n */\n circular: {\n sizes: { small: 24, medium: 40, large: 64 },\n strokeWidth: { small: 3, medium: 4, large: 6 },\n },\n tones: {\n brand: semanticColors.content.brand,\n success: semanticColors.feedback.success.foreground,\n warning: semanticColors.feedback.warning.foreground,\n danger: semanticColors.content.danger,\n },\n track: semanticColors.surface.sunken,\n radius: \"full\",\n} as const satisfies {\n radius: keyof typeof radius;\n slots: readonly string[];\n defaults: {\n size: \"small\" | \"medium\" | \"large\";\n tone: \"brand\" | \"success\" | \"warning\" | \"danger\";\n shape: \"linear\" | \"circular\";\n };\n sizes: Record<\"small\" | \"medium\" | \"large\", number>;\n circular: {\n sizes: Record<\"small\" | \"medium\" | \"large\", number>;\n strokeWidth: Record<\"small\" | \"medium\" | \"large\", number>;\n };\n tones: Record<\"brand\" | \"success\" | \"warning\" | \"danger\", ColorReference>;\n track: ColorReference;\n};\n\nexport type ProgressSize = keyof typeof progressRecipe.sizes;\nexport type ProgressTone = keyof typeof progressRecipe.tones;\nexport type ProgressShape = \"linear\" | \"circular\";\n"]}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * 소셜 로그인 버튼이다. Button의 tone 하나로 풀 수 없어서 별도 계약으로 둔다.
3
+ *
4
+ * HJM의 tone은 **의미**(primary/secondary/danger)이고 팔레트가 테마를 따라 움직인다.
5
+ * 제공자 버튼의 색은 의미가 아니라 **남의 브랜드 자산**이다 — Google·Kakao·Naver·Apple이
6
+ * 각자 로그인 버튼의 배경·글자·테두리·최소 크기를 브랜드 가이드라인으로 규정하고, 심사에서
7
+ * 그대로 쓰기를 요구한다. 그래서 이 색들은 semantic token이 아니고 테마가 다시 칠하지
8
+ * 않는다. 제품이 `.hjm-button.bt-provider-google` 같은 CSS로 덮어 오던 자리를 계약으로
9
+ * 올리되, 값의 출처가 HJM이 아니라는 사실을 타입으로 드러낸다.
10
+ *
11
+ * **HJM이 소유하는 것**: 높이·radius·터치 타깃·포커스 링·로고와 라벨의 배치·큰 글자 대응.
12
+ * **제공자가 소유하는 것**: 색과 로고 모양.
13
+ * **제품이 소유하는 것**: 로고 자산(재배포하지 않으므로 슬롯으로 받는다)과 현지화된 문구
14
+ * ("Google로 계속하기"의 정확한 표현은 제공자 가이드라인과 언어에 따라 다르다).
15
+ */
16
+ export type AuthProviderId = "google" | "kakao" | "naver" | "apple";
17
+ export type AuthProviderSurface = Readonly<{
18
+ /** 제공자 가이드라인이 지정한 배경색. HJM 팔레트가 아니다. */
19
+ background: string;
20
+ /** 같은 가이드라인의 글자/로고 색. */
21
+ content: string;
22
+ /** 배경이 캔버스와 구분되지 않을 때만 가이드라인이 요구하는 테두리. */
23
+ border: string | null;
24
+ }>;
25
+ export type AuthProviderPalette = Readonly<{
26
+ light: AuthProviderSurface;
27
+ /**
28
+ * 제공자가 다크 변형을 따로 규정한 경우에만 다르다. 브랜드색 자체가 정체성인
29
+ * Kakao·Naver는 다크에서도 같은 색을 쓰라고 명시하므로 light와 동일하다.
30
+ */
31
+ dark: AuthProviderSurface;
32
+ }>;
33
+ /**
34
+ * 값의 출처는 각 제공자의 공개 브랜드 가이드라인이다(2026-09 확인).
35
+ * 로고 이미지는 포함하지 않는다 — 배포 조건이 제공자마다 다르고, HJM이 재배포할 권리가
36
+ * 없다. 가이드라인이 바뀌면 이 표를 고치는 것이 유일한 변경 지점이다.
37
+ */
38
+ export declare const authProviderPalettes: {
39
+ readonly google: {
40
+ readonly light: {
41
+ readonly background: "#FFFFFF";
42
+ readonly content: "#1F1F1F";
43
+ readonly border: "#747775";
44
+ };
45
+ readonly dark: {
46
+ readonly background: "#131314";
47
+ readonly content: "#E3E3E3";
48
+ readonly border: "#8E918F";
49
+ };
50
+ };
51
+ readonly kakao: {
52
+ readonly light: {
53
+ readonly background: "#FEE500";
54
+ readonly content: "rgba(0, 0, 0, 0.85)";
55
+ readonly border: null;
56
+ };
57
+ readonly dark: {
58
+ readonly background: "#FEE500";
59
+ readonly content: "rgba(0, 0, 0, 0.85)";
60
+ readonly border: null;
61
+ };
62
+ };
63
+ readonly naver: {
64
+ readonly light: {
65
+ readonly background: "#03C75A";
66
+ readonly content: "#FFFFFF";
67
+ readonly border: null;
68
+ };
69
+ readonly dark: {
70
+ readonly background: "#03C75A";
71
+ readonly content: "#FFFFFF";
72
+ readonly border: null;
73
+ };
74
+ };
75
+ readonly apple: {
76
+ readonly light: {
77
+ readonly background: "#000000";
78
+ readonly content: "#FFFFFF";
79
+ readonly border: null;
80
+ };
81
+ readonly dark: {
82
+ readonly background: "#FFFFFF";
83
+ readonly content: "#000000";
84
+ readonly border: "#000000";
85
+ };
86
+ };
87
+ };
88
+ export type AuthProviderButtonDescriptor = Readonly<{
89
+ provider: AuthProviderId;
90
+ /** 제공자 가이드라인과 언어에 맞춘 문구. renderer가 만들지 않는다. */
91
+ label: string;
92
+ /** 진행 중 표시. 라벨을 지우지 않고 버튼 폭도 유지한다. */
93
+ busy?: boolean;
94
+ disabled?: boolean;
95
+ }>;
96
+ export declare function validateAuthProviderButtonDescriptor(descriptor: AuthProviderButtonDescriptor): void;
97
+ /** 해석된 테마에 맞는 제공자 표면. 테마는 *변형 선택*만 하고 색을 만들지 않는다. */
98
+ export declare function resolveAuthProviderSurface(provider: AuthProviderId, theme: "light" | "dark"): AuthProviderSurface;
99
+ /**
100
+ * 크기는 HJM 것이다 — 한 화면에 네 개가 세로로 쌓이므로 높이·radius·간격이 서로 다르면
101
+ * 목록이 무너진다. `buttonRecipe`의 medium 높이와 같은 값을 쓰고, 최소 터치 타깃도 공유한다.
102
+ */
103
+ export declare const authProviderButtonRecipe: {
104
+ readonly slots: readonly ["root", "logo", "label", "spinner"];
105
+ readonly minHeight: 44;
106
+ readonly minTouchTarget: 44;
107
+ readonly radius: 12;
108
+ readonly paddingHorizontal: 16;
109
+ readonly gap: 12;
110
+ readonly logoSize: 20;
111
+ readonly label: {
112
+ readonly fontSize: 14;
113
+ readonly lineHeight: 20;
114
+ readonly fontWeight: "400";
115
+ };
116
+ readonly borderWidth: 1;
117
+ /** 제공자 색 위에서도 보이도록 포커스 링은 바깥에 그린다. */
118
+ readonly focusOutlineOffset: 2;
119
+ };
120
+ export declare const authProviderButtonBehavior: {
121
+ readonly controlled: readonly [];
122
+ readonly inputs: readonly ["provider", "label", "busy", "disabled"];
123
+ readonly events: readonly ["onPress"];
124
+ readonly stateAxes: {
125
+ readonly availability: readonly ["enabled", "disabled", "busy"];
126
+ readonly interaction: readonly ["idle", "hover", "focusVisible", "pressed"];
127
+ };
128
+ readonly web: {
129
+ readonly roles: readonly ["button"];
130
+ readonly keyboard: readonly ["Enter", "Space"];
131
+ readonly focus: "native";
132
+ };
133
+ readonly native: {
134
+ readonly roles: readonly ["button"];
135
+ readonly states: readonly ["disabled", "busy"];
136
+ readonly actions: readonly ["press"];
137
+ };
138
+ readonly scenarios: readonly ["provider-colors-come-from-the-provider-guideline-and-the-theme-never-recolors-them", "the-theme-only-picks-between-the-providers-own-light-and-dark-variants", "the-logo-asset-is-a-product-supplied-slot-never-bundled-by-the-design-system", "the-label-is-product-copy-because-the-required-wording-differs-per-provider-and-language", "height-radius-and-touch-target-stay-hjm-so-a-stack-of-providers-lines-up", "busy-keeps-the-label-and-the-button-width-instead-of-collapsing-to-a-spinner", "the-focus-ring-is-drawn-outside-the-brand-fill-so-it-survives-every-provider-color"];
139
+ };
140
+ //# sourceMappingURL=provider-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-button.d.ts","sourceRoot":"","sources":["../src/provider-button.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,KAAK,EAAE,mBAAmB,CAAC;IAC3B;;;OAGG;IACH,IAAI,EAAE,mBAAmB,CAAC;CAC3B,CAAC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsByC,CAAC;AAE3E,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,QAAQ,EAAE,cAAc,CAAC;IACzB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH,wBAAgB,oCAAoC,CAClD,UAAU,EAAE,4BAA4B,GACvC,IAAI,CAUN;AAED,qDAAqD;AACrD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,OAAO,GAAG,MAAM,GACtB,mBAAmB,CAErB;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;IAUnC,sCAAsC;;CAE9B,CAAC;AAEX,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;CAmBF,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { buttonRecipe } from "./base-recipes.js";
2
+ import { control, radius, spacing, typography } from "./foundations.js";
3
+ /**
4
+ * 값의 출처는 각 제공자의 공개 브랜드 가이드라인이다(2026-09 확인).
5
+ * 로고 이미지는 포함하지 않는다 — 배포 조건이 제공자마다 다르고, HJM이 재배포할 권리가
6
+ * 없다. 가이드라인이 바뀌면 이 표를 고치는 것이 유일한 변경 지점이다.
7
+ */
8
+ export const authProviderPalettes = {
9
+ // Google Identity: 흰 버튼 #FFFFFF / 글자 #1F1F1F / 테두리 #747775,
10
+ // 어두운 변형 #131314 / #E3E3E3 / #8E918F.
11
+ google: {
12
+ light: { background: "#FFFFFF", content: "#1F1F1F", border: "#747775" },
13
+ dark: { background: "#131314", content: "#E3E3E3", border: "#8E918F" },
14
+ },
15
+ // Kakao 로그인: 배경 #FEE500 고정, 글자는 검정 85% 불투명도.
16
+ kakao: {
17
+ light: { background: "#FEE500", content: "rgba(0, 0, 0, 0.85)", border: null },
18
+ dark: { background: "#FEE500", content: "rgba(0, 0, 0, 0.85)", border: null },
19
+ },
20
+ // 네이버 로그인: 배경 #03C75A 고정, 글자 흰색.
21
+ naver: {
22
+ light: { background: "#03C75A", content: "#FFFFFF", border: null },
23
+ dark: { background: "#03C75A", content: "#FFFFFF", border: null },
24
+ },
25
+ // Sign in with Apple: 검정 버튼이 기본, 밝은 배경 위에서는 흰 버튼 + 검은 테두리.
26
+ apple: {
27
+ light: { background: "#000000", content: "#FFFFFF", border: null },
28
+ dark: { background: "#FFFFFF", content: "#000000", border: "#000000" },
29
+ },
30
+ };
31
+ export function validateAuthProviderButtonDescriptor(descriptor) {
32
+ if (descriptor === null || typeof descriptor !== "object") {
33
+ throw new TypeError("AuthProviderButton descriptor must be an object");
34
+ }
35
+ if (!Object.prototype.hasOwnProperty.call(authProviderPalettes, descriptor.provider)) {
36
+ throw new TypeError(`Unsupported auth provider: ${String(descriptor.provider)}`);
37
+ }
38
+ if (typeof descriptor.label !== "string" || descriptor.label.trim().length === 0) {
39
+ throw new TypeError("AuthProviderButton label must not be empty");
40
+ }
41
+ }
42
+ /** 해석된 테마에 맞는 제공자 표면. 테마는 *변형 선택*만 하고 색을 만들지 않는다. */
43
+ export function resolveAuthProviderSurface(provider, theme) {
44
+ return authProviderPalettes[provider][theme];
45
+ }
46
+ /**
47
+ * 크기는 HJM 것이다 — 한 화면에 네 개가 세로로 쌓이므로 높이·radius·간격이 서로 다르면
48
+ * 목록이 무너진다. `buttonRecipe`의 medium 높이와 같은 값을 쓰고, 최소 터치 타깃도 공유한다.
49
+ */
50
+ export const authProviderButtonRecipe = {
51
+ slots: ["root", "logo", "label", "spinner"],
52
+ minHeight: buttonRecipe.sizes.medium.height,
53
+ minTouchTarget: control.minTouchTarget,
54
+ radius: radius.md,
55
+ paddingHorizontal: spacing.md,
56
+ gap: spacing.sm,
57
+ logoSize: 20,
58
+ label: typography.body,
59
+ borderWidth: 1,
60
+ /** 제공자 색 위에서도 보이도록 포커스 링은 바깥에 그린다. */
61
+ focusOutlineOffset: 2,
62
+ };
63
+ export const authProviderButtonBehavior = {
64
+ controlled: [],
65
+ inputs: ["provider", "label", "busy", "disabled"],
66
+ events: ["onPress"],
67
+ stateAxes: {
68
+ availability: ["enabled", "disabled", "busy"],
69
+ interaction: ["idle", "hover", "focusVisible", "pressed"],
70
+ },
71
+ web: { roles: ["button"], keyboard: ["Enter", "Space"], focus: "native" },
72
+ native: { roles: ["button"], states: ["disabled", "busy"], actions: ["press"] },
73
+ scenarios: [
74
+ "provider-colors-come-from-the-provider-guideline-and-the-theme-never-recolors-them",
75
+ "the-theme-only-picks-between-the-providers-own-light-and-dark-variants",
76
+ "the-logo-asset-is-a-product-supplied-slot-never-bundled-by-the-design-system",
77
+ "the-label-is-product-copy-because-the-required-wording-differs-per-provider-and-language",
78
+ "height-radius-and-touch-target-stay-hjm-so-a-stack-of-providers-lines-up",
79
+ "busy-keeps-the-label-and-the-button-width-instead-of-collapsing-to-a-spinner",
80
+ "the-focus-ring-is-drawn-outside-the-brand-fill-so-it-survives-every-provider-color",
81
+ ],
82
+ };
83
+ //# sourceMappingURL=provider-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-button.js","sourceRoot":"","sources":["../src/provider-button.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAqCxE;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,4DAA4D;IAC5D,sCAAsC;IACtC,MAAM,EAAE;QACN,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;QACvE,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;KACvE;IACD,6CAA6C;IAC7C,KAAK,EAAE;QACL,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,IAAI,EAAE;QAC9E,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,IAAI,EAAE;KAC9E;IACD,iCAAiC;IACjC,KAAK,EAAE;QACL,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;QAClE,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;KAClE;IACD,2DAA2D;IAC3D,KAAK,EAAE;QACL,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;QAClE,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;KACvE;CACuE,CAAC;AAW3E,MAAM,UAAU,oCAAoC,CAClD,UAAwC;IAExC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrF,MAAM,IAAI,SAAS,CAAC,8BAA8B,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,0BAA0B,CACxC,QAAwB,EACxB,KAAuB;IAEvB,OAAO,oBAAoB,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAU;IACpD,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;IAC3C,cAAc,EAAE,OAAO,CAAC,cAAc;IACtC,MAAM,EAAE,MAAM,CAAC,EAAE;IACjB,iBAAiB,EAAE,OAAO,CAAC,EAAE;IAC7B,GAAG,EAAE,OAAO,CAAC,EAAE;IACf,QAAQ,EAAE,EAAE;IACZ,KAAK,EAAE,UAAU,CAAC,IAAI;IACtB,WAAW,EAAE,CAAC;IACd,sCAAsC;IACtC,kBAAkB,EAAE,CAAC;CACb,CAAC;AAEX,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,UAAU,EAAE,EAAE;IACd,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC;IACnB,SAAS,EAAE;QACT,YAAY,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC;QAC7C,WAAW,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,CAAC;KAC1D;IACD,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACzE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;IAC/E,SAAS,EAAE;QACT,oFAAoF;QACpF,wEAAwE;QACxE,8EAA8E;QAC9E,0FAA0F;QAC1F,0EAA0E;QAC1E,8EAA8E;QAC9E,oFAAoF;KACrF;CACkC,CAAC","sourcesContent":["import type { BehaviorContract } from \"./behaviors.js\";\nimport { buttonRecipe } from \"./base-recipes.js\";\nimport { control, radius, spacing, typography } from \"./foundations.js\";\n\n/**\n * 소셜 로그인 버튼이다. Button의 tone 하나로 풀 수 없어서 별도 계약으로 둔다.\n *\n * HJM의 tone은 **의미**(primary/secondary/danger)이고 팔레트가 테마를 따라 움직인다.\n * 제공자 버튼의 색은 의미가 아니라 **남의 브랜드 자산**이다 — Google·Kakao·Naver·Apple이\n * 각자 로그인 버튼의 배경·글자·테두리·최소 크기를 브랜드 가이드라인으로 규정하고, 심사에서\n * 그대로 쓰기를 요구한다. 그래서 이 색들은 semantic token이 아니고 테마가 다시 칠하지\n * 않는다. 제품이 `.hjm-button.bt-provider-google` 같은 CSS로 덮어 오던 자리를 계약으로\n * 올리되, 값의 출처가 HJM이 아니라는 사실을 타입으로 드러낸다.\n *\n * **HJM이 소유하는 것**: 높이·radius·터치 타깃·포커스 링·로고와 라벨의 배치·큰 글자 대응.\n * **제공자가 소유하는 것**: 색과 로고 모양.\n * **제품이 소유하는 것**: 로고 자산(재배포하지 않으므로 슬롯으로 받는다)과 현지화된 문구\n * (\"Google로 계속하기\"의 정확한 표현은 제공자 가이드라인과 언어에 따라 다르다).\n */\nexport type AuthProviderId = \"google\" | \"kakao\" | \"naver\" | \"apple\";\n\nexport type AuthProviderSurface = Readonly<{\n /** 제공자 가이드라인이 지정한 배경색. HJM 팔레트가 아니다. */\n background: string;\n /** 같은 가이드라인의 글자/로고 색. */\n content: string;\n /** 배경이 캔버스와 구분되지 않을 때만 가이드라인이 요구하는 테두리. */\n border: string | null;\n}>;\n\nexport type AuthProviderPalette = Readonly<{\n light: AuthProviderSurface;\n /**\n * 제공자가 다크 변형을 따로 규정한 경우에만 다르다. 브랜드색 자체가 정체성인\n * Kakao·Naver는 다크에서도 같은 색을 쓰라고 명시하므로 light와 동일하다.\n */\n dark: AuthProviderSurface;\n}>;\n\n/**\n * 값의 출처는 각 제공자의 공개 브랜드 가이드라인이다(2026-09 확인).\n * 로고 이미지는 포함하지 않는다 — 배포 조건이 제공자마다 다르고, HJM이 재배포할 권리가\n * 없다. 가이드라인이 바뀌면 이 표를 고치는 것이 유일한 변경 지점이다.\n */\nexport const authProviderPalettes = {\n // Google Identity: 흰 버튼 #FFFFFF / 글자 #1F1F1F / 테두리 #747775,\n // 어두운 변형 #131314 / #E3E3E3 / #8E918F.\n google: {\n light: { background: \"#FFFFFF\", content: \"#1F1F1F\", border: \"#747775\" },\n dark: { background: \"#131314\", content: \"#E3E3E3\", border: \"#8E918F\" },\n },\n // Kakao 로그인: 배경 #FEE500 고정, 글자는 검정 85% 불투명도.\n kakao: {\n light: { background: \"#FEE500\", content: \"rgba(0, 0, 0, 0.85)\", border: null },\n dark: { background: \"#FEE500\", content: \"rgba(0, 0, 0, 0.85)\", border: null },\n },\n // 네이버 로그인: 배경 #03C75A 고정, 글자 흰색.\n naver: {\n light: { background: \"#03C75A\", content: \"#FFFFFF\", border: null },\n dark: { background: \"#03C75A\", content: \"#FFFFFF\", border: null },\n },\n // Sign in with Apple: 검정 버튼이 기본, 밝은 배경 위에서는 흰 버튼 + 검은 테두리.\n apple: {\n light: { background: \"#000000\", content: \"#FFFFFF\", border: null },\n dark: { background: \"#FFFFFF\", content: \"#000000\", border: \"#000000\" },\n },\n} as const satisfies Readonly<Record<AuthProviderId, AuthProviderPalette>>;\n\nexport type AuthProviderButtonDescriptor = Readonly<{\n provider: AuthProviderId;\n /** 제공자 가이드라인과 언어에 맞춘 문구. renderer가 만들지 않는다. */\n label: string;\n /** 진행 중 표시. 라벨을 지우지 않고 버튼 폭도 유지한다. */\n busy?: boolean;\n disabled?: boolean;\n}>;\n\nexport function validateAuthProviderButtonDescriptor(\n descriptor: AuthProviderButtonDescriptor,\n): void {\n if (descriptor === null || typeof descriptor !== \"object\") {\n throw new TypeError(\"AuthProviderButton descriptor must be an object\");\n }\n if (!Object.prototype.hasOwnProperty.call(authProviderPalettes, descriptor.provider)) {\n throw new TypeError(`Unsupported auth provider: ${String(descriptor.provider)}`);\n }\n if (typeof descriptor.label !== \"string\" || descriptor.label.trim().length === 0) {\n throw new TypeError(\"AuthProviderButton label must not be empty\");\n }\n}\n\n/** 해석된 테마에 맞는 제공자 표면. 테마는 *변형 선택*만 하고 색을 만들지 않는다. */\nexport function resolveAuthProviderSurface(\n provider: AuthProviderId,\n theme: \"light\" | \"dark\",\n): AuthProviderSurface {\n return authProviderPalettes[provider][theme];\n}\n\n/**\n * 크기는 HJM 것이다 — 한 화면에 네 개가 세로로 쌓이므로 높이·radius·간격이 서로 다르면\n * 목록이 무너진다. `buttonRecipe`의 medium 높이와 같은 값을 쓰고, 최소 터치 타깃도 공유한다.\n */\nexport const authProviderButtonRecipe = {\n slots: [\"root\", \"logo\", \"label\", \"spinner\"] as const,\n minHeight: buttonRecipe.sizes.medium.height,\n minTouchTarget: control.minTouchTarget,\n radius: radius.md,\n paddingHorizontal: spacing.md,\n gap: spacing.sm,\n logoSize: 20,\n label: typography.body,\n borderWidth: 1,\n /** 제공자 색 위에서도 보이도록 포커스 링은 바깥에 그린다. */\n focusOutlineOffset: 2,\n} as const;\n\nexport const authProviderButtonBehavior = {\n controlled: [],\n inputs: [\"provider\", \"label\", \"busy\", \"disabled\"],\n events: [\"onPress\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\", \"busy\"],\n interaction: [\"idle\", \"hover\", \"focusVisible\", \"pressed\"],\n },\n web: { roles: [\"button\"], keyboard: [\"Enter\", \"Space\"], focus: \"native\" },\n native: { roles: [\"button\"], states: [\"disabled\", \"busy\"], actions: [\"press\"] },\n scenarios: [\n \"provider-colors-come-from-the-provider-guideline-and-the-theme-never-recolors-them\",\n \"the-theme-only-picks-between-the-providers-own-light-and-dark-variants\",\n \"the-logo-asset-is-a-product-supplied-slot-never-bundled-by-the-design-system\",\n \"the-label-is-product-copy-because-the-required-wording-differs-per-provider-and-language\",\n \"height-radius-and-touch-target-stay-hjm-so-a-stack-of-providers-lines-up\",\n \"busy-keeps-the-label-and-the-button-width-instead-of-collapsing-to-a-spinner\",\n \"the-focus-ring-is-drawn-outside-the-brand-fill-so-it-survives-every-provider-color\",\n ],\n} as const satisfies BehaviorContract;\n"]}
package/dist/recipes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { buttonRecipe, fieldRecipe, surfaceDefaults, surfaceGeometry, surfaceRecipe, type ButtonSize, type ButtonTone, type FieldShape, type FieldVariant, type SurfacePadding, type SurfaceRadius, type SurfaceTone, } from "./base-recipes.js";
2
- export { accordionRecipe, alertDialogRecipe, avatarRecipe, badgeRecipe, bottomNavigationRecipe, bottomCtaRecipe, chipRecipe, comboboxRecipe, counterBadgeRecipe, dialogRecipe, dividerRecipe, emptyStateRecipe, formatCounterBadgeCount, iconButtonRecipe, iconRecipe, linkRecipe, listRecipe, listRowRecipe, loadMoreRecipe, menuRecipe, noticeRecipe, progressRecipe, searchFieldRecipe, selectRecipe, selectionGroupRecipe, sectionRecipe, segmentedControlRecipe, selectionControlRecipe, sheetRecipe, skeletonRecipe, spinnerRecipe, stackRecipe, statisticRecipe, switchRecipe, tabsRecipe, textRecipe, toastRecipe, tooltipRecipe, topBarRecipe, type AccordionDensity, type AlertDialogTone, type AvatarShape, type AvatarSize, type BadgeSize, type BadgeTone, type BadgeVariant, type BottomNavigationDensity, type BottomNavigationDistribution, type BottomNavigationPresentation, type ChipSize, type SelectDensity, type SelectSize, type CounterBadgeSize, type CounterBadgeTone, type CounterBadgeVariant, type DialogSize, type IconButtonShape, type IconButtonSize, type IconTone, type IconWeight, type LinkTone, type LinkVariant, type LoadMoreDensity, type ListRowDensity, type MenuDensity, type MenuItemTone, type NoticeTone, type ProgressSize, type ProgressTone, type SearchFieldSize, type SegmentedControlSize, type SelectionControlKind, type SelectionControlPresentation, type SelectionControlSize, type SelectionGroupOrientation, type SelectionGroupPresentation, type SpinnerSize, type SpinnerTone, type StackAlign, type StackAxis, type StackGap, type StackJustify, type StatisticDensity, type StatisticPresentation, type SwitchSize, type TabSize, type TabsLayout, type TabsOverflow, type TextEmphasis, type TextTone, type ToastPlacement, type ToastTone, type ToastToneMark, } from "./component-recipes.js";
2
+ export { accordionRecipe, alertDialogRecipe, avatarRecipe, badgeRecipe, bottomNavigationRecipe, bottomCtaRecipe, chipRecipe, comboboxRecipe, counterBadgeRecipe, dialogRecipe, dividerRecipe, emptyStateRecipe, formatCounterBadgeCount, iconButtonRecipe, iconRecipe, linkRecipe, listRecipe, listRowRecipe, loadMoreRecipe, menuRecipe, noticeRecipe, progressRecipe, searchFieldRecipe, selectRecipe, selectionGroupRecipe, sectionRecipe, segmentedControlRecipe, selectionControlRecipe, sheetRecipe, skeletonRecipe, spinnerRecipe, stackRecipe, statisticRecipe, switchRecipe, tabsRecipe, textRecipe, toastRecipe, tooltipRecipe, topBarRecipe, type AccordionDensity, type AlertDialogTone, type AvatarShape, type AvatarSize, type BadgeSize, type BadgeTone, type BadgeVariant, type BottomNavigationDensity, type BottomNavigationDistribution, type BottomNavigationPresentation, type ChipSize, type SelectDensity, type SelectSize, type CounterBadgeSize, type CounterBadgeTone, type CounterBadgeVariant, type DialogSize, type IconButtonShape, type IconButtonSize, type IconTone, type IconWeight, type LinkTone, type LinkVariant, type LoadMoreDensity, type ListRowDensity, type MenuDensity, type MenuItemTone, type NoticeTone, type ProgressShape, type ProgressSize, type ProgressTone, type SearchFieldSize, type SegmentedControlSize, type SelectionControlKind, type SelectionControlPresentation, type SelectionControlSize, type SelectionGroupOrientation, type SelectionGroupPresentation, type SpinnerSize, type SpinnerTone, type StackAlign, type StackAxis, type StackGap, type StackJustify, type StatisticDensity, type StatisticPresentation, type SwitchSize, type TabSize, type TabsLayout, type TabsOverflow, type TextEmphasis, type TextTone, type ToastPlacement, type ToastTone, type ToastToneMark, } from "./component-recipes.js";
3
3
  export { breadcrumbRecipe } from "./breadcrumb.js";
4
4
  export { aspectRatioRecipe } from "./aspect-ratio.js";
5
5
  export { containerRecipe } from "./container.js";
@@ -31,4 +31,18 @@ export { timelineRecipe } from "./timeline.js";
31
31
  export { treeRecipe } from "./tree.js";
32
32
  export { uploadItemRecipe } from "./upload-item.js";
33
33
  export { visuallyHiddenRecipe } from "./visually-hidden.js";
34
+ export { anchorRecipe } from "./anchor.js";
35
+ export { agreementRecipe } from "./agreement.js";
36
+ export { topRecipe } from "./top.js";
37
+ export { authProviderButtonRecipe } from "./provider-button.js";
38
+ export { headingRecipe } from "./heading.js";
39
+ export { toggleGroupRecipe } from "./toggle-group.js";
40
+ export { tagsInputRecipe } from "./tags-input.js";
41
+ export { skipNavRecipe } from "./skip-nav.js";
42
+ export { bottomInfoRecipe } from "./bottom-info.js";
43
+ export { sidebarRecipe } from "./sidebar.js";
44
+ export { textFormatRecipe } from "./text-formats.js";
45
+ export { collapsibleRecipe } from "./collapsible.js";
46
+ export { assetRecipe } from "./asset.js";
47
+ export { menubarRecipe } from "./menubar.js";
34
48
  //# sourceMappingURL=recipes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"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"}
package/dist/recipes.js CHANGED
@@ -46,4 +46,18 @@ export { timelineRecipe } from "./timeline.js";
46
46
  export { treeRecipe } from "./tree.js";
47
47
  export { uploadItemRecipe } from "./upload-item.js";
48
48
  export { visuallyHiddenRecipe } from "./visually-hidden.js";
49
+ export { anchorRecipe } from "./anchor.js";
50
+ export { agreementRecipe } from "./agreement.js";
51
+ export { topRecipe } from "./top.js";
52
+ export { authProviderButtonRecipe } from "./provider-button.js";
53
+ export { headingRecipe } from "./heading.js";
54
+ export { toggleGroupRecipe } from "./toggle-group.js";
55
+ export { tagsInputRecipe } from "./tags-input.js";
56
+ export { skipNavRecipe } from "./skip-nav.js";
57
+ export { bottomInfoRecipe } from "./bottom-info.js";
58
+ export { sidebarRecipe } from "./sidebar.js";
59
+ export { textFormatRecipe } from "./text-formats.js";
60
+ export { collapsibleRecipe } from "./collapsible.js";
61
+ export { assetRecipe } from "./asset.js";
62
+ export { menubarRecipe } from "./menubar.js";
49
63
  //# sourceMappingURL=recipes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recipes.js","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EACf,aAAa,GAQd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,YAAY,EACZ,UAAU,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,GAuDb,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;EAUE;AACF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAyB,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,iEAAiE;AACjE,yEAAyE;AACzE,sDAAsD;AACtD,yDAAyD;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC","sourcesContent":["export {\n buttonRecipe,\n fieldRecipe,\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type ButtonSize,\n type ButtonTone,\n type FieldShape,\n type FieldVariant,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"./base-recipes.js\";\n\nexport {\n accordionRecipe,\n alertDialogRecipe,\n avatarRecipe,\n badgeRecipe,\n bottomNavigationRecipe,\n bottomCtaRecipe,\n chipRecipe,\n comboboxRecipe,\n counterBadgeRecipe,\n dialogRecipe,\n dividerRecipe,\n emptyStateRecipe,\n formatCounterBadgeCount,\n iconButtonRecipe,\n iconRecipe,\n linkRecipe,\n listRecipe,\n listRowRecipe,\n loadMoreRecipe,\n menuRecipe,\n noticeRecipe,\n progressRecipe,\n searchFieldRecipe,\n selectRecipe,\n selectionGroupRecipe,\n sectionRecipe,\n segmentedControlRecipe,\n selectionControlRecipe,\n sheetRecipe,\n skeletonRecipe,\n spinnerRecipe,\n stackRecipe,\n statisticRecipe,\n switchRecipe,\n tabsRecipe,\n textRecipe,\n toastRecipe,\n tooltipRecipe,\n topBarRecipe,\n type AccordionDensity,\n type AlertDialogTone,\n type AvatarShape,\n type AvatarSize,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant,\n type BottomNavigationDensity,\n type BottomNavigationDistribution,\n type BottomNavigationPresentation,\n type ChipSize,\n type SelectDensity,\n type SelectSize,\n type CounterBadgeSize,\n type CounterBadgeTone,\n type CounterBadgeVariant,\n type DialogSize,\n type IconButtonShape,\n type IconButtonSize,\n type IconTone,\n type IconWeight,\n type LinkTone,\n type LinkVariant,\n type LoadMoreDensity,\n type ListRowDensity,\n type MenuDensity,\n type MenuItemTone,\n type NoticeTone,\n type ProgressSize,\n type ProgressTone,\n type SearchFieldSize,\n type SegmentedControlSize,\n type SelectionControlKind,\n type SelectionControlPresentation,\n type SelectionControlSize,\n type SelectionGroupOrientation,\n type SelectionGroupPresentation,\n type SpinnerSize,\n type SpinnerTone,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type StatisticDensity,\n type StatisticPresentation,\n type SwitchSize,\n type TabSize,\n type TabsLayout,\n type TabsOverflow,\n type TextEmphasis,\n type TextTone,\n type ToastPlacement,\n type ToastTone,\n type ToastToneMark,\n} from \"./component-recipes.js\";\n\n/*\n Batch 2 저작 모듈의 시각 recipe.\n\n 각 컴포넌트의 계약·recipe·행동을 한 모듈에 자급자족으로 담고, 여기서는 **경로만**\n 모은다(`docs/authoring-brief.md`). 여러 저작자가 병렬로 작업할 때 공유 레지스트리를\n 각자 고치면 서로의 변경을 덮어쓰므로, 배선은 리드가 한 번에 한다.\n\n recipe 본문을 `component-recipes.ts`로 옮기지 않는 이유: 그 파일은 이미 1,500줄이 넘고,\n 계약(타입·validator·resolver)과 recipe가 **같은 컴포넌트를 두 파일로 갈라** 놓으면\n 둘이 어긋날 자리가 생긴다. 한 컴포넌트는 한 모듈에 둔다.\n*/\nexport { breadcrumbRecipe } from \"./breadcrumb.js\";\nexport { aspectRatioRecipe } from \"./aspect-ratio.js\";\nexport { containerRecipe } from \"./container.js\";\nexport { cardRecipe, type CardHeadingLevel } from \"./card.js\";\nexport { calendarRecipe } from \"./calendar.js\";\nexport { carouselRecipe } from \"./carousel.js\";\nexport { commandPaletteRecipe } from \"./command-palette.js\";\nexport { dataTableRecipe } from \"./data-table.js\";\nexport { transferListRecipe } from \"./transfer-list.js\";\n// floatingActionButtonRecipe는 여기서 재수출하지 않는다. 이 모듈이 buttonRecipe를\n// 정의하는데 floating-action-button.ts가 그것을 import하므로, 여기에 `export ... from`을\n// 두면 순환이 된다 — ESM은 재수출을 본문보다 먼저 평가해서 buttonRecipe가 아직\n// undefined인 채로 그 모듈이 실행된다. catalog.ts가 해당 모듈에서 직접 가져간다.\nexport { tourRecipe } from \"./tour.js\";\nexport { layoutRecipe } from \"./layout.js\";\nexport { otpFieldRecipe } from \"./otp-field.js\";\nexport { passwordFieldRecipe } from \"./password-field.js\";\nexport { splitterRecipe } from \"./splitter.js\";\nexport { datePickerRecipe } from \"./date-picker.js\";\nexport { descriptionListRecipe } from \"./description-list.js\";\nexport { filePickerRecipe } from \"./file-picker.js\";\nexport { formRecipe } from \"./form.js\";\nexport { imageRecipe } from \"./image.js\";\nexport { numberFieldRecipe } from \"./number-field.js\";\nexport { paginationRecipe } from \"./pagination.js\";\nexport { popoverRecipe } from \"./popover.js\";\nexport { resultRecipe } from \"./result.js\";\nexport { sliderRecipe } from \"./slider.js\";\nexport { stepsRecipe } from \"./steps.js\";\nexport { tagRecipe } from \"./tag.js\";\nexport { sidePanelRecipe } from \"./side-panel.js\";\nexport { timelineRecipe } from \"./timeline.js\";\nexport { treeRecipe } from \"./tree.js\";\nexport { uploadItemRecipe } from \"./upload-item.js\";\nexport { visuallyHiddenRecipe } from \"./visually-hidden.js\";\n"]}
1
+ {"version":3,"file":"recipes.js","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n buttonRecipe,\n fieldRecipe,\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type ButtonSize,\n type ButtonTone,\n type FieldShape,\n type FieldVariant,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"./base-recipes.js\";\n\nexport {\n accordionRecipe,\n alertDialogRecipe,\n avatarRecipe,\n badgeRecipe,\n bottomNavigationRecipe,\n bottomCtaRecipe,\n chipRecipe,\n comboboxRecipe,\n counterBadgeRecipe,\n dialogRecipe,\n dividerRecipe,\n emptyStateRecipe,\n formatCounterBadgeCount,\n iconButtonRecipe,\n iconRecipe,\n linkRecipe,\n listRecipe,\n listRowRecipe,\n loadMoreRecipe,\n menuRecipe,\n noticeRecipe,\n progressRecipe,\n searchFieldRecipe,\n selectRecipe,\n selectionGroupRecipe,\n sectionRecipe,\n segmentedControlRecipe,\n selectionControlRecipe,\n sheetRecipe,\n skeletonRecipe,\n spinnerRecipe,\n stackRecipe,\n statisticRecipe,\n switchRecipe,\n tabsRecipe,\n textRecipe,\n toastRecipe,\n tooltipRecipe,\n topBarRecipe,\n type AccordionDensity,\n type AlertDialogTone,\n type AvatarShape,\n type AvatarSize,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant,\n type BottomNavigationDensity,\n type BottomNavigationDistribution,\n type BottomNavigationPresentation,\n type ChipSize,\n type SelectDensity,\n type SelectSize,\n type CounterBadgeSize,\n type CounterBadgeTone,\n type CounterBadgeVariant,\n type DialogSize,\n type IconButtonShape,\n type IconButtonSize,\n type IconTone,\n type IconWeight,\n type LinkTone,\n type LinkVariant,\n type LoadMoreDensity,\n type ListRowDensity,\n type MenuDensity,\n type MenuItemTone,\n type NoticeTone,\n type ProgressShape,\n type ProgressSize,\n type ProgressTone,\n type SearchFieldSize,\n type SegmentedControlSize,\n type SelectionControlKind,\n type SelectionControlPresentation,\n type SelectionControlSize,\n type SelectionGroupOrientation,\n type SelectionGroupPresentation,\n type SpinnerSize,\n type SpinnerTone,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type StatisticDensity,\n type StatisticPresentation,\n type SwitchSize,\n type TabSize,\n type TabsLayout,\n type TabsOverflow,\n type TextEmphasis,\n type TextTone,\n type ToastPlacement,\n type ToastTone,\n type ToastToneMark,\n} from \"./component-recipes.js\";\n\n/*\n Batch 2 저작 모듈의 시각 recipe.\n\n 각 컴포넌트의 계약·recipe·행동을 한 모듈에 자급자족으로 담고, 여기서는 **경로만**\n 모은다(`docs/authoring-brief.md`). 여러 저작자가 병렬로 작업할 때 공유 레지스트리를\n 각자 고치면 서로의 변경을 덮어쓰므로, 배선은 리드가 한 번에 한다.\n\n recipe 본문을 `component-recipes.ts`로 옮기지 않는 이유: 그 파일은 이미 1,500줄이 넘고,\n 계약(타입·validator·resolver)과 recipe가 **같은 컴포넌트를 두 파일로 갈라** 놓으면\n 둘이 어긋날 자리가 생긴다. 한 컴포넌트는 한 모듈에 둔다.\n*/\nexport { breadcrumbRecipe } from \"./breadcrumb.js\";\nexport { aspectRatioRecipe } from \"./aspect-ratio.js\";\nexport { containerRecipe } from \"./container.js\";\nexport { cardRecipe, type CardHeadingLevel } from \"./card.js\";\nexport { calendarRecipe } from \"./calendar.js\";\nexport { carouselRecipe } from \"./carousel.js\";\nexport { commandPaletteRecipe } from \"./command-palette.js\";\nexport { dataTableRecipe } from \"./data-table.js\";\nexport { transferListRecipe } from \"./transfer-list.js\";\n// floatingActionButtonRecipe는 여기서 재수출하지 않는다. 이 모듈이 buttonRecipe를\n// 정의하는데 floating-action-button.ts가 그것을 import하므로, 여기에 `export ... from`을\n// 두면 순환이 된다 — ESM은 재수출을 본문보다 먼저 평가해서 buttonRecipe가 아직\n// undefined인 채로 그 모듈이 실행된다. catalog.ts가 해당 모듈에서 직접 가져간다.\nexport { tourRecipe } from \"./tour.js\";\nexport { layoutRecipe } from \"./layout.js\";\nexport { otpFieldRecipe } from \"./otp-field.js\";\nexport { passwordFieldRecipe } from \"./password-field.js\";\nexport { splitterRecipe } from \"./splitter.js\";\nexport { datePickerRecipe } from \"./date-picker.js\";\nexport { descriptionListRecipe } from \"./description-list.js\";\nexport { filePickerRecipe } from \"./file-picker.js\";\nexport { formRecipe } from \"./form.js\";\nexport { imageRecipe } from \"./image.js\";\nexport { numberFieldRecipe } from \"./number-field.js\";\nexport { paginationRecipe } from \"./pagination.js\";\nexport { popoverRecipe } from \"./popover.js\";\nexport { resultRecipe } from \"./result.js\";\nexport { sliderRecipe } from \"./slider.js\";\nexport { stepsRecipe } from \"./steps.js\";\nexport { tagRecipe } from \"./tag.js\";\nexport { sidePanelRecipe } from \"./side-panel.js\";\nexport { timelineRecipe } from \"./timeline.js\";\nexport { treeRecipe } from \"./tree.js\";\nexport { uploadItemRecipe } from \"./upload-item.js\";\nexport { visuallyHiddenRecipe } from \"./visually-hidden.js\";\n\nexport { anchorRecipe } from \"./anchor.js\";\nexport { agreementRecipe } from \"./agreement.js\";\nexport { topRecipe } from \"./top.js\";\nexport { authProviderButtonRecipe } from \"./provider-button.js\";\nexport { headingRecipe } from \"./heading.js\";\nexport { toggleGroupRecipe } from \"./toggle-group.js\";\nexport { tagsInputRecipe } from \"./tags-input.js\";\nexport { skipNavRecipe } from \"./skip-nav.js\";\nexport { bottomInfoRecipe } from \"./bottom-info.js\";\nexport { sidebarRecipe } from \"./sidebar.js\";\nexport { textFormatRecipe } from \"./text-formats.js\";\nexport { collapsibleRecipe } from \"./collapsible.js\";\nexport { assetRecipe } from \"./asset.js\";\nexport { menubarRecipe } from \"./menubar.js\";\n"]}
package/dist/sheet.d.ts CHANGED
@@ -48,4 +48,20 @@ export type SheetLifecycle = Readonly<{
48
48
  * Platform adapters still decide when native dismissal has actually completed.
49
49
  */
50
50
  export declare function createSheetLifecycle(initiallyVisible?: boolean): SheetLifecycle;
51
+ /**
52
+ * 사용자가 시트 높이를 바꾸는 축이다. `sheetRecipe.sizes`는 제품이 여는 높이를 정하고,
53
+ * 이것은 열린 뒤 **사용자가** 단계를 옮기는 문제다 — 지도 위 목록처럼 "조금 보기 ↔ 크게
54
+ * 보기"가 필요한 화면이 그 자리다.
55
+ *
56
+ * `auto`는 단계에 들어가지 않는다. 내용이 정하는 높이라 "다음 단계"가 정의되지 않는다.
57
+ *
58
+ * **드래그 물리는 여기 없다.** 이 계약은 단계 목록과 "다음/이전 단계가 무엇인가"만 갖고,
59
+ * 손가락 속도·관성·고무줄은 넣지 않았다 — 실제 제품 화면 없이 그 값을 정하면 기기에서
60
+ * 다시 다 고치게 된다. 대신 **핸들이 접근 가능한 컨트롤**이라 키보드·보조기기에서도
61
+ * 단계를 옮길 수 있다. 제스처는 제품이 얹고, 결과를 같은 `onDetentChange`로 보낸다.
62
+ */
63
+ export type SheetDetent = "medium" | "large" | "full";
64
+ export declare const sheetDetentOrder: readonly ["medium", "large", "full"];
65
+ export declare function validateSheetDetents(detents: readonly SheetDetent[]): void;
66
+ export declare function resolveNextSheetDetent(detents: readonly SheetDetent[], current: SheetDetent, direction: "expand" | "collapse"): SheetDetent | null;
51
67
  //# sourceMappingURL=sheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../src/sheet.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,QAAQ,GACR,MAAM,GACN,SAAS,GACT,OAAO,GACP,cAAc,CAAC;AAEnB;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAAC;CACxC,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GACtB,QAAQ,CAAC;IACP,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACnE,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACxE,CAAC,CAAC;AAEP,eAAO,MAAM,qBAAqB;;;;;;CAMK,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,OAAO,EACb,MAAM,GAAE,kBAA0C,GACjD,OAAO,CAUT;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,IAAI,MAAM,CAAC;IACf,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CACV,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IACX,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACzC,CAAC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,gBAAgB,UAAQ,GACvB,cAAc,CAgChB"}
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../src/sheet.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,QAAQ,GACR,MAAM,GACN,SAAS,GACT,OAAO,GACP,cAAc,CAAC;AAEnB;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAAC;CACxC,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GACtB,QAAQ,CAAC;IACP,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACnE,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACxE,CAAC,CAAC;AAEP,eAAO,MAAM,qBAAqB;;;;;;CAMK,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,OAAO,EACb,MAAM,GAAE,kBAA0C,GACjD,OAAO,CAUT;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,IAAI,MAAM,CAAC;IACf,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,CACV,MAAM,EAAE,kBAAkB,EAC1B,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IACX,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACzC,CAAC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,gBAAgB,UAAQ,GACvB,cAAc,CAgChB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtD,eAAO,MAAM,gBAAgB,sCAAwE,CAAC;AAEtG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAsB1E;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,QAAQ,GAAG,UAAU,GAC/B,WAAW,GAAG,IAAI,CASpB"}
package/dist/sheet.js CHANGED
@@ -66,4 +66,37 @@ export function createSheetLifecycle(initiallyVisible = false) {
66
66
  },
67
67
  };
68
68
  }
69
+ export const sheetDetentOrder = ["medium", "large", "full"];
70
+ export function validateSheetDetents(detents) {
71
+ if (detents.length === 0) {
72
+ throw new RangeError("Sheet detents must not be empty");
73
+ }
74
+ const seen = new Set();
75
+ for (const detent of detents) {
76
+ if (!sheetDetentOrder.includes(detent)) {
77
+ throw new TypeError(`Unsupported Sheet detent: ${String(detent)}`);
78
+ }
79
+ if (seen.has(detent))
80
+ throw new TypeError(`Duplicate Sheet detent: ${detent}`);
81
+ seen.add(detent);
82
+ }
83
+ const ordered = [...detents].sort((left, right) => sheetDetentOrder.indexOf(left) - sheetDetentOrder.indexOf(right));
84
+ if (ordered.some((detent, index) => detent !== detents[index])) {
85
+ /*
86
+ 정렬을 대신 해 주지 않는 이유: 순서가 곧 "다음 단계"의 의미라서, 제품이 적은 순서와
87
+ 실제 이동 순서가 다르면 디버깅할 수 없는 화면이 된다.
88
+ */
89
+ throw new TypeError("Sheet detents must be listed from smallest to largest");
90
+ }
91
+ }
92
+ export function resolveNextSheetDetent(detents, current, direction) {
93
+ validateSheetDetents(detents);
94
+ const index = detents.indexOf(current);
95
+ if (index === -1) {
96
+ throw new RangeError(`Sheet current detent is not in the list: ${current}`);
97
+ }
98
+ const next = direction === "expand" ? index + 1 : index - 1;
99
+ /** 끝에서는 `null`이다 — renderer가 "더 갈 수 없다"를 컨트롤 상태로 표현한다. */
100
+ return next < 0 || next >= detents.length ? null : detents[next];
101
+ }
69
102
  //# sourceMappingURL=sheet.js.map