From 997cc1fa5e991e0320897824320f11aff55fb3bb Mon Sep 17 00:00:00 2001 From: Enrico Sacchetti Date: Tue, 16 Jan 2024 16:30:06 -0500 Subject: [PATCH] feat: upgrade Button to v11 styles Button changes ##BREAKING CHANGES - `skeleton` prop has been removed. Use `ButtonSkeleton` component instead - `size` prop has new values - `kind` prop has new values - `isSelected` is now `selected - `on:mouseover`, `on:mouseenter`, and `on:mouseleave` forwarded events were replaced with `on:pointerover`, `on:pointerenter`, and `on:pointerleave` - `as` no longer accepts boolean types ## Features - New `2xl` size - `expressive` styles now apply to all button sizes - `as` accepts a string to specify a desired HTML element --- COMPONENT_INDEX.md | 57 ++++----- css/all.scss | 8 +- docs/src/COMPONENT_API.json | 66 +++++----- docs/src/pages/components/Button.svx | 61 ++++------ src/Button/Button.svelte | 173 +++++++++++++-------------- types/Button/Button.svelte.d.ts | 56 +++------ 6 files changed, 184 insertions(+), 237 deletions(-) diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index 036a2a74..043fca30 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -372,40 +372,41 @@ 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 | "sm" | "md" | "lg" | "xl" | "2xl" | "lg" | 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 | HTMLElement | 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 | "sm" | "md" | "lg" | "xl" | "2xl" | "lg" | Specify the size of button | +| expressive | No | let | No | boolean | false | Set to `true` to use Carbon's expressive typesetting | +| selected | 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 | keyof import('svelte/elements').SvelteHTMLElements | undefined | Specify an element name to render as the button.
Be sure to provide | +| 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 | +| buttonAttributes | No | let | No | import('svelte/elements').HTMLAnchorAttributes | | +| import('svelte/elements').HTMLButtonAttributes | import('svelte/elements').HTMLAttributes | {} | Button, anchor, or div attributes | ### Slots -| Slot name | Default | Props | Fallback | -| :-------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------- | :------- | -| -- | Yes | { props: { role: "button"; type?: string; tabindex: any; disabled: boolean; href?: string; class: string; [key: string]: any; } } | -- | +| Slot name | Default | Props | Fallback | +| :-------- | :------ | :---- | :------- | +| -- | Yes | -- | -- | ### Events -| Event name | Type | Detail | -| :--------- | :-------- | :----- | -| click | forwarded | -- | -| focus | forwarded | -- | -| blur | forwarded | -- | -| mouseover | forwarded | -- | -| mouseenter | forwarded | -- | -| mouseleave | forwarded | -- | +| Event name | Type | Detail | +| :----------- | :-------- | :----- | +| click | forwarded | -- | +| focus | forwarded | -- | +| blur | forwarded | -- | +| pointerover | forwarded | -- | +| pointerenter | forwarded | -- | +| pointerleave | forwarded | -- | ## `ButtonSet` diff --git a/css/all.scss b/css/all.scss index 8a051526..6864a2fa 100644 --- a/css/all.scss +++ b/css/all.scss @@ -1,7 +1,9 @@ +$prefix: 'bx'; + // Use all Carbon themes @use '@carbon/styles/scss/config' with ( $use-akamai-cdn: true, - $prefix: 'bx' + $prefix: $prefix ); @use "@carbon/styles" as styles; @use "@carbon/styles/scss/utilities" as *; @@ -22,9 +24,9 @@ @include styles.theme(styles.$g100); } -.bx--text-truncate-end { +.#{$prefix}--text-truncate-end { @include text-truncate-end; } -.bx--text-truncate-front { +.#{$prefix}--text-truncate-front { @include text-truncate-front; } diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index a86fb2a0..706aea11 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -486,7 +486,7 @@ "reactive": false }, { - "name": "isSelected", + "name": "selected", "kind": "let", "description": "Set to `true` to enable the selected state for an icon-only, ghost button", "type": "boolean", @@ -546,21 +546,8 @@ { "name": "as", "kind": "let", - "description": "Set to `true` to render a custom HTML element\nProps are destructured as `props` in the default slot (e.g., )", - "type": "boolean", - "value": "false", - "isFunction": false, - "isFunctionDeclaration": false, - "isRequired": false, - "constant": false, - "reactive": false - }, - { - "name": "skeleton", - "kind": "let", - "description": "Set to `true` to display the skeleton state", - "type": "boolean", - "value": "false", + "description": "Specify an element name to render as the button.\nBe sure to provide", + "type": "keyof import('svelte/elements').SvelteHTMLElements", "isFunction": false, "isFunctionDeclaration": false, "isRequired": false, @@ -618,49 +605,50 @@ "name": "ref", "kind": "let", "description": "Obtain a reference to the HTML element", - "type": "null | HTMLAnchorElement | HTMLButtonElement", + "type": "null | HTMLElement", "value": "null", "isFunction": false, "isFunctionDeclaration": false, "isRequired": false, "constant": false, "reactive": true + }, + { + "name": "buttonAttributes", + "kind": "let", + "description": "Button, anchor, or div attributes", + "type": "import('svelte/elements').HTMLAnchorAttributes |\nimport('svelte/elements').HTMLButtonAttributes | import('svelte/elements').HTMLAttributes", + "value": "{}", + "isFunction": false, + "isFunctionDeclaration": false, + "isRequired": false, + "constant": false, + "reactive": false } ], "moduleExports": [], - "slots": [ - { - "name": "__default__", - "default": true, - "slot_props": "{ props: { role: \"button\"; type?: string; tabindex: any; disabled: boolean; href?: string; class: string; [key: string]: any; } }" - } - ], + "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], "events": [ - { "type": "forwarded", "name": "click", "element": "ButtonSkeleton" }, - { "type": "forwarded", "name": "focus", "element": "ButtonSkeleton" }, - { "type": "forwarded", "name": "blur", "element": "ButtonSkeleton" }, + { "type": "forwarded", "name": "click", "element": "svelte:element" }, + { "type": "forwarded", "name": "focus", "element": "svelte:element" }, + { "type": "forwarded", "name": "blur", "element": "svelte:element" }, { "type": "forwarded", - "name": "mouseover", - "element": "ButtonSkeleton" + "name": "pointerover", + "element": "svelte:element" }, { "type": "forwarded", - "name": "mouseenter", - "element": "ButtonSkeleton" + "name": "pointerenter", + "element": "svelte:element" }, { "type": "forwarded", - "name": "mouseleave", - "element": "ButtonSkeleton" + "name": "pointerleave", + "element": "svelte:element" } ], - "typedefs": [], - "rest_props": { "type": "Element", "name": "button | a | div" }, - "extends": { - "interface": "ButtonSkeletonProps", - "import": "\"./ButtonSkeleton.svelte\"" - } + "typedefs": [] }, { "moduleName": "ButtonSet", diff --git a/docs/src/pages/components/Button.svx b/docs/src/pages/components/Button.svx index db942157..e6afd1a7 100644 --- a/docs/src/pages/components/Button.svx +++ b/docs/src/pages/components/Button.svx @@ -36,7 +36,7 @@
- You must provide an iconDescription for the button tooltip. + You must provide an iconDescription for screen readers.
@@ -54,7 +54,7 @@
- You must provide an iconDescription for the button tooltip. + You must provide an iconDescription for screen readers.
@@ -84,41 +84,20 @@ If an `href` value is specified, the component will render an [anchor element](h ## Custom element - -## Field size +## Sizes - - - - - +Button is available in small, medium, large, extra-large, and double-extra-large. +Use `md` (default) when used with form fields. -## Small size - - - - - - - -## Large size - - - - - - - -## Extra-large size - - - - - - + + + + + ## Disabled state @@ -129,12 +108,6 @@ If an `href` value is specified, the component will render an [anchor element](h Set `expressive` to `true` to use Carbon's expressive typesetting. - -
- Expressive styles only work with the default, "lg", and "xl" button sizes. -
-
- @@ -153,13 +126,19 @@ Set `expressive` to `true` to use Carbon's expressive typesetting. +## Additional attributes + +Use `buttonAttributes` to pass any additional attributes. + + + ## Skeleton - -{/if} + diff --git a/types/Button/Button.svelte.d.ts b/types/Button/Button.svelte.d.ts index 675853da..f4127dd2 100644 --- a/types/Button/Button.svelte.d.ts +++ b/types/Button/Button.svelte.d.ts @@ -1,13 +1,6 @@ import type { SvelteComponentTyped } from "svelte"; -import type { SvelteHTMLElements } from "svelte/elements"; -import type { ButtonSkeletonProps } from "./ButtonSkeleton.svelte"; - -type RestProps = SvelteHTMLElements["button"] & - SvelteHTMLElements["a"] & - SvelteHTMLElements["div"]; - -export interface ButtonProps extends ButtonSkeletonProps, RestProps { +export interface ButtonProps { /** * Specify the kind of button * @default "primary" @@ -37,7 +30,7 @@ export interface ButtonProps extends ButtonSkeletonProps, RestProps { * Set to `true` to enable the selected state for an icon-only, ghost button * @default false */ - isSelected?: boolean; + selected?: boolean; /** * Specify the icon to render @@ -65,17 +58,11 @@ export interface ButtonProps extends ButtonSkeletonProps, RestProps { tooltipPosition?: "top" | "right" | "bottom" | "left"; /** - * Set to `true` to render a custom HTML element - * Props are destructured as `props` in the default slot (e.g., ) - * @default false + * Specify an element name to render as the button. + * Be sure to provide + * @default undefined */ - as?: boolean; - - /** - * Set to `true` to display the skeleton state - * @default false - */ - skeleton?: boolean; + as?: keyof import("svelte/elements").SvelteHTMLElements; /** * Set to `true` to disable the button @@ -105,9 +92,16 @@ export interface ButtonProps extends ButtonSkeletonProps, RestProps { * Obtain a reference to the HTML element * @default null */ - ref?: null | HTMLAnchorElement | HTMLButtonElement; + ref?: null | HTMLElement; - [key: `data-${string}`]: any; + /** + * Button, anchor, or div attributes + * @default {} + */ + buttonAttributes?: + | import("svelte/elements").HTMLAnchorAttributes + | import("svelte/elements").HTMLButtonAttributes + | import("svelte/elements").HTMLAttributes; } export default class Button extends SvelteComponentTyped< @@ -116,21 +110,9 @@ export default class Button extends SvelteComponentTyped< click: WindowEventMap["click"]; focus: WindowEventMap["focus"]; blur: WindowEventMap["blur"]; - mouseover: WindowEventMap["mouseover"]; - mouseenter: WindowEventMap["mouseenter"]; - mouseleave: WindowEventMap["mouseleave"]; + pointerover: WindowEventMap["pointerover"]; + pointerenter: WindowEventMap["pointerenter"]; + pointerleave: WindowEventMap["pointerleave"]; }, - { - default: { - props: { - role: "button"; - type?: string; - tabindex: any; - disabled: boolean; - href?: string; - class: string; - [key: string]: any; - }; - }; - } + { default: {} } > {}