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

[Button] Create ButtonUnstyled and useButton #27600

Merged
merged 32 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8e9e330
Add ButtonUnstyled
michaldudak Jun 16, 2021
4711e17
useButton
michaldudak Jun 16, 2021
c5f12ea
Move props to a separate file
michaldudak Aug 2, 2021
aad757a
Move logic to useButton
michaldudak Aug 3, 2021
8a11765
Make useButton props consistent with ButtonUnstyled
michaldudak Aug 4, 2021
858eca8
Add API docs and demos
michaldudak Aug 4, 2021
11359b7
Fix the build
michaldudak Aug 4, 2021
acbd594
Format demos
michaldudak Aug 5, 2021
7290dee
Add better support for the active state
michaldudak Aug 5, 2021
4f10ac0
Add useButton tests
michaldudak Aug 6, 2021
ee1ae90
Merge remote-tracking branch 'upstream/next' into feat/unstyled-button
michaldudak Aug 6, 2021
f21564a
Write API docs
michaldudak Aug 6, 2021
6b33819
Add more demos
michaldudak Aug 9, 2021
c2ee127
Merge remote-tracking branch 'upstream/next' into feat/unstyled-button
michaldudak Aug 9, 2021
06d4b3c
Use useButton in ButtonBase
michaldudak Aug 12, 2021
68b06ab
Merge remote-tracking branch 'upstream/next' into feat/unstyled-button
michaldudak Aug 12, 2021
08d8f41
Fix tests
michaldudak Aug 12, 2021
b85648c
Use useTouchRipple in ButtonBase
michaldudak Aug 12, 2021
d3be252
Extract chainEventHandlers to utils
michaldudak Aug 12, 2021
fcee0fb
Merge branch 'next' into feat/unstyled-button
michaldudak Aug 12, 2021
126e515
Fix the build
michaldudak Aug 12, 2021
b0f669d
Make demos prettier
michaldudak Aug 12, 2021
065052a
Refactor and correct useButton and demos
michaldudak Aug 13, 2021
4d1fcc9
Do not call all event handlers automatically
michaldudak Aug 13, 2021
a46d7c1
Merge branch 'next' into feat/unstyled-button
michaldudak Aug 15, 2021
52ec0a6
Add dark mode for adv customisation demo
michaldudak Aug 15, 2021
75c5c0b
Fix regression tests
michaldudak Aug 15, 2021
4586840
Apply CR suggestions
michaldudak Aug 17, 2021
ce874d9
Merge remote-tracking branch 'upstream/next' into feat/unstyled-button
michaldudak Aug 20, 2021
df52895
Do not dispatch a click event
michaldudak Aug 20, 2021
41858c1
Remove mergeEventHandlers utility
michaldudak Aug 20, 2021
66019df
Tweak transition speed in demos
michaldudak Aug 20, 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
23 changes: 23 additions & 0 deletions docs/pages/api-docs/button-unstyled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react';
import ApiPage from 'docs/src/modules/components/ApiPage';
import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
import jsonPageContent from './button-unstyled.json';

export default function Page(props) {
const { descriptions, pageContent } = props;
return <ApiPage descriptions={descriptions} pageContent={pageContent} />;
}

Page.getInitialProps = () => {
const req = require.context(
'docs/translations/api-docs/button-unstyled',
false,
/button-unstyled.*.json$/,
);
const descriptions = mapApiPageTranslations(req);

return {
descriptions,
pageContent: jsonPageContent,
};
};
25 changes: 25 additions & 0 deletions docs/pages/api-docs/button-unstyled.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"props": {
"action": {
"type": {
"name": "union",
"description": "func<br>&#124;&nbsp;{ current?: { focusVisible: func } }"
}
},
"component": { "type": { "name": "elementType" }, "default": "'button'" },
"components": {
"type": { "name": "shape", "description": "{ Root?: elementType }" },
"default": "{}"
},
"disabled": { "type": { "name": "bool" } }
},
"name": "ButtonUnstyled",
"styles": { "classes": [], "globalClasses": {}, "name": null },
"spread": true,
"forwardsRefTo": "HTMLButtonElement",
"filename": "/packages/material-ui-unstyled/src/ButtonUnstyled/ButtonUnstyled.tsx",
"inheritance": null,
"demos": "<ul><li><a href=\"/components/buttons/\">Buttons</a></li></ul>",
"styledComponent": true,
"cssComponent": false
}
90 changes: 90 additions & 0 deletions docs/src/pages/components/buttons/UnstyledButtonCustom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import ButtonUnstyled, {
buttonUnstyledClasses,
} from '@material-ui/unstyled/ButtonUnstyled';
import StarOutlineIcon from '@material-ui/icons/StarOutline';
import { styled } from '@material-ui/system';

const ButtonRoot = React.forwardRef((props, ref) => {
const { children, ...other } = props;

return (
<svg width="200" height="50" {...other} ref={ref}>
<polygon points="0,50 20,0 200,0 180,50" />
<foreignObject x="20" y="0" width="160" height="50">
<div>{children}</div>
</foreignObject>
</svg>
);
});

ButtonRoot.propTypes = {
children: PropTypes.node,
};

const StyledButtonRoot = styled(ButtonRoot)(`
overflow: visible;
cursor: pointer;

& polygon {
stroke: #0059b2;
stroke-width: 2;
stroke-dasharray: 600,600;
stroke-dashoffset: -600;
stroke-linecap: round;
fill: #007fff;
transition: all 700ms ease;
pointer-events: none;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

&:hover polygon {
stroke-dashoffset: 0;
}

&:focus {
outline: none;
}

&.${buttonUnstyledClasses.focusVisible} {
outline: none;
& polygon {
stroke-dashoffset: 0;
}
}

&.${buttonUnstyledClasses.active} polygon {
fill: #004386;
}

& foreignObject {
pointer-events: none;

& > div {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
}

& svg {
margin: 0 5px;
}
}
`);

const SvgButton = React.forwardRef(function SvgButton(props, ref) {
return <ButtonUnstyled {...props} component={StyledButtonRoot} ref={ref} />;
});

export default function UnstyledButtonCustom() {
return (
<SvgButton>
<StarOutlineIcon />
SVG Button
<StarOutlineIcon />
</SvgButton>
);
}
91 changes: 91 additions & 0 deletions docs/src/pages/components/buttons/UnstyledButtonCustom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as React from 'react';
import ButtonUnstyled, {
ButtonUnstyledProps,
buttonUnstyledClasses,
} from '@material-ui/unstyled/ButtonUnstyled';
import StarOutlineIcon from '@material-ui/icons/StarOutline';
import { styled } from '@material-ui/system';

const ButtonRoot = React.forwardRef(
(props: React.PropsWithChildren<{}>, ref: React.ForwardedRef<any>) => {
michaldudak marked this conversation as resolved.
Show resolved Hide resolved
const { children, ...other } = props;

return (
<svg width="200" height="50" {...other} ref={ref}>
<polygon points="0,50 20,0 200,0 180,50" />
<foreignObject x="20" y="0" width="160" height="50">
<div>{children}</div>
</foreignObject>
</svg>
);
},
);

const StyledButtonRoot = styled(ButtonRoot)(`
overflow: visible;
cursor: pointer;

& polygon {
stroke: #0059b2;
stroke-width: 2;
stroke-dasharray: 600,600;
stroke-dashoffset: -600;
stroke-linecap: round;
fill: #007fff;
transition: all 700ms ease;
pointer-events: none;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

&:hover polygon {
stroke-dashoffset: 0;
}

&:focus {
outline: none;
}

&.${buttonUnstyledClasses.focusVisible} {
outline: none;
& polygon {
stroke-dashoffset: 0;
}
}

&.${buttonUnstyledClasses.active} polygon {
fill: #004386;
}

& foreignObject {
pointer-events: none;

& > div {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
}

& svg {
margin: 0 5px;
}
}
`);

const SvgButton = React.forwardRef(function SvgButton(
props: ButtonUnstyledProps,
ref: React.ForwardedRef<any>,
) {
return <ButtonUnstyled {...props} component={StyledButtonRoot} ref={ref} />;
});

export default function UnstyledButtonCustom() {
return (
<SvgButton>
<StarOutlineIcon />
SVG Button
<StarOutlineIcon />
</SvgButton>
);
}
52 changes: 52 additions & 0 deletions docs/src/pages/components/buttons/UnstyledButtonsSimple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as React from 'react';
import Stack from '@material-ui/core/Stack';
import ButtonUnstyled, {
buttonUnstyledClasses,
} from '@material-ui/unstyled/ButtonUnstyled';
import { styled } from '@material-ui/system';

const CustomButtonRoot = styled('button')(`
background-color: #007fff;
padding: 15px 20px;
border-radius: 10px;
color: #fff;
font-weight: 600;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
transition: all 200ms ease;
cursor: pointer;
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 0 rgba(0, 127, 255, 0);
border: none;

&:hover {
background-color: #0059b2;
}

&.${buttonUnstyledClasses.active} {
background-color: #004386;
}

&.${buttonUnstyledClasses.focusVisible} {
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 5px rgba(0, 127, 255, 0.5);
outline: none;
}

&.${buttonUnstyledClasses.disabled} {
opacity: 0.5;
cursor: not-allowed;
box-shadow: 0 0 0 0 rgba(0, 127, 255, 0);
}
`);

function CustomButton(props) {
return <ButtonUnstyled {...props} component={CustomButtonRoot} />;
}

export default function UnstyledButton() {
return (
<Stack spacing={2} direction="row">
<CustomButton>Button</CustomButton>
<CustomButton disabled>Disabled</CustomButton>
</Stack>
);
}
53 changes: 53 additions & 0 deletions docs/src/pages/components/buttons/UnstyledButtonsSimple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as React from 'react';
import Stack from '@material-ui/core/Stack';
import ButtonUnstyled, {
buttonUnstyledClasses,
ButtonUnstyledProps,
} from '@material-ui/unstyled/ButtonUnstyled';
import { styled } from '@material-ui/system';

const CustomButtonRoot = styled('button')(`
background-color: #007fff;
padding: 15px 20px;
border-radius: 10px;
color: #fff;
font-weight: 600;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
transition: all 200ms ease;
cursor: pointer;
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 0 rgba(0, 127, 255, 0);
border: none;

&:hover {
background-color: #0059b2;
}

&.${buttonUnstyledClasses.active} {
background-color: #004386;
}

&.${buttonUnstyledClasses.focusVisible} {
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 5px rgba(0, 127, 255, 0.5);
outline: none;
}

&.${buttonUnstyledClasses.disabled} {
opacity: 0.5;
cursor: not-allowed;
box-shadow: 0 0 0 0 rgba(0, 127, 255, 0);
}
`);

function CustomButton(props: ButtonUnstyledProps) {
return <ButtonUnstyled {...props} component={CustomButtonRoot} />;
}

export default function UnstyledButton() {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export default function UnstyledButton() {
export default function UnstyledButtonsSimple() {

return (
<Stack spacing={2} direction="row">
<CustomButton>Button</CustomButton>
<CustomButton disabled>Disabled</CustomButton>
</Stack>
);
}
52 changes: 52 additions & 0 deletions docs/src/pages/components/buttons/UnstyledButtonsSpan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as React from 'react';
import Stack from '@material-ui/core/Stack';
import ButtonUnstyled, {
buttonUnstyledClasses,
} from '@material-ui/unstyled/ButtonUnstyled';
import { styled } from '@material-ui/system';

const CustomButtonRoot = styled('button')(`
background-color: #007fff;
padding: 15px 20px;
border-radius: 10px;
color: #fff;
font-weight: 600;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
transition: all 200ms ease;
cursor: pointer;
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 0 rgba(0, 127, 255, 0);
border: none;

&:hover {
background-color: #0059b2;
}

&.${buttonUnstyledClasses.active} {
background-color: #004386;
}

&.${buttonUnstyledClasses.focusVisible} {
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1), 0 0 0 5px rgba(0, 127, 255, 0.5);
outline: none;
}

&.${buttonUnstyledClasses.disabled} {
opacity: 0.5;
cursor: not-allowed;
box-shadow: 0 0 0 0 rgba(0, 127, 255, 0);
}
`);

function CustomButton(props) {
return <ButtonUnstyled {...props} component={CustomButtonRoot} />;
}

export default function UnstyledButton() {
return (
<Stack spacing={2} direction="row">
<CustomButton>Button</CustomButton>
<CustomButton disabled>Disabled</CustomButton>
</Stack>
);
}
Loading