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