@primer/stylelint-config 13.0.0-rc.f33e046 → 13.0.0-rc.f7b4bdd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  var browsers = require('@github/browserslist-config');
4
4
  var stylelint = require('stylelint');
5
- var anymatch = require('anymatch');
5
+ var declarationValueIndex = require('stylelint/lib/utils/declarationValueIndex.cjs');
6
6
  var valueParser = require('postcss-value-parser');
7
+ var node_module = require('node:module');
8
+ var anymatch = require('anymatch');
7
9
  var TapMap = require('tap-map');
8
- var variables = require('@primer/css/dist/variables.json');
9
- var declarationValueIndex = require('stylelint/lib/utils/declarationValueIndex.cjs');
10
+ var variables$1 = require('@primer/css/dist/variables.json');
10
11
  var matchAll = require('string.prototype.matchall');
11
- var node_module = require('node:module');
12
12
 
13
13
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
14
14
  var propertyOrder = [
@@ -184,6 +184,243 @@ var propertyOrder = [
184
184
  'animation-direction',
185
185
  ];
186
186
 
187
+ const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
188
+
189
+ function primitivesVariables(type) {
190
+ const variables = [];
191
+
192
+ const files = [];
193
+ switch (type) {
194
+ case 'spacing':
195
+ files.push('base/size/size.json');
196
+ break
197
+ case 'border':
198
+ files.push('functional/size/border.json');
199
+ break
200
+ }
201
+
202
+ for (const file of files) {
203
+ // eslint-disable-next-line import/no-dynamic-require
204
+ const data = require$2(`@primer/primitives/dist/styleLint/${file}`);
205
+
206
+ for (const key of Object.keys(data)) {
207
+ const size = data[key];
208
+ const values = typeof size['value'] === 'string' ? [size['value']] : size['value'];
209
+
210
+ variables.push({
211
+ name: `--${size['name']}`,
212
+ values,
213
+ });
214
+ }
215
+ }
216
+
217
+ return variables
218
+ }
219
+
220
+ function walkGroups$1(root, validate) {
221
+ for (const node of root.nodes) {
222
+ if (node.type === 'function') {
223
+ walkGroups$1(node, validate);
224
+ } else {
225
+ validate(node);
226
+ }
227
+ }
228
+ return root
229
+ }
230
+
231
+ const {
232
+ createPlugin: createPlugin$1,
233
+ utils: {report: report$1, ruleMessages: ruleMessages$1, validateOptions: validateOptions$1},
234
+ } = stylelint;
235
+
236
+ const ruleName$3 = 'primer/borders';
237
+ const messages$3 = ruleMessages$1(ruleName$3, {
238
+ rejected: (value, replacement, propName) => {
239
+ if (propName && propName.includes('radius') && value.includes('borderWidth')) {
240
+ return `Border radius variables can not be used for border widths`
241
+ }
242
+
243
+ if ((propName && propName.includes('width')) || (borderShorthand(propName) && value.includes('borderRadius'))) {
244
+ return `Border width variables can not be used for border radii`
245
+ }
246
+
247
+ if (!replacement) {
248
+ return `Please use a Primer border variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/size#border`
249
+ }
250
+
251
+ return `Please replace '${value}' with a Primer border variable '${replacement['name']}'. https://primer.style/foundations/primitives/size#border`
252
+ },
253
+ });
254
+
255
+ const variables = primitivesVariables('border');
256
+ const sizes$1 = [];
257
+ const radii = [];
258
+
259
+ // Props that we want to check
260
+ const propList$1 = ['border', 'border-width', 'border-radius'];
261
+ // Values that we want to ignore
262
+ const valueList$1 = ['${'];
263
+
264
+ const borderShorthand = prop =>
265
+ /^border(-(top|right|bottom|left|block-start|block-end|inline-start|inline-end))?$/.test(prop);
266
+
267
+ for (const variable of variables) {
268
+ const name = variable['name'];
269
+
270
+ if (name.includes('borderWidth')) {
271
+ const value = variable['values']
272
+ .pop()
273
+ .replace(/max|\(|\)/g, '')
274
+ .split(',')[0];
275
+ sizes$1.push({
276
+ name,
277
+ values: [value],
278
+ });
279
+ }
280
+
281
+ if (name.includes('borderRadius')) {
282
+ radii.push(variable);
283
+ }
284
+ }
285
+
286
+ /** @type {import('stylelint').Rule} */
287
+ const ruleFunction$1 = (primary, secondaryOptions, context) => {
288
+ return (root, result) => {
289
+ const validOptions = validateOptions$1(result, ruleName$3, {
290
+ actual: primary,
291
+ possible: [true],
292
+ });
293
+
294
+ if (!validOptions) return
295
+
296
+ root.walkDecls(declNode => {
297
+ const {prop, value} = declNode;
298
+
299
+ if (!propList$1.some(borderProp => prop.startsWith(borderProp))) return
300
+ if (/^border(-(top|right|bottom|left|block-start|block-end|inline-start|inline-end))?-color$/.test(prop)) return
301
+ if (valueList$1.some(valueToIgnore => value.includes(valueToIgnore))) return
302
+
303
+ const problems = [];
304
+
305
+ const parsedValue = walkGroups$1(valueParser(value), node => {
306
+ const checkForVariable = (vars, nodeValue) =>
307
+ vars.some(variable =>
308
+ new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(nodeValue),
309
+ );
310
+
311
+ // Only check word types. https://github.com/TrySound/postcss-value-parser#word
312
+ if (node.type !== 'word') {
313
+ return
314
+ }
315
+
316
+ // Exact values to ignore.
317
+ if (
318
+ [
319
+ '*',
320
+ '+',
321
+ '-',
322
+ '/',
323
+ '0',
324
+ 'none',
325
+ 'inherit',
326
+ 'initial',
327
+ 'revert',
328
+ 'revert-layer',
329
+ 'unset',
330
+ 'solid',
331
+ 'dashed',
332
+ 'dotted',
333
+ 'transparent',
334
+ ].includes(node.value)
335
+ ) {
336
+ return
337
+ }
338
+
339
+ const valueUnit = valueParser.unit(node.value);
340
+
341
+ if (valueUnit && (valueUnit.unit === '' || !/^-?[0-9.]+$/.test(valueUnit.number))) {
342
+ return
343
+ }
344
+
345
+ // Skip if the value unit isn't a supported unit.
346
+ if (valueUnit && !['px', 'rem', 'em'].includes(valueUnit.unit)) {
347
+ return
348
+ }
349
+
350
+ // if we're looking at the border property that sets color in shorthand, don't bother checking the color
351
+ if (
352
+ // using border shorthand
353
+ borderShorthand(prop) &&
354
+ // includes a color as a third space-separated value
355
+ value.split(' ').length > 2 &&
356
+ // the color in the third space-separated value includes `node.value`
357
+ value
358
+ .split(' ')
359
+ .slice(2)
360
+ .some(color => color.includes(node.value))
361
+ ) {
362
+ return
363
+ }
364
+
365
+ // If the variable is found in the value, skip it.
366
+ if (prop.includes('width') || borderShorthand(prop)) {
367
+ if (checkForVariable(sizes$1, node.value)) {
368
+ return
369
+ }
370
+ }
371
+
372
+ if (prop.includes('radius')) {
373
+ if (checkForVariable(radii, node.value)) {
374
+ return
375
+ }
376
+ }
377
+
378
+ const replacement = (prop.includes('radius') ? radii : sizes$1).find(variable =>
379
+ variable.values.includes(node.value.replace('-', '')),
380
+ );
381
+ const fixable = replacement && valueUnit && !valueUnit.number.includes('-');
382
+
383
+ if (fixable && context.fix) {
384
+ node.value = node.value.replace(node.value, `var(${replacement['name']})`);
385
+ } else {
386
+ problems.push({
387
+ index: declarationValueIndex(declNode) + node.sourceIndex,
388
+ endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
389
+ message: messages$3.rejected(node.value, replacement, prop),
390
+ });
391
+ }
392
+
393
+ return
394
+ });
395
+
396
+ if (context.fix) {
397
+ declNode.value = parsedValue.toString();
398
+ }
399
+
400
+ if (problems.length) {
401
+ for (const err of problems) {
402
+ report$1({
403
+ index: err.index,
404
+ endIndex: err.endIndex,
405
+ message: err.message,
406
+ node: declNode,
407
+ result,
408
+ ruleName: ruleName$3,
409
+ });
410
+ }
411
+ }
412
+ });
413
+ }
414
+ };
415
+
416
+ ruleFunction$1.ruleName = ruleName$3;
417
+ ruleFunction$1.messages = messages$3;
418
+ ruleFunction$1.meta = {
419
+ fixable: true,
420
+ };
421
+
422
+ var borders = createPlugin$1(ruleName$3, ruleFunction$1);
423
+
187
424
  const SKIP_VALUE_NODE_TYPES = new Set(['space', 'div']);
188
425
  const SKIP_AT_RULE_NAMES = new Set(['each', 'for', 'function', 'mixin']);
189
426
 
@@ -422,24 +659,24 @@ function closest(node, test) {
422
659
  function createVariableRule(ruleName, rules, url) {
423
660
  const plugin = stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
424
661
  if (enabled === false) {
425
- return noop$4
662
+ return noop$2
426
663
  }
427
664
 
428
665
  let actualRules = rules;
429
666
  let overrides = options.rules;
430
667
  if (typeof rules === 'function') {
431
- actualRules = rules({variables, options, ruleName});
668
+ actualRules = rules({variables: variables$1, options, ruleName});
432
669
  } else {
433
670
  actualRules = Object.assign({}, rules);
434
671
  }
435
672
  if (typeof overrides === 'function') {
436
673
  delete options.rules;
437
- overrides = overrides({rules: actualRules, options, ruleName, variables});
674
+ overrides = overrides({rules: actualRules, options, ruleName, variables: variables$1});
438
675
  }
439
676
  if (overrides) {
440
677
  Object.assign(actualRules, overrides);
441
678
  }
442
- const validate = declarationValidator(actualRules, {variables});
679
+ const validate = declarationValidator(actualRules, {variables: variables$1});
443
680
 
444
681
  // The stylelint docs suggest respecting a "disableFix" rule option that
445
682
  // overrides the "global" context.fix (--fix) linting option.
@@ -499,70 +736,7 @@ function createVariableRule(ruleName, rules, url) {
499
736
  return plugin
500
737
  }
501
738
 
502
- function noop$4() {}
503
-
504
- var borders = createVariableRule(
505
- 'primer/borders',
506
- {
507
- border: {
508
- expects: 'a border variable',
509
- props: 'border{,-top,-right,-bottom,-left}',
510
- values: ['$border', 'none', '0'],
511
- components: ['border-width', 'border-style', 'border-color'],
512
- replacements: {
513
- // because shorthand border properties ¯\_(ツ)_/¯
514
- '$border-width $border-style $border-gray': '$border',
515
- '$border-width $border-gray $border-style': '$border',
516
- '$border-style $border-width $border-gray': '$border',
517
- '$border-style $border-gray $border-width': '$border',
518
- '$border-gray $border-width $border-style': '$border',
519
- '$border-gray $border-style $border-width': '$border',
520
- '$border-width $border-style $border-color': '$border',
521
- '$border-width $border-color $border-style': '$border',
522
- '$border-style $border-width $border-color': '$border',
523
- '$border-style $border-color $border-width': '$border',
524
- '$border-color $border-width $border-style': '$border',
525
- '$border-color $border-style $border-width': '$border',
526
- },
527
- },
528
- 'border color': {
529
- expects: 'a border color variable',
530
- props: 'border{,-top,-right,-bottom,-left}-color',
531
- values: [
532
- '$border-*',
533
- 'transparent',
534
- 'currentColor',
535
- // Match variables in any of the following formats: --color-border-*, --color-*-border-*, --color-*-border, --borderColor-, *borderColor*
536
- /var\(--color-(.+-)*border(-.+)*\)/,
537
- /var\(--color-[^)]+\)/,
538
- /var\(--borderColor-[^)]+\)/,
539
- /var\((.+-)*borderColor(-.+)*\)/,
540
- ],
541
- replacements: {
542
- '$border-gray': '$border-color',
543
- },
544
- },
545
- 'border style': {
546
- expects: 'a border style variable',
547
- props: 'border{,-top,-right,-bottom,-left}-style',
548
- values: ['$border-style', 'none'],
549
- },
550
- 'border width': {
551
- expects: 'a border width variable',
552
- props: 'border{,-top,-right,-bottom,-left}-width',
553
- values: ['$border-width*', '0'],
554
- },
555
- 'border radius': {
556
- expects: 'a border radius variable',
557
- props: 'border{,-{top,bottom}-{left,right}}-radius',
558
- values: ['$border-radius', '0', '50%', 'inherit'],
559
- replacements: {
560
- '100%': '50%',
561
- },
562
- },
563
- },
564
- 'https://primer.style/css/utilities/borders',
565
- );
739
+ function noop$2() {}
566
740
 
567
741
  var boxShadow = createVariableRule(
568
742
  'primer/box-shadow',
@@ -627,9 +801,9 @@ var colors = createVariableRule(
627
801
  'https://primer.style/primitives/colors',
628
802
  );
629
803
 
630
- const ruleName$3 = 'primer/responsive-widths';
804
+ const ruleName$2 = 'primer/responsive-widths';
631
805
 
632
- const messages$3 = stylelint.utils.ruleMessages(ruleName$3, {
806
+ const messages$2 = stylelint.utils.ruleMessages(ruleName$2, {
633
807
  rejected: value => {
634
808
  return `A value larger than the smallest viewport could break responsive pages. Use a width value smaller than ${value}. https://primer.style/css/support/breakpoints`
635
809
  },
@@ -637,10 +811,10 @@ const messages$3 = stylelint.utils.ruleMessages(ruleName$3, {
637
811
 
638
812
  // 320px is the smallest viewport size that we support
639
813
 
640
- const walkGroups$1 = (root, validate) => {
814
+ const walkGroups = (root, validate) => {
641
815
  for (const node of root.nodes) {
642
816
  if (node.type === 'function') {
643
- walkGroups$1(node, validate);
817
+ walkGroups(node, validate);
644
818
  } else {
645
819
  validate(node);
646
820
  }
@@ -649,9 +823,9 @@ const walkGroups$1 = (root, validate) => {
649
823
  };
650
824
 
651
825
  // eslint-disable-next-line no-unused-vars
652
- var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}, context) => {
826
+ var responsiveWidths = stylelint.createPlugin(ruleName$2, (enabled, options = {}, context) => {
653
827
  if (!enabled) {
654
- return noop$3
828
+ return noop$1
655
829
  }
656
830
 
657
831
  const lintResult = (root, result) => {
@@ -662,12 +836,12 @@ var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}
662
836
  }
663
837
 
664
838
  if (decl.type !== 'decl' || !decl.prop.match(/^(min-width|width)/)) {
665
- return noop$3
839
+ return noop$1
666
840
  }
667
841
 
668
842
  const problems = [];
669
843
 
670
- walkGroups$1(valueParser(decl.value), node => {
844
+ walkGroups(valueParser(decl.value), node => {
671
845
  // Only check word types. https://github.com/TrySound/postcss-value-parser#word
672
846
  if (node.type !== 'word') {
673
847
  return
@@ -685,7 +859,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}
685
859
  if (parseInt(valueUnit.number) > 320) {
686
860
  problems.push({
687
861
  index: declarationValueIndex(decl) + node.sourceIndex,
688
- message: messages$3.rejected(node.value),
862
+ message: messages$2.rejected(node.value),
689
863
  });
690
864
  }
691
865
  break
@@ -693,7 +867,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}
693
867
  if (parseInt(valueUnit.number) > 100) {
694
868
  problems.push({
695
869
  index: declarationValueIndex(decl) + node.sourceIndex,
696
- message: messages$3.rejected(node.value),
870
+ message: messages$2.rejected(node.value),
697
871
  });
698
872
  }
699
873
  break
@@ -707,7 +881,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}
707
881
  message: err.message,
708
882
  node: decl,
709
883
  result,
710
- ruleName: ruleName$3,
884
+ ruleName: ruleName$2,
711
885
  });
712
886
  }
713
887
  }
@@ -717,70 +891,60 @@ var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}
717
891
  return lintResult
718
892
  });
719
893
 
720
- function noop$3() {}
721
-
722
- // TODO: Pull this in from primer/primitives
723
- const spacerValues = {
724
- '$spacer-1': '4px',
725
- '$spacer-2': '8px',
726
- '$spacer-3': '16px',
727
- '$spacer-4': '24px',
728
- '$spacer-5': '32px',
729
- '$spacer-6': '40px',
730
- '$spacer-7': '48px',
731
- '$spacer-8': '64px',
732
- '$spacer-9': '80px',
733
- '$spacer-10': '96px',
734
- '$spacer-11': '112px',
735
- '$spacer-12': '128px',
736
- '$em-spacer-1': '0.0625em',
737
- '$em-spacer-2': '0.125em',
738
- '$em-spacer-3': '0.25em',
739
- '$em-spacer-4': '0.375em',
740
- '$em-spacer-5': '0.5em',
741
- '$em-spacer-6': '0.75em',
742
- };
894
+ function noop$1() {}
743
895
 
744
- const ruleName$2 = 'primer/spacing';
745
- const messages$2 = stylelint.utils.ruleMessages(ruleName$2, {
896
+ const {
897
+ createPlugin,
898
+ utils: {report, ruleMessages, validateOptions},
899
+ } = stylelint;
900
+
901
+ const ruleName$1 = 'primer/spacing';
902
+ const messages$1 = ruleMessages(ruleName$1, {
746
903
  rejected: (value, replacement) => {
747
- if (replacement === null) {
748
- return `Please use a primer spacer variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/css/storybook/?path=/docs/support-spacing--docs`
904
+ if (!replacement) {
905
+ return `Please use a primer size variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/size`
749
906
  }
750
907
 
751
- return `Please replace ${value} with spacing variable '${replacement}'.`
908
+ return `Please replace '${value}' with size variable '${replacement['name']}'. https://primer.style/foundations/primitives/size`
752
909
  },
753
910
  });
754
911
 
755
- const walkGroups = (root, validate) => {
756
- for (const node of root.nodes) {
757
- if (node.type === 'function') {
758
- walkGroups(node, validate);
759
- } else {
760
- validate(node);
761
- }
762
- }
763
- return root
764
- };
912
+ // Props that we want to check
913
+ const propList = ['padding', 'margin', 'top', 'right', 'bottom', 'left'];
914
+ // Values that we want to ignore
915
+ const valueList = ['${'];
765
916
 
766
- // eslint-disable-next-line no-unused-vars
767
- var spacing = stylelint.createPlugin(ruleName$2, (enabled, options = {}, context) => {
768
- if (!enabled) {
769
- return noop$2
917
+ const sizes = primitivesVariables('spacing');
918
+
919
+ // Add +-1px to each value
920
+ for (const size of sizes) {
921
+ const values = size['values'];
922
+ const px = parseInt(values.find(value => value.includes('px')));
923
+ if (![2, 6].includes(px)) {
924
+ values.push(`${px + 1}px`);
925
+ values.push(`${px - 1}px`);
770
926
  }
927
+ }
771
928
 
772
- const lintResult = (root, result) => {
773
- root.walk(decl => {
774
- if (decl.type !== 'decl' || !decl.prop.match(/^(padding|margin)/)) {
775
- return noop$2
776
- }
929
+ /** @type {import('stylelint').Rule} */
930
+ const ruleFunction = (primary, secondaryOptions, context) => {
931
+ return (root, result) => {
932
+ const validOptions = validateOptions(result, ruleName$1, {
933
+ actual: primary,
934
+ possible: [true],
935
+ });
777
936
 
778
- const problems = [];
937
+ if (!validOptions) return
938
+
939
+ root.walkDecls(declNode => {
940
+ const {prop, value} = declNode;
779
941
 
780
- const parsedValue = walkGroups(valueParser(decl.value), node => {
781
- // Remove leading negative sign, if any.
782
- const cleanValue = node.value.replace(/^-/g, '');
942
+ if (!propList.some(spacingProp => prop.startsWith(spacingProp))) return
943
+ if (valueList.some(valueToIgnore => value.includes(valueToIgnore))) return
783
944
 
945
+ const problems = [];
946
+
947
+ const parsedValue = walkGroups$1(valueParser(value), node => {
784
948
  // Only check word types. https://github.com/TrySound/postcss-value-parser#word
785
949
  if (node.type !== 'word') {
786
950
  return
@@ -791,30 +955,36 @@ var spacing = stylelint.createPlugin(ruleName$2, (enabled, options = {}, context
791
955
  return
792
956
  }
793
957
 
794
- const valueUnit = valueParser.unit(cleanValue);
958
+ const valueUnit = valueParser.unit(node.value);
795
959
 
796
- if (valueUnit && (valueUnit.unit === '' || !/^[0-9.]+$/.test(valueUnit.number))) {
960
+ if (valueUnit && (valueUnit.unit === '' || !/^-?[0-9.]+$/.test(valueUnit.number))) {
797
961
  return
798
962
  }
799
963
 
800
- // If the a variable is found in the value, skip it.
964
+ // Skip if the value unit isn't a supported unit.
965
+ if (valueUnit && !['px', 'rem', 'em'].includes(valueUnit.unit)) {
966
+ return
967
+ }
968
+
969
+ // If the variable is found in the value, skip it.
801
970
  if (
802
- Object.keys(spacerValues).some(variable =>
803
- new RegExp(`${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(cleanValue),
971
+ sizes.some(variable =>
972
+ new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(node.value),
804
973
  )
805
974
  ) {
806
975
  return
807
976
  }
808
977
 
809
- const replacement = Object.keys(spacerValues).find(spacer => spacerValues[spacer] === cleanValue) || null;
810
- const valueMatch = replacement ? spacerValues[replacement] : node.value;
978
+ const replacement = sizes.find(variable => variable.values.includes(node.value.replace('-', '')));
979
+ const fixable = replacement && valueUnit && !valueUnit.number.includes('-');
811
980
 
812
- if (replacement && context.fix) {
813
- node.value = node.value.replace(valueMatch, replacement);
981
+ if (fixable && context.fix) {
982
+ node.value = node.value.replace(node.value, `var(${replacement['name']})`);
814
983
  } else {
815
984
  problems.push({
816
- index: declarationValueIndex(decl) + node.sourceIndex,
817
- message: messages$2.rejected(valueMatch, replacement),
985
+ index: declarationValueIndex(declNode) + node.sourceIndex,
986
+ endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
987
+ message: messages$1.rejected(node.value, replacement),
818
988
  });
819
989
  }
820
990
 
@@ -822,27 +992,32 @@ var spacing = stylelint.createPlugin(ruleName$2, (enabled, options = {}, context
822
992
  });
823
993
 
824
994
  if (context.fix) {
825
- decl.value = parsedValue.toString();
995
+ declNode.value = parsedValue.toString();
826
996
  }
827
997
 
828
998
  if (problems.length) {
829
999
  for (const err of problems) {
830
- stylelint.utils.report({
1000
+ report({
831
1001
  index: err.index,
1002
+ endIndex: err.endIndex,
832
1003
  message: err.message,
833
- node: decl,
1004
+ node: declNode,
834
1005
  result,
835
- ruleName: ruleName$2,
1006
+ ruleName: ruleName$1,
836
1007
  });
837
1008
  }
838
1009
  }
839
1010
  });
840
- };
1011
+ }
1012
+ };
841
1013
 
842
- return lintResult
843
- });
1014
+ ruleFunction.ruleName = ruleName$1;
1015
+ ruleFunction.messages = messages$1;
1016
+ ruleFunction.meta = {
1017
+ fixable: true,
1018
+ };
844
1019
 
845
- function noop$2() {}
1020
+ var spacing = createPlugin(ruleName$1, ruleFunction);
846
1021
 
847
1022
  var typography = createVariableRule(
848
1023
  'primer/typography',
@@ -867,583 +1042,6 @@ var typography = createVariableRule(
867
1042
  'https://primer.style/css/utilities/typography',
868
1043
  );
869
1044
 
870
- // Meant as temp until we can move to primitives or css
871
- const colorTypes = ['accent', 'success', 'attention', 'severe', 'danger', 'open', 'closed', 'done', 'sponsors'];
872
-
873
- var utilities$1 = {
874
- color: [
875
- {
876
- value: 'var(--color-fg-default)',
877
- utilityClass: 'color-fg-default',
878
- },
879
- {
880
- value: 'var(--color-fg-muted)',
881
- utilityClass: 'color-fg-muted',
882
- },
883
- {
884
- value: 'var(--color-fg-subtle)',
885
- utilityClass: 'color-fg-subtle',
886
- },
887
- ].concat(
888
- colorTypes.map(type => {
889
- return {
890
- value: `var(--color-${type}-fg)`,
891
- utilityClass: `color-fg-${type}`,
892
- }
893
- }),
894
- ),
895
- 'background-color': [
896
- {
897
- value: 'var(--color-canvas-default)',
898
- utilityClass: 'color-bg-default',
899
- },
900
- {
901
- value: 'var(--color-canvas-overlay)',
902
- utilityClass: 'color-bg-overlay',
903
- },
904
- {
905
- value: 'var(--color-canvas-inset)',
906
- utilityClass: 'color-bg-inset',
907
- },
908
- {
909
- value: 'var(--color-canvas-subtle)',
910
- utilityClass: 'color-bg-subtle',
911
- },
912
- {
913
- value: 'transparent',
914
- utilityClass: 'color-bg-transparent',
915
- },
916
- ]
917
- .concat(
918
- colorTypes.map(type => {
919
- return {
920
- value: `var(--color-${type}-subtle)`,
921
- utilityClass: `color-bg-${type}`,
922
- }
923
- }),
924
- )
925
- .concat(
926
- colorTypes.map(type => {
927
- return {
928
- value: `var(--color-${type}-emphasis)`,
929
- utilityClass: `color-bg-${type}-emphasis`,
930
- }
931
- }),
932
- ),
933
- 'border-color': [
934
- {
935
- value: 'var(--color-border-default',
936
- utilityClass: 'color-border-default',
937
- },
938
- {
939
- value: 'var(--color-border-muted',
940
- utilityClass: 'color-border-muted',
941
- },
942
- {
943
- value: 'var(--color-border-subtle',
944
- utilityClass: 'color-border-subtle',
945
- },
946
- ]
947
- .concat(
948
- colorTypes.map(type => {
949
- return {
950
- value: `var(--color-${type}-muted)`,
951
- utilityClass: `color-border-${type}`,
952
- }
953
- }),
954
- )
955
- .concat(
956
- colorTypes.map(type => {
957
- return {
958
- value: `var(--color-${type}-emphasis)`,
959
- utilityClass: `color-border-${type}-emphasis`,
960
- }
961
- }),
962
- ),
963
- margin: Array.from(new Array(6)).map((_, i) => {
964
- return {
965
- value: `$spacer-${i + 1}`,
966
- utilityClass: `m-${i + 1}`,
967
- }
968
- }),
969
- 'margin-top': Array.from(new Array(6)).map((_, i) => {
970
- return {
971
- value: `$spacer-${i + 1}`,
972
- utilityClass: `mt-${i + 1}`,
973
- }
974
- }),
975
- 'margin-right': Array.from(new Array(6)).map((_, i) => {
976
- return {
977
- value: `$spacer-${i + 1}`,
978
- utilityClass: `mr-${i + 1}`,
979
- }
980
- }),
981
- 'margin-bottom': Array.from(new Array(6)).map((_, i) => {
982
- return {
983
- value: `$spacer-${i + 1}`,
984
- utilityClass: `mb-${i + 1}`,
985
- }
986
- }),
987
- 'margin-left': Array.from(new Array(6)).map((_, i) => {
988
- return {
989
- value: `$spacer-${i + 1}`,
990
- utilityClass: `ml-${i + 1}`,
991
- }
992
- }),
993
- padding: Array.from(new Array(6)).map((_, i) => {
994
- return {
995
- value: `$spacer-${i + 1}`,
996
- utilityClass: `p-${i + 1}`,
997
- }
998
- }),
999
- 'padding-top': Array.from(new Array(6)).map((_, i) => {
1000
- return {
1001
- value: `$spacer-${i + 1}`,
1002
- utilityClass: `pt-${i + 1}`,
1003
- }
1004
- }),
1005
- 'padding-right': Array.from(new Array(6)).map((_, i) => {
1006
- return {
1007
- value: `$spacer-${i + 1}`,
1008
- utilityClass: `pr-${i + 1}`,
1009
- }
1010
- }),
1011
- 'padding-bottom': Array.from(new Array(6)).map((_, i) => {
1012
- return {
1013
- value: `$spacer-${i + 1}`,
1014
- utilityClass: `pb-${i + 1}`,
1015
- }
1016
- }),
1017
- 'padding-left': Array.from(new Array(6)).map((_, i) => {
1018
- return {
1019
- value: `$spacer-${i + 1}`,
1020
- utilityClass: `pl-${i + 1}`,
1021
- }
1022
- }),
1023
- 'line-height': [
1024
- {
1025
- value: '$lh-condensed-ultra',
1026
- utilityClass: 'lh-condensed-ultra',
1027
- },
1028
- {
1029
- value: '$lh-condensed',
1030
- utilityClass: 'lh-condensed',
1031
- },
1032
- {
1033
- value: '$lh-default',
1034
- utilityClass: 'lh-default',
1035
- },
1036
- {
1037
- value: '0',
1038
- utilityClass: 'lh-0',
1039
- },
1040
- ],
1041
- 'text-align': [
1042
- {
1043
- value: 'left',
1044
- utilityClass: 'text-left',
1045
- },
1046
- {
1047
- value: 'right',
1048
- utilityClass: 'text-right',
1049
- },
1050
- {
1051
- value: 'center',
1052
- utilityClass: 'text-center',
1053
- },
1054
- ],
1055
- 'font-style': [
1056
- {
1057
- value: 'italic',
1058
- utilityClass: 'text-italic',
1059
- },
1060
- ],
1061
- 'text-transform': [
1062
- {
1063
- value: 'uppercase',
1064
- utilityClass: 'text-uppercase',
1065
- },
1066
- ],
1067
- 'text-decoration': [
1068
- {
1069
- value: 'underline',
1070
- utilityClass: 'text-underline',
1071
- },
1072
- {
1073
- value: 'none',
1074
- utilityClass: 'no-underline',
1075
- },
1076
- ],
1077
- 'white-space': [
1078
- {
1079
- value: 'nowrap',
1080
- utilityClass: 'no-wrap',
1081
- },
1082
- {
1083
- value: 'normal',
1084
- utilityClass: 'ws-normal',
1085
- },
1086
- ],
1087
- 'word-break': [
1088
- {
1089
- value: 'break-all',
1090
- utilityClass: 'wb-break-all',
1091
- },
1092
- ],
1093
- width: [
1094
- {
1095
- value: '100%',
1096
- utilityClass: 'width-full',
1097
- },
1098
- {
1099
- value: 'auto%',
1100
- utilityClass: 'width-auto',
1101
- },
1102
- ],
1103
- overflow: [
1104
- {
1105
- value: 'visible',
1106
- utilityClass: 'overflow-visible',
1107
- },
1108
- {
1109
- value: 'hidden',
1110
- utilityClass: 'overflow-hidden',
1111
- },
1112
- {
1113
- value: 'auto',
1114
- utilityClass: 'overflow-auto',
1115
- },
1116
- {
1117
- value: 'scroll',
1118
- utilityClass: 'overflow-scroll',
1119
- },
1120
- ],
1121
- 'overflow-x': [
1122
- {
1123
- value: 'visible',
1124
- utilityClass: 'overflow-x-visible',
1125
- },
1126
- {
1127
- value: 'hidden',
1128
- utilityClass: 'overflow-x-hidden',
1129
- },
1130
- {
1131
- value: 'auto',
1132
- utilityClass: 'overflow-x-auto',
1133
- },
1134
- {
1135
- value: 'scroll',
1136
- utilityClass: 'overflow-x-scroll',
1137
- },
1138
- ],
1139
- 'overflow-y': [
1140
- {
1141
- value: 'visible',
1142
- utilityClass: 'overflow-y-visible',
1143
- },
1144
- {
1145
- value: 'hidden',
1146
- utilityClass: 'overflow-y-hidden',
1147
- },
1148
- {
1149
- value: 'auto',
1150
- utilityClass: 'overflow-y-auto',
1151
- },
1152
- {
1153
- value: 'scroll',
1154
- utilityClass: 'overflow-y-scroll',
1155
- },
1156
- ],
1157
- height: [
1158
- {
1159
- value: '100%',
1160
- utilityClass: 'height-full',
1161
- },
1162
- ],
1163
- 'max-width': [
1164
- {
1165
- value: '100%',
1166
- utilityClass: 'width-fit',
1167
- },
1168
- ],
1169
- 'max-height': [
1170
- {
1171
- value: '100%',
1172
- utilityClass: 'height-fit',
1173
- },
1174
- ],
1175
- 'min-width': [
1176
- {
1177
- value: '0',
1178
- utilityClass: 'min-width-0',
1179
- },
1180
- ],
1181
- float: [
1182
- {
1183
- value: 'left',
1184
- utilityClass: 'float-left',
1185
- },
1186
- {
1187
- value: 'right',
1188
- utilityClass: 'float-right',
1189
- },
1190
- {
1191
- value: 'none',
1192
- utilityClass: 'float-none',
1193
- },
1194
- ],
1195
- 'list-style': [
1196
- {
1197
- value: 'none',
1198
- utilityClass: 'list-style-none',
1199
- },
1200
- ],
1201
- 'user-select': [
1202
- {
1203
- value: 'none',
1204
- utilityClass: 'user-select-none',
1205
- },
1206
- ],
1207
- visibility: [
1208
- {
1209
- value: 'hidden',
1210
- utilityClass: 'v-hidden',
1211
- },
1212
- {
1213
- value: 'visible',
1214
- utilityClass: 'v-visible',
1215
- },
1216
- ],
1217
- 'vertical-align': [
1218
- {
1219
- value: 'middle',
1220
- utilityClass: 'v-align-middle',
1221
- },
1222
- {
1223
- value: 'top',
1224
- utilityClass: 'v-align-top',
1225
- },
1226
- {
1227
- value: 'bottom',
1228
- utilityClass: 'v-align-bottom',
1229
- },
1230
- {
1231
- value: 'text-top',
1232
- utilityClass: 'v-align-text-top',
1233
- },
1234
- {
1235
- value: 'text-bottom',
1236
- utilityClass: 'v-align-text-bottom',
1237
- },
1238
- {
1239
- value: 'text-baseline',
1240
- utilityClass: 'v-align-baseline',
1241
- },
1242
- ],
1243
- 'font-weight': [
1244
- {
1245
- value: '$font-weight-normal',
1246
- utilityClass: 'text-normal',
1247
- },
1248
- {
1249
- value: '$font-weight-bold',
1250
- utilityClass: 'text-bold',
1251
- },
1252
- {
1253
- value: '$font-weight-semibold',
1254
- utilityClass: 'text-semibold',
1255
- },
1256
- {
1257
- value: '$font-weight-light',
1258
- utilityClass: 'text-light',
1259
- },
1260
- ],
1261
- top: [
1262
- {
1263
- value: '0',
1264
- utilityClass: 'top-0',
1265
- },
1266
- {
1267
- value: 'auto',
1268
- utilityClass: 'top-auto',
1269
- },
1270
- ],
1271
- right: [
1272
- {
1273
- value: '0',
1274
- utilityClass: 'right-0',
1275
- },
1276
- {
1277
- value: 'auto',
1278
- utilityClass: 'right-auto',
1279
- },
1280
- ],
1281
- bottom: [
1282
- {
1283
- value: '0',
1284
- utilityClass: 'bottom-0',
1285
- },
1286
- {
1287
- value: 'auto',
1288
- utilityClass: 'bottom-auto',
1289
- },
1290
- ],
1291
- left: [
1292
- {
1293
- value: '0',
1294
- utilityClass: 'left-0',
1295
- },
1296
- {
1297
- value: 'auto',
1298
- utilityClass: 'left-auto',
1299
- },
1300
- ],
1301
- position: [
1302
- {
1303
- value: 'static',
1304
- utilityClass: 'position-static',
1305
- },
1306
- {
1307
- value: 'relative',
1308
- utilityClass: 'position-relative',
1309
- },
1310
- {
1311
- value: 'absolute',
1312
- utilityClass: 'position-absolute',
1313
- },
1314
- {
1315
- value: 'fixed',
1316
- utilityClass: 'position-fixed',
1317
- },
1318
- {
1319
- value: 'sticky',
1320
- utilityClass: 'position-sticky',
1321
- },
1322
- ],
1323
- 'box-shadow': [
1324
- {
1325
- value: 'none',
1326
- utilityClass: 'box-shadow-none',
1327
- },
1328
- {
1329
- value: 'var(--color-shadow-small)',
1330
- utilityClass: 'box-shadow-small',
1331
- },
1332
- {
1333
- value: 'var(--color-shadow-medium)',
1334
- utilityClass: 'box-shadow-medium',
1335
- },
1336
- {
1337
- value: 'var(--color-shadow-large)',
1338
- utilityClass: 'box-shadow-large',
1339
- },
1340
- {
1341
- value: 'var(--color-shadow-extra-large)',
1342
- utilityClass: 'box-shadow-extra-large',
1343
- },
1344
- ],
1345
- border: [
1346
- {
1347
- value: '$border',
1348
- utilityClass: 'border',
1349
- },
1350
- {
1351
- value: '0',
1352
- utilityClass: 'border-0',
1353
- },
1354
- ],
1355
- 'border-top': [
1356
- {
1357
- value: '$border',
1358
- utilityClass: 'border-top',
1359
- },
1360
- {
1361
- value: '0',
1362
- utilityClass: 'border-top-0',
1363
- },
1364
- ],
1365
- 'border-right': [
1366
- {
1367
- value: '$border',
1368
- utilityClass: 'border-right',
1369
- },
1370
- {
1371
- value: '0',
1372
- utilityClass: 'border-right-0',
1373
- },
1374
- ],
1375
- 'border-bottom': [
1376
- {
1377
- value: '$border',
1378
- utilityClass: 'border-bottom',
1379
- },
1380
- {
1381
- value: '0',
1382
- utilityClass: 'border-bottom-0',
1383
- },
1384
- ],
1385
- 'border-left': [
1386
- {
1387
- value: '$border',
1388
- utilityClass: 'border-left',
1389
- },
1390
- {
1391
- value: '0',
1392
- utilityClass: 'border-left-0',
1393
- },
1394
- ],
1395
- };
1396
-
1397
- const ruleName$1 = 'primer/utilities';
1398
-
1399
- const messages$1 = stylelint.utils.ruleMessages(ruleName$1, {
1400
- rejected: (selector, utilityClass) => {
1401
- return `Consider using the Primer utility '.${utilityClass}' instead of the selector '${selector}' in your html. https://primer.style/css/utilities`
1402
- },
1403
- });
1404
-
1405
- // eslint-disable-next-line no-unused-vars
1406
- var utilities = stylelint.createPlugin(ruleName$1, (enabled, options = {}, context) => {
1407
- if (!enabled) {
1408
- return noop$1
1409
- }
1410
-
1411
- const utilityReplacement = (declaration, value) => {
1412
- const declarationUtilities = utilities$1[declaration];
1413
- if (declarationUtilities) {
1414
- return declarationUtilities.find(utility => {
1415
- return utility.value === value
1416
- })
1417
- }
1418
- };
1419
-
1420
- const lintResult = (root, result) => {
1421
- root.walkRules(rule => {
1422
- if (!/^\.[\w\-_]+$/.exec(rule.selector)) {
1423
- return
1424
- }
1425
- const decls = rule.nodes.filter(decl => decl.type === 'decl');
1426
-
1427
- if (decls.length === 1) {
1428
- const replacement = utilityReplacement(decls[0].prop, decls[0].value);
1429
- if (replacement) {
1430
- stylelint.utils.report({
1431
- index: rule.sourceIndex,
1432
- message: messages$1.rejected(rule.selector, replacement.utilityClass),
1433
- node: rule,
1434
- result,
1435
- ruleName: ruleName$1,
1436
- });
1437
- }
1438
- }
1439
- });
1440
- };
1441
-
1442
- return lintResult
1443
- });
1444
-
1445
- function noop$1() {}
1446
-
1447
1045
  const ruleName = 'primer/no-display-colors';
1448
1046
  const messages = stylelint.utils.ruleMessages(ruleName, {
1449
1047
  rejected: varName => `${varName} is in alpha and should be used with caution with approval from the Primer team`,
@@ -1509,7 +1107,6 @@ var index = {
1509
1107
  responsiveWidths,
1510
1108
  spacing,
1511
1109
  typography,
1512
- utilities,
1513
1110
  noDisplayColors,
1514
1111
  ],
1515
1112
  rules: {
@@ -1577,7 +1174,6 @@ var index = {
1577
1174
  'primer/responsive-widths': true,
1578
1175
  'primer/spacing': true,
1579
1176
  'primer/typography': true,
1580
- 'primer/utilities': null,
1581
1177
  'primer/no-display-colors': true,
1582
1178
  'property-no-unknown': [
1583
1179
  true,
@@ -1628,12 +1224,9 @@ var index = {
1628
1224
  'comment-empty-line-before': null,
1629
1225
  'length-zero-no-unit': null,
1630
1226
  'selector-max-type': null,
1631
- 'primer/spacing': null,
1632
1227
  'primer/colors': null,
1633
- 'primer/borders': null,
1634
1228
  'primer/typography': null,
1635
1229
  'primer/box-shadow': null,
1636
- 'primer/utilities': null,
1637
1230
  },
1638
1231
  },
1639
1232
  {
@@ -1658,6 +1251,7 @@ var index = {
1658
1251
  },
1659
1252
  {
1660
1253
  files: ['**/*.module.css'],
1254
+ plugins: ['stylelint-css-modules-no-global-scoped-selector'],
1661
1255
  rules: {
1662
1256
  'property-no-unknown': [
1663
1257
  true,
@@ -1682,12 +1276,10 @@ var index = {
1682
1276
  ignoreFunctions: ['global'],
1683
1277
  },
1684
1278
  ],
1279
+ 'css-modules/no-global-scoped-selector': true,
1685
1280
  // temporarily disabiling Primer plugins while we work on upgrades https://github.com/github/primer/issues/3165
1686
- 'primer/spacing': null,
1687
- 'primer/borders': null,
1688
1281
  'primer/typography': null,
1689
1282
  'primer/box-shadow': null,
1690
- 'primer/utilities': null,
1691
1283
  },
1692
1284
  },
1693
1285
  ],