@riebeckite/plugin-ux 0.0.30 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -16
- package/README_ja.md +3 -14
- package/dist/client.js +45 -80
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -21
- package/dist/src/init.d.ts +1 -1
- package/dist/src/options.d.ts +0 -9
- package/package.json +2 -2
- package/style.css +2 -45
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Client-side progressive enhancements for reading. The plugin leaves the built
|
|
6
6
|
article HTML untouched and adds a reading progress bar, a back-to-top button,
|
|
7
|
-
table-of-contents scroll-spy
|
|
7
|
+
and table-of-contents scroll-spy at runtime.
|
|
8
8
|
|
|
9
9
|
[日本語](./README_ja.md)
|
|
10
10
|
|
|
@@ -17,8 +17,6 @@ table-of-contents scroll-spy, and code copy buttons at runtime.
|
|
|
17
17
|
- **TOC scroll-spy** — observes `a[href^="#"]` links inside the article table of
|
|
18
18
|
contents with `IntersectionObserver` and marks the active link with
|
|
19
19
|
`.rb-ux__toc-active`.
|
|
20
|
-
- **Code copy buttons** — wraps each `pre > code` in `.rb-ux__code` and adds a
|
|
21
|
-
copy button (`.rb-ux__copy`) with a transient "copied" state.
|
|
22
20
|
|
|
23
21
|
Every feature is a no-op when the relevant DOM is absent, and `initUx()` is
|
|
24
22
|
idempotent.
|
|
@@ -36,10 +34,7 @@ export default defineConfig({
|
|
|
36
34
|
progress: true,
|
|
37
35
|
backToTop: true,
|
|
38
36
|
tocScrollSpy: true,
|
|
39
|
-
codeCopy: true,
|
|
40
37
|
backToTopLabel: "Back to top",
|
|
41
|
-
copyLabel: "Copy",
|
|
42
|
-
copiedLabel: "Copied",
|
|
43
38
|
}),
|
|
44
39
|
],
|
|
45
40
|
});
|
|
@@ -54,10 +49,7 @@ The factory is also exported as `ux`.
|
|
|
54
49
|
| `progress` | `boolean` | `true` | Show the reading progress bar |
|
|
55
50
|
| `backToTop` | `boolean` | `true` | Show the back-to-top button |
|
|
56
51
|
| `tocScrollSpy` | `boolean` | `true` | Highlight the active table-of-contents link |
|
|
57
|
-
| `codeCopy` | `boolean` | `true` | Add a copy button to each code block |
|
|
58
52
|
| `backToTopLabel` | `string` | `"Back to top"` | `aria-label` for the back-to-top button |
|
|
59
|
-
| `copyLabel` | `string` | `"Copy"` | Label of the copy button |
|
|
60
|
-
| `copiedLabel` | `string` | `"Copied"` | Transient label shown after copying |
|
|
61
53
|
|
|
62
54
|
## How configuration reaches the client
|
|
63
55
|
|
|
@@ -80,9 +72,6 @@ being inserted twice per page.
|
|
|
80
72
|
| `rb-ux__back-to-top` | Back-to-top button |
|
|
81
73
|
| `rb-ux__back-to-top--visible` | Added while the button is visible |
|
|
82
74
|
| `rb-ux__toc-active` | Active table-of-contents link |
|
|
83
|
-
| `rb-ux__code` | Code block wrapper |
|
|
84
|
-
| `rb-ux__copy` | Copy button |
|
|
85
|
-
| `rb-ux__copy--copied` | Transient copied state |
|
|
86
75
|
|
|
87
76
|
Styles ship as `@riebeckite/plugin-ux/style.css` and use the theme's
|
|
88
77
|
`--rb-color-*` tokens so they do not fight the existing theme.
|
|
@@ -95,16 +84,15 @@ Styles ship as `@riebeckite/plugin-ux/style.css` and use the theme's
|
|
|
95
84
|
- The active table-of-contents link receives `aria-current="true"`.
|
|
96
85
|
- Under `prefers-reduced-motion: reduce`, progress and back-to-top transitions
|
|
97
86
|
are disabled and the back-to-top jump becomes an immediate scroll.
|
|
98
|
-
-
|
|
87
|
+
- The progress bar and buttons are hidden when printing.
|
|
99
88
|
|
|
100
89
|
## Limitations
|
|
101
90
|
|
|
102
91
|
- Client-only: without JavaScript nothing is added.
|
|
103
|
-
-
|
|
92
|
+
- With SPA navigation enabled, the enhancements are re-initialized after the
|
|
93
|
+
page root is replaced.
|
|
104
94
|
- The TOC scroll-spy looks for `.rr-table-of-contents` or `[data-rb-toc]` as
|
|
105
95
|
the table-of-contents container.
|
|
106
|
-
- Copy buttons are skipped inside `.rr-code` blocks (managed by the
|
|
107
|
-
code-enhance plugin) to avoid duplicate copy UI.
|
|
108
96
|
|
|
109
97
|
## Exports
|
|
110
98
|
|
package/README_ja.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- Generated from docs/docs/plugins/ux.ja.md. Edit the canonical documentation in docs/docs/plugins and run `pnpm docs:sync`. -->
|
|
4
4
|
|
|
5
|
-
記事の読みやすさを高めるクライアント側のプログレッシブ・エンハンスメントをまとめたプラグインです。ビルド後の記事 HTML
|
|
5
|
+
記事の読みやすさを高めるクライアント側のプログレッシブ・エンハンスメントをまとめたプラグインです。ビルド後の記事 HTML はそのままに、読み進捗バー・トップへ戻るボタン・目次のスクロール連動ハイライトを追加します。
|
|
6
6
|
|
|
7
7
|
[English](./README.md)
|
|
8
8
|
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
- **読み進捗バー**: 画面上部に固定した細いバー(`.rb-ux__progress`)が記事のスクロール量に追従します。
|
|
12
12
|
- **トップへ戻るボタン**: 一定量スクロールすると表示される button 要素(`.rb-ux__back-to-top`)。`aria-label` を持ち、スムーズスクロールで先頭へ戻ります。
|
|
13
13
|
- **目次のスクロール連動**: 記事の目次コンテナ内の `a[href^="#"]` を `IntersectionObserver` で監視し、現在位置の見出しリンクに `.rb-ux__toc-active` を付けます。
|
|
14
|
-
- **コードのコピーボタン**: 各 `pre > code`(`.rb-ux__code` でラップ)にコピーボタン(`.rb-ux__copy`)を追加します。コピー直後は一時的に「コピーしました」表示へ切り替わります。
|
|
15
14
|
|
|
16
15
|
いずれも対応する DOM が無いページでは何もしません。`initUx()` は何度呼んでも二重に初期化しません。
|
|
17
16
|
|
|
@@ -28,10 +27,7 @@ export default defineConfig({
|
|
|
28
27
|
progress: true,
|
|
29
28
|
backToTop: true,
|
|
30
29
|
tocScrollSpy: true,
|
|
31
|
-
codeCopy: true,
|
|
32
30
|
backToTopLabel: "トップへ戻る",
|
|
33
|
-
copyLabel: "コピー",
|
|
34
|
-
copiedLabel: "コピーしました",
|
|
35
31
|
}),
|
|
36
32
|
],
|
|
37
33
|
});
|
|
@@ -46,10 +42,7 @@ export default defineConfig({
|
|
|
46
42
|
| `progress` | `boolean` | `true` | 読み進捗バーを表示する |
|
|
47
43
|
| `backToTop` | `boolean` | `true` | トップへ戻るボタンを表示する |
|
|
48
44
|
| `tocScrollSpy` | `boolean` | `true` | 目次のスクロール連動ハイライトを有効にする |
|
|
49
|
-
| `codeCopy` | `boolean` | `true` | コードのコピーボタンを追加する |
|
|
50
45
|
| `backToTopLabel` | `string` | `"Back to top"` | トップへ戻るボタンの `aria-label` |
|
|
51
|
-
| `copyLabel` | `string` | `"Copy"` | コピーボタンのラベル |
|
|
52
|
-
| `copiedLabel` | `string` | `"Copied"` | コピー成功時に一時表示するラベル |
|
|
53
46
|
|
|
54
47
|
## 設定がクライアントへ渡る仕組み
|
|
55
48
|
|
|
@@ -66,9 +59,6 @@ export default defineConfig({
|
|
|
66
59
|
| `rb-ux__back-to-top` | トップへ戻る button |
|
|
67
60
|
| `rb-ux__back-to-top--visible` | 表示状態のとき付与 |
|
|
68
61
|
| `rb-ux__toc-active` | 現在位置の目次リンク |
|
|
69
|
-
| `rb-ux__code` | コードブロックのラッパー |
|
|
70
|
-
| `rb-ux__copy` | コピーボタン |
|
|
71
|
-
| `rb-ux__copy--copied` | コピー直後の一時状態 |
|
|
72
62
|
|
|
73
63
|
スタイルは `@riebeckite/plugin-ux/style.css` として配布し、テーマの `--rb-color-*` トークンを参照するため既存テーマと競合しません。
|
|
74
64
|
|
|
@@ -78,14 +68,13 @@ export default defineConfig({
|
|
|
78
68
|
- 進捗バーは `role="progressbar"` と `aria-valuemin` / `aria-valuemax` / `aria-valuenow` を持ちます。
|
|
79
69
|
- 目次の現在位置には `aria-current="true"` を付けます。
|
|
80
70
|
- `prefers-reduced-motion: reduce` では進捗バーとトップへ戻るボタンのアニメーションを無効化し、トップへ戻る動作も即時スクロールへ切り替えます。
|
|
81
|
-
-
|
|
71
|
+
- 印刷時は進捗バーとボタンを非表示にします。
|
|
82
72
|
|
|
83
73
|
## 制限事項
|
|
84
74
|
|
|
85
75
|
- クライアント専用です。JavaScript が無効な環境では何も追加されません。
|
|
86
|
-
- SPA
|
|
76
|
+
- SPA ナビゲーションを有効にした場合は、ページルートの置換後に機能を再初期化します。
|
|
87
77
|
- 目次のスクロール連動は `.rr-table-of-contents` または `[data-rb-toc]` を目次コンテナとして探します。
|
|
88
|
-
- コードのコピーボタンは `.rr-code`(code-enhance プラグインが管理するブロック)には追加しません。二重のコピー UI を避けるためです。
|
|
89
78
|
|
|
90
79
|
## 主なエクスポート
|
|
91
80
|
|
package/dist/client.js
CHANGED
|
@@ -4,10 +4,7 @@ var DEFAULT_UX_CONFIG = {
|
|
|
4
4
|
progress: true,
|
|
5
5
|
backToTop: true,
|
|
6
6
|
tocScrollSpy: true,
|
|
7
|
-
|
|
8
|
-
backToTopLabel: "Back to top",
|
|
9
|
-
copyLabel: "Copy",
|
|
10
|
-
copiedLabel: "Copied"
|
|
7
|
+
backToTopLabel: "Back to top"
|
|
11
8
|
};
|
|
12
9
|
|
|
13
10
|
// src/init.ts
|
|
@@ -16,28 +13,27 @@ var PROGRESS_BAR_CLASS = "rb-ux__progress-bar";
|
|
|
16
13
|
var BACK_TO_TOP_CLASS = "rb-ux__back-to-top";
|
|
17
14
|
var BACK_TO_TOP_VISIBLE_CLASS = "rb-ux__back-to-top--visible";
|
|
18
15
|
var TOC_ACTIVE_CLASS = "rb-ux__toc-active";
|
|
19
|
-
var CODE_CLASS = "rb-ux__code";
|
|
20
|
-
var COPY_CLASS = "rb-ux__copy";
|
|
21
|
-
var COPY_COPIED_CLASS = "rb-ux__copy--copied";
|
|
22
16
|
var BACK_TO_TOP_THRESHOLD = 320;
|
|
23
|
-
var COPIED_STATE_DURATION = 1500;
|
|
24
|
-
var started = false;
|
|
25
|
-
var copiedTimers = /* @__PURE__ */ new WeakMap();
|
|
26
17
|
function initUx() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const config = readUxConfig();
|
|
18
|
+
let cleanup = () => {
|
|
19
|
+
};
|
|
30
20
|
const run = () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
const config = readUxConfig();
|
|
22
|
+
const cleanups = [
|
|
23
|
+
config.progress ? setupProgress() : void 0,
|
|
24
|
+
config.backToTop ? setupBackToTop(config) : void 0,
|
|
25
|
+
config.tocScrollSpy ? setupTocScrollSpy() : void 0
|
|
26
|
+
].filter((value) => value !== void 0);
|
|
27
|
+
cleanup = () => {
|
|
28
|
+
for (const dispose of cleanups) dispose();
|
|
29
|
+
};
|
|
35
30
|
};
|
|
36
31
|
if (document.readyState === "loading") {
|
|
37
32
|
document.addEventListener("DOMContentLoaded", run, { once: true });
|
|
38
|
-
|
|
39
|
-
run();
|
|
33
|
+
return () => document.removeEventListener("DOMContentLoaded", run);
|
|
40
34
|
}
|
|
35
|
+
run();
|
|
36
|
+
return () => cleanup();
|
|
41
37
|
}
|
|
42
38
|
function readUxConfig() {
|
|
43
39
|
const element = document.getElementById(UX_CONFIG_ELEMENT_ID);
|
|
@@ -50,13 +46,10 @@ function readUxConfig() {
|
|
|
50
46
|
parsed.tocScrollSpy,
|
|
51
47
|
DEFAULT_UX_CONFIG.tocScrollSpy
|
|
52
48
|
),
|
|
53
|
-
codeCopy: readBoolean(parsed.codeCopy, DEFAULT_UX_CONFIG.codeCopy),
|
|
54
49
|
backToTopLabel: readString(
|
|
55
50
|
parsed.backToTopLabel,
|
|
56
51
|
DEFAULT_UX_CONFIG.backToTopLabel
|
|
57
|
-
)
|
|
58
|
-
copyLabel: readString(parsed.copyLabel, DEFAULT_UX_CONFIG.copyLabel),
|
|
59
|
-
copiedLabel: readString(parsed.copiedLabel, DEFAULT_UX_CONFIG.copiedLabel)
|
|
52
|
+
)
|
|
60
53
|
};
|
|
61
54
|
}
|
|
62
55
|
function parseConfig(raw) {
|
|
@@ -79,7 +72,7 @@ function readString(value, fallback) {
|
|
|
79
72
|
}
|
|
80
73
|
function setupProgress() {
|
|
81
74
|
const article = findArticle();
|
|
82
|
-
if (!article || hasElement(PROGRESS_CLASS)) return;
|
|
75
|
+
if (!article || hasElement(PROGRESS_CLASS)) return void 0;
|
|
83
76
|
const track = document.createElement("div");
|
|
84
77
|
track.className = PROGRESS_CLASS;
|
|
85
78
|
track.setAttribute("role", "progressbar");
|
|
@@ -95,7 +88,11 @@ function setupProgress() {
|
|
|
95
88
|
fill.style.transform = `scaleX(${ratio})`;
|
|
96
89
|
track.setAttribute("aria-valuenow", String(Math.round(ratio * 100)));
|
|
97
90
|
};
|
|
98
|
-
scheduleOnScroll(update);
|
|
91
|
+
const stop = scheduleOnScroll(update);
|
|
92
|
+
return () => {
|
|
93
|
+
stop();
|
|
94
|
+
track.remove();
|
|
95
|
+
};
|
|
99
96
|
}
|
|
100
97
|
function readingProgress(article) {
|
|
101
98
|
const top = article.getBoundingClientRect().top + window.scrollY;
|
|
@@ -104,7 +101,7 @@ function readingProgress(article) {
|
|
|
104
101
|
return clamp((window.scrollY - top) / (end - top), 0, 1);
|
|
105
102
|
}
|
|
106
103
|
function setupBackToTop(config) {
|
|
107
|
-
if (hasElement(BACK_TO_TOP_CLASS)) return;
|
|
104
|
+
if (hasElement(BACK_TO_TOP_CLASS)) return void 0;
|
|
108
105
|
const button = document.createElement("button");
|
|
109
106
|
button.type = "button";
|
|
110
107
|
button.className = BACK_TO_TOP_CLASS;
|
|
@@ -124,17 +121,21 @@ function setupBackToTop(config) {
|
|
|
124
121
|
window.scrollY >= threshold()
|
|
125
122
|
);
|
|
126
123
|
};
|
|
127
|
-
scheduleOnScroll(update);
|
|
124
|
+
const stop = scheduleOnScroll(update);
|
|
125
|
+
return () => {
|
|
126
|
+
stop();
|
|
127
|
+
button.remove();
|
|
128
|
+
};
|
|
128
129
|
}
|
|
129
130
|
function setupTocScrollSpy() {
|
|
130
131
|
const container = document.querySelector(
|
|
131
132
|
".rr-table-of-contents, [data-rb-toc]"
|
|
132
133
|
);
|
|
133
|
-
if (!container || container.dataset.rbUxToc === "true") return;
|
|
134
|
+
if (!container || container.dataset.rbUxToc === "true") return void 0;
|
|
134
135
|
const links = Array.from(
|
|
135
136
|
container.querySelectorAll('a[href^="#"]')
|
|
136
137
|
);
|
|
137
|
-
if (links.length === 0) return;
|
|
138
|
+
if (links.length === 0) return void 0;
|
|
138
139
|
const linksById = /* @__PURE__ */ new Map();
|
|
139
140
|
for (const link of links) {
|
|
140
141
|
const id = hashToId(link.getAttribute("href"));
|
|
@@ -144,7 +145,7 @@ function setupTocScrollSpy() {
|
|
|
144
145
|
linksById.set(id, existing);
|
|
145
146
|
}
|
|
146
147
|
const headings = Array.from(linksById.keys()).map((id) => document.getElementById(id)).filter((heading) => heading !== null);
|
|
147
|
-
if (headings.length === 0) return;
|
|
148
|
+
if (headings.length === 0) return void 0;
|
|
148
149
|
container.dataset.rbUxToc = "true";
|
|
149
150
|
const activate = (id) => {
|
|
150
151
|
for (const link of links) {
|
|
@@ -179,8 +180,9 @@ function setupTocScrollSpy() {
|
|
|
179
180
|
activate(nextId);
|
|
180
181
|
}
|
|
181
182
|
};
|
|
183
|
+
let observer;
|
|
182
184
|
if (typeof IntersectionObserver === "function") {
|
|
183
|
-
|
|
185
|
+
observer = new IntersectionObserver(
|
|
184
186
|
(entries) => {
|
|
185
187
|
for (const entry of entries) {
|
|
186
188
|
const id = entry.target.id;
|
|
@@ -197,57 +199,15 @@ function setupTocScrollSpy() {
|
|
|
197
199
|
);
|
|
198
200
|
for (const heading of headings) observer.observe(heading);
|
|
199
201
|
}
|
|
200
|
-
scheduleOnScroll(updateActive);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
for (const code of blocks) {
|
|
207
|
-
const pre = code.parentElement;
|
|
208
|
-
if (!pre || pre.dataset.rbUxCopy === "true") continue;
|
|
209
|
-
if (pre.closest(".rr-code")) continue;
|
|
210
|
-
pre.dataset.rbUxCopy = "true";
|
|
211
|
-
const wrapper = document.createElement("div");
|
|
212
|
-
wrapper.className = CODE_CLASS;
|
|
213
|
-
pre.replaceWith(wrapper);
|
|
214
|
-
wrapper.append(pre);
|
|
215
|
-
const button = document.createElement("button");
|
|
216
|
-
button.type = "button";
|
|
217
|
-
button.className = COPY_CLASS;
|
|
218
|
-
button.setAttribute("aria-label", config.copyLabel);
|
|
219
|
-
button.textContent = config.copyLabel;
|
|
220
|
-
button.addEventListener("click", () => {
|
|
221
|
-
void copyCode(button, code, config);
|
|
222
|
-
});
|
|
223
|
-
wrapper.append(button);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
async function copyCode(button, code, config) {
|
|
227
|
-
const text = code.textContent ?? "";
|
|
228
|
-
const clipboard = navigator.clipboard;
|
|
229
|
-
if (text.length === 0 || !clipboard) return;
|
|
230
|
-
try {
|
|
231
|
-
await clipboard.writeText(text);
|
|
232
|
-
} catch {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
showCopiedState(button, config);
|
|
236
|
-
}
|
|
237
|
-
function showCopiedState(button, config) {
|
|
238
|
-
const previous = copiedTimers.get(button);
|
|
239
|
-
if (previous !== void 0) window.clearTimeout(previous);
|
|
240
|
-
button.textContent = config.copiedLabel;
|
|
241
|
-
button.classList.add(COPY_COPIED_CLASS);
|
|
242
|
-
const timer = window.setTimeout(() => {
|
|
243
|
-
button.textContent = config.copyLabel;
|
|
244
|
-
button.classList.remove(COPY_COPIED_CLASS);
|
|
245
|
-
copiedTimers.delete(button);
|
|
246
|
-
}, COPIED_STATE_DURATION);
|
|
247
|
-
copiedTimers.set(button, timer);
|
|
202
|
+
const stop = scheduleOnScroll(updateActive);
|
|
203
|
+
return () => {
|
|
204
|
+
stop();
|
|
205
|
+
observer?.disconnect();
|
|
206
|
+
delete container.dataset.rbUxToc;
|
|
207
|
+
};
|
|
248
208
|
}
|
|
249
209
|
function findArticle() {
|
|
250
|
-
return document.querySelector(
|
|
210
|
+
return document.querySelector(".rb-article-body");
|
|
251
211
|
}
|
|
252
212
|
function hasElement(className) {
|
|
253
213
|
return document.querySelector(`.${className}`) !== null;
|
|
@@ -280,6 +240,11 @@ function scheduleOnScroll(update) {
|
|
|
280
240
|
window.addEventListener("scroll", schedule, { passive: true });
|
|
281
241
|
window.addEventListener("resize", schedule);
|
|
282
242
|
update();
|
|
243
|
+
return () => {
|
|
244
|
+
window.removeEventListener("scroll", schedule);
|
|
245
|
+
window.removeEventListener("resize", schedule);
|
|
246
|
+
if (frame) window.cancelAnimationFrame(frame);
|
|
247
|
+
};
|
|
283
248
|
}
|
|
284
249
|
export {
|
|
285
250
|
initUx
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type UxOptions } from "./src/options.js";
|
|
|
2
2
|
export type { UxOptions, UxResolvedConfig } from "./src/options.js";
|
|
3
3
|
/**
|
|
4
4
|
* Client-only progressive enhancements: a reading progress bar, a
|
|
5
|
-
* back-to-top button, table-of-contents scroll-spy
|
|
5
|
+
* back-to-top button, and table-of-contents scroll-spy.
|
|
6
6
|
*
|
|
7
7
|
* None of the features change the rendered article markup, so the plugin
|
|
8
8
|
* only injects a JSON config element and registers a browser initializer.
|
package/dist/index.js
CHANGED
|
@@ -15,25 +15,16 @@ var DEFAULT_UX_CONFIG = {
|
|
|
15
15
|
progress: true,
|
|
16
16
|
backToTop: true,
|
|
17
17
|
tocScrollSpy: true,
|
|
18
|
-
|
|
19
|
-
backToTopLabel: "Back to top",
|
|
20
|
-
copyLabel: "Copy",
|
|
21
|
-
copiedLabel: "Copied"
|
|
18
|
+
backToTopLabel: "Back to top"
|
|
22
19
|
};
|
|
23
20
|
function resolveUxConfig(options = {}) {
|
|
24
21
|
return {
|
|
25
22
|
progress: options.progress ?? DEFAULT_UX_CONFIG.progress,
|
|
26
23
|
backToTop: options.backToTop ?? DEFAULT_UX_CONFIG.backToTop,
|
|
27
24
|
tocScrollSpy: options.tocScrollSpy ?? DEFAULT_UX_CONFIG.tocScrollSpy,
|
|
28
|
-
codeCopy: options.codeCopy ?? DEFAULT_UX_CONFIG.codeCopy,
|
|
29
25
|
backToTopLabel: normalizeLabel(
|
|
30
26
|
options.backToTopLabel,
|
|
31
27
|
DEFAULT_UX_CONFIG.backToTopLabel
|
|
32
|
-
),
|
|
33
|
-
copyLabel: normalizeLabel(options.copyLabel, DEFAULT_UX_CONFIG.copyLabel),
|
|
34
|
-
copiedLabel: normalizeLabel(
|
|
35
|
-
options.copiedLabel,
|
|
36
|
-
DEFAULT_UX_CONFIG.copiedLabel
|
|
37
28
|
)
|
|
38
29
|
};
|
|
39
30
|
}
|
|
@@ -82,21 +73,16 @@ var ux = uxPlugin;
|
|
|
82
73
|
function validateUxOptions(options) {
|
|
83
74
|
if (!options) return [];
|
|
84
75
|
const issues = [];
|
|
85
|
-
for (const key of [
|
|
86
|
-
"progress",
|
|
87
|
-
"backToTop",
|
|
88
|
-
"tocScrollSpy",
|
|
89
|
-
"codeCopy"
|
|
90
|
-
]) {
|
|
76
|
+
for (const key of ["progress", "backToTop", "tocScrollSpy"]) {
|
|
91
77
|
if (options[key] !== void 0 && typeof options[key] !== "boolean") {
|
|
92
78
|
issues.push({ path: key, message: "Expected a boolean." });
|
|
93
79
|
}
|
|
94
80
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
81
|
+
if (options.backToTopLabel !== void 0 && (typeof options.backToTopLabel !== "string" || options.backToTopLabel.trim() === "")) {
|
|
82
|
+
issues.push({
|
|
83
|
+
path: "backToTopLabel",
|
|
84
|
+
message: "Expected a non-empty string."
|
|
85
|
+
});
|
|
100
86
|
}
|
|
101
87
|
return issues;
|
|
102
88
|
}
|
package/dist/src/init.d.ts
CHANGED
package/dist/src/options.d.ts
CHANGED
|
@@ -11,24 +11,15 @@ export type UxOptions = {
|
|
|
11
11
|
backToTop?: boolean;
|
|
12
12
|
/** Highlight the active entry in the article table of contents. Defaults to `true`. */
|
|
13
13
|
tocScrollSpy?: boolean;
|
|
14
|
-
/** Add a copy button to every code block. Defaults to `true`. */
|
|
15
|
-
codeCopy?: boolean;
|
|
16
14
|
/** Accessible label for the back-to-top button. */
|
|
17
15
|
backToTopLabel?: string;
|
|
18
|
-
/** Label for the code copy button. */
|
|
19
|
-
copyLabel?: string;
|
|
20
|
-
/** Transient label shown after a successful copy. */
|
|
21
|
-
copiedLabel?: string;
|
|
22
16
|
};
|
|
23
17
|
/** Options after defaults have been applied. Serialized into the page. */
|
|
24
18
|
export type UxResolvedConfig = {
|
|
25
19
|
progress: boolean;
|
|
26
20
|
backToTop: boolean;
|
|
27
21
|
tocScrollSpy: boolean;
|
|
28
|
-
codeCopy: boolean;
|
|
29
22
|
backToTopLabel: string;
|
|
30
|
-
copyLabel: string;
|
|
31
|
-
copiedLabel: string;
|
|
32
23
|
};
|
|
33
24
|
/** Id of the JSON configuration element injected into each article. */
|
|
34
25
|
export declare const UX_CONFIG_ELEMENT_ID = "rb-ux-config";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/plugin-ux",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"./style.css": "./style.css"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@riebeckite/core": "0.0.
|
|
24
|
+
"@riebeckite/core": "0.0.32"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
package/style.css
CHANGED
|
@@ -65,59 +65,16 @@
|
|
|
65
65
|
font-weight: 600;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
.rb-ux__code {
|
|
69
|
-
position: relative;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.rb-ux__copy {
|
|
73
|
-
position: absolute;
|
|
74
|
-
inset-block-start: 0.5rem;
|
|
75
|
-
inset-inline-end: 0.5rem;
|
|
76
|
-
z-index: 1;
|
|
77
|
-
padding: 0.2rem 0.5rem;
|
|
78
|
-
border: 1px solid
|
|
79
|
-
var(--rb-color-border, color-mix(in srgb, currentColor 20%, transparent));
|
|
80
|
-
border-radius: 4px;
|
|
81
|
-
background: var(--rb-color-surface, var(--rb-color-paper, #ffffff));
|
|
82
|
-
color: var(--rb-color-muted, #69645c);
|
|
83
|
-
font-size: 0.75rem;
|
|
84
|
-
line-height: 1.4;
|
|
85
|
-
cursor: pointer;
|
|
86
|
-
opacity: 0.9;
|
|
87
|
-
transition:
|
|
88
|
-
opacity 120ms ease,
|
|
89
|
-
color 120ms ease,
|
|
90
|
-
border-color 120ms ease;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.rb-ux__copy:hover,
|
|
94
|
-
.rb-ux__copy:focus-visible {
|
|
95
|
-
opacity: 1;
|
|
96
|
-
color: var(--rb-color-ink, #1c1a17);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.rb-ux__copy:focus-visible {
|
|
100
|
-
outline: 2px solid var(--rb-color-accent, #686868);
|
|
101
|
-
outline-offset: 2px;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.rb-ux__copy--copied {
|
|
105
|
-
color: var(--rb-color-accent, #686868);
|
|
106
|
-
border-color: var(--rb-color-accent, #686868);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
68
|
@media (prefers-reduced-motion: reduce) {
|
|
110
69
|
.rb-ux__progress-bar,
|
|
111
|
-
.rb-ux__back-to-top
|
|
112
|
-
.rb-ux__copy {
|
|
70
|
+
.rb-ux__back-to-top {
|
|
113
71
|
transition: none;
|
|
114
72
|
}
|
|
115
73
|
}
|
|
116
74
|
|
|
117
75
|
@media print {
|
|
118
76
|
.rb-ux__progress,
|
|
119
|
-
.rb-ux__back-to-top
|
|
120
|
-
.rb-ux__copy {
|
|
77
|
+
.rb-ux__back-to-top {
|
|
121
78
|
display: none;
|
|
122
79
|
}
|
|
123
80
|
}
|