@oksigenia/access-panel 0.3.2 → 0.3.4
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/dist/index.d.ts +91 -0
- package/dist/index.js +707 -0
- package/dist/index.js.map +1 -0
- package/dist/web-component.d.ts +20 -0
- package/dist/web-component.js +796 -0
- package/dist/web-component.js.map +1 -0
- package/package.json +9 -9
- package/LICENSE +0 -21
package/dist/index.js
ADDED
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
// src/translations.ts
|
|
2
|
+
var DICT = {
|
|
3
|
+
es: { title: "Accesibilidad", close: "Cerrar", txt: "Texto", size: "Tama\xF1o", lh: "Interlineado", align: "Alineaci\xF3n", font: "Legible", dyslexia: "Fuente Dislexia", vis: "Visual", contrast: "Contraste", gray: "Grises", hide: "Ocultar Img", links: "Links", ori: "Orientaci\xF3n", guide: "Gu\xEDa", cursor: "Cursor Grande", pause: "Parar Animac.", reset: "Restablecer Todo", dev: "Desarrollado por", ls: "Espaciado", cb: "Daltonismo", focus: "Foco" },
|
|
4
|
+
en: { title: "Accessibility", close: "Close", txt: "Text", size: "Size", lh: "Line Height", align: "Align", font: "Readable Font", dyslexia: "Dyslexia Font", vis: "Visual", contrast: "Contrast", gray: "Grayscale", hide: "Hide Images", links: "Highlight Links", ori: "Orientation", guide: "Reading Guide", cursor: "Big Cursor", pause: "Pause Anim.", reset: "Reset All", dev: "Developed by", ls: "Letter Spacing", cb: "Color Blind", focus: "Focus" },
|
|
5
|
+
gn: { title: "Oikeha (Accesibilidad)", close: "Mboty", txt: "Mo\xF1e'\u1EBDr\xE3", size: "Tuichakue", lh: "Jei", align: "Mbojoja", font: "Letra Por\xE3", dyslexia: "Dislexia", vis: "Hechapy", contrast: "Sa'y", gray: "H\u0169 ha T\u0129", hide: "Moka\xF1y Ta'anga", links: "Joajuha", ori: "S\xE3mbyhy", guide: "S\xE3mbyhyha", cursor: "Cursor Guasu", pause: "Mboopyta", reset: "Mbojevy", dev: "Apojare", ls: "Rapykue", cb: "Sa'yvy", focus: "\xD1emoha" },
|
|
6
|
+
fr: { title: "Accessibilit\xE9", close: "Fermer", txt: "Texte", size: "Taille", lh: "Interligne", align: "Alignement", font: "Police Lisible", dyslexia: "Police Dyslexie", vis: "Visuel", contrast: "Contraste", gray: "Niveaux Gris", hide: "Masquer Img", links: "Liens", ori: "Orientation", guide: "Guide Lecture", cursor: "Grand Curseur", pause: "Pause Anim.", reset: "R\xE9initialiser", dev: "D\xE9velopp\xE9 par", ls: "Espacement", cb: "Daltonisme", focus: "Focus" },
|
|
7
|
+
it: { title: "Accessibilit\xE0", close: "Chiudi", txt: "Testo", size: "Dimensione", lh: "Interlinea", align: "Allineamento", font: "Leggibile", dyslexia: "Font Dislessia", vis: "Visivo", contrast: "Contrasto", gray: "Scala Grig.", hide: "Nascondi Img", links: "Link", ori: "Orientamento", guide: "Guida", cursor: "Cursore Grande", pause: "Pausa Anim.", reset: "Reimposta", dev: "Sviluppato da", ls: "Spaziatura", cb: "Daltonismo", focus: "Focus" },
|
|
8
|
+
de: { title: "Barrierefreiheit", close: "Schlie\xDFen", txt: "Text", size: "Gr\xF6\xDFe", lh: "Zeilenh\xF6he", align: "Ausrichtung", font: "Lesbar", dyslexia: "Dyslexie", vis: "Visuell", contrast: "Kontrast", gray: "Graustufen", hide: "Bilder Aus", links: "Links", ori: "Orientierung", guide: "Lesehilfe", cursor: "Gro\xDFer Cursor", pause: "Anim. Stopp", reset: "Zur\xFCcksetzen", dev: "Entwickelt von", ls: "Buchst.abst.", cb: "Farbblindheit", focus: "Fokus" },
|
|
9
|
+
nl: { title: "Toegankelijkheid", close: "Sluiten", txt: "Tekst", size: "Grootte", lh: "Regelhoogte", align: "Uitlijning", font: "Leesbaar", dyslexia: "Dyslexie", vis: "Visueel", contrast: "Contrast", gray: "Grijstinten", hide: "Verberg Afb.", links: "Links", ori: "Ori\xEBntatie", guide: "Leesgids", cursor: "Grote Cursor", pause: "Anim. Pauze", reset: "Resetten", dev: "Ontwikkeld door", ls: "Letterspatie", cb: "Kleurenblind", focus: "Focus" },
|
|
10
|
+
sv: { title: "Tillg\xE4nglighet", close: "St\xE4ng", txt: "Text", size: "Storlek", lh: "Radh\xF6jd", align: "Justering", font: "L\xE4sbar", dyslexia: "Dyslexi", vis: "Visuell", contrast: "Kontrast", gray: "Gr\xE5skala", hide: "D\xF6lj Bilder", links: "L\xE4nkar", ori: "Orientering", guide: "L\xE4slinjal", cursor: "Stor Mark\xF6r", pause: "Pausa Anim.", reset: "\xC5terst\xE4ll", dev: "Utvecklad av", ls: "Bokstavsavst.", cb: "F\xE4rgblindhet", focus: "Fokus" }
|
|
11
|
+
};
|
|
12
|
+
function getTranslation(locale) {
|
|
13
|
+
const lc = locale.toLowerCase();
|
|
14
|
+
if (lc === "gn" || lc.startsWith("gn-") || lc.startsWith("gn_")) return DICT.gn;
|
|
15
|
+
const base = lc.split(/[-_]/)[0];
|
|
16
|
+
return DICT[base] ?? DICT.en;
|
|
17
|
+
}
|
|
18
|
+
function supportedLocales() {
|
|
19
|
+
return Object.keys(DICT);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/icons.ts
|
|
23
|
+
var ICON_TXT = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M2.5,4v3h5v12h3V7h5V4H2.5z M21.5,9h-9v3h3v7h3v-7h3V9z"/></svg>';
|
|
24
|
+
var ICON_LH = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6,7h2.5L5,3.5L1.5,7H4v10H1.5L5,20.5L8.5,17H6V7z M10,5v2h12V5H10z M10,19h12v-2H10V19z M10,13h12v-2H10V13z"/></svg>';
|
|
25
|
+
var ICON_ALIGN = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3,21h18v-2H3V21z M3,17h12v-2H3V17z M3,13h18v-2H3V13z M3,9h12V7H3V9z M3,3v2h18V3H3z"/></svg>';
|
|
26
|
+
var ICON_FONT = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.93,13.5h4.14L12,7.98L9.93,13.5z M5,18l2.25-6h9.5L19,18h3L14.75,3h-5.5L2,18H5z"/></svg>';
|
|
27
|
+
var ICON_DYSLEXIA = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M5,18 L7.5,12 L16.5,12 L19,18 L22,18 L13.5,3 L10.5,3 L2,18 L5,18 Z M12,5.5 L15.5,10 L8.5,10 L12,5.5 Z"/></svg>';
|
|
28
|
+
var ICON_CONTRAST = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20V4c4.41,0,8,3.59,8,8 S16.41,20,12,20z"/></svg>';
|
|
29
|
+
var ICON_GRAY = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18L2 12C2 6.48 6.48 2 12 2v18z"/></svg>';
|
|
30
|
+
var ICON_HIDE = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75C21.27 10.61 17 7.5 12 7.5c-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg>';
|
|
31
|
+
var ICON_LINK = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>';
|
|
32
|
+
var ICON_GUIDE = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 13h18v-2H3v2zm-2 4h22v-2H1v2zM1 7v2h22V7H1z"/></svg>';
|
|
33
|
+
var ICON_CURSOR = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M5.5 3.21V20.8l4.51-4.52 2.13 5.2h2.29l-2.14-5.2H17L5.5 3.21z"/></svg>';
|
|
34
|
+
var ICON_PAUSE = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>';
|
|
35
|
+
var ICON_LS = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M5 5v14h2V5H5zm4 0v14h2V5H9zm4 4v6h2V9h-2zm4-4v14h2V5h-2z"/></svg>';
|
|
36
|
+
var ICON_COLORBLIND = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></svg>';
|
|
37
|
+
var ICON_FOCUS = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 7V3h4v2H5v2H3zm14-4h4v4h-2V5h-2V3zm4 14v4h-4v-2h2v-2h2zM7 21H3v-4h2v2h2v2z"/></svg>';
|
|
38
|
+
var TRIGGER_ICONS = {
|
|
39
|
+
vitruvian: '<svg viewBox="0 0 122.88 122.88" fill="currentColor"><path d="M61.44,0A61.46,61.46,0,1,1,18,18,61.21,61.21,0,0,1,61.44,0Zm-.39,74.18L52.1,98.91a4.94,4.94,0,0,1-2.58,2.83A5,5,0,0,1,42.7,95.5l6.24-17.28a26.3,26.3,0,0,0,1.17-4,40.64,40.64,0,0,0,.54-4.18c.24-2.53.41-5.27.54-7.9s.22-5.18.29-7.29c.09-2.63-.62-2.8-2.73-3.3l-.44-.1-18-3.39A5,5,0,0,1,27.08,46a5,5,0,0,1,5.05-7.74l19.34,3.63c.77.07,1.52.16,2.31.25a57.64,57.64,0,0,0,7.18.53A81.13,81.13,0,0,0,69.9,42c.9-.1,1.75-.21,2.6-.29l18.25-3.42A5,5,0,0,1,94.5,39a5,5,0,0,1,1.3,7,5,5,0,0,1-3.21,2.09L75.15,51.37c-.58.13-1.1.22-1.56.29-1.82.31-2.72.47-2.61,3.06.08,1.89.31,4.15.61,6.51.35,2.77.81,5.71,1.29,8.4.31,1.77.6,3.19,1,4.55s.79,2.75,1.39,4.42l6.11,16.9a5,5,0,0,1-6.82,6.24,4.94,4.94,0,0,1-2.58-2.83L63,74.23,62,72.4l-1,1.78Zm.39-53.52a8.83,8.83,0,1,1-6.24,2.59,8.79,8.79,0,0,1,6.24-2.59Zm36.35,4.43a51.42,51.42,0,1,0,15,36.35,51.27,51.27,0,0,0-15-36.35Z"/></svg>',
|
|
40
|
+
wheelchair: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M19 13v-2c-1.54.02-3.09-.75-4.07-1.83l-1.29-1.43c-.17-.19-.38-.34-.61-.45-.01 0-.01-.01-.02-.01H13c-.35-.2-.75-.3-1.19-.26C10.76 7.11 10 8.04 10 9.09V15c0 1.1.9 2 2 2h5v5h2v-5.5c0-1.1-.9-2-2-2h-3v-3.45c1.29 1.07 3.25 1.94 5 1.95zm-6.17 5c-.41 1.16-1.52 2-2.83 2-1.66 0-3-1.34-3-3 0-1.31.84-2.41 2-2.83V12.1c-2.28.46-4 2.48-4 4.9 0 2.76 2.24 5 5 5 2.42 0 4.44-1.72 4.9-4h-2.07zM12 6c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>',
|
|
41
|
+
eye: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>',
|
|
42
|
+
universal: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm9 7h-6v13h-2v-6h-2v6H9V9H3V7h18v2z"/></svg>'
|
|
43
|
+
};
|
|
44
|
+
var ICON_CLOSE = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
|
|
45
|
+
var COLORBLIND_FILTERS_SVG = '<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;width:0;height:0;overflow:hidden;" aria-hidden="true"><defs><filter id="oks-filter-protanopia"><feColorMatrix type="matrix" values="0.567 0.433 0 0 0 0.558 0.442 0 0 0 0 0.242 0.758 0 0 0 0 0 1 0"/></filter><filter id="oks-filter-deuteranopia"><feColorMatrix type="matrix" values="0.625 0.375 0 0 0 0.7 0.3 0 0 0 0 0.3 0.7 0 0 0 0 0 1 0"/></filter><filter id="oks-filter-tritanopia"><feColorMatrix type="matrix" values="0.95 0.05 0 0 0 0 0.433 0.567 0 0 0 0.475 0.525 0 0 0 0 0 1 0"/></filter></defs></svg>';
|
|
46
|
+
|
|
47
|
+
// src/render.ts
|
|
48
|
+
function buildPanelHtml(opts) {
|
|
49
|
+
const { t, triggerIcon } = opts;
|
|
50
|
+
const trig = TRIGGER_ICONS[triggerIcon];
|
|
51
|
+
const grid = (rows) => `<div class="oks-access-grid">${rows.join("")}</div>`;
|
|
52
|
+
const multi = (action, prefix, levels, label, icon, full = false) => {
|
|
53
|
+
const fullClass = full ? " full-width" : "";
|
|
54
|
+
const dots = Array.from({ length: levels }, () => "<span></span>").join("");
|
|
55
|
+
return `<button class="oks-access-opt multi-step${fullClass}" data-action="${action}" data-prefix="${prefix}" data-levels="${levels}" aria-pressed="false" type="button"><span class="oks-icon">${icon}</span><span class="oks-label">${label}</span><div class="oks-levels">${dots}</div></button>`;
|
|
56
|
+
};
|
|
57
|
+
const toggle = (klass, label, icon) => `<button class="oks-access-opt" data-action="toggle" data-class="${klass}" aria-pressed="false" type="button"><span class="oks-icon">${icon}</span><span class="oks-label">${label}</span></button>`;
|
|
58
|
+
const overlay = (id, label, icon) => `<button class="oks-access-opt" data-action="overlay" data-target="${id}" aria-pressed="false" type="button"><span class="oks-icon">${icon}</span><span class="oks-label">${label}</span></button>`;
|
|
59
|
+
const guide = (label, icon) => `<button class="oks-access-opt" data-action="guide" aria-pressed="false" type="button"><span class="oks-icon">${icon}</span><span class="oks-label">${label}</span></button>`;
|
|
60
|
+
return `
|
|
61
|
+
<div class="oks-access-wrapper" id="oks-wrapper" data-position="${opts.position}">
|
|
62
|
+
<button class="oks-access-btn" id="oks-trigger" aria-label="${escapeAttr(t.title)}" aria-expanded="false" aria-controls="oks-panel" type="button">
|
|
63
|
+
${trig}
|
|
64
|
+
</button>
|
|
65
|
+
<span class="oks-active-badge"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4"><polyline points="20 6 9 17 4 12"/></svg></span>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="oks-access-panel" id="oks-panel" role="dialog" aria-modal="true" aria-labelledby="oks-panel-title" aria-hidden="true">
|
|
68
|
+
<div class="oks-access-header">
|
|
69
|
+
<h3 id="oks-panel-title">${escapeHtml(t.title)}</h3>
|
|
70
|
+
<button class="oks-access-close" id="oks-close" aria-label="${escapeAttr(t.close)}" type="button">${ICON_CLOSE}</button>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="oks-access-content">
|
|
73
|
+
<h4 class="oks-access-title">${escapeHtml(t.txt)}</h4>
|
|
74
|
+
${grid([
|
|
75
|
+
multi("multi", "oks-zoom", 4, t.size, ICON_TXT),
|
|
76
|
+
multi("multi", "oks-lh", 3, t.lh, ICON_LH),
|
|
77
|
+
multi("multi", "oks-align", 3, t.align, ICON_ALIGN),
|
|
78
|
+
toggle("oks-a11y-font", t.font, ICON_FONT),
|
|
79
|
+
toggle("oks-dyslexia", t.dyslexia, ICON_DYSLEXIA),
|
|
80
|
+
multi("multi", "oks-ls", 3, t.ls, ICON_LS)
|
|
81
|
+
])}
|
|
82
|
+
<h4 class="oks-access-title">${escapeHtml(t.vis)}</h4>
|
|
83
|
+
${grid([
|
|
84
|
+
toggle("oks-a11y-contrast", t.contrast, ICON_CONTRAST),
|
|
85
|
+
overlay("oks-overlay-gray", t.gray, ICON_GRAY),
|
|
86
|
+
toggle("oks-a11y-hide", t.hide, ICON_HIDE),
|
|
87
|
+
toggle("oks-a11y-links", t.links, ICON_LINK),
|
|
88
|
+
multi("colorblind", "oks-colorblind", 3, t.cb, ICON_COLORBLIND, true)
|
|
89
|
+
])}
|
|
90
|
+
<h4 class="oks-access-title">${escapeHtml(t.ori)}</h4>
|
|
91
|
+
${grid([
|
|
92
|
+
guide(t.guide, ICON_GUIDE),
|
|
93
|
+
toggle("oks-big-cursor", t.cursor, ICON_CURSOR),
|
|
94
|
+
toggle("oks-a11y-pause", t.pause, ICON_PAUSE),
|
|
95
|
+
toggle("oks-a11y-focus", t.focus, ICON_FOCUS)
|
|
96
|
+
])}
|
|
97
|
+
</div>
|
|
98
|
+
<div class="oks-access-footer">
|
|
99
|
+
<button class="oks-access-reset" id="oks-reset" type="button">${escapeHtml(t.reset)}</button>
|
|
100
|
+
<div class="oks-access-branding">${escapeHtml(t.dev)} <a href="https://oksigenia.com" target="_blank" rel="noopener noreferrer">Oksigenia</a></div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
function escapeHtml(s) {
|
|
106
|
+
return s.replace(/[&<>"]/g, (c) => ({
|
|
107
|
+
"&": "&",
|
|
108
|
+
"<": "<",
|
|
109
|
+
">": ">",
|
|
110
|
+
'"': """
|
|
111
|
+
})[c] ?? c);
|
|
112
|
+
}
|
|
113
|
+
function escapeAttr(s) {
|
|
114
|
+
return escapeHtml(s).replace(/'/g, "'");
|
|
115
|
+
}
|
|
116
|
+
function positionRules(position) {
|
|
117
|
+
switch (position) {
|
|
118
|
+
case "top-left":
|
|
119
|
+
return { wrap: "top: 20px; left: 20px;", panel: "top: 80px; left: 20px;" };
|
|
120
|
+
case "top-right":
|
|
121
|
+
return { wrap: "top: 20px; right: 20px;", panel: "top: 80px; right: 20px;" };
|
|
122
|
+
case "mid-left":
|
|
123
|
+
return { wrap: "top: 50%; left: 20px; transform: translateY(-50%);", panel: "top: 50%; left: 90px; transform: translateY(-50%);" };
|
|
124
|
+
case "mid-right":
|
|
125
|
+
return { wrap: "top: 50%; right: 20px; transform: translateY(-50%);", panel: "top: 50%; right: 90px; transform: translateY(-50%);" };
|
|
126
|
+
case "bottom-left":
|
|
127
|
+
return { wrap: "bottom: 20px; left: 20px;", panel: "bottom: 100px; left: 20px;" };
|
|
128
|
+
case "bottom-right":
|
|
129
|
+
return { wrap: "bottom: 20px; right: 20px;", panel: "bottom: 100px; right: 20px;" };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function positionCss(position, mobile) {
|
|
133
|
+
const d = positionRules(position);
|
|
134
|
+
let css = `.oks-access-wrapper { ${d.wrap} } .oks-access-panel { ${d.panel} }`;
|
|
135
|
+
if (mobile && mobile !== position) {
|
|
136
|
+
const m = positionRules(mobile);
|
|
137
|
+
css += `@media (max-width: 768px) { .oks-access-wrapper { top: auto; right: auto; bottom: auto; left: auto; transform: none; ${m.wrap} } }`;
|
|
138
|
+
}
|
|
139
|
+
return css;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/state.ts
|
|
143
|
+
var DEFAULT_STATE = Object.freeze({
|
|
144
|
+
zoom: 0,
|
|
145
|
+
lh: 0,
|
|
146
|
+
align: 0,
|
|
147
|
+
ls: 0,
|
|
148
|
+
colorblind: 0,
|
|
149
|
+
font: false,
|
|
150
|
+
dyslexia: false,
|
|
151
|
+
contrast: false,
|
|
152
|
+
hideImages: false,
|
|
153
|
+
highlightLinks: false,
|
|
154
|
+
bigCursor: false,
|
|
155
|
+
pauseAnim: false,
|
|
156
|
+
focusOutline: false,
|
|
157
|
+
grayOverlay: false,
|
|
158
|
+
readingGuide: false
|
|
159
|
+
});
|
|
160
|
+
function loadState(key) {
|
|
161
|
+
if (typeof localStorage === "undefined") return { ...DEFAULT_STATE };
|
|
162
|
+
try {
|
|
163
|
+
const raw = localStorage.getItem(key);
|
|
164
|
+
if (!raw) return { ...DEFAULT_STATE };
|
|
165
|
+
const parsed = JSON.parse(raw);
|
|
166
|
+
if (!parsed || typeof parsed !== "object") return { ...DEFAULT_STATE };
|
|
167
|
+
return { ...DEFAULT_STATE, ...parsed };
|
|
168
|
+
} catch {
|
|
169
|
+
return { ...DEFAULT_STATE };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function saveState(key, state) {
|
|
173
|
+
if (typeof localStorage === "undefined") return;
|
|
174
|
+
try {
|
|
175
|
+
const out = {};
|
|
176
|
+
for (const [k, v] of Object.entries(state)) {
|
|
177
|
+
if (typeof v === "number" && v > 0) out[k] = v;
|
|
178
|
+
else if (typeof v === "boolean" && v) out[k] = v;
|
|
179
|
+
}
|
|
180
|
+
if (Object.keys(out).length === 0) {
|
|
181
|
+
localStorage.removeItem(key);
|
|
182
|
+
} else {
|
|
183
|
+
localStorage.setItem(key, JSON.stringify(out));
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function isStateEmpty(state) {
|
|
189
|
+
return state.zoom === 0 && state.lh === 0 && state.align === 0 && state.ls === 0 && state.colorblind === 0 && !state.font && !state.dyslexia && !state.contrast && !state.hideImages && !state.highlightLinks && !state.bigCursor && !state.pauseAnim && !state.focusOutline && !state.grayOverlay && !state.readingGuide;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/behavior.ts
|
|
193
|
+
var MULTI_KEYS = {
|
|
194
|
+
"oks-zoom": "zoom",
|
|
195
|
+
"oks-lh": "lh",
|
|
196
|
+
"oks-align": "align",
|
|
197
|
+
"oks-ls": "ls",
|
|
198
|
+
"oks-colorblind": "colorblind"
|
|
199
|
+
};
|
|
200
|
+
var MULTI_LEVELS = {
|
|
201
|
+
"oks-zoom": 4,
|
|
202
|
+
"oks-lh": 3,
|
|
203
|
+
"oks-align": 3,
|
|
204
|
+
"oks-ls": 3,
|
|
205
|
+
"oks-colorblind": 3
|
|
206
|
+
};
|
|
207
|
+
var TOGGLE_KEYS = {
|
|
208
|
+
"oks-a11y-font": "font",
|
|
209
|
+
"oks-dyslexia": "dyslexia",
|
|
210
|
+
"oks-a11y-contrast": "contrast",
|
|
211
|
+
"oks-a11y-hide": "hideImages",
|
|
212
|
+
"oks-a11y-links": "highlightLinks",
|
|
213
|
+
"oks-big-cursor": "bigCursor",
|
|
214
|
+
"oks-a11y-pause": "pauseAnim",
|
|
215
|
+
"oks-a11y-focus": "focusOutline"
|
|
216
|
+
};
|
|
217
|
+
function bindPanelBehavior(root, opts = {}) {
|
|
218
|
+
const storageKey = opts.storageKey ?? "oksiacSettings";
|
|
219
|
+
const trigger = root.getElementById("oks-trigger");
|
|
220
|
+
const panel = root.getElementById("oks-panel");
|
|
221
|
+
const closeBtn = root.getElementById("oks-close");
|
|
222
|
+
const resetBtn = root.getElementById("oks-reset");
|
|
223
|
+
const wrapper = root.getElementById("oks-wrapper");
|
|
224
|
+
const opts$ = Array.from(root.querySelectorAll(".oks-access-opt"));
|
|
225
|
+
if (!trigger || !panel || !closeBtn || !resetBtn || !wrapper) {
|
|
226
|
+
return () => {
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
let state = loadState(storageKey);
|
|
230
|
+
function applyState() {
|
|
231
|
+
const body = document.body;
|
|
232
|
+
const root2 = document.documentElement;
|
|
233
|
+
body.className = body.className.replace(/\boks-\w+(?:-\d+)?\b/g, "").trim();
|
|
234
|
+
[1, 2, 3].forEach((l) => root2.classList.remove(`oks-colorblind-${l}`));
|
|
235
|
+
if (state.zoom > 0) body.classList.add(`oks-zoom-${state.zoom}`);
|
|
236
|
+
if (state.lh > 0) body.classList.add(`oks-lh-${state.lh}`);
|
|
237
|
+
if (state.align > 0) body.classList.add(`oks-align-${state.align}`);
|
|
238
|
+
if (state.ls > 0) body.classList.add(`oks-ls-${state.ls}`);
|
|
239
|
+
if (state.colorblind > 0) root2.classList.add(`oks-colorblind-${state.colorblind}`);
|
|
240
|
+
if (state.font) body.classList.add("oks-a11y-font");
|
|
241
|
+
if (state.dyslexia) body.classList.add("oks-dyslexia");
|
|
242
|
+
if (state.contrast) body.classList.add("oks-a11y-contrast");
|
|
243
|
+
if (state.hideImages) body.classList.add("oks-a11y-hide");
|
|
244
|
+
if (state.highlightLinks) body.classList.add("oks-a11y-links");
|
|
245
|
+
if (state.bigCursor) body.classList.add("oks-big-cursor");
|
|
246
|
+
if (state.pauseAnim) body.classList.add("oks-a11y-pause");
|
|
247
|
+
if (state.focusOutline) body.classList.add("oks-a11y-focus");
|
|
248
|
+
if (state.readingGuide) body.classList.add("oks-a11y-guide");
|
|
249
|
+
const overlay = ensureOverlay();
|
|
250
|
+
overlay.classList.toggle("is-active", state.grayOverlay);
|
|
251
|
+
syncButtonsFromState();
|
|
252
|
+
wrapper?.classList.toggle("has-active", !isStateEmpty(state));
|
|
253
|
+
}
|
|
254
|
+
function syncButtonsFromState() {
|
|
255
|
+
for (const btn of opts$) {
|
|
256
|
+
const action = btn.getAttribute("data-action");
|
|
257
|
+
if (action === "multi" || action === "colorblind") {
|
|
258
|
+
const prefix = btn.getAttribute("data-prefix") ?? "";
|
|
259
|
+
const key = MULTI_KEYS[prefix];
|
|
260
|
+
if (!key) continue;
|
|
261
|
+
const lvl = state[key];
|
|
262
|
+
btn.setAttribute("data-level", String(lvl));
|
|
263
|
+
btn.classList.toggle("is-active", lvl > 0);
|
|
264
|
+
btn.setAttribute("aria-pressed", lvl > 0 ? "true" : "false");
|
|
265
|
+
} else if (action === "toggle") {
|
|
266
|
+
const klass = btn.getAttribute("data-class") ?? "";
|
|
267
|
+
const key = TOGGLE_KEYS[klass];
|
|
268
|
+
if (!key) continue;
|
|
269
|
+
const val = state[key];
|
|
270
|
+
btn.classList.toggle("is-active", val);
|
|
271
|
+
btn.setAttribute("aria-pressed", val ? "true" : "false");
|
|
272
|
+
} else if (action === "overlay") {
|
|
273
|
+
btn.classList.toggle("is-active", state.grayOverlay);
|
|
274
|
+
btn.setAttribute("aria-pressed", state.grayOverlay ? "true" : "false");
|
|
275
|
+
} else if (action === "guide") {
|
|
276
|
+
btn.classList.toggle("is-active", state.readingGuide);
|
|
277
|
+
btn.setAttribute("aria-pressed", state.readingGuide ? "true" : "false");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const onOptClick = (e) => {
|
|
282
|
+
const btn = e.currentTarget;
|
|
283
|
+
const action = btn.getAttribute("data-action");
|
|
284
|
+
if (action === "multi") {
|
|
285
|
+
const prefix = btn.getAttribute("data-prefix") ?? "";
|
|
286
|
+
const key = MULTI_KEYS[prefix];
|
|
287
|
+
const max = MULTI_LEVELS[prefix] ?? 0;
|
|
288
|
+
if (!key) return;
|
|
289
|
+
const lvl = (state[key] + 1) % (max + 1);
|
|
290
|
+
state[key] = lvl;
|
|
291
|
+
} else if (action === "colorblind") {
|
|
292
|
+
state.colorblind = (state.colorblind + 1) % 4;
|
|
293
|
+
} else if (action === "toggle") {
|
|
294
|
+
const klass = btn.getAttribute("data-class") ?? "";
|
|
295
|
+
const key = TOGGLE_KEYS[klass];
|
|
296
|
+
if (!key) return;
|
|
297
|
+
state[key] = !state[key];
|
|
298
|
+
if (klass === "oks-a11y-contrast" && state.contrast) state.grayOverlay = false;
|
|
299
|
+
} else if (action === "overlay") {
|
|
300
|
+
state.grayOverlay = !state.grayOverlay;
|
|
301
|
+
if (state.grayOverlay) state.contrast = false;
|
|
302
|
+
} else if (action === "guide") {
|
|
303
|
+
state.readingGuide = !state.readingGuide;
|
|
304
|
+
}
|
|
305
|
+
applyState();
|
|
306
|
+
saveState(storageKey, state);
|
|
307
|
+
};
|
|
308
|
+
const onReset = () => {
|
|
309
|
+
state = { ...DEFAULT_STATE };
|
|
310
|
+
applyState();
|
|
311
|
+
saveState(storageKey, state);
|
|
312
|
+
};
|
|
313
|
+
const openPanel = () => {
|
|
314
|
+
panel.classList.add("is-open");
|
|
315
|
+
panel.setAttribute("aria-hidden", "false");
|
|
316
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
317
|
+
const first = panel.querySelector("button:not([disabled])");
|
|
318
|
+
first?.focus();
|
|
319
|
+
};
|
|
320
|
+
const closePanel = () => {
|
|
321
|
+
panel.classList.remove("is-open");
|
|
322
|
+
panel.setAttribute("aria-hidden", "true");
|
|
323
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
324
|
+
trigger.focus();
|
|
325
|
+
};
|
|
326
|
+
const onTriggerClick = (e) => {
|
|
327
|
+
e.stopPropagation();
|
|
328
|
+
if (panel.classList.contains("is-open")) closePanel();
|
|
329
|
+
else openPanel();
|
|
330
|
+
};
|
|
331
|
+
const onDocClick = (e) => {
|
|
332
|
+
if (!panel.classList.contains("is-open")) return;
|
|
333
|
+
const t = e.target;
|
|
334
|
+
if (!panel.contains(t) && !trigger.contains(t) && !wrapper.contains(t)) closePanel();
|
|
335
|
+
};
|
|
336
|
+
const onKeyDown = (e) => {
|
|
337
|
+
if (!panel.classList.contains("is-open")) return;
|
|
338
|
+
if (e.key === "Escape") {
|
|
339
|
+
closePanel();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (e.key !== "Tab") return;
|
|
343
|
+
const focusable = Array.from(panel.querySelectorAll("button:not([disabled])"));
|
|
344
|
+
if (focusable.length === 0) return;
|
|
345
|
+
const first = focusable[0];
|
|
346
|
+
const last = focusable[focusable.length - 1];
|
|
347
|
+
const active = root.activeElement;
|
|
348
|
+
if (e.shiftKey) {
|
|
349
|
+
if (active === first) {
|
|
350
|
+
e.preventDefault();
|
|
351
|
+
last.focus();
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
if (active === last) {
|
|
355
|
+
e.preventDefault();
|
|
356
|
+
first.focus();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
const onMove = (e) => {
|
|
361
|
+
if (!state.readingGuide) return;
|
|
362
|
+
const guide = document.getElementById("oks-reading-guide");
|
|
363
|
+
if (!guide) return;
|
|
364
|
+
const y = e.touches?.[0]?.clientY ?? e.clientY;
|
|
365
|
+
if (typeof y === "number") guide.style.top = `${y}px`;
|
|
366
|
+
};
|
|
367
|
+
trigger.addEventListener("click", onTriggerClick);
|
|
368
|
+
closeBtn.addEventListener("click", closePanel);
|
|
369
|
+
resetBtn.addEventListener("click", onReset);
|
|
370
|
+
for (const btn of opts$) btn.addEventListener("click", onOptClick);
|
|
371
|
+
document.addEventListener("click", onDocClick);
|
|
372
|
+
document.addEventListener("keydown", onKeyDown);
|
|
373
|
+
document.addEventListener("mousemove", onMove);
|
|
374
|
+
document.addEventListener("touchmove", onMove, { passive: true });
|
|
375
|
+
applyState();
|
|
376
|
+
return () => {
|
|
377
|
+
trigger.removeEventListener("click", onTriggerClick);
|
|
378
|
+
closeBtn.removeEventListener("click", closePanel);
|
|
379
|
+
resetBtn.removeEventListener("click", onReset);
|
|
380
|
+
for (const btn of opts$) btn.removeEventListener("click", onOptClick);
|
|
381
|
+
document.removeEventListener("click", onDocClick);
|
|
382
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
383
|
+
document.removeEventListener("mousemove", onMove);
|
|
384
|
+
document.removeEventListener("touchmove", onMove);
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function ensureOverlay() {
|
|
388
|
+
let el = document.getElementById("oks-overlay-gray");
|
|
389
|
+
if (!el) {
|
|
390
|
+
el = document.createElement("div");
|
|
391
|
+
el.id = "oks-overlay-gray";
|
|
392
|
+
el.className = "oks-overlay-effect";
|
|
393
|
+
document.body.appendChild(el);
|
|
394
|
+
}
|
|
395
|
+
return el;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/styles.ts
|
|
399
|
+
var PANEL_CSS = `
|
|
400
|
+
:host {
|
|
401
|
+
--oks-btn-size: 55px;
|
|
402
|
+
--oks-bg: #000;
|
|
403
|
+
--oks-icon: #fff;
|
|
404
|
+
--oks-h-bg: #fff;
|
|
405
|
+
--oks-h-icon: #000;
|
|
406
|
+
--oks-z: 9999999;
|
|
407
|
+
}
|
|
408
|
+
.oks-access-wrapper {
|
|
409
|
+
position: fixed;
|
|
410
|
+
z-index: var(--oks-z);
|
|
411
|
+
line-height: 1;
|
|
412
|
+
}
|
|
413
|
+
.oks-access-btn {
|
|
414
|
+
width: var(--oks-btn-size);
|
|
415
|
+
height: var(--oks-btn-size);
|
|
416
|
+
border-radius: 50%;
|
|
417
|
+
background: var(--oks-bg);
|
|
418
|
+
color: var(--oks-icon);
|
|
419
|
+
border: 2px solid #fff;
|
|
420
|
+
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
|
|
421
|
+
display: flex;
|
|
422
|
+
align-items: center;
|
|
423
|
+
justify-content: center;
|
|
424
|
+
cursor: pointer;
|
|
425
|
+
transition: 0.2s;
|
|
426
|
+
padding: 0;
|
|
427
|
+
}
|
|
428
|
+
.oks-access-btn:hover {
|
|
429
|
+
background: var(--oks-h-bg);
|
|
430
|
+
color: var(--oks-h-icon);
|
|
431
|
+
transform: scale(1.1);
|
|
432
|
+
}
|
|
433
|
+
.oks-access-btn svg {
|
|
434
|
+
fill: currentColor;
|
|
435
|
+
display: block;
|
|
436
|
+
margin: 0 auto;
|
|
437
|
+
width: 60%;
|
|
438
|
+
height: 60%;
|
|
439
|
+
}
|
|
440
|
+
.oks-active-badge {
|
|
441
|
+
position: absolute;
|
|
442
|
+
top: -2px;
|
|
443
|
+
right: -2px;
|
|
444
|
+
width: 20px;
|
|
445
|
+
height: 20px;
|
|
446
|
+
background: #25D366;
|
|
447
|
+
border-radius: 50%;
|
|
448
|
+
border: 2px solid #fff;
|
|
449
|
+
display: flex;
|
|
450
|
+
align-items: center;
|
|
451
|
+
justify-content: center;
|
|
452
|
+
color: #fff;
|
|
453
|
+
opacity: 0;
|
|
454
|
+
pointer-events: none;
|
|
455
|
+
}
|
|
456
|
+
.oks-active-badge svg { width: 12px; height: 12px; }
|
|
457
|
+
.oks-access-wrapper.has-active .oks-active-badge { opacity: 1; }
|
|
458
|
+
|
|
459
|
+
.oks-access-panel {
|
|
460
|
+
position: fixed;
|
|
461
|
+
width: 340px;
|
|
462
|
+
max-height: 90vh;
|
|
463
|
+
background: #fff;
|
|
464
|
+
border-radius: 20px;
|
|
465
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
466
|
+
z-index: var(--oks-z);
|
|
467
|
+
display: flex;
|
|
468
|
+
flex-direction: column;
|
|
469
|
+
opacity: 0;
|
|
470
|
+
pointer-events: none;
|
|
471
|
+
transition: 0.2s;
|
|
472
|
+
border: 1px solid rgba(0,0,0,0.1);
|
|
473
|
+
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
474
|
+
color: #333;
|
|
475
|
+
}
|
|
476
|
+
.oks-access-panel.is-open { opacity: 1; pointer-events: all; }
|
|
477
|
+
.oks-access-header {
|
|
478
|
+
padding: 15px 20px;
|
|
479
|
+
border-bottom: 1px solid #eee;
|
|
480
|
+
display: flex;
|
|
481
|
+
justify-content: space-between;
|
|
482
|
+
align-items: center;
|
|
483
|
+
}
|
|
484
|
+
.oks-access-header h3 { margin: 0; font-size: 18px; color: #000; }
|
|
485
|
+
.oks-access-close {
|
|
486
|
+
background: #f0f0f0;
|
|
487
|
+
color: #333;
|
|
488
|
+
border: 1px solid #ddd;
|
|
489
|
+
width: 44px;
|
|
490
|
+
height: 44px;
|
|
491
|
+
border-radius: 50%;
|
|
492
|
+
cursor: pointer;
|
|
493
|
+
display: flex;
|
|
494
|
+
align-items: center;
|
|
495
|
+
justify-content: center;
|
|
496
|
+
transition: 0.2s;
|
|
497
|
+
padding: 0;
|
|
498
|
+
}
|
|
499
|
+
.oks-access-close:hover { background: #e0e0e0; border-color: #ccc; }
|
|
500
|
+
.oks-access-close svg { width: 24px; height: 24px; stroke-width: 2.5px; }
|
|
501
|
+
.oks-access-content { padding: 0 20px 20px; overflow-y: auto; }
|
|
502
|
+
.oks-access-title {
|
|
503
|
+
margin: 10px 0 5px;
|
|
504
|
+
font-size: 11px;
|
|
505
|
+
font-weight: 800;
|
|
506
|
+
text-transform: uppercase;
|
|
507
|
+
color: #888;
|
|
508
|
+
}
|
|
509
|
+
.oks-access-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
|
510
|
+
.oks-access-opt {
|
|
511
|
+
background: #f9f9f9;
|
|
512
|
+
border: 2px solid #eee;
|
|
513
|
+
border-radius: 10px;
|
|
514
|
+
padding: 10px;
|
|
515
|
+
display: flex;
|
|
516
|
+
flex-direction: column;
|
|
517
|
+
align-items: center;
|
|
518
|
+
justify-content: center;
|
|
519
|
+
cursor: pointer;
|
|
520
|
+
min-height: 70px;
|
|
521
|
+
color: #333;
|
|
522
|
+
transition: 0.2s;
|
|
523
|
+
font: inherit;
|
|
524
|
+
}
|
|
525
|
+
.oks-access-opt.full-width { grid-column: span 2; }
|
|
526
|
+
.oks-access-opt.is-active {
|
|
527
|
+
border-color: #000;
|
|
528
|
+
background: #fff;
|
|
529
|
+
box-shadow: 0 0 0 1px #000;
|
|
530
|
+
}
|
|
531
|
+
.oks-access-opt:hover { background: #000; color: #fff; border-color: #000; }
|
|
532
|
+
.oks-icon { font-size: 28px; margin-bottom: 3px; display: block; line-height: 1; }
|
|
533
|
+
.oks-icon svg { width: 24px; height: 24px; fill: currentColor; }
|
|
534
|
+
.oks-label {
|
|
535
|
+
font-size: 11px;
|
|
536
|
+
font-weight: 700;
|
|
537
|
+
text-transform: uppercase;
|
|
538
|
+
text-align: center;
|
|
539
|
+
line-height: 1.2;
|
|
540
|
+
}
|
|
541
|
+
.oks-levels { display: flex; gap: 3px; height: 5px; width: 50%; margin-top: 5px; }
|
|
542
|
+
.oks-levels span { flex: 1; background: #ddd; border-radius: 3px; }
|
|
543
|
+
.oks-access-opt[data-level="1"] .oks-levels span:nth-child(1),
|
|
544
|
+
.oks-access-opt[data-level="2"] .oks-levels span:nth-child(-n+2),
|
|
545
|
+
.oks-access-opt[data-level="3"] .oks-levels span:nth-child(-n+3),
|
|
546
|
+
.oks-access-opt[data-level="4"] .oks-levels span:nth-child(-n+4) { background: #000; }
|
|
547
|
+
.oks-access-opt:hover .oks-levels span { background: #555; }
|
|
548
|
+
.oks-access-footer {
|
|
549
|
+
padding: 12px 20px;
|
|
550
|
+
border-top: 1px solid #eee;
|
|
551
|
+
text-align: center;
|
|
552
|
+
}
|
|
553
|
+
.oks-access-reset {
|
|
554
|
+
width: 100%;
|
|
555
|
+
padding: 8px;
|
|
556
|
+
border: 2px solid #000;
|
|
557
|
+
color: #000;
|
|
558
|
+
background: transparent;
|
|
559
|
+
font-weight: 700;
|
|
560
|
+
cursor: pointer;
|
|
561
|
+
border-radius: 6px;
|
|
562
|
+
font-size: 12px;
|
|
563
|
+
}
|
|
564
|
+
.oks-access-reset:hover { background: #000; color: #fff; }
|
|
565
|
+
.oks-access-branding { margin-top: 12px; font-size: 12px; color: #000; font-weight: 700; }
|
|
566
|
+
.oks-access-branding a { color: #000; text-decoration: none; border-bottom: 1px dotted #000; }
|
|
567
|
+
|
|
568
|
+
@media (max-width: 768px) {
|
|
569
|
+
.oks-access-panel {
|
|
570
|
+
width: 100%; height: 100%; max-height: 100%;
|
|
571
|
+
top: 0; left: 0; right: 0; bottom: 0;
|
|
572
|
+
border-radius: 0;
|
|
573
|
+
}
|
|
574
|
+
.oks-access-opt { min-height: 88px; padding: 14px 8px; }
|
|
575
|
+
.oks-icon svg { width: 30px; height: 30px; }
|
|
576
|
+
.oks-label { font-size: 12px; line-height: 1.3; }
|
|
577
|
+
.oks-access-grid { gap: 10px; }
|
|
578
|
+
.oks-access-content { padding: 0 16px 24px; }
|
|
579
|
+
.oks-access-title { font-size: 12px; margin: 14px 0 6px; }
|
|
580
|
+
.oks-access-reset { padding: 14px; font-size: 14px; }
|
|
581
|
+
}
|
|
582
|
+
`;
|
|
583
|
+
var EFFECT_CSS = `
|
|
584
|
+
html.oks-colorblind-1 { filter: url('#oks-filter-protanopia'); }
|
|
585
|
+
html.oks-colorblind-2 { filter: url('#oks-filter-deuteranopia'); }
|
|
586
|
+
html.oks-colorblind-3 { filter: url('#oks-filter-tritanopia'); }
|
|
587
|
+
|
|
588
|
+
/* Text-size levels.
|
|
589
|
+
Applied to <html> via :has(), not to <body>. rem is anchored to the root
|
|
590
|
+
element, so a site whose CSS sizes things in rem (most modern Astro / Tailwind
|
|
591
|
+
builds) needs the root font-size to change for the scale to take effect.
|
|
592
|
+
A previous version applied this to body with %, which only moved descendants
|
|
593
|
+
that inherited font-size from body \u2014 anything sized in rem stayed locked to
|
|
594
|
+
the 16px default of <html>. An even earlier version used the universal
|
|
595
|
+
selector with em and compounded the factor at every nesting level.
|
|
596
|
+
:has(body.oks-zoom-N) is the right anchor: one change at the root, rem
|
|
597
|
+
descendants scale exactly once. Hard-coded px is intentionally left alone;
|
|
598
|
+
browser zoom covers that case. */
|
|
599
|
+
html:has(body.oks-zoom-1) { font-size: 110% !important; }
|
|
600
|
+
html:has(body.oks-zoom-2) { font-size: 120% !important; }
|
|
601
|
+
html:has(body.oks-zoom-3) { font-size: 135% !important; }
|
|
602
|
+
html:has(body.oks-zoom-4) { font-size: 150% !important; }
|
|
603
|
+
|
|
604
|
+
body.oks-lh-1 * { line-height: 1.6 !important; }
|
|
605
|
+
body.oks-lh-2 * { line-height: 1.9 !important; }
|
|
606
|
+
body.oks-lh-3 * { line-height: 2.2 !important; }
|
|
607
|
+
|
|
608
|
+
body.oks-a11y-font { font-family: Arial, sans-serif !important; }
|
|
609
|
+
|
|
610
|
+
body.oks-dyslexia * {
|
|
611
|
+
font-family: 'Comic Sans MS', 'Verdana', sans-serif !important;
|
|
612
|
+
letter-spacing: 0.05em !important;
|
|
613
|
+
word-spacing: 0.1em !important;
|
|
614
|
+
line-height: 1.6 !important;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
body.oks-a11y-hide img { opacity: 0 !important; visibility: hidden !important; }
|
|
618
|
+
body.oks-a11y-links a { text-decoration: underline !important; background: #ff0 !important; color: #000 !important; }
|
|
619
|
+
|
|
620
|
+
body.oks-align-1 * { text-align: left !important; }
|
|
621
|
+
body.oks-align-2 * { text-align: center !important; }
|
|
622
|
+
body.oks-align-3 * { text-align: right !important; }
|
|
623
|
+
|
|
624
|
+
body.oks-a11y-pause * { animation: none !important; transition: none !important; }
|
|
625
|
+
|
|
626
|
+
body.oks-ls-1 * { letter-spacing: 0.05em !important; }
|
|
627
|
+
body.oks-ls-2 * { letter-spacing: 0.10em !important; }
|
|
628
|
+
body.oks-ls-3 * { letter-spacing: 0.16em !important; }
|
|
629
|
+
|
|
630
|
+
body.oks-a11y-focus a:not(oksigenia-access-panel):not(oksigenia-access-panel *),
|
|
631
|
+
body.oks-a11y-focus button:not(oksigenia-access-panel):not(oksigenia-access-panel *),
|
|
632
|
+
body.oks-a11y-focus input,
|
|
633
|
+
body.oks-a11y-focus select,
|
|
634
|
+
body.oks-a11y-focus textarea {
|
|
635
|
+
outline: 2px dashed rgba(0, 95, 204, 0.45) !important;
|
|
636
|
+
outline-offset: 2px !important;
|
|
637
|
+
}
|
|
638
|
+
body.oks-a11y-focus *:focus-visible {
|
|
639
|
+
outline: 3px solid #005fcc !important;
|
|
640
|
+
outline-offset: 3px !important;
|
|
641
|
+
box-shadow: 0 0 0 6px rgba(0, 95, 204, 0.25) !important;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
body.oks-a11y-contrast.oks-a11y-focus *:focus,
|
|
645
|
+
body.oks-a11y-contrast.oks-a11y-focus *:focus-visible {
|
|
646
|
+
outline-color: #0ff !important;
|
|
647
|
+
box-shadow: 0 0 0 6px rgba(0, 255, 255, 0.3) !important;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
@media (pointer: fine) {
|
|
651
|
+
body.oks-big-cursor, body.oks-big-cursor a, body.oks-big-cursor button {
|
|
652
|
+
cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 24 24'%3E%3Cpath d='M4 2L4 18L8 14L11 21L14 19.5L11 13L15.5 13Z' stroke='white' stroke-width='4' stroke-linejoin='round' fill='white'/%3E%3Cpath d='M4 2L4 18L8 14L11 21L14 19.5L11 13L15.5 13Z' fill='black'/%3E%3C/svg%3E") 8 4, auto !important;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
body.oks-a11y-contrast,
|
|
657
|
+
body.oks-a11y-contrast *:not(oksigenia-access-panel):not(oksigenia-access-panel *) {
|
|
658
|
+
background-color: #000 !important;
|
|
659
|
+
color: #ff0 !important;
|
|
660
|
+
border-color: #ff0 !important;
|
|
661
|
+
text-shadow: none !important;
|
|
662
|
+
box-shadow: none !important;
|
|
663
|
+
}
|
|
664
|
+
body.oks-a11y-contrast img { filter: grayscale(100%) contrast(120%) !important; }
|
|
665
|
+
body.oks-a11y-contrast a:not(oksigenia-access-panel *) { color: #0ff !important; text-decoration: underline !important; }
|
|
666
|
+
|
|
667
|
+
/* High-contrast applies background:#000 to every descendant of body to flip
|
|
668
|
+
the page to inverted colours. That selector also catches our own overlays
|
|
669
|
+
(.oks-reading-guide, .oks-overlay-effect), which would then paint a solid
|
|
670
|
+
black band on top of the text and defeat their purpose. Restore the
|
|
671
|
+
overlay-specific values here so they keep working in high-contrast mode. */
|
|
672
|
+
body.oks-a11y-contrast .oks-reading-guide {
|
|
673
|
+
background-color: rgba(255, 255, 0, 0.25) !important;
|
|
674
|
+
border-top-color: #ff0 !important;
|
|
675
|
+
border-bottom-color: #ff0 !important;
|
|
676
|
+
}
|
|
677
|
+
body.oks-a11y-contrast .oks-overlay-effect {
|
|
678
|
+
background-color: transparent !important;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
.oks-overlay-effect {
|
|
682
|
+
position: fixed; top: 0; left: 0;
|
|
683
|
+
width: 100%; height: 100%;
|
|
684
|
+
pointer-events: none;
|
|
685
|
+
z-index: 999990;
|
|
686
|
+
display: none;
|
|
687
|
+
backdrop-filter: grayscale(100%);
|
|
688
|
+
}
|
|
689
|
+
.oks-overlay-effect.is-active { display: block; }
|
|
690
|
+
|
|
691
|
+
.oks-reading-guide {
|
|
692
|
+
position: fixed; left: 0;
|
|
693
|
+
width: 100%; height: 50px;
|
|
694
|
+
background: rgba(255, 255, 0, 0.2);
|
|
695
|
+
border-top: 3px solid red;
|
|
696
|
+
border-bottom: 3px solid red;
|
|
697
|
+
pointer-events: none;
|
|
698
|
+
z-index: 2147483647;
|
|
699
|
+
display: none;
|
|
700
|
+
transform: translateY(-50%);
|
|
701
|
+
}
|
|
702
|
+
body.oks-a11y-guide .oks-reading-guide { display: block; }
|
|
703
|
+
`;
|
|
704
|
+
|
|
705
|
+
export { COLORBLIND_FILTERS_SVG, DEFAULT_STATE, EFFECT_CSS, PANEL_CSS, bindPanelBehavior, buildPanelHtml, getTranslation, isStateEmpty, loadState, positionCss, saveState, supportedLocales };
|
|
706
|
+
//# sourceMappingURL=index.js.map
|
|
707
|
+
//# sourceMappingURL=index.js.map
|