enarratio-emdash 0.1.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,21 +1,76 @@
1
- # Changelog
2
-
3
- All notable changes to enarratio-emdash are recorded here. The format follows
4
- [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
5
- [Semantic Versioning](https://semver.org/). Before 1.0.0, a minor version may change the options or
6
- the saved block's fields; every such change is listed here.
7
-
8
- ## [Unreleased]
9
-
10
- ## [0.1.0] - 2026-10-24
11
-
12
- ### Added
13
-
14
- - The Chart block for EmDash's Portable Text editor: bar, line, stacked area, scatter and heatmap
15
- charts drawn on the server by enarratio-astro 0.1.0 (Enarratio 0.3.1) from pasted CSV or
16
- spreadsheet data, with a required description, a data table, and light and dark themes.
17
- - Optional interactivity per chart, from Enarratio's enhancement script, added only to pages with
18
- an interactive chart.
19
- - `enarratioPlugin({ styles })`: `"theme"` (default), `"base"` for sites whose tokens define the
20
- colors, or `"none"`.
21
- - A note in place of a chart that cannot be drawn, saying why.
1
+ # Changelog
2
+
3
+ All notable changes to enarratio-emdash are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
5
+ [Semantic Versioning](https://semver.org/). Before 1.0.0, a minor version may change the options or
6
+ the saved block's fields; every such change is listed here.
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.4.2] - 2026-11-03
11
+
12
+ ### Changed
13
+
14
+ - Draws with enarratio-astro 0.4.2 (Enarratio 0.7.3: a chart no longer moves the page when the enhancement layer
15
+ loads, and a block that is not interactive shows no controls waiting for it). No block field changes.
16
+
17
+ ## [0.4.1] - 2026-11-03
18
+
19
+ ### Changed
20
+
21
+ - Draws with enarratio-astro 0.4.1 (Enarratio 0.7.2: timeline text never renders under 12 px).
22
+ - Requires Node.js 22.22 or later (was 22.16), the floor Astro 7.4 sets.
23
+
24
+ ## [0.4.0] - 2026-11-01
25
+
26
+ ### Changed
27
+
28
+ - Built on enarratio-astro 0.4.0 (Enarratio 0.7.0). No block field changes.
29
+
30
+ ### Release
31
+
32
+ - Staging works: the release job's setup-node moves from v4 to v7 (see enarratio-astro 0.4.0).
33
+
34
+ - Each release's `npm pack` tarball gets a GitHub artifact attestation beside npm's provenance:
35
+ `gh attestation verify enarratio-emdash-<version>.tgz --repo DrDustinEdwards/astro` checks a download.
36
+
37
+ ## [0.3.0] - 2026-10-31
38
+
39
+ ### Changed
40
+
41
+ - Built on enarratio-astro 0.3.0 (Enarratio 0.5.0). No block field changes.
42
+ - First release on npm since 0.1.0: 0.2.0 and 0.2.1 never reached npm, because trusted publishing was not yet
43
+ set up.
44
+ - The Data field's placeholder example and the README's theme example use neutral names.
45
+
46
+ ## [0.2.1] - 2026-10-31
47
+
48
+ ### Changed
49
+
50
+ - Built on enarratio-astro 0.2.1 (Enarratio 0.4.1).
51
+
52
+ ## [0.2.0] - 2026-10-31
53
+
54
+ ### Changed
55
+
56
+ - Draws with enarratio-astro 0.2.0 (Enarratio 0.4.0): a head with the title and the finding, a
57
+ summary under the chart, a CSV download, and wide charts that scroll sideways on a phone. The
58
+ caption field is now labeled for method or caveats; the source has its own field.
59
+
60
+ ### Added
61
+
62
+ - Fields `subtitle`, `notes`, `source`, `sourceHref`, `byline`, `xUnit` and `yUnit`. Blocks saved by
63
+ 0.1.0 draw as before.
64
+
65
+ ## [0.1.0] - 2026-10-24
66
+
67
+ ### Added
68
+
69
+ - The Chart block for EmDash's Portable Text editor: bar, line, stacked area, scatter and heatmap
70
+ charts drawn on the server by enarratio-astro 0.1.0 (Enarratio 0.3.1) from pasted CSV or
71
+ spreadsheet data, with a required description, a data table, and light and dark themes.
72
+ - Optional interactivity per chart, from Enarratio's enhancement script, added only to pages with
73
+ an interactive chart.
74
+ - `enarratioPlugin({ styles })`: `"theme"` (default), `"base"` for sites whose tokens define the
75
+ colors, or `"none"`.
76
+ - A note in place of a chart that cannot be drawn, saying why.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Dustin Edwards
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dustin Edwards
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,120 +1,122 @@
1
- # enarratio-emdash
2
-
3
- **Accessible charts for [EmDash](https://github.com/emdash-cms/emdash) sites, drawn on the server by
4
- [Enarratio](https://github.com/DrDustinEdwards/enarratio).**
5
-
6
- The plugin adds a **Chart** block to EmDash's Portable Text editor. An editor types `/chart`, pastes
7
- data from a spreadsheet (or types CSV), writes one sentence saying what the chart shows, and names
8
- the columns to plot. The published page gets the chart as HTML and SVG: complete before any script
9
- runs, readable by screen readers and search engines, with a data table, and in light and dark.
10
-
11
- It draws bar (stacked, side by side, vertical or horizontal; counting rows when no value column is
12
- given), line, stacked area, scatter (with an optional regression line and 95% band) and heatmap
13
- charts. A chart can be made interactive: hover and focus details, keyboard navigation, and
14
- click-to-filter, from Enarratio's small enhancement script, which is added only to pages that have
15
- an interactive chart.
16
-
17
- Supports EmDash 1.0 or later and Astro 6 or later. Status: 0.x, so options may change before 1.0;
18
- every change is in the [changelog](https://github.com/DrDustinEdwards/astro/blob/main/packages/enarratio-emdash/CHANGELOG.md).
19
-
20
- ## Install
21
-
22
- ```sh
23
- npm install enarratio-emdash
24
- ```
25
-
26
- Register it in `astro.config.mjs`, then build and deploy the site:
27
-
28
- ```js
29
- import emdash from "emdash/astro";
30
- import { enarratioPlugin } from "enarratio-emdash";
31
-
32
- export default defineConfig({
33
- integrations: [
34
- emdash({
35
- // ...your database and storage
36
- plugins: [enarratioPlugin()],
37
- }),
38
- ],
39
- });
40
- ```
41
-
42
- Nothing else is needed: EmDash adds the plugin's renderer to its `<PortableText>` component.
43
-
44
- ## Why a native plugin
45
-
46
- EmDash runs registry plugins in a sandbox, and sandboxed plugins cannot render on public pages. A
47
- block that draws on the page needs an Astro component loaded when the site builds, which only a
48
- native plugin (an npm package listed in `astro.config.mjs`) can provide. Native plugins run with the
49
- site's authority. This one declares no capabilities, makes no network requests and stores nothing:
50
- it only reads the block an editor saved and draws it.
51
-
52
- ## The Chart block
53
-
54
- | Field | Used by | Notes |
55
- |---|---|---|
56
- | Chart | all | Bar, Line, Area (stacked), Scatter or Heatmap. |
57
- | Title | all | Shown above the chart. Optional. |
58
- | Description | all | **Required.** What the chart shows and finds, in a sentence. It names the chart for screen readers. |
59
- | Data | all | CSV, semicolon-separated, or pasted from a spreadsheet (tab-separated). The first row names the columns. Numbers such as `1,234` (quoted in CSV) are read as numbers; an empty cell is a gap. Up to 5000 rows and 50 columns. |
60
- | Column along the x axis | all | Column names match without regard to case. Line and area charts read ISO dates (`2026-03-01`) as a time axis. |
61
- | Column of values (y) | all | Bar charts count rows when it is blank. For a heatmap, the row column. |
62
- | Series column | bar, line, area, scatter | Splits rows into series, told apart by color and by legend, labels or symbols. |
63
- | Heatmap: column of cell values | heatmap | |
64
- | Axis labels, caption | all | Optional. The caption is for source, method or caveats. |
65
- | Bar: several series, direction | bar | Stacked or side by side; vertical or horizontal. |
66
- | y scale | line, scatter | Linear or logarithmic. |
67
- | Regression | scatter | Least-squares line with its 95% confidence band. |
68
- | Data table | all | Behind a "Data table" toggle (default) or hidden for screen readers only. Every chart has one. |
69
- | Interactive | all | Adds Enarratio's enhancement script to the page. Off by default, so pages stay script-free. |
70
-
71
- A block that cannot be drawn (a column that is not in the data, text in a number column, a missing
72
- description) is replaced on the page by a short note saying why, and the reason is logged, so one
73
- mistake never breaks the page. Text in every field is escaped.
74
-
75
- ## Styles
76
-
77
- The plugin writes the chart CSS once per page that has a chart. `enarratioPlugin({ styles })` picks
78
- what it writes:
79
-
80
- - `"theme"` (default): Enarratio's default theme, in light and dark. Charts follow the page's
81
- `color-scheme`, so a site with `<meta name="color-scheme" content="light dark">` gets dark charts
82
- in dark mode.
83
- - `"base"`: Enarratio's layout rules without colors or fonts, for a site whose own design tokens
84
- define the `--enarratio-*` properties. [Capsomer](https://github.com/DrDustinEdwards/capsomer)'s
85
- tokens do.
86
- - `"none"`: nothing; the site includes Enarratio's stylesheet itself.
87
-
88
- To use your own Enarratio theme, or a theme that switches with an attribute instead of
89
- `color-scheme`, wrap the renderer and pass it to `<PortableText>`, which takes precedence over the
90
- plugin's:
91
-
92
- ```astro
93
- ---
94
- // src/components/SiteChart.astro
95
- import { Chart } from "enarratio-emdash/astro";
96
- import { labTheme } from "../lab-theme";
97
- ---
98
- <Chart node={Astro.props.node} theme={labTheme} stylesheetOptions={{ colorScheme: { dark: '[data-theme="dark"]' } }} />
99
- ```
100
-
101
- ```astro
102
- <PortableText value={post.data.content} components={{ type: { enarratioChart: SiteChart } }} />
103
- ```
104
-
105
- Enarratio's [README](https://github.com/DrDustinEdwards/enarratio#themes) covers themes and the
106
- custom properties.
107
-
108
- ## How it draws
109
-
110
- The block is rendered by [enarratio-astro](https://github.com/DrDustinEdwards/astro/tree/main/packages/enarratio-astro#readme)'s `Chart` component, so a chart
111
- saved in EmDash looks the same as one in an Astro page or a Markdown file. Bar, line and area
112
- charts are drawn by `enarratio/lite`, which builds the SVG as a string with no DOM, the cheapest
113
- render on Cloudflare Workers. Scatter plots and heatmaps load `enarratio/plot` (Observable Plot and
114
- linkedom) only on a page that has one.
115
-
116
- Development, the demo site and releases: the [repository README](https://github.com/DrDustinEdwards/astro#readme).
117
-
118
- ## License
119
-
120
- [MIT](LICENSE). Copyright (c) 2026 Dustin Edwards.
1
+ # enarratio-emdash
2
+
3
+ **Accessible charts for [EmDash](https://github.com/emdash-cms/emdash) sites, drawn on the server by
4
+ [Enarratio](https://github.com/DrDustinEdwards/enarratio).**
5
+
6
+ The plugin adds a **Chart** block to EmDash's Portable Text editor. An editor types `/chart`, pastes
7
+ data from a spreadsheet (or types CSV), writes one sentence saying what the chart shows, and names
8
+ the columns to plot. The published page gets the chart as HTML and SVG: complete before any script
9
+ runs, readable by screen readers and search engines, with a data table, and in light and dark.
10
+
11
+ It draws bar (stacked, side by side, vertical or horizontal; counting rows when no value column is
12
+ given), line, stacked area, scatter (with an optional regression line and 95% band) and heatmap
13
+ charts. A chart can be made interactive: hover and focus details, keyboard navigation, and
14
+ click-to-filter, from Enarratio's small enhancement script, which is added only to pages that have
15
+ an interactive chart.
16
+
17
+ Supports EmDash 1.0 or later and Astro 6 or later. Status: 0.x, so options may change before 1.0;
18
+ every change is in the [changelog](https://github.com/DrDustinEdwards/astro/blob/main/packages/enarratio-emdash/CHANGELOG.md).
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ npm install enarratio-emdash
24
+ ```
25
+
26
+ Register it in `astro.config.mjs`, then build and deploy the site:
27
+
28
+ ```js
29
+ import emdash from "emdash/astro";
30
+ import { enarratioPlugin } from "enarratio-emdash";
31
+
32
+ export default defineConfig({
33
+ integrations: [
34
+ emdash({
35
+ // ...your database and storage
36
+ plugins: [enarratioPlugin()],
37
+ }),
38
+ ],
39
+ });
40
+ ```
41
+
42
+ Nothing else is needed: EmDash adds the plugin's renderer to its `<PortableText>` component.
43
+
44
+ ## Why a native plugin
45
+
46
+ EmDash runs registry plugins in a sandbox, and sandboxed plugins cannot render on public pages. A
47
+ block that draws on the page needs an Astro component loaded when the site builds, which only a
48
+ native plugin (an npm package listed in `astro.config.mjs`) can provide. Native plugins run with the
49
+ site's authority. This one declares no capabilities, makes no network requests and stores nothing:
50
+ it only reads the block an editor saved and draws it.
51
+
52
+ ## The Chart block
53
+
54
+ | Field | Used by | Notes |
55
+ |---|---|---|
56
+ | Chart | all | Bar, Line, Area (stacked), Scatter or Heatmap. |
57
+ | Title, subtitle | all | Shown above the chart. Optional. |
58
+ | Description | all | **Required.** What the chart shows and finds, in a sentence. It names the chart for screen readers. |
59
+ | Data | all | CSV, semicolon-separated, or pasted from a spreadsheet (tab-separated). The first row names the columns. Numbers such as `1,234` (quoted in CSV) are read as numbers; an empty cell is a gap. Up to 5000 rows and 50 columns. |
60
+ | Column along the x axis | all | Column names match without regard to case. Line and area charts read ISO dates (`2026-03-01`) as a time axis. |
61
+ | Column of values (y) | all | Bar charts count rows when it is blank. For a heatmap, the row column. |
62
+ | Series column | bar, line, area, scatter | Splits rows into series, told apart by color and by legend, labels or symbols. |
63
+ | Heatmap: column of cell values | heatmap | |
64
+ | Axis labels and units | all | Optional. A unit shows after its axis label. |
65
+ | Caption, notes | all | Optional. The caption is for method or caveats; notes are for definitions. |
66
+ | Source, source link, byline | all | Optional. The source line, linked when a link is given, sits beside a CSV download of the data. |
67
+ | Bar: several series, direction | bar | Stacked or side by side; vertical or horizontal. |
68
+ | y scale | line, scatter | Linear or logarithmic. |
69
+ | Regression | scatter | Least-squares line with its 95% confidence band. |
70
+ | Data table | all | Behind a "Data table" toggle (default) or hidden for screen readers only. Every chart has one. |
71
+ | Interactive | all | Adds Enarratio's enhancement script to the page. Off by default, so pages stay script-free. |
72
+
73
+ A block that cannot be drawn (a column that is not in the data, text in a number column, a missing
74
+ description) is replaced on the page by a short note saying why, and the reason is logged, so one
75
+ mistake never breaks the page. Text in every field is escaped.
76
+
77
+ ## Styles
78
+
79
+ The plugin writes the chart CSS once per page that has a chart. `enarratioPlugin({ styles })` picks
80
+ what it writes:
81
+
82
+ - `"theme"` (default): Enarratio's default theme, in light and dark. Charts follow the page's
83
+ `color-scheme`, so a site with `<meta name="color-scheme" content="light dark">` gets dark charts
84
+ in dark mode.
85
+ - `"base"`: Enarratio's layout rules without colors or fonts, for a site whose own design tokens
86
+ define the `--enarratio-*` properties. [Capsomer](https://github.com/DrDustinEdwards/capsomer)'s
87
+ tokens do.
88
+ - `"none"`: nothing; the site includes Enarratio's stylesheet itself.
89
+
90
+ To use your own Enarratio theme, or a theme that switches with an attribute instead of
91
+ `color-scheme`, wrap the renderer and pass it to `<PortableText>`, which takes precedence over the
92
+ plugin's:
93
+
94
+ ```astro
95
+ ---
96
+ // src/components/SiteChart.astro
97
+ import { Chart } from "enarratio-emdash/astro";
98
+ import { siteTheme } from "../site-theme";
99
+ ---
100
+ <Chart node={Astro.props.node} theme={siteTheme} stylesheetOptions={{ colorScheme: { dark: '[data-theme="dark"]' } }} />
101
+ ```
102
+
103
+ ```astro
104
+ <PortableText value={post.data.content} components={{ type: { enarratioChart: SiteChart } }} />
105
+ ```
106
+
107
+ Enarratio's [README](https://github.com/DrDustinEdwards/enarratio#themes) covers themes and the
108
+ custom properties.
109
+
110
+ ## How it draws
111
+
112
+ The block is rendered by [enarratio-astro](https://github.com/DrDustinEdwards/astro/tree/main/packages/enarratio-astro#readme)'s `Chart` component, so a chart
113
+ saved in EmDash looks the same as one in an Astro page or a Markdown file. Bar, line and area
114
+ charts are drawn by `enarratio/lite`, which builds the SVG as a string with no DOM, the cheapest
115
+ render on Cloudflare Workers. Scatter plots and heatmaps load `enarratio/plot` (Observable Plot and
116
+ linkedom) only on a page that has one.
117
+
118
+ Development, the demo site and releases: the [repository README](https://github.com/DrDustinEdwards/astro#readme).
119
+
120
+ ## License
121
+
122
+ [MIT](LICENSE). Copyright (c) 2026 Dustin Edwards.
package/dist/block.d.ts CHANGED
@@ -7,8 +7,13 @@ export interface ChartNode {
7
7
  readonly _key?: string;
8
8
  readonly chart?: string;
9
9
  readonly title?: string;
10
+ readonly subtitle?: string;
10
11
  readonly alt?: string;
11
12
  readonly caption?: string;
13
+ readonly notes?: string;
14
+ readonly source?: string;
15
+ readonly sourceHref?: string;
16
+ readonly byline?: string;
12
17
  readonly data?: string;
13
18
  readonly x?: string;
14
19
  readonly y?: string;
@@ -16,6 +21,8 @@ export interface ChartNode {
16
21
  readonly value?: string;
17
22
  readonly xLabel?: string;
18
23
  readonly yLabel?: string;
24
+ readonly xUnit?: string;
25
+ readonly yUnit?: string;
19
26
  readonly layout?: string;
20
27
  readonly orientation?: string;
21
28
  readonly scale?: string;
package/dist/block.js CHANGED
@@ -25,6 +25,11 @@ export const chartBlock = {
25
25
  initial_value: "bar",
26
26
  },
27
27
  { type: "text_input", action_id: "title", label: "Title" },
28
+ {
29
+ type: "text_input",
30
+ action_id: "subtitle",
31
+ label: "Subtitle: how to read the chart (optional)",
32
+ },
28
33
  {
29
34
  type: "text_input",
30
35
  action_id: "alt",
@@ -36,7 +41,7 @@ export const chartBlock = {
36
41
  type: "text_input",
37
42
  action_id: "data",
38
43
  label: "Data",
39
- placeholder: "Paste from a spreadsheet or type CSV. The first row names the columns.\nyear,type,count\n2024,Talks,3",
44
+ placeholder: "Paste from a spreadsheet or type CSV. The first row names the columns.\nyear,type,count\n2024,Guides,3",
40
45
  multiline: true,
41
46
  },
42
47
  { type: "text_input", action_id: "x", label: "Column along the x axis" },
@@ -54,11 +59,17 @@ export const chartBlock = {
54
59
  { type: "text_input", action_id: "value", label: "Heatmap: column of cell values" },
55
60
  { type: "text_input", action_id: "xLabel", label: "x axis label (optional)" },
56
61
  { type: "text_input", action_id: "yLabel", label: "y axis label (optional)" },
62
+ { type: "text_input", action_id: "xUnit", label: "x axis unit, such as kg (optional)" },
63
+ { type: "text_input", action_id: "yUnit", label: "y axis unit (optional)" },
57
64
  {
58
65
  type: "text_input",
59
66
  action_id: "caption",
60
- label: "Caption: source, method or caveats (optional)",
67
+ label: "Caption: method or caveats (optional)",
61
68
  },
69
+ { type: "text_input", action_id: "notes", label: "Notes: what a measure means (optional)" },
70
+ { type: "text_input", action_id: "source", label: "Source of the data (optional)" },
71
+ { type: "text_input", action_id: "sourceHref", label: "Link to the source, https (optional)" },
72
+ { type: "text_input", action_id: "byline", label: "Made by (optional)" },
62
73
  {
63
74
  type: "select",
64
75
  action_id: "layout",
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  import type { PluginDescriptor, ResolvedPlugin } from "emdash";
11
11
  export { BLOCK_TYPE, type ChartNode, chartBlock } from "./block.js";
12
12
  /** Kept equal to package.json's version, which a test checks. */
13
- export declare const VERSION = "0.1.0";
13
+ export declare const VERSION = "0.4.2";
14
14
  /** Options for {@link enarratioPlugin}. */
15
15
  export interface EnarratioPluginOptions {
16
16
  /**
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { definePlugin } from "emdash";
2
2
  import { chartBlock } from "./block.js";
3
3
  export { BLOCK_TYPE, chartBlock } from "./block.js";
4
4
  /** Kept equal to package.json's version, which a test checks. */
5
- export const VERSION = "0.1.0";
5
+ export const VERSION = "0.4.2";
6
6
  const ID = "enarratio";
7
7
  const COMPONENTS = {
8
8
  theme: "enarratio-emdash/astro",
package/package.json CHANGED
@@ -1,62 +1,62 @@
1
- {
2
- "name": "enarratio-emdash",
3
- "version": "0.1.0",
4
- "description": "EmDash plugin: a Chart block for the Portable Text editor, drawn on the server by Enarratio as accessible HTML and SVG",
5
- "keywords": [
6
- "emdash",
7
- "emdash-plugin",
8
- "astro",
9
- "charts",
10
- "accessibility",
11
- "enarratio"
12
- ],
13
- "license": "MIT",
14
- "author": "Dustin Edwards (https://dustinedwards.info)",
15
- "type": "module",
16
- "sideEffects": false,
17
- "main": "./dist/index.js",
18
- "exports": {
19
- ".": {
20
- "types": "./dist/index.d.ts",
21
- "import": "./dist/index.js"
22
- },
23
- "./astro": "./src/astro/index.ts",
24
- "./astro/base": "./src/astro/base.ts",
25
- "./astro/none": "./src/astro/none.ts",
26
- "./package.json": "./package.json"
27
- },
28
- "files": [
29
- "dist",
30
- "src",
31
- "CHANGELOG.md",
32
- "README.md"
33
- ],
34
- "engines": {
35
- "node": ">=22.16"
36
- },
37
- "peerDependencies": {
38
- "astro": ">=6.0.0",
39
- "emdash": ">=1.0.0"
40
- },
41
- "publishConfig": {
42
- "access": "public",
43
- "tag": "latest"
44
- },
45
- "homepage": "https://github.com/DrDustinEdwards/astro/tree/main/packages/enarratio-emdash#readme",
46
- "bugs": {
47
- "url": "https://github.com/DrDustinEdwards/astro/issues"
48
- },
49
- "repository": {
50
- "type": "git",
51
- "url": "git+https://github.com/DrDustinEdwards/astro.git",
52
- "directory": "packages/enarratio-emdash"
53
- },
54
- "scripts": {
55
- "build": "tsc -p tsconfig.build.json",
56
- "test": "vitest run",
57
- "prepare": "npm run build"
58
- },
59
- "dependencies": {
60
- "enarratio-astro": "0.1.0"
61
- }
62
- }
1
+ {
2
+ "name": "enarratio-emdash",
3
+ "version": "0.4.2",
4
+ "description": "EmDash plugin: a Chart block for the Portable Text editor, drawn on the server by Enarratio as accessible HTML and SVG",
5
+ "keywords": [
6
+ "emdash",
7
+ "emdash-plugin",
8
+ "astro",
9
+ "charts",
10
+ "accessibility",
11
+ "enarratio"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "Dustin Edwards (https://dustinedwards.info)",
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "main": "./dist/index.js",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
23
+ "./astro": "./src/astro/index.ts",
24
+ "./astro/base": "./src/astro/base.ts",
25
+ "./astro/none": "./src/astro/none.ts",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "src",
31
+ "CHANGELOG.md",
32
+ "README.md"
33
+ ],
34
+ "engines": {
35
+ "node": ">=22.22"
36
+ },
37
+ "peerDependencies": {
38
+ "astro": "7.4.4",
39
+ "emdash": "1.4.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "tag": "latest"
44
+ },
45
+ "homepage": "https://github.com/DrDustinEdwards/astro/tree/main/packages/enarratio-emdash#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/DrDustinEdwards/astro/issues"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/DrDustinEdwards/astro.git",
52
+ "directory": "packages/enarratio-emdash"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.build.json",
56
+ "test": "vitest run",
57
+ "prepare": "npm run build"
58
+ },
59
+ "dependencies": {
60
+ "enarratio-astro": "0.4.2"
61
+ }
62
+ }
@@ -1,39 +1,46 @@
1
- ---
2
- /**
3
- * Renders a saved Chart block with enarratio-astro's Chart. EmDash passes the block as `node`;
4
- * the plugin's `styles` option picks the entry (astro, astro/base, astro/none) and so the `styles`
5
- * prop. A site can also wrap this component to pass its own Enarratio theme, and register the
6
- * wrapper through `<PortableText components={{ type: { enarratioChart: MyChart } }}>`.
7
- */
8
- import type { StyleOptions } from "enarratio-astro";
9
- import Chart from "enarratio-astro/Chart.astro";
10
- import type { ChartNode } from "../block.ts";
11
-
12
- interface Props extends StyleOptions {
13
- node: ChartNode;
14
- }
15
-
16
- const { node, ...style } = Astro.props;
17
- ---
18
-
19
- <Chart
20
- type={node.chart}
21
- data={node.data ?? ""}
22
- alt={node.alt}
23
- title={node.title}
24
- caption={node.caption}
25
- x={node.x}
26
- y={node.y}
27
- series={node.series}
28
- value={node.value}
29
- xLabel={node.xLabel}
30
- yLabel={node.yLabel}
31
- layout={node.layout}
32
- orientation={node.orientation}
33
- scale={node.scale}
34
- regression={node.regression}
35
- dataTable={node.dataTable}
36
- id={node._key ? `chart-${node._key}` : undefined}
37
- interactive={node.interactive === true}
38
- {...style}
39
- />
1
+ ---
2
+ /**
3
+ * Renders a saved Chart block with enarratio-astro's Chart. EmDash passes the block as `node`;
4
+ * the plugin's `styles` option picks the entry (astro, astro/base, astro/none) and so the `styles`
5
+ * prop. A site can also wrap this component to pass its own Enarratio theme, and register the
6
+ * wrapper through `<PortableText components={{ type: { enarratioChart: MyChart } }}>`.
7
+ */
8
+ import type { StyleOptions } from "enarratio-astro";
9
+ import Chart from "enarratio-astro/Chart.astro";
10
+ import type { ChartNode } from "../block.ts";
11
+
12
+ interface Props extends StyleOptions {
13
+ node: ChartNode;
14
+ }
15
+
16
+ const { node, ...style } = Astro.props;
17
+ ---
18
+
19
+ <Chart
20
+ type={node.chart}
21
+ data={node.data ?? ""}
22
+ alt={node.alt}
23
+ title={node.title}
24
+ subtitle={node.subtitle}
25
+ caption={node.caption}
26
+ notes={node.notes}
27
+ source={node.source}
28
+ sourceHref={node.sourceHref}
29
+ byline={node.byline}
30
+ x={node.x}
31
+ y={node.y}
32
+ series={node.series}
33
+ value={node.value}
34
+ xLabel={node.xLabel}
35
+ yLabel={node.yLabel}
36
+ xUnit={node.xUnit}
37
+ yUnit={node.yUnit}
38
+ layout={node.layout}
39
+ orientation={node.orientation}
40
+ scale={node.scale}
41
+ regression={node.regression}
42
+ dataTable={node.dataTable}
43
+ id={node._key ? `chart-${node._key}` : undefined}
44
+ interactive={node.interactive === true}
45
+ {...style}
46
+ />
@@ -1,6 +1,6 @@
1
- ---
2
- /** The Chart block with Enarratio's rules but no colors: the site's tokens define them. */
3
- import Chart from "./Chart.astro";
4
- ---
5
-
6
- <Chart node={Astro.props.node} styles="base" />
1
+ ---
2
+ /** The Chart block with Enarratio's rules but no colors: the site's tokens define them. */
3
+ import Chart from "./Chart.astro";
4
+ ---
5
+
6
+ <Chart node={Astro.props.node} styles="base" />
@@ -1,6 +1,6 @@
1
- ---
2
- /** The Chart block with no CSS of its own: the site includes Enarratio's stylesheet itself. */
3
- import Chart from "./Chart.astro";
4
- ---
5
-
6
- <Chart node={Astro.props.node} styles="none" />
1
+ ---
2
+ /** The Chart block with no CSS of its own: the site includes Enarratio's stylesheet itself. */
3
+ import Chart from "./Chart.astro";
4
+ ---
5
+
6
+ <Chart node={Astro.props.node} styles="none" />
package/src/astro/base.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** The renderer for `enarratioPlugin({ styles: "base" })`: Enarratio's rules, the site's colors. */
2
- import ChartBase from "./ChartBase.astro";
3
-
4
- export const blockComponents = { enarratioChart: ChartBase };
1
+ /** The renderer for `enarratioPlugin({ styles: "base" })`: Enarratio's rules, the site's colors. */
2
+ import ChartBase from "./ChartBase.astro";
3
+
4
+ export const blockComponents = { enarratioChart: ChartBase };
@@ -1,7 +1,7 @@
1
- // The type checker does not read .astro files; Astro's own compiler checks them when a site builds.
2
- declare module "*.astro" {
3
- import type { AstroComponentFactory } from "astro/runtime/server/index.js";
4
-
5
- const component: AstroComponentFactory;
6
- export default component;
7
- }
1
+ // The type checker does not read .astro files; Astro's own compiler checks them when a site builds.
2
+ declare module "*.astro" {
3
+ import type { AstroComponentFactory } from "astro/runtime/server/index.js";
4
+
5
+ const component: AstroComponentFactory;
6
+ export default component;
7
+ }
@@ -1,9 +1,9 @@
1
- /**
2
- * The site-side renderer EmDash merges into `<PortableText>`, writing the default theme's CSS.
3
- * The key must equal the block's `_type` (BLOCK_TYPE). `./base` and `./none` are the same
4
- * renderer for the plugin's other `styles` options.
5
- */
6
- import Chart from "./Chart.astro";
7
-
8
- export const blockComponents = { enarratioChart: Chart };
9
- export { Chart };
1
+ /**
2
+ * The site-side renderer EmDash merges into `<PortableText>`, writing the default theme's CSS.
3
+ * The key must equal the block's `_type` (BLOCK_TYPE). `./base` and `./none` are the same
4
+ * renderer for the plugin's other `styles` options.
5
+ */
6
+ import Chart from "./Chart.astro";
7
+
8
+ export const blockComponents = { enarratioChart: Chart };
9
+ export { Chart };
package/src/astro/none.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** The renderer for `enarratioPlugin({ styles: "none" })`: no CSS from the plugin. */
2
- import ChartUnstyled from "./ChartUnstyled.astro";
3
-
4
- export const blockComponents = { enarratioChart: ChartUnstyled };
1
+ /** The renderer for `enarratioPlugin({ styles: "none" })`: no CSS from the plugin. */
2
+ import ChartUnstyled from "./ChartUnstyled.astro";
3
+
4
+ export const blockComponents = { enarratioChart: ChartUnstyled };
package/src/block.ts CHANGED
@@ -1,136 +1,154 @@
1
- import type { PortableTextBlockConfig } from "emdash";
2
-
3
- /** The Portable Text `_type` of a chart block, and the key of its renderer. */
4
- export const BLOCK_TYPE = "enarratioChart";
5
-
6
- /** A saved Chart block: the editor form's values, every one optional until the chart is drawn. */
7
- export interface ChartNode {
8
- readonly _type: string;
9
- readonly _key?: string;
10
- readonly chart?: string;
11
- readonly title?: string;
12
- readonly alt?: string;
13
- readonly caption?: string;
14
- readonly data?: string;
15
- readonly x?: string;
16
- readonly y?: string;
17
- readonly series?: string;
18
- readonly value?: string;
19
- readonly xLabel?: string;
20
- readonly yLabel?: string;
21
- readonly layout?: string;
22
- readonly orientation?: string;
23
- readonly scale?: string;
24
- readonly regression?: boolean;
25
- readonly dataTable?: string;
26
- readonly interactive?: boolean;
27
- }
28
-
29
- /**
30
- * The chart block as the editor shows it: one form, whose `action_id`s become the saved block's
31
- * properties. Every field but the chart kind, description, data and x column is optional, and
32
- * the labels say which chart kinds read it.
33
- */
34
- export const chartBlock: PortableTextBlockConfig = {
35
- type: BLOCK_TYPE,
36
- label: "Chart",
37
- description: "An accessible chart drawn from data you paste",
38
- category: "Media",
39
- fields: [
40
- {
41
- type: "select",
42
- action_id: "chart",
43
- label: "Chart",
44
- options: [
45
- { label: "Bar", value: "bar" },
46
- { label: "Line", value: "line" },
47
- { label: "Area (stacked)", value: "area" },
48
- { label: "Scatter", value: "scatter" },
49
- { label: "Heatmap", value: "heatmap" },
50
- ],
51
- initial_value: "bar",
52
- },
53
- { type: "text_input", action_id: "title", label: "Title" },
54
- {
55
- type: "text_input",
56
- action_id: "alt",
57
- label: "Description (required)",
58
- placeholder: "What the chart shows and what it finds, in a sentence. Screen readers read it.",
59
- multiline: true,
60
- },
61
- {
62
- type: "text_input",
63
- action_id: "data",
64
- label: "Data",
65
- placeholder:
66
- "Paste from a spreadsheet or type CSV. The first row names the columns.\nyear,type,count\n2024,Talks,3",
67
- multiline: true,
68
- },
69
- { type: "text_input", action_id: "x", label: "Column along the x axis" },
70
- {
71
- type: "text_input",
72
- action_id: "y",
73
- label: "Column of values (y)",
74
- placeholder: "Bar charts count rows when this is blank. Heatmaps: the row column.",
75
- },
76
- {
77
- type: "text_input",
78
- action_id: "series",
79
- label: "Column that splits rows into series (optional)",
80
- },
81
- { type: "text_input", action_id: "value", label: "Heatmap: column of cell values" },
82
- { type: "text_input", action_id: "xLabel", label: "x axis label (optional)" },
83
- { type: "text_input", action_id: "yLabel", label: "y axis label (optional)" },
84
- {
85
- type: "text_input",
86
- action_id: "caption",
87
- label: "Caption: source, method or caveats (optional)",
88
- },
89
- {
90
- type: "select",
91
- action_id: "layout",
92
- label: "Bar: several series",
93
- options: [
94
- { label: "Stacked", value: "stacked" },
95
- { label: "Side by side", value: "grouped" },
96
- ],
97
- initial_value: "stacked",
98
- },
99
- {
100
- type: "select",
101
- action_id: "orientation",
102
- label: "Bar: direction",
103
- options: [
104
- { label: "Vertical", value: "vertical" },
105
- { label: "Horizontal", value: "horizontal" },
106
- ],
107
- initial_value: "vertical",
108
- },
109
- {
110
- type: "select",
111
- action_id: "scale",
112
- label: "Line and scatter: y scale",
113
- options: [
114
- { label: "Linear", value: "linear" },
115
- { label: "Logarithmic", value: "log" },
116
- ],
117
- initial_value: "linear",
118
- },
119
- { type: "toggle", action_id: "regression", label: "Scatter: regression line with 95% band" },
120
- {
121
- type: "select",
122
- action_id: "dataTable",
123
- label: "Data table",
124
- options: [
125
- { label: "Behind a Data table toggle", value: "details" },
126
- { label: "Hidden, for screen readers only", value: "visually-hidden" },
127
- ],
128
- initial_value: "details",
129
- },
130
- {
131
- type: "toggle",
132
- action_id: "interactive",
133
- label: "Interactive: hover details, keyboard navigation and filtering (adds a small script)",
134
- },
135
- ],
136
- };
1
+ import type { PortableTextBlockConfig } from "emdash";
2
+
3
+ /** The Portable Text `_type` of a chart block, and the key of its renderer. */
4
+ export const BLOCK_TYPE = "enarratioChart";
5
+
6
+ /** A saved Chart block: the editor form's values, every one optional until the chart is drawn. */
7
+ export interface ChartNode {
8
+ readonly _type: string;
9
+ readonly _key?: string;
10
+ readonly chart?: string;
11
+ readonly title?: string;
12
+ readonly subtitle?: string;
13
+ readonly alt?: string;
14
+ readonly caption?: string;
15
+ readonly notes?: string;
16
+ readonly source?: string;
17
+ readonly sourceHref?: string;
18
+ readonly byline?: string;
19
+ readonly data?: string;
20
+ readonly x?: string;
21
+ readonly y?: string;
22
+ readonly series?: string;
23
+ readonly value?: string;
24
+ readonly xLabel?: string;
25
+ readonly yLabel?: string;
26
+ readonly xUnit?: string;
27
+ readonly yUnit?: string;
28
+ readonly layout?: string;
29
+ readonly orientation?: string;
30
+ readonly scale?: string;
31
+ readonly regression?: boolean;
32
+ readonly dataTable?: string;
33
+ readonly interactive?: boolean;
34
+ }
35
+
36
+ /**
37
+ * The chart block as the editor shows it: one form, whose `action_id`s become the saved block's
38
+ * properties. Every field but the chart kind, description, data and x column is optional, and
39
+ * the labels say which chart kinds read it.
40
+ */
41
+ export const chartBlock: PortableTextBlockConfig = {
42
+ type: BLOCK_TYPE,
43
+ label: "Chart",
44
+ description: "An accessible chart drawn from data you paste",
45
+ category: "Media",
46
+ fields: [
47
+ {
48
+ type: "select",
49
+ action_id: "chart",
50
+ label: "Chart",
51
+ options: [
52
+ { label: "Bar", value: "bar" },
53
+ { label: "Line", value: "line" },
54
+ { label: "Area (stacked)", value: "area" },
55
+ { label: "Scatter", value: "scatter" },
56
+ { label: "Heatmap", value: "heatmap" },
57
+ ],
58
+ initial_value: "bar",
59
+ },
60
+ { type: "text_input", action_id: "title", label: "Title" },
61
+ {
62
+ type: "text_input",
63
+ action_id: "subtitle",
64
+ label: "Subtitle: how to read the chart (optional)",
65
+ },
66
+ {
67
+ type: "text_input",
68
+ action_id: "alt",
69
+ label: "Description (required)",
70
+ placeholder: "What the chart shows and what it finds, in a sentence. Screen readers read it.",
71
+ multiline: true,
72
+ },
73
+ {
74
+ type: "text_input",
75
+ action_id: "data",
76
+ label: "Data",
77
+ placeholder:
78
+ "Paste from a spreadsheet or type CSV. The first row names the columns.\nyear,type,count\n2024,Guides,3",
79
+ multiline: true,
80
+ },
81
+ { type: "text_input", action_id: "x", label: "Column along the x axis" },
82
+ {
83
+ type: "text_input",
84
+ action_id: "y",
85
+ label: "Column of values (y)",
86
+ placeholder: "Bar charts count rows when this is blank. Heatmaps: the row column.",
87
+ },
88
+ {
89
+ type: "text_input",
90
+ action_id: "series",
91
+ label: "Column that splits rows into series (optional)",
92
+ },
93
+ { type: "text_input", action_id: "value", label: "Heatmap: column of cell values" },
94
+ { type: "text_input", action_id: "xLabel", label: "x axis label (optional)" },
95
+ { type: "text_input", action_id: "yLabel", label: "y axis label (optional)" },
96
+ { type: "text_input", action_id: "xUnit", label: "x axis unit, such as kg (optional)" },
97
+ { type: "text_input", action_id: "yUnit", label: "y axis unit (optional)" },
98
+ {
99
+ type: "text_input",
100
+ action_id: "caption",
101
+ label: "Caption: method or caveats (optional)",
102
+ },
103
+ { type: "text_input", action_id: "notes", label: "Notes: what a measure means (optional)" },
104
+ { type: "text_input", action_id: "source", label: "Source of the data (optional)" },
105
+ { type: "text_input", action_id: "sourceHref", label: "Link to the source, https (optional)" },
106
+ { type: "text_input", action_id: "byline", label: "Made by (optional)" },
107
+ {
108
+ type: "select",
109
+ action_id: "layout",
110
+ label: "Bar: several series",
111
+ options: [
112
+ { label: "Stacked", value: "stacked" },
113
+ { label: "Side by side", value: "grouped" },
114
+ ],
115
+ initial_value: "stacked",
116
+ },
117
+ {
118
+ type: "select",
119
+ action_id: "orientation",
120
+ label: "Bar: direction",
121
+ options: [
122
+ { label: "Vertical", value: "vertical" },
123
+ { label: "Horizontal", value: "horizontal" },
124
+ ],
125
+ initial_value: "vertical",
126
+ },
127
+ {
128
+ type: "select",
129
+ action_id: "scale",
130
+ label: "Line and scatter: y scale",
131
+ options: [
132
+ { label: "Linear", value: "linear" },
133
+ { label: "Logarithmic", value: "log" },
134
+ ],
135
+ initial_value: "linear",
136
+ },
137
+ { type: "toggle", action_id: "regression", label: "Scatter: regression line with 95% band" },
138
+ {
139
+ type: "select",
140
+ action_id: "dataTable",
141
+ label: "Data table",
142
+ options: [
143
+ { label: "Behind a Data table toggle", value: "details" },
144
+ { label: "Hidden, for screen readers only", value: "visually-hidden" },
145
+ ],
146
+ initial_value: "details",
147
+ },
148
+ {
149
+ type: "toggle",
150
+ action_id: "interactive",
151
+ label: "Interactive: hover details, keyboard navigation and filtering (adds a small script)",
152
+ },
153
+ ],
154
+ };
package/src/index.ts CHANGED
@@ -1,61 +1,61 @@
1
- /**
2
- * Enarratio charts for EmDash: a Chart block for the Portable Text editor, drawn on the server
3
- * by Enarratio as accessible HTML and SVG.
4
- *
5
- * @example
6
- * // astro.config.mjs
7
- * import { enarratioPlugin } from "enarratio-emdash";
8
- * emdash({ plugins: [enarratioPlugin()] });
9
- */
10
- import type { PluginDescriptor, ResolvedPlugin } from "emdash";
11
- import { definePlugin } from "emdash";
12
- import { chartBlock } from "./block.js";
13
-
14
- export { BLOCK_TYPE, type ChartNode, chartBlock } from "./block.js";
15
-
16
- /** Kept equal to package.json's version, which a test checks. */
17
- export const VERSION = "0.1.0";
18
- const ID = "enarratio";
19
-
20
- /** Options for {@link enarratioPlugin}. */
21
- export interface EnarratioPluginOptions {
22
- /**
23
- * The CSS the plugin writes, once per page with a chart:
24
- * - `"theme"` (default): Enarratio's default theme, colors and rules, light and dark.
25
- * - `"base"`: the rules without colors or fonts, for a site whose own tokens define the
26
- * `--enarratio-*` properties (Capsomer's tokens do).
27
- * - `"none"`: nothing; the site includes Enarratio's stylesheet itself.
28
- */
29
- readonly styles?: "theme" | "base" | "none";
30
- }
31
-
32
- const COMPONENTS = {
33
- theme: "enarratio-emdash/astro",
34
- base: "enarratio-emdash/astro/base",
35
- none: "enarratio-emdash/astro/none",
36
- } as const;
37
-
38
- /** The descriptor a site lists in `astro.config.mjs`. */
39
- export function enarratioPlugin(options: EnarratioPluginOptions = {}): PluginDescriptor {
40
- return {
41
- id: ID,
42
- version: VERSION,
43
- format: "native",
44
- entrypoint: "enarratio-emdash",
45
- // Astro imports the renderer while it builds the site, before any plugin option reaches it,
46
- // so each styles option is its own entry.
47
- componentsEntry: COMPONENTS[options.styles ?? "theme"],
48
- };
49
- }
50
-
51
- /** The plugin EmDash loads at run time: the Chart block, and no capabilities, since it only draws. */
52
- export function createPlugin(): ResolvedPlugin {
53
- return definePlugin({
54
- id: ID,
55
- version: VERSION,
56
- capabilities: [],
57
- admin: { portableTextBlocks: [chartBlock] },
58
- });
59
- }
60
-
61
- export default createPlugin;
1
+ /**
2
+ * Enarratio charts for EmDash: a Chart block for the Portable Text editor, drawn on the server
3
+ * by Enarratio as accessible HTML and SVG.
4
+ *
5
+ * @example
6
+ * // astro.config.mjs
7
+ * import { enarratioPlugin } from "enarratio-emdash";
8
+ * emdash({ plugins: [enarratioPlugin()] });
9
+ */
10
+ import type { PluginDescriptor, ResolvedPlugin } from "emdash";
11
+ import { definePlugin } from "emdash";
12
+ import { chartBlock } from "./block.js";
13
+
14
+ export { BLOCK_TYPE, type ChartNode, chartBlock } from "./block.js";
15
+
16
+ /** Kept equal to package.json's version, which a test checks. */
17
+ export const VERSION = "0.4.2";
18
+ const ID = "enarratio";
19
+
20
+ /** Options for {@link enarratioPlugin}. */
21
+ export interface EnarratioPluginOptions {
22
+ /**
23
+ * The CSS the plugin writes, once per page with a chart:
24
+ * - `"theme"` (default): Enarratio's default theme, colors and rules, light and dark.
25
+ * - `"base"`: the rules without colors or fonts, for a site whose own tokens define the
26
+ * `--enarratio-*` properties (Capsomer's tokens do).
27
+ * - `"none"`: nothing; the site includes Enarratio's stylesheet itself.
28
+ */
29
+ readonly styles?: "theme" | "base" | "none";
30
+ }
31
+
32
+ const COMPONENTS = {
33
+ theme: "enarratio-emdash/astro",
34
+ base: "enarratio-emdash/astro/base",
35
+ none: "enarratio-emdash/astro/none",
36
+ } as const;
37
+
38
+ /** The descriptor a site lists in `astro.config.mjs`. */
39
+ export function enarratioPlugin(options: EnarratioPluginOptions = {}): PluginDescriptor {
40
+ return {
41
+ id: ID,
42
+ version: VERSION,
43
+ format: "native",
44
+ entrypoint: "enarratio-emdash",
45
+ // Astro imports the renderer while it builds the site, before any plugin option reaches it,
46
+ // so each styles option is its own entry.
47
+ componentsEntry: COMPONENTS[options.styles ?? "theme"],
48
+ };
49
+ }
50
+
51
+ /** The plugin EmDash loads at run time: the Chart block, and no capabilities, since it only draws. */
52
+ export function createPlugin(): ResolvedPlugin {
53
+ return definePlugin({
54
+ id: ID,
55
+ version: VERSION,
56
+ capabilities: [],
57
+ admin: { portableTextBlocks: [chartBlock] },
58
+ });
59
+ }
60
+
61
+ export default createPlugin;