@ascribed/elements 0.2.0 → 0.2.1-next.11
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/CONTRACT.md +2 -2
- package/README.md +7 -0
- package/css/style.css +89 -64
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/names.d.ts +95 -0
- package/dist/names.js +99 -0
- package/dist/names.js.map +1 -0
- package/dist/tabs.js +2 -1
- package/dist/tabs.js.map +1 -1
- package/package.json +2 -1
package/CONTRACT.md
CHANGED
|
@@ -12,11 +12,11 @@ The site output (SPEC §9.4) is markdown plus custom elements. This contract is
|
|
|
12
12
|
| Project widget | [An element named after the widget](#6-project-widgets), and `<ascribe-group>` for groups | The project's own; `<ascribe-group>` is the library's |
|
|
13
13
|
| Glossary term | [An ordinary link](#7-glossary-terms), marked with `data-ascribe-term` | Optional CSS |
|
|
14
14
|
|
|
15
|
-
A change to this contract changes the site emitter (`crates/
|
|
15
|
+
A change to this contract changes the site emitter (`crates/ascribe-emit`), the element library, and the site-render fixtures (`tests/render/`) together.
|
|
16
16
|
|
|
17
17
|
## 0. Rules for every element
|
|
18
18
|
|
|
19
|
-
**Light DOM, CSS, no behavior.** Elements render into the light DOM, so site styles apply and content stays visible to search engines and assistive technology (SPEC §9.7). They're styled with CSS and themed with custom properties whose names start with `--ascribe-`; the package README lists them. Only `<ascribe-tabs>` runs JavaScript. Everything else must render meaningfully with the library's CSS and no script, and must stay readable with neither.
|
|
19
|
+
**Light DOM, CSS, no behavior.** Elements render into the light DOM, so site styles apply and content stays visible to search engines and assistive technology (SPEC §9.7). They're styled with CSS and themed with custom properties whose names start with `--ascribe-`; the package README lists them. The names are part of this contract; their default values aren't, and a release may change them, noting it in the changelog. Only `<ascribe-tabs>` runs JavaScript. Everything else must render meaningfully with the library's CSS and no script, and must stay readable with neither.
|
|
20
20
|
|
|
21
21
|
**How the emitter writes elements.** Custom elements are raw HTML blocks in CommonMark, so the layout matters:
|
|
22
22
|
|
package/README.md
CHANGED
|
@@ -29,6 +29,12 @@ directly.
|
|
|
29
29
|
Set any of these custom properties on `:root`, or on any ancestor of the
|
|
30
30
|
elements. Defaults are in `css/style.css`.
|
|
31
31
|
|
|
32
|
+
The names are part of the [contract](CONTRACT.md) and don't change. The
|
|
33
|
+
default values are Ascribe's design tokens, shared with review and the HTML
|
|
34
|
+
report, and a release may change them; the changelog says so under **Behavior
|
|
35
|
+
change**, with the previous values. A site that needs a fixed look sets the
|
|
36
|
+
properties itself.
|
|
37
|
+
|
|
32
38
|
| Group | Properties |
|
|
33
39
|
|---|---|
|
|
34
40
|
| Type | `--ascribe-font-family`, `--ascribe-font-size-small`, `--ascribe-font-weight-strong` |
|
|
@@ -108,6 +114,7 @@ ascribe-availability::before {
|
|
|
108
114
|
`pnpm --filter @ascribed/elements test` compiles the library and drives Chromium
|
|
109
115
|
through Playwright in Chromium, Firefox, and WebKit. Install them with
|
|
110
116
|
`pnpm --filter @ascribed/elements exec playwright-core install chromium firefox webkit`.
|
|
117
|
+
CI runs them in Playwright's container image, which has all three.
|
|
111
118
|
Chromium uses `/opt/pw-browsers/chromium` when present, or the binary in
|
|
112
119
|
`ASCRIBE_CHROMIUM`. `ASCRIBE_ENGINES=chromium` (a comma-separated subset) runs
|
|
113
120
|
fewer engines on a machine that can't install all three.
|
package/css/style.css
CHANGED
|
@@ -19,53 +19,65 @@
|
|
|
19
19
|
--ascribe-font-weight-strong: 600;
|
|
20
20
|
|
|
21
21
|
/* Spacing, borders */
|
|
22
|
+
--ascribe-border-width: 1px;
|
|
23
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: spacing, light. */
|
|
22
24
|
--ascribe-space: 1rem;
|
|
23
25
|
--ascribe-space-small: 0.5rem;
|
|
24
|
-
--ascribe-border-
|
|
25
|
-
--ascribe-border-color: #d0d7de;
|
|
26
|
+
--ascribe-border-color: #e3e6ec;
|
|
26
27
|
--ascribe-radius: 0.375rem;
|
|
28
|
+
/* End of generated spacing. */
|
|
27
29
|
|
|
28
30
|
/* Surfaces and text */
|
|
29
31
|
--ascribe-text-color: inherit;
|
|
30
|
-
--ascribe-muted-color: #57606a;
|
|
31
32
|
--ascribe-surface-color: transparent;
|
|
33
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: text, light. */
|
|
34
|
+
--ascribe-muted-color: #676c75;
|
|
35
|
+
/* End of generated text. */
|
|
32
36
|
|
|
33
37
|
/* Note types: an accent color and a tinted background each. */
|
|
34
|
-
|
|
35
|
-
--ascribe-note-
|
|
36
|
-
--ascribe-
|
|
37
|
-
--ascribe-tip-
|
|
38
|
-
--ascribe-
|
|
39
|
-
--ascribe-important-
|
|
40
|
-
--ascribe-
|
|
41
|
-
--ascribe-warning-
|
|
42
|
-
--ascribe-
|
|
43
|
-
--ascribe-caution-
|
|
38
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: notes, light. */
|
|
39
|
+
--ascribe-note-color: #474dc6;
|
|
40
|
+
--ascribe-note-background: #f5f6fe;
|
|
41
|
+
--ascribe-tip-color: #057256;
|
|
42
|
+
--ascribe-tip-background: #e1fff2;
|
|
43
|
+
--ascribe-important-color: #932f8e;
|
|
44
|
+
--ascribe-important-background: #fff2fd;
|
|
45
|
+
--ascribe-warning-color: #845502;
|
|
46
|
+
--ascribe-warning-background: #fef5eb;
|
|
47
|
+
--ascribe-caution-color: #a73303;
|
|
48
|
+
--ascribe-caution-background: #fef4f1;
|
|
49
|
+
/* End of generated notes. */
|
|
44
50
|
|
|
45
51
|
/* Steps */
|
|
46
|
-
--ascribe-steps-color: #0969da;
|
|
47
52
|
--ascribe-steps-marker-size: 1.75rem;
|
|
53
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: steps, light. */
|
|
54
|
+
--ascribe-steps-color: #5962e8;
|
|
48
55
|
--ascribe-steps-marker-text-color: #ffffff;
|
|
56
|
+
/* End of generated steps. */
|
|
49
57
|
|
|
50
58
|
/* Tabs */
|
|
51
|
-
|
|
52
|
-
--ascribe-tab-
|
|
53
|
-
--ascribe-tab-
|
|
54
|
-
--ascribe-tab-
|
|
59
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: tabs, light. */
|
|
60
|
+
--ascribe-tab-color: #676c75;
|
|
61
|
+
--ascribe-tab-active-color: #5962e8;
|
|
62
|
+
--ascribe-tab-focus-color: #5962e8;
|
|
63
|
+
--ascribe-tab-hover-background: #f7f9fd;
|
|
64
|
+
/* End of generated tabs. */
|
|
55
65
|
|
|
56
66
|
/* Availability lifecycle states: an accent color and a background each. */
|
|
57
|
-
|
|
58
|
-
--ascribe-state-
|
|
59
|
-
--ascribe-state-
|
|
60
|
-
--ascribe-state-ga-
|
|
61
|
-
--ascribe-state-
|
|
62
|
-
--ascribe-state-preview-
|
|
63
|
-
--ascribe-state-
|
|
64
|
-
--ascribe-state-beta-
|
|
65
|
-
--ascribe-state-
|
|
66
|
-
--ascribe-state-deprecated-
|
|
67
|
-
--ascribe-state-
|
|
68
|
-
--ascribe-state-removed-
|
|
67
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: states, light. */
|
|
68
|
+
--ascribe-state-color: #676c75;
|
|
69
|
+
--ascribe-state-background: #f0f3f7;
|
|
70
|
+
--ascribe-state-ga-color: #057256;
|
|
71
|
+
--ascribe-state-ga-background: #e1fff2;
|
|
72
|
+
--ascribe-state-preview-color: #932f8e;
|
|
73
|
+
--ascribe-state-preview-background: #fff2fd;
|
|
74
|
+
--ascribe-state-beta-color: #474dc6;
|
|
75
|
+
--ascribe-state-beta-background: #f5f6fe;
|
|
76
|
+
--ascribe-state-deprecated-color: #845502;
|
|
77
|
+
--ascribe-state-deprecated-background: #fef5eb;
|
|
78
|
+
--ascribe-state-removed-color: #a73303;
|
|
79
|
+
--ascribe-state-removed-background: #fef4f1;
|
|
80
|
+
/* End of generated states. */
|
|
69
81
|
}
|
|
70
82
|
|
|
71
83
|
/* The same colors, light and dark. `light-dark()` picks by the element's
|
|
@@ -73,40 +85,53 @@
|
|
|
73
85
|
`light-dark()` keeps the light colors above. */
|
|
74
86
|
@supports (color: light-dark(#000, #fff)) {
|
|
75
87
|
:root {
|
|
76
|
-
|
|
77
|
-
--ascribe-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
--ascribe-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
--ascribe-
|
|
86
|
-
--ascribe-
|
|
87
|
-
--ascribe-
|
|
88
|
-
--ascribe-
|
|
89
|
-
|
|
90
|
-
--ascribe-
|
|
91
|
-
--ascribe-
|
|
92
|
-
|
|
93
|
-
--ascribe-
|
|
94
|
-
--ascribe-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
--ascribe-
|
|
99
|
-
--ascribe-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
--ascribe-
|
|
104
|
-
--ascribe-
|
|
105
|
-
--ascribe-
|
|
106
|
-
--ascribe-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
88
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: spacing, light-dark. */
|
|
89
|
+
--ascribe-border-color: light-dark(#e3e6ec, #393d46);
|
|
90
|
+
/* End of generated spacing. */
|
|
91
|
+
|
|
92
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: text, light-dark. */
|
|
93
|
+
--ascribe-muted-color: light-dark(#676c75, #a5a9b2);
|
|
94
|
+
/* End of generated text. */
|
|
95
|
+
|
|
96
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: notes, light-dark. */
|
|
97
|
+
--ascribe-note-color: light-dark(#474dc6, #91a1fe);
|
|
98
|
+
--ascribe-note-background: light-dark(#f5f6fe, #161b3a);
|
|
99
|
+
--ascribe-tip-color: light-dark(#057256, #22c598);
|
|
100
|
+
--ascribe-tip-background: light-dark(#e1fff2, #02251a);
|
|
101
|
+
--ascribe-important-color: light-dark(#932f8e, #ffc8f9);
|
|
102
|
+
--ascribe-important-background: light-dark(#fff2fd, #2d132b);
|
|
103
|
+
--ascribe-warning-color: light-dark(#845502, #e0992e);
|
|
104
|
+
--ascribe-warning-background: light-dark(#fef5eb, #2b1a03);
|
|
105
|
+
--ascribe-caution-color: light-dark(#a73303, #fe7f57);
|
|
106
|
+
--ascribe-caution-background: light-dark(#fef4f1, #341308);
|
|
107
|
+
/* End of generated notes. */
|
|
108
|
+
|
|
109
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: steps, light-dark. */
|
|
110
|
+
--ascribe-steps-color: light-dark(#5962e8, #91a1fe);
|
|
111
|
+
--ascribe-steps-marker-text-color: light-dark(#ffffff, #0c0f16);
|
|
112
|
+
/* End of generated steps. */
|
|
113
|
+
|
|
114
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: tabs, light-dark. */
|
|
115
|
+
--ascribe-tab-color: light-dark(#676c75, #a5a9b2);
|
|
116
|
+
--ascribe-tab-active-color: light-dark(#5962e8, #91a1fe);
|
|
117
|
+
--ascribe-tab-focus-color: light-dark(#5962e8, #b3c0ff);
|
|
118
|
+
--ascribe-tab-hover-background: light-dark(#f7f9fd, #13171f);
|
|
119
|
+
/* End of generated tabs. */
|
|
120
|
+
|
|
121
|
+
/* Generated from design/tokens.toml by scripts/design/tokens.ts: states, light-dark. */
|
|
122
|
+
--ascribe-state-color: light-dark(#676c75, #a5a9b2);
|
|
123
|
+
--ascribe-state-background: light-dark(#f0f3f7, #22272e);
|
|
124
|
+
--ascribe-state-ga-color: light-dark(#057256, #22c598);
|
|
125
|
+
--ascribe-state-ga-background: light-dark(#e1fff2, #02251a);
|
|
126
|
+
--ascribe-state-preview-color: light-dark(#932f8e, #ffc8f9);
|
|
127
|
+
--ascribe-state-preview-background: light-dark(#fff2fd, #2d132b);
|
|
128
|
+
--ascribe-state-beta-color: light-dark(#474dc6, #91a1fe);
|
|
129
|
+
--ascribe-state-beta-background: light-dark(#f5f6fe, #161b3a);
|
|
130
|
+
--ascribe-state-deprecated-color: light-dark(#845502, #e0992e);
|
|
131
|
+
--ascribe-state-deprecated-background: light-dark(#fef5eb, #2b1a03);
|
|
132
|
+
--ascribe-state-removed-color: light-dark(#a73303, #fe7f57);
|
|
133
|
+
--ascribe-state-removed-background: light-dark(#fef4f1, #341308);
|
|
134
|
+
/* End of generated states. */
|
|
110
135
|
}
|
|
111
136
|
|
|
112
137
|
/* A page that says which it is. */
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
// (`@ascribed/elements/style.css`), which works without this script.
|
|
4
4
|
import { AscribeGroup } from "./group.js";
|
|
5
5
|
import { AscribeTab, AscribeTabs } from "./tabs.js";
|
|
6
|
+
import { ELEMENT_GROUP, ELEMENT_TAB, ELEMENT_TABS } from "./names.js";
|
|
6
7
|
export { AscribeGroup, AscribeTab, AscribeTabs };
|
|
7
8
|
const registry = [
|
|
8
|
-
[
|
|
9
|
-
[
|
|
10
|
-
[
|
|
9
|
+
[ELEMENT_TABS, AscribeTabs],
|
|
10
|
+
[ELEMENT_TAB, AscribeTab],
|
|
11
|
+
[ELEMENT_GROUP, AscribeGroup],
|
|
11
12
|
];
|
|
12
13
|
for (const [name, constructor] of registry) {
|
|
13
14
|
if (!customElements.get(name))
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mEAAmE;AACnE,qEAAqE;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mEAAmE;AACnE,qEAAqE;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAEjD,MAAM,QAAQ,GAAyC;IACrD,CAAC,YAAY,EAAE,WAAW,CAAC;IAC3B,CAAC,WAAW,EAAE,UAAU,CAAC;IACzB,CAAC,aAAa,EAAE,YAAY,CAAC;CAC9B,CAAC;AAEF,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAC;IAC3C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["// @ascribed/elements: registers Ascribe's custom elements. Only\n// <ascribe-tabs> has behavior; the rest are styled by the CSS file\n// (`@ascribed/elements/style.css`), which works without this script.\n\nimport { AscribeGroup } from \"./group.js\";\nimport { AscribeTab, AscribeTabs } from \"./tabs.js\";\nimport { ELEMENT_GROUP, ELEMENT_TAB, ELEMENT_TABS } from \"./names.js\";\n\nexport { AscribeGroup, AscribeTab, AscribeTabs };\n\nconst registry: [string, CustomElementConstructor][] = [\n [ELEMENT_TABS, AscribeTabs],\n [ELEMENT_TAB, AscribeTab],\n [ELEMENT_GROUP, AscribeGroup],\n];\n\nfor (const [name, constructor] of registry) {\n if (!customElements.get(name)) customElements.define(name, constructor);\n}\n"]}
|
package/dist/names.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */
|
|
2
|
+
export declare const ELEMENT_NOTE = "ascribe-note";
|
|
3
|
+
/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */
|
|
4
|
+
export declare const ELEMENT_STEPS = "ascribe-steps";
|
|
5
|
+
/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */
|
|
6
|
+
export declare const ELEMENT_TABS = "ascribe-tabs";
|
|
7
|
+
/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */
|
|
8
|
+
export declare const ELEMENT_TAB = "ascribe-tab";
|
|
9
|
+
/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */
|
|
10
|
+
export declare const ELEMENT_AVAILABILITY = "ascribe-availability";
|
|
11
|
+
/**
|
|
12
|
+
* `<ascribe-availability-target>`: one target of `<ascribe-availability>`
|
|
13
|
+
* (packages/elements/CONTRACT.md §4).
|
|
14
|
+
*/
|
|
15
|
+
export declare const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
|
|
16
|
+
/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
|
|
17
|
+
export declare const ELEMENT_GROUP = "ascribe-group";
|
|
18
|
+
/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
|
|
19
|
+
export declare const ELEMENT_ATTRIBUTES = "ascribe-attributes";
|
|
20
|
+
/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
|
|
21
|
+
export declare const COMMENT_ANCHOR = "ascribe-anchor";
|
|
22
|
+
/** A block's source anchor (site-render contract §7.1). */
|
|
23
|
+
export declare const DATA_SOURCE = "data-ascribe-source";
|
|
24
|
+
/** The includes a block came through (site-render contract §7.1). */
|
|
25
|
+
export declare const DATA_VIA = "data-ascribe-via";
|
|
26
|
+
/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */
|
|
27
|
+
export declare const DATA_TERM = "data-ascribe-term";
|
|
28
|
+
/** The element the report draws into. */
|
|
29
|
+
export declare const ID_REPORT = "ascribe-review";
|
|
30
|
+
/** The `<script type="application/json">` holding the report's data. */
|
|
31
|
+
export declare const ID_REPORT_DATA = "ascribe-review-data";
|
|
32
|
+
/**
|
|
33
|
+
* The page's light or dark scheme, `light` or `dark`, on the root
|
|
34
|
+
* element (docs/content/guides/astro.md).
|
|
35
|
+
*/
|
|
36
|
+
export declare const DATA_SCHEME = "data-ascribe-scheme";
|
|
37
|
+
/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */
|
|
38
|
+
export declare const DATA_SHOW = "data-ascribe-show";
|
|
39
|
+
/**
|
|
40
|
+
* On a marked block: its change, `added`, `changed`, `removed`, `moved`,
|
|
41
|
+
* or `moved-from`.
|
|
42
|
+
*/
|
|
43
|
+
export declare const DATA_CHANGE = "data-ascribe-change";
|
|
44
|
+
/** On every element review adds to the page, so it can be taken away again. */
|
|
45
|
+
export declare const DATA_UI = "data-ascribe-ui";
|
|
46
|
+
/** On a change's label: the change. */
|
|
47
|
+
export declare const DATA_LABEL = "data-ascribe-label";
|
|
48
|
+
/** On a tab's hint: `added` or `changed`. */
|
|
49
|
+
export declare const DATA_HINT = "data-ascribe-hint";
|
|
50
|
+
/** On a moved block: the id its "moved from" link points at. */
|
|
51
|
+
export declare const DATA_MOVE = "data-ascribe-move";
|
|
52
|
+
/** On a changed block whose copy as it was follows it. */
|
|
53
|
+
export declare const DATA_HAS_WAS = "data-ascribe-has-was";
|
|
54
|
+
/** On a copy of a block as it was, shown only with the page as it was. */
|
|
55
|
+
export declare const DATA_WAS_ONLY = "data-ascribe-was-only";
|
|
56
|
+
/** On a changed, removed, or moved block: its source anchor as it was. */
|
|
57
|
+
export declare const DATA_WAS_SOURCE = "data-ascribe-was-source";
|
|
58
|
+
/** On the elements that hold the threads' overlay. */
|
|
59
|
+
export declare const DATA_OVERLAY = "data-ascribe-overlay";
|
|
60
|
+
/** On the style element the Astro dev toolbar adds for the marks. */
|
|
61
|
+
export declare const DATA_REVIEW = "data-ascribe-review";
|
|
62
|
+
/** On the root of a page whose changes are marked. */
|
|
63
|
+
export declare const CLASS_MARKS = "ascribe-marks";
|
|
64
|
+
/** A change's label. */
|
|
65
|
+
export declare const CLASS_LABEL = "ascribe-label";
|
|
66
|
+
/** A label placed before its block rather than over it. */
|
|
67
|
+
export declare const CLASS_LABEL_BEFORE = "ascribe-label-before";
|
|
68
|
+
/** Inserted text. */
|
|
69
|
+
export declare const CLASS_INS = "ascribe-ins";
|
|
70
|
+
/** Deleted text. */
|
|
71
|
+
export declare const CLASS_DEL = "ascribe-del";
|
|
72
|
+
/** A removed block. */
|
|
73
|
+
export declare const CLASS_REMOVED = "ascribe-removed";
|
|
74
|
+
/** A removed block's content. */
|
|
75
|
+
export declare const CLASS_REMOVED_BODY = "ascribe-removed-body";
|
|
76
|
+
/** The button that shows or collapses a removed block. */
|
|
77
|
+
export declare const CLASS_TOGGLE = "ascribe-toggle";
|
|
78
|
+
/** On a removed block that's shown. */
|
|
79
|
+
export declare const CLASS_OPEN = "ascribe-open";
|
|
80
|
+
/** What stands where a moved block was. */
|
|
81
|
+
export declare const CLASS_MOVED_FROM = "ascribe-moved-from";
|
|
82
|
+
/** The note with a moved block's link. */
|
|
83
|
+
export declare const CLASS_MOVE_NOTE = "ascribe-move-note";
|
|
84
|
+
/** A move note after its block, not inside it. */
|
|
85
|
+
export declare const CLASS_MOVE_AFTER = "ascribe-move-after";
|
|
86
|
+
/** The link between a moved block and where it was. */
|
|
87
|
+
export declare const CLASS_MOVE_LINK = "ascribe-move-link";
|
|
88
|
+
/** A moved block's copy as it was, where it was. */
|
|
89
|
+
export declare const CLASS_WAS_COPY = "ascribe-was-copy";
|
|
90
|
+
/** A tab's hint that it holds changes. */
|
|
91
|
+
export declare const CLASS_HINT = "ascribe-hint";
|
|
92
|
+
/** A block flashed after going to it. */
|
|
93
|
+
export declare const CLASS_FLASH = "ascribe-flash";
|
|
94
|
+
/** The tip that shows a block's source on hover and focus. */
|
|
95
|
+
export declare const CLASS_WHERE = "ascribe-where";
|
package/dist/names.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// The names Ascribe puts on a page: elements, attributes, classes, and ids.
|
|
2
|
+
// Generated from crates/ascribe-core/src/names.rs by
|
|
3
|
+
// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.
|
|
4
|
+
/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */
|
|
5
|
+
export const ELEMENT_NOTE = "ascribe-note";
|
|
6
|
+
/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */
|
|
7
|
+
export const ELEMENT_STEPS = "ascribe-steps";
|
|
8
|
+
/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */
|
|
9
|
+
export const ELEMENT_TABS = "ascribe-tabs";
|
|
10
|
+
/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */
|
|
11
|
+
export const ELEMENT_TAB = "ascribe-tab";
|
|
12
|
+
/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */
|
|
13
|
+
export const ELEMENT_AVAILABILITY = "ascribe-availability";
|
|
14
|
+
/**
|
|
15
|
+
* `<ascribe-availability-target>`: one target of `<ascribe-availability>`
|
|
16
|
+
* (packages/elements/CONTRACT.md §4).
|
|
17
|
+
*/
|
|
18
|
+
export const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
|
|
19
|
+
/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
|
|
20
|
+
export const ELEMENT_GROUP = "ascribe-group";
|
|
21
|
+
/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
|
|
22
|
+
export const ELEMENT_ATTRIBUTES = "ascribe-attributes";
|
|
23
|
+
/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
|
|
24
|
+
export const COMMENT_ANCHOR = "ascribe-anchor";
|
|
25
|
+
/** A block's source anchor (site-render contract §7.1). */
|
|
26
|
+
export const DATA_SOURCE = "data-ascribe-source";
|
|
27
|
+
/** The includes a block came through (site-render contract §7.1). */
|
|
28
|
+
export const DATA_VIA = "data-ascribe-via";
|
|
29
|
+
/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */
|
|
30
|
+
export const DATA_TERM = "data-ascribe-term";
|
|
31
|
+
/** The element the report draws into. */
|
|
32
|
+
export const ID_REPORT = "ascribe-review";
|
|
33
|
+
/** The `<script type="application/json">` holding the report's data. */
|
|
34
|
+
export const ID_REPORT_DATA = "ascribe-review-data";
|
|
35
|
+
/**
|
|
36
|
+
* The page's light or dark scheme, `light` or `dark`, on the root
|
|
37
|
+
* element (docs/content/guides/astro.md).
|
|
38
|
+
*/
|
|
39
|
+
export const DATA_SCHEME = "data-ascribe-scheme";
|
|
40
|
+
/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */
|
|
41
|
+
export const DATA_SHOW = "data-ascribe-show";
|
|
42
|
+
/**
|
|
43
|
+
* On a marked block: its change, `added`, `changed`, `removed`, `moved`,
|
|
44
|
+
* or `moved-from`.
|
|
45
|
+
*/
|
|
46
|
+
export const DATA_CHANGE = "data-ascribe-change";
|
|
47
|
+
/** On every element review adds to the page, so it can be taken away again. */
|
|
48
|
+
export const DATA_UI = "data-ascribe-ui";
|
|
49
|
+
/** On a change's label: the change. */
|
|
50
|
+
export const DATA_LABEL = "data-ascribe-label";
|
|
51
|
+
/** On a tab's hint: `added` or `changed`. */
|
|
52
|
+
export const DATA_HINT = "data-ascribe-hint";
|
|
53
|
+
/** On a moved block: the id its "moved from" link points at. */
|
|
54
|
+
export const DATA_MOVE = "data-ascribe-move";
|
|
55
|
+
/** On a changed block whose copy as it was follows it. */
|
|
56
|
+
export const DATA_HAS_WAS = "data-ascribe-has-was";
|
|
57
|
+
/** On a copy of a block as it was, shown only with the page as it was. */
|
|
58
|
+
export const DATA_WAS_ONLY = "data-ascribe-was-only";
|
|
59
|
+
/** On a changed, removed, or moved block: its source anchor as it was. */
|
|
60
|
+
export const DATA_WAS_SOURCE = "data-ascribe-was-source";
|
|
61
|
+
/** On the elements that hold the threads' overlay. */
|
|
62
|
+
export const DATA_OVERLAY = "data-ascribe-overlay";
|
|
63
|
+
/** On the style element the Astro dev toolbar adds for the marks. */
|
|
64
|
+
export const DATA_REVIEW = "data-ascribe-review";
|
|
65
|
+
/** On the root of a page whose changes are marked. */
|
|
66
|
+
export const CLASS_MARKS = "ascribe-marks";
|
|
67
|
+
/** A change's label. */
|
|
68
|
+
export const CLASS_LABEL = "ascribe-label";
|
|
69
|
+
/** A label placed before its block rather than over it. */
|
|
70
|
+
export const CLASS_LABEL_BEFORE = "ascribe-label-before";
|
|
71
|
+
/** Inserted text. */
|
|
72
|
+
export const CLASS_INS = "ascribe-ins";
|
|
73
|
+
/** Deleted text. */
|
|
74
|
+
export const CLASS_DEL = "ascribe-del";
|
|
75
|
+
/** A removed block. */
|
|
76
|
+
export const CLASS_REMOVED = "ascribe-removed";
|
|
77
|
+
/** A removed block's content. */
|
|
78
|
+
export const CLASS_REMOVED_BODY = "ascribe-removed-body";
|
|
79
|
+
/** The button that shows or collapses a removed block. */
|
|
80
|
+
export const CLASS_TOGGLE = "ascribe-toggle";
|
|
81
|
+
/** On a removed block that's shown. */
|
|
82
|
+
export const CLASS_OPEN = "ascribe-open";
|
|
83
|
+
/** What stands where a moved block was. */
|
|
84
|
+
export const CLASS_MOVED_FROM = "ascribe-moved-from";
|
|
85
|
+
/** The note with a moved block's link. */
|
|
86
|
+
export const CLASS_MOVE_NOTE = "ascribe-move-note";
|
|
87
|
+
/** A move note after its block, not inside it. */
|
|
88
|
+
export const CLASS_MOVE_AFTER = "ascribe-move-after";
|
|
89
|
+
/** The link between a moved block and where it was. */
|
|
90
|
+
export const CLASS_MOVE_LINK = "ascribe-move-link";
|
|
91
|
+
/** A moved block's copy as it was, where it was. */
|
|
92
|
+
export const CLASS_WAS_COPY = "ascribe-was-copy";
|
|
93
|
+
/** A tab's hint that it holds changes. */
|
|
94
|
+
export const CLASS_HINT = "ascribe-hint";
|
|
95
|
+
/** A block flashed after going to it. */
|
|
96
|
+
export const CLASS_FLASH = "ascribe-flash";
|
|
97
|
+
/** The tip that shows a block's source on hover and focus. */
|
|
98
|
+
export const CLASS_WHERE = "ascribe-where";
|
|
99
|
+
//# sourceMappingURL=names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qDAAqD;AACrD,4EAA4E;AAE5E,mEAAmE;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,yEAAyE;AACzE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAE3C,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AAEzC,sFAAsF;AACtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;AAEzE,sFAAsF;AACtF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,gGAAgG;AAChG,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAE1C,wEAAwE;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAEzC,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAE/C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,gEAAgE;AAChE,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;AAE7C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAErD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAEzD,sDAAsD;AACtD,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,sDAAsD;AACtD,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,wBAAwB;AACxB,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,qBAAqB;AACrB,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AAEvC,oBAAoB;AACpB,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AAEvC,uBAAuB;AACvB,MAAM,CAAC,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE/C,iCAAiC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAE7C,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAErD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,kDAAkD;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAErD,uDAAuD;AACvD,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,oDAAoD;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,yCAAyC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/guides/astro.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
|
package/dist/tabs.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// element with behavior. Without this script every tab shows with its label
|
|
3
3
|
// (CSS generated content); with it, the group follows the WAI-ARIA tabs
|
|
4
4
|
// pattern.
|
|
5
|
+
import { ELEMENT_TAB } from "./names.js";
|
|
5
6
|
const STORAGE_PREFIX = "ascribe-tabs:";
|
|
6
7
|
/** Choices made this page load, for readers whose storage is unavailable. */
|
|
7
8
|
const pageChoices = new Map();
|
|
@@ -58,7 +59,7 @@ export class AscribeTabs extends HTMLElement {
|
|
|
58
59
|
#setup() {
|
|
59
60
|
if (!this.isConnected || this.#ready)
|
|
60
61
|
return;
|
|
61
|
-
this.#tabs = Array.from(this.children).filter((child) => child.localName ===
|
|
62
|
+
this.#tabs = Array.from(this.children).filter((child) => child.localName === ELEMENT_TAB);
|
|
62
63
|
if (this.#tabs.length === 0)
|
|
63
64
|
return;
|
|
64
65
|
this.#ready = true;
|
package/dist/tabs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["// <ascribe-tabs> and <ascribe-tab> (CONTRACT.md §3): the library's only\n// element with behavior. Without this script every tab shows with its label\n// (CSS generated content); with it, the group follows the WAI-ARIA tabs\n// pattern.\n\nconst STORAGE_PREFIX = \"ascribe-tabs:\";\n\n/** Choices made this page load, for readers whose storage is unavailable. */\nconst pageChoices = new Map<string, string>();\n\n/** Every connected, initialized group with a `sync` attribute. */\nconst syncedGroups = new Set<AscribeTabs>();\n\nlet idCounter = 0;\n\nfunction readChoice(dimension: string): string | null {\n // This page's choices are always at least as fresh as storage, which a\n // failed write leaves behind.\n const chosen = pageChoices.get(dimension);\n if (chosen !== undefined) return chosen;\n try {\n return localStorage.getItem(STORAGE_PREFIX + dimension);\n } catch {\n // Storage can be blocked or unavailable.\n return null;\n }\n}\n\nfunction writeChoice(dimension: string, value: string): void {\n pageChoices.set(dimension, value);\n try {\n localStorage.setItem(STORAGE_PREFIX + dimension, value);\n } catch {\n // The choice lasts for the page only.\n }\n}\n\nfunction valuesOf(tab: Element): string[] {\n return (tab.getAttribute(\"value\") ?? \"\").split(/\\s+/).filter(Boolean);\n}\n\n/** A tab panel: one arm of a `@variant` group. Styled by CSS; no behavior. */\nexport class AscribeTab extends HTMLElement {}\n\nexport class AscribeTabs extends HTMLElement {\n #tablist: HTMLElement | null = null;\n #tabs: HTMLElement[] = [];\n #buttons: HTMLButtonElement[] = [];\n #selected = 0;\n #ready = false;\n\n connectedCallback(): void {\n // A parser-created element is connected before its children are parsed.\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => this.#setup(), { once: true });\n } else {\n this.#setup();\n }\n }\n\n disconnectedCallback(): void {\n this.#teardown();\n }\n\n #setup(): void {\n if (!this.isConnected || this.#ready) return;\n this.#tabs = Array.from(this.children).filter(\n (child): child is HTMLElement => child.localName === \"ascribe-tab\",\n );\n if (this.#tabs.length === 0) return;\n this.#ready = true;\n\n const tablist = document.createElement(\"div\");\n tablist.setAttribute(\"role\", \"tablist\");\n this.#tablist = tablist;\n\n this.#buttons = this.#tabs.map((tab) => {\n if (!tab.id) tab.id = `ascribe-tab-${++idCounter}`;\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.id = `${tab.id}-button`;\n button.setAttribute(\"role\", \"tab\");\n button.setAttribute(\"aria-controls\", tab.id);\n button.textContent = tab.getAttribute(\"label\") ?? \"\";\n button.addEventListener(\"click\", () => this.#choose(this.#buttons.indexOf(button)));\n button.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n tablist.append(button);\n tab.setAttribute(\"role\", \"tabpanel\");\n tab.setAttribute(\"aria-labelledby\", button.id);\n return button;\n });\n this.prepend(tablist);\n\n const sync = this.getAttribute(\"sync\");\n let initial = 0;\n if (sync !== null) {\n syncedGroups.add(this);\n const remembered = readChoice(sync);\n const match = remembered === null ? -1 : this.#indexOfValue(remembered);\n if (match >= 0) initial = match;\n }\n this.#select(initial);\n }\n\n #teardown(): void {\n if (!this.#ready) return;\n syncedGroups.delete(this);\n this.#tablist?.remove();\n for (const tab of this.#tabs) {\n tab.removeAttribute(\"role\");\n tab.removeAttribute(\"aria-labelledby\");\n tab.removeAttribute(\"hidden\");\n }\n this.#tablist = null;\n this.#tabs = [];\n this.#buttons = [];\n this.#ready = false;\n }\n\n #indexOfValue(value: string): number {\n return this.#tabs.findIndex((tab) => valuesOf(tab).includes(value));\n }\n\n /** Select a tab without recording or syncing the choice. */\n #select(index: number): void {\n this.#selected = index;\n this.#tabs.forEach((tab, i) => {\n tab.toggleAttribute(\"hidden\", i !== index);\n });\n this.#buttons.forEach((button, i) => {\n button.setAttribute(\"aria-selected\", String(i === index));\n button.tabIndex = i === index ? 0 : -1;\n });\n }\n\n /** The reader picked a tab: select it and, for a synced group, tell the rest. */\n #choose(index: number): void {\n this.#select(index);\n const sync = this.getAttribute(\"sync\");\n const tab = this.#tabs[index];\n const choice = tab ? valuesOf(tab)[0] : undefined;\n if (sync === null || choice === undefined) return;\n writeChoice(sync, choice);\n for (const group of syncedGroups) {\n if (group !== this && group.getAttribute(\"sync\") === sync) group.#follow(choice);\n }\n }\n\n /** Another group with the same `sync` made a choice; keep our selection if we have no match. */\n #follow(value: string): void {\n const index = this.#indexOfValue(value);\n if (index >= 0) this.#select(index);\n }\n\n #onKeydown(event: KeyboardEvent): void {\n const last = this.#tabs.length - 1;\n let next: number;\n switch (event.key) {\n case \"ArrowRight\":\n next = this.#selected === last ? 0 : this.#selected + 1;\n break;\n case \"ArrowLeft\":\n next = this.#selected === 0 ? last : this.#selected - 1;\n break;\n case \"Home\":\n next = 0;\n break;\n case \"End\":\n next = last;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#choose(next);\n this.#buttons[next]?.focus();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../src/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["// <ascribe-tabs> and <ascribe-tab> (CONTRACT.md §3): the library's only\n// element with behavior. Without this script every tab shows with its label\n// (CSS generated content); with it, the group follows the WAI-ARIA tabs\n// pattern.\n\nimport { ELEMENT_TAB } from \"./names.js\";\n\nconst STORAGE_PREFIX = \"ascribe-tabs:\";\n\n/** Choices made this page load, for readers whose storage is unavailable. */\nconst pageChoices = new Map<string, string>();\n\n/** Every connected, initialized group with a `sync` attribute. */\nconst syncedGroups = new Set<AscribeTabs>();\n\nlet idCounter = 0;\n\nfunction readChoice(dimension: string): string | null {\n // This page's choices are always at least as fresh as storage, which a\n // failed write leaves behind.\n const chosen = pageChoices.get(dimension);\n if (chosen !== undefined) return chosen;\n try {\n return localStorage.getItem(STORAGE_PREFIX + dimension);\n } catch {\n // Storage can be blocked or unavailable.\n return null;\n }\n}\n\nfunction writeChoice(dimension: string, value: string): void {\n pageChoices.set(dimension, value);\n try {\n localStorage.setItem(STORAGE_PREFIX + dimension, value);\n } catch {\n // The choice lasts for the page only.\n }\n}\n\nfunction valuesOf(tab: Element): string[] {\n return (tab.getAttribute(\"value\") ?? \"\").split(/\\s+/).filter(Boolean);\n}\n\n/** A tab panel: one arm of a `@variant` group. Styled by CSS; no behavior. */\nexport class AscribeTab extends HTMLElement {}\n\nexport class AscribeTabs extends HTMLElement {\n #tablist: HTMLElement | null = null;\n #tabs: HTMLElement[] = [];\n #buttons: HTMLButtonElement[] = [];\n #selected = 0;\n #ready = false;\n\n connectedCallback(): void {\n // A parser-created element is connected before its children are parsed.\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => this.#setup(), { once: true });\n } else {\n this.#setup();\n }\n }\n\n disconnectedCallback(): void {\n this.#teardown();\n }\n\n #setup(): void {\n if (!this.isConnected || this.#ready) return;\n this.#tabs = Array.from(this.children).filter(\n (child): child is HTMLElement => child.localName === ELEMENT_TAB,\n );\n if (this.#tabs.length === 0) return;\n this.#ready = true;\n\n const tablist = document.createElement(\"div\");\n tablist.setAttribute(\"role\", \"tablist\");\n this.#tablist = tablist;\n\n this.#buttons = this.#tabs.map((tab) => {\n if (!tab.id) tab.id = `ascribe-tab-${++idCounter}`;\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.id = `${tab.id}-button`;\n button.setAttribute(\"role\", \"tab\");\n button.setAttribute(\"aria-controls\", tab.id);\n button.textContent = tab.getAttribute(\"label\") ?? \"\";\n button.addEventListener(\"click\", () => this.#choose(this.#buttons.indexOf(button)));\n button.addEventListener(\"keydown\", (event) => this.#onKeydown(event));\n tablist.append(button);\n tab.setAttribute(\"role\", \"tabpanel\");\n tab.setAttribute(\"aria-labelledby\", button.id);\n return button;\n });\n this.prepend(tablist);\n\n const sync = this.getAttribute(\"sync\");\n let initial = 0;\n if (sync !== null) {\n syncedGroups.add(this);\n const remembered = readChoice(sync);\n const match = remembered === null ? -1 : this.#indexOfValue(remembered);\n if (match >= 0) initial = match;\n }\n this.#select(initial);\n }\n\n #teardown(): void {\n if (!this.#ready) return;\n syncedGroups.delete(this);\n this.#tablist?.remove();\n for (const tab of this.#tabs) {\n tab.removeAttribute(\"role\");\n tab.removeAttribute(\"aria-labelledby\");\n tab.removeAttribute(\"hidden\");\n }\n this.#tablist = null;\n this.#tabs = [];\n this.#buttons = [];\n this.#ready = false;\n }\n\n #indexOfValue(value: string): number {\n return this.#tabs.findIndex((tab) => valuesOf(tab).includes(value));\n }\n\n /** Select a tab without recording or syncing the choice. */\n #select(index: number): void {\n this.#selected = index;\n this.#tabs.forEach((tab, i) => {\n tab.toggleAttribute(\"hidden\", i !== index);\n });\n this.#buttons.forEach((button, i) => {\n button.setAttribute(\"aria-selected\", String(i === index));\n button.tabIndex = i === index ? 0 : -1;\n });\n }\n\n /** The reader picked a tab: select it and, for a synced group, tell the rest. */\n #choose(index: number): void {\n this.#select(index);\n const sync = this.getAttribute(\"sync\");\n const tab = this.#tabs[index];\n const choice = tab ? valuesOf(tab)[0] : undefined;\n if (sync === null || choice === undefined) return;\n writeChoice(sync, choice);\n for (const group of syncedGroups) {\n if (group !== this && group.getAttribute(\"sync\") === sync) group.#follow(choice);\n }\n }\n\n /** Another group with the same `sync` made a choice; keep our selection if we have no match. */\n #follow(value: string): void {\n const index = this.#indexOfValue(value);\n if (index >= 0) this.#select(index);\n }\n\n #onKeydown(event: KeyboardEvent): void {\n const last = this.#tabs.length - 1;\n let next: number;\n switch (event.key) {\n case \"ArrowRight\":\n next = this.#selected === last ? 0 : this.#selected + 1;\n break;\n case \"ArrowLeft\":\n next = this.#selected === 0 ? last : this.#selected - 1;\n break;\n case \"Home\":\n next = 0;\n break;\n case \"End\":\n next = last;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#choose(next);\n this.#buttons[next]?.focus();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ascribed/elements",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-next.11",
|
|
4
4
|
"description": "Ascribe's web component library for the site output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
+
"gitHead": "dd64394135ff782efb8db030c81ac3b38e0f92c5",
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "tsc -p tsconfig.build.json",
|
|
41
42
|
"typecheck": "tsc --noEmit",
|