@atlaskit/eslint-plugin-design-system 8.37.2 → 8.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -0
- package/constellation/index/usage.mdx +1 -0
- package/constellation/use-tokens-space/usage.mdx +30 -0
- package/dist/cjs/ast-nodes/object-entry.js +35 -0
- package/dist/cjs/ast-nodes/object.js +12 -0
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/use-primitives/utils/validate-styles.js +11 -2
- package/dist/cjs/rules/use-tokens-space/index.js +54 -0
- package/dist/cjs/rules/use-tokens-space/transformers/index.js +12 -0
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/index.js +130 -0
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/style-map.js +80 -0
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/supported.js +14 -0
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +37 -0
- package/dist/cjs/rules/use-tokens-space/utils/index.js +12 -0
- package/dist/cjs/rules/use-tokens-space/utils/is-string-or-number.js +9 -0
- package/dist/es2019/ast-nodes/object-entry.js +37 -3
- package/dist/es2019/ast-nodes/object.js +12 -0
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/use-primitives/utils/validate-styles.js +11 -2
- package/dist/es2019/rules/use-tokens-space/index.js +38 -0
- package/dist/es2019/rules/use-tokens-space/transformers/index.js +1 -0
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/index.js +121 -0
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/style-map.js +152 -0
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/supported.js +8 -0
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +30 -0
- package/dist/es2019/rules/use-tokens-space/utils/index.js +1 -0
- package/dist/es2019/rules/use-tokens-space/utils/is-string-or-number.js +3 -0
- package/dist/esm/ast-nodes/object-entry.js +37 -3
- package/dist/esm/ast-nodes/object.js +12 -0
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/use-primitives/utils/validate-styles.js +11 -2
- package/dist/esm/rules/use-tokens-space/index.js +48 -0
- package/dist/esm/rules/use-tokens-space/transformers/index.js +1 -0
- package/dist/esm/rules/use-tokens-space/transformers/style-property/index.js +120 -0
- package/dist/esm/rules/use-tokens-space/transformers/style-property/style-map.js +73 -0
- package/dist/esm/rules/use-tokens-space/transformers/style-property/supported.js +8 -0
- package/dist/esm/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +29 -0
- package/dist/esm/rules/use-tokens-space/utils/index.js +1 -0
- package/dist/esm/rules/use-tokens-space/utils/is-string-or-number.js +3 -0
- package/dist/types/ast-nodes/object-entry.d.ts +12 -2
- package/dist/types/ast-nodes/object.d.ts +1 -0
- package/dist/types/index.codegen.d.ts +1 -0
- package/dist/types/presets/all.codegen.d.ts +2 -1
- package/dist/types/rules/index.codegen.d.ts +5 -4
- package/dist/types/rules/use-tokens-space/index.d.ts +3 -0
- package/dist/types/rules/use-tokens-space/transformers/index.d.ts +1 -0
- package/dist/types/rules/use-tokens-space/transformers/style-property/index.d.ts +26 -0
- package/dist/types/rules/use-tokens-space/transformers/style-property/style-map.d.ts +7 -0
- package/dist/types/rules/use-tokens-space/transformers/style-property/supported.d.ts +6 -0
- package/dist/types/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +14 -0
- package/dist/types/rules/use-tokens-space/utils/index.d.ts +1 -0
- package/dist/types/rules/use-tokens-space/utils/is-string-or-number.d.ts +1 -0
- package/dist/types/rules/use-visually-hidden/constants.d.ts +1 -1
- package/dist/types/rules/utils/create-rule.d.ts +1 -1
- package/dist/types-ts4.5/ast-nodes/object-entry.d.ts +12 -2
- package/dist/types-ts4.5/ast-nodes/object.d.ts +1 -0
- package/dist/types-ts4.5/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +5 -4
- package/dist/types-ts4.5/rules/use-tokens-space/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/index.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/index.d.ts +26 -0
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/style-map.d.ts +7 -0
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/supported.d.ts +6 -0
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +14 -0
- package/dist/types-ts4.5/rules/use-tokens-space/utils/index.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-tokens-space/utils/is-string-or-number.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-visually-hidden/constants.d.ts +1 -1
- package/dist/types-ts4.5/rules/utils/create-rule.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::d1c25758089a050334359276ede0ca3a>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -32,6 +32,7 @@ import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-car
|
|
|
32
32
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
33
33
|
import usePrimitives from './use-primitives';
|
|
34
34
|
import usePrimitivesText from './use-primitives-text';
|
|
35
|
+
import useTokensSpace from './use-tokens-space';
|
|
35
36
|
import useTokensTypography from './use-tokens-typography';
|
|
36
37
|
import useVisuallyHidden from './use-visually-hidden';
|
|
37
38
|
export default {
|
|
@@ -64,6 +65,7 @@ export default {
|
|
|
64
65
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
65
66
|
'use-primitives': usePrimitives,
|
|
66
67
|
'use-primitives-text': usePrimitivesText,
|
|
68
|
+
'use-tokens-space': useTokensSpace,
|
|
67
69
|
'use-tokens-typography': useTokensTypography,
|
|
68
70
|
'use-visually-hidden': useVisuallyHidden
|
|
69
71
|
};
|
|
@@ -86,7 +86,6 @@ const isTokenCall = node => {
|
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
88
88
|
const token = ast.FunctionCall.getArgumentAtPos(node, 0);
|
|
89
|
-
const fallback = ast.FunctionCall.getArgumentAtPos(node, 1);
|
|
90
89
|
if (!token || token.type !== 'Literal') {
|
|
91
90
|
return false;
|
|
92
91
|
}
|
|
@@ -97,7 +96,17 @@ const isTokenCall = node => {
|
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
// Not all `token()` calls have a fall back. This is fine, but if there is a fallback, make sure it's the same as the fallback xcss will use
|
|
100
|
-
if (
|
|
99
|
+
if (node.arguments.length === 2) {
|
|
100
|
+
const fallback = ast.FunctionCall.getArgumentAtPos(node, 1);
|
|
101
|
+
|
|
102
|
+
// `getArgumentAtPos` is only able to understand `Literal` and `ObjectExpression` statements
|
|
103
|
+
// If there are 2 args, but `fallback` is undefined, then the fallback is something wild, like `token('space.100, `${gridSize * rem(3)`})`
|
|
104
|
+
if (!fallback) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
if (fallback.type !== 'Literal') {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
101
110
|
if (spaceTokenMap[fallback.value] !== token.value) {
|
|
102
111
|
return false;
|
|
103
112
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createLintRule } from '../utils/create-rule';
|
|
2
|
+
import { StyleProperty } from './transformers';
|
|
3
|
+
const rule = createLintRule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'use-tokens-space',
|
|
6
|
+
type: 'problem',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
hasSuggestions: true,
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Enforces usage of space design tokens rather than hard-coded values.',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
noRawSpacingValues: 'The use of spacing primitives or tokens is preferred over the direct application of spacing properties.'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
'CallExpression[callee.name="css"] ObjectExpression Property': node => StyleProperty.lint(node, {
|
|
21
|
+
context
|
|
22
|
+
}),
|
|
23
|
+
'CallExpression[callee.name="keyframes"] ObjectExpression Property': node => StyleProperty.lint(node, {
|
|
24
|
+
context
|
|
25
|
+
}),
|
|
26
|
+
'CallExpression[callee.name="cssMap"] ObjectExpression Property': node => StyleProperty.lint(node, {
|
|
27
|
+
context
|
|
28
|
+
}),
|
|
29
|
+
'CallExpression[callee.object.name=styled] ObjectExpression Property': node => StyleProperty.lint(node, {
|
|
30
|
+
context
|
|
31
|
+
}),
|
|
32
|
+
'CallExpression[callee.object.name=styled2] ObjectExpression Property': node => StyleProperty.lint(node, {
|
|
33
|
+
context
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
export default rule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StyleProperty } from './style-property';
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/react/require-jsdoc */
|
|
2
|
+
|
|
3
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
4
|
+
import * as ast from '../../../../ast-nodes';
|
|
5
|
+
import { isStringOrNumber } from '../../utils';
|
|
6
|
+
import { styleMap } from './style-map';
|
|
7
|
+
import supported from './supported';
|
|
8
|
+
import { upsertImportDeclaration } from './upsert-import-declaration';
|
|
9
|
+
const messageId = 'noRawSpacingValues';
|
|
10
|
+
export const StyleProperty = {
|
|
11
|
+
lint(node, {
|
|
12
|
+
context
|
|
13
|
+
}) {
|
|
14
|
+
// Check whether all criteria needed to make a transformation are met
|
|
15
|
+
const {
|
|
16
|
+
success,
|
|
17
|
+
ref
|
|
18
|
+
} = StyleProperty._check(node);
|
|
19
|
+
if (!success) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
context.report({
|
|
23
|
+
node: ref.node.value,
|
|
24
|
+
messageId,
|
|
25
|
+
fix: ref.token ? StyleProperty._fix(ref, context) : undefined
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
_check(node) {
|
|
29
|
+
if (!isNodeOfType(node, 'Property')) {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
ref: undefined
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Currently, we support values like:
|
|
38
|
+
* ```
|
|
39
|
+
* {
|
|
40
|
+
* padding: '8px', // value.type is Literal
|
|
41
|
+
* margin: -8, // value.type is UnaryExpression
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
if (!(isNodeOfType(node.value, 'Literal') || isNodeOfType(node.value, 'UnaryExpression'))) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
ref: undefined
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const {
|
|
52
|
+
value: property
|
|
53
|
+
} = ast.ObjectEntry.getProperty(node);
|
|
54
|
+
|
|
55
|
+
// Bail if the property is not `padding`, `margin`, etc
|
|
56
|
+
if (!property || !styleMap[property]) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
ref: undefined
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const value = ast.ObjectEntry.getValue(node);
|
|
63
|
+
|
|
64
|
+
// This is mainly useful as a type guard, so the checks after don't have to have duplicate checks for other types.
|
|
65
|
+
if (!isStringOrNumber(value)) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
ref: undefined
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ignore CSS vars. See: https://stash.atlassian.com/projects/ATLASSIAN/repos/atlassian-frontend-monorepo/pull-requests/74844/overview?commentId=6741571
|
|
73
|
+
if (value.toString().startsWith('var(')) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
ref: undefined
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// There are valid values to ignore, such as `margin: auto`
|
|
81
|
+
if (supported.values.ignore.includes(value)) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
ref: undefined
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Don't report on stuff like `padding: '8px 16px'`.
|
|
89
|
+
// We may iterate to handle values like this in future.
|
|
90
|
+
if (value.toString().includes(' ')) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
ref: undefined
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const ref = {
|
|
97
|
+
node,
|
|
98
|
+
token: styleMap[property][value],
|
|
99
|
+
fallback: value
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
ref
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* All required validation steps have been taken care of before this
|
|
108
|
+
* transformer is called, so it just goes ahead providing all necessary fixes
|
|
109
|
+
*/
|
|
110
|
+
_fix(ref, context) {
|
|
111
|
+
return fixer => {
|
|
112
|
+
const importFix = upsertImportDeclaration({
|
|
113
|
+
module: '@atlaskit/tokens',
|
|
114
|
+
specifiers: ['token']
|
|
115
|
+
}, context, fixer);
|
|
116
|
+
const tokenCall = ref.fallback ? `token('${ref.token}', '${ref.fallback}')` : `token('${ref.token}')`;
|
|
117
|
+
const tokenFix = fixer.replaceText(ref.node.value, tokenCall);
|
|
118
|
+
return [importFix, tokenFix].filter(fix => Boolean(fix)); // Some of the transformers can return arrays with undefined, so filter them out
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16054
|
|
2
|
+
const tokenMap = {
|
|
3
|
+
'-2px': 'space.negative.025',
|
|
4
|
+
'-4px': 'space.negative.050',
|
|
5
|
+
'-6px': 'space.negative.075',
|
|
6
|
+
'-8px': 'space.negative.100',
|
|
7
|
+
'-12px': 'space.negative.150',
|
|
8
|
+
'-16px': 'space.negative.200',
|
|
9
|
+
'-20px': 'space.negative.250',
|
|
10
|
+
'-24px': 'space.negative.300',
|
|
11
|
+
'-32px': 'space.negative.400',
|
|
12
|
+
[-2]: 'space.negative.025',
|
|
13
|
+
[-4]: 'space.negative.050',
|
|
14
|
+
[-6]: 'space.negative.075',
|
|
15
|
+
[-8]: 'space.negative.100',
|
|
16
|
+
[-12]: 'space.negative.150',
|
|
17
|
+
[-16]: 'space.negative.200',
|
|
18
|
+
[-20]: 'space.negative.250',
|
|
19
|
+
[-24]: 'space.negative.300',
|
|
20
|
+
[-32]: 'space.negative.400',
|
|
21
|
+
// '0px': 'space.0', // Don't map 0 to match the implementation of `ensure-design-token-usage`
|
|
22
|
+
'2px': 'space.025',
|
|
23
|
+
'4px': 'space.050',
|
|
24
|
+
'6px': 'space.075',
|
|
25
|
+
'8px': 'space.100',
|
|
26
|
+
'12px': 'space.150',
|
|
27
|
+
'16px': 'space.200',
|
|
28
|
+
'20px': 'space.250',
|
|
29
|
+
'24px': 'space.300',
|
|
30
|
+
'32px': 'space.400',
|
|
31
|
+
'40px': 'space.500',
|
|
32
|
+
'48px': 'space.600',
|
|
33
|
+
'64px': 'space.800',
|
|
34
|
+
'80px': 'space.1000',
|
|
35
|
+
// 0: 'space.0', // Don't map 0 to match the implementation of `ensure-design-token-usage`
|
|
36
|
+
2: 'space.025',
|
|
37
|
+
4: 'space.050',
|
|
38
|
+
6: 'space.075',
|
|
39
|
+
8: 'space.100',
|
|
40
|
+
12: 'space.150',
|
|
41
|
+
16: 'space.200',
|
|
42
|
+
20: 'space.250',
|
|
43
|
+
24: 'space.300',
|
|
44
|
+
32: 'space.400',
|
|
45
|
+
40: 'space.500',
|
|
46
|
+
48: 'space.600',
|
|
47
|
+
64: 'space.800',
|
|
48
|
+
80: 'space.1000',
|
|
49
|
+
'-0.125rem': 'space.negative.025',
|
|
50
|
+
'-0.25rem': 'space.negative.050',
|
|
51
|
+
'-0.375rem': 'space.negative.075',
|
|
52
|
+
'-0.5rem': 'space.negative.100',
|
|
53
|
+
'-0.75rem': 'space.negative.150',
|
|
54
|
+
'-1rem': 'space.negative.200',
|
|
55
|
+
'-1.25rem': 'space.negative.250',
|
|
56
|
+
'-1.5rem': 'space.negative.300',
|
|
57
|
+
'-2rem': 'space.negative.400',
|
|
58
|
+
'0.125rem': 'space.025',
|
|
59
|
+
'0.25rem': 'space.050',
|
|
60
|
+
'0.375rem': 'space.075',
|
|
61
|
+
'0.5rem': 'space.100',
|
|
62
|
+
'0.75rem': 'space.150',
|
|
63
|
+
'1rem': 'space.200',
|
|
64
|
+
'1.25rem': 'space.250',
|
|
65
|
+
'1.5rem': 'space.300',
|
|
66
|
+
'2rem': 'space.400',
|
|
67
|
+
'2.5rem': 'space.500',
|
|
68
|
+
'3rem': 'space.600',
|
|
69
|
+
'4rem': 'space.800',
|
|
70
|
+
'5rem': 'space.1000',
|
|
71
|
+
'-0.125em': 'space.negative.025',
|
|
72
|
+
'-0.25em': 'space.negative.050',
|
|
73
|
+
'-0.375em': 'space.negative.075',
|
|
74
|
+
'-0.5em': 'space.negative.100',
|
|
75
|
+
'-0.75em': 'space.negative.150',
|
|
76
|
+
'-1em': 'space.negative.200',
|
|
77
|
+
'-1.25em': 'space.negative.250',
|
|
78
|
+
'-1.5em': 'space.negative.300',
|
|
79
|
+
'-2em': 'space.negative.400',
|
|
80
|
+
'0.125em': 'space.025',
|
|
81
|
+
'0.25em': 'space.050',
|
|
82
|
+
'0.375em': 'space.075',
|
|
83
|
+
'0.5em': 'space.100',
|
|
84
|
+
'0.75em': 'space.150',
|
|
85
|
+
'1em': 'space.200',
|
|
86
|
+
'1.25em': 'space.250',
|
|
87
|
+
'1.5em': 'space.300',
|
|
88
|
+
'2em': 'space.400',
|
|
89
|
+
'2.5em': 'space.500',
|
|
90
|
+
'3em': 'space.600',
|
|
91
|
+
'4em': 'space.800',
|
|
92
|
+
'5em': 'space.1000'
|
|
93
|
+
};
|
|
94
|
+
export const styleMap = {
|
|
95
|
+
'column-gap': tokenMap,
|
|
96
|
+
columnGap: tokenMap,
|
|
97
|
+
gap: tokenMap,
|
|
98
|
+
'grid-column-gap': tokenMap,
|
|
99
|
+
'grid-row-gap': tokenMap,
|
|
100
|
+
gridColumnGap: tokenMap,
|
|
101
|
+
gridRowGap: tokenMap,
|
|
102
|
+
'margin-block-end': tokenMap,
|
|
103
|
+
'margin-block-start': tokenMap,
|
|
104
|
+
'margin-block': tokenMap,
|
|
105
|
+
'margin-bottom': tokenMap,
|
|
106
|
+
'margin-inline-end': tokenMap,
|
|
107
|
+
'margin-inline-start': tokenMap,
|
|
108
|
+
'margin-inline': tokenMap,
|
|
109
|
+
'margin-left': tokenMap,
|
|
110
|
+
'margin-right': tokenMap,
|
|
111
|
+
'margin-top': tokenMap,
|
|
112
|
+
'outline-offset': tokenMap,
|
|
113
|
+
outlineOffset: tokenMap,
|
|
114
|
+
'padding-block-end': tokenMap,
|
|
115
|
+
'padding-block-start': tokenMap,
|
|
116
|
+
'padding-block': tokenMap,
|
|
117
|
+
'padding-bottom': tokenMap,
|
|
118
|
+
'padding-inline-end': tokenMap,
|
|
119
|
+
'padding-inline-start': tokenMap,
|
|
120
|
+
'padding-inline': tokenMap,
|
|
121
|
+
'padding-left': tokenMap,
|
|
122
|
+
'padding-right': tokenMap,
|
|
123
|
+
'padding-top': tokenMap,
|
|
124
|
+
'row-gap': tokenMap,
|
|
125
|
+
rowGap: tokenMap,
|
|
126
|
+
margin: tokenMap,
|
|
127
|
+
marginBlock: tokenMap,
|
|
128
|
+
marginBlockEnd: tokenMap,
|
|
129
|
+
marginBlockStart: tokenMap,
|
|
130
|
+
marginBottom: tokenMap,
|
|
131
|
+
marginInline: tokenMap,
|
|
132
|
+
marginInlineEnd: tokenMap,
|
|
133
|
+
marginInlineStart: tokenMap,
|
|
134
|
+
marginLeft: tokenMap,
|
|
135
|
+
marginRight: tokenMap,
|
|
136
|
+
marginTop: tokenMap,
|
|
137
|
+
padding: tokenMap,
|
|
138
|
+
paddingBlock: tokenMap,
|
|
139
|
+
paddingBlockEnd: tokenMap,
|
|
140
|
+
paddingBlockStart: tokenMap,
|
|
141
|
+
paddingBottom: tokenMap,
|
|
142
|
+
paddingInline: tokenMap,
|
|
143
|
+
paddingInlineEnd: tokenMap,
|
|
144
|
+
paddingInlineStart: tokenMap,
|
|
145
|
+
paddingLeft: tokenMap,
|
|
146
|
+
paddingRight: tokenMap,
|
|
147
|
+
paddingTop: tokenMap
|
|
148
|
+
// bottom: tokenMap,
|
|
149
|
+
// left: tokenMap,
|
|
150
|
+
// right: tokenMap,
|
|
151
|
+
// top: tokenMap,
|
|
152
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
values: {
|
|
3
|
+
ignore: ['auto', 'initial', 'inherit', 'unset', 'revert', 'revert-layer', 'none',
|
|
4
|
+
// outline-offset can be set to none
|
|
5
|
+
// Currently the DST opinion is that 0 is valid. It doesn't need to be converted to `space.0`
|
|
6
|
+
0, '0', '0px', '0em', '0rem']
|
|
7
|
+
}
|
|
8
|
+
};
|
package/dist/es2019/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as ast from '../../../../ast-nodes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Currently this is defined here because it's not very general purpose.
|
|
5
|
+
* If we were to move this to `ast-nodes`, half the implementation would be in `Root`,
|
|
6
|
+
* and the other half would be in `Import`.
|
|
7
|
+
*
|
|
8
|
+
* TODO: Refactor and move to `ast-nodes`
|
|
9
|
+
*
|
|
10
|
+
* Note: It does not handle default imports, namespace imports, or aliased imports.
|
|
11
|
+
*/
|
|
12
|
+
export const upsertImportDeclaration = ({
|
|
13
|
+
module,
|
|
14
|
+
specifiers
|
|
15
|
+
}, context, fixer) => {
|
|
16
|
+
// Find any imports that match the packageName
|
|
17
|
+
const root = context.getSourceCode().ast.body;
|
|
18
|
+
const importDeclarations = ast.Root.findImportsByModule(root, module);
|
|
19
|
+
|
|
20
|
+
// The import doesn't exist yet, we can just insert a whole new one
|
|
21
|
+
if (importDeclarations.length === 0) {
|
|
22
|
+
return ast.Root.insertImport(root, {
|
|
23
|
+
module,
|
|
24
|
+
specifiers
|
|
25
|
+
}, fixer);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// The import exists so, modify the existing one
|
|
29
|
+
return ast.Import.insertNamedSpecifiers(importDeclarations[0], specifiers, fixer);
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { isStringOrNumber } from './is-string-or-number';
|
|
@@ -1,5 +1,40 @@
|
|
|
1
|
+
/* eslint-disable @repo/internal/react/require-jsdoc */
|
|
2
|
+
|
|
1
3
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
var ObjectEntry = {
|
|
4
|
+
export var ObjectEntry = {
|
|
5
|
+
getProperty: function getProperty(node) {
|
|
6
|
+
if (isNodeOfType(node.key, 'Identifier')) {
|
|
7
|
+
return {
|
|
8
|
+
type: 'Identifier',
|
|
9
|
+
value: node.key.name
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
if (isNodeOfType(node.key, 'Literal') && node.key.value) {
|
|
13
|
+
return {
|
|
14
|
+
type: 'Literal',
|
|
15
|
+
value: node.key.value.toString()
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
type: undefined,
|
|
20
|
+
value: undefined
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
getValue: function getValue(node) {
|
|
24
|
+
// The value is a number, like `-3`
|
|
25
|
+
if (isNodeOfType(node.value, 'UnaryExpression') && isNodeOfType(node.value.argument, 'Literal') && node.value.argument.raw) {
|
|
26
|
+
if (node.value.operator === '-') {
|
|
27
|
+
return -1 * Number.parseInt(node.value.argument.raw);
|
|
28
|
+
}
|
|
29
|
+
return Number.parseInt(node.value.argument.raw);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The value is a string, like `'4px'`
|
|
33
|
+
if (isNodeOfType(node.value, 'Literal') && node.value.value) {
|
|
34
|
+
return node.value.value;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
},
|
|
3
38
|
deleteEntry: function deleteEntry(node, context, fixer) {
|
|
4
39
|
var _lastToken;
|
|
5
40
|
// context.getSourceCode() is deprecated in favour of context.sourceCode, however this returns undefined for some reason
|
|
@@ -31,5 +66,4 @@ var ObjectEntry = {
|
|
|
31
66
|
return node.key.name;
|
|
32
67
|
}
|
|
33
68
|
}
|
|
34
|
-
};
|
|
35
|
-
export { ObjectEntry };
|
|
69
|
+
};
|
|
@@ -99,6 +99,18 @@ var ASTObjectExpression = {
|
|
|
99
99
|
key: identifier(key),
|
|
100
100
|
value: literal(value)
|
|
101
101
|
}).toString(), ", "));
|
|
102
|
+
},
|
|
103
|
+
recurse: function recurse(node, callback) {
|
|
104
|
+
node.properties.forEach(function (entry) {
|
|
105
|
+
// Call the callback first, in case the user wants to do something with SpreadElements
|
|
106
|
+
callback(entry);
|
|
107
|
+
if (!isNodeOfType(entry, 'Property')) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (isNodeOfType(entry.value, 'ObjectExpression')) {
|
|
111
|
+
ASTObjectExpression.recurse(entry.value, callback);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
102
114
|
}
|
|
103
115
|
};
|
|
104
116
|
export { ASTObjectExpression as Object };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::d95217b658f807294de3c81123068bf1>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -35,6 +35,7 @@ export default {
|
|
|
35
35
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
36
36
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
37
37
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
38
|
+
'@atlaskit/design-system/use-tokens-space': 'error',
|
|
38
39
|
'@atlaskit/design-system/use-tokens-typography': 'warn',
|
|
39
40
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
40
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::d1c25758089a050334359276ede0ca3a>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -32,6 +32,7 @@ import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-car
|
|
|
32
32
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
33
33
|
import usePrimitives from './use-primitives';
|
|
34
34
|
import usePrimitivesText from './use-primitives-text';
|
|
35
|
+
import useTokensSpace from './use-tokens-space';
|
|
35
36
|
import useTokensTypography from './use-tokens-typography';
|
|
36
37
|
import useVisuallyHidden from './use-visually-hidden';
|
|
37
38
|
export default {
|
|
@@ -64,6 +65,7 @@ export default {
|
|
|
64
65
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
65
66
|
'use-primitives': usePrimitives,
|
|
66
67
|
'use-primitives-text': usePrimitivesText,
|
|
68
|
+
'use-tokens-space': useTokensSpace,
|
|
67
69
|
'use-tokens-typography': useTokensTypography,
|
|
68
70
|
'use-visually-hidden': useVisuallyHidden
|
|
69
71
|
};
|
|
@@ -84,7 +84,6 @@ var isTokenCall = function isTokenCall(node) {
|
|
|
84
84
|
return false;
|
|
85
85
|
}
|
|
86
86
|
var token = ast.FunctionCall.getArgumentAtPos(node, 0);
|
|
87
|
-
var fallback = ast.FunctionCall.getArgumentAtPos(node, 1);
|
|
88
87
|
if (!token || token.type !== 'Literal') {
|
|
89
88
|
return false;
|
|
90
89
|
}
|
|
@@ -95,7 +94,17 @@ var isTokenCall = function isTokenCall(node) {
|
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
// Not all `token()` calls have a fall back. This is fine, but if there is a fallback, make sure it's the same as the fallback xcss will use
|
|
98
|
-
if (
|
|
97
|
+
if (node.arguments.length === 2) {
|
|
98
|
+
var fallback = ast.FunctionCall.getArgumentAtPos(node, 1);
|
|
99
|
+
|
|
100
|
+
// `getArgumentAtPos` is only able to understand `Literal` and `ObjectExpression` statements
|
|
101
|
+
// If there are 2 args, but `fallback` is undefined, then the fallback is something wild, like `token('space.100, `${gridSize * rem(3)`})`
|
|
102
|
+
if (!fallback) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (fallback.type !== 'Literal') {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
99
108
|
if (spaceTokenMap[fallback.value] !== token.value) {
|
|
100
109
|
return false;
|
|
101
110
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createLintRule } from '../utils/create-rule';
|
|
2
|
+
import { StyleProperty } from './transformers';
|
|
3
|
+
var rule = createLintRule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'use-tokens-space',
|
|
6
|
+
type: 'problem',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
hasSuggestions: true,
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Enforces usage of space design tokens rather than hard-coded values.',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
noRawSpacingValues: 'The use of spacing primitives or tokens is preferred over the direct application of spacing properties.'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
create: function create(context) {
|
|
19
|
+
return {
|
|
20
|
+
'CallExpression[callee.name="css"] ObjectExpression Property': function CallExpressionCalleeNameCssObjectExpressionProperty(node) {
|
|
21
|
+
return StyleProperty.lint(node, {
|
|
22
|
+
context: context
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
'CallExpression[callee.name="keyframes"] ObjectExpression Property': function CallExpressionCalleeNameKeyframesObjectExpressionProperty(node) {
|
|
26
|
+
return StyleProperty.lint(node, {
|
|
27
|
+
context: context
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
'CallExpression[callee.name="cssMap"] ObjectExpression Property': function CallExpressionCalleeNameCssMapObjectExpressionProperty(node) {
|
|
31
|
+
return StyleProperty.lint(node, {
|
|
32
|
+
context: context
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
'CallExpression[callee.object.name=styled] ObjectExpression Property': function CallExpressionCalleeObjectNameStyledObjectExpressionProperty(node) {
|
|
36
|
+
return StyleProperty.lint(node, {
|
|
37
|
+
context: context
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
'CallExpression[callee.object.name=styled2] ObjectExpression Property': function CallExpressionCalleeObjectNameStyled2ObjectExpressionProperty(node) {
|
|
41
|
+
return StyleProperty.lint(node, {
|
|
42
|
+
context: context
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
export default rule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StyleProperty } from './style-property';
|