Skip to content

Commit 4ea2bcc

Browse files
cogwizzlenkrantzkodiakhq[bot]
authored
Pill Variant Large (#3978)
* feat: Updating the FormPillGroup component to have size property. * feat: Adding test for new FormPillGroup changes. * chore: Updating storybook story for the FormPillGroup. * chore: Adding changeset information for size variant change. * feat: Updating FormPillGroup components to allow for the font size to be changed dynamically for the FormPills. * feat: Updating the patch to be a minor change rather than a full version number. * fix: Fixing type mistake with fontSize property. * feat: Updating type docs due to failed check. * fix: Fixing formatting problems. * chore: Updating import order. * Revert "feat: Updating type docs due to failed check." This reverts commit e9fe825. * feat: Updating type docs. * fix: Update .changeset/strange-paws-smell.md to include package. Co-authored-by: Nora Krantz <75342690+nkrantz@users.noreply.github.com> * refactor: Replacing "L" variant with "large" variant in FormPillGroup. * refactor: Updating the FormPillGroup component to use a more simple way of retrieving styles. * feat: Updating the changeset. * chore: Adding a JSDoc comment. * chore: Minor update to syntax. * refactor: Refactoring the FormPillGroup styling and props. * feat: Changing the height of the pill for large size variant. * chore: Formatting. * fix: Adding code back that was removed by mistake. * chore: Adding TSDoc. * chore: TSDoc why have you forsaken me?!?! Fixing typedoc. * fix: Removing property that is not used. * chore: small fontSize fix and forgot to add to docs site until now --------- Co-authored-by: Nora Krantz <75342690+nkrantz@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: “nora <nkrantz@twilio.com>
1 parent fe8825e commit 4ea2bcc

File tree

10 files changed

+144
-31
lines changed

10 files changed

+144
-31
lines changed

.changeset/strange-paws-smell.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@twilio-paste/core": minor
3+
"@twilio-paste/form-pill-group": minor
4+
---
5+
6+
[Form Pill Group] Adding size property to the FormPillGroup component. Sizes include default and "large".

packages/paste-core/components/form-pill-group/src/FormPillButton.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
2-
import type { BoxElementProps } from "@twilio-paste/box";
2+
import type { BoxElementProps, BoxProps } from "@twilio-paste/box";
33
import { ErrorIcon } from "@twilio-paste/icons/esm/ErrorIcon";
44
import { ScreenReaderOnly } from "@twilio-paste/screen-reader-only";
55
import * as React from "react";
66

77
import { hoverPillStyles, pillStyles } from "./FormPill.styles";
8-
import type { PillVariant } from "./types";
8+
import type { FormPillGroupSizeVariant, PillVariant } from "./types";
9+
import { FormPillGroupContext } from "./useFormPillState";
910

1011
interface FormPillStylesProps {
1112
variant?: PillVariant;
@@ -21,6 +22,17 @@ interface FormPillStylesProps {
2122
i18nErrorLabel?: string;
2223
}
2324

25+
const sizeStyles: Record<FormPillGroupSizeVariant, Pick<BoxProps, "fontSize" | "height">> = {
26+
default: {
27+
fontSize: "fontSize20",
28+
height: "sizeIcon40",
29+
},
30+
large: {
31+
fontSize: "fontSize30",
32+
height: "sizeIcon50",
33+
},
34+
};
35+
2436
export const FormPillButton = React.forwardRef<HTMLElement, FormPillStylesProps>(
2537
(
2638
{
@@ -39,6 +51,8 @@ export const FormPillButton = React.forwardRef<HTMLElement, FormPillStylesProps>
3951
const hasHoverStyles = isHoverable && !isDisabled;
4052
return hasHoverStyles ? { ...pillStyles[variant], ...hoverPillStyles[variant] } : pillStyles[variant];
4153
}, [isHoverable, isDisabled, variant]);
54+
const { size } = React.useContext(FormPillGroupContext);
55+
const { height, fontSize } = sizeStyles[size];
4256

4357
return (
4458
<Box
@@ -55,9 +69,9 @@ export const FormPillButton = React.forwardRef<HTMLElement, FormPillStylesProps>
5569
borderRadius="borderRadiusPill"
5670
borderStyle="none"
5771
cursor="default"
58-
height="sizeIcon40"
72+
height={height}
5973
fontFamily="inherit"
60-
fontSize="fontSize20"
74+
fontSize={fontSize}
6175
fontWeight="fontWeightMedium"
6276
outline="none"
6377
paddingLeft="space30"

packages/paste-core/components/form-pill-group/src/FormPillGroup.tsx

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { Box, safelySpreadBoxProps } from "@twilio-paste/box";
2-
import type { BoxElementProps } from "@twilio-paste/box";
2+
import type { BoxElementProps, BoxProps } from "@twilio-paste/box";
33
import { Composite } from "@twilio-paste/reakit-library";
44
import type { CompositeProps } from "@twilio-paste/reakit-library";
55
import { ScreenReaderOnly } from "@twilio-paste/screen-reader-only";
66
import { useUID } from "@twilio-paste/uid-library";
77
import * as React from "react";
88

9+
import type { FormPillGroupSizeVariant } from "./types";
10+
import { FormPillGroupContext } from "./useFormPillState";
11+
912
export interface FormPillGroupProps
1013
extends Omit<CompositeProps, "unstable_virtual" | "unstable_moves" | "unstable_system" | "wrapElement" | "wrap"> {
1114
/**
@@ -39,26 +42,50 @@ export interface FormPillGroupProps
3942
* @memberof FormPillGroupProps
4043
*/
4144
display?: "flex" | "inline-flex";
45+
/**
46+
* Size variant that affects the size and spacing of the pills within the FormPillGroup. 'large' and 'default' are the only supported values.
47+
*
48+
* @default 'default'
49+
* @memberof FormPillGroupProps
50+
*/
51+
size?: FormPillGroupSizeVariant;
4252
}
4353

54+
/**
55+
* Contains the style properties for the FormPillGroup component and the FormPill component.
56+
*/
57+
const SizeStyles: Record<FormPillGroupSizeVariant, Pick<BoxProps, "columnGap" | "rowGap">> = {
58+
default: {
59+
columnGap: "space20",
60+
rowGap: "space20",
61+
},
62+
large: {
63+
columnGap: "space30",
64+
rowGap: "space30",
65+
},
66+
};
67+
4468
const FormPillGroupStyles = React.forwardRef<HTMLUListElement, FormPillGroupProps>(
45-
({ element = "FORM_PILL_GROUP", display = "flex", ...props }, ref) => (
46-
<Box
47-
{...safelySpreadBoxProps(props)}
48-
element={element}
49-
ref={ref}
50-
role="listbox"
51-
lineHeight="lineHeight30"
52-
margin="space0"
53-
padding="space0"
54-
display={display}
55-
flexWrap="wrap"
56-
rowGap="space20"
57-
columnGap="space20"
58-
>
59-
{props.children}
60-
</Box>
61-
),
69+
({ element = "FORM_PILL_GROUP", display = "flex", size = "default", ...props }, ref) => {
70+
return (
71+
<FormPillGroupContext.Provider value={{ size }}>
72+
<Box
73+
{...safelySpreadBoxProps(props)}
74+
element={element}
75+
ref={ref}
76+
role="listbox"
77+
lineHeight="lineHeight30"
78+
margin="space0"
79+
padding="space0"
80+
display={display}
81+
flexWrap="wrap"
82+
{...SizeStyles[size]}
83+
>
84+
{props.children}
85+
</Box>
86+
</FormPillGroupContext.Provider>
87+
);
88+
},
6289
);
6390

6491
FormPillGroupStyles.displayName = "StyledFormPillGroup";
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import type { FormPillInitialState, FormPillStateReturn } from "./useFormPillState";
1+
import type { CompositeStateReturn } from "@twilio-paste/reakit-library";
2+
3+
import type { FormPillInitialState } from "./useFormPillState";
24

35
// for the sake of documenting the types we rename the state hook types to append Props to the name, so we can docuemnt them and not cause a breaking change.
4-
type FormPillStateReturnProps = FormPillStateReturn;
6+
type FormPillStateReturnProps = CompositeStateReturn;
57
type FormPillInitialStateProps = FormPillInitialState;
68

79
export type { FormPillStateReturnProps, FormPillInitialStateProps };
@@ -10,4 +12,4 @@ export type { FormPillProps } from "./FormPill";
1012
export { FormPillGroup } from "./FormPillGroup";
1113
export type { FormPillGroupProps } from "./FormPillGroup";
1214
export { useFormPillState } from "./useFormPillState";
13-
export type { FormPillStateReturn, FormPillInitialState };
15+
export type { CompositeStateReturn as FormPillStateReturn, FormPillInitialState };

packages/paste-core/components/form-pill-group/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ import type { BoxStyleProps } from "@twilio-paste/box";
22

33
export type PillVariant = "error" | "default";
44
export type VariantStyles = Record<PillVariant, BoxStyleProps>;
5+
/** The size variants for the FormPillGroup component. */
6+
export type FormPillGroupSizeVariant = "default" | "large";
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { useCompositeState } from "@twilio-paste/reakit-library";
2-
import type { CompositeInitialState, CompositeStateReturn as FormPillStateReturn } from "@twilio-paste/reakit-library";
2+
import type { CompositeInitialState, CompositeStateReturn } from "@twilio-paste/reakit-library";
3+
import { createContext } from "react";
4+
5+
import type { FormPillGroupSizeVariant } from "./types";
36

4-
export type { FormPillStateReturn };
57
export type FormPillInitialState = Omit<CompositeInitialState, "orientation" | "loop">;
68

7-
export const useFormPillState = (config: FormPillInitialState = {}): FormPillStateReturn => {
9+
export const useFormPillState = (config: FormPillInitialState = {}): CompositeStateReturn => {
810
return {
911
...useCompositeState({
1012
...config,
@@ -13,3 +15,11 @@ export const useFormPillState = (config: FormPillInitialState = {}): FormPillSta
1315
}),
1416
};
1517
};
18+
19+
export interface FormPillGroupContextState {
20+
size: FormPillGroupSizeVariant;
21+
}
22+
23+
export const FormPillGroupContext = createContext<FormPillGroupContextState>({
24+
size: "default",
25+
});

packages/paste-core/components/form-pill-group/stories/index.stories.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CalendarIcon } from "@twilio-paste/icons/esm/CalendarIcon";
44
import * as React from "react";
55

66
import { FormPill, FormPillGroup, useFormPillState } from "../src";
7+
import type { FormPillGroupSizeVariant } from "../src/FormPillGroup";
78

89
const PILL_NAMES = [
910
"Default pill",
@@ -15,12 +16,18 @@ const PILL_NAMES = [
1516
];
1617

1718
export const Basic: React.FC<
18-
React.PropsWithChildren<{ selected?: boolean; dismissable?: boolean; disabled?: boolean; ariaLabel?: string }>
19-
> = ({ selected = false, dismissable = false, disabled = false, ariaLabel = "Basic pills:" }) => {
19+
React.PropsWithChildren<{
20+
selected?: boolean;
21+
dismissable?: boolean;
22+
disabled?: boolean;
23+
ariaLabel?: string;
24+
size?: FormPillGroupSizeVariant;
25+
}>
26+
> = ({ selected = false, dismissable = false, disabled = false, ariaLabel = "Basic pills:", size }) => {
2027
const pillState = useFormPillState();
2128
return (
2229
<form>
23-
<FormPillGroup {...pillState} data-testid="form-pill-group" aria-label={ariaLabel}>
30+
<FormPillGroup {...pillState} data-testid="form-pill-group" aria-label={ariaLabel} size={size}>
2431
{PILL_NAMES.map((pill, index) => (
2532
<FormPill
2633
key={pill}
@@ -41,6 +48,7 @@ export const Basic: React.FC<
4148
);
4249
};
4350

51+
export const Large = (): JSX.Element => <Basic size="large" ariaLabel="Large pill group:" />;
4452
export const Disabled = (): JSX.Element => <Basic disabled ariaLabel="Disabled pills:" />;
4553
export const Selected = (): JSX.Element => <Basic selected ariaLabel="Selected pills:" />;
4654
export const Dismissable = (): JSX.Element => <Basic dismissable ariaLabel="Dismissable pills:" />;

packages/paste-core/components/form-pill-group/type-docs.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,13 @@
22592259
"required": false,
22602260
"externalProp": true
22612261
},
2262+
"size": {
2263+
"type": "FormPillGroupSizeVariant",
2264+
"defaultValue": "'default'",
2265+
"required": false,
2266+
"externalProp": false,
2267+
"description": "Size variant that affects the size and spacing of the pills within the FormPillGroup. 'large' and 'default' are the only supported values."
2268+
},
22622269
"slot": {
22632270
"type": "string",
22642271
"defaultValue": null,

packages/paste-website/src/component-examples/FormPillGroup.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@ render(
2626
)
2727
`.trim();
2828

29+
export const largeExample = `
30+
const BasicFormPillGroup = () => {
31+
const pillState = useFormPillState();
32+
33+
return (
34+
<form>
35+
<FormPillGroup {...pillState} aria-label="Products:" size="large">
36+
<FormPill {...pillState}>
37+
Voice
38+
</FormPill>
39+
<FormPill {...pillState}>
40+
<ProductVideoIcon decorative />
41+
Video
42+
</FormPill>
43+
<FormPill {...pillState}>
44+
<ProductVerifyIcon decorative />
45+
Verify
46+
</FormPill>
47+
</FormPillGroup>
48+
</form>
49+
);
50+
};
51+
52+
render(
53+
<BasicFormPillGroup />
54+
)
55+
`.trim();
56+
2957
export const selectableExample = `
3058
const SelectableFormPillGroup = () => {
3159
const [pills] = React.useState(['SMS', 'MMS', 'Fax', 'Voice', 'Messaging', 'Chat']);

packages/paste-website/src/pages/components/form-pill-group/index.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {DoDont, Do, Dont} from '../../../components/DoDont';
3636
import {SidebarCategoryRoutes} from '../../../constants';
3737
import {
3838
basicExample,
39+
largeExample,
3940
selectableExample,
4041
dismissableExample,
4142
selectableAndDismissableExample,
@@ -137,6 +138,14 @@ A Form Pill can have an optional [Avatar](/components/avatar) or [Icon](/compone
137138
{basicExample}
138139
</LivePreview>
139140

141+
### Large
142+
143+
Use `size="large"` Form Pills only for specific and approved use cases, such as in the filter group pattern (link coming soon!).
144+
145+
<LivePreview scope={{FormPill, FormPillGroup, useFormPillState, ProductVideoIcon, ProductVerifyIcon}} noInline>
146+
{largeExample}
147+
</LivePreview>
148+
140149
### Selectable
141150

142151
Use a Selectable Form Pill to show an option that a user can select or deselect.

0 commit comments

Comments
 (0)