@react-spectrum/codemods 0.2.1 → 0.3.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/dist/index.js CHANGED
File without changes
@@ -22,6 +22,39 @@ exports.changes = {
22
22
  }
23
23
  ]
24
24
  },
25
+ ActionGroup: {
26
+ changes: [
27
+ {
28
+ description: 'Comment out overflowMode',
29
+ reason: 'It has not been implemented yet',
30
+ function: {
31
+ name: 'commentOutProp',
32
+ args: { propToComment: 'overflowMode' }
33
+ }
34
+ },
35
+ {
36
+ description: 'Comment out buttonLabelBehavior',
37
+ reason: 'It has not been implemented yet',
38
+ function: {
39
+ name: 'commentOutProp',
40
+ args: { propToComment: 'buttonLabelBehavior' }
41
+ }
42
+ },
43
+ {
44
+ description: 'Comment out summaryIcon',
45
+ reason: 'It has not been implemented yet',
46
+ function: {
47
+ name: 'commentOutProp',
48
+ args: { propToComment: 'summaryIcon' }
49
+ }
50
+ },
51
+ {
52
+ description: 'Replace with ActionButtonGroup or ToggleButtonGroup',
53
+ reason: 'The API has changed',
54
+ function: { name: 'updateActionGroup', args: {} }
55
+ }
56
+ ]
57
+ },
25
58
  ActionMenu: {
26
59
  changes: [
27
60
  {
@@ -334,6 +367,30 @@ exports.changes = {
334
367
  name: 'moveRenderPropsToChild',
335
368
  args: { newChildComponent: 'Dialog' }
336
369
  }
370
+ },
371
+ {
372
+ description: 'Rename isDismissable to isDismissible',
373
+ reason: 'Fixed spelling',
374
+ function: { name: 'updatePropName', args: { oldProp: 'isDismissable', newProp: 'isDismissible' } }
375
+ },
376
+ {
377
+ description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop',
378
+ reason: 'Updated API',
379
+ function: { name: 'updateDialogChild', args: {} }
380
+ }
381
+ ]
382
+ },
383
+ DialogContainer: {
384
+ changes: [
385
+ {
386
+ description: 'Rename isDismissable to isDismissible',
387
+ reason: 'Fixed spelling',
388
+ function: { name: 'updatePropName', args: { oldProp: 'isDismissable', newProp: 'isDismissible' } }
389
+ },
390
+ {
391
+ description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop',
392
+ reason: 'Updated API',
393
+ function: { name: 'updateDialogChild', args: {} }
337
394
  }
338
395
  ]
339
396
  },
@@ -49,6 +49,8 @@ availableComponents.add('Item');
49
49
  availableComponents.add('Section');
50
50
  // Don't update v3 Provider
51
51
  availableComponents.delete('Provider');
52
+ // Replaced by ActionButtonGroup and ToggleButtonGroup
53
+ availableComponents.add('ActionGroup');
52
54
  function transformer(file, api, options) {
53
55
  let j = api.jscodeshift.withParser({
54
56
  parse(source) {
@@ -227,7 +229,7 @@ function transformer(file, api, options) {
227
229
  if (importedComponents.size) {
228
230
  // Add imports to existing @react-spectrum/s2 import if it exists, otherwise add a new one.
229
231
  let importSpecifiers = new Set([...importedComponents]
230
- .filter(([c]) => c !== 'Flex' && c !== 'Grid' && c !== 'View' && c !== 'Item' && c !== 'Section')
232
+ .filter(([c]) => c !== 'Flex' && c !== 'Grid' && c !== 'View' && c !== 'Item' && c !== 'Section' && c !== 'ActionGroup')
231
233
  .map(([, specifier]) => specifier));
232
234
  let existingImport = root.find(j.ImportDeclaration, {
233
235
  source: { value: '@react-spectrum/s2' }
@@ -140,7 +140,7 @@ const UNIT_RE = /(%|px|em|rem|vw|vh|auto|cm|mm|in|pt|pc|ex|ch|rem|vmin|vmax|fr)$
140
140
  const FUNC_RE = /^\s*\w+\(/;
141
141
  // const SPECTRUM_VARIABLE_RE = /(static-)?size-\d+|single-line-(height|width)/g;
142
142
  const SIZING_RE = /auto|100vh|min-content|max-content|fit-content/;
143
- function convertDimension(value, toPixels = false) {
143
+ function convertDimension(value, type) {
144
144
  let pixelValue;
145
145
  if (typeof value === 'number') {
146
146
  pixelValue = value;
@@ -170,10 +170,10 @@ function convertDimension(value, toPixels = false) {
170
170
  if (pixelValue == null) {
171
171
  throw new Error('invalid dimension: ' + value);
172
172
  }
173
- if (toPixels) {
173
+ if (type === 'px') {
174
174
  return `${pixelValue}px`;
175
175
  }
176
- if (spacingValues.includes(pixelValue)) {
176
+ if (type === 'size' || spacingValues.includes(pixelValue)) {
177
177
  return pixelValue;
178
178
  }
179
179
  // TODO: Convert to rems? Find nearest value?
@@ -184,16 +184,16 @@ function convertGridTrack(value, toPixels = false) {
184
184
  return value;
185
185
  }
186
186
  else {
187
- return convertDimension(value, toPixels);
187
+ return convertDimension(value, toPixels ? 'px' : 'space');
188
188
  }
189
189
  }
190
- function convertUnsafeDimension(value) {
190
+ function convertUnsafeDimension(value, type) {
191
191
  if (typeof value === 'number') {
192
- return convertDimension(value);
192
+ return convertDimension(value, type);
193
193
  }
194
194
  let m = value.match(/^var\(--spectrum-global-dimension-(static-)?size-(.*)\)$/);
195
195
  if (m) {
196
- return convertDimension(`${m[1] || ''}size-${m[2]}`);
196
+ return convertDimension(`${m[1] || ''}size-${m[2]}`, type);
197
197
  }
198
198
  return null;
199
199
  }
@@ -63,7 +63,21 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
63
63
  case 'maxWidth':
64
64
  case 'height':
65
65
  case 'minHeight':
66
- case 'maxHeight':
66
+ case 'maxHeight': {
67
+ if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
68
+ let val = (0, dimensions_1.convertDimension)(value.value, 'size');
69
+ if (val != null) {
70
+ return {
71
+ macroValues: [{ key: mappedProp, value: val }]
72
+ };
73
+ }
74
+ }
75
+ else if (value.type === 'ObjectExpression') {
76
+ return getResponsiveValue(prop, value, element, colorVersion);
77
+ }
78
+ // return [mappedProp, customProp, [[customProp, value]]];
79
+ return null;
80
+ }
67
81
  case 'margin':
68
82
  case 'marginStart':
69
83
  case 'marginEnd':
@@ -79,7 +93,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
79
93
  case 'end':
80
94
  case 'flexBasis': {
81
95
  if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
82
- let val = (0, dimensions_1.convertDimension)(value.value);
96
+ let val = (0, dimensions_1.convertDimension)(value.value, 'space');
83
97
  if (val != null) {
84
98
  return {
85
99
  macroValues: [{ key: mappedProp, value: val }]
@@ -182,7 +196,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
182
196
  case 'rowGap':
183
197
  if (element === 'Flex' || element === 'Grid') {
184
198
  if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
185
- let val = (0, dimensions_1.convertDimension)(value.value);
199
+ let val = (0, dimensions_1.convertDimension)(value.value, 'space');
186
200
  if (val != null) {
187
201
  return {
188
202
  macroValues: [{ key: mappedProp, value: val }]
@@ -308,7 +322,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
308
322
  case 'paddingBottom':
309
323
  if (element === 'View') {
310
324
  if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
311
- let val = (0, dimensions_1.convertDimension)(value.value);
325
+ let val = (0, dimensions_1.convertDimension)(value.value, 'space');
312
326
  if (val != null) {
313
327
  return {
314
328
  macroValues: [{ key: mappedProp, value: val }]
@@ -410,7 +424,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
410
424
  // Try to automatically convert size prop to a macro value for components that supported size.
411
425
  if (element === 'ColorArea' || element === 'ColorWheel') {
412
426
  if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
413
- let val = (0, dimensions_1.convertDimension)(value.value);
427
+ let val = (0, dimensions_1.convertDimension)(value.value, 'size');
414
428
  if (val != null) {
415
429
  return {
416
430
  macroValues: [{ key: 'size', value: val }]
@@ -285,7 +285,16 @@ function moveRenderPropsToChild(path, options) {
285
285
  t.isArrowFunctionExpression(renderFunction.expression) &&
286
286
  t.isJSXElement(renderFunction.expression.body)) {
287
287
  const dialogElement = renderFunction.expression.body;
288
- const newRenderFunction = t.jsxExpressionContainer(t.arrowFunctionExpression(renderFunction.expression.params, t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), dialogElement.children)));
288
+ const originalParam = renderFunction.expression.params[0];
289
+ if (!t.isIdentifier(originalParam)) {
290
+ (0, utils_1.addComment)(path.node.children[renderFunctionIndex], ' TODO(S2-upgrade): Could not automatically move the render props. You\'ll need to update this manually.');
291
+ return;
292
+ }
293
+ const paramName = originalParam.name;
294
+ const objectPattern = t.objectPattern([
295
+ t.objectProperty(t.identifier(paramName), t.identifier(paramName), false, true)
296
+ ]);
297
+ const newRenderFunction = t.jsxExpressionContainer(t.arrowFunctionExpression([objectPattern], t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), dialogElement.children)));
289
298
  let removedOnDismiss = false;
290
299
  const attributes = dialogElement.openingElement.attributes.filter((attr) => {
291
300
  if (t.isJSXAttribute(attr) && attr.name.name === 'onDismiss') {
@@ -358,7 +367,7 @@ function updateComponentWithinCollection(path, options) {
358
367
  * Example: If they're declaring declaring Items somewhere above the collection.
359
368
  */
360
369
  function commentIfParentCollectionNotDetected(path) {
361
- const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList']);
370
+ const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ActionButtonGroup', 'ToggleButtonGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList']);
362
371
  if (t.isJSXElement(path.node)) {
363
372
  // Find closest parent collection component
364
373
  let closestParentCollection = path.findParent((p) => t.isJSXElement(p.node) &&
@@ -532,7 +541,7 @@ function convertDimensionValueToPx(path, options) {
532
541
  if (attrPath && t.isJSXAttribute(attrPath.node) && attrPath.node.name.name === propToConvertValue) {
533
542
  if (t.isStringLiteral(attrPath.node.value)) {
534
543
  try {
535
- let value = (0, dimensions_1.convertDimension)(attrPath.node.value.value);
544
+ let value = (0, dimensions_1.convertDimension)(attrPath.node.value.value, 'size');
536
545
  if (value && typeof value === 'number') {
537
546
  attrPath.node.value = t.jsxExpressionContainer(t.numericLiteral(value));
538
547
  }
@@ -685,6 +694,158 @@ function updateLegacyLink(path) {
685
694
  }
686
695
  }
687
696
  }
697
+ /**
698
+ * Updates DialogTrigger and DialogContainer to the new API.
699
+ *
700
+ * Example:
701
+ * - When `type="popover"`, replaces Dialog with `<Popover>`.
702
+ * - When `type="fullscreen"`, replaces Dialog with `<FullscreenDialog>`.
703
+ * - When `type="fullscreenTakeover"`, replaces Dialog with `<FullscreenDialog variant="fullscreenTakeover">`.
704
+ */
705
+ function updateDialogChild(path) {
706
+ let typePath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'type');
707
+ let type = typePath?.node.value?.type === 'StringLiteral' ? typePath.node.value?.value : 'modal';
708
+ let newComponent = 'Dialog';
709
+ let props = [];
710
+ if (type === 'popover') {
711
+ newComponent = 'Popover';
712
+ }
713
+ else if (type === 'fullscreen' || type === 'fullscreenTakeover') {
714
+ newComponent = 'FullscreenDialog';
715
+ if (type === 'fullscreenTakeover') {
716
+ props.push(t.jsxAttribute(t.jsxIdentifier('variant'), t.stringLiteral(type)));
717
+ }
718
+ }
719
+ for (let prop of ['isDismissible', 'mobileType', 'hideArrow', 'placement', 'shouldFlip', 'isKeyboardDismissDisabled', 'containerPadding', 'offset', 'crossOffset']) {
720
+ let attr = path.get('openingElement').get('attributes').find(attr => attr.isJSXAttribute() && attr.node.name.name === prop);
721
+ if (attr) {
722
+ props.push(attr.node);
723
+ attr.remove();
724
+ }
725
+ }
726
+ typePath?.remove();
727
+ let localName = newComponent;
728
+ if (newComponent !== 'Dialog' && availableComponents.has(newComponent)) {
729
+ let program = path.findParent((p) => t.isProgram(p.node));
730
+ localName = (0, utils_1.addComponentImport)(program, newComponent);
731
+ }
732
+ path.traverse({
733
+ JSXElement(dialog) {
734
+ if (!t.isJSXIdentifier(dialog.node.openingElement.name) || (0, utils_1.getName)(dialog, dialog.node.openingElement.name) !== 'Dialog') {
735
+ return;
736
+ }
737
+ dialog.node.openingElement.name = t.jsxIdentifier(localName);
738
+ if (dialog.node.closingElement) {
739
+ dialog.node.closingElement.name = t.jsxIdentifier(localName);
740
+ }
741
+ dialog.node.openingElement.attributes.push(...props);
742
+ }
743
+ });
744
+ }
745
+ function updateActionGroup(path) {
746
+ let selectionModePath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'selectionMode');
747
+ let selectionMode = t.isStringLiteral(selectionModePath?.node.value) ? selectionModePath.node.value.value : 'none';
748
+ let newComponent, childComponent;
749
+ if (selectionMode === 'none') {
750
+ newComponent = 'ActionButtonGroup';
751
+ childComponent = 'ActionButton';
752
+ selectionModePath?.remove();
753
+ }
754
+ else {
755
+ newComponent = 'ToggleButtonGroup';
756
+ childComponent = 'ToggleButton';
757
+ }
758
+ let localName = newComponent;
759
+ if (availableComponents.has(newComponent)) {
760
+ let program = path.findParent((p) => t.isProgram(p.node));
761
+ localName = (0, utils_1.addComponentImport)(program, newComponent);
762
+ }
763
+ let localChildName = childComponent;
764
+ if (availableComponents.has(childComponent)) {
765
+ let program = path.findParent((p) => t.isProgram(p.node));
766
+ localChildName = (0, utils_1.addComponentImport)(program, childComponent);
767
+ }
768
+ // Convert dynamic collection to an array.map.
769
+ let items = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'items');
770
+ let itemArg;
771
+ if (items && t.isJSXExpressionContainer(items.node.value) && t.isExpression(items.node.value.expression)) {
772
+ let child = path.get('children').find(c => c.isJSXExpressionContainer());
773
+ if (child && child.isJSXExpressionContainer() && t.isFunction(child.node.expression)) {
774
+ let arg = child.node.expression.params[0];
775
+ if (t.isIdentifier(arg)) {
776
+ itemArg = arg;
777
+ }
778
+ child.replaceWith(t.jsxExpressionContainer(t.callExpression(t.memberExpression(items.node.value.expression, t.identifier('map')), [child.node.expression])));
779
+ }
780
+ }
781
+ items?.remove();
782
+ let onAction = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'onAction');
783
+ // Pull disabledKeys prop out into a variable, converted to a Set.
784
+ // Then we can check it in the isDisabled prop of each item.
785
+ let disabledKeysPath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'disabledKeys');
786
+ let disabledKeys;
787
+ if (disabledKeysPath && t.isJSXExpressionContainer(disabledKeysPath.node.value) && t.isExpression(disabledKeysPath.node.value.expression)) {
788
+ disabledKeys = path.scope.generateUidIdentifier('disabledKeys');
789
+ path.scope.push({
790
+ id: disabledKeys,
791
+ init: t.newExpression(t.identifier('Set'), [disabledKeysPath.node.value.expression]),
792
+ kind: 'let'
793
+ });
794
+ disabledKeysPath.remove();
795
+ }
796
+ path.traverse({
797
+ JSXElement(child) {
798
+ if (t.isJSXIdentifier(child.node.openingElement.name) && child.node.openingElement.name.name === 'Item') {
799
+ // Replace Item with ActionButton or ToggleButton.
800
+ let childNode = t.cloneNode(child.node);
801
+ childNode.openingElement.name = t.jsxIdentifier(localChildName);
802
+ if (childNode.closingElement) {
803
+ childNode.closingElement.name = t.jsxIdentifier(localChildName);
804
+ }
805
+ // If there is no key prop and we are using dynamic collections, add a default computed from item.key ?? item.id.
806
+ let key = childNode.openingElement.attributes.find(attr => t.isJSXAttribute(attr) && attr.name.name === 'key');
807
+ if (!key && itemArg) {
808
+ let id = t.jsxExpressionContainer(t.logicalExpression('??', t.memberExpression(itemArg, t.identifier('key')), t.memberExpression(itemArg, t.identifier('id'))));
809
+ key = t.jsxAttribute(t.jsxIdentifier('key'), id);
810
+ childNode.openingElement.attributes.push(key);
811
+ }
812
+ // If this is a ToggleButtonGroup, add an id prop in addition to key when needed.
813
+ if (key && newComponent === 'ToggleButtonGroup') {
814
+ // If we are in an array.map we need both key and id. Otherwise, we only need id.
815
+ if (itemArg) {
816
+ childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('id'), key.value));
817
+ }
818
+ else {
819
+ key.name.name = 'id';
820
+ }
821
+ }
822
+ let keyValue = undefined;
823
+ if (key && t.isJSXExpressionContainer(key.value) && t.isExpression(key.value.expression)) {
824
+ keyValue = key.value.expression;
825
+ }
826
+ else if (key && t.isStringLiteral(key.value)) {
827
+ keyValue = key.value;
828
+ }
829
+ // Add an onPress to each item that calls the previous onAction, passing in the key.
830
+ if (onAction && t.isJSXExpressionContainer(onAction.node.value) && t.isExpression(onAction.node.value.expression)) {
831
+ childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('onPress'), t.jsxExpressionContainer(keyValue
832
+ ? t.arrowFunctionExpression([], t.callExpression(onAction.node.value.expression, [keyValue]))
833
+ : onAction.node.value.expression)));
834
+ }
835
+ // Add an isDisabled prop to each item, testing whether it is in disabledKeys.
836
+ if (disabledKeys && keyValue) {
837
+ childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('isDisabled'), t.jsxExpressionContainer(t.callExpression(t.memberExpression(disabledKeys, t.identifier('has')), [keyValue]))));
838
+ }
839
+ child.replaceWith(childNode);
840
+ }
841
+ }
842
+ });
843
+ onAction?.remove();
844
+ path.node.openingElement.name = t.jsxIdentifier(localName);
845
+ if (path.node.closingElement) {
846
+ path.node.closingElement.name = t.jsxIdentifier(localName);
847
+ }
848
+ }
688
849
  exports.functionMap = {
689
850
  updatePropNameAndValue,
690
851
  updatePropValueAndAddNewProp,
@@ -704,5 +865,7 @@ exports.functionMap = {
704
865
  updatePlacementToSingleValue,
705
866
  removeComponentIfWithinParent,
706
867
  updateAvatarSize,
707
- updateLegacyLink
868
+ updateLegacyLink,
869
+ updateDialogChild,
870
+ updateActionGroup
708
871
  };
@@ -160,7 +160,12 @@ function handleProperty(element, property, value) {
160
160
  case 'maxWidth':
161
161
  case 'height':
162
162
  case 'minHeight':
163
- case 'maxHeight':
163
+ case 'maxHeight': {
164
+ if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
165
+ return (0, dimensions_1.convertUnsafeDimension)(value.value, 'size');
166
+ }
167
+ break;
168
+ }
164
169
  case 'margin':
165
170
  case 'marginInlineStart':
166
171
  case 'marginInlineEnd':
@@ -178,7 +183,7 @@ function handleProperty(element, property, value) {
178
183
  case 'insetInlineEnd':
179
184
  case 'flexBasis': {
180
185
  if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
181
- return (0, dimensions_1.convertUnsafeDimension)(value.value);
186
+ return (0, dimensions_1.convertUnsafeDimension)(value.value, 'space');
182
187
  }
183
188
  break;
184
189
  }
@@ -196,7 +201,7 @@ function handleProperty(element, property, value) {
196
201
  case 'columnGap': {
197
202
  if (element === 'View' || element === 'Flex' || element === 'Grid') {
198
203
  if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
199
- return (0, dimensions_1.convertUnsafeDimension)(value.value);
204
+ return (0, dimensions_1.convertUnsafeDimension)(value.value, 'space');
200
205
  }
201
206
  }
202
207
  break;
@@ -155,10 +155,6 @@ exports.iconMap = new Map([
155
155
  'Channel',
156
156
  'Channel'
157
157
  ],
158
- [
159
- 'ChatAdd',
160
- 'Channel'
161
- ],
162
158
  [
163
159
  'Checkmark',
164
160
  'CheckmarkSize300'
@@ -711,10 +707,22 @@ exports.iconMap = new Map([
711
707
  'Pause',
712
708
  'Pause'
713
709
  ],
710
+ [
711
+ 'PauseCircle',
712
+ 'PauseCircle'
713
+ ],
714
714
  [
715
715
  'Pending',
716
716
  'ClockPending'
717
717
  ],
718
+ [
719
+ 'PinOff',
720
+ 'PinOff'
721
+ ],
722
+ [
723
+ 'PinOn',
724
+ 'PinOn'
725
+ ],
718
726
  [
719
727
  'Play',
720
728
  'Play'
@@ -991,6 +999,10 @@ exports.iconMap = new Map([
991
999
  'TextBulleted',
992
1000
  'ListBulleted'
993
1001
  ],
1002
+ [
1003
+ 'TextIncrease',
1004
+ 'TextIncrease'
1005
+ ],
994
1006
  [
995
1007
  'TextItalic',
996
1008
  'TextItalic'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-spectrum/codemods",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "main": "dist/index.js",
5
5
  "source": "src/index.ts",
6
6
  "bin": "dist/index.js",
@@ -24,8 +24,8 @@
24
24
  "@babel/parser": "^7.24.5",
25
25
  "@babel/traverse": "^7.24.5",
26
26
  "@babel/types": "^7.24.5",
27
- "@react-spectrum/s2": "^0.4.1",
28
- "@react-types/shared": "^3.25.0",
27
+ "@react-spectrum/s2": "^0.5.0",
28
+ "@react-types/shared": "^3.26.0",
29
29
  "@types/node": "^20",
30
30
  "boxen": "^5.1.2",
31
31
  "build": "^0.1.4",
@@ -48,5 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "8e0a28d188cdbdbd2b32296fa034b1b02ddde229"
51
+ "gitHead": "71f0ef23053f9e03ee7e97df736e8b083e006849"
52
52
  }