✨(react) add a nano button, proper icon sizes
Previously we had to hack the button in order to display small clickable icons, like the clear button in the DatePicker. By introducing a new nano button we can natively achieve that. Also make more homegenous font size and icon sizes in existing button sizes.
This commit is contained in:
5
.changeset/heavy-scissors-sing.md
Normal file
5
.changeset/heavy-scissors-sing.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@openfun/cunningham-react": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add Button nano size
|
||||||
@@ -63,6 +63,20 @@ The button can be set to full width. You can use the `fullWidth` prop to do so.
|
|||||||
<Story id="components-button--full-width-with-icon"/>
|
<Story id="components-button--full-width-with-icon"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
|
## Size
|
||||||
|
|
||||||
|
You can adjust the size of the button by using the `size` prop. Default value is `medium`.
|
||||||
|
|
||||||
|
<Canvas sourceState="shown">
|
||||||
|
<Story id="components-button--primary"/>
|
||||||
|
</Canvas>
|
||||||
|
<Canvas sourceState="shown">
|
||||||
|
<Story id="components-button--small"/>
|
||||||
|
</Canvas>
|
||||||
|
<Canvas sourceState="shown">
|
||||||
|
<Story id="components-button--nano"/>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
## Props
|
## Props
|
||||||
|
|
||||||
You can use all the props of the native html `<button>` element props plus the following.
|
You can use all the props of the native html `<button>` element props plus the following.
|
||||||
@@ -109,4 +123,4 @@ many tertiary buttons as needed.
|
|||||||
|
|
||||||
Secondary button to be used when important non-reversible action surrounded by red.
|
Secondary button to be used when important non-reversible action surrounded by red.
|
||||||
|
|
||||||
<img src="components/Button/resources/dd_4.svg"/>
|
<img src="components/Button/resources/dd_4.svg"/>
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
transition: all var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
|
transition: all var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover, &:focus-visible, &:active, &.c__button--active {
|
&:hover, &:focus-visible, &:active, &.c__button--active {
|
||||||
border-radius: var(--c--components--button--border-radius--active);
|
border-radius: var(--c--components--button--border-radius--active);
|
||||||
}
|
}
|
||||||
@@ -45,6 +50,10 @@
|
|||||||
&.c__button--icon-only {
|
&.c__button--icon-only {
|
||||||
width: var(--c--components--button--medium-height);
|
width: var(--c--components--button--medium-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c__button__icon, .c__button__icon * {
|
||||||
|
font-size: var(--c--components--button--medium-icon-font-size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--small {
|
&--small {
|
||||||
@@ -55,6 +64,25 @@
|
|||||||
&.c__button--icon-only {
|
&.c__button--icon-only {
|
||||||
width: var(--c--components--button--small-height);
|
width: var(--c--components--button--small-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c__button__icon, .c__button__icon * {
|
||||||
|
font-size: var(--c--components--button--small-icon-font-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&--nano {
|
||||||
|
height: var(--c--components--button--nano-height);
|
||||||
|
font-size: var(--c--components--button--nano-font-size);
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
|
||||||
|
&.c__button--icon-only {
|
||||||
|
width: var(--c--components--button--nano-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.c__button__icon, .c__button__icon * {
|
||||||
|
font-size: var(--c--components--button--nano-icon-font-size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--icon-only {
|
&--icon-only {
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ export const Small: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Nano: Story = {
|
||||||
|
args: {
|
||||||
|
children: "Primary",
|
||||||
|
color: "primary",
|
||||||
|
size: "nano",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const FullWidth: Story = {
|
export const FullWidth: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: "Primary",
|
children: "Primary",
|
||||||
@@ -67,44 +75,14 @@ export const FullWidthWithIcon: Story = {
|
|||||||
children: "Primary",
|
children: "Primary",
|
||||||
color: "primary",
|
color: "primary",
|
||||||
fullWidth: true,
|
fullWidth: true,
|
||||||
icon: (
|
icon: <span className="material-icons">bolt</span>,
|
||||||
<svg
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IconLeft: Story = {
|
export const IconLeft: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: "Icon",
|
children: "Icon",
|
||||||
icon: (
|
icon: <span className="material-icons">bolt</span>,
|
||||||
<svg
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
color: "primary",
|
color: "primary",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -113,22 +91,7 @@ export const IconRight: Story = {
|
|||||||
args: {
|
args: {
|
||||||
children: "Icon",
|
children: "Icon",
|
||||||
iconPosition: "right",
|
iconPosition: "right",
|
||||||
icon: (
|
icon: <span className="material-icons">bolt</span>,
|
||||||
<svg
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
color: "primary",
|
color: "primary",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -136,22 +99,7 @@ export const IconRight: Story = {
|
|||||||
export const IconOnly: Story = {
|
export const IconOnly: Story = {
|
||||||
args: {
|
args: {
|
||||||
"aria-label": "Button with only an icon",
|
"aria-label": "Button with only an icon",
|
||||||
icon: (
|
icon: <span className="material-icons">bolt</span>,
|
||||||
<svg
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
),
|
|
||||||
color: "primary",
|
color: "primary",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { ButtonHTMLAttributes, forwardRef, ReactNode } from "react";
|
|||||||
|
|
||||||
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
color?: "primary" | "secondary" | "tertiary" | "danger";
|
color?: "primary" | "secondary" | "tertiary" | "danger";
|
||||||
size?: "medium" | "small";
|
size?: "medium" | "small" | "nano";
|
||||||
icon?: ReactNode;
|
icon?: ReactNode;
|
||||||
iconPosition?: "left" | "right";
|
iconPosition?: "left" | "right";
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
@@ -42,11 +42,13 @@ export const Button = forwardRef<HTMLButtonElement, Props>(
|
|||||||
if (fullWidth) {
|
if (fullWidth) {
|
||||||
classes.push("c__button--full-width");
|
classes.push("c__button--full-width");
|
||||||
}
|
}
|
||||||
|
const iconElement = <span className="c__button__icon">{icon}</span>;
|
||||||
|
// const iconElement = icon;
|
||||||
return (
|
return (
|
||||||
<button className={classes.join(" ")} {...props} ref={ref}>
|
<button className={classes.join(" ")} {...props} ref={ref}>
|
||||||
{!!icon && iconPosition === "left" && icon}
|
{!!icon && iconPosition === "left" && iconElement}
|
||||||
{children}
|
{children}
|
||||||
{!!icon && iconPosition === "right" && icon}
|
{!!icon && iconPosition === "right" && iconElement}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,8 +7,13 @@ export const tokens = (defaults: DefaultTokens) => {
|
|||||||
"border-radius--focus": "8px",
|
"border-radius--focus": "8px",
|
||||||
"medium-height": "48px",
|
"medium-height": "48px",
|
||||||
"small-height": "32px",
|
"small-height": "32px",
|
||||||
|
"nano-height": "24px",
|
||||||
"medium-font-size": defaults.theme.font.sizes.l,
|
"medium-font-size": defaults.theme.font.sizes.l,
|
||||||
|
"medium-icon-font-size": "1.5rem",
|
||||||
"small-font-size": defaults.theme.font.sizes.m,
|
"small-font-size": defaults.theme.font.sizes.m,
|
||||||
|
"small-icon-font-size": defaults.theme.font.sizes.l,
|
||||||
|
"nano-font-size": defaults.theme.font.sizes.m,
|
||||||
|
"nano-icon-font-size": defaults.theme.font.sizes.l,
|
||||||
"font-weight": defaults.theme.font.weights.regular,
|
"font-weight": defaults.theme.font.weights.regular,
|
||||||
"font-family": defaults.theme.font.families.base,
|
"font-family": defaults.theme.font.families.base,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,6 +87,15 @@
|
|||||||
--c--theme--font--weights--black: 800;
|
--c--theme--font--weights--black: 800;
|
||||||
--c--theme--font--families--base: "Roboto Flex Variable", sans-serif;
|
--c--theme--font--families--base: "Roboto Flex Variable", sans-serif;
|
||||||
--c--theme--font--families--accent: "Roboto Flex Variable", sans-serif;
|
--c--theme--font--families--accent: "Roboto Flex Variable", sans-serif;
|
||||||
|
--c--theme--font--letterspacings--h1: normal;
|
||||||
|
--c--theme--font--letterspacings--h2: normal;
|
||||||
|
--c--theme--font--letterspacings--h3: normal;
|
||||||
|
--c--theme--font--letterspacings--h4: normal;
|
||||||
|
--c--theme--font--letterspacings--h5: 1px;
|
||||||
|
--c--theme--font--letterspacings--h6: normal;
|
||||||
|
--c--theme--font--letterspacings--l: normal;
|
||||||
|
--c--theme--font--letterspacings--m: normal;
|
||||||
|
--c--theme--font--letterspacings--s: normal;
|
||||||
--c--theme--spacings--xl: 4rem;
|
--c--theme--spacings--xl: 4rem;
|
||||||
--c--theme--spacings--l: 3rem;
|
--c--theme--spacings--l: 3rem;
|
||||||
--c--theme--spacings--b: 1.625rem;
|
--c--theme--spacings--b: 1.625rem;
|
||||||
@@ -200,8 +209,13 @@
|
|||||||
--c--components--button--border-radius--focus: 8px;
|
--c--components--button--border-radius--focus: 8px;
|
||||||
--c--components--button--medium-height: 48px;
|
--c--components--button--medium-height: 48px;
|
||||||
--c--components--button--small-height: 32px;
|
--c--components--button--small-height: 32px;
|
||||||
|
--c--components--button--nano-height: 24px;
|
||||||
--c--components--button--medium-font-size: var(--c--theme--font--sizes--l);
|
--c--components--button--medium-font-size: var(--c--theme--font--sizes--l);
|
||||||
|
--c--components--button--medium-icon-font-size: 1.5rem;
|
||||||
--c--components--button--small-font-size: var(--c--theme--font--sizes--m);
|
--c--components--button--small-font-size: var(--c--theme--font--sizes--m);
|
||||||
|
--c--components--button--small-icon-font-size: var(--c--theme--font--sizes--l);
|
||||||
|
--c--components--button--nano-font-size: var(--c--theme--font--sizes--m);
|
||||||
|
--c--components--button--nano-icon-font-size: var(--c--theme--font--sizes--l);
|
||||||
--c--components--button--font-weight: var(--c--theme--font--weights--regular);
|
--c--components--button--font-weight: var(--c--theme--font--weights--regular);
|
||||||
--c--components--button--font-family: var(--c--theme--font--families--base);
|
--c--components--button--font-family: var(--c--theme--font--families--base);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user