@lssm/lib.accessibility 0.0.0-canary-20251207012602 → 0.0.0-canary-20251207043720

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.
@@ -171,5 +171,4 @@ function AccessibilityPanel({ className }) {
171
171
  }
172
172
 
173
173
  //#endregion
174
- export { AccessibilityPanel };
175
- //# sourceMappingURL=AccessibilityPanel.js.map
174
+ export { AccessibilityPanel };
@@ -17,5 +17,4 @@ function AccessibilityProvider({ children, skipTargetId = "main" }) {
17
17
  }
18
18
 
19
19
  //#endregion
20
- export { AccessibilityProvider };
21
- //# sourceMappingURL=AccessibilityProvider.js.map
20
+ export { AccessibilityProvider };
File without changes
@@ -20,5 +20,4 @@ function NextRouteAnnouncer() {
20
20
  }
21
21
 
22
22
  //#endregion
23
- export { NextRouteAnnouncer };
24
- //# sourceMappingURL=next-route-announcer.js.map
23
+ export { NextRouteAnnouncer };
@@ -116,5 +116,4 @@ function a11yRootClassName() {
116
116
  }
117
117
 
118
118
  //#endregion
119
- export { A11YPreferencesProvider, a11yRootClassName, useA11YPreferences };
120
- //# sourceMappingURL=preferences.js.map
119
+ export { A11YPreferencesProvider, a11yRootClassName, useA11YPreferences };
@@ -70,5 +70,3 @@ body {
70
70
  line-height: var(--a11y-line-height, 1.5);
71
71
  }
72
72
 
73
-
74
- /*# sourceMappingURL=styles-C5GUMPoX.css.map*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lssm/lib.accessibility",
3
- "version": "0.0.0-canary-20251207012602",
3
+ "version": "0.0.0-canary-20251207043720",
4
4
  "scripts": {
5
5
  "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
6
6
  "build": "bun build:bundle && bun build:types",
@@ -36,11 +36,11 @@
36
36
  "./dist/*.css"
37
37
  ],
38
38
  "exports": {
39
- ".": "./dist/index.js",
40
- "./AccessibilityPanel": "./dist/AccessibilityPanel.js",
41
- "./AccessibilityProvider": "./dist/AccessibilityProvider.js",
42
- "./next-route-announcer": "./dist/next-route-announcer.js",
43
- "./preferences": "./dist/preferences.js",
39
+ ".": "./src/index.ts",
40
+ "./AccessibilityPanel": "./src/AccessibilityPanel.tsx",
41
+ "./AccessibilityProvider": "./src/AccessibilityProvider.tsx",
42
+ "./next-route-announcer": "./src/next-route-announcer.tsx",
43
+ "./preferences": "./src/preferences.tsx",
44
44
  "./*": "./*"
45
45
  },
46
46
  "files": [
@@ -48,6 +48,14 @@
48
48
  "README.md"
49
49
  ],
50
50
  "publishConfig": {
51
- "access": "public"
51
+ "access": "public",
52
+ "exports": {
53
+ ".": "./dist/index.js",
54
+ "./AccessibilityPanel": "./dist/AccessibilityPanel.js",
55
+ "./AccessibilityProvider": "./dist/AccessibilityProvider.js",
56
+ "./next-route-announcer": "./dist/next-route-announcer.js",
57
+ "./preferences": "./dist/preferences.js",
58
+ "./*": "./*"
59
+ }
52
60
  }
53
61
  }
@@ -1,11 +0,0 @@
1
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
-
3
- //#region src/AccessibilityPanel.d.ts
4
- declare function AccessibilityPanel({
5
- className
6
- }: {
7
- className?: string;
8
- }): react_jsx_runtime0.JSX.Element;
9
- //#endregion
10
- export { AccessibilityPanel };
11
- //# sourceMappingURL=AccessibilityPanel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AccessibilityPanel.d.ts","names":[],"sources":["../src/AccessibilityPanel.tsx"],"sourcesContent":[],"mappings":";;;iBAyBgB,kBAAA;;;;IAAwD,kBAAA,CAAA,GAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AccessibilityPanel.js","names":[],"sources":["../src/AccessibilityPanel.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from '@lssm/lib.ui-kit-web/ui/dialog';\nimport { Button } from '@lssm/lib.design-system';\nimport { Switch } from '@lssm/lib.ui-kit-web/ui/switch';\nimport { Label } from '@lssm/lib.ui-kit-web/ui/label';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@lssm/lib.ui-kit-web/ui/select';\nimport { useA11YPreferences } from './preferences';\nimport { cn } from '@lssm/lib.ui-kit-web/ui/utils';\n\nexport function AccessibilityPanel({ className }: { className?: string }) {\n const { preferences, setPreferences } = useA11YPreferences();\n\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant=\"outline\" aria-haspopup=\"dialog\">\n Accessibility\n </Button>\n </DialogTrigger>\n <DialogPortal>\n <DialogOverlay className=\"fixed inset-0 z-50 bg-black/40\" />\n <DialogContent\n className={cn(\n // 'fixed right-0 top-0 z-50 h-full w-full max-w-md bg-background p-6 shadow-lg outline-hidden focus-visible:ring-2 focus-visible:ring-ring',\n 'bg-background focus-visible:ring-ring max-w-md p-6 shadow-lg outline-hidden focus-visible:ring-2',\n className\n )}\n aria-describedby=\"a11y-panel-desc\"\n >\n <DialogTitle className=\"text-lg font-semibold\">\n Accessibility settings\n </DialogTitle>\n <p id=\"a11y-panel-desc\" className=\"text-muted-foreground text-sm\">\n Adjust text size, spacing, focus and motion to suit your needs.\n </p>\n\n <div className=\"mt-6 space-y-6\">\n <div className=\"space-y-2\">\n <Label>Text size</Label>\n <Select\n value={preferences.textSize}\n onValueChange={(v) => setPreferences({ textSize: v as any })}\n >\n <SelectTrigger aria-label=\"Text size\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"s\">Small</SelectItem>\n <SelectItem value=\"m\">Medium</SelectItem>\n <SelectItem value=\"l\">Large</SelectItem>\n <SelectItem value=\"xl\">Extra Large</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"text-spacing\">\n Increase text spacing (WCAG 1.4.12)\n </Label>\n <Switch\n id=\"text-spacing\"\n checked={preferences.textSpacing === 'increased'}\n onCheckedChange={(c) =>\n setPreferences({ textSpacing: c ? 'increased' : 'normal' })\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"line-height\">Increase line height</Label>\n <Switch\n id=\"line-height\"\n checked={preferences.lineHeight === 'increased'}\n onCheckedChange={(c) =>\n setPreferences({ lineHeight: c ? 'increased' : 'normal' })\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"underline-links\">Always underline links</Label>\n <Switch\n id=\"underline-links\"\n checked={preferences.underlineLinks}\n onCheckedChange={(c) => setPreferences({ underlineLinks: c })}\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"focus-ring\">Thick focus ring</Label>\n <Switch\n id=\"focus-ring\"\n checked={preferences.focusRing === 'thick'}\n onCheckedChange={(c) =>\n setPreferences({ focusRing: c ? 'thick' : 'normal' })\n }\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label>Motion</Label>\n <Select\n value={preferences.reduceMotion}\n onValueChange={(v) =>\n setPreferences({ reduceMotion: v as any })\n }\n >\n <SelectTrigger aria-label=\"Motion preferences\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"system\">Follow system</SelectItem>\n <SelectItem value=\"reduce\">Reduce motion</SelectItem>\n <SelectItem value=\"no-preference\">Allow motion</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"contrast\">High contrast</Label>\n <Switch\n id=\"contrast\"\n checked={preferences.highContrast}\n onCheckedChange={(c) => setPreferences({ highContrast: c })}\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <Label htmlFor=\"dyslexia-font\">Dyslexia-friendly font</Label>\n <Switch\n id=\"dyslexia-font\"\n checked={preferences.dyslexiaFont}\n onCheckedChange={(c) => setPreferences({ dyslexiaFont: c })}\n />\n </div>\n </div>\n\n <div className=\"mt-8 flex justify-end gap-2\">\n <DialogClose asChild>\n <Button variant=\"secondary\">Close</Button>\n </DialogClose>\n </div>\n </DialogContent>\n </DialogPortal>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAyBA,SAAgB,mBAAmB,EAAE,aAAqC;CACxE,MAAM,EAAE,aAAa,mBAAmB,oBAAoB;AAE5D,QACE,qBAAC,qBACC,oBAAC;EAAc;YACb,oBAAC;GAAO,SAAQ;GAAU,iBAAc;aAAS;IAExC;GACK,EAChB,qBAAC,2BACC,oBAAC,iBAAc,WAAU,mCAAmC,EAC5D,qBAAC;EACC,WAAW,GAET,oGACA,UACD;EACD,oBAAiB;;GAEjB,oBAAC;IAAY,WAAU;cAAwB;KAEjC;GACd,oBAAC;IAAE,IAAG;IAAkB,WAAU;cAAgC;KAE9D;GAEJ,qBAAC;IAAI,WAAU;;KACb,qBAAC;MAAI,WAAU;iBACb,oBAAC,mBAAM,cAAiB,EACxB,qBAAC;OACC,OAAO,YAAY;OACnB,gBAAgB,MAAM,eAAe,EAAE,UAAU,GAAU,CAAC;kBAE5D,oBAAC;QAAc,cAAW;kBACxB,oBAAC,gBAAc;SACD,EAChB,qBAAC;QACC,oBAAC;SAAW,OAAM;mBAAI;UAAkB;QACxC,oBAAC;SAAW,OAAM;mBAAI;UAAmB;QACzC,oBAAC;SAAW,OAAM;mBAAI;UAAkB;QACxC,oBAAC;SAAW,OAAM;mBAAK;UAAwB;WACjC;QACT;OACL;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAe;QAEtB,EACR,oBAAC;OACC,IAAG;OACH,SAAS,YAAY,gBAAgB;OACrC,kBAAkB,MAChB,eAAe,EAAE,aAAa,IAAI,cAAc,UAAU,CAAC;QAE7D;OACE;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAc;QAA4B,EACzD,oBAAC;OACC,IAAG;OACH,SAAS,YAAY,eAAe;OACpC,kBAAkB,MAChB,eAAe,EAAE,YAAY,IAAI,cAAc,UAAU,CAAC;QAE5D;OACE;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAkB;QAA8B,EAC/D,oBAAC;OACC,IAAG;OACH,SAAS,YAAY;OACrB,kBAAkB,MAAM,eAAe,EAAE,gBAAgB,GAAG,CAAC;QAC7D;OACE;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAa;QAAwB,EACpD,oBAAC;OACC,IAAG;OACH,SAAS,YAAY,cAAc;OACnC,kBAAkB,MAChB,eAAe,EAAE,WAAW,IAAI,UAAU,UAAU,CAAC;QAEvD;OACE;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC,mBAAM,WAAc,EACrB,qBAAC;OACC,OAAO,YAAY;OACnB,gBAAgB,MACd,eAAe,EAAE,cAAc,GAAU,CAAC;kBAG5C,oBAAC;QAAc,cAAW;kBACxB,oBAAC,gBAAc;SACD,EAChB,qBAAC;QACC,oBAAC;SAAW,OAAM;mBAAS;UAA0B;QACrD,oBAAC;SAAW,OAAM;mBAAS;UAA0B;QACrD,oBAAC;SAAW,OAAM;mBAAgB;UAAyB;WAC7C;QACT;OACL;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAW;QAAqB,EAC/C,oBAAC;OACC,IAAG;OACH,SAAS,YAAY;OACrB,kBAAkB,MAAM,eAAe,EAAE,cAAc,GAAG,CAAC;QAC3D;OACE;KAEN,qBAAC;MAAI,WAAU;iBACb,oBAAC;OAAM,SAAQ;iBAAgB;QAA8B,EAC7D,oBAAC;OACC,IAAG;OACH,SAAS,YAAY;OACrB,kBAAkB,MAAM,eAAe,EAAE,cAAc,GAAG,CAAC;QAC3D;OACE;;KACF;GAEN,oBAAC;IAAI,WAAU;cACb,oBAAC;KAAY;eACX,oBAAC;MAAO,SAAQ;gBAAY;OAAc;MAC9B;KACV;;GACQ,IACH,IACR"}
@@ -1,14 +0,0 @@
1
- import * as React$1 from "react";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
3
-
4
- //#region src/AccessibilityProvider.d.ts
5
- declare function AccessibilityProvider({
6
- children,
7
- skipTargetId
8
- }: {
9
- children: React$1.ReactNode;
10
- skipTargetId?: string;
11
- }): react_jsx_runtime0.JSX.Element;
12
- //#endregion
13
- export { AccessibilityProvider };
14
- //# sourceMappingURL=AccessibilityProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AccessibilityProvider.d.ts","names":[],"sources":["../src/AccessibilityProvider.tsx"],"sourcesContent":[],"mappings":";;;;iBAQgB,qBAAA;;;AAAhB;YAIY,OAAA,CAAM;;AAJlB,CAAA,CAAA,EAMC,kBAAA,CAAA,GAAA,CAAA,OANoC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AccessibilityProvider.js","names":[],"sources":["../src/AccessibilityProvider.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { A11YPreferencesProvider } from './preferences';\nimport { SRLiveRegionProvider } from '@lssm/lib.ui-kit-web/ui/live-region';\nimport { NextRouteAnnouncer } from './next-route-announcer';\nimport { SkipLink } from '@lssm/lib.ui-kit-web/ui/skip-link';\n\nexport function AccessibilityProvider({\n children,\n skipTargetId = 'main',\n}: {\n children: React.ReactNode;\n skipTargetId?: string;\n}) {\n return (\n <A11YPreferencesProvider>\n <SRLiveRegionProvider>\n <SkipLink targetId={skipTargetId} />\n <NextRouteAnnouncer />\n {children}\n </SRLiveRegionProvider>\n </A11YPreferencesProvider>\n );\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,sBAAsB,EACpC,UACA,eAAe,UAId;AACD,QACE,oBAAC,qCACC,qBAAC;EACC,oBAAC,YAAS,UAAU,eAAgB;EACpC,oBAAC,uBAAqB;EACrB;KACoB,GACC"}
package/dist/index.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { AccessibilityPanel } from "./AccessibilityPanel.js";
2
- import { AccessibilityProvider } from "./AccessibilityProvider.js";
3
- import { A11YPreferencesProvider, AccessibilityPreferences, useA11YPreferences } from "./preferences.js";
4
- import { NextRouteAnnouncer } from "./next-route-announcer.js";
5
- import { SRLiveRegionProvider, useSRLiveRegion } from "@lssm/lib.ui-kit-web/ui/live-region";
6
- import { SkipLink } from "@lssm/lib.ui-kit-web/ui/skip-link";
7
- import { VisuallyHidden } from "@lssm/lib.ui-kit-web/ui/visually-hidden";
8
- import { RouteAnnouncer } from "@lssm/lib.ui-kit-web/ui/route-announcer";
9
- import { FocusOnRouteChange } from "@lssm/lib.ui-kit-web/ui/focus-on-route-change";
10
- import { useReducedMotion } from "@lssm/lib.ui-kit-web/ui/use-reduced-motion";
11
- export { A11YPreferencesProvider, AccessibilityPanel, type AccessibilityPreferences, AccessibilityProvider, FocusOnRouteChange, NextRouteAnnouncer, RouteAnnouncer, SRLiveRegionProvider, SkipLink, VisuallyHidden, useA11YPreferences, useReducedMotion, useSRLiveRegion };
@@ -1 +0,0 @@
1
- export { };
@@ -1,7 +0,0 @@
1
- import * as react_jsx_runtime1 from "react/jsx-runtime";
2
-
3
- //#region src/next-route-announcer.d.ts
4
- declare function NextRouteAnnouncer(): react_jsx_runtime1.JSX.Element;
5
- //#endregion
6
- export { NextRouteAnnouncer };
7
- //# sourceMappingURL=next-route-announcer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"next-route-announcer.d.ts","names":[],"sources":["../src/next-route-announcer.tsx"],"sourcesContent":[],"mappings":";;;iBAIgB,kBAAA,CAAA,GAAkB,kBAAA,CAAA,GAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"next-route-announcer.js","names":["React"],"sources":["../src/next-route-announcer.tsx"],"sourcesContent":["'use client';\nimport * as React from 'react';\nimport { usePathname } from 'next/navigation';\n\nexport function NextRouteAnnouncer() {\n const pathname = usePathname();\n const [message, setMessage] = React.useState('');\n\n React.useEffect(() => {\n // announce current document title whenever pathname changes\n if (typeof document !== 'undefined') {\n setMessage(document.title || pathname || '');\n }\n }, [pathname]);\n\n return (\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\">\n {message}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAIA,SAAgB,qBAAqB;CACnC,MAAM,WAAW,aAAa;CAC9B,MAAM,CAAC,SAAS,cAAcA,QAAM,SAAS,GAAG;AAEhD,SAAM,gBAAgB;AAEpB,MAAI,OAAO,aAAa,YACtB,YAAW,SAAS,SAAS,YAAY,GAAG;IAE7C,CAAC,SAAS,CAAC;AAEd,QACE,oBAAC;EAAI,aAAU;EAAS,eAAY;EAAO,WAAU;YAClD;GACG"}
@@ -1,36 +0,0 @@
1
- import React from "react";
2
- import * as react_jsx_runtime2 from "react/jsx-runtime";
3
-
4
- //#region src/preferences.d.ts
5
- type TextSize = 's' | 'm' | 'l' | 'xl';
6
- type TextSpacing = 'normal' | 'increased';
7
- type LineHeight = 'normal' | 'increased';
8
- type UnderlineLinks = boolean;
9
- type FocusRing = 'normal' | 'thick';
10
- type ReduceMotion = 'system' | 'reduce' | 'no-preference';
11
- type HighContrast = boolean;
12
- type DyslexiaFont = boolean;
13
- interface AccessibilityPreferences {
14
- textSize: TextSize;
15
- textSpacing: TextSpacing;
16
- lineHeight: LineHeight;
17
- underlineLinks: UnderlineLinks;
18
- focusRing: FocusRing;
19
- reduceMotion: ReduceMotion;
20
- highContrast: HighContrast;
21
- dyslexiaFont: DyslexiaFont;
22
- }
23
- interface PreferencesContextValue {
24
- preferences: AccessibilityPreferences;
25
- setPreferences: (updater: Partial<AccessibilityPreferences> | ((p: AccessibilityPreferences) => AccessibilityPreferences)) => void;
26
- }
27
- declare function useA11YPreferences(): PreferencesContextValue;
28
- declare function A11YPreferencesProvider({
29
- children
30
- }: {
31
- children: React.ReactNode;
32
- }): react_jsx_runtime2.JSX.Element;
33
- declare function a11yRootClassName(): string;
34
- //#endregion
35
- export { A11YPreferencesProvider, AccessibilityPreferences, DyslexiaFont, FocusRing, HighContrast, LineHeight, ReduceMotion, TextSize, TextSpacing, UnderlineLinks, a11yRootClassName, useA11YPreferences };
36
- //# sourceMappingURL=preferences.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preferences.d.ts","names":[],"sources":["../src/preferences.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,QAAA;KACA,WAAA;KACA,UAAA;AAFA,KAGA,cAAA,GAHQ,OAAA;AACR,KAGA,SAAA,GAHW,QAAA,GAAA,OAAA;AACX,KAGA,YAAA,GAHU,QAAA,GAAA,QAAA,GAAA,eAAA;AACV,KAGA,YAAA,GAHc,OAAA;AACd,KAGA,YAAA,GAHS,OAAA;AACT,UAIK,wBAAA,CAJO;EACZ,QAAA,EAIA,QAJY;EACZ,WAAA,EAIG,WAJS;EAEP,UAAA,EAGH,UAHG;EACL,cAAA,EAGM,cAHN;EACG,SAAA,EAGF,SAHE;EACD,YAAA,EAGE,YAHF;EACI,YAAA,EAGF,YAHE;EACL,YAAA,EAGG,YAHH;;UA0HH,uBAAA,CAxHM;EACA,WAAA,EAwHD,wBAxHC;EAAY,cAAA,EAAA,CAAA,OAAA,EA2HpB,OA3HoB,CA2HZ,wBA3HY,CAAA,GAAA,CAAA,CAAA,CAAA,EA4Hf,wBA5He,EAAA,GA4Hc,wBA5Hd,CAAA,EAAA,GAAA,IAAA;AAC3B;AAuHc,iBAYC,kBAAA,CAAA,CAZD,EAYmB,uBAZnB;AAGC,iBAkBA,uBAAA,CAlBA;EAAA;CAAA,EAAA;EAAR,QAAA,EAqBI,KAAA,CAAM,SArBV;CACK,CAAA,EAqBZ,kBAAA,CAAA,GAAA,CAAA,OArBY;AAA6B,iBAiF1B,iBAAA,CAAA,CAjF0B,EAAA,MAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"preferences.js","names":["DEFAULT_PREFERENCES: AccessibilityPreferences","changed: Partial<AccessibilityPreferences>"],"sources":["../src/preferences.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nexport type TextSize = 's' | 'm' | 'l' | 'xl';\nexport type TextSpacing = 'normal' | 'increased';\nexport type LineHeight = 'normal' | 'increased';\nexport type UnderlineLinks = boolean;\nexport type FocusRing = 'normal' | 'thick';\nexport type ReduceMotion = 'system' | 'reduce' | 'no-preference';\nexport type HighContrast = boolean;\nexport type DyslexiaFont = boolean;\n\nexport interface AccessibilityPreferences {\n textSize: TextSize;\n textSpacing: TextSpacing;\n lineHeight: LineHeight;\n underlineLinks: UnderlineLinks;\n focusRing: FocusRing;\n reduceMotion: ReduceMotion;\n highContrast: HighContrast;\n dyslexiaFont: DyslexiaFont;\n}\n\nconst DEFAULT_PREFERENCES: AccessibilityPreferences = {\n textSize: 'm',\n textSpacing: 'normal',\n lineHeight: 'normal',\n underlineLinks: false,\n focusRing: 'normal',\n reduceMotion: 'system',\n highContrast: false,\n dyslexiaFont: false,\n};\n\nconst STORAGE_KEY = 'a11y:preferences:v1';\n\nfunction getStoredPreferences(): AccessibilityPreferences | null {\n try {\n const raw =\n typeof window !== 'undefined'\n ? window.localStorage.getItem(STORAGE_KEY)\n : null;\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n return { ...DEFAULT_PREFERENCES, ...parsed } as AccessibilityPreferences;\n } catch {\n return null;\n }\n}\n\nfunction savePreferences(prefs: AccessibilityPreferences) {\n try {\n if (typeof window !== 'undefined') {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));\n }\n } catch {\n // ignore\n }\n}\n\nfunction applyCssVariables(prefs: AccessibilityPreferences) {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n const body = document.body;\n // Type scale (base multiplier)\n const sizeMap: Record<TextSize, string> = {\n s: '0.95',\n m: '1',\n l: '1.1',\n xl: '1.25',\n };\n root.style.setProperty('--a11y-text-scale', sizeMap[prefs.textSize]);\n // Target size: increase on larger text choices\n const targetMin =\n prefs.textSize === 'l' || prefs.textSize === 'xl' ? '44px' : '0px';\n root.style.setProperty('--a11y-target-min', targetMin);\n\n // Spacing per WCAG 1.4.12\n root.style.setProperty(\n '--a11y-letter-spacing',\n prefs.textSpacing === 'increased' ? '0.12em' : 'normal'\n );\n root.style.setProperty(\n '--a11y-word-spacing',\n prefs.textSpacing === 'increased' ? '0.16em' : 'normal'\n );\n root.style.setProperty(\n '--a11y-line-height',\n prefs.lineHeight === 'increased' ? '1.6' : '1.5'\n );\n\n // Links\n root.style.setProperty(\n '--a11y-underline-links',\n // Use 'revert' so we don't override the site's default when disabled\n prefs.underlineLinks ? 'underline' : 'revert'\n );\n\n // Focus ring\n root.style.setProperty(\n '--a11y-focus-ring-width',\n prefs.focusRing === 'thick' ? '4px' : '2px'\n );\n\n // Reduce motion\n root.style.setProperty('--a11y-reduce-motion', prefs.reduceMotion);\n\n // Contrast\n root.style.setProperty(\n '--a11y-contrast-mode',\n prefs.highContrast ? 'high' : 'normal'\n );\n if (prefs.highContrast) {\n root.setAttribute('data-contrast', 'high');\n } else {\n root.removeAttribute('data-contrast');\n }\n\n // Dyslexia-friendly font (consumer should map to an available font family)\n root.style.setProperty(\n '--a11y-font-family-alt-enabled',\n prefs.dyslexiaFont ? '1' : '0'\n );\n\n // Inline fallbacks in case global CSS variables are not wired/included by the app bundler.\n // These properties are inheritable, so setting them on <body> yields broad coverage.\n if (body) {\n if (prefs.textSpacing === 'increased') {\n body.style.letterSpacing = '0.12em';\n body.style.wordSpacing = '0.16em';\n } else {\n body.style.letterSpacing = '';\n body.style.wordSpacing = '';\n }\n\n body.style.lineHeight = prefs.lineHeight === 'increased' ? '1.6' : '';\n }\n}\n\ninterface PreferencesContextValue {\n preferences: AccessibilityPreferences;\n setPreferences: (\n updater:\n | Partial<AccessibilityPreferences>\n | ((p: AccessibilityPreferences) => AccessibilityPreferences)\n ) => void;\n}\n\nconst PreferencesContext = React.createContext<PreferencesContextValue | null>(\n null\n);\n\nexport function useA11YPreferences() {\n const ctx = React.useContext(PreferencesContext);\n if (!ctx)\n throw new Error(\n 'useA11YPreferences must be used within A11YPreferencesProvider'\n );\n return ctx;\n}\n\nexport function A11YPreferencesProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const [preferences, setPreferencesState] =\n React.useState<AccessibilityPreferences>(DEFAULT_PREFERENCES);\n const [hydrated, setHydrated] = React.useState(false);\n\n React.useEffect(() => {\n const stored = getStoredPreferences();\n const next = stored ?? DEFAULT_PREFERENCES;\n setPreferencesState(next);\n setHydrated(true);\n applyCssVariables(next);\n }, []);\n\n const setPreferences = React.useCallback<\n PreferencesContextValue['setPreferences']\n >((updater) => {\n setPreferencesState((prev) => {\n const next =\n typeof updater === 'function' ? updater(prev) : { ...prev, ...updater };\n savePreferences(next);\n applyCssVariables(next);\n try {\n if (typeof window !== 'undefined') {\n const changed: Partial<AccessibilityPreferences> = {};\n for (const key of Object.keys(\n next\n ) as (keyof AccessibilityPreferences)[]) {\n if (next[key] !== prev[key]) {\n changed[key] = next[key] as any;\n }\n }\n window.dispatchEvent(\n new CustomEvent('a11y:pref_changed', {\n detail: {\n previous: prev,\n current: next,\n changed,\n },\n })\n );\n }\n } catch {}\n return next;\n });\n }, []);\n\n const value = React.useMemo(\n () => ({ preferences, setPreferences }),\n [preferences, setPreferences]\n );\n\n return (\n <PreferencesContext value={value}>\n {children}\n {!hydrated ? null : null}\n </PreferencesContext>\n );\n}\n\n// Helper to compute className additions that respect tokens (optional)\nexport function a11yRootClassName() {\n return 'a11y-root';\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"styles-C5GUMPoX.css","names":[],"sources":["../src/styles.css"],"sourcesContent":[":root {\n --a11y-text-scale: 1;\n --a11y-letter-spacing: normal;\n --a11y-word-spacing: normal;\n --a11y-line-height: 1.5;\n --a11y-underline-links: auto;\n --a11y-focus-ring-width: 2px;\n --a11y-reduce-motion: system;\n --a11y-contrast-mode: normal;\n --a11y-font-family-alt-enabled: 0;\n}\n\nhtml,\nbody {\n font-size: calc(16px * var(--a11y-text-scale));\n}\n\nbody,\np,\nli {\n letter-spacing: var(--a11y-letter-spacing);\n word-spacing: var(--a11y-word-spacing);\n line-height: var(--a11y-line-height);\n}\n\na {\n text-decoration: var(--a11y-underline-links);\n}\n\n:where(button, [role='button'], a, input, select, textarea) {\n outline-offset: 2px;\n min-height: var(--a11y-target-min, 0);\n min-width: var(--a11y-target-min, 0);\n}\n\n:where(:focus-visible) {\n outline: var(--a11y-focus-ring-width) solid currentColor;\n}\n\n/* High contrast mode surface example tokens (apps should map their colors) */\n:root[data-contrast='high'],\n:root[style*='--a11y-contrast-mode: high'] {\n /* Apps can read this signal to swap theme */\n}\n\n/* Dyslexia-friendly font: consumers should apply a font-family when enabled */\n:root[style*='--a11y-font-family-alt-enabled: 1'] body {\n font-family: var(--font-dyslexia, system-ui, sans-serif);\n}\n\n/* Respect reduced motion preference and explicit override */\n@media (prefers-reduced-motion: reduce) {\n :root[style*='--a11y-reduce-motion: system'] * {\n animation: none !important;\n transition: none !important;\n scroll-behavior: auto !important;\n }\n}\n:root[style*='--a11y-reduce-motion: reduce'] * {\n animation: none !important;\n transition: none !important;\n scroll-behavior: auto !important;\n}\n\n/* Explicit fallbacks for environments not honoring custom properties thoroughly */\nbody {\n /* If variables are missing, ensure readable defaults */\n letter-spacing: var(--a11y-letter-spacing, normal);\n word-spacing: var(--a11y-word-spacing, normal);\n line-height: var(--a11y-line-height, 1.5);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA"}