Skip to content

Commit

Permalink
Adds large IconButton size (#2253)
Browse files Browse the repository at this point in the history
## Summary:
- IconButton: Add option for `large` value for `size` prop (24x24 icon size with target area of 48x48)

Issue: WB-1694

## Test plan:
- New large size for the IconButton meets specifications
  - `?path=/story/packages-iconbutton--sizes`
  - `?path=/docs/packages-iconbutton-all-variants--docs`
- IconButton stories have 0 warnings in the Storybook a11y addon

Author: beaesguerra

Reviewers: jandrade

Required Reviewers:

Approved By: jandrade

Checks: ✅ codecov/project, ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Lint (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ gerald, ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Lint (ubuntu-latest, 20.x), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ⏭️  Chromatic - Skip on Release PR (changesets), 🚫 Chromatic - Get results on regular PRs, ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Lint (ubuntu-latest, 20.x), ⏭️  Publish npm snapshot, ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ gerald, 🚫 Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ⏭️  Publish npm snapshot, ⏭️  Chromatic - Skip on Release PR (changesets), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ⌛ undefined

Pull Request URL: #2253
  • Loading branch information
beaesguerra authored Jun 17, 2024
1 parent cb95286 commit 16e1635
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 33 deletions.
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) => (
<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]);

0 comments on commit 16e1635

Please sign in to comment.