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

Setup snapshots for visual regression for components with css #3181

Merged
merged 5 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
447 changes: 447 additions & 0 deletions e2e/components/drafts/Button2.test.ts

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions src/drafts/Button2/Button.dev.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {SearchIcon, TriangleDownIcon, EyeIcon} from '@primer/octicons-react'
import React from 'react'
import {Button, IconButton} from '.'

export default {
title: 'Drafts/Components/Button/DevOnly',
}

export const InvisibleVariants = () => {
const count = 4
return (
<div style={{display: 'flex', flexDirection: 'row', gap: '1rem'}}>
<Button variant="invisible">Button</Button>
<Button variant="invisible" leadingIcon={SearchIcon}>
Button
</Button>
<Button variant="invisible" trailingAction={TriangleDownIcon}>
Button
</Button>
<Button variant="primary">
Button
<Button.Counter>{count}</Button.Counter>
</Button>
<Button variant="invisible" leadingIcon={EyeIcon}>
Button
<Button.Counter>{count}</Button.Counter>
</Button>
<Button variant="invisible" leadingIcon={EyeIcon} trailingAction={TriangleDownIcon}>
Button
<Button.Counter>{count}</Button.Counter>
</Button>
<IconButton icon={TriangleDownIcon} variant="invisible" aria-label="Invisible" />
</div>
)
}

export const TestSxProp = () => {
const count = 4
return (
<div style={{display: 'flex', flexDirection: 'row', gap: '1rem'}}>
<Button
size="medium"
sx={{
color: 'deeppink',
}}
>
Medium Pink
</Button>
<Button
size="small"
sx={{
':hover': {
color: 'deepskyblue',
},
[`@media screen and (max-width: 768px)`]: {
color: 'salmon',
},
'@media screen and (min-width: 768px)': {
':focus': {
color: 'green',
},
},
'@media (min-width: 1440)': {
color: 'deeppink',
},
}}
>
Pink
</Button>
<Button leadingIcon={SearchIcon} variant="invisible" sx={{color: 'deeppink'}}>
Pink
</Button>
<Button
size="small"
variant="invisible"
sx={{
width: 32,
height: 32,
'&:focus': {
outline: 0,
'& > span': {
boxShadow: `inset 0 0 0 2px deeppink`,
},
},
}}
>
Custom size
</Button>
<Button size="small" block variant="invisible" sx={{width: 320}}>
Overriden Block
</Button>
<Button>
Watch
<Button.Counter sx={{fontSize: 32}}>{count}</Button.Counter>
</Button>
</div>
)
}
70 changes: 70 additions & 0 deletions src/drafts/Button2/Button.docs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"id": "button",
"name": "Button",
"status": "alpha",
"a11yReviewed": false,
"stories": [],
"props": [
{
"name": "children",
"required": true,
"type": "React.ReactNode",
"description": "The content of the button."
},
{
"name": "variant",
"type": "| 'default'\n| 'primary'\n| 'danger'\n| 'outline'\n| 'invisible'",
"defaultValue": "'default'",
"description": "Change the visual style of the button."
},
{
"name": "size",
"type": "| 'small'\n| 'medium'\n| 'large'",
"defaultValue": "'medium'"
},
{
"name": "leadingIcon",
"type": "React.ComponentType<OcticonProps>",
"description": "An icon to display before the button text."
},
{
"name": "trailingIcon",
"type": "React.ComponentType<OcticonProps>",
"description": "An icon to display after the button text."
},
{
"name": "as",
"type": "React.ElementType",
"defaultValue": "'button'"
},
{
"name": "sx",
"type": "SystemStyleObject"
},
{
"name": "ref",
"type": "React.RefObject<HTMLButtonElement>"
}
],
"passthrough": {
"element": "button",
"url": "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes"
},
"subcomponents": [
{
"name": "Button.Counter",
"props": [
{
"name": "children",
"required": true,
"type": "number",
"description": "The counter value."
},
{
"name": "sx",
"type": "SystemStyleObject"
}
]
}
]
}
41 changes: 41 additions & 0 deletions src/drafts/Button2/Button.features.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {EyeIcon, TriangleDownIcon, HeartIcon} from '@primer/octicons-react'
import React, {useState} from 'react'
import {Button} from '.'

export default {
title: 'Drafts/Components/Button/Features',
}

export const Primary = () => <Button variant="primary">Primary</Button>

export const Danger = () => <Button variant="danger">Danger</Button>

export const Invisible = () => <Button variant="invisible">Invisible</Button>

export const Outline = () => <Button variant="outline">Outline</Button>

export const LeadingVisual = () => <Button leadingIcon={HeartIcon}>Leading visual</Button>

export const TrailingVisual = () => <Button trailingIcon={EyeIcon}>Trailing visual</Button>

export const TrailingCounter = () => {
const [count, setCount] = useState(0)
return (
<Button onClick={() => setCount(count + 1)}>
Watch
<Button.Counter>{count}</Button.Counter>
</Button>
)
}

export const TrailingAction = () => <Button trailingAction={TriangleDownIcon}>Trailing action</Button>

export const Block = () => <Button block>Default</Button>

export const Disabled = () => <Button disabled>Default</Button>

export const Small = () => <Button size="small">Default</Button>

export const Medium = () => <Button size="medium">Default</Button>

export const Large = () => <Button size="large">Default</Button>
62 changes: 62 additions & 0 deletions src/drafts/Button2/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react'
import {EyeClosedIcon, EyeIcon, SearchIcon, TriangleDownIcon, XIcon, HeartIcon} from '@primer/octicons-react'
import {Story, Meta} from '@storybook/react'
import {Button} from '.'
import {OcticonArgType} from '../../utils/story-helpers'

export default {
title: 'Drafts/Components/Button',
argTypes: {
size: {
control: {
type: 'radio',
},
options: ['small', 'medium', 'large'],
},
disabled: {
control: {
type: 'boolean',
},
},
variant: {
control: {
type: 'radio',
options: ['default', 'primary', 'danger', 'invisible'],
},
},
alignContent: {
control: {
type: 'radio',
options: ['center', 'start'],
},
},
block: {
control: {
type: 'boolean',
},
},
leadingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
trailingIcon: OcticonArgType([EyeClosedIcon, EyeIcon, SearchIcon, XIcon, HeartIcon]),
trailingAction: OcticonArgType([TriangleDownIcon]),
trailingVisualCount: {
control: {
type: 'number',
},
},
},
args: {
block: false,
size: 'medium',
disabled: false,
variant: 'default',
alignContent: 'center',
trailingIcon: null,
leadingIcon: null,
trailingAction: null,
trailingVisualCount: undefined,
},
} as Meta<typeof Button>

export const Playground: Story<typeof Button> = args => <Button {...args}>Default</Button>

export const Default = () => <Button>Default</Button>
90 changes: 90 additions & 0 deletions src/drafts/Button2/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, {forwardRef} from 'react'
import {ButtonProps} from './types'
import {ButtonBase} from './ButtonBase'
import {ForwardRefComponent as PolymorphicForwardRefComponent} from '../../utils/polymorphic'
import {defaultSxProp} from '../../utils/defaultSxProp'
import {BetterSystemStyleObject} from '../../sx'

const ButtonComponent = forwardRef(({children, sx: sxProp = defaultSxProp, ...props}, forwardedRef): JSX.Element => {
let sxStyles = sxProp

// grap the button props that have associated data attributes in the styles
const {block, size, leadingIcon, trailingIcon, trailingAction} = props

if (sxProp !== null && Object.keys(sxProp).length > 0) {
sxStyles = generateCustomSxProp({block, size, leadingIcon, trailingIcon, trailingAction}, sxProp)
}

return (
<ButtonBase ref={forwardedRef} as="button" sx={sxStyles} type="button" {...props}>
{children}
</ButtonBase>
)
}) as PolymorphicForwardRefComponent<'button', ButtonProps>

// This function is used to generate a custom cssSelector for the sxProp

// The usual sx prop can like this:
// sx={{
// [`@media (max-width: 768px)`]: {
// '& > ul': {
// backgroundColor: 'deeppink',
// },
// '&:hover': {
// backgroundColor: 'yellow',
// },
// },
// '&:hover': {
// backgroundColor: 'yellow',
// },
// '&': {
// width : 320px
// }
// }}
//*
/* What we want for Button styles is this:
sx={{
// [`@media (max-width: 768px)`]: {
// '&[data-attribute="something"] > ul': {
// backgroundColor: 'deeppink',
// },
// '&[data-attribute="something"]:hover': {
// backgroundColor: 'yellow',
// },
// },
// '&[data-attribute="something"]:hover': {
// backgroundColor: 'yellow',
// },
// '&[data-attribute="something"]': {
// width : 320px
// }
// }}

// We need to make sure we append the customCSSSelector to the original class selector. i.e & - > &[data-attribute="Icon"][data-size="small"]
*/
export function generateCustomSxProp(
props: Partial<Pick<ButtonProps, 'size' | 'block' | 'leadingIcon' | 'trailingIcon' | 'trailingAction'>>,
providedSx: BetterSystemStyleObject,
) {
// Possible data attributes: data-size, data-block, data-no-visuals
const size = props.size && props.size !== 'medium' ? `[data-size="${props.size}"]` : '' // medium is a default size therefore it doesn't have a data attribute that used for styling
const block = props.block ? `[data-block="block"]` : ''
const noVisuals = props.leadingIcon || props.trailingIcon || props.trailingAction ? '' : '[data-no-visuals="true"]'

// this is custom selector. We need to make sure we add the data attributes to the base css class (& -> &[data-attributename="value"]])
const cssSelector = `&${size}${block}${noVisuals}` // &[data-size="small"][data-block="block"][data-no-visuals="true"]

const customSxProp: {
[key: string]: BetterSystemStyleObject
} = {}

if (!providedSx) return customSxProp
else {
customSxProp[cssSelector] = providedSx
return customSxProp
}
}

ButtonComponent.displayName = 'Button'

export {ButtonComponent}
Loading