@jomae/catalog 0.2.0 → 0.4.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 (180) hide show
  1. package/README.md +2 -2
  2. package/dist/baseline.d.ts +11 -0
  3. package/dist/baseline.d.ts.map +1 -1
  4. package/dist/baseline.js +50 -1
  5. package/dist/baseline.js.map +1 -1
  6. package/dist/format.js +1 -1
  7. package/dist/format.js.map +1 -1
  8. package/dist/generated/baseline.d.ts +6 -0
  9. package/dist/generated/baseline.d.ts.map +1 -1
  10. package/dist/generated/baseline.js +512 -35
  11. package/dist/generated/baseline.js.map +1 -1
  12. package/dist/generated/sizes.d.ts.map +1 -1
  13. package/dist/generated/sizes.js +464 -9
  14. package/dist/generated/sizes.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/rules/abort-controller.d.ts +3 -0
  20. package/dist/rules/abort-controller.d.ts.map +1 -0
  21. package/dist/rules/abort-controller.js +25 -0
  22. package/dist/rules/abort-controller.js.map +1 -0
  23. package/dist/rules/accordion.d.ts.map +1 -1
  24. package/dist/rules/accordion.js +1 -0
  25. package/dist/rules/accordion.js.map +1 -1
  26. package/dist/rules/aspect-ratio.d.ts.map +1 -1
  27. package/dist/rules/aspect-ratio.js +1 -0
  28. package/dist/rules/aspect-ratio.js.map +1 -1
  29. package/dist/rules/broadcast-channel.d.ts +3 -0
  30. package/dist/rules/broadcast-channel.d.ts.map +1 -0
  31. package/dist/rules/broadcast-channel.js +25 -0
  32. package/dist/rules/broadcast-channel.js.map +1 -0
  33. package/dist/rules/carousel.d.ts.map +1 -1
  34. package/dist/rules/carousel.js +4 -0
  35. package/dist/rules/carousel.js.map +1 -1
  36. package/dist/rules/clipboard.d.ts +3 -0
  37. package/dist/rules/clipboard.d.ts.map +1 -0
  38. package/dist/rules/clipboard.js +32 -0
  39. package/dist/rules/clipboard.js.map +1 -0
  40. package/dist/rules/color-functions.d.ts.map +1 -1
  41. package/dist/rules/color-functions.js +9 -1
  42. package/dist/rules/color-functions.js.map +1 -1
  43. package/dist/rules/compression-streams.d.ts +3 -0
  44. package/dist/rules/compression-streams.d.ts.map +1 -0
  45. package/dist/rules/compression-streams.js +25 -0
  46. package/dist/rules/compression-streams.js.map +1 -0
  47. package/dist/rules/container-queries.d.ts.map +1 -1
  48. package/dist/rules/container-queries.js +2 -0
  49. package/dist/rules/container-queries.js.map +1 -1
  50. package/dist/rules/content-visibility.d.ts +3 -0
  51. package/dist/rules/content-visibility.d.ts.map +1 -0
  52. package/dist/rules/content-visibility.js +33 -0
  53. package/dist/rules/content-visibility.js.map +1 -0
  54. package/dist/rules/date-time-input.d.ts +3 -0
  55. package/dist/rules/date-time-input.d.ts.map +1 -0
  56. package/dist/rules/date-time-input.js +33 -0
  57. package/dist/rules/date-time-input.js.map +1 -0
  58. package/dist/rules/dialog.d.ts.map +1 -1
  59. package/dist/rules/dialog.js +4 -0
  60. package/dist/rules/dialog.js.map +1 -1
  61. package/dist/rules/discrete-transitions.d.ts.map +1 -1
  62. package/dist/rules/discrete-transitions.js +1 -0
  63. package/dist/rules/discrete-transitions.js.map +1 -1
  64. package/dist/rules/drag-and-drop.d.ts +3 -0
  65. package/dist/rules/drag-and-drop.d.ts.map +1 -0
  66. package/dist/rules/drag-and-drop.js +29 -0
  67. package/dist/rules/drag-and-drop.js.map +1 -0
  68. package/dist/rules/field-sizing.d.ts.map +1 -1
  69. package/dist/rules/field-sizing.js +8 -1
  70. package/dist/rules/field-sizing.js.map +1 -1
  71. package/dist/rules/fluid-type.d.ts.map +1 -1
  72. package/dist/rules/fluid-type.js +1 -0
  73. package/dist/rules/fluid-type.js.map +1 -1
  74. package/dist/rules/focus-visible.d.ts +3 -0
  75. package/dist/rules/focus-visible.d.ts.map +1 -0
  76. package/dist/rules/focus-visible.js +26 -0
  77. package/dist/rules/focus-visible.js.map +1 -0
  78. package/dist/rules/fullscreen.d.ts +3 -0
  79. package/dist/rules/fullscreen.d.ts.map +1 -0
  80. package/dist/rules/fullscreen.js +28 -0
  81. package/dist/rules/fullscreen.js.map +1 -0
  82. package/dist/rules/height-animation.d.ts.map +1 -1
  83. package/dist/rules/height-animation.js +1 -0
  84. package/dist/rules/height-animation.js.map +1 -1
  85. package/dist/rules/index.d.ts.map +1 -1
  86. package/dist/rules/index.js +44 -0
  87. package/dist/rules/index.js.map +1 -1
  88. package/dist/rules/intersection-observer.d.ts +3 -0
  89. package/dist/rules/intersection-observer.d.ts.map +1 -0
  90. package/dist/rules/intersection-observer.js +34 -0
  91. package/dist/rules/intersection-observer.js.map +1 -0
  92. package/dist/rules/lazy-loading.d.ts.map +1 -1
  93. package/dist/rules/lazy-loading.js +3 -0
  94. package/dist/rules/lazy-loading.js.map +1 -1
  95. package/dist/rules/line-clamp.d.ts +3 -0
  96. package/dist/rules/line-clamp.d.ts.map +1 -0
  97. package/dist/rules/line-clamp.js +38 -0
  98. package/dist/rules/line-clamp.js.map +1 -0
  99. package/dist/rules/masonry.d.ts.map +1 -1
  100. package/dist/rules/masonry.js +3 -0
  101. package/dist/rules/masonry.js.map +1 -1
  102. package/dist/rules/number-format.d.ts +3 -0
  103. package/dist/rules/number-format.d.ts.map +1 -0
  104. package/dist/rules/number-format.js +25 -0
  105. package/dist/rules/number-format.js.map +1 -0
  106. package/dist/rules/page-visibility.d.ts +3 -0
  107. package/dist/rules/page-visibility.d.ts.map +1 -0
  108. package/dist/rules/page-visibility.js +24 -0
  109. package/dist/rules/page-visibility.js.map +1 -0
  110. package/dist/rules/popover.d.ts.map +1 -1
  111. package/dist/rules/popover.js +3 -0
  112. package/dist/rules/popover.js.map +1 -1
  113. package/dist/rules/relative-time.d.ts +3 -0
  114. package/dist/rules/relative-time.d.ts.map +1 -0
  115. package/dist/rules/relative-time.js +23 -0
  116. package/dist/rules/relative-time.js.map +1 -0
  117. package/dist/rules/resizable-panels.d.ts +3 -0
  118. package/dist/rules/resizable-panels.d.ts.map +1 -0
  119. package/dist/rules/resizable-panels.js +34 -0
  120. package/dist/rules/resizable-panels.js.map +1 -0
  121. package/dist/rules/resize-observer.d.ts +3 -0
  122. package/dist/rules/resize-observer.d.ts.map +1 -0
  123. package/dist/rules/resize-observer.js +27 -0
  124. package/dist/rules/resize-observer.js.map +1 -0
  125. package/dist/rules/screen-wake-lock.d.ts +3 -0
  126. package/dist/rules/screen-wake-lock.d.ts.map +1 -0
  127. package/dist/rules/screen-wake-lock.js +23 -0
  128. package/dist/rules/screen-wake-lock.js.map +1 -0
  129. package/dist/rules/scroll-animations.d.ts.map +1 -1
  130. package/dist/rules/scroll-animations.js +1 -0
  131. package/dist/rules/scroll-animations.js.map +1 -1
  132. package/dist/rules/scroll-lock.d.ts.map +1 -1
  133. package/dist/rules/scroll-lock.js +1 -0
  134. package/dist/rules/scroll-lock.js.map +1 -1
  135. package/dist/rules/scrollbars.d.ts.map +1 -1
  136. package/dist/rules/scrollbars.js +4 -0
  137. package/dist/rules/scrollbars.js.map +1 -1
  138. package/dist/rules/select.d.ts.map +1 -1
  139. package/dist/rules/select.js +11 -1
  140. package/dist/rules/select.js.map +1 -1
  141. package/dist/rules/smooth-scroll.d.ts.map +1 -1
  142. package/dist/rules/smooth-scroll.js +2 -0
  143. package/dist/rules/smooth-scroll.js.map +1 -1
  144. package/dist/rules/speech-recognition.d.ts +3 -0
  145. package/dist/rules/speech-recognition.d.ts.map +1 -0
  146. package/dist/rules/speech-recognition.js +27 -0
  147. package/dist/rules/speech-recognition.js.map +1 -0
  148. package/dist/rules/speech-synthesis.d.ts +3 -0
  149. package/dist/rules/speech-synthesis.d.ts.map +1 -0
  150. package/dist/rules/speech-synthesis.js +22 -0
  151. package/dist/rules/speech-synthesis.js.map +1 -0
  152. package/dist/rules/sticky.d.ts.map +1 -1
  153. package/dist/rules/sticky.js +3 -0
  154. package/dist/rules/sticky.js.map +1 -1
  155. package/dist/rules/structured-clone.d.ts +3 -0
  156. package/dist/rules/structured-clone.d.ts.map +1 -0
  157. package/dist/rules/structured-clone.js +21 -0
  158. package/dist/rules/structured-clone.js.map +1 -0
  159. package/dist/rules/text-box-trim.d.ts.map +1 -1
  160. package/dist/rules/text-box-trim.js +1 -0
  161. package/dist/rules/text-box-trim.js.map +1 -1
  162. package/dist/rules/text-wrap-balance.d.ts.map +1 -1
  163. package/dist/rules/text-wrap-balance.js +1 -0
  164. package/dist/rules/text-wrap-balance.js.map +1 -1
  165. package/dist/rules/view-transitions.d.ts.map +1 -1
  166. package/dist/rules/view-transitions.js +1 -0
  167. package/dist/rules/view-transitions.js.map +1 -1
  168. package/dist/rules/web-bluetooth.d.ts +3 -0
  169. package/dist/rules/web-bluetooth.d.ts.map +1 -0
  170. package/dist/rules/web-bluetooth.js +25 -0
  171. package/dist/rules/web-bluetooth.js.map +1 -0
  172. package/dist/rules/web-share.d.ts +3 -0
  173. package/dist/rules/web-share.d.ts.map +1 -0
  174. package/dist/rules/web-share.js +27 -0
  175. package/dist/rules/web-share.js.map +1 -0
  176. package/dist/schema.d.ts +2 -0
  177. package/dist/schema.d.ts.map +1 -1
  178. package/dist/schema.js +3 -1
  179. package/dist/schema.js.map +1 -1
  180. package/package.json +3 -3
@@ -0,0 +1,34 @@
1
+ export const resizablePanels = {
2
+ id: "resizable-panels",
3
+ title: "Resizable panels",
4
+ replaces: [
5
+ "react-resizable-panels",
6
+ "re-resizable",
7
+ "react-split-pane",
8
+ "splitpanes",
9
+ ],
10
+ featureIds: ["resize"],
11
+ native: "resize",
12
+ human: {
13
+ explainer: "A resizable-panel library tracks pointer events on a drag handle, computes the new size, and writes it back to state on every move. The resize property gives one element a drag handle for free: the browser tracks the pointer and grows or shrinks the element, no JavaScript involved. It only resizes the element it is set on, so it covers a single sidebar or textarea, not a split view where dragging one panel has to shrink its neighbor.",
14
+ snippet: `.sidebar {
15
+ resize: horizontal;
16
+ overflow: auto;
17
+ min-width: 12rem;
18
+ max-width: 32rem;
19
+ }`,
20
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/resize",
21
+ },
22
+ agent: {
23
+ when: "letting someone drag-resize a single panel, such as a sidebar or a textarea",
24
+ unless: [
25
+ "You need the block/inline logical values rather than horizontal/vertical/both. Those only reached Firefox in version 63 and Safari in 16; the classic physical-direction values have been supported everywhere for over a decade.",
26
+ "You need multiple panels to resize together, such as a split view where dragging one edge shrinks its neighbor. resize only affects the element it is set on.",
27
+ "You need to read back or persist the size someone chose. resize has no resize event; ResizeObserver still covers that, and it is a JavaScript API, not CSS.",
28
+ "You need to style the drag handle itself, or place it somewhere other than the element's edge or corner. The native handle's appearance is fixed.",
29
+ "You need a minimum of two resizable regions sharing the freed-up or reclaimed space, the way a split-pane library redistributes width between panels.",
30
+ ],
31
+ snippet: ".sidebar { resize: horizontal; overflow: auto; min-width: 12rem; max-width: 32rem; }",
32
+ },
33
+ };
34
+ //# sourceMappingURL=resizable-panels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizable-panels.js","sourceRoot":"","sources":["../../src/rules/resizable-panels.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE;QACR,wBAAwB;QACxB,cAAc;QACd,kBAAkB;QAClB,YAAY;KACb;IACD,UAAU,EAAE,CAAC,QAAQ,CAAC;IACtB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE;QACL,SAAS,EACP,ubAAub;QACzb,OAAO,EAAE;;;;;EAKX;QACE,MAAM,EAAE,yDAAyD;KAClE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6EAA6E;QACnF,MAAM,EAAE;YACN,mOAAmO;YACnO,+JAA+J;YAC/J,6JAA6J;YAC7J,mJAAmJ;YACnJ,uJAAuJ;SACxJ;QACD,OAAO,EACL,sFAAsF;KACzF;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const resizeObserver: Rule;
3
+ //# sourceMappingURL=resize-observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize-observer.d.ts","sourceRoot":"","sources":["../../src/rules/resize-observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,IA0B5B,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const resizeObserver = {
2
+ id: "resize-observer",
3
+ title: "Element resize tracking",
4
+ replaces: ["resize-observer-polyfill", "@juggle/resize-observer"],
5
+ featureIds: ["resize-observer"],
6
+ native: "ResizeObserver",
7
+ human: {
8
+ explainer: "These polyfills exist because ResizeObserver had gaps in browser support. That gap closed years ago: every major engine ships it natively now. Calling it directly watches an element's box for size changes and calls you back, with no listener on window resize and no manual layout math.",
9
+ snippet: `const observer = new ResizeObserver((entries) => {
10
+ for (const entry of entries) {
11
+ console.log(entry.contentBoxSize);
12
+ }
13
+ });
14
+ observer.observe(document.querySelector("#panel"));`,
15
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver",
16
+ },
17
+ agent: {
18
+ when: "running code when an element's own box changes size, not just the viewport",
19
+ unless: [
20
+ "You need a framework hook's ergonomics, such as a ref and a reactive size value, rather than managing an observer instance yourself.",
21
+ "You're targeting an engine old enough that the polyfill's manual measurement fallback is still doing real work.",
22
+ "You need devicePixelContentBoxSize specifically. That entry is still limited to Chromium engines.",
23
+ ],
24
+ snippet: "new ResizeObserver((entries) => { ... }).observe(el);",
25
+ },
26
+ };
27
+ //# sourceMappingURL=resize-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize-observer.js","sourceRoot":"","sources":["../../src/rules/resize-observer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,yBAAyB;IAChC,QAAQ,EAAE,CAAC,0BAA0B,EAAE,yBAAyB,CAAC;IACjE,UAAU,EAAE,CAAC,iBAAiB,CAAC;IAC/B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE;QACL,SAAS,EACP,+RAA+R;QACjS,OAAO,EAAE;;;;;oDAKuC;QAChD,MAAM,EAAE,iEAAiE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4EAA4E;QAClF,MAAM,EAAE;YACN,sIAAsI;YACtI,iHAAiH;YACjH,mGAAmG;SACpG;QACD,OAAO,EAAE,uDAAuD;KACjE;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const screenWakeLock: Rule;
3
+ //# sourceMappingURL=screen-wake-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-wake-lock.d.ts","sourceRoot":"","sources":["../../src/rules/screen-wake-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,IAuB5B,CAAC"}
@@ -0,0 +1,23 @@
1
+ export const screenWakeLock = {
2
+ id: "screen-wake-lock",
3
+ title: "Keeping the screen awake",
4
+ replaces: ["nosleep.js", "react-use-wake-lock"],
5
+ featureIds: ["screen-wake-lock"],
6
+ native: 'navigator.wakeLock.request("screen")',
7
+ human: {
8
+ explainer: "nosleep.js kept the screen on with a trick: playing a silent, invisible video, because there was no direct way to ask for this. The Wake Lock API asks directly, and releases automatically when the tab is backgrounded rather than needing you to remember to stop the video yourself.",
9
+ snippet: `const lock = await navigator.wakeLock.request("screen");
10
+ // later, or automatically when the tab backgrounds
11
+ await lock.release();`,
12
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API",
13
+ },
14
+ agent: {
15
+ when: "keeping the screen from sleeping while a page is active, such as during a recipe, presentation, or workout",
16
+ unless: [
17
+ "You support Safari before version 16.4, or need the lock to survive the tab losing focus. The platform releases it automatically the moment the tab backgrounds, with no way to opt out.",
18
+ "You need this in a non-secure (non-HTTPS) context, where the API isn't available at all.",
19
+ ],
20
+ snippet: `const lock = await navigator.wakeLock.request("screen");`,
21
+ },
22
+ };
23
+ //# sourceMappingURL=screen-wake-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-wake-lock.js","sourceRoot":"","sources":["../../src/rules/screen-wake-lock.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,CAAC,YAAY,EAAE,qBAAqB,CAAC;IAC/C,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,sCAAsC;IAC9C,KAAK,EAAE;QACL,SAAS,EACP,0RAA0R;QAC5R,OAAO,EAAE;;sBAES;QAClB,MAAM,EACJ,uEAAuE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4GAA4G;QAClH,MAAM,EAAE;YACN,0LAA0L;YAC1L,0FAA0F;SAC3F;QACD,OAAO,EAAE,0DAA0D;KACpE;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-animations.d.ts","sourceRoot":"","sources":["../../src/rules/scroll-animations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,gBAAgB,EAAE,IAyD9B,CAAC"}
1
+ {"version":3,"file":"scroll-animations.d.ts","sourceRoot":"","sources":["../../src/rules/scroll-animations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,gBAAgB,EAAE,IA2D9B,CAAC"}
@@ -35,6 +35,7 @@ export const scrollAnimations = {
35
35
  animation-timeline: scroll(root block);
36
36
  transform-origin: left;
37
37
  }`,
38
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timeline",
38
39
  },
39
40
  agent: {
40
41
  when: "fading or moving elements in as they scroll into view, or driving a reading-progress bar",
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-animations.js","sourceRoot":"","sources":["../../src/rules/scroll-animations.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,EAAE,EAAE,0BAA0B;IAC9B,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC;IAC7E,UAAU,EAAE,CAAC,0BAA0B,CAAC;IACxC,MAAM,EAAE,yCAAyC;IACjD,KAAK,EAAE;QACL,SAAS,EACP,ugBAAugB;QACzgB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0FAA0F;QAChG,MAAM,EAAE;YACN,0KAA0K;YAC1K,sLAAsL;YACtL,2IAA2I;YAC3I,sHAAsH;YACtH,4IAA4I;SAC7I;QACD,OAAO,EAAE;;;;;;;EAOX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"scroll-animations.js","sourceRoot":"","sources":["../../src/rules/scroll-animations.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,EAAE,EAAE,0BAA0B;IAC9B,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC;IAC7E,UAAU,EAAE,CAAC,0BAA0B,CAAC;IACxC,MAAM,EAAE,yCAAyC;IACjD,KAAK,EAAE;QACL,SAAS,EACP,ugBAAugB;QACzgB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BX;QACE,MAAM,EACJ,qEAAqE;KACxE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0FAA0F;QAChG,MAAM,EAAE;YACN,0KAA0K;YAC1K,sLAAsL;YACtL,2IAA2I;YAC3I,sHAAsH;YACtH,4IAA4I;SAC7I;QACD,OAAO,EAAE;;;;;;;EAOX;KACC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-lock.d.ts","sourceRoot":"","sources":["../../src/rules/scroll-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IAuCxB,CAAC"}
1
+ {"version":3,"file":"scroll-lock.d.ts","sourceRoot":"","sources":["../../src/rules/scroll-lock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IAyCxB,CAAC"}
@@ -22,6 +22,7 @@ export const scrollLock = {
22
22
  body {
23
23
  overscroll-behavior-y: contain;
24
24
  }`,
25
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior",
25
26
  },
26
27
  agent: {
27
28
  when: "stopping the page behind a modal or drawer from scrolling when the overlay reaches its end",
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-lock.js","sourceRoot":"","sources":["../../src/rules/scroll-lock.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,sCAAsC;IAC7C,QAAQ,EAAE;QACR,kBAAkB;QAClB,kBAAkB;QAClB,WAAW;QACX,aAAa;KACd;IACD,UAAU,EAAE,CAAC,qBAAqB,CAAC;IACnC,MAAM,EAAE,8BAA8B;IACtC,KAAK,EAAE;QACL,SAAS,EACP,mfAAmf;QACrf,OAAO,EAAE;;;;;;;;;;EAUX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4FAA4F;QAClG,MAAM,EAAE;YACN,0KAA0K;YAC1K,2MAA2M;YAC3M,0IAA0I;YAC1I,kFAAkF;SACnF;QACD,OAAO,EAAE;;;EAGX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"scroll-lock.js","sourceRoot":"","sources":["../../src/rules/scroll-lock.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,sCAAsC;IAC7C,QAAQ,EAAE;QACR,kBAAkB;QAClB,kBAAkB;QAClB,WAAW;QACX,aAAa;KACd;IACD,UAAU,EAAE,CAAC,qBAAqB,CAAC;IACnC,MAAM,EAAE,8BAA8B;IACtC,KAAK,EAAE;QACL,SAAS,EACP,mfAAmf;QACrf,OAAO,EAAE;;;;;;;;;;EAUX;QACE,MAAM,EACJ,sEAAsE;KACzE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4FAA4F;QAClG,MAAM,EAAE;YACN,0KAA0K;YAC1K,2MAA2M;YAC3M,0IAA0I;YAC1I,kFAAkF;SACnF;QACD,OAAO,EAAE;;;EAGX;KACC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scrollbars.d.ts","sourceRoot":"","sources":["../../src/rules/scrollbars.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IA2CxB,CAAC"}
1
+ {"version":3,"file":"scrollbars.d.ts","sourceRoot":"","sources":["../../src/rules/scrollbars.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IA+CxB,CAAC"}
@@ -9,6 +9,9 @@ export const scrollbars = {
9
9
  "overlayscrollbars",
10
10
  "overlayscrollbars-react",
11
11
  "perfect-scrollbar",
12
+ "vue-perfect-scrollbar",
13
+ "overlayscrollbars-vue",
14
+ "ngx-perfect-scrollbar",
12
15
  ],
13
16
  featureIds: ["scrollbar-width", "scrollbar-color", "scrollbar-gutter"],
14
17
  native: "scrollbar-width, scrollbar-color and scrollbar-gutter",
@@ -25,6 +28,7 @@ html {
25
28
  scrollbar-color: #666 transparent;
26
29
  overflow-y: auto;
27
30
  }`,
31
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color",
28
32
  },
29
33
  agent: {
30
34
  when: "restyling a scrollbar to match a dark theme, or stopping layout shift when a scrollbar appears",
@@ -1 +1 @@
1
- {"version":3,"file":"scrollbars.js","sourceRoot":"","sources":["../../src/rules/scrollbars.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,mBAAmB;IACvB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE;QACR,yBAAyB;QACzB,2BAA2B;QAC3B,WAAW;QACX,iBAAiB;QACjB,mBAAmB;QACnB,yBAAyB;QACzB,mBAAmB;KACpB;IACD,UAAU,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC;IACtE,MAAM,EAAE,uDAAuD;IAC/D,KAAK,EAAE;QACL,SAAS,EACP,wdAAwd;QAC1d,OAAO,EAAE;;;;;;;;;;EAUX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gGAAgG;QACtG,MAAM,EAAE;YACN,iMAAiM;YACjM,yGAAyG;YACzG,6HAA6H;YAC7H,iHAAiH;SAClH;QACD,OAAO,EAAE;;;;EAIX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"scrollbars.js","sourceRoot":"","sources":["../../src/rules/scrollbars.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,mBAAmB;IACvB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE;QACR,yBAAyB;QACzB,2BAA2B;QAC3B,WAAW;QACX,iBAAiB;QACjB,mBAAmB;QACnB,yBAAyB;QACzB,mBAAmB;QACnB,uBAAuB;QACvB,uBAAuB;QACvB,uBAAuB;KACxB;IACD,UAAU,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC;IACtE,MAAM,EAAE,uDAAuD;IAC/D,KAAK,EAAE;QACL,SAAS,EACP,wdAAwd;QAC1d,OAAO,EAAE;;;;;;;;;;EAUX;QACE,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gGAAgG;QACtG,MAAM,EAAE;YACN,iMAAiM;YACjM,yGAAyG;YACzG,6HAA6H;YAC7H,iHAAiH;SAClH;QACD,OAAO,EAAE;;;;EAIX;KACC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/rules/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,MAAM,EAAE,IAqDpB,CAAC"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/rules/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,MAAM,EAAE,IA+DpB,CAAC"}
@@ -1,7 +1,16 @@
1
1
  export const select = {
2
2
  id: "customizable-select",
3
3
  title: "Custom select menus",
4
- replaces: ["react-select", "choices.js", "select2", "tom-select"],
4
+ replaces: [
5
+ "react-select",
6
+ "choices.js",
7
+ "select2",
8
+ "tom-select",
9
+ "vue-select",
10
+ "vue-multiselect",
11
+ "@ng-select/ng-select",
12
+ "svelte-select",
13
+ ],
5
14
  featureIds: ["customizable-select"],
6
15
  native: "appearance: base-select on <select>",
7
16
  human: {
@@ -33,6 +42,7 @@ export const select = {
33
42
  font-weight: 600;
34
43
  }
35
44
  </style>`,
45
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/appearance",
36
46
  },
37
47
  agent: {
38
48
  when: "styling a select's options with markup, such as a flag or a two-line label",
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/rules/select.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC;IACjE,UAAU,EAAE,CAAC,qBAAqB,CAAC;IACnC,MAAM,EAAE,qCAAqC;IAC7C,KAAK,EAAE;QACL,SAAS,EACP,+YAA+Y;QACjZ,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;SA0BJ;KACN;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4EAA4E;QAClF,MAAM,EAAE;YACN,0LAA0L;YAC1L,qFAAqF;YACrF,gLAAgL;YAChL,qEAAqE;SACtE;QACD,OAAO,EAAE;;;;;;SAMJ;KACN;CACF,CAAC"}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/rules/select.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,qBAAqB;IAC5B,QAAQ,EAAE;QACR,cAAc;QACd,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,YAAY;QACZ,iBAAiB;QACjB,sBAAsB;QACtB,eAAe;KAChB;IACD,UAAU,EAAE,CAAC,qBAAqB,CAAC;IACnC,MAAM,EAAE,qCAAqC;IAC7C,KAAK,EAAE;QACL,SAAS,EACP,+YAA+Y;QACjZ,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;SA0BJ;QACL,MAAM,EAAE,6DAA6D;KACtE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,4EAA4E;QAClF,MAAM,EAAE;YACN,0LAA0L;YAC1L,qFAAqF;YACrF,gLAAgL;YAChL,qEAAqE;SACtE;QACD,OAAO,EAAE;;;;;;SAMJ;KACN;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"smooth-scroll.d.ts","sourceRoot":"","sources":["../../src/rules/smooth-scroll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAwC1B,CAAC"}
1
+ {"version":3,"file":"smooth-scroll.d.ts","sourceRoot":"","sources":["../../src/rules/smooth-scroll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IA0C1B,CAAC"}
@@ -7,6 +7,7 @@ export const smoothScroll = {
7
7
  "scroll-behavior-polyfill",
8
8
  "smooth-scroll",
9
9
  "jump.js",
10
+ "vue-scrollto",
10
11
  ],
11
12
  featureIds: ["scroll-behavior"],
12
13
  native: "scroll-behavior: smooth with scroll-margin-top",
@@ -23,6 +24,7 @@ export const smoothScroll = {
23
24
  [id] {
24
25
  scroll-margin-top: 5rem;
25
26
  }`,
27
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior",
26
28
  },
27
29
  agent: {
28
30
  when: "making in-page anchor links scroll smoothly to their target",
@@ -1 +1 @@
1
- {"version":3,"file":"smooth-scroll.js","sourceRoot":"","sources":["../../src/rules/smooth-scroll.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,uCAAuC;IAC9C,QAAQ,EAAE;QACR,cAAc;QACd,uBAAuB;QACvB,0BAA0B;QAC1B,eAAe;QACf,SAAS;KACV;IACD,UAAU,EAAE,CAAC,iBAAiB,CAAC;IAC/B,MAAM,EAAE,gDAAgD;IACxD,KAAK,EAAE;QACL,SAAS,EACP,mYAAmY;QACrY,OAAO,EAAE;;;;;;;;;;EAUX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6DAA6D;QACnE,MAAM,EAAE;YACN,mHAAmH;YACnH,6GAA6G;YAC7G,gFAAgF;YAChF,8KAA8K;SAC/K;QACD,OAAO,EAAE;;;kCAGqB;KAC/B;CACF,CAAC"}
1
+ {"version":3,"file":"smooth-scroll.js","sourceRoot":"","sources":["../../src/rules/smooth-scroll.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,uCAAuC;IAC9C,QAAQ,EAAE;QACR,cAAc;QACd,uBAAuB;QACvB,0BAA0B;QAC1B,eAAe;QACf,SAAS;QACT,cAAc;KACf;IACD,UAAU,EAAE,CAAC,iBAAiB,CAAC;IAC/B,MAAM,EAAE,gDAAgD;IACxD,KAAK,EAAE;QACL,SAAS,EACP,mYAAmY;QACrY,OAAO,EAAE;;;;;;;;;;EAUX;QACE,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6DAA6D;QACnE,MAAM,EAAE;YACN,mHAAmH;YACnH,6GAA6G;YAC7G,gFAAgF;YAChF,8KAA8K;SAC/K;QACD,OAAO,EAAE;;;kCAGqB;KAC/B;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const speechRecognition: Rule;
3
+ //# sourceMappingURL=speech-recognition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech-recognition.d.ts","sourceRoot":"","sources":["../../src/rules/speech-recognition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,iBAAiB,EAAE,IA2B/B,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const speechRecognition = {
2
+ id: "speech-recognition",
3
+ title: "Voice input",
4
+ replaces: ["annyang", "react-speech-recognition"],
5
+ featureIds: ["speech-recognition"],
6
+ native: "SpeechRecognition",
7
+ human: {
8
+ explainer: "annyang and react-speech-recognition both wrap the same underlying API, adding phrase matching or restart-on-silence logic around it. The API itself lets a page listen for speech and get back a transcript, with no server round-trip for the recognition step in Chromium's implementation.",
9
+ snippet: `const recognition = new SpeechRecognition();
10
+ recognition.onresult = (event) => {
11
+ console.log(event.results[0][0].transcript);
12
+ };
13
+ recognition.start();`,
14
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition",
15
+ },
16
+ agent: {
17
+ when: "capturing a speech-to-text transcript directly in the browser",
18
+ unless: [
19
+ "You need this outside Chrome or Edge. No other engine ships SpeechRecognition, so this is Chromium-only in practice today.",
20
+ "You need continuous recognition that automatically restarts after the browser's built-in silence timeout. That restart logic is exactly what these libraries still add.",
21
+ "You need offline recognition. Chrome's implementation sends audio to Google's servers for transcription.",
22
+ ],
23
+ snippet: `const recognition = new SpeechRecognition();
24
+ recognition.start();`,
25
+ },
26
+ };
27
+ //# sourceMappingURL=speech-recognition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech-recognition.js","sourceRoot":"","sources":["../../src/rules/speech-recognition.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,aAAa;IACpB,QAAQ,EAAE,CAAC,SAAS,EAAE,0BAA0B,CAAC;IACjD,UAAU,EAAE,CAAC,oBAAoB,CAAC;IAClC,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE;QACL,SAAS,EACP,gSAAgS;QAClS,OAAO,EAAE;;;;qBAIQ;QACjB,MAAM,EACJ,oEAAoE;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,+DAA+D;QACrE,MAAM,EAAE;YACN,4HAA4H;YAC5H,yKAAyK;YACzK,0GAA0G;SAC3G;QACD,OAAO,EAAE;qBACQ;KAClB;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const speechSynthesis: Rule;
3
+ //# sourceMappingURL=speech-synthesis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech-synthesis.d.ts","sourceRoot":"","sources":["../../src/rules/speech-synthesis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAqB7B,CAAC"}
@@ -0,0 +1,22 @@
1
+ export const speechSynthesis = {
2
+ id: "speech-synthesis",
3
+ title: "Text to speech",
4
+ replaces: ["speak-tts", "react-text-to-speech"],
5
+ featureIds: ["speech-synthesis"],
6
+ native: "SpeechSynthesis and SpeechSynthesisUtterance",
7
+ human: {
8
+ explainer: "speak-tts is a queueing and promise layer over the browser's own SpeechSynthesis API. The browser already exposes every installed system voice and a speaking queue; the wrapper mostly makes calling it feel more like a promise.",
9
+ snippet: `const utterance = new SpeechSynthesisUtterance("Hello there");
10
+ speechSynthesis.speak(utterance);`,
11
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis",
12
+ },
13
+ agent: {
14
+ when: "reading text aloud with the browser's own text-to-speech engine",
15
+ unless: [
16
+ "You need a specific voice bundled with your app rather than whatever the person's operating system happens to have installed. Voice availability and quality vary by device.",
17
+ "You need the callback-based API wrapped in a promise, or queueing logic across multiple utterances. The library still saves real code there.",
18
+ ],
19
+ snippet: "speechSynthesis.speak(new SpeechSynthesisUtterance(text));",
20
+ },
21
+ };
22
+ //# sourceMappingURL=speech-synthesis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech-synthesis.js","sourceRoot":"","sources":["../../src/rules/speech-synthesis.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC/C,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,8CAA8C;IACtD,KAAK,EAAE;QACL,SAAS,EACP,oOAAoO;QACtO,OAAO,EAAE;kCACqB;QAC9B,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,iEAAiE;QACvE,MAAM,EAAE;YACN,8KAA8K;YAC9K,8IAA8I;SAC/I;QACD,OAAO,EAAE,4DAA4D;KACtE;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sticky.d.ts","sourceRoot":"","sources":["../../src/rules/sticky.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,MAAM,EAAE,IAsCpB,CAAC"}
1
+ {"version":3,"file":"sticky.d.ts","sourceRoot":"","sources":["../../src/rules/sticky.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,MAAM,EAAE,IAyCpB,CAAC"}
@@ -7,6 +7,8 @@ export const sticky = {
7
7
  "react-sticky",
8
8
  "sticky-kit",
9
9
  "stickybits",
10
+ "vue-sticky-directive",
11
+ "vue-sticky",
10
12
  ],
11
13
  featureIds: ["sticky-positioning"],
12
14
  native: "position: sticky",
@@ -24,6 +26,7 @@ export const sticky = {
24
26
  top: 5rem;
25
27
  align-self: start;
26
28
  }`,
29
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/position#sticky",
27
30
  },
28
31
  agent: {
29
32
  when: "a header, sidebar or table head should stick while its container scrolls",
@@ -1 +1 @@
1
- {"version":3,"file":"sticky.js","sourceRoot":"","sources":["../../src/rules/sticky.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE;QACR,WAAW;QACX,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,YAAY;KACb;IACD,UAAU,EAAE,CAAC,oBAAoB,CAAC;IAClC,MAAM,EAAE,kBAAkB;IAC1B,KAAK,EAAE;QACL,SAAS,EACP,iaAAia;QACna,OAAO,EAAE;;;;;;;;;;;EAWX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0EAA0E;QAChF,MAAM,EAAE;YACN,iLAAiL;YACjL,kLAAkL;YAClL,qFAAqF;SACtF;QACD,OAAO,EAAE;6DACgD;KAC1D;CACF,CAAC"}
1
+ {"version":3,"file":"sticky.js","sourceRoot":"","sources":["../../src/rules/sticky.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAS;IAC1B,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE;QACR,WAAW;QACX,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,YAAY;QACZ,sBAAsB;QACtB,YAAY;KACb;IACD,UAAU,EAAE,CAAC,oBAAoB,CAAC;IAClC,MAAM,EAAE,kBAAkB;IAC1B,KAAK,EAAE;QACL,SAAS,EACP,iaAAia;QACna,OAAO,EAAE;;;;;;;;;;;EAWX;QACE,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0EAA0E;QAChF,MAAM,EAAE;YACN,iLAAiL;YACjL,kLAAkL;YAClL,qFAAqF;SACtF;QACD,OAAO,EAAE;6DACgD;KAC1D;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const structuredCloneRule: Rule;
3
+ //# sourceMappingURL=structured-clone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-clone.d.ts","sourceRoot":"","sources":["../../src/rules/structured-clone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,mBAAmB,EAAE,IAoBjC,CAAC"}
@@ -0,0 +1,21 @@
1
+ export const structuredCloneRule = {
2
+ id: "structured-clone",
3
+ title: "Deep cloning",
4
+ replaces: ["lodash.clonedeep", "rfdc", "clone", "klona"],
5
+ featureIds: ["structured-clone"],
6
+ native: "structuredClone()",
7
+ human: {
8
+ explainer: "These packages walk an object graph by hand, copying nested arrays and objects one property at a time so the copy shares no references with the original. A global function now does the same job: structuredClone() copies arrays, plain objects, Maps, Sets, and dates in one call, no walking required.",
9
+ snippet: "const copy = structuredClone(original);",
10
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/structuredClone",
11
+ },
12
+ agent: {
13
+ when: "deep-copying plain data such as arrays, objects, Maps, Sets, and dates",
14
+ unless: [
15
+ "You need to clone functions, DOM nodes, or class instances with prototypes. structuredClone throws on all three, where lodash's version silently drops what it can't handle instead.",
16
+ "You need to clone something containing a value structuredClone doesn't support, such as an Error's custom properties beyond message and name.",
17
+ ],
18
+ snippet: "const copy = structuredClone(original);",
19
+ },
20
+ };
21
+ //# sourceMappingURL=structured-clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-clone.js","sourceRoot":"","sources":["../../src/rules/structured-clone.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAS;IACvC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,CAAC,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;IACxD,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE;QACL,SAAS,EACP,4SAA4S;QAC9S,OAAO,EAAE,yCAAyC;QAClD,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,wEAAwE;QAC9E,MAAM,EAAE;YACN,sLAAsL;YACtL,+IAA+I;SAChJ;QACD,OAAO,EAAE,yCAAyC;KACnD;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-box-trim.d.ts","sourceRoot":"","sources":["../../src/rules/text-box-trim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IA+BzB,CAAC"}
1
+ {"version":3,"file":"text-box-trim.d.ts","sourceRoot":"","sources":["../../src/rules/text-box-trim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IAgCzB,CAAC"}
@@ -18,6 +18,7 @@ export const textBoxTrim = {
18
18
  text-box-trim: trim-both;
19
19
  text-box-edge: cap alphabetic;
20
20
  }`,
21
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/text-box-trim",
21
22
  },
22
23
  agent: {
23
24
  when: "removing a font's built-in leading so text sits flush in its box",
@@ -1 +1 @@
1
- {"version":3,"file":"text-box-trim.js","sourceRoot":"","sources":["../../src/rules/text-box-trim.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,qBAAqB,CAAC;IAChE,UAAU,EAAE,CAAC,UAAU,CAAC;IACxB,MAAM,EAAE,iCAAiC;IACzC,KAAK,EAAE;QACL,SAAS,EACP,+bAA+b;QACjc,OAAO,EAAE;;;;;;;;;;;EAWX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,kEAAkE;QACxE,MAAM,EAAE;YACN,oMAAoM;YACpM,+LAA+L;YAC/L,yGAAyG;SAC1G;QACD,OAAO,EAAE,4CAA4C;KACtD;CACF,CAAC"}
1
+ {"version":3,"file":"text-box-trim.js","sourceRoot":"","sources":["../../src/rules/text-box-trim.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,qBAAqB,CAAC;IAChE,UAAU,EAAE,CAAC,UAAU,CAAC;IACxB,MAAM,EAAE,iCAAiC;IACzC,KAAK,EAAE;QACL,SAAS,EACP,+bAA+b;QACjc,OAAO,EAAE;;;;;;;;;;;EAWX;QACE,MAAM,EAAE,gEAAgE;KACzE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,kEAAkE;QACxE,MAAM,EAAE;YACN,oMAAoM;YACpM,+LAA+L;YAC/L,yGAAyG;SAC1G;QACD,OAAO,EAAE,4CAA4C;KACtD;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-wrap-balance.d.ts","sourceRoot":"","sources":["../../src/rules/text-wrap-balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAiC7B,CAAC"}
1
+ {"version":3,"file":"text-wrap-balance.d.ts","sourceRoot":"","sources":["../../src/rules/text-wrap-balance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAkC7B,CAAC"}
@@ -18,6 +18,7 @@ blockquote {
18
18
  p {
19
19
  text-wrap: pretty;
20
20
  }`,
21
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap",
21
22
  },
22
23
  agent: {
23
24
  when: "stopping a heading or short blurb from breaking with one word on the last line",
@@ -1 +1 @@
1
- {"version":3,"file":"text-wrap-balance.js","sourceRoot":"","sources":["../../src/rules/text-wrap-balance.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,mBAAmB;IACvB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE,CAAC,qBAAqB,EAAE,cAAc,CAAC;IACjD,UAAU,EAAE,CAAC,mBAAmB,CAAC;IACjC,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE;QACL,SAAS,EACP,qbAAqb;QACvb,OAAO,EAAE;;;;;;;;;;;EAWX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gFAAgF;QACtF,MAAM,EAAE;YACN,4JAA4J;YAC5J,mKAAmK;YACnK,gIAAgI;YAChI,gJAAgJ;SACjJ;QACD,OAAO,EAAE;yBACY;KACtB;CACF,CAAC"}
1
+ {"version":3,"file":"text-wrap-balance.js","sourceRoot":"","sources":["../../src/rules/text-wrap-balance.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,mBAAmB;IACvB,KAAK,EAAE,mBAAmB;IAC1B,QAAQ,EAAE,CAAC,qBAAqB,EAAE,cAAc,CAAC;IACjD,UAAU,EAAE,CAAC,mBAAmB,CAAC;IACjC,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE;QACL,SAAS,EACP,qbAAqb;QACvb,OAAO,EAAE;;;;;;;;;;;EAWX;QACE,MAAM,EAAE,4DAA4D;KACrE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gFAAgF;QACtF,MAAM,EAAE;YACN,4JAA4J;YAC5J,mKAAmK;YACnK,gIAAgI;YAChI,gJAAgJ;SACjJ;QACD,OAAO,EAAE;yBACY;KACtB;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"view-transitions.d.ts","sourceRoot":"","sources":["../../src/rules/view-transitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAoD7B,CAAC"}
1
+ {"version":3,"file":"view-transitions.d.ts","sourceRoot":"","sources":["../../src/rules/view-transitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAsD7B,CAAC"}
@@ -32,6 +32,7 @@ document.startViewTransition(() => {
32
32
  animation: none;
33
33
  }
34
34
  }`,
35
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API",
35
36
  },
36
37
  agent: {
37
38
  when: "cross-fading between two states, or growing a thumbnail into a hero image across a navigation",
@@ -1 +1 @@
1
- {"version":3,"file":"view-transitions.js","sourceRoot":"","sources":["../../src/rules/view-transitions.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,4BAA4B;IACnC,QAAQ,EAAE;QACR,uBAAuB;QACvB,uBAAuB;QACvB,UAAU;QACV,MAAM;KACP;IACD,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,0BAA0B;IAClC,KAAK,EAAE;QACL,SAAS,EACP,gcAAgc;QAClc,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;EAoBX;KACC;IACD,KAAK,EAAE;QACL,IAAI,EAAE,+FAA+F;QACrG,MAAM,EAAE;YACN,+LAA+L;YAC/L,4JAA4J;YAC5J,6HAA6H;YAC7H,oGAAoG;YACpG,2FAA2F;SAC5F;QACD,OAAO,EAAE;;;;;EAKX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"view-transitions.js","sourceRoot":"","sources":["../../src/rules/view-transitions.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,4BAA4B;IACnC,QAAQ,EAAE;QACR,uBAAuB;QACvB,uBAAuB;QACvB,UAAU;QACV,MAAM;KACP;IACD,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,0BAA0B;IAClC,KAAK,EAAE;QACL,SAAS,EACP,gcAAgc;QAClc,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;EAoBX;QACE,MAAM,EACJ,uEAAuE;KAC1E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,+FAA+F;QACrG,MAAM,EAAE;YACN,+LAA+L;YAC/L,4JAA4J;YAC5J,6HAA6H;YAC7H,oGAAoG;YACpG,2FAA2F;SAC5F;QACD,OAAO,EAAE;;;;;EAKX;KACC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const webBluetooth: Rule;
3
+ //# sourceMappingURL=web-bluetooth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-bluetooth.d.ts","sourceRoot":"","sources":["../../src/rules/web-bluetooth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IA0B1B,CAAC"}
@@ -0,0 +1,25 @@
1
+ export const webBluetooth = {
2
+ id: "web-bluetooth",
3
+ title: "Bluetooth device access",
4
+ replaces: ["@capacitor-community/bluetooth-le", "cordova-plugin-ble-central"],
5
+ featureIds: ["web-bluetooth"],
6
+ native: "navigator.bluetooth.requestDevice()",
7
+ human: {
8
+ explainer: "Talking to a Bluetooth peripheral from a web app used to mean wrapping the page in a native shell such as Cordova or Capacitor and reaching for a plugin that called into the operating system's own Bluetooth stack. A page running directly in a supporting browser can request a device, connect to its GATT services, and read or write characteristics with no native wrapper at all. This is a narrower case than most of this catalog. It replaces the native-app packaging step these plugins exist for, rather than a JavaScript library doing work the browser could already do.",
9
+ snippet: `const device = await navigator.bluetooth.requestDevice({
10
+ acceptAllDevices: true,
11
+ });
12
+ const server = await device.gatt.connect();`,
13
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API",
14
+ },
15
+ agent: {
16
+ when: "connecting to a Bluetooth Low Energy device directly from a web page",
17
+ unless: [
18
+ "You need to support iOS in any browser. Apple has stated it has no plans to implement Web Bluetooth. That gap is permanent for iPhone and iPad users.",
19
+ "You need background scanning or a connection that survives the tab closing. The API only works while the page is open.",
20
+ "You are already shipping a native app shell for other reasons. The plugin ecosystem is more mature for background operation and OS-level pairing UI.",
21
+ ],
22
+ snippet: "await navigator.bluetooth.requestDevice({ acceptAllDevices: true });",
23
+ },
24
+ };
25
+ //# sourceMappingURL=web-bluetooth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-bluetooth.js","sourceRoot":"","sources":["../../src/rules/web-bluetooth.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,yBAAyB;IAChC,QAAQ,EAAE,CAAC,mCAAmC,EAAE,4BAA4B,CAAC;IAC7E,UAAU,EAAE,CAAC,eAAe,CAAC;IAC7B,MAAM,EAAE,qCAAqC;IAC7C,KAAK,EAAE;QACL,SAAS,EACP,4jBAA4jB;QAC9jB,OAAO,EAAE;;;4CAG+B;QACxC,MAAM,EACJ,oEAAoE;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,sEAAsE;QAC5E,MAAM,EAAE;YACN,uJAAuJ;YACvJ,wHAAwH;YACxH,sJAAsJ;SACvJ;QACD,OAAO,EACL,sEAAsE;KACzE;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const webShare: Rule;
3
+ //# sourceMappingURL=web-share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-share.d.ts","sourceRoot":"","sources":["../../src/rules/web-share.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,QAAQ,EAAE,IA2BtB,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const webShare = {
2
+ id: "web-share",
3
+ title: "Sharing to other apps",
4
+ replaces: ["react-share", "vue-social-sharing", "ngx-sharebuttons"],
5
+ featureIds: ["share"],
6
+ native: "navigator.share()",
7
+ human: {
8
+ explainer: "A share library renders a row of buttons, each pointing at one network's own share-intent URL, so the page decides where the content can go. navigator.share() opens the operating system's own share sheet instead, the same one every native app uses, and lets the person pick where it goes.",
9
+ snippet: `async function share() {
10
+ await navigator.share({
11
+ title: document.title,
12
+ url: location.href,
13
+ });
14
+ }`,
15
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share",
16
+ },
17
+ agent: {
18
+ when: "letting someone share the current page or a piece of content to whatever app they choose",
19
+ unless: [
20
+ "You need a button for one specific network, such as a fixed Twitter/X or LinkedIn share link. The OS share sheet lists whatever apps the person has installed, not a chosen set.",
21
+ "You support Firefox on desktop. It has never shipped the Web Share API outside Android.",
22
+ "You need to share a file the person doesn't already have a URL for. That needs the file-sharing variant of the API, which has narrower browser support again.",
23
+ ],
24
+ snippet: "await navigator.share({ title: document.title, url: location.href });",
25
+ },
26
+ };
27
+ //# sourceMappingURL=web-share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-share.js","sourceRoot":"","sources":["../../src/rules/web-share.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAS;IAC5B,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,CAAC,aAAa,EAAE,oBAAoB,EAAE,kBAAkB,CAAC;IACnE,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE;QACL,SAAS,EACP,kSAAkS;QACpS,OAAO,EAAE;;;;;EAKX;QACE,MAAM,EAAE,kEAAkE;KAC3E;IACD,KAAK,EAAE;QACL,IAAI,EAAE,0FAA0F;QAChG,MAAM,EAAE;YACN,kLAAkL;YAClL,yFAAyF;YACzF,+JAA+J;SAChK;QACD,OAAO,EACL,uEAAuE;KAC1E;CACF,CAAC"}
package/dist/schema.d.ts CHANGED
@@ -43,6 +43,7 @@ export declare const ruleSchema: z.ZodObject<{
43
43
  explainer: z.ZodString;
44
44
  snippet: z.ZodString;
45
45
  demoUrl: z.ZodOptional<z.ZodURL>;
46
+ mdnUrl: z.ZodOptional<z.ZodURL>;
46
47
  }, z.core.$strip>;
47
48
  agent: z.ZodObject<{
48
49
  when: z.ZodString;
@@ -70,6 +71,7 @@ export declare const catalogSchema: z.ZodArray<z.ZodObject<{
70
71
  explainer: z.ZodString;
71
72
  snippet: z.ZodString;
72
73
  demoUrl: z.ZodOptional<z.ZodURL>;
74
+ mdnUrl: z.ZodOptional<z.ZodURL>;
73
75
  }, z.core.$strip>;
74
76
  agent: z.ZodObject<{
75
77
  when: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;EAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAkBlE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;iBAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;iBA0DnB,CAAC;AAEL,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;kBA2BxB,CAAC;AAEH,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,CAEnD"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;EAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAkBlE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;iBAK/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DnB,CAAC;AAEL,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;kBA2BxB,CAAC;AAEH,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,CAEnD"}
package/dist/schema.js CHANGED
@@ -60,10 +60,12 @@ export const ruleSchema = z
60
60
  human: z.object({
61
61
  /** 2 to 4 sentences of prose. */
62
62
  explainer: z.string().min(1),
63
- /** Copy-pasteable CSS or HTML. */
63
+ /** Copy-pasteable CSS, HTML, or JavaScript. */
64
64
  snippet: z.string().min(1),
65
65
  /** A live demo or a post that walks through it. */
66
66
  demoUrl: z.url().optional(),
67
+ /** The MDN reference page for the native feature. */
68
+ mdnUrl: z.url().optional(),
67
69
  }),
68
70
  /** Terse projection for LLM surfaces. Budget roughly 200 tokens. */
69
71
  agent: z.object({