@atlaskit/eslint-plugin-design-system 15.0.0 → 15.1.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.
@@ -0,0 +1,548 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ import tokenDefaultValues from '@atlaskit/tokens/token-default-values';
6
+ import { createLintRule } from '../utils/create-lint-rule';
7
+ var DURATION_TOKEN_NAMES = ['motion.duration.instant', 'motion.duration.xxshort', 'motion.duration.xshort', 'motion.duration.short', 'motion.duration.medium', 'motion.duration.long', 'motion.duration.xlong', 'motion.duration.xxlong'];
8
+ function parseDurationMs(value) {
9
+ var ms = value.match(/^(\d+(?:\.\d+)?)ms$/);
10
+ if (ms) {
11
+ return parseFloat(ms[1]);
12
+ }
13
+ var s = value.match(/^(\d+(?:\.\d+)?)s$/);
14
+ if (s) {
15
+ return parseFloat(s[1]) * 1000;
16
+ }
17
+ return null;
18
+ }
19
+ var DURATION_TOKENS = DURATION_TOKEN_NAMES.map(function (name) {
20
+ var rawValue = tokenDefaultValues[name];
21
+ var ms = parseDurationMs(rawValue);
22
+ if (ms === null) {
23
+ throw new Error("use-tokens-motion: could not parse duration for token ".concat(name, ": ").concat(rawValue));
24
+ }
25
+ return {
26
+ ms: ms,
27
+ token: name
28
+ };
29
+ }).sort(function (a, b) {
30
+ return a.ms - b.ms;
31
+ });
32
+ var EASING_TOKEN_NAMES = ['motion.easing.in.practical', 'motion.easing.inout.bold', 'motion.easing.out.practical', 'motion.easing.out.bold'];
33
+ function parseCubicBezierParams(value) {
34
+ var match = value.match(/^cubic-bezier\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/);
35
+ if (!match) {
36
+ return null;
37
+ }
38
+ return [parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])];
39
+ }
40
+ var EASING_TOKENS = EASING_TOKEN_NAMES.map(function (name) {
41
+ var rawValue = tokenDefaultValues[name];
42
+ var params = parseCubicBezierParams(rawValue);
43
+ if (!params) {
44
+ throw new Error("use-tokens-motion: could not parse cubic-bezier for token ".concat(name, ": ").concat(rawValue));
45
+ }
46
+ return {
47
+ value: rawValue,
48
+ token: name,
49
+ params: params
50
+ };
51
+ });
52
+
53
+ // Splits on top-level commas (outside function parens) — preserves cubic-bezier(...) commas.
54
+ function splitOnTopLevelCommas(value) {
55
+ var parts = [];
56
+ var depth = 0;
57
+ var current = '';
58
+ var _iterator = _createForOfIteratorHelper(value),
59
+ _step;
60
+ try {
61
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
62
+ var ch = _step.value;
63
+ if (ch === '(') {
64
+ depth++;
65
+ current += ch;
66
+ } else if (ch === ')') {
67
+ depth--;
68
+ current += ch;
69
+ } else if (ch === ',' && depth === 0) {
70
+ parts.push(current.trim());
71
+ current = '';
72
+ } else {
73
+ current += ch;
74
+ }
75
+ }
76
+ } catch (err) {
77
+ _iterator.e(err);
78
+ } finally {
79
+ _iterator.f();
80
+ }
81
+ if (current.trim().length > 0) {
82
+ parts.push(current.trim());
83
+ }
84
+ return parts;
85
+ }
86
+ var DURATION_PROPERTIES = new Set(['transitionDuration', 'animationDuration']);
87
+ var EASING_PROPERTIES = new Set(['transitionTimingFunction', 'animationTimingFunction']);
88
+
89
+ // Explicit semantic mappings for CSS keyword easings to motion tokens.
90
+ // Pinned by design intent, confirmed with design system team (Alex + Akshay).
91
+ var CSS_KEYWORD_EASING_TOKEN_MAP = {
92
+ ease: 'motion.easing.out.practical',
93
+ 'ease-out': 'motion.easing.out.practical',
94
+ 'ease-in': 'motion.easing.in.practical',
95
+ 'ease-in-out': 'motion.easing.inout.bold'
96
+ // linear (0,0,1,1) — warn only, no autofix (per Akshay: too generic, no good token match)
97
+ };
98
+
99
+ // Non-curve easing values with no meaningful cubic-bezier representation — skip entirely
100
+ var SKIP_EASING_VALUES = new Set(['step-start', 'step-end', 'inherit', 'initial', 'unset', 'none']);
101
+ function euclideanDistance(a, b) {
102
+ return Math.sqrt(a.reduce(function (sum, val, i) {
103
+ return sum + Math.pow(val - b[i], 2);
104
+ }, 0));
105
+ }
106
+
107
+ // Maximum Euclidean distance for easing autofix — beyond this threshold, we report-only
108
+ var EASING_AUTOFIX_THRESHOLD = 0.5;
109
+ function findClosestEasingToken(params) {
110
+ var minDist = Infinity;
111
+ var closest = EASING_TOKENS[0];
112
+ var _iterator2 = _createForOfIteratorHelper(EASING_TOKENS),
113
+ _step2;
114
+ try {
115
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
116
+ var entry = _step2.value;
117
+ var dist = euclideanDistance(params, entry.params);
118
+ if (dist < minDist) {
119
+ minDist = dist;
120
+ closest = entry;
121
+ }
122
+ }
123
+ } catch (err) {
124
+ _iterator2.e(err);
125
+ } finally {
126
+ _iterator2.f();
127
+ }
128
+ if (minDist > EASING_AUTOFIX_THRESHOLD) {
129
+ return null;
130
+ }
131
+ return {
132
+ token: closest.token,
133
+ value: closest.value,
134
+ dist: minDist
135
+ };
136
+ }
137
+ function findClosestDurationTokens(ms) {
138
+ var exact = DURATION_TOKENS.find(function (t) {
139
+ return t.ms === ms;
140
+ });
141
+ if (exact) {
142
+ return [exact];
143
+ }
144
+ var minDist = Infinity;
145
+ var _iterator3 = _createForOfIteratorHelper(DURATION_TOKENS),
146
+ _step3;
147
+ try {
148
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
149
+ var entry = _step3.value;
150
+ var dist = Math.abs(entry.ms - ms);
151
+ if (dist < minDist) {
152
+ minDist = dist;
153
+ }
154
+ }
155
+ } catch (err) {
156
+ _iterator3.e(err);
157
+ } finally {
158
+ _iterator3.f();
159
+ }
160
+ var closest = DURATION_TOKENS.filter(function (t) {
161
+ return Math.abs(t.ms - ms) === minDist;
162
+ });
163
+ return closest;
164
+ }
165
+ var useTokensMotion = createLintRule({
166
+ meta: {
167
+ name: 'use-tokens-motion',
168
+ type: 'suggestion',
169
+ hasSuggestions: true,
170
+ docs: {
171
+ description: 'Enforces usage of motion design tokens rather than hard-coded duration and easing values.',
172
+ recommended: false,
173
+ severity: 'warn'
174
+ },
175
+ messages: {
176
+ useMotionDurationToken: "Use a motion duration token instead of the hard-coded value '{{ value }}'.",
177
+ useMotionDurationTokenSuggest: 'Replace with {{ suggestion }}.',
178
+ useMotionDurationTokenNearest: "No exact token match for '{{ value }}'. Nearest: {{ suggestion1 }} or {{ suggestion2 }}.",
179
+ useMotionDurationTokenSingleNearest: "No exact token match for '{{ value }}'. Nearest: {{ suggestion }}.",
180
+ useMotionEasingToken: "Use a motion easing token instead of the hard-coded value '{{ value }}'.",
181
+ useMotionEasingTokenSuggest: 'Replace with {{ suggestion }}.',
182
+ useMotionEasingTokenUnknown: "Use a motion easing token from @atlaskit/tokens instead of the hard-coded value '{{ value }}'."
183
+ }
184
+ },
185
+ create: function create(context) {
186
+ var tokensImportNode = null;
187
+ var hasTokenSpecifier = false;
188
+ function buildTokenCall(tokenName, fallback) {
189
+ return "token('".concat(tokenName, "', '").concat(fallback, "')");
190
+ }
191
+ function getImportFix(fixer) {
192
+ var _context$sourceCode;
193
+ if (hasTokenSpecifier) {
194
+ return [];
195
+ }
196
+ if (tokensImportNode) {
197
+ // @atlaskit/tokens is imported but without `token` — add `token` to existing import
198
+ var lastSpecifier = tokensImportNode.specifiers[tokensImportNode.specifiers.length - 1];
199
+ if (lastSpecifier) {
200
+ return [fixer.insertTextAfter(lastSpecifier, ', token')];
201
+ }
202
+ // Empty import — replace the whole declaration
203
+ return [fixer.replaceText(tokensImportNode, "import { token } from '@atlaskit/tokens';")];
204
+ }
205
+ var sourceCode = (_context$sourceCode = context.sourceCode) !== null && _context$sourceCode !== void 0 ? _context$sourceCode : context.getSourceCode();
206
+ var programBody = sourceCode.ast.body;
207
+ // Insert after the last existing import, or at top if no imports exist
208
+ var lastImport = _toConsumableArray(programBody).reverse().find(function (n) {
209
+ return n.type === 'ImportDeclaration';
210
+ });
211
+ if (lastImport) {
212
+ return [fixer.insertTextAfter(lastImport, "\nimport { token } from '@atlaskit/tokens';")];
213
+ }
214
+ if (programBody.length > 0) {
215
+ return [fixer.insertTextBefore(programBody[0], "import { token } from '@atlaskit/tokens';\n")];
216
+ }
217
+ return [];
218
+ }
219
+
220
+ // Returns autofix string for a single duration value, or null if ambiguous (equidistant)
221
+ function resolveDurationToken(value) {
222
+ var ms = parseDurationMs(value);
223
+ if (ms === null) {
224
+ return null;
225
+ }
226
+ var exact = DURATION_TOKENS.find(function (t) {
227
+ return t.ms === ms;
228
+ });
229
+ if (exact) {
230
+ return buildTokenCall(exact.token, value);
231
+ }
232
+ return null;
233
+ }
234
+ function handleDurationProperty(node, rawValue) {
235
+ var segments = splitOnTopLevelCommas(rawValue);
236
+ if (segments.length === 1) {
237
+ var ms = parseDurationMs(rawValue);
238
+ if (ms === null) {
239
+ return;
240
+ }
241
+ var exactMatch = DURATION_TOKENS.find(function (t) {
242
+ return t.ms === ms;
243
+ });
244
+ if (exactMatch) {
245
+ var suggestion = buildTokenCall(exactMatch.token, rawValue);
246
+ context.report({
247
+ node: node,
248
+ messageId: 'useMotionDurationToken',
249
+ data: {
250
+ value: rawValue
251
+ },
252
+ suggest: [{
253
+ messageId: 'useMotionDurationTokenSuggest',
254
+ data: {
255
+ suggestion: suggestion
256
+ },
257
+ fix: function fix(fixer) {
258
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, suggestion)]);
259
+ }
260
+ }]
261
+ });
262
+ } else {
263
+ var result = findClosestDurationTokens(ms);
264
+ if (result.length >= 2) {
265
+ var suggestion1 = buildTokenCall(result[0].token, rawValue);
266
+ var suggestion2 = buildTokenCall(result[1].token, rawValue);
267
+ context.report({
268
+ node: node,
269
+ messageId: 'useMotionDurationTokenNearest',
270
+ data: {
271
+ value: rawValue,
272
+ suggestion1: "".concat(suggestion1, " (").concat(result[0].ms, "ms)"),
273
+ suggestion2: "".concat(suggestion2, " (").concat(result[1].ms, "ms)")
274
+ }
275
+ });
276
+ } else {
277
+ var _suggestion = buildTokenCall(result[0].token, rawValue);
278
+ context.report({
279
+ node: node,
280
+ messageId: 'useMotionDurationTokenSingleNearest',
281
+ data: {
282
+ value: rawValue,
283
+ suggestion: "".concat(_suggestion, " (").concat(result[0].ms, "ms)")
284
+ }
285
+ });
286
+ }
287
+ }
288
+ return;
289
+ }
290
+ var resolved = segments.map(resolveDurationToken);
291
+ if (resolved.some(function (s) {
292
+ return s === null;
293
+ })) {
294
+ return;
295
+ }
296
+ var templateLiteral = '`' + resolved.map(function (s) {
297
+ return "${".concat(s, "}");
298
+ }).join(', ') + '`';
299
+ context.report({
300
+ node: node,
301
+ messageId: 'useMotionDurationToken',
302
+ data: {
303
+ value: rawValue
304
+ },
305
+ suggest: [{
306
+ messageId: 'useMotionDurationTokenSuggest',
307
+ data: {
308
+ suggestion: templateLiteral
309
+ },
310
+ fix: function fix(fixer) {
311
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, templateLiteral)]);
312
+ }
313
+ }]
314
+ });
315
+ }
316
+
317
+ // Returns autofix string for a single easing value, or null if no token suggestion is possible
318
+ function resolveEasingToken(value) {
319
+ var trimmed = value.trim();
320
+ if (SKIP_EASING_VALUES.has(trimmed)) {
321
+ return null;
322
+ }
323
+ if (trimmed in CSS_KEYWORD_EASING_TOKEN_MAP) {
324
+ return buildTokenCall(CSS_KEYWORD_EASING_TOKEN_MAP[trimmed], trimmed);
325
+ }
326
+ // linear has no curve (0,0,1,1) — warn only, no autofix
327
+ if (trimmed === 'linear') {
328
+ return null;
329
+ }
330
+ if (trimmed.startsWith('linear(')) {
331
+ // linear() is used for spring animations — motion.easing.spring is experimental, skip
332
+ return null;
333
+ }
334
+ var params = parseCubicBezierParams(trimmed);
335
+ if (!params) {
336
+ return null;
337
+ }
338
+ var exact = EASING_TOKENS.find(function (t) {
339
+ return t.value === trimmed;
340
+ });
341
+ if (exact) {
342
+ return buildTokenCall(exact.token, trimmed);
343
+ }
344
+ var closest = findClosestEasingToken(params);
345
+ return closest ? buildTokenCall(closest.token, trimmed) : null;
346
+ }
347
+ function handleEasingProperty(node, rawValue) {
348
+ var segments = splitOnTopLevelCommas(rawValue);
349
+
350
+ // Multi-value path: resolve each segment, autofix only if all resolve cleanly
351
+ if (segments.length > 1) {
352
+ var resolved = segments.map(resolveEasingToken);
353
+ if (resolved.some(function (s) {
354
+ return s === null;
355
+ })) {
356
+ return;
357
+ }
358
+ var templateLiteral = '`' + resolved.map(function (s) {
359
+ return "${".concat(s, "}");
360
+ }).join(', ') + '`';
361
+ context.report({
362
+ node: node,
363
+ messageId: 'useMotionEasingToken',
364
+ data: {
365
+ value: rawValue
366
+ },
367
+ suggest: [{
368
+ messageId: 'useMotionEasingTokenSuggest',
369
+ data: {
370
+ suggestion: templateLiteral
371
+ },
372
+ fix: function fix(fixer) {
373
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, templateLiteral)]);
374
+ }
375
+ }]
376
+ });
377
+ return;
378
+ }
379
+ var trimmed = rawValue.trim();
380
+ if (SKIP_EASING_VALUES.has(trimmed)) {
381
+ return;
382
+ }
383
+
384
+ // CSS keyword easings: convert to cubic-bezier equivalent and find closest token
385
+ if (trimmed in CSS_KEYWORD_EASING_TOKEN_MAP) {
386
+ var suggestion = buildTokenCall(CSS_KEYWORD_EASING_TOKEN_MAP[trimmed], trimmed);
387
+ context.report({
388
+ node: node,
389
+ messageId: 'useMotionEasingToken',
390
+ data: {
391
+ value: trimmed
392
+ },
393
+ suggest: [{
394
+ messageId: 'useMotionEasingTokenSuggest',
395
+ data: {
396
+ suggestion: suggestion
397
+ },
398
+ fix: function fix(fixer) {
399
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, suggestion)]);
400
+ }
401
+ }]
402
+ });
403
+ return;
404
+ }
405
+ // linear has no curve (0,0,1,1) — warn only, no autofix
406
+ if (trimmed === 'linear') {
407
+ context.report({
408
+ node: node,
409
+ messageId: 'useMotionEasingTokenUnknown',
410
+ data: {
411
+ value: trimmed
412
+ }
413
+ });
414
+ return;
415
+ }
416
+ if (trimmed.startsWith('linear(')) {
417
+ // linear() is used for spring animations — motion.easing.spring is experimental, skip
418
+ return;
419
+ }
420
+ var params = parseCubicBezierParams(trimmed);
421
+ if (!params) {
422
+ context.report({
423
+ node: node,
424
+ messageId: 'useMotionEasingTokenUnknown',
425
+ data: {
426
+ value: rawValue
427
+ }
428
+ });
429
+ return;
430
+ }
431
+ var exact = EASING_TOKENS.find(function (t) {
432
+ return t.value === trimmed;
433
+ });
434
+ if (exact) {
435
+ var _suggestion2 = buildTokenCall(exact.token, rawValue);
436
+ context.report({
437
+ node: node,
438
+ messageId: 'useMotionEasingToken',
439
+ data: {
440
+ value: rawValue
441
+ },
442
+ suggest: [{
443
+ messageId: 'useMotionEasingTokenSuggest',
444
+ data: {
445
+ suggestion: _suggestion2
446
+ },
447
+ fix: function fix(fixer) {
448
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, _suggestion2)]);
449
+ }
450
+ }]
451
+ });
452
+ return;
453
+ }
454
+ var closest = findClosestEasingToken(params);
455
+ if (closest) {
456
+ var _suggestion3 = buildTokenCall(closest.token, rawValue);
457
+ context.report({
458
+ node: node,
459
+ messageId: 'useMotionEasingToken',
460
+ data: {
461
+ value: rawValue
462
+ },
463
+ suggest: [{
464
+ messageId: 'useMotionEasingTokenSuggest',
465
+ data: {
466
+ suggestion: _suggestion3
467
+ },
468
+ fix: function fix(fixer) {
469
+ return [].concat(_toConsumableArray(getImportFix(fixer)), [fixer.replaceText(node.value, _suggestion3)]);
470
+ }
471
+ }]
472
+ });
473
+ } else {
474
+ context.report({
475
+ node: node,
476
+ messageId: 'useMotionEasingTokenUnknown',
477
+ data: {
478
+ value: rawValue
479
+ }
480
+ });
481
+ }
482
+ }
483
+ function handleProperty(node) {
484
+ var key = node.key;
485
+ if (key.type !== 'Identifier') {
486
+ return;
487
+ }
488
+ var isDuration = DURATION_PROPERTIES.has(key.name);
489
+ var isEasing = EASING_PROPERTIES.has(key.name);
490
+ if (!isDuration && !isEasing) {
491
+ return;
492
+ }
493
+ var value = node.value;
494
+ if (value.type === 'TemplateLiteral') {
495
+ // Only handle no-interpolation template literals (e.g. `200ms`) — treat as string
496
+ var tl = value;
497
+ if (tl.expressions.length === 0 && tl.quasis.length === 1) {
498
+ var _tl$quasis$0$value$co;
499
+ var rawValue = (_tl$quasis$0$value$co = tl.quasis[0].value.cooked) !== null && _tl$quasis$0$value$co !== void 0 ? _tl$quasis$0$value$co : tl.quasis[0].value.raw;
500
+ if (isDuration) {
501
+ handleDurationProperty(node, rawValue);
502
+ } else {
503
+ handleEasingProperty(node, rawValue);
504
+ }
505
+ }
506
+ return;
507
+ }
508
+ if (value.type === 'CallExpression') {
509
+ var ce = value;
510
+ if (ce.callee.type === 'Identifier' && ce.callee.name === 'token') {
511
+ return;
512
+ }
513
+ return;
514
+ }
515
+ if (value.type === 'Literal') {
516
+ var lit = value;
517
+ var _rawValue;
518
+ if (typeof lit.value === 'string') {
519
+ _rawValue = lit.value;
520
+ } else if (typeof lit.value === 'number') {
521
+ // Treat bare numbers as ms
522
+ _rawValue = "".concat(lit.value, "ms");
523
+ } else {
524
+ return;
525
+ }
526
+ if (isDuration) {
527
+ handleDurationProperty(node, _rawValue);
528
+ } else {
529
+ handleEasingProperty(node, _rawValue);
530
+ }
531
+ }
532
+ }
533
+ return {
534
+ ImportDeclaration: function ImportDeclaration(node) {
535
+ if (node.source.value === '@atlaskit/tokens') {
536
+ tokensImportNode = node;
537
+ hasTokenSpecifier = node.specifiers.some(function (s) {
538
+ return s.type === 'ImportSpecifier' && s.local.name === 'token';
539
+ });
540
+ }
541
+ },
542
+ Property: function Property(node) {
543
+ handleProperty(node);
544
+ }
545
+ };
546
+ }
547
+ });
548
+ export default useTokensMotion;
@@ -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::4cd2dfd73ed3cdd152ee6481087c49ee>>
3
+ * @codegen <<SignedSource::eb0cc6324a0dfa4a3a11b16ab0a6cd4f>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Linter } from 'eslint';
@@ -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::8efae2c2e169f84381b978b4bc47433d>>
3
+ * @codegen <<SignedSource::80cbd12c57061c4fb2660da2e808210f>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { ESLint } from 'eslint';
@@ -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::b90bcf0b2fb6429faae59c7a454e3260>>
3
+ * @codegen <<SignedSource::d404a0bd62a78d4bad7ee376df0bd475>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Rule } from 'eslint';
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const useTokensMotion: Rule.RuleModule;
3
+ export default useTokensMotion;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
3
  "description": "The essential plugin for use with the Atlassian Design System.",
4
- "version": "15.0.0",
4
+ "version": "15.1.0",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
7
7
  "publishConfig": {