accented 0.0.0-20250124142030 → 0.0.0-20250303013509

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 (129) hide show
  1. package/README.md +55 -3
  2. package/dist/accented.d.ts +3 -1
  3. package/dist/accented.d.ts.map +1 -1
  4. package/dist/accented.js +69 -50
  5. package/dist/accented.js.map +1 -1
  6. package/dist/constants.d.ts +3 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +3 -0
  9. package/dist/constants.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 +26 -19
  13. package/dist/dom-updater.js.map +1 -1
  14. package/dist/elements/{accented-container.d.ts → accented-dialog.d.ts} +10 -4
  15. package/dist/elements/accented-dialog.d.ts.map +1 -0
  16. package/dist/elements/accented-dialog.js +371 -0
  17. package/dist/elements/accented-dialog.js.map +1 -0
  18. package/dist/elements/accented-trigger.d.ts +361 -0
  19. package/dist/elements/accented-trigger.d.ts.map +1 -0
  20. package/dist/elements/accented-trigger.js +188 -0
  21. package/dist/elements/accented-trigger.js.map +1 -0
  22. package/dist/intersection-observer.d.ts +5 -0
  23. package/dist/intersection-observer.d.ts.map +1 -0
  24. package/dist/intersection-observer.js +28 -0
  25. package/dist/intersection-observer.js.map +1 -0
  26. package/dist/log-and-rethrow.d.ts +2 -0
  27. package/dist/log-and-rethrow.d.ts.map +1 -0
  28. package/dist/log-and-rethrow.js +7 -0
  29. package/dist/log-and-rethrow.js.map +1 -0
  30. package/dist/logger.d.ts.map +1 -1
  31. package/dist/logger.js +10 -5
  32. package/dist/logger.js.map +1 -1
  33. package/dist/register-elements.d.ts +2 -0
  34. package/dist/register-elements.d.ts.map +1 -0
  35. package/dist/register-elements.js +21 -0
  36. package/dist/register-elements.js.map +1 -0
  37. package/dist/resize-listener.d.ts +2 -0
  38. package/dist/resize-listener.d.ts.map +1 -0
  39. package/dist/resize-listener.js +18 -0
  40. package/dist/resize-listener.js.map +1 -0
  41. package/dist/scanner.d.ts +2 -2
  42. package/dist/scanner.d.ts.map +1 -1
  43. package/dist/scanner.js +97 -33
  44. package/dist/scanner.js.map +1 -1
  45. package/dist/scroll-listeners.d.ts +2 -0
  46. package/dist/scroll-listeners.d.ts.map +1 -0
  47. package/dist/scroll-listeners.js +38 -0
  48. package/dist/scroll-listeners.js.map +1 -0
  49. package/dist/state.d.ts +1 -0
  50. package/dist/state.d.ts.map +1 -1
  51. package/dist/state.js +6 -0
  52. package/dist/state.js.map +1 -1
  53. package/dist/types.d.ts +71 -18
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/types.js +1 -0
  56. package/dist/types.js.map +1 -1
  57. package/dist/utils/deep-merge.js +1 -1
  58. package/dist/utils/deep-merge.js.map +1 -1
  59. package/dist/utils/get-element-html.d.ts +2 -0
  60. package/dist/utils/get-element-html.d.ts.map +1 -0
  61. package/dist/utils/get-element-html.js +14 -0
  62. package/dist/utils/get-element-html.js.map +1 -0
  63. package/dist/utils/get-element-position.d.ts +3 -0
  64. package/dist/utils/get-element-position.d.ts.map +1 -0
  65. package/dist/utils/get-element-position.js +58 -0
  66. package/dist/utils/get-element-position.js.map +1 -0
  67. package/dist/utils/get-scrollable-ancestors.d.ts +2 -0
  68. package/dist/utils/get-scrollable-ancestors.d.ts.map +1 -0
  69. package/dist/utils/get-scrollable-ancestors.js +15 -0
  70. package/dist/utils/get-scrollable-ancestors.js.map +1 -0
  71. package/dist/utils/is-html-element.d.ts +2 -0
  72. package/dist/utils/is-html-element.d.ts.map +1 -0
  73. package/dist/utils/is-html-element.js +7 -0
  74. package/dist/utils/is-html-element.js.map +1 -0
  75. package/dist/utils/recalculate-positions.d.ts +2 -0
  76. package/dist/utils/recalculate-positions.d.ts.map +1 -0
  77. package/dist/utils/recalculate-positions.js +27 -0
  78. package/dist/utils/recalculate-positions.js.map +1 -0
  79. package/dist/utils/recalculate-scrollable-ancestors.d.ts +2 -0
  80. package/dist/utils/recalculate-scrollable-ancestors.d.ts.map +1 -0
  81. package/dist/utils/recalculate-scrollable-ancestors.js +13 -0
  82. package/dist/utils/recalculate-scrollable-ancestors.js.map +1 -0
  83. package/dist/utils/supports-anchor-positioning.d.ts +6 -0
  84. package/dist/utils/supports-anchor-positioning.d.ts.map +1 -0
  85. package/dist/utils/supports-anchor-positioning.js +4 -0
  86. package/dist/utils/supports-anchor-positioning.js.map +1 -0
  87. package/dist/utils/transform-violations.d.ts.map +1 -1
  88. package/dist/utils/transform-violations.js +9 -0
  89. package/dist/utils/transform-violations.js.map +1 -1
  90. package/dist/utils/update-elements-with-issues.d.ts +3 -1
  91. package/dist/utils/update-elements-with-issues.d.ts.map +1 -1
  92. package/dist/utils/update-elements-with-issues.js +25 -7
  93. package/dist/utils/update-elements-with-issues.js.map +1 -1
  94. package/dist/validate-options.d.ts +3 -0
  95. package/dist/validate-options.d.ts.map +1 -0
  96. package/dist/validate-options.js +42 -0
  97. package/dist/validate-options.js.map +1 -0
  98. package/package.json +2 -1
  99. package/src/accented.ts +78 -58
  100. package/src/constants.ts +2 -0
  101. package/src/dom-updater.ts +26 -18
  102. package/src/elements/accented-dialog.ts +394 -0
  103. package/src/elements/accented-trigger.ts +214 -0
  104. package/src/intersection-observer.ts +28 -0
  105. package/src/log-and-rethrow.ts +9 -0
  106. package/src/logger.ts +11 -6
  107. package/src/register-elements.ts +21 -0
  108. package/src/resize-listener.ts +17 -0
  109. package/src/scanner.ts +108 -37
  110. package/src/scroll-listeners.ts +37 -0
  111. package/src/state.ts +12 -0
  112. package/src/types.ts +78 -19
  113. package/src/utils/deep-merge.test.ts +7 -0
  114. package/src/utils/deep-merge.ts +1 -1
  115. package/src/utils/get-element-html.ts +13 -0
  116. package/src/utils/get-element-position.ts +59 -0
  117. package/src/utils/get-scrollable-ancestors.ts +14 -0
  118. package/src/utils/is-html-element.ts +6 -0
  119. package/src/utils/recalculate-positions.ts +27 -0
  120. package/src/utils/recalculate-scrollable-ancestors.ts +13 -0
  121. package/src/utils/supports-anchor-positioning.ts +7 -0
  122. package/src/utils/transform-violations.ts +12 -1
  123. package/src/utils/update-elements-with-issues.test.ts +91 -16
  124. package/src/utils/update-elements-with-issues.ts +40 -20
  125. package/src/validate-options.ts +44 -0
  126. package/dist/elements/accented-container.d.ts.map +0 -1
  127. package/dist/elements/accented-container.js +0 -131
  128. package/dist/elements/accented-container.js.map +0 -1
  129. package/src/elements/accented-container.ts +0 -147
@@ -1,6 +1,11 @@
1
- import type { AxeResults } from 'axe-core';
1
+ import type { AxeResults, ImpactValue } from 'axe-core';
2
2
  import type { Issue, ElementWithIssues } from '../types';
3
3
 
4
+ function impactCompare(a: ImpactValue, b: ImpactValue) {
5
+ const impactOrder = [null, 'minor', 'moderate', 'serious', 'critical'];
6
+ return impactOrder.indexOf(a) - impactOrder.indexOf(b);
7
+ }
8
+
4
9
  export default function transformViolations(violations: typeof AxeResults.violations) {
5
10
  const elementsWithIssues: Array<ElementWithIssues> = [];
6
11
 
@@ -41,5 +46,11 @@ export default function transformViolations(violations: typeof AxeResults.violat
41
46
  }
42
47
  }
43
48
 
49
+ for (const elementWithIssues of elementsWithIssues) {
50
+ elementWithIssues.issues.sort((a, b) => {
51
+ return -impactCompare(a.impact, b.impact) || a.id.localeCompare(b.id);
52
+ });
53
+ }
54
+
44
55
  return elementsWithIssues;
45
56
  }
@@ -6,11 +6,11 @@ import type { ExtendedElementWithIssues, Issue } from '../types';
6
6
  import updateElementsWithIssues from './update-elements-with-issues';
7
7
 
8
8
  import type { AxeResults, ImpactValue } from 'axe-core';
9
- import type { AccentedContainer } from '../elements/accented-container';
9
+ import type { AccentedTrigger } from '../elements/accented-trigger';
10
10
  type Violation = AxeResults['violations'][number];
11
11
  type Node = Violation['nodes'][number];
12
12
 
13
- const win: Window = {
13
+ const win: Window & { CSS: typeof CSS } = {
14
14
  document: {
15
15
  // @ts-expect-error the return value is of incorrect type.
16
16
  createElement: () => ({
@@ -22,16 +22,36 @@ const win: Window = {
22
22
  },
23
23
  // @ts-expect-error we're missing a lot of properties
24
24
  getComputedStyle: () => ({
25
- zIndex: ''
26
- })
25
+ zIndex: '',
26
+ direction: 'ltr'
27
+ }),
28
+ // @ts-expect-error we're missing a lot of properties
29
+ CSS: {
30
+ supports: () => true
31
+ }
27
32
  }
28
33
 
34
+ const getBoundingClientRect = () => ({});
35
+
36
+ // @ts-expect-error element is not HTMLElement
37
+ const element1: HTMLElement = {getBoundingClientRect, isConnected: true};
29
38
  // @ts-expect-error element is not HTMLElement
30
- const element1: HTMLElement = {};
39
+ const element2: HTMLElement = {getBoundingClientRect, isConnected: true};
31
40
  // @ts-expect-error element is not HTMLElement
32
- const element2: HTMLElement = {};
41
+ const element3: HTMLElement = {getBoundingClientRect, isConnected: false};
42
+
43
+ const trigger = win.document.createElement('accented-trigger') as AccentedTrigger;
44
+
45
+ const position = signal({
46
+ left: 0,
47
+ width: 100,
48
+ top: 0,
49
+ height: 100
50
+ });
33
51
 
34
- const accentedContainer = win.document.createElement('accented-container') as AccentedContainer;
52
+ const visible = signal(true);
53
+
54
+ const scrollableAncestors = signal(new Set<HTMLElement>());
35
55
 
36
56
  const commonNodeProps = {
37
57
  html: '<div></div>',
@@ -51,6 +71,11 @@ const node2: Node = {
51
71
  element: element2,
52
72
  };
53
73
 
74
+ const node3: Node = {
75
+ ...commonNodeProps,
76
+ element: element3,
77
+ };
78
+
54
79
  const commonViolationProps = {
55
80
  help: 'help',
56
81
  helpUrl: 'http://example.com',
@@ -77,6 +102,12 @@ const violation3: Violation = {
77
102
  nodes: [node2]
78
103
  };
79
104
 
105
+ const violation4: Violation = {
106
+ ...commonViolationProps,
107
+ id: 'id4',
108
+ nodes: [node3]
109
+ };
110
+
80
111
  const commonIssueProps = {
81
112
  title: 'help',
82
113
  description: 'description',
@@ -105,13 +136,19 @@ suite('updateElementsWithIssues', () => {
105
136
  {
106
137
  id: 1,
107
138
  element: element1,
108
- accentedContainer,
139
+ position,
140
+ visible,
141
+ trigger,
142
+ scrollableAncestors,
109
143
  issues: signal([issue1])
110
144
  },
111
145
  {
112
146
  id: 2,
113
147
  element: element2,
114
- accentedContainer,
148
+ position,
149
+ visible,
150
+ trigger,
151
+ scrollableAncestors,
115
152
  issues: signal([issue2])
116
153
  }
117
154
  ]);
@@ -128,13 +165,19 @@ suite('updateElementsWithIssues', () => {
128
165
  {
129
166
  id: 1,
130
167
  element: element1,
131
- accentedContainer,
168
+ position,
169
+ visible,
170
+ trigger,
171
+ scrollableAncestors,
132
172
  issues: signal([issue1])
133
173
  },
134
174
  {
135
175
  id: 2,
136
176
  element: element2,
137
- accentedContainer,
177
+ position,
178
+ visible,
179
+ trigger,
180
+ scrollableAncestors,
138
181
  issues: signal([issue2])
139
182
  }
140
183
  ]);
@@ -151,13 +194,19 @@ suite('updateElementsWithIssues', () => {
151
194
  {
152
195
  id: 1,
153
196
  element: element1,
154
- accentedContainer,
197
+ position,
198
+ visible,
199
+ trigger,
200
+ scrollableAncestors,
155
201
  issues: signal([issue1])
156
202
  },
157
203
  {
158
204
  id: 2,
159
205
  element: element2,
160
- accentedContainer,
206
+ position,
207
+ visible,
208
+ trigger,
209
+ scrollableAncestors,
161
210
  issues: signal([issue2, issue3])
162
211
  }
163
212
  ]);
@@ -174,7 +223,10 @@ suite('updateElementsWithIssues', () => {
174
223
  {
175
224
  id: 1,
176
225
  element: element1,
177
- accentedContainer,
226
+ position,
227
+ visible,
228
+ trigger,
229
+ scrollableAncestors,
178
230
  issues: signal([issue1])
179
231
  }
180
232
  ]);
@@ -186,18 +238,41 @@ suite('updateElementsWithIssues', () => {
186
238
  assert.equal(extendedElementsWithIssues.value[1]?.issues.value.length, 1);
187
239
  });
188
240
 
241
+ test('one disconnected element added', () => {
242
+ const extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>> = signal([
243
+ {
244
+ id: 1,
245
+ element: element1,
246
+ position,
247
+ visible,
248
+ trigger,
249
+ scrollableAncestors,
250
+ issues: signal([issue1])
251
+ }
252
+ ]);
253
+ updateElementsWithIssues(extendedElementsWithIssues, [violation1, violation4], win, 'accented');
254
+ assert.equal(extendedElementsWithIssues.value.length, 1);
255
+ assert.equal(extendedElementsWithIssues.value[0]?.element, element1);
256
+ });
257
+
189
258
  test('one element removed', () => {
190
259
  const extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>> = signal([
191
260
  {
192
261
  id: 1,
193
262
  element: element1,
194
- accentedContainer,
263
+ position,
264
+ visible,
265
+ trigger,
266
+ scrollableAncestors,
195
267
  issues: signal([issue1])
196
268
  },
197
269
  {
198
270
  id: 2,
199
271
  element: element2,
200
- accentedContainer,
272
+ position,
273
+ visible,
274
+ trigger,
275
+ scrollableAncestors,
201
276
  issues: signal([issue2])
202
277
  }
203
278
  ]);
@@ -4,11 +4,15 @@ import { batch, signal } from '@preact/signals-core';
4
4
  import type { ExtendedElementWithIssues } from '../types';
5
5
  import transformViolations from './transform-violations.js';
6
6
  import areIssueSetsEqual from './are-issue-sets-equal.js';
7
- import type { AccentedContainer } from '../elements/accented-container';
7
+ import type { AccentedTrigger } from '../elements/accented-trigger';
8
+ import type { AccentedDialog } from '../elements/accented-dialog';
9
+ import getElementPosition from './get-element-position.js';
10
+ import getScrollableAncestors from './get-scrollable-ancestors.js';
11
+ import supportsAnchorPositioning from './supports-anchor-positioning.js';
8
12
 
9
13
  let count = 0;
10
14
 
11
- export default function updateElementsWithIssues(extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>, violations: typeof AxeResults.violations, win: Window, name: string) {
15
+ export default function updateElementsWithIssues(extendedElementsWithIssues: Signal<Array<ExtendedElementWithIssues>>, violations: typeof AxeResults.violations, win: Window & { CSS: typeof CSS }, name: string) {
12
16
  const updatedElementsWithIssues = transformViolations(violations);
13
17
 
14
18
  batch(() => {
@@ -32,24 +36,40 @@ export default function updateElementsWithIssues(extendedElementsWithIssues: Sig
32
36
  .filter(extendedElementWithIssues => {
33
37
  return !removedElementsWithIssues.some(removedElementWithIssues => removedElementWithIssues.element === extendedElementWithIssues.element);
34
38
  })
35
- .concat(addedElementsWithIssues.map(addedElementWithIssues => {
36
- const id = count++;
37
- const accentedContainer = win.document.createElement(`${name}-container`) as AccentedContainer;
38
- const elementZIndex = parseInt(win.getComputedStyle(addedElementWithIssues.element).zIndex, 10);
39
- if (!isNaN(elementZIndex)) {
40
- accentedContainer.style.setProperty('z-index', (elementZIndex + 1).toString());
41
- }
42
- accentedContainer.style.setProperty('position-anchor', `--${name}-anchor-${id}`);
43
- accentedContainer.dataset.id = id.toString();
44
- const issues = signal(addedElementWithIssues.issues);
45
- accentedContainer.issues = issues;
46
- return {
47
- id,
48
- element: addedElementWithIssues.element,
49
- accentedContainer,
50
- issues
51
- };
52
- }));
39
+ .concat(addedElementsWithIssues
40
+ .filter(addedElementWithIssues => addedElementWithIssues.element.isConnected)
41
+ .map(addedElementWithIssues => {
42
+ const id = count++;
43
+ const trigger = win.document.createElement(`${name}-trigger`) as AccentedTrigger;
44
+ const elementZIndex = parseInt(win.getComputedStyle(addedElementWithIssues.element).zIndex, 10);
45
+ if (!isNaN(elementZIndex)) {
46
+ trigger.style.setProperty('z-index', (elementZIndex + 1).toString(), 'important');
47
+ }
48
+ trigger.style.setProperty('position-anchor', `--${name}-anchor-${id}`, 'important');
49
+ trigger.dataset.id = id.toString();
50
+ const accentedDialog = win.document.createElement(`${name}-dialog`) as AccentedDialog;
51
+ trigger.dialog = accentedDialog;
52
+ const position = getElementPosition(addedElementWithIssues.element, win);
53
+ trigger.position = signal(position);
54
+ trigger.visible = signal(true);
55
+ trigger.element = addedElementWithIssues.element;
56
+ const scrollableAncestors = supportsAnchorPositioning(win) ?
57
+ new Set<HTMLElement>() :
58
+ getScrollableAncestors(addedElementWithIssues.element, win);
59
+ const issues = signal(addedElementWithIssues.issues);
60
+ accentedDialog.issues = issues;
61
+ accentedDialog.element = addedElementWithIssues.element;
62
+ return {
63
+ id,
64
+ element: addedElementWithIssues.element,
65
+ visible: trigger.visible,
66
+ position: trigger.position,
67
+ scrollableAncestors: signal(scrollableAncestors),
68
+ trigger,
69
+ issues
70
+ };
71
+ })
72
+ );
53
73
  }
54
74
  });
55
75
  }
@@ -0,0 +1,44 @@
1
+ import type { AccentedOptions } from './types';
2
+ import { allowedAxeOptions } from './types.js';
3
+
4
+ // The space of valid CSS and HTML names is wider than this,
5
+ // but with Unicode it gets complicated quickly, so I'm sticking to only allowing
6
+ // lowercase alphanumeric names that possibly contain dashes that start with a letter.
7
+ const nameRegex = /^[a-z]([a-z0-9]|-)+$/;
8
+
9
+ export default function validateOptions(options: AccentedOptions) {
10
+ if (typeof options !== 'object' || options === null) {
11
+ throw new TypeError(`Accented: invalid argument. The options parameter must be an object if provided. It’s currently set to ${options}.`);
12
+ }
13
+ if (options.throttle !== undefined) {
14
+ if (typeof options.throttle !== 'object' || options.throttle === null) {
15
+ throw new TypeError(`Accented: invalid argument. \`throttle\` option must be an object if provided. It’s currently set to ${options.throttle}.`);
16
+ }
17
+ if (options.throttle.wait !== undefined && (typeof options.throttle.wait !== 'number' || options.throttle.wait < 0)) {
18
+ 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}.`);
19
+ }
20
+ }
21
+ if (options.output !== undefined) {
22
+ if (typeof options.output !== 'object' || options.output === null) {
23
+ throw new TypeError(`Accented: invalid argument. \`output\` option must be an object if provided. It’s currently set to ${options.output}.`);
24
+ }
25
+ if (options.output.console !== undefined && typeof options.output.console !== 'boolean') {
26
+ console.warn(`Accented: invalid argument. \`output.console\` option is expected to be a boolean. It’s currently set to ${options.output.console}.`);
27
+ }
28
+ }
29
+ if (options.callback !== undefined && typeof options.callback !== 'function') {
30
+ throw new TypeError(`Accented: invalid argument. \`callback\` option must be a function if provided. It’s currently set to ${options.callback}.`);
31
+ }
32
+ if (options.name !== undefined && (typeof options.name !== 'string' || !options.name.match(nameRegex))) {
33
+ 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}.`);
34
+ }
35
+ if (options.axeOptions !== undefined) {
36
+ if (typeof options.axeOptions !== 'object' || options.axeOptions === null) {
37
+ throw new TypeError(`Accented: invalid argument. \`axeOptions\` option must be an object if provided. It’s currently set to ${options.axeOptions}.`);
38
+ }
39
+ const unsupportedKeys = Object.keys(options.axeOptions).filter(key => !(allowedAxeOptions as unknown as Array<string>).includes(key));
40
+ if (unsupportedKeys.length > 0) {
41
+ throw new TypeError(`Accented: invalid argument. \`axeOptions\` contains the following unsupported keys: ${unsupportedKeys.join(', ')}. Valid options are: ${allowedAxeOptions.join(', ')}.`);
42
+ }
43
+ }
44
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"accented-container.d.ts","sourceRoot":"","sources":["../../src/elements/accented-container.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1C;+BAIqB,MAAM;;iCAkEN,eAAe,GAAG,SAAS;iCAE3B,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;gBAElC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAtE5C,wBAwIE"}
@@ -1,131 +0,0 @@
1
- import { effect } from '@preact/signals-core';
2
- // We want Accented to not throw an error in Node, and use static imports,
3
- // so we can't export `class extends HTMLElement` because HTMLElement is not available in Node.
4
- export default (name) => {
5
- const containerTemplate = document.createElement('template');
6
- containerTemplate.innerHTML = `
7
- <button id="trigger">⚠</button>
8
- <dialog dir="ltr" aria-labelledby="title">
9
- <h2 id="title">Issues</h2>
10
- <ul id="issues"></ul>
11
- </dialog>
12
- `;
13
- const issueTemplate = document.createElement('template');
14
- issueTemplate.innerHTML = `
15
- <li>
16
- <a></a>
17
- <div></div>
18
- </li>
19
- `;
20
- const descriptionTemplate = document.createElement('template');
21
- descriptionTemplate.innerHTML = `
22
- <span></span>
23
- <ul></ul>
24
- `;
25
- const stylesheet = new CSSStyleSheet();
26
- stylesheet.replaceSync(`
27
- :host {
28
- position: absolute;
29
- inset-inline-end: anchor(end);
30
- inset-block-end: anchor(end);
31
-
32
- /* Popover-specific stuff */
33
- border: none;
34
- padding: 0;
35
- margin-inline-end: 0;
36
- margin-block-end: 0;
37
- }
38
-
39
- #trigger {
40
- box-sizing: border-box;
41
- font-size: 1rem;
42
- inline-size: max(32px, 2rem);
43
- block-size: max(32px, 2rem);
44
-
45
- /* Make it look better in forced-colors mode, */
46
- border: 2px solid transparent;
47
-
48
- background-color: var(--${name}-primary-color);
49
- color: var(--${name}-secondary-color);
50
-
51
- outline-offset: -4px;
52
- outline-color: var(--${name}-secondary-color);
53
-
54
- &:focus-visible {
55
- outline-width: 2px;
56
- outline-style: solid;
57
- }
58
-
59
- &:hover:not(:focus-visible) {
60
- outline-width: 2px;
61
- outline-style: dashed;
62
- }
63
- }
64
- `);
65
- return class AccentedContainerLocal extends HTMLElement {
66
- #abortController;
67
- #disposeOfEffect;
68
- issues;
69
- constructor() {
70
- super();
71
- this.attachShadow({ mode: 'open' });
72
- const content = containerTemplate.content.cloneNode(true);
73
- if (this.shadowRoot) {
74
- this.shadowRoot.adoptedStyleSheets.push(stylesheet);
75
- this.shadowRoot.append(content);
76
- }
77
- }
78
- connectedCallback() {
79
- if (this.shadowRoot) {
80
- const { shadowRoot } = this;
81
- const trigger = shadowRoot.getElementById('trigger');
82
- const dialog = shadowRoot.querySelector('dialog');
83
- this.#abortController = new AbortController();
84
- trigger?.addEventListener('click', () => {
85
- dialog?.showModal();
86
- }, { signal: this.#abortController.signal });
87
- this.#disposeOfEffect = effect(() => {
88
- if (this.issues) {
89
- const issues = this.issues.value;
90
- const issuesList = shadowRoot.getElementById('issues');
91
- if (issuesList) {
92
- issuesList.innerHTML = '';
93
- for (const issue of issues) {
94
- const issueContent = issueTemplate.content.cloneNode(true);
95
- const a = issueContent.querySelector('a');
96
- const div = issueContent.querySelector('div');
97
- if (a && div) {
98
- a.textContent = issue.title;
99
- a.href = issue.url;
100
- const descriptionItems = issue.description.split(/\n\s*/);
101
- const descriptionContent = descriptionTemplate.content.cloneNode(true);
102
- const descriptionTitle = descriptionContent.querySelector('span');
103
- const descriptionList = descriptionContent.querySelector('ul');
104
- if (descriptionTitle && descriptionList && descriptionItems.length > 1) {
105
- descriptionTitle.textContent = descriptionItems[0];
106
- for (const descriptionItem of descriptionItems.slice(1)) {
107
- const li = document.createElement('li');
108
- li.textContent = descriptionItem;
109
- descriptionList.appendChild(li);
110
- }
111
- div.appendChild(descriptionContent);
112
- }
113
- }
114
- issuesList.appendChild(issueContent);
115
- }
116
- }
117
- }
118
- });
119
- }
120
- }
121
- disconnectedCallback() {
122
- if (this.#abortController) {
123
- this.#abortController.abort();
124
- }
125
- if (this.#disposeOfEffect) {
126
- this.#disposeOfEffect();
127
- }
128
- }
129
- };
130
- };
131
- //# sourceMappingURL=accented-container.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accented-container.js","sourceRoot":"","sources":["../../src/elements/accented-container.ts"],"names":[],"mappings":"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"}
@@ -1,147 +0,0 @@
1
- import type { Issue } from '../types';
2
- import type { Signal } from '@preact/signals-core';
3
- import { effect } from '@preact/signals-core';
4
-
5
- export interface AccentedContainer extends HTMLElement {
6
- issues: Signal<Array<Issue>> | undefined;
7
- }
8
-
9
- // We want Accented to not throw an error in Node, and use static imports,
10
- // so we can't export `class extends HTMLElement` because HTMLElement is not available in Node.
11
- export default (name: string) => {
12
- const containerTemplate = document.createElement('template');
13
- containerTemplate.innerHTML = `
14
- <button id="trigger">⚠</button>
15
- <dialog dir="ltr" aria-labelledby="title">
16
- <h2 id="title">Issues</h2>
17
- <ul id="issues"></ul>
18
- </dialog>
19
- `;
20
-
21
- const issueTemplate = document.createElement('template');
22
- issueTemplate.innerHTML = `
23
- <li>
24
- <a></a>
25
- <div></div>
26
- </li>
27
- `;
28
-
29
- const descriptionTemplate = document.createElement('template');
30
- descriptionTemplate.innerHTML = `
31
- <span></span>
32
- <ul></ul>
33
- `;
34
-
35
- const stylesheet = new CSSStyleSheet();
36
- stylesheet.replaceSync(`
37
- :host {
38
- position: absolute;
39
- inset-inline-end: anchor(end);
40
- inset-block-end: anchor(end);
41
-
42
- /* Popover-specific stuff */
43
- border: none;
44
- padding: 0;
45
- margin-inline-end: 0;
46
- margin-block-end: 0;
47
- }
48
-
49
- #trigger {
50
- box-sizing: border-box;
51
- font-size: 1rem;
52
- inline-size: max(32px, 2rem);
53
- block-size: max(32px, 2rem);
54
-
55
- /* Make it look better in forced-colors mode, */
56
- border: 2px solid transparent;
57
-
58
- background-color: var(--${name}-primary-color);
59
- color: var(--${name}-secondary-color);
60
-
61
- outline-offset: -4px;
62
- outline-color: var(--${name}-secondary-color);
63
-
64
- &:focus-visible {
65
- outline-width: 2px;
66
- outline-style: solid;
67
- }
68
-
69
- &:hover:not(:focus-visible) {
70
- outline-width: 2px;
71
- outline-style: dashed;
72
- }
73
- }
74
- `);
75
-
76
- return class AccentedContainerLocal extends HTMLElement implements AccentedContainer {
77
- #abortController: AbortController | undefined;
78
-
79
- #disposeOfEffect: (() => void) | undefined;
80
-
81
- issues: Signal<Array<Issue>> | undefined;
82
-
83
- constructor() {
84
- super();
85
- this.attachShadow({ mode: 'open' });
86
- const content = containerTemplate.content.cloneNode(true);
87
- if (this.shadowRoot) {
88
- this.shadowRoot.adoptedStyleSheets.push(stylesheet);
89
- this.shadowRoot.append(content);
90
- }
91
- }
92
-
93
- connectedCallback() {
94
- if (this.shadowRoot) {
95
- const { shadowRoot } = this;
96
- const trigger = shadowRoot.getElementById('trigger');
97
- const dialog = shadowRoot.querySelector('dialog');
98
- this.#abortController = new AbortController();
99
- trigger?.addEventListener('click', () => {
100
- dialog?.showModal();
101
- }, { signal: this.#abortController.signal });
102
-
103
- this.#disposeOfEffect = effect(() => {
104
- if (this.issues) {
105
- const issues = this.issues.value;
106
- const issuesList = shadowRoot.getElementById('issues');
107
- if (issuesList) {
108
- issuesList.innerHTML = '';
109
- for (const issue of issues) {
110
- const issueContent = issueTemplate.content.cloneNode(true) as Element;
111
- const a = issueContent.querySelector('a');
112
- const div = issueContent.querySelector('div');
113
- if (a && div) {
114
- a.textContent = issue.title;
115
- a.href = issue.url;
116
- const descriptionItems = issue.description.split(/\n\s*/);
117
- const descriptionContent = descriptionTemplate.content.cloneNode(true) as Element;
118
- const descriptionTitle = descriptionContent.querySelector('span');
119
- const descriptionList = descriptionContent.querySelector('ul');
120
- if (descriptionTitle && descriptionList && descriptionItems.length > 1) {
121
- descriptionTitle.textContent = descriptionItems[0]!;
122
- for (const descriptionItem of descriptionItems.slice(1)) {
123
- const li = document.createElement('li');
124
- li.textContent = descriptionItem;
125
- descriptionList.appendChild(li);
126
- }
127
- div.appendChild(descriptionContent);
128
- }
129
- }
130
- issuesList.appendChild(issueContent);
131
- }
132
- }
133
- }
134
- });
135
- }
136
- }
137
-
138
- disconnectedCallback() {
139
- if (this.#abortController) {
140
- this.#abortController.abort();
141
- }
142
- if (this.#disposeOfEffect) {
143
- this.#disposeOfEffect();
144
- }
145
- }
146
- };
147
- };