@jomae/catalog 0.3.0 → 0.6.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.
Files changed (257) hide show
  1. package/README.md +21 -3
  2. package/dist/baseline.d.ts +36 -0
  3. package/dist/baseline.d.ts.map +1 -1
  4. package/dist/baseline.js +75 -2
  5. package/dist/baseline.js.map +1 -1
  6. package/dist/categories.d.ts +20 -0
  7. package/dist/categories.d.ts.map +1 -0
  8. package/dist/categories.js +62 -0
  9. package/dist/categories.js.map +1 -0
  10. package/dist/detect.d.ts +2 -1
  11. package/dist/detect.d.ts.map +1 -1
  12. package/dist/detect.js +17 -2
  13. package/dist/detect.js.map +1 -1
  14. package/dist/format.js +1 -1
  15. package/dist/format.js.map +1 -1
  16. package/dist/generated/baseline-history.d.ts +21 -0
  17. package/dist/generated/baseline-history.d.ts.map +1 -0
  18. package/dist/generated/baseline-history.js +20 -0
  19. package/dist/generated/baseline-history.js.map +1 -0
  20. package/dist/generated/baseline.d.ts +16 -0
  21. package/dist/generated/baseline.d.ts.map +1 -1
  22. package/dist/generated/baseline.js +683 -44
  23. package/dist/generated/baseline.js.map +1 -1
  24. package/dist/generated/guides.d.ts +16 -0
  25. package/dist/generated/guides.d.ts.map +1 -0
  26. package/dist/generated/guides.js +153 -0
  27. package/dist/generated/guides.js.map +1 -0
  28. package/dist/generated/sizes.d.ts.map +1 -1
  29. package/dist/generated/sizes.js +683 -48
  30. package/dist/generated/sizes.js.map +1 -1
  31. package/dist/generated/support-claims.d.ts +15 -0
  32. package/dist/generated/support-claims.d.ts.map +1 -0
  33. package/dist/generated/support-claims.js +69 -0
  34. package/dist/generated/support-claims.js.map +1 -0
  35. package/dist/guides.d.ts +46 -0
  36. package/dist/guides.d.ts.map +1 -0
  37. package/dist/guides.js +55 -0
  38. package/dist/guides.js.map +1 -0
  39. package/dist/history.d.ts +11 -0
  40. package/dist/history.d.ts.map +1 -0
  41. package/dist/history.js +14 -0
  42. package/dist/history.js.map +1 -0
  43. package/dist/index.d.ts +5 -1
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +5 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/rules/abort-controller.d.ts +3 -0
  48. package/dist/rules/abort-controller.d.ts.map +1 -0
  49. package/dist/rules/abort-controller.js +26 -0
  50. package/dist/rules/abort-controller.js.map +1 -0
  51. package/dist/rules/accordion.d.ts.map +1 -1
  52. package/dist/rules/accordion.js +3 -0
  53. package/dist/rules/accordion.js.map +1 -1
  54. package/dist/rules/array-grouping.d.ts +3 -0
  55. package/dist/rules/array-grouping.d.ts.map +1 -0
  56. package/dist/rules/array-grouping.js +29 -0
  57. package/dist/rules/array-grouping.js.map +1 -0
  58. package/dist/rules/aspect-ratio.d.ts.map +1 -1
  59. package/dist/rules/aspect-ratio.js +1 -0
  60. package/dist/rules/aspect-ratio.js.map +1 -1
  61. package/dist/rules/base64.d.ts +3 -0
  62. package/dist/rules/base64.d.ts.map +1 -0
  63. package/dist/rules/base64.js +41 -0
  64. package/dist/rules/base64.js.map +1 -0
  65. package/dist/rules/broadcast-channel.d.ts +3 -0
  66. package/dist/rules/broadcast-channel.d.ts.map +1 -0
  67. package/dist/rules/broadcast-channel.js +26 -0
  68. package/dist/rules/broadcast-channel.js.map +1 -0
  69. package/dist/rules/carousel.d.ts.map +1 -1
  70. package/dist/rules/carousel.js +10 -0
  71. package/dist/rules/carousel.js.map +1 -1
  72. package/dist/rules/clipboard.d.ts +3 -0
  73. package/dist/rules/clipboard.d.ts.map +1 -0
  74. package/dist/rules/clipboard.js +35 -0
  75. package/dist/rules/clipboard.js.map +1 -0
  76. package/dist/rules/color-functions.d.ts.map +1 -1
  77. package/dist/rules/color-functions.js +9 -1
  78. package/dist/rules/color-functions.js.map +1 -1
  79. package/dist/rules/compression-streams.d.ts +3 -0
  80. package/dist/rules/compression-streams.d.ts.map +1 -0
  81. package/dist/rules/compression-streams.js +26 -0
  82. package/dist/rules/compression-streams.js.map +1 -0
  83. package/dist/rules/container-queries.d.ts.map +1 -1
  84. package/dist/rules/container-queries.js +3 -0
  85. package/dist/rules/container-queries.js.map +1 -1
  86. package/dist/rules/content-visibility.d.ts.map +1 -1
  87. package/dist/rules/content-visibility.js +11 -2
  88. package/dist/rules/content-visibility.js.map +1 -1
  89. package/dist/rules/custom-highlight.d.ts +3 -0
  90. package/dist/rules/custom-highlight.d.ts.map +1 -0
  91. package/dist/rules/custom-highlight.js +39 -0
  92. package/dist/rules/custom-highlight.js.map +1 -0
  93. package/dist/rules/date-time-input.d.ts.map +1 -1
  94. package/dist/rules/date-time-input.js +4 -0
  95. package/dist/rules/date-time-input.js.map +1 -1
  96. package/dist/rules/dialog.d.ts.map +1 -1
  97. package/dist/rules/dialog.js +11 -0
  98. package/dist/rules/dialog.js.map +1 -1
  99. package/dist/rules/discrete-transitions.d.ts.map +1 -1
  100. package/dist/rules/discrete-transitions.js +6 -0
  101. package/dist/rules/discrete-transitions.js.map +1 -1
  102. package/dist/rules/drag-and-drop.d.ts +3 -0
  103. package/dist/rules/drag-and-drop.d.ts.map +1 -0
  104. package/dist/rules/drag-and-drop.js +47 -0
  105. package/dist/rules/drag-and-drop.js.map +1 -0
  106. package/dist/rules/duration-format.d.ts +3 -0
  107. package/dist/rules/duration-format.d.ts.map +1 -0
  108. package/dist/rules/duration-format.js +37 -0
  109. package/dist/rules/duration-format.js.map +1 -0
  110. package/dist/rules/event-target.d.ts +3 -0
  111. package/dist/rules/event-target.d.ts.map +1 -0
  112. package/dist/rules/event-target.js +51 -0
  113. package/dist/rules/event-target.js.map +1 -0
  114. package/dist/rules/fetch.d.ts +3 -0
  115. package/dist/rules/fetch.d.ts.map +1 -0
  116. package/dist/rules/fetch.js +46 -0
  117. package/dist/rules/fetch.js.map +1 -0
  118. package/dist/rules/field-sizing.d.ts.map +1 -1
  119. package/dist/rules/field-sizing.js +10 -2
  120. package/dist/rules/field-sizing.js.map +1 -1
  121. package/dist/rules/fluid-type.d.ts.map +1 -1
  122. package/dist/rules/fluid-type.js +3 -1
  123. package/dist/rules/fluid-type.js.map +1 -1
  124. package/dist/rules/focus-visible.d.ts +3 -0
  125. package/dist/rules/focus-visible.d.ts.map +1 -0
  126. package/dist/rules/focus-visible.js +27 -0
  127. package/dist/rules/focus-visible.js.map +1 -0
  128. package/dist/rules/fullscreen.d.ts +3 -0
  129. package/dist/rules/fullscreen.d.ts.map +1 -0
  130. package/dist/rules/fullscreen.js +29 -0
  131. package/dist/rules/fullscreen.js.map +1 -0
  132. package/dist/rules/height-animation.d.ts.map +1 -1
  133. package/dist/rules/height-animation.js +2 -0
  134. package/dist/rules/height-animation.js.map +1 -1
  135. package/dist/rules/index.d.ts.map +1 -1
  136. package/dist/rules/index.js +102 -3
  137. package/dist/rules/index.js.map +1 -1
  138. package/dist/rules/inert.d.ts +3 -0
  139. package/dist/rules/inert.d.ts.map +1 -0
  140. package/dist/rules/inert.js +37 -0
  141. package/dist/rules/inert.js.map +1 -0
  142. package/dist/rules/intersection-observer.d.ts +3 -0
  143. package/dist/rules/intersection-observer.d.ts.map +1 -0
  144. package/dist/rules/intersection-observer.js +36 -0
  145. package/dist/rules/intersection-observer.js.map +1 -0
  146. package/dist/rules/lazy-loading.d.ts.map +1 -1
  147. package/dist/rules/lazy-loading.js +4 -0
  148. package/dist/rules/lazy-loading.js.map +1 -1
  149. package/dist/rules/line-clamp.d.ts +3 -0
  150. package/dist/rules/line-clamp.d.ts.map +1 -0
  151. package/dist/rules/line-clamp.js +39 -0
  152. package/dist/rules/line-clamp.js.map +1 -0
  153. package/dist/rules/masonry.d.ts.map +1 -1
  154. package/dist/rules/masonry.js +3 -0
  155. package/dist/rules/masonry.js.map +1 -1
  156. package/dist/rules/natural-sort.d.ts +3 -0
  157. package/dist/rules/natural-sort.d.ts.map +1 -0
  158. package/dist/rules/natural-sort.js +41 -0
  159. package/dist/rules/natural-sort.js.map +1 -0
  160. package/dist/rules/number-format.d.ts +3 -0
  161. package/dist/rules/number-format.d.ts.map +1 -0
  162. package/dist/rules/number-format.js +27 -0
  163. package/dist/rules/number-format.js.map +1 -0
  164. package/dist/rules/page-visibility.d.ts +3 -0
  165. package/dist/rules/page-visibility.d.ts.map +1 -0
  166. package/dist/rules/page-visibility.js +29 -0
  167. package/dist/rules/page-visibility.js.map +1 -0
  168. package/dist/rules/popover.d.ts.map +1 -1
  169. package/dist/rules/popover.js +10 -1
  170. package/dist/rules/popover.js.map +1 -1
  171. package/dist/rules/random-uuid.d.ts +3 -0
  172. package/dist/rules/random-uuid.d.ts.map +1 -0
  173. package/dist/rules/random-uuid.js +31 -0
  174. package/dist/rules/random-uuid.js.map +1 -0
  175. package/dist/rules/relative-time.d.ts +3 -0
  176. package/dist/rules/relative-time.d.ts.map +1 -0
  177. package/dist/rules/relative-time.js +24 -0
  178. package/dist/rules/relative-time.js.map +1 -0
  179. package/dist/rules/resizable-panels.d.ts.map +1 -1
  180. package/dist/rules/resizable-panels.js +4 -2
  181. package/dist/rules/resizable-panels.js.map +1 -1
  182. package/dist/rules/resize-observer.d.ts +3 -0
  183. package/dist/rules/resize-observer.d.ts.map +1 -0
  184. package/dist/rules/resize-observer.js +28 -0
  185. package/dist/rules/resize-observer.js.map +1 -0
  186. package/dist/rules/screen-wake-lock.d.ts +3 -0
  187. package/dist/rules/screen-wake-lock.d.ts.map +1 -0
  188. package/dist/rules/screen-wake-lock.js +25 -0
  189. package/dist/rules/screen-wake-lock.js.map +1 -0
  190. package/dist/rules/scroll-animations.d.ts.map +1 -1
  191. package/dist/rules/scroll-animations.js +9 -1
  192. package/dist/rules/scroll-animations.js.map +1 -1
  193. package/dist/rules/scroll-lock.d.ts.map +1 -1
  194. package/dist/rules/scroll-lock.js +8 -7
  195. package/dist/rules/scroll-lock.js.map +1 -1
  196. package/dist/rules/scrollbars.d.ts.map +1 -1
  197. package/dist/rules/scrollbars.js +8 -0
  198. package/dist/rules/scrollbars.js.map +1 -1
  199. package/dist/rules/select.d.ts.map +1 -1
  200. package/dist/rules/select.js +17 -1
  201. package/dist/rules/select.js.map +1 -1
  202. package/dist/rules/server-sent-events.d.ts +3 -0
  203. package/dist/rules/server-sent-events.d.ts.map +1 -0
  204. package/dist/rules/server-sent-events.js +38 -0
  205. package/dist/rules/server-sent-events.js.map +1 -0
  206. package/dist/rules/smooth-scroll.d.ts.map +1 -1
  207. package/dist/rules/smooth-scroll.js +3 -0
  208. package/dist/rules/smooth-scroll.js.map +1 -1
  209. package/dist/rules/speech-recognition.d.ts +3 -0
  210. package/dist/rules/speech-recognition.d.ts.map +1 -0
  211. package/dist/rules/speech-recognition.js +36 -0
  212. package/dist/rules/speech-recognition.js.map +1 -0
  213. package/dist/rules/speech-synthesis.d.ts +3 -0
  214. package/dist/rules/speech-synthesis.d.ts.map +1 -0
  215. package/dist/rules/speech-synthesis.js +25 -0
  216. package/dist/rules/speech-synthesis.js.map +1 -0
  217. package/dist/rules/sticky.d.ts.map +1 -1
  218. package/dist/rules/sticky.js +4 -0
  219. package/dist/rules/sticky.js.map +1 -1
  220. package/dist/rules/structured-clone.d.ts +3 -0
  221. package/dist/rules/structured-clone.d.ts.map +1 -0
  222. package/dist/rules/structured-clone.js +32 -0
  223. package/dist/rules/structured-clone.js.map +1 -0
  224. package/dist/rules/text-box-trim.d.ts.map +1 -1
  225. package/dist/rules/text-box-trim.js +3 -1
  226. package/dist/rules/text-box-trim.js.map +1 -1
  227. package/dist/rules/text-wrap-balance.d.ts.map +1 -1
  228. package/dist/rules/text-wrap-balance.js +2 -0
  229. package/dist/rules/text-wrap-balance.js.map +1 -1
  230. package/dist/rules/url-search-params.d.ts +3 -0
  231. package/dist/rules/url-search-params.d.ts.map +1 -0
  232. package/dist/rules/url-search-params.js +42 -0
  233. package/dist/rules/url-search-params.js.map +1 -0
  234. package/dist/rules/view-transitions.d.ts.map +1 -1
  235. package/dist/rules/view-transitions.js +9 -0
  236. package/dist/rules/view-transitions.js.map +1 -1
  237. package/dist/rules/web-bluetooth.d.ts +3 -0
  238. package/dist/rules/web-bluetooth.d.ts.map +1 -0
  239. package/dist/rules/web-bluetooth.js +26 -0
  240. package/dist/rules/web-bluetooth.js.map +1 -0
  241. package/dist/rules/web-crypto.d.ts +3 -0
  242. package/dist/rules/web-crypto.d.ts.map +1 -0
  243. package/dist/rules/web-crypto.js +32 -0
  244. package/dist/rules/web-crypto.js.map +1 -0
  245. package/dist/rules/web-share.d.ts +3 -0
  246. package/dist/rules/web-share.d.ts.map +1 -0
  247. package/dist/rules/web-share.js +28 -0
  248. package/dist/rules/web-share.js.map +1 -0
  249. package/dist/schema.d.ts +22 -0
  250. package/dist/schema.d.ts.map +1 -1
  251. package/dist/schema.js +64 -5
  252. package/dist/schema.js.map +1 -1
  253. package/dist/support.d.ts +11 -0
  254. package/dist/support.d.ts.map +1 -0
  255. package/dist/support.js +31 -0
  256. package/dist/support.js.map +1 -0
  257. package/package.json +2 -2
@@ -0,0 +1,46 @@
1
+ export const fetchRule = {
2
+ id: "fetch",
3
+ title: "HTTP requests",
4
+ category: "async-data",
5
+ replaces: [
6
+ "axios",
7
+ "superagent",
8
+ "redaxios",
9
+ "whatwg-fetch",
10
+ "unfetch",
11
+ "isomorphic-fetch",
12
+ "cross-fetch",
13
+ ],
14
+ featureIds: ["fetch"],
15
+ native: "fetch()",
16
+ human: {
17
+ explainer: "axios was written when fetch was not everywhere and XMLHttpRequest was the floor. Most of what it adds is now a few lines at the call site: fetch resolves for any response the server sent, so you check response.ok yourself, and it hands back a stream, so you call response.json(). Cancellation is an AbortController, and a timeout is AbortSignal.timeout() passed as the signal. Interceptors and upload progress are what is genuinely missing, and they are the reasons to keep the library.",
18
+ snippet: `const res = await fetch("/api/items", {
19
+ method: "POST",
20
+ headers: { "Content-Type": "application/json" },
21
+ body: JSON.stringify(payload),
22
+ // Aborts and rejects after five seconds.
23
+ signal: AbortSignal.timeout(5000),
24
+ });
25
+
26
+ // fetch only rejects on a network error, so check the status yourself.
27
+ if (!res.ok) throw new Error(\`\${res.status} \${res.statusText}\`);
28
+ const items = await res.json();`,
29
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch",
30
+ },
31
+ agent: {
32
+ when: "making HTTP requests from the browser or from Node {{nodejs:api.fetch}} and up",
33
+ unless: [
34
+ "You use interceptors to attach auth headers or refresh a token on 401 across every call. fetch has no hook for that, so it becomes a wrapper every request has to route through.",
35
+ "You rely on a 4xx or 5xx rejecting. fetch resolves for any response the server sent, so every call site needs an explicit response.ok check and existing catch blocks quietly stop firing.",
36
+ "You need upload progress. Download progress can come off the response stream, but tracking bytes sent still needs XMLHttpRequest, which is what axios uses underneath.",
37
+ "You share one client with Node below {{nodejs:api.fetch}}, where there is no global fetch, or you depend on axios features with no equivalent: XSRF cookie handling, automatic transforms, or the adapter system.",
38
+ "Your tests mock axios directly. Moving to fetch means rewriting those mocks, which is real work for no behaviour change.",
39
+ "You need a request timeout below Chrome {{chrome:abortsignal-timeout}}, Safari {{safari:abortsignal-timeout}} or Firefox {{firefox:abortsignal-timeout}}. fetch itself is far older than all three, but AbortSignal.timeout() is not, so an older target needs a setTimeout calling controller.abort().",
40
+ ],
41
+ snippet: `const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
42
+ if (!res.ok) throw new Error(String(res.status));
43
+ const data = await res.json();`,
44
+ },
45
+ };
46
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/rules/fetch.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,eAAe;IACtB,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,OAAO;QACP,YAAY;QACZ,UAAU;QACV,cAAc;QACd,SAAS;QACT,kBAAkB;QAClB,aAAa;KACd;IACD,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE;QACL,SAAS,EACP,yeAAye;QAC3e,OAAO,EAAE;;;;;;;;;;gCAUmB;QAC5B,MAAM,EAAE,+DAA+D;KACxE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gFAAgF;QACtF,MAAM,EAAE;YACN,kLAAkL;YAClL,4LAA4L;YAC5L,wKAAwK;YACxK,mNAAmN;YACnN,0HAA0H;YAC1H,ySAAyS;SAC1S;QACD,OAAO,EAAE;;+BAEkB;KAC5B;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"field-sizing.d.ts","sourceRoot":"","sources":["../../src/rules/field-sizing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IAqCzB,CAAC"}
1
+ {"version":3,"file":"field-sizing.d.ts","sourceRoot":"","sources":["../../src/rules/field-sizing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IA6CzB,CAAC"}
@@ -1,7 +1,14 @@
1
1
  export const fieldSizing = {
2
2
  id: "field-sizing",
3
3
  title: "Auto-growing textareas",
4
- replaces: ["react-textarea-autosize", "autosize", "react-autosize-textarea"],
4
+ category: "forms",
5
+ replaces: [
6
+ "react-textarea-autosize",
7
+ "autosize",
8
+ "react-autosize-textarea",
9
+ "vue-textarea-autosize",
10
+ "ngx-autosize",
11
+ ],
5
12
  featureIds: ["field-sizing"],
6
13
  native: "field-sizing: content",
7
14
  human: {
@@ -24,7 +31,7 @@ input[type="text"] {
24
31
  agent: {
25
32
  when: "a textarea or input should grow to fit what the user has typed",
26
33
  unless: [
27
- "You need Safari or Firefox support today. field-sizing reached Baseline newly available only in mid-2026, so verify against your support target and keep a fallback if you cannot afford a fixed-height textarea.",
34
+ "Your support target reaches below Chrome {{chrome:field-sizing}}, Firefox {{firefox:field-sizing}} or Safari {{safari:field-sizing}}. Every engine ships field-sizing now, but Safari only at the end of 2025 and Firefox in 2026, so an older target still needs the fallback.",
28
35
  "You need the measured height in JavaScript, for example to sync a neighbouring element.",
29
36
  "You need to animate the height change. field-sizing resizes without a transition.",
30
37
  ],
@@ -34,5 +41,6 @@ input[type="text"] {
34
41
  max-height: 12lh;
35
42
  }`,
36
43
  },
44
+ guides: ["form-fields-automatically-fit-contents"],
37
45
  };
38
46
  //# sourceMappingURL=field-sizing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-sizing.js","sourceRoot":"","sources":["../../src/rules/field-sizing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,wBAAwB;IAC/B,QAAQ,EAAE,CAAC,yBAAyB,EAAE,UAAU,EAAE,yBAAyB,CAAC;IAC5E,UAAU,EAAE,CAAC,cAAc,CAAC;IAC5B,MAAM,EAAE,uBAAuB;IAC/B,KAAK,EAAE;QACL,SAAS,EACP,oYAAoY;QACtY,OAAO,EAAE;;;;;;;;;;;;EAYX;QACE,MAAM,EAAE,+DAA+D;KACxE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gEAAgE;QACtE,MAAM,EAAE;YACN,mNAAmN;YACnN,yFAAyF;YACzF,mFAAmF;SACpF;QACD,OAAO,EAAE;;;;EAIX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"field-sizing.js","sourceRoot":"","sources":["../../src/rules/field-sizing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,wBAAwB;IAC/B,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE;QACR,yBAAyB;QACzB,UAAU;QACV,yBAAyB;QACzB,uBAAuB;QACvB,cAAc;KACf;IACD,UAAU,EAAE,CAAC,cAAc,CAAC;IAC5B,MAAM,EAAE,uBAAuB;IAC/B,KAAK,EAAE;QACL,SAAS,EACP,oYAAoY;QACtY,OAAO,EAAE;;;;;;;;;;;;EAYX;QACE,MAAM,EAAE,+DAA+D;KACxE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gEAAgE;QACtE,MAAM,EAAE;YACN,iRAAiR;YACjR,yFAAyF;YACzF,mFAAmF;SACpF;QACD,OAAO,EAAE;;;;EAIX;KACC;IACD,MAAM,EAAE,CAAC,wCAAwC,CAAC;CACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fluid-type.d.ts","sourceRoot":"","sources":["../../src/rules/fluid-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,IA8BvB,CAAC"}
1
+ {"version":3,"file":"fluid-type.d.ts","sourceRoot":"","sources":["../../src/rules/fluid-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,IAgCvB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  export const fluidType = {
2
2
  id: "fluid-type-clamp",
3
3
  title: "Fluid type scales",
4
- replaces: ["fitty", "fittext.js", "textfit", "react-textfit"],
4
+ category: "typography",
5
+ replaces: ["fittext.js"],
5
6
  featureIds: ["min-max-clamp"],
6
7
  native: "clamp() with a viewport-relative middle value",
7
8
  human: {
@@ -27,5 +28,6 @@ export const fluidType = {
27
28
  snippet: `h1 { font-size: clamp(2rem, 1.5rem + 2.5vw, 4rem); }
28
29
  .card h2 { font-size: clamp(1.25rem, 0.9rem + 2cqi, 2rem); }`,
29
30
  },
31
+ guides: ["fluid-scaling"],
30
32
  };
31
33
  //# sourceMappingURL=fluid-type.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fluid-type.js","sourceRoot":"","sources":["../../src/rules/fluid-type.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,CAAC;IAC7D,UAAU,EAAE,CAAC,eAAe,CAAC;IAC7B,MAAM,EAAE,+CAA+C;IACvD,KAAK,EAAE;QACL,SAAS,EACP,uaAAua;QACza,OAAO,EAAE;;;;;;;;EAQX;QACE,MAAM,EAAE,wDAAwD;KACjE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6FAA6F;QACnG,MAAM,EAAE;YACN,oMAAoM;YACpM,gGAAgG;YAChG,kDAAkD;SACnD;QACD,OAAO,EAAE;6DACgD;KAC1D;CACF,CAAC"}
1
+ {"version":3,"file":"fluid-type.js","sourceRoot":"","sources":["../../src/rules/fluid-type.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,YAAY,CAAC;IACxB,UAAU,EAAE,CAAC,eAAe,CAAC;IAC7B,MAAM,EAAE,+CAA+C;IACvD,KAAK,EAAE;QACL,SAAS,EACP,uaAAua;QACza,OAAO,EAAE;;;;;;;;EAQX;QACE,MAAM,EAAE,wDAAwD;KACjE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6FAA6F;QACnG,MAAM,EAAE;YACN,oMAAoM;YACpM,gGAAgG;YAChG,kDAAkD;SACnD;QACD,OAAO,EAAE;6DACgD;KAC1D;IACD,MAAM,EAAE,CAAC,eAAe,CAAC;CAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const focusVisible: Rule;
3
+ //# sourceMappingURL=focus-visible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible.d.ts","sourceRoot":"","sources":["../../src/rules/focus-visible.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IA0B1B,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const focusVisible = {
2
+ id: "focus-visible",
3
+ title: "Keyboard-only focus styling",
4
+ category: "forms",
5
+ replaces: ["focus-visible"],
6
+ featureIds: ["focus-visible"],
7
+ native: ":focus-visible",
8
+ human: {
9
+ explainer: "The focus-visible polyfill watches whether the last interaction was a keyboard press or a pointer click, then toggles a class so a mouse click doesn't leave a focus ring behind. The CSS pseudo-class :focus-visible does that same judgment call natively: the browser decides whether focus came from something that benefits from a visible ring, no JavaScript class-toggling required.",
10
+ snippet: `button:focus {
11
+ outline: none;
12
+ }
13
+ button:focus-visible {
14
+ outline: 2px solid var(--accent);
15
+ }`,
16
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible",
17
+ },
18
+ agent: {
19
+ when: "showing a focus ring only for keyboard or other non-pointer focus, not for a mouse click",
20
+ unless: [
21
+ "You need to support Internet Explorer or a browser old enough to predate :focus-visible, which the polyfill's JS-based heuristic still covers.",
22
+ "You need the exact same heuristic across every browser version, including ones that shipped :focus-visible before the spec's behavior settled. Small heuristic differences existed early on.",
23
+ ],
24
+ snippet: "button:focus-visible { outline: 2px solid var(--accent); }",
25
+ },
26
+ };
27
+ //# sourceMappingURL=focus-visible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-visible.js","sourceRoot":"","sources":["../../src/rules/focus-visible.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,UAAU,EAAE,CAAC,eAAe,CAAC;IAC7B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE;QACL,SAAS,EACP,8XAA8X;QAChY,OAAO,EAAE;;;;;EAKX;QACE,MAAM,EAAE,iEAAiE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0FAA0F;QAChG,MAAM,EAAE;YACN,gJAAgJ;YAChJ,8LAA8L;SAC/L;QACD,OAAO,EAAE,4DAA4D;KACtE;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const fullscreen: Rule;
3
+ //# sourceMappingURL=fullscreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullscreen.d.ts","sourceRoot":"","sources":["../../src/rules/fullscreen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IA8BxB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export const fullscreen = {
2
+ id: "fullscreen",
3
+ title: "Fullscreen toggling",
4
+ category: "device-apis",
5
+ replaces: ["screenfull", "react-full-screen", "vue-fullscreen"],
6
+ featureIds: ["fullscreen"],
7
+ native: "Element.requestFullscreen()",
8
+ human: {
9
+ explainer: "screenfull's whole job is normalizing the vendor-prefixed versions of this API across engines. Now that every major browser ships the unprefixed requestFullscreen()/exitFullscreen() pair, that normalization layer is no longer needed for current versions.",
10
+ snippet: `async function toggleFullscreen(el) {
11
+ if (document.fullscreenElement) {
12
+ await document.exitFullscreen();
13
+ } else {
14
+ await el.requestFullscreen();
15
+ }
16
+ }`,
17
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen",
18
+ },
19
+ agent: {
20
+ when: "toggling an element, such as a video player or image viewer, into and out of fullscreen",
21
+ unless: [
22
+ "You support Safari below {{safari:api.Element.requestFullscreen}}, where the unprefixed API only recently landed.",
23
+ "You're targeting iOS Safari specifically. It still doesn't support fullscreen on arbitrary elements, only on the built-in video player.",
24
+ "You need the older vendor-prefixed fallback chain screenfull still maintains for browsers this old.",
25
+ ],
26
+ snippet: "document.fullscreenElement ? document.exitFullscreen() : el.requestFullscreen();",
27
+ },
28
+ };
29
+ //# sourceMappingURL=fullscreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullscreen.js","sourceRoot":"","sources":["../../src/rules/fullscreen.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,YAAY;IAChB,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE,aAAa;IACvB,QAAQ,EAAE,CAAC,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,CAAC;IAC/D,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,MAAM,EAAE,6BAA6B;IACrC,KAAK,EAAE;QACL,SAAS,EACP,gQAAgQ;QAClQ,OAAO,EAAE;;;;;;EAMX;QACE,MAAM,EACJ,4EAA4E;KAC/E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,yFAAyF;QAC/F,MAAM,EAAE;YACN,mHAAmH;YACnH,yIAAyI;YACzI,qGAAqG;SACtG;QACD,OAAO,EACL,kFAAkF;KACrF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"height-animation.d.ts","sourceRoot":"","sources":["../../src/rules/height-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IA8C7B,CAAC"}
1
+ {"version":3,"file":"height-animation.d.ts","sourceRoot":"","sources":["../../src/rules/height-animation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAgD7B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export const heightAnimation = {
2
2
  id: "height-auto-animation",
3
3
  title: "Animating to height auto",
4
+ category: "animation",
4
5
  replaces: ["react-collapse", "react-animate-height", "react-smooth-collapse"],
5
6
  featureIds: ["interpolate-size", "calc-size"],
6
7
  native: "interpolate-size: allow-keywords, or calc-size()",
@@ -43,5 +44,6 @@ export const heightAnimation = {
43
44
  .panel { height: 0; overflow: hidden; transition: height 0.3s; }
44
45
  .panel[data-open] { height: auto; }`,
45
46
  },
47
+ guides: ["animate-to-intrinsic-sizes"],
46
48
  };
47
49
  //# sourceMappingURL=height-animation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"height-animation.js","sourceRoot":"","sources":["../../src/rules/height-animation.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,uBAAuB;IAC3B,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,CAAC;IAC7E,UAAU,EAAE,CAAC,kBAAkB,EAAE,WAAW,CAAC;IAC7C,MAAM,EAAE,kDAAkD;IAC1D,KAAK,EAAE;QACL,SAAS,EACP,ybAAyb;QAC3b,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;EAsBX;QACE,MAAM,EAAE,4DAA4D;KACrE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qEAAqE;QAC3E,MAAM,EAAE;YACN,4NAA4N;YAC5N,6IAA6I;YAC7I,gGAAgG;YAChG,8GAA8G;SAC/G;QACD,OAAO,EAAE;;oCAEuB;KACjC;CACF,CAAC"}
1
+ {"version":3,"file":"height-animation.js","sourceRoot":"","sources":["../../src/rules/height-animation.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,uBAAuB;IAC3B,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,CAAC;IAC7E,UAAU,EAAE,CAAC,kBAAkB,EAAE,WAAW,CAAC;IAC7C,MAAM,EAAE,kDAAkD;IAC1D,KAAK,EAAE;QACL,SAAS,EACP,ybAAyb;QAC3b,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;EAsBX;QACE,MAAM,EAAE,4DAA4D;KACrE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qEAAqE;QAC3E,MAAM,EAAE;YACN,4NAA4N;YAC5N,6IAA6I;YAC7I,gGAAgG;YAChG,8GAA8G;SAC/G;QACD,OAAO,EAAE;;oCAEuB;KACjC;IACD,MAAM,EAAE,CAAC,4BAA4B,CAAC;CACvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AA2BzC;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,SAAS,IAAI,EA0BhC,CAAC;AAEF,yBAAyB;AACzB,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAE/C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAEpD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AA0JzC;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,SAAS,IAAI,EAAqC,CAAC;AAEvE,yBAAyB;AACzB,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAE/C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAEpD,CAAC"}
@@ -1,59 +1,158 @@
1
+ import { resolveSupportClaims } from "../support.js";
2
+ import { abortController } from "./abort-controller.js";
1
3
  import { accordion } from "./accordion.js";
4
+ import { arrayGrouping } from "./array-grouping.js";
2
5
  import { aspectRatio } from "./aspect-ratio.js";
6
+ import { base64 } from "./base64.js";
7
+ import { broadcastChannel } from "./broadcast-channel.js";
3
8
  import { carousel } from "./carousel.js";
9
+ import { clipboard } from "./clipboard.js";
4
10
  import { colorFunctions } from "./color-functions.js";
11
+ import { compressionStreams } from "./compression-streams.js";
5
12
  import { containerQueries } from "./container-queries.js";
6
13
  import { contentVisibility } from "./content-visibility.js";
14
+ import { customHighlight } from "./custom-highlight.js";
7
15
  import { dateTimeInput } from "./date-time-input.js";
8
16
  import { dialog } from "./dialog.js";
9
17
  import { discreteTransitions } from "./discrete-transitions.js";
18
+ import { dragAndDrop } from "./drag-and-drop.js";
19
+ import { durationFormat } from "./duration-format.js";
20
+ import { eventTarget } from "./event-target.js";
21
+ import { fetchRule } from "./fetch.js";
10
22
  import { fieldSizing } from "./field-sizing.js";
11
23
  import { fluidType } from "./fluid-type.js";
24
+ import { focusVisible } from "./focus-visible.js";
25
+ import { fullscreen } from "./fullscreen.js";
12
26
  import { heightAnimation } from "./height-animation.js";
27
+ import { inert } from "./inert.js";
28
+ import { intersectionObserver } from "./intersection-observer.js";
13
29
  import { lazyLoading } from "./lazy-loading.js";
30
+ import { lineClamp } from "./line-clamp.js";
14
31
  import { masonry } from "./masonry.js";
32
+ import { naturalSort } from "./natural-sort.js";
33
+ import { numberFormat } from "./number-format.js";
34
+ import { pageVisibility } from "./page-visibility.js";
15
35
  import { popover } from "./popover.js";
36
+ import { randomUuid } from "./random-uuid.js";
37
+ import { relativeTime } from "./relative-time.js";
16
38
  import { resizablePanels } from "./resizable-panels.js";
39
+ import { resizeObserver } from "./resize-observer.js";
40
+ import { screenWakeLock } from "./screen-wake-lock.js";
17
41
  import { scrollAnimations } from "./scroll-animations.js";
18
42
  import { scrollLock } from "./scroll-lock.js";
19
43
  import { scrollbars } from "./scrollbars.js";
20
44
  import { select } from "./select.js";
45
+ import { serverSentEvents } from "./server-sent-events.js";
21
46
  import { smoothScroll } from "./smooth-scroll.js";
47
+ import { speechRecognition } from "./speech-recognition.js";
48
+ import { speechSynthesis } from "./speech-synthesis.js";
22
49
  import { sticky } from "./sticky.js";
50
+ import { structuredCloneRule } from "./structured-clone.js";
23
51
  import { textBoxTrim } from "./text-box-trim.js";
24
52
  import { textWrapBalance } from "./text-wrap-balance.js";
53
+ import { urlSearchParams } from "./url-search-params.js";
25
54
  import { viewTransitions } from "./view-transitions.js";
55
+ import { webBluetooth } from "./web-bluetooth.js";
56
+ import { webCrypto } from "./web-crypto.js";
57
+ import { webShare } from "./web-share.js";
26
58
  /**
27
- * Every rule in the catalog. Order is not significant: surfaces sort by
28
- * replaceable weight or support tier, not by position here.
59
+ * Interpolates the {{browser:key}} tokens a rule's prose uses in place of a
60
+ * hand-typed browser version. Done once here, so the website, the CLI, the
61
+ * MCP server and the skill reference all read resolved prose without any of
62
+ * them knowing the mechanism exists.
29
63
  */
30
- export const rules = [
64
+ function withResolvedClaims(rule) {
65
+ return {
66
+ ...rule,
67
+ // title and native render in page titles, OG cards, the CLI header and
68
+ // every finding. They were left out once and a token shipped raw.
69
+ title: resolveSupportClaims(rule.title),
70
+ native: resolveSupportClaims(rule.native),
71
+ human: {
72
+ ...rule.human,
73
+ explainer: resolveSupportClaims(rule.human.explainer),
74
+ snippet: resolveSupportClaims(rule.human.snippet),
75
+ },
76
+ agent: {
77
+ ...rule.agent,
78
+ when: resolveSupportClaims(rule.agent.when),
79
+ unless: rule.agent.unless.map(resolveSupportClaims),
80
+ snippet: resolveSupportClaims(rule.agent.snippet),
81
+ },
82
+ ...(rule.manualBaseline
83
+ ? {
84
+ manualBaseline: {
85
+ ...rule.manualBaseline,
86
+ note: resolveSupportClaims(rule.manualBaseline.note),
87
+ },
88
+ }
89
+ : {}),
90
+ };
91
+ }
92
+ /** The rules exactly as authored, tokens and all. */
93
+ const rawRules = [
94
+ abortController,
31
95
  accordion,
32
96
  aspectRatio,
97
+ broadcastChannel,
33
98
  carousel,
99
+ clipboard,
34
100
  colorFunctions,
101
+ compressionStreams,
35
102
  containerQueries,
36
103
  contentVisibility,
104
+ customHighlight,
37
105
  dateTimeInput,
38
106
  dialog,
39
107
  discreteTransitions,
108
+ dragAndDrop,
40
109
  fieldSizing,
41
110
  fluidType,
111
+ focusVisible,
112
+ fullscreen,
42
113
  heightAnimation,
114
+ inert,
115
+ intersectionObserver,
43
116
  lazyLoading,
117
+ lineClamp,
44
118
  masonry,
119
+ numberFormat,
120
+ pageVisibility,
45
121
  popover,
122
+ relativeTime,
46
123
  resizablePanels,
124
+ resizeObserver,
125
+ screenWakeLock,
47
126
  scrollAnimations,
48
127
  scrollLock,
49
128
  scrollbars,
50
129
  select,
51
130
  smoothScroll,
131
+ speechRecognition,
132
+ speechSynthesis,
52
133
  sticky,
134
+ structuredCloneRule,
53
135
  textBoxTrim,
54
136
  textWrapBalance,
55
137
  viewTransitions,
138
+ webBluetooth,
139
+ webShare,
140
+ arrayGrouping,
141
+ base64,
142
+ durationFormat,
143
+ eventTarget,
144
+ fetchRule,
145
+ naturalSort,
146
+ randomUuid,
147
+ serverSentEvents,
148
+ urlSearchParams,
149
+ webCrypto,
56
150
  ];
151
+ /**
152
+ * Every rule in the catalog. Order is not significant: surfaces sort by
153
+ * replaceable weight or support tier, not by position here.
154
+ */
155
+ export const rules = rawRules.map(withResolvedClaims);
57
156
  /** Lookup by rule id. */
58
157
  export const rulesById = new Map(rules.map((rule) => [rule.id, rule]));
59
158
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAoB;IACpC,SAAS;IACT,WAAW;IACX,QAAQ;IACR,cAAc;IACd,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,MAAM;IACN,mBAAmB;IACnB,WAAW;IACX,SAAS;IACT,eAAe;IACf,WAAW;IACX,OAAO;IACP,OAAO;IACP,eAAe;IACf,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,MAAM;IACN,YAAY;IACZ,MAAM;IACN,WAAW;IACX,eAAe;IACf,eAAe;CAChB,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,SAAS,GAA8B,IAAI,GAAG,CACzD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAA8B,IAAI,GAAG,CAC9D,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAU,CAAC,CAAC,CAC1E,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const inert: Rule;
3
+ //# sourceMappingURL=inert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert.d.ts","sourceRoot":"","sources":["../../src/rules/inert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,KAAK,EAAE,IAqCnB,CAAC"}
@@ -0,0 +1,37 @@
1
+ export const inert = {
2
+ id: "inert",
3
+ title: "Focus trapping",
4
+ category: "forms",
5
+ replaces: [
6
+ "focus-trap",
7
+ "focus-trap-react",
8
+ "react-focus-lock",
9
+ "focus-lock",
10
+ "vue-focus-lock",
11
+ "wicg-inert",
12
+ ],
13
+ featureIds: ["inert"],
14
+ native: "the inert attribute",
15
+ human: {
16
+ explainer: "A focus trap works by listening for keydown, noticing that Tab has left the overlay, and putting focus back. The inert attribute comes at it from the other side: mark the rest of the page inert and the browser drops it from the tab order, from the accessibility tree and from pointer events, so there is no escape to catch. If the overlay is a <dialog> opened with showModal(), the browser applies the same treatment to everything behind it and you write nothing at all.",
17
+ snippet: `<!-- While the panel is open, the rest of the page is unreachable:
18
+ no tab stops, no clicks, and hidden from screen readers. -->
19
+ <main id="page" inert>...</main>
20
+ <aside class="panel">...</aside>`,
21
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/inert",
22
+ },
23
+ agent: {
24
+ when: "keeping keyboard focus inside an open modal, drawer or menu",
25
+ unless: [
26
+ "Focus has to cycle from the last element in the overlay back to the first. inert stops focus reaching the rest of the page, and the browser then moves on to the URL bar rather than wrapping inside your container.",
27
+ "You rely on the library restoring focus to the element that opened the overlay. inert does not track that, so storing the previous activeElement and calling focus() on close is yours to write.",
28
+ "The overlay lives inside the same subtree you would have to mark inert, so there is no ancestor you can set the attribute on without disabling the overlay along with it.",
29
+ "You are using the initial-focus, Escape handling and scroll locking the library bundles around the trap, and separating those out costs more than keeping the dependency.",
30
+ "Your support target includes browsers older than Chrome {{chrome:inert}}, Firefox {{firefox:inert}} or Safari {{safari:inert}}. They ignore inert, and focus escapes quietly rather than failing in a way you would notice.",
31
+ ],
32
+ snippet: `page.inert = true; // opening the overlay
33
+ page.inert = false; // closing it`,
34
+ },
35
+ guides: ["accessibility", "navigation-drawer"],
36
+ };
37
+ //# sourceMappingURL=inert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert.js","sourceRoot":"","sources":["../../src/rules/inert.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,KAAK,GAAS;IACzB,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE;QACR,YAAY;QACZ,kBAAkB;QAClB,kBAAkB;QAClB,YAAY;QACZ,gBAAgB;QAChB,YAAY;KACb;IACD,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,MAAM,EAAE,qBAAqB;IAC7B,KAAK,EAAE;QACL,SAAS,EACP,wdAAwd;QAC1d,OAAO,EAAE;;;iCAGoB;QAC7B,MAAM,EACJ,qFAAqF;KACxF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6DAA6D;QACnE,MAAM,EAAE;YACN,sNAAsN;YACtN,kMAAkM;YAClM,2KAA2K;YAC3K,2KAA2K;YAC3K,6NAA6N;SAC9N;QACD,OAAO,EAAE;mCACsB;KAChC;IACD,MAAM,EAAE,CAAC,eAAe,EAAE,mBAAmB,CAAC;CAC/C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const intersectionObserver: Rule;
3
+ //# sourceMappingURL=intersection-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intersection-observer.d.ts","sourceRoot":"","sources":["../../src/rules/intersection-observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,oBAAoB,EAAE,IAqClC,CAAC"}
@@ -0,0 +1,36 @@
1
+ export const intersectionObserver = {
2
+ id: "intersection-observer",
3
+ title: "Visibility tracking",
4
+ category: "async-data",
5
+ replaces: [
6
+ "react-intersection-observer",
7
+ "react-visibility-sensor",
8
+ "react-in-viewport",
9
+ "svelte-intersection-observer",
10
+ "intersection-observer",
11
+ ],
12
+ featureIds: ["intersection-observer"],
13
+ native: "IntersectionObserver",
14
+ human: {
15
+ explainer: "These libraries all wrap the same browser API. IntersectionObserver watches an element and calls you back when it crosses a viewport threshold, without a scroll listener recalculating positions on every frame. Calling it directly removes a dependency for something the browser already does off the main thread.",
16
+ snippet: `const observer = new IntersectionObserver(
17
+ (entries) => {
18
+ for (const entry of entries) {
19
+ if (entry.isIntersecting) console.log("visible:", entry.target);
20
+ }
21
+ },
22
+ { threshold: 0.5 },
23
+ );
24
+ observer.observe(document.querySelector("#target"));`,
25
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API",
26
+ },
27
+ agent: {
28
+ when: "running code when an element scrolls into or out of view, such as triggering analytics, infinite scroll, or an entrance animation",
29
+ unless: [
30
+ "You want a framework hook's ergonomics, such as a boolean and a ref, rather than managing an observer instance yourself. The library is doing less work than it looks like at that point, but it's still less code at each call site.",
31
+ "You need to track intersection against a scrolling ancestor other than the viewport in a browser old enough to have inconsistent support for the root option.",
32
+ ],
33
+ snippet: "new IntersectionObserver((entries) => { ... }, { threshold: 0.5 });",
34
+ },
35
+ };
36
+ //# sourceMappingURL=intersection-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intersection-observer.js","sourceRoot":"","sources":["../../src/rules/intersection-observer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAS;IACxC,EAAE,EAAE,uBAAuB;IAC3B,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,6BAA6B;QAC7B,yBAAyB;QACzB,mBAAmB;QACnB,8BAA8B;QAC9B,uBAAuB;KACxB;IACD,UAAU,EAAE,CAAC,uBAAuB,CAAC;IACrC,MAAM,EAAE,sBAAsB;IAC9B,KAAK,EAAE;QACL,SAAS,EACP,wTAAwT;QAC1T,OAAO,EAAE;;;;;;;;qDAQwC;QACjD,MAAM,EACJ,4EAA4E;KAC/E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,mIAAmI;QACzI,MAAM,EAAE;YACN,uOAAuO;YACvO,+JAA+J;SAChK;QACD,OAAO,EACL,qEAAqE;KACxE;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-loading.d.ts","sourceRoot":"","sources":["../../src/rules/lazy-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IAiCzB,CAAC"}
1
+ {"version":3,"file":"lazy-loading.d.ts","sourceRoot":"","sources":["../../src/rules/lazy-loading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IAqCzB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export const lazyLoading = {
2
2
  id: "lazy-loading",
3
3
  title: "Lazy-loaded images and iframes",
4
+ category: "async-data",
4
5
  replaces: [
5
6
  "lozad",
6
7
  "lazysizes",
@@ -8,6 +9,8 @@ export const lazyLoading = {
8
9
  "react-lazyload",
9
10
  "react-lazy-load-image-component",
10
11
  "yall-js",
12
+ "vue-lazyload",
13
+ "v-lazy-image",
11
14
  ],
12
15
  featureIds: ["loading-lazy"],
13
16
  native: 'loading="lazy"',
@@ -29,5 +32,6 @@ export const lazyLoading = {
29
32
  snippet: `<img src="/photo.jpg" alt="" loading="lazy" />
30
33
  <iframe src="/embed" loading="lazy"></iframe>`,
31
34
  },
35
+ guides: ["optimize-image-priority"],
32
36
  };
33
37
  //# sourceMappingURL=lazy-loading.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-loading.js","sourceRoot":"","sources":["../../src/rules/lazy-loading.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,gCAAgC;IACvC,QAAQ,EAAE;QACR,OAAO;QACP,WAAW;QACX,kBAAkB;QAClB,gBAAgB;QAChB,iCAAiC;QACjC,SAAS;KACV;IACD,UAAU,EAAE,CAAC,cAAc,CAAC;IAC5B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE;QACL,SAAS,EACP,4XAA4X;QAC9X,OAAO,EAAE;iEACoD;QAC7D,MAAM,EACJ,uEAAuE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gFAAgF;QACtF,MAAM,EAAE;YACN,gJAAgJ;YAChJ,6GAA6G;YAC7G,0IAA0I;YAC1I,4HAA4H;YAC5H,4GAA4G;SAC7G;QACD,OAAO,EAAE;8CACiC;KAC3C;CACF,CAAC"}
1
+ {"version":3,"file":"lazy-loading.js","sourceRoot":"","sources":["../../src/rules/lazy-loading.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,gCAAgC;IACvC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,OAAO;QACP,WAAW;QACX,kBAAkB;QAClB,gBAAgB;QAChB,iCAAiC;QACjC,SAAS;QACT,cAAc;QACd,cAAc;KACf;IACD,UAAU,EAAE,CAAC,cAAc,CAAC;IAC5B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE;QACL,SAAS,EACP,4XAA4X;QAC9X,OAAO,EAAE;iEACoD;QAC7D,MAAM,EACJ,uEAAuE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gFAAgF;QACtF,MAAM,EAAE;YACN,gJAAgJ;YAChJ,6GAA6G;YAC7G,0IAA0I;YAC1I,4HAA4H;YAC5H,4GAA4G;SAC7G;QACD,OAAO,EAAE;8CACiC;KAC3C;IACD,MAAM,EAAE,CAAC,yBAAyB,CAAC;CACpC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const lineClamp: Rule;
3
+ //# sourceMappingURL=line-clamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-clamp.d.ts","sourceRoot":"","sources":["../../src/rules/line-clamp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,IAwCvB,CAAC"}
@@ -0,0 +1,39 @@
1
+ export const lineClamp = {
2
+ id: "line-clamp",
3
+ title: "Multi-line text truncation",
4
+ category: "typography",
5
+ replaces: [
6
+ "react-clamp-lines",
7
+ "react-line-clamp",
8
+ "clamp-js",
9
+ "line-clamp",
10
+ "vue-clamp",
11
+ ],
12
+ featureIds: [],
13
+ manualBaseline: {
14
+ status: "widely",
15
+ verifiedOn: "2026-09-03",
16
+ note: "web-features tracks the unprefixed line-clamp property under the ID 'line-clamp', which has near-zero real-world support. The -webkit- prefixed form this rule actually recommends has been supported in every major engine for years (BCD records it only under a prefixed entry, so there is no unprefixed version to cite here), so the automated resolution would misreport a decades-safe technique as limited availability.",
17
+ },
18
+ native: "-webkit-line-clamp",
19
+ human: {
20
+ explainer: "Truncating text after a fixed number of lines, with an ellipsis, used to mean measuring rendered line height in JavaScript and cutting the string by hand. The line-clamp property does it in CSS, no measuring and no re-running on resize or font load. Only the vendor-prefixed form is safe to use today; the unprefixed property is still landing.",
21
+ snippet: `.excerpt {
22
+ display: -webkit-box;
23
+ -webkit-box-orient: vertical;
24
+ -webkit-line-clamp: 3;
25
+ overflow: hidden;
26
+ }`,
27
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp",
28
+ },
29
+ agent: {
30
+ when: "truncating a block of text to a fixed number of lines with an ellipsis",
31
+ unless: [
32
+ "You need to combine this with a display value other than -webkit-box on the same element, since the prefixed property requires it.",
33
+ "You need to know the exact character or word where the text was cut, for something like a 'read more' link that continues from that point.",
34
+ "You're relying on a build tool to add this prefix for you and it doesn't; -webkit-line-clamp still needs to be written by hand, autoprefixer tools do not treat it as one they add automatically in every configuration.",
35
+ ],
36
+ snippet: ".excerpt { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }",
37
+ },
38
+ };
39
+ //# sourceMappingURL=line-clamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-clamp.js","sourceRoot":"","sources":["../../src/rules/line-clamp.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,YAAY;IAChB,KAAK,EAAE,4BAA4B;IACnC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,mBAAmB;QACnB,kBAAkB;QAClB,UAAU;QACV,YAAY;QACZ,WAAW;KACZ;IACD,UAAU,EAAE,EAAE;IACd,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,IAAI,EAAE,maAAma;KAC1a;IACD,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE;QACL,SAAS,EACP,yVAAyV;QAC3V,OAAO,EAAE;;;;;EAKX;QACE,MAAM,EACJ,qEAAqE;KACxE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,wEAAwE;QAC9E,MAAM,EAAE;YACN,oIAAoI;YACpI,4IAA4I;YAC5I,0NAA0N;SAC3N;QACD,OAAO,EACL,2GAA2G;KAC9G;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"masonry.d.ts","sourceRoot":"","sources":["../../src/rules/masonry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,IAyDrB,CAAC"}
1
+ {"version":3,"file":"masonry.d.ts","sourceRoot":"","sources":["../../src/rules/masonry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,IA4DrB,CAAC"}