Skip to content

Feat/form components changes #4311

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

Merged
merged 33 commits into from
May 15, 2025
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
da0fd28
feat(button): update loading state styling
PixeledCode Apr 10, 2025
c388bc4
feat(tokens): update aliases and tokens
PixeledCode Apr 10, 2025
83e3877
feat(button): update border radius based on size
PixeledCode Apr 10, 2025
31ddc63
feat(checkbox): update styles
PixeledCode Apr 10, 2025
59fab90
feat(label): add optional prop
PixeledCode Apr 10, 2025
62bbfcb
feat(faux-input): update broder radius
PixeledCode Apr 10, 2025
8fd8090
feat(input-box): update border radius
PixeledCode Apr 10, 2025
498e674
feat(file-picker): update border radius
PixeledCode Apr 10, 2025
7a579b0
feat(file-uploader): update background color
PixeledCode Apr 10, 2025
e4ef93d
feat(tokens): add new tokens
PixeledCode Apr 10, 2025
51fb20d
feat(visual-picker): update disabled state bg
PixeledCode Apr 10, 2025
b41d4ec
feat(menu): update styles
PixeledCode Apr 11, 2025
cb546bc
feat(combobox): update styles
PixeledCode Apr 11, 2025
ab517d0
feat(prefix): update color for disabled examples
PixeledCode Apr 16, 2025
5a68c69
feat(core): add changesets
PixeledCode Apr 16, 2025
0262ab6
feat(type): update type docs
PixeledCode Apr 16, 2025
4d4b445
feat(core): fix tests
PixeledCode Apr 16, 2025
b789f55
feat(core): fix typo
PixeledCode Apr 16, 2025
6cdd66c
feat(prefix): update color for disabled examples
PixeledCode Apr 23, 2025
68a08db
fix(label): contrast issue
PixeledCode Apr 23, 2025
29cab8d
feat(label): update docs
PixeledCode Apr 24, 2025
4b5cdfc
fix(label): fix require dot causing scrolling issues
PixeledCode Apr 25, 2025
75d23bd
feat(label): add i18nOptionalLabel prop
PixeledCode Apr 28, 2025
0ec57d8
feat(label): update typedocs
PixeledCode Apr 28, 2025
1bf4f41
feat(core): update combobox and menu item
PixeledCode Apr 30, 2025
99e8bf9
feat(tokens): update tokens
PixeledCode Apr 30, 2025
8a7fb93
feat(tokens): update dark tokens
PixeledCode Apr 30, 2025
1d28c0c
feat(tokens): remove tokens from twilio dark which are imported from …
PixeledCode Apr 30, 2025
61bd22c
feat(tokens): update snapshot
PixeledCode Apr 30, 2025
f45dd3e
fix: update tokens in dark and default theme for contrast
serifluous May 7, 2025
6c946ac
fix(form): fix tests
PixeledCode May 8, 2025
aa0d119
fix(form): fix cypress test
PixeledCode May 8, 2025
f2918c5
Merge branch 'main' into feat/form-components-changes
kodiakhq[bot] May 15, 2025
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
17 changes: 17 additions & 0 deletions .changeset/curly-jeans-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@twilio-paste/base-radio-checkbox": patch
"@twilio-paste/button": patch
"@twilio-paste/checkbox": patch
"@twilio-paste/combobox": patch
"@twilio-paste/file-picker": patch
"@twilio-paste/file-uploader": patch
"@twilio-paste/input": patch
"@twilio-paste/input-box": patch
"@twilio-paste/menu": patch
"@twilio-paste/select": patch
"@twilio-paste/textarea": patch
"@twilio-paste/visual-picker": patch
"@twilio-paste/core": patch
---

[Base Radio Checkbox, Button, Combobox, File Picker, File Uploader, Input, Input Box, Menu, Select, Textarea, Visual Picker] Update styles of form related components
6 changes: 6 additions & 0 deletions .changeset/lazy-icons-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@twilio-paste/design-tokens": patch
"@twilio-paste/core": patch
Comment on lines +2 to +3
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"@twilio-paste/design-tokens": patch
"@twilio-paste/core": patch
"@twilio-paste/design-tokens": minor
"@twilio-paste/core": minor

---

[Design Tokens] Update palette and new elevation token
6 changes: 6 additions & 0 deletions .changeset/selfish-birds-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@twilio-paste/label": minor
"@twilio-paste/core": minor
---

[Label] Update font weight, expose new prop for optional variant and fix require dot causing scrolling issue
2 changes: 1 addition & 1 deletion cypress/integration/token-list/index.spec.ts
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ describe("Token list filter format control and theme control", function () {
cy.get('[data-cy="theme-control"]').select("dark").should("have.value", "dark");
cy.get('[data-cy="tokens-table-container"] li:first dd [data-paste-element="TEXT"]:first').should(
"include.text",
"rgb(18, 28, 45)",
"rgb(24, 37, 60)",
);
cy.get('[data-cy="theme-control"]').select("default").should("have.value", "default");
cy.get('[data-cy="tokens-table-container"] li:first dd [data-paste-element="TEXT"]:first').should(
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ describe("AccountSwitcher", () => {
});
expect(screen.getByRole("button", { name: "Switch accounts" })).toHaveStyleRule(
"background-color",
"rgb(214, 31, 31)",
"rgb(219, 19, 42)",
);
expect(screen.getByRole("menu")).toHaveStyleRule("border-color", "rgb(117, 12, 12)");
expect(screen.getByRole("menuitem", { name: "Account settings" })).toHaveStyleRule(
@@ -59,7 +59,7 @@ describe("AccountSwitcher", () => {
});
expect(screen.getByRole("button", { name: "Switch accounts" })).toHaveStyleRule(
"background-color",
"rgb(214, 31, 31)",
"rgb(219, 19, 42)",
);
expect(screen.getByRole("menu")).toHaveStyleRule("border-color", "rgb(117, 12, 12)");
expect(screen.getByRole("menuitem", { name: "Account settings" })).toHaveStyleRule(
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ describe("Alert Dialog customization", () => {
});
it("should apply styles to Alert Dialog with custom element prop", () => {
const { container } = render(<CustomizedDestructiveAlertDialog />);
expect(screen.getByTestId("destructive_alert_dialog")).toHaveStyleRule("background-color", "rgb(214, 31, 31)");
expect(screen.getByTestId("destructive_alert_dialog")).toHaveStyleRule("background-color", "rgb(219, 19, 42)");
expect(container.querySelector('[data-paste-element="FOO_HEADER_WRAPPER"]')).toHaveStyleRule("border", "inherit");
expect(screen.getByText("Alert Dialog")).toHaveStyleRule("background-color", "rgb(235, 244, 255)");
expect(
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ describe("Alert Dialog", () => {
it("Should have a destructive button style when the destructive prop is included", () => {
render(<DestructiveAlertDialog />, { wrapper: ThemeWrapper });
const button = screen.getByRole("button", { name: "Delete" });
expect(button).toHaveStyleRule("background-color", "rgb(214, 31, 31)");
expect(button).toHaveStyleRule("background-color", "rgb(219, 19, 42)");
});

it("Should have a disabled destructive button style when the onConfirmDisabled prop is included", () => {
Original file line number Diff line number Diff line change
@@ -55,8 +55,8 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
color: "colorTextInverse",
}}
_disabledSibling={{
borderColor: "colorBorderWeaker",
backgroundColor: "colorBackgroundStrong",
borderColor: "colorBorderWeak",
backgroundColor: "colorBackground",
}}
_invalidSibling={{
borderColor: "colorBorderError",
@@ -65,7 +65,7 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
borderColor: "colorBorderErrorStronger",
}}
_invalidAndDisabledSibling={{
borderColor: "colorBorderWeaker",
borderColor: "colorBorderWeak",
}}
_checkedAndHoverSibling={{
borderColor: "colorBorderPrimaryStronger",
@@ -86,8 +86,8 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
: undefined
}
_checkedAndDisabledSibling={{
borderColor: "colorBorderWeaker",
backgroundColor: "colorBackgroundStrong",
borderColor: "colorBorderWeak",
backgroundColor: "colorBackground",
color: "colorTextWeaker",
}}
_checkedAndInvalidSibling={{
@@ -100,8 +100,8 @@ const BaseRadioCheckboxControl = React.forwardRef<HTMLSpanElement, BaseRadioChec
backgroundColor: "colorBackgroundErrorStronger",
}}
_checkedAndInvalidAndDisabledSibling={{
borderColor: "colorBorderWeaker",
backgroundColor: "colorBackgroundStrong",
borderColor: "colorBorderWeak",
backgroundColor: "colorBackground",
color: "colorTextWeaker",
}}
{...props}
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextDestructive",
color: "colorTextWeaker",
backgroundColor: "colorBackgroundBody",
boxShadow: "shadowBorderWeak",
boxShadow: "shadowBorderWeaker",
Comment on lines +33 to +35
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggestion: All the loading styles for buttons inherit from baseLoadingStyles right? If the color and boxShadow are denied there could we clean the button variants up here by removing them? Seems unnecessary to define them a second time. The only time we'd need to override it is for Inverse which is currently being done.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

only color is the common in all loading state button except reset variant

});

const disabledStyles: BoxStyleProps = merge(BaseStyles.disabled, {
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextDestructive",
color: "colorTextWeaker",
});

const disabledStyles = merge(BaseStyles.disabled, {
Original file line number Diff line number Diff line change
@@ -15,11 +15,11 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextLinkDestructive",
color: "colorTextWeaker",
textAlign: "left",
_hover: { color: "colorTextLinkDestructiveStronger" },
_active: { color: "colorTextLinkDestructiveStronger" },
_focus: { color: "colorTextLinkDestructiveStronger" },
_hover: { color: "colorTextWeaker" },
_active: { color: "colorTextWeaker" },
_focus: { color: "colorTextWeaker" },
});

const disabledStyles: BoxStyleProps = merge(BaseStyles.disabled, {
@@ -30,6 +30,11 @@ const disabledStyles: BoxStyleProps = merge(BaseStyles.disabled, {
_focus: { color: "colorTextLinkDestructiveWeak" },
});

const linkSizeStyles = (size: keyof typeof SizeStyles): BoxStyleProps =>
merge(SizeStyles[size], {
borderRadius: "borderRadius20",
});

const ButtonStyleMapping = {
default: defaultStyles,
loading: loadingStyles,
@@ -45,7 +50,7 @@ const DestructiveLinkButton = React.forwardRef<HTMLButtonElement, DirectButtonPr
width={fullWidth ? "100%" : "auto"}
{...safelySpreadBoxProps({ as, ...props })}
{...ButtonStyleMapping[buttonState]}
{...SizeStyles[size]}
{...linkSizeStyles(size)}
/>
);
},
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const baseLoadingStyles: BoxStyleProps = {
color: "colorTextDestructive",
color: "colorTextWeaker",
backgroundColor: "colorBackgroundBody",
boxShadow: "shadowBorderWeak",
boxShadow: "shadowBorderWeaker",
};

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
4 changes: 2 additions & 2 deletions packages/paste-core/components/button/src/InverseButton.tsx
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextInverse",
color: "colorTextInverseWeakest",
backgroundColor: "colorBackgroundInverseStrong",
boxShadow: "shadowBorderInverseWeaker",
boxShadow: "shadowBorderInverseWeakest",
});

const disabledStyles = merge(BaseStyles.disabled, {
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextInverse",
color: "colorTextInverseWeakest",
textAlign: "left",
});

@@ -25,6 +25,11 @@ const disabledStyles: BoxStyleProps = merge(BaseStyles.disabled, {
textAlign: "left",
});

const linkSizeStyles = (size: keyof typeof SizeStyles): BoxStyleProps =>
merge(SizeStyles[size], {
borderRadius: "borderRadius20",
});

const ButtonStyleMapping = {
default: defaultStyles,
loading: loadingStyles,
@@ -40,7 +45,7 @@ const InverseLinkButton = React.forwardRef<HTMLButtonElement, DirectButtonProps>
width={fullWidth ? "100%" : "auto"}
{...safelySpreadBoxProps({ as, ...props })}
{...ButtonStyleMapping[buttonState]}
{...SizeStyles[size]}
{...linkSizeStyles(size)}
/>
);
},
9 changes: 7 additions & 2 deletions packages/paste-core/components/button/src/LinkButton.tsx
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextPrimary",
color: "colorTextWeaker",
textAlign: "left",
});

@@ -24,6 +24,11 @@ const disabledStyles: BoxStyleProps = merge(BaseStyles.disabled, {
textAlign: "left",
});

const linkSizeStyles = (size: keyof typeof SizeStyles): BoxStyleProps =>
merge(SizeStyles[size], {
borderRadius: "borderRadius20",
});

const ButtonStyleMapping = {
default: defaultStyles,
loading: loadingStyles,
@@ -39,7 +44,7 @@ const LinkButton = React.forwardRef<HTMLButtonElement, DirectButtonProps>(
width={fullWidth ? "100%" : "auto"}
{...safelySpreadBoxProps({ as, ...props })}
{...ButtonStyleMapping[buttonState]}
{...SizeStyles[size]}
{...linkSizeStyles(size)}
/>
);
},
4 changes: 2 additions & 2 deletions packages/paste-core/components/button/src/PrimaryButton.tsx
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextPrimary",
color: "colorTextWeaker",
backgroundColor: "colorBackgroundBody",
boxShadow: "shadowBorderWeak",
boxShadow: "shadowBorderWeaker",
});

const disabledStyles = merge(BaseStyles.disabled, {
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextPrimary",
color: "colorTextWeaker",
});

const disabledStyles = merge(BaseStyles.disabled, {
4 changes: 2 additions & 2 deletions packages/paste-core/components/button/src/SecondaryButton.tsx
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const baseLoadingStyles: BoxStyleProps = {
color: "colorTextPrimary",
color: "colorTextWeaker",
backgroundColor: "colorBackgroundBody",
boxShadow: "shadowBorderWeak",
boxShadow: "shadowBorderWeaker",
};

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ const defaultStyles: BoxStyleProps = merge(BaseStyles.default, {
});

const loadingStyles: BoxStyleProps = merge(BaseStyles.loading, {
color: "colorTextPrimary",
color: "colorTextWeaker",
});

const disabledStyles = merge(BaseStyles.disabled, {
8 changes: 4 additions & 4 deletions packages/paste-core/components/button/src/styles.ts
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ export const SizeStyles: { [key in ButtonSizes]: BoxStyleProps } = {
paddingBottom: "space30",
paddingLeft: "space40",
paddingRight: "space40",
borderRadius: "borderRadius20",
borderRadius: "borderRadius30",
fontSize: "fontSize30",
lineHeight: "lineHeight20",
},
@@ -53,17 +53,17 @@ export const SizeStyles: { [key in ButtonSizes]: BoxStyleProps } = {
paddingBottom: "space20",
paddingLeft: "space30",
paddingRight: "space30",
borderRadius: "borderRadius10",
borderRadius: "borderRadius30",
fontSize: "fontSize30",
lineHeight: "lineHeight20",
},
icon: {
padding: "space30",
borderRadius: "borderRadius20",
borderRadius: "borderRadius30",
},
icon_small: {
padding: "space20",
borderRadius: "borderRadius20",
borderRadius: "borderRadius30",
},
reset: {
paddingTop: "space0",
4 changes: 2 additions & 2 deletions packages/paste-core/components/card/__test__/card.test.tsx
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ describe("Customization", () => {
);
const renderedCard = screen.getByTestId("customizable-card");
expect(renderedCard).toHaveStyleRule("background-color", "rgb(244, 244, 246)");
expect(renderedCard).toHaveStyleRule("border-color", "rgb(214, 31, 31)");
expect(renderedCard).toHaveStyleRule("border-color", "rgb(219, 19, 42)");
});

it("should add custom styles to Card with a custom element data attribute", (): void => {
@@ -94,6 +94,6 @@ describe("Customization", () => {
);
const renderedCard = screen.getByTestId("customizable-card");
expect(renderedCard).toHaveStyleRule("background-color", "rgb(244, 244, 246)");
expect(renderedCard).toHaveStyleRule("border-color", "rgb(214, 31, 31)");
expect(renderedCard).toHaveStyleRule("border-color", "rgb(219, 19, 42)");
});
});
2 changes: 1 addition & 1 deletion packages/paste-core/components/checkbox/src/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ const selectAllStyleProps = {
paddingRight: "space30",
paddingBottom: "space20",
paddingLeft: "space30",
borderRadius: "borderRadius10",
borderRadius: "borderRadius20",
backgroundColor: "colorBackground",
};

Loading

Unchanged files with check annotations Beta

convertRawTokenJSONToArray({
"color-text-weak": {
type: "color",
category: "text-color",

Check warning on line 20 in packages/paste-color-contrast-utils/__tests__/colorContrastPairingUtils.spec.ts

GitHub Actions / Lint repository

Define a constant instead of duplicating this literal 7 times
value: "#aeb2c1",
comment: "Weaker body text for visual hierarchy. Inaccessible unless used on disabled controls.",
originalValue: "{!palette-gray-40}",
const { defineTest } = require("jscodeshift/dist/testUtils");

Check warning on line 1 in packages/paste-codemods/transforms/__tests__/barreled-to-unbarreled.spec.tsx

GitHub Actions / Lint repository

Do not use "require"

Check warning on line 1 in packages/paste-codemods/transforms/__tests__/barreled-to-unbarreled.spec.tsx

GitHub Actions / Lint repository

A `require()` style import is forbidden
defineTest(__dirname, "barreled-to-unbarreled", null, "barreled-to-unbarreled", { parser: "ts" });

Check warning on line 3 in packages/paste-codemods/transforms/__tests__/barreled-to-unbarreled.spec.tsx

GitHub Actions / Lint repository

Do not use "__dirname"
let packageExports = {};
try {
// eslint-disable-next-line global-require, import/no-dynamic-require
packageExports = require(name);

Check warning on line 26 in packages/paste-codemods/tools/generatePackageExportsMap.ts

GitHub Actions / Lint repository

Do not use "require"

Check warning on line 26 in packages/paste-codemods/tools/generatePackageExportsMap.ts

GitHub Actions / Lint repository

A `require()` style import is forbidden
} catch (error) {
// eslint-disable-next-line no-console
console.log(`Failed to dynamically require package: ${name}`, error);
const mapping = await generatePackageExportsMap();
// Write to disk
writeToFile(path.join(__dirname, ".cache/mappings.json"), mapping, {

Check warning on line 10 in packages/paste-codemods/tools/create-package-mappings.ts

GitHub Actions / Lint repository

Do not use "__dirname"
successMessage: "Wrote core packages export mapping to .cache/mappings.json file!",
errorMessage: "Could not generate mappings!",
formatJson: true,
const mockMapping = await generatePackageExportsMap(mockGetPastePackages);
expect(mockMapping).toEqual({
BOX_PROPS_TO_BLOCK: "@twilio-paste/core/box",

Check warning on line 37 in packages/paste-codemods/tools/__tests__/tools.spec.ts

GitHub Actions / Lint repository

Define a constant instead of duplicating this literal 4 times
Box: "@twilio-paste/core/box",
ComboboxPrimitive: "@twilio-paste/core/combobox-primitive",

Check warning on line 39 in packages/paste-codemods/tools/__tests__/tools.spec.ts

GitHub Actions / Lint repository

Define a constant instead of duplicating this literal 3 times
DisclosurePrimitive: "@twilio-paste/core/disclosure-primitive",

Check warning on line 40 in packages/paste-codemods/tools/__tests__/tools.spec.ts

GitHub Actions / Lint repository

Define a constant instead of duplicating this literal 3 times
DisclosurePrimitiveContent: "@twilio-paste/core/disclosure-primitive",
Stack: "@twilio-paste/core/stack",
getCustomElementStyles: "@twilio-paste/core/box",