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

Adds large IconButton size #2253

Merged
merged 3 commits into from
Jun 17, 2024
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
5 changes: 5 additions & 0 deletions .changeset/four-donuts-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-blocks-icon-button": minor
---

IconButton: Add option for `large` value for `size` prop (24x24 icon size with target area of 48x48)
88 changes: 61 additions & 27 deletions __docs__/wonder-blocks-icon-button/icon-button-variants.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export default {

type StoryComponentType = StoryObj<typeof IconButton>;

const sizes: ("xsmall" | "small" | "medium" | "large")[] = [
"xsmall",
"small",
"medium",
"large",
];

const KindVariants = ({
kind,
light,
Expand All @@ -38,7 +45,7 @@ const KindVariants = ({
<>
<View
style={[
styles.gridRow,
styles.gridCol,
light &&
(theme === "khanmigo"
? styles.darkKhanmigo
Expand All @@ -48,17 +55,24 @@ const KindVariants = ({
<LabelMedium style={light && {color: color.white}}>
{kind}-default
</LabelMedium>
<IconButton
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
color="default"
/>
<View style={[styles.iconButtons]}>
{sizes.map((size) => (
Copy link
Member

Choose a reason for hiding this comment

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

praise: Excellent use of the "All variants" snapshot 👏 👏

<IconButton
aria-label="Send"
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
color="default"
size={size}
key={size}
/>
))}
</View>
</View>
<View
style={[
styles.gridRow,
styles.gridCol,
light &&
(theme === "khanmigo"
? styles.darkKhanmigo
Expand All @@ -68,17 +82,24 @@ const KindVariants = ({
<LabelMedium style={light && {color: color.white}}>
{kind}-destructive
</LabelMedium>
<IconButton
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
color="destructive"
/>
<View style={[styles.iconButtons]}>
{sizes.map((size) => (
<IconButton
aria-label="Send"
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
color="destructive"
size={size}
key={size}
/>
))}
</View>
</View>
<View
style={[
styles.gridRow,
styles.gridCol,
light &&
(theme === "khanmigo"
? styles.darkKhanmigo
Expand All @@ -88,13 +109,20 @@ const KindVariants = ({
<LabelMedium style={light && {color: color.white}}>
{kind}-disabled
</LabelMedium>
<IconButton
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
disabled={true}
/>
<View style={[styles.iconButtons]}>
{sizes.map((size) => (
<IconButton
aria-label="Send"
icon={paperPlaneIcon}
onClick={action("clicked")}
kind={kind}
light={light}
disabled={true}
size={size}
key={size}
/>
))}
</View>
</View>
</>
)}
Expand Down Expand Up @@ -160,11 +188,17 @@ const styles = StyleSheet.create({
gridTemplateColumns: "repeat(3, 250px)",
gap: spacing.large_24,
},
gridRow: {
flexDirection: "row",
gridCol: {
flexDirection: "column",
alignItems: "center",
gap: spacing.medium_16,
gap: spacing.large_24,
justifyContent: "space-between",
padding: spacing.medium_16,
},
iconButtons: {
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: spacing.xLarge_32,
},
});
17 changes: 15 additions & 2 deletions __docs__/wonder-blocks-icon-button/icon-button.argtypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,27 @@ export default {
type: "select",
},
description: "The size of the icon button.",
options: ["xsmall", "small", "medium"],
options: ["xsmall", "small", "medium", "large"],
table: {
type: {
summary: `"xsmall" | "small" | "medium"`,
summary: `"xsmall" | "small" | "medium" | "large"`,
},
defaultValue: {
summary: `"medium"`,
},
},
},
"aria-label": {
description:
"The description of this component for the screenreader to read.",
control: {
type: "text",
},
table: {
category: "Accessibility",
type: {
summary: "string",
},
},
},
};
14 changes: 13 additions & 1 deletion __docs__/wonder-blocks-icon-button/icon-button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ export default {
},
},
argTypes: IconButtonArgtypes,
args: {
"aria-label": "Search",
},
} as Meta<typeof IconButton>;

type StoryComponentType = StoryObj<typeof IconButton>;
Expand Down Expand Up @@ -115,6 +118,7 @@ export const Default: StoryComponentType = {
* - `xsmall` (16px icon with a 24px touch target).
* - `small` (24px icon with a 32px touch target).
* - `medium` (24px icon with a 40px touch target).
* - `large` (24px icon with a 48px touch target).
*/
export const Sizes: StoryComponentType = {
...Default,
Expand All @@ -139,6 +143,10 @@ export const Sizes: StoryComponentType = {
<LabelMedium style={styles.label}>medium</LabelMedium>
<IconButton {...args} size="medium" />
</View>
<View style={styles.row}>
<LabelMedium style={styles.label}>large</LabelMedium>
<IconButton {...args} size="large" />
</View>
</View>
),
};
Expand Down Expand Up @@ -185,26 +193,30 @@ export const Variants: StoryComponentType = {
*/
export const WithColor: StoryComponentType = {
name: "Color",
render: () => (
render: (args) => (
<View style={styles.row}>
<IconButton
{...args}
icon={minusCircle}
onClick={() => {}}
color="destructive"
/>
<IconButton
{...args}
icon={minusCircle}
onClick={() => {}}
kind="secondary"
color="destructive"
/>
<IconButton
{...args}
icon={minusCircle}
onClick={() => {}}
kind="tertiary"
color="destructive"
/>
<IconButton
{...args}
disabled={true}
icon={minusCircle}
aria-label="search"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {Link} from "react-router-dom";
import IconButtonCore from "./icon-button-core";
import ThemedIconButton from "../themes/themed-icon-button";

export type IconButtonSize = "xsmall" | "small" | "medium";
export type IconButtonSize = "xsmall" | "small" | "medium" | "large";

export type SharedProps = Partial<Omit<AriaProps, "aria-disabled">> & {
/**
Expand Down Expand Up @@ -42,7 +42,8 @@ export type SharedProps = Partial<Omit<AriaProps, "aria-disabled">> & {
testId?: string;
/**
* Size of the icon button.
* One of `xsmall` (16 icon, 20 target), `small` (24, 32), or `medium (24, 40).
* One of `xsmall` (16 icon, 20 target), `small` (24, 32), `medium` (24, 40),
* or `large` (24, 48).
* Defaults to `medium`.
*/
size?: IconButtonSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe("iconSizeForButtonSize", () => {
${"xsmall"} | ${"small"}
${"small"} | ${"medium"}
${"medium"} | ${"medium"}
${"large"} | ${"medium"}
`(
"should return $expectedIconSize icon for $buttonSize icon button",
({buttonSize, expectedIconSize}) => {
Expand All @@ -20,6 +21,7 @@ describe("targetPixelsForSize", () => {
${"xsmall"} | ${24}
${"small"} | ${32}
${"medium"} | ${40}
${"large"} | ${48}
`(
"should return $expectedTargetPixels for $size icon button",
({size, expectedTargetPixels}) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ export const iconSizeForButtonSize = (size: IconButtonSize): IconSize => {
return "medium";
case "medium":
return "medium";
case "large":
return "medium";
}
};

/**
* A function that returns the size of the touch target in pixels for a given icon button size.
*/
export const targetPixelsForSize = (size: IconButtonSize): number =>
({xsmall: 24, small: 32, medium: 40}[size]);
({xsmall: 24, small: 32, medium: 40, large: 48}[size]);
Loading