Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate utility components #1316

Merged
merged 40 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e97fdc7
add utility props to Box
VanAnderson Jun 22, 2021
4ccefb0
update box docs
VanAnderson Jun 22, 2021
26d08f6
export box props
VanAnderson Jun 22, 2021
29e6d9f
update snapshots
VanAnderson Jun 22, 2021
64adf68
Create green-worms-nail.md
VanAnderson Jun 22, 2021
6556f3f
AvatarStack story in storybook
VanAnderson Jun 22, 2021
ca4884f
Deprecate components with JSDoc
VanAnderson Jun 22, 2021
eddac82
Update documentation
VanAnderson Jun 22, 2021
50aa394
Create metal-swans-allow.md
VanAnderson Jun 22, 2021
3a04406
deprecate utility components
VanAnderson Jun 28, 2021
5d76285
deprecate utility components
VanAnderson Jun 28, 2021
07d6f51
fix linter errors
VanAnderson Jun 28, 2021
4c4e183
fix build errors
VanAnderson Jun 28, 2021
a1d3c9f
fix build errors
VanAnderson Jun 28, 2021
2b93818
progress
VanAnderson Jun 29, 2021
3b3ccd7
code mode for deprecating utility components
VanAnderson Jun 30, 2021
aa3e8ea
Merge remote-tracking branch 'origin/main' into VanAnderson/deprecate…
colebemis Jul 20, 2021
4cf24a2
Update snapshots
colebemis Jul 20, 2021
699250b
BorderBox and additional test cases for codemod
VanAnderson Jul 21, 2021
2c61036
changeset documentation for utility component deprecation
VanAnderson Jul 21, 2021
7d0edf5
update codemod and test coverage
VanAnderson Jul 21, 2021
d696220
deprecate BorderBox
VanAnderson Jul 21, 2021
0b3d5db
better deprecation comments
VanAnderson Jul 21, 2021
96bc59d
correct codemod in changeset docs
VanAnderson Jul 21, 2021
d8ae367
run codemod on stories folder
VanAnderson Jul 21, 2021
9b96c60
complete borderBox deprecation
VanAnderson Jul 21, 2021
fc37baf
remove duplicate identifier
VanAnderson Jul 21, 2021
0b383df
border box is deprecated in docs
VanAnderson Jul 21, 2021
b1ca888
Update src/Grid.tsx
VanAnderson Jul 21, 2021
651b574
adjust codemod changeset docs
VanAnderson Jul 21, 2021
e192a0a
safe nav operator for codemod find operation
VanAnderson Jul 21, 2021
de80479
Update src/Position.tsx
VanAnderson Jul 22, 2021
90e5885
Update .changeset/metal-swans-allow.md
VanAnderson Jul 22, 2021
87def33
Update src/Popover.tsx
VanAnderson Jul 22, 2021
9d5e8b4
Update .changeset/metal-swans-allow.md
colebemis Jul 22, 2021
47f3a2e
Update snapshot
colebemis Jul 22, 2021
997286f
Edit changeset
colebemis Jul 22, 2021
a1408d1
Merge branch 'main' into VanAnderson/deprecate-utility-components
colebemis Jul 22, 2021
4b67a09
Update deprecated docs
colebemis Jul 22, 2021
1965269
Merge branch 'VanAnderson/deprecate-utility-components' of github.com…
colebemis Jul 22, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/green-worms-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": patch
---

Box may accept all system props.
5 changes: 5 additions & 0 deletions .changeset/metal-swans-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": minor
---

Deprecate utility components.
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be helpful for consumers if we listed all the deprecated components explicitly here.

Copy link
Contributor

Choose a reason for hiding this comment

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

In addition to a list of deprecated components, let's also include instructions on how to run the codemod here.

156 changes: 156 additions & 0 deletions codemods/__tests__/deprecateUtilityComponents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import {defineInlineTest} from 'jscodeshift/dist/testUtils'
import deprecateUtilityComponents from '../deprecateUtilityComponents'

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Flex} from '@primer/components'
export default () => (
<Flex>
<div />
</Flex>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box display="flex">
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we test that other props are preserved? Example:

- <Flex flexDirection="column">
+ <Box display="flex" flexDirection="column">

<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Grid} from '@primer/components'
export default () => (
<Grid>
<div />
</Grid>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box display="grid">
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Position} from '@primer/components'
export default () => (
<Position>
<div />
</Position>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box>
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Absolute} from '@primer/components'
export default () => (
<Absolute>
<div />
</Absolute>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box position="absolute">
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Relative} from '@primer/components'
export default () => (
<Relative>
<div />
</Relative>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box position="relative">
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Fixed} from '@primer/components'
export default () => (
<Fixed>
<div />
</Fixed>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box position="fixed">
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)

defineInlineTest(
deprecateUtilityComponents,
{},
`
import {Sticky} from '@primer/components'
export default () => (
<Sticky>
<div />
</Sticky>
)
`.trim(),
`
import {Box} from '@primer/components'
export default () => (
<Box position="sticky">
<div />
</Box>
)
`.trim(),
'deprecateUtilityComponents'
)
98 changes: 98 additions & 0 deletions codemods/deprecateUtilityComponents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const prettify = require('./lib/prettify')

module.exports = (file, api) => {
const j = api.jscodeshift
const ast = j(file.source)

deprecateComponents(ast, j, '@primer/components', {
Flex: {
identifier: 'Box',
attributes: {
display: 'flex'
}
},
Grid: {
identifier: 'Box',
attributes: {
display: 'grid'
}
},
Position: {
identifier: 'Box',
attributes: {}
},
Absolute: {
identifier: 'Box',
attributes: {
position: 'absolute'
}
},
Relative: {
identifier: 'Box',
attributes: {
position: 'relative'
}
},
Fixed: {
identifier: 'Box',
attributes: {
position: 'fixed'
}
},
Sticky: {
identifier: 'Box',
attributes: {
position: 'sticky'
}
}
})

return prettify(ast, file)
}

function deprecateComponents(ast, j, importSource, importMap) {
const imports = ast.find(j.ImportDeclaration, {source: {value: importSource}})
const importsByName = {}

imports.forEach(decl => {
j(decl)
.find(j.ImportSpecifier)
.forEach(spec => {
importsByName[spec.node.imported.name] = spec
})
})

for (const [from, to] of Object.entries(importMap)) {
rewriteImport(from, to.identifier, to.attributes)
}

function rewriteImport(from, to, attributes) {
imports.forEach(decl => {
j(decl)
.find(j.ImportSpecifier, {imported: {name: from}})
.forEach(spec => {
if (importsByName[to]) {
// if the destination import already exists and there are members
// in this identifier, then this one is a dupe
j(spec).remove()
} else {
// otherwise, we can safely rename this one to the new identifier
spec.node.imported.name = to
importsByName[to] = spec
}
})
})

ast.find(j.JSXOpeningElement, {name: {name: from}}).forEach(nodePath => {
for (const [attr, value] of Object.entries(attributes || {})) {
nodePath.value.attributes.push(j.jsxAttribute(j.jsxIdentifier(attr), j.literal(value)))
}
})

// replace all of the rewritten identifiers with member expressions
ast
.find(j.Identifier, {name: from})
.filter(id => id.parent.node.type !== 'ImportSpecifier')
.replaceWith(j.jsxIdentifier(to))
}
}
2 changes: 1 addition & 1 deletion codemods/lib/prettify.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = function prettify(ast, file) {
source,
Object.assign(
{
parser: 'babylon',
parser: 'babel',
filepath: file.path
},
config
Expand Down
12 changes: 4 additions & 8 deletions docs/content/AnchoredOverlay.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,19 @@ The overlay can be opened and navigated using keyboard or mouse.
const closeOverlay = React.useCallback(() => setIsOpen(false), [setIsOpen])
return (
<AnchoredOverlay
renderAnchor={(anchorProps) => (
<DropdownButton {...anchorProps}>
Click me to open
</DropdownButton>
)}
renderAnchor={anchorProps => <DropdownButton {...anchorProps}>Click me to open</DropdownButton>}
open={isOpen}
onOpen={openOverlay}
onClose={closeOverlay}
>
<Flex flexDirection="column" maxWidth="300px" padding={2}>
<Box display="flex" flexDirection="column" maxWidth="300px" padding={2}>
<p>
This menu automatically receives a focus trap and focus zone. Use up/down keys to navigate between buttons
This menu automatically receives a focus trap and focus zone. Use up/down keys to navigate between buttons
</p>
<Button mb={1}>Button 1</Button>
<Button mb={1}>Button 2</Button>
<Button>Button 3</Button>
</Flex>
</Box>
</AnchoredOverlay>
)
}}
Expand Down
80 changes: 61 additions & 19 deletions docs/content/Box.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,75 @@ title: Box

The Box component serves as a wrapper component for most layout related needs. Use Box to set values such as `display`, `width`, `height`, and more. See the LAYOUT section of our [System Props](/system-props) documentation for the full list of available props. In practice, this component is used frequently as a wrapper around other components to achieve Box Model related styling.

## Default example

```jsx live live
<Box>
Box can be used to create both{' '}
<Box as="span" color="text.inverse" bg="bg.successInverse">
inline
</Box>{' '}
and
<Box color="text.inverse" bg="bg.dangerInverse">
block-level elements,
## Examples

### Default

```jsx live
<Box color="text.secondary" bg="bg.tertiary" p={3}>
Hello
</Box>
```

### Border on all sides

```jsx live
<Box borderColor="border.primary" borderWidth={1} borderStyle="solid" p={3}>
Hello
</Box>
```

### Border on one side

```jsx live
<Box borderColor="border.primary" borderBottomWidth={1} borderBottomStyle="solid" pb={3}>
Hello
</Box>
```

### Flexbox

Use `Box` to create [flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) layouts.

```jsx live
<Box display="flex">
<Box p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
1
</Box>
<Box flexGrow={1} p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
2
</Box>
<Box p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
3
</Box>
</Box>
```

### Grid

Use `Box` to create [grid](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids) layouts.

```jsx live
<Box display="grid" gridTemplateColumns="1fr 1fr" gridGap={3}>
<Box p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
1
</Box>
<Box color="text.inverse" bg="bg.warningInverse" width={[1, 1, 1 / 2]}>
elements with fixed or responsive width and height,
<Box p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
2
</Box>
<Box color="text.inverse" bg="bg.infoInverse" p={4} mt={2}>
and more!
<Box p={3} borderColor="border.primary" borderWidth={1} borderStyle="solid">
3
</Box>
</Box>
```

## System props

Box components get the `COMMON`, `LAYOUT`, and `FLEX` categories of system props. Read our [System Props](/system-props) doc page for a full list of available props.
Box components may receive system props of any category. Read our [System Props](/system-props) doc page for a full list of available props.

## Component props

| Prop name | Type | Default | Description |
| :-------- | :----- | :-----: | :---------------------------------- |
| as | String | `div` | sets the HTML tag for the component |
| Prop | Type | Default | Description |
| :--- | :------------------ | :----------------------------------------------------------------------: | :---------- |
| `as` | | [`"div"`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) | |
| `sx` | `SystemStyleObject` | — | |
Loading