@primer/stylelint-config 13.0.0-rc.fe9ab86 → 13.0.1-rc.5358628
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 +325 -91
- package/dist/index.mjs +325 -91
- package/package.json +10 -16
- package/plugins/box-shadow.js +97 -21
- package/plugins/lib/utils.js +8 -0
- package/plugins/typography.js +186 -23
package/dist/index.cjs
CHANGED
|
@@ -7,7 +7,7 @@ var valueParser = require('postcss-value-parser');
|
|
|
7
7
|
var node_module = require('node:module');
|
|
8
8
|
var anymatch = require('anymatch');
|
|
9
9
|
var TapMap = require('tap-map');
|
|
10
|
-
var variables$
|
|
10
|
+
var variables$3 = require('@primer/css/dist/variables.json');
|
|
11
11
|
var matchAll = require('string.prototype.matchall');
|
|
12
12
|
|
|
13
13
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -197,6 +197,14 @@ function primitivesVariables(type) {
|
|
|
197
197
|
case 'border':
|
|
198
198
|
files.push('functional/size/border.json');
|
|
199
199
|
break
|
|
200
|
+
case 'typography':
|
|
201
|
+
files.push('base/typography/typography.json');
|
|
202
|
+
files.push('functional/typography/typography.json');
|
|
203
|
+
break
|
|
204
|
+
case 'box-shadow':
|
|
205
|
+
files.push('functional/themes/light.json');
|
|
206
|
+
files.push('functional/size/border.json');
|
|
207
|
+
break
|
|
200
208
|
}
|
|
201
209
|
|
|
202
210
|
for (const file of files) {
|
|
@@ -229,12 +237,12 @@ function walkGroups$1(root, validate) {
|
|
|
229
237
|
}
|
|
230
238
|
|
|
231
239
|
const {
|
|
232
|
-
createPlugin: createPlugin$
|
|
233
|
-
utils: {report: report$
|
|
240
|
+
createPlugin: createPlugin$3,
|
|
241
|
+
utils: {report: report$3, ruleMessages: ruleMessages$3, validateOptions: validateOptions$3},
|
|
234
242
|
} = stylelint;
|
|
235
243
|
|
|
236
|
-
const ruleName$
|
|
237
|
-
const messages$
|
|
244
|
+
const ruleName$5 = 'primer/borders';
|
|
245
|
+
const messages$5 = ruleMessages$3(ruleName$5, {
|
|
238
246
|
rejected: (value, replacement, propName) => {
|
|
239
247
|
if (propName && propName.includes('radius') && value.includes('borderWidth')) {
|
|
240
248
|
return `Border radius variables can not be used for border widths`
|
|
@@ -252,19 +260,19 @@ const messages$3 = ruleMessages$1(ruleName$3, {
|
|
|
252
260
|
},
|
|
253
261
|
});
|
|
254
262
|
|
|
255
|
-
const variables = primitivesVariables('border');
|
|
263
|
+
const variables$2 = primitivesVariables('border');
|
|
256
264
|
const sizes$1 = [];
|
|
257
265
|
const radii = [];
|
|
258
266
|
|
|
259
267
|
// Props that we want to check
|
|
260
|
-
const propList$
|
|
268
|
+
const propList$2 = ['border', 'border-width', 'border-radius'];
|
|
261
269
|
// Values that we want to ignore
|
|
262
270
|
const valueList$1 = ['${'];
|
|
263
271
|
|
|
264
272
|
const borderShorthand = prop =>
|
|
265
273
|
/^border(-(top|right|bottom|left|block-start|block-end|inline-start|inline-end))?$/.test(prop);
|
|
266
274
|
|
|
267
|
-
for (const variable of variables) {
|
|
275
|
+
for (const variable of variables$2) {
|
|
268
276
|
const name = variable['name'];
|
|
269
277
|
|
|
270
278
|
if (name.includes('borderWidth')) {
|
|
@@ -284,9 +292,9 @@ for (const variable of variables) {
|
|
|
284
292
|
}
|
|
285
293
|
|
|
286
294
|
/** @type {import('stylelint').Rule} */
|
|
287
|
-
const ruleFunction$
|
|
295
|
+
const ruleFunction$3 = (primary, secondaryOptions, context) => {
|
|
288
296
|
return (root, result) => {
|
|
289
|
-
const validOptions = validateOptions$
|
|
297
|
+
const validOptions = validateOptions$3(result, ruleName$5, {
|
|
290
298
|
actual: primary,
|
|
291
299
|
possible: [true],
|
|
292
300
|
});
|
|
@@ -296,7 +304,7 @@ const ruleFunction$1 = (primary, secondaryOptions, context) => {
|
|
|
296
304
|
root.walkDecls(declNode => {
|
|
297
305
|
const {prop, value} = declNode;
|
|
298
306
|
|
|
299
|
-
if (!propList$
|
|
307
|
+
if (!propList$2.some(borderProp => prop.startsWith(borderProp))) return
|
|
300
308
|
if (/^border(-(top|right|bottom|left|block-start|block-end|inline-start|inline-end))?-color$/.test(prop)) return
|
|
301
309
|
if (valueList$1.some(valueToIgnore => value.includes(valueToIgnore))) return
|
|
302
310
|
|
|
@@ -386,7 +394,7 @@ const ruleFunction$1 = (primary, secondaryOptions, context) => {
|
|
|
386
394
|
problems.push({
|
|
387
395
|
index: declarationValueIndex(declNode) + node.sourceIndex,
|
|
388
396
|
endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
|
|
389
|
-
message: messages$
|
|
397
|
+
message: messages$5.rejected(node.value, replacement, prop),
|
|
390
398
|
});
|
|
391
399
|
}
|
|
392
400
|
|
|
@@ -399,13 +407,13 @@ const ruleFunction$1 = (primary, secondaryOptions, context) => {
|
|
|
399
407
|
|
|
400
408
|
if (problems.length) {
|
|
401
409
|
for (const err of problems) {
|
|
402
|
-
report$
|
|
410
|
+
report$3({
|
|
403
411
|
index: err.index,
|
|
404
412
|
endIndex: err.endIndex,
|
|
405
413
|
message: err.message,
|
|
406
414
|
node: declNode,
|
|
407
415
|
result,
|
|
408
|
-
ruleName: ruleName$
|
|
416
|
+
ruleName: ruleName$5,
|
|
409
417
|
});
|
|
410
418
|
}
|
|
411
419
|
}
|
|
@@ -413,13 +421,108 @@ const ruleFunction$1 = (primary, secondaryOptions, context) => {
|
|
|
413
421
|
}
|
|
414
422
|
};
|
|
415
423
|
|
|
416
|
-
ruleFunction$
|
|
417
|
-
ruleFunction$
|
|
418
|
-
ruleFunction$
|
|
424
|
+
ruleFunction$3.ruleName = ruleName$5;
|
|
425
|
+
ruleFunction$3.messages = messages$5;
|
|
426
|
+
ruleFunction$3.meta = {
|
|
419
427
|
fixable: true,
|
|
420
428
|
};
|
|
421
429
|
|
|
422
|
-
var borders = createPlugin$
|
|
430
|
+
var borders = createPlugin$3(ruleName$5, ruleFunction$3);
|
|
431
|
+
|
|
432
|
+
const {
|
|
433
|
+
createPlugin: createPlugin$2,
|
|
434
|
+
utils: {report: report$2, ruleMessages: ruleMessages$2, validateOptions: validateOptions$2},
|
|
435
|
+
} = stylelint;
|
|
436
|
+
|
|
437
|
+
const ruleName$4 = 'primer/box-shadow';
|
|
438
|
+
const messages$4 = ruleMessages$2(ruleName$4, {
|
|
439
|
+
rejected: (value, replacement) => {
|
|
440
|
+
if (!replacement) {
|
|
441
|
+
return `Please use a Primer box-shadow variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/color#shadow or https://primer.style/foundations/primitives/size#border-size`
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return `Please replace '${value}' with a Primer box-shadow variable '${replacement['name']}'. https://primer.style/foundations/primitives/color#shadow or https://primer.style/foundations/primitives/size#border-size`
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
const variables$1 = primitivesVariables('box-shadow');
|
|
449
|
+
const shadows = [];
|
|
450
|
+
|
|
451
|
+
for (const variable of variables$1) {
|
|
452
|
+
const name = variable['name'];
|
|
453
|
+
|
|
454
|
+
// TODO: Decide if this is safe. Someday we might have variables that
|
|
455
|
+
// have 'shadow' in the name but aren't full box-shadows.
|
|
456
|
+
if (name.includes('shadow') || name.includes('boxShadow')) {
|
|
457
|
+
shadows.push(variable);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/** @type {import('stylelint').Rule} */
|
|
462
|
+
const ruleFunction$2 = (primary, secondaryOptions, context) => {
|
|
463
|
+
return (root, result) => {
|
|
464
|
+
const validOptions = validateOptions$2(result, ruleName$4, {
|
|
465
|
+
actual: primary,
|
|
466
|
+
possible: [true],
|
|
467
|
+
});
|
|
468
|
+
const validValues = shadows;
|
|
469
|
+
|
|
470
|
+
if (!validOptions) return
|
|
471
|
+
|
|
472
|
+
root.walkDecls(declNode => {
|
|
473
|
+
const {prop, value} = declNode;
|
|
474
|
+
|
|
475
|
+
if (prop !== 'box-shadow') return
|
|
476
|
+
|
|
477
|
+
if (value === 'none') return
|
|
478
|
+
|
|
479
|
+
const problems = [];
|
|
480
|
+
|
|
481
|
+
const checkForVariable = (vars, nodeValue) => {
|
|
482
|
+
return vars.some(variable =>
|
|
483
|
+
new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(nodeValue),
|
|
484
|
+
)
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
if (checkForVariable(validValues, value)) {
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const replacement = validValues.find(variable => variable.values.includes(value));
|
|
492
|
+
|
|
493
|
+
if (replacement && context.fix) {
|
|
494
|
+
declNode.value = value.replace(value, `var(${replacement['name']})`);
|
|
495
|
+
} else {
|
|
496
|
+
problems.push({
|
|
497
|
+
index: declarationValueIndex(declNode),
|
|
498
|
+
endIndex: declarationValueIndex(declNode) + value.length,
|
|
499
|
+
message: messages$4.rejected(value, replacement),
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (problems.length) {
|
|
504
|
+
for (const err of problems) {
|
|
505
|
+
report$2({
|
|
506
|
+
index: err.index,
|
|
507
|
+
endIndex: err.endIndex,
|
|
508
|
+
message: err.message,
|
|
509
|
+
node: declNode,
|
|
510
|
+
result,
|
|
511
|
+
ruleName: ruleName$4,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
ruleFunction$2.ruleName = ruleName$4;
|
|
520
|
+
ruleFunction$2.messages = messages$4;
|
|
521
|
+
ruleFunction$2.meta = {
|
|
522
|
+
fixable: true,
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
var boxShadow = createPlugin$2(ruleName$4, ruleFunction$2);
|
|
423
526
|
|
|
424
527
|
const SKIP_VALUE_NODE_TYPES = new Set(['space', 'div']);
|
|
425
528
|
const SKIP_AT_RULE_NAMES = new Set(['each', 'for', 'function', 'mixin']);
|
|
@@ -665,18 +768,18 @@ function createVariableRule(ruleName, rules, url) {
|
|
|
665
768
|
let actualRules = rules;
|
|
666
769
|
let overrides = options.rules;
|
|
667
770
|
if (typeof rules === 'function') {
|
|
668
|
-
actualRules = rules({variables: variables$
|
|
771
|
+
actualRules = rules({variables: variables$3, options, ruleName});
|
|
669
772
|
} else {
|
|
670
773
|
actualRules = Object.assign({}, rules);
|
|
671
774
|
}
|
|
672
775
|
if (typeof overrides === 'function') {
|
|
673
776
|
delete options.rules;
|
|
674
|
-
overrides = overrides({rules: actualRules, options, ruleName, variables: variables$
|
|
777
|
+
overrides = overrides({rules: actualRules, options, ruleName, variables: variables$3});
|
|
675
778
|
}
|
|
676
779
|
if (overrides) {
|
|
677
780
|
Object.assign(actualRules, overrides);
|
|
678
781
|
}
|
|
679
|
-
const validate = declarationValidator(actualRules, {variables: variables$
|
|
782
|
+
const validate = declarationValidator(actualRules, {variables: variables$3});
|
|
680
783
|
|
|
681
784
|
// The stylelint docs suggest respecting a "disableFix" rule option that
|
|
682
785
|
// overrides the "global" context.fix (--fix) linting option.
|
|
@@ -710,10 +813,9 @@ function createVariableRule(ruleName, rules, url) {
|
|
|
710
813
|
const message = stylelint.utils
|
|
711
814
|
.ruleMessages(ruleName, {
|
|
712
815
|
rejected: m => {
|
|
713
|
-
|
|
816
|
+
{
|
|
714
817
|
return `${m}. See ${url}.`
|
|
715
818
|
}
|
|
716
|
-
return `${m}.`
|
|
717
819
|
},
|
|
718
820
|
})
|
|
719
821
|
.rejected(error);
|
|
@@ -738,27 +840,6 @@ function createVariableRule(ruleName, rules, url) {
|
|
|
738
840
|
|
|
739
841
|
function noop$2() {}
|
|
740
842
|
|
|
741
|
-
var boxShadow = createVariableRule(
|
|
742
|
-
'primer/box-shadow',
|
|
743
|
-
{
|
|
744
|
-
'box shadow': {
|
|
745
|
-
expects: 'a box-shadow variable',
|
|
746
|
-
props: 'box-shadow',
|
|
747
|
-
values: [
|
|
748
|
-
'$box-shadow*',
|
|
749
|
-
'$*-shadow',
|
|
750
|
-
'none',
|
|
751
|
-
// Match variables in any of the following formats: --color-shadow-*, --color-*-shadow-*, --color-*-shadow, --shadow-*, *shadow*
|
|
752
|
-
/var\(--color-(.+-)*shadow(-.+)*\)/,
|
|
753
|
-
/var\(--shadow(-.+)*\)/,
|
|
754
|
-
/var\((.+-)*shadow(-.+)*\)/,
|
|
755
|
-
],
|
|
756
|
-
singular: true,
|
|
757
|
-
},
|
|
758
|
-
},
|
|
759
|
-
'https://primer.style/css/utilities/box-shadow',
|
|
760
|
-
);
|
|
761
|
-
|
|
762
843
|
const bgVars = [
|
|
763
844
|
'$bg-*',
|
|
764
845
|
'$tooltip-background-color',
|
|
@@ -801,9 +882,9 @@ var colors = createVariableRule(
|
|
|
801
882
|
'https://primer.style/primitives/colors',
|
|
802
883
|
);
|
|
803
884
|
|
|
804
|
-
const ruleName$
|
|
885
|
+
const ruleName$3 = 'primer/responsive-widths';
|
|
805
886
|
|
|
806
|
-
const messages$
|
|
887
|
+
const messages$3 = stylelint.utils.ruleMessages(ruleName$3, {
|
|
807
888
|
rejected: value => {
|
|
808
889
|
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`
|
|
809
890
|
},
|
|
@@ -823,7 +904,7 @@ const walkGroups = (root, validate) => {
|
|
|
823
904
|
};
|
|
824
905
|
|
|
825
906
|
// eslint-disable-next-line no-unused-vars
|
|
826
|
-
var responsiveWidths = stylelint.createPlugin(ruleName$
|
|
907
|
+
var responsiveWidths = stylelint.createPlugin(ruleName$3, (enabled, options = {}, context) => {
|
|
827
908
|
if (!enabled) {
|
|
828
909
|
return noop$1
|
|
829
910
|
}
|
|
@@ -859,7 +940,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$2, (enabled, options = {}
|
|
|
859
940
|
if (parseInt(valueUnit.number) > 320) {
|
|
860
941
|
problems.push({
|
|
861
942
|
index: declarationValueIndex(decl) + node.sourceIndex,
|
|
862
|
-
message: messages$
|
|
943
|
+
message: messages$3.rejected(node.value),
|
|
863
944
|
});
|
|
864
945
|
}
|
|
865
946
|
break
|
|
@@ -867,7 +948,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$2, (enabled, options = {}
|
|
|
867
948
|
if (parseInt(valueUnit.number) > 100) {
|
|
868
949
|
problems.push({
|
|
869
950
|
index: declarationValueIndex(decl) + node.sourceIndex,
|
|
870
|
-
message: messages$
|
|
951
|
+
message: messages$3.rejected(node.value),
|
|
871
952
|
});
|
|
872
953
|
}
|
|
873
954
|
break
|
|
@@ -881,7 +962,7 @@ var responsiveWidths = stylelint.createPlugin(ruleName$2, (enabled, options = {}
|
|
|
881
962
|
message: err.message,
|
|
882
963
|
node: decl,
|
|
883
964
|
result,
|
|
884
|
-
ruleName: ruleName$
|
|
965
|
+
ruleName: ruleName$3,
|
|
885
966
|
});
|
|
886
967
|
}
|
|
887
968
|
}
|
|
@@ -894,12 +975,12 @@ var responsiveWidths = stylelint.createPlugin(ruleName$2, (enabled, options = {}
|
|
|
894
975
|
function noop$1() {}
|
|
895
976
|
|
|
896
977
|
const {
|
|
897
|
-
createPlugin,
|
|
898
|
-
utils: {report, ruleMessages, validateOptions},
|
|
978
|
+
createPlugin: createPlugin$1,
|
|
979
|
+
utils: {report: report$1, ruleMessages: ruleMessages$1, validateOptions: validateOptions$1},
|
|
899
980
|
} = stylelint;
|
|
900
981
|
|
|
901
|
-
const ruleName$
|
|
902
|
-
const messages$
|
|
982
|
+
const ruleName$2 = 'primer/spacing';
|
|
983
|
+
const messages$2 = ruleMessages$1(ruleName$2, {
|
|
903
984
|
rejected: (value, replacement) => {
|
|
904
985
|
if (!replacement) {
|
|
905
986
|
return `Please use a primer size variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/size`
|
|
@@ -910,7 +991,7 @@ const messages$1 = ruleMessages(ruleName$1, {
|
|
|
910
991
|
});
|
|
911
992
|
|
|
912
993
|
// Props that we want to check
|
|
913
|
-
const propList = ['padding', 'margin', 'top', 'right', 'bottom', 'left'];
|
|
994
|
+
const propList$1 = ['padding', 'margin', 'top', 'right', 'bottom', 'left'];
|
|
914
995
|
// Values that we want to ignore
|
|
915
996
|
const valueList = ['${'];
|
|
916
997
|
|
|
@@ -927,9 +1008,9 @@ for (const size of sizes) {
|
|
|
927
1008
|
}
|
|
928
1009
|
|
|
929
1010
|
/** @type {import('stylelint').Rule} */
|
|
930
|
-
const ruleFunction = (primary, secondaryOptions, context) => {
|
|
1011
|
+
const ruleFunction$1 = (primary, secondaryOptions, context) => {
|
|
931
1012
|
return (root, result) => {
|
|
932
|
-
const validOptions = validateOptions(result, ruleName$
|
|
1013
|
+
const validOptions = validateOptions$1(result, ruleName$2, {
|
|
933
1014
|
actual: primary,
|
|
934
1015
|
possible: [true],
|
|
935
1016
|
});
|
|
@@ -939,7 +1020,7 @@ const ruleFunction = (primary, secondaryOptions, context) => {
|
|
|
939
1020
|
root.walkDecls(declNode => {
|
|
940
1021
|
const {prop, value} = declNode;
|
|
941
1022
|
|
|
942
|
-
if (!propList.some(spacingProp => prop.startsWith(spacingProp))) return
|
|
1023
|
+
if (!propList$1.some(spacingProp => prop.startsWith(spacingProp))) return
|
|
943
1024
|
if (valueList.some(valueToIgnore => value.includes(valueToIgnore))) return
|
|
944
1025
|
|
|
945
1026
|
const problems = [];
|
|
@@ -984,7 +1065,7 @@ const ruleFunction = (primary, secondaryOptions, context) => {
|
|
|
984
1065
|
problems.push({
|
|
985
1066
|
index: declarationValueIndex(declNode) + node.sourceIndex,
|
|
986
1067
|
endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
|
|
987
|
-
message: messages$
|
|
1068
|
+
message: messages$2.rejected(node.value, replacement),
|
|
988
1069
|
});
|
|
989
1070
|
}
|
|
990
1071
|
|
|
@@ -995,6 +1076,189 @@ const ruleFunction = (primary, secondaryOptions, context) => {
|
|
|
995
1076
|
declNode.value = parsedValue.toString();
|
|
996
1077
|
}
|
|
997
1078
|
|
|
1079
|
+
if (problems.length) {
|
|
1080
|
+
for (const err of problems) {
|
|
1081
|
+
report$1({
|
|
1082
|
+
index: err.index,
|
|
1083
|
+
endIndex: err.endIndex,
|
|
1084
|
+
message: err.message,
|
|
1085
|
+
node: declNode,
|
|
1086
|
+
result,
|
|
1087
|
+
ruleName: ruleName$2,
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
ruleFunction$1.ruleName = ruleName$2;
|
|
1096
|
+
ruleFunction$1.messages = messages$2;
|
|
1097
|
+
ruleFunction$1.meta = {
|
|
1098
|
+
fixable: true,
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
var spacing = createPlugin$1(ruleName$2, ruleFunction$1);
|
|
1102
|
+
|
|
1103
|
+
const {
|
|
1104
|
+
createPlugin,
|
|
1105
|
+
utils: {report, ruleMessages, validateOptions},
|
|
1106
|
+
} = stylelint;
|
|
1107
|
+
|
|
1108
|
+
const ruleName$1 = 'primer/typography';
|
|
1109
|
+
const messages$1 = ruleMessages(ruleName$1, {
|
|
1110
|
+
rejected: (value, replacement) => {
|
|
1111
|
+
// no possible replacement
|
|
1112
|
+
if (!replacement) {
|
|
1113
|
+
return `Please use a Primer typography variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/typography`
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// multiple possible replacements
|
|
1117
|
+
if (replacement.length) {
|
|
1118
|
+
return `Please use one of the following Primer typography variables instead of '${value}': ${replacement.map(replacementObj => `'${replacementObj.name}'`).join(', ')}. https://primer.style/foundations/primitives/typography`
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// one possible replacement
|
|
1122
|
+
return `Please replace '${value}' with Primer typography variable '${replacement['name']}'. https://primer.style/foundations/primitives/typography`
|
|
1123
|
+
},
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1126
|
+
const fontWeightKeywordMap = {
|
|
1127
|
+
normal: 400,
|
|
1128
|
+
bold: 700,
|
|
1129
|
+
bolder: 600,
|
|
1130
|
+
lighter: 300,
|
|
1131
|
+
};
|
|
1132
|
+
const getClosestFontWeight = (goalWeightNumber, fontWeightsTokens) => {
|
|
1133
|
+
return fontWeightsTokens.reduce((prev, curr) =>
|
|
1134
|
+
Math.abs(curr.values - goalWeightNumber) < Math.abs(prev.values - goalWeightNumber) ? curr : prev,
|
|
1135
|
+
).values
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
const variables = primitivesVariables('typography');
|
|
1139
|
+
const fontSizes = [];
|
|
1140
|
+
const fontWeights = [];
|
|
1141
|
+
const lineHeights = [];
|
|
1142
|
+
const fontStacks = [];
|
|
1143
|
+
const fontShorthands = [];
|
|
1144
|
+
|
|
1145
|
+
// Props that we want to check for typography variables
|
|
1146
|
+
const propList = ['font-size', 'font-weight', 'line-height', 'font-family', 'font'];
|
|
1147
|
+
|
|
1148
|
+
for (const variable of variables) {
|
|
1149
|
+
const name = variable['name'];
|
|
1150
|
+
|
|
1151
|
+
if (name.includes('size')) {
|
|
1152
|
+
fontSizes.push(variable);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
if (name.includes('weight')) {
|
|
1156
|
+
fontWeights.push(variable);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
if (name.includes('lineHeight')) {
|
|
1160
|
+
lineHeights.push(variable);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
if (name.includes('fontStack')) {
|
|
1164
|
+
fontStacks.push(variable);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
if (name.includes('shorthand')) {
|
|
1168
|
+
fontShorthands.push(variable);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/** @type {import('stylelint').Rule} */
|
|
1173
|
+
const ruleFunction = primary => {
|
|
1174
|
+
return (root, result) => {
|
|
1175
|
+
const validOptions = validateOptions(result, ruleName$1, {
|
|
1176
|
+
actual: primary,
|
|
1177
|
+
possible: [true],
|
|
1178
|
+
});
|
|
1179
|
+
let validValues = [];
|
|
1180
|
+
|
|
1181
|
+
if (!validOptions) return
|
|
1182
|
+
|
|
1183
|
+
root.walkDecls(declNode => {
|
|
1184
|
+
const {prop, value} = declNode;
|
|
1185
|
+
|
|
1186
|
+
if (!propList.some(typographyProp => prop === typographyProp)) return
|
|
1187
|
+
|
|
1188
|
+
const problems = [];
|
|
1189
|
+
|
|
1190
|
+
const checkForVariable = (vars, nodeValue) =>
|
|
1191
|
+
vars.some(variable =>
|
|
1192
|
+
new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(nodeValue),
|
|
1193
|
+
);
|
|
1194
|
+
|
|
1195
|
+
// Exact values to ignore.
|
|
1196
|
+
if (value === 'inherit') {
|
|
1197
|
+
return
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
switch (prop) {
|
|
1201
|
+
case 'font-size':
|
|
1202
|
+
validValues = fontSizes;
|
|
1203
|
+
break
|
|
1204
|
+
case 'font-weight':
|
|
1205
|
+
validValues = fontWeights;
|
|
1206
|
+
break
|
|
1207
|
+
case 'line-height':
|
|
1208
|
+
validValues = lineHeights;
|
|
1209
|
+
break
|
|
1210
|
+
case 'font-family':
|
|
1211
|
+
validValues = fontStacks;
|
|
1212
|
+
break
|
|
1213
|
+
case 'font':
|
|
1214
|
+
validValues = fontShorthands;
|
|
1215
|
+
break
|
|
1216
|
+
default:
|
|
1217
|
+
validValues = [];
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
if (checkForVariable(validValues, value)) {
|
|
1221
|
+
return
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const getReplacements = () => {
|
|
1225
|
+
const replacementTokens = validValues.filter(variable => {
|
|
1226
|
+
if (!(variable.values instanceof Array)) {
|
|
1227
|
+
let nodeValue = value;
|
|
1228
|
+
|
|
1229
|
+
if (prop === 'font-weight') {
|
|
1230
|
+
nodeValue = getClosestFontWeight(fontWeightKeywordMap[value] || value, fontWeights);
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
return variable.values.toString() === nodeValue.toString()
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
return variable.values.includes(value.replace('-', ''))
|
|
1237
|
+
});
|
|
1238
|
+
|
|
1239
|
+
if (!replacementTokens.length) {
|
|
1240
|
+
return
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
return replacementTokens[0]
|
|
1244
|
+
};
|
|
1245
|
+
const replacement = getReplacements();
|
|
1246
|
+
const fixable = replacement && !replacement.length;
|
|
1247
|
+
let fixedValue = '';
|
|
1248
|
+
if (fixable) {
|
|
1249
|
+
fixedValue = value.replace(value, `var(${replacement['name']})`);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
problems.push({
|
|
1253
|
+
index: declarationValueIndex(declNode),
|
|
1254
|
+
endIndex: declarationValueIndex(declNode) + value.length,
|
|
1255
|
+
message: messages$1.rejected(value, replacement, prop),
|
|
1256
|
+
fix: () => {
|
|
1257
|
+
if (!fixable) return
|
|
1258
|
+
declNode.value = fixedValue;
|
|
1259
|
+
},
|
|
1260
|
+
});
|
|
1261
|
+
|
|
998
1262
|
if (problems.length) {
|
|
999
1263
|
for (const err of problems) {
|
|
1000
1264
|
report({
|
|
@@ -1004,6 +1268,7 @@ const ruleFunction = (primary, secondaryOptions, context) => {
|
|
|
1004
1268
|
node: declNode,
|
|
1005
1269
|
result,
|
|
1006
1270
|
ruleName: ruleName$1,
|
|
1271
|
+
fix: err.fix,
|
|
1007
1272
|
});
|
|
1008
1273
|
}
|
|
1009
1274
|
}
|
|
@@ -1017,30 +1282,7 @@ ruleFunction.meta = {
|
|
|
1017
1282
|
fixable: true,
|
|
1018
1283
|
};
|
|
1019
1284
|
|
|
1020
|
-
var
|
|
1021
|
-
|
|
1022
|
-
var typography = createVariableRule(
|
|
1023
|
-
'primer/typography',
|
|
1024
|
-
{
|
|
1025
|
-
'font-size': {
|
|
1026
|
-
expects: 'a font-size variable',
|
|
1027
|
-
values: ['$body-font-size', '$h{000,00,0,1,2,3,4,5,6}-size', '$font-size-*', '1', '1em', 'inherit'],
|
|
1028
|
-
},
|
|
1029
|
-
'font-weight': {
|
|
1030
|
-
props: 'font-weight',
|
|
1031
|
-
values: ['$font-weight-*', 'inherit'],
|
|
1032
|
-
replacements: {
|
|
1033
|
-
bold: '$font-weight-bold',
|
|
1034
|
-
normal: '$font-weight-normal',
|
|
1035
|
-
},
|
|
1036
|
-
},
|
|
1037
|
-
'line-height': {
|
|
1038
|
-
props: 'line-height',
|
|
1039
|
-
values: ['$body-line-height', '$lh-*', '0', '1', '1em', 'inherit'],
|
|
1040
|
-
},
|
|
1041
|
-
},
|
|
1042
|
-
'https://primer.style/css/utilities/typography',
|
|
1043
|
-
);
|
|
1285
|
+
var typography = createPlugin(ruleName$1, ruleFunction);
|
|
1044
1286
|
|
|
1045
1287
|
const ruleName = 'primer/no-display-colors';
|
|
1046
1288
|
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
@@ -1144,7 +1386,6 @@ var index = {
|
|
|
1144
1386
|
'declaration-property-value-disallowed-list': {
|
|
1145
1387
|
'/^transition/': ['/all/'],
|
|
1146
1388
|
'/^background/': ['http:', 'https:'],
|
|
1147
|
-
'/^border/': ['none'],
|
|
1148
1389
|
'/.+/': ['initial'],
|
|
1149
1390
|
},
|
|
1150
1391
|
'function-calc-no-unspaced-operator': true,
|
|
@@ -1225,8 +1466,6 @@ var index = {
|
|
|
1225
1466
|
'length-zero-no-unit': null,
|
|
1226
1467
|
'selector-max-type': null,
|
|
1227
1468
|
'primer/colors': null,
|
|
1228
|
-
'primer/typography': null,
|
|
1229
|
-
'primer/box-shadow': null,
|
|
1230
1469
|
},
|
|
1231
1470
|
},
|
|
1232
1471
|
{
|
|
@@ -1251,7 +1490,6 @@ var index = {
|
|
|
1251
1490
|
},
|
|
1252
1491
|
{
|
|
1253
1492
|
files: ['**/*.module.css'],
|
|
1254
|
-
plugins: ['stylelint-css-modules-no-global-scoped-selector'],
|
|
1255
1493
|
rules: {
|
|
1256
1494
|
'property-no-unknown': [
|
|
1257
1495
|
true,
|
|
@@ -1276,10 +1514,6 @@ var index = {
|
|
|
1276
1514
|
ignoreFunctions: ['global'],
|
|
1277
1515
|
},
|
|
1278
1516
|
],
|
|
1279
|
-
'css-modules/no-global-scoped-selector': true,
|
|
1280
|
-
// temporarily disabiling Primer plugins while we work on upgrades https://github.com/github/primer/issues/3165
|
|
1281
|
-
'primer/typography': null,
|
|
1282
|
-
'primer/box-shadow': null,
|
|
1283
1517
|
},
|
|
1284
1518
|
},
|
|
1285
1519
|
],
|