@vamos-ui/react 0.0.0-stage → 0.3.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 (704) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -2
  3. package/dist/blocks/block-heading.d.ts +29 -0
  4. package/dist/blocks/block-heading.js +39 -0
  5. package/dist/blocks/block-image.d.ts +52 -0
  6. package/dist/blocks/block-image.js +48 -0
  7. package/dist/blocks/block-link.d.ts +30 -0
  8. package/dist/blocks/block-link.js +36 -0
  9. package/dist/blocks/create-blocks.d.ts +54 -0
  10. package/dist/blocks/create-blocks.js +52 -0
  11. package/dist/blocks/index.d.ts +55 -0
  12. package/dist/blocks/index.js +59 -0
  13. package/dist/blocks/json-ld.d.ts +18 -0
  14. package/dist/blocks/json-ld.js +44 -0
  15. package/dist/blocks/labels.d.ts +20 -0
  16. package/dist/blocks/labels.js +43 -0
  17. package/dist/blocks/rich-text.d.ts +36 -0
  18. package/dist/blocks/rich-text.js +106 -0
  19. package/dist/blocks/schema/define-block.d.ts +151 -0
  20. package/dist/blocks/schema/define-block.js +120 -0
  21. package/dist/blocks/schema/emphasis.d.ts +17 -0
  22. package/dist/blocks/schema/emphasis.js +69 -0
  23. package/dist/blocks/schema/fields.d.ts +497 -0
  24. package/dist/blocks/schema/fields.js +240 -0
  25. package/dist/blocks/schema/icons.d.ts +2 -0
  26. package/dist/blocks/schema/icons.js +26 -0
  27. package/dist/blocks/schema/index.d.ts +18 -0
  28. package/dist/blocks/schema/index.js +21 -0
  29. package/dist/blocks/schema/lint-types.d.ts +16 -0
  30. package/dist/blocks/schema/lint-types.js +2 -0
  31. package/dist/blocks/schema/lint.d.ts +32 -0
  32. package/dist/blocks/schema/lint.js +164 -0
  33. package/dist/blocks/schema/localize.d.ts +20 -0
  34. package/dist/blocks/schema/localize.js +29 -0
  35. package/dist/blocks/schema/localized.d.ts +25 -0
  36. package/dist/blocks/schema/localized.js +53 -0
  37. package/dist/blocks/schema/migrate.d.ts +24 -0
  38. package/dist/blocks/schema/migrate.js +75 -0
  39. package/dist/blocks/schema/nodes.d.ts +196 -0
  40. package/dist/blocks/schema/nodes.js +78 -0
  41. package/dist/blocks/schema/rich-doc-schema.d.ts +32 -0
  42. package/dist/blocks/schema/rich-doc-schema.js +66 -0
  43. package/dist/blocks/schema/rich-doc.d.ts +90 -0
  44. package/dist/blocks/schema/rich-doc.js +62 -0
  45. package/dist/blocks/schema/safety.d.ts +20 -0
  46. package/dist/blocks/schema/safety.js +49 -0
  47. package/dist/blocks/schema/types.d.ts +172 -0
  48. package/dist/blocks/schema/types.js +3 -0
  49. package/dist/blocks/schema/validate.d.ts +17 -0
  50. package/dist/blocks/schema/validate.js +32 -0
  51. package/dist/blocks/schema/walk.d.ts +22 -0
  52. package/dist/blocks/schema/walk.js +60 -0
  53. package/dist/blocks/section-header.d.ts +38 -0
  54. package/dist/blocks/section-header.js +22 -0
  55. package/dist/blocks/section.d.ts +59 -0
  56. package/dist/blocks/section.js +66 -0
  57. package/dist/blocks/site/_kit-1.d.ts +101 -0
  58. package/dist/blocks/site/_kit-1.js +137 -0
  59. package/dist/blocks/site/_site-icon-1.d.ts +6 -0
  60. package/dist/blocks/site/_site-icon-1.js +15 -0
  61. package/dist/blocks/site/announcement-bar.d.ts +42 -0
  62. package/dist/blocks/site/announcement-bar.js +38 -0
  63. package/dist/blocks/site/announcement-dismiss.d.ts +18 -0
  64. package/dist/blocks/site/announcement-dismiss.js +28 -0
  65. package/dist/blocks/site/article-layout.d.ts +65 -0
  66. package/dist/blocks/site/article-layout.js +88 -0
  67. package/dist/blocks/site/blog-list.d.ts +79 -0
  68. package/dist/blocks/site/blog-list.js +78 -0
  69. package/dist/blocks/site/comparison-table.d.ts +54 -0
  70. package/dist/blocks/site/comparison-table.js +38 -0
  71. package/dist/blocks/site/consent-banner.d.ts +52 -0
  72. package/dist/blocks/site/consent-banner.js +33 -0
  73. package/dist/blocks/site/contact-dock.d.ts +52 -0
  74. package/dist/blocks/site/contact-dock.js +55 -0
  75. package/dist/blocks/site/contact-form.d.ts +60 -0
  76. package/dist/blocks/site/contact-form.js +45 -0
  77. package/dist/blocks/site/cta-booking.d.ts +43 -0
  78. package/dist/blocks/site/cta-booking.js +69 -0
  79. package/dist/blocks/site/cta.d.ts +74 -0
  80. package/dist/blocks/site/cta.js +113 -0
  81. package/dist/blocks/site/embed-facade.d.ts +20 -0
  82. package/dist/blocks/site/embed-facade.js +21 -0
  83. package/dist/blocks/site/faq.d.ts +48 -0
  84. package/dist/blocks/site/faq.js +52 -0
  85. package/dist/blocks/site/feature-grid.d.ts +46 -0
  86. package/dist/blocks/site/feature-grid.js +50 -0
  87. package/dist/blocks/site/feature-tabs.d.ts +22 -0
  88. package/dist/blocks/site/feature-tabs.js +11 -0
  89. package/dist/blocks/site/footer.d.ts +68 -0
  90. package/dist/blocks/site/footer.js +61 -0
  91. package/dist/blocks/site/gallery-section.d.ts +42 -0
  92. package/dist/blocks/site/gallery-section.js +48 -0
  93. package/dist/blocks/site/hero-video.d.ts +15 -0
  94. package/dist/blocks/site/hero-video.js +31 -0
  95. package/dist/blocks/site/hero.d.ts +64 -0
  96. package/dist/blocks/site/hero.js +73 -0
  97. package/dist/blocks/site/logo-strip.d.ts +44 -0
  98. package/dist/blocks/site/logo-strip.js +27 -0
  99. package/dist/blocks/site/map-hours.d.ts +83 -0
  100. package/dist/blocks/site/map-hours.js +125 -0
  101. package/dist/blocks/site/media-text.d.ts +45 -0
  102. package/dist/blocks/site/media-text.js +56 -0
  103. package/dist/blocks/site/menu-list.d.ts +74 -0
  104. package/dist/blocks/site/menu-list.js +84 -0
  105. package/dist/blocks/site/navbar-submenu.d.ts +18 -0
  106. package/dist/blocks/site/navbar-submenu.js +51 -0
  107. package/dist/blocks/site/navbar.d.ts +67 -0
  108. package/dist/blocks/site/navbar.js +64 -0
  109. package/dist/blocks/site/not-found.d.ts +40 -0
  110. package/dist/blocks/site/not-found.js +38 -0
  111. package/dist/blocks/site/page-intro.d.ts +46 -0
  112. package/dist/blocks/site/page-intro.js +44 -0
  113. package/dist/blocks/site/pricing-table.d.ts +67 -0
  114. package/dist/blocks/site/pricing-table.js +83 -0
  115. package/dist/blocks/site/process.d.ts +36 -0
  116. package/dist/blocks/site/process.js +42 -0
  117. package/dist/blocks/site/registry-1.d.ts +720 -0
  118. package/dist/blocks/site/registry-1.js +783 -0
  119. package/dist/blocks/site/registry-2.d.ts +914 -0
  120. package/dist/blocks/site/registry-2.js +563 -0
  121. package/dist/blocks/site/rich-text-section.d.ts +34 -0
  122. package/dist/blocks/site/rich-text-section.js +32 -0
  123. package/dist/blocks/site/shared/brand-icons.d.ts +21 -0
  124. package/dist/blocks/site/shared/brand-icons.js +56 -0
  125. package/dist/blocks/site/shared/consent-gate.d.ts +41 -0
  126. package/dist/blocks/site/shared/consent-gate.js +43 -0
  127. package/dist/blocks/site/shared/consent-island.d.ts +38 -0
  128. package/dist/blocks/site/shared/consent-island.js +63 -0
  129. package/dist/blocks/site/shared/consent.d.ts +49 -0
  130. package/dist/blocks/site/shared/consent.js +130 -0
  131. package/dist/blocks/site/shared/contact-form-island.d.ts +41 -0
  132. package/dist/blocks/site/shared/contact-form-island.js +100 -0
  133. package/dist/blocks/site/shared/copy-link.d.ts +10 -0
  134. package/dist/blocks/site/shared/copy-link.js +25 -0
  135. package/dist/blocks/site/shared/dock-avoid.d.ts +15 -0
  136. package/dist/blocks/site/shared/dock-avoid.js +107 -0
  137. package/dist/blocks/site/shared/dock-hours.d.ts +13 -0
  138. package/dist/blocks/site/shared/dock-hours.js +25 -0
  139. package/dist/blocks/site/shared/gallery-lightbox.d.ts +12 -0
  140. package/dist/blocks/site/shared/gallery-lightbox.js +10 -0
  141. package/dist/blocks/site/shared/island-keys.d.ts +10 -0
  142. package/dist/blocks/site/shared/island-keys.js +44 -0
  143. package/dist/blocks/site/shared/kit-2.d.ts +55 -0
  144. package/dist/blocks/site/shared/kit-2.js +84 -0
  145. package/dist/blocks/site/shared/labels-2.d.ts +209 -0
  146. package/dist/blocks/site/shared/labels-2.js +427 -0
  147. package/dist/blocks/site/shared/open-now.d.ts +22 -0
  148. package/dist/blocks/site/shared/open-now.js +27 -0
  149. package/dist/blocks/site/shared/opening-hours.d.ts +117 -0
  150. package/dist/blocks/site/shared/opening-hours.js +245 -0
  151. package/dist/blocks/site/shared/site-accent.d.ts +48 -0
  152. package/dist/blocks/site/shared/site-accent.js +249 -0
  153. package/dist/blocks/site/shared/site-form.d.ts +79 -0
  154. package/dist/blocks/site/shared/site-form.js +111 -0
  155. package/dist/blocks/site/shared/site-routing.d.ts +54 -0
  156. package/dist/blocks/site/shared/site-routing.js +86 -0
  157. package/dist/blocks/site/shared/testimonials-carousel.d.ts +17 -0
  158. package/dist/blocks/site/shared/testimonials-carousel.js +64 -0
  159. package/dist/blocks/site/site-shell.d.ts +108 -0
  160. package/dist/blocks/site/site-shell.js +254 -0
  161. package/dist/blocks/site/stats-band.d.ts +42 -0
  162. package/dist/blocks/site/stats-band.js +45 -0
  163. package/dist/blocks/site/team.d.ts +44 -0
  164. package/dist/blocks/site/team.js +48 -0
  165. package/dist/blocks/site/testimonials.d.ts +68 -0
  166. package/dist/blocks/site/testimonials.js +66 -0
  167. package/dist/blocks/types.d.ts +63 -0
  168. package/dist/blocks/types.js +2 -0
  169. package/dist/business/approval-flow.d.ts +152 -0
  170. package/dist/business/approval-flow.js +221 -0
  171. package/dist/business/export-core.d.ts +55 -0
  172. package/dist/business/export-core.js +101 -0
  173. package/dist/business/export.d.ts +148 -0
  174. package/dist/business/export.js +264 -0
  175. package/dist/business/import-core.d.ts +104 -0
  176. package/dist/business/import-core.js +281 -0
  177. package/dist/business/import-wizard.d.ts +186 -0
  178. package/dist/business/import-wizard.js +401 -0
  179. package/dist/business/index.d.ts +12 -0
  180. package/dist/business/index.js +22 -0
  181. package/dist/business/line-items-core.d.ts +129 -0
  182. package/dist/business/line-items-core.js +183 -0
  183. package/dist/business/line-items.d.ts +119 -0
  184. package/dist/business/line-items.js +299 -0
  185. package/dist/business/multi-step-form.d.ts +131 -0
  186. package/dist/business/multi-step-form.js +337 -0
  187. package/dist/business/permission-core.d.ts +59 -0
  188. package/dist/business/permission-core.js +99 -0
  189. package/dist/business/permission-matrix.d.ts +158 -0
  190. package/dist/business/permission-matrix.js +341 -0
  191. package/dist/business/setup-checklist.d.ts +80 -0
  192. package/dist/business/setup-checklist.js +92 -0
  193. package/dist/business/signer-status.d.ts +53 -0
  194. package/dist/business/signer-status.js +76 -0
  195. package/dist/charts/area-chart.d.ts +35 -0
  196. package/dist/charts/area-chart.js +33 -0
  197. package/dist/charts/bar-chart.d.ts +27 -0
  198. package/dist/charts/bar-chart.js +46 -0
  199. package/dist/charts/bar-list.d.ts +47 -0
  200. package/dist/charts/bar-list.js +60 -0
  201. package/dist/charts/chart-shell.d.ts +173 -0
  202. package/dist/charts/chart-shell.js +205 -0
  203. package/dist/charts/chart.d.ts +73 -0
  204. package/dist/charts/chart.js +106 -0
  205. package/dist/charts/combo-chart.d.ts +29 -0
  206. package/dist/charts/combo-chart.js +47 -0
  207. package/dist/charts/donut-chart.d.ts +33 -0
  208. package/dist/charts/donut-chart.js +113 -0
  209. package/dist/charts/funnel.d.ts +51 -0
  210. package/dist/charts/funnel.js +69 -0
  211. package/dist/charts/gauge.d.ts +62 -0
  212. package/dist/charts/gauge.js +104 -0
  213. package/dist/charts/heatmap.d.ts +81 -0
  214. package/dist/charts/heatmap.js +338 -0
  215. package/dist/charts/index.d.ts +12 -0
  216. package/dist/charts/index.js +14 -0
  217. package/dist/charts/line-chart.d.ts +21 -0
  218. package/dist/charts/line-chart.js +36 -0
  219. package/dist/charts/test-utils.d.ts +2 -0
  220. package/dist/charts/test-utils.js +38 -0
  221. package/dist/charts/utils.d.ts +130 -0
  222. package/dist/charts/utils.js +262 -0
  223. package/dist/components/_qr-core.d.ts +26 -0
  224. package/dist/components/_qr-core.js +376 -0
  225. package/dist/components/accordion.d.ts +47 -0
  226. package/dist/components/accordion.js +70 -0
  227. package/dist/components/activity-timeline.d.ts +149 -0
  228. package/dist/components/activity-timeline.js +122 -0
  229. package/dist/components/address-field.d.ts +116 -0
  230. package/dist/components/address-field.js +219 -0
  231. package/dist/components/alert-dialog.d.ts +99 -0
  232. package/dist/components/alert-dialog.js +192 -0
  233. package/dist/components/alert.d.ts +42 -0
  234. package/dist/components/alert.js +82 -0
  235. package/dist/components/app-shell.d.ts +159 -0
  236. package/dist/components/app-shell.js +289 -0
  237. package/dist/components/attachment-list.d.ts +96 -0
  238. package/dist/components/attachment-list.js +196 -0
  239. package/dist/components/audit-log.d.ts +150 -0
  240. package/dist/components/audit-log.js +205 -0
  241. package/dist/components/avatar.d.ts +87 -0
  242. package/dist/components/avatar.js +126 -0
  243. package/dist/components/backup-codes.d.ts +42 -0
  244. package/dist/components/backup-codes.js +67 -0
  245. package/dist/components/badge.d.ts +41 -0
  246. package/dist/components/badge.js +68 -0
  247. package/dist/components/breadcrumb.d.ts +78 -0
  248. package/dist/components/breadcrumb.js +106 -0
  249. package/dist/components/button-group.d.ts +52 -0
  250. package/dist/components/button-group.js +77 -0
  251. package/dist/components/button.d.ts +58 -0
  252. package/dist/components/button.js +107 -0
  253. package/dist/components/calendar.d.ts +240 -0
  254. package/dist/components/calendar.js +483 -0
  255. package/dist/components/card.d.ts +66 -0
  256. package/dist/components/card.js +76 -0
  257. package/dist/components/carousel.d.ts +170 -0
  258. package/dist/components/carousel.js +348 -0
  259. package/dist/components/checkbox.d.ts +78 -0
  260. package/dist/components/checkbox.js +138 -0
  261. package/dist/components/color-picker.d.ts +112 -0
  262. package/dist/components/color-picker.js +235 -0
  263. package/dist/components/combobox.d.ts +136 -0
  264. package/dist/components/combobox.js +294 -0
  265. package/dist/components/command.d.ts +281 -0
  266. package/dist/components/command.js +498 -0
  267. package/dist/components/comment-thread.d.ts +252 -0
  268. package/dist/components/comment-thread.js +449 -0
  269. package/dist/components/context-menu.d.ts +77 -0
  270. package/dist/components/context-menu.js +82 -0
  271. package/dist/components/currency-input.d.ts +43 -0
  272. package/dist/components/currency-input.js +85 -0
  273. package/dist/components/date-picker.d.ts +141 -0
  274. package/dist/components/date-picker.js +241 -0
  275. package/dist/components/date-range-picker.d.ts +91 -0
  276. package/dist/components/date-range-picker.js +251 -0
  277. package/dist/components/description-list.d.ts +92 -0
  278. package/dist/components/description-list.js +42 -0
  279. package/dist/components/dialog.d.ts +139 -0
  280. package/dist/components/dialog.js +185 -0
  281. package/dist/components/dropdown-menu.d.ts +100 -0
  282. package/dist/components/dropdown-menu.js +102 -0
  283. package/dist/components/editor-layout.d.ts +166 -0
  284. package/dist/components/editor-layout.js +237 -0
  285. package/dist/components/empty-state.d.ts +49 -0
  286. package/dist/components/empty-state.js +68 -0
  287. package/dist/components/entity-card.d.ts +83 -0
  288. package/dist/components/entity-card.js +92 -0
  289. package/dist/components/file-upload.d.ts +256 -0
  290. package/dist/components/file-upload.js +490 -0
  291. package/dist/components/formatted-input.d.ts +177 -0
  292. package/dist/components/formatted-input.js +399 -0
  293. package/dist/components/hierarchy-chart.d.ts +190 -0
  294. package/dist/components/hierarchy-chart.js +890 -0
  295. package/dist/components/hover-card.d.ts +21 -0
  296. package/dist/components/hover-card.js +32 -0
  297. package/dist/components/iban-input.d.ts +38 -0
  298. package/dist/components/iban-input.js +112 -0
  299. package/dist/components/id-input.d.ts +65 -0
  300. package/dist/components/id-input.js +130 -0
  301. package/dist/components/image.d.ts +130 -0
  302. package/dist/components/image.js +168 -0
  303. package/dist/components/input-otp.d.ts +62 -0
  304. package/dist/components/input-otp.js +73 -0
  305. package/dist/components/input.d.ts +141 -0
  306. package/dist/components/input.js +187 -0
  307. package/dist/components/item.d.ts +96 -0
  308. package/dist/components/item.js +113 -0
  309. package/dist/components/kbd.d.ts +64 -0
  310. package/dist/components/kbd.js +119 -0
  311. package/dist/components/list-layout.d.ts +144 -0
  312. package/dist/components/list-layout.js +210 -0
  313. package/dist/components/native-select.d.ts +33 -0
  314. package/dist/components/native-select.js +48 -0
  315. package/dist/components/navigation-menu.d.ts +127 -0
  316. package/dist/components/navigation-menu.js +129 -0
  317. package/dist/components/notification-center.d.ts +164 -0
  318. package/dist/components/notification-center.js +399 -0
  319. package/dist/components/page-header.d.ts +60 -0
  320. package/dist/components/page-header.js +60 -0
  321. package/dist/components/pagination.d.ts +121 -0
  322. package/dist/components/pagination.js +174 -0
  323. package/dist/components/phone-input.d.ts +49 -0
  324. package/dist/components/phone-input.js +266 -0
  325. package/dist/components/pin-map.d.ts +58 -0
  326. package/dist/components/pin-map.js +167 -0
  327. package/dist/components/popover.d.ts +38 -0
  328. package/dist/components/popover.js +69 -0
  329. package/dist/components/progress.d.ts +79 -0
  330. package/dist/components/progress.js +97 -0
  331. package/dist/components/qr-code.d.ts +36 -0
  332. package/dist/components/qr-code.js +27 -0
  333. package/dist/components/radio-group.d.ts +43 -0
  334. package/dist/components/radio-group.js +81 -0
  335. package/dist/components/record-detail-layout.d.ts +167 -0
  336. package/dist/components/record-detail-layout.js +233 -0
  337. package/dist/components/record-picker.d.ts +199 -0
  338. package/dist/components/record-picker.js +650 -0
  339. package/dist/components/resizable.d.ts +50 -0
  340. package/dist/components/resizable.js +88 -0
  341. package/dist/components/scroll-area.d.ts +40 -0
  342. package/dist/components/scroll-area.js +56 -0
  343. package/dist/components/select.d.ts +126 -0
  344. package/dist/components/select.js +137 -0
  345. package/dist/components/separator.d.ts +31 -0
  346. package/dist/components/separator.js +41 -0
  347. package/dist/components/settings-layout.d.ts +134 -0
  348. package/dist/components/settings-layout.js +180 -0
  349. package/dist/components/sheet.d.ts +103 -0
  350. package/dist/components/sheet.js +165 -0
  351. package/dist/components/sidebar.d.ts +171 -0
  352. package/dist/components/sidebar.js +421 -0
  353. package/dist/components/signature-pad.d.ts +85 -0
  354. package/dist/components/signature-pad.js +283 -0
  355. package/dist/components/skeleton.d.ts +64 -0
  356. package/dist/components/skeleton.js +53 -0
  357. package/dist/components/sla-timer.d.ts +75 -0
  358. package/dist/components/sla-timer.js +142 -0
  359. package/dist/components/slider.d.ts +57 -0
  360. package/dist/components/slider.js +133 -0
  361. package/dist/components/slug-input.d.ts +69 -0
  362. package/dist/components/slug-input.js +201 -0
  363. package/dist/components/sparkline.d.ts +54 -0
  364. package/dist/components/sparkline.js +122 -0
  365. package/dist/components/spinner.d.ts +34 -0
  366. package/dist/components/spinner.js +34 -0
  367. package/dist/components/stat.d.ts +135 -0
  368. package/dist/components/stat.js +130 -0
  369. package/dist/components/status-picker.d.ts +107 -0
  370. package/dist/components/status-picker.js +175 -0
  371. package/dist/components/stepper.d.ts +86 -0
  372. package/dist/components/stepper.js +103 -0
  373. package/dist/components/switch.d.ts +34 -0
  374. package/dist/components/switch.js +70 -0
  375. package/dist/components/table.d.ts +101 -0
  376. package/dist/components/table.js +72 -0
  377. package/dist/components/tabs.d.ts +103 -0
  378. package/dist/components/tabs.js +173 -0
  379. package/dist/components/tag-input.d.ts +77 -0
  380. package/dist/components/tag-input.js +305 -0
  381. package/dist/components/task-list.d.ts +89 -0
  382. package/dist/components/task-list.js +238 -0
  383. package/dist/components/time-picker.d.ts +119 -0
  384. package/dist/components/time-picker.js +399 -0
  385. package/dist/components/toast.d.ts +87 -0
  386. package/dist/components/toast.js +142 -0
  387. package/dist/components/toggle.d.ts +77 -0
  388. package/dist/components/toggle.js +109 -0
  389. package/dist/components/tooltip.d.ts +69 -0
  390. package/dist/components/tooltip.js +105 -0
  391. package/dist/components/top-bar.d.ts +87 -0
  392. package/dist/components/top-bar.js +99 -0
  393. package/dist/components/tour.d.ts +60 -0
  394. package/dist/components/tour.js +139 -0
  395. package/dist/components/tree-select.d.ts +89 -0
  396. package/dist/components/tree-select.js +243 -0
  397. package/dist/components/tree-view.d.ts +109 -0
  398. package/dist/components/tree-view.js +170 -0
  399. package/dist/components/typography.d.ts +107 -0
  400. package/dist/components/typography.js +128 -0
  401. package/dist/components/user-picker.d.ts +89 -0
  402. package/dist/components/user-picker.js +162 -0
  403. package/dist/components/version-history.d.ts +191 -0
  404. package/dist/components/version-history.js +431 -0
  405. package/dist/data-table/csv.d.ts +27 -0
  406. package/dist/data-table/csv.js +68 -0
  407. package/dist/data-table/data-table.d.ts +423 -0
  408. package/dist/data-table/data-table.js +1259 -0
  409. package/dist/data-table/filter-bar.d.ts +146 -0
  410. package/dist/data-table/filter-bar.js +569 -0
  411. package/dist/data-table/filter-fns.d.ts +65 -0
  412. package/dist/data-table/filter-fns.js +382 -0
  413. package/dist/data-table/index.d.ts +8 -0
  414. package/dist/data-table/index.js +9 -0
  415. package/dist/data-table/saved-views.d.ts +100 -0
  416. package/dist/data-table/saved-views.js +251 -0
  417. package/dist/data-table/types.d.ts +168 -0
  418. package/dist/data-table/types.js +87 -0
  419. package/dist/data-table/url-state.d.ts +94 -0
  420. package/dist/data-table/url-state.js +303 -0
  421. package/dist/data-table/view-state.d.ts +16 -0
  422. package/dist/data-table/view-state.js +81 -0
  423. package/dist/editor/_test-setup.d.ts +1 -0
  424. package/dist/editor/_test-setup.js +33 -0
  425. package/dist/editor/block-editor.d.ts +137 -0
  426. package/dist/editor/block-editor.js +280 -0
  427. package/dist/editor/commands.d.ts +31 -0
  428. package/dist/editor/commands.js +150 -0
  429. package/dist/editor/context.d.ts +108 -0
  430. package/dist/editor/context.js +30 -0
  431. package/dist/editor/convert.d.ts +66 -0
  432. package/dist/editor/convert.js +567 -0
  433. package/dist/editor/drag-handle.d.ts +10 -0
  434. package/dist/editor/drag-handle.js +69 -0
  435. package/dist/editor/extensions.d.ts +34 -0
  436. package/dist/editor/extensions.js +239 -0
  437. package/dist/editor/index.d.ts +14 -0
  438. package/dist/editor/index.js +17 -0
  439. package/dist/editor/inserter.d.ts +12 -0
  440. package/dist/editor/inserter.js +88 -0
  441. package/dist/editor/inspector.d.ts +17 -0
  442. package/dist/editor/inspector.js +65 -0
  443. package/dist/editor/items.d.ts +62 -0
  444. package/dist/editor/items.js +195 -0
  445. package/dist/editor/labels.d.ts +119 -0
  446. package/dist/editor/labels.js +130 -0
  447. package/dist/editor/markdown.d.ts +14 -0
  448. package/dist/editor/markdown.js +209 -0
  449. package/dist/editor/menus.d.ts +20 -0
  450. package/dist/editor/menus.js +236 -0
  451. package/dist/editor/nodes.d.ts +14 -0
  452. package/dist/editor/nodes.js +201 -0
  453. package/dist/editor/outline.d.ts +11 -0
  454. package/dist/editor/outline.js +52 -0
  455. package/dist/editor/schema-form.d.ts +64 -0
  456. package/dist/editor/schema-form.js +290 -0
  457. package/dist/editor/slash-menu.d.ts +15 -0
  458. package/dist/editor/slash-menu.js +119 -0
  459. package/dist/fonts/catalog.d.ts +53 -0
  460. package/dist/fonts/catalog.js +121 -0
  461. package/dist/fonts/font-picker.d.ts +70 -0
  462. package/dist/fonts/font-picker.js +225 -0
  463. package/dist/fonts/index.d.ts +6 -0
  464. package/dist/fonts/index.js +7 -0
  465. package/dist/fonts/loader.d.ts +66 -0
  466. package/dist/fonts/loader.js +161 -0
  467. package/dist/fonts/pairing-picker.d.ts +31 -0
  468. package/dist/fonts/pairing-picker.js +81 -0
  469. package/dist/fonts/pairings.d.ts +84 -0
  470. package/dist/fonts/pairings.js +149 -0
  471. package/dist/fonts/provider.d.ts +34 -0
  472. package/dist/fonts/provider.js +51 -0
  473. package/dist/form/index.d.ts +1 -0
  474. package/dist/form/index.js +1 -0
  475. package/dist/format/core.d.ts +149 -0
  476. package/dist/format/core.js +357 -0
  477. package/dist/format/index.d.ts +4 -0
  478. package/dist/format/index.js +5 -0
  479. package/dist/format/use-format.d.ts +1 -0
  480. package/dist/format/use-format.js +3 -0
  481. package/dist/index.d.ts +91 -0
  482. package/dist/index.js +92 -0
  483. package/dist/lib/cn.d.ts +3 -0
  484. package/dist/lib/cn.js +16 -0
  485. package/dist/lib/color.d.ts +64 -0
  486. package/dist/lib/color.js +177 -0
  487. package/dist/lib/compose-refs.d.ts +24 -0
  488. package/dist/lib/compose-refs.js +45 -0
  489. package/dist/lib/data-islands.d.ts +194 -0
  490. package/dist/lib/data-islands.js +368 -0
  491. package/dist/lib/date.d.ts +129 -0
  492. package/dist/lib/date.js +386 -0
  493. package/dist/lib/field-context.d.ts +64 -0
  494. package/dist/lib/field-context.js +62 -0
  495. package/dist/lib/floating-arrow.d.ts +18 -0
  496. package/dist/lib/floating-arrow.js +15 -0
  497. package/dist/lib/islands.d.ts +38 -0
  498. package/dist/lib/islands.js +40 -0
  499. package/dist/lib/labels.d.ts +51 -0
  500. package/dist/lib/labels.js +56 -0
  501. package/dist/lib/layer.d.ts +36 -0
  502. package/dist/lib/layer.js +42 -0
  503. package/dist/lib/locale.d.ts +85 -0
  504. package/dist/lib/locale.js +105 -0
  505. package/dist/lib/menu.d.ts +58 -0
  506. package/dist/lib/menu.js +99 -0
  507. package/dist/lib/message-format.d.ts +20 -0
  508. package/dist/lib/message-format.js +116 -0
  509. package/dist/lib/nav.d.ts +132 -0
  510. package/dist/lib/nav.js +178 -0
  511. package/dist/lib/provider.d.ts +100 -0
  512. package/dist/lib/provider.js +105 -0
  513. package/dist/lib/public.d.ts +23 -0
  514. package/dist/lib/public.js +34 -0
  515. package/dist/lib/sr-name.d.ts +18 -0
  516. package/dist/lib/sr-name.js +17 -0
  517. package/dist/lib/text.d.ts +100 -0
  518. package/dist/lib/text.js +233 -0
  519. package/dist/lib/theme-scope.d.ts +58 -0
  520. package/dist/lib/theme-scope.js +59 -0
  521. package/dist/lib/use-async-list.d.ts +60 -0
  522. package/dist/lib/use-async-list.js +119 -0
  523. package/dist/lib/use-container-width.d.ts +19 -0
  524. package/dist/lib/use-container-width.js +39 -0
  525. package/dist/lib/use-controllable-state.d.ts +33 -0
  526. package/dist/lib/use-controllable-state.js +56 -0
  527. package/dist/lib/use-edge-fade.d.ts +13 -0
  528. package/dist/lib/use-edge-fade.js +43 -0
  529. package/dist/lib/use-formatted-input.d.ts +69 -0
  530. package/dist/lib/use-formatted-input.js +152 -0
  531. package/dist/lib/use-hotkeys.d.ts +80 -0
  532. package/dist/lib/use-hotkeys.js +221 -0
  533. package/dist/lib/use-hover-intent.d.ts +44 -0
  534. package/dist/lib/use-hover-intent.js +119 -0
  535. package/dist/lib/use-media-query.d.ts +21 -0
  536. package/dist/lib/use-media-query.js +28 -0
  537. package/dist/lib/use-reduced-motion.d.ts +8 -0
  538. package/dist/lib/use-reduced-motion.js +13 -0
  539. package/dist/lib/use-tree.d.ts +153 -0
  540. package/dist/lib/use-tree.js +534 -0
  541. package/dist/lib/value-format.d.ts +25 -0
  542. package/dist/lib/value-format.js +56 -0
  543. package/dist/lib/variants.d.ts +131 -0
  544. package/dist/lib/variants.js +109 -0
  545. package/dist/locale-data/core/date.d.ts +24 -0
  546. package/dist/locale-data/core/date.js +68 -0
  547. package/dist/locale-data/core/decimal.d.ts +19 -0
  548. package/dist/locale-data/core/decimal.js +79 -0
  549. package/dist/locale-data/core/holidays.d.ts +30 -0
  550. package/dist/locale-data/core/holidays.js +79 -0
  551. package/dist/locale-data/core/iban.d.ts +29 -0
  552. package/dist/locale-data/core/iban.js +74 -0
  553. package/dist/locale-data/core/index.d.ts +7 -0
  554. package/dist/locale-data/core/index.js +6 -0
  555. package/dist/locale-data/core/types.d.ts +173 -0
  556. package/dist/locale-data/core/types.js +6 -0
  557. package/dist/locale-data/core/week-info.d.ts +23 -0
  558. package/dist/locale-data/core/week-info.js +85 -0
  559. package/dist/locale-data/core/working-days.d.ts +27 -0
  560. package/dist/locale-data/core/working-days.js +133 -0
  561. package/dist/locale-data/index.d.ts +2 -0
  562. package/dist/locale-data/index.js +4 -0
  563. package/dist/locale-data/tr/address-tr.json +1 -0
  564. package/dist/locale-data/tr/address.d.ts +23 -0
  565. package/dist/locale-data/tr/address.js +52 -0
  566. package/dist/locale-data/tr/holidays.d.ts +31 -0
  567. package/dist/locale-data/tr/holidays.js +81 -0
  568. package/dist/locale-data/tr/iban.d.ts +21 -0
  569. package/dist/locale-data/tr/iban.js +45 -0
  570. package/dist/locale-data/tr/id.d.ts +36 -0
  571. package/dist/locale-data/tr/id.js +120 -0
  572. package/dist/locale-data/tr/index.d.ts +12 -0
  573. package/dist/locale-data/tr/index.js +33 -0
  574. package/dist/locale-data/tr/kdv.d.ts +91 -0
  575. package/dist/locale-data/tr/kdv.js +222 -0
  576. package/dist/locales/en.d.ts +2102 -0
  577. package/dist/locales/en.js +2088 -0
  578. package/dist/locales/tr.d.ts +2086 -0
  579. package/dist/locales/tr.js +2087 -0
  580. package/dist/media/focal-point.d.ts +42 -0
  581. package/dist/media/focal-point.js +96 -0
  582. package/dist/media/gallery-layout.d.ts +19 -0
  583. package/dist/media/gallery-layout.js +61 -0
  584. package/dist/media/gallery.d.ts +64 -0
  585. package/dist/media/gallery.js +140 -0
  586. package/dist/media/image-cropper.d.ts +86 -0
  587. package/dist/media/image-cropper.js +170 -0
  588. package/dist/media/image-field.d.ts +115 -0
  589. package/dist/media/image-field.js +212 -0
  590. package/dist/media/index.d.ts +19 -0
  591. package/dist/media/index.js +23 -0
  592. package/dist/media/lightbox.d.ts +82 -0
  593. package/dist/media/lightbox.js +171 -0
  594. package/dist/media/link-preview.d.ts +97 -0
  595. package/dist/media/link-preview.js +177 -0
  596. package/dist/media/media-library.d.ts +244 -0
  597. package/dist/media/media-library.js +776 -0
  598. package/dist/media/media-picker.d.ts +96 -0
  599. package/dist/media/media-picker.js +209 -0
  600. package/dist/media/media-provider.d.ts +23 -0
  601. package/dist/media/media-provider.js +44 -0
  602. package/dist/media/media-utils.d.ts +39 -0
  603. package/dist/media/media-utils.js +145 -0
  604. package/dist/media/memory-adapter.d.ts +22 -0
  605. package/dist/media/memory-adapter.js +162 -0
  606. package/dist/media/rest-adapter.d.ts +90 -0
  607. package/dist/media/rest-adapter.js +208 -0
  608. package/dist/media/serp.d.ts +62 -0
  609. package/dist/media/serp.js +108 -0
  610. package/dist/media/test-fixtures.d.ts +3 -0
  611. package/dist/media/test-fixtures.js +37 -0
  612. package/dist/media/types.d.ts +183 -0
  613. package/dist/media/types.js +3 -0
  614. package/dist/media/use-pan-zoom.d.ts +51 -0
  615. package/dist/media/use-pan-zoom.js +156 -0
  616. package/dist/media/use-upload-queue.d.ts +64 -0
  617. package/dist/media/use-upload-queue.js +115 -0
  618. package/dist/media/video-player.d.ts +135 -0
  619. package/dist/media/video-player.js +319 -0
  620. package/dist/motion/core.d.ts +32 -0
  621. package/dist/motion/core.js +77 -0
  622. package/dist/motion/count-up.d.ts +29 -0
  623. package/dist/motion/count-up.js +92 -0
  624. package/dist/motion/index.d.ts +11 -0
  625. package/dist/motion/index.js +13 -0
  626. package/dist/motion/motion-scope.d.ts +17 -0
  627. package/dist/motion/motion-scope.js +16 -0
  628. package/dist/motion/page-transition.d.ts +33 -0
  629. package/dist/motion/page-transition.js +61 -0
  630. package/dist/motion/parallax.d.ts +37 -0
  631. package/dist/motion/parallax.js +90 -0
  632. package/dist/motion/pointer.d.ts +38 -0
  633. package/dist/motion/pointer.js +117 -0
  634. package/dist/motion/reveal.d.ts +72 -0
  635. package/dist/motion/reveal.js +133 -0
  636. package/dist/motion/scroll-shrink.d.ts +18 -0
  637. package/dist/motion/scroll-shrink.js +47 -0
  638. package/dist/motion/skeleton-swap.d.ts +17 -0
  639. package/dist/motion/skeleton-swap.js +43 -0
  640. package/dist/motion/text-reveal.d.ts +30 -0
  641. package/dist/motion/text-reveal.js +29 -0
  642. package/dist/motion/ticker.d.ts +35 -0
  643. package/dist/motion/ticker.js +16 -0
  644. package/dist/next/index.d.ts +42 -0
  645. package/dist/next/index.js +36 -0
  646. package/dist/render/block-renderer.d.ts +56 -0
  647. package/dist/render/block-renderer.js +137 -0
  648. package/dist/render/index.d.ts +6 -0
  649. package/dist/render/index.js +7 -0
  650. package/dist/render/prepare.d.ts +61 -0
  651. package/dist/render/prepare.js +119 -0
  652. package/dist/scheduler/core/duration.d.ts +83 -0
  653. package/dist/scheduler/core/duration.js +174 -0
  654. package/dist/scheduler/core/gantt.d.ts +63 -0
  655. package/dist/scheduler/core/gantt.js +226 -0
  656. package/dist/scheduler/core/index.d.ts +6 -0
  657. package/dist/scheduler/core/index.js +7 -0
  658. package/dist/scheduler/core/layout.d.ts +97 -0
  659. package/dist/scheduler/core/layout.js +249 -0
  660. package/dist/scheduler/core/time-scale.d.ts +89 -0
  661. package/dist/scheduler/core/time-scale.js +173 -0
  662. package/dist/scheduler/gantt.d.ts +125 -0
  663. package/dist/scheduler/gantt.js +532 -0
  664. package/dist/scheduler/index.d.ts +6 -0
  665. package/dist/scheduler/index.js +7 -0
  666. package/dist/scheduler/resource-calendar.d.ts +218 -0
  667. package/dist/scheduler/resource-calendar.js +661 -0
  668. package/dist/scheduler/scheduler.d.ts +168 -0
  669. package/dist/scheduler/scheduler.js +768 -0
  670. package/dist/scheduler/shared.d.ts +63 -0
  671. package/dist/scheduler/shared.js +145 -0
  672. package/dist/scheduler/time-tracker.d.ts +138 -0
  673. package/dist/scheduler/time-tracker.js +403 -0
  674. package/dist/sortable/core.d.ts +67 -0
  675. package/dist/sortable/core.js +167 -0
  676. package/dist/sortable/index.d.ts +8 -0
  677. package/dist/sortable/index.js +10 -0
  678. package/dist/sortable/kanban-core.d.ts +70 -0
  679. package/dist/sortable/kanban-core.js +67 -0
  680. package/dist/sortable/kanban.d.ts +147 -0
  681. package/dist/sortable/kanban.js +472 -0
  682. package/dist/sortable/sortable-list.d.ts +71 -0
  683. package/dist/sortable/sortable-list.js +76 -0
  684. package/dist/sortable/sortable-tree.d.ts +105 -0
  685. package/dist/sortable/sortable-tree.js +462 -0
  686. package/dist/sortable/sortable.d.ts +188 -0
  687. package/dist/sortable/sortable.js +485 -0
  688. package/dist/sortable/use-pointer-drag.d.ts +75 -0
  689. package/dist/sortable/use-pointer-drag.js +173 -0
  690. package/dist/sortable/use-time-scale.d.ts +11 -0
  691. package/dist/sortable/use-time-scale.js +19 -0
  692. package/dist/styles/base.css +51 -0
  693. package/dist/styles/blocks.css +949 -0
  694. package/dist/styles/calendar.css +642 -0
  695. package/dist/styles/charts.css +264 -0
  696. package/dist/styles/data.css +474 -0
  697. package/dist/styles/editors.css +1022 -0
  698. package/dist/styles/forms.css +406 -0
  699. package/dist/styles/media.css +515 -0
  700. package/dist/styles/motion.css +389 -0
  701. package/dist/styles/navigation.css +293 -0
  702. package/dist/styles/overlays.css +244 -0
  703. package/dist/styles.css +743 -0
  704. package/package.json +160 -4
@@ -0,0 +1,254 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../lib/cn.js";
5
+ import { ThemeScope } from "../../lib/theme-scope.js";
6
+ import { useControllableState } from "../../lib/use-controllable-state.js";
7
+ import { isBuiltInAccent, siteAccent, siteAccentCss, siteAccentKey } from "./shared/site-accent.js";
8
+ import { motionAllowed } from "../../motion/core.js";
9
+ import { startPageTransition, viewTransitionsSupported } from "../../motion/page-transition.js";
10
+ import { parseSiteHref, readSiteLocation, sitePageHref, writeSiteLocation } from "./shared/site-routing.js";
11
+ const SiteShellContext = React.createContext(null);
12
+ /** Page, locale and navigation of the closest Site shell. Throws outside one. */
13
+ export function useSiteShell() {
14
+ const ctx = React.useContext(SiteShellContext);
15
+ if (!ctx)
16
+ throw new Error("useSiteShell must be used inside <SiteShell>.");
17
+ return ctx;
18
+ }
19
+ /**
20
+ * The frame of a demo or single-route website: EN/TR switch, inner-page switching and the
21
+ * site's own look (accent from one colour, font, material, density), scoped to its root.
22
+ *
23
+ * Every language and page is rendered on the server as plain blocks; the shell shows one of
24
+ * each and swaps on links like `?page=pricing`, `?page=home#faq` or `?lang=tr` inside it —
25
+ * so server-rendered Navbar and Footer links work as they are. On a page change it scrolls to
26
+ * the top of the site, moves focus to the page's `h1` and marks matching links
27
+ * `aria-current="page"`. Back/forward follow the URL. Overlays opened inside keep its theme.
28
+ *
29
+ * ```tsx
30
+ * <SiteShell accent="#B4532A" font="editorial" material="solid" pages={["home", "shop"]}>
31
+ * <Navbar items={[{ label: "Shop", href: "?page=shop" }]} … />
32
+ * <SiteShellPage id="home"><Hero … /></SiteShellPage>
33
+ * <SiteShellPage id="shop"><PageIntro title="Shop" … /></SiteShellPage>
34
+ * </SiteShell>
35
+ * ```
36
+ */
37
+ export const SiteShell = React.forwardRef(function SiteShell({ accent, accentDark, font, material, density, theme, dir, locales = ["en", "tr"], locale: localeProp, defaultLocale, onLocaleChange, pages = ["home"], page: pageProp, defaultPage, onPageChange, routing = "search", pageParam = "page", localeParam = "lang", motion = "subtle", className, onClick, children, ...props }, ref) {
38
+ const homeLocale = defaultLocale ?? locales[0] ?? "en";
39
+ const homePage = defaultPage ?? pages[0] ?? "home";
40
+ const [locale, setLocale] = useControllableState({ value: localeProp, defaultValue: homeLocale, onChange: onLocaleChange, name: "SiteShell" });
41
+ const [page, setPage] = useControllableState({ value: pageProp, defaultValue: homePage, onChange: onPageChange, name: "SiteShell" });
42
+ const rootRef = React.useRef(null);
43
+ const setRoot = React.useCallback((node) => {
44
+ rootRef.current = node;
45
+ if (typeof ref === "function")
46
+ ref(node);
47
+ else if (ref)
48
+ ref.current = node;
49
+ }, [ref]);
50
+ /** What to do after the next render: focus the h1, scroll to the top or to an anchor. */
51
+ const pending = React.useRef(null);
52
+ const [pageEnter, setPageEnter] = React.useState(false);
53
+ /** Swap page/locale as a page transition: a View Transition, or a fade on the new page. */
54
+ const transition = React.useCallback((commit) => {
55
+ const root = rootRef.current;
56
+ const animate = motion !== "off" && motionAllowed(root);
57
+ setPageEnter(animate && !viewTransitionsSupported());
58
+ if (animate)
59
+ startPageTransition(commit, { scope: root });
60
+ else
61
+ commit();
62
+ }, [motion]);
63
+ const transitionRef = React.useRef(transition);
64
+ transitionRef.current = transition;
65
+ const pageKey = pages.join("|");
66
+ const localeKey = locales.join("|");
67
+ const params = React.useMemo(() => ({ pageParam, localeParam }), [pageParam, localeParam]);
68
+ const apply = React.useCallback((to, mode) => {
69
+ const nextPage = to.page && pages.includes(to.page) ? to.page : page;
70
+ const nextLocale = to.locale && locales.includes(to.locale) ? to.locale : locale;
71
+ const pageChanged = nextPage !== page;
72
+ if (mode !== "none" && routing !== "memory" && typeof window !== "undefined") {
73
+ const url = writeSiteLocation(window.location, { page: nextPage, locale: nextLocale, anchor: to.anchor }, { page: homePage, locale: homeLocale }, routing, params);
74
+ if (mode === "push")
75
+ window.history.pushState(null, "", url);
76
+ else
77
+ window.history.replaceState(null, "", url);
78
+ }
79
+ if (pageChanged)
80
+ pending.current = { focus: !to.anchor, scroll: true, anchor: to.anchor };
81
+ if (pageChanged || nextLocale !== locale) {
82
+ transition(() => {
83
+ if (nextLocale !== locale)
84
+ setLocale(nextLocale);
85
+ if (pageChanged)
86
+ setPage(nextPage);
87
+ });
88
+ }
89
+ else if (to.anchor)
90
+ scrollToAnchor(rootRef.current, to.anchor, false);
91
+ // The Navbar's mobile menu is a native popover: close it after any switch.
92
+ rootRef.current?.querySelectorAll("[popover]").forEach((p) => {
93
+ try {
94
+ p.hidePopover();
95
+ }
96
+ catch {
97
+ /* not open */
98
+ }
99
+ });
100
+ },
101
+ // eslint-disable-next-line react-hooks/exhaustive-deps
102
+ [page, locale, pageKey, localeKey, routing, homePage, homeLocale, params, setLocale, setPage, transition]);
103
+ // URL → state on mount and on back/forward.
104
+ React.useEffect(() => {
105
+ if (routing === "memory")
106
+ return;
107
+ const sync = (initial) => {
108
+ const loc = readSiteLocation(window.location.search, window.location.hash, routing, params);
109
+ const nextPage = loc.page && pages.includes(loc.page) ? loc.page : homePage;
110
+ const nextLocale = loc.locale && locales.includes(loc.locale) ? loc.locale : homeLocale;
111
+ const anchor = routing === "search" && window.location.hash.length > 1 ? decodeURIComponent(window.location.hash.slice(1)) : undefined;
112
+ const commit = () => {
113
+ setLocale(nextLocale);
114
+ setPage((prev) => {
115
+ if (prev !== nextPage)
116
+ pending.current = { focus: !initial && !anchor, scroll: !initial, anchor: initial ? anchor : undefined };
117
+ return nextPage;
118
+ });
119
+ };
120
+ if (initial)
121
+ commit();
122
+ else
123
+ transitionRef.current(commit);
124
+ };
125
+ // A deep link (`?page=order`) is server-rendered as home and switched here. As a transition,
126
+ // React finishes hydrating the home tree (and any Suspense boundary still dehydrated) before
127
+ // swapping pages, instead of re-rendering mid-hydration — which shifted useId values.
128
+ React.startTransition(() => sync(true));
129
+ const onPop = () => sync(false);
130
+ window.addEventListener("popstate", onPop);
131
+ if (routing === "hash")
132
+ window.addEventListener("hashchange", onPop);
133
+ return () => {
134
+ window.removeEventListener("popstate", onPop);
135
+ window.removeEventListener("hashchange", onPop);
136
+ };
137
+ // eslint-disable-next-line react-hooks/exhaustive-deps
138
+ }, [routing, pageKey, localeKey, homePage, homeLocale, params]);
139
+ // After a page change: scroll, focus the h1, and mark the current links.
140
+ React.useEffect(() => {
141
+ const root = rootRef.current;
142
+ if (!root)
143
+ return;
144
+ const todo = pending.current;
145
+ pending.current = null;
146
+ if (todo?.anchor)
147
+ scrollToAnchor(root, todo.anchor, true);
148
+ else if (todo?.scroll) {
149
+ const top = root.getBoundingClientRect().top + window.scrollY;
150
+ if (window.scrollY > top)
151
+ window.scrollTo({ top: Math.max(0, top), behavior: "instant" });
152
+ }
153
+ if (todo?.focus) {
154
+ const h1 = root.querySelector(`[data-site-page="${cssString(page)}"] h1`) ?? root.querySelector("h1");
155
+ if (h1) {
156
+ if (!h1.hasAttribute("tabindex"))
157
+ h1.setAttribute("tabindex", "-1");
158
+ h1.focus({ preventScroll: true });
159
+ }
160
+ }
161
+ root.querySelectorAll("a[href]").forEach((a) => {
162
+ const loc = parseSiteHref(a.getAttribute("href"), params);
163
+ if (!loc?.page || loc.anchor)
164
+ return;
165
+ if (loc.page === page)
166
+ a.setAttribute("aria-current", "page");
167
+ else if (a.getAttribute("aria-current") === "page")
168
+ a.removeAttribute("aria-current");
169
+ });
170
+ }, [page, locale, params]);
171
+ const handleClick = (e) => {
172
+ onClick?.(e);
173
+ if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
174
+ return;
175
+ const a = e.target?.closest?.("a[href]");
176
+ if (!a || (a.target && a.target !== "_self") || a.hasAttribute("download"))
177
+ return;
178
+ const loc = parseSiteHref(a.getAttribute("href"), params);
179
+ if (!loc)
180
+ return;
181
+ if (loc.page && !pages.includes(loc.page))
182
+ return;
183
+ if (loc.locale && !locales.includes(loc.locale))
184
+ return;
185
+ e.preventDefault();
186
+ apply(loc, "push");
187
+ };
188
+ const ctx = React.useMemo(() => ({
189
+ page,
190
+ locale,
191
+ pages,
192
+ locales,
193
+ navigate: (to) => apply(to, "push"),
194
+ hrefFor: (p, anchor) => sitePageHref(p, anchor, { routing, pageParam }),
195
+ motion,
196
+ pageEnter,
197
+ }),
198
+ // eslint-disable-next-line react-hooks/exhaustive-deps
199
+ [page, locale, pageKey, localeKey, apply, routing, pageParam, motion, pageEnter]);
200
+ // A colour → scoped variables. A name (built-in preset or your own, like "brand") goes
201
+ // straight to data-accent.
202
+ const custom = accent && !isBuiltInAccent(accent) && looksLikeColour(accent) ? accent : undefined;
203
+ const accentStyle = React.useMemo(() => {
204
+ if (!custom)
205
+ return null;
206
+ try {
207
+ const key = siteAccentKey(`${custom}${accentDark ? `-${accentDark}` : ""}`);
208
+ return { key, css: siteAccentCss(siteAccent(custom, { dark: accentDark }), key) };
209
+ }
210
+ catch (err) {
211
+ if (process.env.NODE_ENV !== "production")
212
+ console.warn(`[vamos-ui] SiteShell: ${err.message}`);
213
+ return null;
214
+ }
215
+ }, [custom, accentDark]);
216
+ return (_jsx(SiteShellContext.Provider, { value: ctx, children: _jsxs(ThemeScope, { ref: setRoot, theme: theme, material: material, density: density, font: font, dir: dir, accent: accentStyle ? "site" : custom ? undefined : accent, "data-site-accent": accentStyle?.key, "data-site-shell": "", "data-motion": motion, "data-page": page, lang: locale, className: cn("vb-scope font-sans text-fg", className), onClick: handleClick, ...props, children: [accentStyle ? _jsx("style", { children: accentStyle.css }) : null, children] }) }));
217
+ });
218
+ const looksLikeColour = (v) => v.trim().startsWith("#") || v.includes("(");
219
+ const cssString = (s) => s.replace(/["\\]/g, "\\$&");
220
+ function scrollToAnchor(root, anchor, instant) {
221
+ const el = root?.ownerDocument.getElementById(anchor);
222
+ if (!el)
223
+ return;
224
+ el.scrollIntoView?.({ block: "start", behavior: instant ? "instant" : undefined });
225
+ }
226
+ /** One inner page: rendered only while it is the shell's current page. */
227
+ export function SiteShellPage({ id, title, children }) {
228
+ const { page, pageEnter } = useSiteShell();
229
+ const active = page === id;
230
+ const first = React.useRef(true);
231
+ React.useEffect(() => {
232
+ if (active && title && !first.current)
233
+ document.title = title;
234
+ first.current = false;
235
+ }, [active, title]);
236
+ if (!active)
237
+ return null;
238
+ return (_jsx("div", { "data-site-page": id, "data-page-enter": pageEnter ? "" : undefined, className: "contents", children: children }));
239
+ }
240
+ /** One language version: rendered only while it is the shell's current locale (with `lang`). */
241
+ export function SiteShellLocale({ code, children }) {
242
+ const { locale } = useSiteShell();
243
+ if (locale !== code)
244
+ return null;
245
+ return (_jsx("div", { lang: code, className: "contents", children: children }));
246
+ }
247
+ /**
248
+ * A link to an inner page for client code. Server components can use a plain
249
+ * `href={sitePageHref("pricing")}` instead; the shell handles both.
250
+ */
251
+ export const SiteShellLink = React.forwardRef(function SiteShellLink({ page, anchor, ...props }, ref) {
252
+ const { hrefFor, page: current } = useSiteShell();
253
+ return _jsx("a", { ref: ref, href: hrefFor(page, anchor), "aria-current": !anchor && current === page ? "page" : undefined, ...props });
254
+ });
@@ -0,0 +1,42 @@
1
+ import * as React from "react";
2
+ import type { BlockBaseProps } from "../types.js";
3
+ import type { RichDoc } from "../schema/rich-doc.js";
4
+ import { type SiteBlockLabels } from "./_kit-1.js";
5
+ export type StatsBandVariant = "inline" | "with-text" | "ledger";
6
+ export interface StatItem {
7
+ /** Numbers are formatted with `Intl` (4.8 → "4,8" in tr); strings are shown verbatim ("24/7"). */
8
+ value: number | string;
9
+ /** Small superscript unit ("%", "k", "min"). */
10
+ unit?: string;
11
+ /** Spoken unit for screen readers ("percent"). `%` is spelled out automatically. */
12
+ unitLabel?: string;
13
+ label: React.ReactNode;
14
+ /** Where the figure comes from ("Google Business Profile, Oct 2026"). Unsourced figures read as marketing. */
15
+ source?: React.ReactNode;
16
+ }
17
+ export interface StatsBandProps extends Omit<BlockBaseProps, "variant" | "labels"> {
18
+ /**
19
+ * inline: 3–4 figures on one line between vertical rules; unit as a superscript, label below.
20
+ * with-text: a paragraph on the start side, a 2×2 grid of figures on the end side.
21
+ * ledger: label, dotted leader, figure — an annual report line; mono source below.
22
+ */
23
+ variant?: StatsBandVariant;
24
+ eyebrow?: React.ReactNode;
25
+ title?: React.ReactNode;
26
+ lead?: React.ReactNode;
27
+ /** with-text: the paragraph(s) beside the figures. */
28
+ body?: RichDoc | string;
29
+ items: StatItem[];
30
+ labels?: SiteBlockLabels;
31
+ }
32
+ /**
33
+ * Concrete, sourced numbers ("4.8 on Google · 1,240 reviews"). Semantic `dl`, Intl formatting,
34
+ * units spelled out for screen readers. Numeric figures count up once when they scroll into view
35
+ * (motion kit CountUp: width reserved, final value for screen readers, still under reduced
36
+ * motion / `motion="off"`); the items reveal in sequence. Server component.
37
+ *
38
+ * ```tsx
39
+ * <StatsBand items={[{ value: 4.8, label: "Google rating", source: "1,240 reviews, Nov 2026" }]} />
40
+ * ```
41
+ */
42
+ export declare function StatsBand({ variant, eyebrow, title, lead, body, items, id, theme, anchor, className, headingLevel, labels, locale, components, editMode }: StatsBandProps): React.JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/cn.js";
3
+ import { Container, Section } from "../section.js";
4
+ import { SectionHeader } from "../section-header.js";
5
+ import { RichText } from "../rich-text.js";
6
+ import { CountUp } from "../../motion/count-up.js";
7
+ import { Reveal, Stagger } from "../../motion/reveal.js";
8
+ import { siteText, useBlockIds } from "./_kit-1.js";
9
+ function formatValue(v, locale) {
10
+ if (typeof v !== "number")
11
+ return v;
12
+ const decimals = Math.min(2, (String(v).split(".")[1] ?? "").length);
13
+ return new Intl.NumberFormat(locale, { minimumFractionDigits: decimals, maximumFractionDigits: decimals }).format(v);
14
+ }
15
+ /**
16
+ * Concrete, sourced numbers ("4.8 on Google · 1,240 reviews"). Semantic `dl`, Intl formatting,
17
+ * units spelled out for screen readers. Numeric figures count up once when they scroll into view
18
+ * (motion kit CountUp: width reserved, final value for screen readers, still under reduced
19
+ * motion / `motion="off"`); the items reveal in sequence. Server component.
20
+ *
21
+ * ```tsx
22
+ * <StatsBand items={[{ value: 4.8, label: "Google rating", source: "1,240 reviews, Nov 2026" }]} />
23
+ * ```
24
+ */
25
+ export function StatsBand({ variant = "inline", eyebrow, title, lead, body, items, id, theme, anchor, className, headingLevel = 2, labels, locale = "en-US", components, editMode }) {
26
+ const t = siteText(labels, locale);
27
+ const { base, headingId } = useBlockIds(id, "stats");
28
+ const figure = (s, size) => {
29
+ const spoken = s.unitLabel ?? (s.unit === "%" ? t("percent") : s.unit);
30
+ return (_jsxs("span", { className: cn("font-display tabular text-fg", size), children: [typeof s.value === "number" && !editMode ? _jsx(CountUp, { value: s.value, locale: locale }) : formatValue(s.value, locale), s.unit ? (_jsxs(_Fragment, { children: [_jsx("sup", { "aria-hidden": true, className: "vb-stat-unit ms-[0.08em] align-super font-sans text-[0.38em] font-medium tracking-normal text-fg-muted", children: s.unit }), _jsxs("span", { className: "sr-only", children: [" ", spoken] })] })) : null] }));
31
+ };
32
+ const source = (s, cls) => s.source ? (_jsxs("dd", { className: cn("font-mono text-[0.6875rem] leading-snug tracking-[0.02em] text-fg-subtle", cls), children: [_jsx("span", { className: "sr-only", children: t("source", { source: "" }) }), s.source] })) : null;
33
+ const header = title || eyebrow || (lead && variant !== "with-text") ? (_jsx(Reveal, { disabled: editMode, children: _jsx(SectionHeader, { eyebrow: eyebrow, title: title, lead: variant === "with-text" ? undefined : lead, headingLevel: headingLevel, headingId: headingId, editMode: editMode, labels: labels, locale: locale }) })) : null;
34
+ let content;
35
+ if (variant === "ledger") {
36
+ content = (_jsxs("div", { className: "grid gap-x-(--gutter) gap-y-10 @4xl:grid-cols-12", children: [header ? _jsx("div", { className: "@4xl:col-span-4", children: header }) : null, _jsx(Stagger, { asChild: true, effect: "fade", disabled: editMode, children: _jsx("dl", { className: cn("flex flex-col border-t border-line", header ? "@4xl:col-span-7 @4xl:col-start-6" : "@4xl:col-span-12"), children: items.map((s, i) => (_jsxs("div", { className: "grid grid-cols-[auto_1fr_auto] items-baseline gap-x-4 gap-y-1 border-b border-line py-5", "data-field": editMode ? `props.items.${i}` : undefined, children: [_jsx("dt", { className: "text-body text-fg", children: s.label }), _jsx("span", { "aria-hidden": true, className: "vb-leader self-end" }), _jsx("dd", { className: "text-end", children: figure(s, "text-display-m") }), source(s, "col-span-3")] }, i))) }) })] }));
37
+ }
38
+ else if (variant === "with-text") {
39
+ content = (_jsxs("div", { className: "grid gap-x-(--gutter) gap-y-12 @4xl:grid-cols-12 @4xl:items-start", children: [_jsxs("div", { className: "flex flex-col gap-6 @4xl:col-span-5", children: [header, lead ? _jsx("p", { className: "vb-lead text-lead text-fg-muted", children: lead }) : null, body ? _jsx(RichText, { doc: body, components: components, labels: labels, locale: locale, headingOffset: 1, editMode: editMode, field: "props.body" }) : null] }), _jsx(Stagger, { asChild: true, disabled: editMode, children: _jsx("dl", { className: "grid grid-cols-2 border-s border-t border-line @4xl:col-span-6 @4xl:col-start-7", children: items.slice(0, 4).map((s, i) => (_jsxs("div", { className: "flex flex-col gap-2 border-e border-b border-line p-[clamp(1rem,3cqi,2rem)]", "data-field": editMode ? `props.items.${i}` : undefined, children: [_jsx("dt", { className: "order-2 text-small text-fg-muted text-pretty", children: s.label }), _jsx("dd", { className: "order-1", children: figure(s, "text-display-l") }), source(s, "order-3 mt-auto pt-3")] }, i))) }) })] }));
40
+ }
41
+ else {
42
+ content = (_jsxs("div", { className: "flex flex-col gap-12", children: [header, _jsx(Stagger, { asChild: true, disabled: editMode, children: _jsx("dl", { className: cn("grid grid-cols-2 gap-y-10", items.length >= 3 && "@4xl:grid-cols-3", items.length >= 4 && "@4xl:grid-cols-4", items.length >= 5 && "@6xl:grid-cols-5"), children: items.map((s, i) => (_jsxs("div", { className: "vb-stat-inline flex flex-col gap-2 border-line ps-[clamp(0.75rem,2.5cqi,2rem)]", "data-field": editMode ? `props.items.${i}` : undefined, children: [_jsx("dt", { className: "order-2 max-w-[24ch] text-small text-fg-muted text-pretty", children: s.label }), _jsx("dd", { className: "order-1", children: figure(s, "text-display-l") }), source(s, "order-3")] }, i))) }) })] }));
43
+ }
44
+ return (_jsx(Section, { theme: theme, anchor: anchor, headingId: title ? headingId : undefined, blockId: base, blockType: "stats", editMode: editMode, className: cn("vb-stats", className), "data-variant": variant, children: _jsx(Container, { children: content }) }));
45
+ }
@@ -0,0 +1,44 @@
1
+ import * as React from "react";
2
+ import type { BlockBaseProps } from "../types.js";
3
+ import type { SocialNetwork } from "../schema/types.js";
4
+ import { type Site2BlockLabels } from "./shared/labels-2.js";
5
+ import { type SiteImage2 } from "./shared/kit-2.js";
6
+ export type TeamVariant = "portrait" | "list" | "feature";
7
+ export interface TeamMember {
8
+ name: React.ReactNode;
9
+ /** Honorific kept apart from the name ("Dr.", "Op. Dr.") — order differs per locale. */
10
+ title?: React.ReactNode;
11
+ role: React.ReactNode;
12
+ /** Specialty line in `list` ("Deep tissue · Sports massage"). */
13
+ specialty?: React.ReactNode;
14
+ /** 4:5 portrait. No photo = an empty inset area, never initials. */
15
+ photo?: SiteImage2;
16
+ bio?: React.ReactNode;
17
+ /** Up to 3 profile links, rendered as short text links ("LinkedIn"). */
18
+ links?: {
19
+ network: SocialNetwork;
20
+ href: string;
21
+ }[];
22
+ }
23
+ export interface TeamProps extends Omit<BlockBaseProps, "variant" | "labels"> {
24
+ /**
25
+ * portrait: 3–4 columns of 4:5 portraits, name + mono role below. list: a typographic list
26
+ * (name · role · specialty) with a portrait revealed on hover. feature: one founder or lead
27
+ * specialist, large portrait beside a long bio, the name set like a signature.
28
+ */
29
+ variant?: TeamVariant;
30
+ eyebrow?: React.ReactNode;
31
+ title?: React.ReactNode;
32
+ lead?: React.ReactNode;
33
+ members: TeamMember[];
34
+ labels?: Site2BlockLabels;
35
+ }
36
+ /**
37
+ * Team and specialist introduction — spa therapists, clinic doctors, an agency team. Card-less
38
+ * by default (D6-1). Server component; the hover portrait in `list` is CSS only.
39
+ *
40
+ * ```tsx
41
+ * <Team title="The people behind your *treatment*" members={[{ name: "Elif Aydın", role: "Lead therapist", photo }]} />
42
+ * ```
43
+ */
44
+ export declare function Team({ variant: variantProp, eyebrow, title, lead, members, id, anchor, theme, headingLevel, className, labels, locale, components, editMode }: TeamProps): React.JSX.Element;
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn2 as cn } from "./shared/kit-2.js";
3
+ import { Section, Container } from "../section.js";
4
+ import { SectionHeader } from "../section-header.js";
5
+ import { BlockImage } from "../block-image.js";
6
+ import { BlockLink } from "../block-link.js";
7
+ import { site2Text } from "./shared/labels-2.js";
8
+ import { fieldAttr, textOf, useBlockIds2 } from "./shared/kit-2.js";
9
+ import { BRAND_NAMES } from "./shared/brand-icons.js";
10
+ /**
11
+ * Team and specialist introduction — spa therapists, clinic doctors, an agency team. Card-less
12
+ * by default (D6-1). Server component; the hover portrait in `list` is CSS only.
13
+ *
14
+ * ```tsx
15
+ * <Team title="The people behind your *treatment*" members={[{ name: "Elif Aydın", role: "Lead therapist", photo }]} />
16
+ * ```
17
+ */
18
+ export function Team({ variant: variantProp = "portrait", eyebrow, title, lead, members, id, anchor, theme, headingLevel = 2, className, labels, locale = "en-US", components, editMode }) {
19
+ const t = site2Text(labels, locale);
20
+ const { headingId } = useBlockIds2(id, "team");
21
+ const variant = members.length === 1 ? "feature" : variantProp;
22
+ const ctx = { t, locale, components, labels, editMode };
23
+ const header = title || eyebrow || lead ? _jsx(SectionHeader, { eyebrow: eyebrow, title: title, lead: lead, headingId: headingId, headingLevel: headingLevel, editMode: editMode, labels: labels, locale: locale, align: variant === "portrait" ? "split" : "start" }) : null;
24
+ return (_jsx(Section, { theme: theme, anchor: anchor, headingId: title ? headingId : undefined, blockId: id, blockType: "team", editMode: editMode, className: cn("vb-team", className), "data-variant": variant, children: _jsx(Container, { className: "flex flex-col gap-12 @4xl:gap-16", children: variant === "feature" ? (_jsx(FeatureMember, { member: members[0], header: header, ctx: ctx })) : (_jsxs(_Fragment, { children: [header, variant === "list" ? (_jsx("ul", { className: "vb-team-list flex flex-col border-b border-line", children: members.map((m, i) => (_jsx(ListMember, { member: m, index: i, ctx: ctx }, i))) })) : (_jsx("ul", { className: cn("grid grid-cols-2 gap-x-(--gutter) gap-y-12", members.length % 4 === 0 || members.length > 6 ? "@4xl:grid-cols-4" : "@4xl:grid-cols-3"), children: members.map((m, i) => (_jsx(PortraitMember, { member: m, index: i, ctx: ctx }, i))) }))] })) }) }));
25
+ }
26
+ function DisplayName({ member }) {
27
+ return (_jsxs(_Fragment, { children: [member.title ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-fg-muted", children: member.title }), " "] })) : null, member.name] }));
28
+ }
29
+ function ProfileLinks({ member, ctx, className }) {
30
+ if (!member.links?.length)
31
+ return null;
32
+ const name = textOf(member.name);
33
+ return (_jsx("span", { className: cn("flex flex-wrap gap-x-3 gap-y-1", className), children: member.links.slice(0, 3).map((l, i) => (_jsx(BlockLink, { href: l.href, newTab: true, components: ctx.components, labels: ctx.labels, locale: ctx.locale, "aria-label": name ? ctx.t("profileOf", { name, network: BRAND_NAMES[l.network] }) : undefined, className: "relative z-10 text-small text-fg-muted underline decoration-line underline-offset-[0.25em] transition-colors hover:text-fg hover:decoration-current focus-ring rounded-[2px]", children: BRAND_NAMES[l.network] }, i))) }));
34
+ }
35
+ function Portrait({ photo, ctx, className, sizes }) {
36
+ if (!photo?.src)
37
+ return _jsx("span", { "aria-hidden": true, className: cn("block aspect-[4/5] rounded-ui bg-surface-2", className) });
38
+ return _jsx(BlockImage, { ...photo, alt: photo.alt ?? "", decorative: !photo.alt, aspect: "4:5", sizes: sizes, className: cn("rounded-ui", className), components: ctx.components });
39
+ }
40
+ function PortraitMember({ member, index, ctx }) {
41
+ return (_jsxs("li", { className: "flex flex-col gap-4", children: [_jsx(Portrait, { photo: member.photo, ctx: ctx, sizes: "(min-width: 56rem) 25vw, 50vw" }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs("div", { className: "flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1", children: [_jsx("h3", { className: "text-h3 font-semibold tracking-[-0.012em] text-fg", ...fieldAttr(ctx.editMode, `members.${index}.name`), children: _jsx(DisplayName, { member: member }) }), _jsx(ProfileLinks, { member: member, ctx: ctx })] }), _jsx("p", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-fg-muted", children: member.role }), member.bio ? _jsx("p", { className: "mt-2 text-small text-fg-muted text-pretty", children: member.bio }) : null] })] }));
42
+ }
43
+ function ListMember({ member, index, ctx }) {
44
+ return (_jsxs("li", { className: "vb-team-row group/row relative grid grid-cols-[3.5rem_1fr] items-center gap-x-4 gap-y-1 border-t border-line py-6 @2xl:grid-cols-12 @2xl:gap-x-(--gutter)", children: [_jsx("span", { className: "row-span-2 @2xl:hidden", children: _jsx(Portrait, { photo: member.photo, ctx: ctx, className: "w-14 rounded-ui-sm", sizes: "56px" }) }), _jsx("h3", { className: "text-h3 font-semibold tracking-[-0.012em] text-fg @2xl:col-span-4", ...fieldAttr(ctx.editMode, `members.${index}.name`), children: _jsx(DisplayName, { member: member }) }), _jsx("p", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-fg-muted @2xl:col-span-3", children: member.role }), _jsxs("div", { className: "col-start-2 flex flex-wrap items-baseline gap-x-6 gap-y-1 @2xl:col-span-5 @2xl:col-start-auto @2xl:justify-between", children: [member.specialty ? _jsx("p", { className: "text-small text-fg-muted", children: member.specialty }) : _jsx("span", {}), _jsx(ProfileLinks, { member: member, ctx: ctx })] }), member.photo?.src ? (_jsx("span", { "aria-hidden": true, className: "vb-team-hover pointer-events-none absolute end-[22%] top-1/2 z-10 hidden w-40 -translate-y-1/2 @4xl:block", children: _jsx(BlockImage, { ...member.photo, decorative: true, aspect: "4:5", sizes: "160px", className: "rounded-ui", components: ctx.components }) })) : null] }));
45
+ }
46
+ function FeatureMember({ member, header, ctx }) {
47
+ return (_jsxs("div", { className: "grid gap-x-(--gutter) gap-y-10 @4xl:grid-cols-12 @4xl:items-start", children: [_jsx("div", { className: "@4xl:col-span-5", children: _jsx(Portrait, { photo: member.photo, ctx: ctx, sizes: "(min-width: 56rem) 40vw, 100vw" }) }), _jsxs("div", { className: "flex flex-col gap-8 @4xl:col-span-6 @4xl:col-start-7 @4xl:pt-6", children: [header, member.bio ? _jsx("div", { className: "text-lead text-fg-muted text-pretty [&_p+p]:mt-4", children: typeof member.bio === "string" ? member.bio.split(/\n{2,}/).map((p, i) => _jsx("p", { children: p }, i)) : member.bio }) : null, _jsxs("div", { className: "flex flex-col gap-2 border-t border-line pt-6", children: [_jsx("p", { className: "vb-signature font-display text-display-m italic text-fg", ...fieldAttr(ctx.editMode, "members.0.name"), children: _jsx(DisplayName, { member: member }) }), _jsx("p", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-fg-muted", children: member.role }), _jsx(ProfileLinks, { member: member, ctx: ctx, className: "mt-2" })] })] })] }));
48
+ }
@@ -0,0 +1,68 @@
1
+ import * as React from "react";
2
+ import type { BlockBaseProps } from "../types.js";
3
+ import { type Site2BlockLabels } from "./shared/labels-2.js";
4
+ import { type SiteImage2, type SiteLink2 } from "./shared/kit-2.js";
5
+ export type TestimonialsVariant = "feature" | "wall" | "carousel" | "reviews";
6
+ export type ReviewSource = "google" | "yandex" | "tripadvisor" | "trustpilot" | "direct";
7
+ export declare const REVIEW_SOURCE_NAMES: Record<ReviewSource, string>;
8
+ export interface TestimonialItem {
9
+ quote: React.ReactNode;
10
+ author: React.ReactNode;
11
+ role?: React.ReactNode;
12
+ company?: React.ReactNode;
13
+ /** Small square portrait. No avatar = name only (never an initials circle). */
14
+ avatar?: SiteImage2;
15
+ /** Company logo (feature variant). */
16
+ logo?: SiteImage2;
17
+ /** 1–5. Rendered only with a `source` (D6-8). */
18
+ rating?: number;
19
+ source?: ReviewSource;
20
+ /** `YYYY-MM-DD`. */
21
+ date?: string;
22
+ /** Link to the original review. */
23
+ link?: SiteLink2;
24
+ }
25
+ export interface ReviewSummary {
26
+ rating: number;
27
+ count: number;
28
+ source: ReviewSource;
29
+ link?: SiteLink2;
30
+ }
31
+ export interface TestimonialsProps extends Omit<BlockBaseProps, "variant" | "labels"> {
32
+ /**
33
+ * feature: one large serif quote with a hanging quote mark. wall: uneven columns of quotes, no
34
+ * cards. carousel: sliding quotes with arrows and a "3 / 8" counter (no autoplay).
35
+ * reviews: sticky rating summary beside a dated review list.
36
+ */
37
+ variant?: TestimonialsVariant;
38
+ eyebrow?: React.ReactNode;
39
+ title?: React.ReactNode;
40
+ lead?: React.ReactNode;
41
+ items: TestimonialItem[];
42
+ /** `reviews` variant: "4.8 on Google — 1,240 reviews". */
43
+ summary?: ReviewSummary;
44
+ labels?: Site2BlockLabels;
45
+ }
46
+ /**
47
+ * Customer voices: agency references, Google reviews for a spa or restaurant, SaaS quotes.
48
+ * `figure > blockquote + figcaption`, locale quotation marks, stars only with a named source.
49
+ * Server component; `carousel` adds a ~1 KB scroll-snap island.
50
+ *
51
+ * ```tsx
52
+ * <Testimonials variant="wall" title="What clients *say*" items={quotes} />
53
+ * ```
54
+ */
55
+ export declare function Testimonials({ variant: variantProp, eyebrow, title, lead, items, summary, id, anchor, theme, headingLevel, className, labels, locale, components, editMode, }: TestimonialsProps): React.JSX.Element;
56
+ /** Monochrome stars with a text alternative ("4.8 out of 5"). */
57
+ declare const RATING_STAR_SIZE: {
58
+ readonly sm: "size-3";
59
+ readonly md: "size-3.5";
60
+ readonly lg: "size-5";
61
+ };
62
+ export declare function RatingStars({ rating, label, size, className }: {
63
+ rating: number;
64
+ label: string;
65
+ size?: keyof typeof RATING_STAR_SIZE;
66
+ className?: string;
67
+ }): React.JSX.Element;
68
+ export {};
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { Star } from "lucide-react";
4
+ import { cn2 as cn } from "./shared/kit-2.js";
5
+ import { createFormatter } from "../../format/core.js";
6
+ import { Section, Container } from "../section.js";
7
+ import { SectionHeader } from "../section-header.js";
8
+ import { BlockImage } from "../block-image.js";
9
+ import { BlockLink } from "../block-link.js";
10
+ import { labelTemplates, site2Text } from "./shared/labels-2.js";
11
+ import { fieldAttr, formatDate2, isoDay, useBlockIds2 } from "./shared/kit-2.js";
12
+ import { TestimonialsCarousel } from "./shared/testimonials-carousel.js";
13
+ import { carouselLabelKeys } from "./shared/island-keys.js";
14
+ import { Reveal, Stagger } from "../../motion/reveal.js";
15
+ export const REVIEW_SOURCE_NAMES = { google: "Google", yandex: "Yandex", tripadvisor: "Tripadvisor", trustpilot: "Trustpilot", direct: "" };
16
+ /**
17
+ * Customer voices: agency references, Google reviews for a spa or restaurant, SaaS quotes.
18
+ * `figure > blockquote + figcaption`, locale quotation marks, stars only with a named source.
19
+ * Server component; `carousel` adds a ~1 KB scroll-snap island.
20
+ *
21
+ * ```tsx
22
+ * <Testimonials variant="wall" title="What clients *say*" items={quotes} />
23
+ * ```
24
+ */
25
+ export function Testimonials({ variant: variantProp = "feature", eyebrow, title, lead, items, summary, id, anchor, theme, headingLevel = 2, className, labels, locale = "en-US", components, editMode, }) {
26
+ const t = site2Text(labels, locale);
27
+ const { headingId } = useBlockIds2(id, "testimonials");
28
+ const variant = variantProp === "carousel" && items.length < 2 ? "feature" : variantProp;
29
+ const ctx = { t, locale, components, labels, editMode };
30
+ const header = title || eyebrow || lead ? _jsx(SectionHeader, { eyebrow: eyebrow, title: title, lead: lead, headingId: headingId, headingLevel: headingLevel, editMode: editMode, labels: labels, locale: locale }) : null;
31
+ return (_jsx(Section, { theme: theme, anchor: anchor, headingId: title ? headingId : undefined, blockId: id, blockType: "testimonials", editMode: editMode, className: cn("vb-testimonials", className), "data-variant": variant, children: _jsx(Container, { className: "flex flex-col gap-12 @4xl:gap-16", children: variant === "carousel" ? (_jsx(TestimonialsCarousel, { header: header, count: items.length, labels: labelTemplates(labels, carouselLabelKeys), locale: locale, children: items.map((item, i) => (_jsx(QuoteFigure, { item: item, index: i, ctx: ctx, size: "m" }, i))) })) : (_jsxs(_Fragment, { children: [variant !== "reviews" ? header : null, variant === "feature" ? (_jsx(Reveal, { disabled: editMode, children: _jsx(FeatureQuote, { item: items[0], ctx: ctx }) })) : variant === "wall" ? (_jsx(Stagger, { asChild: true, disabled: editMode, children: _jsx("ul", { className: "vb-quote-wall gap-x-(--gutter) @2xl:columns-2 @4xl:columns-3", children: items.map((item, i) => (_jsx("li", { className: "mb-12 break-inside-avoid border-t border-line pt-6", children: _jsx(QuoteFigure, { item: item, index: i, ctx: ctx }) }, i))) }) })) : (_jsx(Reveal, { disabled: editMode, children: _jsx(ReviewsLayout, { header: header, items: items, summary: summary, ctx: ctx }) }))] })) }) }));
32
+ }
33
+ /** Monochrome stars with a text alternative ("4.8 out of 5"). */
34
+ const RATING_STAR_SIZE = { sm: "size-3", md: "size-3.5", lg: "size-5" };
35
+ export function RatingStars({ rating, label, size = "md", className }) {
36
+ const r = Math.max(0, Math.min(5, rating));
37
+ const s = RATING_STAR_SIZE[size];
38
+ return (_jsx("span", { role: "img", "aria-label": label, className: cn("inline-flex items-center gap-0.5 text-fg", className), children: [0, 1, 2, 3, 4].map((i) => {
39
+ const fill = Math.max(0, Math.min(1, r - i));
40
+ return (_jsxs("span", { "aria-hidden": true, className: cn("relative inline-flex", s), children: [_jsx(Star, { strokeWidth: 1.5, className: cn("absolute inset-0 text-fg-subtle", s) }), fill > 0 ? (_jsx("span", { className: "absolute inset-y-0 start-0 overflow-hidden", style: { width: `${fill * 100}%` }, children: _jsx(Star, { strokeWidth: 1.5, className: cn("fill-current", s) }) })) : null] }, i));
41
+ }) }));
42
+ }
43
+ function Attribution({ item, ctx, align = "start", as: Comp = "figcaption" }) {
44
+ const meta = [item.role, item.company].filter(Boolean);
45
+ return (_jsxs(Comp, { className: cn("flex items-center gap-3", align === "between" && "justify-between"), children: [_jsxs("span", { className: "flex items-center gap-3", children: [item.avatar ? (_jsx(BlockImage, { ...item.avatar, alt: item.avatar.alt ?? "", decorative: !item.avatar.alt, aspect: "1:1", sizes: "40px", className: "size-10 shrink-0 rounded-full", components: ctx.components })) : null, _jsxs("span", { className: "flex flex-col", children: [_jsx("span", { className: "text-sm font-medium text-fg", children: item.author }), meta.length ? (_jsx("span", { className: "font-mono text-eyebrow uppercase tracking-[0.06em] text-fg-muted", children: meta.map((m, i) => (_jsxs(React.Fragment, { children: [i > 0 ? " · " : null, m] }, i))) })) : null] })] }), align === "between" && item.logo ? (_jsx(BlockImage, { ...item.logo, alt: item.logo.alt ?? "", decorative: !item.logo.alt, fit: "contain", className: "h-7 w-24 bg-transparent opacity-80", imgClassName: "vb-logo-mono", components: ctx.components })) : null] }));
46
+ }
47
+ function SourceLine({ item, ctx }) {
48
+ const showRating = item.rating !== undefined && item.source;
49
+ const name = item.source ? REVIEW_SOURCE_NAMES[item.source] : "";
50
+ if (!showRating && !item.date && !name)
51
+ return null;
52
+ return (_jsxs("p", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-fg-muted", children: [showRating ? _jsx(RatingStars, { rating: item.rating, label: ctx.t("ratingOutOf", { rating: item.rating }) }) : null, name ? (item.link ? (_jsx(BlockLink, { href: item.link.href, newTab: item.link.newTab ?? true, components: ctx.components, labels: ctx.labels, locale: ctx.locale, className: "underline decoration-line underline-offset-[0.25em] hover:decoration-current focus-ring rounded-[2px]", children: name })) : (_jsx("span", { children: name }))) : null, item.date ? _jsx("time", { dateTime: isoDay(item.date), children: formatDate2(isoDay(item.date), ctx.locale, "medium") }) : null] }));
53
+ }
54
+ function QuoteFigure({ item, index, ctx, size = "s" }) {
55
+ return (_jsxs("figure", { className: "flex flex-col gap-5", children: [_jsx(SourceLine, { item: item, ctx: ctx }), _jsx("blockquote", { className: cn("text-fg text-pretty", size === "m" ? "text-lead" : "text-body"), ...fieldAttr(ctx.editMode, `items.${index}.quote`), children: _jsxs("p", { children: [_jsx("span", { "aria-hidden": true, children: ctx.t("quoteOpen") }), item.quote, _jsx("span", { "aria-hidden": true, children: ctx.t("quoteClose") })] }) }), _jsx(Attribution, { item: item, ctx: ctx })] }));
56
+ }
57
+ function FeatureQuote({ item, ctx }) {
58
+ return (_jsxs("figure", { className: "grid gap-y-10 @4xl:grid-cols-12 @4xl:gap-x-(--gutter)", children: [_jsxs("blockquote", { className: "relative @4xl:col-span-10 @4xl:col-start-2", ...fieldAttr(ctx.editMode, "items.0.quote"), children: [_jsx("span", { "aria-hidden": true, className: "vb-quote-mark pointer-events-none absolute -top-[0.08em] end-full me-[0.12em] font-display text-display-l leading-none text-accent-ink", children: ctx.t("quoteOpen") }), _jsxs("p", { className: "font-display text-display-m text-fg text-pretty", children: [item.quote, _jsx("span", { "aria-hidden": true, children: ctx.t("quoteClose") })] })] }), _jsxs("figcaption", { className: "flex flex-col gap-4 border-t border-line pt-6 @4xl:col-span-10 @4xl:col-start-2", children: [_jsx(Attribution, { item: item, ctx: ctx, align: "between", as: "div" }), _jsx(SourceLine, { item: item, ctx: ctx })] })] }));
59
+ }
60
+ function ReviewsLayout({ header, items, summary, ctx }) {
61
+ const nf = createFormatter(ctx.locale);
62
+ const sourceName = summary ? REVIEW_SOURCE_NAMES[summary.source] : "";
63
+ return (_jsxs("div", { className: "grid gap-x-(--gutter) gap-y-12 @4xl:grid-cols-12", children: [_jsxs("div", { className: "flex flex-col gap-8 @4xl:sticky @4xl:top-[calc(var(--topbar-h,0px)+2rem)] @4xl:col-span-4 @4xl:self-start", children: [header, summary ? (_jsxs("div", { className: "flex flex-col gap-3 border-t border-line pt-6", children: [_jsxs("p", { className: "flex items-baseline gap-3", children: [_jsx("span", { className: "font-display text-display-l tabular text-fg", children: nf.number(summary.rating, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) }), _jsx(RatingStars, { rating: summary.rating, label: ctx.t("ratingOutOf", { rating: nf.number(summary.rating, { maximumFractionDigits: 1 }) }) })] }), _jsxs("p", { className: "text-small text-fg-muted", children: [sourceName
64
+ ? ctx.t("ratingSummary", { rating: nf.number(summary.rating, { maximumFractionDigits: 1 }), source: sourceName })
65
+ : ctx.t("ratingSummaryDirect", { rating: nf.number(summary.rating, { maximumFractionDigits: 1 }) }), " ", "\u2014 ", ctx.t("reviewCount", { count: summary.count })] }), summary.link ? (_jsx(BlockLink, { href: summary.link.href, newTab: summary.link.newTab ?? true, appearance: "link", components: ctx.components, labels: ctx.labels, locale: ctx.locale, className: "self-start text-small", children: summary.link.label ?? ctx.t("readAllReviews") })) : null] })) : null] }), _jsx("ol", { className: "flex flex-col @4xl:col-span-7 @4xl:col-start-6", children: items.map((item, i) => (_jsx("li", { className: "border-t border-line py-7 first:border-t-0 first:pt-0 @4xl:first:border-t @4xl:first:pt-7", children: _jsx(QuoteFigure, { item: item, index: i, ctx: ctx }) }, i))) })] }));
66
+ }