188 lines
8.1 KiB
JavaScript
188 lines
8.1 KiB
JavaScript
'use client';
|
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
import { useState } from 'react';
|
|
import { useAccessibility } from './AccessibilityProvider.js';
|
|
const DEFAULT_TEXTS = {
|
|
bigCursor: 'Duży kursor',
|
|
close: 'Zamknij',
|
|
contrast: 'Kontrast',
|
|
contrastHigh: 'Wysoki',
|
|
contrastInverted: 'Odwrócony',
|
|
grayscale: 'Skala szarości',
|
|
lineHeight: 'Odstęp między liniami',
|
|
open: 'Otwórz panel dostępności',
|
|
readableFont: 'Czytelna czcionka',
|
|
reduceMotion: 'Wyłącz animacje',
|
|
reset: 'Resetuj',
|
|
textSize: 'Rozmiar tekstu',
|
|
title: 'Dostępność',
|
|
underlineLinks: 'Podkreśl linki'
|
|
};
|
|
/**
|
|
* Accessibility toolbar: a floating button that opens a panel of options (text
|
|
* size, line height, contrast, grayscale, underline links, readable font, reduce
|
|
* motion, big cursor). Choices persist in a cookie and apply as data-attributes
|
|
* on <html> (the project's CSS styles them).
|
|
*
|
|
* Unstyled by default — pass classNames to match the project's design (like
|
|
* CookieBanner). Wrap the app in <AccessibilityProvider> first.
|
|
*
|
|
* <AccessibilityWidget classNames={{ button: 'a11y-btn', panel: 'a11y-panel' }} />
|
|
*/ export function AccessibilityWidget({ classNames, texts }) {
|
|
const { reset, set, state } = useAccessibility();
|
|
const [open, setOpen] = useState(false);
|
|
const t = {
|
|
...DEFAULT_TEXTS,
|
|
...texts
|
|
};
|
|
const cn = classNames ?? {};
|
|
const toggle = (key)=>set(key, !state[key]);
|
|
const isActive = (on)=>on ? cn.active ?? '' : '';
|
|
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
children: [
|
|
/*#__PURE__*/ _jsx("button", {
|
|
"aria-expanded": open,
|
|
"aria-label": t.open,
|
|
className: cn.button,
|
|
onClick: ()=>setOpen((o)=>!o),
|
|
type: "button",
|
|
children: /*#__PURE__*/ _jsx("span", {
|
|
"aria-hidden": "true",
|
|
children: "♿"
|
|
})
|
|
}),
|
|
open && /*#__PURE__*/ _jsxs("div", {
|
|
"aria-label": t.title,
|
|
className: cn.panel,
|
|
role: "dialog",
|
|
children: [
|
|
/*#__PURE__*/ _jsxs("div", {
|
|
className: cn.row,
|
|
children: [
|
|
/*#__PURE__*/ _jsx("span", {
|
|
className: cn.label,
|
|
children: t.textSize
|
|
}),
|
|
/*#__PURE__*/ _jsx("div", {
|
|
className: cn.control,
|
|
children: [
|
|
0,
|
|
1,
|
|
2,
|
|
3
|
|
].map((n)=>/*#__PURE__*/ _jsxs("button", {
|
|
className: isActive(state.textSize === n),
|
|
onClick: ()=>set('textSize', n),
|
|
type: "button",
|
|
children: [
|
|
"A",
|
|
n > 0 ? '+'.repeat(n) : ''
|
|
]
|
|
}, n))
|
|
})
|
|
]
|
|
}),
|
|
/*#__PURE__*/ _jsxs("div", {
|
|
className: cn.row,
|
|
children: [
|
|
/*#__PURE__*/ _jsx("span", {
|
|
className: cn.label,
|
|
children: t.lineHeight
|
|
}),
|
|
/*#__PURE__*/ _jsx("div", {
|
|
className: cn.control,
|
|
children: [
|
|
0,
|
|
1,
|
|
2
|
|
].map((n)=>/*#__PURE__*/ _jsx("button", {
|
|
className: isActive(state.lineHeight === n),
|
|
onClick: ()=>set('lineHeight', n),
|
|
type: "button",
|
|
children: n === 0 ? '—' : '≡'.repeat(n)
|
|
}, n))
|
|
})
|
|
]
|
|
}),
|
|
/*#__PURE__*/ _jsxs("div", {
|
|
className: cn.row,
|
|
children: [
|
|
/*#__PURE__*/ _jsx("span", {
|
|
className: cn.label,
|
|
children: t.contrast
|
|
}),
|
|
/*#__PURE__*/ _jsxs("div", {
|
|
className: cn.control,
|
|
children: [
|
|
/*#__PURE__*/ _jsx("button", {
|
|
className: isActive(state.contrast === 'high'),
|
|
onClick: ()=>set('contrast', state.contrast === 'high' ? 'default' : 'high'),
|
|
type: "button",
|
|
children: t.contrastHigh
|
|
}),
|
|
/*#__PURE__*/ _jsx("button", {
|
|
className: isActive(state.contrast === 'inverted'),
|
|
onClick: ()=>set('contrast', state.contrast === 'inverted' ? 'default' : 'inverted'),
|
|
type: "button",
|
|
children: t.contrastInverted
|
|
})
|
|
]
|
|
})
|
|
]
|
|
}),
|
|
[
|
|
[
|
|
'grayscale',
|
|
t.grayscale
|
|
],
|
|
[
|
|
'underlineLinks',
|
|
t.underlineLinks
|
|
],
|
|
[
|
|
'readableFont',
|
|
t.readableFont
|
|
],
|
|
[
|
|
'reduceMotion',
|
|
t.reduceMotion
|
|
],
|
|
[
|
|
'bigCursor',
|
|
t.bigCursor
|
|
]
|
|
].map(([key, label])=>/*#__PURE__*/ _jsxs("div", {
|
|
className: cn.row,
|
|
children: [
|
|
/*#__PURE__*/ _jsx("span", {
|
|
className: cn.label,
|
|
children: label
|
|
}),
|
|
/*#__PURE__*/ _jsx("button", {
|
|
"aria-pressed": Boolean(state[key]),
|
|
className: `${cn.control ?? ''} ${isActive(Boolean(state[key]))}`,
|
|
onClick: ()=>toggle(key),
|
|
type: "button",
|
|
children: state[key] ? 'ON' : 'OFF'
|
|
})
|
|
]
|
|
}, key)),
|
|
/*#__PURE__*/ _jsx("button", {
|
|
className: cn.resetButton,
|
|
onClick: reset,
|
|
type: "button",
|
|
children: t.reset
|
|
}),
|
|
/*#__PURE__*/ _jsx("button", {
|
|
className: cn.closeButton,
|
|
onClick: ()=>setOpen(false),
|
|
type: "button",
|
|
children: t.close
|
|
})
|
|
]
|
|
})
|
|
]
|
|
});
|
|
}
|
|
|
|
//# sourceMappingURL=AccessibilityWidget.js.map
|