@k2b/ui 0.31.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/dist/base.css +2 -0
  2. package/dist/browser/actions/ViewTabs.js +8 -0
  3. package/dist/browser/actions/ViewTabs.js.map +1 -1
  4. package/dist/browser/content/Chart.js +104 -55
  5. package/dist/browser/content/Chart.js.map +1 -1
  6. package/dist/browser/content/ChartExplorer.js +5 -3
  7. package/dist/browser/content/ChartExplorer.js.map +1 -1
  8. package/dist/browser/content/MapView.js +4 -4
  9. package/dist/browser/content/MapView.js.map +1 -1
  10. package/dist/browser/content/chart-inspection-core.js +4 -1
  11. package/dist/browser/content/chart-inspection-core.js.map +1 -1
  12. package/dist/browser/content/code-highlight.js +66 -0
  13. package/dist/browser/content/code-highlight.js.map +1 -1
  14. package/dist/browser/content/index.js +1 -0
  15. package/dist/browser/content/index.js.map +1 -1
  16. package/dist/browser/content/map-view-live.js +47 -10
  17. package/dist/browser/content/map-view-live.js.map +1 -1
  18. package/dist/browser/content/map-view-types.js.map +1 -1
  19. package/dist/browser/inputs/AutocompleteEditor.js +167 -104
  20. package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
  21. package/dist/browser/inputs/RichSelect.js +1474 -0
  22. package/dist/browser/inputs/RichSelect.js.map +1 -0
  23. package/dist/browser/inputs/TextInput.js +95 -60
  24. package/dist/browser/inputs/TextInput.js.map +1 -1
  25. package/dist/browser/inputs/choice.js +19 -8
  26. package/dist/browser/inputs/choice.js.map +1 -1
  27. package/dist/browser/inputs/index.js +1 -0
  28. package/dist/browser/inputs/index.js.map +1 -1
  29. package/dist/browser/inputs/rich-select-messages.js +46 -0
  30. package/dist/browser/inputs/rich-select-messages.js.map +1 -0
  31. package/dist/browser/layout/AppWorkspace.js +177 -135
  32. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  33. package/dist/browser/layout/DetailPanel.js +10 -1
  34. package/dist/browser/layout/DetailPanel.js.map +1 -1
  35. package/dist/browser/layout/Navigation.js +14 -5
  36. package/dist/browser/layout/Navigation.js.map +1 -1
  37. package/dist/browser/layout/PageTitle.js +9 -3
  38. package/dist/browser/layout/PageTitle.js.map +1 -1
  39. package/dist/browser/layout/ResizeSeparator.js +8 -2
  40. package/dist/browser/layout/ResizeSeparator.js.map +1 -1
  41. package/dist/browser/layout/app-workspace-controller.js +192 -31
  42. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  43. package/dist/browser/layout/navigation-model.js.map +1 -1
  44. package/dist/browser/layout/resize-separator.js +25 -1
  45. package/dist/browser/layout/resize-separator.js.map +1 -1
  46. package/dist/browser/surfaces/Skeleton.js +14 -0
  47. package/dist/browser/surfaces/Skeleton.js.map +1 -0
  48. package/dist/browser/surfaces/index.js +1 -0
  49. package/dist/browser/surfaces/index.js.map +1 -1
  50. package/dist/ssr/actions/ViewTabs.js +8 -0
  51. package/dist/ssr/actions/ViewTabs.js.map +1 -1
  52. package/dist/ssr/content/Chart.js +27 -7
  53. package/dist/ssr/content/Chart.js.map +1 -1
  54. package/dist/ssr/content/ChartExplorer.js +5 -3
  55. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  56. package/dist/ssr/content/MapView.js +4 -4
  57. package/dist/ssr/content/MapView.js.map +1 -1
  58. package/dist/ssr/content/chart-inspection-core.js +4 -1
  59. package/dist/ssr/content/chart-inspection-core.js.map +1 -1
  60. package/dist/ssr/content/code-highlight.js +66 -0
  61. package/dist/ssr/content/code-highlight.js.map +1 -1
  62. package/dist/ssr/content/index.js +1 -0
  63. package/dist/ssr/content/index.js.map +1 -1
  64. package/dist/ssr/content/map-view-types.js.map +1 -1
  65. package/dist/ssr/inputs/AutocompleteEditor.js +64 -24
  66. package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
  67. package/dist/ssr/inputs/RichSelect.js +950 -0
  68. package/dist/ssr/inputs/RichSelect.js.map +1 -0
  69. package/dist/ssr/inputs/TextInput.js +40 -16
  70. package/dist/ssr/inputs/TextInput.js.map +1 -1
  71. package/dist/ssr/inputs/choice.js +19 -8
  72. package/dist/ssr/inputs/choice.js.map +1 -1
  73. package/dist/ssr/inputs/index.js +1 -0
  74. package/dist/ssr/inputs/index.js.map +1 -1
  75. package/dist/ssr/inputs/rich-select-messages.js +46 -0
  76. package/dist/ssr/inputs/rich-select-messages.js.map +1 -0
  77. package/dist/ssr/layout/AppWorkspace.js +36 -7
  78. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  79. package/dist/ssr/layout/DetailPanel.js +1 -1
  80. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  81. package/dist/ssr/layout/Navigation.js +1 -1
  82. package/dist/ssr/layout/Navigation.js.map +1 -1
  83. package/dist/ssr/layout/PageTitle.js +9 -3
  84. package/dist/ssr/layout/PageTitle.js.map +1 -1
  85. package/dist/ssr/layout/ResizeSeparator.js +4 -1
  86. package/dist/ssr/layout/ResizeSeparator.js.map +1 -1
  87. package/dist/ssr/layout/app-workspace-controller.js +192 -31
  88. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  89. package/dist/ssr/layout/navigation-model.js.map +1 -1
  90. package/dist/ssr/layout/resize-separator.js +25 -1
  91. package/dist/ssr/layout/resize-separator.js.map +1 -1
  92. package/dist/ssr/surfaces/Skeleton.js +8 -0
  93. package/dist/ssr/surfaces/Skeleton.js.map +1 -0
  94. package/dist/ssr/surfaces/index.js +1 -0
  95. package/dist/ssr/surfaces/index.js.map +1 -1
  96. package/dist/styles.css +1 -1
  97. package/dist/types/content/Chart.d.ts +4 -2
  98. package/dist/types/content/ChartExplorer.d.ts +0 -1
  99. package/dist/types/content/code-highlight.d.ts +3 -1
  100. package/dist/types/content/index.d.ts +1 -0
  101. package/dist/types/content/map-view-live.d.ts +1 -1
  102. package/dist/types/content/map-view-types.d.ts +2 -0
  103. package/dist/types/inputs/AutocompleteEditor.d.ts +6 -1
  104. package/dist/types/inputs/RichSelect.d.ts +93 -0
  105. package/dist/types/inputs/TextInput.d.ts +5 -2
  106. package/dist/types/inputs/choice.d.ts +24 -4
  107. package/dist/types/inputs/index.d.ts +2 -0
  108. package/dist/types/inputs/rich-select-messages.d.ts +21 -0
  109. package/dist/types/layout/AppWorkspace.d.ts +7 -0
  110. package/dist/types/layout/DetailPanel.d.ts +2 -0
  111. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  112. package/dist/types/layout/navigation-model.d.ts +2 -0
  113. package/dist/types/layout/resize-separator.d.ts +1 -0
  114. package/dist/types/surfaces/Skeleton.d.ts +6 -0
  115. package/dist/types/surfaces/index.d.ts +1 -0
  116. package/package.json +4 -4
@@ -31,8 +31,10 @@ import DataTable from "./DataTable";
31
31
 
32
32
  /** One legend entry; `color` is the palette index the renderer gave the series (0 is `--stdlib-chart-c1`). */
33
33
 
34
- const tsvCell = (value, numeric = false) => {
35
- const safe = !numeric && /^[=+\-@\t\r]/.test(value) ? `'${value}` : value;
34
+ // Only the copied text can prove that a cell is a number; a numeric sort key cannot.
35
+ const plainNumber = /^[-+]?\p{Sc}?\s?\d[\d.,\s]*(?:\s?(?:%|\p{Sc}))?$/u;
36
+ const tsvCell = value => {
37
+ const safe = /^[=+\-@\t\r]/.test(value) && !plainNumber.test(value) ? `'${value}` : value;
36
38
  return /[\t\r\n"]/.test(safe) ? `"${safe.replaceAll('"', '""')}"` : safe;
37
39
  };
38
40
  export function ChartExplorer(props) {
@@ -111,7 +113,7 @@ export function ChartExplorer(props) {
111
113
  setView("chart");
112
114
  props.onChartChange?.(value.slice("chart:".length));
113
115
  };
114
- const copyText = () => [props.columns.map(c => tsvCell(c.label)).join("\t"), ...rows().map(row => props.columns.map(c => tsvCell(c.value(row), typeof c.sortValue?.(row) === "number")).join("\t"))].join("\n");
116
+ const copyText = () => [props.columns.map(c => tsvCell(c.label)).join("\t"), ...rows().map(row => props.columns.map(c => tsvCell(c.value(row))).join("\t"))].join("\n");
115
117
  return _$ssr(_tmpl$5, `k2b-chart-explorer ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("aria-labelledby", _$escape(id, true), false), _$escape(_$createComponent(Dynamic, {
116
118
  get component() {
117
119
  return `h${props.headingLevel ?? 3}`;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/ChartExplorer.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, createUniqueId, For, type JSX, Show } from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { CopyButton } from \"../actions/CopyButton\";\nimport { SelectChip } from \"../inputs/SelectChip\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { DescriptionList } from \"../surfaces/DescriptionList\";\nimport { Paper } from \"../surfaces/Paper\";\nimport { ChartSnapshotView } from \"./ChartSnapshotView\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { type ChartExplorerData, type ChartExplorerRow, validateChartExplorerData } from \"./chart-explorer\";\nimport { useChartMessages } from \"./chart-messages\";\nimport DataTable, { type DataTableSort } from \"./DataTable\";\n\nexport type ChartExplorerColumn<T> = {\n id: string;\n label: string;\n value: (row: T) => string;\n /** Optional table cell presentation; value remains the plain text used for copy/details. */\n render?: (row: T) => JSX.Element;\n /**\n * Explicit comparable value. Omit to leave the column unsortable.\n * Returning a number also exempts the cell from spreadsheet formula guarding on copy.\n */\n sortValue?: (row: T) => string | number | null;\n align?: \"left\" | \"center\" | \"right\";\n};\n/** One legend entry; `color` is the palette index the renderer gave the series (0 is `--stdlib-chart-c1`). */\nexport type ChartLegendEntry = {\n label: string;\n color: number;\n /** Line pattern of a line series; a solid series shows a filled swatch. */\n style?: \"solid\" | \"dashed\" | \"dotted\";\n /** A comparison series, drawn hollow like its marks. */\n reference?: boolean;\n};\nexport type ChartExplorerProps<T extends ChartExplorerRow> = {\n cursor?: ChartCursor;\n title: string;\n /** Level of the title heading. Defaults to 3; a chart inside a titled group of charts sits one level below it. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n description?: JSX.Element;\n data: ChartExplorerData<T>;\n columns: readonly ChartExplorerColumn<T>[];\n view?: \"chart\" | \"table\";\n defaultView?: \"chart\" | \"table\";\n onViewChange?: (view: \"chart\" | \"table\") => void;\n /**\n * Several charts of the same rows. The switcher then lists each chart and the table; `chart` names the one `data`\n * holds, and `onChartChange` reports a pick, so the owner passes the matching data.\n */\n charts?: readonly { id: string; label: string }[];\n chart?: string;\n onChartChange?: (id: string) => void;\n /** Filter controls between the header and the viewport, such as ChartFilterControls. */\n controls?: JSX.Element;\n /** The table renders at most this many rows of the sorted order; sorting and Copy data use every row. */\n tableRows?: number;\n sort?: DataTableSort | null;\n defaultSort?: DataTableSort | null;\n onSortChange?: (sort: DataTableSort | null) => void;\n selectedKey?: string | null;\n onSelectedKeyChange?: (key: string | null) => void;\n /** false hides the complete local detail area for a shared selection panel. */\n renderDetails?: false | ((row: T) => JSX.Element);\n height?: string;\n /**\n * Series names below the chart, wrapping inside the fixed viewport height. Use it instead of the renderer's legend,\n * which draws in one row and runs out of narrow columns.\n */\n legend?: readonly ChartLegendEntry[];\n /** What the viewport shows without rows, for example while they load; defaults to \"No data\". */\n empty?: JSX.Element;\n class?: string;\n};\n\nconst tsvCell = (value: string, numeric = false) => {\n const safe = !numeric && /^[=+\\-@\\t\\r]/.test(value) ? `'${value}` : value;\n return /[\\t\\r\\n\"]/.test(safe) ? `\"${safe.replaceAll('\"', '\"\"')}\"` : safe;\n};\n\nexport function ChartExplorer<T extends ChartExplorerRow>(props: ChartExplorerProps<T>) {\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const locale = useLocale();\n const id = `k2b-chart-explorer-${createUniqueId()}`;\n const data = () => props.data;\n const [copyFailed, setCopyFailed] = createSignal(false);\n const [localSelection, setLocalSelection] = createSignal<string | null>(null);\n const [localView, setLocalView] = createSignal(props.defaultView ?? \"chart\");\n const [localSort, setLocalSort] = createSignal<DataTableSort | null>(props.defaultSort ?? null);\n const view = () => props.view ?? localView();\n const sort = () => (props.sort === undefined ? localSort() : props.sort);\n const setView = (value: \"chart\" | \"table\") => {\n if (props.view === undefined) setLocalView(value);\n props.onViewChange?.(value);\n };\n const setSort = (value: DataTableSort | null) => {\n if (props.sort === undefined) setLocalSort(value);\n props.onSortChange?.(value);\n };\n const rowsByKey = createMemo(() => new Map(data().rows.map((row) => [row.key, row])));\n const rawSelected = () => (props.selectedKey !== undefined ? props.selectedKey : localSelection());\n const selected = () => (rowsByKey().has(rawSelected() ?? \"\") ? rawSelected() : null);\n const selectedRow = () => rowsByKey().get(selected() ?? \"\");\n const select = (key: string | null) => {\n if (key !== null && !rowsByKey().has(key)) return;\n setLocalSelection(key);\n props.onSelectedKeyChange?.(key);\n };\n if (\n !props.columns.length ||\n props.columns.some((column) => !column.id) ||\n new Set(props.columns.map((column) => column.id)).size !== props.columns.length\n ) {\n throw new Error(\"Chart columns require unique nonempty IDs and at least one column\");\n }\n validateChartExplorerData(data());\n createEffect(() => validateChartExplorerData(data()));\n createEffect(() => {\n if (props.selectedKey === undefined && rawSelected() !== null && selected() === null) select(null);\n });\n const rows = createMemo(() => {\n const result = [...data().rows];\n const order = sort();\n const column = props.columns.find((c) => c.id === order?.key);\n const value = column?.sortValue;\n if (!order || !value) return result;\n const collator = new Intl.Collator(locale(), { numeric: true });\n return result.sort((a, b) => {\n const av = value(a),\n bv = value(b);\n if (av === null) return bv === null ? 0 : 1;\n if (bv === null) return -1;\n const comparison = typeof av === \"number\" && typeof bv === \"number\" ? av - bv : collator.compare(String(av), String(bv));\n return order.direction === \"asc\" ? comparison : -comparison;\n });\n });\n const shownRows = () => (props.tableRows === undefined ? rows() : rows().slice(0, props.tableRows));\n // Chart ids are data; a prefix keeps one named \"table\" apart from the table entry.\n const switcherValue = () => (view() === \"table\" || !props.charts?.length ? view() : `chart:${props.chart ?? props.charts[0]?.id}`);\n const switcherOptions = () =>\n props.charts?.length\n ? [\n ...props.charts.map((chart) => ({ value: `chart:${chart.id}`, label: chart.label })),\n { value: \"table\", label: chartMessages().chartData },\n ]\n : [\n { value: \"chart\", label: chartMessages().chartDiagram },\n { value: \"table\", label: chartMessages().chartData },\n ];\n const pick = (value: string) => {\n if (value === \"table\" || value === \"chart\") return setView(value);\n setView(\"chart\");\n props.onChartChange?.(value.slice(\"chart:\".length));\n };\n const copyText = () =>\n [\n props.columns.map((c) => tsvCell(c.label)).join(\"\\t\"),\n ...rows().map((row) => props.columns.map((c) => tsvCell(c.value(row), typeof c.sortValue?.(row) === \"number\")).join(\"\\t\")),\n ].join(\"\\n\");\n return (\n <section class={`k2b-chart-explorer ${props.class ?? \"\"}`} aria-labelledby={id}>\n <header class=\"k2b-chart-explorer__header\">\n <div>\n <Dynamic component={`h${props.headingLevel ?? 3}`} id={id} class=\"k2b-chart-explorer__title\">\n {props.title}\n </Dynamic>\n <Show when={props.description}>\n <div>{props.description}</div>\n </Show>\n </div>\n <div class=\"k2b-chart-explorer__actions\">\n <CopyButton\n text={copyText()}\n label={chartMessages().chartCopyData}\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n disabled={!rows().length}\n onCopyError={() => setCopyFailed(true)}\n onCopied={() => setCopyFailed(false)}\n />\n <SelectChip<string>\n value={switcherValue()}\n onValueChange={pick}\n aria-label={chartMessages().chartView}\n options={switcherOptions()}\n />\n </div>\n </header>\n <Show when={copyFailed()}>\n <span role=\"alert\">{chartMessages().chartCopyFailed}</span>\n </Show>\n {props.controls}\n <div\n class=\"k2b-chart-explorer__viewport\"\n data-legend={view() === \"chart\" && props.legend?.length && data().rows.length > 0 ? \"true\" : undefined}\n data-capped={view() === \"table\" && shownRows().length < rows().length ? \"true\" : undefined}\n style={{ height: props.height ?? \"18rem\" }}\n >\n <Show when={data().rows.length > 0} fallback={<div class=\"k2b-chart__empty\">{props.empty ?? messages().noData}</div>}>\n <Show\n when={view() === \"chart\"}\n fallback={\n <>\n <DataTable\n rows={shownRows()}\n columns={props.columns.map((column) => ({\n id: column.id,\n header: column.label,\n value: column.value,\n align: column.align,\n sortable: Boolean(column.sortValue),\n }))}\n ariaLabelledBy={id}\n getRowId={(row) => row.key}\n selectedRowId={selected()}\n sort={sort()}\n fillHeight\n surface=\"paper\"\n onRowClick={(row) => select(row.key)}\n renderCell={({ row, col, value, render }) => {\n const custom = props.columns.find((column) => column.id === col.id)?.render;\n const cell = () => (custom ? custom(row) : render(value));\n return !custom && col.id === props.columns[0]?.id ? (\n <Button variant=\"text\" size=\"sm\" onClick={() => select(row.key)}>\n {cell()}\n </Button>\n ) : (\n cell()\n );\n }}\n renderHeader={({ col, render }) =>\n col.sortable ? (\n <Button\n variant=\"text\"\n size=\"sm\"\n onClick={() =>\n setSort({\n key: col.id,\n direction: sort()?.key === col.id && sort()?.direction === \"asc\" ? \"desc\" : \"asc\",\n })\n }\n >\n {props.columns.find((column) => column.id === col.id)?.label}\n {/* The data table's own marker: inactive columns keep a dimmed arrow so the header reads as sortable. */}\n <i\n class={`k2b-data-table__sort-icon ti ${sort()?.key === col.id && sort()?.direction === \"asc\" ? \"ti-arrow-up\" : \"ti-arrow-down\"}`}\n data-active={sort()?.key === col.id ? \"true\" : undefined}\n aria-hidden=\"true\"\n />\n </Button>\n ) : (\n render()\n )\n }\n />\n <Show when={shownRows().length < rows().length}>\n <p class=\"k2b-chart-explorer__note\">\n {chartMessages().chartRowsShown({\n shown: new Intl.NumberFormat(locale()).format(shownRows().length),\n total: new Intl.NumberFormat(locale()).format(rows().length),\n })}\n </p>\n </Show>\n </>\n }\n >\n <ChartSnapshotView\n cursor={props.cursor}\n snapshot={data().chart}\n selectedKey={selected()}\n onSelect={select}\n style={props.legend?.length ? undefined : { height: \"100%\" }}\n />\n <Show when={props.legend?.length}>\n <ul class=\"k2b-chart-legend\" aria-label={chartMessages().chartLegend}>\n <For each={props.legend}>\n {(entry) => (\n <li>\n <span\n class=\"k2b-chart-legend__swatch\"\n data-style={entry.style && entry.style !== \"solid\" ? entry.style : undefined}\n data-reference={entry.reference ? \"true\" : undefined}\n style={{ \"--k2b-chart-legend-color\": `var(--stdlib-chart-c${(Math.abs(Math.trunc(entry.color)) % 8) + 1})` }}\n aria-hidden=\"true\"\n />\n {entry.label}\n </li>\n )}\n </For>\n </ul>\n </Show>\n </Show>\n </Show>\n </div>\n <Show when={props.renderDetails !== false}>\n <div class=\"k2b-chart-explorer__details\" aria-live=\"polite\">\n <Show when={selectedRow()}>\n {(row) => (\n <Paper class=\"k2b-chart-explorer__detail-paper\">\n <div class=\"k2b-chart-explorer__detail-header\">\n <span>{chartMessages().chartSelectedDatum}</span>\n <IconButton variant=\"text\" size=\"sm\" label={messages().clearSelection} onClick={() => select(null)}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n {props.renderDetails ? (\n props.renderDetails(row())\n ) : (\n <DescriptionList\n columns={3}\n size=\"sm\"\n items={props.columns.map((column) => ({\n term: column.label,\n description: column.value(row()),\n }))}\n />\n )}\n </Paper>\n )}\n </Show>\n </div>\n </Show>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/ChartExplorer.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, createUniqueId, For, type JSX, Show } from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { CopyButton } from \"../actions/CopyButton\";\nimport { SelectChip } from \"../inputs/SelectChip\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { DescriptionList } from \"../surfaces/DescriptionList\";\nimport { Paper } from \"../surfaces/Paper\";\nimport { ChartSnapshotView } from \"./ChartSnapshotView\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { type ChartExplorerData, type ChartExplorerRow, validateChartExplorerData } from \"./chart-explorer\";\nimport { useChartMessages } from \"./chart-messages\";\nimport DataTable, { type DataTableSort } from \"./DataTable\";\n\nexport type ChartExplorerColumn<T> = {\n id: string;\n label: string;\n value: (row: T) => string;\n /** Optional table cell presentation; value remains the plain text used for copy/details. */\n render?: (row: T) => JSX.Element;\n /**\n * Explicit comparable value. Omit to leave the column unsortable.\n */\n sortValue?: (row: T) => string | number | null;\n align?: \"left\" | \"center\" | \"right\";\n};\n/** One legend entry; `color` is the palette index the renderer gave the series (0 is `--stdlib-chart-c1`). */\nexport type ChartLegendEntry = {\n label: string;\n color: number;\n /** Line pattern of a line series; a solid series shows a filled swatch. */\n style?: \"solid\" | \"dashed\" | \"dotted\";\n /** A comparison series, drawn hollow like its marks. */\n reference?: boolean;\n};\nexport type ChartExplorerProps<T extends ChartExplorerRow> = {\n cursor?: ChartCursor;\n title: string;\n /** Level of the title heading. Defaults to 3; a chart inside a titled group of charts sits one level below it. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n description?: JSX.Element;\n data: ChartExplorerData<T>;\n columns: readonly ChartExplorerColumn<T>[];\n view?: \"chart\" | \"table\";\n defaultView?: \"chart\" | \"table\";\n onViewChange?: (view: \"chart\" | \"table\") => void;\n /**\n * Several charts of the same rows. The switcher then lists each chart and the table; `chart` names the one `data`\n * holds, and `onChartChange` reports a pick, so the owner passes the matching data.\n */\n charts?: readonly { id: string; label: string }[];\n chart?: string;\n onChartChange?: (id: string) => void;\n /** Filter controls between the header and the viewport, such as ChartFilterControls. */\n controls?: JSX.Element;\n /** The table renders at most this many rows of the sorted order; sorting and Copy data use every row. */\n tableRows?: number;\n sort?: DataTableSort | null;\n defaultSort?: DataTableSort | null;\n onSortChange?: (sort: DataTableSort | null) => void;\n selectedKey?: string | null;\n onSelectedKeyChange?: (key: string | null) => void;\n /** false hides the complete local detail area for a shared selection panel. */\n renderDetails?: false | ((row: T) => JSX.Element);\n height?: string;\n /**\n * Series names below the chart, wrapping inside the fixed viewport height. Use it instead of the renderer's legend,\n * which draws in one row and runs out of narrow columns.\n */\n legend?: readonly ChartLegendEntry[];\n /** What the viewport shows without rows, for example while they load; defaults to \"No data\". */\n empty?: JSX.Element;\n class?: string;\n};\n\n// Only the copied text can prove that a cell is a number; a numeric sort key cannot.\nconst plainNumber = /^[-+]?\\p{Sc}?\\s?\\d[\\d.,\\s]*(?:\\s?(?:%|\\p{Sc}))?$/u;\nconst tsvCell = (value: string) => {\n const safe = /^[=+\\-@\\t\\r]/.test(value) && !plainNumber.test(value) ? `'${value}` : value;\n return /[\\t\\r\\n\"]/.test(safe) ? `\"${safe.replaceAll('\"', '\"\"')}\"` : safe;\n};\n\nexport function ChartExplorer<T extends ChartExplorerRow>(props: ChartExplorerProps<T>) {\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const locale = useLocale();\n const id = `k2b-chart-explorer-${createUniqueId()}`;\n const data = () => props.data;\n const [copyFailed, setCopyFailed] = createSignal(false);\n const [localSelection, setLocalSelection] = createSignal<string | null>(null);\n const [localView, setLocalView] = createSignal(props.defaultView ?? \"chart\");\n const [localSort, setLocalSort] = createSignal<DataTableSort | null>(props.defaultSort ?? null);\n const view = () => props.view ?? localView();\n const sort = () => (props.sort === undefined ? localSort() : props.sort);\n const setView = (value: \"chart\" | \"table\") => {\n if (props.view === undefined) setLocalView(value);\n props.onViewChange?.(value);\n };\n const setSort = (value: DataTableSort | null) => {\n if (props.sort === undefined) setLocalSort(value);\n props.onSortChange?.(value);\n };\n const rowsByKey = createMemo(() => new Map(data().rows.map((row) => [row.key, row])));\n const rawSelected = () => (props.selectedKey !== undefined ? props.selectedKey : localSelection());\n const selected = () => (rowsByKey().has(rawSelected() ?? \"\") ? rawSelected() : null);\n const selectedRow = () => rowsByKey().get(selected() ?? \"\");\n const select = (key: string | null) => {\n if (key !== null && !rowsByKey().has(key)) return;\n setLocalSelection(key);\n props.onSelectedKeyChange?.(key);\n };\n if (\n !props.columns.length ||\n props.columns.some((column) => !column.id) ||\n new Set(props.columns.map((column) => column.id)).size !== props.columns.length\n ) {\n throw new Error(\"Chart columns require unique nonempty IDs and at least one column\");\n }\n validateChartExplorerData(data());\n createEffect(() => validateChartExplorerData(data()));\n createEffect(() => {\n if (props.selectedKey === undefined && rawSelected() !== null && selected() === null) select(null);\n });\n const rows = createMemo(() => {\n const result = [...data().rows];\n const order = sort();\n const column = props.columns.find((c) => c.id === order?.key);\n const value = column?.sortValue;\n if (!order || !value) return result;\n const collator = new Intl.Collator(locale(), { numeric: true });\n return result.sort((a, b) => {\n const av = value(a),\n bv = value(b);\n if (av === null) return bv === null ? 0 : 1;\n if (bv === null) return -1;\n const comparison = typeof av === \"number\" && typeof bv === \"number\" ? av - bv : collator.compare(String(av), String(bv));\n return order.direction === \"asc\" ? comparison : -comparison;\n });\n });\n const shownRows = () => (props.tableRows === undefined ? rows() : rows().slice(0, props.tableRows));\n // Chart ids are data; a prefix keeps one named \"table\" apart from the table entry.\n const switcherValue = () => (view() === \"table\" || !props.charts?.length ? view() : `chart:${props.chart ?? props.charts[0]?.id}`);\n const switcherOptions = () =>\n props.charts?.length\n ? [\n ...props.charts.map((chart) => ({ value: `chart:${chart.id}`, label: chart.label })),\n { value: \"table\", label: chartMessages().chartData },\n ]\n : [\n { value: \"chart\", label: chartMessages().chartDiagram },\n { value: \"table\", label: chartMessages().chartData },\n ];\n const pick = (value: string) => {\n if (value === \"table\" || value === \"chart\") return setView(value);\n setView(\"chart\");\n props.onChartChange?.(value.slice(\"chart:\".length));\n };\n const copyText = () =>\n [\n props.columns.map((c) => tsvCell(c.label)).join(\"\\t\"),\n ...rows().map((row) => props.columns.map((c) => tsvCell(c.value(row))).join(\"\\t\")),\n ].join(\"\\n\");\n return (\n <section class={`k2b-chart-explorer ${props.class ?? \"\"}`} aria-labelledby={id}>\n <header class=\"k2b-chart-explorer__header\">\n <div>\n <Dynamic component={`h${props.headingLevel ?? 3}`} id={id} class=\"k2b-chart-explorer__title\">\n {props.title}\n </Dynamic>\n <Show when={props.description}>\n <div>{props.description}</div>\n </Show>\n </div>\n <div class=\"k2b-chart-explorer__actions\">\n <CopyButton\n text={copyText()}\n label={chartMessages().chartCopyData}\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n disabled={!rows().length}\n onCopyError={() => setCopyFailed(true)}\n onCopied={() => setCopyFailed(false)}\n />\n <SelectChip<string>\n value={switcherValue()}\n onValueChange={pick}\n aria-label={chartMessages().chartView}\n options={switcherOptions()}\n />\n </div>\n </header>\n <Show when={copyFailed()}>\n <span role=\"alert\">{chartMessages().chartCopyFailed}</span>\n </Show>\n {props.controls}\n <div\n class=\"k2b-chart-explorer__viewport\"\n data-legend={view() === \"chart\" && props.legend?.length && data().rows.length > 0 ? \"true\" : undefined}\n data-capped={view() === \"table\" && shownRows().length < rows().length ? \"true\" : undefined}\n style={{ height: props.height ?? \"18rem\" }}\n >\n <Show when={data().rows.length > 0} fallback={<div class=\"k2b-chart__empty\">{props.empty ?? messages().noData}</div>}>\n <Show\n when={view() === \"chart\"}\n fallback={\n <>\n <DataTable\n rows={shownRows()}\n columns={props.columns.map((column) => ({\n id: column.id,\n header: column.label,\n value: column.value,\n align: column.align,\n sortable: Boolean(column.sortValue),\n }))}\n ariaLabelledBy={id}\n getRowId={(row) => row.key}\n selectedRowId={selected()}\n sort={sort()}\n fillHeight\n surface=\"paper\"\n onRowClick={(row) => select(row.key)}\n renderCell={({ row, col, value, render }) => {\n const custom = props.columns.find((column) => column.id === col.id)?.render;\n const cell = () => (custom ? custom(row) : render(value));\n return !custom && col.id === props.columns[0]?.id ? (\n <Button variant=\"text\" size=\"sm\" onClick={() => select(row.key)}>\n {cell()}\n </Button>\n ) : (\n cell()\n );\n }}\n renderHeader={({ col, render }) =>\n col.sortable ? (\n <Button\n variant=\"text\"\n size=\"sm\"\n onClick={() =>\n setSort({\n key: col.id,\n direction: sort()?.key === col.id && sort()?.direction === \"asc\" ? \"desc\" : \"asc\",\n })\n }\n >\n {props.columns.find((column) => column.id === col.id)?.label}\n {/* The data table's own marker: inactive columns keep a dimmed arrow so the header reads as sortable. */}\n <i\n class={`k2b-data-table__sort-icon ti ${sort()?.key === col.id && sort()?.direction === \"asc\" ? \"ti-arrow-up\" : \"ti-arrow-down\"}`}\n data-active={sort()?.key === col.id ? \"true\" : undefined}\n aria-hidden=\"true\"\n />\n </Button>\n ) : (\n render()\n )\n }\n />\n <Show when={shownRows().length < rows().length}>\n <p class=\"k2b-chart-explorer__note\">\n {chartMessages().chartRowsShown({\n shown: new Intl.NumberFormat(locale()).format(shownRows().length),\n total: new Intl.NumberFormat(locale()).format(rows().length),\n })}\n </p>\n </Show>\n </>\n }\n >\n <ChartSnapshotView\n cursor={props.cursor}\n snapshot={data().chart}\n selectedKey={selected()}\n onSelect={select}\n style={props.legend?.length ? undefined : { height: \"100%\" }}\n />\n <Show when={props.legend?.length}>\n <ul class=\"k2b-chart-legend\" aria-label={chartMessages().chartLegend}>\n <For each={props.legend}>\n {(entry) => (\n <li>\n <span\n class=\"k2b-chart-legend__swatch\"\n data-style={entry.style && entry.style !== \"solid\" ? entry.style : undefined}\n data-reference={entry.reference ? \"true\" : undefined}\n style={{ \"--k2b-chart-legend-color\": `var(--stdlib-chart-c${(Math.abs(Math.trunc(entry.color)) % 8) + 1})` }}\n aria-hidden=\"true\"\n />\n {entry.label}\n </li>\n )}\n </For>\n </ul>\n </Show>\n </Show>\n </Show>\n </div>\n <Show when={props.renderDetails !== false}>\n <div class=\"k2b-chart-explorer__details\" aria-live=\"polite\">\n <Show when={selectedRow()}>\n {(row) => (\n <Paper class=\"k2b-chart-explorer__detail-paper\">\n <div class=\"k2b-chart-explorer__detail-header\">\n <span>{chartMessages().chartSelectedDatum}</span>\n <IconButton variant=\"text\" size=\"sm\" label={messages().clearSelection} onClick={() => select(null)}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n {props.renderDetails ? (\n props.renderDetails(row())\n ) : (\n <DescriptionList\n columns={3}\n size=\"sm\"\n items={props.columns.map((column) => ({\n term: column.label,\n description: column.value(row()),\n }))}\n />\n )}\n </Paper>\n )}\n </Show>\n </div>\n </Show>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -41,6 +41,7 @@ export function MapView(props) {
41
41
  const notice = children(() => props.notice);
42
42
  const empty = children(() => props.empty);
43
43
  const [state, setState] = createSignal("static");
44
+ createEffect(() => props.onStateChange?.(state()));
44
45
  const [dark, setDark] = createSignal(false);
45
46
  const [boxStyle, setBoxStyle] = createSignal();
46
47
  const [liveScale, setLiveScale] = createSignal();
@@ -196,12 +197,11 @@ export function MapView(props) {
196
197
  "CooperativeGesturesHandler.MacHelpText": t.gestureMac,
197
198
  "CooperativeGesturesHandler.MobileHelpText": t.gestureMobile
198
199
  }
199
- });
200
+ }, fail);
200
201
  map = instance;
201
202
  instance.on("error", event => {
202
- // Tile and source errors name their source and leave the map usable; a style that does not load does not.
203
- const styleFailed = !("sourceId" in event) && !("tile" in event);
204
- if (styleFailed && (state() === "loading" || replacingStyle)) fail();
203
+ // A missing paid resource must remain visible and recoverable, including failures after initial load.
204
+ if ("sourceId" in event || "tile" in event || state() === "loading" || replacingStyle) fail();
205
205
  });
206
206
  instance.on("style.load", () => {
207
207
  replacingStyle = false;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/MapView.tsx"],"sourcesContent":["import type { Map as LiveMap } from \"maplibre-gl\";\nimport { children, createEffect, createMemo, createSignal, type JSX, on, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { MapFootRow, MapGeometry, type MapScale, referenceScale, selectedMarker } from \"./MapViewFrame\";\nimport {\n DEFAULT_PADDING,\n fitCamera,\n type MapFrame,\n mapFrame,\n metersPerPixel,\n pinOffsets,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport type { MapViewMarker, MapViewProps, MapViewStyle } from \"./map-view-types\";\n\nexport type { MapViewProps } from \"./map-view-types\";\n\ntype MapState = \"static\" | \"loading\" | \"ready\" | \"error\" | \"no-webgl\" | \"empty\";\n\nfunction supportsWebgl(): boolean {\n try {\n const canvas = document.createElement(\"canvas\");\n // MapLibre 6 draws with WebGL 2 only; a browser with just WebGL 1 gets the static frame and the notice.\n const gl = canvas.getContext(\"webgl2\");\n if (!gl) return false;\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n return true;\n } catch {\n return false;\n }\n}\n\n/** A static server frame enhanced with a same-origin MapLibre worker only after it enters the viewport. */\nexport function MapView(props: MapViewProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const selectedId = createMemo(() => selected()?.id);\n const notice = children(() => props.notice);\n const empty = children(() => props.empty);\n const [state, setState] = createSignal<MapState>(\"static\");\n const [dark, setDark] = createSignal(false);\n const [boxStyle, setBoxStyle] = createSignal<JSX.CSSProperties>();\n const [liveScale, setLiveScale] = createSignal<MapScale>();\n const [measuredWidth, setMeasuredWidth] = createSignal<number>();\n // The zoom the person chose, once they zoomed; pin separation follows it relative to the current fit.\n const [chosenZoom, setChosenZoom] = createSignal<number>();\n const zoomFactor = createMemo(() => {\n const zoom = chosenZoom();\n const f = frame();\n const width = measuredWidth();\n if (zoom === undefined || !f || width === undefined) return 1;\n return 2 ** (zoom - fitCamera(f, width, props.padding ?? DEFAULT_PADDING).zoom);\n });\n const [needsReload, setNeedsReload] = createSignal(false);\n // The server picks the scale bar for the widest fit; once the width is known, the bar names a distance that fits it.\n const scale = createMemo((): MapScale | undefined => {\n const f = frame();\n if (!f) return undefined;\n const live = liveScale();\n if (live) return live;\n const width = measuredWidth();\n if (width === undefined) return referenceScale(f, props.padding ?? DEFAULT_PADDING);\n const camera = fitCamera(f, width, props.padding ?? DEFAULT_PADDING);\n const mpp = metersPerPixel(camera.center[1], camera.zoom);\n const bar = scaleBar(mpp);\n return { label: bar.label, width: `${bar.meters / mpp}px` };\n });\n const resolvedStyle = (): MapViewStyle => {\n const source = props.style;\n return typeof source === \"object\" && \"dark\" in source ? (dark() ? source.dark : source.light) : source;\n };\n let root!: HTMLDivElement;\n let live!: HTMLDivElement;\n let info!: HTMLDivElement;\n let map: LiveMap | undefined;\n let currentStyle: MapViewStyle | undefined;\n let disposed = false;\n let visible = false;\n let mounted = false;\n let touched = false;\n let replacingStyle = false;\n let generation = 0;\n let intersection: IntersectionObserver | undefined;\n let resize: ResizeObserver | undefined;\n let infoResize: ResizeObserver | undefined;\n const themes: MutationObserver[] = [];\n\n // From the person's first camera change on, the camera stays theirs; pin separation follows its zoom.\n const touch = () => {\n touched = true;\n if (map) setChosenZoom(map.getZoom());\n };\n const removeMap = () => {\n generation++;\n const previous = map;\n map = undefined;\n previous?.remove();\n setBoxStyle(undefined);\n setLiveScale(undefined);\n setChosenZoom(undefined);\n currentStyle = undefined;\n replacingStyle = false;\n };\n // MapLibre wraps its center across the antimeridian; geometry is drawn in the world copy nearest the camera.\n const worldCopy = (live: LiveMap, f: MapFrame): number => Math.round((live.getCenter().lng + 180) / 360 - (f.minX + f.spanX / 2));\n const syncOverlay = () => {\n const f = frame();\n if (!map || !f || state() !== \"ready\") return;\n const copy = worldCopy(map, f);\n const a = unprojectPoint(f.minX + copy, f.minY);\n const b = unprojectPoint(f.minX + copy + f.spanX, f.minY + f.spanY);\n const top = map.project([a.lon, a.lat]);\n const bottom = map.project([b.lon, b.lat]);\n setBoxStyle({\n left: `${top.x}px`,\n top: `${top.y}px`,\n width: `${bottom.x - top.x}px`,\n height: `${bottom.y - top.y}px`,\n transform: \"none\",\n });\n const mpp = metersPerPixel(map.getCenter().lat, map.getZoom());\n const bar = scaleBar(mpp);\n setLiveScale({ label: bar.label, width: `${bar.meters / mpp}px` });\n };\n const refit = () => {\n const f = frame();\n if (map && f && !touched) map.jumpTo(fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING));\n syncOverlay();\n };\n const start = async () => {\n if (disposed || !visible || !frame()) return;\n removeMap();\n touched = false;\n if (!supportsWebgl()) {\n setState(\"no-webgl\");\n return;\n }\n const attempt = generation;\n setState(\"loading\");\n const fail = () => {\n if (disposed || attempt !== generation) return;\n removeMap();\n setState(\"error\");\n };\n let engine: typeof import(\"./map-view-live\");\n try {\n engine = await import(\"./map-view-live\");\n } catch {\n // The map code did not load, for example because the page outlived a release that removed its files.\n // Importing the same address again cannot help; a reload fetches the current page and its map code.\n if (disposed || attempt !== generation) return;\n setNeedsReload(true);\n fail();\n return;\n }\n try {\n const { createMap } = engine;\n if (disposed || attempt !== generation) return;\n const f = frame();\n if (!f) return;\n currentStyle = resolvedStyle();\n const t = messages();\n const instance = createMap({\n container: live,\n style: currentStyle,\n ...fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING),\n attributionControl: false,\n cooperativeGestures: true,\n dragRotate: false,\n // Shift-drag box zoom needs MapLibre's own stylesheet for its rectangle and starts without an input event.\n boxZoom: false,\n pitchWithRotate: false,\n touchPitch: false,\n maxPitch: 0,\n bearing: 0,\n pitch: 0,\n keyboard: true,\n trackResize: false,\n // MapLibre's own gestures (keyboard and double-click zoom, inertia) follow the same choice as our buttons.\n // The value is read when the map starts; MapLibre keeps one setting for all maps on the page.\n reduceMotion: prefersReducedMotion(),\n locale: {\n \"Map.Title\": t.canvasTitle,\n \"CooperativeGesturesHandler.WindowsHelpText\": t.gestureWindows,\n \"CooperativeGesturesHandler.MacHelpText\": t.gestureMac,\n \"CooperativeGesturesHandler.MobileHelpText\": t.gestureMobile,\n },\n });\n map = instance;\n instance.on(\"error\", (event) => {\n // Tile and source errors name their source and leave the map usable; a style that does not load does not.\n const styleFailed = !(\"sourceId\" in event) && !(\"tile\" in event);\n if (styleFailed && (state() === \"loading\" || replacingStyle)) fail();\n });\n instance.on(\"style.load\", () => {\n replacingStyle = false;\n });\n instance.on(\"load\", () => {\n if (disposed || attempt !== generation) return;\n setState(\"ready\");\n refit();\n });\n instance.on(\"movestart\", (event) => {\n if (event.originalEvent) touch();\n });\n instance.on(\"move\", syncOverlay);\n // Pin separation is decided again once a zoom ends, not on every animation frame.\n instance.on(\"zoomend\", () => {\n if (map === instance && touched) setChosenZoom(instance.getZoom());\n });\n instance.on(\"resize\", syncOverlay);\n } catch {\n fail();\n }\n };\n const clearSelectedPin = () => {\n const marker = selected();\n if (!marker || state() !== \"ready\" || !map) return;\n const f = frame();\n const lon = marker.point.lon + (f ? worldCopy(map, f) * 360 : 0);\n const p = map.project([lon, marker.point.lat]);\n const offset = f ? pinOffsets(sortMarkers(props.markers ?? []), f, zoomFactor(), props.ownLocation?.point).get(marker.id) : undefined;\n const x = p.x + (offset?.dx ?? 0);\n const y = p.y + (offset?.dy ?? 0);\n const w = root.clientWidth;\n const h = root.clientHeight;\n const tile = info.getBoundingClientRect();\n const bounds = root.getBoundingClientRect();\n const tileTop = tile.top - bounds.top - 8;\n const covered =\n tile.height > 0 &&\n x >= tile.left - bounds.left - 8 &&\n x <= tile.right - bounds.left + 8 &&\n y >= tileTop &&\n y <= tile.bottom - bounds.top + 8;\n if (!covered && x >= 16 && x <= w - 16 && y >= 16 && y <= h - 16) return;\n touch();\n // Put the drawn pin, offset included, in the free band above the tile.\n const targetX = w / 2;\n const targetY = tile.height > 0 ? tileTop / 2 : h / 2;\n const target = map.unproject([x + w / 2 - targetX, y + h / 2 - targetY]);\n const camera = { center: [target.lng, target.lat] satisfies [number, number] };\n if (prefersReducedMotion()) map.jumpTo(camera);\n else map.easeTo(camera);\n };\n onMount(() => {\n mounted = true;\n const theme = () => setDark(!!root.closest('.dark, .k2b-dark, [data-theme=\"dark\"]'));\n theme();\n for (let ancestor: Element | null = root; ancestor; ancestor = ancestor.parentElement) {\n const observer = new MutationObserver(theme);\n observer.observe(ancestor, { attributes: true, attributeFilter: [\"class\", \"data-theme\"] });\n themes.push(observer);\n }\n setMeasuredWidth(root.clientWidth);\n resize = new ResizeObserver(() => {\n setMeasuredWidth(root.clientWidth);\n map?.resize();\n refit();\n });\n resize.observe(root);\n infoResize = new ResizeObserver(clearSelectedPin);\n infoResize.observe(info);\n const enter = () => {\n visible = true;\n intersection?.disconnect();\n if (frame()) void start();\n };\n if (!frame()) setState(\"empty\");\n if (typeof IntersectionObserver === \"undefined\") enter();\n else {\n intersection = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) enter();\n },\n { threshold: 0, rootMargin: \"0px\" },\n );\n intersection.observe(root);\n }\n });\n createEffect(\n on(\n frame,\n (value) => {\n if (!mounted) return;\n if (!value) {\n removeMap();\n setState(\"empty\");\n } else if (state() === \"empty\") {\n setState(\"static\");\n if (visible) void start();\n } else refit();\n },\n { defer: true },\n ),\n );\n createEffect(() => {\n const style = resolvedStyle();\n if (state() === \"ready\" && map && style !== currentStyle) {\n currentStyle = style;\n replacingStyle = true;\n map.setStyle(style);\n }\n });\n createEffect(() => {\n selected();\n state();\n untrack(clearSelectedPin);\n });\n onCleanup(() => {\n disposed = true;\n intersection?.disconnect();\n resize?.disconnect();\n infoResize?.disconnect();\n for (const observer of themes) observer.disconnect();\n removeMap();\n });\n const zoom = (direction: \"in\" | \"out\") => {\n if (!map || state() !== \"ready\") return;\n touch();\n const options = { animate: !prefersReducedMotion() };\n if (direction === \"in\") map.zoomIn(options);\n else map.zoomOut(options);\n };\n return (\n <div\n ref={root}\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state={state()}\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <div ref={live} class=\"k2b-map-view__live\" />\n <Show\n when={frame()}\n fallback={\n <div class=\"k2b-map-view__empty\">\n <Show when={empty()}>\n <span>{empty()}</span>\n </Show>\n </div>\n }\n >\n {(value) => (\n <MapGeometry {...props} frame={value()} boxStyle={boxStyle()} zoomFactor={zoomFactor()} onSelect={props.onSelect} interactive />\n )}\n </Show>\n <div class=\"k2b-map-view__messages\">\n <Show when={notice()}>\n <div class=\"k2b-map-view__notice\">{notice()}</div>\n </Show>\n <Show when={state() === \"loading\" || state() === \"error\" || state() === \"no-webgl\"}>\n <div class=\"k2b-map-view__status\" role=\"status\">\n <i\n aria-hidden=\"true\"\n class={state() === \"loading\" ? \"ti ti-loader-2 k2b-spin\" : state() === \"error\" ? \"ti ti-alert-circle\" : \"ti ti-info-circle\"}\n />\n <span>{state() === \"loading\" ? messages().loading : state() === \"error\" ? messages().error : messages().noWebgl}</span>\n <Show when={state() === \"error\"}>\n <Button size=\"xs\" variant=\"text\" onClick={() => (needsReload() ? window.location.reload() : void start())}>\n {needsReload() ? messages().reload : messages().retry}\n </Button>\n </Show>\n </div>\n </Show>\n </div>\n <div class=\"k2b-map-view__controls\">\n <div class=\"k2b-map-view__zoom\">\n <IconButton label={messages().zoomIn} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"in\")}>\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton label={messages().zoomOut} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"out\")}>\n <i class=\"ti ti-minus\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Show when={props.onLocate}>\n <IconButton\n class=\"k2b-map-view__locate\"\n tooltip={false}\n label={messages().locate}\n aria-pressed={!!props.ownLocation}\n onClick={() => props.onLocate?.()}\n >\n <i class=\"ti ti-current-location\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </div>\n <div class=\"k2b-map-view__foot\">\n <div ref={info} class=\"k2b-map-view__info\" aria-live=\"polite\">\n <Show when={selectedId()} keyed>\n {(_id) => {\n // Keep the tile's state and focus for this selection while its marker data refreshes.\n const initial = selected();\n const current = () => selected() ?? initial;\n const marker: MapViewMarker = {\n get id() {\n return current()!.id;\n },\n get point() {\n return current()!.point;\n },\n get mark() {\n return current()!.mark;\n },\n get label() {\n return current()!.label;\n },\n get tone() {\n return current()!.tone;\n },\n get selected() {\n return current()!.selected;\n },\n };\n return props.infoTile?.(marker);\n }}\n </Show>\n </div>\n <MapFootRow scale={scale()}>{props.attribution}</MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/MapView.tsx"],"sourcesContent":["import type { Map as LiveMap } from \"maplibre-gl\";\nimport { children, createEffect, createMemo, createSignal, type JSX, on, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { MapFootRow, MapGeometry, type MapScale, referenceScale, selectedMarker } from \"./MapViewFrame\";\nimport {\n DEFAULT_PADDING,\n fitCamera,\n type MapFrame,\n mapFrame,\n metersPerPixel,\n pinOffsets,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport type { MapViewMarker, MapViewProps, MapViewStyle } from \"./map-view-types\";\n\nexport type { MapViewProps } from \"./map-view-types\";\n\ntype MapState = \"static\" | \"loading\" | \"ready\" | \"error\" | \"no-webgl\" | \"empty\";\n\nfunction supportsWebgl(): boolean {\n try {\n const canvas = document.createElement(\"canvas\");\n // MapLibre 6 draws with WebGL 2 only; a browser with just WebGL 1 gets the static frame and the notice.\n const gl = canvas.getContext(\"webgl2\");\n if (!gl) return false;\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n return true;\n } catch {\n return false;\n }\n}\n\n/** A static server frame enhanced with a same-origin MapLibre worker only after it enters the viewport. */\nexport function MapView(props: MapViewProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const selectedId = createMemo(() => selected()?.id);\n const notice = children(() => props.notice);\n const empty = children(() => props.empty);\n const [state, setState] = createSignal<MapState>(\"static\");\n createEffect(() => props.onStateChange?.(state()));\n const [dark, setDark] = createSignal(false);\n const [boxStyle, setBoxStyle] = createSignal<JSX.CSSProperties>();\n const [liveScale, setLiveScale] = createSignal<MapScale>();\n const [measuredWidth, setMeasuredWidth] = createSignal<number>();\n // The zoom the person chose, once they zoomed; pin separation follows it relative to the current fit.\n const [chosenZoom, setChosenZoom] = createSignal<number>();\n const zoomFactor = createMemo(() => {\n const zoom = chosenZoom();\n const f = frame();\n const width = measuredWidth();\n if (zoom === undefined || !f || width === undefined) return 1;\n return 2 ** (zoom - fitCamera(f, width, props.padding ?? DEFAULT_PADDING).zoom);\n });\n const [needsReload, setNeedsReload] = createSignal(false);\n // The server picks the scale bar for the widest fit; once the width is known, the bar names a distance that fits it.\n const scale = createMemo((): MapScale | undefined => {\n const f = frame();\n if (!f) return undefined;\n const live = liveScale();\n if (live) return live;\n const width = measuredWidth();\n if (width === undefined) return referenceScale(f, props.padding ?? DEFAULT_PADDING);\n const camera = fitCamera(f, width, props.padding ?? DEFAULT_PADDING);\n const mpp = metersPerPixel(camera.center[1], camera.zoom);\n const bar = scaleBar(mpp);\n return { label: bar.label, width: `${bar.meters / mpp}px` };\n });\n const resolvedStyle = (): MapViewStyle => {\n const source = props.style;\n return typeof source === \"object\" && \"dark\" in source ? (dark() ? source.dark : source.light) : source;\n };\n let root!: HTMLDivElement;\n let live!: HTMLDivElement;\n let info!: HTMLDivElement;\n let map: LiveMap | undefined;\n let currentStyle: MapViewStyle | undefined;\n let disposed = false;\n let visible = false;\n let mounted = false;\n let touched = false;\n let replacingStyle = false;\n let generation = 0;\n let intersection: IntersectionObserver | undefined;\n let resize: ResizeObserver | undefined;\n let infoResize: ResizeObserver | undefined;\n const themes: MutationObserver[] = [];\n\n // From the person's first camera change on, the camera stays theirs; pin separation follows its zoom.\n const touch = () => {\n touched = true;\n if (map) setChosenZoom(map.getZoom());\n };\n const removeMap = () => {\n generation++;\n const previous = map;\n map = undefined;\n previous?.remove();\n setBoxStyle(undefined);\n setLiveScale(undefined);\n setChosenZoom(undefined);\n currentStyle = undefined;\n replacingStyle = false;\n };\n // MapLibre wraps its center across the antimeridian; geometry is drawn in the world copy nearest the camera.\n const worldCopy = (live: LiveMap, f: MapFrame): number => Math.round((live.getCenter().lng + 180) / 360 - (f.minX + f.spanX / 2));\n const syncOverlay = () => {\n const f = frame();\n if (!map || !f || state() !== \"ready\") return;\n const copy = worldCopy(map, f);\n const a = unprojectPoint(f.minX + copy, f.minY);\n const b = unprojectPoint(f.minX + copy + f.spanX, f.minY + f.spanY);\n const top = map.project([a.lon, a.lat]);\n const bottom = map.project([b.lon, b.lat]);\n setBoxStyle({\n left: `${top.x}px`,\n top: `${top.y}px`,\n width: `${bottom.x - top.x}px`,\n height: `${bottom.y - top.y}px`,\n transform: \"none\",\n });\n const mpp = metersPerPixel(map.getCenter().lat, map.getZoom());\n const bar = scaleBar(mpp);\n setLiveScale({ label: bar.label, width: `${bar.meters / mpp}px` });\n };\n const refit = () => {\n const f = frame();\n if (map && f && !touched) map.jumpTo(fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING));\n syncOverlay();\n };\n const start = async () => {\n if (disposed || !visible || !frame()) return;\n removeMap();\n touched = false;\n if (!supportsWebgl()) {\n setState(\"no-webgl\");\n return;\n }\n const attempt = generation;\n setState(\"loading\");\n const fail = () => {\n if (disposed || attempt !== generation) return;\n removeMap();\n setState(\"error\");\n };\n let engine: typeof import(\"./map-view-live\");\n try {\n engine = await import(\"./map-view-live\");\n } catch {\n // The map code did not load, for example because the page outlived a release that removed its files.\n // Importing the same address again cannot help; a reload fetches the current page and its map code.\n if (disposed || attempt !== generation) return;\n setNeedsReload(true);\n fail();\n return;\n }\n try {\n const { createMap } = engine;\n if (disposed || attempt !== generation) return;\n const f = frame();\n if (!f) return;\n currentStyle = resolvedStyle();\n const t = messages();\n const instance = createMap(\n {\n container: live,\n style: currentStyle,\n ...fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING),\n attributionControl: false,\n cooperativeGestures: true,\n dragRotate: false,\n // Shift-drag box zoom needs MapLibre's own stylesheet for its rectangle and starts without an input event.\n boxZoom: false,\n pitchWithRotate: false,\n touchPitch: false,\n maxPitch: 0,\n bearing: 0,\n pitch: 0,\n keyboard: true,\n trackResize: false,\n // MapLibre's own gestures (keyboard and double-click zoom, inertia) follow the same choice as our buttons.\n // The value is read when the map starts; MapLibre keeps one setting for all maps on the page.\n reduceMotion: prefersReducedMotion(),\n locale: {\n \"Map.Title\": t.canvasTitle,\n \"CooperativeGesturesHandler.WindowsHelpText\": t.gestureWindows,\n \"CooperativeGesturesHandler.MacHelpText\": t.gestureMac,\n \"CooperativeGesturesHandler.MobileHelpText\": t.gestureMobile,\n },\n },\n fail,\n );\n map = instance;\n instance.on(\"error\", (event) => {\n // A missing paid resource must remain visible and recoverable, including failures after initial load.\n if (\"sourceId\" in event || \"tile\" in event || state() === \"loading\" || replacingStyle) fail();\n });\n instance.on(\"style.load\", () => {\n replacingStyle = false;\n });\n instance.on(\"load\", () => {\n if (disposed || attempt !== generation) return;\n setState(\"ready\");\n refit();\n });\n instance.on(\"movestart\", (event) => {\n if (event.originalEvent) touch();\n });\n instance.on(\"move\", syncOverlay);\n // Pin separation is decided again once a zoom ends, not on every animation frame.\n instance.on(\"zoomend\", () => {\n if (map === instance && touched) setChosenZoom(instance.getZoom());\n });\n instance.on(\"resize\", syncOverlay);\n } catch {\n fail();\n }\n };\n const clearSelectedPin = () => {\n const marker = selected();\n if (!marker || state() !== \"ready\" || !map) return;\n const f = frame();\n const lon = marker.point.lon + (f ? worldCopy(map, f) * 360 : 0);\n const p = map.project([lon, marker.point.lat]);\n const offset = f ? pinOffsets(sortMarkers(props.markers ?? []), f, zoomFactor(), props.ownLocation?.point).get(marker.id) : undefined;\n const x = p.x + (offset?.dx ?? 0);\n const y = p.y + (offset?.dy ?? 0);\n const w = root.clientWidth;\n const h = root.clientHeight;\n const tile = info.getBoundingClientRect();\n const bounds = root.getBoundingClientRect();\n const tileTop = tile.top - bounds.top - 8;\n const covered =\n tile.height > 0 &&\n x >= tile.left - bounds.left - 8 &&\n x <= tile.right - bounds.left + 8 &&\n y >= tileTop &&\n y <= tile.bottom - bounds.top + 8;\n if (!covered && x >= 16 && x <= w - 16 && y >= 16 && y <= h - 16) return;\n touch();\n // Put the drawn pin, offset included, in the free band above the tile.\n const targetX = w / 2;\n const targetY = tile.height > 0 ? tileTop / 2 : h / 2;\n const target = map.unproject([x + w / 2 - targetX, y + h / 2 - targetY]);\n const camera = { center: [target.lng, target.lat] satisfies [number, number] };\n if (prefersReducedMotion()) map.jumpTo(camera);\n else map.easeTo(camera);\n };\n onMount(() => {\n mounted = true;\n const theme = () => setDark(!!root.closest('.dark, .k2b-dark, [data-theme=\"dark\"]'));\n theme();\n for (let ancestor: Element | null = root; ancestor; ancestor = ancestor.parentElement) {\n const observer = new MutationObserver(theme);\n observer.observe(ancestor, { attributes: true, attributeFilter: [\"class\", \"data-theme\"] });\n themes.push(observer);\n }\n setMeasuredWidth(root.clientWidth);\n resize = new ResizeObserver(() => {\n setMeasuredWidth(root.clientWidth);\n map?.resize();\n refit();\n });\n resize.observe(root);\n infoResize = new ResizeObserver(clearSelectedPin);\n infoResize.observe(info);\n const enter = () => {\n visible = true;\n intersection?.disconnect();\n if (frame()) void start();\n };\n if (!frame()) setState(\"empty\");\n if (typeof IntersectionObserver === \"undefined\") enter();\n else {\n intersection = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) enter();\n },\n { threshold: 0, rootMargin: \"0px\" },\n );\n intersection.observe(root);\n }\n });\n createEffect(\n on(\n frame,\n (value) => {\n if (!mounted) return;\n if (!value) {\n removeMap();\n setState(\"empty\");\n } else if (state() === \"empty\") {\n setState(\"static\");\n if (visible) void start();\n } else refit();\n },\n { defer: true },\n ),\n );\n createEffect(() => {\n const style = resolvedStyle();\n if (state() === \"ready\" && map && style !== currentStyle) {\n currentStyle = style;\n replacingStyle = true;\n map.setStyle(style);\n }\n });\n createEffect(() => {\n selected();\n state();\n untrack(clearSelectedPin);\n });\n onCleanup(() => {\n disposed = true;\n intersection?.disconnect();\n resize?.disconnect();\n infoResize?.disconnect();\n for (const observer of themes) observer.disconnect();\n removeMap();\n });\n const zoom = (direction: \"in\" | \"out\") => {\n if (!map || state() !== \"ready\") return;\n touch();\n const options = { animate: !prefersReducedMotion() };\n if (direction === \"in\") map.zoomIn(options);\n else map.zoomOut(options);\n };\n return (\n <div\n ref={root}\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state={state()}\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <div ref={live} class=\"k2b-map-view__live\" />\n <Show\n when={frame()}\n fallback={\n <div class=\"k2b-map-view__empty\">\n <Show when={empty()}>\n <span>{empty()}</span>\n </Show>\n </div>\n }\n >\n {(value) => (\n <MapGeometry {...props} frame={value()} boxStyle={boxStyle()} zoomFactor={zoomFactor()} onSelect={props.onSelect} interactive />\n )}\n </Show>\n <div class=\"k2b-map-view__messages\">\n <Show when={notice()}>\n <div class=\"k2b-map-view__notice\">{notice()}</div>\n </Show>\n <Show when={state() === \"loading\" || state() === \"error\" || state() === \"no-webgl\"}>\n <div class=\"k2b-map-view__status\" role=\"status\">\n <i\n aria-hidden=\"true\"\n class={state() === \"loading\" ? \"ti ti-loader-2 k2b-spin\" : state() === \"error\" ? \"ti ti-alert-circle\" : \"ti ti-info-circle\"}\n />\n <span>{state() === \"loading\" ? messages().loading : state() === \"error\" ? messages().error : messages().noWebgl}</span>\n <Show when={state() === \"error\"}>\n <Button size=\"xs\" variant=\"text\" onClick={() => (needsReload() ? window.location.reload() : void start())}>\n {needsReload() ? messages().reload : messages().retry}\n </Button>\n </Show>\n </div>\n </Show>\n </div>\n <div class=\"k2b-map-view__controls\">\n <div class=\"k2b-map-view__zoom\">\n <IconButton label={messages().zoomIn} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"in\")}>\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton label={messages().zoomOut} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"out\")}>\n <i class=\"ti ti-minus\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Show when={props.onLocate}>\n <IconButton\n class=\"k2b-map-view__locate\"\n tooltip={false}\n label={messages().locate}\n aria-pressed={!!props.ownLocation}\n onClick={() => props.onLocate?.()}\n >\n <i class=\"ti ti-current-location\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </div>\n <div class=\"k2b-map-view__foot\">\n <div ref={info} class=\"k2b-map-view__info\" aria-live=\"polite\">\n <Show when={selectedId()} keyed>\n {(_id) => {\n // Keep the tile's state and focus for this selection while its marker data refreshes.\n const initial = selected();\n const current = () => selected() ?? initial;\n const marker: MapViewMarker = {\n get id() {\n return current()!.id;\n },\n get point() {\n return current()!.point;\n },\n get mark() {\n return current()!.mark;\n },\n get label() {\n return current()!.label;\n },\n get tone() {\n return current()!.tone;\n },\n get selected() {\n return current()!.selected;\n },\n };\n return props.infoTile?.(marker);\n }}\n </Show>\n </div>\n <MapFootRow scale={scale()}>{props.attribution}</MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -295,7 +295,10 @@ export function createChartInspector(options) {
295
295
  if (hit && nodes.includes(hit)) return hit;
296
296
  if (seriesChart()) {
297
297
  const plot = updatePlotBounds();
298
- if (plot && (x < plot.left || x > plot.right || y < plot.top || y > plot.bottom)) return;
298
+ // SVG transforms and DOM rectangles can round the same painted edge
299
+ // differently. Keep its half-pixel raster fringe inspectable.
300
+ const edgeTolerance = 0.5;
301
+ if (plot && (x < plot.left - edgeTolerance || x > plot.right + edgeTolerance || y < plot.top - edgeTolerance || y > plot.bottom + edgeTolerance)) return;
299
302
  }
300
303
  // Exact shapes win. A small physical hit radius also reaches tiny or
301
304
  // zero-sized marks; distant whitespace leaves the chart unselected.