@kodffe/ui 0.0.0-stage → 0.10.1

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 (304) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +11 -0
  2. package/dist/accordion/accordion.d.ts +44 -0
  3. package/dist/accordion/accordion.js +84 -0
  4. package/dist/accordion/accordion.js.map +1 -0
  5. package/dist/alert/alert.d.ts +17 -0
  6. package/dist/alert/alert.js +59 -0
  7. package/dist/alert/alert.js.map +1 -0
  8. package/dist/app-shell/app-footer.d.ts +29 -0
  9. package/dist/app-shell/app-footer.js +39 -0
  10. package/dist/app-shell/app-footer.js.map +1 -0
  11. package/dist/app-shell/app-shell-context.d.ts +10 -0
  12. package/dist/app-shell/app-shell-context.js +12 -0
  13. package/dist/app-shell/app-shell-context.js.map +1 -0
  14. package/dist/app-shell/app-shell.d.ts +42 -0
  15. package/dist/app-shell/app-shell.js +191 -0
  16. package/dist/app-shell/app-shell.js.map +1 -0
  17. package/dist/app-shell/floating-actions.d.ts +19 -0
  18. package/dist/app-shell/floating-actions.js +59 -0
  19. package/dist/app-shell/floating-actions.js.map +1 -0
  20. package/dist/app-shell/workspace-switcher.d.ts +25 -0
  21. package/dist/app-shell/workspace-switcher.js +82 -0
  22. package/dist/app-shell/workspace-switcher.js.map +1 -0
  23. package/dist/badge/badge.d.ts +19 -0
  24. package/dist/badge/badge.js +59 -0
  25. package/dist/badge/badge.js.map +1 -0
  26. package/dist/banner/banner.d.ts +22 -0
  27. package/dist/banner/banner.js +80 -0
  28. package/dist/banner/banner.js.map +1 -0
  29. package/dist/breadcrumbs/breadcrumbs.d.ts +18 -0
  30. package/dist/breadcrumbs/breadcrumbs.js +45 -0
  31. package/dist/breadcrumbs/breadcrumbs.js.map +1 -0
  32. package/dist/button/button.d.ts +38 -0
  33. package/dist/button/button.js +83 -0
  34. package/dist/button/button.js.map +1 -0
  35. package/dist/card/card.d.ts +159 -0
  36. package/dist/card/card.js +390 -0
  37. package/dist/card/card.js.map +1 -0
  38. package/dist/card/insight-card.d.ts +19 -0
  39. package/dist/card/insight-card.js +51 -0
  40. package/dist/card/insight-card.js.map +1 -0
  41. package/dist/card/integration-card.d.ts +19 -0
  42. package/dist/card/integration-card.js +70 -0
  43. package/dist/card/integration-card.js.map +1 -0
  44. package/dist/charts/charts.d.ts +75 -0
  45. package/dist/charts/charts.js +453 -0
  46. package/dist/charts/charts.js.map +1 -0
  47. package/dist/choice/choice.d.ts +39 -0
  48. package/dist/choice/choice.js +143 -0
  49. package/dist/choice/choice.js.map +1 -0
  50. package/dist/combobox/combobox.d.ts +46 -0
  51. package/dist/combobox/combobox.js +196 -0
  52. package/dist/combobox/combobox.js.map +1 -0
  53. package/dist/command-palette/command-palette.d.ts +35 -0
  54. package/dist/command-palette/command-palette.js +164 -0
  55. package/dist/command-palette/command-palette.js.map +1 -0
  56. package/dist/confirm-dialog/confirm-dialog.d.ts +37 -0
  57. package/dist/confirm-dialog/confirm-dialog.js +106 -0
  58. package/dist/confirm-dialog/confirm-dialog.js.map +1 -0
  59. package/dist/content/assistant.d.ts +86 -0
  60. package/dist/content/assistant.js +213 -0
  61. package/dist/content/assistant.js.map +1 -0
  62. package/dist/content/content.d.ts +45 -0
  63. package/dist/content/content.js +136 -0
  64. package/dist/content/content.js.map +1 -0
  65. package/dist/data-display/avatar-sizes.d.ts +8 -0
  66. package/dist/data-display/avatar-sizes.js +12 -0
  67. package/dist/data-display/avatar-sizes.js.map +1 -0
  68. package/dist/data-display/avatar.d.ts +21 -0
  69. package/dist/data-display/avatar.js +53 -0
  70. package/dist/data-display/avatar.js.map +1 -0
  71. package/dist/data-display/chip.d.ts +20 -0
  72. package/dist/data-display/chip.js +64 -0
  73. package/dist/data-display/chip.js.map +1 -0
  74. package/dist/data-display/code-block.d.ts +14 -0
  75. package/dist/data-display/code-block.js +50 -0
  76. package/dist/data-display/code-block.js.map +1 -0
  77. package/dist/data-display/data-display.d.ts +73 -0
  78. package/dist/data-display/data-display.js +227 -0
  79. package/dist/data-display/data-display.js.map +1 -0
  80. package/dist/data-display/insights.d.ts +120 -0
  81. package/dist/data-display/insights.js +220 -0
  82. package/dist/data-display/insights.js.map +1 -0
  83. package/dist/data-table/cells.d.ts +86 -0
  84. package/dist/data-table/cells.js +163 -0
  85. package/dist/data-table/cells.js.map +1 -0
  86. package/dist/data-table/data-table.d.ts +112 -0
  87. package/dist/data-table/data-table.js +558 -0
  88. package/dist/data-table/data-table.js.map +1 -0
  89. package/dist/date-picker/date-picker.d.ts +61 -0
  90. package/dist/date-picker/date-picker.js +309 -0
  91. package/dist/date-picker/date-picker.js.map +1 -0
  92. package/dist/drawer/drawer.d.ts +32 -0
  93. package/dist/drawer/drawer.js +72 -0
  94. package/dist/drawer/drawer.js.map +1 -0
  95. package/dist/empty-state/empty-state.d.ts +25 -0
  96. package/dist/empty-state/empty-state.js +78 -0
  97. package/dist/empty-state/empty-state.js.map +1 -0
  98. package/dist/error-state/error-state.d.ts +19 -0
  99. package/dist/error-state/error-state.js +56 -0
  100. package/dist/error-state/error-state.js.map +1 -0
  101. package/dist/event-calendar/calendar-logic.test.d.ts +1 -0
  102. package/dist/event-calendar/dates.d.ts +35 -0
  103. package/dist/event-calendar/dates.js +55 -0
  104. package/dist/event-calendar/dates.js.map +1 -0
  105. package/dist/event-calendar/event-calendar.d.ts +125 -0
  106. package/dist/event-calendar/event-calendar.js +795 -0
  107. package/dist/event-calendar/event-calendar.js.map +1 -0
  108. package/dist/event-calendar/event-details.d.ts +50 -0
  109. package/dist/event-calendar/event-details.js +124 -0
  110. package/dist/event-calendar/event-details.js.map +1 -0
  111. package/dist/event-calendar/layout.d.ts +48 -0
  112. package/dist/event-calendar/layout.js +55 -0
  113. package/dist/event-calendar/layout.js.map +1 -0
  114. package/dist/file-upload/file-upload.d.ts +70 -0
  115. package/dist/file-upload/file-upload.js +307 -0
  116. package/dist/file-upload/file-upload.js.map +1 -0
  117. package/dist/filters/filters.d.ts +48 -0
  118. package/dist/filters/filters.js +103 -0
  119. package/dist/filters/filters.js.map +1 -0
  120. package/dist/form-field/form-field.d.ts +39 -0
  121. package/dist/form-field/form-field.js +88 -0
  122. package/dist/form-field/form-field.js.map +1 -0
  123. package/dist/hover-card/hover-card.d.ts +15 -0
  124. package/dist/hover-card/hover-card.js +27 -0
  125. package/dist/hover-card/hover-card.js.map +1 -0
  126. package/dist/hover-card/person-hover-card.d.ts +26 -0
  127. package/dist/hover-card/person-hover-card.js +85 -0
  128. package/dist/hover-card/person-hover-card.js.map +1 -0
  129. package/dist/icon/icon-tile.d.ts +20 -0
  130. package/dist/icon/icon-tile.js +55 -0
  131. package/dist/icon/icon-tile.js.map +1 -0
  132. package/dist/icon/icon.d.ts +14 -0
  133. package/dist/icon/icon.js +28 -0
  134. package/dist/icon/icon.js.map +1 -0
  135. package/dist/icon/icons.generated.d.ts +358 -0
  136. package/dist/icon/icons.generated.js +362 -0
  137. package/dist/icon/icons.generated.js.map +1 -0
  138. package/dist/index.d.ts +90 -0
  139. package/dist/index.js +88 -0
  140. package/dist/input/extra-inputs.d.ts +122 -0
  141. package/dist/input/extra-inputs.js +351 -0
  142. package/dist/input/extra-inputs.js.map +1 -0
  143. package/dist/input/field-styles.d.ts +5 -0
  144. package/dist/input/field-styles.js +14 -0
  145. package/dist/input/field-styles.js.map +1 -0
  146. package/dist/input/input.d.ts +50 -0
  147. package/dist/input/input.js +107 -0
  148. package/dist/input/input.js.map +1 -0
  149. package/dist/layout/layout.d.ts +41 -0
  150. package/dist/layout/layout.js +90 -0
  151. package/dist/layout/layout.js.map +1 -0
  152. package/dist/lib/control-styles.d.ts +9 -0
  153. package/dist/lib/control-styles.js +16 -0
  154. package/dist/lib/control-styles.js.map +1 -0
  155. package/dist/lib/cx.d.ts +2 -0
  156. package/dist/lib/cx.js +8 -0
  157. package/dist/lib/cx.js.map +1 -0
  158. package/dist/lib/glyphs.d.ts +13 -0
  159. package/dist/lib/glyphs.js +67 -0
  160. package/dist/lib/glyphs.js.map +1 -0
  161. package/dist/lib/segmented-styles.d.ts +8 -0
  162. package/dist/lib/segmented-styles.js +12 -0
  163. package/dist/lib/segmented-styles.js.map +1 -0
  164. package/dist/lib/select-on-arrow.d.ts +7 -0
  165. package/dist/lib/select-on-arrow.js +21 -0
  166. package/dist/lib/select-on-arrow.js.map +1 -0
  167. package/dist/lib/skip-link.d.ts +5 -0
  168. package/dist/lib/skip-link.js +13 -0
  169. package/dist/lib/skip-link.js.map +1 -0
  170. package/dist/lib/use-media-query.d.ts +4 -0
  171. package/dist/lib/use-media-query.js +15 -0
  172. package/dist/lib/use-media-query.js.map +1 -0
  173. package/dist/lists/lists.d.ts +76 -0
  174. package/dist/lists/lists.js +133 -0
  175. package/dist/lists/lists.js.map +1 -0
  176. package/dist/locale-switch/locale-switch.d.ts +29 -0
  177. package/dist/locale-switch/locale-switch.js +62 -0
  178. package/dist/locale-switch/locale-switch.js.map +1 -0
  179. package/dist/logo/logo.d.ts +31 -0
  180. package/dist/logo/logo.js +157 -0
  181. package/dist/logo/logo.js.map +1 -0
  182. package/dist/logo/product-logo.d.ts +19 -0
  183. package/dist/logo/product-logo.js +46 -0
  184. package/dist/logo/product-logo.js.map +1 -0
  185. package/dist/marketing/marketing.d.ts +176 -0
  186. package/dist/marketing/marketing.js +451 -0
  187. package/dist/marketing/marketing.js.map +1 -0
  188. package/dist/marketing/newsletter-form.d.ts +21 -0
  189. package/dist/marketing/newsletter-form.js +100 -0
  190. package/dist/marketing/newsletter-form.js.map +1 -0
  191. package/dist/mascot/mascot.d.ts +28 -0
  192. package/dist/mascot/mascot.js +28 -0
  193. package/dist/mascot/mascot.js.map +1 -0
  194. package/dist/mascot/mascots.generated.d.ts +284 -0
  195. package/dist/mascot/mascots.generated.js +287 -0
  196. package/dist/mascot/mascots.generated.js.map +1 -0
  197. package/dist/master-detail/master-detail.d.ts +30 -0
  198. package/dist/master-detail/master-detail.js +71 -0
  199. package/dist/master-detail/master-detail.js.map +1 -0
  200. package/dist/menu/account-menu.d.ts +44 -0
  201. package/dist/menu/account-menu.js +78 -0
  202. package/dist/menu/account-menu.js.map +1 -0
  203. package/dist/menu/context-menu.d.ts +31 -0
  204. package/dist/menu/context-menu.js +111 -0
  205. package/dist/menu/context-menu.js.map +1 -0
  206. package/dist/menu/dropdown-menu.d.ts +49 -0
  207. package/dist/menu/dropdown-menu.js +152 -0
  208. package/dist/menu/dropdown-menu.js.map +1 -0
  209. package/dist/menu/menu-styles.d.ts +8 -0
  210. package/dist/menu/menu-styles.js +6 -0
  211. package/dist/menu/menu-styles.js.map +1 -0
  212. package/dist/menu/menubar.d.ts +31 -0
  213. package/dist/menu/menubar.js +125 -0
  214. package/dist/menu/menubar.js.map +1 -0
  215. package/dist/modal/modal.d.ts +34 -0
  216. package/dist/modal/modal.js +58 -0
  217. package/dist/modal/modal.js.map +1 -0
  218. package/dist/notification-center/notification-center.d.ts +51 -0
  219. package/dist/notification-center/notification-center.js +244 -0
  220. package/dist/notification-center/notification-center.js.map +1 -0
  221. package/dist/otp-input/otp-input.d.ts +23 -0
  222. package/dist/otp-input/otp-input.js +61 -0
  223. package/dist/otp-input/otp-input.js.map +1 -0
  224. package/dist/overlay/overlay.d.ts +53 -0
  225. package/dist/overlay/overlay.js +103 -0
  226. package/dist/overlay/overlay.js.map +1 -0
  227. package/dist/page-header/page-header.d.ts +55 -0
  228. package/dist/page-header/page-header.js +114 -0
  229. package/dist/page-header/page-header.js.map +1 -0
  230. package/dist/page-header/record-headers.d.ts +51 -0
  231. package/dist/page-header/record-headers.js +134 -0
  232. package/dist/page-header/record-headers.js.map +1 -0
  233. package/dist/page-header/section-header.d.ts +21 -0
  234. package/dist/page-header/section-header.js +44 -0
  235. package/dist/page-header/section-header.js.map +1 -0
  236. package/dist/page-navigation/page-navigation.d.ts +59 -0
  237. package/dist/page-navigation/page-navigation.js +136 -0
  238. package/dist/page-navigation/page-navigation.js.map +1 -0
  239. package/dist/pagination/pagination.d.ts +28 -0
  240. package/dist/pagination/pagination.js +102 -0
  241. package/dist/pagination/pagination.js.map +1 -0
  242. package/dist/phone-input/phone-input.d.ts +34 -0
  243. package/dist/phone-input/phone-input.js +171 -0
  244. package/dist/phone-input/phone-input.js.map +1 -0
  245. package/dist/popover/popover.d.ts +23 -0
  246. package/dist/popover/popover.js +40 -0
  247. package/dist/popover/popover.js.map +1 -0
  248. package/dist/progress/progress.d.ts +21 -0
  249. package/dist/progress/progress.js +49 -0
  250. package/dist/progress/progress.js.map +1 -0
  251. package/dist/segmented-control/segmented-control.d.ts +32 -0
  252. package/dist/segmented-control/segmented-control.js +29 -0
  253. package/dist/segmented-control/segmented-control.js.map +1 -0
  254. package/dist/select/select.d.ts +48 -0
  255. package/dist/select/select.js +136 -0
  256. package/dist/select/select.js.map +1 -0
  257. package/dist/settings/permission-matrix.d.ts +29 -0
  258. package/dist/settings/permission-matrix.js +101 -0
  259. package/dist/settings/permission-matrix.js.map +1 -0
  260. package/dist/settings/settings-row.d.ts +32 -0
  261. package/dist/settings/settings-row.js +63 -0
  262. package/dist/settings/settings-row.js.map +1 -0
  263. package/dist/side-nav/side-nav.d.ts +36 -0
  264. package/dist/side-nav/side-nav.js +123 -0
  265. package/dist/side-nav/side-nav.js.map +1 -0
  266. package/dist/site-header/site-header.d.ts +32 -0
  267. package/dist/site-header/site-header.js +99 -0
  268. package/dist/site-header/site-header.js.map +1 -0
  269. package/dist/skeleton/skeleton.d.ts +16 -0
  270. package/dist/skeleton/skeleton.js +19 -0
  271. package/dist/skeleton/skeleton.js.map +1 -0
  272. package/dist/slider/slider.d.ts +15 -0
  273. package/dist/slider/slider.js +48 -0
  274. package/dist/slider/slider.js.map +1 -0
  275. package/dist/spinner/spinner.d.ts +15 -0
  276. package/dist/spinner/spinner.js +42 -0
  277. package/dist/spinner/spinner.js.map +1 -0
  278. package/dist/stepper/step-dots.d.ts +16 -0
  279. package/dist/stepper/step-dots.js +26 -0
  280. package/dist/stepper/step-dots.js.map +1 -0
  281. package/dist/stepper/stepper.d.ts +26 -0
  282. package/dist/stepper/stepper.js +113 -0
  283. package/dist/stepper/stepper.js.map +1 -0
  284. package/dist/tabs/tabs.d.ts +31 -0
  285. package/dist/tabs/tabs.js +66 -0
  286. package/dist/tabs/tabs.js.map +1 -0
  287. package/dist/templates/app-templates.d.ts +126 -0
  288. package/dist/templates/app-templates.js +153 -0
  289. package/dist/templates/app-templates.js.map +1 -0
  290. package/dist/templates/site-templates.d.ts +49 -0
  291. package/dist/templates/site-templates.js +110 -0
  292. package/dist/templates/site-templates.js.map +1 -0
  293. package/dist/toast/toast-store.d.ts +54 -0
  294. package/dist/toast/toast-store.js +49 -0
  295. package/dist/toast/toast-store.js.map +1 -0
  296. package/dist/toast/toaster.d.ts +15 -0
  297. package/dist/toast/toaster.js +124 -0
  298. package/dist/toast/toaster.js.map +1 -0
  299. package/dist/tooltip/tooltip.d.ts +29 -0
  300. package/dist/tooltip/tooltip.js +54 -0
  301. package/dist/tooltip/tooltip.js.map +1 -0
  302. package/package.json +88 -3
  303. package/styles.css +521 -0
  304. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-headers.js","names":["EntityHeader","cx","className","icon","avatarSrc","IconTile","Avatar","onChangeImage","IconButton","labels","name","abbreviation","badges","location","links","Icon","l","actions","ProfileHeader","cover","subtitle","localTime"],"sources":["../../src/page-header/record-headers.tsx"],"sourcesContent":["'use client';\nimport { type ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { IconTile } from '../icon/icon-tile';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Avatar } from '../data-display/avatar';\nimport { IconButton } from '../button/button';\n\n/* ---------------- EntityHeader ---------------- */\n\nexport interface EntityHeaderProps {\n name: string;\n /** A short code next to the name (\"ACM\"). */\n abbreviation?: string;\n /** An icon tile (companies, projects) or a photo (`avatarSrc`, people). */\n icon?: IconName;\n avatarSrc?: string;\n /** Tile color for `icon`, e.g. the client's category color. */\n color?: string;\n /** Shows an edit button on the picture. */\n onChangeImage?: () => void;\n badges?: ReactNode;\n location?: string;\n links?: { label: string; href: string; icon?: IconName }[];\n /** Right side: \"Edit\", \"More\". */\n actions?: ReactNode;\n labels?: { changeImage?: string };\n className?: string;\n}\n\n/**\n * The header of a record's page (a client, a product, a company): picture, name, code, badges, links, actions.\n * A div, not <header>: inside <main> it is page content, and several would be duplicate banner landmarks.\n */\nexport function EntityHeader({\n name,\n abbreviation,\n icon,\n avatarSrc,\n color = 'var(--kf-primary)',\n onChangeImage,\n badges,\n location,\n links = [],\n actions,\n labels = {},\n className,\n}: EntityHeaderProps) {\n return (\n <div className={cx('flex flex-wrap items-start justify-between gap-x-6 gap-y-4 font-sans', className)}>\n <div className=\"flex min-w-[min(100%,16rem)] flex-1 items-center gap-4\">\n <div className=\"relative shrink-0\">\n {icon && !avatarSrc ? (\n <IconTile icon={icon} size=\"xl\" color={color} />\n ) : (\n <Avatar name={name} src={avatarSrc} size=\"xl\" className=\"size-16!\" decorative />\n )}\n {onChangeImage && (\n <IconButton\n icon=\"edit\"\n label={labels.changeImage ?? 'Change picture'}\n size=\"sm\"\n variant=\"primary\"\n onClick={onChangeImage}\n className=\"absolute -right-1.5 -bottom-1.5 ring-3 ring-bg\"\n />\n )}\n </div>\n <div className=\"grid min-w-0 gap-1.5\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"m-0 font-display text-2xl font-bold tracking-tight text-fg\">{name}</h1>\n {abbreviation && (\n <span className=\"rounded-sm bg-surface-muted px-1.5 py-0.5 font-mono text-xs font-semibold text-fg-muted\">\n {abbreviation}\n </span>\n )}\n {badges}\n </div>\n {(location || links.length > 0) && (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-fg-muted\">\n {location && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon name=\"c-location\" size={16} />\n {location}\n </span>\n )}\n {links.map((l) => (\n <a\n key={l.href}\n href={l.href}\n className=\"inline-flex items-center gap-1 rounded-xs text-link no-underline hover:underline focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus\"\n >\n <Icon name={l.icon ?? 'c-external'} size={16} />\n {l.label}\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </div>\n );\n}\n\n/* ---------------- ProfileHeader ---------------- */\n\nexport interface ProfileHeaderProps {\n name: string;\n avatarSrc?: string;\n /** \"Product designer · Design team\" */\n subtitle?: ReactNode;\n badges?: ReactNode;\n location?: string;\n /** Pre-formatted local time (\"10:42 (UTC−05:00)\"), computed by the page to avoid hydration mismatches. */\n localTime?: string;\n actions?: ReactNode;\n /** Status dot on the avatar (see `Avatar`). */\n statusColor?: string;\n statusLabel?: string;\n /** Cover band color or gradient. Default: the brand gradient. */\n cover?: string;\n className?: string;\n}\n\n/** A person's profile header: cover band, large avatar, name, role · team, badges, location and local time. */\nexport function ProfileHeader({\n name,\n avatarSrc,\n subtitle,\n badges,\n location,\n localTime,\n actions,\n statusColor,\n statusLabel,\n cover,\n className,\n}: ProfileHeaderProps) {\n return (\n <div className={cx('overflow-hidden rounded-xl border border-border bg-surface font-sans', className)}>\n <div\n aria-hidden=\"true\"\n className={cx('h-24 sm:h-32', !cover && 'bg-gradient-brand')}\n style={cover ? { background: cover } : undefined}\n />\n <div className=\"grid gap-4 px-card pb-card\">\n <div className=\"-mt-10 flex flex-wrap items-end justify-between gap-3\">\n <Avatar\n name={name}\n src={avatarSrc}\n size=\"xl\"\n statusColor={statusColor}\n statusLabel={statusLabel}\n className=\"size-24! text-3xl! ring-4 ring-surface\"\n />\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </div>\n <div className=\"grid gap-1.5\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"m-0 font-display text-2xl font-bold tracking-tight text-fg\">{name}</h1>\n {badges}\n </div>\n {subtitle && <p className=\"m-0 text-[15px] text-fg-muted\">{subtitle}</p>}\n {(location || localTime) && (\n <p className=\"m-0 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-fg-muted\">\n {location && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon name=\"c-location\" size={16} />\n {location}\n </span>\n )}\n {localTime && (\n <span className=\"inline-flex items-center gap-1\">\n <Icon name=\"time\" size={16} />\n {localTime}\n </span>\n )}\n </p>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import type { IconName } from '../icon/icon';
3
+ export interface SectionHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
4
+ title: ReactNode;
5
+ description?: ReactNode;
6
+ /** Accent before the title: `bar` (default), `dot` or `none`. Ignored with `icon`. */
7
+ marker?: 'bar' | 'dot' | 'none';
8
+ /** An icon tile before the title instead of the marker. */
9
+ icon?: IconName;
10
+ /** A count after the title ("Clients 24"). */
11
+ count?: number;
12
+ /** Right side: usually one button ("New client") or a link ("View all"). */
13
+ actions?: ReactNode;
14
+ /** Default 2: the page title is the h1 in `PageHeader`. */
15
+ headingLevel?: 2 | 3;
16
+ }
17
+ /**
18
+ * Title of a section inside a page (above a list, table or group of cards): marker or icon, title, count,
19
+ * description and actions on the right. For the page itself use `PageHeader`; for a card's own header, `CardHeader`.
20
+ */
21
+ export declare function SectionHeader({ title, description, marker, icon, count, actions, headingLevel, className, ...rest }: SectionHeaderProps): import("react").JSX.Element;
@@ -0,0 +1,44 @@
1
+ import { cx as e } from "../lib/cx.js";
2
+ import { IconTile as t } from "../icon/icon-tile.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/page-header/section-header.tsx
5
+ function i({ title: i, description: a, marker: o = "bar", icon: s, count: c, actions: l, headingLevel: u = 2, className: d, ...f }) {
6
+ let p = `h${u}`;
7
+ return /* @__PURE__ */ r("div", {
8
+ className: e("flex flex-wrap items-end justify-between gap-x-4 gap-y-3 font-sans", d),
9
+ ...f,
10
+ children: [/* @__PURE__ */ r("div", {
11
+ className: "flex min-w-[min(100%,14rem)] flex-1 items-start gap-3",
12
+ children: [s && /* @__PURE__ */ n(t, {
13
+ icon: s,
14
+ size: "md"
15
+ }), /* @__PURE__ */ r("div", {
16
+ className: "grid min-w-0 gap-1",
17
+ children: [/* @__PURE__ */ r(p, {
18
+ className: "m-0 flex items-center gap-2 font-display text-xl font-bold tracking-tight text-fg",
19
+ children: [
20
+ !s && o !== "none" && /* @__PURE__ */ n("span", {
21
+ "aria-hidden": "true",
22
+ className: e("shrink-0 bg-accent", o === "bar" ? "h-5 w-1 rounded-full" : "size-2 rounded-full")
23
+ }),
24
+ i,
25
+ c !== void 0 && /* @__PURE__ */ n("span", {
26
+ className: "rounded-full bg-surface-muted px-2 py-0.5 font-sans text-xs font-semibold text-fg-muted tabular-nums",
27
+ children: c
28
+ })
29
+ ]
30
+ }), a && /* @__PURE__ */ n("p", {
31
+ className: "m-0 text-sm text-pretty text-fg-muted",
32
+ children: a
33
+ })]
34
+ })]
35
+ }), l && /* @__PURE__ */ n("div", {
36
+ className: "flex shrink-0 flex-wrap items-center gap-2",
37
+ children: l
38
+ })]
39
+ });
40
+ }
41
+ //#endregion
42
+ export { i as SectionHeader };
43
+
44
+ //# sourceMappingURL=section-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-header.js","names":["SectionHeader","rest","H","headingLevel","cx","className","icon","IconTile","marker","title","count","description","actions"],"sources":["../../src/page-header/section-header.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { IconTile } from '../icon/icon-tile';\nimport type { IconName } from '../icon/icon';\n\nexport interface SectionHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Accent before the title: `bar` (default), `dot` or `none`. Ignored with `icon`. */\n marker?: 'bar' | 'dot' | 'none';\n /** An icon tile before the title instead of the marker. */\n icon?: IconName;\n /** A count after the title (\"Clients 24\"). */\n count?: number;\n /** Right side: usually one button (\"New client\") or a link (\"View all\"). */\n actions?: ReactNode;\n /** Default 2: the page title is the h1 in `PageHeader`. */\n headingLevel?: 2 | 3;\n}\n\n/**\n * Title of a section inside a page (above a list, table or group of cards): marker or icon, title, count,\n * description and actions on the right. For the page itself use `PageHeader`; for a card's own header, `CardHeader`.\n */\nexport function SectionHeader({\n title,\n description,\n marker = 'bar',\n icon,\n count,\n actions,\n headingLevel = 2,\n className,\n ...rest\n}: SectionHeaderProps) {\n const H = `h${headingLevel}` as const;\n return (\n <div className={cx('flex flex-wrap items-end justify-between gap-x-4 gap-y-3 font-sans', className)} {...rest}>\n <div className=\"flex min-w-[min(100%,14rem)] flex-1 items-start gap-3\">\n {icon && <IconTile icon={icon} size=\"md\" />}\n <div className=\"grid min-w-0 gap-1\">\n <H className=\"m-0 flex items-center gap-2 font-display text-xl font-bold tracking-tight text-fg\">\n {!icon && marker !== 'none' && (\n <span\n aria-hidden=\"true\"\n className={cx('shrink-0 bg-accent', marker === 'bar' ? 'h-5 w-1 rounded-full' : 'size-2 rounded-full')}\n />\n )}\n {title}\n {count !== undefined && (\n <span className=\"rounded-full bg-surface-muted px-2 py-0.5 font-sans text-xs font-semibold text-fg-muted tabular-nums\">\n {count}\n </span>\n )}\n </H>\n {description && <p className=\"m-0 text-sm text-pretty text-fg-muted\">{description}</p>}\n </div>\n </div>\n {actions && <div className=\"flex shrink-0 flex-wrap items-center gap-2\">{actions}</div>}\n </div>\n );\n}\n"],"mappings":";;;;AAwBA,SAAgBA,EAAc,EAC5B,UACA,gBACA,YAAS,OACT,SACA,UACA,YACA,kBAAe,GACf,cACA,GAAGC,KACkB;CACrB,IAAMC,IAAI,IAAIC;CACd,OACE,kBAAC,OAAD;EAAK,WAAWC,EAAG,sEAAsEC,CAAS;EAAG,GAAIJ;EAAzG,UAAA,CACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACGK,KAAQ,kBAACC,GAAD;IAAgB;IAAM,MAAK;GAAM,CAAA,GAC1C,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAACL,GAAD;KAAG,WAAU;KAAb,UAAA;MACG,CAACI,KAAQE,MAAW,UACnB,kBAAC,QAAD;OACE,eAAY;OACZ,WAAWJ,EAAG,sBAAsBI,MAAW,QAAQ,yBAAyB,qBAAqB;MACtG,CAAA;MAEFC;MACAC,MAAU,KAAA,KACT,kBAAC,QAAD;OAAM,WAAU;OACb,UAAAA;MACG,CAAA;KAEP;IACF,CAAA,GAAAC,KAAe,kBAAC,KAAD;KAAG,WAAU;KAAyC,UAAAA;IAAe,CAAA,CAClF;GACF,CAAA,CAAA;EACJ,CAAA,GAAAC,KAAW,kBAAC,OAAD;GAAK,WAAU;GAA8C,UAAAA;EAAa,CAAA,CACnF;;AAET"}
@@ -0,0 +1,59 @@
1
+ import { type ElementType } from 'react';
2
+ import { type IconName } from '../icon/icon';
3
+ import { type TimelineItem } from '../data-display/data-display';
4
+ import { type StepDot } from '../stepper/step-dots';
5
+ export interface TocItem {
6
+ /** The section's element id. */
7
+ id: string;
8
+ label: string;
9
+ icon?: IconName;
10
+ /** 2 (default) or 3 for a nested heading. */
11
+ level?: 2 | 3;
12
+ }
13
+ /**
14
+ * "On this page" for long articles: links to the sections, sticky, and the section in view is highlighted
15
+ * (IntersectionObserver). Links work without JavaScript.
16
+ */
17
+ export declare function TableOfContents({ items, label, className, }: {
18
+ items: TocItem[];
19
+ label?: string;
20
+ className?: string;
21
+ }): import("react").JSX.Element;
22
+ export interface PrevNextLink {
23
+ title: string;
24
+ href: string;
25
+ }
26
+ /** "Previous / Next" cards at the end of a docs article. */
27
+ export declare function PrevNextNav({ prev, next, linkAs: Link, labels, className, }: {
28
+ prev?: PrevNextLink;
29
+ next?: PrevNextLink;
30
+ linkAs?: ElementType;
31
+ labels?: {
32
+ prev?: string;
33
+ next?: string;
34
+ nav?: string;
35
+ };
36
+ className?: string;
37
+ }): import("react").JSX.Element;
38
+ export interface Cycle {
39
+ id: string;
40
+ /** Period label ("Nov 1 – 15"). */
41
+ label: string;
42
+ href: string;
43
+ steps: StepDot[];
44
+ /** Shown on hover or focus: the period's status history. */
45
+ timeline?: TimelineItem[];
46
+ }
47
+ /**
48
+ * Compact rows for period-based processes (payroll cycles): label, step dots and a chevron. Hovering or focusing a
49
+ * row shows its status timeline and "Open the cycle".
50
+ */
51
+ export declare function CycleNavigator({ cycles, linkAs: Link, labels, className, 'aria-label': label, }: {
52
+ cycles: Cycle[];
53
+ linkAs?: ElementType;
54
+ labels?: {
55
+ open?: string;
56
+ };
57
+ className?: string;
58
+ 'aria-label'?: string;
59
+ }): import("react").JSX.Element;
@@ -0,0 +1,136 @@
1
+ "use client";
2
+ import { cx as e } from "../lib/cx.js";
3
+ import { Icon as t } from "../icon/icon.js";
4
+ import { HoverCard as n, HoverCardContent as r, HoverCardTrigger as i } from "../hover-card/hover-card.js";
5
+ import { Glyph as a } from "../lib/glyphs.js";
6
+ import { StepDots as o } from "../stepper/step-dots.js";
7
+ import { Timeline as s } from "../data-display/data-display.js";
8
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
9
+ import { useEffect as u, useState as d } from "react";
10
+ //#region src/page-navigation/page-navigation.tsx
11
+ function f({ items: n, label: r = "On this page", className: i }) {
12
+ let [a, o] = d(n[0]?.id);
13
+ return u(() => {
14
+ let e = n.map((e) => document.getElementById(e.id)).filter(Boolean);
15
+ if (!e.length || typeof IntersectionObserver > "u") return;
16
+ let t = new IntersectionObserver((e) => {
17
+ let t = e.filter((e) => e.isIntersecting).sort((e, t) => e.boundingClientRect.top - t.boundingClientRect.top);
18
+ t[0] && o(t[0].target.id);
19
+ }, { rootMargin: "-15% 0px -70% 0px" });
20
+ return e.forEach((e) => t.observe(e)), () => t.disconnect();
21
+ }, [n]), /* @__PURE__ */ l("nav", {
22
+ "aria-label": r,
23
+ className: e("sticky top-[calc(var(--spacing-appbar)+1.5rem)] grid gap-2 font-sans text-sm", i),
24
+ children: [/* @__PURE__ */ c("p", {
25
+ className: "m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase",
26
+ children: r
27
+ }), /* @__PURE__ */ c("ul", {
28
+ className: "m-0 grid list-none gap-0.5 border-l border-border p-0",
29
+ children: n.map((n) => {
30
+ let r = n.id === a;
31
+ return /* @__PURE__ */ c("li", { children: /* @__PURE__ */ l("a", {
32
+ href: `#${n.id}`,
33
+ "aria-current": r ? "location" : void 0,
34
+ onClick: () => o(n.id),
35
+ className: e("-ml-px flex items-center gap-2 border-l-2 py-1.5 pr-2 no-underline focus-visible:outline-3 focus-visible:-outline-offset-2 focus-visible:outline-focus", n.level === 3 ? "pl-6" : "pl-3", r ? "border-primary font-semibold text-link" : "border-transparent text-fg-muted hover:text-fg"),
36
+ children: [n.icon && /* @__PURE__ */ c(t, {
37
+ name: n.icon,
38
+ size: 16,
39
+ className: "shrink-0"
40
+ }), n.label]
41
+ }) }, n.id);
42
+ })
43
+ })]
44
+ });
45
+ }
46
+ function p({ prev: t, next: n, linkAs: r = "a", labels: i = {}, className: o }) {
47
+ let s = "grid gap-1 rounded-lg border border-border bg-surface p-4 no-underline transition-colors hover:border-primary focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus";
48
+ return /* @__PURE__ */ l("nav", {
49
+ "aria-label": i.nav ?? "Pagination",
50
+ className: e("grid gap-3 font-sans sm:grid-cols-2", o),
51
+ children: [t ? /* @__PURE__ */ l(r, {
52
+ href: t.href,
53
+ rel: "prev",
54
+ className: s,
55
+ children: [/* @__PURE__ */ l("span", {
56
+ className: "inline-flex items-center gap-1 text-xs font-semibold text-fg-muted",
57
+ children: [/* @__PURE__ */ c(a, {
58
+ name: "chevron-left",
59
+ size: 14
60
+ }), i.prev ?? "Previous"]
61
+ }), /* @__PURE__ */ c("span", {
62
+ className: "font-semibold text-link",
63
+ children: t.title
64
+ })]
65
+ }) : /* @__PURE__ */ c("span", {
66
+ "aria-hidden": "true",
67
+ className: "hidden sm:block"
68
+ }), n && /* @__PURE__ */ l(r, {
69
+ href: n.href,
70
+ rel: "next",
71
+ className: e(s, "text-right sm:justify-items-end"),
72
+ children: [/* @__PURE__ */ l("span", {
73
+ className: "inline-flex items-center gap-1 text-xs font-semibold text-fg-muted",
74
+ children: [i.next ?? "Next", /* @__PURE__ */ c(a, {
75
+ name: "chevron-right",
76
+ size: 14
77
+ })]
78
+ }), /* @__PURE__ */ c("span", {
79
+ className: "font-semibold text-link",
80
+ children: n.title
81
+ })]
82
+ })]
83
+ });
84
+ }
85
+ function m({ cycles: t, linkAs: u = "a", labels: d = {}, className: f, "aria-label": p }) {
86
+ return /* @__PURE__ */ c("ul", {
87
+ "aria-label": p,
88
+ className: e("m-0 grid list-none gap-1 p-0 font-sans", f),
89
+ children: t.map((e) => {
90
+ let t = /* @__PURE__ */ l(u, {
91
+ href: e.href,
92
+ className: "flex items-center gap-3 rounded-sm px-2.5 py-2 text-sm text-fg no-underline hover:bg-surface-muted focus-visible:outline-3 focus-visible:-outline-offset-2 focus-visible:outline-focus",
93
+ children: [
94
+ /* @__PURE__ */ c("span", {
95
+ className: "min-w-0 flex-1 truncate font-medium",
96
+ children: e.label
97
+ }),
98
+ /* @__PURE__ */ c(o, { steps: e.steps }),
99
+ /* @__PURE__ */ c(a, {
100
+ name: "chevron-right",
101
+ size: 14,
102
+ className: "text-fg-muted"
103
+ })
104
+ ]
105
+ });
106
+ return /* @__PURE__ */ c("li", { children: e.timeline ? /* @__PURE__ */ l(n, {
107
+ openDelay: 300,
108
+ children: [/* @__PURE__ */ c(i, {
109
+ asChild: !0,
110
+ children: t
111
+ }), /* @__PURE__ */ l(r, {
112
+ side: "right",
113
+ align: "start",
114
+ size: "sm",
115
+ className: "grid gap-3",
116
+ children: [
117
+ /* @__PURE__ */ c("p", {
118
+ className: "m-0 font-semibold text-fg",
119
+ children: e.label
120
+ }),
121
+ /* @__PURE__ */ c(s, { items: e.timeline }),
122
+ /* @__PURE__ */ l(u, {
123
+ href: e.href,
124
+ className: "text-sm font-semibold text-link no-underline hover:underline",
125
+ children: [d.open ?? "Open the cycle", " →"]
126
+ })
127
+ ]
128
+ })]
129
+ }) : t }, e.id);
130
+ })
131
+ });
132
+ }
133
+ //#endregion
134
+ export { m as CycleNavigator, p as PrevNextNav, f as TableOfContents };
135
+
136
+ //# sourceMappingURL=page-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-navigation.js","names":["TableOfContents","active","setActive","useState","items","useEffect","els","i","io","visible","entries","a","b","el","label","cx","className","on","Icon","PrevNextNav","Link","card","labels","prev","Glyph","next","CycleNavigator","cycles","row","c","StepDots","HoverCard","HoverCardTrigger","HoverCardContent","Timeline"],"sources":["../../src/page-navigation/page-navigation.tsx"],"sourcesContent":["'use client';\nimport { useEffect, useState, type ElementType } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Timeline, type TimelineItem } from '../data-display/data-display';\nimport { HoverCard, HoverCardContent, HoverCardTrigger } from '../hover-card/hover-card';\nimport { StepDots, type StepDot } from '../stepper/step-dots';\n\n/* ---------------- TableOfContents ---------------- */\n\nexport interface TocItem {\n /** The section's element id. */\n id: string;\n label: string;\n icon?: IconName;\n /** 2 (default) or 3 for a nested heading. */\n level?: 2 | 3;\n}\n\n/**\n * \"On this page\" for long articles: links to the sections, sticky, and the section in view is highlighted\n * (IntersectionObserver). Links work without JavaScript.\n */\nexport function TableOfContents({\n items,\n label = 'On this page',\n className,\n}: {\n items: TocItem[];\n label?: string;\n className?: string;\n}) {\n const [active, setActive] = useState(items[0]?.id);\n useEffect(() => {\n const els = items.map((i) => document.getElementById(i.id)).filter(Boolean) as HTMLElement[];\n if (!els.length || typeof IntersectionObserver === 'undefined') return;\n const io = new IntersectionObserver(\n (entries) => {\n const visible = entries\n .filter((e) => e.isIntersecting)\n .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);\n if (visible[0]) setActive(visible[0].target.id);\n },\n { rootMargin: '-15% 0px -70% 0px' },\n );\n els.forEach((el) => io.observe(el));\n return () => io.disconnect();\n }, [items]);\n return (\n <nav\n aria-label={label}\n className={cx('sticky top-[calc(var(--spacing-appbar)+1.5rem)] grid gap-2 font-sans text-sm', className)}\n >\n <p className=\"m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase\">{label}</p>\n <ul className=\"m-0 grid list-none gap-0.5 border-l border-border p-0\">\n {items.map((i) => {\n const on = i.id === active;\n return (\n <li key={i.id}>\n <a\n href={`#${i.id}`}\n aria-current={on ? 'location' : undefined}\n onClick={() => setActive(i.id)}\n className={cx(\n '-ml-px flex items-center gap-2 border-l-2 py-1.5 pr-2 no-underline focus-visible:outline-3 focus-visible:-outline-offset-2 focus-visible:outline-focus',\n i.level === 3 ? 'pl-6' : 'pl-3',\n on ? 'border-primary font-semibold text-link' : 'border-transparent text-fg-muted hover:text-fg',\n )}\n >\n {i.icon && <Icon name={i.icon} size={16} className=\"shrink-0\" />}\n {i.label}\n </a>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n\n/* ---------------- PrevNextNav ---------------- */\n\nexport interface PrevNextLink {\n title: string;\n href: string;\n}\n\n/** \"Previous / Next\" cards at the end of a docs article. */\nexport function PrevNextNav({\n prev,\n next,\n linkAs: Link = 'a',\n labels = {},\n className,\n}: {\n prev?: PrevNextLink;\n next?: PrevNextLink;\n linkAs?: ElementType;\n labels?: { prev?: string; next?: string; nav?: string };\n className?: string;\n}) {\n const card =\n 'grid gap-1 rounded-lg border border-border bg-surface p-4 no-underline transition-colors hover:border-primary focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus';\n return (\n <nav aria-label={labels.nav ?? 'Pagination'} className={cx('grid gap-3 font-sans sm:grid-cols-2', className)}>\n {prev ? (\n <Link href={prev.href} rel=\"prev\" className={card}>\n <span className=\"inline-flex items-center gap-1 text-xs font-semibold text-fg-muted\">\n <Glyph name=\"chevron-left\" size={14} />\n {labels.prev ?? 'Previous'}\n </span>\n <span className=\"font-semibold text-link\">{prev.title}</span>\n </Link>\n ) : (\n <span aria-hidden=\"true\" className=\"hidden sm:block\" />\n )}\n {next && (\n <Link href={next.href} rel=\"next\" className={cx(card, 'text-right sm:justify-items-end')}>\n <span className=\"inline-flex items-center gap-1 text-xs font-semibold text-fg-muted\">\n {labels.next ?? 'Next'}\n <Glyph name=\"chevron-right\" size={14} />\n </span>\n <span className=\"font-semibold text-link\">{next.title}</span>\n </Link>\n )}\n </nav>\n );\n}\n\n/* ---------------- CycleNavigator ---------------- */\n\nexport interface Cycle {\n id: string;\n /** Period label (\"Nov 1 – 15\"). */\n label: string;\n href: string;\n steps: StepDot[];\n /** Shown on hover or focus: the period's status history. */\n timeline?: TimelineItem[];\n}\n\n/**\n * Compact rows for period-based processes (payroll cycles): label, step dots and a chevron. Hovering or focusing a\n * row shows its status timeline and \"Open the cycle\".\n */\nexport function CycleNavigator({\n cycles,\n linkAs: Link = 'a',\n labels = {},\n className,\n 'aria-label': label,\n}: {\n cycles: Cycle[];\n linkAs?: ElementType;\n labels?: { open?: string };\n className?: string;\n 'aria-label'?: string;\n}) {\n return (\n <ul aria-label={label} className={cx('m-0 grid list-none gap-1 p-0 font-sans', className)}>\n {cycles.map((c) => {\n const row = (\n <Link\n href={c.href}\n className=\"flex items-center gap-3 rounded-sm px-2.5 py-2 text-sm text-fg no-underline hover:bg-surface-muted focus-visible:outline-3 focus-visible:-outline-offset-2 focus-visible:outline-focus\"\n >\n <span className=\"min-w-0 flex-1 truncate font-medium\">{c.label}</span>\n <StepDots steps={c.steps} />\n <Glyph name=\"chevron-right\" size={14} className=\"text-fg-muted\" />\n </Link>\n );\n return (\n <li key={c.id}>\n {c.timeline ? (\n <HoverCard openDelay={300}>\n <HoverCardTrigger asChild>{row}</HoverCardTrigger>\n <HoverCardContent side=\"right\" align=\"start\" size=\"sm\" className=\"grid gap-3\">\n <p className=\"m-0 font-semibold text-fg\">{c.label}</p>\n <Timeline items={c.timeline} />\n <Link href={c.href} className=\"text-sm font-semibold text-link no-underline hover:underline\">\n {labels.open ?? 'Open the cycle'} →\n </Link>\n </HoverCardContent>\n </HoverCard>\n ) : (\n row\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ export interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
3
+ /** Current page, 1-based. */
4
+ page: number;
5
+ pageCount: number;
6
+ onPageChange: (page: number) => void;
7
+ /** Pages shown on each side of the current one (desktop). */
8
+ siblings?: number;
9
+ /** `pages` (default): numbered pages. `compact`: previous / "Page 1 of 4" / next, for table footers. */
10
+ variant?: 'pages' | 'compact';
11
+ labels?: Partial<typeof LABELS>;
12
+ }
13
+ declare const LABELS: {
14
+ nav: string;
15
+ previous: string;
16
+ next: string;
17
+ /** `{page}` and `{count}` are replaced. */
18
+ pageOf: string;
19
+ page: string;
20
+ };
21
+ /** Builds the list of pages with ellipses: 1 … 4 5 [6] 7 8 … 20 */
22
+ export declare function paginationRange(page: number, pageCount: number, siblings?: number): (number | 'gap')[];
23
+ /**
24
+ * Moves between pages of a list. Desktop: numbered pages with ellipses. Mobile: previous / next
25
+ * with "Page 3 of 12". For infinite feeds prefer a "Load more" button.
26
+ */
27
+ export declare function Pagination({ page, pageCount, onPageChange, siblings, variant, labels: overrides, className, ...rest }: PaginationProps): import("react").JSX.Element | null;
28
+ export {};
@@ -0,0 +1,102 @@
1
+ import { cx as e } from "../lib/cx.js";
2
+ import { Glyph as t } from "../lib/glyphs.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/pagination/pagination.tsx
5
+ var i = {
6
+ nav: "Pagination",
7
+ previous: "Previous",
8
+ next: "Next",
9
+ pageOf: "Page {page} of {count}",
10
+ page: "Page {page}"
11
+ };
12
+ function a(e, t, n = 1) {
13
+ if (t <= n * 2 + 5) return Array.from({ length: t }, (e, t) => t + 1);
14
+ let r = Math.max(2, e - n), i = Math.min(t - 1, e + n), a = [1];
15
+ r > 2 && a.push("gap");
16
+ for (let e = r; e <= i; e++) a.push(e);
17
+ return i < t - 1 && a.push("gap"), a.push(t), a;
18
+ }
19
+ function o({ page: o, pageCount: s, onPageChange: c, siblings: l = 1, variant: u = "pages", labels: d, className: f, ...p }) {
20
+ let m = {
21
+ ...i,
22
+ ...d
23
+ };
24
+ if (u === "compact") {
25
+ let i = Math.max(s, 1), a = e("inline-grid size-9 cursor-pointer place-items-center rounded-sm border border-border bg-surface text-fg", "hover:bg-surface-muted disabled:pointer-events-none disabled:opacity-40 pointer-coarse:size-11", "focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus");
26
+ return /* @__PURE__ */ r("nav", {
27
+ "aria-label": m.nav,
28
+ className: e("flex items-center gap-2 font-sans", f),
29
+ ...p,
30
+ children: [
31
+ /* @__PURE__ */ n("button", {
32
+ type: "button",
33
+ className: a,
34
+ "aria-label": m.previous,
35
+ disabled: o <= 1,
36
+ onClick: () => c(o - 1),
37
+ children: /* @__PURE__ */ n(t, { name: "chevron-left" })
38
+ }),
39
+ /* @__PURE__ */ n("span", {
40
+ className: "text-sm whitespace-nowrap text-fg-muted tabular-nums",
41
+ "aria-live": "polite",
42
+ children: m.pageOf.replace("{page}", String(o)).replace("{count}", String(i))
43
+ }),
44
+ /* @__PURE__ */ n("button", {
45
+ type: "button",
46
+ className: a,
47
+ "aria-label": m.next,
48
+ disabled: o >= i,
49
+ onClick: () => c(o + 1),
50
+ children: /* @__PURE__ */ n(t, { name: "chevron-right" })
51
+ })
52
+ ]
53
+ });
54
+ }
55
+ if (s <= 1) return null;
56
+ let h = e("inline-flex h-10 min-w-10 cursor-pointer items-center justify-center rounded-full border-0 bg-transparent px-3 font-sans text-sm font-semibold text-fg", "hover:bg-surface-muted disabled:pointer-events-none disabled:opacity-40", "focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus");
57
+ return /* @__PURE__ */ r("nav", {
58
+ "aria-label": m.nav,
59
+ className: e("flex items-center justify-between gap-2 font-sans sm:justify-center", f),
60
+ ...p,
61
+ children: [
62
+ /* @__PURE__ */ r("button", {
63
+ type: "button",
64
+ className: e(h, "gap-1"),
65
+ disabled: o <= 1,
66
+ onClick: () => c(o - 1),
67
+ children: [/* @__PURE__ */ n(t, { name: "chevron-left" }), /* @__PURE__ */ n("span", { children: m.previous })]
68
+ }),
69
+ /* @__PURE__ */ n("span", {
70
+ className: "text-sm text-fg-muted sm:hidden",
71
+ "aria-live": "polite",
72
+ children: m.pageOf.replace("{page}", String(o)).replace("{count}", String(s))
73
+ }),
74
+ /* @__PURE__ */ n("ul", {
75
+ className: "m-0 hidden list-none items-center gap-1 p-0 sm:flex",
76
+ children: a(o, s, l).map((t, r) => t === "gap" ? /* @__PURE__ */ n("li", {
77
+ "aria-hidden": "true",
78
+ className: "px-1 text-fg-muted",
79
+ children: "…"
80
+ }, `gap-${r}`) : /* @__PURE__ */ n("li", { children: /* @__PURE__ */ n("button", {
81
+ type: "button",
82
+ "aria-label": m.page.replace("{page}", String(t)),
83
+ "aria-current": t === o ? "page" : void 0,
84
+ onClick: () => c(t),
85
+ className: e(h, "tabular-nums aria-[current=page]:bg-primary aria-[current=page]:text-on-primary"),
86
+ children: t
87
+ }) }, t))
88
+ }),
89
+ /* @__PURE__ */ r("button", {
90
+ type: "button",
91
+ className: e(h, "gap-1"),
92
+ disabled: o >= s,
93
+ onClick: () => c(o + 1),
94
+ children: [/* @__PURE__ */ n("span", { children: m.next }), /* @__PURE__ */ n(t, { name: "chevron-right" })]
95
+ })
96
+ ]
97
+ });
98
+ }
99
+ //#endregion
100
+ export { o as Pagination, a as paginationRange };
101
+
102
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","names":["LABELS","paginationRange","pageCount","siblings","i","start","page","end","range","p","Pagination","overrides","rest","labels","variant","count","arrow","cx","className","onPageChange","Glyph","btn"],"sources":["../../src/pagination/pagination.tsx"],"sourcesContent":["import type { HTMLAttributes } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\n\nexport interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {\n /** Current page, 1-based. */\n page: number;\n pageCount: number;\n onPageChange: (page: number) => void;\n /** Pages shown on each side of the current one (desktop). */\n siblings?: number;\n /** `pages` (default): numbered pages. `compact`: previous / \"Page 1 of 4\" / next, for table footers. */\n variant?: 'pages' | 'compact';\n labels?: Partial<typeof LABELS>;\n}\n\nconst LABELS = {\n nav: 'Pagination',\n previous: 'Previous',\n next: 'Next',\n /** `{page}` and `{count}` are replaced. */\n pageOf: 'Page {page} of {count}',\n page: 'Page {page}',\n};\n\n/** Builds the list of pages with ellipses: 1 … 4 5 [6] 7 8 … 20 */\nexport function paginationRange(page: number, pageCount: number, siblings = 1): (number | 'gap')[] {\n const total = siblings * 2 + 5;\n if (pageCount <= total) return Array.from({ length: pageCount }, (_, i) => i + 1);\n const start = Math.max(2, page - siblings);\n const end = Math.min(pageCount - 1, page + siblings);\n const range: (number | 'gap')[] = [1];\n if (start > 2) range.push('gap');\n for (let p = start; p <= end; p++) range.push(p);\n if (end < pageCount - 1) range.push('gap');\n range.push(pageCount);\n return range;\n}\n\n/**\n * Moves between pages of a list. Desktop: numbered pages with ellipses. Mobile: previous / next\n * with \"Page 3 of 12\". For infinite feeds prefer a \"Load more\" button.\n */\nexport function Pagination({\n page,\n pageCount,\n onPageChange,\n siblings = 1,\n variant = 'pages',\n labels: overrides,\n className,\n ...rest\n}: PaginationProps) {\n const labels = { ...LABELS, ...overrides };\n if (variant === 'compact') {\n const count = Math.max(pageCount, 1);\n const arrow = cx(\n 'inline-grid size-9 cursor-pointer place-items-center rounded-sm border border-border bg-surface text-fg',\n 'hover:bg-surface-muted disabled:pointer-events-none disabled:opacity-40 pointer-coarse:size-11',\n 'focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus',\n );\n return (\n <nav aria-label={labels.nav} className={cx('flex items-center gap-2 font-sans', className)} {...rest}>\n <button\n type=\"button\"\n className={arrow}\n aria-label={labels.previous}\n disabled={page <= 1}\n onClick={() => onPageChange(page - 1)}\n >\n <Glyph name=\"chevron-left\" />\n </button>\n <span className=\"text-sm whitespace-nowrap text-fg-muted tabular-nums\" aria-live=\"polite\">\n {labels.pageOf.replace('{page}', String(page)).replace('{count}', String(count))}\n </span>\n <button\n type=\"button\"\n className={arrow}\n aria-label={labels.next}\n disabled={page >= count}\n onClick={() => onPageChange(page + 1)}\n >\n <Glyph name=\"chevron-right\" />\n </button>\n </nav>\n );\n }\n if (pageCount <= 1) return null;\n const btn = cx(\n 'inline-flex h-10 min-w-10 cursor-pointer items-center justify-center rounded-full border-0 bg-transparent px-3 font-sans text-sm font-semibold text-fg',\n 'hover:bg-surface-muted disabled:pointer-events-none disabled:opacity-40',\n 'focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus',\n );\n return (\n <nav\n aria-label={labels.nav}\n className={cx('flex items-center justify-between gap-2 font-sans sm:justify-center', className)}\n {...rest}\n >\n <button type=\"button\" className={cx(btn, 'gap-1')} disabled={page <= 1} onClick={() => onPageChange(page - 1)}>\n <Glyph name=\"chevron-left\" />\n <span>{labels.previous}</span>\n </button>\n <span className=\"text-sm text-fg-muted sm:hidden\" aria-live=\"polite\">\n {labels.pageOf.replace('{page}', String(page)).replace('{count}', String(pageCount))}\n </span>\n <ul className=\"m-0 hidden list-none items-center gap-1 p-0 sm:flex\">\n {paginationRange(page, pageCount, siblings).map((p, i) =>\n p === 'gap' ? (\n <li key={`gap-${i}`} aria-hidden=\"true\" className=\"px-1 text-fg-muted\">\n …\n </li>\n ) : (\n <li key={p}>\n <button\n type=\"button\"\n aria-label={labels.page.replace('{page}', String(p))}\n aria-current={p === page ? 'page' : undefined}\n onClick={() => onPageChange(p)}\n className={cx(btn, 'tabular-nums aria-[current=page]:bg-primary aria-[current=page]:text-on-primary')}\n >\n {p}\n </button>\n </li>\n ),\n )}\n </ul>\n <button\n type=\"button\"\n className={cx(btn, 'gap-1')}\n disabled={page >= pageCount}\n onClick={() => onPageChange(page + 1)}\n >\n <span>{labels.next}</span>\n <Glyph name=\"chevron-right\" />\n </button>\n </nav>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type ControlSize } from '../input/field-styles';
2
+ export interface Country {
3
+ /** ISO 3166-1 alpha-2. */
4
+ code: string;
5
+ name: string;
6
+ dial: string;
7
+ }
8
+ /** Kodffe's markets first (US, LATAM, Spain). Pass `countries` to change the list. */
9
+ export declare const DEFAULT_COUNTRIES: Country[];
10
+ export interface PhoneValue {
11
+ country: string;
12
+ /** National number, digits only. */
13
+ number: string;
14
+ }
15
+ export interface PhoneInputProps {
16
+ value: PhoneValue;
17
+ onChange: (value: PhoneValue) => void;
18
+ countries?: Country[];
19
+ size?: ControlSize;
20
+ id?: string;
21
+ disabled?: boolean;
22
+ required?: boolean;
23
+ invalid?: boolean;
24
+ placeholder?: string;
25
+ countryLabel?: string;
26
+ className?: string;
27
+ }
28
+ /** E.164 string for APIs (Brevo, WhatsApp, Twilio): `+593991234567`. */
29
+ export declare const toE164: (value: PhoneValue, countries?: Country[]) => string;
30
+ /**
31
+ * Country code + national number. The country is a native select (fast on every device); the
32
+ * number keeps digits only and uses the phone keypad (`type="tel"`). Validate length on submit.
33
+ */
34
+ export declare function PhoneInput({ value, onChange, countries, size, placeholder, countryLabel, className, ...rest }: PhoneInputProps): import("react").JSX.Element;