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.
- package/LICENSE +1 -1
- package/README.md +43 -41
- package/dist/components/accordion/Accordion.d.ts +18 -0
- package/dist/components/accordion/Accordion.js +1 -1
- package/dist/components/anchor/Anchor.js +1 -1
- package/dist/components/animate-appear/AnimateAppear.d.ts +2 -13
- package/dist/components/animate-appear/AnimateAppear.js +1 -1
- package/dist/components/animate-blink/AnimateBlink.d.ts +2 -2
- package/dist/components/animate-blink/AnimateBlink.js +1 -1
- package/dist/components/animate-counter/AnimateCounter.d.ts +45 -0
- package/dist/components/animate-counter/AnimateCounter.js +1 -0
- package/dist/components/animate-counter/index.d.ts +1 -0
- package/dist/components/animate-counter/index.js +1 -0
- package/dist/components/animate-fade/AnimateFade.d.ts +2 -2
- package/dist/components/animate-fade/AnimateFade.js +1 -1
- package/dist/components/animate-float/AnimateFloat.d.ts +35 -0
- package/dist/components/animate-float/AnimateFloat.js +1 -0
- package/dist/components/animate-float/index.d.ts +1 -0
- package/dist/components/animate-float/index.js +1 -0
- package/dist/components/animate-grow/AnimateGrow.d.ts +2 -2
- package/dist/components/animate-grow/AnimateGrow.js +1 -1
- package/dist/components/animate-marquee/AnimateMarquee.d.ts +5 -3
- package/dist/components/animate-marquee/AnimateMarquee.js +1 -1
- package/dist/components/animate-reveal/AnimateReveal.d.ts +41 -0
- package/dist/components/animate-reveal/AnimateReveal.js +1 -0
- package/dist/components/animate-reveal/index.d.ts +1 -0
- package/dist/components/animate-reveal/index.js +1 -0
- package/dist/components/animate-rotate/AnimateRotate.d.ts +2 -2
- package/dist/components/animate-rotate/AnimateRotate.js +1 -1
- package/dist/components/animate-scramble/AnimateScramble.d.ts +48 -0
- package/dist/components/animate-scramble/AnimateScramble.js +1 -0
- package/dist/components/animate-scramble/index.d.ts +1 -0
- package/dist/components/animate-scramble/index.js +1 -0
- package/dist/components/animate-shake/AnimateShake.d.ts +39 -0
- package/dist/components/animate-shake/AnimateShake.js +1 -0
- package/dist/components/animate-shake/index.d.ts +1 -0
- package/dist/components/animate-shake/index.js +1 -0
- package/dist/components/animate-slide/AnimateSlide.d.ts +2 -2
- package/dist/components/animate-slide/AnimateSlide.js +1 -1
- package/dist/components/animate-split/AnimateSplit.d.ts +61 -0
- package/dist/components/animate-split/AnimateSplit.js +1 -0
- package/dist/components/animate-split/index.d.ts +1 -0
- package/dist/components/animate-split/index.js +1 -0
- package/dist/components/animate-typing/AnimateTyping.js +1 -1
- package/dist/components/animate-zoom/AnimateZoom.d.ts +2 -2
- package/dist/components/animate-zoom/AnimateZoom.js +1 -1
- package/dist/components/app-logo/AppLogo.js +1 -1
- package/dist/components/avatar/Avatar.js +1 -1
- package/dist/components/bar-chart/BarChart.js +1 -1
- package/dist/components/bottom-navigation/BottomNavigation.d.ts +10 -0
- package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
- package/dist/components/button/Button.js +1 -1
- package/dist/components/calendar/Calendar.js +1 -1
- package/dist/components/carousel/Carousel.d.ts +13 -0
- package/dist/components/carousel/Carousel.js +1 -1
- package/dist/components/checkbox/Checkbox.js +1 -1
- package/dist/components/code-block/CodeBlock.js +1 -1
- package/dist/components/color-picker/ColorPicker.js +1 -1
- package/dist/components/combobox/Combobox.d.ts +18 -0
- package/dist/components/combobox/Combobox.js +1 -1
- package/dist/components/command-palette/CommandPalette.js +1 -1
- package/dist/components/container/Container.d.ts +12 -4
- package/dist/components/container/Container.js +1 -1
- package/dist/components/data-table/DataTable.js +1 -1
- package/dist/components/date-picker/DatePicker.js +1 -1
- package/dist/components/date-range-picker/DateRangePicker.js +1 -1
- package/dist/components/date-time-picker/DateTimePicker.js +1 -1
- package/dist/components/dialog/Dialog.js +1 -1
- package/dist/components/drawer/Drawer.js +1 -1
- package/dist/components/flex/Flex.d.ts +93 -0
- package/dist/components/flex/Flex.js +1 -0
- package/dist/components/flex/index.d.ts +2 -0
- package/dist/components/flex/index.js +1 -0
- package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
- package/dist/components/footer/Footer.d.ts +4 -3
- package/dist/components/footer/Footer.js +1 -1
- package/dist/components/gallery/Gallery.d.ts +150 -0
- package/dist/components/gallery/Gallery.js +1 -0
- package/dist/components/gallery/GalleryViewer.d.ts +30 -0
- package/dist/components/gallery/GalleryViewer.js +1 -0
- package/dist/components/gallery/index.d.ts +2 -0
- package/dist/components/gallery/index.js +1 -0
- package/dist/components/gauge-chart/GaugeChart.js +1 -1
- package/dist/components/grid/Grid.d.ts +11 -1
- package/dist/components/grid/Grid.js +1 -1
- package/dist/components/grid-container/GridContainer.js +1 -1
- package/dist/components/header/Header.d.ts +5 -4
- package/dist/components/header/Header.js +1 -1
- package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
- package/dist/components/hover-card/HoverCard.js +1 -1
- package/dist/components/how-to-steps/HowToSteps.js +1 -1
- package/dist/components/image/Image.d.ts +155 -7
- package/dist/components/image/Image.js +1 -1
- package/dist/components/image/index.d.ts +1 -1
- package/dist/components/menu/Menu.js +1 -1
- package/dist/components/meter/Meter.d.ts +7 -0
- package/dist/components/meter/Meter.js +1 -1
- package/dist/components/navigation-menu/NavigationMenu.js +1 -1
- package/dist/components/number-field/NumberField.js +1 -1
- package/dist/components/otp-field/OtpField.js +1 -1
- package/dist/components/overlay/Overlay.js +1 -1
- package/dist/components/panes/Panes.js +1 -1
- package/dist/components/pie-chart/PieChart.js +1 -1
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/progress-circular/ProgressCircular.d.ts +10 -1
- package/dist/components/progress-circular/ProgressCircular.js +1 -1
- package/dist/components/progress-linear/ProgressLinear.d.ts +7 -1
- package/dist/components/progress-linear/ProgressLinear.js +1 -1
- package/dist/components/provider/NebaProvider.js +1 -1
- package/dist/components/radio-group/RadioGroup.js +1 -1
- package/dist/components/rating/Rating.js +1 -1
- package/dist/components/scatter-chart/ScatterChart.js +1 -1
- package/dist/components/scroll-area/ScrollArea.js +1 -1
- package/dist/components/scroll-zone/ScrollZone.d.ts +17 -11
- package/dist/components/scroll-zone/ScrollZone.js +1 -1
- package/dist/components/select/Select.d.ts +13 -0
- package/dist/components/select/Select.js +1 -1
- package/dist/components/show/Show.d.ts +60 -0
- package/dist/components/show/Show.js +1 -0
- package/dist/components/show/index.d.ts +2 -0
- package/dist/components/show/index.js +1 -0
- package/dist/components/sidebar/Sidebar.js +1 -1
- package/dist/components/slider/Slider.d.ts +37 -2
- package/dist/components/slider/Slider.js +1 -1
- package/dist/components/spoiler/Spoiler.js +1 -1
- package/dist/components/stack/Stack.d.ts +126 -0
- package/dist/components/stack/Stack.js +1 -0
- package/dist/components/stack/index.d.ts +1 -0
- package/dist/components/stack/index.js +1 -0
- package/dist/components/statistic/Statistic.d.ts +8 -3
- package/dist/components/tabs/Tabs.d.ts +46 -0
- package/dist/components/tabs/Tabs.js +1 -1
- package/dist/components/text-field/TextField.js +1 -1
- package/dist/components/time-picker/TimePicker.js +1 -1
- package/dist/components/timeline-chart/TimelineChart.js +1 -1
- package/dist/components/toast/Toast.js +1 -1
- package/dist/components/toggle/Toggle.js +1 -1
- package/dist/components/tooltip/Tooltip.js +1 -1
- package/dist/components/tour/Tour.js +1 -1
- package/dist/components/transfer/Transfer.js +1 -1
- package/dist/components/tree-select/TreeSelect.d.ts +2 -0
- package/dist/components/tree-select/TreeSelect.js +1 -1
- package/dist/components/tree-view/TreeView.js +1 -1
- package/dist/components/typography/Typography.js +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useMediaQuery.d.ts +35 -1
- package/dist/hooks/useMediaQuery.js +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +65 -2
- package/dist/internal/animate.js +1 -1
- package/dist/internal/cache.d.ts +24 -0
- package/dist/internal/cache.js +1 -0
- package/dist/internal/calendar.d.ts +15 -42
- package/dist/internal/calendar.js +1 -1
- package/dist/internal/chart-frame.d.ts +48 -3
- package/dist/internal/chart-frame.js +1 -1
- package/dist/internal/chart-line.js +1 -1
- package/dist/internal/chart.d.ts +16 -0
- package/dist/internal/chart.js +1 -1
- package/dist/internal/date.js +1 -1
- package/dist/internal/drag.d.ts +8 -6
- package/dist/internal/drag.js +1 -1
- package/dist/internal/format.d.ts +21 -7
- package/dist/internal/format.js +1 -1
- package/dist/internal/grid.d.ts +29 -27
- package/dist/internal/grid.js +1 -1
- package/dist/internal/i18n.d.ts +92 -0
- package/dist/internal/i18n.js +1 -1
- package/dist/internal/icons.d.ts +25 -0
- package/dist/internal/icons.js +1 -1
- package/dist/internal/link.d.ts +5 -4
- package/dist/internal/media.d.ts +9 -2
- package/dist/internal/media.js +1 -1
- package/dist/internal/observe.js +1 -1
- package/dist/internal/page-layout.d.ts +11 -9
- package/dist/internal/page-layout.js +1 -1
- package/dist/internal/picker.d.ts +8 -3
- package/dist/internal/picker.js +1 -1
- package/dist/internal/progress.d.ts +24 -1
- package/dist/internal/progress.js +1 -1
- package/dist/internal/responsive.d.ts +97 -0
- package/dist/internal/responsive.js +1 -0
- package/dist/internal/styles.d.ts +140 -2
- package/dist/internal/styles.js +1 -1
- package/dist/internal/text.d.ts +32 -0
- package/dist/internal/text.js +1 -0
- package/dist/internal/wheel.d.ts +38 -0
- package/dist/internal/wheel.js +1 -0
- package/dist/locales/ar.js +1 -1
- package/dist/locales/de.js +1 -1
- package/dist/locales/es.js +1 -1
- package/dist/locales/fr.js +1 -1
- package/dist/locales/hi.js +1 -1
- package/dist/locales/id.js +1 -1
- package/dist/locales/it.js +1 -1
- package/dist/locales/ja.js +1 -1
- package/dist/locales/ko.js +1 -1
- package/dist/locales/nl.js +1 -1
- package/dist/locales/pl.js +1 -1
- package/dist/locales/pt.js +1 -1
- package/dist/locales/ru.js +1 -1
- package/dist/locales/th.js +1 -1
- package/dist/locales/tr.js +1 -1
- package/dist/locales/vi.js +1 -1
- package/dist/locales/zh-hans.js +1 -1
- package/dist/locales/zh-hant.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +411 -30
- package/dist/types.d.ts +119 -6
- package/package.json +19 -18
- package/dist/components/avatar-group/AvatarGroup.d.ts +0 -47
- package/dist/components/avatar-group/AvatarGroup.js +0 -1
- package/dist/components/avatar-group/index.d.ts +0 -2
- package/dist/components/avatar-group/index.js +0 -1
- package/dist/internal/avatar-group.d.ts +0 -22
- 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`
|
|
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.
|
package/dist/internal/animate.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import
|
|
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
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
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
|
-
/**
|
|
363
|
-
|
|
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&>.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
|
|
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)})]})}
|
package/dist/internal/chart.d.ts
CHANGED
|
@@ -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
|
*
|
package/dist/internal/chart.js
CHANGED
|
@@ -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)}
|
package/dist/internal/date.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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))}
|