@daoyi/nmtl-ui 2.0.1-beta.140 → 2.0.1-beta.142
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.
|
@@ -73,6 +73,7 @@ var zhtw = {
|
|
|
73
73
|
"aria.autocomplete.search": "執行搜尋",
|
|
74
74
|
"aria.loading": "載入中",
|
|
75
75
|
"aria.modal.close": "關閉視窗",
|
|
76
|
+
"chronology.noteToggle": ",顯示或隱藏資料來源",
|
|
76
77
|
"chronology.slideAnnounce": "第 {index} 張,共 {total} 張:{date} {title}",
|
|
77
78
|
"chronology.eventsLabel": "大事年表事件(方向鍵切換)",
|
|
78
79
|
"chronology.zoomIn": "放大時間刻度",
|
|
@@ -212,6 +213,7 @@ var zhcn = {
|
|
|
212
213
|
"aria.autocomplete.search": "执行搜寻",
|
|
213
214
|
"aria.loading": "载入中",
|
|
214
215
|
"aria.modal.close": "关闭视窗",
|
|
216
|
+
"chronology.noteToggle": ",显示或隐藏资料来源",
|
|
215
217
|
"chronology.slideAnnounce": "第 {index} 张,共 {total} 张:{date} {title}",
|
|
216
218
|
"chronology.eventsLabel": "大事年表事件(方向键切换)",
|
|
217
219
|
"chronology.zoomIn": "放大时间刻度",
|
|
@@ -353,6 +355,7 @@ var enus = {
|
|
|
353
355
|
"aria.autocomplete.search": "Search",
|
|
354
356
|
"aria.loading": "Loading",
|
|
355
357
|
"aria.modal.close": "Close dialog",
|
|
358
|
+
"chronology.noteToggle": ", show or hide sources",
|
|
356
359
|
"chronology.slideAnnounce": "Slide {index} of {total}: {date} {title}",
|
|
357
360
|
"chronology.eventsLabel": "Timeline events (use arrow keys)",
|
|
358
361
|
"chronology.zoomIn": "Zoom in the timeline",
|
|
@@ -44,11 +44,50 @@ var prepareMedia = function prepareMedia(media) {
|
|
|
44
44
|
link: undefined
|
|
45
45
|
});
|
|
46
46
|
};
|
|
47
|
+
|
|
48
|
+
/* 「註」原本是 span,只能滑鼠 hover 顯示資料來源,鍵盤與報讀軟體讀不到(WCAG 2.1.1/1.4.13,2026-10-08 人工測試回饋)
|
|
49
|
+
→ 改成按鈕(aria-expanded/aria-controls),開關由 syncTimelineA11y 處理 */
|
|
50
|
+
var noteSeq = 0;
|
|
51
|
+
var enhanceNotes = function enhanceNotes(html, toggleHint) {
|
|
52
|
+
if (typeof html !== 'string' || html.indexOf('remark') === -1 || typeof DOMParser === 'undefined') return html;
|
|
53
|
+
var doc = new DOMParser().parseFromString("<body>".concat(html, "</body>"), 'text/html');
|
|
54
|
+
var changed = false;
|
|
55
|
+
doc.body.querySelectorAll('.tooltip').forEach(function (tip) {
|
|
56
|
+
var remark = tip.querySelector('span.remark');
|
|
57
|
+
var text = tip.querySelector('.tooltiptext');
|
|
58
|
+
if (!remark || !text) return;
|
|
59
|
+
/* 資料來源是空的(後台沒填):整個「註」不顯示,避免按下去只有「資料來源:」(2026-10-08) */
|
|
60
|
+
/* 主站的來源包在 .tooltipsources;子站直接寫「資料來源:…」→ 去掉開頭的標籤(到第一個「:」或「:」)再判斷 */
|
|
61
|
+
var sources = tip.querySelector('.tooltipsources');
|
|
62
|
+
var sourceText = sources ? sources.textContent : text.textContent.replace(/^[^::]*[::]/, '');
|
|
63
|
+
if (!sourceText.trim()) {
|
|
64
|
+
tip.remove();
|
|
65
|
+
changed = true;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
noteSeq += 1;
|
|
69
|
+
var id = "tl-note-".concat(noteSeq);
|
|
70
|
+
text.id = id;
|
|
71
|
+
var button = doc.createElement('button');
|
|
72
|
+
button.type = 'button';
|
|
73
|
+
button.className = remark.className;
|
|
74
|
+
button.textContent = remark.textContent;
|
|
75
|
+
button.setAttribute('aria-expanded', 'false');
|
|
76
|
+
button.setAttribute('aria-controls', id);
|
|
77
|
+
button.setAttribute('aria-label', "".concat(remark.textContent.trim()).concat(toggleHint));
|
|
78
|
+
remark.replaceWith(button);
|
|
79
|
+
changed = true;
|
|
80
|
+
});
|
|
81
|
+
return changed ? doc.body.innerHTML : html;
|
|
82
|
+
};
|
|
47
83
|
var prepareSlide = function prepareSlide(slide) {
|
|
48
84
|
if (!slide) return slide;
|
|
85
|
+
var noteHint = getIntl().formatMessage({
|
|
86
|
+
id: 'chronology.noteToggle'
|
|
87
|
+
});
|
|
49
88
|
var text = slide.text ? _objectSpread2(_objectSpread2({}, slide.text), {}, {
|
|
50
89
|
headline: hint(slide.text.headline),
|
|
51
|
-
text: hint(slide.text.text)
|
|
90
|
+
text: enhanceNotes(hint(slide.text.text), noteHint)
|
|
52
91
|
}) : slide.text;
|
|
53
92
|
return _objectSpread2(_objectSpread2({}, slide), {}, {
|
|
54
93
|
text: text,
|
|
@@ -14,6 +14,7 @@ var MENU_BUTTON_LABELS = [['.tl-icon-zoom-in', 'chronology.zoomIn'], ['.tl-icon-
|
|
|
14
14
|
* 5. 下方時間刻度的事件標記:原本只能滑鼠點選。改為 tablist/tab(只有目前事件可 Tab 到),
|
|
15
15
|
* 方向鍵/Home/End/PageUp/PageDown 換到對應事件
|
|
16
16
|
* 6. 放大、縮小、回到第一張:原本是沒有名稱的 span,補 role="button"、tabindex、名稱,Enter/空白鍵可操作
|
|
17
|
+
* 9. 「註」按鈕:開關資料來源(aria-expanded),Esc 關閉、換頁收起
|
|
17
18
|
* 8. Google 雲端硬碟預覽器 iframe:tabindex="-1"+aria-hidden(見 prepareTimelineData 檔頭 GN1210200E)
|
|
18
19
|
* 7. 套件在 document 上監聽左右鍵換頁(每建一次就多綁一個、從不移除),焦點在頁籤、搜尋框等時間軸外的元件時
|
|
19
20
|
* 按左右鍵也會換投影片 → 只有焦點在這個時間軸的箭頭上才讓它生效
|
|
@@ -192,6 +193,34 @@ var syncTimelineA11y = function syncTimelineA11y(timeline, root) {
|
|
|
192
193
|
setTimeout(syncMenuButtons, 0);
|
|
193
194
|
};
|
|
194
195
|
|
|
196
|
+
/* 9. 「註」按鈕:點擊/Enter/空白鍵開關資料來源,Esc 關閉;換頁時全部收起 */
|
|
197
|
+
var closeNotes = function closeNotes(except) {
|
|
198
|
+
root.querySelectorAll('.tooltip.tooltip--open').forEach(function (tip) {
|
|
199
|
+
if (tip === except) return;
|
|
200
|
+
tip.classList.remove('tooltip--open');
|
|
201
|
+
var button = tip.querySelector('button.remark');
|
|
202
|
+
if (button) button.setAttribute('aria-expanded', 'false');
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
var onNoteClick = function onNoteClick(e) {
|
|
206
|
+
var button = e.target.closest && e.target.closest('.tooltip button.remark');
|
|
207
|
+
if (!button) return;
|
|
208
|
+
var tip = button.closest('.tooltip');
|
|
209
|
+
var open = !tip.classList.contains('tooltip--open');
|
|
210
|
+
closeNotes(tip);
|
|
211
|
+
tip.classList.toggle('tooltip--open', open);
|
|
212
|
+
button.setAttribute('aria-expanded', String(open));
|
|
213
|
+
};
|
|
214
|
+
var onNoteKeyDown = function onNoteKeyDown(e) {
|
|
215
|
+
if (e.key !== 'Escape') return;
|
|
216
|
+
var tip = e.target.closest && e.target.closest('.tooltip.tooltip--open');
|
|
217
|
+
if (!tip) return;
|
|
218
|
+
e.preventDefault();
|
|
219
|
+
closeNotes();
|
|
220
|
+
var button = tip.querySelector('button.remark');
|
|
221
|
+
if (button) button.focus();
|
|
222
|
+
};
|
|
223
|
+
|
|
195
224
|
/* 7. 套件的全域左右鍵:焦點不在本時間軸的箭頭上就不換頁(時間刻度標記由 5. 自己處理) */
|
|
196
225
|
var blockKeyNav = false;
|
|
197
226
|
/* 套件每建一次時間軸就多綁一個 document 監聽器、從不移除;元件卸載或重建後,舊實例仍會被左右鍵觸發 →
|
|
@@ -225,6 +254,8 @@ var syncTimelineA11y = function syncTimelineA11y(timeline, root) {
|
|
|
225
254
|
window.addEventListener('keydown', onKeyCapture, true);
|
|
226
255
|
window.addEventListener('keydown', onKeyBubble);
|
|
227
256
|
root.addEventListener('keydown', onMarkerKeyDown);
|
|
257
|
+
root.addEventListener('click', onNoteClick);
|
|
258
|
+
root.addEventListener('keydown', onNoteKeyDown);
|
|
228
259
|
root.addEventListener('keydown', onMenuKeyDown);
|
|
229
260
|
var timer;
|
|
230
261
|
/* changed:只有真正換頁(change 事件)才播報,初次載入與重建不播 */
|
|
@@ -253,7 +284,8 @@ var syncTimelineA11y = function syncTimelineA11y(timeline, root) {
|
|
|
253
284
|
};
|
|
254
285
|
/* 投影片是套件非同步建出來的:建好(loaded)與每次換頁(change)都重新套用 */
|
|
255
286
|
var onChange = function onChange() {
|
|
256
|
-
|
|
287
|
+
closeNotes();
|
|
288
|
+
apply(true);
|
|
257
289
|
};
|
|
258
290
|
timeline.on('loaded', apply);
|
|
259
291
|
timeline.on('change', onChange);
|
|
@@ -285,6 +317,8 @@ var syncTimelineA11y = function syncTimelineA11y(timeline, root) {
|
|
|
285
317
|
window.removeEventListener('keydown', onKeyCapture, true);
|
|
286
318
|
window.removeEventListener('keydown', onKeyBubble);
|
|
287
319
|
root.removeEventListener('keydown', onMarkerKeyDown);
|
|
320
|
+
root.removeEventListener('click', onNoteClick);
|
|
321
|
+
root.removeEventListener('keydown', onNoteKeyDown);
|
|
288
322
|
root.removeEventListener('keydown', onMenuKeyDown);
|
|
289
323
|
if (live.parentNode) live.parentNode.removeChild(live);
|
|
290
324
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daoyi/nmtl-ui",
|
|
3
3
|
"packageManager": "pnpm@10.34.5",
|
|
4
|
-
"version": "2.0.1-beta.
|
|
4
|
+
"version": "2.0.1-beta.142",
|
|
5
5
|
"description": "This project is to be used as a starter kit for building React component using Storybook and Rollup",
|
|
6
6
|
"author": "daoyi",
|
|
7
7
|
"main": "lib/index.js",
|