accented 0.0.0-20250424114613 → 0.0.0-20250618181418

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.
Files changed (201) hide show
  1. package/README.md +0 -209
  2. package/dist/accented.d.ts +2 -2
  3. package/dist/accented.d.ts.map +1 -1
  4. package/dist/accented.js +24 -20
  5. package/dist/accented.js.map +1 -1
  6. package/dist/common/tokens.d.ts +2 -0
  7. package/dist/common/tokens.d.ts.map +1 -0
  8. package/dist/common/tokens.js +2 -0
  9. package/dist/common/tokens.js.map +1 -0
  10. package/dist/dom-updater.d.ts +1 -1
  11. package/dist/dom-updater.d.ts.map +1 -1
  12. package/dist/dom-updater.js +14 -13
  13. package/dist/dom-updater.js.map +1 -1
  14. package/dist/elements/accented-dialog.d.ts +2 -3
  15. package/dist/elements/accented-dialog.d.ts.map +1 -1
  16. package/dist/elements/accented-dialog.js +14 -8
  17. package/dist/elements/accented-dialog.js.map +1 -1
  18. package/dist/elements/accented-trigger.d.ts +3 -4
  19. package/dist/elements/accented-trigger.d.ts.map +1 -1
  20. package/dist/elements/accented-trigger.js +8 -10
  21. package/dist/elements/accented-trigger.js.map +1 -1
  22. package/dist/fullscreen-listener.d.ts +1 -1
  23. package/dist/fullscreen-listener.d.ts.map +1 -1
  24. package/dist/fullscreen-listener.js +3 -4
  25. package/dist/fullscreen-listener.js.map +1 -1
  26. package/dist/intersection-observer.d.ts +1 -1
  27. package/dist/intersection-observer.d.ts.map +1 -1
  28. package/dist/intersection-observer.js +12 -6
  29. package/dist/intersection-observer.js.map +1 -1
  30. package/dist/log-and-rethrow.d.ts +1 -1
  31. package/dist/log-and-rethrow.d.ts.map +1 -1
  32. package/dist/log-and-rethrow.js +2 -3
  33. package/dist/log-and-rethrow.js.map +1 -1
  34. package/dist/logger.d.ts +1 -1
  35. package/dist/logger.d.ts.map +1 -1
  36. package/dist/logger.js +2 -2
  37. package/dist/logger.js.map +1 -1
  38. package/dist/register-elements.d.ts +1 -1
  39. package/dist/register-elements.d.ts.map +1 -1
  40. package/dist/register-elements.js +6 -7
  41. package/dist/register-elements.js.map +1 -1
  42. package/dist/resize-listener.d.ts +1 -1
  43. package/dist/resize-listener.d.ts.map +1 -1
  44. package/dist/resize-listener.js +3 -4
  45. package/dist/resize-listener.js.map +1 -1
  46. package/dist/scanner.d.ts +2 -2
  47. package/dist/scanner.d.ts.map +1 -1
  48. package/dist/scanner.js +25 -27
  49. package/dist/scanner.js.map +1 -1
  50. package/dist/scroll-listeners.d.ts +1 -1
  51. package/dist/scroll-listeners.d.ts.map +1 -1
  52. package/dist/scroll-listeners.js +3 -4
  53. package/dist/scroll-listeners.js.map +1 -1
  54. package/dist/state.d.ts +1 -1
  55. package/dist/state.d.ts.map +1 -1
  56. package/dist/state.js +4 -5
  57. package/dist/state.js.map +1 -1
  58. package/dist/task-queue.d.ts +2 -2
  59. package/dist/task-queue.d.ts.map +1 -1
  60. package/dist/task-queue.js +1 -1
  61. package/dist/task-queue.js.map +1 -1
  62. package/dist/types.d.ts +3 -3
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/utils/are-elements-with-issues-equal.d.ts +2 -2
  65. package/dist/utils/are-elements-with-issues-equal.d.ts.map +1 -1
  66. package/dist/utils/are-elements-with-issues-equal.js +3 -3
  67. package/dist/utils/are-elements-with-issues-equal.js.map +1 -1
  68. package/dist/utils/are-issue-sets-equal.d.ts +2 -2
  69. package/dist/utils/are-issue-sets-equal.d.ts.map +1 -1
  70. package/dist/utils/are-issue-sets-equal.js +3 -3
  71. package/dist/utils/are-issue-sets-equal.js.map +1 -1
  72. package/dist/utils/containing-blocks.d.ts.map +1 -1
  73. package/dist/utils/containing-blocks.js +1 -1
  74. package/dist/utils/containing-blocks.js.map +1 -1
  75. package/dist/utils/contains.d.ts +1 -1
  76. package/dist/utils/contains.d.ts.map +1 -1
  77. package/dist/utils/contains.js +1 -1
  78. package/dist/utils/contains.js.map +1 -1
  79. package/dist/utils/deduplicate-nodes.js +0 -1
  80. package/dist/utils/deduplicate-nodes.js.map +1 -1
  81. package/dist/utils/deep-merge.d.ts +1 -1
  82. package/dist/utils/deep-merge.d.ts.map +1 -1
  83. package/dist/utils/deep-merge.js +6 -5
  84. package/dist/utils/deep-merge.js.map +1 -1
  85. package/dist/utils/dom-helpers.d.ts.map +1 -1
  86. package/dist/utils/dom-helpers.js +4 -2
  87. package/dist/utils/dom-helpers.js.map +1 -1
  88. package/dist/utils/ensure-non-empty.d.ts +1 -1
  89. package/dist/utils/ensure-non-empty.d.ts.map +1 -1
  90. package/dist/utils/ensure-non-empty.js +2 -2
  91. package/dist/utils/ensure-non-empty.js.map +1 -1
  92. package/dist/utils/get-element-html.d.ts +1 -1
  93. package/dist/utils/get-element-html.d.ts.map +1 -1
  94. package/dist/utils/get-element-html.js +4 -2
  95. package/dist/utils/get-element-html.js.map +1 -1
  96. package/dist/utils/get-element-position.d.ts +2 -2
  97. package/dist/utils/get-element-position.d.ts.map +1 -1
  98. package/dist/utils/get-element-position.js +21 -25
  99. package/dist/utils/get-element-position.js.map +1 -1
  100. package/dist/utils/get-parent.d.ts +1 -1
  101. package/dist/utils/get-parent.d.ts.map +1 -1
  102. package/dist/utils/get-parent.js +1 -1
  103. package/dist/utils/get-parent.js.map +1 -1
  104. package/dist/utils/get-scan-context.d.ts +2 -2
  105. package/dist/utils/get-scan-context.d.ts.map +1 -1
  106. package/dist/utils/get-scan-context.js +9 -9
  107. package/dist/utils/get-scan-context.js.map +1 -1
  108. package/dist/utils/get-scrollable-ancestors.d.ts +1 -1
  109. package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -1
  110. package/dist/utils/get-scrollable-ancestors.js +5 -5
  111. package/dist/utils/get-scrollable-ancestors.js.map +1 -1
  112. package/dist/utils/is-node-in-scan-context.d.ts +2 -2
  113. package/dist/utils/is-node-in-scan-context.d.ts.map +1 -1
  114. package/dist/utils/is-node-in-scan-context.js +5 -5
  115. package/dist/utils/is-node-in-scan-context.js.map +1 -1
  116. package/dist/utils/is-non-empty.d.ts +2 -0
  117. package/dist/utils/is-non-empty.d.ts.map +1 -0
  118. package/dist/utils/is-non-empty.js +4 -0
  119. package/dist/utils/is-non-empty.js.map +1 -0
  120. package/dist/utils/normalize-context.d.ts +2 -2
  121. package/dist/utils/normalize-context.d.ts.map +1 -1
  122. package/dist/utils/normalize-context.js +10 -8
  123. package/dist/utils/normalize-context.js.map +1 -1
  124. package/dist/utils/recalculate-positions.d.ts +1 -1
  125. package/dist/utils/recalculate-positions.d.ts.map +1 -1
  126. package/dist/utils/recalculate-positions.js +5 -5
  127. package/dist/utils/recalculate-positions.js.map +1 -1
  128. package/dist/utils/recalculate-scrollable-ancestors.d.ts +1 -1
  129. package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -1
  130. package/dist/utils/recalculate-scrollable-ancestors.js +4 -4
  131. package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -1
  132. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts +1 -1
  133. package/dist/utils/shadow-dom-aware-mutation-observer.d.ts.map +1 -1
  134. package/dist/utils/shadow-dom-aware-mutation-observer.js +19 -22
  135. package/dist/utils/shadow-dom-aware-mutation-observer.js.map +1 -1
  136. package/dist/utils/supports-anchor-positioning.d.ts +1 -1
  137. package/dist/utils/supports-anchor-positioning.d.ts.map +1 -1
  138. package/dist/utils/supports-anchor-positioning.js +1 -1
  139. package/dist/utils/supports-anchor-positioning.js.map +1 -1
  140. package/dist/utils/transform-violations.d.ts +2 -2
  141. package/dist/utils/transform-violations.d.ts.map +1 -1
  142. package/dist/utils/transform-violations.js +9 -9
  143. package/dist/utils/transform-violations.js.map +1 -1
  144. package/dist/utils/update-elements-with-issues.d.ts +3 -3
  145. package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
  146. package/dist/utils/update-elements-with-issues.js +34 -29
  147. package/dist/utils/update-elements-with-issues.js.map +1 -1
  148. package/dist/validate-options.d.ts +2 -2
  149. package/dist/validate-options.d.ts.map +1 -1
  150. package/dist/validate-options.js +24 -23
  151. package/dist/validate-options.js.map +1 -1
  152. package/package.json +5 -3
  153. package/src/accented.test.ts +2 -2
  154. package/src/accented.ts +34 -26
  155. package/src/common/tokens.ts +1 -0
  156. package/src/dom-updater.ts +26 -19
  157. package/src/elements/accented-dialog.ts +69 -43
  158. package/src/elements/accented-trigger.ts +52 -43
  159. package/src/fullscreen-listener.ts +15 -11
  160. package/src/intersection-observer.ts +27 -16
  161. package/src/log-and-rethrow.ts +2 -3
  162. package/src/logger.ts +8 -6
  163. package/src/register-elements.ts +7 -7
  164. package/src/resize-listener.ts +15 -11
  165. package/src/scanner.ts +55 -41
  166. package/src/scroll-listeners.ts +27 -19
  167. package/src/state.ts +24 -21
  168. package/src/task-queue.test.ts +5 -4
  169. package/src/task-queue.ts +2 -2
  170. package/src/types.ts +52 -53
  171. package/src/utils/are-elements-with-issues-equal.ts +7 -5
  172. package/src/utils/are-issue-sets-equal.test.ts +10 -6
  173. package/src/utils/are-issue-sets-equal.ts +8 -6
  174. package/src/utils/containing-blocks.ts +6 -3
  175. package/src/utils/contains.test.ts +2 -2
  176. package/src/utils/contains.ts +1 -1
  177. package/src/utils/deduplicate-nodes.ts +1 -1
  178. package/src/utils/deep-merge.test.ts +8 -1
  179. package/src/utils/deep-merge.ts +11 -8
  180. package/src/utils/dom-helpers.ts +6 -2
  181. package/src/utils/ensure-non-empty.ts +2 -2
  182. package/src/utils/get-element-html.ts +4 -2
  183. package/src/utils/get-element-position.ts +37 -24
  184. package/src/utils/get-parent.ts +1 -1
  185. package/src/utils/get-scan-context.test.ts +14 -8
  186. package/src/utils/get-scan-context.ts +12 -15
  187. package/src/utils/get-scrollable-ancestors.ts +8 -5
  188. package/src/utils/is-node-in-scan-context.test.ts +3 -3
  189. package/src/utils/is-node-in-scan-context.ts +6 -6
  190. package/src/utils/is-non-empty.ts +3 -0
  191. package/src/utils/normalize-context.test.ts +9 -9
  192. package/src/utils/normalize-context.ts +17 -10
  193. package/src/utils/recalculate-positions.ts +5 -5
  194. package/src/utils/recalculate-scrollable-ancestors.ts +4 -4
  195. package/src/utils/shadow-dom-aware-mutation-observer.ts +21 -24
  196. package/src/utils/supports-anchor-positioning.ts +3 -3
  197. package/src/utils/transform-violations.test.ts +22 -20
  198. package/src/utils/transform-violations.ts +14 -10
  199. package/src/utils/update-elements-with-issues.test.ts +49 -49
  200. package/src/utils/update-elements-with-issues.ts +96 -71
  201. package/src/validate-options.ts +91 -38
@@ -1,39 +1,37 @@
1
1
  import { allowedAxeOptions } from './types.js';
2
2
  import { isNode, isNodeList } from './utils/dom-helpers.js';
3
3
  function isSelector(contextFragment) {
4
- return typeof contextFragment === 'string'
5
- || isNode(contextFragment)
6
- || 'fromShadowDom' in contextFragment;
4
+ return (typeof contextFragment === 'string' ||
5
+ isNode(contextFragment) ||
6
+ 'fromShadowDom' in contextFragment);
7
7
  }
8
8
  function validateSelector(selector) {
9
9
  if (typeof selector === 'string') {
10
10
  return;
11
11
  }
12
- else if (isNode(selector)) {
12
+ if (isNode(selector)) {
13
13
  return;
14
14
  }
15
- else if ('fromShadowDom' in selector) {
16
- if (!Array.isArray(selector.fromShadowDom)
17
- || selector.fromShadowDom.length < 2 ||
18
- !selector.fromShadowDom.every(item => typeof item === 'string')) {
15
+ if ('fromShadowDom' in selector) {
16
+ if (!Array.isArray(selector.fromShadowDom) ||
17
+ selector.fromShadowDom.length < 2 ||
18
+ !selector.fromShadowDom.every((item) => typeof item === 'string')) {
19
19
  throw new TypeError(`Accented: invalid argument. \`fromShadowDom\` must be an array of strings with at least 2 elements. It’s currently set to ${selector.fromShadowDom}.`);
20
20
  }
21
21
  return;
22
22
  }
23
- else {
24
- const neverSelector = selector;
25
- throw new TypeError(`Accented: invalid argument. The selector must be one of: string, Node, or an object with a \`fromShadowDom\` property. It’s currently set to ${neverSelector}.`);
26
- }
23
+ const neverSelector = selector;
24
+ throw new TypeError(`Accented: invalid argument. The selector must be one of: string, Node, or an object with a \`fromShadowDom\` property. It’s currently set to ${neverSelector}.`);
27
25
  }
28
26
  function isSelectorList(contextFragment) {
29
- return (typeof contextFragment === 'object' && isNodeList(contextFragment))
30
- || (Array.isArray(contextFragment) && contextFragment.every(item => isSelector(item)));
27
+ return ((typeof contextFragment === 'object' && isNodeList(contextFragment)) ||
28
+ (Array.isArray(contextFragment) && contextFragment.every((item) => isSelector(item))));
31
29
  }
32
30
  function validateSelectorList(selectorList) {
33
31
  if (isNodeList(selectorList)) {
34
32
  return;
35
33
  }
36
- else if (Array.isArray(selectorList)) {
34
+ if (Array.isArray(selectorList)) {
37
35
  for (const selector of selectorList) {
38
36
  validateSelector(selector);
39
37
  }
@@ -59,14 +57,15 @@ function validateContextProp(context) {
59
57
  }
60
58
  }
61
59
  function isContextObject(contextFragment) {
62
- return typeof contextFragment === 'object' && contextFragment !== null
63
- && ('include' in contextFragment || 'exclude' in contextFragment);
60
+ return (typeof contextFragment === 'object' &&
61
+ contextFragment !== null &&
62
+ ('include' in contextFragment || 'exclude' in contextFragment));
64
63
  }
65
64
  function validateContextObject(contextObject) {
66
- if ('include' in contextObject) {
65
+ if ('include' in contextObject && contextObject.include !== undefined) {
67
66
  validateContextProp(contextObject.include);
68
67
  }
69
- if ('exclude' in contextObject) {
68
+ if ('exclude' in contextObject && contextObject.exclude !== undefined) {
70
69
  validateContextProp(contextObject.exclude);
71
70
  }
72
71
  }
@@ -86,7 +85,7 @@ function validateContext(context) {
86
85
  // but with Unicode it gets complicated quickly, so I'm sticking to only allowing
87
86
  // lowercase alphanumeric names that possibly contain dashes that start with a letter.
88
87
  const nameRegex = /^[a-z]([a-z0-9]|-)+$/;
89
- export default function validateOptions(options) {
88
+ export function validateOptions(options) {
90
89
  if (typeof options !== 'object' || options === null) {
91
90
  throw new TypeError(`Accented: invalid argument. The options parameter must be an object if provided. It’s currently set to ${options}.`);
92
91
  }
@@ -94,7 +93,8 @@ export default function validateOptions(options) {
94
93
  if (typeof options.throttle !== 'object' || options.throttle === null) {
95
94
  throw new TypeError(`Accented: invalid argument. \`throttle\` option must be an object if provided. It’s currently set to ${options.throttle}.`);
96
95
  }
97
- if (options.throttle.wait !== undefined && (typeof options.throttle.wait !== 'number' || options.throttle.wait < 0)) {
96
+ if (options.throttle.wait !== undefined &&
97
+ (typeof options.throttle.wait !== 'number' || options.throttle.wait < 0)) {
98
98
  throw new TypeError(`Accented: invalid argument. \`throttle.wait\` option must be a non-negative number if provided. It’s currently set to ${options.throttle.wait}.`);
99
99
  }
100
100
  }
@@ -109,14 +109,15 @@ export default function validateOptions(options) {
109
109
  if (options.callback !== undefined && typeof options.callback !== 'function') {
110
110
  throw new TypeError(`Accented: invalid argument. \`callback\` option must be a function if provided. It’s currently set to ${options.callback}.`);
111
111
  }
112
- if (options.name !== undefined && (typeof options.name !== 'string' || !options.name.match(nameRegex))) {
112
+ if (options.name !== undefined &&
113
+ (typeof options.name !== 'string' || !options.name.match(nameRegex))) {
113
114
  throw new TypeError(`Accented: invalid argument. \`name\` option must be a string that starts with a lowercase letter and only contains lowercase alphanumeric characters and dashes. It’s currently set to ${options.name}.`);
114
115
  }
115
116
  if (options.axeOptions !== undefined) {
116
117
  if (typeof options.axeOptions !== 'object' || options.axeOptions === null) {
117
118
  throw new TypeError(`Accented: invalid argument. \`axeOptions\` option must be an object if provided. It’s currently set to ${options.axeOptions}.`);
118
119
  }
119
- const unsupportedKeys = Object.keys(options.axeOptions).filter(key => !allowedAxeOptions.includes(key));
120
+ const unsupportedKeys = Object.keys(options.axeOptions).filter((key) => !allowedAxeOptions.includes(key));
120
121
  if (unsupportedKeys.length > 0) {
121
122
  throw new TypeError(`Accented: invalid argument. \`axeOptions\` contains the following unsupported keys: ${unsupportedKeys.join(', ')}. Valid options are: ${allowedAxeOptions.join(', ')}.`);
122
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate-options.js","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate-options.js","sourceRoot":"","sources":["../src/validate-options.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accented",
3
- "version": "0.0.0-20250424114613",
3
+ "version": "0.0.0-20250618181418",
4
4
  "description": "Continuous accessibility testing and issue highlighting for web development",
5
5
  "type": "module",
6
6
  "main": "dist/accented.js",
@@ -34,11 +34,13 @@
34
34
  "jsdom": "^26.0.0"
35
35
  },
36
36
  "scripts": {
37
- "build": "tsc",
37
+ "build": "pnpm copyCommon && tsc",
38
+ "copyCommon": "node --import tsx ./scripts/copy-common.ts",
39
+ "watchCommon": "node --import tsx ./scripts/watch-common.ts",
38
40
  "checkBuiltFiles": "node --import tsx ./scripts/check-built-files.ts",
39
41
  "checkImportsInBuiltFiles": "node ./dist/accented.js",
40
42
  "typecheckTests": "tsc -p ./tsconfig.test.json",
41
- "watch": "tsc --watch",
43
+ "watch": "pnpm copyCommon && (pnpm watchCommon & tsc --watch)",
42
44
  "test": "node --test --import tsx \"./**/*.test.ts\""
43
45
  }
44
46
  }
@@ -1,8 +1,8 @@
1
1
  import assert from 'node:assert/strict';
2
- import {suite, test} from 'node:test';
2
+ import { suite, test } from 'node:test';
3
3
  import type { Mock } from 'node:test';
4
4
 
5
- import accented from './accented.js';
5
+ import { accented } from './accented';
6
6
 
7
7
  suite('Accented', () => {
8
8
  test('runs without errors in NodeJS and issues a warning and a trace (it’s meant to be a no-op on the server side)', (t) => {
package/src/accented.ts CHANGED
@@ -1,19 +1,18 @@
1
-
2
- import registerElements from './register-elements.js';
3
- import createDomUpdater from './dom-updater.js';
4
- import createLogger from './logger.js';
5
- import createScanner from './scanner.js';
6
- import setupScrollListeners from './scroll-listeners.js';
7
- import setupResizeListener from './resize-listener.js';
8
- import setupFullscreenListener from './fullscreen-listener.js';
9
- import setupIntersectionObserver from './intersection-observer.js';
1
+ import { createDomUpdater } from './dom-updater.js';
2
+ import { setupResizeListener as setupFullscreenListener } from './fullscreen-listener.js';
3
+ import { setupIntersectionObserver } from './intersection-observer.js';
4
+ import { logAndRethrow } from './log-and-rethrow.js';
5
+ import { createLogger } from './logger.js';
6
+ import { registerElements } from './register-elements.js';
7
+ import { setupResizeListener } from './resize-listener.js';
8
+ import { createScanner } from './scanner.js';
9
+ import { setupScrollListeners } from './scroll-listeners.js';
10
10
  import { enabled, extendedElementsWithIssues } from './state.js';
11
- import deepMerge from './utils/deep-merge.js';
12
- import type { AccentedOptions, DisableAccented } from './types';
13
- import validateOptions from './validate-options.js';
14
- import supportsAnchorPositioning from './utils/supports-anchor-positioning.js';
15
- import logAndRethrow from './log-and-rethrow.js';
11
+ import type { AccentedOptions, DisableAccented } from './types.ts';
16
12
  import { initializeContainingBlockSupportSet } from './utils/containing-blocks.js';
13
+ import { deepMerge } from './utils/deep-merge.js';
14
+ import { supportsAnchorPositioning } from './utils/supports-anchor-positioning.js';
15
+ import { validateOptions } from './validate-options.js';
17
16
 
18
17
  export type { AccentedOptions, DisableAccented };
19
18
 
@@ -42,24 +41,25 @@ export type { AccentedOptions, DisableAccented };
42
41
  * }
43
42
  * });
44
43
  */
45
- export default function accented(options: AccentedOptions = {}): DisableAccented {
46
-
44
+ export function accented(options: AccentedOptions = {}): DisableAccented {
47
45
  validateOptions(options);
48
46
 
49
47
  try {
50
48
  if (typeof window === 'undefined' || typeof document === 'undefined') {
51
- console.warn('Accented: this script can only run in the browser, and it’s likely running on the server now. Exiting.');
49
+ console.warn(
50
+ 'Accented: this script can only run in the browser, and it’s likely running on the server now. Exiting.',
51
+ );
52
52
  console.trace();
53
53
  return () => {};
54
54
  }
55
55
 
56
56
  const defaultOutput: Required<AccentedOptions['output']> = {
57
- console: true
57
+ console: true,
58
58
  };
59
59
 
60
60
  const defaultThrottle: Required<AccentedOptions['throttle']> = {
61
61
  wait: 1000,
62
- leading: true
62
+ leading: true,
63
63
  };
64
64
 
65
65
  // IMPORTANT: when changing any of the properties or values, also do the following:
@@ -73,16 +73,19 @@ export default function accented(options: AccentedOptions = {}): DisableAccented
73
73
  name: 'accented',
74
74
  output: defaultOutput,
75
75
  throttle: defaultThrottle,
76
- callback: () => {}
76
+ callback: () => {},
77
77
  };
78
78
 
79
- const {context, axeOptions, name, output, throttle, callback} = deepMerge(defaultOptions, options);
79
+ const { context, axeOptions, name, output, throttle, callback } = deepMerge(
80
+ defaultOptions,
81
+ options,
82
+ );
80
83
 
81
84
  if (enabled.value) {
82
85
  // Add link to the recipes section of the docs (#56).
83
86
  console.warn(
84
87
  'You are trying to run the Accented library more than once. ' +
85
- 'This will likely lead to errors.'
88
+ 'This will likely lead to errors.',
86
89
  );
87
90
  console.trace();
88
91
  }
@@ -92,13 +95,18 @@ export default function accented(options: AccentedOptions = {}): DisableAccented
92
95
  initializeContainingBlockSupportSet();
93
96
  registerElements(name);
94
97
 
95
- const {disconnect: cleanupIntersectionObserver, intersectionObserver } = supportsAnchorPositioning(window) ? {} : setupIntersectionObserver();
98
+ const { disconnect: cleanupIntersectionObserver, intersectionObserver } =
99
+ setupIntersectionObserver();
96
100
  const cleanupScanner = createScanner(name, context, axeOptions, throttle, callback);
97
101
  const cleanupDomUpdater = createDomUpdater(name, intersectionObserver);
98
102
  const cleanupLogger = output.console ? createLogger() : () => {};
99
- const cleanupScrollListeners = supportsAnchorPositioning(window) ? () => {} : setupScrollListeners();
100
- const cleanupResizeListener = supportsAnchorPositioning(window) ? () => {} : setupResizeListener();
101
- const cleanupFullscreenListener = supportsAnchorPositioning(window) ? () => {} : setupFullscreenListener();
103
+ const cleanupScrollListeners = setupScrollListeners();
104
+ const cleanupResizeListener = supportsAnchorPositioning(window)
105
+ ? () => {}
106
+ : setupResizeListener();
107
+ const cleanupFullscreenListener = supportsAnchorPositioning(window)
108
+ ? () => {}
109
+ : setupFullscreenListener();
102
110
 
103
111
  return () => {
104
112
  try {
@@ -0,0 +1 @@
1
+ export const primaryColor = 'oklch(0.5 0.3 0)';
@@ -1,10 +1,11 @@
1
1
  import { effect } from '@preact/signals-core';
2
+ import { primaryColor } from './common/tokens.js';
2
3
  import { extendedElementsWithIssues, rootNodes } from './state.js';
3
- import type { ExtendedElementWithIssues } from './types';
4
- import areElementsWithIssuesEqual from './utils/are-elements-with-issues-equal.js';
5
- import supportsAnchorPositioning from './utils/supports-anchor-positioning.js';
4
+ import type { ExtendedElementWithIssues } from './types.ts';
5
+ import { areElementsWithIssuesEqual } from './utils/are-elements-with-issues-equal.js';
6
6
  import { isDocument, isDocumentFragment, isShadowRoot } from './utils/dom-helpers.js';
7
- import getParent from './utils/get-parent.js';
7
+ import { getParent } from './utils/get-parent.js';
8
+ import { supportsAnchorPositioning } from './utils/supports-anchor-positioning.js';
8
9
 
9
10
  const shouldInsertTriggerInsideElement = (element: Element): boolean => {
10
11
  /**
@@ -30,17 +31,17 @@ const shouldInsertTriggerInsideElement = (element: Element): boolean => {
30
31
  return noParent || isTableCell || isSummary;
31
32
  };
32
33
 
33
- export default function createDomUpdater(name: string, intersectionObserver?: IntersectionObserver) {
34
+ export function createDomUpdater(name: string, intersectionObserver?: IntersectionObserver) {
34
35
  const attrName = `data-${name}`;
35
36
 
36
- function getAnchorNames (anchorNameValue: string) {
37
+ function getAnchorNames(anchorNameValue: string) {
37
38
  return anchorNameValue
38
39
  .split(',')
39
- .map(anchorName => anchorName.trim())
40
- .filter(anchorName => anchorName.startsWith('--'));
40
+ .map((anchorName) => anchorName.trim())
41
+ .filter((anchorName) => anchorName.startsWith('--'));
41
42
  }
42
43
 
43
- function setAnchorName (elementWithIssues: ExtendedElementWithIssues) {
44
+ function setAnchorName(elementWithIssues: ExtendedElementWithIssues) {
44
45
  const { element, id, anchorNameValue } = elementWithIssues;
45
46
  const anchorNames = getAnchorNames(anchorNameValue);
46
47
  if (anchorNames.length > 0) {
@@ -50,7 +51,7 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
50
51
  }
51
52
  }
52
53
 
53
- function removeAnchorName (elementWithIssues: ExtendedElementWithIssues) {
54
+ function removeAnchorName(elementWithIssues: ExtendedElementWithIssues) {
54
55
  const { element, anchorNameValue } = elementWithIssues;
55
56
  const anchorNames = getAnchorNames(anchorNameValue);
56
57
  if (anchorNames.length > 0) {
@@ -60,7 +61,7 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
60
61
  }
61
62
  }
62
63
 
63
- function setIssues (extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
64
+ function setIssues(extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
64
65
  for (const elementWithIssues of extendedElementsWithIssues) {
65
66
  if (elementWithIssues.skipRender) {
66
67
  continue;
@@ -81,7 +82,7 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
81
82
  }
82
83
  }
83
84
 
84
- function removeIssues (extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
85
+ function removeIssues(extendedElementsWithIssues: Array<ExtendedElementWithIssues>) {
85
86
  for (const elementWithIssues of extendedElementsWithIssues) {
86
87
  if (elementWithIssues.skipRender) {
87
88
  continue;
@@ -103,7 +104,7 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
103
104
  :root {
104
105
  /* Ensure that the primary / secondary color combination meets WCAG 1.4.3 Contrast (Minimum) */
105
106
  /* OKLCH stuff: https://oklch.com/ */
106
- --${name}-primary-color: oklch(0.5 0.3 0);
107
+ --${name}-primary-color: ${primaryColor};
107
108
  --${name}-secondary-color: oklch(0.98 0 0);
108
109
  --${name}-outline-width: 2px;
109
110
  --${name}-outline-style: solid;
@@ -124,8 +125,10 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
124
125
 
125
126
  const disposeOfStyleSheetsEffect = effect(() => {
126
127
  const newRootNodes = rootNodes.value;
127
- const addedRootNodes = [...newRootNodes].filter(rootNode => !previousRootNodes.has(rootNode));
128
- const removedRootNodes = [...previousRootNodes].filter(rootNode => !newRootNodes.has(rootNode));
128
+ const addedRootNodes = [...newRootNodes].filter((rootNode) => !previousRootNodes.has(rootNode));
129
+ const removedRootNodes = [...previousRootNodes].filter(
130
+ (rootNode) => !newRootNodes.has(rootNode),
131
+ );
129
132
  for (const rootNode of addedRootNodes) {
130
133
  if (isDocument(rootNode) || (isDocumentFragment(rootNode) && isShadowRoot(rootNode))) {
131
134
  rootNode.adoptedStyleSheets.push(stylesheet);
@@ -140,11 +143,15 @@ export default function createDomUpdater(name: string, intersectionObserver?: In
140
143
  });
141
144
 
142
145
  const disposeOfElementsEffect = effect(() => {
143
- const added = extendedElementsWithIssues.value.filter(elementWithIssues => {
144
- return !previousExtendedElementsWithIssues.some(previousElementWithIssues => areElementsWithIssuesEqual(previousElementWithIssues, elementWithIssues));
146
+ const added = extendedElementsWithIssues.value.filter((elementWithIssues) => {
147
+ return !previousExtendedElementsWithIssues.some((previousElementWithIssues) =>
148
+ areElementsWithIssuesEqual(previousElementWithIssues, elementWithIssues),
149
+ );
145
150
  });
146
- const removed = previousExtendedElementsWithIssues.filter(previousElementWithIssues => {
147
- return !extendedElementsWithIssues.value.some(elementWithIssues => areElementsWithIssuesEqual(elementWithIssues, previousElementWithIssues));
151
+ const removed = previousExtendedElementsWithIssues.filter((previousElementWithIssues) => {
152
+ return !extendedElementsWithIssues.value.some((elementWithIssues) =>
153
+ areElementsWithIssuesEqual(elementWithIssues, previousElementWithIssues),
154
+ );
148
155
  });
149
156
  removeIssues(removed);
150
157
  setIssues(added);
@@ -1,8 +1,9 @@
1
- import type { Issue } from '../types';
2
1
  import type { Signal } from '@preact/signals-core';
3
- import getElementHtml from '../utils/get-element-html.js';
4
2
  import { accentedUrl } from '../constants.js';
5
- import logAndRethrow from '../log-and-rethrow.js';
3
+ import { logAndRethrow } from '../log-and-rethrow.js';
4
+ import type { Issue } from '../types.ts';
5
+ import { getElementHtml } from '../utils/get-element-html.js';
6
+ import { isNonEmpty } from '../utils/is-non-empty.js';
6
7
 
7
8
  export interface AccentedDialog extends HTMLElement {
8
9
  issues: Signal<Array<Issue>> | undefined;
@@ -13,7 +14,7 @@ export interface AccentedDialog extends HTMLElement {
13
14
 
14
15
  // We want Accented to not throw an error in Node, and use static imports,
15
16
  // so we can't export `class extends HTMLElement` because HTMLElement is not available in Node.
16
- export default () => {
17
+ export const getAccentedDialog = () => {
17
18
  const dialogTemplate = document.createElement('template');
18
19
  dialogTemplate.innerHTML = `
19
20
  <dialog dir="ltr" lang="en" aria-labelledby="title">
@@ -247,11 +248,11 @@ export default () => {
247
248
 
248
249
  element: Element | undefined;
249
250
 
250
- open: boolean = false;
251
+ open = false;
251
252
 
252
253
  constructor() {
254
+ super();
253
255
  try {
254
- super();
255
256
  this.attachShadow({ mode: 'open' });
256
257
  const content = dialogTemplate.content.cloneNode(true);
257
258
  if (this.shadowRoot) {
@@ -270,31 +271,43 @@ export default () => {
270
271
  const dialog = shadowRoot.querySelector('dialog');
271
272
  const closeButton = shadowRoot.querySelector('#close');
272
273
  this.#abortController = new AbortController();
273
- closeButton?.addEventListener('click', () => {
274
- try {
275
- dialog?.close();
276
- } catch (error) {
277
- logAndRethrow(error);
278
- }
279
- }, { signal: this.#abortController.signal });
280
-
281
- dialog?.addEventListener('click', (event) => {
282
- try {
283
- this.#onDialogClick(event);
284
- } catch (error) {
285
- logAndRethrow(error);
286
- }
287
- }, { signal: this.#abortController.signal });
288
-
289
- dialog?.addEventListener('keydown', (event) => {
290
- try {
291
- if (event.key === 'Escape') {
292
- event.stopPropagation();
274
+ closeButton?.addEventListener(
275
+ 'click',
276
+ () => {
277
+ try {
278
+ dialog?.close();
279
+ } catch (error) {
280
+ logAndRethrow(error);
293
281
  }
294
- } catch (error) {
295
- logAndRethrow(error);
296
- }
297
- }, { signal: this.#abortController.signal });
282
+ },
283
+ { signal: this.#abortController.signal },
284
+ );
285
+
286
+ dialog?.addEventListener(
287
+ 'click',
288
+ (event) => {
289
+ try {
290
+ this.#onDialogClick(event);
291
+ } catch (error) {
292
+ logAndRethrow(error);
293
+ }
294
+ },
295
+ { signal: this.#abortController.signal },
296
+ );
297
+
298
+ dialog?.addEventListener(
299
+ 'keydown',
300
+ (event) => {
301
+ try {
302
+ if (event.key === 'Escape') {
303
+ event.stopPropagation();
304
+ }
305
+ } catch (error) {
306
+ logAndRethrow(error);
307
+ }
308
+ },
309
+ { signal: this.#abortController.signal },
310
+ );
298
311
 
299
312
  if (this.issues) {
300
313
  const issues = this.issues.value;
@@ -307,18 +320,23 @@ export default () => {
307
320
  const impact = issueContent.querySelector('.impact');
308
321
  const description = issueContent.querySelector('.description');
309
322
  if (title && impact && description) {
310
- title.textContent = issue.title + ' (' + issue.id + ')';
323
+ title.textContent = `${issue.title} (${issue.id})`;
311
324
  title.href = issue.url;
312
325
 
313
- impact.textContent = 'User impact: ' + issue.impact;
326
+ impact.textContent = `User impact: ${issue.impact}`;
314
327
  impact.setAttribute('data-impact', String(issue.impact));
315
328
 
316
329
  const descriptionItems = issue.description.split(/\n\s*/);
317
330
  const descriptionContent = descriptionTemplate.content.cloneNode(true) as Element;
318
331
  const descriptionTitle = descriptionContent.querySelector('span');
319
332
  const descriptionList = descriptionContent.querySelector('ul');
320
- if (descriptionTitle && descriptionList && descriptionItems.length > 1) {
321
- descriptionTitle.textContent = descriptionItems[0]!;
333
+ if (
334
+ descriptionTitle &&
335
+ descriptionList &&
336
+ isNonEmpty(descriptionItems) &&
337
+ descriptionItems.length > 1
338
+ ) {
339
+ descriptionTitle.textContent = descriptionItems[0];
322
340
  for (const descriptionItem of descriptionItems.slice(1)) {
323
341
  const li = document.createElement('li');
324
342
  li.textContent = descriptionItem;
@@ -339,14 +357,18 @@ export default () => {
339
357
  }
340
358
  }
341
359
 
342
- dialog?.addEventListener('close', () => {
343
- try {
344
- this.open = false;
345
- this.dispatchEvent(new Event('close'));
346
- } catch (error) {
347
- logAndRethrow(error);
348
- }
349
- }, { signal: this.#abortController.signal });
360
+ dialog?.addEventListener(
361
+ 'close',
362
+ () => {
363
+ try {
364
+ this.open = false;
365
+ this.dispatchEvent(new Event('close'));
366
+ } catch (error) {
367
+ logAndRethrow(error);
368
+ }
369
+ },
370
+ { signal: this.#abortController.signal },
371
+ );
350
372
  }
351
373
  } catch (error) {
352
374
  logAndRethrow(error);
@@ -375,7 +397,11 @@ export default () => {
375
397
 
376
398
  #onDialogClick(event: MouseEvent) {
377
399
  const dialog = event.currentTarget as HTMLDialogElement;
378
- if (!dialog || typeof dialog.getBoundingClientRect !== 'function' || typeof dialog.close !== 'function') {
400
+ if (
401
+ !dialog ||
402
+ typeof dialog.getBoundingClientRect !== 'function' ||
403
+ typeof dialog.close !== 'function'
404
+ ) {
379
405
  return;
380
406
  }
381
407
  const rect = dialog.getBoundingClientRect();