From a1302baa44a9d313534e88d44de87a94cf60e074 Mon Sep 17 00:00:00 2001 From: Enrico Sacchetti Date: Sat, 28 Jan 2023 21:08:55 -0500 Subject: [PATCH 1/2] feat(button): adopt v11 styles - forward focus and blur events - provide button role for custom elements using 'as' BREAKING CHANGE: danger-tertiary and danger-ghost props were renamed to danger--tertiary and danger--ghost BREAKING CHANGE: buttons now have a larger minimum width --- COMPONENT_INDEX.md | 36 ++++++------- docs/src/COMPONENT_API.json | 6 ++- docs/src/pages/components/Button.svx | 6 +-- .../Button/Button.svelte | 51 +++++++++++-------- .../Button/ButtonSet.svelte | 4 +- .../Button/ButtonSkeleton.svelte | 24 ++++----- tests/Button.test.svelte | 6 +-- 7 files changed, 70 insertions(+), 63 deletions(-) diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index 19a7489721..0e9101d817 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -372,23 +372,23 @@ export type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584; ### Props -| Prop name | Required | Kind | Reactive | Type | Default value | Description | -| :--------------- | :------- | :--------------- | :------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ref | No | let | Yes | null | HTMLAnchorElement | HTMLButtonElement | null | Obtain a reference to the HTML element | -| kind | No | let | No | "primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger-tertiary" | "danger-ghost" | "primary" | Specify the kind of button | -| size | No | let | No | "default" | "field" | "small" | "lg" | "xl" | "default" | Specify the size of button | -| expressive | No | let | No | boolean | false | Set to `true` to use Carbon's expressive typesetting | -| isSelected | No | let | No | boolean | false | Set to `true` to enable the selected state for an icon-only, ghost button | -| icon | No | let | No | typeof import("svelte").SvelteComponent | undefined | Specify the icon to render | -| iconDescription | No | let | No | string | undefined | Specify the ARIA label for the button icon | -| tooltipAlignment | No | let | No | "start" | "center" | "end" | "center" | Set the alignment of the tooltip relative to the icon.
Only applies to icon-only buttons | -| tooltipPosition | No | let | No | "top" | "right" | "bottom" | "left" | "bottom" | Set the position of the tooltip relative to the icon | -| as | No | let | No | boolean | false | Set to `true` to render a custom HTML element
Props are destructured as `props` in the default slot (e.g., <Button let:props><div {...props}>...</div></Button>) | -| skeleton | No | let | No | boolean | false | Set to `true` to display the skeleton state | -| disabled | No | let | No | boolean | false | Set to `true` to disable the button | -| href | No | let | No | string | undefined | Set the `href` to use an anchor link | -| tabindex | No | let | No | string | "0" | Specify the tabindex | -| type | No | let | No | string | "button" | Specify the `type` attribute for the button element | +| Prop name | Required | Kind | Reactive | Type | Default value | Description | +| :--------------- | :------- | :--------------- | :------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ref | No | let | Yes | null | HTMLAnchorElement | HTMLButtonElement | null | Obtain a reference to the HTML element | +| kind | No | let | No | "primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger--tertiary" | "danger--ghost" | "primary" | Specify the kind of button | +| size | No | let | No | "default" | "field" | "small" | "lg" | "xl" | "default" | Specify the size of button | +| expressive | No | let | No | boolean | false | Set to `true` to use Carbon's expressive typesetting | +| isSelected | No | let | No | boolean | false | Set to `true` to enable the selected state for an icon-only, ghost button | +| icon | No | let | No | typeof import("svelte").SvelteComponent | undefined | Specify the icon to render | +| iconDescription | No | let | No | string | undefined | Specify the ARIA label for the button icon | +| tooltipAlignment | No | let | No | "start" | "center" | "end" | "center" | Set the alignment of the tooltip relative to the icon.
Only applies to icon-only buttons | +| tooltipPosition | No | let | No | "top" | "right" | "bottom" | "left" | "bottom" | Set the position of the tooltip relative to the icon | +| as | No | let | No | boolean | false | Set to `true` to render a custom HTML element
Props are destructured as `props` in the default slot (e.g., <Button let:props><div {...props}>...</div></Button>) | +| skeleton | No | let | No | boolean | false | Set to `true` to display the skeleton state | +| disabled | No | let | No | boolean | false | Set to `true` to disable the button | +| href | No | let | No | string | undefined | Set the `href` to use an anchor link | +| tabindex | No | let | No | string | "0" | Specify the tabindex | +| type | No | let | No | string | "button" | Specify the `type` attribute for the button element | ### Slots @@ -404,6 +404,8 @@ export type BreakpointValue = 320 | 672 | 1056 | 1312 | 1584; | mouseover | forwarded | -- | | mouseenter | forwarded | -- | | mouseleave | forwarded | -- | +| focus | forwarded | -- | +| blur | forwarded | -- | ## `ButtonSet` diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index 4d02aaa68a..768afb158f 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -453,7 +453,7 @@ "name": "kind", "kind": "let", "description": "Specify the kind of button", - "type": "\"primary\" | \"secondary\" | \"tertiary\" | \"ghost\" | \"danger\" | \"danger-tertiary\" | \"danger-ghost\"", + "type": "\"primary\" | \"secondary\" | \"tertiary\" | \"ghost\" | \"danger\" | \"danger--tertiary\" | \"danger--ghost\"", "value": "\"primary\"", "isFunction": false, "isFunctionDeclaration": false, @@ -651,7 +651,9 @@ "type": "forwarded", "name": "mouseleave", "element": "ButtonSkeleton" - } + }, + { "type": "forwarded", "name": "focus", "element": "ButtonSkeleton" }, + { "type": "forwarded", "name": "blur", "element": "ButtonSkeleton" } ], "typedefs": [], "rest_props": { "type": "Element", "name": "button | a | div" }, diff --git a/docs/src/pages/components/Button.svx b/docs/src/pages/components/Button.svx index cde19987ca..c81cd4daac 100644 --- a/docs/src/pages/components/Button.svx +++ b/docs/src/pages/components/Button.svx @@ -30,7 +30,7 @@ ## Danger tertiary button - + ## Danger tertiary, icon-only button @@ -40,11 +40,11 @@ - + ## Button with icon diff --git a/src/carbon-components-svelte/Button/Button.svelte b/src/carbon-components-svelte/Button/Button.svelte index 3f55273028..17b3fe87ec 100644 --- a/src/carbon-components-svelte/Button/Button.svelte +++ b/src/carbon-components-svelte/Button/Button.svelte @@ -7,7 +7,7 @@ /** * Specify the kind of button - * @type {"primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger-tertiary" | "danger-ghost"} + * @type {"primary" | "secondary" | "tertiary" | "ghost" | "danger" | "danger--tertiary" | "danger--ghost"} */ export let kind = "primary"; @@ -79,6 +79,7 @@ import { getContext } from "svelte"; import ButtonSkeleton from "./ButtonSkeleton.svelte"; + import "@carbon/styles/scss/components/button/_index.scss"; const ctx = getContext("ComposedModal"); @@ -95,30 +96,30 @@ hasIconOnly && kind === "ghost" && !href ? isSelected : undefined, ...$$restProps, class: [ - "bx--btn", - expressive && "bx--btn--expressive", + "cds--btn", + expressive && "cds--btn--expressive", ((size === "small" && !expressive) || (size === "sm" && !expressive) || (size === "small" && !expressive)) && - "bx--btn--sm", + "cds--btn--sm", (size === "field" && !expressive) || - (size === "md" && !expressive && "bx--btn--md"), - size === "field" && "bx--btn--field", - size === "small" && "bx--btn--sm", - size === "lg" && "bx--btn--lg", - size === "xl" && "bx--btn--xl", - kind && `bx--btn--${kind}`, - disabled && "bx--btn--disabled", - hasIconOnly && "bx--btn--icon-only", - hasIconOnly && "bx--tooltip__trigger", - hasIconOnly && "bx--tooltip--a11y", + (size === "md" && !expressive && "cds--btn--md"), + size === "field" && "cds--btn--field", + size === "small" && "cds--btn--sm", + size === "lg" && "cds--btn--lg", + size === "xl" && "cds--btn--xl", + kind && `cds--btn--${kind}`, + disabled && "cds--btn--disabled", + hasIconOnly && "cds--btn--icon-only", + hasIconOnly && "cds--tooltip__trigger", + hasIconOnly && "cds--tooltip--a11y", hasIconOnly && tooltipPosition && - `bx--btn--icon-only--${tooltipPosition}`, + `cds--btn--icon-only--${tooltipPosition}`, hasIconOnly && tooltipAlignment && - `bx--tooltip--align-${tooltipAlignment}`, - hasIconOnly && isSelected && kind === "ghost" && "bx--btn--selected", + `cds--tooltip--align-${tooltipAlignment}`, + hasIconOnly && isSelected && kind === "ghost" && "cds--btn--selected", $$restProps.class, ] .filter(Boolean) @@ -137,9 +138,11 @@ on:mouseover on:mouseenter on:mouseleave + on:focus + on:blur /> {:else if as} - + {:else if href && !disabled} {#if hasIconOnly} - {iconDescription} + {iconDescription} {/if} @@ -168,14 +173,16 @@ on:mouseover on:mouseenter on:mouseleave + on:focus + on:blur > {#if hasIconOnly} - {iconDescription} + {iconDescription} {/if}