@galaxy-io/dls 1.2.7 → 1.3.1
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/README.md +2 -0
- package/dist/avatar/Avatar.d.ts +2 -1
- package/dist/avatar/Avatar.js +103 -14
- package/dist/buttons/Button.d.ts +6 -1
- package/dist/buttons/Button.js +8 -4
- package/dist/charts/BarChart.d.ts +30 -20
- package/dist/charts/BarChart.js +183 -253
- package/dist/charts/ChartAxis.d.ts +47 -22
- package/dist/charts/ChartAxis.js +81 -60
- package/dist/charts/ChartCategoryTargets.d.ts +27 -0
- package/dist/charts/ChartCategoryTargets.js +75 -0
- package/dist/charts/ChartEmptyState.d.ts +17 -0
- package/dist/charts/ChartEmptyState.js +29 -0
- package/dist/charts/ChartFrame.d.ts +110 -0
- package/dist/charts/ChartFrame.js +143 -0
- package/dist/charts/ChartLegend.d.ts +27 -4
- package/dist/charts/ChartLegend.js +46 -23
- package/dist/charts/ChartPrimitives.d.ts +230 -0
- package/dist/charts/ChartPrimitives.js +305 -0
- package/dist/charts/ChartTooltip.d.ts +25 -4
- package/dist/charts/ChartTooltip.js +55 -49
- package/dist/charts/LineChart.d.ts +42 -20
- package/dist/charts/LineChart.js +175 -241
- package/dist/charts/PieChart.d.ts +48 -32
- package/dist/charts/PieChart.js +180 -170
- package/dist/charts/barChartGeometry.d.ts +120 -0
- package/dist/charts/barChartGeometry.js +210 -0
- package/dist/charts/barChartLegend.d.ts +25 -0
- package/dist/charts/barChartLegend.js +23 -0
- package/dist/charts/chartFormat.d.ts +27 -0
- package/dist/charts/chartFormat.js +71 -0
- package/dist/charts/chartScales.d.ts +120 -0
- package/dist/charts/chartScales.js +165 -0
- package/dist/charts/chartTheme.d.ts +18 -0
- package/dist/charts/chartTheme.js +26 -0
- package/dist/charts/constants.d.ts +241 -18
- package/dist/charts/constants.js +261 -32
- package/dist/charts/lineChartGeometry.d.ts +92 -0
- package/dist/charts/lineChartGeometry.js +134 -0
- package/dist/charts/pieChartGeometry.d.ts +60 -0
- package/dist/charts/pieChartGeometry.js +79 -0
- package/dist/charts/types.d.ts +428 -54
- package/dist/charts/types.js +155 -0
- package/dist/charts/useCartesianChartLayout.d.ts +70 -0
- package/dist/charts/useCartesianChartLayout.js +56 -0
- package/dist/charts/useChartDimensions.d.ts +47 -0
- package/dist/charts/useChartDimensions.js +63 -0
- package/dist/charts/useChartFormatters.d.ts +19 -0
- package/dist/charts/useChartFormatters.js +20 -0
- package/dist/charts/useChartInteraction.d.ts +76 -0
- package/dist/charts/useChartInteraction.js +126 -0
- package/dist/charts/useChartTooltipPosition.d.ts +53 -0
- package/dist/charts/useChartTooltipPosition.js +39 -0
- package/dist/charts/useSeriesColorResolver.d.ts +37 -0
- package/dist/charts/useSeriesColorResolver.js +27 -0
- package/dist/hooks/useElementClientSize.d.ts +20 -0
- package/dist/hooks/useElementClientSize.js +43 -0
- package/dist/inputs/CheckboxInput.d.ts +7 -2
- package/dist/inputs/CheckboxInput.js +30 -14
- package/dist/inputs/Input.d.ts +1 -1
- package/dist/inputs/Input.js +6 -2
- package/dist/inputs/MultiSelectInput.js +1 -1
- package/dist/inputs/RadioInput.js +7 -2
- package/dist/styles.css +69 -74
- package/dist/table/InfiniteSpreadsheet.d.ts +6 -0
- package/dist/table/InfiniteSpreadsheet.js +235 -0
- package/dist/table/InfiniteTable.d.ts +7 -88
- package/dist/table/InfiniteTable.js +366 -577
- package/dist/{spreadsheet → table}/SpreadsheetCell.d.ts +6 -4
- package/dist/table/SpreadsheetCell.js +71 -0
- package/dist/{spreadsheet → table}/SpreadsheetCellEditor.js +27 -21
- package/dist/table/SpreadsheetHeaderCell.d.ts +23 -0
- package/dist/table/SpreadsheetHeaderCell.js +91 -0
- package/dist/table/SpreadsheetMenuItem.d.ts +14 -0
- package/dist/table/SpreadsheetMenuItem.js +33 -0
- package/dist/table/SpreadsheetPrimitives.d.ts +172 -0
- package/dist/table/SpreadsheetPrimitives.js +105 -0
- package/dist/table/SpreadsheetRow.d.ts +33 -0
- package/dist/table/SpreadsheetRow.js +73 -0
- package/dist/{spreadsheet → table}/SpreadsheetRowActionCell.d.ts +5 -7
- package/dist/table/SpreadsheetRowActionCell.js +51 -0
- package/dist/table/TableExpandCell.d.ts +11 -0
- package/dist/table/TableExpandCell.js +24 -0
- package/dist/table/TableExpandedRow.d.ts +16 -0
- package/dist/table/TableExpandedRow.js +77 -0
- package/dist/table/TableHeaderCellContent.d.ts +30 -0
- package/dist/table/TableHeaderCellContent.js +48 -0
- package/dist/table/TablePrimitives.d.ts +307 -0
- package/dist/table/TablePrimitives.js +298 -0
- package/dist/table/TableSelectCell.d.ts +18 -0
- package/dist/table/TableSelectCell.js +26 -0
- package/dist/table/TableStatusRow.d.ts +18 -0
- package/dist/table/TableStatusRow.js +50 -0
- package/dist/table/VirtualizedInfiniteTable.d.ts +11 -27
- package/dist/table/VirtualizedInfiniteTable.js +182 -317
- package/dist/table/types.d.ts +249 -0
- package/dist/table/types.js +51 -0
- package/dist/table/useInfiniteScrollSentinel.d.ts +24 -0
- package/dist/table/useInfiniteScrollSentinel.js +53 -0
- package/dist/{spreadsheet/hooks → table}/useSpreadsheetEditing.d.ts +1 -1
- package/dist/{spreadsheet/hooks → table}/useSpreadsheetEditing.js +1 -1
- package/dist/table/useTableColumnLayout.d.ts +28 -0
- package/dist/table/useTableColumnLayout.js +63 -0
- package/dist/table/useTableColumnResize.d.ts +38 -0
- package/dist/table/useTableColumnResize.js +155 -0
- package/dist/table/useTableKeyboardNavigation.d.ts +25 -0
- package/dist/table/useTableKeyboardNavigation.js +83 -0
- package/dist/table/useTableRowExpansion.d.ts +24 -0
- package/dist/table/useTableRowExpansion.js +62 -0
- package/dist/table/useTableRowSelection.d.ts +27 -0
- package/dist/table/useTableRowSelection.js +94 -0
- package/dist/table/utils.d.ts +50 -0
- package/dist/table/utils.js +78 -0
- package/dist/text/MarkdownText.js +45 -27
- package/dist/theme/variants/dark.js +1 -1
- package/dist/widget/Widget.d.ts +2 -0
- package/dist/widget/Widget.js +14 -7
- package/package.json +1 -5
- package/dist/assets/components/enrichment/PerplexityIcon.d.ts +0 -3
- package/dist/assets/components/enrichment/PerplexityIcon.js +0 -35
- package/dist/assets/components/enrichment/TavilyIcon.d.ts +0 -3
- package/dist/assets/components/enrichment/TavilyIcon.js +0 -15
- package/dist/assets/components/onboarding/TenantSetupDark.d.ts +0 -3
- package/dist/assets/components/onboarding/TenantSetupDark.js +0 -498
- package/dist/assets/components/onboarding/TenantSetupLight.d.ts +0 -3
- package/dist/assets/components/onboarding/TenantSetupLight.js +0 -482
- package/dist/assets/components/onboarding/UserSetupDark.d.ts +0 -3
- package/dist/assets/components/onboarding/UserSetupDark.js +0 -1086
- package/dist/assets/components/onboarding/UserSetupLight.d.ts +0 -3
- package/dist/assets/components/onboarding/UserSetupLight.js +0 -1024
- package/dist/assets/components/onboarding/WorkspaceSetupBuildDark.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupBuildDark.js +0 -466
- package/dist/assets/components/onboarding/WorkspaceSetupBuildLight.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupBuildLight.js +0 -460
- package/dist/assets/components/onboarding/WorkspaceSetupConnectDark.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupConnectDark.js +0 -336
- package/dist/assets/components/onboarding/WorkspaceSetupConnectLight.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupConnectLight.js +0 -336
- package/dist/assets/components/onboarding/WorkspaceSetupIntegrateDark.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupIntegrateDark.js +0 -153
- package/dist/assets/components/onboarding/WorkspaceSetupIntegrateLight.d.ts +0 -3
- package/dist/assets/components/onboarding/WorkspaceSetupIntegrateLight.js +0 -153
- package/dist/assets/components/projects/MappingMethodAutoIntrospectDark.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodAutoIntrospectDark.js +0 -117
- package/dist/assets/components/projects/MappingMethodAutoIntrospectLight.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodAutoIntrospectLight.js +0 -117
- package/dist/assets/components/projects/MappingMethodBlankDark.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodBlankDark.js +0 -150
- package/dist/assets/components/projects/MappingMethodBlankDarkHovered.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodBlankDarkHovered.js +0 -150
- package/dist/assets/components/projects/MappingMethodBlankLight.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodBlankLight.js +0 -150
- package/dist/assets/components/projects/MappingMethodBlankLightHovered.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodBlankLightHovered.js +0 -150
- package/dist/assets/components/projects/MappingMethodJsonDark.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodJsonDark.js +0 -90
- package/dist/assets/components/projects/MappingMethodJsonDarkHovered.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodJsonDarkHovered.js +0 -90
- package/dist/assets/components/projects/MappingMethodJsonLight.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodJsonLight.js +0 -90
- package/dist/assets/components/projects/MappingMethodJsonLightHovered.d.ts +0 -3
- package/dist/assets/components/projects/MappingMethodJsonLightHovered.js +0 -90
- package/dist/assets/components/projects/ProjectsEmptyStateDark.d.ts +0 -3
- package/dist/assets/components/projects/ProjectsEmptyStateDark.js +0 -454
- package/dist/assets/components/projects/ProjectsEmptyStateLight.d.ts +0 -3
- package/dist/assets/components/projects/ProjectsEmptyStateLight.js +0 -456
- package/dist/assets/components/root/CreateProjectActionCardDark.d.ts +0 -3
- package/dist/assets/components/root/CreateProjectActionCardDark.js +0 -1796
- package/dist/assets/components/root/CreateProjectActionCardDarkHovered.d.ts +0 -3
- package/dist/assets/components/root/CreateProjectActionCardDarkHovered.js +0 -1796
- package/dist/assets/components/root/CreateProjectActionCardLight.d.ts +0 -3
- package/dist/assets/components/root/CreateProjectActionCardLight.js +0 -1786
- package/dist/assets/components/root/CreateProjectActionCardLightHovered.d.ts +0 -3
- package/dist/assets/components/root/CreateProjectActionCardLightHovered.js +0 -1786
- package/dist/assets/components/root/CreateSourceActionCardDark.d.ts +0 -3
- package/dist/assets/components/root/CreateSourceActionCardDark.js +0 -879
- package/dist/assets/components/root/CreateSourceActionCardDarkHovered.d.ts +0 -3
- package/dist/assets/components/root/CreateSourceActionCardDarkHovered.js +0 -879
- package/dist/assets/components/root/CreateSourceActionCardLight.d.ts +0 -3
- package/dist/assets/components/root/CreateSourceActionCardLight.js +0 -889
- package/dist/assets/components/root/CreateSourceActionCardLightHovered.d.ts +0 -3
- package/dist/assets/components/root/CreateSourceActionCardLightHovered.js +0 -889
- package/dist/assets/components/sources/AttioIcon.d.ts +0 -3
- package/dist/assets/components/sources/AttioIcon.js +0 -11
- package/dist/assets/components/sources/BigquerySourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/BigquerySourceIcon.js +0 -39
- package/dist/assets/components/sources/BrowserbaseSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/BrowserbaseSourceIcon.js +0 -35
- package/dist/assets/components/sources/ClickhouseLogoSourceIconDark.d.ts +0 -3
- package/dist/assets/components/sources/ClickhouseLogoSourceIconDark.js +0 -13
- package/dist/assets/components/sources/ClickhouseLogoSourceIconLight.d.ts +0 -3
- package/dist/assets/components/sources/ClickhouseLogoSourceIconLight.js +0 -13
- package/dist/assets/components/sources/ConfluenceSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/ConfluenceSourceIcon.js +0 -30
- package/dist/assets/components/sources/GithubSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/GithubSourceIcon.js +0 -27
- package/dist/assets/components/sources/GoogleDriveIcon.d.ts +0 -3
- package/dist/assets/components/sources/GoogleDriveIcon.js +0 -45
- package/dist/assets/components/sources/HubspotSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/HubspotSourceIcon.js +0 -14
- package/dist/assets/components/sources/JiraSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/JiraSourceIcon.js +0 -54
- package/dist/assets/components/sources/LinearSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/LinearSourceIcon.js +0 -14
- package/dist/assets/components/sources/MysqlLogoSourceIconDark.d.ts +0 -3
- package/dist/assets/components/sources/MysqlLogoSourceIconDark.js +0 -17
- package/dist/assets/components/sources/NetsuiteSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/NetsuiteSourceIcon.js +0 -32
- package/dist/assets/components/sources/NotionIcon.d.ts +0 -3
- package/dist/assets/components/sources/NotionIcon.js +0 -20
- package/dist/assets/components/sources/PostgresqlIcon.d.ts +0 -3
- package/dist/assets/components/sources/PostgresqlIcon.js +0 -61
- package/dist/assets/components/sources/S3Icon.d.ts +0 -3
- package/dist/assets/components/sources/S3Icon.js +0 -76
- package/dist/assets/components/sources/SalesforceSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/SalesforceSourceIcon.js +0 -23
- package/dist/assets/components/sources/SlackIcon.d.ts +0 -3
- package/dist/assets/components/sources/SlackIcon.js +0 -32
- package/dist/assets/components/sources/SnowflakeLogoSourceIconDark.d.ts +0 -3
- package/dist/assets/components/sources/SnowflakeLogoSourceIconDark.js +0 -14
- package/dist/assets/components/sources/SnowflakeLogoSourceIconLight.d.ts +0 -3
- package/dist/assets/components/sources/SnowflakeLogoSourceIconLight.js +0 -14
- package/dist/assets/components/sources/WikipediaSourceIcon.d.ts +0 -3
- package/dist/assets/components/sources/WikipediaSourceIcon.js +0 -1490
- package/dist/avatar/AvatarEmpty.d.ts +0 -7
- package/dist/avatar/AvatarEmpty.js +0 -99
- package/dist/avatar/types.d.ts +0 -5
- package/dist/avatar/types.js +0 -9
- package/dist/charts/utils.d.ts +0 -29
- package/dist/charts/utils.js +0 -62
- package/dist/icons/BackIcon.d.ts +0 -3
- package/dist/icons/BackIcon.js +0 -13
- package/dist/icons/CloseIcon.d.ts +0 -3
- package/dist/icons/CloseIcon.js +0 -13
- package/dist/icons/CreateIcon.d.ts +0 -3
- package/dist/icons/CreateIcon.js +0 -13
- package/dist/icons/ForwardIcon.d.ts +0 -3
- package/dist/icons/ForwardIcon.js +0 -13
- package/dist/icons/HelpIcon.d.ts +0 -3
- package/dist/icons/HelpIcon.js +0 -14
- package/dist/icons/ProjectsIcon.d.ts +0 -3
- package/dist/icons/ProjectsIcon.js +0 -12
- package/dist/icons/SearchIcon.d.ts +0 -3
- package/dist/icons/SearchIcon.js +0 -12
- package/dist/icons/SourcesIcon.d.ts +0 -3
- package/dist/icons/SourcesIcon.js +0 -12
- package/dist/icons/TextIcon.d.ts +0 -4
- package/dist/icons/TextIcon.js +0 -22
- package/dist/icons/WebScrapeIcon.d.ts +0 -4
- package/dist/icons/WebScrapeIcon.js +0 -22
- package/dist/icons/WebhookIcon.d.ts +0 -4
- package/dist/icons/WebhookIcon.js +0 -22
- package/dist/icons/sources/AttioLogomark.d.ts +0 -4
- package/dist/icons/sources/AttioLogomark.js +0 -8
- package/dist/icons/sources/BrowserbaseLogomark.d.ts +0 -4
- package/dist/icons/sources/BrowserbaseLogomark.js +0 -8
- package/dist/icons/sources/ClickhouseLogomark.d.ts +0 -4
- package/dist/icons/sources/ClickhouseLogomark.js +0 -16
- package/dist/icons/sources/ConfluenceLogomark.d.ts +0 -4
- package/dist/icons/sources/ConfluenceLogomark.js +0 -8
- package/dist/icons/sources/GithubLogomark.d.ts +0 -4
- package/dist/icons/sources/GithubLogomark.js +0 -8
- package/dist/icons/sources/GoogleBigqueryLogomark.d.ts +0 -4
- package/dist/icons/sources/GoogleBigqueryLogomark.js +0 -8
- package/dist/icons/sources/GoogleDriveLogomark.d.ts +0 -4
- package/dist/icons/sources/GoogleDriveLogomark.js +0 -8
- package/dist/icons/sources/HubspotLogomark.d.ts +0 -4
- package/dist/icons/sources/HubspotLogomark.js +0 -8
- package/dist/icons/sources/JiraLogomark.d.ts +0 -4
- package/dist/icons/sources/JiraLogomark.js +0 -8
- package/dist/icons/sources/LinearLogomark.d.ts +0 -4
- package/dist/icons/sources/LinearLogomark.js +0 -8
- package/dist/icons/sources/MySQLLogomark.d.ts +0 -4
- package/dist/icons/sources/MySQLLogomark.js +0 -8
- package/dist/icons/sources/NetsuiteLogomark.d.ts +0 -4
- package/dist/icons/sources/NetsuiteLogomark.js +0 -8
- package/dist/icons/sources/NotionLogomark.d.ts +0 -4
- package/dist/icons/sources/NotionLogomark.js +0 -8
- package/dist/icons/sources/PostgresLogomark.d.ts +0 -4
- package/dist/icons/sources/PostgresLogomark.js +0 -8
- package/dist/icons/sources/S3Logomark.d.ts +0 -4
- package/dist/icons/sources/S3Logomark.js +0 -8
- package/dist/icons/sources/SalesforceLogomark.d.ts +0 -4
- package/dist/icons/sources/SalesforceLogomark.js +0 -8
- package/dist/icons/sources/SlackLogoIconmark.d.ts +0 -4
- package/dist/icons/sources/SlackLogoIconmark.js +0 -8
- package/dist/icons/sources/SnowflakeLogomark.d.ts +0 -4
- package/dist/icons/sources/SnowflakeLogomark.js +0 -16
- package/dist/icons/sources/WikipediaLogomark.d.ts +0 -4
- package/dist/icons/sources/WikipediaLogomark.js +0 -8
- package/dist/spreadsheet/InfiniteSpreadsheet.d.ts +0 -3
- package/dist/spreadsheet/InfiniteSpreadsheet.js +0 -265
- package/dist/spreadsheet/SpreadsheetAddColumnButton.d.ts +0 -6
- package/dist/spreadsheet/SpreadsheetAddColumnButton.js +0 -32
- package/dist/spreadsheet/SpreadsheetCell.js +0 -115
- package/dist/spreadsheet/SpreadsheetHeaderCell.d.ts +0 -18
- package/dist/spreadsheet/SpreadsheetHeaderCell.js +0 -141
- package/dist/spreadsheet/SpreadsheetRow.d.ts +0 -21
- package/dist/spreadsheet/SpreadsheetRow.js +0 -68
- package/dist/spreadsheet/SpreadsheetRowActionCell.js +0 -78
- package/dist/spreadsheet/hooks/useColumnResize.d.ts +0 -6
- package/dist/spreadsheet/hooks/useColumnResize.js +0 -46
- package/dist/spreadsheet/types.d.ts +0 -92
- package/dist/spreadsheet/types.js +0 -21
- /package/dist/{spreadsheet → table}/SpreadsheetCellEditor.d.ts +0 -0
package/dist/charts/ChartAxis.js
CHANGED
|
@@ -1,18 +1,49 @@
|
|
|
1
1
|
import Text, { TextSize, TextVariant } from "../text/Text.js";
|
|
2
2
|
import FlexWrapper, { AlignItems, JustifyContent } from "../containers/FlexWrapper.js";
|
|
3
|
+
import { ChartCategoryLabelMode } from "./types.js";
|
|
3
4
|
import "./constants.js";
|
|
4
|
-
import {
|
|
5
|
+
import { getCategoryLabelStride } from "./chartScales.js";
|
|
6
|
+
import { ChartAxisLabelBox, ChartGridLine } from "./ChartPrimitives.js";
|
|
5
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
8
|
//#region src/charts/ChartAxis.tsx
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
var ChartValueAxis = ({ ticks, scale, plotWidth, plotHeight, marginLeft, formatter, showGrid = true, title }) => {
|
|
10
|
+
const titleBand = title ? 26 : 0;
|
|
11
|
+
const labelWidth = Math.max(0, marginLeft - titleBand - 12);
|
|
12
|
+
return /* @__PURE__ */ jsxs("g", {
|
|
13
|
+
"aria-hidden": true,
|
|
14
|
+
children: [ticks.map((tick) => /* @__PURE__ */ jsxs("g", {
|
|
15
|
+
transform: `translate(0, ${scale(tick)})`,
|
|
16
|
+
children: [showGrid && /* @__PURE__ */ jsx(ChartGridLine, {
|
|
17
|
+
x1: -12,
|
|
18
|
+
x2: plotWidth + 12,
|
|
19
|
+
y1: 0,
|
|
20
|
+
y2: 0
|
|
21
|
+
}), labelWidth > 0 && /* @__PURE__ */ jsx(ChartAxisLabelBox, {
|
|
22
|
+
x: -marginLeft + titleBand,
|
|
23
|
+
y: -20 / 2,
|
|
24
|
+
width: labelWidth,
|
|
25
|
+
height: 20,
|
|
26
|
+
children: /* @__PURE__ */ jsx(FlexWrapper, {
|
|
27
|
+
justifyContent: JustifyContent.END,
|
|
28
|
+
alignItems: AlignItems.CENTER,
|
|
29
|
+
fillWidth: true,
|
|
30
|
+
fillHeight: true,
|
|
31
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
32
|
+
size: TextSize.CAPTION,
|
|
33
|
+
variant: TextVariant.TERTIARY,
|
|
34
|
+
align: "right",
|
|
35
|
+
isEllipsis: true,
|
|
36
|
+
children: formatter(tick)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
})]
|
|
40
|
+
}, tick)), title && /* @__PURE__ */ jsx("g", {
|
|
41
|
+
transform: `translate(${-marginLeft + 18 / 2}, ${plotHeight / 2}) rotate(-90)`,
|
|
42
|
+
children: /* @__PURE__ */ jsx(ChartAxisLabelBox, {
|
|
43
|
+
x: -plotHeight / 2,
|
|
44
|
+
y: -18 / 2,
|
|
45
|
+
width: plotHeight,
|
|
46
|
+
height: 18,
|
|
16
47
|
children: /* @__PURE__ */ jsx(FlexWrapper, {
|
|
17
48
|
justifyContent: JustifyContent.CENTER,
|
|
18
49
|
alignItems: AlignItems.CENTER,
|
|
@@ -22,22 +53,28 @@ var XAxis = ({ scale, transform, formatter = defaultLabelFormatter }) => {
|
|
|
22
53
|
size: TextSize.CAPTION,
|
|
23
54
|
variant: TextVariant.TERTIARY,
|
|
24
55
|
align: "center",
|
|
25
|
-
|
|
56
|
+
isEllipsis: true,
|
|
57
|
+
children: title
|
|
26
58
|
})
|
|
27
59
|
})
|
|
28
|
-
}
|
|
29
|
-
})
|
|
60
|
+
})
|
|
61
|
+
})]
|
|
30
62
|
});
|
|
31
63
|
};
|
|
32
|
-
var
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
64
|
+
var ChartCategoryAxis = ({ labels, positions, step, plotWidth, plotHeight, formatter, mode = ChartCategoryLabelMode.AUTO, title }) => {
|
|
65
|
+
const formatted = labels.map(formatter);
|
|
66
|
+
const stride = mode === ChartCategoryLabelMode.AUTO ? getCategoryLabelStride(formatted, step) : 1;
|
|
67
|
+
const labelWidth = step * stride;
|
|
68
|
+
const labelInset = (labelWidth - step) / 2;
|
|
69
|
+
return /* @__PURE__ */ jsxs("g", {
|
|
70
|
+
transform: `translate(0, ${plotHeight})`,
|
|
71
|
+
"aria-hidden": true,
|
|
72
|
+
children: [formatted.map((label, index) => {
|
|
73
|
+
if (index % stride !== 0) return null;
|
|
74
|
+
return /* @__PURE__ */ jsx(ChartAxisLabelBox, {
|
|
75
|
+
x: positions[index] - labelInset,
|
|
39
76
|
y: 8,
|
|
40
|
-
width:
|
|
77
|
+
width: labelWidth,
|
|
41
78
|
height: 24,
|
|
42
79
|
children: /* @__PURE__ */ jsx(FlexWrapper, {
|
|
43
80
|
justifyContent: JustifyContent.CENTER,
|
|
@@ -48,47 +85,31 @@ var XAxisPoint = ({ scale, transform, formatter = defaultLabelFormatter }) => {
|
|
|
48
85
|
size: TextSize.CAPTION,
|
|
49
86
|
variant: TextVariant.TERTIARY,
|
|
50
87
|
align: "center",
|
|
51
|
-
|
|
88
|
+
isEllipsis: mode !== ChartCategoryLabelMode.ALL,
|
|
89
|
+
children: label
|
|
52
90
|
})
|
|
53
91
|
})
|
|
54
|
-
}, label);
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
children: /* @__PURE__ */ jsx(Text, {
|
|
75
|
-
size: TextSize.CAPTION,
|
|
76
|
-
variant: TextVariant.TERTIARY,
|
|
77
|
-
children: formatter(tick)
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
}), showGrid && /* @__PURE__ */ jsx("line", {
|
|
81
|
-
x1: 0,
|
|
82
|
-
x2: plotWidth,
|
|
83
|
-
y1: 0,
|
|
84
|
-
y2: 0,
|
|
85
|
-
stroke: theme.color.border.primary,
|
|
86
|
-
strokeOpacity: .5,
|
|
87
|
-
strokeDasharray: "2,2"
|
|
88
|
-
})]
|
|
89
|
-
}, tick);
|
|
90
|
-
})
|
|
92
|
+
}, `${index}:${label}`);
|
|
93
|
+
}), title && /* @__PURE__ */ jsx(ChartAxisLabelBox, {
|
|
94
|
+
x: 0,
|
|
95
|
+
y: 32,
|
|
96
|
+
width: plotWidth,
|
|
97
|
+
height: 18,
|
|
98
|
+
children: /* @__PURE__ */ jsx(FlexWrapper, {
|
|
99
|
+
justifyContent: JustifyContent.CENTER,
|
|
100
|
+
alignItems: AlignItems.CENTER,
|
|
101
|
+
fillWidth: true,
|
|
102
|
+
fillHeight: true,
|
|
103
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
104
|
+
size: TextSize.CAPTION,
|
|
105
|
+
variant: TextVariant.TERTIARY,
|
|
106
|
+
align: "center",
|
|
107
|
+
isEllipsis: true,
|
|
108
|
+
children: title
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
})]
|
|
91
112
|
});
|
|
92
113
|
};
|
|
93
114
|
//#endregion
|
|
94
|
-
export {
|
|
115
|
+
export { ChartCategoryAxis, ChartValueAxis };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ChartCategoryTarget } from "./types";
|
|
2
|
+
import type { ChartInteraction } from "./useChartInteraction";
|
|
3
|
+
/**
|
|
4
|
+
* The interactive layer: one focusable target per category, above the marks.
|
|
5
|
+
*
|
|
6
|
+
* Shared by all three charts so pointer and keyboard behave identically. Before
|
|
7
|
+
* this existed each chart spelled hit testing its own way — two rendered targets
|
|
8
|
+
* conditionally, the pie attached handlers permanently and computed
|
|
9
|
+
* `data-interactive` instead — and none of them was reachable by keyboard at
|
|
10
|
+
* all.
|
|
11
|
+
*
|
|
12
|
+
* **Focus rides the existing hover channel.** `onFocus` calls
|
|
13
|
+
* `onCategoryEnter` and `onBlur` calls `onCategoryLeave`, so the tooltip, the
|
|
14
|
+
* cursor line, the legend dimming and every `getMarkState` light up for a
|
|
15
|
+
* keyboard reader exactly as they do for a pointer — without
|
|
16
|
+
* `useChartInteraction` growing a third state axis to keep in sync.
|
|
17
|
+
*/
|
|
18
|
+
interface ChartCategoryTargetsProps {
|
|
19
|
+
targets: ChartCategoryTarget[];
|
|
20
|
+
interaction: ChartInteraction;
|
|
21
|
+
/** Accessible name for one category. Derived from the tooltip, so they agree. */
|
|
22
|
+
getAriaLabel: (index: number) => string;
|
|
23
|
+
/** Arrow keys wrap at the ends. True for radial charts — a circle has no ends. */
|
|
24
|
+
wrap?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare const ChartCategoryTargets: ({ targets, interaction, getAriaLabel, wrap, }: ChartCategoryTargetsProps) => import("react").JSX.Element;
|
|
27
|
+
export default ChartCategoryTargets;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ChartTargetShape } from "./types.js";
|
|
2
|
+
import { clamp } from "./chartScales.js";
|
|
3
|
+
import { ChartCategoryTargetLayer, ChartHitTarget, ChartHitTargetPath } from "./ChartPrimitives.js";
|
|
4
|
+
import { match } from "ts-pattern";
|
|
5
|
+
import { useCallback, useRef, useState } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/charts/ChartCategoryTargets.tsx
|
|
8
|
+
var ChartCategoryTargets = ({ targets, interaction, getAriaLabel, wrap = false }) => {
|
|
9
|
+
const [focusIndex, setFocusIndex] = useState(0);
|
|
10
|
+
const nodeRefs = useRef([]);
|
|
11
|
+
/**
|
|
12
|
+
* Roving tabindex, preferring whatever is pinned.
|
|
13
|
+
*
|
|
14
|
+
* Tabbing away and back returns to the category the reader was holding rather
|
|
15
|
+
* than to the start, which is the difference between the pin being a place
|
|
16
|
+
* you are and a thing that merely happened.
|
|
17
|
+
*/
|
|
18
|
+
const rovingIndex = clamp(interaction.pinnedIndex ?? focusIndex, 0, targets.length - 1);
|
|
19
|
+
const moveTo = useCallback((next) => {
|
|
20
|
+
const last = targets.length - 1;
|
|
21
|
+
const bounded = wrap ? (next % targets.length + targets.length) % targets.length : clamp(next, 0, last);
|
|
22
|
+
setFocusIndex(bounded);
|
|
23
|
+
nodeRefs.current[bounded]?.focus();
|
|
24
|
+
}, [targets.length, wrap]);
|
|
25
|
+
const onKeyDown = useCallback((event, index) => {
|
|
26
|
+
if (match(event.key).with("ArrowRight", "ArrowDown", () => moveTo(index + 1)).with("ArrowLeft", "ArrowUp", () => moveTo(index - 1)).with("Home", () => moveTo(0)).with("End", () => moveTo(targets.length - 1)).with("Enter", " ", () => interaction.onCategoryClick(index)).with("Escape", () => interaction.onBackdropClick()).otherwise(() => void 0) !== void 0 || [
|
|
27
|
+
"ArrowRight",
|
|
28
|
+
"ArrowDown",
|
|
29
|
+
"ArrowLeft",
|
|
30
|
+
"ArrowUp",
|
|
31
|
+
"Home",
|
|
32
|
+
"End",
|
|
33
|
+
"Enter",
|
|
34
|
+
" ",
|
|
35
|
+
"Escape"
|
|
36
|
+
].includes(event.key)) event.preventDefault();
|
|
37
|
+
}, [
|
|
38
|
+
moveTo,
|
|
39
|
+
interaction,
|
|
40
|
+
targets.length
|
|
41
|
+
]);
|
|
42
|
+
return /* @__PURE__ */ jsx(ChartCategoryTargetLayer, { children: targets.map((target, index) => {
|
|
43
|
+
const shared = {
|
|
44
|
+
tabIndex: index === rovingIndex ? 0 : -1,
|
|
45
|
+
role: "button",
|
|
46
|
+
"aria-label": getAriaLabel(index),
|
|
47
|
+
"aria-pressed": interaction.pinnedIndex === index,
|
|
48
|
+
"data-interactive": "true",
|
|
49
|
+
onFocus: () => interaction.onCategoryEnter(index),
|
|
50
|
+
onBlur: () => interaction.onCategoryLeave(),
|
|
51
|
+
onMouseEnter: () => interaction.onCategoryEnter(index),
|
|
52
|
+
onMouseLeave: () => interaction.onCategoryLeave(),
|
|
53
|
+
onClick: () => interaction.onCategoryClick(index),
|
|
54
|
+
onKeyDown: (event) => onKeyDown(event, index)
|
|
55
|
+
};
|
|
56
|
+
return match(target).with({ shape: ChartTargetShape.RECT }, (rect) => /* @__PURE__ */ jsx(ChartHitTarget, {
|
|
57
|
+
ref: (node) => {
|
|
58
|
+
nodeRefs.current[index] = node;
|
|
59
|
+
},
|
|
60
|
+
x: rect.x,
|
|
61
|
+
y: rect.y,
|
|
62
|
+
width: rect.width,
|
|
63
|
+
height: rect.height,
|
|
64
|
+
...shared
|
|
65
|
+
}, rect.key)).with({ shape: ChartTargetShape.PATH }, (path) => /* @__PURE__ */ jsx(ChartHitTargetPath, {
|
|
66
|
+
ref: (node) => {
|
|
67
|
+
nodeRefs.current[index] = node;
|
|
68
|
+
},
|
|
69
|
+
d: path.d,
|
|
70
|
+
...shared
|
|
71
|
+
}, path.key)).exhaustive();
|
|
72
|
+
}) });
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
export { ChartCategoryTargets as default };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
interface ChartEmptyStateProps {
|
|
3
|
+
/** Caller-supplied content. Falls back to a centred "No data". */
|
|
4
|
+
content?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Overlay shown when a chart has nothing to plot.
|
|
8
|
+
*
|
|
9
|
+
* Rendered over the reserved plot box rather than in place of it, so the axes
|
|
10
|
+
* stay at full size and the chart does not resize when data arrives.
|
|
11
|
+
*
|
|
12
|
+
* What counts as empty is each chart's own call and deliberately inconsistent:
|
|
13
|
+
* a bar chart of all zeros is a flat chart with real data, while a pie of all
|
|
14
|
+
* zeros has no whole to apportion.
|
|
15
|
+
*/
|
|
16
|
+
declare const ChartEmptyState: ({ content }: ChartEmptyStateProps) => import("react").JSX.Element;
|
|
17
|
+
export default ChartEmptyState;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Text, { TextSize, TextVariant } from "../text/Text.js";
|
|
2
|
+
import FlexWrapper, { AlignItems, JustifyContent } from "../containers/FlexWrapper.js";
|
|
3
|
+
import { ChartEmptyOverlay } from "./ChartPrimitives.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/charts/ChartEmptyState.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Overlay shown when a chart has nothing to plot.
|
|
8
|
+
*
|
|
9
|
+
* Rendered over the reserved plot box rather than in place of it, so the axes
|
|
10
|
+
* stay at full size and the chart does not resize when data arrives.
|
|
11
|
+
*
|
|
12
|
+
* What counts as empty is each chart's own call and deliberately inconsistent:
|
|
13
|
+
* a bar chart of all zeros is a flat chart with real data, while a pie of all
|
|
14
|
+
* zeros has no whole to apportion.
|
|
15
|
+
*/
|
|
16
|
+
var ChartEmptyState = ({ content }) => /* @__PURE__ */ jsx(ChartEmptyOverlay, {
|
|
17
|
+
role: "status",
|
|
18
|
+
children: content ?? /* @__PURE__ */ jsx(FlexWrapper, {
|
|
19
|
+
justifyContent: JustifyContent.CENTER,
|
|
20
|
+
alignItems: AlignItems.CENTER,
|
|
21
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22
|
+
size: TextSize.CAPTION,
|
|
23
|
+
variant: TextVariant.TERTIARY,
|
|
24
|
+
children: "No data"
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
export { ChartEmptyState as default };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { ChartKind } from "./types";
|
|
3
|
+
import type { ChartCategoryTarget, ChartLegendItem, ChartPlotTooltipModel, ChartTooltipRenderer } from "./types";
|
|
4
|
+
import type { ChartDimensions } from "./useChartDimensions";
|
|
5
|
+
import type { ChartInteraction } from "./useChartInteraction";
|
|
6
|
+
import type { ChartTooltipVerticalAlign } from "./useChartTooltipPosition";
|
|
7
|
+
/**
|
|
8
|
+
* The shell every chart renders into: measured root, reserved plot box, SVG and
|
|
9
|
+
* its margin translate, the interactive plot group, the backdrop, the tooltip,
|
|
10
|
+
* the empty state and the legend.
|
|
11
|
+
*
|
|
12
|
+
* **The frame owns the plot translate.** Marks are drawn inside a
|
|
13
|
+
* `translate(margin.left, margin.top)` group, and every coordinate handed to
|
|
14
|
+
* this component — including the tooltip anchor and `placeAwayFromX` — is in
|
|
15
|
+
* that same plot space. Charts never add the margin themselves; three
|
|
16
|
+
* hand-written copies of `+ margin.left` is precisely what drifts silently.
|
|
17
|
+
*
|
|
18
|
+
* Knows nothing about scales, marks or geometry — all of that arrives through
|
|
19
|
+
* `axes` and `children`.
|
|
20
|
+
*
|
|
21
|
+
* @internal Published as a subpath only because this package has no barrel
|
|
22
|
+
* files, not because charts are meant to be composed out of it.
|
|
23
|
+
*/
|
|
24
|
+
export interface ChartFrameProps {
|
|
25
|
+
/**
|
|
26
|
+
* The element `useChartDimensions` measures — the *plot box*, not the root.
|
|
27
|
+
*
|
|
28
|
+
* Measuring the plot box is what keeps `fillHeight` honest: the legend is a
|
|
29
|
+
* sibling in the root's flex column, so the box's height is already the space
|
|
30
|
+
* left over for the plot and no one has to subtract a wrapped legend. Width is
|
|
31
|
+
* unaffected, the box being `width: 100%` of the root either way.
|
|
32
|
+
*
|
|
33
|
+
* Created by the chart, not here: the chart needs the resulting dimensions
|
|
34
|
+
* during its own render — to size the geometry and to feed
|
|
35
|
+
* `useChartInteraction` — so the ref has to exist before this component does.
|
|
36
|
+
* A named prop rather than `ref` because ref-as-a-prop needs React 19 and this
|
|
37
|
+
* package still supports 18.
|
|
38
|
+
*/
|
|
39
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
40
|
+
dimensions: ChartDimensions;
|
|
41
|
+
fillWidth?: boolean;
|
|
42
|
+
fillHeight?: boolean;
|
|
43
|
+
interaction: ChartInteraction;
|
|
44
|
+
/** Which chart this is. Only used to phrase the default accessible name. */
|
|
45
|
+
kind: ChartKind;
|
|
46
|
+
/** Categories on the axis, or slices for a pie. Names the plot, so it counts
|
|
47
|
+
* what is *rendered* rather than what was supplied. */
|
|
48
|
+
categoryCount: number;
|
|
49
|
+
/** Overrides the name derived from {@link kind} and the counts. */
|
|
50
|
+
ariaLabel?: string;
|
|
51
|
+
/** Long description, associated with the SVG via `aria-describedby`. */
|
|
52
|
+
ariaDescription?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Axes, drawn inside the plot translate group *before* {@link children}, so
|
|
55
|
+
* grid lines paint under the marks. Radial charts pass nothing.
|
|
56
|
+
*/
|
|
57
|
+
axes?: ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Marks, drawn inside the plot group above the backdrop.
|
|
60
|
+
*
|
|
61
|
+
* Rendered only once measured, so no caller writes that guard. Note it is
|
|
62
|
+
* still *evaluated* on the unmeasured pass — as is the geometry it maps over,
|
|
63
|
+
* which each chart's `useMemo` already runs at a 0×0 plot. Geometry builders
|
|
64
|
+
* must stay total at zero; they already are.
|
|
65
|
+
*/
|
|
66
|
+
children?: ReactNode;
|
|
67
|
+
/** HTML painted over the plot and under the tooltip — the donut centre. */
|
|
68
|
+
plotOverlay?: ReactNode;
|
|
69
|
+
noTooltip?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Builds one category's tooltip, in plot coordinates.
|
|
72
|
+
*
|
|
73
|
+
* Taken as a function rather than a finished model because the frame needs it
|
|
74
|
+
* twice: once for the category under the pointer, and once per category to
|
|
75
|
+
* name it for a screen reader. Deriving both from the same builder is what
|
|
76
|
+
* makes the accessible name incapable of disagreeing with the tooltip.
|
|
77
|
+
*
|
|
78
|
+
* Must be stable; memoize it at the call site.
|
|
79
|
+
*/
|
|
80
|
+
buildCategoryTooltip: (index: number) => ChartPlotTooltipModel | null;
|
|
81
|
+
tooltipRenderer?: ChartTooltipRenderer;
|
|
82
|
+
/**
|
|
83
|
+
* One target per category, in plot coordinates and in category order.
|
|
84
|
+
*
|
|
85
|
+
* Empty disables interaction entirely, which is what a chart with nothing to
|
|
86
|
+
* plot passes.
|
|
87
|
+
*/
|
|
88
|
+
categoryTargets?: ChartCategoryTarget[];
|
|
89
|
+
/** Applied to the target layer. Radial charts pass their centre translate. */
|
|
90
|
+
categoryTargetsTransform?: string;
|
|
91
|
+
/** Arrow keys wrap at the ends. True for radial charts. */
|
|
92
|
+
wrapCategoryNavigation?: boolean;
|
|
93
|
+
/** Overrides the accessible name of a category, which defaults to its tooltip. */
|
|
94
|
+
describeCategory?: (index: number) => string;
|
|
95
|
+
/** Half a category's width, so the tooltip sits beside the marks. */
|
|
96
|
+
anchorHalfWidth?: number;
|
|
97
|
+
/** Radial charts pass their centre, in plot coordinates. */
|
|
98
|
+
placeAwayFromX?: number;
|
|
99
|
+
verticalAlign?: ChartTooltipVerticalAlign;
|
|
100
|
+
/** Each chart defines "empty" for itself; the frame only renders the result. */
|
|
101
|
+
isEmpty: boolean;
|
|
102
|
+
isLoading?: boolean;
|
|
103
|
+
contentWhenEmpty?: ReactNode;
|
|
104
|
+
showLegend?: boolean;
|
|
105
|
+
legendItems: ChartLegendItem[];
|
|
106
|
+
/** Defaults to the left margin, aligning the legend with the plot, not the gutter. */
|
|
107
|
+
legendInset?: number;
|
|
108
|
+
}
|
|
109
|
+
declare const ChartFrame: ({ containerRef, dimensions, fillWidth, fillHeight, interaction, kind, categoryCount, ariaLabel, ariaDescription, axes, children, plotOverlay, noTooltip, buildCategoryTooltip, tooltipRenderer, categoryTargets, categoryTargetsTransform, wrapCategoryNavigation, describeCategory, anchorHalfWidth, placeAwayFromX, verticalAlign, isEmpty, isLoading, contentWhenEmpty, showLegend, legendItems, legendInset, }: ChartFrameProps) => import("react").JSX.Element;
|
|
110
|
+
export default ChartFrame;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { ChartKind } from "./types.js";
|
|
2
|
+
import { describeTooltipModel } from "./chartFormat.js";
|
|
3
|
+
import { ChartBackdrop, ChartPlotBox, ChartPlotGroup, ChartRoot, ChartSvg } from "./ChartPrimitives.js";
|
|
4
|
+
import ChartCategoryTargets from "./ChartCategoryTargets.js";
|
|
5
|
+
import ChartEmptyState from "./ChartEmptyState.js";
|
|
6
|
+
import ChartLegend from "./ChartLegend.js";
|
|
7
|
+
import ChartTooltip from "./ChartTooltip.js";
|
|
8
|
+
import { match } from "ts-pattern";
|
|
9
|
+
import { useCallback, useId, useMemo } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/charts/ChartFrame.tsx
|
|
12
|
+
var ChartFrame = ({ containerRef, dimensions, fillWidth, fillHeight, interaction, kind, categoryCount, ariaLabel, ariaDescription, axes, children, plotOverlay, noTooltip = false, buildCategoryTooltip, tooltipRenderer, categoryTargets, categoryTargetsTransform, wrapCategoryNavigation, describeCategory, anchorHalfWidth, placeAwayFromX, verticalAlign, isEmpty, isLoading = false, contentWhenEmpty, showLegend = false, legendItems, legendInset }) => {
|
|
13
|
+
const { width, height, plotWidth, plotHeight, margin, isMeasured, reservedHeight, reservedAspectRatio } = dimensions;
|
|
14
|
+
const generatedId = useId();
|
|
15
|
+
const descriptionId = ariaDescription ? `${generatedId}-desc` : void 0;
|
|
16
|
+
/**
|
|
17
|
+
* Default accessible name, phrased here so the three charts cannot drift.
|
|
18
|
+
*
|
|
19
|
+
* Both counts describe what is *on screen*: `legendItems` rather than the
|
|
20
|
+
* `series` record, because a stacked bar's legend names its components, not
|
|
21
|
+
* its metrics — counting the record would announce "1 series" for a chart
|
|
22
|
+
* showing three. The two charts previously counted different things for the
|
|
23
|
+
* same situation, which is the drift this removes.
|
|
24
|
+
*/
|
|
25
|
+
const resolvedAriaLabel = ariaLabel ?? match(kind).with(ChartKind.PIE, () => `Pie chart with ${categoryCount} slices`).with(ChartKind.BAR, () => `Bar chart with ${categoryCount} categories and ${legendItems.length} series`).with(ChartKind.LINE, () => `Line chart with ${categoryCount} categories and ${legendItems.length} series`).exhaustive();
|
|
26
|
+
const tooltipModel = useMemo(() => noTooltip || interaction.activeIndex === null ? null : buildCategoryTooltip(interaction.activeIndex), [
|
|
27
|
+
noTooltip,
|
|
28
|
+
buildCategoryTooltip,
|
|
29
|
+
interaction.activeIndex
|
|
30
|
+
]);
|
|
31
|
+
/**
|
|
32
|
+
* Plot space → container space, applied once, here.
|
|
33
|
+
*
|
|
34
|
+
* Memoized for correctness, not arithmetic cost. `ChartTooltip` retains the
|
|
35
|
+
* last model by *identity* so it can keep its content while fading out, and
|
|
36
|
+
* adjusts that state during render when the identity changes. A fresh object
|
|
37
|
+
* on every parent render would therefore trigger an extra render pass on
|
|
38
|
+
* every render — including every pointer move — without ever looping or
|
|
39
|
+
* visibly breaking.
|
|
40
|
+
*/
|
|
41
|
+
const positionedTooltip = useMemo(() => tooltipModel === null ? null : {
|
|
42
|
+
...tooltipModel,
|
|
43
|
+
anchorX: tooltipModel.anchorX + margin.left,
|
|
44
|
+
anchorY: tooltipModel.anchorY + margin.top
|
|
45
|
+
}, [
|
|
46
|
+
tooltipModel,
|
|
47
|
+
margin.left,
|
|
48
|
+
margin.top
|
|
49
|
+
]);
|
|
50
|
+
/**
|
|
51
|
+
* Name each category from its own tooltip, unless the chart says otherwise.
|
|
52
|
+
*
|
|
53
|
+
* Same builder as the visible tooltip, so the two cannot describe the chart
|
|
54
|
+
* differently.
|
|
55
|
+
*/
|
|
56
|
+
const nameCategory = useCallback((index) => {
|
|
57
|
+
if (describeCategory) return describeCategory(index);
|
|
58
|
+
const model = buildCategoryTooltip(index);
|
|
59
|
+
return model ? describeTooltipModel(model) : "";
|
|
60
|
+
}, [describeCategory, buildCategoryTooltip]);
|
|
61
|
+
/**
|
|
62
|
+
* Whether the marks are reachable at all.
|
|
63
|
+
*
|
|
64
|
+
* Drives the SVG's role, which is the real cost of keyboard access:
|
|
65
|
+
* `role="img"` prunes the whole subtree from the accessibility tree, so
|
|
66
|
+
* nothing inside it can ever be focused *and* announced. A chart with live
|
|
67
|
+
* targets therefore has to be a `group` — and everything that is not a target
|
|
68
|
+
* has to be explicitly hidden, since under `group` it would otherwise become
|
|
69
|
+
* traversable. When there is nothing to reach, `img` stays: it announces one
|
|
70
|
+
* summary rather than an empty group.
|
|
71
|
+
*/
|
|
72
|
+
const hasFocusableTargets = isMeasured && !noTooltip && !isLoading && !isEmpty && (categoryTargets?.length ?? 0) > 0;
|
|
73
|
+
return /* @__PURE__ */ jsxs(ChartRoot, {
|
|
74
|
+
$fillWidth: fillWidth,
|
|
75
|
+
$fillHeight: fillHeight,
|
|
76
|
+
children: [/* @__PURE__ */ jsxs(ChartPlotBox, {
|
|
77
|
+
ref: containerRef,
|
|
78
|
+
$reservedHeight: reservedHeight,
|
|
79
|
+
$reservedAspectRatio: reservedAspectRatio,
|
|
80
|
+
$fillHeight: fillHeight,
|
|
81
|
+
children: [
|
|
82
|
+
isMeasured && /* @__PURE__ */ jsxs(ChartSvg, {
|
|
83
|
+
width,
|
|
84
|
+
height,
|
|
85
|
+
role: hasFocusableTargets ? "group" : "img",
|
|
86
|
+
"aria-label": resolvedAriaLabel,
|
|
87
|
+
"aria-describedby": descriptionId,
|
|
88
|
+
children: [ariaDescription && /* @__PURE__ */ jsx("desc", {
|
|
89
|
+
id: descriptionId,
|
|
90
|
+
children: ariaDescription
|
|
91
|
+
}), /* @__PURE__ */ jsxs("g", {
|
|
92
|
+
transform: `translate(${margin.left}, ${margin.top})`,
|
|
93
|
+
children: [
|
|
94
|
+
axes,
|
|
95
|
+
/* @__PURE__ */ jsx("g", {
|
|
96
|
+
"aria-hidden": "true",
|
|
97
|
+
children: /* @__PURE__ */ jsxs(ChartPlotGroup, {
|
|
98
|
+
"data-active": interaction.isEngaged ? "true" : "false",
|
|
99
|
+
children: [/* @__PURE__ */ jsx(ChartBackdrop, {
|
|
100
|
+
width: plotWidth,
|
|
101
|
+
height: plotHeight,
|
|
102
|
+
"data-interactive": interaction.pinnedIndex !== null ? "true" : "false",
|
|
103
|
+
onClick: interaction.onBackdropClick
|
|
104
|
+
}), children]
|
|
105
|
+
})
|
|
106
|
+
}),
|
|
107
|
+
hasFocusableTargets && categoryTargets && /* @__PURE__ */ jsx("g", {
|
|
108
|
+
transform: categoryTargetsTransform,
|
|
109
|
+
children: /* @__PURE__ */ jsx(ChartCategoryTargets, {
|
|
110
|
+
targets: categoryTargets,
|
|
111
|
+
interaction,
|
|
112
|
+
getAriaLabel: nameCategory,
|
|
113
|
+
wrap: wrapCategoryNavigation
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
]
|
|
117
|
+
})]
|
|
118
|
+
}),
|
|
119
|
+
isMeasured && plotOverlay,
|
|
120
|
+
isMeasured && !noTooltip && /* @__PURE__ */ jsx(ChartTooltip, {
|
|
121
|
+
model: positionedTooltip,
|
|
122
|
+
containerWidth: width,
|
|
123
|
+
containerHeight: height,
|
|
124
|
+
anchorHalfWidth,
|
|
125
|
+
placeAwayFromX: placeAwayFromX === void 0 ? void 0 : placeAwayFromX + margin.left,
|
|
126
|
+
verticalAlign,
|
|
127
|
+
renderer: tooltipRenderer
|
|
128
|
+
}),
|
|
129
|
+
isMeasured && isEmpty && !isLoading && /* @__PURE__ */ jsx(ChartEmptyState, { content: contentWhenEmpty })
|
|
130
|
+
]
|
|
131
|
+
}), showLegend && /* @__PURE__ */ jsx(ChartLegend, {
|
|
132
|
+
items: legendItems,
|
|
133
|
+
inset: legendInset ?? margin.left,
|
|
134
|
+
hoveredKey: interaction.hoveredSeriesKey,
|
|
135
|
+
pinnedKey: interaction.pinnedSeriesKey,
|
|
136
|
+
onItemEnter: interaction.onSeriesEnter,
|
|
137
|
+
onItemLeave: interaction.onSeriesLeave,
|
|
138
|
+
onItemClick: interaction.onSeriesClick
|
|
139
|
+
})]
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
//#endregion
|
|
143
|
+
export { ChartFrame as default };
|
|
@@ -1,7 +1,30 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChartLegendItem } from "./types";
|
|
2
2
|
interface ChartLegendProps {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
items: ChartLegendItem[];
|
|
4
|
+
/** Left padding aligning the legend with the plot, not the axis gutter. */
|
|
5
|
+
inset: number;
|
|
6
|
+
/** Series key currently hovered anywhere in the chart. */
|
|
7
|
+
hoveredKey?: string | null;
|
|
8
|
+
/** Series key currently pinned. Drives `aria-pressed`. */
|
|
9
|
+
pinnedKey?: string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Supplying these makes the legend interactive. Omit them and it renders as
|
|
12
|
+
* inert text, with no button semantics for a screen reader to announce.
|
|
13
|
+
*/
|
|
14
|
+
onItemEnter?: (key: string) => void;
|
|
15
|
+
onItemLeave?: () => void;
|
|
16
|
+
onItemClick?: (key: string) => void;
|
|
5
17
|
}
|
|
6
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Legend for the chart components.
|
|
20
|
+
*
|
|
21
|
+
* Hovering an entry isolates its series and clicking pins that isolation.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately *not* a visibility toggle: hiding a series would have to rescale
|
|
24
|
+
* the value axis to stay honest — otherwise the remaining bars sit mysteriously
|
|
25
|
+
* short — and that belongs with the geometry layer rather than bolted on here.
|
|
26
|
+
* Isolation only changes opacity, so the domain is untouched and the numbers
|
|
27
|
+
* keep meaning what they did.
|
|
28
|
+
*/
|
|
29
|
+
declare const ChartLegend: ({ items, inset, hoveredKey, pinnedKey, onItemEnter, onItemLeave, onItemClick, }: ChartLegendProps) => import("react").JSX.Element | null;
|
|
7
30
|
export default ChartLegend;
|