abledom 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -130,6 +130,14 @@ declare class FocusableElementLabelRule extends ValidationRule {
130
130
  validate(element: HTMLElement): ValidationResult | null;
131
131
  }
132
132
 
133
+ declare class ContrastRule extends ValidationRule {
134
+ type: ValidationRuleType;
135
+ name: string;
136
+ anchored: boolean;
137
+ accept(element: HTMLElement): boolean;
138
+ validate(element: HTMLElement): ValidationResult | null;
139
+ }
140
+
133
141
  /*!
134
142
  * Copyright (c) Microsoft Corporation. All rights reserved.
135
143
  * Licensed under the MIT License.
@@ -220,4 +228,4 @@ declare function matchesSelector(element: HTMLElement, selector: string): boolea
220
228
  declare function isDisplayNone(element: HTMLElement): boolean;
221
229
  declare function isElementVisible(element: HTMLElement): boolean;
222
230
 
223
- export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
231
+ export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
package/dist/index.d.ts CHANGED
@@ -130,6 +130,14 @@ declare class FocusableElementLabelRule extends ValidationRule {
130
130
  validate(element: HTMLElement): ValidationResult | null;
131
131
  }
132
132
 
133
+ declare class ContrastRule extends ValidationRule {
134
+ type: ValidationRuleType;
135
+ name: string;
136
+ anchored: boolean;
137
+ accept(element: HTMLElement): boolean;
138
+ validate(element: HTMLElement): ValidationResult | null;
139
+ }
140
+
133
141
  /*!
134
142
  * Copyright (c) Microsoft Corporation. All rights reserved.
135
143
  * Licensed under the MIT License.
@@ -220,4 +228,4 @@ declare function matchesSelector(element: HTMLElement, selector: string): boolea
220
228
  declare function isDisplayNone(element: HTMLElement): boolean;
221
229
  declare function isElementVisible(element: HTMLElement): boolean;
222
230
 
223
- export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
231
+ export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
package/dist/index.js CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  AbleDOM: () => AbleDOM,
26
26
  AtomicRule: () => AtomicRule,
27
27
  BadFocusRule: () => BadFocusRule,
28
+ ContrastRule: () => ContrastRule,
28
29
  CustomNotifyRule: () => CustomNotifyRule,
29
30
  ExistingIdRule: () => ExistingIdRule,
30
31
  FindElementRule: () => FindElementRule,
@@ -96,7 +97,7 @@ var ValidationRule = class {
96
97
  };
97
98
 
98
99
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/ui.css
99
- var ui_default = "#abledom-report {\n bottom: 20px;\n display: flex;\n flex-direction: column;\n left: 10px;\n max-height: 80%;\n max-width: 60%;\n padding: 4px 8px;\n position: fixed;\n z-index: 100500;\n}\n\n#abledom-report :focus-visible {\n outline: 3px solid red;\n mix-blend-mode: difference;\n}\n\n#abledom-report.abledom-align-left {\n left: 10px;\n right: auto;\n}\n\n#abledom-report.abledom-align-right {\n left: auto;\n right: 10px;\n}\n\n#abledom-report.abledom-align-bottom {\n bottom: 20px;\n top: auto;\n}\n\n#abledom-report.abledom-align-top {\n /* flex-direction: column-reverse; */\n bottom: auto;\n top: 10px;\n}\n\n.abledom-menu-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-block;\n margin: 2px auto 2px 0;\n}\n\n#abledom-report.abledom-align-right .abledom-menu-container {\n margin: 2px 0 2px auto;\n}\n\n.abledom-menu {\n background-color: rgba(140, 10, 121, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n\n.abledom-menu .issues-count {\n margin: 0 8px;\n display: inline-block;\n}\n\n.abledom-menu .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-menu .align-button {\n border-right-color: rgba(0, 0, 0, 0.4);\n border-radius: 0;\n margin: 0;\n}\n\n.abledom-menu .align-button:active,\n#abledom-report .pressed {\n background: linear-gradient(\n 180deg,\n rgba(130, 130, 130, 1) 0%,\n rgba(180, 180, 180, 1) 100%\n );\n}\n\n.abledom-menu .align-button-first {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n margin-left: 8px;\n}\n.abledom-menu .align-button-last {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n border-right-color: rgba(255, 255, 255, 0.4);\n}\n\n.abledom-issues-container {\n overflow: scroll;\n max-height: calc(100vh - 100px);\n}\n\n#abledom-report.abledom-align-right .abledom-issues-container {\n text-align: right;\n}\n\n.abledom-issue-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-flex;\n margin: 2px 0;\n}\n\n.abledom-issue {\n background-color: rgba(164, 2, 2, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n.abledom-issue_warning {\n background-color: rgba(163, 82, 1, 0.7);\n}\n.abledom-issue_info {\n background-color: rgba(0, 0, 255, 0.7);\n}\n\n.abledom-issue .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-issue .button:hover {\n opacity: 0.7;\n}\n\n.abledom-issue .button.close {\n background: none;\n border-color: transparent;\n color: #fff;\n margin: 0;\n}\n\n.abledom-highlight {\n background-color: yellow;\n box-sizing: border-box;\n display: none;\n opacity: 0.6;\n position: fixed;\n z-index: 100499;\n}\n\n.abledom-highlight-border1 {\n border-top: 2px solid red;\n border-bottom: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n top: -2px;\n width: calc(100% + 20px);\n height: calc(100% + 4px);\n margin: 0 -10px;\n}\n\n.abledom-highlight-border2 {\n border-left: 2px solid red;\n border-right: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n width: calc(100% + 4px);\n left: -2px;\n height: calc(100% + 20px);\n margin: -10px 0;\n}\n";
100
+ var ui_default = "#abledom-report {\n bottom: 20px;\n display: flex;\n flex-direction: column;\n left: 10px;\n max-height: 80%;\n max-width: 60%;\n padding: 4px 8px;\n position: fixed;\n z-index: 100500;\n}\n\n#abledom-report :focus-visible {\n outline: 3px solid red;\n mix-blend-mode: difference;\n}\n\n#abledom-report.abledom-align-left {\n left: 10px;\n right: auto;\n}\n\n#abledom-report.abledom-align-right {\n left: auto;\n right: 10px;\n}\n\n#abledom-report.abledom-align-bottom {\n bottom: 20px;\n top: auto;\n}\n\n#abledom-report.abledom-align-top {\n /* flex-direction: column-reverse; */\n bottom: auto;\n top: 10px;\n}\n\n.abledom-menu-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-block;\n margin: 2px auto 2px 0;\n}\n\n#abledom-report.abledom-align-right .abledom-menu-container {\n margin: 2px 0 2px auto;\n}\n\n.abledom-menu {\n background-color: rgba(140, 10, 121, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n\n.abledom-menu .issues-count {\n margin: 0 8px;\n display: inline-block;\n}\n\n.abledom-menu .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-menu .align-button {\n border-right-color: rgba(0, 0, 0, 0.4);\n border-radius: 0;\n margin: 0;\n}\n\n.abledom-menu .align-button:active,\n#abledom-report .pressed {\n background: linear-gradient(\n 180deg,\n rgba(130, 130, 130, 1) 0%,\n rgba(180, 180, 180, 1) 100%\n );\n}\n\n.abledom-menu .align-button-first {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n margin-left: 8px;\n}\n.abledom-menu .align-button-last {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n border-right-color: rgba(255, 255, 255, 0.4);\n}\n\n.abledom-issues-container {\n overflow: auto;\n max-height: calc(100vh - 100px);\n}\n\n#abledom-report.abledom-align-right .abledom-issues-container {\n text-align: right;\n}\n\n.abledom-issue-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-flex;\n margin: 2px 0;\n}\n\n.abledom-issue {\n background-color: rgba(164, 2, 2, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n.abledom-issue_warning {\n background-color: rgba(163, 82, 1, 0.7);\n}\n.abledom-issue_info {\n background-color: rgba(0, 0, 255, 0.7);\n}\n\n.abledom-issue .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-issue .button:hover {\n opacity: 0.7;\n}\n\n.abledom-issue .button.close {\n background: none;\n border-color: transparent;\n color: #fff;\n margin: 0;\n}\n\n.abledom-highlight {\n background-color: yellow;\n box-sizing: border-box;\n display: none;\n opacity: 0.6;\n position: fixed;\n z-index: 100499;\n}\n\n.abledom-highlight-border1 {\n border-top: 2px solid red;\n border-bottom: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n top: -2px;\n width: calc(100% + 20px);\n height: calc(100% + 4px);\n margin: 0 -10px;\n}\n\n.abledom-highlight-border2 {\n border-left: 2px solid red;\n border-right: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n width: calc(100% + 4px);\n left: -2px;\n height: calc(100% + 20px);\n margin: -10px 0;\n}\n";
100
101
 
101
102
  // src/ui/domBuilder.ts
102
103
  var DOMBuilder = class {
@@ -154,7 +155,7 @@ var DOMBuilder = class {
154
155
  };
155
156
 
156
157
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/close.svg
157
- var close_default = function buildSVG(parent) {
158
+ var close_default = (function buildSVG(parent) {
158
159
  const builder = new DOMBuilder(parent);
159
160
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
160
161
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -165,10 +166,10 @@ var close_default = function buildSVG(parent) {
165
166
  builder.closeTag();
166
167
  builder.closeTag();
167
168
  return parent.firstElementChild;
168
- };
169
+ });
169
170
 
170
171
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/help.svg
171
- var help_default = function buildSVG2(parent) {
172
+ var help_default = (function buildSVG2(parent) {
172
173
  const builder = new DOMBuilder(parent);
173
174
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
174
175
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -179,10 +180,10 @@ var help_default = function buildSVG2(parent) {
179
180
  builder.closeTag();
180
181
  builder.closeTag();
181
182
  return parent.firstElementChild;
182
- };
183
+ });
183
184
 
184
185
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/log.svg
185
- var log_default = function buildSVG3(parent) {
186
+ var log_default = (function buildSVG3(parent) {
186
187
  const builder = new DOMBuilder(parent);
187
188
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
188
189
  builder.openTag("polyline", { "points": "4 7 9 12 4 17" }, void 0, "http://www.w3.org/2000/svg");
@@ -191,10 +192,10 @@ var log_default = function buildSVG3(parent) {
191
192
  builder.closeTag();
192
193
  builder.closeTag();
193
194
  return parent.firstElementChild;
194
- };
195
+ });
195
196
 
196
197
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/reveal.svg
197
- var reveal_default = function buildSVG4(parent) {
198
+ var reveal_default = (function buildSVG4(parent) {
198
199
  const builder = new DOMBuilder(parent);
199
200
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
200
201
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -209,10 +210,10 @@ var reveal_default = function buildSVG4(parent) {
209
210
  builder.closeTag();
210
211
  builder.closeTag();
211
212
  return parent.firstElementChild;
212
- };
213
+ });
213
214
 
214
215
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/bug.svg
215
- var bug_default = function buildSVG5(parent) {
216
+ var bug_default = (function buildSVG5(parent) {
216
217
  const builder = new DOMBuilder(parent);
217
218
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
218
219
  builder.openTag("ellipse", { "cx": "10", "cy": "12", "rx": "4", "ry": "5", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -237,10 +238,10 @@ var bug_default = function buildSVG5(parent) {
237
238
  builder.closeTag();
238
239
  builder.closeTag();
239
240
  return parent.firstElementChild;
240
- };
241
+ });
241
242
 
242
243
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/hideall.svg
243
- var hideall_default = function buildSVG6(parent) {
244
+ var hideall_default = (function buildSVG6(parent) {
244
245
  const builder = new DOMBuilder(parent);
245
246
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
246
247
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -251,10 +252,10 @@ var hideall_default = function buildSVG6(parent) {
251
252
  builder.closeTag();
252
253
  builder.closeTag();
253
254
  return parent.firstElementChild;
254
- };
255
+ });
255
256
 
256
257
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/muteall.svg
257
- var muteall_default = function buildSVG7(parent) {
258
+ var muteall_default = (function buildSVG7(parent) {
258
259
  const builder = new DOMBuilder(parent);
259
260
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
260
261
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -267,10 +268,10 @@ var muteall_default = function buildSVG7(parent) {
267
268
  builder.closeTag();
268
269
  builder.closeTag();
269
270
  return parent.firstElementChild;
270
- };
271
+ });
271
272
 
272
273
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/showall.svg
273
- var showall_default = function buildSVG8(parent) {
274
+ var showall_default = (function buildSVG8(parent) {
274
275
  const builder = new DOMBuilder(parent);
275
276
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
276
277
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -279,47 +280,47 @@ var showall_default = function buildSVG8(parent) {
279
280
  builder.closeTag();
280
281
  builder.closeTag();
281
282
  return parent.firstElementChild;
282
- };
283
+ });
283
284
 
284
285
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/aligntopleft.svg
285
- var aligntopleft_default = function buildSVG9(parent) {
286
+ var aligntopleft_default = (function buildSVG9(parent) {
286
287
  const builder = new DOMBuilder(parent);
287
288
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
288
289
  builder.openTag("rect", { "x": "3", "y": "3", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
289
290
  builder.closeTag();
290
291
  builder.closeTag();
291
292
  return parent.firstElementChild;
292
- };
293
+ });
293
294
 
294
295
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/aligntopright.svg
295
- var aligntopright_default = function buildSVG10(parent) {
296
+ var aligntopright_default = (function buildSVG10(parent) {
296
297
  const builder = new DOMBuilder(parent);
297
298
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
298
299
  builder.openTag("rect", { "x": "11", "y": "3", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
299
300
  builder.closeTag();
300
301
  builder.closeTag();
301
302
  return parent.firstElementChild;
302
- };
303
+ });
303
304
 
304
305
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/alignbottomright.svg
305
- var alignbottomright_default = function buildSVG11(parent) {
306
+ var alignbottomright_default = (function buildSVG11(parent) {
306
307
  const builder = new DOMBuilder(parent);
307
308
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
308
309
  builder.openTag("rect", { "x": "11", "y": "11", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
309
310
  builder.closeTag();
310
311
  builder.closeTag();
311
312
  return parent.firstElementChild;
312
- };
313
+ });
313
314
 
314
315
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/alignbottomleft.svg
315
- var alignbottomleft_default = function buildSVG12(parent) {
316
+ var alignbottomleft_default = (function buildSVG12(parent) {
316
317
  const builder = new DOMBuilder(parent);
317
318
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
318
319
  builder.openTag("rect", { "x": "3", "y": "11", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
319
320
  builder.closeTag();
320
321
  builder.closeTag();
321
322
  return parent.firstElementChild;
322
- };
323
+ });
323
324
 
324
325
  // src/ui/ui.ts
325
326
  var pressedClass = "pressed";
@@ -1618,6 +1619,147 @@ var FocusableElementLabelRule = class extends ValidationRule {
1618
1619
  }
1619
1620
  };
1620
1621
 
1622
+ // src/rules/contrast.ts
1623
+ function hexToRgb(hex) {
1624
+ hex = hex.replace(/^#/, "");
1625
+ if (hex.length === 3) {
1626
+ hex = hex.split("").map((x) => x + x).join("");
1627
+ }
1628
+ if (hex.length !== 6) {
1629
+ return null;
1630
+ }
1631
+ const num = parseInt(hex, 16);
1632
+ return [num >> 16 & 255, num >> 8 & 255, num & 255];
1633
+ }
1634
+ function parseColor(color) {
1635
+ color = color.trim();
1636
+ if (color.startsWith("#")) {
1637
+ return hexToRgb(color);
1638
+ }
1639
+ const rgbMatch = color.match(
1640
+ /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)$/
1641
+ );
1642
+ if (rgbMatch) {
1643
+ return [
1644
+ parseInt(rgbMatch[1], 10),
1645
+ parseInt(rgbMatch[2], 10),
1646
+ parseInt(rgbMatch[3], 10)
1647
+ ];
1648
+ }
1649
+ return null;
1650
+ }
1651
+ function luminance([r, g, b]) {
1652
+ const a = [r, g, b].map((v) => {
1653
+ v /= 255;
1654
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
1655
+ });
1656
+ return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
1657
+ }
1658
+ function contrastRatio(l1, l2) {
1659
+ return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
1660
+ }
1661
+ function isTransparent(color) {
1662
+ if (!color) {
1663
+ return true;
1664
+ }
1665
+ color = color.trim();
1666
+ if (color === "transparent" || color === "rgba(0, 0, 0, 0)") {
1667
+ return true;
1668
+ }
1669
+ const rgbaMatch = color.match(/^rgba?\(\d+,\s*\d+,\s*\d+,\s*([\d.]+)\)$/);
1670
+ if (rgbaMatch && parseFloat(rgbaMatch[1]) === 0) {
1671
+ return true;
1672
+ }
1673
+ return false;
1674
+ }
1675
+ var ContrastRule = class extends ValidationRule {
1676
+ constructor() {
1677
+ super(...arguments);
1678
+ __publicField(this, "type", 1 /* Error */);
1679
+ __publicField(this, "name", "ContrastRule");
1680
+ __publicField(this, "anchored", true);
1681
+ }
1682
+ accept(element) {
1683
+ if (!isElementVisible(element)) {
1684
+ return false;
1685
+ }
1686
+ const hasDirectTextContent = Array.from(element.childNodes).some((node) => {
1687
+ var _a;
1688
+ if (node.nodeType === Node.TEXT_NODE) {
1689
+ const text = (_a = node.textContent) == null ? void 0 : _a.trim();
1690
+ return text && text.length > 0;
1691
+ }
1692
+ return false;
1693
+ });
1694
+ return hasDirectTextContent;
1695
+ }
1696
+ validate(element) {
1697
+ const win = this.window;
1698
+ if (!win) {
1699
+ return null;
1700
+ }
1701
+ const style = win.getComputedStyle(element);
1702
+ const fg = parseColor(style.color);
1703
+ if (!fg) {
1704
+ return null;
1705
+ }
1706
+ const hasChildWithDifferentColor = Array.from(element.children).some(
1707
+ (child) => {
1708
+ var _a;
1709
+ if (child instanceof HTMLElement && ((_a = child.textContent) == null ? void 0 : _a.trim())) {
1710
+ const childStyle = win.getComputedStyle(child);
1711
+ const childColor = parseColor(childStyle.color);
1712
+ if (childColor && (childColor[0] !== fg[0] || childColor[1] !== fg[1] || childColor[2] !== fg[2])) {
1713
+ return true;
1714
+ }
1715
+ }
1716
+ return false;
1717
+ }
1718
+ );
1719
+ if (hasChildWithDifferentColor) {
1720
+ return null;
1721
+ }
1722
+ let bg = null;
1723
+ let el = element;
1724
+ let depth = 0;
1725
+ const maxDepth = 50;
1726
+ while (el && depth < maxDepth) {
1727
+ const bgColor = win.getComputedStyle(el).backgroundColor;
1728
+ if (!isTransparent(bgColor)) {
1729
+ const parsedBg = parseColor(bgColor);
1730
+ if (parsedBg) {
1731
+ bg = parsedBg;
1732
+ break;
1733
+ }
1734
+ }
1735
+ el = el.parentElement;
1736
+ depth++;
1737
+ }
1738
+ if (!bg) {
1739
+ bg = [255, 255, 255];
1740
+ }
1741
+ const l1 = luminance(fg);
1742
+ const l2 = luminance(bg);
1743
+ const ratio = contrastRatio(l1, l2);
1744
+ const fontSize = parseFloat(style.fontSize);
1745
+ const fontWeight = style.fontWeight;
1746
+ const isBold = fontWeight === "bold" || fontWeight === "bolder" || parseInt(fontWeight, 10) >= 700;
1747
+ const isLarge = fontSize >= 24 || fontSize >= 18.66 && isBold;
1748
+ const minRatio = isLarge ? 3 : 4.5;
1749
+ if (ratio < minRatio) {
1750
+ return {
1751
+ issue: {
1752
+ id: "contrast",
1753
+ message: `Text contrast ratio is ${ratio.toFixed(2)}:1, which is below the minimum of ${minRatio}:1 (text: rgb(${fg.join(", ")}), background: rgb(${bg.join(", ")})) on ${element.tagName}`,
1754
+ element,
1755
+ help: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html"
1756
+ }
1757
+ };
1758
+ }
1759
+ return null;
1760
+ }
1761
+ };
1762
+
1621
1763
  // src/rules/existingid.ts
1622
1764
  var ExistingIdRule = class extends ValidationRule {
1623
1765
  constructor() {
@@ -1869,6 +2011,7 @@ var CustomNotifyRule = class extends ValidationRule {
1869
2011
  AbleDOM,
1870
2012
  AtomicRule,
1871
2013
  BadFocusRule,
2014
+ ContrastRule,
1872
2015
  CustomNotifyRule,
1873
2016
  ExistingIdRule,
1874
2017
  FindElementRule,