neba 1.11.0 → 1.13.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 (218) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +43 -41
  3. package/dist/components/accordion/Accordion.d.ts +18 -0
  4. package/dist/components/accordion/Accordion.js +1 -1
  5. package/dist/components/anchor/Anchor.js +1 -1
  6. package/dist/components/animate-appear/AnimateAppear.d.ts +2 -13
  7. package/dist/components/animate-appear/AnimateAppear.js +1 -1
  8. package/dist/components/animate-blink/AnimateBlink.d.ts +2 -2
  9. package/dist/components/animate-blink/AnimateBlink.js +1 -1
  10. package/dist/components/animate-counter/AnimateCounter.d.ts +45 -0
  11. package/dist/components/animate-counter/AnimateCounter.js +1 -0
  12. package/dist/components/animate-counter/index.d.ts +1 -0
  13. package/dist/components/animate-counter/index.js +1 -0
  14. package/dist/components/animate-fade/AnimateFade.d.ts +2 -2
  15. package/dist/components/animate-fade/AnimateFade.js +1 -1
  16. package/dist/components/animate-float/AnimateFloat.d.ts +35 -0
  17. package/dist/components/animate-float/AnimateFloat.js +1 -0
  18. package/dist/components/animate-float/index.d.ts +1 -0
  19. package/dist/components/animate-float/index.js +1 -0
  20. package/dist/components/animate-grow/AnimateGrow.d.ts +2 -2
  21. package/dist/components/animate-grow/AnimateGrow.js +1 -1
  22. package/dist/components/animate-marquee/AnimateMarquee.d.ts +5 -3
  23. package/dist/components/animate-marquee/AnimateMarquee.js +1 -1
  24. package/dist/components/animate-reveal/AnimateReveal.d.ts +41 -0
  25. package/dist/components/animate-reveal/AnimateReveal.js +1 -0
  26. package/dist/components/animate-reveal/index.d.ts +1 -0
  27. package/dist/components/animate-reveal/index.js +1 -0
  28. package/dist/components/animate-rotate/AnimateRotate.d.ts +2 -2
  29. package/dist/components/animate-rotate/AnimateRotate.js +1 -1
  30. package/dist/components/animate-scramble/AnimateScramble.d.ts +48 -0
  31. package/dist/components/animate-scramble/AnimateScramble.js +1 -0
  32. package/dist/components/animate-scramble/index.d.ts +1 -0
  33. package/dist/components/animate-scramble/index.js +1 -0
  34. package/dist/components/animate-shake/AnimateShake.d.ts +39 -0
  35. package/dist/components/animate-shake/AnimateShake.js +1 -0
  36. package/dist/components/animate-shake/index.d.ts +1 -0
  37. package/dist/components/animate-shake/index.js +1 -0
  38. package/dist/components/animate-slide/AnimateSlide.d.ts +2 -2
  39. package/dist/components/animate-slide/AnimateSlide.js +1 -1
  40. package/dist/components/animate-split/AnimateSplit.d.ts +61 -0
  41. package/dist/components/animate-split/AnimateSplit.js +1 -0
  42. package/dist/components/animate-split/index.d.ts +1 -0
  43. package/dist/components/animate-split/index.js +1 -0
  44. package/dist/components/animate-typing/AnimateTyping.js +1 -1
  45. package/dist/components/animate-zoom/AnimateZoom.d.ts +2 -2
  46. package/dist/components/animate-zoom/AnimateZoom.js +1 -1
  47. package/dist/components/app-logo/AppLogo.js +1 -1
  48. package/dist/components/avatar/Avatar.js +1 -1
  49. package/dist/components/bar-chart/BarChart.js +1 -1
  50. package/dist/components/bottom-navigation/BottomNavigation.d.ts +10 -0
  51. package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
  52. package/dist/components/button/Button.js +1 -1
  53. package/dist/components/calendar/Calendar.js +1 -1
  54. package/dist/components/carousel/Carousel.d.ts +13 -0
  55. package/dist/components/carousel/Carousel.js +1 -1
  56. package/dist/components/checkbox/Checkbox.js +1 -1
  57. package/dist/components/code-block/CodeBlock.js +1 -1
  58. package/dist/components/color-picker/ColorPicker.js +1 -1
  59. package/dist/components/combobox/Combobox.d.ts +18 -0
  60. package/dist/components/combobox/Combobox.js +1 -1
  61. package/dist/components/command-palette/CommandPalette.js +1 -1
  62. package/dist/components/container/Container.d.ts +12 -4
  63. package/dist/components/container/Container.js +1 -1
  64. package/dist/components/data-table/DataTable.js +1 -1
  65. package/dist/components/date-picker/DatePicker.js +1 -1
  66. package/dist/components/date-range-picker/DateRangePicker.js +1 -1
  67. package/dist/components/date-time-picker/DateTimePicker.js +1 -1
  68. package/dist/components/dialog/Dialog.js +1 -1
  69. package/dist/components/drawer/Drawer.js +1 -1
  70. package/dist/components/flex/Flex.d.ts +93 -0
  71. package/dist/components/flex/Flex.js +1 -0
  72. package/dist/components/flex/index.d.ts +2 -0
  73. package/dist/components/flex/index.js +1 -0
  74. package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
  75. package/dist/components/footer/Footer.d.ts +4 -3
  76. package/dist/components/footer/Footer.js +1 -1
  77. package/dist/components/gallery/Gallery.d.ts +150 -0
  78. package/dist/components/gallery/Gallery.js +1 -0
  79. package/dist/components/gallery/GalleryViewer.d.ts +30 -0
  80. package/dist/components/gallery/GalleryViewer.js +1 -0
  81. package/dist/components/gallery/index.d.ts +2 -0
  82. package/dist/components/gallery/index.js +1 -0
  83. package/dist/components/gauge-chart/GaugeChart.js +1 -1
  84. package/dist/components/grid/Grid.d.ts +11 -1
  85. package/dist/components/grid/Grid.js +1 -1
  86. package/dist/components/grid-container/GridContainer.js +1 -1
  87. package/dist/components/header/Header.d.ts +5 -4
  88. package/dist/components/header/Header.js +1 -1
  89. package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
  90. package/dist/components/hover-card/HoverCard.js +1 -1
  91. package/dist/components/how-to-steps/HowToSteps.js +1 -1
  92. package/dist/components/image/Image.d.ts +155 -7
  93. package/dist/components/image/Image.js +1 -1
  94. package/dist/components/image/index.d.ts +1 -1
  95. package/dist/components/menu/Menu.js +1 -1
  96. package/dist/components/meter/Meter.d.ts +7 -0
  97. package/dist/components/meter/Meter.js +1 -1
  98. package/dist/components/navigation-menu/NavigationMenu.js +1 -1
  99. package/dist/components/number-field/NumberField.js +1 -1
  100. package/dist/components/otp-field/OtpField.js +1 -1
  101. package/dist/components/overlay/Overlay.js +1 -1
  102. package/dist/components/panes/Panes.js +1 -1
  103. package/dist/components/pie-chart/PieChart.js +1 -1
  104. package/dist/components/popover/Popover.js +1 -1
  105. package/dist/components/progress-circular/ProgressCircular.d.ts +10 -1
  106. package/dist/components/progress-circular/ProgressCircular.js +1 -1
  107. package/dist/components/progress-linear/ProgressLinear.d.ts +7 -1
  108. package/dist/components/progress-linear/ProgressLinear.js +1 -1
  109. package/dist/components/provider/NebaProvider.js +1 -1
  110. package/dist/components/radio-group/RadioGroup.js +1 -1
  111. package/dist/components/rating/Rating.js +1 -1
  112. package/dist/components/scatter-chart/ScatterChart.js +1 -1
  113. package/dist/components/scroll-area/ScrollArea.js +1 -1
  114. package/dist/components/scroll-zone/ScrollZone.d.ts +17 -11
  115. package/dist/components/scroll-zone/ScrollZone.js +1 -1
  116. package/dist/components/select/Select.d.ts +13 -0
  117. package/dist/components/select/Select.js +1 -1
  118. package/dist/components/show/Show.d.ts +60 -0
  119. package/dist/components/show/Show.js +1 -0
  120. package/dist/components/show/index.d.ts +2 -0
  121. package/dist/components/show/index.js +1 -0
  122. package/dist/components/sidebar/Sidebar.js +1 -1
  123. package/dist/components/slider/Slider.d.ts +37 -2
  124. package/dist/components/slider/Slider.js +1 -1
  125. package/dist/components/spoiler/Spoiler.js +1 -1
  126. package/dist/components/stack/Stack.d.ts +126 -0
  127. package/dist/components/stack/Stack.js +1 -0
  128. package/dist/components/stack/index.d.ts +1 -0
  129. package/dist/components/stack/index.js +1 -0
  130. package/dist/components/statistic/Statistic.d.ts +8 -3
  131. package/dist/components/tabs/Tabs.d.ts +46 -0
  132. package/dist/components/tabs/Tabs.js +1 -1
  133. package/dist/components/text-field/TextField.js +1 -1
  134. package/dist/components/time-picker/TimePicker.js +1 -1
  135. package/dist/components/timeline-chart/TimelineChart.js +1 -1
  136. package/dist/components/toast/Toast.js +1 -1
  137. package/dist/components/toggle/Toggle.js +1 -1
  138. package/dist/components/tooltip/Tooltip.js +1 -1
  139. package/dist/components/tour/Tour.js +1 -1
  140. package/dist/components/transfer/Transfer.js +1 -1
  141. package/dist/components/tree-select/TreeSelect.d.ts +2 -0
  142. package/dist/components/tree-select/TreeSelect.js +1 -1
  143. package/dist/components/tree-view/TreeView.js +1 -1
  144. package/dist/components/typography/Typography.js +1 -1
  145. package/dist/hooks/index.d.ts +1 -1
  146. package/dist/hooks/index.js +1 -1
  147. package/dist/hooks/useMediaQuery.d.ts +35 -1
  148. package/dist/hooks/useMediaQuery.js +1 -1
  149. package/dist/index.d.ts +10 -1
  150. package/dist/index.js +1 -1
  151. package/dist/internal/animate.d.ts +65 -2
  152. package/dist/internal/animate.js +1 -1
  153. package/dist/internal/cache.d.ts +24 -0
  154. package/dist/internal/cache.js +1 -0
  155. package/dist/internal/calendar.d.ts +15 -42
  156. package/dist/internal/calendar.js +1 -1
  157. package/dist/internal/chart-frame.d.ts +48 -3
  158. package/dist/internal/chart-frame.js +1 -1
  159. package/dist/internal/chart-line.js +1 -1
  160. package/dist/internal/chart.d.ts +16 -0
  161. package/dist/internal/chart.js +1 -1
  162. package/dist/internal/date.js +1 -1
  163. package/dist/internal/drag.d.ts +8 -6
  164. package/dist/internal/drag.js +1 -1
  165. package/dist/internal/format.d.ts +21 -7
  166. package/dist/internal/format.js +1 -1
  167. package/dist/internal/grid.d.ts +29 -27
  168. package/dist/internal/grid.js +1 -1
  169. package/dist/internal/i18n.d.ts +92 -0
  170. package/dist/internal/i18n.js +1 -1
  171. package/dist/internal/icons.d.ts +25 -0
  172. package/dist/internal/icons.js +1 -1
  173. package/dist/internal/link.d.ts +5 -4
  174. package/dist/internal/media.d.ts +9 -2
  175. package/dist/internal/media.js +1 -1
  176. package/dist/internal/observe.js +1 -1
  177. package/dist/internal/page-layout.d.ts +11 -9
  178. package/dist/internal/page-layout.js +1 -1
  179. package/dist/internal/picker.d.ts +8 -3
  180. package/dist/internal/picker.js +1 -1
  181. package/dist/internal/progress.d.ts +24 -1
  182. package/dist/internal/progress.js +1 -1
  183. package/dist/internal/responsive.d.ts +97 -0
  184. package/dist/internal/responsive.js +1 -0
  185. package/dist/internal/styles.d.ts +140 -2
  186. package/dist/internal/styles.js +1 -1
  187. package/dist/internal/text.d.ts +32 -0
  188. package/dist/internal/text.js +1 -0
  189. package/dist/internal/wheel.d.ts +38 -0
  190. package/dist/internal/wheel.js +1 -0
  191. package/dist/locales/ar.js +1 -1
  192. package/dist/locales/de.js +1 -1
  193. package/dist/locales/es.js +1 -1
  194. package/dist/locales/fr.js +1 -1
  195. package/dist/locales/hi.js +1 -1
  196. package/dist/locales/id.js +1 -1
  197. package/dist/locales/it.js +1 -1
  198. package/dist/locales/ja.js +1 -1
  199. package/dist/locales/ko.js +1 -1
  200. package/dist/locales/nl.js +1 -1
  201. package/dist/locales/pl.js +1 -1
  202. package/dist/locales/pt.js +1 -1
  203. package/dist/locales/ru.js +1 -1
  204. package/dist/locales/th.js +1 -1
  205. package/dist/locales/tr.js +1 -1
  206. package/dist/locales/vi.js +1 -1
  207. package/dist/locales/zh-hans.js +1 -1
  208. package/dist/locales/zh-hant.js +1 -1
  209. package/dist/styles.css +1 -1
  210. package/dist/tailwind.css +411 -30
  211. package/dist/types.d.ts +119 -6
  212. package/package.json +19 -18
  213. package/dist/components/avatar-group/AvatarGroup.d.ts +0 -47
  214. package/dist/components/avatar-group/AvatarGroup.js +0 -1
  215. package/dist/components/avatar-group/index.d.ts +0 -2
  216. package/dist/components/avatar-group/index.js +0 -1
  217. package/dist/internal/avatar-group.d.ts +0 -22
  218. package/dist/internal/avatar-group.js +0 -1
@@ -28,7 +28,7 @@
28
28
  * components, and their logic stays in their own files.
29
29
  */
30
30
  import * as React from 'react';
31
- import type { NebaAnimateRepeat, NebaAnimateTrigger, NebaAnimation, NebaSide, NebaTransition } from '../types.js';
31
+ import type { NebaAnimateRepeat, NebaAnimateTimeline, NebaAnimateTrigger, NebaAnimation, NebaSide, NebaTransition } from '../types.js';
32
32
  /**
33
33
  * Which keyframe an effect runs.
34
34
  *
@@ -49,6 +49,8 @@ export declare const animBaseClass = "neba-anim";
49
49
  * an arrival, so its number is a period.
50
50
  */
51
51
  export declare const defaultDurations: Record<NebaAnimation, number>;
52
+ /** Where a `reveal` is clipped to before its edge travels across. */
53
+ export declare function revealClip(side: NebaSide): string;
52
54
  /** A number is pixels; a string is already a CSS length. */
53
55
  export declare function lengthValue(value: number | string): string;
54
56
  export declare function isInfinite(repeat: NebaAnimateRepeat | undefined): boolean;
@@ -66,6 +68,11 @@ export interface AnimationSlotOptions {
66
68
  y?: string;
67
69
  angle?: string;
68
70
  angleTo?: string;
71
+ clip?: string;
72
+ /** `view` points the effect at a scroll timeline instead of the clock. */
73
+ timeline?: NebaAnimateTimeline;
74
+ /** The `animation-range` a `view` timeline is mapped over. */
75
+ range?: string;
69
76
  }
70
77
  /**
71
78
  * The `--n-anim-*` slots, as an inline style object.
@@ -86,6 +93,30 @@ export declare function slideOffsets(from: NebaSide, distance: number | string):
86
93
  x: string;
87
94
  y: string;
88
95
  };
96
+ export interface StaggerOptions {
97
+ /** Milliseconds of delay added per child. */
98
+ stagger: number;
99
+ /** Milliseconds of duration added per child. Negative speeds them up. */
100
+ durationStep: number;
101
+ /** Runs the list last-to-first. Only the order reverses. */
102
+ reverse: boolean;
103
+ }
104
+ /** Whether these options ask for anything the root cannot do on its own. */
105
+ export declare function staggers({ stagger, durationStep }: StaggerOptions): boolean;
106
+ /**
107
+ * The same effect on each child, held back by its position.
108
+ *
109
+ * The animation is written onto the children **themselves** rather than onto
110
+ * wrappers around them. A row of `<li>`s stays a row of `<li>`s, a grid's cells
111
+ * stay its direct children, and nothing about the layout changes because the
112
+ * list is being animated. Only a bare string has no element to write onto, so
113
+ * that one gets a `<span>`.
114
+ *
115
+ * The step is per *child*, which means what is passed matters: eight children
116
+ * are eight steps, and one child holding eight things is one step. That is also
117
+ * how to opt part of a list out — group it.
118
+ */
119
+ export declare function staggerChildren(children: React.ReactNode, effectClass: string, slots: AnimationSlotOptions, { stagger, durationStep, reverse }: StaggerOptions): React.ReactNode[];
89
120
  /**
90
121
  * What a component's `transition` prop turns into: one class pair and a handful
91
122
  * of custom properties, merged into whatever the component was already writing.
@@ -99,6 +130,19 @@ export declare function transitionProps(transition: NebaTransition | undefined):
99
130
  className: string;
100
131
  style: React.CSSProperties;
101
132
  };
133
+ /**
134
+ * The same reading, one step before it becomes a class and a style object.
135
+ *
136
+ * A component that draws its children into boxes of its own — Stack — needs the
137
+ * *options* rather than the finished style, because it has a step per child to
138
+ * add to the delay before the slots are filled. Splitting it here is what keeps
139
+ * one table: `transition="fade"` on a Card and on a Stack item are the same
140
+ * fade, read by the same code.
141
+ */
142
+ export declare function transitionParts(transition: NebaTransition | undefined): {
143
+ effect: NebaAnimation;
144
+ slots: AnimationSlotOptions;
145
+ } | null;
102
146
  /**
103
147
  * Whether the reader has asked for less motion — the hook the three effects
104
148
  * with motion written in JavaScript read. It lives in `media.ts` beside the
@@ -146,8 +190,25 @@ export interface AnimationRun {
146
190
  */
147
191
  export declare function useAnimationRun({ trigger, play, once, threshold, paused, infinite }: AnimationRunOptions): AnimationRun;
148
192
  export interface AnimateElementParams extends AnimationSlotOptions, AnimationRunOptions {
149
- /** Which keyframe. `null` for the components that write their own. */
193
+ /** Which keyframe, out of the shared table. `null` to bring your own. */
150
194
  effect: NebaAnimation | null;
195
+ /**
196
+ * A keyframe class of this component's own, for an effect that is not in the
197
+ * `transition` vocabulary — `AnimateFloat` and `AnimateShake`. Everything else
198
+ * about them is the same machinery, `stagger` included, which is the whole
199
+ * reason this is a parameter rather than a second hook.
200
+ */
201
+ effectClass?: string;
202
+ /** What `data-neba-animation` says. Defaults to `effect`. */
203
+ name?: string;
204
+ /**
205
+ * What is inside. Only read to hand each child an effect of its own — pass it
206
+ * and render `children` back, or leave it out and render your own.
207
+ */
208
+ children?: React.ReactNode;
209
+ stagger?: number;
210
+ durationStep?: number;
211
+ reverse?: boolean;
151
212
  }
152
213
  export interface AnimateElement {
153
214
  ref: React.RefCallback<HTMLElement>;
@@ -155,6 +216,8 @@ export interface AnimateElement {
155
216
  style: React.CSSProperties;
156
217
  /** The hover handlers and the two data attributes, ready to be spread. */
157
218
  props: React.HTMLAttributes<HTMLElement> & Record<string, unknown>;
219
+ /** The children as given, or one animation each once a step is asked for. */
220
+ children: React.ReactNode;
158
221
  }
159
222
  /**
160
223
  * Everything an `Animate*` root needs, in one call.
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{observeVisibility as n}from"./observe.js";export const animationClasses={fade:"neba-anim-fade",grow:"neba-anim-scale",slide:"neba-anim-slide",zoom:"neba-anim-scale",rotate:"neba-anim-rotate",blink:"neba-anim-blink"};export const animBaseClass="neba-anim";export const defaultDurations={fade:320,grow:340,slide:380,zoom:340,rotate:460,blink:900};export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function isInfinite(e){return"infinite"===e}export function animationSlots(e){const n={"--n-anim-duration":`${e.duration}ms`,"--n-anim-delay":`${e.delay}ms`,"--n-anim-repeat":(i=e.repeat,"infinite"===i?"infinite":String(i)),"--n-anim-direction":(t=e.mode??"in",a=e.alternate,"out"===t?a?"alternate-reverse":"reverse":a?"alternate":"normal")};var t,a,i;return e.easing&&(n["--n-anim-ease"]=e.easing),void 0!==e.opacity&&(n["--n-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(n["--n-anim-scale"]=String(e.scale)),void 0!==e.x&&(n["--n-anim-x"]=e.x),void 0!==e.y&&(n["--n-anim-y"]=e.y),void 0!==e.angle&&(n["--n-anim-angle"]=e.angle),void 0!==e.angleTo&&(n["--n-anim-angle-to"]=e.angleTo),n}export function slideOffsets(e,n){const t=lengthValue(n),a="number"==typeof n?-n+"px":`calc(-1 * ${t})`;switch(e){case"top":return{x:"0px",y:a};case"bottom":return{x:"0px",y:t};case"left":return{x:a,y:"0px"};default:return{x:t,y:"0px"}}}export function transitionProps(e){if(!e)return{className:"",style:{}};const n="string"==typeof e?{type:e}:e,{type:t}=n,a={duration:n.duration??defaultDurations[t],delay:n.delay??0,easing:n.easing,repeat:n.repeat??("blink"===t?"infinite":1),alternate:n.alternate};if("grow"!==t&&"zoom"!==t||(a.scale=n.scale??("zoom"===t?.4:.8)),"slide"===t){const{x:e,y:t}=slideOffsets(n.from??"bottom",n.distance??"100%");a.x=e,a.y=t}return"rotate"===t&&(a.angle=`${n.angle??-180}deg`),{className:`neba-anim ${animationClasses[t]}`,style:animationSlots(a)}}export{usePrefersReducedMotion}from"./media.js";export function useAnimationRun({trigger:t,play:a,once:i,threshold:o,paused:r,infinite:s}){const l=e.useRef(null),[u,m]=e.useState("mount"===t),[c,f]=e.useState(0),d=e.useCallback(()=>{m(!0),f(e=>e+1)},[]);e.useLayoutEffect(()=>{const e=l.current;if(!e||0===c)return;const n=[e,...e.querySelectorAll(".neba-anim, .neba-marquee-track")];for(const e of n)e.style.animationName="none";e.offsetWidth;for(const e of n)e.style.animationName=""},[c]),e.useEffect(()=>{if("visible"!==t)return;const e=l.current;if(!e)return;let a=null;if(a=n(e,o,e=>{e?(d(),i&&(a?.(),a=null)):i||m(!1)}),a)return()=>a?.();m(!0)},[t,i,o,d]),e.useEffect(()=>{"manual"===t&&(a?d():m(!1))},[t,a,d]);const p="hover"===t?{onPointerEnter:d,onFocus:d,onPointerLeave:()=>{s&&m(!1)},onBlur:()=>{s&&m(!1)}}:{};return{ref:e.useCallback(e=>{l.current=e},[]),state:u&&!r?"running":"paused",started:u,handlers:p}}export function useAnimateElement(e){const{effect:n,trigger:t,play:a,once:i,threshold:o,paused:r,infinite:s,...l}=e,u=useAnimationRun({trigger:t,play:a,once:i,threshold:o,paused:r,infinite:s});return{ref:u.ref,className:n?`neba-anim ${animationClasses[n]}`:"",style:{...animationSlots(l),"--n-anim-state":u.state},props:{...u.handlers,"data-neba-animation":n??void 0,"data-state":u.state}}}
1
+ "use client";import{jsx as e}from"react/jsx-runtime";import*as n from"react";import{observeVisibility as t}from"./observe.js";import{cx as a}from"./styles.js";export const animationClasses={fade:"neba-anim-fade",grow:"neba-anim-scale",slide:"neba-anim-slide",zoom:"neba-anim-scale",rotate:"neba-anim-rotate",blink:"neba-anim-blink",reveal:"neba-anim-reveal"};export const animBaseClass="neba-anim";export const defaultDurations={fade:320,grow:340,slide:380,zoom:340,rotate:460,blink:900,reveal:620};export function revealClip(e){switch(e){case"top":return"inset(0 0 100% 0)";case"bottom":return"inset(100% 0 0 0)";case"right":return"inset(0 0 0 100%)";default:return"inset(0 100% 0 0)"}}export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function isInfinite(e){return"infinite"===e}export function animationSlots(e){const n={"--n-anim-duration":`${e.duration}ms`,"--n-anim-delay":`${e.delay}ms`,"--n-anim-repeat":(r=e.repeat,"infinite"===r?"infinite":String(r)),"--n-anim-direction":(t=e.mode??"in",a=e.alternate,"out"===t?a?"alternate-reverse":"reverse":a?"alternate":"normal")};var t,a,r;return e.easing&&(n["--n-anim-ease"]=e.easing),void 0!==e.opacity&&(n["--n-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(n["--n-anim-scale"]=String(e.scale)),void 0!==e.x&&(n["--n-anim-x"]=e.x),void 0!==e.y&&(n["--n-anim-y"]=e.y),void 0!==e.angle&&(n["--n-anim-angle"]=e.angle),void 0!==e.angleTo&&(n["--n-anim-angle-to"]=e.angleTo),void 0!==e.clip&&(n["--n-anim-clip"]=e.clip),"view"===e.timeline&&(n["--n-anim-timeline"]="view()",n["--n-anim-range"]=e.range??"entry 0% cover 45%"),n}export function slideOffsets(e,n){const t=lengthValue(n),a="number"==typeof n?-n+"px":`calc(-1 * ${t})`;switch(e){case"top":return{x:"0px",y:a};case"bottom":return{x:"0px",y:t};case"left":return{x:a,y:"0px"};default:return{x:t,y:"0px"}}}export function staggers({stagger:e,durationStep:n}){return 0!==e||0!==n}export function staggerChildren(t,r,i,{stagger:s,durationStep:o,reverse:l}){const u=n.Children.toArray(t);return u.map((t,c)=>{const m=l?u.length-1-c:c,f=animationSlots({...i,delay:i.delay+m*s,duration:Math.max(0,i.duration+m*o)});if(!n.isValidElement(t))return e("span",{className:r,style:f,children:t},c);const d=t.props;return n.cloneElement(t,{className:a(r,d.className),style:{...f,...d.style}})})}export function transitionProps(e){const n=transitionParts(e);return n?{className:`neba-anim ${animationClasses[n.effect]}`,style:animationSlots(n.slots)}:{className:"",style:{}}}export function transitionParts(e){if(!e)return null;const n="string"==typeof e?{type:e}:e,{type:t}=n,a={duration:n.duration??defaultDurations[t],delay:n.delay??0,easing:n.easing,repeat:n.repeat??("blink"===t?"infinite":1),alternate:n.alternate,timeline:n.timeline,range:n.range};if("grow"!==t&&"zoom"!==t||(a.scale=n.scale??("zoom"===t?.4:.8)),"slide"===t){const{x:e,y:t}=slideOffsets(n.from??"bottom",n.distance??"100%");a.x=e,a.y=t}return"rotate"===t&&(a.angle=`${n.angle??-180}deg`),"reveal"===t&&(a.clip=revealClip(n.side??"left")),{effect:t,slots:a}}export{usePrefersReducedMotion}from"./media.js";export function useAnimationRun({trigger:e,play:a,once:r,threshold:i,paused:s,infinite:o}){const l=n.useRef(null),[u,c]=n.useState("mount"===e),[m,f]=n.useState(0),d=n.useCallback(()=>{c(!0),f(e=>e+1)},[]);n.useLayoutEffect(()=>{const e=l.current;if(!e||0===m)return;const n=[e,...e.querySelectorAll(".neba-anim, .neba-marquee-track")];for(const e of n)e.style.animationName="none";e.offsetWidth;for(const e of n)e.style.animationName=""},[m]),n.useEffect(()=>{if("visible"!==e)return;const n=l.current;if(!n)return;let a=null;if(a=t(n,i,e=>{e?(d(),r&&(a?.(),a=null)):r||c(!1)}),a)return()=>a?.();c(!0)},[e,r,i,d]),n.useEffect(()=>{"manual"===e&&(a?d():c(!1))},[e,a,d]);const p="hover"===e?{onPointerEnter:d,onFocus:d,onPointerLeave:()=>{o&&c(!1)},onBlur:()=>{o&&c(!1)}}:{};return{ref:n.useCallback(e=>{l.current=e},[]),state:u&&!s?"running":"paused",started:u,handlers:p}}export function useAnimateElement(e){const{effect:n,trigger:t,play:a,once:r,threshold:i,paused:s,infinite:o,children:l,stagger:u=0,durationStep:c=0,reverse:m=!1,effectClass:f,name:d,...p}=e,g=useAnimationRun({trigger:t,play:a,once:r,threshold:i,paused:s,infinite:o}),y=n?animationClasses[n]:f,x=y?`neba-anim ${y}`:"",v=""!==x&&staggers({stagger:u,durationStep:c,reverse:m}),b="view"===p.timeline?"running":g.state;return{ref:g.ref,className:v?"":x,style:v?{"--n-anim-state":b}:{...animationSlots(p),"--n-anim-state":b},props:{...g.handlers,"data-neba-animation":d??n??void 0,"data-state":b},children:v?staggerChildren(l,x,p,{stagger:u,durationStep:c,reverse:m}):l}}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A memo that cannot grow without bound.
3
+ *
4
+ * Five caches in this folder are keyed on something a caller chose — a
5
+ * `locale`, a media query string, the options behind a `format` prop — and
6
+ * every one of those keys arrives through a public prop or a public hook. The
7
+ * library's own use of them is a handful of entries each: a dozen queries, two
8
+ * segmenter granularities, however many languages a product ships. A caller
9
+ * computing a key is the case with no ceiling, and what sits on the far side is
10
+ * an `Intl` object or a live `MediaQueryList` rather than a few bytes.
11
+ *
12
+ * So there is a ceiling, and reaching it empties the store rather than evicting
13
+ * the coldest entry. An LRU wants a second structure and an ordering to
14
+ * maintain on every read, which is real work on the one path this exists to
15
+ * make cheap; emptying is a single branch, and the worst it can do is make the
16
+ * next call build what it would have built anyway. The limit is far above
17
+ * anything the library itself reaches, so an ordinary page never meets it.
18
+ *
19
+ * One rule comes with the shape: a store must not hold `undefined` as a value,
20
+ * or every read of that key misses and builds again. All five hold an object, a
21
+ * number or `null`.
22
+ */
23
+ /** Reads `key` out of `store`, filling it in with `build` on a miss. */
24
+ export declare function memoise<K, V>(store: Map<K, V>, key: K, build: () => V): V;
@@ -0,0 +1 @@
1
+ export function memoise(e,t,n){const o=e.get(t);if(void 0!==o)return o;e.size>=64&&e.clear();const r=n();return e.set(t,r),r}
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type TimeUnit } from './date.js';
3
+ import { type PickerMessages } from './i18n.js';
3
4
  import type { NebaColor, NebaDateGranularity, NebaDensity, NebaSize, NebaWeekday } from '../types.js';
4
5
  /**
5
6
  * The calendar grid and the clock columns, written once for the four pickers.
@@ -20,49 +21,21 @@ import type { NebaColor, NebaDateGranularity, NebaDensity, NebaSize, NebaWeekday
20
21
  /**
21
22
  * Every string a picker says that is not a date.
22
23
  *
23
- * One object rather than twenty props. These are a set: a caller who has to
24
- * translate "Previous month" has to translate "Next month" in the same breath,
25
- * and a component with twenty `*Label` props is a component whose signature is
26
- * mostly apology. The dates themselves are never in here — those come from
27
- * `Intl`, which already knows what July is called in more languages than this
28
- * file ever will.
24
+ * The set itself lives in `internal/i18n.ts`, with the other nineteen
25
+ * namespaces and the eighteen translations of each — the name stays here
26
+ * because it is what the `labels` prop is typed against.
29
27
  */
30
- export interface PickerLabels {
31
- /** The calendar's steppers, in day view. */
32
- previousMonth: string;
33
- nextMonth: string;
34
- /** The same steppers in month view, where they move by a year. */
35
- previousYear: string;
36
- nextYear: string;
37
- /** And in year view, where they move by a page of twelve. */
38
- previousYears: string;
39
- nextYears: string;
40
- /** The two header buttons that open the month grid and the year grid. */
41
- chooseMonth: string;
42
- chooseYear: string;
43
- /**
44
- * The footer's actions. Three shortcuts rather than one because the button
45
- * jumps to the current *unit*, and a month picker whose footer says "Today"
46
- * is offering a day it has no way to accept.
47
- */
48
- today: string;
49
- thisMonth: string;
50
- thisYear: string;
51
- now: string;
52
- clear: string;
53
- done: string;
54
- /** The clock's columns. */
55
- hour: string;
56
- minute: string;
57
- second: string;
58
- meridiem: string;
59
- /** Which end of a range the calendar is currently asking for. */
60
- start: string;
61
- end: string;
62
- }
63
- export declare const defaultPickerLabels: PickerLabels;
64
- /** Merges a caller's overrides over the defaults, once per render. */
65
- export declare function usePickerLabels(overrides?: Partial<PickerLabels>): PickerLabels;
28
+ export type PickerLabels = PickerMessages;
29
+ /**
30
+ * The twenty strings for a locale, with a caller's own wording over the top.
31
+ *
32
+ * `locale` answers the language and `overrides` answers the wording, which is
33
+ * why both are taken: a product in Korean should not have to write out twenty
34
+ * labels to stop a calendar saying "Previous month", and a product that wants
35
+ * "Back" instead of "Previous month" should not have to register a language to
36
+ * say so.
37
+ */
38
+ export declare function usePickerLabels(overrides: Partial<PickerLabels> | undefined, locale: string | undefined): PickerLabels;
66
39
  export interface CalendarProps {
67
40
  size: NebaSize;
68
41
  color: NebaColor;
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as o from"react";import{Button as r}from"../components/button/Button.js";import{ChevronIcon as a}from"./icons.js";import{controlHeightClasses as l,controlTextClasses as s,cx as i,gapClasses as c,metaTextClasses as u,pressTransitionClasses as d,srOnlyClasses as m,transitionClasses as h}from"./styles.js";import{addDays as g,addMonths as f,addYears as b,calendarWeeks as p,compareDay as v,isDayOutside as x,isMonthBeforeYear as y,isSameDay as w,isSameMonth as D,isUnitOutside as N,isValidDate as S,makeDate as M,meridiemLabels as P,monthLabels as C,startOfDay as k,startOfMonth as z,today as Y,weekdayLabels as A,withTime as j,YEAR_PAGE_SIZE as E,yearPageStart as F}from"./date.js";import{dateFormatter as T}from"./format.js";export const defaultPickerLabels={previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",clear:"Clear",done:"Done",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End"};export function usePickerLabels(e){return o.useMemo(()=>e?{...defaultPickerLabels,...e}:defaultPickerLabels,[e])}const R={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"},B={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-xs)",md:"rounded-(--neba-radius-sm)",lg:"rounded-(--neba-radius-md)",xl:"rounded-(--neba-radius-lg)"},H={xs:"rounded-s-(--neba-radius-xs)",sm:"rounded-s-(--neba-radius-xs)",md:"rounded-s-(--neba-radius-sm)",lg:"rounded-s-(--neba-radius-md)",xl:"rounded-s-(--neba-radius-lg)"},L={xs:"rounded-e-(--neba-radius-xs)",sm:"rounded-e-(--neba-radius-xs)",md:"rounded-e-(--neba-radius-sm)",lg:"rounded-e-(--neba-radius-md)",xl:"rounded-e-(--neba-radius-lg)"},K=["relative flex select-none items-center justify-center tabular-nums","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,d,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--n-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function O({children:n,label:o,selected:r,inRange:a=!1,rangeEdge:l=null,current:s=!1,muted:c=!1,disabled:u=!1,focused:d=!1,size:m,className:h,onClick:g,onPointerEnter:f,onKeyDown:b}){return t("button",{type:"button",role:"gridcell","aria-label":o,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":u||void 0,tabIndex:d?0:-1,"data-focus-target":d?"true":void 0,className:i(K,"start"===l?H[m]:"end"===l?L[m]:"middle"===l?"rounded-none":B[m],u?"cursor-not-allowed text-(--neba-disabled-fg)":r?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":a?"cursor-pointer bg-(--n-soft) text-(--neba-fg) hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)":s?"cursor-pointer font-semibold text-(--n-accent) hover:bg-(--n-soft) active:bg-(--n-soft-press)":c?"cursor-pointer text-(--neba-muted-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)",h),onClick:()=>{u||g()},onPointerEnter:f,onKeyDown:b,children:[n,s?e("span",{"aria-hidden":"true",className:"absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current"}):null]})}function U({size:o,color:u,view:d,month:m,locale:h,labels:g,showPreviousButton:f,showNextButton:b,onStep:p,onViewChange:v}){const x=C(h,"long")[m.getMonth()],w=String(m.getFullYear()),D=y(h),N="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],S=(t,n)=>n?e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":N[-1===t?0:1],onClick:()=>p(t),startIcon:e("span",{className:i("flex items-center",-1===t?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(a,{})})}):e("span",{"aria-hidden":"true",className:i(l[o],"w-(--n-cell)")}),M=t=>e("span",{className:i("flex items-center text-(--neba-muted-fg)","[transition:rotate_var(--neba-duration)_var(--neba-ease)]",t&&"rotate-180"),children:e(a,{})}),P=e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":g.chooseMonth,"aria-expanded":"month"===d,onClick:()=>v("month"===d?"day":"month"),endIcon:M("month"===d),children:x},"month"),k=e(r,{variant:"text",size:o,color:u,density:"compact",className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,onClick:()=>v("year"===d?"day":"year"),endIcon:M("year"===d),children:w},"year"),z=F(m.getFullYear());return t("div",{className:"flex items-center justify-between gap-1",children:[S(-1,f),e("div",{className:i("flex min-w-0 flex-1 items-center justify-center",c[o]),children:"year"===d?e("span",{className:i("flex items-center font-medium tabular-nums text-(--neba-fg)",l[o],s[o]),children:`${z}–${z+E-1}`}):"month"===d?k:t(n,D?{children:[P,k]}:{children:[k,P]})}),S(1,b)]})}const q={day:0,month:1,year:2};export function Calendar({size:n,color:r,locale:a,weekStartsOn:l,month:s,onMonthChange:u,selected:d,rangeStart:m=null,rangeEnd:h=null,onSelect:g,granularity:p="day",renderDay:v,onPreviewChange:y,minDate:w,maxDate:N,shouldDisableDate:P,showOutsideDays:C=!0,autoFocus:A=!1,showPreviousButton:j=!0,showNextButton:F=!0,labels:T,className:B}){const[H,L]=o.useState(p),K=q[H]<q[p]?p:H,O=o.useMemo(()=>d.filter(S),[d]),[V,G]=o.useState(()=>{const e=O.find(e=>D(e,s));return e?k(e):D(Y(),s)?Y():z(s)}),J=o.useRef(A),Q=o.useRef(null);o.useEffect(()=>{G(e=>D(e,s)?e:z(s))},[s]),o.useLayoutEffect(()=>{J.current&&(J.current=!1,Q.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const W=o.useCallback(e=>x(e,w,N)||(P?.(e)??!1),[w,N,P]),X=e=>{J.current=!0,L(e)},Z=e=>{J.current=!0,u(e)};return t("div",{ref:Q,className:i("flex flex-col",c[n],B),style:{"--n-cell":R[n]},onPointerLeave:()=>y?.(null),children:[e(U,{size:n,color:r,view:K,month:s,locale:a,labels:T,showPreviousButton:j,showNextButton:F,onStep:e=>{u("day"===K?f(s,e):b(s,"month"===K?e:e*E))},onViewChange:X}),e("div",{className:"h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*7)]",children:"day"===K?e(I,{size:n,locale:a,weekStartsOn:l,month:s,chosen:O,rangeStart:m,rangeEnd:h,focusedDate:V,renderDay:v,showOutsideDays:C,isDisabled:W,onSelect:e=>{G(e),g(e)},onPreviewChange:y,onMoveFocus:e=>{J.current=!0,G(e),D(e,s)||u(z(e))}}):"month"===K?e($,{size:n,locale:a,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"month"===p?P:void 0,onMoveCursor:Z,onPick:e=>{const t=M(s.getFullYear(),e,1);u(t),"month"===p?g(t):X("day")}}):e(_,{size:n,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"year"===p?P:void 0,onMoveCursor:Z,onPick:e=>{if("year"===p){const t=M(e,0,1);return u(t),void g(t)}u(M(e,s.getMonth(),1)),X("month")}})})]})}function I({size:n,locale:o,weekStartsOn:r,month:a,chosen:l,rangeStart:c,rangeEnd:d,focusedDate:m,renderDay:h,showOutsideDays:b,isDisabled:x,onSelect:y,onPreviewChange:N,onMoveFocus:M}){const P=p(a,r),C=A(o,r,"short"),k=A(o,r,"long"),z=T(o,{dateStyle:"full"}),j=(F=d,S(E=c)&&S(F)?v(E,F)<=0?[E,F]:[F,E]:null);var E,F;const R=Y();return t("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:C.map((t,o)=>e("span",{role:"columnheader","aria-label":k[o],className:i("flex h-(--n-cell) items-center justify-center font-medium text-(--neba-muted-fg) select-none",u[n]),children:t},o))}),P.map((o,c)=>e("div",{role:"row",className:"grid grid-cols-7",children:o.map(o=>{const c=!D(o,a);if(c&&!b)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--n-cell)"},o.getTime());const u=l.some(e=>w(e,o)),d=null!==j&&v(o,j[0])>=0&&v(o,j[1])<=0,p=null!==j&&d&&w(o,j[0]),S=null!==j&&d&&w(o,j[1]);return t(O,{size:n,label:z.format(o),selected:u,inRange:d&&!u,rangeEdge:d?p&&S?"both":p?"start":S?"end":"middle":null,current:w(o,R)&&!u,muted:c,disabled:x(o),focused:w(o,m),className:i("size-(--n-cell)",s[n]),onClick:()=>y(o),onPointerEnter:()=>N?.(o),onKeyDown:e=>((e,t)=>{const n=(t.getDay()-r+7)%7,o={ArrowLeft:()=>g(t,-1),ArrowRight:()=>g(t,1),ArrowUp:()=>g(t,-7),ArrowDown:()=>g(t,7),Home:()=>g(t,-n),End:()=>g(t,6-n),PageUp:()=>f(t,e.shiftKey?-12:-1),PageDown:()=>f(t,e.shiftKey?12:1)}[e.key];o&&(e.preventDefault(),M(o()))})(e,o),children:[o.getDate(),h?h(o):null]},o.getTime())})},c))]})}function $({size:t,locale:n,month:o,chosen:r,minDate:a,maxDate:l,shouldDisable:c,onMoveCursor:u,onPick:d}){const m=C(n,"short"),h=C(n,"long"),g=o.getFullYear(),b=new Date,p=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==t&&(e.preventDefault(),u(f(z(o),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(n=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(u=>{const f=3*n+u,v=M(g,f,1);return e(O,{size:t,label:`${h[f]} ${g}`,selected:r.some(e=>e.getFullYear()===g&&e.getMonth()===f),current:b.getFullYear()===g&&b.getMonth()===f,disabled:N(v,"month",a,l)||(c?.(v)??!1),focused:f===o.getMonth(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>d(f),onKeyDown:p,children:m[f]},f)})},n))})}function _({size:t,month:n,chosen:o,minDate:r,maxDate:a,shouldDisable:l,onMoveCursor:c,onPick:u}){const d=F(n.getFullYear()),m=(new Date).getFullYear(),h=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-E,PageDown:E}[e.key];void 0!==t&&(e.preventDefault(),c(b(z(n),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(c=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(g=>{const f=d+4*c+g,b=M(f,0,1);return e(O,{size:t,label:String(f),selected:o.some(e=>e.getFullYear()===f),current:f===m,disabled:N(b,"year",r,a)||(l?.(b)??!1),focused:f===n.getFullYear(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>u(f),onKeyDown:h,children:f},f)})},c))})}function V(e){const t=e.parentElement;if(!t)return;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect(),r=n.top-o.top-t.clientTop+t.scrollTop,a=r+n.height;r<t.scrollTop?t.scrollTop=r:a>t.scrollTop+t.clientHeight&&(t.scrollTop=a-t.clientHeight)}export function TimeGrid({size:n,density:r,locale:a,value:c,referenceDate:u,onChange:d,hour12:h,showSeconds:g,hourStep:f,minuteStep:b,secondStep:p,shouldDisableTime:v,autoFocus:x=!1,labels:y,className:w}){const D=c??u,N=o.useRef(null),[S,M]=o.useMemo(()=>P(a),[a]);o.useEffect(()=>{const e=N.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(V),x){const t=e?.querySelector('[role="listbox"]');(t?.querySelector('[data-chosen="true"]')??t?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[x]);const C=o.useMemo(()=>{const e=Math.ceil((h?12:24)/f),t=Array.from({length:e},(e,t)=>t*f);return h?t.map(e=>0===e?12:e):t},[h,f]),k=o.useMemo(()=>Array.from({length:Math.ceil(60/b)},(e,t)=>t*b),[b]),z=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,t)=>t*p),[p]),Y=e=>String(e).padStart(2,"0"),A=h?D.getHours()%12||12:D.getHours(),E=(t,o,r,a,u)=>e("div",{role:"listbox","aria-label":o,className:i("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*2)]","scroll-py-0.5 [scrollbar-width:thin]"),children:r.map(o=>{const r=((e,t)=>j(D,"hour"===e?{hours:h?t%12+(D.getHours()>=12?12:0):t}:"minute"===e?{minutes:t}:"second"===e?{seconds:t}:{hours:D.getHours()%12+12*t}))(t,o),m=null!==c&&a(o),g=v?.(r,t)??!1;return e("button",{type:"button",role:"option","aria-selected":m,"aria-disabled":g||void 0,"data-chosen":m?"true":void 0,className:i(K,B[n],l[n],s[n],"w-full shrink-0",g?"cursor-not-allowed text-(--neba-disabled-fg)":m?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)"),onClick:()=>{g||d(r)},children:u(o)},o)})},t);return t("div",{ref:N,className:i("flex","compact"===r?"gap-0.5":"gap-1",w),style:{"--n-cell":R[n]},children:[E("hour",y.hour,C,e=>e===A,e=>h?String(e):Y(e)),E("minute",y.minute,k,e=>e===D.getMinutes(),Y),g?E("second",y.second,z,e=>e===D.getSeconds(),Y):null,h?E("meridiem",y.meridiem,[0,1],e=>(D.getHours()>=12?1:0)===e,e=>0===e?S:M):null,e("span",{className:m,"aria-live":"polite",children:null===c?"":T(a,{hour:"numeric",minute:"2-digit",...g?{second:"2-digit"}:{}}).format(c)})]})}
1
+ "use client";import{jsx as e,jsxs as n,Fragment as t}from"react/jsx-runtime";import*as o from"react";import{Button as r}from"../components/button/Button.js";import{ChevronIcon as l}from"./icons.js";import{controlHeightClasses as a,controlTextClasses as s,cx as i,gapClasses as c,metaTextClasses as u,pressTransitionClasses as d,srOnlyClasses as m,transitionClasses as h}from"./styles.js";import{addDays as g,addMonths as f,addYears as b,calendarWeeks as p,compareDay as v,isDayOutside as x,isMonthBeforeYear as y,isSameDay as w,isSameMonth as D,isUnitOutside as N,isValidDate as S,makeDate as M,meridiemLabels as C,monthLabels as k,startOfDay as z,startOfMonth as P,today as j,weekdayLabels as A,withTime as F,YEAR_PAGE_SIZE as Y,yearPageStart as E}from"./date.js";import{dateFormatter as R}from"./format.js";import{pickerMessages as T,useMessages as B}from"./i18n.js";export function usePickerLabels(e,n){const t=B(T,n);return o.useMemo(()=>e?{...t,...e}:t,[t,e])}const H={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"},K={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-xs)",md:"rounded-(--neba-radius-sm)",lg:"rounded-(--neba-radius-md)",xl:"rounded-(--neba-radius-lg)"},L={xs:"rounded-s-(--neba-radius-xs)",sm:"rounded-s-(--neba-radius-xs)",md:"rounded-s-(--neba-radius-sm)",lg:"rounded-s-(--neba-radius-md)",xl:"rounded-s-(--neba-radius-lg)"},O={xs:"rounded-e-(--neba-radius-xs)",sm:"rounded-e-(--neba-radius-xs)",md:"rounded-e-(--neba-radius-sm)",lg:"rounded-e-(--neba-radius-md)",xl:"rounded-e-(--neba-radius-lg)"},U=["relative flex select-none items-center justify-center tabular-nums","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,d,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--n-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function q({children:t,label:o,selected:r,inRange:l=!1,rangeEdge:a=null,current:s=!1,muted:c=!1,disabled:u=!1,focused:d=!1,size:m,className:h,onClick:g,onPointerEnter:f,onKeyDown:b}){return n("button",{type:"button",role:"gridcell","aria-label":o,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":u||void 0,tabIndex:d?0:-1,"data-focus-target":d?"true":void 0,className:i(U,"start"===a?L[m]:"end"===a?O[m]:"middle"===a?"rounded-none":K[m],u?"cursor-not-allowed text-(--neba-disabled-fg)":r?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":l?"cursor-pointer bg-(--n-soft) text-(--neba-fg) hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)":s?"cursor-pointer font-semibold text-(--n-accent) hover:bg-(--n-soft) active:bg-(--n-soft-press)":c?"cursor-pointer text-(--neba-muted-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)",h),onClick:()=>{u||g()},onPointerEnter:f,onKeyDown:b,children:[t,s?e("span",{"aria-hidden":"true",className:"absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current"}):null]})}function I({size:o,color:u,view:d,month:m,locale:h,labels:g,showPreviousButton:f,showNextButton:b,onStep:p,onViewChange:v}){const x=k(h,"long")[m.getMonth()],w=String(m.getFullYear()),D=y(h),N="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],S=(n,t)=>t?e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":N[-1===n?0:1],onClick:()=>p(n),startIcon:e("span",{className:i("flex items-center",-1===n?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(l,{})})}):e("span",{"aria-hidden":"true",className:i(a[o],"w-(--n-cell)")}),M=n=>e("span",{className:i("flex items-center text-(--neba-muted-fg)","[transition:rotate_var(--neba-duration)_var(--neba-ease)]",n&&"rotate-180"),children:e(l,{})}),C=e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":g.chooseMonth,"aria-expanded":"month"===d,onClick:()=>v("month"===d?"day":"month"),endIcon:M("month"===d),children:x},"month"),z=e(r,{variant:"text",size:o,color:u,density:"compact",className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,onClick:()=>v("year"===d?"day":"year"),endIcon:M("year"===d),children:w},"year"),P=E(m.getFullYear());return n("div",{className:"flex items-center justify-between gap-1",children:[S(-1,f),e("div",{className:i("flex min-w-0 flex-1 items-center justify-center",c[o]),children:"year"===d?e("span",{className:i("flex items-center font-medium tabular-nums text-(--neba-fg)",a[o],s[o]),children:`${P}–${P+Y-1}`}):"month"===d?z:n(t,D?{children:[C,z]}:{children:[z,C]})}),S(1,b)]})}const $={day:0,month:1,year:2};export function Calendar({size:t,color:r,locale:l,weekStartsOn:a,month:s,onMonthChange:u,selected:d,rangeStart:m=null,rangeEnd:h=null,onSelect:g,granularity:p="day",renderDay:v,onPreviewChange:y,minDate:w,maxDate:N,shouldDisableDate:C,showOutsideDays:k=!0,autoFocus:A=!1,showPreviousButton:F=!0,showNextButton:E=!0,labels:R,className:T}){const[B,K]=o.useState(p),L=$[B]<$[p]?p:B,O=o.useMemo(()=>d.filter(S),[d]),[U,q]=o.useState(()=>{const e=O.find(e=>D(e,s));return e?z(e):D(j(),s)?j():P(s)}),J=o.useRef(A),Q=o.useRef(null);o.useEffect(()=>{q(e=>D(e,s)?e:P(s))},[s]),o.useLayoutEffect(()=>{J.current&&(J.current=!1,Q.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const W=o.useCallback(e=>x(e,w,N)||(C?.(e)??!1),[w,N,C]),X=e=>{J.current=!0,K(e)},Z=e=>{J.current=!0,u(e)};return n("div",{ref:Q,className:i("flex flex-col",c[t],T),style:{"--n-cell":H[t]},onPointerLeave:()=>y?.(null),children:[e(I,{size:t,color:r,view:L,month:s,locale:l,labels:R,showPreviousButton:F,showNextButton:E,onStep:e=>{u("day"===L?f(s,e):b(s,"month"===L?e:e*Y))},onViewChange:X}),e("div",{className:"h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*7)]",children:"day"===L?e(_,{size:t,locale:l,weekStartsOn:a,month:s,chosen:O,rangeStart:m,rangeEnd:h,focusedDate:U,renderDay:v,showOutsideDays:k,isDisabled:W,onSelect:e=>{q(e),g(e)},onPreviewChange:y,onMoveFocus:e=>{J.current=!0,q(e),D(e,s)||u(P(e))}}):"month"===L?e(V,{size:t,locale:l,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"month"===p?C:void 0,onMoveCursor:Z,onPick:e=>{const n=M(s.getFullYear(),e,1);u(n),"month"===p?g(n):X("day")}}):e(G,{size:t,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"year"===p?C:void 0,onMoveCursor:Z,onPick:e=>{if("year"===p){const n=M(e,0,1);return u(n),void g(n)}u(M(e,s.getMonth(),1)),X("month")}})})]})}function _({size:t,locale:o,weekStartsOn:r,month:l,chosen:a,rangeStart:c,rangeEnd:d,focusedDate:m,renderDay:h,showOutsideDays:b,isDisabled:x,onSelect:y,onPreviewChange:N,onMoveFocus:M}){const C=p(l,r),k=A(o,r,"short"),z=A(o,r,"long"),P=R(o,{dateStyle:"full"}),F=(E=d,S(Y=c)&&S(E)?v(Y,E)<=0?[Y,E]:[E,Y]:null);var Y,E;const T=j();return n("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:k.map((n,o)=>e("span",{role:"columnheader","aria-label":z[o],className:i("flex h-(--n-cell) items-center justify-center font-medium text-(--neba-muted-fg) select-none",u[t]),children:n},o))}),C.map((o,c)=>e("div",{role:"row",className:"grid grid-cols-7",children:o.map(o=>{const c=!D(o,l);if(c&&!b)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--n-cell)"},o.getTime());const u=a.some(e=>w(e,o)),d=null!==F&&v(o,F[0])>=0&&v(o,F[1])<=0,p=null!==F&&d&&w(o,F[0]),S=null!==F&&d&&w(o,F[1]);return n(q,{size:t,label:P.format(o),selected:u,inRange:d&&!u,rangeEdge:d?p&&S?"both":p?"start":S?"end":"middle":null,current:w(o,T)&&!u,muted:c,disabled:x(o),focused:w(o,m),className:i("size-(--n-cell)",s[t]),onClick:()=>y(o),onPointerEnter:()=>N?.(o),onKeyDown:e=>((e,n)=>{const t=(n.getDay()-r+7)%7,o={ArrowLeft:()=>g(n,-1),ArrowRight:()=>g(n,1),ArrowUp:()=>g(n,-7),ArrowDown:()=>g(n,7),Home:()=>g(n,-t),End:()=>g(n,6-t),PageUp:()=>f(n,e.shiftKey?-12:-1),PageDown:()=>f(n,e.shiftKey?12:1)}[e.key];o&&(e.preventDefault(),M(o()))})(e,o),children:[o.getDate(),h?h(o):null]},o.getTime())})},c))]})}function V({size:n,locale:t,month:o,chosen:r,minDate:l,maxDate:a,shouldDisable:c,onMoveCursor:u,onPick:d}){const m=k(t,"short"),h=k(t,"long"),g=o.getFullYear(),b=new Date,p=e=>{const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==n&&(e.preventDefault(),u(f(P(o),n)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(t=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(u=>{const f=3*t+u,v=M(g,f,1);return e(q,{size:n,label:`${h[f]} ${g}`,selected:r.some(e=>e.getFullYear()===g&&e.getMonth()===f),current:b.getFullYear()===g&&b.getMonth()===f,disabled:N(v,"month",l,a)||(c?.(v)??!1),focused:f===o.getMonth(),className:i("h-(--n-cell) w-full",s[n]),onClick:()=>d(f),onKeyDown:p,children:m[f]},f)})},t))})}function G({size:n,month:t,chosen:o,minDate:r,maxDate:l,shouldDisable:a,onMoveCursor:c,onPick:u}){const d=E(t.getFullYear()),m=(new Date).getFullYear(),h=e=>{const n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-Y,PageDown:Y}[e.key];void 0!==n&&(e.preventDefault(),c(b(P(t),n)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(c=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(g=>{const f=d+4*c+g,b=M(f,0,1);return e(q,{size:n,label:String(f),selected:o.some(e=>e.getFullYear()===f),current:f===m,disabled:N(b,"year",r,l)||(a?.(b)??!1),focused:f===t.getFullYear(),className:i("h-(--n-cell) w-full",s[n]),onClick:()=>u(f),onKeyDown:h,children:f},f)})},c))})}function J(e){const n=e.parentElement;if(!n)return;const t=e.getBoundingClientRect(),o=n.getBoundingClientRect(),r=t.top-o.top-n.clientTop+n.scrollTop,l=r+t.height;r<n.scrollTop?n.scrollTop=r:l>n.scrollTop+n.clientHeight&&(n.scrollTop=l-n.clientHeight)}export function TimeGrid({size:t,density:r,locale:l,value:c,referenceDate:u,onChange:d,hour12:h,showSeconds:g,hourStep:f,minuteStep:b,secondStep:p,shouldDisableTime:v,autoFocus:x=!1,labels:y,className:w}){const D=c??u,N=o.useRef(null),[S,M]=o.useMemo(()=>C(l),[l]);o.useEffect(()=>{const e=N.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(J),x){const n=e?.querySelector('[role="listbox"]');(n?.querySelector('[data-chosen="true"]')??n?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[x]);const k=o.useMemo(()=>{const e=Math.ceil((h?12:24)/f),n=Array.from({length:e},(e,n)=>n*f);return h?n.map(e=>0===e?12:e):n},[h,f]),z=o.useMemo(()=>Array.from({length:Math.ceil(60/b)},(e,n)=>n*b),[b]),P=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,n)=>n*p),[p]),j=e=>String(e).padStart(2,"0"),A=h?D.getHours()%12||12:D.getHours(),Y=(n,o,r,l,u)=>e("div",{role:"listbox","aria-label":o,className:i("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*2)]","scroll-py-0.5 [scrollbar-width:thin]"),children:r.map(o=>{const r=((e,n)=>F(D,"hour"===e?{hours:h?n%12+(D.getHours()>=12?12:0):n}:"minute"===e?{minutes:n}:"second"===e?{seconds:n}:{hours:D.getHours()%12+12*n}))(n,o),m=null!==c&&l(o),g=v?.(r,n)??!1;return e("button",{type:"button",role:"option","aria-selected":m,"aria-disabled":g||void 0,"data-chosen":m?"true":void 0,className:i(U,K[t],a[t],s[t],"w-full shrink-0",g?"cursor-not-allowed text-(--neba-disabled-fg)":m?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)"),onClick:()=>{g||d(r)},children:u(o)},o)})},n);return n("div",{ref:N,className:i("flex","compact"===r?"gap-0.5":"gap-1",w),style:{"--n-cell":H[t]},children:[Y("hour",y.hour,k,e=>e===A,e=>h?String(e):j(e)),Y("minute",y.minute,z,e=>e===D.getMinutes(),j),g?Y("second",y.second,P,e=>e===D.getSeconds(),j):null,h?Y("meridiem",y.meridiem,[0,1],e=>(D.getHours()>=12?1:0)===e,e=>0===e?S:M):null,e("span",{className:m,"aria-live":"polite",children:null===c?"":R(l,{hour:"numeric",minute:"2-digit",...g?{second:"2-digit"}:{}}).format(c)})]})}
@@ -46,6 +46,38 @@ declare function useMeasuredWidth(ref: React.RefObject<HTMLElement | null>): num
46
46
  * would be two edges where the design language wants one. `variant="outline"`
47
47
  * is there for the chart that stands on the page by itself.
48
48
  */
49
+ /**
50
+ * How a mark answers the pointer: the three properties one is allowed to change
51
+ * when the reader points at it, and how long each takes.
52
+ *
53
+ * One declaration and one class on every mark, rather than one per property.
54
+ * `transition` is a shorthand, so two of them on the same element are decided by
55
+ * their order in the generated stylesheet rather than by intent — a scatter mark
56
+ * carrying a fade *and* a grow written separately keeps whichever Tailwind
57
+ * happened to emit last, which is the kind of bug that looks like the browser's
58
+ * fault. A property an element never changes costs it nothing.
59
+ *
60
+ * **`opacity`** is two states that are the same sentence at two scales. A whole
61
+ * *series* drops to 0.28 when the legend is pointed at one of the others; a
62
+ * single *datum* sits at 0.92 until the crosshair reaches it. Both mean "this is
63
+ * the one you asked about". It is also the one place a chart may say something
64
+ * with opacity at all: nothing here is a control, and "not the one you are
65
+ * pointing at" is not a state a colour family can carry without recolouring the
66
+ * data.
67
+ *
68
+ * **`r`** and **`scale`** are the same pixel of growth reached two ways, because
69
+ * the two shapes that grow are drawn differently. A line's marker is a
70
+ * `<circle>`, whose radius is the geometry property `r` — a number, which
71
+ * travels. A scatter's mark is an arbitrary `<path>`, whose size lives inside
72
+ * `d`, which does not; that one grows on the independent `scale` property about
73
+ * the point it is pinned to, so a triangle grows where it stands rather than
74
+ * drifting toward the middle of its own bounding box.
75
+ *
76
+ * Only the pie and the heatmap ever moved on any of this. The line, the area,
77
+ * the bar, the scatter and the timeline snapped, and a dashboard holding two of
78
+ * each showed both answers at once.
79
+ */
80
+ export declare const markTransitionClasses: string;
49
81
  export interface ChartBaseProps extends Omit<BoxProps, 'children' | 'title'> {
50
82
  /**
51
83
  * How tall the drawing is. A number is pixels; a string is any CSS length.
@@ -241,8 +273,15 @@ interface DataTableProps {
241
273
  * It is clipped rather than `display: none`, for the reason `srOnlyClasses`
242
274
  * gives: the second one takes it off the accessibility tree along with the
243
275
  * screen, which would leave the chart exactly as mute as before.
276
+ *
277
+ * Memoised, and it is the one component in this file that has to be. It is a
278
+ * row per category and a cell per series, and it is built in the same render
279
+ * body that holds the crosshair's state — so without this every cell of it is
280
+ * reconciled again for each pixel the pointer travels across the picture, on a
281
+ * table nobody is looking at. Every prop it takes is either a primitive or
282
+ * something already memoised above.
244
283
  */
245
- declare function ChartDataTable({ id, caption, corner, categories, series, values, format, locale }: DataTableProps): React.JSX.Element;
284
+ declare const ChartDataTable: React.MemoExoticComponent<({ id, caption, corner, categories, series, values, format, locale }: DataTableProps) => React.JSX.Element>;
246
285
  interface SurfaceProps extends Omit<BoxProps, 'children'> {
247
286
  legend: React.ReactNode;
248
287
  legendSide: NonNullable<NebaChartLegend['side']>;
@@ -359,8 +398,14 @@ interface CartesianProps extends CartesianChartProps {
359
398
  * @default 24
360
399
  */
361
400
  markRadius?: number;
362
- /** The table under the chart, for a chart whose data is not a grid. */
363
- table?: (id: string) => React.ReactNode;
401
+ /**
402
+ * The table under the chart, for a chart whose data is not a grid.
403
+ *
404
+ * It is handed the frame's own `format`, already stable across a render, so a
405
+ * table of its own is memoised on the same terms `ChartDataTable` is rather
406
+ * than building a formatter that a pointer moving over the picture rebuilds.
407
+ */
408
+ table?: (id: string, format: (value: number) => string) => React.ReactNode;
364
409
  /** The legend's swatch, for a chart whose marks are not all the same shape. */
365
410
  swatch?: (index: number, color: string) => React.ReactNode;
366
411
  /**
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import*as l from"react";import{Box as a}from"../components/box/Box.js";import{bandScale as i,categoryAt as r,categoryCount as s,categoryExtent as o,chartFontSizes as c,compactNumber as d,extentOf as u,fitsLast as h,formatCategory as m,markerRadii as f,plotHeights as x,seriesColor as g,showsTick as p,textWidth as b,tickStride as v,toValues as y,truncate as k,valueScale as w}from"./chart.js";import{numberFormatter as M}from"./format.js";import{observeResize as N}from"./observe.js";import{chartMessages as z,emptyMessages as S,useMessages as C}from"./i18n.js";import{cx as A,hasContent as P,metaTextClasses as j,srOnlyClasses as W,transitionClasses as B}from"./styles.js";const F="undefined"==typeof document?l.useEffect:l.useLayoutEffect,E=[];function I(e){const[t,n]=l.useState(0);return F(()=>{const t=e.current;if(!t)return;const l=()=>n(t.clientWidth);return l(),N(t,l)},[e]),t}function R(e){const[t,n]=l.useState(()=>{const t=new Set;return e.forEach((e,n)=>{e.hidden&&t.add(n)}),t}),[a,i]=l.useState(null),r=l.useCallback(e=>{n(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);return{visible:e.map((e,n)=>!t.has(n)),hovered:a,toggle:r,setHovered:i}}const H={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse",right:"flex-row"},$={start:"justify-start",center:"justify-center",end:"justify-end"};function _({series:l,colors:a,options:i,visibility:r,size:s,values:o,swatch:c}){const d=!1!==i.interactive,u="left"===i.side||"right"===i.side;return e("ul",{className:A("flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0",u?"min-w-0 flex-col items-start":"",$[i.align??"center"],j[s]),children:l.map((l,i)=>{const s=r.visible[i],u=null!==r.hovered&&r.hovered!==i,h=l.name??`${i+1}`,m=s?a[i]:"var(--neba-disabled-fg)",f=n(t,{children:[e("span",c?{"aria-hidden":"true",className:"flex size-2.5 shrink-0 items-center justify-center",children:c(i,m)}:{"aria-hidden":"true",className:"size-2.5 shrink-0 rounded-[0.1875rem]",style:{backgroundColor:m}}),e("span",{className:"min-w-0 truncate",children:h}),o?.[i]?e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:o[i]}):null]});return e("li",{className:"min-w-0",children:d?e("button",{type:"button","aria-pressed":s,onClick:()=>r.toggle(i),onPointerEnter:()=>r.setHovered(i),onPointerLeave:()=>r.setHovered(null),onFocus:()=>r.setHovered(i),onBlur:()=>r.setHovered(null),className:A("flex min-w-0 cursor-pointer items-center gap-1.5 rounded-(--neba-radius-xs)","px-1 py-0.5 text-(--neba-fg)",B,"hover:bg-(--n-soft)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1",s?"":"text-(--neba-disabled-fg)",u?"opacity-55":""),children:f}):e("span",{className:A("flex min-w-0 items-center gap-1.5 px-1 py-0.5 text-(--neba-fg)",s?"":"text-(--neba-disabled-fg)"),children:f})},l.name??i)})})}function T({steps:l,from:a,to:i,middle:r,align:s,vertical:o,size:c}){return e("div",{className:A("flex",o?"":$[s]),children:n("div",{className:A("grid grid-cols-[auto_auto_auto] items-center gap-x-2",j[c]),children:[e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:a}),e("span",{"aria-hidden":"true",className:A("flex h-2.5 overflow-hidden rounded-[0.1875rem]",o?"w-20":"w-24"),children:l.map(t=>e("span",{className:"h-full flex-1",style:{backgroundColor:t}},t))}),e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:i}),r?n(t,{children:[e("span",{}),e("span",{className:"text-center tabular-nums text-(--neba-muted-fg)",children:r}),e("span",{})]}):null]})})}function L({heading:t,items:l,x:a,y:i,flip:r,size:s}){return n("div",{"data-neba-tooltip":"",className:A("pointer-events-none absolute z-10 max-w-56 min-w-24","rounded-(--neba-radius-sm) border p-2","[background-image:var(--neba-grain),var(--neba-sheen)]","[background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]","bg-(--neba-panel-press) [border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-2),var(--neba-plate-glass)]",j[s]),style:r?{right:`calc(100% - ${a}px + 10px)`,top:i}:{left:a+10,top:i},children:[e("div",{className:"mb-1 font-medium text-(--neba-fg)",children:t}),e("ul",{className:"flex list-none flex-col gap-0.5 p-0",children:l.map(t=>n("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"size-2 shrink-0 rounded-[0.125rem]",style:{backgroundColor:t.color}}),t.name?e("span",{className:"min-w-0 flex-1 truncate text-(--neba-muted-fg)",children:t.name}):null,e("span",{className:"ms-auto shrink-0 font-medium tabular-nums text-(--neba-fg)",children:t.label??t.formatted})]},t.seriesIndex))})]})}function V({heading:a,items:i}){return e("span",{role:"status","aria-live":"polite",className:W,children:0===i.length?null:n(t,{children:[P(a)?n(t,{children:[a,", "]}):null,i.map((e,t)=>n(l.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex))]})})}function D({id:t,caption:l,corner:a,categories:i,series:r,values:s,format:o,locale:c}){return n("table",{id:t,className:W,children:[l?e("caption",{children:l}):null,e("thead",{children:n("tr",{children:[e("th",{scope:"col",children:a??""}),r.map((t,n)=>e("th",{scope:"col",children:t.name??n+1},t.name??n))]})}),e("tbody",{children:i.map((t,l)=>n("tr",{children:[e("th",{scope:"row",children:m(t,c)}),r.map((t,n)=>{const a=s[n]?.[l];return e("td",void 0!==a?.label?{children:a.label}:{children:null==a?.value?"":o(a.value)},t.name??n)})]},l))})]})}function X({legend:t,legendSide:l,children:i,table:r,className:s,...o}){return n(a,{...o,className:A("relative flex gap-3",H[l],s??void 0),children:[e("div",{className:"relative min-w-0 flex-1",children:i}),t,r]})}export function CartesianChart({series:t,categories:a,xAxis:h,yAxis:p,horizontal:v=!1,stacked:N=!1,includeZero:P=!0,bandRatio:W=1,inset:B=!1,headroom:F=0,markInset:H=0,xScale:$="band",marks:T,markRadius:Z=24,table:K,swatch:U,scale:q,markTooltip:G,height:J,format:O,locale:Q,label:ee,legend:te,tooltip:ne,empty:le,size:ae="md",variant:ie="text",padded:re=!1,className:se,children:oe,...ce}){const de=l.useRef(null),ue=I(de),he=C(S,Q),me=C(z,Q),fe=l.useId(),xe=R(t),[ge,pe]=l.useState(null),[be,ve]=l.useState(null),[ye,ke]=l.useState(null),we=l.useCallback(e=>O?M(Q,O).format(e):d(e,Q),[O,Q]),Me=l.useMemo(()=>y(t),[t]),Ne=l.useMemo(()=>t.map((e,t)=>g(e,t)),[t]),ze=s(t),Se=l.useMemo(()=>Array.from({length:ze},(e,t)=>r(t,a,Me)),[ze,a,Me]),Ce=Me.filter((e,t)=>xe.visible[t]),Ae=u(Ce,N),Pe="number"==typeof J?J:void 0===J?x[ae]:null,je=c[ae],We=p,Be=h,Fe=q??w(Ae,{min:We?.min,max:We?.max,tickCount:We?.tickCount,includeZero:P}),Ee="value"===$?o(Ce,a):null,Ie="value"===$?w(Ee,{min:Be?.min,max:Be?.max,tickCount:Be?.tickCount,includeZero:!1}):null,Re=Fe.ticks.map((e,t)=>We?.tickFormat?String(We.tickFormat(e,t)):we(e)),He=Ie?Ie.ticks.map((e,t)=>Be?.tickFormat?String(Be.tickFormat(e,t)):d(e,Q)):Se.map((e,t)=>Be?.tickFormat?String(Be.tickFormat(e,t)):m(e,Q)),$e=Re.reduce((e,t)=>Math.max(e,b(t,je)),0),_e=je+6,Te=We?.hidden?0:$e+10+(We?.label?_e:0),Le=(ue-(v?0:Te)-16)/Math.max(1,ze),Ve=Ie?He:v||Le-6>=2.4*je?He.map(e=>k(e,v?150:Le-6,je)):He,De=Ve.reduce((e,t)=>Math.max(e,b(t,je)),0),Xe=v?Be?.hidden?0:De+10+(Be?.label?_e:0):Te,Ye=v?We?.hidden?0:je+12+(We?.label?_e:0):Be?.hidden?0:je+12+(Be?.label?_e:0),Ze=(v?Be:We)?.thickness??Xe,Ke=(v?We:Be)?.thickness??Ye,Ue=(v||Ie?12:Math.max(8,Ve.length?De/2:8))+H,qe=f[ae]+4+F+H,Ge=Pe??0,Je={left:Ze+H,top:qe,width:Math.max(0,ue-Ze-H-Ue),height:Math.max(0,Ge-qe-Ke-H)},Oe=v?Je.height:Je.width,Qe=i(B?Math.max(1,ze-1):ze,Oe,W),et=l.useCallback(e=>B?ze<=1?Oe/2:Oe*e/(ze-1):Qe.centre(e),[B,ze,Oe,Qe]),tt=l.useCallback(e=>v?Je.left+Fe.fraction(e)*Je.width:Je.top+(1-Fe.fraction(e))*Je.height,[v,Je.left,Je.top,Je.width,Je.height,Fe]),nt=l.useCallback((e,t)=>v?{x:tt(t),y:Je.top+et(e)}:{x:Je.left+et(e),y:tt(t)},[v,tt,et,Je.left,Je.top]),lt=l.useCallback(e=>v?Je.top+(1-(Ie?.fraction(e)??0))*Je.height:Je.left+(Ie?.fraction(e)??0)*Je.width,[v,Je.left,Je.top,Je.width,Je.height,Ie]),at=tt(Math.min(Math.max(0,Fe.min),Fe.max)),it={plot:Je,values:Me,visible:xe.visible,colors:Ne,scale:Fe,band:Qe,horizontal:v,valuePx:tt,categoryPx:et,point:nt,categoryScale:Ie,categoryValuePx:lt,zeroPx:at,categories:Se,format:we,size:ae},rt=T?T(it):E,st=!1===ne?{mode:"none"}:!0===ne||void 0===ne?{}:ne,ot=st.mode??(T?"item":"index"),ct=null===be?null:rt[be]??null,dt=T?ct?ct.index:null:ge,ut=T?rt.length:ze,ht=()=>{pe(null),ve(null),ke(null)},mt=e=>{const t=null===e?null:Math.min(ut-1,Math.max(0,e));T?ve(t):pe(t)},ft=e=>{ke(null);mt(((T?be:ge)??(e>0?-1:ut))+e)},xt=null===dt?[]:t.flatMap((e,t)=>{if(!xe.visible[t]||ct&&ct.series!==t)return[];const n=Me[t]?.[dt];return n&&null!==n.value?[{seriesIndex:t,name:e.name,color:n.color??Ne[t],value:n.value,formatted:we(n.value),label:n.label}]:[]}),gt=ct&&G?G(ct):null,pt=gt?gt.items:"item"===ot&&xt.length>1&&null!==ye?[xt.reduce((e,t)=>Math.abs(tt(t.value??0)-ye)<Math.abs(tt(e.value??0)-ye)?t:e)]:xt,bt=ct?Me[ct.series]?.[ct.index]?.x??a?.[ct.index]??ct.index:void 0,vt=ct?ct.x:v?tt(pt[0]?.value??0):Je.left+et(dt??0),yt=ct?ct.y:v?Je.top+et(dt??0):Je.top,kt=ct?(ct.x-Je.left)/Math.max(1,Je.width)>.6:(v?Fe.fraction(pt[0]?.value??0):et(dt??0)/Math.max(1,Oe))>.6,wt=!1===te?{interactive:!1}:!0===te||void 0===te?{}:te,Mt=!0===te||!1!==te&&t.length>1,Nt=wt.side??"bottom",zt={...it,hovered:xe.hovered,activeIndex:dt,marks:rt,activeMark:ct},St=0===ze||null===Ae||"value"===$&&null===Ee;return n(X,{...ce,size:ae,variant:ie,padded:re,className:se,legendSide:Nt,legend:Mt?e(_,{series:t,colors:Ne,options:wt,visibility:xe,size:ae,swatch:U,values:wt.showValue&&null!==dt?t.map((e,t)=>{const n=Me[t]?.[dt]?.value;return null==n?void 0:we(n)}):void 0}):null,table:St?null:K?.(fe)??e(D,{id:fe,caption:ee,corner:Be?.label,categories:Se,series:t,values:Me,format:we,locale:Q}),children:[n("div",{ref:de,role:"img",tabIndex:St?void 0:0,"aria-label":ee??me.label,"aria-describedby":St?void 0:fe,onPointerMove:e=>{"none"!==ot&&(T?ve(((e,t)=>{const n=de.current;if(!n||0===rt.length)return null;const l=n.getBoundingClientRect(),a=e-l.left,i=t-l.top;let r=null,s=1/0,o=1/0;return rt.forEach((e,t)=>{const n=Math.hypot(e.x-a,e.y-i),l=void 0===e.rx?Math.max(0,n-e.r):Math.hypot(Math.max(0,Math.abs(e.x-a)-e.rx),Math.max(0,Math.abs(e.y-i)-(e.ry??e.rx)));l<=Z&&(l<s||l===s&&n<o)&&(s=l,o=n,r=t)}),r})(e.clientX,e.clientY)):pe(((e,t)=>{const n=de.current;if(!n||0===ze)return null;const l=n.getBoundingClientRect(),a=v?t-l.top-Je.top:e-l.left-Je.left;if(a<-Qe.step||a>Oe+Qe.step)return null;const i=B?ze<=1?0:Math.round(a/Oe*(ze-1)):Math.floor(a/Qe.step);return Math.min(ze-1,Math.max(0,i))})(e.clientX,e.clientY)),"item"===ot&&ke(((e,t)=>{const n=de.current;if(!n)return null;const l=n.getBoundingClientRect();return v?e-l.left:t-l.top})(e.clientX,e.clientY)))},onPointerLeave:ht,onKeyDown:"none"===ot?void 0:e=>{const t=v?"ArrowDown":"ArrowRight",n=v?"ArrowUp":"ArrowLeft";if(e.key===t)ft(1);else if(e.key===n)ft(-1);else if("Home"===e.key)mt(0);else if("End"===e.key)mt(ut-1);else{if("Escape"!==e.key)return;ht()}e.preventDefault()},onBlur:ht,className:A("relative w-full","rounded-(--neba-radius-xs)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"),style:{height:Pe??J},children:[St?e("div",{className:A("flex h-full items-center justify-center text-(--neba-muted-fg)",j[ae]),children:le??he.title}):ue>0?n("svg",{width:ue,height:Ge||"100%",viewBox:`0 0 ${ue} ${Ge}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(Y,{plot:Je,scale:Fe,band:Qe,horizontal:v,inset:B,categoryPx:et,valuePx:tt,tickTexts:Re,categoryTexts:Ve,categoryScale:Ie,categoryValuePx:lt,valueAxis:We,categoryAxis:Be,fontSize:je,zeroPx:at}),null===dt||T||"index"!==ot||!1===st.crosshair?null:(()=>{const t=et(dt);return e("line",v?{x1:Je.left,x2:Je.left+Je.width,y1:Je.top+t,y2:Je.top+t,stroke:"var(--neba-chart-baseline)",strokeWidth:1}:{x1:Je.left+t,x2:Je.left+t,y1:Je.top,y2:Je.top+Je.height,stroke:"var(--neba-chart-baseline)",strokeWidth:1})})(),oe(zt)]}):null,null!==dt&&pt.length>0&&"none"!==ot?st.render?e("div",{className:"pointer-events-none absolute z-10",style:kt?{right:`calc(100% - ${vt}px + 10px)`,top:yt}:{left:vt+10,top:yt},children:st.render({index:dt,category:bt??Se[dt],items:pt})}):e(L,{heading:gt?gt.heading:m(bt??Se[dt],Q),items:pt,x:vt,y:yt,flip:kt,size:ae}):null]}),"none"===ot?null:e(V,{heading:null===dt?void 0:gt?.heading??m(bt??Se[dt],Q),items:pt})]})}function Y({plot:l,scale:a,horizontal:i,categoryPx:r,valuePx:s,tickTexts:o,categoryTexts:c,categoryScale:d,categoryValuePx:u,valueAxis:m,categoryAxis:f,fontSize:x,zeroPx:g}){const y=!1!==m?.grid&&!m?.hidden,k=!f?.hidden&&(f?.grid??null!==d),w=e=>d?u(d.ticks[e]):(i?l.top:l.left)+r(e),M=v(c.length,i?l.height:l.width,i?1.8*x:Math.max(...c.map(e=>b(e,x)),1)+12),N=v(a.ticks.length,i?l.width:l.height,i?Math.max(...o.map(e=>b(e,x)),1)+16:2*x),z=c.length>1?Math.abs(w(1)-w(0)):l.width,S=a.ticks.length>1?Math.abs(s(a.ticks[1])-s(a.ticks[0])):l.height,C=h(c.length,M,z,i?1.8*x:b(c[c.length-1]??"",x)),A=h(a.ticks.length,N,S,i?b(o[o.length-1]??"",x):1.6*x);return n("g",{children:[a.ticks.map((t,r)=>{const c=s(t),d=Math.abs(t)<1e-9;return n("g",{children:[y?e("line",i?{x1:c,x2:c,y1:l.top,y2:l.top+l.height,stroke:d?"var(--neba-chart-baseline)":"var(--neba-chart-grid)",strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:c,y2:c,stroke:d?"var(--neba-chart-baseline)":"var(--neba-chart-grid)",strokeWidth:1}):null,m?.hidden||!p(r,a.ticks.length,N,A)?null:e("text",i?{x:c,y:l.top+l.height+x+6,textAnchor:0===r?"start":r===a.ticks.length-1?"end":"middle",fontSize:x,fill:"var(--neba-muted-fg)",className:"tabular-nums",children:o[r]}:{x:l.left-8,y:c,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--neba-muted-fg)",className:"tabular-nums",children:o[r]})]},t)}),f?.hidden?null:n(t,{children:[e("line",i?{x1:g,x2:g,y1:l.top,y2:l.top+l.height,stroke:"var(--neba-chart-axis)",strokeWidth:1}:{x1:l.left,x2:l.left+l.width,y1:g,y2:g,stroke:"var(--neba-chart-axis)",strokeWidth:1}),c.map((t,a)=>{const r=w(a),s=p(a,c.length,M,C);return i?s?e("text",{x:l.left-8,y:r,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--neba-muted-fg)",className:d?"tabular-nums":void 0,children:t},a):null:n("g",{children:[k?e("line",{x1:r,x2:r,y1:l.top,y2:l.top+l.height,stroke:"var(--neba-chart-grid)",strokeWidth:1}):null,s?e("text",{x:r,y:l.top+l.height+x+6,textAnchor:d?0===a?"start":a===c.length-1?"end":"middle":"middle",fontSize:x,fill:"var(--neba-muted-fg)",className:d?"tabular-nums":void 0,children:t}):null]},a)})]}),m?.label?e("text",{x:i?l.left+l.width:l.left,y:i?l.top+l.height+2*x+12:l.top-8,textAnchor:i?"end":"start",fontSize:x,fill:"var(--neba-muted-fg)",fontWeight:500,children:m.label}):null,f?.label&&!i?e("text",{x:l.left+l.width,y:l.top+l.height+2*x+12,textAnchor:"end",fontSize:x,fill:"var(--neba-muted-fg)",fontWeight:500,children:f.label}):null]})}export{D as ChartDataTable,_ as ChartLegendBar,T as ChartScaleLegend,V as ChartStatus,X as ChartSurface,L as ChartTooltipPanel,I as useMeasuredWidth,R as useVisibility};
1
+ "use client";import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import*as a from"react";import{Box as l}from"../components/box/Box.js";import{bandScale as i,categoryAt as r,categoryCount as s,categoryExtent as o,chartFontSizes as c,compactNumber as d,extentOf as u,fitsLast as h,formatCategory as m,markerRadii as f,plotHeights as x,seriesColor as g,showsTick as p,textWidth as b,tickStride as v,toValues as y,truncate as k,valueScale as w}from"./chart.js";import{numberFormatter as N}from"./format.js";import{observeResize as M}from"./observe.js";import{chartMessages as z,emptyMessages as S,useMessages as C}from"./i18n.js";import{cx as A,hasContent as P,metaTextClasses as j,srOnlyClasses as _,transitionClasses as W}from"./styles.js";const B="undefined"==typeof document?a.useEffect:a.useLayoutEffect,F=[];function E(e){const[t,n]=a.useState(0);return B(()=>{const t=e.current;if(!t)return;const a=()=>n(t.clientWidth);return a(),M(t,a)},[e]),t}export const markTransitionClasses=["[transition:opacity_var(--neba-duration)_var(--neba-ease),","r_var(--neba-duration)_var(--neba-ease),","scale_var(--neba-duration)_var(--neba-ease)]"].join("");function I(e){const[t,n]=a.useState(()=>{const t=new Set;return e.forEach((e,n)=>{e.hidden&&t.add(n)}),t}),[l,i]=a.useState(null),r=a.useCallback(e=>{n(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);return{visible:e.map((e,n)=>!t.has(n)),hovered:l,toggle:r,setHovered:i}}const R={top:"flex-col-reverse",bottom:"flex-col",left:"flex-row-reverse",right:"flex-row"},$={start:"justify-start",center:"justify-center",end:"justify-end"};function H({series:a,colors:l,options:i,visibility:r,size:s,values:o,swatch:c}){const d=!1!==i.interactive,u="left"===i.side||"right"===i.side;return e("ul",{className:A("flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0",u?"min-w-0 flex-col items-start":"",$[i.align??"center"],j[s]),children:a.map((a,i)=>{const s=r.visible[i],u=null!==r.hovered&&r.hovered!==i,h=a.name??`${i+1}`,m=s?l[i]:"var(--neba-disabled-fg)",f=n(t,{children:[e("span",c?{"aria-hidden":"true",className:"flex size-2.5 shrink-0 items-center justify-center",children:c(i,m)}:{"aria-hidden":"true",className:`size-2.5 shrink-0 rounded-[0.1875rem] ${W}`,style:{backgroundColor:m}}),e("span",{className:"min-w-0 truncate",children:h}),o?.[i]?e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:o[i]}):null]});return e("li",{className:"min-w-0",children:d?e("button",{type:"button","aria-pressed":s,onClick:()=>r.toggle(i),onPointerEnter:()=>r.setHovered(i),onPointerLeave:()=>r.setHovered(null),onFocus:()=>r.setHovered(i),onBlur:()=>r.setHovered(null),className:A("flex min-w-0 cursor-pointer items-center gap-1.5 rounded-(--neba-radius-xs)","px-1 py-0.5 text-(--neba-fg)","[transition-property:background-color,color,opacity]","[transition-duration:var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]","hover:bg-(--n-soft)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1",s?"":"text-(--neba-disabled-fg)",u?"opacity-55":""),children:f}):e("span",{className:A("flex min-w-0 items-center gap-1.5 px-1 py-0.5 text-(--neba-fg)",s?"":"text-(--neba-disabled-fg)"),children:f})},a.name??i)})})}function T({steps:a,from:l,to:i,middle:r,align:s,vertical:o,size:c}){return e("div",{className:A("flex",o?"":$[s]),children:n("div",{className:A("grid grid-cols-[auto_auto_auto] items-center gap-x-2",j[c]),children:[e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:l}),e("span",{"aria-hidden":"true",className:A("flex h-2.5 overflow-hidden rounded-[0.1875rem]",o?"w-20":"w-24"),children:a.map(t=>e("span",{className:"h-full flex-1",style:{backgroundColor:t}},t))}),e("span",{className:"shrink-0 tabular-nums text-(--neba-muted-fg)",children:i}),r?n(t,{children:[e("span",{}),e("span",{className:"text-center tabular-nums text-(--neba-muted-fg)",children:r}),e("span",{})]}):null]})})}function L({heading:t,items:a,x:l,y:i,flip:r,size:s}){return n("div",{"data-neba-tooltip":"",className:A("pointer-events-none absolute z-10 max-w-56 min-w-24","rounded-(--neba-radius-sm) border p-2","[background-image:var(--neba-grain),var(--neba-sheen)]","[background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]","bg-(--neba-panel-press) [border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-2),var(--neba-plate-glass)]",j[s]),style:r?{right:`calc(100% - ${l}px + 10px)`,top:i}:{left:l+10,top:i},children:[e("div",{className:"mb-1 font-medium text-(--neba-fg)",children:t}),e("ul",{className:"flex list-none flex-col gap-0.5 p-0",children:a.map(t=>n("li",{className:"flex items-center gap-1.5",children:[e("span",{"aria-hidden":"true",className:"size-2 shrink-0 rounded-[0.125rem]",style:{backgroundColor:t.color}}),t.name?e("span",{className:"min-w-0 flex-1 truncate text-(--neba-muted-fg)",children:t.name}):null,e("span",{className:"ms-auto shrink-0 font-medium tabular-nums text-(--neba-fg)",children:t.label??t.formatted})]},t.seriesIndex))})]})}function V({heading:l,items:i}){return e("span",{role:"status","aria-live":"polite",className:_,children:0===i.length?null:n(t,{children:[P(l)?n(t,{children:[l,", "]}):null,i.map((e,t)=>n(a.Fragment,{children:[t>0?", ":null,e.name?`${e.name}: `:null,e.label??e.formatted]},e.seriesIndex))]})})}const D=/*@__PURE__*/a.memo(function({id:t,caption:a,corner:l,categories:i,series:r,values:s,format:o,locale:c}){return n("table",{id:t,className:_,children:[a?e("caption",{children:a}):null,e("thead",{children:n("tr",{children:[e("th",{scope:"col",children:l??""}),r.map((t,n)=>e("th",{scope:"col",children:t.name??n+1},t.name??n))]})}),e("tbody",{children:i.map((t,a)=>n("tr",{children:[e("th",{scope:"row",children:m(t,c)}),r.map((t,n)=>{const l=s[n]?.[a];return e("td",void 0!==l?.label?{children:l.label}:{children:null==l?.value?"":o(l.value)},t.name??n)})]},a))})]})});function X({legend:t,legendSide:a,children:i,table:r,className:s,...o}){return n(l,{...o,className:A("relative flex gap-3",R[a],s??void 0),children:[e("div",{className:"relative min-w-0 flex-1",children:i}),t,r]})}export function CartesianChart({series:t,categories:l,xAxis:h,yAxis:p,horizontal:v=!1,stacked:M=!1,includeZero:P=!0,bandRatio:_=1,inset:W=!1,headroom:B=0,markInset:R=0,xScale:$="band",marks:T,markRadius:Z=24,table:q,swatch:J,scale:K,markTooltip:O,height:U,format:G,locale:Q,label:ee,legend:te,tooltip:ne,empty:ae,size:le="md",variant:ie="text",padded:re=!1,className:se,children:oe,...ce}){const de=a.useRef(null),ue=E(de),he=C(S,Q),me=C(z,Q),fe=a.useId(),xe=I(t),[ge,pe]=a.useState(null),[be,ve]=a.useState(null),[ye,ke]=a.useState(null),we=G?JSON.stringify(G):"",Ne=a.useCallback(e=>G?N(Q,G).format(e):d(e,Q),[we,Q]),Me=a.useMemo(()=>y(t),[t]),ze=a.useMemo(()=>t.map((e,t)=>g(e,t)),[t]),Se=s(t),Ce=a.useMemo(()=>Array.from({length:Se},(e,t)=>r(t,l,Me)),[Se,l,Me]),Ae=Me.filter((e,t)=>xe.visible[t]),Pe=u(Ae,M),je="number"==typeof U?U:void 0===U?x[le]:null,_e=c[le],We=p,Be=h,Fe=K??w(Pe,{min:We?.min,max:We?.max,tickCount:We?.tickCount,includeZero:P}),Ee="value"===$?o(Ae,l):null,Ie="value"===$?w(Ee,{min:Be?.min,max:Be?.max,tickCount:Be?.tickCount,includeZero:!1}):null,Re=Fe.ticks.map((e,t)=>We?.tickFormat?String(We.tickFormat(e,t)):Ne(e)),$e=Ie?Ie.ticks.map((e,t)=>Be?.tickFormat?String(Be.tickFormat(e,t)):d(e,Q)):Ce.map((e,t)=>Be?.tickFormat?String(Be.tickFormat(e,t)):m(e,Q)),He=Re.reduce((e,t)=>Math.max(e,b(t,_e)),0),Te=_e+6,Le=We?.hidden?0:He+10+(We?.label?Te:0),Ve=(ue-(v?0:Le)-16)/Math.max(1,Se),De=Ie?$e:v||Ve-6>=2.4*_e?$e.map(e=>k(e,v?150:Ve-6,_e)):$e,Xe=De.reduce((e,t)=>Math.max(e,b(t,_e)),0),Ye=v?Be?.hidden?0:Xe+10+(Be?.label?Te:0):Le,Ze=v?We?.hidden?0:_e+12+(We?.label?Te:0):Be?.hidden?0:_e+12+(Be?.label?Te:0),qe=(v?Be:We)?.thickness??Ye,Je=(v?We:Be)?.thickness??Ze,Ke=(v||Ie?12:Math.max(8,De.length?Xe/2:8))+R,Oe=f[le]+4+B+R,Ue=je??0,Ge={left:qe+R,top:Oe,width:Math.max(0,ue-qe-R-Ke),height:Math.max(0,Ue-Oe-Je-R)},Qe=v?Ge.height:Ge.width,et=i(W?Math.max(1,Se-1):Se,Qe,_),tt=a.useCallback(e=>W?Se<=1?Qe/2:Qe*e/(Se-1):et.centre(e),[W,Se,Qe,et]),nt=a.useCallback(e=>v?Ge.left+Fe.fraction(e)*Ge.width:Ge.top+(1-Fe.fraction(e))*Ge.height,[v,Ge.left,Ge.top,Ge.width,Ge.height,Fe]),at=a.useCallback((e,t)=>v?{x:nt(t),y:Ge.top+tt(e)}:{x:Ge.left+tt(e),y:nt(t)},[v,nt,tt,Ge.left,Ge.top]),lt=a.useCallback(e=>v?Ge.top+(1-(Ie?.fraction(e)??0))*Ge.height:Ge.left+(Ie?.fraction(e)??0)*Ge.width,[v,Ge.left,Ge.top,Ge.width,Ge.height,Ie]),it=nt(Math.min(Math.max(0,Fe.min),Fe.max)),rt={plot:Ge,values:Me,visible:xe.visible,colors:ze,scale:Fe,band:et,horizontal:v,valuePx:nt,categoryPx:tt,point:at,categoryScale:Ie,categoryValuePx:lt,zeroPx:it,categories:Ce,format:Ne,size:le},st=T?T(rt):F,ot=!1===ne?{mode:"none"}:!0===ne||void 0===ne?{}:ne,ct=ot.mode??(T?"item":"index"),dt=null===be?null:st[be]??null,ut=T?dt?dt.index:null:ge,ht=T?st.length:Se,mt=()=>{pe(null),ve(null),ke(null)},ft=e=>{const t=null===e?null:Math.min(ht-1,Math.max(0,e));T?ve(t):pe(t)},xt=e=>{ke(null);ft(((T?be:ge)??(e>0?-1:ht))+e)},gt=null===ut?[]:t.flatMap((e,t)=>{if(!xe.visible[t]||dt&&dt.series!==t)return[];const n=Me[t]?.[ut];return n&&null!==n.value?[{seriesIndex:t,name:e.name,color:n.color??ze[t],value:n.value,formatted:Ne(n.value),label:n.label}]:[]}),pt=dt&&O?O(dt):null,bt=pt?pt.items:"item"===ct&&gt.length>1&&null!==ye?[gt.reduce((e,t)=>Math.abs(nt(t.value??0)-ye)<Math.abs(nt(e.value??0)-ye)?t:e)]:gt,vt=dt?Me[dt.series]?.[dt.index]?.x??l?.[dt.index]??dt.index:void 0,yt=dt?dt.x:v?nt(bt[0]?.value??0):Ge.left+tt(ut??0),kt=dt?dt.y:v?Ge.top+tt(ut??0):Ge.top,wt=dt?(dt.x-Ge.left)/Math.max(1,Ge.width)>.6:(v?Fe.fraction(bt[0]?.value??0):tt(ut??0)/Math.max(1,Qe))>.6,Nt=!1===te?{interactive:!1}:!0===te||void 0===te?{}:te,Mt=!0===te||!1!==te&&t.length>1,zt=Nt.side??"bottom",St={...rt,hovered:xe.hovered,activeIndex:ut,marks:st,activeMark:dt},Ct=0===Se||null===Pe||"value"===$&&null===Ee;return n(X,{...ce,size:le,variant:ie,padded:re,className:se,legendSide:zt,legend:Mt?e(H,{series:t,colors:ze,options:Nt,visibility:xe,size:le,swatch:J,values:Nt.showValue&&null!==ut?t.map((e,t)=>{const n=Me[t]?.[ut]?.value;return null==n?void 0:Ne(n)}):void 0}):null,table:Ct?null:q?.(fe,Ne)??e(D,{id:fe,caption:ee,corner:Be?.label,categories:Ce,series:t,values:Me,format:Ne,locale:Q}),children:[n("div",{ref:de,role:"img",tabIndex:Ct?void 0:0,"aria-label":ee??me.label,"aria-describedby":Ct?void 0:fe,onPointerMove:e=>{"none"!==ct&&(T?ve(((e,t)=>{const n=de.current;if(!n||0===st.length)return null;const a=n.getBoundingClientRect(),l=e-a.left,i=t-a.top;let r=null,s=1/0,o=1/0;return st.forEach((e,t)=>{const n=e.x-l,a=e.y-i,c=Math.sqrt(n*n+a*a);let d;if(void 0===e.rx)d=Math.max(0,c-e.r);else{const t=Math.max(0,Math.abs(n)-e.rx),l=Math.max(0,Math.abs(a)-(e.ry??e.rx));d=Math.sqrt(t*t+l*l)}d<=Z&&(d<s||d===s&&c<o)&&(s=d,o=c,r=t)}),r})(e.clientX,e.clientY)):pe(((e,t)=>{const n=de.current;if(!n||0===Se)return null;const a=n.getBoundingClientRect(),l=v?t-a.top-Ge.top:e-a.left-Ge.left;if(l<-et.step||l>Qe+et.step)return null;const i=W?Se<=1?0:Math.round(l/Qe*(Se-1)):Math.floor(l/et.step);return Math.min(Se-1,Math.max(0,i))})(e.clientX,e.clientY)),"item"===ct&&ke(((e,t)=>{const n=de.current;if(!n)return null;const a=n.getBoundingClientRect();return v?e-a.left:t-a.top})(e.clientX,e.clientY)))},onPointerLeave:mt,onKeyDown:"none"===ct?void 0:e=>{const t=v?"ArrowDown":"ArrowRight",n=v?"ArrowUp":"ArrowLeft";if(e.key===t)xt(1);else if(e.key===n)xt(-1);else if("Home"===e.key)ft(0);else if("End"===e.key)ft(ht-1);else{if("Escape"!==e.key)return;mt()}e.preventDefault()},onBlur:mt,className:A("relative w-full","rounded-(--neba-radius-xs)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"),style:{height:je??U},children:[Ct?e("div",{className:A("flex h-full items-center justify-center text-(--neba-muted-fg)",j[le]),children:ae??he.title}):ue>0?n("svg",{width:ue,height:Ue||"100%",viewBox:`0 0 ${ue} ${Ue}`,"aria-hidden":"true",className:"block overflow-visible",children:[e(Y,{plot:Ge,scale:Fe,band:et,horizontal:v,inset:W,categoryPx:tt,valuePx:nt,tickTexts:Re,categoryTexts:De,categoryScale:Ie,categoryValuePx:lt,valueAxis:We,categoryAxis:Be,fontSize:_e,zeroPx:it}),null===ut||T||"index"!==ct||!1===ot.crosshair?null:(()=>{const t=tt(ut);return e("line",v?{x1:Ge.left,x2:Ge.left+Ge.width,y1:Ge.top+t,y2:Ge.top+t,stroke:"var(--neba-chart-baseline)",strokeWidth:1}:{x1:Ge.left+t,x2:Ge.left+t,y1:Ge.top,y2:Ge.top+Ge.height,stroke:"var(--neba-chart-baseline)",strokeWidth:1})})(),oe(St)]}):null,null!==ut&&bt.length>0&&"none"!==ct?ot.render?e("div",{className:"pointer-events-none absolute z-10",style:wt?{right:`calc(100% - ${yt}px + 10px)`,top:kt}:{left:yt+10,top:kt},children:ot.render({index:ut,category:vt??Ce[ut],items:bt})}):e(L,{heading:pt?pt.heading:m(vt??Ce[ut],Q),items:bt,x:yt,y:kt,flip:wt,size:le}):null]}),"none"===ct?null:e(V,{heading:null===ut?void 0:pt?.heading??m(vt??Ce[ut],Q),items:bt})]})}function Y({plot:a,scale:l,horizontal:i,categoryPx:r,valuePx:s,tickTexts:o,categoryTexts:c,categoryScale:d,categoryValuePx:u,valueAxis:m,categoryAxis:f,fontSize:x,zeroPx:g}){const y=!1!==m?.grid&&!m?.hidden,k=!f?.hidden&&(f?.grid??null!==d),w=e=>d?u(d.ticks[e]):(i?a.top:a.left)+r(e),N=v(c.length,i?a.height:a.width,i?1.8*x:Math.max(...c.map(e=>b(e,x)),1)+12),M=v(l.ticks.length,i?a.width:a.height,i?Math.max(...o.map(e=>b(e,x)),1)+16:2*x),z=c.length>1?Math.abs(w(1)-w(0)):a.width,S=l.ticks.length>1?Math.abs(s(l.ticks[1])-s(l.ticks[0])):a.height,C=h(c.length,N,z,i?1.8*x:b(c[c.length-1]??"",x)),A=h(l.ticks.length,M,S,i?b(o[o.length-1]??"",x):1.6*x);return n("g",{children:[l.ticks.map((t,r)=>{const c=s(t),d=Math.abs(t)<1e-9;return n("g",{children:[y?e("line",i?{x1:c,x2:c,y1:a.top,y2:a.top+a.height,stroke:d?"var(--neba-chart-baseline)":"var(--neba-chart-grid)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:c,y2:c,stroke:d?"var(--neba-chart-baseline)":"var(--neba-chart-grid)",strokeWidth:1}):null,m?.hidden||!p(r,l.ticks.length,M,A)?null:e("text",i?{x:c,y:a.top+a.height+x+6,textAnchor:0===r?"start":r===l.ticks.length-1?"end":"middle",fontSize:x,fill:"var(--neba-muted-fg)",className:"tabular-nums",children:o[r]}:{x:a.left-8,y:c,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--neba-muted-fg)",className:"tabular-nums",children:o[r]})]},t)}),f?.hidden?null:n(t,{children:[e("line",i?{x1:g,x2:g,y1:a.top,y2:a.top+a.height,stroke:"var(--neba-chart-axis)",strokeWidth:1}:{x1:a.left,x2:a.left+a.width,y1:g,y2:g,stroke:"var(--neba-chart-axis)",strokeWidth:1}),c.map((t,l)=>{const r=w(l),s=p(l,c.length,N,C);return i?s?e("text",{x:a.left-8,y:r,textAnchor:"end",dominantBaseline:"central",fontSize:x,fill:"var(--neba-muted-fg)",className:d?"tabular-nums":void 0,children:t},l):null:n("g",{children:[k?e("line",{x1:r,x2:r,y1:a.top,y2:a.top+a.height,stroke:"var(--neba-chart-grid)",strokeWidth:1}):null,s?e("text",{x:r,y:a.top+a.height+x+6,textAnchor:d?0===l?"start":l===c.length-1?"end":"middle":"middle",fontSize:x,fill:"var(--neba-muted-fg)",className:d?"tabular-nums":void 0,children:t}):null]},l)})]}),m?.label?e("text",{x:i?a.left+a.width:a.left,y:i?a.top+a.height+2*x+12:a.top-8,textAnchor:i?"end":"start",fontSize:x,fill:"var(--neba-muted-fg)",fontWeight:500,children:m.label}):null,f?.label&&!i?e("text",{x:a.left+a.width,y:a.top+a.height+2*x+12,textAnchor:"end",fontSize:x,fill:"var(--neba-muted-fg)",fontWeight:500,children:f.label}):null]})}export{D as ChartDataTable,H as ChartLegendBar,T as ChartScaleLegend,V as ChartStatus,X as ChartSurface,L as ChartTooltipPanel,E as useMeasuredWidth,I as useVisibility};
@@ -1 +1 @@
1
- import{jsx as l,jsxs as e}from"react/jsx-runtime";import{areaPath as t,chartFontSizes as r,linePath as n,lineWidths as o,markerRadii as a,markGap as i}from"./chart.js";export function LineSeries({context:s,curve:u,filled:f,stacked:c,markers:p,valueLabels:d,connectNulls:x,gradient:h,idPrefix:m}){const{values:v,visible:k,colors:$,hovered:b,activeIndex:y,plot:g,point:j,zeroPx:C,size:L,format:W}=s,z=o[L],B=a[L],E=k.indexOf(!0),G=[],M=[];return v.forEach((l,e)=>{const t=l.map((l,e)=>M[e]??0);G.push(t),c&&k[e]&&l.forEach((l,e)=>{M[e]=(M[e]??0)+(l.value??0)})}),e("g",{children:[e("defs",{children:[h?$.map((t,r)=>e("linearGradient",{id:`${m}-stroke-${r}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${t} 45%, transparent)`}),l("stop",{offset:"100%",stopColor:t})]},`stroke-${r}`)):null,f&&!c?$.map((t,r)=>e("linearGradient",{id:`${m}-fill-${r}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${t} 28%, transparent)`}),l("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${t} 2%, transparent)`})]},`fill-${r}`)):null]}),v.map((o,a)=>{if(!k[a])return null;const s=$[a],v=null!==b&&b!==a,M=o.map((l,e)=>{if(null===l.value)return null;const t=c?G[a][e]+l.value:l.value;return j(e,t)}),N=x?M.filter(Boolean):M,P=o.map((l,e)=>null===l.value?null:c?j(e,G[a][e]):{x:j(e,l.value).x,y:C}),S=f&&c,w=function(l,e){if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let t=l.length-1;t>=0;t--)if(null!==l[t].value){e=t;break}return l=>l===e}let t=1/0,r=-1/0;for(const e of l)null!==e.value&&(t=Math.min(t,e.value),r=Math.max(r,e.value));return e=>{const n=l[e].value;return null!==n&&(n===t||n===r)}}(o,d);return e("g",{opacity:v?.28:1,children:[f?l("path",{d:t(N,x?P.filter(Boolean):P,u),fill:c?`color-mix(in oklab, ${s} 70%, transparent)`:`url(#${m}-fill-${a})`,stroke:"none"}):null,S&&a!==E?l("path",{d:n(x?P.filter(Boolean):P,u),fill:"none",stroke:"var(--neba-chart-gap)",strokeWidth:i}):null,S?null:l("path",{d:n(N,u),fill:"none",stroke:h?`url(#${m}-stroke-${a})`:s,strokeWidth:z,strokeLinecap:"round",strokeLinejoin:"round"}),M.map((e,t)=>{if(!e)return null;return"all"===p||"auto"===p&&o.length<=14||t===y?l("circle",{cx:e.x,cy:e.y,r:t===y?B+1:B,fill:o[t].color??s,stroke:"var(--neba-chart-gap)",strokeWidth:i},t):null}),"none"===d?null:M.map((e,t)=>{const n=o[t].value;return e&&null!==n&&w(t)?l("text",{x:e.x,y:e.y-B-5,textAnchor:e.x>g.left+g.width-24?"end":e.x<g.left+24?"start":"middle",fontSize:r[L],fontWeight:500,fill:"var(--neba-fg)",className:"tabular-nums",children:o[t].label??W(n)},`label-${t}`):null})]},a)})]})}
1
+ import{jsx as l,jsxs as e}from"react/jsx-runtime";import{areaPath as r,chartFontSizes as t,linePath as n,lineWidths as o,markerRadii as a,markGap as i}from"./chart.js";import{markTransitionClasses as s}from"./chart-frame.js";export function LineSeries({context:u,curve:f,filled:c,stacked:p,markers:d,valueLabels:m,connectNulls:x,gradient:h,idPrefix:v}){const{values:k,visible:$,colors:b,hovered:y,activeIndex:g,plot:j,point:C,zeroPx:L,size:N,format:W}=u,z=o[N],B=a[N],E=$.indexOf(!0),G=[],M=[];return k.forEach((l,e)=>{const r=l.map((l,e)=>M[e]??0);G.push(r),p&&$[e]&&l.forEach((l,e)=>{M[e]=(M[e]??0)+(l.value??0)})}),e("g",{children:[e("defs",{children:[h?b.map((r,t)=>e("linearGradient",{id:`${v}-stroke-${t}`,x1:"0",y1:"0",x2:"1",y2:"0",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 45%, transparent)`}),l("stop",{offset:"100%",stopColor:r})]},`stroke-${t}`)):null,c&&!p?b.map((r,t)=>e("linearGradient",{id:`${v}-fill-${t}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[l("stop",{offset:"0%",stopColor:`color-mix(in oklab, ${r} 28%, transparent)`}),l("stop",{offset:"100%",stopColor:`color-mix(in oklab, ${r} 2%, transparent)`})]},`fill-${t}`)):null]}),k.map((o,a)=>{if(!$[a])return null;const u=b[a],k=null!==y&&y!==a,M=o.map((l,e)=>{if(null===l.value)return null;const r=p?G[a][e]+l.value:l.value;return C(e,r)}),P=x?M.filter(Boolean):M,S=o.map((l,e)=>null===l.value?null:p?C(e,G[a][e]):{x:C(e,l.value).x,y:L}),w=c&&p,A=function(l,e){if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let r=l.length-1;r>=0;r--)if(null!==l[r].value){e=r;break}return l=>l===e}let r=1/0,t=-1/0;for(const e of l)null!==e.value&&(r=Math.min(r,e.value),t=Math.max(t,e.value));return e=>{const n=l[e].value;return null!==n&&(n===r||n===t)}}(o,m);return e("g",{opacity:k?.28:1,className:s,children:[c?l("path",{d:r(P,x?S.filter(Boolean):S,f),fill:p?`color-mix(in oklab, ${u} 70%, transparent)`:`url(#${v}-fill-${a})`,stroke:"none"}):null,w&&a!==E?l("path",{d:n(x?S.filter(Boolean):S,f),fill:"none",stroke:"var(--neba-chart-gap)",strokeWidth:i}):null,w?null:l("path",{d:n(P,f),fill:"none",stroke:h?`url(#${v}-stroke-${a})`:u,strokeWidth:z,strokeLinecap:"round",strokeLinejoin:"round"}),M.map((e,r)=>{if(!e)return null;return"all"===d||"auto"===d&&o.length<=14||r===g?l("circle",{cx:e.x,cy:e.y,r:r===g?B+1:B,fill:o[r].color??u,stroke:"var(--neba-chart-gap)",strokeWidth:i,className:s},r):null}),"none"===m?null:M.map((e,r)=>{const n=o[r].value;return e&&null!==n&&A(r)?l("text",{x:e.x,y:e.y-B-5,textAnchor:e.x>j.left+j.width-24?"end":e.x<j.left+24?"start":"middle",fontSize:t[N],fontWeight:500,fill:"var(--neba-fg)",className:"tabular-nums",children:o[r].label??W(n)},`label-${r}`):null})]},a)})]})}
@@ -384,6 +384,22 @@ export declare const markShapes: readonly MarkShape[];
384
384
  * the hover treatment are then unarguably the same on all five.
385
385
  */
386
386
  export declare function markPath(shape: MarkShape, cx: number, cy: number, r: number): string;
387
+ /**
388
+ * The centre line of that slice, as an *open* path.
389
+ *
390
+ * `arcPath` below draws the slice itself, which is a closed shape — and a shape
391
+ * whose `d` has to be rewritten every time the value moves. `d` is not a
392
+ * property CSS can travel along, so a dial drawn that way jumps to each new
393
+ * reading. Stroked instead, the same ring is one line with a width, and how much
394
+ * of it is drawn is `stroke-dashoffset`, which is a number and does travel.
395
+ *
396
+ * It is what ProgressCircular already does, bent to an arbitrary span — which is
397
+ * the point: a gauge is a Meter bent into an arc, and the four indicators in
398
+ * this library have to agree about what a value changing looks like.
399
+ *
400
+ * Angles are degrees clockwise from twelve o'clock, as below.
401
+ */
402
+ export declare function ringPath(cx: number, cy: number, radius: number, from: number, to: number): string;
387
403
  /**
388
404
  * A slice of a ring, as a path.
389
405
  *
@@ -1 +1 @@
1
- import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--neba-chart-1)","var(--neba-chart-2)","var(--neba-chart-3)","var(--neba-chart-4)","var(--neba-chart-5)","var(--neba-chart-6)","var(--neba-chart-7)","var(--neba-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--neba-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function r(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:o=!0}=e;let a=e.min??(t?t.min:0),i=e.max??(t?t.max:1);if(o&&void 0===e.min&&(a=Math.min(a,0)),o&&void 0===e.max&&(i=Math.max(i,0)),i===a){const t=Math.abs(i)>0?.5*Math.abs(i):1;a-=t,i+=t}const u=void 0!==e.min&&void 0!==e.max?function(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let o=r(t/Math.max(1,e)),a=1/0;for(const r of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*r*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<a&&(a=l,o=u)}return o}(i-a,n):r((i-a)/Math.max(1,n)),s=void 0!==e.min?a:Math.floor(a/u)*u,c=void 0!==e.max?i:Math.ceil(i/u)*u,l=c-s||1,h=[];for(let t=s;t<=c+1e-9*u;t+=u)h.push(Number(t.toFixed(12)));return{min:s,max:c,ticks:h,fraction:t=>(t-s)/l}}const o=1e3,a=6e4,i=36e5,u=24*i,s=[{unit:"second",count:1,size:o},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:a},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:i},{unit:"hour",count:3,size:3*i},{unit:"hour",count:6,size:6*i},{unit:"hour",count:12,size:12*i},{unit:"day",count:1,size:u},{unit:"day",count:2,size:2*u},{unit:"week",count:1,size:7*u},{unit:"week",count:2,size:14*u},{unit:"month",count:1,size:30*u},{unit:"quarter",count:1,size:91*u},{unit:"month",count:6,size:182*u},{unit:"year",count:1,size:365*u}];function c(t,e,n){const r=new Date(t);if("year"===e)r.setFullYear(r.getFullYear()+n);else if("quarter"===e)r.setMonth(r.getMonth()+3*n);else if("month"===e)r.setMonth(r.getMonth()+n);else if("week"===e)r.setDate(r.getDate()+7*n);else if("day"===e)r.setDate(r.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?a:o);r.setHours(r.getHours()+n)}return r.getTime()}const l={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};function h(t,e,n){let r=function(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/a)*a:Math.floor(t/o)*o}(t,l[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=c(r,e,n);if(o>t)return r;r=o}return r}export function timeScale(t,e={}){const{tickCount:n=6}=e;let o=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),a=e.max??t?.max??o+u;a<=o&&(o-=u/2,a+=u/2);const i=a-o;let l=s[0],m=1/0;for(const t of s){const e=Math.abs(i/t.size-n);e<m&&(m=e,l=t)}const f=l.unit,$="year"===f?Math.max(1,Math.round(r(i/n/(365*u)))):l.count,x=e.min??h(o,f,$),p=[];let M=x;for(let t=0;t<500&&(p.push(M),!(M>a));t++)M=c(M,f,$);const g=e.max??p[p.length-1],d=g-x||1;return{min:x,max:g,ticks:p.filter(t=>t>=x&&t<=g),unit:f,step:$,fraction:t=>(t-x)/d}}function m(t,e){if("second"===t)return{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"};if("minute"===t||"hour"===t)return{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if("year"===t)return{year:"numeric"};const n="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...n,year:"numeric"}:n}export function formatTimeValue(e,n,r){return t(r,m(n,!0)).format(new Date(e))}export function formatTimeTicks(e,n,r){const o=new Set(e.map(t=>new Date(t).getFullYear())).size>1;return e.map((e,a)=>t(r,m(n,o||0===a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const o=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?o():r.push(e);return o(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const a=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(a(e),o=e+1);return a(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const u=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${u(i,-i)}H${t+n-i}${u(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${u(-i,i)}H${t+i}${u(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${u(i,i)}V${e+r-i}${u(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${u(-i,-i)}V${e+i}${u(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const f={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*f[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t){return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`}const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function arcPath(t,e,n,r,o,a){const i=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}ZM${i(r,o)}A${r} ${r} 0 1 0 ${i(r,t)}A${r} ${r} 0 1 0 ${i(r,o)}Z`:`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}Z`}const u=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}Z`:`M${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}L${i(r,a)}A${r} ${r} 0 ${u} 0 ${i(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const m=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},f=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||m([...h,t])<=m(h)||f(),h.push(t);return h.length>0&&f(),i}const $={month:"short",day:"numeric"},x={notation:"compact",maximumFractionDigits:1},p={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,$).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,x).format(t):e(n,p).format(t)}
1
+ import{dateFormatter as t,numberFormatter as e}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--neba-chart-1)","var(--neba-chart-2)","var(--neba-chart-3)","var(--neba-chart-4)","var(--neba-chart-5)","var(--neba-chart-6)","var(--neba-chart-7)","var(--neba-chart-8)"];const n=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return n.has(t)?`var(--neba-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function r(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5,includeZero:o=!0}=e;let a=e.min??(t?t.min:0),i=e.max??(t?t.max:1);if(o&&void 0===e.min&&(a=Math.min(a,0)),o&&void 0===e.max&&(i=Math.max(i,0)),i===a){const t=Math.abs(i)>0?.5*Math.abs(i):1;a-=t,i+=t}const u=void 0!==e.min&&void 0!==e.max?function(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let o=r(t/Math.max(1,e)),a=1/0;for(const r of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*r*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const h=Math.abs(c-e);h<a&&(a=h,o=u)}return o}(i-a,n):r((i-a)/Math.max(1,n)),s=void 0!==e.min?a:Math.floor(a/u)*u,c=void 0!==e.max?i:Math.ceil(i/u)*u,h=c-s||1,l=[];for(let t=s;t<=c+1e-9*u;t+=u)l.push(Number(t.toFixed(12)));return{min:s,max:c,ticks:l,fraction:t=>(t-s)/h}}const o=1e3,a=6e4,i=36e5,u=24*i,s=[{unit:"second",count:1,size:o},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:a},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:i},{unit:"hour",count:3,size:3*i},{unit:"hour",count:6,size:6*i},{unit:"hour",count:12,size:12*i},{unit:"day",count:1,size:u},{unit:"day",count:2,size:2*u},{unit:"week",count:1,size:7*u},{unit:"week",count:2,size:14*u},{unit:"month",count:1,size:30*u},{unit:"quarter",count:1,size:91*u},{unit:"month",count:6,size:182*u},{unit:"year",count:1,size:365*u}];function c(t,e,n){const r=new Date(t);if("year"===e)r.setFullYear(r.getFullYear()+n);else if("quarter"===e)r.setMonth(r.getMonth()+3*n);else if("month"===e)r.setMonth(r.getMonth()+n);else if("week"===e)r.setDate(r.getDate()+7*n);else if("day"===e)r.setDate(r.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?a:o);r.setHours(r.getHours()+n)}return r.getTime()}const h={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};function l(t,e,n){let r=function(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/a)*a:Math.floor(t/o)*o}(t,h[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=c(r,e,n);if(o>t)return r;r=o}return r}export function timeScale(t,e={}){const{tickCount:n=6}=e;let o=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),a=e.max??t?.max??o+u;a<=o&&(o-=u/2,a+=u/2);const i=a-o;let h=s[0],m=1/0;for(const t of s){const e=Math.abs(i/t.size-n);e<m&&(m=e,h=t)}const $=h.unit,f="year"===$?Math.max(1,Math.round(r(i/n/(365*u)))):h.count,x=e.min??l(o,$,f),M=[];let p=x;for(let t=0;t<500&&(M.push(p),!(p>a));t++)p=c(p,$,f);const g=e.max??M[M.length-1],d=g-x||1;return{min:x,max:g,ticks:M.filter(t=>t>=x&&t<=g),unit:$,step:f,fraction:t=>(t-x)/d}}function m(t,e){if("second"===t)return{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"};if("minute"===t||"hour"===t)return{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if("year"===t)return{year:"numeric"};const n="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...n,year:"numeric"}:n}export function formatTimeValue(e,n,r){return t(r,m(n,!0)).format(new Date(e))}export function formatTimeTicks(e,n,r){const o=new Set(e.map(t=>new Date(t).getFullYear())).size>1;return e.map((e,a)=>t(r,m(n,o||0===a)).format(new Date(e)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const o=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?o():r.push(e);return o(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const a=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(a(e),o=e+1);return a(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const u=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${u(i,-i)}H${t+n-i}${u(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${u(-i,i)}H${t+i}${u(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${u(i,i)}V${e+r-i}${u(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${u(-i,-i)}V${e+i}${u(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const $={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*$[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t){return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`}const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function ringPath(t,e,n,r,o){const a=r=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(o-r)>=360){const t=r+180;return`M${a(r)}A${n} ${n} 0 1 1 ${a(t)}A${n} ${n} 0 1 1 ${a(r)}`}const i=Math.abs(o-r)>180?1:0;return`M${a(r)}A${n} ${n} 0 ${i} 1 ${a(o)}`}export function arcPath(t,e,n,r,o,a){const i=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}ZM${i(r,o)}A${r} ${r} 0 1 0 ${i(r,t)}A${r} ${r} 0 1 0 ${i(r,o)}Z`:`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}Z`}const u=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}Z`:`M${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}L${i(r,a)}A${r} ${r} 0 ${u} 0 ${i(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):4}export function rampFill(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,h=n,l=[];const m=t=>{const e=Math.min(c,h),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},$=()=>{const t=l.reduce((t,e)=>t+e.area,0),e=Math.min(c,h),n=e>0?t/e:0,r=c>=h;let o=0;for(const t of l){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,h-=n),l=[]};for(const t of a)0===l.length||m([...l,t])<=m(l)||$(),l.push(t);return l.length>0&&$(),i}const f={month:"short",day:"numeric"},x={notation:"compact",maximumFractionDigits:1},M={maximumFractionDigits:2};export function formatCategory(e,n){return e instanceof Date?t(n,f).format(e):String(e)}export function compactNumber(t,n){return Math.abs(t)>=1e4?e(n,x).format(t):e(n,M).format(t)}
@@ -1 +1 @@
1
- import{dateFormatter as t}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function startOfUnit(t,e){return"year"===e?startOfYear(t):"month"===e?startOfMonth(t):startOfDay(t)}export function endOfUnit(t,e){const r=t.getFullYear();return"year"===e?makeDate(r,11,31):"month"===e?makeDate(r,t.getMonth(),daysInMonth(r,t.getMonth())):startOfDay(t)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=t.getFullYear(),n=t.getMonth()+e,o=new Date(t.getTime()),a=makeDate(r,n,1);return o.setFullYear(a.getFullYear(),a.getMonth(),Math.min(t.getDate(),daysInMonth(a.getFullYear(),a.getMonth()))),o}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function isDayInRange(t,e,r){return!(!isValidDate(e)||!isValidDate(r))&&(compareDay(t,e)>0&&compareDay(t,r)<0)}export function clampDate(t,e,r){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(r)&&t.getTime()>r.getTime()?new Date(r.getTime()):t}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function isUnitOutside(t,e,r,n){return!!(isValidDate(r)&&compareDay(endOfUnit(t,e),r)<0)||isValidDate(n)&&compareDay(startOfUnit(t,e),n)>0}export function minutesOfDay(t){return 60*t.getHours()+t.getMinutes()}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(e,r,n){return isValidDate(e)?t(r,n).format(e):""}const e=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58));export function displaySamples(r,n){const o=t(r,n);return[...new Set(e.map(t=>o.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const r=t=>String(t).padStart(2,"0"),n=`${r(t.getHours())}:${r(t.getMinutes())}`;return e?`${n}:${r(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const r=makeDate(2021,7,1);export function weekdayLabels(e,n,o="short"){const a=t(e,{weekday:o});return Array.from({length:7},(t,e)=>a.format(addDays(r,(n+e)%7)))}export function monthLabels(e,r="short"){const n=t(e,{month:r});return Array.from({length:12},(t,e)=>n.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(e){const n=t(e,{year:"numeric",month:"long"}).formatToParts(r);return n.findIndex(t=>"month"===t.type)<n.findIndex(t=>"year"===t.type)}export function isHour12(e){const r=t(e,{hour:"numeric"}).resolvedOptions();return r.hourCycle?"h11"===r.hourCycle||"h12"===r.hourCycle:!0===r.hour12}export function meridiemLabels(e){const n=t(e,{hour:"numeric",hour12:!0}),o=t=>{const e=n.formatToParts(withTime(r,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[o(9),o(21)]}export function localeWeekStart(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}
1
+ import{memoise as t}from"./cache.js";import{dateFormatter as e}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function startOfUnit(t,e){return"year"===e?startOfYear(t):"month"===e?startOfMonth(t):startOfDay(t)}export function endOfUnit(t,e){const r=t.getFullYear();return"year"===e?makeDate(r,11,31):"month"===e?makeDate(r,t.getMonth(),daysInMonth(r,t.getMonth())):startOfDay(t)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=t.getFullYear(),n=t.getMonth()+e,o=new Date(t.getTime()),a=makeDate(r,n,1);return o.setFullYear(a.getFullYear(),a.getMonth(),Math.min(t.getDate(),daysInMonth(a.getFullYear(),a.getMonth()))),o}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function isDayInRange(t,e,r){return!(!isValidDate(e)||!isValidDate(r))&&(compareDay(t,e)>0&&compareDay(t,r)<0)}export function clampDate(t,e,r){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(r)&&t.getTime()>r.getTime()?new Date(r.getTime()):t}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function isUnitOutside(t,e,r,n){return!!(isValidDate(r)&&compareDay(endOfUnit(t,e),r)<0)||isValidDate(n)&&compareDay(startOfUnit(t,e),n)>0}export function minutesOfDay(t){return 60*t.getHours()+t.getMinutes()}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(t,r,n){return isValidDate(t)?e(r,n).format(t):""}const r=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58));export function displaySamples(t,n){const o=e(t,n);return[...new Set(r.map(t=>o.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const r=t=>String(t).padStart(2,"0"),n=`${r(t.getHours())}:${r(t.getMinutes())}`;return e?`${n}:${r(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const n=makeDate(2021,7,1);export function weekdayLabels(t,r,o="short"){const a=e(t,{weekday:o});return Array.from({length:7},(t,e)=>a.format(addDays(n,(r+e)%7)))}export function monthLabels(t,r="short"){const n=e(t,{month:r});return Array.from({length:12},(t,e)=>n.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(t){const r=e(t,{year:"numeric",month:"long"}).formatToParts(n);return r.findIndex(t=>"month"===t.type)<r.findIndex(t=>"year"===t.type)}export function isHour12(t){const r=e(t,{hour:"numeric"}).resolvedOptions();return r.hourCycle?"h11"===r.hourCycle||"h12"===r.hourCycle:!0===r.hour12}export function meridiemLabels(t){const r=e(t,{hour:"numeric",hour12:!0}),o=t=>{const e=r.formatToParts(withTime(n,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[o(9),o(21)]}const o=new Map;export function localeWeekStart(e){return t(o,e??"",()=>function(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}(e))}