@epilot/spark-ui 0.20.0 → 0.20.2
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/dist/components/accordion.cjs +7 -7
- package/dist/components/accordion.cjs.map +1 -1
- package/dist/components/accordion.d.ts +1 -1
- package/dist/components/accordion.js +1 -1
- package/dist/components/alert-dialog.cjs +10 -10
- package/dist/components/alert-dialog.cjs.map +1 -1
- package/dist/components/alert-dialog.js +1 -1
- package/dist/components/attachment.cjs +10 -10
- package/dist/components/attachment.cjs.map +1 -1
- package/dist/components/attachment.d.cts +2 -2
- package/dist/components/attachment.d.ts +2 -2
- package/dist/components/autocomplete.cjs +13 -13
- package/dist/components/autocomplete.cjs.map +1 -1
- package/dist/components/autocomplete.js +1 -1
- package/dist/components/avatar.cjs +2 -2
- package/dist/components/avatar.cjs.map +1 -1
- package/dist/components/avatar.js +1 -1
- package/dist/components/badge.cjs +2 -2
- package/dist/components/badge.cjs.map +1 -1
- package/dist/components/badge.js +2 -2
- package/dist/components/badge.js.map +1 -1
- package/dist/components/bar-chart-with-total.d.cts +1 -1
- package/dist/components/bar-chart-with-total.d.ts +1 -1
- package/dist/components/bar-chart.cjs +4 -4
- package/dist/components/bar-chart.cjs.map +1 -1
- package/dist/components/bar-chart.js +2 -2
- package/dist/components/bar-chart.js.map +1 -1
- package/dist/components/box.cjs +2 -2
- package/dist/components/box.cjs.map +1 -1
- package/dist/components/box.js +1 -1
- package/dist/components/breadcrumbs.cjs +7 -7
- package/dist/components/breadcrumbs.cjs.map +1 -1
- package/dist/components/bubble.cjs +5 -5
- package/dist/components/bubble.cjs.map +1 -1
- package/dist/components/bubble.d.cts +1 -1
- package/dist/components/bubble.d.ts +1 -1
- package/dist/components/button-group.cjs +5 -5
- package/dist/components/button-group.cjs.map +1 -1
- package/dist/components/button-group.js +1 -1
- package/dist/components/button.cjs +2 -2
- package/dist/components/button.cjs.map +1 -1
- package/dist/components/button.d.cts +3 -3
- package/dist/components/button.d.ts +3 -3
- package/dist/components/button.js +1 -1
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar.cjs +12 -11
- package/dist/components/calendar.cjs.map +1 -1
- package/dist/components/calendar.js +5 -4
- package/dist/components/calendar.js.map +1 -1
- package/dist/components/callout.cjs +8 -8
- package/dist/components/callout.cjs.map +1 -1
- package/dist/components/callout.d.ts +1 -1
- package/dist/components/callout.js +1 -1
- package/dist/components/card.cjs +16 -16
- package/dist/components/card.cjs.map +1 -1
- package/dist/components/card.js +2 -2
- package/dist/components/card.js.map +1 -1
- package/dist/components/chart.cjs +2 -2
- package/dist/components/chart.cjs.map +1 -1
- package/dist/components/checkbox.cjs +2 -2
- package/dist/components/checkbox.cjs.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/circular-gauge.cjs +3 -3
- package/dist/components/circular-gauge.cjs.map +1 -1
- package/dist/components/circular-gauge.js +1 -1
- package/dist/components/circular-gauge.js.map +1 -1
- package/dist/components/day-of-week-picker.cjs +4 -4
- package/dist/components/day-of-week-picker.cjs.map +1 -1
- package/dist/components/dialog.cjs +9 -9
- package/dist/components/dialog.cjs.map +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/donut-chart.cjs.map +1 -1
- package/dist/components/donut-chart.js.map +1 -1
- package/dist/components/drawer.cjs +8 -8
- package/dist/components/drawer.cjs.map +1 -1
- package/dist/components/drawer.js +2 -2
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown-menu.cjs +11 -11
- package/dist/components/dropdown-menu.cjs.map +1 -1
- package/dist/components/dropdown-menu.js +1 -1
- package/dist/components/empty-state.d.ts +1 -1
- package/dist/components/energy-breakdown.cjs +80 -0
- package/dist/components/energy-breakdown.cjs.map +1 -0
- package/dist/components/energy-breakdown.d.cts +24 -0
- package/dist/components/energy-breakdown.d.ts +24 -0
- package/dist/components/energy-breakdown.js +79 -0
- package/dist/components/energy-breakdown.js.map +1 -0
- package/dist/components/energy-history-chart.cjs +63 -0
- package/dist/components/energy-history-chart.cjs.map +1 -0
- package/dist/components/energy-history-chart.d.cts +64 -0
- package/dist/components/energy-history-chart.d.ts +64 -0
- package/dist/components/energy-history-chart.js +62 -0
- package/dist/components/energy-history-chart.js.map +1 -0
- package/dist/components/entity-card.cjs +11 -11
- package/dist/components/entity-card.cjs.map +1 -1
- package/dist/components/entity-card.d.ts +1 -1
- package/dist/components/field.cjs +16 -16
- package/dist/components/field.cjs.map +1 -1
- package/dist/components/field.js +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/hero-metric.cjs +4 -4
- package/dist/components/hero-metric.cjs.map +1 -1
- package/dist/components/icon.cjs +6 -6
- package/dist/components/icon.cjs.map +1 -1
- package/dist/components/icon.js +5 -5
- package/dist/components/icon.js.map +1 -1
- package/dist/components/info-block.cjs +9 -9
- package/dist/components/info-block.cjs.map +1 -1
- package/dist/components/info-block.d.cts +1 -1
- package/dist/components/info-block.d.ts +1 -1
- package/dist/components/input-date.cjs +5 -4
- package/dist/components/input-date.cjs.map +1 -1
- package/dist/components/input-date.d.cts +3 -1
- package/dist/components/input-date.d.ts +3 -1
- package/dist/components/input-date.js +3 -2
- package/dist/components/input-date.js.map +1 -1
- package/dist/components/input-group.cjs +5 -5
- package/dist/components/input-group.cjs.map +1 -1
- package/dist/components/input-otp.cjs +3 -3
- package/dist/components/input-otp.cjs.map +1 -1
- package/dist/components/input-otp.js +1 -1
- package/dist/components/input.cjs +3 -3
- package/dist/components/input.cjs.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/label.cjs +2 -2
- package/dist/components/label.cjs.map +1 -1
- package/dist/components/layout.cjs +2 -2
- package/dist/components/layout.cjs.map +1 -1
- package/dist/components/line-chart.cjs +7 -7
- package/dist/components/line-chart.cjs.map +1 -1
- package/dist/components/line-chart.js +5 -5
- package/dist/components/line-chart.js.map +1 -1
- package/dist/components/list.cjs +11 -11
- package/dist/components/list.cjs.map +1 -1
- package/dist/components/list.d.cts +7 -2
- package/dist/components/list.d.ts +7 -2
- package/dist/components/list.js +2 -2
- package/dist/components/list.js.map +1 -1
- package/dist/components/marker.cjs +4 -4
- package/dist/components/marker.cjs.map +1 -1
- package/dist/components/marker.d.cts +1 -1
- package/dist/components/marker.d.ts +1 -1
- package/dist/components/message-scroller.cjs +8 -8
- package/dist/components/message-scroller.cjs.map +1 -1
- package/dist/components/message-scroller.js +4 -4
- package/dist/components/message-scroller.js.map +1 -1
- package/dist/components/message.cjs +7 -7
- package/dist/components/message.cjs.map +1 -1
- package/dist/components/number-flow.d.cts +2 -12
- package/dist/components/number-flow.d.ts +2 -12
- package/dist/components/page-header.cjs +6 -6
- package/dist/components/page-header.cjs.map +1 -1
- package/dist/components/page-header.js +1 -1
- package/dist/components/period-tabs.cjs +6 -6
- package/dist/components/period-tabs.cjs.map +1 -1
- package/dist/components/pill.cjs +4 -4
- package/dist/components/pill.cjs.map +1 -1
- package/dist/components/pill.js +4 -4
- package/dist/components/pill.js.map +1 -1
- package/dist/components/popover.cjs +2 -2
- package/dist/components/popover.cjs.map +1 -1
- package/dist/components/power-history-chart.cjs +498 -0
- package/dist/components/power-history-chart.cjs.map +1 -0
- package/dist/components/power-history-chart.d.cts +71 -0
- package/dist/components/power-history-chart.d.ts +71 -0
- package/dist/components/power-history-chart.js +496 -0
- package/dist/components/power-history-chart.js.map +1 -0
- package/dist/components/power-network.cjs +559 -0
- package/dist/components/power-network.cjs.map +1 -0
- package/dist/components/power-network.d.cts +80 -0
- package/dist/components/power-network.d.ts +80 -0
- package/dist/components/power-network.js +553 -0
- package/dist/components/power-network.js.map +1 -0
- package/dist/components/progress.cjs +3 -3
- package/dist/components/progress.cjs.map +1 -1
- package/dist/components/progress.js +1 -1
- package/dist/components/progress.js.map +1 -1
- package/dist/components/radio-card-group.cjs +3 -3
- package/dist/components/radio-card-group.cjs.map +1 -1
- package/dist/components/radio.cjs +3 -3
- package/dist/components/radio.cjs.map +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/sankey-chart.cjs +15 -5
- package/dist/components/sankey-chart.cjs.map +1 -1
- package/dist/components/sankey-chart.d.cts +3 -2
- package/dist/components/sankey-chart.d.ts +3 -2
- package/dist/components/sankey-chart.js +13 -4
- package/dist/components/sankey-chart.js.map +1 -1
- package/dist/components/schedule-editor.cjs +9 -9
- package/dist/components/schedule-editor.cjs.map +1 -1
- package/dist/components/schedule-list.cjs +11 -11
- package/dist/components/schedule-list.cjs.map +1 -1
- package/dist/components/schedule-list.js +1 -1
- package/dist/components/scroll-area.cjs +3 -3
- package/dist/components/scroll-area.cjs.map +1 -1
- package/dist/components/segmented-control.cjs +8 -8
- package/dist/components/segmented-control.cjs.map +1 -1
- package/dist/components/segmented-control.d.cts +2 -16
- package/dist/components/segmented-control.d.ts +2 -16
- package/dist/components/segmented-control.js +5 -5
- package/dist/components/segmented-control.js.map +1 -1
- package/dist/components/select.cjs +13 -13
- package/dist/components/select.cjs.map +1 -1
- package/dist/components/select.js +2 -2
- package/dist/components/separator.cjs +3 -3
- package/dist/components/separator.cjs.map +1 -1
- package/dist/components/series-legend.cjs +4 -4
- package/dist/components/series-legend.cjs.map +1 -1
- package/dist/components/sheet.cjs +9 -9
- package/dist/components/sheet.cjs.map +1 -1
- package/dist/components/sheet.js +1 -1
- package/dist/components/skeleton.cjs +3 -3
- package/dist/components/skeleton.cjs.map +1 -1
- package/dist/components/slider.cjs +11 -11
- package/dist/components/slider.cjs.map +1 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/solar-forecast-chart.cjs +108 -0
- package/dist/components/solar-forecast-chart.cjs.map +1 -0
- package/dist/components/solar-forecast-chart.d.cts +77 -0
- package/dist/components/solar-forecast-chart.d.ts +77 -0
- package/dist/components/solar-forecast-chart.js +103 -0
- package/dist/components/solar-forecast-chart.js.map +1 -0
- package/dist/components/sortable-list.cjs +3 -3
- package/dist/components/sortable-list.cjs.map +1 -1
- package/dist/components/spinner.cjs +2 -2
- package/dist/components/spinner.cjs.map +1 -1
- package/dist/components/stat-card.cjs +8 -8
- package/dist/components/stat-card.cjs.map +1 -1
- package/dist/components/stepper.cjs +3 -3
- package/dist/components/stepper.cjs.map +1 -1
- package/dist/components/stepper.js +1 -1
- package/dist/components/switch.cjs +3 -3
- package/dist/components/switch.cjs.map +1 -1
- package/dist/components/switch.js +2 -2
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.cjs +9 -9
- package/dist/components/table.cjs.map +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/tabs.cjs +10 -10
- package/dist/components/tabs.cjs.map +1 -1
- package/dist/components/tabs.d.cts +1 -8
- package/dist/components/tabs.d.ts +1 -8
- package/dist/components/tabs.js +3 -3
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/textarea.cjs +3 -3
- package/dist/components/textarea.cjs.map +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/theme.cjs +2 -2
- package/dist/components/theme.cjs.map +1 -1
- package/dist/components/theme.js +1 -1
- package/dist/components/thumbnail.cjs +3 -3
- package/dist/components/thumbnail.cjs.map +1 -1
- package/dist/components/time-picker.cjs +3 -3
- package/dist/components/time-picker.cjs.map +1 -1
- package/dist/components/toast.cjs +40 -15
- package/dist/components/toast.cjs.map +1 -1
- package/dist/components/toast.d.cts +15 -2
- package/dist/components/toast.d.ts +15 -2
- package/dist/components/toast.js +33 -8
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.cjs +40 -0
- package/dist/components/toggle-group.cjs.map +1 -0
- package/dist/components/toggle-group.d.cts +28 -0
- package/dist/components/toggle-group.d.ts +28 -0
- package/dist/components/toggle-group.js +37 -0
- package/dist/components/toggle-group.js.map +1 -0
- package/dist/components/toggle.cjs +69 -0
- package/dist/components/toggle.cjs.map +1 -0
- package/dist/components/toggle.d.cts +23 -0
- package/dist/components/toggle.d.ts +23 -0
- package/dist/components/toggle.js +66 -0
- package/dist/components/toggle.js.map +1 -0
- package/dist/components/tooltip.cjs +4 -4
- package/dist/components/tooltip.cjs.map +1 -1
- package/dist/components/tooltip.js +2 -2
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typography.cjs +6 -6
- package/dist/components/typography.cjs.map +1 -1
- package/dist/components/wizard-layout.cjs +8 -8
- package/dist/components/wizard-layout.cjs.map +1 -1
- package/dist/lib/generate-radix-colors.cjs +1 -1
- package/dist/lib/generate-radix-colors.cjs.map +1 -1
- package/dist/lib/generate-radix-colors.js +1 -1
- package/dist/lib/generate-radix-colors.js.map +1 -1
- package/dist/lib/input-box-variants.cjs +9 -9
- package/dist/lib/input-box-variants.cjs.map +1 -1
- package/dist/lib/toggle-group-context.cjs +12 -0
- package/dist/lib/toggle-group-context.cjs.map +1 -0
- package/dist/lib/toggle-group-context.d.cts +17 -0
- package/dist/lib/toggle-group-context.d.ts +17 -0
- package/dist/lib/toggle-group-context.js +9 -0
- package/dist/lib/toggle-group-context.js.map +1 -0
- package/dist/number-flow-Bch81ixZ.d.cts +14 -0
- package/dist/number-flow-Bch81ixZ.d.ts +14 -0
- package/dist/styles/spark-default.css +11 -0
- package/dist/styles/theme.css +15 -4
- package/dist/utils/build-sankey-nodes.cjs +72 -0
- package/dist/utils/build-sankey-nodes.cjs.map +1 -0
- package/dist/utils/build-sankey-nodes.d.cts +27 -0
- package/dist/utils/build-sankey-nodes.d.ts +27 -0
- package/dist/utils/build-sankey-nodes.js +71 -0
- package/dist/utils/build-sankey-nodes.js.map +1 -0
- package/dist/utils/cn.cjs +2 -2
- package/dist/utils/cn.d.cts +1 -1
- package/dist/utils/cn.d.ts +1 -1
- package/dist/utils/cn.js +1 -1
- package/dist/utils/format.cjs +14 -0
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.d.cts +8 -1
- package/dist/utils/format.d.ts +8 -1
- package/dist/utils/format.js +12 -1
- package/dist/utils/format.js.map +1 -1
- package/package.json +1 -1
package/dist/components/pill.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../utils/cn.js";
|
|
3
2
|
import { accentByColor } from "../lib/accent-colors.js";
|
|
4
|
-
import {
|
|
3
|
+
import { cn } from "../utils/cn.js";
|
|
5
4
|
import * as React$1 from "react";
|
|
5
|
+
import { Close } from "@epilot/spark-icons";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/pill.tsx
|
|
8
8
|
/**
|
|
@@ -39,7 +39,7 @@ const Pill = React$1.forwardRef(function Pill({ className, children, styleVarian
|
|
|
39
39
|
"data-accent-color": color ? accentByColor[color] : void 0,
|
|
40
40
|
...interaction,
|
|
41
41
|
ref,
|
|
42
|
-
className: cn("inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none", "bg-(--spark-style-bg,var(--
|
|
42
|
+
className: cn("inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none", "bg-(--spark-style-bg,var(--neutral-a3)) text-(--spark-style-fg,var(--spark-badge-fg,var(--neutral-a11)))", "shadow-[inset_0_0_0_var(--spark-style-border-width,1px)_var(--spark-style-border,transparent)]", focusable && "transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden motion-reduce:transition-none", clickable && "cursor-pointer hover:bg-(--spark-style-bg-hover,var(--neutral-a4))", disabled && "pointer-events-none opacity-50", className),
|
|
43
43
|
...props,
|
|
44
44
|
children: [children, removable ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
45
45
|
className: "sr-only",
|
|
@@ -51,7 +51,7 @@ const Pill = React$1.forwardRef(function Pill({ className, children, styleVarian
|
|
|
51
51
|
event.stopPropagation();
|
|
52
52
|
onRemove?.(event);
|
|
53
53
|
},
|
|
54
|
-
className: "-mr-1 inline-flex size-4 shrink-0 items-center justify-center rounded-full transition-colors hover:bg-(--spark-style-bg-hover,var(--
|
|
54
|
+
className: "-mr-1 inline-flex size-4 shrink-0 items-center justify-center rounded-full transition-colors hover:bg-(--spark-style-bg-hover,var(--neutral-a4)) motion-reduce:transition-none",
|
|
55
55
|
children: /* @__PURE__ */ jsx(Close, { className: "[--spark-icon-size:14px]" })
|
|
56
56
|
})] }) : null]
|
|
57
57
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pill.js","names":["React"],"sources":["../../src/components/pill.tsx"],"sourcesContent":["import { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkAccentColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\ntype PillRemoveProps =\n | { onRemove?: undefined; removeLabel?: string }\n | {\n /** Fires on a pointer click of the (decorative) glyph, or Delete/Backspace while the pill has focus. */\n onRemove: (event: React.SyntheticEvent) => void\n /** Visually-hidden text folded into the pill's accessible name -- the glyph itself is `aria-hidden`. */\n removeLabel: string\n }\n\ntype PillProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'onClick'> &\n PillRemoveProps & {\n styleVariant?: SparkStyle\n color?: SparkAccentColor\n disabled?: boolean\n onClick?: (event: React.SyntheticEvent<HTMLSpanElement>) => void\n }\n\n/**\n * Like Badge, but interactive: `onClick` makes the whole pill a button\n * (Enter/Space), `onRemove` adds a Delete/Backspace-and-click affordance.\n * Both are optional -- with neither, it's a static label.\n */\nconst Pill = React.forwardRef<HTMLSpanElement, PillProps>(function Pill(\n {\n className,\n children,\n styleVariant,\n color,\n disabled = false,\n onClick,\n onRemove,\n removeLabel,\n onKeyDown,\n ...props\n },\n ref,\n) {\n const clickable = !disabled && onClick !== undefined\n const removable = !disabled && onRemove !== undefined\n const focusable = clickable || removable\n const hasLook = styleVariant !== undefined || color !== undefined\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLSpanElement>) => {\n onKeyDown?.(event)\n if (clickable && (event.key === 'Enter' || event.key === ' ')) {\n if (event.key === ' ') event.preventDefault()\n onClick?.(event)\n }\n if (removable && (event.key === 'Delete' || event.key === 'Backspace')) {\n onRemove?.(event)\n }\n }\n\n // button role and click handler travel together, so a clickable pill always\n // answers Enter/Space; a removable-only pill stays generic and answers Delete\n const interaction = {\n onKeyDown: handleKeyDown,\n ...(clickable && { role: 'button' as const, onClick }),\n ...(focusable && { tabIndex: 0 }),\n }\n\n return (\n <span\n aria-disabled={disabled || undefined}\n aria-keyshortcuts={removable ? 'Delete' : undefined}\n data-slot=\"pill\"\n data-style={hasLook ? (styleVariant ?? 'soft') : undefined}\n data-accent-color={color ? accentByColor[color] : undefined}\n {...interaction}\n ref={ref}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none',\n 'bg-(--spark-style-bg,var(--
|
|
1
|
+
{"version":3,"file":"pill.js","names":["React"],"sources":["../../src/components/pill.tsx"],"sourcesContent":["import { Close } from '@epilot/spark-icons'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkAccentColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\ntype PillRemoveProps =\n | { onRemove?: undefined; removeLabel?: string }\n | {\n /** Fires on a pointer click of the (decorative) glyph, or Delete/Backspace while the pill has focus. */\n onRemove: (event: React.SyntheticEvent) => void\n /** Visually-hidden text folded into the pill's accessible name -- the glyph itself is `aria-hidden`. */\n removeLabel: string\n }\n\ntype PillProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'onClick'> &\n PillRemoveProps & {\n styleVariant?: SparkStyle\n color?: SparkAccentColor\n disabled?: boolean\n onClick?: (event: React.SyntheticEvent<HTMLSpanElement>) => void\n }\n\n/**\n * Like Badge, but interactive: `onClick` makes the whole pill a button\n * (Enter/Space), `onRemove` adds a Delete/Backspace-and-click affordance.\n * Both are optional -- with neither, it's a static label.\n */\nconst Pill = React.forwardRef<HTMLSpanElement, PillProps>(function Pill(\n {\n className,\n children,\n styleVariant,\n color,\n disabled = false,\n onClick,\n onRemove,\n removeLabel,\n onKeyDown,\n ...props\n },\n ref,\n) {\n const clickable = !disabled && onClick !== undefined\n const removable = !disabled && onRemove !== undefined\n const focusable = clickable || removable\n const hasLook = styleVariant !== undefined || color !== undefined\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLSpanElement>) => {\n onKeyDown?.(event)\n if (clickable && (event.key === 'Enter' || event.key === ' ')) {\n if (event.key === ' ') event.preventDefault()\n onClick?.(event)\n }\n if (removable && (event.key === 'Delete' || event.key === 'Backspace')) {\n onRemove?.(event)\n }\n }\n\n // button role and click handler travel together, so a clickable pill always\n // answers Enter/Space; a removable-only pill stays generic and answers Delete\n const interaction = {\n onKeyDown: handleKeyDown,\n ...(clickable && { role: 'button' as const, onClick }),\n ...(focusable && { tabIndex: 0 }),\n }\n\n return (\n <span\n aria-disabled={disabled || undefined}\n aria-keyshortcuts={removable ? 'Delete' : undefined}\n data-slot=\"pill\"\n data-style={hasLook ? (styleVariant ?? 'soft') : undefined}\n data-accent-color={color ? accentByColor[color] : undefined}\n {...interaction}\n ref={ref}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none',\n 'bg-(--spark-style-bg,var(--neutral-a3)) text-(--spark-style-fg,var(--spark-badge-fg,var(--neutral-a11)))',\n 'shadow-[inset_0_0_0_var(--spark-style-border-width,1px)_var(--spark-style-border,transparent)]',\n focusable &&\n 'transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden motion-reduce:transition-none',\n clickable &&\n 'cursor-pointer hover:bg-(--spark-style-bg-hover,var(--neutral-a4))',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n {removable ? (\n <>\n {/* aria-hidden hides the glyph itself; this carries removeLabel into the pill's own accessible name */}\n <span className=\"sr-only\">{removeLabel}</span>\n <span\n aria-hidden=\"true\"\n data-slot=\"pill-remove\"\n onClick={(event) => {\n event.stopPropagation()\n onRemove?.(event)\n }}\n className=\"-mr-1 inline-flex size-4 shrink-0 items-center justify-center rounded-full transition-colors hover:bg-(--spark-style-bg-hover,var(--neutral-a4)) motion-reduce:transition-none\"\n >\n <Close className=\"[--spark-icon-size:14px]\" />\n </span>\n </>\n ) : null}\n </span>\n )\n})\n\nPill.displayName = 'Pill'\n\nexport { Pill }\nexport type { PillProps }\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAM,OAAOA,QAAM,WAAuC,SAAS,KACjE,EACE,WACA,UACA,cACA,OACA,WAAW,OACX,SACA,UACA,aACA,WACA,GAAG,SAEL,KACA;CACA,MAAM,YAAY,CAAC,YAAY,YAAY,KAAA;CAC3C,MAAM,YAAY,CAAC,YAAY,aAAa,KAAA;CAC5C,MAAM,YAAY,aAAa;CAC/B,MAAM,UAAU,iBAAiB,KAAA,KAAa,UAAU,KAAA;CAExD,MAAM,iBAAiB,UAAgD;EACrE,YAAY,KAAK;EACjB,IAAI,cAAc,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;GAC7D,IAAI,MAAM,QAAQ,KAAK,MAAM,eAAe;GAC5C,UAAU,KAAK;EACjB;EACA,IAAI,cAAc,MAAM,QAAQ,YAAY,MAAM,QAAQ,cACxD,WAAW,KAAK;CAEpB;CAIA,MAAM,cAAc;EAClB,WAAW;EACX,GAAI,aAAa;GAAE,MAAM;GAAmB;EAAQ;EACpD,GAAI,aAAa,EAAE,UAAU,EAAE;CACjC;CAEA,OACE,qBAAC,QAAD;EACE,iBAAe,YAAY,KAAA;EAC3B,qBAAmB,YAAY,WAAW,KAAA;EAC1C,aAAU;EACV,cAAY,UAAW,gBAAgB,SAAU,KAAA;EACjD,qBAAmB,QAAQ,cAAc,SAAS,KAAA;EAClD,GAAI;EACC;EACL,WAAW,GACT,0FACA,4GACA,kGACA,aACE,iIACF,aACE,sEACF,YAAY,kCACZ,SACF;EACA,GAAI;YAnBN,CAqBG,UACA,YACC,qBAAA,UAAA,EAAA,UAAA,CAEE,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAkB,CAAA,GAC7C,oBAAC,QAAD;GACE,eAAY;GACZ,aAAU;GACV,UAAU,UAAU;IAClB,MAAM,gBAAgB;IACtB,WAAW,KAAK;GAClB;GACA,WAAU;aAEV,oBAAC,OAAD,EAAO,WAAU,2BAA4B,CAAA;EACzC,CAAA,CACN,EAAA,CAAA,IACA,IACA;;AAEV,CAAC;AAED,KAAK,cAAc"}
|
|
@@ -7,7 +7,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
7
7
|
let _base_ui_react_merge_props = require("@base-ui/react/merge-props");
|
|
8
8
|
let _base_ui_react_use_render = require("@base-ui/react/use-render");
|
|
9
9
|
let _base_ui_react_popover = require("@base-ui/react/popover");
|
|
10
|
-
let
|
|
10
|
+
let cn = require("cn");
|
|
11
11
|
//#region src/components/popover.tsx
|
|
12
12
|
const PopoverAnchorContext = react.createContext(null);
|
|
13
13
|
function Popover(props) {
|
|
@@ -56,7 +56,7 @@ function PopoverContent({ className, align = "center", sideOffset = 4, side, ali
|
|
|
56
56
|
sideOffset,
|
|
57
57
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_popover.Popover.Popup, {
|
|
58
58
|
"data-slot": "popover-content",
|
|
59
|
-
className: (0,
|
|
59
|
+
className: (0, cn.cn)("z-50 w-72 origin-(--transform-origin) rounded-lg border border-gray-a1 bg-gray-1 p-4 text-gray-a12 shadow-md outline-hidden transition-[opacity,scale,translate] duration-100 motion-reduce:transition-none", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-2 data-[side=left]:data-starting-style:translate-x-2 data-[side=right]:data-starting-style:-translate-x-2 data-[side=top]:data-starting-style:translate-y-2", "data-ending-style:scale-95 data-ending-style:opacity-0", className),
|
|
60
60
|
...props
|
|
61
61
|
})
|
|
62
62
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.cjs","names":["React","PopoverPrimitive"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import { mergeProps } from '@base-ui/react/merge-props'\nimport { Popover as PopoverPrimitive } from '@base-ui/react/popover'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\n// Base UI dropped the Anchor part; the anchor element registers itself here and\n// PopoverContent feeds it to the Positioner.\nconst PopoverAnchorContext = React.createContext<{\n anchor: HTMLElement | null\n setAnchor: (element: HTMLElement | null) => void\n} | null>(null)\n\nfunction Popover(props: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null)\n const value = React.useMemo(() => ({ anchor, setAnchor }), [anchor])\n return (\n <PopoverAnchorContext.Provider value={value}>\n <PopoverPrimitive.Root {...props} />\n </PopoverAnchorContext.Provider>\n )\n}\n\nfunction PopoverTrigger(\n props: React.ComponentProps<typeof PopoverPrimitive.Trigger>,\n) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\n// A Close part inside the popup is also what enables Base UI's focus trap for modal popovers.\nfunction PopoverClose(\n props: React.ComponentProps<typeof PopoverPrimitive.Close>,\n) {\n return <PopoverPrimitive.Close data-slot=\"popover-close\" {...props} />\n}\n\n/** Anchors the popover to this element instead of the trigger. Pass `render` to\n * wrap an existing element (was radix `asChild`). */\nfunction PopoverAnchor({ render, ...props }: useRender.ComponentProps<'div'>) {\n const context = React.useContext(PopoverAnchorContext)\n return useRender({\n defaultTagName: 'div',\n render,\n ref: context?.setAnchor,\n props: mergeProps<'div'>(\n { 'data-slot': 'popover-anchor' } as React.ComponentProps<'div'>,\n props,\n ),\n })\n}\n\ntype PopoverContentProps = React.ComponentProps<typeof PopoverPrimitive.Popup> &\n Pick<\n PopoverPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'anchor'\n > &\n Pick<PopoverPrimitive.Portal.Props, 'container'>\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n side,\n alignOffset,\n anchor,\n container,\n ...props\n}: PopoverContentProps) {\n const context = React.useContext(PopoverAnchorContext)\n return (\n <PopoverPrimitive.Portal container={container}>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n anchor={anchor ?? context?.anchor ?? undefined}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-content\"\n className={cn(\n 'z-50 w-72 origin-(--transform-origin) rounded-lg border border-gray-a1 bg-gray-1 p-4 text-gray-a12 shadow-md outline-hidden transition-[opacity,scale,translate] duration-100 motion-reduce:transition-none',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-2 data-[side=left]:data-starting-style:translate-x-2 data-[side=right]:data-starting-style:-translate-x-2 data-[side=top]:data-starting-style:translate-y-2',\n // exit: fade + zoom (was animate-out)\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger }\n"],"mappings":";;;;;;;;;;;AAQA,MAAM,uBAAuBA,MAAM,cAGzB,IAAI;AAEd,SAAS,QAAQ,OAA2D;CAC1E,MAAM,CAAC,QAAQ,aAAaA,MAAM,SAA6B,IAAI;CACnE,MAAM,QAAQA,MAAM,eAAe;EAAE;EAAQ;CAAU,IAAI,CAAC,MAAM,CAAC;CACnE,OACE,iBAAA,GAAA,kBAAA,KAAC,qBAAqB,UAAtB;EAAsC;YACpC,iBAAA,GAAA,kBAAA,KAACC,uBAAAA,QAAiB,MAAlB,EAAuB,GAAI,MAAQ,CAAA;CACN,CAAA;AAEnC;AAEA,SAAS,eACP,OACA;CACA,OAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC3E;AAGA,SAAS,aACP,OACA;CACA,OAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;;;AAIA,SAAS,cAAc,EAAE,QAAQ,GAAG,SAA0C;CAE5E,QAAA,GAAA,0BAAA,WAAiB;EACf,gBAAgB;EAChB;EACA,KAJcD,MAAM,WAAW,oBAIpB,GAAG;EACd,QAAA,GAAA,2BAAA,YACE,EAAE,aAAa,iBAAiB,GAChC,KACF;CACF,CAAC;AACH;AASA,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,aAAa,GACb,MACA,aACA,QACA,WACA,GAAG,SACmB;CACtB,MAAM,UAAUA,MAAM,WAAW,oBAAoB;CACrD,OACE,iBAAA,GAAA,kBAAA,KAACC,uBAAAA,QAAiB,QAAlB;EAAoC;YAClC,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,YAAlB;GACS;GACM;GACb,QAAQ,UAAU,SAAS,UAAU,KAAA;GACrC,WAAU;GACJ;GACM;aAEZ,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;IACE,aAAU;IACV,YAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"popover.cjs","names":["React","PopoverPrimitive"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import { mergeProps } from '@base-ui/react/merge-props'\nimport { Popover as PopoverPrimitive } from '@base-ui/react/popover'\nimport { useRender } from '@base-ui/react/use-render'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\n// Base UI dropped the Anchor part; the anchor element registers itself here and\n// PopoverContent feeds it to the Positioner.\nconst PopoverAnchorContext = React.createContext<{\n anchor: HTMLElement | null\n setAnchor: (element: HTMLElement | null) => void\n} | null>(null)\n\nfunction Popover(props: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null)\n const value = React.useMemo(() => ({ anchor, setAnchor }), [anchor])\n return (\n <PopoverAnchorContext.Provider value={value}>\n <PopoverPrimitive.Root {...props} />\n </PopoverAnchorContext.Provider>\n )\n}\n\nfunction PopoverTrigger(\n props: React.ComponentProps<typeof PopoverPrimitive.Trigger>,\n) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\n// A Close part inside the popup is also what enables Base UI's focus trap for modal popovers.\nfunction PopoverClose(\n props: React.ComponentProps<typeof PopoverPrimitive.Close>,\n) {\n return <PopoverPrimitive.Close data-slot=\"popover-close\" {...props} />\n}\n\n/** Anchors the popover to this element instead of the trigger. Pass `render` to\n * wrap an existing element (was radix `asChild`). */\nfunction PopoverAnchor({ render, ...props }: useRender.ComponentProps<'div'>) {\n const context = React.useContext(PopoverAnchorContext)\n return useRender({\n defaultTagName: 'div',\n render,\n ref: context?.setAnchor,\n props: mergeProps<'div'>(\n { 'data-slot': 'popover-anchor' } as React.ComponentProps<'div'>,\n props,\n ),\n })\n}\n\ntype PopoverContentProps = React.ComponentProps<typeof PopoverPrimitive.Popup> &\n Pick<\n PopoverPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'anchor'\n > &\n Pick<PopoverPrimitive.Portal.Props, 'container'>\n\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n side,\n alignOffset,\n anchor,\n container,\n ...props\n}: PopoverContentProps) {\n const context = React.useContext(PopoverAnchorContext)\n return (\n <PopoverPrimitive.Portal container={container}>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n anchor={anchor ?? context?.anchor ?? undefined}\n className=\"isolate z-50\"\n side={side}\n sideOffset={sideOffset}\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-content\"\n className={cn(\n 'z-50 w-72 origin-(--transform-origin) rounded-lg border border-gray-a1 bg-gray-1 p-4 text-gray-a12 shadow-md outline-hidden transition-[opacity,scale,translate] duration-100 motion-reduce:transition-none',\n // enter: fade + zoom + a slight per-side slide (was animate-in)\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-[side=bottom]:data-starting-style:-translate-y-2 data-[side=left]:data-starting-style:translate-x-2 data-[side=right]:data-starting-style:-translate-x-2 data-[side=top]:data-starting-style:translate-y-2',\n // exit: fade + zoom (was animate-out)\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger }\n"],"mappings":";;;;;;;;;;;AAQA,MAAM,uBAAuBA,MAAM,cAGzB,IAAI;AAEd,SAAS,QAAQ,OAA2D;CAC1E,MAAM,CAAC,QAAQ,aAAaA,MAAM,SAA6B,IAAI;CACnE,MAAM,QAAQA,MAAM,eAAe;EAAE;EAAQ;CAAU,IAAI,CAAC,MAAM,CAAC;CACnE,OACE,iBAAA,GAAA,kBAAA,KAAC,qBAAqB,UAAtB;EAAsC;YACpC,iBAAA,GAAA,kBAAA,KAACC,uBAAAA,QAAiB,MAAlB,EAAuB,GAAI,MAAQ,CAAA;CACN,CAAA;AAEnC;AAEA,SAAS,eACP,OACA;CACA,OAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,SAAlB;EAA0B,aAAU;EAAkB,GAAI;CAAQ,CAAA;AAC3E;AAGA,SAAS,aACP,OACA;CACA,OAAO,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;;;AAIA,SAAS,cAAc,EAAE,QAAQ,GAAG,SAA0C;CAE5E,QAAA,GAAA,0BAAA,WAAiB;EACf,gBAAgB;EAChB;EACA,KAJcD,MAAM,WAAW,oBAIpB,GAAG;EACd,QAAA,GAAA,2BAAA,YACE,EAAE,aAAa,iBAAiB,GAChC,KACF;CACF,CAAC;AACH;AASA,SAAS,eAAe,EACtB,WACA,QAAQ,UACR,aAAa,GACb,MACA,aACA,QACA,WACA,GAAG,SACmB;CACtB,MAAM,UAAUA,MAAM,WAAW,oBAAoB;CACrD,OACE,iBAAA,GAAA,kBAAA,KAACC,uBAAAA,QAAiB,QAAlB;EAAoC;YAClC,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,YAAlB;GACS;GACM;GACb,QAAQ,UAAU,SAAS,UAAU,KAAA;GACrC,WAAU;GACJ;GACM;aAEZ,iBAAA,GAAA,kBAAA,KAACA,uBAAAA,QAAiB,OAAlB;IACE,aAAU;IACV,YAAA,GAAA,GAAA,IACE,+MAEA,8DACA,mNAEA,0DACA,SACF;IACA,GAAI;GACL,CAAA;EAC0B,CAAA;CACN,CAAA;AAE7B"}
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const require_chunk = require("../chunk-DY84GLCh.cjs");
|
|
4
|
+
const require_hooks_use_chart_zoom = require("../hooks/use-chart-zoom.cjs");
|
|
5
|
+
const require_hooks_use_reduced_motion = require("../hooks/use-reduced-motion.cjs");
|
|
6
|
+
require("../utils/chars.cjs");
|
|
7
|
+
const require_utils_format = require("../utils/format.cjs");
|
|
8
|
+
const require_utils_chart_scale = require("../utils/chart-scale.cjs");
|
|
9
|
+
const require_utils_chart_time_ticks = require("../utils/chart-time-ticks.cjs");
|
|
10
|
+
const require_components_chart = require("./chart.cjs");
|
|
11
|
+
const require_components_series_legend = require("./series-legend.cjs");
|
|
12
|
+
const require_components_typography = require("./typography.cjs");
|
|
13
|
+
let react = require("react");
|
|
14
|
+
react = require_chunk.__toESM(react);
|
|
15
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
16
|
+
let _visx_event = require("@visx/event");
|
|
17
|
+
let _visx_scale = require("@visx/scale");
|
|
18
|
+
let _visx_shape = require("@visx/shape");
|
|
19
|
+
let _visx_curve = require("@visx/curve");
|
|
20
|
+
let _visx_tooltip = require("@visx/tooltip");
|
|
21
|
+
let _visx_vendor_d3_array = require("@visx/vendor/d3-array");
|
|
22
|
+
let cn = require("cn");
|
|
23
|
+
//#region src/components/power-history-chart.tsx
|
|
24
|
+
const AREA_KEYS = [
|
|
25
|
+
"solar",
|
|
26
|
+
"grid",
|
|
27
|
+
"battery"
|
|
28
|
+
];
|
|
29
|
+
const SERIES_KEYS = [
|
|
30
|
+
"solar",
|
|
31
|
+
"grid",
|
|
32
|
+
"battery",
|
|
33
|
+
"consumption"
|
|
34
|
+
];
|
|
35
|
+
const SERIES_COLORS = {
|
|
36
|
+
solar: "var(--orange-a9)",
|
|
37
|
+
grid: "var(--blue-9)",
|
|
38
|
+
battery: "var(--green-a9)",
|
|
39
|
+
consumption: "var(--neutral-12)"
|
|
40
|
+
};
|
|
41
|
+
const PADDING_TOP = 20;
|
|
42
|
+
const PADDING_BOTTOM = 28;
|
|
43
|
+
const PADDING_RIGHT = 8;
|
|
44
|
+
const X_TICK_COUNT = 6;
|
|
45
|
+
const DEFAULT_HEIGHT = 260;
|
|
46
|
+
const DETAILED_X_AXIS_THRESHOLD = 360 * 60 * 1e3;
|
|
47
|
+
const tBisector = (0, _visx_vendor_d3_array.bisector)((d) => d.t);
|
|
48
|
+
function touchDistance(a, b) {
|
|
49
|
+
return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
|
|
50
|
+
}
|
|
51
|
+
function touchMidpoint(a, b) {
|
|
52
|
+
return {
|
|
53
|
+
clientX: (a.clientX + b.clientX) / 2,
|
|
54
|
+
clientY: (a.clientY + b.clientY) / 2
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Diverging "power sources" area chart over a continuous time axis: solar
|
|
59
|
+
* (orange), grid (blue) and battery (green) areas around a zero baseline, with
|
|
60
|
+
* consumption overlaid as a line. Negative values (grid feed-in, battery
|
|
61
|
+
* charging) dip below zero. For instantaneous power (day view). A legend at the
|
|
62
|
+
* top toggles each series on/off; the y-axis rescales to the visible ones. visx.
|
|
63
|
+
*/
|
|
64
|
+
function PowerHistoryChart({ data, unit, formatX, formatTooltipX, formatValue, labels, omitSeries, highlightAt, title, className, height = DEFAULT_HEIGHT, zoomable = false, zoomResetLabel, zoomDomain, onZoomDomainChange }) {
|
|
65
|
+
const plotClipId = react.useId();
|
|
66
|
+
const fmtTooltipX = formatTooltipX ?? formatX;
|
|
67
|
+
const containerRef = (0, react.useRef)(null);
|
|
68
|
+
const reducedMotion = require_hooks_use_reduced_motion.useReducedMotion();
|
|
69
|
+
const [width, setWidth] = (0, react.useState)(0);
|
|
70
|
+
const [hiddenSeries, setHiddenSeries] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
71
|
+
const omitted = (0, react.useMemo)(() => new Set(omitSeries), [omitSeries]);
|
|
72
|
+
const toggleSeries = (0, react.useCallback)((id) => {
|
|
73
|
+
setHiddenSeries((prev) => {
|
|
74
|
+
const next = new Set(prev);
|
|
75
|
+
if (next.has(id)) next.delete(id);
|
|
76
|
+
else next.add(id);
|
|
77
|
+
return next;
|
|
78
|
+
});
|
|
79
|
+
}, []);
|
|
80
|
+
const isHidden = (0, react.useCallback)((key) => omitted.has(key) || hiddenSeries.has(key), [hiddenSeries, omitted]);
|
|
81
|
+
const { showTooltip, hideTooltip, tooltipData, tooltipLeft, tooltipTop, tooltipOpen } = (0, _visx_tooltip.useTooltip)();
|
|
82
|
+
(0, react.useEffect)(() => {
|
|
83
|
+
const element = containerRef.current;
|
|
84
|
+
if (!element) return;
|
|
85
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
86
|
+
const entry = entries[0];
|
|
87
|
+
if (!entry) return;
|
|
88
|
+
setWidth(entry.contentRect.width);
|
|
89
|
+
});
|
|
90
|
+
resizeObserver.observe(element);
|
|
91
|
+
return () => resizeObserver.disconnect();
|
|
92
|
+
}, []);
|
|
93
|
+
const fmtValue = (value) => formatValue ? formatValue(value) : `${require_utils_format.twoDecimalFormat.format(value)} ${unit}`;
|
|
94
|
+
const tMin = data.length ? data[0]?.t ?? 0 : 0;
|
|
95
|
+
const tMax = data.length ? data[data.length - 1]?.t ?? 0 : 0;
|
|
96
|
+
const zoom = require_hooks_use_chart_zoom.useChartZoom({
|
|
97
|
+
enabled: zoomable,
|
|
98
|
+
fullDomain: (0, react.useMemo)(() => {
|
|
99
|
+
if (data.length === 0) return null;
|
|
100
|
+
return [tMin, tMax];
|
|
101
|
+
}, [
|
|
102
|
+
data.length,
|
|
103
|
+
tMin,
|
|
104
|
+
tMax
|
|
105
|
+
]),
|
|
106
|
+
zoomDomain,
|
|
107
|
+
onZoomDomainChange
|
|
108
|
+
});
|
|
109
|
+
const viewMin = zoom.zoomWindow?.[0] ?? tMin;
|
|
110
|
+
const viewMax = zoom.zoomWindow?.[1] ?? tMax;
|
|
111
|
+
const visibleData = (0, react.useMemo)(() => data.filter((d) => d.t >= viewMin && d.t <= viewMax), [
|
|
112
|
+
data,
|
|
113
|
+
viewMin,
|
|
114
|
+
viewMax
|
|
115
|
+
]);
|
|
116
|
+
const { yMin, yMax } = (0, react.useMemo)(() => {
|
|
117
|
+
let min = 0;
|
|
118
|
+
let max = 0;
|
|
119
|
+
for (const d of visibleData) {
|
|
120
|
+
if (!isHidden("solar")) max = Math.max(max, d.solar);
|
|
121
|
+
if (!isHidden("consumption")) max = Math.max(max, d.consumption);
|
|
122
|
+
if (!isHidden("grid")) {
|
|
123
|
+
max = Math.max(max, d.grid);
|
|
124
|
+
min = Math.min(min, d.grid);
|
|
125
|
+
}
|
|
126
|
+
if (!isHidden("battery")) {
|
|
127
|
+
max = Math.max(max, d.battery);
|
|
128
|
+
min = Math.min(min, d.battery);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
yMin: min,
|
|
133
|
+
yMax: max
|
|
134
|
+
};
|
|
135
|
+
}, [visibleData, isHidden]);
|
|
136
|
+
const { ticks: yTicks, min: lo, max: hi } = (0, react.useMemo)(() => require_utils_chart_scale.buildYAxisScale(yMin, yMax), [yMin, yMax]);
|
|
137
|
+
const displayedYDomain = require_hooks_use_chart_zoom.useAnimatedChartDomain([lo, hi], {
|
|
138
|
+
animateChanges: zoom.isPinching,
|
|
139
|
+
reducedMotion
|
|
140
|
+
});
|
|
141
|
+
const gutter = (0, react.useMemo)(() => require_utils_chart_scale.measureYAxisGutter(yTicks, require_utils_chart_scale.formatYAxisTick), [yTicks]);
|
|
142
|
+
const plotRight = Math.max(gutter, width - PADDING_RIGHT);
|
|
143
|
+
const xScale = (0, react.useMemo)(() => (0, _visx_scale.scaleLinear)({
|
|
144
|
+
domain: [viewMin, viewMax === viewMin ? viewMin + 1 : viewMax],
|
|
145
|
+
range: [gutter, plotRight]
|
|
146
|
+
}), [
|
|
147
|
+
viewMin,
|
|
148
|
+
viewMax,
|
|
149
|
+
plotRight,
|
|
150
|
+
gutter
|
|
151
|
+
]);
|
|
152
|
+
const plotHeight = Math.max(0, height - PADDING_BOTTOM - PADDING_TOP);
|
|
153
|
+
const plotWidth = Math.max(0, plotRight - gutter);
|
|
154
|
+
const yScale = (0, react.useMemo)(() => (0, _visx_scale.scaleLinear)({
|
|
155
|
+
domain: [displayedYDomain[0], displayedYDomain[1] === displayedYDomain[0] ? displayedYDomain[0] + 1 : displayedYDomain[1]],
|
|
156
|
+
range: [height - PADDING_BOTTOM, PADDING_TOP]
|
|
157
|
+
}), [displayedYDomain, height]);
|
|
158
|
+
const xTicks = (0, react.useMemo)(() => require_utils_chart_time_ticks.buildTimeTicks(viewMin, viewMax, X_TICK_COUNT), [viewMin, viewMax]);
|
|
159
|
+
const formatAxisX = zoom.isZoomed && viewMax - viewMin <= DETAILED_X_AXIS_THRESHOLD ? fmtTooltipX : formatX;
|
|
160
|
+
const domainXFromEvent = (0, react.useCallback)((event) => {
|
|
161
|
+
const point = (0, _visx_event.localPoint)(event);
|
|
162
|
+
if (!point) return null;
|
|
163
|
+
return xScale.invert(point.x);
|
|
164
|
+
}, [xScale]);
|
|
165
|
+
const handleTooltip = (0, react.useCallback)((event) => {
|
|
166
|
+
if (zoom.isBrushing || zoom.isPanning) return;
|
|
167
|
+
const point = (0, _visx_event.localPoint)(event);
|
|
168
|
+
if (!point || data.length === 0) return;
|
|
169
|
+
const xMs = xScale.invert(point.x);
|
|
170
|
+
const index = tBisector.left(data, xMs, 1);
|
|
171
|
+
const d0 = data[index - 1];
|
|
172
|
+
const d1 = data[index];
|
|
173
|
+
if (!d0) return;
|
|
174
|
+
const d = d1 && xMs - d0.t > d1.t - xMs ? d1 : d0;
|
|
175
|
+
showTooltip({
|
|
176
|
+
tooltipData: d,
|
|
177
|
+
tooltipLeft: xScale(d.t),
|
|
178
|
+
tooltipTop: PADDING_TOP
|
|
179
|
+
});
|
|
180
|
+
}, [
|
|
181
|
+
data,
|
|
182
|
+
showTooltip,
|
|
183
|
+
xScale,
|
|
184
|
+
zoom.isBrushing,
|
|
185
|
+
zoom.isPanning
|
|
186
|
+
]);
|
|
187
|
+
const legendItems = SERIES_KEYS.filter((key) => !omitted.has(key)).map((key) => ({
|
|
188
|
+
id: key,
|
|
189
|
+
label: labels[key],
|
|
190
|
+
color: SERIES_COLORS[key]
|
|
191
|
+
}));
|
|
192
|
+
const tooltipRows = tooltipData ? SERIES_KEYS.filter((key) => !isHidden(key)).map((key) => ({
|
|
193
|
+
key,
|
|
194
|
+
label: labels[key],
|
|
195
|
+
color: SERIES_COLORS[key],
|
|
196
|
+
value: fmtValue(tooltipData[key])
|
|
197
|
+
})) : [];
|
|
198
|
+
const showHighlight = highlightAt !== void 0 && highlightAt >= viewMin && highlightAt <= viewMax;
|
|
199
|
+
const [tooltipRef, tooltipSize] = require_components_chart.useMeasuredSize();
|
|
200
|
+
const tooltipPos = require_components_chart.clampTooltipPosition({
|
|
201
|
+
anchorX: tooltipLeft ?? 0,
|
|
202
|
+
anchorY: tooltipTop ?? PADDING_TOP,
|
|
203
|
+
width,
|
|
204
|
+
height,
|
|
205
|
+
tipWidth: tooltipSize.width,
|
|
206
|
+
tipHeight: tooltipSize.height,
|
|
207
|
+
placement: "beside"
|
|
208
|
+
});
|
|
209
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
210
|
+
className: (0, cn.cn)("flex w-full flex-col gap-2", className),
|
|
211
|
+
children: [
|
|
212
|
+
title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_typography.SectionTitle, { children: title }),
|
|
213
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_series_legend.SeriesLegend, {
|
|
214
|
+
items: legendItems,
|
|
215
|
+
hiddenIds: hiddenSeries,
|
|
216
|
+
onToggle: toggleSeries
|
|
217
|
+
}),
|
|
218
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
219
|
+
className: "px-1 text-xs text-gray-light",
|
|
220
|
+
children: unit
|
|
221
|
+
}),
|
|
222
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
223
|
+
ref: containerRef,
|
|
224
|
+
className: "relative w-full",
|
|
225
|
+
style: { height },
|
|
226
|
+
children: [
|
|
227
|
+
width > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
228
|
+
width,
|
|
229
|
+
height,
|
|
230
|
+
children: [
|
|
231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("defs", { children: [AREA_KEYS.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("linearGradient", {
|
|
232
|
+
id: `power-history-fill-${key}`,
|
|
233
|
+
x1: "0",
|
|
234
|
+
y1: "0",
|
|
235
|
+
x2: "0",
|
|
236
|
+
y2: "1",
|
|
237
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", {
|
|
238
|
+
offset: "0%",
|
|
239
|
+
stopColor: SERIES_COLORS[key],
|
|
240
|
+
stopOpacity: .35
|
|
241
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", {
|
|
242
|
+
offset: "100%",
|
|
243
|
+
stopColor: SERIES_COLORS[key],
|
|
244
|
+
stopOpacity: .04
|
|
245
|
+
})]
|
|
246
|
+
}, key)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("clipPath", {
|
|
247
|
+
id: plotClipId,
|
|
248
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
249
|
+
height: plotHeight,
|
|
250
|
+
width: plotWidth,
|
|
251
|
+
x: gutter,
|
|
252
|
+
y: PADDING_TOP
|
|
253
|
+
})
|
|
254
|
+
})] }),
|
|
255
|
+
yTicks.map((tick) => {
|
|
256
|
+
const y = yScale(tick);
|
|
257
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
258
|
+
x1: gutter,
|
|
259
|
+
x2: plotRight,
|
|
260
|
+
y1: y,
|
|
261
|
+
y2: y,
|
|
262
|
+
stroke: "var(--neutral-a4)",
|
|
263
|
+
strokeWidth: 1
|
|
264
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
265
|
+
x: gutter - 7,
|
|
266
|
+
y: y + 3,
|
|
267
|
+
textAnchor: "end",
|
|
268
|
+
fill: "var(--neutral-a11)",
|
|
269
|
+
fontSize: 10,
|
|
270
|
+
children: require_utils_chart_scale.formatYAxisTick(tick)
|
|
271
|
+
})] }, `y-tick-${tick}`);
|
|
272
|
+
}),
|
|
273
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
274
|
+
clipPath: `url(#${plotClipId})`,
|
|
275
|
+
"data-testid": "chart-plot-clip",
|
|
276
|
+
children: [
|
|
277
|
+
AREA_KEYS.filter((key) => !isHidden(key)).map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_shape.Area, {
|
|
278
|
+
data,
|
|
279
|
+
x: (d) => xScale(d.t),
|
|
280
|
+
y0: yScale(0),
|
|
281
|
+
y1: (d) => yScale(d[key]),
|
|
282
|
+
curve: _visx_curve.curveMonotoneX,
|
|
283
|
+
fill: `url(#power-history-fill-${key})`,
|
|
284
|
+
stroke: "transparent"
|
|
285
|
+
}, `area-${key}`)),
|
|
286
|
+
AREA_KEYS.filter((key) => !isHidden(key)).map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_shape.LinePath, {
|
|
287
|
+
data,
|
|
288
|
+
x: (d) => xScale(d.t),
|
|
289
|
+
y: (d) => yScale(d[key]),
|
|
290
|
+
curve: _visx_curve.curveMonotoneX,
|
|
291
|
+
stroke: SERIES_COLORS[key],
|
|
292
|
+
strokeWidth: 1.5,
|
|
293
|
+
fill: "none"
|
|
294
|
+
}, `line-${key}`)),
|
|
295
|
+
!isHidden("consumption") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_shape.LinePath, {
|
|
296
|
+
data,
|
|
297
|
+
x: (d) => xScale(d.t),
|
|
298
|
+
y: (d) => yScale(d.consumption),
|
|
299
|
+
curve: _visx_curve.curveMonotoneX,
|
|
300
|
+
stroke: SERIES_COLORS.consumption,
|
|
301
|
+
strokeWidth: 1.5,
|
|
302
|
+
fill: "none"
|
|
303
|
+
})
|
|
304
|
+
]
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
307
|
+
x1: gutter,
|
|
308
|
+
x2: plotRight,
|
|
309
|
+
y1: yScale(0),
|
|
310
|
+
y2: yScale(0),
|
|
311
|
+
stroke: "var(--neutral-a6)",
|
|
312
|
+
strokeWidth: 1
|
|
313
|
+
}),
|
|
314
|
+
showHighlight && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
315
|
+
x1: xScale(highlightAt),
|
|
316
|
+
x2: xScale(highlightAt),
|
|
317
|
+
y1: PADDING_TOP,
|
|
318
|
+
y2: height - PADDING_BOTTOM,
|
|
319
|
+
stroke: "var(--spark-a9)",
|
|
320
|
+
strokeWidth: 1.5,
|
|
321
|
+
strokeDasharray: "5 4",
|
|
322
|
+
pointerEvents: "none"
|
|
323
|
+
}),
|
|
324
|
+
xTicks.map((tick, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
325
|
+
x: xScale(tick),
|
|
326
|
+
y: height - PADDING_BOTTOM + 16,
|
|
327
|
+
textAnchor: index === 0 ? "start" : index === xTicks.length - 1 ? "end" : "middle",
|
|
328
|
+
fill: "var(--neutral-a11)",
|
|
329
|
+
fontSize: 10,
|
|
330
|
+
children: formatAxisX(tick)
|
|
331
|
+
}, `x-tick-${tick}`)),
|
|
332
|
+
tooltipOpen && tooltipData && !zoom.isBrushing && !zoom.isPanning && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
333
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
334
|
+
x1: xScale(tooltipData.t),
|
|
335
|
+
x2: xScale(tooltipData.t),
|
|
336
|
+
y1: PADDING_TOP,
|
|
337
|
+
y2: height - PADDING_BOTTOM,
|
|
338
|
+
stroke: "var(--neutral-a6)",
|
|
339
|
+
strokeDasharray: "4 4",
|
|
340
|
+
pointerEvents: "none"
|
|
341
|
+
}),
|
|
342
|
+
AREA_KEYS.filter((key) => !isHidden(key)).map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
343
|
+
cx: xScale(tooltipData.t),
|
|
344
|
+
cy: yScale(tooltipData[key]),
|
|
345
|
+
r: 3.5,
|
|
346
|
+
fill: SERIES_COLORS[key],
|
|
347
|
+
stroke: "white",
|
|
348
|
+
strokeWidth: 1.5,
|
|
349
|
+
pointerEvents: "none"
|
|
350
|
+
}, `dot-${key}`)),
|
|
351
|
+
!isHidden("consumption") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
352
|
+
cx: xScale(tooltipData.t),
|
|
353
|
+
cy: yScale(tooltipData.consumption),
|
|
354
|
+
r: 3.5,
|
|
355
|
+
fill: SERIES_COLORS.consumption,
|
|
356
|
+
stroke: "white",
|
|
357
|
+
strokeWidth: 1.5,
|
|
358
|
+
pointerEvents: "none"
|
|
359
|
+
})
|
|
360
|
+
] }),
|
|
361
|
+
zoom.brushBand && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
362
|
+
"data-testid": "chart-brush-band",
|
|
363
|
+
x: Math.min(xScale(zoom.brushBand[0]), xScale(zoom.brushBand[1])),
|
|
364
|
+
y: PADDING_TOP,
|
|
365
|
+
width: Math.abs(xScale(zoom.brushBand[1]) - xScale(zoom.brushBand[0])),
|
|
366
|
+
height: plotHeight,
|
|
367
|
+
fill: "var(--spark-a4)",
|
|
368
|
+
pointerEvents: "none"
|
|
369
|
+
}),
|
|
370
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
371
|
+
x: gutter,
|
|
372
|
+
y: PADDING_TOP,
|
|
373
|
+
width: plotWidth,
|
|
374
|
+
height: plotHeight,
|
|
375
|
+
fill: "transparent",
|
|
376
|
+
style: zoomable ? { touchAction: "pan-y" } : void 0,
|
|
377
|
+
onMouseLeave: () => {
|
|
378
|
+
if (!zoom.isBrushing) hideTooltip();
|
|
379
|
+
},
|
|
380
|
+
onMouseMove: (event) => {
|
|
381
|
+
if (zoom.isBrushing) {
|
|
382
|
+
const domainX = domainXFromEvent(event);
|
|
383
|
+
if (domainX != null) zoom.onPointerMove(domainX);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
handleTooltip(event);
|
|
387
|
+
},
|
|
388
|
+
onPointerDown: (event) => {
|
|
389
|
+
if (!zoomable || event.pointerType === "touch") return;
|
|
390
|
+
if (event.button !== 0) return;
|
|
391
|
+
const domainX = domainXFromEvent(event);
|
|
392
|
+
if (domainX == null) return;
|
|
393
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
394
|
+
hideTooltip();
|
|
395
|
+
zoom.onPointerDown(domainX);
|
|
396
|
+
},
|
|
397
|
+
onPointerMove: (event) => {
|
|
398
|
+
if (!zoomable) return;
|
|
399
|
+
const domainX = domainXFromEvent(event);
|
|
400
|
+
if (domainX != null) zoom.onPointerMove(domainX);
|
|
401
|
+
},
|
|
402
|
+
onPointerUp: (event) => {
|
|
403
|
+
if (!zoomable) return;
|
|
404
|
+
const domainX = domainXFromEvent(event);
|
|
405
|
+
if (domainX != null) zoom.onPointerUp(domainX);
|
|
406
|
+
else zoom.onPointerCancel();
|
|
407
|
+
},
|
|
408
|
+
onPointerCancel: () => {
|
|
409
|
+
zoom.onPointerCancel();
|
|
410
|
+
},
|
|
411
|
+
onDoubleClick: () => {
|
|
412
|
+
if (zoomable) zoom.onDoubleClick();
|
|
413
|
+
},
|
|
414
|
+
onTouchStart: (event) => {
|
|
415
|
+
if (!zoomable) return;
|
|
416
|
+
if (event.touches.length === 2) {
|
|
417
|
+
const [a, b] = [event.touches[0], event.touches[1]];
|
|
418
|
+
if (!a || !b) return;
|
|
419
|
+
const point = (0, _visx_event.localPoint)(event.currentTarget, touchMidpoint(a, b));
|
|
420
|
+
if (!point) return;
|
|
421
|
+
const midpoint = Math.min(1, Math.max(0, (point.x - gutter) / plotWidth));
|
|
422
|
+
zoom.onPinchStart(touchDistance(a, b), midpoint);
|
|
423
|
+
hideTooltip();
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (event.touches.length === 1 && zoom.isZoomed) {
|
|
427
|
+
const point = (0, _visx_event.localPoint)(event);
|
|
428
|
+
if (!point) return;
|
|
429
|
+
zoom.onPanStart({
|
|
430
|
+
x: (point.x - gutter) / plotWidth,
|
|
431
|
+
y: (point.y - PADDING_TOP) / plotHeight
|
|
432
|
+
});
|
|
433
|
+
hideTooltip();
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
onTouchMove: (event) => {
|
|
437
|
+
if (zoomable && event.touches.length === 2) {
|
|
438
|
+
const [a, b] = [event.touches[0], event.touches[1]];
|
|
439
|
+
if (!a || !b) return;
|
|
440
|
+
const point = (0, _visx_event.localPoint)(event.currentTarget, touchMidpoint(a, b));
|
|
441
|
+
if (!point) return;
|
|
442
|
+
const midpoint = Math.min(1, Math.max(0, (point.x - gutter) / plotWidth));
|
|
443
|
+
zoom.onPinchMove(touchDistance(a, b), midpoint);
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (event.touches.length === 1 && zoom.isZoomed) {
|
|
447
|
+
const point = (0, _visx_event.localPoint)(event);
|
|
448
|
+
if (!point) return;
|
|
449
|
+
zoom.onPanMove({
|
|
450
|
+
x: (point.x - gutter) / plotWidth,
|
|
451
|
+
y: (point.y - PADDING_TOP) / plotHeight
|
|
452
|
+
});
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
if (event.touches.length === 1) handleTooltip(event);
|
|
456
|
+
},
|
|
457
|
+
onTouchEnd: (event) => {
|
|
458
|
+
if (zoomable && event.touches.length < 2) zoom.onPinchEnd();
|
|
459
|
+
if (event.touches.length === 0) {
|
|
460
|
+
if (zoomable) zoom.onPanEnd();
|
|
461
|
+
if (zoomable) zoom.onTap();
|
|
462
|
+
hideTooltip();
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
onTouchCancel: () => {
|
|
466
|
+
zoom.onPinchEnd();
|
|
467
|
+
zoom.onPanEnd();
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
]
|
|
471
|
+
}),
|
|
472
|
+
zoom.isZoomed && zoomResetLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_chart.ChartZoomResetButton, {
|
|
473
|
+
label: zoomResetLabel,
|
|
474
|
+
onReset: zoom.resetZoom
|
|
475
|
+
}),
|
|
476
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
477
|
+
ref: tooltipRef,
|
|
478
|
+
className: "pointer-events-none absolute z-10",
|
|
479
|
+
style: {
|
|
480
|
+
left: tooltipPos.left,
|
|
481
|
+
top: tooltipPos.top,
|
|
482
|
+
opacity: tooltipOpen && tooltipData && !zoom.isPanning && !zoom.isBrushing ? 1 : 0,
|
|
483
|
+
transition: reducedMotion ? "opacity 140ms ease-out" : "left 140ms ease-out, top 140ms ease-out, opacity 140ms ease-out"
|
|
484
|
+
},
|
|
485
|
+
children: tooltipData && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_chart.ChartTooltipCard, {
|
|
486
|
+
label: fmtTooltipX(tooltipData.t),
|
|
487
|
+
rows: tooltipRows
|
|
488
|
+
})
|
|
489
|
+
})
|
|
490
|
+
]
|
|
491
|
+
})
|
|
492
|
+
]
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
//#endregion
|
|
496
|
+
exports.PowerHistoryChart = PowerHistoryChart;
|
|
497
|
+
|
|
498
|
+
//# sourceMappingURL=power-history-chart.cjs.map
|