@ojiepermana/angular 22.1.10 → 22.1.12

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 (340) hide show
  1. package/README.md +32 -26
  2. package/chart/README.md +272 -0
  3. package/component/README.md +89 -0
  4. package/component/accordion/README.md +195 -0
  5. package/component/alert/README.md +184 -0
  6. package/component/alert-dialog/README.md +255 -0
  7. package/component/aspect-ratio/README.md +116 -0
  8. package/component/avatar/README.md +182 -0
  9. package/component/badge/README.md +143 -0
  10. package/component/breadcrumb/README.md +223 -0
  11. package/component/button/README.md +141 -0
  12. package/component/button-group/README.md +214 -0
  13. package/component/calendar/README.md +137 -0
  14. package/component/card/README.md +232 -0
  15. package/component/carousel/README.md +276 -0
  16. package/component/checkbox/README.md +153 -0
  17. package/component/collapsible/README.md +216 -0
  18. package/component/combobox/README.md +202 -0
  19. package/component/command/README.md +287 -0
  20. package/component/composer/README.md +241 -0
  21. package/component/context-menu/README.md +268 -0
  22. package/component/date-picker/README.md +202 -0
  23. package/component/dialog/README.md +276 -0
  24. package/component/drawer/README.md +147 -0
  25. package/component/dropdown-menu/README.md +336 -0
  26. package/component/editor/README.md +152 -0
  27. package/component/empty/README.md +193 -0
  28. package/component/form/README.md +216 -0
  29. package/component/hover-card/README.md +150 -0
  30. package/component/icon/README.md +25 -0
  31. package/component/input/README.md +160 -0
  32. package/component/input-group/README.md +245 -0
  33. package/component/input-otp/README.md +331 -0
  34. package/component/item/README.md +254 -0
  35. package/component/kanban/README.md +81 -0
  36. package/component/kbd/README.md +141 -0
  37. package/component/label/README.md +137 -0
  38. package/component/menubar/README.md +270 -0
  39. package/component/native-select/README.md +176 -0
  40. package/component/navigation-menu/README.md +165 -0
  41. package/component/pagination/README.md +151 -0
  42. package/component/pillbox/README.md +68 -0
  43. package/component/popover/README.md +54 -0
  44. package/component/progress/README.md +160 -0
  45. package/component/radio/README.md +212 -0
  46. package/component/resizable/README.md +178 -0
  47. package/component/scroll-area/README.md +150 -0
  48. package/component/select/README.md +228 -0
  49. package/component/separator/README.md +175 -0
  50. package/component/sheet/README.md +190 -0
  51. package/component/skeleton/README.md +158 -0
  52. package/component/slider/README.md +207 -0
  53. package/component/spinner/README.md +160 -0
  54. package/component/switch/README.md +170 -0
  55. package/component/table/README.md +292 -0
  56. package/component/tabs/README.md +220 -0
  57. package/component/textarea/README.md +169 -0
  58. package/component/timeline/README.md +94 -0
  59. package/component/toast/README.md +173 -0
  60. package/component/toggle/README.md +133 -0
  61. package/component/toggle-group/README.md +234 -0
  62. package/component/tooltip/README.md +230 -0
  63. package/fesm2022/ojiepermana-angular-chart-area.mjs +289 -3
  64. package/fesm2022/ojiepermana-angular-chart-bar.mjs +722 -3
  65. package/fesm2022/ojiepermana-angular-chart-core.mjs +1482 -3
  66. package/fesm2022/ojiepermana-angular-chart-line.mjs +294 -3
  67. package/fesm2022/ojiepermana-angular-chart-pie.mjs +291 -3
  68. package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1301 -3
  69. package/fesm2022/ojiepermana-angular-chart-radar.mjs +421 -3
  70. package/fesm2022/ojiepermana-angular-chart-radial.mjs +295 -3
  71. package/fesm2022/ojiepermana-angular-chart-scatter.mjs +306 -3
  72. package/fesm2022/ojiepermana-angular-chart.mjs +12 -3
  73. package/fesm2022/ojiepermana-angular-component-accordion.mjs +267 -3
  74. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +359 -3
  75. package/fesm2022/ojiepermana-angular-component-alert.mjs +101 -3
  76. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +31 -3
  77. package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -3
  78. package/fesm2022/ojiepermana-angular-component-badge.mjs +57 -3
  79. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +192 -3
  80. package/fesm2022/ojiepermana-angular-component-button-group.mjs +95 -3
  81. package/fesm2022/ojiepermana-angular-component-button.mjs +73 -3
  82. package/fesm2022/ojiepermana-angular-component-calendar.mjs +718 -3
  83. package/fesm2022/ojiepermana-angular-component-card.mjs +167 -3
  84. package/fesm2022/ojiepermana-angular-component-carousel.mjs +326 -3
  85. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +190 -3
  86. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +117 -3
  87. package/fesm2022/ojiepermana-angular-component-combobox.mjs +327 -3
  88. package/fesm2022/ojiepermana-angular-component-command.mjs +351 -3
  89. package/fesm2022/ojiepermana-angular-component-composer.mjs +359 -3
  90. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +158 -3
  91. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +482 -3
  92. package/fesm2022/ojiepermana-angular-component-dialog.mjs +400 -3
  93. package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -3
  94. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +689 -3
  95. package/fesm2022/ojiepermana-angular-component-editor.mjs +511 -3
  96. package/fesm2022/ojiepermana-angular-component-empty.mjs +134 -3
  97. package/fesm2022/ojiepermana-angular-component-form.mjs +438 -3
  98. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +273 -3
  99. package/fesm2022/ojiepermana-angular-component-icon.mjs +139 -3
  100. package/fesm2022/ojiepermana-angular-component-input-group.mjs +176 -3
  101. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +550 -3
  102. package/fesm2022/ojiepermana-angular-component-input.mjs +52 -3
  103. package/fesm2022/ojiepermana-angular-component-item.mjs +264 -3
  104. package/fesm2022/ojiepermana-angular-component-kanban.mjs +310 -3
  105. package/fesm2022/ojiepermana-angular-component-kbd.mjs +48 -3
  106. package/fesm2022/ojiepermana-angular-component-label.mjs +27 -3
  107. package/fesm2022/ojiepermana-angular-component-menubar.mjs +327 -3
  108. package/fesm2022/ojiepermana-angular-component-native-select.mjs +62 -3
  109. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +378 -3
  110. package/fesm2022/ojiepermana-angular-component-pagination.mjs +238 -3
  111. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +999 -3
  112. package/fesm2022/ojiepermana-angular-component-popover.mjs +201 -3
  113. package/fesm2022/ojiepermana-angular-component-progress.mjs +57 -3
  114. package/fesm2022/ojiepermana-angular-component-radio.mjs +180 -3
  115. package/fesm2022/ojiepermana-angular-component-resizable.mjs +493 -3
  116. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +51 -3
  117. package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +227 -3
  118. package/fesm2022/ojiepermana-angular-component-select.mjs +609 -3
  119. package/fesm2022/ojiepermana-angular-component-separator.mjs +31 -3
  120. package/fesm2022/ojiepermana-angular-component-sheet.mjs +407 -3
  121. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +25 -3
  122. package/fesm2022/ojiepermana-angular-component-slider.mjs +456 -3
  123. package/fesm2022/ojiepermana-angular-component-spinner.mjs +56 -3
  124. package/fesm2022/ojiepermana-angular-component-switch.mjs +145 -3
  125. package/fesm2022/ojiepermana-angular-component-table.mjs +155 -3
  126. package/fesm2022/ojiepermana-angular-component-tabs.mjs +315 -3
  127. package/fesm2022/ojiepermana-angular-component-textarea.mjs +46 -3
  128. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -3
  129. package/fesm2022/ojiepermana-angular-component-toast.mjs +241 -3
  130. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +290 -3
  131. package/fesm2022/ojiepermana-angular-component-toggle.mjs +76 -3
  132. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +519 -3
  133. package/fesm2022/ojiepermana-angular-component-utils-core.mjs +310 -3
  134. package/fesm2022/ojiepermana-angular-component-utils-overlay.mjs +62 -3
  135. package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +34 -3
  136. package/fesm2022/ojiepermana-angular-component-utils.mjs +3 -2
  137. package/fesm2022/ojiepermana-angular-component.mjs +4 -4
  138. package/fesm2022/ojiepermana-angular-navigation-core.mjs +21 -3
  139. package/fesm2022/ojiepermana-angular-navigation-icon.mjs +20 -3
  140. package/fesm2022/ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs +91 -0
  141. package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs +512 -0
  142. package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-Cd-jh6tg.mjs +623 -0
  143. package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs +404 -0
  144. package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs +466 -0
  145. package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-DNKU6viC.mjs +2642 -0
  146. package/fesm2022/ojiepermana-angular-navigation-service.mjs +725 -3
  147. package/fesm2022/ojiepermana-angular-navigation-types.mjs +65 -4
  148. package/fesm2022/ojiepermana-angular-navigation.mjs +4 -10
  149. package/fesm2022/ojiepermana-angular-sdk.mjs +204 -4
  150. package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +1387 -3
  151. package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +331 -3
  152. package/fesm2022/ojiepermana-angular-theme-layout-types.mjs +45 -4
  153. package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +1044 -3
  154. package/fesm2022/ojiepermana-angular-theme-layout.mjs +729 -3
  155. package/fesm2022/ojiepermana-angular-theme-page-core.mjs +381 -3
  156. package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +267 -3
  157. package/fesm2022/ojiepermana-angular-theme-page-root.mjs +361 -3
  158. package/fesm2022/ojiepermana-angular-theme-page-side.mjs +198 -3
  159. package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +110 -3
  160. package/fesm2022/ojiepermana-angular-theme-page.mjs +7 -2
  161. package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +338 -3
  162. package/fesm2022/ojiepermana-angular-theme-shell-types.mjs +160 -4
  163. package/fesm2022/ojiepermana-angular-theme-shell.mjs +811 -3
  164. package/fesm2022/ojiepermana-angular-theme-styles.mjs +783 -3
  165. package/fesm2022/ojiepermana-angular-theme.mjs +4 -4
  166. package/fesm2022/ojiepermana-angular.mjs +6 -11
  167. package/navigation/README.md +374 -0
  168. package/package.json +81 -20
  169. package/sdk/README.md +212 -0
  170. package/sdk/schematics/collection.json +20 -0
  171. package/sdk/schematics/init/index.js +83 -0
  172. package/sdk/schematics/init/schema.json +19 -0
  173. package/sdk/schematics/ng-add/index.js +147 -0
  174. package/sdk/schematics/ng-add/schema.json +14 -0
  175. package/sdk/schematics/package.json +3 -0
  176. package/sdk/schematics/sdk/index.js +175 -0
  177. package/sdk/schematics/sdk/schema.json +19 -0
  178. package/sdk/sdk.config.example.json +24 -0
  179. package/sdk/src/config/loader.js +43 -0
  180. package/sdk/src/config/schema.js +59 -0
  181. package/sdk/src/emit/client.js +251 -0
  182. package/sdk/src/emit/metadata.js +310 -0
  183. package/sdk/src/emit/models.js +104 -0
  184. package/sdk/src/emit/navigation.js +56 -0
  185. package/sdk/src/emit/operations.js +118 -0
  186. package/sdk/src/emit/public-api.js +54 -0
  187. package/sdk/src/emit/services.js +110 -0
  188. package/sdk/src/engine.js +67 -0
  189. package/sdk/src/layout/per-domain.js +360 -0
  190. package/sdk/src/package.json +3 -0
  191. package/sdk/src/parser/bundle.js +25 -0
  192. package/sdk/src/parser/ir.js +429 -0
  193. package/sdk/src/parser/types.js +7 -0
  194. package/sdk/src/render/template.js +152 -0
  195. package/sdk/src/writer/index.js +286 -0
  196. package/theme/README.md +126 -0
  197. package/theme/component/settings/README.md +135 -0
  198. package/theme/layout/README.md +539 -0
  199. package/theme/page/README.md +453 -0
  200. package/theme/shell/README.md +340 -0
  201. package/theme/styles/README.md +178 -0
  202. package/theme/styles/css/base/components.css +553 -0
  203. package/theme/styles/css/base/index.css +14 -0
  204. package/theme/styles/css/base/package.css +9 -0
  205. package/theme/styles/css/base/prefers-dark.css +86 -0
  206. package/theme/styles/css/base/print.css +62 -0
  207. package/theme/styles/css/base/status.css +38 -0
  208. package/theme/styles/css/base/tailwind.css +165 -0
  209. package/theme/styles/css/base/theme.css +373 -0
  210. package/theme/styles/css/base/tokens.css +361 -0
  211. package/theme/styles/css/color/amber.css +72 -0
  212. package/theme/styles/css/color/blue.css +72 -0
  213. package/theme/styles/css/color/brand.css +38 -0
  214. package/theme/styles/css/color/cyan.css +72 -0
  215. package/theme/styles/css/color/emerald.css +72 -0
  216. package/theme/styles/css/color/fuchsia.css +72 -0
  217. package/theme/styles/css/color/green.css +72 -0
  218. package/theme/styles/css/color/index.css +19 -0
  219. package/theme/styles/css/color/indigo.css +72 -0
  220. package/theme/styles/css/color/lime.css +72 -0
  221. package/theme/styles/css/color/orange.css +72 -0
  222. package/theme/styles/css/color/pink.css +72 -0
  223. package/theme/styles/css/color/purple.css +72 -0
  224. package/theme/styles/css/color/red.css +72 -0
  225. package/theme/styles/css/color/rose.css +72 -0
  226. package/theme/styles/css/color/sky.css +72 -0
  227. package/theme/styles/css/color/teal.css +72 -0
  228. package/theme/styles/css/color/violet.css +72 -0
  229. package/theme/styles/css/color/yellow.css +72 -0
  230. package/theme/styles/css/index.css +18 -0
  231. package/theme/styles/css/neutral/gray.css +63 -0
  232. package/theme/styles/css/neutral/index.css +11 -0
  233. package/theme/styles/css/neutral/mauve.css +63 -0
  234. package/theme/styles/css/neutral/mist.css +63 -0
  235. package/theme/styles/css/neutral/neutral.css +63 -0
  236. package/theme/styles/css/neutral/olive.css +63 -0
  237. package/theme/styles/css/neutral/slate.css +63 -0
  238. package/theme/styles/css/neutral/stone.css +63 -0
  239. package/theme/styles/css/neutral/taupe.css +63 -0
  240. package/theme/styles/css/neutral/zinc.css +63 -0
  241. package/theme/styles/css/radius/index.css +30 -0
  242. package/theme/styles/css/space/index.css +20 -0
  243. package/types/ojiepermana-angular-chart-area.d.ts +76 -1
  244. package/types/ojiepermana-angular-chart-bar.d.ts +201 -1
  245. package/types/ojiepermana-angular-chart-core.d.ts +811 -1
  246. package/types/ojiepermana-angular-chart-line.d.ts +75 -1
  247. package/types/ojiepermana-angular-chart-pie.d.ts +131 -1
  248. package/types/ojiepermana-angular-chart-primitives.d.ts +291 -1
  249. package/types/ojiepermana-angular-chart-radar.d.ts +116 -1
  250. package/types/ojiepermana-angular-chart-radial.d.ts +116 -1
  251. package/types/ojiepermana-angular-chart-scatter.d.ts +125 -1
  252. package/types/ojiepermana-angular-chart.d.ts +2 -1
  253. package/types/ojiepermana-angular-component-accordion.d.ts +85 -1
  254. package/types/ojiepermana-angular-component-alert-dialog.d.ts +140 -1
  255. package/types/ojiepermana-angular-component-alert.d.ts +42 -1
  256. package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -1
  257. package/types/ojiepermana-angular-component-avatar.d.ts +56 -1
  258. package/types/ojiepermana-angular-component-badge.d.ts +24 -1
  259. package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -1
  260. package/types/ojiepermana-angular-component-button-group.d.ts +26 -1
  261. package/types/ojiepermana-angular-component-button.d.ts +27 -1
  262. package/types/ojiepermana-angular-component-calendar.d.ts +111 -1
  263. package/types/ojiepermana-angular-component-card.d.ts +69 -1
  264. package/types/ojiepermana-angular-component-carousel.d.ts +86 -1
  265. package/types/ojiepermana-angular-component-checkbox.d.ts +42 -1
  266. package/types/ojiepermana-angular-component-collapsible.d.ts +42 -1
  267. package/types/ojiepermana-angular-component-combobox.d.ts +60 -1
  268. package/types/ojiepermana-angular-component-command.d.ts +130 -1
  269. package/types/ojiepermana-angular-component-composer.d.ts +90 -1
  270. package/types/ojiepermana-angular-component-context-menu.d.ts +54 -1
  271. package/types/ojiepermana-angular-component-date-picker.d.ts +109 -1
  272. package/types/ojiepermana-angular-component-dialog.d.ts +136 -1
  273. package/types/ojiepermana-angular-component-drawer.d.ts +1 -1
  274. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +248 -1
  275. package/types/ojiepermana-angular-component-editor.d.ts +135 -1
  276. package/types/ojiepermana-angular-component-empty.d.ts +50 -1
  277. package/types/ojiepermana-angular-component-form.d.ts +159 -1
  278. package/types/ojiepermana-angular-component-hover-card.d.ts +75 -1
  279. package/types/ojiepermana-angular-component-icon.d.ts +89 -1
  280. package/types/ojiepermana-angular-component-input-group.d.ts +51 -1
  281. package/types/ojiepermana-angular-component-input-otp.d.ts +155 -1
  282. package/types/ojiepermana-angular-component-input.d.ts +21 -1
  283. package/types/ojiepermana-angular-component-item.d.ts +93 -1
  284. package/types/ojiepermana-angular-component-kanban.d.ts +70 -1
  285. package/types/ojiepermana-angular-component-kbd.d.ts +16 -1
  286. package/types/ojiepermana-angular-component-label.d.ts +11 -1
  287. package/types/ojiepermana-angular-component-menubar.d.ts +93 -1
  288. package/types/ojiepermana-angular-component-native-select.d.ts +26 -1
  289. package/types/ojiepermana-angular-component-navigation-menu.d.ts +104 -1
  290. package/types/ojiepermana-angular-component-pagination.d.ts +33 -1
  291. package/types/ojiepermana-angular-component-pillbox.d.ts +222 -1
  292. package/types/ojiepermana-angular-component-popover.d.ts +66 -1
  293. package/types/ojiepermana-angular-component-progress.d.ts +17 -1
  294. package/types/ojiepermana-angular-component-radio.d.ts +60 -1
  295. package/types/ojiepermana-angular-component-resizable.d.ts +117 -1
  296. package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -1
  297. package/types/ojiepermana-angular-component-segmented-control.d.ts +58 -1
  298. package/types/ojiepermana-angular-component-select.d.ts +122 -1
  299. package/types/ojiepermana-angular-component-separator.d.ts +14 -1
  300. package/types/ojiepermana-angular-component-sheet.d.ts +130 -1
  301. package/types/ojiepermana-angular-component-skeleton.d.ts +10 -1
  302. package/types/ojiepermana-angular-component-slider.d.ts +83 -1
  303. package/types/ojiepermana-angular-component-spinner.d.ts +13 -1
  304. package/types/ojiepermana-angular-component-switch.d.ts +44 -1
  305. package/types/ojiepermana-angular-component-table.d.ts +57 -1
  306. package/types/ojiepermana-angular-component-tabs.d.ts +124 -1
  307. package/types/ojiepermana-angular-component-textarea.d.ts +17 -1
  308. package/types/ojiepermana-angular-component-timeline.d.ts +64 -1
  309. package/types/ojiepermana-angular-component-toast.d.ts +64 -1
  310. package/types/ojiepermana-angular-component-toggle-group.d.ts +90 -1
  311. package/types/ojiepermana-angular-component-toggle.d.ts +25 -1
  312. package/types/ojiepermana-angular-component-tooltip.d.ts +143 -1
  313. package/types/ojiepermana-angular-component-utils-core.d.ts +184 -1
  314. package/types/ojiepermana-angular-component-utils-overlay.d.ts +21 -1
  315. package/types/ojiepermana-angular-component-utils-scale.d.ts +19 -1
  316. package/types/ojiepermana-angular-component-utils.d.ts +2 -1
  317. package/types/ojiepermana-angular-component.d.ts +2 -1
  318. package/types/ojiepermana-angular-navigation-core.d.ts +59 -1
  319. package/types/ojiepermana-angular-navigation-icon.d.ts +12 -1
  320. package/types/ojiepermana-angular-navigation-service.d.ts +116 -1
  321. package/types/ojiepermana-angular-navigation-types.d.ts +144 -1
  322. package/types/ojiepermana-angular-navigation.d.ts +507 -1
  323. package/types/ojiepermana-angular-sdk.d.ts +89 -1
  324. package/types/ojiepermana-angular-theme-component-settings.d.ts +154 -1
  325. package/types/ojiepermana-angular-theme-layout-services.d.ts +147 -1
  326. package/types/ojiepermana-angular-theme-layout-types.d.ts +40 -1
  327. package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +299 -1
  328. package/types/ojiepermana-angular-theme-layout.d.ts +129 -1
  329. package/types/ojiepermana-angular-theme-page-core.d.ts +157 -1
  330. package/types/ojiepermana-angular-theme-page-filter.d.ts +77 -1
  331. package/types/ojiepermana-angular-theme-page-root.d.ts +88 -1
  332. package/types/ojiepermana-angular-theme-page-side.d.ts +50 -1
  333. package/types/ojiepermana-angular-theme-page-slots.d.ts +40 -1
  334. package/types/ojiepermana-angular-theme-page.d.ts +5 -1
  335. package/types/ojiepermana-angular-theme-shell-services.d.ts +193 -1
  336. package/types/ojiepermana-angular-theme-shell-types.d.ts +105 -1
  337. package/types/ojiepermana-angular-theme-shell.d.ts +100 -1
  338. package/types/ojiepermana-angular-theme-styles.d.ts +319 -1
  339. package/types/ojiepermana-angular-theme.d.ts +2 -1
  340. package/types/ojiepermana-angular.d.ts +5 -5
@@ -1,7 +1,1305 @@
1
- export * from '@ojiepermana/angular-chart/primitives';
1
+ import * as i0 from '@angular/core';
2
+ import { inject, input, computed, Component, viewChild, DestroyRef, signal, Directive, ElementRef, NgZone, PLATFORM_ID, afterNextRender, afterRenderEffect, contentChild, TemplateRef } from '@angular/core';
3
+ import { CartesianContext, linearTicks, bandTicks, ChartContext, CategoricalViewportContext, ScatterViewportContext, nearestCategoryIndex, normalizeIndexRange, panIndexRange, panNumericDomain, indexRangeSize, normalizeNumericDomain, zoomNumericDomain, zoomIndexRange, seriesColorVar, effectiveIndexRange } from '@ojiepermana/angular/chart/core';
4
+ import { DOCUMENT, isPlatformBrowser, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
2
5
 
3
- // Generated by scripts/gen-umbrella-entrypoints.mjs — do not edit by hand.
6
+ /**
7
+ * X axis for a cartesian chart. Reads scales from `CartesianContext`.
8
+ *
9
+ * Renders as `<svg:g>` — must be placed inside the owning chart's SVG.
10
+ */
11
+ class ChartAxisX {
12
+ ctx = inject(CartesianContext);
13
+ /** Approximate tick count for linear (value) scales. */
14
+ tickCount = input(5, /* @ts-ignore */
15
+ ...(ngDevMode ? [{ debugName: "tickCount" }] : /* istanbul ignore next */ []));
16
+ /** Show 6-px tick marks between the axis line and the labels. */
17
+ tickLine = input(true, /* @ts-ignore */
18
+ ...(ngDevMode ? [{ debugName: "tickLine" }] : /* istanbul ignore next */ []));
19
+ /** Formatter for numeric tick labels. */
20
+ tickFormat = input((v) => String(v), /* @ts-ignore */
21
+ ...(ngDevMode ? [{ debugName: "tickFormat" }] : /* istanbul ignore next */ []));
22
+ innerWidth = this.ctx.innerWidth;
23
+ transform = computed(() => `translate(0,${this.ctx.innerHeight()})`, /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "transform" }] : /* istanbul ignore next */ []));
25
+ ticks = computed(() => {
26
+ const horizontal = this.ctx.orientation() === 'horizontal';
27
+ if (horizontal) {
28
+ const scale = this.ctx.valueScale();
29
+ return scale ? linearTicks(scale, this.tickCount(), this.tickFormat()) : [];
30
+ }
31
+ const scale = this.ctx.categoryScale();
32
+ return scale ? bandTicks(scale) : [];
33
+ }, /* @ts-ignore */
34
+ ...(ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []));
35
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartAxisX, deps: [], target: i0.ɵɵFactoryTarget.Component });
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartAxisX, isStandalone: true, selector: "svg:g[ChartAxisX]", inputs: { tickCount: { classPropertyName: "tickCount", publicName: "tickCount", isSignal: true, isRequired: false, transformFunction: null }, tickLine: { classPropertyName: "tickLine", publicName: "tickLine", isSignal: true, isRequired: false, transformFunction: null }, tickFormat: { classPropertyName: "tickFormat", publicName: "tickFormat", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.transform": "transform()" }, classAttribute: "chart-axis chart-axis-x text-muted-foreground" }, ngImport: i0, template: `
37
+ <svg:line class="stroke-border" [attr.x1]="0" [attr.x2]="innerWidth()" y1="0" y2="0" />
38
+ @for (t of ticks(); track t.value) {
39
+ <svg:g [attr.transform]="'translate(' + t.offset + ',0)'">
40
+ @if (tickLine()) {
41
+ <svg:line class="stroke-border" y1="0" y2="6" />
42
+ }
43
+ <svg:text
44
+ class="fill-current"
45
+ y="18"
46
+ text-anchor="middle"
47
+ style="font-size: var(--text-xs); font-family: var(--font-sans)"
48
+ >
49
+ {{ t.label }}
50
+ </svg:text>
51
+ </svg:g>
52
+ }
53
+ `, isInline: true });
54
+ }
55
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartAxisX, decorators: [{
56
+ type: Component,
57
+ args: [{
58
+ selector: 'svg:g[ChartAxisX]',
59
+ host: {
60
+ class: 'chart-axis chart-axis-x text-muted-foreground',
61
+ '[attr.transform]': 'transform()',
62
+ },
63
+ template: `
64
+ <svg:line class="stroke-border" [attr.x1]="0" [attr.x2]="innerWidth()" y1="0" y2="0" />
65
+ @for (t of ticks(); track t.value) {
66
+ <svg:g [attr.transform]="'translate(' + t.offset + ',0)'">
67
+ @if (tickLine()) {
68
+ <svg:line class="stroke-border" y1="0" y2="6" />
69
+ }
70
+ <svg:text
71
+ class="fill-current"
72
+ y="18"
73
+ text-anchor="middle"
74
+ style="font-size: var(--text-xs); font-family: var(--font-sans)"
75
+ >
76
+ {{ t.label }}
77
+ </svg:text>
78
+ </svg:g>
79
+ }
80
+ `,
81
+ }]
82
+ }], propDecorators: { tickCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickCount", required: false }] }], tickLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickLine", required: false }] }], tickFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickFormat", required: false }] }] } });
83
+
84
+ /**
85
+ * Y axis for a cartesian chart. Reads scales from `CartesianContext`.
86
+ *
87
+ * Renders as `<svg:g>` — must be placed inside the owning chart's SVG.
88
+ */
89
+ class ChartAxisY {
90
+ ctx = inject(CartesianContext);
91
+ tickCount = input(5, /* @ts-ignore */
92
+ ...(ngDevMode ? [{ debugName: "tickCount" }] : /* istanbul ignore next */ []));
93
+ tickLine = input(true, /* @ts-ignore */
94
+ ...(ngDevMode ? [{ debugName: "tickLine" }] : /* istanbul ignore next */ []));
95
+ tickFormat = input((v) => String(v), /* @ts-ignore */
96
+ ...(ngDevMode ? [{ debugName: "tickFormat" }] : /* istanbul ignore next */ []));
97
+ innerHeight = this.ctx.innerHeight;
98
+ ticks = computed(() => {
99
+ const horizontal = this.ctx.orientation() === 'horizontal';
100
+ if (horizontal) {
101
+ const scale = this.ctx.categoryScale();
102
+ return scale ? bandTicks(scale) : [];
103
+ }
104
+ const scale = this.ctx.valueScale();
105
+ return scale ? linearTicks(scale, this.tickCount(), this.tickFormat()) : [];
106
+ }, /* @ts-ignore */
107
+ ...(ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []));
108
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartAxisY, deps: [], target: i0.ɵɵFactoryTarget.Component });
109
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartAxisY, isStandalone: true, selector: "svg:g[ChartAxisY]", inputs: { tickCount: { classPropertyName: "tickCount", publicName: "tickCount", isSignal: true, isRequired: false, transformFunction: null }, tickLine: { classPropertyName: "tickLine", publicName: "tickLine", isSignal: true, isRequired: false, transformFunction: null }, tickFormat: { classPropertyName: "tickFormat", publicName: "tickFormat", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "chart-axis chart-axis-y text-muted-foreground" }, ngImport: i0, template: `
110
+ <svg:line class="stroke-border" x1="0" x2="0" [attr.y1]="0" [attr.y2]="innerHeight()" />
111
+ @for (t of ticks(); track t.value) {
112
+ <svg:g [attr.transform]="'translate(0,' + t.offset + ')'">
113
+ @if (tickLine()) {
114
+ <svg:line class="stroke-border" x1="-6" x2="0" />
115
+ }
116
+ <svg:text
117
+ class="fill-current"
118
+ x="-8"
119
+ dy="0.32em"
120
+ text-anchor="end"
121
+ style="font-size: var(--text-xs); font-family: var(--font-sans)"
122
+ >
123
+ {{ t.label }}
124
+ </svg:text>
125
+ </svg:g>
126
+ }
127
+ `, isInline: true });
128
+ }
129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartAxisY, decorators: [{
130
+ type: Component,
131
+ args: [{
132
+ selector: 'svg:g[ChartAxisY]',
133
+ host: {
134
+ class: 'chart-axis chart-axis-y text-muted-foreground',
135
+ },
136
+ template: `
137
+ <svg:line class="stroke-border" x1="0" x2="0" [attr.y1]="0" [attr.y2]="innerHeight()" />
138
+ @for (t of ticks(); track t.value) {
139
+ <svg:g [attr.transform]="'translate(0,' + t.offset + ')'">
140
+ @if (tickLine()) {
141
+ <svg:line class="stroke-border" x1="-6" x2="0" />
142
+ }
143
+ <svg:text
144
+ class="fill-current"
145
+ x="-8"
146
+ dy="0.32em"
147
+ text-anchor="end"
148
+ style="font-size: var(--text-xs); font-family: var(--font-sans)"
149
+ >
150
+ {{ t.label }}
151
+ </svg:text>
152
+ </svg:g>
153
+ }
154
+ `,
155
+ }]
156
+ }], propDecorators: { tickCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickCount", required: false }] }], tickLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickLine", required: false }] }], tickFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickFormat", required: false }] }] } });
157
+
158
+ /**
159
+ * Horizontal / vertical grid lines for the cartesian plotting area.
160
+ *
161
+ * Reads tick positions from `CartesianContext.valueScale`. Direction of the
162
+ * grid lines follows `orientation`:
163
+ * - vertical → horizontal grid lines (one per y-tick)
164
+ * - horizontal → vertical grid lines (one per x-tick)
165
+ */
166
+ class ChartGrid {
167
+ ctx = inject(CartesianContext);
168
+ tickCount = input(5, /* @ts-ignore */
169
+ ...(ngDevMode ? [{ debugName: "tickCount" }] : /* istanbul ignore next */ []));
170
+ ticks = computed(() => {
171
+ const scale = this.ctx.valueScale();
172
+ return scale ? linearTicks(scale, this.tickCount()) : [];
173
+ }, /* @ts-ignore */
174
+ ...(ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []));
175
+ line = (offset) => {
176
+ if (this.ctx.orientation() === 'vertical') {
177
+ return { x1: 0, x2: this.ctx.innerWidth(), y1: offset, y2: offset };
178
+ }
179
+ return { x1: offset, x2: offset, y1: 0, y2: this.ctx.innerHeight() };
180
+ };
181
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
182
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartGrid, isStandalone: true, selector: "svg:g[ChartGrid]", inputs: { tickCount: { classPropertyName: "tickCount", publicName: "tickCount", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "chart-grid text-border" }, ngImport: i0, template: `
183
+ @for (t of ticks(); track t.value) {
184
+ <svg:line
185
+ class="stroke-border"
186
+ stroke-dasharray="3 3"
187
+ [attr.x1]="line(t.offset).x1"
188
+ [attr.x2]="line(t.offset).x2"
189
+ [attr.y1]="line(t.offset).y1"
190
+ [attr.y2]="line(t.offset).y2"
191
+ />
192
+ }
193
+ `, isInline: true });
194
+ }
195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartGrid, decorators: [{
196
+ type: Component,
197
+ args: [{
198
+ selector: 'svg:g[ChartGrid]',
199
+ host: {
200
+ class: 'chart-grid text-border',
201
+ },
202
+ template: `
203
+ @for (t of ticks(); track t.value) {
204
+ <svg:line
205
+ class="stroke-border"
206
+ stroke-dasharray="3 3"
207
+ [attr.x1]="line(t.offset).x1"
208
+ [attr.x2]="line(t.offset).x2"
209
+ [attr.y1]="line(t.offset).y1"
210
+ [attr.y2]="line(t.offset).y2"
211
+ />
212
+ }
213
+ `,
214
+ }]
215
+ }], propDecorators: { tickCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickCount", required: false }] }] } });
216
+
217
+ /**
218
+ * Crosshair primitive — a line drawn through the currently active data point
219
+ * perpendicular to the categorical axis. Reads `activePoint` from
220
+ * `ChartContext` and the scales from `CartesianContext`.
221
+ *
222
+ * Place inside a cartesian chart's SVG inner group.
223
+ */
224
+ class ChartCrosshair {
225
+ root = inject(ChartContext);
226
+ cart = inject(CartesianContext);
227
+ line = computed(() => {
228
+ const active = this.root.activePoint();
229
+ const scale = this.cart.categoryScale();
230
+ const categories = this.cart.categories();
231
+ if (!active || !scale || active.index < 0 || active.index >= categories.length) {
232
+ return null;
233
+ }
234
+ const base = scale(categories[active.index]) ?? 0;
235
+ const pos = base + scale.bandwidth() / 2;
236
+ if (this.cart.orientation() === 'vertical') {
237
+ return { x1: pos, x2: pos, y1: 0, y2: this.cart.innerHeight() };
238
+ }
239
+ return { x1: 0, x2: this.cart.innerWidth(), y1: pos, y2: pos };
240
+ }, /* @ts-ignore */
241
+ ...(ngDevMode ? [{ debugName: "line" }] : /* istanbul ignore next */ []));
242
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartCrosshair, deps: [], target: i0.ɵɵFactoryTarget.Component });
243
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartCrosshair, isStandalone: true, selector: "svg:g[ChartCrosshair]", host: { classAttribute: "chart-crosshair" }, ngImport: i0, template: `
244
+ @if (line(); as l) {
245
+ <svg:line
246
+ class="stroke-border"
247
+ stroke-dasharray="3 3"
248
+ [attr.x1]="l.x1"
249
+ [attr.x2]="l.x2"
250
+ [attr.y1]="l.y1"
251
+ [attr.y2]="l.y2"
252
+ />
253
+ }
254
+ `, isInline: true });
255
+ }
256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartCrosshair, decorators: [{
257
+ type: Component,
258
+ args: [{
259
+ selector: 'svg:g[ChartCrosshair]',
260
+ host: { class: 'chart-crosshair' },
261
+ template: `
262
+ @if (line(); as l) {
263
+ <svg:line
264
+ class="stroke-border"
265
+ stroke-dasharray="3 3"
266
+ [attr.x1]="l.x1"
267
+ [attr.x2]="l.x2"
268
+ [attr.y1]="l.y1"
269
+ [attr.y2]="l.y2"
270
+ />
271
+ }
272
+ `,
273
+ }]
274
+ }] });
275
+
276
+ function clamp(value, min, max) {
277
+ return Math.min(max, Math.max(min, value));
278
+ }
279
+ function sameDomain(a, b) {
280
+ return Math.abs(a[0] - b[0]) < 1e-9 && Math.abs(a[1] - b[1]) < 1e-9;
281
+ }
282
+ class ChartBrush {
283
+ hitbox = viewChild.required('hitbox', /* @ts-ignore */
284
+ ...(ngDevMode ? [{ debugName: "hitbox" }] : /* istanbul ignore next */ []));
285
+ cart = inject(CartesianContext, { optional: true });
286
+ categorical = inject(CategoricalViewportContext, { optional: true });
287
+ scatter = inject(ScatterViewportContext, { optional: true });
288
+ document = inject(DOCUMENT);
289
+ /**
290
+ * Torn down the moment a drag ends. Permanent `window:` bindings marked the
291
+ * view dirty for every pointer move anywhere on the page, brush or no brush.
292
+ */
293
+ detachDragListeners = null;
294
+ constructor() {
295
+ inject(DestroyRef).onDestroy(() => this.detachDragListeners?.());
296
+ }
297
+ mode = signal(null, /* @ts-ignore */
298
+ ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
299
+ activePointerId = signal(null, /* @ts-ignore */
300
+ ...(ngDevMode ? [{ debugName: "activePointerId" }] : /* istanbul ignore next */ []));
301
+ categoryStartIndex = signal(null, /* @ts-ignore */
302
+ ...(ngDevMode ? [{ debugName: "categoryStartIndex" }] : /* istanbul ignore next */ []));
303
+ categoryPanStart = signal(null, /* @ts-ignore */
304
+ ...(ngDevMode ? [{ debugName: "categoryPanStart" }] : /* istanbul ignore next */ []));
305
+ scatterBrush = signal(null, /* @ts-ignore */
306
+ ...(ngDevMode ? [{ debugName: "scatterBrush" }] : /* istanbul ignore next */ []));
307
+ scatterPan = signal(null, /* @ts-ignore */
308
+ ...(ngDevMode ? [{ debugName: "scatterPan" }] : /* istanbul ignore next */ []));
309
+ width = computed(() => this.scatter?.innerWidth() ?? this.cart?.innerWidth() ?? 0, /* @ts-ignore */
310
+ ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
311
+ height = computed(() => this.scatter?.innerHeight() ?? this.cart?.innerHeight() ?? 0, /* @ts-ignore */
312
+ ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
313
+ categoryPreview = computed(() => {
314
+ const cart = this.cart;
315
+ const viewport = this.categorical;
316
+ const range = viewport?.brushRange();
317
+ const scale = cart?.categoryScale();
318
+ const categories = cart?.categories() ?? [];
319
+ if (!cart || !viewport || !range || !scale || categories.length === 0) {
320
+ return null;
321
+ }
322
+ const visibleStart = viewport.zoomRange()?.startIndex ?? 0;
323
+ const startVisible = range.startIndex - visibleStart;
324
+ const endVisible = range.endIndex - visibleStart;
325
+ if (startVisible < 0 || endVisible >= categories.length) {
326
+ return null;
327
+ }
328
+ const first = scale(categories[startVisible]) ?? 0;
329
+ const last = (scale(categories[endVisible]) ?? 0) + scale.bandwidth();
330
+ if (cart.orientation() === 'vertical') {
331
+ return {
332
+ x: Math.min(first, last),
333
+ y: 0,
334
+ width: Math.abs(last - first),
335
+ height: cart.innerHeight(),
336
+ };
337
+ }
338
+ return {
339
+ x: 0,
340
+ y: Math.min(first, last),
341
+ width: cart.innerWidth(),
342
+ height: Math.abs(last - first),
343
+ };
344
+ }, /* @ts-ignore */
345
+ ...(ngDevMode ? [{ debugName: "categoryPreview" }] : /* istanbul ignore next */ []));
346
+ scatterPreviewRect = computed(() => {
347
+ const preview = this.scatterBrush();
348
+ if (!preview) {
349
+ return null;
350
+ }
351
+ return {
352
+ x: Math.min(preview.start.x, preview.current.x),
353
+ y: Math.min(preview.start.y, preview.current.y),
354
+ width: Math.abs(preview.current.x - preview.start.x),
355
+ height: Math.abs(preview.current.y - preview.start.y),
356
+ };
357
+ }, /* @ts-ignore */
358
+ ...(ngDevMode ? [{ debugName: "scatterPreviewRect" }] : /* istanbul ignore next */ []));
359
+ onPointerDown(event) {
360
+ if (this.activePointerId() != null) {
361
+ return;
362
+ }
363
+ const local = this.localPoint(event);
364
+ if (!local) {
365
+ return;
366
+ }
367
+ if (this.scatter) {
368
+ if (!this.scatter.fullXDomain() || !this.scatter.fullYDomain()) {
369
+ return;
370
+ }
371
+ event.preventDefault();
372
+ this.beginDrag(event);
373
+ this.onScatterPointerDown(event, local);
374
+ return;
375
+ }
376
+ if (!this.cart || !this.categorical) {
377
+ return;
378
+ }
379
+ const index = nearestCategoryIndex({
380
+ categoryScale: this.cart.categoryScale,
381
+ categories: this.cart.categories,
382
+ orientation: this.cart.orientation,
383
+ }, local.x, local.y);
384
+ if (index < 0) {
385
+ return;
386
+ }
387
+ event.preventDefault();
388
+ this.beginDrag(event);
389
+ const visibleStart = this.categorical.zoomRange()?.startIndex ?? 0;
390
+ const absoluteIndex = visibleStart + index;
391
+ if (event.pointerType === 'touch' && this.categorical.hasZoom()) {
392
+ this.mode.set('category-pan');
393
+ this.categoryPanStart.set({
394
+ coord: this.pointerAxis(local),
395
+ range: this.categorical.zoomRange(),
396
+ });
397
+ return;
398
+ }
399
+ this.mode.set('category-brush');
400
+ this.categoryStartIndex.set(absoluteIndex);
401
+ this.categorical.brushRange.set({ startIndex: absoluteIndex, endIndex: absoluteIndex });
402
+ }
403
+ onPointerMove(event) {
404
+ if (this.activePointerId() !== event.pointerId) {
405
+ return;
406
+ }
407
+ const local = this.localPoint(event);
408
+ if (!local) {
409
+ return;
410
+ }
411
+ if (this.mode() === 'category-brush' && this.cart && this.categorical) {
412
+ const startIndex = this.categoryStartIndex();
413
+ if (startIndex == null) {
414
+ return;
415
+ }
416
+ const index = nearestCategoryIndex({
417
+ categoryScale: this.cart.categoryScale,
418
+ categories: this.cart.categories,
419
+ orientation: this.cart.orientation,
420
+ }, local.x, local.y);
421
+ if (index < 0) {
422
+ return;
423
+ }
424
+ const visibleStart = this.categorical.zoomRange()?.startIndex ?? 0;
425
+ this.categorical.brushRange.set(normalizeIndexRange(startIndex, visibleStart + index, this.categorical.dataCount()));
426
+ return;
427
+ }
428
+ if (this.mode() === 'category-pan' && this.cart && this.categorical) {
429
+ const pan = this.categoryPanStart();
430
+ if (!pan) {
431
+ return;
432
+ }
433
+ const scale = this.cart.categoryScale();
434
+ const step = scale?.step?.() ?? scale?.bandwidth() ?? 0;
435
+ if (step <= 0) {
436
+ return;
437
+ }
438
+ const deltaSteps = Math.round((pan.coord - this.pointerAxis(local)) / step);
439
+ this.categorical.zoomRange.set(panIndexRange(pan.range, this.categorical.dataCount(), deltaSteps));
440
+ return;
441
+ }
442
+ if (this.mode() === 'scatter-brush') {
443
+ const preview = this.scatterBrush();
444
+ if (!preview) {
445
+ return;
446
+ }
447
+ this.scatterBrush.set({ start: preview.start, current: local });
448
+ return;
449
+ }
450
+ if (this.mode() === 'scatter-pan' && this.scatter) {
451
+ const pan = this.scatterPan();
452
+ const xScale = this.scatter.xScale();
453
+ const yScale = this.scatter.yScale();
454
+ const fullX = this.scatter.fullXDomain();
455
+ const fullY = this.scatter.fullYDomain();
456
+ if (!pan || !xScale || !yScale || !fullX || !fullY) {
457
+ return;
458
+ }
459
+ const deltaX = xScale.invert(pan.start.x) - xScale.invert(local.x);
460
+ const deltaY = yScale.invert(pan.start.y) - yScale.invert(local.y);
461
+ this.scatter.zoomXDomain.set(panNumericDomain(pan.xDomain, fullX, deltaX));
462
+ this.scatter.zoomYDomain.set(panNumericDomain(pan.yDomain, fullY, deltaY));
463
+ }
464
+ }
465
+ onPointerUp(event) {
466
+ if (event && this.activePointerId() !== event.pointerId) {
467
+ return;
468
+ }
469
+ if (this.mode() === 'category-brush' && this.categorical) {
470
+ const range = this.categorical.brushRange();
471
+ if (range && indexRangeSize(range, this.categorical.dataCount()) > 1) {
472
+ this.categorical.zoomRange.set(range);
473
+ }
474
+ this.categorical.brushRange.set(null);
475
+ }
476
+ if (this.mode() === 'scatter-brush' && this.scatter) {
477
+ const preview = this.scatterBrush();
478
+ const xScale = this.scatter.xScale();
479
+ const yScale = this.scatter.yScale();
480
+ const fullX = this.scatter.fullXDomain();
481
+ const fullY = this.scatter.fullYDomain();
482
+ if (preview && xScale && yScale && fullX && fullY) {
483
+ const width = Math.abs(preview.current.x - preview.start.x);
484
+ const height = Math.abs(preview.current.y - preview.start.y);
485
+ if (width >= 6 && height >= 6) {
486
+ const nextX = normalizeNumericDomain(xScale.invert(preview.start.x), xScale.invert(preview.current.x));
487
+ const nextY = normalizeNumericDomain(yScale.invert(preview.start.y), yScale.invert(preview.current.y));
488
+ this.scatter.zoomXDomain.set(sameDomain(nextX, fullX) ? null : nextX);
489
+ this.scatter.zoomYDomain.set(sameDomain(nextY, fullY) ? null : nextY);
490
+ }
491
+ }
492
+ this.scatterBrush.set(null);
493
+ }
494
+ this.mode.set(null);
495
+ this.categoryStartIndex.set(null);
496
+ this.categoryPanStart.set(null);
497
+ this.scatterPan.set(null);
498
+ this.endDrag(event);
499
+ }
500
+ onPointerCancel(event) {
501
+ if (this.activePointerId() !== event.pointerId) {
502
+ return;
503
+ }
504
+ this.mode.set(null);
505
+ this.categorical?.brushRange.set(null);
506
+ this.scatterBrush.set(null);
507
+ this.categoryStartIndex.set(null);
508
+ this.categoryPanStart.set(null);
509
+ this.scatterPan.set(null);
510
+ this.endDrag(event);
511
+ }
512
+ onWheel(event) {
513
+ const local = this.localPoint(event);
514
+ if (!local) {
515
+ return;
516
+ }
517
+ event.preventDefault();
518
+ if (this.scatter) {
519
+ const xScale = this.scatter.xScale();
520
+ const yScale = this.scatter.yScale();
521
+ const fullX = this.scatter.fullXDomain();
522
+ const fullY = this.scatter.fullYDomain();
523
+ if (!xScale || !yScale || !fullX || !fullY) {
524
+ return;
525
+ }
526
+ const factor = event.deltaY < 0 ? 0.8 : 1.25;
527
+ const currentX = this.scatter.zoomXDomain() ?? fullX;
528
+ const currentY = this.scatter.zoomYDomain() ?? fullY;
529
+ const nextX = zoomNumericDomain(currentX, fullX, xScale.invert(local.x), factor);
530
+ const nextY = zoomNumericDomain(currentY, fullY, yScale.invert(local.y), factor);
531
+ this.scatter.zoomXDomain.set(sameDomain(nextX, fullX) ? null : nextX);
532
+ this.scatter.zoomYDomain.set(sameDomain(nextY, fullY) ? null : nextY);
533
+ return;
534
+ }
535
+ if (!this.cart || !this.categorical) {
536
+ return;
537
+ }
538
+ const visibleIndex = nearestCategoryIndex({
539
+ categoryScale: this.cart.categoryScale,
540
+ categories: this.cart.categories,
541
+ orientation: this.cart.orientation,
542
+ }, local.x, local.y);
543
+ if (visibleIndex < 0) {
544
+ return;
545
+ }
546
+ const anchor = (this.categorical.zoomRange()?.startIndex ?? 0) + visibleIndex;
547
+ const factor = event.deltaY < 0 ? 0.75 : 1.25;
548
+ this.categorical.zoomRange.set(zoomIndexRange(this.categorical.zoomRange(), this.categorical.dataCount(), anchor, factor));
549
+ this.categorical.brushRange.set(null);
550
+ }
551
+ resetZoom() {
552
+ this.categorical?.resetZoom();
553
+ this.scatter?.resetZoom();
554
+ this.scatterBrush.set(null);
555
+ }
556
+ beginDrag(event) {
557
+ this.activePointerId.set(event.pointerId);
558
+ this.hitbox().nativeElement.setPointerCapture(event.pointerId);
559
+ const move = (next) => this.onPointerMove(next);
560
+ const up = (next) => this.onPointerUp(next);
561
+ const cancel = (next) => this.onPointerCancel(next);
562
+ this.document.addEventListener('pointermove', move);
563
+ this.document.addEventListener('pointerup', up);
564
+ this.document.addEventListener('pointercancel', cancel);
565
+ this.detachDragListeners = () => {
566
+ this.document.removeEventListener('pointermove', move);
567
+ this.document.removeEventListener('pointerup', up);
568
+ this.document.removeEventListener('pointercancel', cancel);
569
+ this.detachDragListeners = null;
570
+ };
571
+ }
572
+ endDrag(event) {
573
+ if (event && this.hitbox().nativeElement.hasPointerCapture(event.pointerId)) {
574
+ this.hitbox().nativeElement.releasePointerCapture(event.pointerId);
575
+ }
576
+ this.detachDragListeners?.();
577
+ this.activePointerId.set(null);
578
+ }
579
+ onScatterPointerDown(event, local) {
580
+ const fullX = this.scatter?.fullXDomain();
581
+ const fullY = this.scatter?.fullYDomain();
582
+ if (!this.scatter || !fullX || !fullY) {
583
+ return;
584
+ }
585
+ if (event.pointerType === 'touch' && this.scatter.hasZoom()) {
586
+ this.mode.set('scatter-pan');
587
+ this.scatterPan.set({
588
+ start: local,
589
+ xDomain: this.scatter.zoomXDomain() ?? fullX,
590
+ yDomain: this.scatter.zoomYDomain() ?? fullY,
591
+ });
592
+ return;
593
+ }
594
+ this.mode.set('scatter-brush');
595
+ this.scatterBrush.set({ start: local, current: local });
596
+ }
597
+ localPoint(event) {
598
+ const hitbox = this.hitbox()?.nativeElement;
599
+ const width = this.width();
600
+ const height = this.height();
601
+ if (!hitbox || width <= 0 || height <= 0) {
602
+ return null;
603
+ }
604
+ const rect = hitbox.getBoundingClientRect();
605
+ if (rect.width <= 0 || rect.height <= 0) {
606
+ return null;
607
+ }
608
+ return {
609
+ x: clamp(((event.clientX - rect.left) / rect.width) * width, 0, width),
610
+ y: clamp(((event.clientY - rect.top) / rect.height) * height, 0, height),
611
+ };
612
+ }
613
+ pointerAxis(local) {
614
+ return this.cart?.orientation() === 'horizontal' ? local.y : local.x;
615
+ }
616
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartBrush, deps: [], target: i0.ɵɵFactoryTarget.Component });
617
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartBrush, isStandalone: true, selector: "svg:g[ChartBrush]", host: { classAttribute: "chart-brush" }, viewQueries: [{ propertyName: "hitbox", first: true, predicate: ["hitbox"], descendants: true, isSignal: true }], ngImport: i0, template: `
618
+ <svg:rect
619
+ #hitbox
620
+ class="fill-transparent touch-none"
621
+ x="0"
622
+ y="0"
623
+ [attr.width]="width()"
624
+ [attr.height]="height()"
625
+ (pointerdown)="onPointerDown($event)"
626
+ (wheel)="onWheel($event)"
627
+ (dblclick)="resetZoom()"
628
+ />
629
+
630
+ @if (categoryPreview(); as rect) {
631
+ <svg:rect
632
+ class="fill-foreground/10 stroke-foreground/30"
633
+ [attr.x]="rect.x"
634
+ [attr.y]="rect.y"
635
+ [attr.width]="rect.width"
636
+ [attr.height]="rect.height"
637
+ stroke-dasharray="4 3"
638
+ />
639
+ }
640
+
641
+ @if (scatterPreviewRect(); as rect) {
642
+ <svg:rect
643
+ class="fill-foreground/10 stroke-foreground/30"
644
+ [attr.x]="rect.x"
645
+ [attr.y]="rect.y"
646
+ [attr.width]="rect.width"
647
+ [attr.height]="rect.height"
648
+ stroke-dasharray="4 3"
649
+ />
650
+ }
651
+ `, isInline: true });
652
+ }
653
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartBrush, decorators: [{
654
+ type: Component,
655
+ args: [{
656
+ selector: 'svg:g[ChartBrush]',
657
+ host: { class: 'chart-brush' },
658
+ template: `
659
+ <svg:rect
660
+ #hitbox
661
+ class="fill-transparent touch-none"
662
+ x="0"
663
+ y="0"
664
+ [attr.width]="width()"
665
+ [attr.height]="height()"
666
+ (pointerdown)="onPointerDown($event)"
667
+ (wheel)="onWheel($event)"
668
+ (dblclick)="resetZoom()"
669
+ />
670
+
671
+ @if (categoryPreview(); as rect) {
672
+ <svg:rect
673
+ class="fill-foreground/10 stroke-foreground/30"
674
+ [attr.x]="rect.x"
675
+ [attr.y]="rect.y"
676
+ [attr.width]="rect.width"
677
+ [attr.height]="rect.height"
678
+ stroke-dasharray="4 3"
679
+ />
680
+ }
681
+
682
+ @if (scatterPreviewRect(); as rect) {
683
+ <svg:rect
684
+ class="fill-foreground/10 stroke-foreground/30"
685
+ [attr.x]="rect.x"
686
+ [attr.y]="rect.y"
687
+ [attr.width]="rect.width"
688
+ [attr.height]="rect.height"
689
+ stroke-dasharray="4 3"
690
+ />
691
+ }
692
+ `,
693
+ }]
694
+ }], ctorParameters: () => [], propDecorators: { hitbox: [{ type: i0.ViewChild, args: ['hitbox', { isSignal: true }] }] } });
695
+
696
+ /**
697
+ * Attach to a chart's `<svg:svg>` to publish pointer-driven active-point
698
+ * state into the surrounding `ChartContext`.
699
+ *
700
+ * Computes the local (x, y) of the pointer relative to the inner plotting
701
+ * area, resolves the nearest category, and updates
702
+ * `ChartContext.activePoint`. Clears it on `pointerleave`.
703
+ */
704
+ class ChartPointerTracker {
705
+ root = inject(ChartContext);
706
+ cart = inject(CartesianContext);
707
+ viewport = inject(CategoricalViewportContext, { optional: true });
708
+ onMove(event) {
709
+ const target = event.currentTarget;
710
+ if (!target)
711
+ return;
712
+ const rect = target.getBoundingClientRect();
713
+ if (rect.width === 0 || rect.height === 0)
714
+ return;
715
+ const { width, height } = this.root.dimensions();
716
+ // Map client coords → viewBox coords (SVG uses `0 0 width height`,
717
+ // preserveAspectRatio="none" so axes scale independently).
718
+ const scaleX = width / rect.width;
719
+ const scaleY = height / rect.height;
720
+ const viewX = (event.clientX - rect.left) * scaleX;
721
+ const viewY = (event.clientY - rect.top) * scaleY;
722
+ const margin = this.cart.margin();
723
+ const localX = viewX - margin.left;
724
+ const localY = viewY - margin.top;
725
+ const index = nearestCategoryIndex({
726
+ categoryScale: this.cart.categoryScale,
727
+ categories: this.cart.categories,
728
+ orientation: this.cart.orientation,
729
+ }, localX, localY);
730
+ if (index < 0) {
731
+ this.root.activePoint.set(null);
732
+ return;
733
+ }
734
+ this.root.activePoint.set({
735
+ index,
736
+ datumIndex: (this.viewport?.zoomRange()?.startIndex ?? 0) + index,
737
+ clientX: event.clientX,
738
+ clientY: event.clientY,
739
+ });
740
+ }
741
+ onLeave() {
742
+ this.root.activePoint.set(null);
743
+ }
744
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartPointerTracker, deps: [], target: i0.ɵɵFactoryTarget.Directive });
745
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: ChartPointerTracker, isStandalone: true, selector: "svg:svg[ChartPointerTracker]", host: { listeners: { "pointermove": "onMove($event)", "pointerleave": "onLeave()" } }, ngImport: i0 });
746
+ }
747
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartPointerTracker, decorators: [{
748
+ type: Directive,
749
+ args: [{
750
+ selector: 'svg:svg[ChartPointerTracker]',
751
+ host: {
752
+ '(pointermove)': 'onMove($event)',
753
+ '(pointerleave)': 'onLeave()',
754
+ },
755
+ }]
756
+ }] });
757
+
758
+ /** Locate the chart container DOM in order to position the tooltip. */
759
+ function chartContainerElement(el) {
760
+ // Climb to the nearest `[data-chart]` (the ChartContainer host).
761
+ let node = el;
762
+ while (node && !node.hasAttribute('data-chart')) {
763
+ node = node.parentElement;
764
+ }
765
+ return node;
766
+ }
767
+ /** Card width assumed before the card has ever been laid out. */
768
+ const FALLBACK_TOOLTIP_WIDTH = 128;
769
+ /**
770
+ * Tooltip overlay — renders the default tooltip card (or a user-supplied
771
+ * template) anchored to the currently active data point.
772
+ *
773
+ * Shadcn-compatible knobs:
774
+ * - `indicator="line"` / `"none"` / `"dashed"` — swap the row glyph
775
+ * - `hideLabel` — drop the header row
776
+ * - `label="Activities"` — override the header text
777
+ * - `labelKey="activities"` — resolve the header from `config[labelKey].label`
778
+ * - `labelFormatter` — transform the header (e.g. ISO date → long date)
779
+ * - `formatter` — format per-row values (e.g. `"380 kcal"`)
780
+ * - `valueKey` — for pie/radial/radar, read row value from a single field
781
+ * - Icons are picked up automatically from `config[key].icon`.
782
+ */
783
+ class ChartTooltip {
784
+ root = inject(ChartContext);
785
+ host = inject((ElementRef));
786
+ zone = inject(NgZone);
787
+ platformId = inject(PLATFORM_ID);
788
+ destroyRef = inject(DestroyRef);
789
+ /**
790
+ * The two measurements `position` needs, taken outside it.
791
+ *
792
+ * `position` used to call `getBoundingClientRect` and read `offsetWidth`
793
+ * while the template evaluated it, which forced layout on every tick and left
794
+ * the tooltip stale after a resize — a computed only re-runs for the signals
795
+ * it reads, and a DOM box is not one.
796
+ */
797
+ containerBox = signal(null, { ...(ngDevMode ? { debugName: "containerBox" } : /* istanbul ignore next */ {}), equal: (a, b) => a?.left === b?.left && a?.top === b?.top && a?.width === b?.width });
798
+ tooltipBox = signal({ width: FALLBACK_TOOLTIP_WIDTH, height: 0 }, { ...(ngDevMode ? { debugName: "tooltipBox" } : /* istanbul ignore next */ {}), equal: (a, b) => a.width === b.width && a.height === b.height });
799
+ constructor() {
800
+ if (!isPlatformBrowser(this.platformId)) {
801
+ return;
802
+ }
803
+ afterNextRender(() => this.observeContainer());
804
+ afterRenderEffect(() => {
805
+ // Reading the payload ties the measurement to the card's content, so a
806
+ // wider row re-measures without the computed ever touching the DOM.
807
+ this.payload();
808
+ this.measure();
809
+ });
810
+ }
811
+ /** Data key on each datum whose value is the category label (x-axis). */
812
+ xKey = input(null, /* @ts-ignore */
813
+ ...(ngDevMode ? [{ debugName: "xKey" }] : /* istanbul ignore next */ []));
814
+ /** Data source (optional — if omitted tooltip reads from chart data via activePoint.datumIndex). */
815
+ data = input(null, /* @ts-ignore */
816
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
817
+ /**
818
+ * Optional key for per-datum value lookup (pie / radial / radar datasets
819
+ * store values on a single field like `visitors` instead of one field per
820
+ * series). When set and `activePoint.seriesKey` is active, the tooltip row
821
+ * reads `datum[valueKey]` for its value.
822
+ */
823
+ valueKey = input(null, /* @ts-ignore */
824
+ ...(ngDevMode ? [{ debugName: "valueKey" }] : /* istanbul ignore next */ []));
825
+ /** Indicator variant next to each row. Default `'dot'`. */
826
+ indicator = input('dot', /* @ts-ignore */
827
+ ...(ngDevMode ? [{ debugName: "indicator" }] : /* istanbul ignore next */ []));
828
+ /** Hide the header label entirely. */
829
+ hideLabel = input(false, /* @ts-ignore */
830
+ ...(ngDevMode ? [{ debugName: "hideLabel" }] : /* istanbul ignore next */ []));
831
+ /** Override the header label with a fixed string. Takes precedence over `labelKey`. */
832
+ label = input(null, /* @ts-ignore */
833
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
834
+ /**
835
+ * Resolve the header label from `config[labelKey].label`. Useful when the
836
+ * header should come from a config entry rather than the datum itself
837
+ * (shadcn's "Custom label" variant).
838
+ */
839
+ labelKey = input(null, /* @ts-ignore */
840
+ ...(ngDevMode ? [{ debugName: "labelKey" }] : /* istanbul ignore next */ []));
841
+ /** Transform the final header string (e.g. ISO date → long date). */
842
+ labelFormatter = input(null, /* @ts-ignore */
843
+ ...(ngDevMode ? [{ debugName: "labelFormatter" }] : /* istanbul ignore next */ []));
844
+ /** Format each row's value (return string — HTML is not interpreted). */
845
+ formatter = input(null, /* @ts-ignore */
846
+ ...(ngDevMode ? [{ debugName: "formatter" }] : /* istanbul ignore next */ []));
847
+ customTpl = contentChild((TemplateRef), /* @ts-ignore */
848
+ ...(ngDevMode ? [{ debugName: "customTpl" }] : /* istanbul ignore next */ []));
849
+ visible = computed(() => this.root.activePoint() !== null, /* @ts-ignore */
850
+ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
851
+ payload = computed(() => {
852
+ const active = this.root.activePoint();
853
+ const rows = this.data();
854
+ if (!active || !rows)
855
+ return null;
856
+ const dataIndex = active.datumIndex != null && active.datumIndex < rows.length
857
+ ? active.datumIndex
858
+ : active.index;
859
+ if (dataIndex < 0 || dataIndex >= rows.length)
860
+ return null;
861
+ const cfg = this.root.config();
862
+ const visibleKeys = this.root.visibleSeriesKeys();
863
+ const datum = rows[dataIndex];
864
+ const xKey = this.xKey();
865
+ const category = xKey && xKey in datum ? String(datum[xKey]) : String(active.index);
866
+ // When the active point targets a single series (pie/radial/radar hover),
867
+ // collapse the tooltip to just that row.
868
+ const activeSeriesKey = active.seriesKey && visibleKeys.includes(active.seriesKey) ? active.seriesKey : null;
869
+ const keys = activeSeriesKey ? [activeSeriesKey] : visibleKeys;
870
+ const valueKey = this.valueKey();
871
+ const tooltipRows = keys.map((k) => {
872
+ // For single-slice hover on pie/radial/radar the value lives on a
873
+ // shared `valueKey` field, not on a per-series column.
874
+ const rawValue = valueKey != null && activeSeriesKey === k ? datum[valueKey] : datum[k];
875
+ return {
876
+ seriesKey: k,
877
+ label: cfg[k]?.label ?? k,
878
+ value: rawValue,
879
+ color: seriesColorVar(k),
880
+ icon: cfg[k]?.icon,
881
+ };
882
+ });
883
+ return { category, datum, rows: tooltipRows };
884
+ }, /* @ts-ignore */
885
+ ...(ngDevMode ? [{ debugName: "payload" }] : /* istanbul ignore next */ []));
886
+ /** Resolve the header string honoring `label`, `labelKey`, then `labelFormatter`. */
887
+ headerText(p) {
888
+ if (this.hideLabel())
889
+ return null;
890
+ const override = this.label();
891
+ const labelKey = this.labelKey();
892
+ const cfg = this.root.config();
893
+ const fromKey = labelKey ? (cfg[labelKey]?.label ?? labelKey) : null;
894
+ const raw = override ?? fromKey ?? p.category;
895
+ const fmt = this.labelFormatter();
896
+ return fmt ? fmt(raw, p) : raw;
897
+ }
898
+ /** Apply per-row value formatter (or stringify). */
899
+ formatRow(row, p) {
900
+ const fmt = this.formatter();
901
+ if (fmt)
902
+ return fmt(row.value, row, p);
903
+ return row.value == null ? '' : String(row.value);
904
+ }
905
+ position = computed(() => {
906
+ const active = this.root.activePoint();
907
+ const box = this.containerBox();
908
+ if (!active || active.clientX == null || active.clientY == null || !box) {
909
+ return { x: 0, y: 0 };
910
+ }
911
+ // Map client coords → offset within the chart container (the element
912
+ // marked with `data-chart`, which is our positioning ancestor).
913
+ const { width: tooltipWidth, height: tooltipHeight } = this.tooltipBox();
914
+ const padding = 8;
915
+ const minX = padding + tooltipWidth / 2;
916
+ const maxX = Math.max(minX, box.width - padding - tooltipWidth / 2);
917
+ const x = Math.min(maxX, Math.max(minX, active.clientX - box.left));
918
+ // Y is the tooltip's bottom edge because the card is translated upward.
919
+ const minY = padding + tooltipHeight;
920
+ const y = Math.max(minY, active.clientY - box.top - padding);
921
+ return { x, y };
922
+ }, /* @ts-ignore */
923
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
924
+ observeContainer() {
925
+ const container = chartContainerElement(this.host.nativeElement);
926
+ if (!container) {
927
+ return;
928
+ }
929
+ this.measureContainer(container);
930
+ if (typeof ResizeObserver === 'undefined') {
931
+ return;
932
+ }
933
+ const observer = new ResizeObserver(() => this.zone.run(() => this.measureContainer(container)));
934
+ observer.observe(container);
935
+ this.destroyRef.onDestroy(() => observer.disconnect());
936
+ }
937
+ measure() {
938
+ const container = chartContainerElement(this.host.nativeElement);
939
+ if (container) {
940
+ this.measureContainer(container);
941
+ }
942
+ const card = this.host.nativeElement.querySelector('[role="tooltip"]');
943
+ this.tooltipBox.set({
944
+ width: card?.offsetWidth || FALLBACK_TOOLTIP_WIDTH,
945
+ height: card?.offsetHeight ?? 0,
946
+ });
947
+ }
948
+ measureContainer(container) {
949
+ const rect = container.getBoundingClientRect();
950
+ this.containerBox.set({ left: rect.left, top: rect.top, width: rect.width });
951
+ }
952
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartTooltip, deps: [], target: i0.ɵɵFactoryTarget.Component });
953
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartTooltip, isStandalone: true, selector: "ChartTooltip", inputs: { xKey: { classPropertyName: "xKey", publicName: "xKey", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, indicator: { classPropertyName: "indicator", publicName: "indicator", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, labelFormatter: { classPropertyName: "labelFormatter", publicName: "labelFormatter", isSignal: true, isRequired: false, transformFunction: null }, formatter: { classPropertyName: "formatter", publicName: "formatter", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-hidden": "!visible()" }, classAttribute: "pointer-events-none absolute inset-0 z-10" }, queries: [{ propertyName: "customTpl", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0, template: `
954
+ @if (payload(); as p) {
955
+ <div
956
+ role="tooltip"
957
+ class="pointer-events-none absolute grid min-w-32 max-w-72 -translate-x-1/2 -translate-y-full gap-1.5 rounded-lg border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-3 py-1.5 text-xs shadow-md"
958
+ [style.left.px]="position().x"
959
+ [style.top.px]="position().y"
960
+ >
961
+ @if (customTpl(); as tpl) {
962
+ <ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }" />
963
+ } @else {
964
+ @if (!hideLabel() && headerText(p); as header) {
965
+ <div class="font-medium">{{ header }}</div>
966
+ }
967
+ <ul class="grid gap-1.5">
968
+ @for (row of p.rows; track row.seriesKey) {
969
+ <li class="flex w-full flex-wrap items-stretch gap-2">
970
+ <span class="flex flex-1 items-center gap-1.5">
971
+ @switch (indicator()) {
972
+ @case ('dot') {
973
+ <span
974
+ class="h-2.5 w-2.5 shrink-0 rounded-sm"
975
+ [style.background]="row.color"
976
+ [style.borderColor]="row.color"
977
+ ></span>
978
+ }
979
+ @case ('line') {
980
+ <span
981
+ class="h-full min-h-4 w-1 shrink-0 rounded-sm"
982
+ [style.background]="row.color"
983
+ ></span>
984
+ }
985
+ @case ('dashed') {
986
+ <span
987
+ class="h-0 w-3 shrink-0 self-center border-t-2 border-dashed"
988
+ [style.borderColor]="row.color"
989
+ ></span>
990
+ }
991
+ }
992
+ @if (row.icon; as icon) {
993
+ <span class="mr-1 inline-flex items-center text-muted-foreground">
994
+ <ng-container *ngComponentOutlet="icon" />
995
+ </span>
996
+ }
997
+ <span class="text-muted-foreground">{{ row.label }}</span>
998
+ </span>
999
+ <span class="font-mono font-medium tabular-nums text-foreground">
1000
+ {{ formatRow(row, p) }}
1001
+ </span>
1002
+ </li>
1003
+ }
1004
+ </ul>
1005
+ }
1006
+ </div>
1007
+ }
1008
+
1009
+ <!-- Live region — announces category changes to AT. -->
1010
+ <div class="sr-only" aria-live="polite" aria-atomic="true">
1011
+ @if (payload(); as p) {
1012
+ {{ p.category }}
1013
+ }
1014
+ </div>
1015
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
1016
+ }
1017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartTooltip, decorators: [{
1018
+ type: Component,
1019
+ args: [{
1020
+ selector: 'ChartTooltip',
1021
+ imports: [NgTemplateOutlet, NgComponentOutlet],
1022
+ host: {
1023
+ class: 'pointer-events-none absolute inset-0 z-10',
1024
+ '[attr.aria-hidden]': '!visible()',
1025
+ },
1026
+ template: `
1027
+ @if (payload(); as p) {
1028
+ <div
1029
+ role="tooltip"
1030
+ class="pointer-events-none absolute grid min-w-32 max-w-72 -translate-x-1/2 -translate-y-full gap-1.5 rounded-lg border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-3 py-1.5 text-xs shadow-md"
1031
+ [style.left.px]="position().x"
1032
+ [style.top.px]="position().y"
1033
+ >
1034
+ @if (customTpl(); as tpl) {
1035
+ <ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }" />
1036
+ } @else {
1037
+ @if (!hideLabel() && headerText(p); as header) {
1038
+ <div class="font-medium">{{ header }}</div>
1039
+ }
1040
+ <ul class="grid gap-1.5">
1041
+ @for (row of p.rows; track row.seriesKey) {
1042
+ <li class="flex w-full flex-wrap items-stretch gap-2">
1043
+ <span class="flex flex-1 items-center gap-1.5">
1044
+ @switch (indicator()) {
1045
+ @case ('dot') {
1046
+ <span
1047
+ class="h-2.5 w-2.5 shrink-0 rounded-sm"
1048
+ [style.background]="row.color"
1049
+ [style.borderColor]="row.color"
1050
+ ></span>
1051
+ }
1052
+ @case ('line') {
1053
+ <span
1054
+ class="h-full min-h-4 w-1 shrink-0 rounded-sm"
1055
+ [style.background]="row.color"
1056
+ ></span>
1057
+ }
1058
+ @case ('dashed') {
1059
+ <span
1060
+ class="h-0 w-3 shrink-0 self-center border-t-2 border-dashed"
1061
+ [style.borderColor]="row.color"
1062
+ ></span>
1063
+ }
1064
+ }
1065
+ @if (row.icon; as icon) {
1066
+ <span class="mr-1 inline-flex items-center text-muted-foreground">
1067
+ <ng-container *ngComponentOutlet="icon" />
1068
+ </span>
1069
+ }
1070
+ <span class="text-muted-foreground">{{ row.label }}</span>
1071
+ </span>
1072
+ <span class="font-mono font-medium tabular-nums text-foreground">
1073
+ {{ formatRow(row, p) }}
1074
+ </span>
1075
+ </li>
1076
+ }
1077
+ </ul>
1078
+ }
1079
+ </div>
1080
+ }
1081
+
1082
+ <!-- Live region — announces category changes to AT. -->
1083
+ <div class="sr-only" aria-live="polite" aria-atomic="true">
1084
+ @if (payload(); as p) {
1085
+ {{ p.category }}
1086
+ }
1087
+ </div>
1088
+ `,
1089
+ }]
1090
+ }], ctorParameters: () => [], propDecorators: { xKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "xKey", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: false }] }], indicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicator", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], labelFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelFormatter", required: false }] }], formatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatter", required: false }] }], customTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
1091
+
1092
+ /**
1093
+ * Legend — renders a list of series swatches. Clicking an item toggles
1094
+ * visibility via `ChartContext.toggleSeries`.
1095
+ *
1096
+ * Place as a child of `<Chart>`:
1097
+ * ```html
1098
+ * <Chart [config]="cfg">
1099
+ * <ChartBar ... />
1100
+ * <ChartLegend />
1101
+ * </Chart>
1102
+ * ```
1103
+ */
1104
+ class ChartLegend {
1105
+ root = inject(ChartContext);
1106
+ items = computed(() => {
1107
+ const cfg = this.root.config();
1108
+ const hidden = this.root.hiddenSeries();
1109
+ return this.root.seriesKeys().map((key) => ({
1110
+ seriesKey: key,
1111
+ label: cfg[key]?.label ?? key,
1112
+ color: seriesColorVar(key),
1113
+ hidden: hidden.has(key),
1114
+ }));
1115
+ }, /* @ts-ignore */
1116
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
1117
+ toggle(key) {
1118
+ this.root.toggleSeries(key);
1119
+ }
1120
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartLegend, deps: [], target: i0.ɵɵFactoryTarget.Component });
1121
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartLegend, isStandalone: true, selector: "ChartLegend", host: { classAttribute: "block pt-3" }, ngImport: i0, template: `
1122
+ <ul
1123
+ class="flex flex-wrap items-center justify-center gap-3 text-xs"
1124
+ aria-label="Toggle chart series visibility"
1125
+ >
1126
+ @for (item of items(); track item.seriesKey) {
1127
+ <li>
1128
+ <button
1129
+ type="button"
1130
+ class="inline-flex min-h-11 items-center gap-2 rounded-md px-2.5 py-1.5 outline-none transition-opacity focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1131
+ [class.opacity-50]="item.hidden"
1132
+ [attr.aria-pressed]="!item.hidden"
1133
+ [attr.aria-label]="(item.hidden ? 'Show ' : 'Hide ') + item.label"
1134
+ (click)="toggle(item.seriesKey)"
1135
+ >
1136
+ <span
1137
+ class="inline-block h-2.5 w-2.5 rounded-sm"
1138
+ [style.background]="item.color"
1139
+ ></span>
1140
+ <span class="text-muted-foreground">{{ item.label }}</span>
1141
+ </button>
1142
+ </li>
1143
+ }
1144
+ </ul>
1145
+ `, isInline: true });
1146
+ }
1147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartLegend, decorators: [{
1148
+ type: Component,
1149
+ args: [{
1150
+ selector: 'ChartLegend',
1151
+ host: { class: 'block pt-3' },
1152
+ template: `
1153
+ <ul
1154
+ class="flex flex-wrap items-center justify-center gap-3 text-xs"
1155
+ aria-label="Toggle chart series visibility"
1156
+ >
1157
+ @for (item of items(); track item.seriesKey) {
1158
+ <li>
1159
+ <button
1160
+ type="button"
1161
+ class="inline-flex min-h-11 items-center gap-2 rounded-md px-2.5 py-1.5 outline-none transition-opacity focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1162
+ [class.opacity-50]="item.hidden"
1163
+ [attr.aria-pressed]="!item.hidden"
1164
+ [attr.aria-label]="(item.hidden ? 'Show ' : 'Hide ') + item.label"
1165
+ (click)="toggle(item.seriesKey)"
1166
+ >
1167
+ <span
1168
+ class="inline-block h-2.5 w-2.5 rounded-sm"
1169
+ [style.background]="item.color"
1170
+ ></span>
1171
+ <span class="text-muted-foreground">{{ item.label }}</span>
1172
+ </button>
1173
+ </li>
1174
+ }
1175
+ </ul>
1176
+ `,
1177
+ }]
1178
+ }] });
1179
+
1180
+ function formatNumber(value) {
1181
+ return Math.abs(value) >= 10 ? value.toFixed(0) : value.toFixed(1);
1182
+ }
1183
+ class ChartZoomControls {
1184
+ categorical = inject(CategoricalViewportContext, { optional: true });
1185
+ scatter = inject(ScatterViewportContext, { optional: true });
1186
+ status = computed(() => {
1187
+ if (this.categorical?.hasZoom()) {
1188
+ const count = this.categorical.dataCount();
1189
+ // The chart renders the renormalized window, so the status has to quote
1190
+ // the same one; the raw range can still name rows the data no longer has.
1191
+ const range = effectiveIndexRange(this.categorical.zoomRange(), count);
1192
+ if (!range) {
1193
+ return null;
1194
+ }
1195
+ return `Showing ${range.startIndex + 1}-${range.endIndex + 1} of ${count}`;
1196
+ }
1197
+ if (this.scatter?.hasZoom()) {
1198
+ const xDomain = this.scatter.zoomXDomain() ?? this.scatter.fullXDomain();
1199
+ const yDomain = this.scatter.zoomYDomain() ?? this.scatter.fullYDomain();
1200
+ if (!xDomain || !yDomain) {
1201
+ return null;
1202
+ }
1203
+ return `X ${formatNumber(xDomain[0])}-${formatNumber(xDomain[1])} · Y ${formatNumber(yDomain[0])}-${formatNumber(yDomain[1])}`;
1204
+ }
1205
+ return null;
1206
+ }, /* @ts-ignore */
1207
+ ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
1208
+ hint = computed(() => {
1209
+ if (this.scatter) {
1210
+ return 'Drag to brush a region. Use the wheel to zoom and one-finger touch drag to pan while zoomed.';
1211
+ }
1212
+ return 'Drag to select a category range. Use the wheel to zoom and one-finger touch drag to pan while zoomed.';
1213
+ }, /* @ts-ignore */
1214
+ ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
1215
+ resetZoom() {
1216
+ this.categorical?.resetZoom();
1217
+ this.scatter?.resetZoom();
1218
+ }
1219
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartZoomControls, deps: [], target: i0.ɵɵFactoryTarget.Component });
1220
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: ChartZoomControls, isStandalone: true, selector: "ChartZoomControls", host: { classAttribute: "mt-3 flex flex-wrap items-center justify-between gap-3 text-xs text-muted-foreground" }, ngImport: i0, template: `
1221
+ <p>{{ hint() }}</p>
1222
+
1223
+ @if (status(); as currentStatus) {
1224
+ <div class="flex flex-wrap items-center gap-2">
1225
+ <span
1226
+ class="rounded-full border border-border bg-background px-2.5 py-1 font-medium text-foreground"
1227
+ >
1228
+ {{ currentStatus }}
1229
+ </span>
1230
+ <button
1231
+ type="button"
1232
+ class="inline-flex min-h-11 items-center rounded-md border border-border bg-background px-3 text-foreground transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1233
+ (click)="resetZoom()"
1234
+ >
1235
+ Reset zoom
1236
+ </button>
1237
+ </div>
1238
+ }
1239
+ `, isInline: true });
1240
+ }
1241
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ChartZoomControls, decorators: [{
1242
+ type: Component,
1243
+ args: [{
1244
+ selector: 'ChartZoomControls',
1245
+ host: {
1246
+ class: 'mt-3 flex flex-wrap items-center justify-between gap-3 text-xs text-muted-foreground',
1247
+ },
1248
+ template: `
1249
+ <p>{{ hint() }}</p>
1250
+
1251
+ @if (status(); as currentStatus) {
1252
+ <div class="flex flex-wrap items-center gap-2">
1253
+ <span
1254
+ class="rounded-full border border-border bg-background px-2.5 py-1 font-medium text-foreground"
1255
+ >
1256
+ {{ currentStatus }}
1257
+ </span>
1258
+ <button
1259
+ type="button"
1260
+ class="inline-flex min-h-11 items-center rounded-md border border-border bg-background px-3 text-foreground transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1261
+ (click)="resetZoom()"
1262
+ >
1263
+ Reset zoom
1264
+ </button>
1265
+ </div>
1266
+ }
1267
+ `,
1268
+ }]
1269
+ }] });
1270
+
1271
+ class PieCenter {
1272
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: PieCenter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1273
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: PieCenter, isStandalone: true, selector: "ChartPieCenter", host: { classAttribute: "flex max-w-40 flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1274
+ }
1275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: PieCenter, decorators: [{
1276
+ type: Component,
1277
+ args: [{
1278
+ selector: 'ChartPieCenter',
1279
+ host: {
1280
+ class: 'flex max-w-40 flex-col items-center justify-center text-center',
1281
+ },
1282
+ template: `<ng-content />`,
1283
+ }]
1284
+ }] });
1285
+
1286
+ class RadialCenter {
1287
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: RadialCenter, deps: [], target: i0.ɵɵFactoryTarget.Component });
1288
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: RadialCenter, isStandalone: true, selector: "ChartRadialCenter", host: { classAttribute: "flex max-w-40 flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true });
1289
+ }
1290
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: RadialCenter, decorators: [{
1291
+ type: Component,
1292
+ args: [{
1293
+ selector: 'ChartRadialCenter',
1294
+ host: {
1295
+ class: 'flex max-w-40 flex-col items-center justify-center text-center',
1296
+ },
1297
+ template: `<ng-content />`,
1298
+ }]
1299
+ }] });
4
1300
 
5
1301
  /**
6
1302
  * Generated bundle index. Do not edit.
7
- */
1303
+ */
1304
+
1305
+ export { ChartAxisX, ChartAxisY, ChartBrush, ChartCrosshair, ChartGrid, ChartLegend, ChartPointerTracker, ChartTooltip, ChartZoomControls, PieCenter, RadialCenter };