@jomae/catalog 0.6.0 → 0.9.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 (194) hide show
  1. package/README.md +1 -1
  2. package/dist/generated/baseline-history.js +4 -4
  3. package/dist/generated/baseline.d.ts.map +1 -1
  4. package/dist/generated/baseline.js +113 -1
  5. package/dist/generated/baseline.js.map +1 -1
  6. package/dist/generated/guides.d.ts.map +1 -1
  7. package/dist/generated/guides.js +6 -2
  8. package/dist/generated/guides.js.map +1 -1
  9. package/dist/generated/lint-rules.d.ts +26 -0
  10. package/dist/generated/lint-rules.d.ts.map +1 -0
  11. package/dist/generated/lint-rules.js +361 -0
  12. package/dist/generated/lint-rules.js.map +1 -0
  13. package/dist/generated/sizes.d.ts.map +1 -1
  14. package/dist/generated/sizes.js +128 -13
  15. package/dist/generated/sizes.js.map +1 -1
  16. package/dist/generated/support-claims.d.ts.map +1 -1
  17. package/dist/generated/support-claims.js +7 -1
  18. package/dist/generated/support-claims.js.map +1 -1
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/lint.d.ts +53 -0
  24. package/dist/lint.d.ts.map +1 -0
  25. package/dist/lint.js +41 -0
  26. package/dist/lint.js.map +1 -0
  27. package/dist/markdown.d.ts +31 -0
  28. package/dist/markdown.d.ts.map +1 -0
  29. package/dist/markdown.js +273 -0
  30. package/dist/markdown.js.map +1 -0
  31. package/dist/rules/abort-controller.d.ts.map +1 -1
  32. package/dist/rules/abort-controller.js +3 -0
  33. package/dist/rules/abort-controller.js.map +1 -1
  34. package/dist/rules/accordion.d.ts.map +1 -1
  35. package/dist/rules/accordion.js +3 -0
  36. package/dist/rules/accordion.js.map +1 -1
  37. package/dist/rules/array-grouping.d.ts.map +1 -1
  38. package/dist/rules/array-grouping.js +1 -0
  39. package/dist/rules/array-grouping.js.map +1 -1
  40. package/dist/rules/aspect-ratio.d.ts.map +1 -1
  41. package/dist/rules/aspect-ratio.js +4 -0
  42. package/dist/rules/aspect-ratio.js.map +1 -1
  43. package/dist/rules/base64.d.ts.map +1 -1
  44. package/dist/rules/base64.js +3 -0
  45. package/dist/rules/base64.js.map +1 -1
  46. package/dist/rules/broadcast-channel.d.ts.map +1 -1
  47. package/dist/rules/broadcast-channel.js +3 -0
  48. package/dist/rules/broadcast-channel.js.map +1 -1
  49. package/dist/rules/carousel.d.ts.map +1 -1
  50. package/dist/rules/carousel.js +5 -0
  51. package/dist/rules/carousel.js.map +1 -1
  52. package/dist/rules/clipboard.d.ts.map +1 -1
  53. package/dist/rules/clipboard.js +3 -0
  54. package/dist/rules/clipboard.js.map +1 -1
  55. package/dist/rules/container-queries.d.ts.map +1 -1
  56. package/dist/rules/container-queries.js +3 -0
  57. package/dist/rules/container-queries.js.map +1 -1
  58. package/dist/rules/date-time-input.d.ts.map +1 -1
  59. package/dist/rules/date-time-input.js +4 -0
  60. package/dist/rules/date-time-input.js.map +1 -1
  61. package/dist/rules/dialog.d.ts.map +1 -1
  62. package/dist/rules/dialog.js +4 -0
  63. package/dist/rules/dialog.js.map +1 -1
  64. package/dist/rules/discrete-transitions.d.ts.map +1 -1
  65. package/dist/rules/discrete-transitions.js +4 -0
  66. package/dist/rules/discrete-transitions.js.map +1 -1
  67. package/dist/rules/display-names.d.ts +3 -0
  68. package/dist/rules/display-names.d.ts.map +1 -0
  69. package/dist/rules/display-names.js +33 -0
  70. package/dist/rules/display-names.js.map +1 -0
  71. package/dist/rules/duration-format.d.ts.map +1 -1
  72. package/dist/rules/duration-format.js +3 -0
  73. package/dist/rules/duration-format.js.map +1 -1
  74. package/dist/rules/event-target.d.ts.map +1 -1
  75. package/dist/rules/event-target.js +1 -0
  76. package/dist/rules/event-target.js.map +1 -1
  77. package/dist/rules/focus-visible.d.ts.map +1 -1
  78. package/dist/rules/focus-visible.js +4 -0
  79. package/dist/rules/focus-visible.js.map +1 -1
  80. package/dist/rules/fullscreen.d.ts.map +1 -1
  81. package/dist/rules/fullscreen.js +3 -0
  82. package/dist/rules/fullscreen.js.map +1 -1
  83. package/dist/rules/height-animation.d.ts.map +1 -1
  84. package/dist/rules/height-animation.js +5 -1
  85. package/dist/rules/height-animation.js.map +1 -1
  86. package/dist/rules/index.d.ts.map +1 -1
  87. package/dist/rules/index.js +16 -0
  88. package/dist/rules/index.js.map +1 -1
  89. package/dist/rules/inert.d.ts.map +1 -1
  90. package/dist/rules/inert.js +4 -0
  91. package/dist/rules/inert.js.map +1 -1
  92. package/dist/rules/intersection-observer.d.ts.map +1 -1
  93. package/dist/rules/intersection-observer.js +1 -0
  94. package/dist/rules/intersection-observer.js.map +1 -1
  95. package/dist/rules/lazy-loading.d.ts.map +1 -1
  96. package/dist/rules/lazy-loading.js +4 -0
  97. package/dist/rules/lazy-loading.js.map +1 -1
  98. package/dist/rules/line-clamp.d.ts.map +1 -1
  99. package/dist/rules/line-clamp.js +4 -0
  100. package/dist/rules/line-clamp.js.map +1 -1
  101. package/dist/rules/list-format.d.ts +3 -0
  102. package/dist/rules/list-format.d.ts.map +1 -0
  103. package/dist/rules/list-format.js +37 -0
  104. package/dist/rules/list-format.js.map +1 -0
  105. package/dist/rules/masonry.d.ts.map +1 -1
  106. package/dist/rules/masonry.js +4 -0
  107. package/dist/rules/masonry.js.map +1 -1
  108. package/dist/rules/natural-sort.d.ts.map +1 -1
  109. package/dist/rules/natural-sort.js +4 -0
  110. package/dist/rules/natural-sort.js.map +1 -1
  111. package/dist/rules/number-format.d.ts.map +1 -1
  112. package/dist/rules/number-format.js +4 -0
  113. package/dist/rules/number-format.js.map +1 -1
  114. package/dist/rules/page-visibility.d.ts.map +1 -1
  115. package/dist/rules/page-visibility.js +3 -0
  116. package/dist/rules/page-visibility.js.map +1 -1
  117. package/dist/rules/popover.d.ts.map +1 -1
  118. package/dist/rules/popover.js +5 -0
  119. package/dist/rules/popover.js.map +1 -1
  120. package/dist/rules/random-uuid.d.ts.map +1 -1
  121. package/dist/rules/random-uuid.js +4 -0
  122. package/dist/rules/random-uuid.js.map +1 -1
  123. package/dist/rules/relative-time.d.ts.map +1 -1
  124. package/dist/rules/relative-time.js +4 -0
  125. package/dist/rules/relative-time.js.map +1 -1
  126. package/dist/rules/resizable-panels.d.ts.map +1 -1
  127. package/dist/rules/resizable-panels.js +3 -0
  128. package/dist/rules/resizable-panels.js.map +1 -1
  129. package/dist/rules/resize-observer.d.ts.map +1 -1
  130. package/dist/rules/resize-observer.js +4 -0
  131. package/dist/rules/resize-observer.js.map +1 -1
  132. package/dist/rules/scroll-animations.d.ts.map +1 -1
  133. package/dist/rules/scroll-animations.js +4 -0
  134. package/dist/rules/scroll-animations.js.map +1 -1
  135. package/dist/rules/scroll-lock.d.ts.map +1 -1
  136. package/dist/rules/scroll-lock.js +3 -0
  137. package/dist/rules/scroll-lock.js.map +1 -1
  138. package/dist/rules/scrollbars.d.ts.map +1 -1
  139. package/dist/rules/scrollbars.js +3 -0
  140. package/dist/rules/scrollbars.js.map +1 -1
  141. package/dist/rules/segmenter.d.ts +3 -0
  142. package/dist/rules/segmenter.d.ts.map +1 -0
  143. package/dist/rules/segmenter.js +41 -0
  144. package/dist/rules/segmenter.js.map +1 -0
  145. package/dist/rules/select.d.ts.map +1 -1
  146. package/dist/rules/select.js +3 -0
  147. package/dist/rules/select.js.map +1 -1
  148. package/dist/rules/signal-timeout.d.ts +3 -0
  149. package/dist/rules/signal-timeout.d.ts.map +1 -0
  150. package/dist/rules/signal-timeout.js +31 -0
  151. package/dist/rules/signal-timeout.js.map +1 -0
  152. package/dist/rules/smooth-scroll.d.ts.map +1 -1
  153. package/dist/rules/smooth-scroll.js +4 -0
  154. package/dist/rules/smooth-scroll.js.map +1 -1
  155. package/dist/rules/sticky.d.ts.map +1 -1
  156. package/dist/rules/sticky.js +4 -0
  157. package/dist/rules/sticky.js.map +1 -1
  158. package/dist/rules/structured-clone.d.ts.map +1 -1
  159. package/dist/rules/structured-clone.js +1 -0
  160. package/dist/rules/structured-clone.js.map +1 -1
  161. package/dist/rules/text-wrap-balance.d.ts.map +1 -1
  162. package/dist/rules/text-wrap-balance.js +3 -0
  163. package/dist/rules/text-wrap-balance.js.map +1 -1
  164. package/dist/rules/url-pattern.d.ts +3 -0
  165. package/dist/rules/url-pattern.d.ts.map +1 -0
  166. package/dist/rules/url-pattern.js +36 -0
  167. package/dist/rules/url-pattern.js.map +1 -0
  168. package/dist/rules/url-search-params.d.ts.map +1 -1
  169. package/dist/rules/url-search-params.js +1 -0
  170. package/dist/rules/url-search-params.js.map +1 -1
  171. package/dist/rules/web-animations.d.ts +3 -0
  172. package/dist/rules/web-animations.d.ts.map +1 -0
  173. package/dist/rules/web-animations.js +40 -0
  174. package/dist/rules/web-animations.js.map +1 -0
  175. package/dist/rules/web-locks.d.ts +3 -0
  176. package/dist/rules/web-locks.d.ts.map +1 -0
  177. package/dist/rules/web-locks.js +35 -0
  178. package/dist/rules/web-locks.js.map +1 -0
  179. package/dist/rules/web-share.d.ts.map +1 -1
  180. package/dist/rules/web-share.js +3 -0
  181. package/dist/rules/web-share.js.map +1 -1
  182. package/dist/rules/with-resolvers.d.ts +3 -0
  183. package/dist/rules/with-resolvers.d.ts.map +1 -0
  184. package/dist/rules/with-resolvers.js +30 -0
  185. package/dist/rules/with-resolvers.js.map +1 -0
  186. package/dist/schema.d.ts +4 -0
  187. package/dist/schema.d.ts.map +1 -1
  188. package/dist/schema.js +34 -0
  189. package/dist/schema.js.map +1 -1
  190. package/dist/search.d.ts +29 -0
  191. package/dist/search.d.ts.map +1 -0
  192. package/dist/search.js +84 -0
  193. package/dist/search.js.map +1 -0
  194. package/package.json +2 -2
@@ -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,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"}
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;QAC1C,UAAU,EAAE;YACV,mGAAmG;YACnG,2EAA2E;SAC5E;KACF;IACD,MAAM,EAAE,CAAC,yBAAyB,CAAC;CACpC,CAAC"}
@@ -1 +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"}
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,IA4CvB,CAAC"}
@@ -34,6 +34,10 @@ export const lineClamp = {
34
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
35
  ],
36
36
  snippet: ".excerpt { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }",
37
+ handRolled: [
38
+ "measuring rendered text in a hidden element or on a canvas to decide where a line should visually end",
39
+ "slicing a string by character count before rendering it, so a card title fits its two lines",
40
+ ],
37
41
  },
38
42
  };
39
43
  //# sourceMappingURL=line-clamp.js.map
@@ -1 +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
+ {"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;QAC7G,UAAU,EAAE;YACV,uGAAuG;YACvG,6FAA6F;SAC9F;KACF;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const listFormat: Rule;
3
+ //# sourceMappingURL=list-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-format.d.ts","sourceRoot":"","sources":["../../src/rules/list-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IAqCxB,CAAC"}
@@ -0,0 +1,37 @@
1
+ export const listFormat = {
2
+ id: "intl-list-format",
3
+ title: "Joining a list into a sentence",
4
+ category: "formatting",
5
+ replaces: ["humanize-list"],
6
+ featureIds: ["intl-list-format"],
7
+ native: "Intl.ListFormat",
8
+ human: {
9
+ explainer: 'Commas between the items and an "and" before the last one looks like string work until there is a second language. Intl.ListFormat renders the list with the separators and the conjunction the locale actually uses, so English gets its serial comma and German gets "und" without either being written down. It also handles disjunctions, where the joining word is "or", and plain unit lists with no conjunction at all.',
10
+ snippet: `const fmt = new Intl.ListFormat("en", { type: "conjunction" });
11
+ fmt.format(["apples", "pears", "plums"]);
12
+ // "apples, pears, and plums"
13
+
14
+ new Intl.ListFormat("de").format(["Äpfel", "Birnen", "Pflaumen"]);
15
+ // "Äpfel, Birnen und Pflaumen"
16
+
17
+ new Intl.ListFormat("en", { type: "disjunction" }).format(["red", "blue"]);
18
+ // "red or blue"`,
19
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat",
20
+ },
21
+ agent: {
22
+ when: 'joining several items into one phrase, such as "apples, pears, and plums"',
23
+ unless: [
24
+ 'You truncate long lists, as in "Ana, Ben and 4 others". Intl.ListFormat renders every item it is given, so deciding how many to show and building the "and N more" item stays your code.',
25
+ "You need a separator the locale does not use, such as joining with a slash or a bullet for a breadcrumb. That is Array.prototype.join, and neither the library nor Intl is involved.",
26
+ "The items are not already strings. format() throws a TypeError on anything else, where humanize-list coerces, so numbers and nulls that used to render now break.",
27
+ "You depend on humanize-list's exact output, including its oxfordComma option. Intl follows the locale's own convention, so switching changes visible text in English.",
28
+ "You need each item wrapped in markup. formatToParts() gives you the pieces and their types, but reassembling them into elements is work the plain format() call does not do.",
29
+ ],
30
+ snippet: `new Intl.ListFormat("en", { type: "conjunction" }).format([
31
+ "apples",
32
+ "pears",
33
+ "plums",
34
+ ]);`,
35
+ },
36
+ };
37
+ //# sourceMappingURL=list-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-format.js","sourceRoot":"","sources":["../../src/rules/list-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,kBAAkB;IACtB,KAAK,EAAE,gCAAgC;IACvC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,UAAU,EAAE,CAAC,kBAAkB,CAAC;IAChC,MAAM,EAAE,iBAAiB;IACzB,KAAK,EAAE;QACL,SAAS,EACP,gaAAga;QACla,OAAO,EAAE;;;;;;;;iBAQI;QACb,MAAM,EACJ,kGAAkG;KACrG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,2EAA2E;QACjF,MAAM,EAAE;YACN,0LAA0L;YAC1L,sLAAsL;YACtL,mKAAmK;YACnK,uKAAuK;YACvK,8KAA8K;SAC/K;QACD,OAAO,EAAE;;;;IAIT;KACD;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,IA4DrB,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,IAgErB,CAAC"}
@@ -55,6 +55,10 @@ export const masonry = {
55
55
  .gallery { columns: 16rem; }
56
56
  .gallery > * { break-inside: avoid; }
57
57
  }`,
58
+ handRolled: [
59
+ "distributing items into column arrays in JavaScript by tracking each column's running height",
60
+ "absolutely positioning items after measuring them so the gaps between rows close up",
61
+ ],
58
62
  },
59
63
  };
60
64
  //# sourceMappingURL=masonry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"masonry.js","sourceRoot":"","sources":["../../src/rules/masonry.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,iBAAiB;IACxB,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE;QACR,mBAAmB;QACnB,gBAAgB;QAChB,yBAAyB;QACzB,OAAO;QACP,qBAAqB;QACrB,aAAa;QACb,iBAAiB;KAClB;IACD,UAAU,EAAE,CAAC,SAAS,CAAC;IACvB,MAAM,EAAE,4BAA4B;IACpC,KAAK,EAAE;QACL,SAAS,EACP,wiBAAwiB;QAC1iB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;EAoBX;QACE,MAAM,EACJ,iFAAiF;KACpF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,uFAAuF;QAC7F,MAAM,EAAE;YACN,8LAA8L;YAC9L,6EAA6E;YAC7E,iEAAiE;YACjE,yHAAyH;SAC1H;QACD,OAAO,EAAE;;;;;;;;EAQX;KACC;CACF,CAAC"}
1
+ {"version":3,"file":"masonry.js","sourceRoot":"","sources":["../../src/rules/masonry.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,iBAAiB;IACxB,QAAQ,EAAE,QAAQ;IAClB,QAAQ,EAAE;QACR,mBAAmB;QACnB,gBAAgB;QAChB,yBAAyB;QACzB,OAAO;QACP,qBAAqB;QACrB,aAAa;QACb,iBAAiB;KAClB;IACD,UAAU,EAAE,CAAC,SAAS,CAAC;IACvB,MAAM,EAAE,4BAA4B;IACpC,KAAK,EAAE;QACL,SAAS,EACP,wiBAAwiB;QAC1iB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;EAoBX;QACE,MAAM,EACJ,iFAAiF;KACpF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,uFAAuF;QAC7F,MAAM,EAAE;YACN,8LAA8L;YAC9L,6EAA6E;YAC7E,iEAAiE;YACjE,yHAAyH;SAC1H;QACD,OAAO,EAAE;;;;;;;;EAQX;QACE,UAAU,EAAE;YACV,8FAA8F;YAC9F,qFAAqF;SACtF;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"natural-sort.d.ts","sourceRoot":"","sources":["../../src/rules/natural-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IAyCzB,CAAC"}
1
+ {"version":3,"file":"natural-sort.d.ts","sourceRoot":"","sources":["../../src/rules/natural-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,WAAW,EAAE,IA6CzB,CAAC"}
@@ -36,6 +36,10 @@ export const naturalSort = {
36
36
  ],
37
37
  snippet: `const collator = new Intl.Collator(undefined, { numeric: true });
38
38
  list.sort(collator.compare);`,
39
+ handRolled: [
40
+ "a comparator pulling digits out of strings with a regex and comparing them as numbers",
41
+ "zero-padding numbers inside strings so a plain sort puts item10 after item9",
42
+ ],
39
43
  },
40
44
  };
41
45
  //# sourceMappingURL=natural-sort.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"natural-sort.js","sourceRoot":"","sources":["../../src/rules/natural-sort.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,kCAAkC;IACzC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,iBAAiB;QACjB,sBAAsB;QACtB,iBAAiB;QACjB,wBAAwB;KACzB;IACD,UAAU,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,EAAE,kCAAkC;IAC1C,KAAK,EAAE;QACL,SAAS,EACP,kYAAkY;QACpY,OAAO,EAAE;;;;;;;;;;2BAUc;QACvB,MAAM,EACJ,gGAAgG;KACnG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qEAAqE;QAC3E,MAAM,EAAE;YACN,uMAAuM;YACvM,kKAAkK;YAClK,mKAAmK;YACnK,6IAA6I;YAC7I,6IAA6I;SAC9I;QACD,OAAO,EAAE;6BACgB;KAC1B;CACF,CAAC"}
1
+ {"version":3,"file":"natural-sort.js","sourceRoot":"","sources":["../../src/rules/natural-sort.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,kCAAkC;IACzC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,iBAAiB;QACjB,sBAAsB;QACtB,iBAAiB;QACjB,wBAAwB;KACzB;IACD,UAAU,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,EAAE,kCAAkC;IAC1C,KAAK,EAAE;QACL,SAAS,EACP,kYAAkY;QACpY,OAAO,EAAE;;;;;;;;;;2BAUc;QACvB,MAAM,EACJ,gGAAgG;KACnG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qEAAqE;QAC3E,MAAM,EAAE;YACN,uMAAuM;YACvM,kKAAkK;YAClK,mKAAmK;YACnK,6IAA6I;YAC7I,6IAA6I;SAC9I;QACD,OAAO,EAAE;6BACgB;QACzB,UAAU,EAAE;YACV,uFAAuF;YACvF,6EAA6E;SAC9E;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"number-format.d.ts","sourceRoot":"","sources":["../../src/rules/number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IA4B1B,CAAC"}
1
+ {"version":3,"file":"number-format.d.ts","sourceRoot":"","sources":["../../src/rules/number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAgC1B,CAAC"}
@@ -22,6 +22,10 @@ export const numberFormat = {
22
22
  "You need a custom format pattern, such as a specific abbreviation style, that the options Intl.NumberFormat exposes cannot express.",
23
23
  ],
24
24
  snippet: 'new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);',
25
+ handRolled: [
26
+ "a regex inserting thousands separators into a number's string form",
27
+ "toFixed followed by string surgery to add a currency symbol and group the digits",
28
+ ],
25
29
  },
26
30
  };
27
31
  //# sourceMappingURL=number-format.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"number-format.js","sourceRoot":"","sources":["../../src/rules/number-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,6CAA6C;IACpD,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC;IACnE,UAAU,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE;QACL,SAAS,EACP,wZAAwZ;QAC1Z,OAAO,EAAE;;;kCAGqB;QAC9B,MAAM,EACJ,oGAAoG;KACvG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,yGAAyG;QAC/G,MAAM,EAAE;YACN,0fAA0f;YAC1f,mOAAmO;YACnO,qJAAqJ;YACrJ,qIAAqI;SACtI;QACD,OAAO,EACL,uFAAuF;KAC1F;CACF,CAAC"}
1
+ {"version":3,"file":"number-format.js","sourceRoot":"","sources":["../../src/rules/number-format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,6CAA6C;IACpD,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC;IACnE,UAAU,EAAE,CAAC,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB;IAC3B,KAAK,EAAE;QACL,SAAS,EACP,wZAAwZ;QAC1Z,OAAO,EAAE;;;kCAGqB;QAC9B,MAAM,EACJ,oGAAoG;KACvG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,yGAAyG;QAC/G,MAAM,EAAE;YACN,0fAA0f;YAC1f,mOAAmO;YACnO,qJAAqJ;YACrJ,qIAAqI;SACtI;QACD,OAAO,EACL,uFAAuF;QACzF,UAAU,EAAE;YACV,oEAAoE;YACpE,kFAAkF;SACnF;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"page-visibility.d.ts","sourceRoot":"","sources":["../../src/rules/page-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,IA6B5B,CAAC"}
1
+ {"version":3,"file":"page-visibility.d.ts","sourceRoot":"","sources":["../../src/rules/page-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,cAAc,EAAE,IAgC5B,CAAC"}
@@ -20,6 +20,9 @@ export const pageVisibility = {
20
20
  "You need to distinguish a window occluded by another window from a genuinely backgrounded tab. visibilityState only reports the latter.",
21
21
  ],
22
22
  snippet: `document.addEventListener("visibilitychange", () => { ... });`,
23
+ handRolled: [
24
+ "a blur handler standing in for the tab being backgrounded, pausing a poll that a focus handler resumes",
25
+ ],
23
26
  },
24
27
  guides: [
25
28
  "detect-initial-visibility-state",
@@ -1 +1 @@
1
- {"version":3,"file":"page-visibility.js","sourceRoot":"","sources":["../../src/rules/page-visibility.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,uBAAuB,EAAE,cAAc,CAAC;IACnD,UAAU,EAAE,CAAC,iBAAiB,CAAC;IAC/B,MAAM,EAAE,yDAAyD;IACjE,KAAK,EAAE;QACL,SAAS,EACP,wRAAwR;QAC1R,OAAO,EAAE;;;IAGT;QACA,MAAM,EACJ,kFAAkF;KACrF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,kGAAkG;QACxG,MAAM,EAAE;YACN,+GAA+G;YAC/G,yIAAyI;SAC1I;QACD,OAAO,EAAE,+DAA+D;KACzE;IACD,MAAM,EAAE;QACN,iCAAiC;QACjC,iCAAiC;KAClC;CACF,CAAC"}
1
+ {"version":3,"file":"page-visibility.js","sourceRoot":"","sources":["../../src/rules/page-visibility.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,gBAAgB;IACvB,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,uBAAuB,EAAE,cAAc,CAAC;IACnD,UAAU,EAAE,CAAC,iBAAiB,CAAC;IAC/B,MAAM,EAAE,yDAAyD;IACjE,KAAK,EAAE;QACL,SAAS,EACP,wRAAwR;QAC1R,OAAO,EAAE;;;IAGT;QACA,MAAM,EACJ,kFAAkF;KACrF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,kGAAkG;QACxG,MAAM,EAAE;YACN,+GAA+G;YAC/G,yIAAyI;SAC1I;QACD,OAAO,EAAE,+DAA+D;QACxE,UAAU,EAAE;YACV,wGAAwG;SACzG;KACF;IACD,MAAM,EAAE;QACN,iCAAiC;QACjC,iCAAiC;KAClC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../src/rules/popover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,IAuErB,CAAC"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../src/rules/popover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,IA4ErB,CAAC"}
@@ -62,6 +62,11 @@ export const popover = {
62
62
  position-try-fallbacks: flip-block;
63
63
  }
64
64
  </style>`,
65
+ handRolled: [
66
+ "calling getBoundingClientRect on a trigger inside scroll and resize listeners to place a floating panel",
67
+ "writing top and left onto a tooltip from a requestAnimationFrame loop",
68
+ "flip logic comparing a panel's rect against the viewport and moving it to the other side of its trigger",
69
+ ],
65
70
  },
66
71
  guides: [
67
72
  "position-aware-tooltips",
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../src/rules/popover.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,4BAA4B;IAChC,KAAK,EAAE,kCAAkC;IACzC,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE;QACR,oBAAoB;QACpB,wBAAwB;QACxB,kBAAkB;QAClB,gBAAgB;QAChB,WAAW;QACX,UAAU;QACV,gBAAgB;QAChB,cAAc;QACd,eAAe;QACf,cAAc;QACd,WAAW;QACX,2BAA2B;KAC5B;IACD,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC;IAC7C,MAAM,EAAE,6CAA6C;IACrD,KAAK,EAAE;QACL,SAAS,EACP,ugBAAugB;QACzgB,OAAO,EAAE;;;;;;;;;;;;;;;;;;SAkBJ;QACL,OAAO,EAAE,6CAA6C;QACtD,MAAM,EAAE,8DAA8D;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,oEAAoE;QAC1E,MAAM,EAAE;YACN,uUAAuU;YACvU,iIAAiI;YACjI,0DAA0D;YAC1D,iHAAiH;YACjH,uEAAuE;SACxE;QACD,OAAO,EAAE;;;;;;;;;;SAUJ;KACN;IACD,MAAM,EAAE;QACN,yBAAyB;QACzB,6BAA6B;QAC7B,8CAA8C;KAC/C;CACF,CAAC"}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../src/rules/popover.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,4BAA4B;IAChC,KAAK,EAAE,kCAAkC;IACzC,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE;QACR,oBAAoB;QACpB,wBAAwB;QACxB,kBAAkB;QAClB,gBAAgB;QAChB,WAAW;QACX,UAAU;QACV,gBAAgB;QAChB,cAAc;QACd,eAAe;QACf,cAAc;QACd,WAAW;QACX,2BAA2B;KAC5B;IACD,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC;IAC7C,MAAM,EAAE,6CAA6C;IACrD,KAAK,EAAE;QACL,SAAS,EACP,ugBAAugB;QACzgB,OAAO,EAAE;;;;;;;;;;;;;;;;;;SAkBJ;QACL,OAAO,EAAE,6CAA6C;QACtD,MAAM,EAAE,8DAA8D;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,oEAAoE;QAC1E,MAAM,EAAE;YACN,uUAAuU;YACvU,iIAAiI;YACjI,0DAA0D;YAC1D,iHAAiH;YACjH,uEAAuE;SACxE;QACD,OAAO,EAAE;;;;;;;;;;SAUJ;QACL,UAAU,EAAE;YACV,yGAAyG;YACzG,uEAAuE;YACvE,yGAAyG;SAC1G;KACF;IACD,MAAM,EAAE;QACN,yBAAyB;QACzB,6BAA6B;QAC7B,8CAA8C;KAC/C;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"random-uuid.d.ts","sourceRoot":"","sources":["../../src/rules/random-uuid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IA+BxB,CAAC"}
1
+ {"version":3,"file":"random-uuid.d.ts","sourceRoot":"","sources":["../../src/rules/random-uuid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,UAAU,EAAE,IAmCxB,CAAC"}
@@ -26,6 +26,10 @@ export const randomUuid = {
26
26
  "You need identifiers shorter or differently shaped than a 36-character UUID, which is what nanoid and short-uuid are for.",
27
27
  ],
28
28
  snippet: "const id = crypto.randomUUID();",
29
+ handRolled: [
30
+ "a v4 id built from Math.random() and a template string of x and y placeholders",
31
+ "Date.now() joined to Math.random().toString(36) to make something unique enough",
32
+ ],
29
33
  },
30
34
  };
31
35
  //# sourceMappingURL=random-uuid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"random-uuid.js","sourceRoot":"","sources":["../../src/rules/random-uuid.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,CAAC;IAC3D,UAAU,EAAE,EAAE;IACd,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,IAAI,EAAE,+gBAA+gB;KACthB;IACD,MAAM,EAAE,qBAAqB;IAC7B,KAAK,EAAE;QACL,SAAS,EACP,2ZAA2Z;QAC7Z,OAAO,EAAE;0CAC6B;QACtC,MAAM,EACJ,oEAAoE;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6BAA6B;QACnC,MAAM,EAAE;YACN,oKAAoK;YACpK,wJAAwJ;YACxJ,qJAAqJ;YACrJ,wRAAwR;YACxR,2HAA2H;SAC5H;QACD,OAAO,EAAE,iCAAiC;KAC3C;CACF,CAAC"}
1
+ {"version":3,"file":"random-uuid.js","sourceRoot":"","sources":["../../src/rules/random-uuid.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,kBAAkB;IACzB,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,CAAC;IAC3D,UAAU,EAAE,EAAE;IACd,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,IAAI,EAAE,+gBAA+gB;KACthB;IACD,MAAM,EAAE,qBAAqB;IAC7B,KAAK,EAAE;QACL,SAAS,EACP,2ZAA2Z;QAC7Z,OAAO,EAAE;0CAC6B;QACtC,MAAM,EACJ,oEAAoE;KACvE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,6BAA6B;QACnC,MAAM,EAAE;YACN,oKAAoK;YACpK,wJAAwJ;YACxJ,qJAAqJ;YACrJ,wRAAwR;YACxR,2HAA2H;SAC5H;QACD,OAAO,EAAE,iCAAiC;QAC1C,UAAU,EAAE;YACV,gFAAgF;YAChF,iFAAiF;SAClF;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../src/rules/relative-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IAyB1B,CAAC"}
1
+ {"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../src/rules/relative-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,YAAY,EAAE,IA6B1B,CAAC"}
@@ -19,6 +19,10 @@ rtf.format(-5, "minute"); // "5 minutes ago"`,
19
19
  "You need a locale Intl's relative-time data doesn't cover well on your target browsers, or offline locale data bundled ahead of time.",
20
20
  ],
21
21
  snippet: 'new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-5, "minute");',
22
+ handRolled: [
23
+ "a chain of millisecond thresholds turning a date difference into minutes, hours or days ago",
24
+ "a table of singular and plural unit names written out to build phrases like 3 days ago",
25
+ ],
22
26
  },
23
27
  };
24
28
  //# sourceMappingURL=relative-time.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../../src/rules/relative-time.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,qBAAqB,EAAE,YAAY,EAAE,eAAe,CAAC;IAChE,UAAU,EAAE,CAAC,2BAA2B,CAAC;IACzC,MAAM,EAAE,yBAAyB;IACjC,KAAK,EAAE;QACL,SAAS,EACP,gTAAgT;QAClT,OAAO,EAAE;6CACgC;QACzC,MAAM,EACJ,0GAA0G;KAC7G;IACD,KAAK,EAAE;QACL,IAAI,EAAE,iFAAiF;QACvF,MAAM,EAAE;YACN,iQAAiQ;YACjQ,iNAAiN;YACjN,uIAAuI;SACxI;QACD,OAAO,EACL,8EAA8E;KACjF;CACF,CAAC"}
1
+ {"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../../src/rules/relative-time.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,0BAA0B;IACjC,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,qBAAqB,EAAE,YAAY,EAAE,eAAe,CAAC;IAChE,UAAU,EAAE,CAAC,2BAA2B,CAAC;IACzC,MAAM,EAAE,yBAAyB;IACjC,KAAK,EAAE;QACL,SAAS,EACP,gTAAgT;QAClT,OAAO,EAAE;6CACgC;QACzC,MAAM,EACJ,0GAA0G;KAC7G;IACD,KAAK,EAAE;QACL,IAAI,EAAE,iFAAiF;QACvF,MAAM,EAAE;YACN,iQAAiQ;YACjQ,iNAAiN;YACjN,uIAAuI;SACxI;QACD,OAAO,EACL,8EAA8E;QAChF,UAAU,EAAE;YACV,6FAA6F;YAC7F,wFAAwF;SACzF;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"resizable-panels.d.ts","sourceRoot":"","sources":["../../src/rules/resizable-panels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IA+B7B,CAAC"}
1
+ {"version":3,"file":"resizable-panels.d.ts","sourceRoot":"","sources":["../../src/rules/resizable-panels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,EAAE,IAkC7B,CAAC"}
@@ -26,6 +26,9 @@ export const resizablePanels = {
26
26
  "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.",
27
27
  ],
28
28
  snippet: ".sidebar { resize: horizontal; overflow: auto; min-width: 12rem; max-width: 32rem; }",
29
+ handRolled: [
30
+ "a mousedown on one panel's edge with mousemove handlers writing a width onto that same panel",
31
+ ],
29
32
  },
30
33
  };
31
34
  //# sourceMappingURL=resizable-panels.js.map
@@ -1 +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,QAAQ;IAClB,QAAQ,EAAE,CAAC,cAAc,CAAC;IAC1B,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,6IAA6I;YAC7I,wUAAwU;YACxU,+JAA+J;YAC/J,6JAA6J;YAC7J,mJAAmJ;YACnJ,uJAAuJ;SACxJ;QACD,OAAO,EACL,sFAAsF;KACzF;CACF,CAAC"}
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,QAAQ;IAClB,QAAQ,EAAE,CAAC,cAAc,CAAC;IAC1B,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,6IAA6I;YAC7I,wUAAwU;YACxU,+JAA+J;YAC/J,6JAA6J;YAC7J,mJAAmJ;YACnJ,uJAAuJ;SACxJ;QACD,OAAO,EACL,sFAAsF;QACxF,UAAU,EAAE;YACV,8FAA8F;SAC/F;KACF;CACF,CAAC"}
@@ -1 +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,IA2B5B,CAAC"}
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,IA+B5B,CAAC"}
@@ -23,6 +23,10 @@ observer.observe(document.querySelector("#panel"));`,
23
23
  "You need devicePixelContentBoxSize specifically. Chrome has it from {{chrome:api.ResizeObserverEntry.devicePixelContentBoxSize}} and Firefox from {{firefox:api.ResizeObserverEntry.devicePixelContentBoxSize}}, but Safari does not implement it at all.",
24
24
  ],
25
25
  snippet: "new ResizeObserver((entries) => { ... }).observe(el);",
26
+ handRolled: [
27
+ "polling an element's dimensions on an interval to notice when they change",
28
+ ],
26
29
  },
30
+ lintRule: "unicorn/prefer-observer-apis",
27
31
  };
28
32
  //# sourceMappingURL=resize-observer.js.map
@@ -1 +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,YAAY;IACtB,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,2PAA2P;SAC5P;QACD,OAAO,EAAE,uDAAuD;KACjE;CACF,CAAC"}
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,YAAY;IACtB,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,2PAA2P;SAC5P;QACD,OAAO,EAAE,uDAAuD;QAChE,UAAU,EAAE;YACV,2EAA2E;SAC5E;KACF;IACD,QAAQ,EAAE,8BAA8B;CACzC,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,IAmE9B,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,IAuE9B,CAAC"}
@@ -55,6 +55,10 @@ export const scrollAnimations = {
55
55
  animation-range: entry 0% cover 40%;
56
56
  }
57
57
  }`,
58
+ handRolled: [
59
+ "a scroll listener setting a progress bar's width from scrollY over scrollHeight",
60
+ "mapping scroll position to a transform or an opacity on every scroll event",
61
+ ],
58
62
  },
59
63
  guides: [
60
64
  "parallax-scroll-effects",
@@ -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,WAAW;IACrB,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,2PAA2P;YAC3P,sLAAsL;YACtL,2IAA2I;YAC3I,sHAAsH;YACtH,4IAA4I;SAC7I;QACD,OAAO,EAAE;;;;;;;EAOX;KACC;IACD,MAAM,EAAE;QACN,yBAAyB;QACzB,gBAAgB;QAChB,2BAA2B;QAC3B,2BAA2B;QAC3B,4BAA4B;KAC7B;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,WAAW;IACrB,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,2PAA2P;YAC3P,sLAAsL;YACtL,2IAA2I;YAC3I,sHAAsH;YACtH,4IAA4I;SAC7I;QACD,OAAO,EAAE;;;;;;;EAOX;QACE,UAAU,EAAE;YACV,iFAAiF;YACjF,4EAA4E;SAC7E;KACF;IACD,MAAM,EAAE;QACN,yBAAyB;QACzB,gBAAgB;QAChB,2BAA2B;QAC3B,2BAA2B;QAC3B,4BAA4B;KAC7B;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,IA0CxB,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,IA6CxB,CAAC"}
@@ -37,6 +37,9 @@ body {
37
37
  overflow-y: auto;
38
38
  overscroll-behavior: contain;
39
39
  }`,
40
+ handRolled: [
41
+ "setting document.body.style.overflow to hidden when an overlay opens, and restoring it on close",
42
+ ],
40
43
  },
41
44
  };
42
45
  //# sourceMappingURL=scroll-lock.js.map
@@ -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,WAAW;IACrB,QAAQ,EAAE,CAAC,kBAAkB,CAAC;IAC9B,UAAU,EAAE,EAAE;IACd,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,IAAI,EAAE,mlBAAmlB;KAC1lB;IACD,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
+ {"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,WAAW;IACrB,QAAQ,EAAE,CAAC,kBAAkB,CAAC;IAC9B,UAAU,EAAE,EAAE;IACd,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,YAAY;QACxB,IAAI,EAAE,mlBAAmlB;KAC1lB;IACD,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;QACE,UAAU,EAAE;YACV,iGAAiG;SAClG;KACF;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,IAoDxB,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,IAuDxB,CAAC"}
@@ -44,6 +44,9 @@ html {
44
44
  scrollbar-width: thin;
45
45
  scrollbar-color: #666 transparent;
46
46
  }`,
47
+ handRolled: [
48
+ "measuring the scrollbar width from innerWidth minus documentElement.clientWidth and padding the body by it",
49
+ ],
47
50
  },
48
51
  guides: [
49
52
  "customize-scrollbar-color-and-thickness",
@@ -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,WAAW;IACrB,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;IACD,MAAM,EAAE;QACN,yCAAyC;QACzC,yCAAyC;KAC1C;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,WAAW;IACrB,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;QACE,UAAU,EAAE;YACV,4GAA4G;SAC7G;KACF;IACD,MAAM,EAAE;QACN,yCAAyC;QACzC,yCAAyC;KAC1C;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const segmenter: Rule;
3
+ //# sourceMappingURL=segmenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmenter.d.ts","sourceRoot":"","sources":["../../src/rules/segmenter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,IAyCvB,CAAC"}
@@ -0,0 +1,41 @@
1
+ export const segmenter = {
2
+ id: "intl-segmenter",
3
+ title: "Splitting text by character or word",
4
+ category: "formatting",
5
+ replaces: [
6
+ "graphemer",
7
+ "grapheme-splitter",
8
+ "string-length",
9
+ "lodash.words",
10
+ "split-graphemes",
11
+ ],
12
+ featureIds: ["intl-segmenter"],
13
+ native: "Intl.Segmenter",
14
+ human: {
15
+ explainer: 'A string\'s length counts UTF-16 code units, so a thumbs-up with a skin tone reads as four and slicing at an arbitrary index can cut a character in half. These libraries fix that by shipping their own copy of the Unicode grapheme cluster rules, which is most of their weight. Intl.Segmenter reads the copy the browser already holds and segments by grapheme, word or sentence, so "how many characters" and "what are the words" both get a locale-aware answer.',
16
+ snippet: `const graphemes = new Intl.Segmenter("en", { granularity: "grapheme" });
17
+
18
+ "👍🏽ok".length; // 6
19
+ [...graphemes.segment("👍🏽ok")].length; // 3
20
+
21
+ const words = new Intl.Segmenter("en", { granularity: "word" });
22
+ [...words.segment("Hello, world")]
23
+ .filter((part) => part.isWordLike)
24
+ .map((part) => part.segment);
25
+ // ["Hello", "world"]`,
26
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter",
27
+ },
28
+ agent: {
29
+ when: "counting, splitting or truncating text by user-perceived character, word or sentence",
30
+ unless: [
31
+ "You use lodash.words to split identifiers, as in fooBarBaz or snake_case. That is a camel case convention rather than a Unicode word boundary, and Intl.Segmenter will not split it.",
32
+ "You only need code points rather than grapheme clusters. Array.from(str) and the spread form already split by code point, with no Segmenter and no library.",
33
+ "You need segmentation that cannot move. Each engine ships its own Unicode version, so a recent emoji can segment differently between browsers and can change when one updates.",
34
+ "The same code runs on a Node build compiled with small-icu, where the locale data Segmenter depends on is largely absent.",
35
+ "You measure the width of terminal output. string-length also strips ANSI escape codes before counting, and Intl.Segmenter counts them as segments, so a colourised CLI silently gets its column widths wrong.",
36
+ ],
37
+ snippet: `const seg = new Intl.Segmenter("en", { granularity: "grapheme" });
38
+ const count = [...seg.segment(text)].length;`,
39
+ },
40
+ };
41
+ //# sourceMappingURL=segmenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmenter.js","sourceRoot":"","sources":["../../src/rules/segmenter.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,gBAAgB;IACpB,KAAK,EAAE,qCAAqC;IAC5C,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE;QACR,WAAW;QACX,mBAAmB;QACnB,eAAe;QACf,cAAc;QACd,iBAAiB;KAClB;IACD,UAAU,EAAE,CAAC,gBAAgB,CAAC;IAC9B,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE;QACL,SAAS,EACP,2cAA2c;QAC7c,OAAO,EAAE;;;;;;;;;sBASS;QAClB,MAAM,EACJ,iGAAiG;KACpG;IACD,KAAK,EAAE;QACL,IAAI,EAAE,sFAAsF;QAC5F,MAAM,EAAE;YACN,sLAAsL;YACtL,6JAA6J;YAC7J,gLAAgL;YAChL,2HAA2H;YAC3H,+MAA+M;SAChN;QACD,OAAO,EAAE;6CACgC;KAC1C;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,IAsEpB,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,IAyEpB,CAAC"}
@@ -60,6 +60,9 @@ export const select = {
60
60
  <style>
61
61
  select, select::picker(select) { appearance: base-select; }
62
62
  </style>`,
63
+ handRolled: [
64
+ "a div with role=listbox and children with role=option, wired to arrow keys and Enter by hand",
65
+ ],
63
66
  },
64
67
  guides: [
65
68
  "animated-select-picker",
@@ -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,OAAO;IACjB,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;IACD,MAAM,EAAE;QACN,wBAAwB;QACxB,wBAAwB;QACxB,8BAA8B;QAC9B,yBAAyB;KAC1B;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,OAAO;IACjB,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;QACL,UAAU,EAAE;YACV,8FAA8F;SAC/F;KACF;IACD,MAAM,EAAE;QACN,wBAAwB;QACxB,wBAAwB;QACxB,8BAA8B;QAC9B,yBAAyB;KAC1B;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../schema.ts";
2
+ export declare const signalTimeout: Rule;
3
+ //# sourceMappingURL=signal-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-timeout.d.ts","sourceRoot":"","sources":["../../src/rules/signal-timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,aAAa,EAAE,IA+B3B,CAAC"}
@@ -0,0 +1,31 @@
1
+ export const signalTimeout = {
2
+ id: "abortsignal-timeout",
3
+ title: "Timing out async work",
4
+ category: "async-data",
5
+ replaces: ["p-timeout", "promise-timeout"],
6
+ featureIds: ["abortsignal-timeout"],
7
+ native: "AbortSignal.timeout()",
8
+ human: {
9
+ explainer: "These packages race your promise against a timer and reject when the timer wins. The work carries on in the background, because a promise has no cancel, so a timed-out request still holds its connection and still lands its response. AbortSignal.timeout() returns a signal that aborts itself after the given time, and anything that takes a signal stops for real. AbortSignal.any() combines it with a controller when a timeout and a manual cancel both have to work.",
10
+ snippet: `const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
11
+
12
+ // A timeout the user can also cancel.
13
+ const controller = new AbortController();
14
+ const response2 = await fetch(url, {
15
+ signal: AbortSignal.any([controller.signal, AbortSignal.timeout(5000)]),
16
+ });`,
17
+ mdnUrl: "https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static",
18
+ },
19
+ agent: {
20
+ when: "giving a cancellable operation such as fetch a deadline",
21
+ unless: [
22
+ "What you are timing out takes no AbortSignal. A plain promise from a library with no signal option cannot be aborted, so racing it is still the only option and that race is what p-timeout is.",
23
+ "You need a specific error, or a fallback value instead of a rejection. AbortSignal.timeout() rejects with a TimeoutError DOMException and offers no hook, where p-timeout takes your own error or resolves with a default.",
24
+ "The combined signal has to say why it aborted. AbortSignal.any() adopts the reason of whichever signal fired, so telling a timeout from a user cancel means reading signal.reason rather than catching a distinct type.",
25
+ "You support browsers below Chrome {{chrome:abortsignal-timeout}}, Firefox {{firefox:abortsignal-timeout}} or Safari {{safari:abortsignal-timeout}}. AbortSignal.any() landed separately, so check it too if the snippet uses both.",
26
+ ],
27
+ snippet: "await fetch(url, { signal: AbortSignal.timeout(5000) });",
28
+ },
29
+ lintRule: "unicorn/prefer-abort-signal-timeout",
30
+ };
31
+ //# sourceMappingURL=signal-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-timeout.js","sourceRoot":"","sources":["../../src/rules/signal-timeout.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,uBAAuB;IAC9B,QAAQ,EAAE,YAAY;IACtB,QAAQ,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAC1C,UAAU,EAAE,CAAC,qBAAqB,CAAC;IACnC,MAAM,EAAE,uBAAuB;IAC/B,KAAK,EAAE;QACL,SAAS,EACP,idAAid;QACnd,OAAO,EAAE;;;;;;IAMT;QACA,MAAM,EACJ,6EAA6E;KAChF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,yDAAyD;QAC/D,MAAM,EAAE;YACN,iMAAiM;YACjM,4NAA4N;YAC5N,yNAAyN;YACzN,oOAAoO;SACrO;QACD,OAAO,EAAE,0DAA0D;KACpE;IACD,QAAQ,EAAE,qCAAqC;CAChD,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,IA4C1B,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,IAgD1B,CAAC"}
@@ -39,6 +39,10 @@ export const smoothScroll = {
39
39
  :root { scroll-behavior: smooth; }
40
40
  }
41
41
  [id] { scroll-margin-top: 5rem; }`,
42
+ handRolled: [
43
+ "a requestAnimationFrame loop easing scrollTop from where it is toward a target",
44
+ "an easing function like easeInOutQuad written next to a scroll routine",
45
+ ],
42
46
  },
43
47
  guides: ["scroll-target-on-load"],
44
48
  };
@@ -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,WAAW;IACrB,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;IACD,MAAM,EAAE,CAAC,uBAAuB,CAAC;CAClC,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,WAAW;IACrB,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;QAC9B,UAAU,EAAE;YACV,gFAAgF;YAChF,wEAAwE;SACzE;KACF;IACD,MAAM,EAAE,CAAC,uBAAuB,CAAC;CAClC,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,IA2CpB,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,IA+CpB,CAAC"}
@@ -38,6 +38,10 @@ export const sticky = {
38
38
  ],
39
39
  snippet: `.header { position: sticky; top: 0; z-index: 10; }
40
40
  .sidebar { position: sticky; top: 5rem; align-self: start; }`,
41
+ handRolled: [
42
+ "a scroll listener toggling a fixed class once an element passes an offset",
43
+ "storing an element's original offsetTop so a placeholder can hold the gap when it goes fixed",
44
+ ],
41
45
  },
42
46
  guides: ["state-aware-sticky-headers", "scroll-position-aware-elements"],
43
47
  };
@@ -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,QAAQ;IAClB,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;IACD,MAAM,EAAE,CAAC,4BAA4B,EAAE,gCAAgC,CAAC;CACzE,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,QAAQ;IAClB,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;QACzD,UAAU,EAAE;YACV,2EAA2E;YAC3E,8FAA8F;SAC/F;KACF;IACD,MAAM,EAAE,CAAC,4BAA4B,EAAE,gCAAgC,CAAC;CACzE,CAAC"}
@@ -1 +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,IA+BjC,CAAC"}
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,IAgCjC,CAAC"}
@@ -28,5 +28,6 @@ export const structuredCloneRule = {
28
28
  ],
29
29
  snippet: "const copy = structuredClone(original);",
30
30
  },
31
+ lintRule: "unicorn/prefer-structured-clone",
31
32
  };
32
33
  //# sourceMappingURL=structured-clone.js.map
@@ -1 +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,YAAY;IACtB,QAAQ,EAAE;QACR,kBAAkB;QAClB,MAAM;QACN,OAAO;QACP,OAAO;QACP,YAAY;QACZ,WAAW;QACX,YAAY;KACb;IACD,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,+JAA+J;YAC/J,uOAAuO;YACvO,+IAA+I;YAC/I,+NAA+N;SAChO;QACD,OAAO,EAAE,yCAAyC;KACnD;CACF,CAAC"}
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,YAAY;IACtB,QAAQ,EAAE;QACR,kBAAkB;QAClB,MAAM;QACN,OAAO;QACP,OAAO;QACP,YAAY;QACZ,WAAW;QACX,YAAY;KACb;IACD,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,+JAA+J;YAC/J,uOAAuO;YACvO,+IAA+I;YAC/I,+NAA+N;SAChO;QACD,OAAO,EAAE,yCAAyC;KACnD;IACD,QAAQ,EAAE,iCAAiC;CAC5C,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,IAoC7B,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,IAuC7B,CAAC"}
@@ -31,6 +31,9 @@ p {
31
31
  ],
32
32
  snippet: `h1, h2, h3 { text-wrap: balance; }
33
33
  p { text-wrap: pretty; }`,
34
+ handRolled: [
35
+ "inserting a br or a non-breaking space between the last two words of a heading so it does not orphan one",
36
+ ],
34
37
  },
35
38
  guides: ["improve-text-layout-and-legibility"],
36
39
  };