@atlaskit/eslint-plugin-design-system 15.0.0 → 15.1.1

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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 15.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`2b3eee14e8063`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2b3eee14e8063) -
8
+ Update lozenge-badge-tag-labelling-system-migration ESLint rule and codemod for the new Lozenge
9
+ API.
10
+ - Lozenges no longer migrate to `<Tag>`. The `<Lozenge>` component stays as `<Lozenge>`.
11
+ - Legacy `appearance` values are now auto-fixed in-place to new semantic values: `default` →
12
+ `neutral`, `inprogress` → `information`, `moved` → `warning`, `removed` → `danger`, `new` →
13
+ `discovery`. The value `success` is unchanged.
14
+ - `isBold` is intentionally not flagged: while the feature flag
15
+ `platform-dst-lozenge-tag-badge-visual-uplifts` is OFF, users still need `isBold` to render
16
+ subtle Lozenges. It will be cleaned up in a separate pass after rollout.
17
+
18
+ ## 15.1.0
19
+
20
+ ### Minor Changes
21
+
22
+ - [`c6fce4a43355c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c6fce4a43355c) -
23
+ Add new `use-tokens-motion` ESLint rule to enforce the use of motion design tokens for durations
24
+ and easing values. This rule was moved from `@atlaskit/eslint-plugin-platform`
25
+ (`compiled/use-motion-token-values`) to the design-system plugin as a first-class rule.
26
+
3
27
  ## 15.0.0
4
28
 
5
29
  ### Major Changes
package/README.md CHANGED
@@ -123,6 +123,7 @@ module.exports = {
123
123
  | <a href="./src/rules/use-spotlight-package/README.md">use-spotlight-package</a> | Discourage the use of @atlaskit/onboarding in favor of @atlaskit/spotlight. | | Yes | Yes |
124
124
  | <a href="./src/rules/use-tag-group-label/README.md">use-tag-group-label</a> | Ensures tag groups are described to assistive technology by a direct label or by another element. | Yes | | Yes |
125
125
  | <a href="./src/rules/use-textfield-autocomplete/README.md">use-textfield-autocomplete</a> | Enforce that Textfield components with type="email", "tel", or "url" have an appropriate autocomplete value for WCAG 2.2 SC 1.3.5 compliance (Identify Input Purpose). | Yes | Yes | |
126
+ | <a href="./src/rules/use-tokens-motion/README.md">use-tokens-motion</a> | Enforces usage of motion design tokens rather than hard-coded duration and easing values. | | | Yes |
126
127
  | <a href="./src/rules/use-tokens-shape/README.md">use-tokens-shape</a> | Enforces usage of shape design tokens rather than hard-coded values. | | Yes | Yes |
127
128
  | <a href="./src/rules/use-tokens-space/README.md">use-tokens-space</a> | Enforces usage of space design tokens rather than hard-coded values. | | Yes | Yes |
128
129
  | <a href="./src/rules/use-tokens-typography/README.md">use-tokens-typography</a> | Enforces usage of design tokens for typography properties rather than hard-coded values. | Yes | Yes | Yes |
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  /**
8
8
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
9
- * @codegen <<SignedSource::4cd2dfd73ed3cdd152ee6481087c49ee>>
9
+ * @codegen <<SignedSource::eb0cc6324a0dfa4a3a11b16ab0a6cd4f>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -87,6 +87,7 @@ var rules = {
87
87
  '@atlaskit/design-system/use-spotlight-package': 'warn',
88
88
  '@atlaskit/design-system/use-tag-group-label': 'warn',
89
89
  '@atlaskit/design-system/use-textfield-autocomplete': 'warn',
90
+ '@atlaskit/design-system/use-tokens-motion': 'warn',
90
91
  '@atlaskit/design-system/use-tokens-shape': 'error',
91
92
  '@atlaskit/design-system/use-tokens-space': 'error',
92
93
  '@atlaskit/design-system/use-tokens-typography': 'warn',
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  /**
8
8
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
9
- * @codegen <<SignedSource::8efae2c2e169f84381b978b4bc47433d>>
9
+ * @codegen <<SignedSource::80cbd12c57061c4fb2660da2e808210f>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -86,6 +86,7 @@ var rules = {
86
86
  '@atlaskit/design-system/use-spotlight-package': 'warn',
87
87
  '@atlaskit/design-system/use-tag-group-label': 'warn',
88
88
  '@atlaskit/design-system/use-textfield-autocomplete': 'warn',
89
+ '@atlaskit/design-system/use-tokens-motion': 'warn',
89
90
  '@atlaskit/design-system/use-tokens-shape': 'error',
90
91
  '@atlaskit/design-system/use-tokens-space': 'error',
91
92
  '@atlaskit/design-system/use-tokens-typography': 'warn',
@@ -79,13 +79,14 @@ var _useSimpleForm = _interopRequireDefault(require("./use-simple-form"));
79
79
  var _useSpotlightPackage = _interopRequireDefault(require("./use-spotlight-package"));
80
80
  var _useTagGroupLabel = _interopRequireDefault(require("./use-tag-group-label"));
81
81
  var _useTextfieldAutocomplete = _interopRequireDefault(require("./use-textfield-autocomplete"));
82
+ var _useTokensMotion = _interopRequireDefault(require("./use-tokens-motion"));
82
83
  var _useTokensShape = _interopRequireDefault(require("./use-tokens-shape"));
83
84
  var _useTokensSpace = _interopRequireDefault(require("./use-tokens-space"));
84
85
  var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typography"));
85
86
  var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
86
87
  /**
87
88
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
88
- * @codegen <<SignedSource::b90bcf0b2fb6429faae59c7a454e3260>>
89
+ * @codegen <<SignedSource::d404a0bd62a78d4bad7ee376df0bd475>>
89
90
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
90
91
  */
91
92
 
@@ -164,6 +165,7 @@ var rules = exports.rules = {
164
165
  'use-spotlight-package': _useSpotlightPackage.default,
165
166
  'use-tag-group-label': _useTagGroupLabel.default,
166
167
  'use-textfield-autocomplete': _useTextfieldAutocomplete.default,
168
+ 'use-tokens-motion': _useTokensMotion.default,
167
169
  'use-tokens-shape': _useTokensShape.default,
168
170
  'use-tokens-space': _useTokensSpace.default,
169
171
  'use-tokens-typography': _useTokensTypography.default,
@@ -22,9 +22,7 @@ var rule = (0, _createLintRule.createLintRule)({
22
22
  },
23
23
  messages: {
24
24
  updateAppearance: 'Update appearance value to new semantic value.',
25
- migrateTag: 'Non-bold <Lozenge> variants should migrate to <Tag> component. For safe, staged rollout, use the `migration_fallback="lozenge"` prop which renders as Lozenge when the feature flag is off.',
26
- manualReview: "Dynamic 'isBold' props require manual review before migration.",
27
- dynamicLozengeAppearance: "Dynamic 'appearance' prop values require manual review before migrating to Tag. Please verify the appearance value and manually convert it to the appropriate color prop value.",
25
+ migrateTag: '<SimpleTag> and <RemovableTag> components should migrate to the new <Tag> or <AvatarTag> component.',
28
26
  updateBadgeAppearance: 'Update Badge appearance value "{{oldValue}}" to new semantic value "{{newValue}}".',
29
27
  dynamicBadgeAppearance: 'Dynamic appearance prop values require manual review to ensure they use the new semantic values: neutral, information, inverse, danger, success.'
30
28
  }
@@ -70,13 +68,6 @@ var rule = (0, _createLintRule.createLintRule)({
70
68
  */
71
69
  var newTagImports = {};
72
70
 
73
- /**
74
- * Check if a JSX attribute value is a literal false
75
- */
76
- function isLiteralFalse(node) {
77
- return node && node.type === 'JSXExpressionContainer' && node.expression && node.expression.type === 'Literal' && node.expression.value === false;
78
- }
79
-
80
71
  /**
81
72
  * Check if a JSX attribute value is dynamic (not a static literal value)
82
73
  * Can be used for any prop type (boolean, string, etc.)
@@ -113,37 +104,22 @@ var rule = (0, _createLintRule.createLintRule)({
113
104
  }
114
105
 
115
106
  /**
116
- * Map old appearance values to new semantic appearance values
117
- * Both Lozenge and Tag now use the same appearance prop with new semantic values
107
+ * Map old Lozenge appearance values to new semantic appearance values.
108
+ * The new Lozenge no longer uses legacy values it uses semantic color names
109
+ * that align with the new labelling system.
118
110
  */
119
111
  function mapToNewAppearanceValue(oldValue) {
120
112
  var mapping = {
121
- success: 'success',
122
- default: 'default',
123
- removed: 'removed',
124
- inprogress: 'inprogress',
125
- new: 'new',
126
- moved: 'moved'
113
+ default: 'neutral',
114
+ inprogress: 'information',
115
+ moved: 'warning',
116
+ removed: 'danger',
117
+ new: 'discovery',
118
+ success: 'success'
127
119
  };
128
120
  return mapping[oldValue] || oldValue;
129
121
  }
130
122
 
131
- /**
132
- * Map Lozenge appearance values to Tag color values
133
- * Used when migrating Lozenge to Tag component
134
- */
135
- function mapLozengeAppearanceToTagColor(appearanceValue) {
136
- var mapping = {
137
- success: 'lime',
138
- default: 'gray',
139
- removed: 'red',
140
- inprogress: 'blue',
141
- new: 'purple',
142
- moved: 'yellow'
143
- };
144
- return mapping[appearanceValue] || appearanceValue;
145
- }
146
-
147
123
  /**
148
124
  * Map Badge old appearance values to new semantic appearance values
149
125
  */
@@ -269,7 +245,7 @@ var rule = (0, _createLintRule.createLintRule)({
269
245
 
270
246
  /**
271
247
  * Generate the replacement JSX element text for Tag migration
272
- * Handles both regular Tag and avatarTag migrations
248
+ * Handles both regular Tag and AvatarTag migrations for SimpleTag/RemovableTag.
273
249
  */
274
250
  function generateTagReplacement(node) {
275
251
  var _context$sourceCode;
@@ -288,20 +264,7 @@ var rule = (0, _createLintRule.createLintRule)({
288
264
  return;
289
265
  }
290
266
  if (attrName === 'appearance') {
291
- // For Lozenge migrations, convert appearance to color prop
292
- // For SimpleTag/RemovableTag migrations, delete appearance prop
293
- if (options.isLozengeMigration) {
294
- // Map Lozenge appearance value to Tag color value and change prop name from appearance to color
295
- var stringValue = extractStringValue(attr.value);
296
- if (stringValue && typeof stringValue === 'string') {
297
- var mappedColor = mapLozengeAppearanceToTagColor(stringValue);
298
- newAttributes.push("color=\"".concat(mappedColor, "\""));
299
- }
300
- // If we can't extract the string value (dynamic expression), skip it
301
- // Dynamic expressions should be caught earlier and require manual review
302
- // This code path shouldn't be reached, but we skip to be safe
303
- }
304
- // For SimpleTag/RemovableTag migrations, skip appearance prop (delete it)
267
+ // Delete appearance prop not used in new Tag/AvatarTag API
305
268
  return;
306
269
  }
307
270
  if (attrName === 'color') {
@@ -310,10 +273,10 @@ var rule = (0, _createLintRule.createLintRule)({
310
273
  if (options.isAvatarTag) {
311
274
  return;
312
275
  }
313
- var _stringValue = extractStringValue(attr.value);
314
- if (_stringValue && typeof _stringValue === 'string') {
315
- var _mappedColor = mapTagColorValue(_stringValue);
316
- newAttributes.push("color=\"".concat(_mappedColor, "\""));
276
+ var stringValue = extractStringValue(attr.value);
277
+ if (stringValue && typeof stringValue === 'string') {
278
+ var mappedColor = mapTagColorValue(stringValue);
279
+ newAttributes.push("color=\"".concat(mappedColor, "\""));
317
280
  } else {
318
281
  // If we can't extract the string value, keep as-is
319
282
  var value = attr.value ? sourceCode.getText(attr.value) : '';
@@ -363,15 +326,10 @@ var rule = (0, _createLintRule.createLintRule)({
363
326
  }
364
327
  });
365
328
 
366
- // Add isRemovable={false} for SimpleTag migrations and Lozenge migrations
367
- if (options.isSimpleTag || options.isLozengeMigration) {
329
+ // Add isRemovable={false} for SimpleTag migrations
330
+ if (options.isSimpleTag) {
368
331
  newAttributes.push('isRemovable={false}');
369
332
  }
370
-
371
- // Add migration_fallback="lozenge" for Lozenge migrations to enable safe staged rollout
372
- if (options.isLozengeMigration) {
373
- newAttributes.push('migration_fallback="lozenge"');
374
- }
375
333
  var attributesText = newAttributes.length > 0 ? " ".concat(newAttributes.join(' ')) : '';
376
334
  var children = node.children.length > 0 ? sourceCode.getText().slice(node.openingElement.range[1], node.closingElement ? node.closingElement.range[0] : node.range[1]) : '';
377
335
  var componentName = options.preserveComponentName ? node.openingElement.name.name : options.isAvatarTag ? 'AvatarTag' : 'Tag';
@@ -642,77 +600,22 @@ var rule = (0, _createLintRule.createLintRule)({
642
600
  }
643
601
  var attributesMap = getAttributesMap(node.openingElement.attributes);
644
602
  var appearanceProp = attributesMap.appearance;
645
- var isBoldProp = attributesMap.isBold;
646
603
 
647
- // Handle appearance prop value migration
604
+ // Handle appearance prop value migration — always update to new semantic values.
605
+ // isBold is intentionally not flagged: users may still need it while the feature flag
606
+ // platform-dst-lozenge-tag-badge-visual-uplifts is OFF (subtle variant still rendered).
648
607
  if (appearanceProp) {
649
- var shouldMigrateToTag = !isBoldProp || isLiteralFalse(isBoldProp.value);
650
- if (!shouldMigrateToTag) {
651
- // Only update appearance values for Lozenge components that stay as Lozenge
652
- var _stringValue2 = extractStringValue(appearanceProp.value);
653
- if (_stringValue2 && typeof _stringValue2 === 'string') {
654
- var _mappedValue = mapToNewAppearanceValue(_stringValue2);
655
- if (_mappedValue !== _stringValue2) {
656
- context.report({
657
- node: appearanceProp,
658
- messageId: 'updateAppearance',
659
- fix: createAppearanceFixer(appearanceProp.value, _mappedValue)
660
- });
661
- }
662
- }
663
- }
664
- }
665
-
666
- // Handle isBold prop and Tag migration
667
- if (isBoldProp) {
668
- if (isLiteralFalse(isBoldProp.value)) {
669
- // isBold={false} should migrate to Tag
670
- // Check if appearance is dynamic - if so, require manual review
671
- if (appearanceProp && isDynamicExpression(appearanceProp.value)) {
608
+ var _stringValue = extractStringValue(appearanceProp.value);
609
+ if (_stringValue && typeof _stringValue === 'string') {
610
+ var _mappedValue = mapToNewAppearanceValue(_stringValue);
611
+ if (_mappedValue !== _stringValue) {
672
612
  context.report({
673
613
  node: appearanceProp,
674
- messageId: 'dynamicLozengeAppearance'
614
+ messageId: 'updateAppearance',
615
+ fix: createAppearanceFixer(appearanceProp.value, _mappedValue)
675
616
  });
676
- return;
677
617
  }
678
- context.report({
679
- node: node,
680
- messageId: 'migrateTag',
681
- fix: function fix(fixer) {
682
- var replacement = generateTagReplacement(node, {
683
- isLozengeMigration: true
684
- });
685
- return fixer.replaceText(node, replacement);
686
- }
687
- });
688
- } else if (isDynamicExpression(isBoldProp.value)) {
689
- // Dynamic isBold requires manual review
690
- context.report({
691
- node: isBoldProp,
692
- messageId: 'manualReview'
693
- });
694
618
  }
695
- // isBold={true} or isBold (implicit true) - no action needed
696
- } else {
697
- // No isBold prop means implicit false, should migrate to Tag
698
- // Check if appearance is dynamic - if so, require manual review
699
- if (appearanceProp && isDynamicExpression(appearanceProp.value)) {
700
- context.report({
701
- node: appearanceProp,
702
- messageId: 'dynamicLozengeAppearance'
703
- });
704
- return;
705
- }
706
- context.report({
707
- node: node,
708
- messageId: 'migrateTag',
709
- fix: function fix(fixer) {
710
- var replacement = generateTagReplacement(node, {
711
- isLozengeMigration: true
712
- });
713
- return fixer.replaceText(node, replacement);
714
- }
715
- });
716
619
  }
717
620
  }
718
621
  };