Skip to content

Commit

Permalink
feat: codemods for Badge and Well (#6941)
Browse files Browse the repository at this point in the history
* add Well codemod

* add migration docs for well

* add codemod for badge

* update well font

* add story for testing style macro

* add to migration docs
  • Loading branch information
reidbarber committed Aug 27, 2024
1 parent 95c8344 commit 32574f8
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 47 deletions.
26 changes: 26 additions & 0 deletions .storybook-s2/docs/Migrating.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export function Migrating() {
<li className={style({font: 'body', marginY: 8})}>Update <Code>size</Code> to be a pixel value if it currently matches <Code>'avatar-size-*'</Code></li>
</ul>

<H3>Badge</H3>
<ul className="sb-unstyled">
<li className={style({font: 'body', marginY: 8})}>Change <Code>variant="info"</Code> to <Code>variant="informative"</Code></li>
</ul>

<H3>Breadcrumbs</H3>
<ul className="sb-unstyled">
<li className={style({font: 'body', marginY: 8})}>[PENDING] Comment out <Code>showRoot</Code> (it has not been implemented yet)</li>
Expand Down Expand Up @@ -343,6 +348,27 @@ export function Migrating() {
<li className={style({font: 'body', marginY: 8})}>Update <Code>View</Code> to be a <Code>div</Code> and apply styles using the style macro</li>
</ul>

<H3>Well</H3>
<ul className="sb-unstyled">
<li className={style({font: 'body', marginY: 8})}>
Update <Code>Well</Code> to be a <Code>div</Code> and apply styles using the style macro:
<pre className={'sb-unstyled ' + style({padding: 32, marginY: 32, backgroundColor: 'layer-1', borderRadius: 'xl', fontFamily: 'code', fontSize: 'code-sm', lineHeight: 'code'})}>
<div>{`<div className={style({`}</div>
<div>{` display: 'block',`}</div>
<div>{` textAlign: 'start',`}</div>
<div>{` padding: 16,`}</div>
<div>{` minWidth: 160,`}</div>
<div>{` marginTop: 4,`}</div>
<div>{` borderWidth: 1,`}</div>
<div>{` borderRadius: 'sm',`}</div>
<div>{` borderStyle: 'solid',`}</div>
<div>{` borderColor: 'transparent-black-75',`}</div>
<div>{` font: 'body-sm'`}</div>
<div>{`})} />`}</div>
</pre>
</li>
</ul>

<H2>Style props</H2>
<P>React Spectrum v3 supported a limited set of <Link href="https://react-spectrum.adobe.com/react-spectrum/styling.html#style-props">style props</Link> for layout and positioning using Spectrum-defined values. Usage of these should be updated to instead use the <Link href="?path=/docs/style-macro--docs">style macro</Link>.</P>
<P>Example:</P>
Expand Down
52 changes: 52 additions & 0 deletions packages/@react-spectrum/s2/stories/StyleMacro.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

import {Link} from '../src';
import React from 'react';
import {style} from '../style/spectrum-theme' with {type: 'macro'};

export default {
title: 'S2 Style Macro',
parameters: {
docs: {disable: true}
}
};

export function Example() {
return (
<div className={style({backgroundColor: 'orange-500', color: 'black', font: 'body', paddingX: 8, paddingY: 4, borderRadius: 'lg'})}>
Test
</div>
);
}

export function Well() {
return (
<div
className={style({
display: 'block',
textAlign: 'start',
minWidth: 160,
padding: 16,
marginTop: 4,
borderWidth: 1,
borderRadius: 'sm',
backgroundColor: 'layer-1',
borderStyle: 'solid',
borderColor: 'transparent-black-75',
font: 'body-sm'
})}>
S2 style macro equivalent to v3 <Link href="https://react-spectrum.adobe.com/react-spectrum/Well.html" target="_blank">Well</Link>.
</div>
);
}

Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`No change 1`] = `
exports[`Change variant info to informative 1`] = `
"import { Badge } from "@react-spectrum/s2";
let variant = 'info';
let props = {variant: 'info'};
<div>
<Badge variant="positive">Licensed</Badge>
<Badge variant="informative">
Content Info
</Badge>
<Badge variant={"informative"}>
Content Info
</Badge>
<Badge // TODO(S2-upgrade): Prop variant could not be automatically updated because variant could not be followed.
variant={variant}>
Content Info
</Badge>
<Badge // TODO(S2-upgrade): check this spread for style props
{...props}>
Content Info
</Badge>
</div>"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Updates Well to be div with style macro 1`] = `
"import { Well } from "@react-spectrum/s2";
import { style } from "@react-spectrum/s2/style" with { type: "macro" };
<div>
<div
className={style({
display: "block",
textAlign: "start",
minWidth: 160,
padding: 16,
marginTop: 4,
borderWidth: 1,
borderRadius: "sm",
backgroundColor: "layer-1",
borderStyle: "solid",
borderColor: "transparent-black-75",
font: "body-sm"
})}>
Well content
</div>
<div
role="region"
aria-labelledby="wellLabel"
className={style({
display: "block",
textAlign: "start",
minWidth: 160,
padding: 16,
marginTop: 4,
borderWidth: 1,
borderRadius: "sm",
backgroundColor: "layer-1",
borderStyle: "solid",
borderColor: "transparent-black-75",
font: "body-sm"
})}>
<h3 id="wellLabel">Shipping Address</h3>
<p>601 Townsend Street<br /> San Francisco, CA 94103</p>
</div>
</div>"
`;
18 changes: 15 additions & 3 deletions packages/dev/codemods/src/s1-to-s2/__tests__/badge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@ const test = (name: string, input: string) => {
defineSnapshotTest(transform, {}, input, name);
};

test('No change', `
test('Change variant info to informative', `
import {Badge} from '@adobe/react-spectrum';
let variant = 'info';
let props = {variant: 'info'};
<div>
<Badge variant="positive">Licensed</Badge>
<Badge variant="info">
Content Info
</Badge>
<Badge variant={"info"}>
Content Info
</Badge>
<Badge variant={variant}>
Content Info
</Badge>
<Badge {...props}>
Content Info
</Badge>
</div>
`);
21 changes: 21 additions & 0 deletions packages/dev/codemods/src/s1-to-s2/__tests__/well.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-ignore
import {defineSnapshotTest} from 'jscodeshift/dist/testUtils';
import transform from '../src/codemods/codemod';

const test = (name: string, input: string) => {
defineSnapshotTest(transform, {}, input, name);
};

test('Updates Well to be div with style macro', `
import {Well} from '@adobe/react-spectrum';
<div>
<Well>
Well content
</Well>
<Well role="region" aria-labelledby="wellLabel">
<h3 id="wellLabel">Shipping Address</h3>
<p>601 Townsend Street<br /> San Francisco, CA 94103</p>
</Well>
</div>
`);
56 changes: 17 additions & 39 deletions packages/dev/codemods/src/s1-to-s2/src/codemods/changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ export const changes: ChangesJSON = {
}
]
},
Badge: {
changes: [
{
description: "Change variant='info' to variant='informative'",
reason: 'Updated naming convention',
function: {
name: 'updatePropNameAndValue',
args: {
oldProp: 'variant',
oldValue: 'info',
newProp: 'variant',
newValue: 'informative'
}
}
}
]
},
Breadcrumbs: {
changes: [
{
Expand Down Expand Up @@ -426,19 +443,6 @@ export const changes: ChangesJSON = {
}
]
},
Flex: {
changes: [
{
description:
'Update Flex to be a div and apply flex styles using the style macro',
reason: 'Updated API',
function: {
name: 'updateToNewComponent',
args: {newComponent: 'div'}
}
}
]
},
Form: {
changes: [
{
Expand All @@ -461,19 +465,6 @@ export const changes: ChangesJSON = {
}
]
},
Grid: {
changes: [
{
description:
'Update Grid to be a div and apply grid styles using the style macro',
reason: 'Updated API',
function: {
name: 'updateToNewComponent',
args: {newComponent: 'div'}
}
}
]
},
InlineAlert: {
changes: [
{
Expand Down Expand Up @@ -1200,18 +1191,5 @@ export const changes: ChangesJSON = {
}
}
]
},
View: {
changes: [
{
description:
'Update View to be a div and apply styles using the style macro',
reason: 'Updated API',
function: {
name: 'updateToNewComponent',
args: {newComponent: 'div'}
}
}
]
}
};
1 change: 1 addition & 0 deletions packages/dev/codemods/src/s1-to-s2/src/codemods/codemod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let availableComponents = getComponents();
availableComponents.add('View');
availableComponents.add('Flex');
availableComponents.add('Grid');
availableComponents.add('Well');

// Replaced by collection component-specific items
availableComponents.add('Item');
Expand Down
16 changes: 14 additions & 2 deletions packages/dev/codemods/src/s1-to-s2/src/codemods/styleProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ function handleProp(
addComment(path.node, ' TODO(S2-upgrade): check this UNSAFE_style');
break;
case 'UNSAFE_className':
if (element === 'Flex' || element === 'Grid' || element === 'View') {
if (element === 'Flex' || element === 'Grid' || element === 'View' || element === 'Well') {
path.get('name').replaceWith(t.jsxIdentifier('className'));
} else {
addComment(path.node, ' TODO(S2-upgrade): check this UNSAFE_className');
Expand All @@ -511,11 +511,23 @@ export function transformStyleProps(path: NodePath<t.JSXElement>, element: strin
let dynamicValues = new Map<string, t.ObjectProperty['value']>;
let conditions = new Map<string, t.ObjectProperty['value']>;

let isDOMElement = element === 'Flex' || element === 'Grid' || element === 'View';
let isDOMElement = element === 'Flex' || element === 'Grid' || element === 'View' || element === 'Well';
if (element === 'Flex') {
macroValues.set('display', 'flex');
} else if (element === 'Grid') {
macroValues.set('display', 'grid');
} else if (element === 'Well') {
macroValues.set('display', 'block');
macroValues.set('textAlign', 'start');
macroValues.set('minWidth', 160);
macroValues.set('padding', 16);
macroValues.set('marginTop', 4);
macroValues.set('borderWidth', 1);
macroValues.set('borderRadius', 'sm');
macroValues.set('backgroundColor', 'layer-1');
macroValues.set('borderStyle', 'solid');
macroValues.set('borderColor', 'transparent-black-75');
macroValues.set('font', 'body-sm');
}

let attrs = path.get('openingElement').get('attributes');
Expand Down

1 comment on commit 32574f8

@rspbot
Copy link

@rspbot rspbot commented on 32574f8 Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.