@isoftdata/svelte-button
Advanced tools
+99
-84
@@ -1,45 +0,79 @@ | ||
| <script>import ButtonContents from "./ButtonContents.svelte"; | ||
| let btnClass = ""; | ||
| export let block = false; | ||
| export { btnClass as class }; | ||
| export let button = void 0; | ||
| export let color = "primary"; | ||
| export let colorGreyDisabled = true; | ||
| export let disabled = false; | ||
| export let download = null; | ||
| export let href = null; | ||
| export let icon = { | ||
| class: "", | ||
| color: null, | ||
| style: null, | ||
| prefix: "fas", | ||
| fixedWidth: true, | ||
| icon: null | ||
| }; | ||
| export let iconClass = null; | ||
| export let id = null; | ||
| export let outline = false; | ||
| export let size = ""; | ||
| export let style = null; | ||
| export let target = null; | ||
| export let textClass = null; | ||
| export let title = null; | ||
| export let type = "button"; | ||
| export let wrap = false; | ||
| export let isLoading = false; | ||
| $: | ||
| computedColor = `btn-${color !== "link" && outline && (!disabled || !colorGreyDisabled) ? "outline-" : ""}${disabled && colorGreyDisabled ? "secondary" : color}`; | ||
| $: | ||
| computedSize = size ? `btn-${size}` : ""; | ||
| $: | ||
| computedClass = `btn ${computedSize} ${computedColor} ${btnClass}`; | ||
| $: | ||
| computedIcon = { | ||
| ...icon, | ||
| icon: icon.icon || iconClass, | ||
| class: icon.class || "", | ||
| color: icon.color && !disabled ? `color: ${icon.color};` : "", | ||
| prefix: icon.prefix || "fas", | ||
| fixedWidth: icon.fixedWidth || true | ||
| }; | ||
| <script lang="ts"> | ||
| import type { ComponentProps, Snippet } from 'svelte' | ||
| import Icon from '@isoftdata/svelte-icon' | ||
| import type { IconName } from '@fortawesome/fontawesome-common-types' | ||
| import type { ButtonColors } from '@isoftdata/utility-bootstrap' | ||
| import type { AriaAttributes, ClassValue, HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements' | ||
| import { getIconProps } from '@isoftdata/svelte-icon' | ||
| type IconProps = ComponentProps<Icon> | ||
| interface Props extends Omit<HTMLButtonAttributes & HTMLAnchorAttributes, 'class' | 'color' | 'disabled' | 'type' | keyof AriaAttributes | `bind:${string}` | `on:${string}`> { | ||
| block?: boolean | ||
| button?: HTMLButtonElement | HTMLAnchorElement | undefined | ||
| class?: ClassValue | ||
| color?: ButtonColors | ||
| colorGreyDisabled?: boolean | ||
| disabled?: boolean | ||
| download?: string | null | ||
| href?: string | null | ||
| icon?: IconName | IconProps | ||
| /** @deprecated use the `icon` prop instead */ | ||
| iconClass?: IconName | null | ||
| id?: string | null | ||
| outline?: boolean | ||
| size?: '' | 'xs' | 'sm' | 'lg' | ||
| style?: string | null | ||
| target?: string | null | ||
| textClass?: string | null | ||
| title?: string | null | ||
| type?: 'button' | 'submit' | 'reset' | ||
| wrap?: boolean | ||
| isLoading?: boolean | ||
| children?: Snippet | ||
| } | ||
| let { | ||
| block = false, | ||
| button = $bindable(undefined), | ||
| class: className = '', | ||
| color = 'primary', | ||
| colorGreyDisabled = true, | ||
| disabled = false, | ||
| download = null, | ||
| href = null, | ||
| icon = { | ||
| class: '', | ||
| color: null, | ||
| style: null, | ||
| prefix: 'fas', | ||
| fixedWidth: true, | ||
| icon: null, | ||
| }, | ||
| iconClass = null, | ||
| id = null, | ||
| outline = false, | ||
| size = '', | ||
| style = null, | ||
| target = null, | ||
| textClass = null, | ||
| title = null, | ||
| type = 'button', | ||
| wrap = false, | ||
| isLoading = false, | ||
| children, | ||
| ...rest | ||
| }: Props = $props() | ||
| let computedColor = $derived(`btn-${color !== 'link' && outline && (!disabled || !colorGreyDisabled) ? 'outline-' : ''}${disabled && colorGreyDisabled ? 'secondary' : color}`) | ||
| let computedSize = $derived(size ? `btn-${size}` : '') | ||
| let computedClass = $derived(`btn ${computedSize} ${computedColor} ${className}`) | ||
| let computedIcon: IconProps = $derived( | ||
| getIconProps(iconClass ?? icon, { | ||
| prefix: 'fas', | ||
| fixedWidth: true, | ||
| isLoading, | ||
| }), | ||
| ) | ||
| </script> | ||
@@ -57,12 +91,2 @@ | ||
| class:text-white={(disabled || isLoading) && !outline} | ||
| on:click | ||
| on:dblclick | ||
| on:mousedown | ||
| on:mouseup | ||
| on:mouseover | ||
| on:mouseout | ||
| on:keydown | ||
| on:keyup | ||
| on:focus | ||
| on:blur | ||
| {title} | ||
@@ -73,13 +97,5 @@ {target} | ||
| bind:this={button} | ||
| {...$$restProps} | ||
| {...rest} | ||
| > | ||
| <ButtonContents | ||
| icon={computedIcon} | ||
| {wrap} | ||
| {textClass} | ||
| showText={!!$$slots.default} | ||
| {isLoading} | ||
| > | ||
| <slot /> | ||
| </ButtonContents> | ||
| {@render buttonContents()} | ||
| </a> | ||
@@ -90,12 +106,2 @@ {:else} | ||
| {style} | ||
| on:click | ||
| on:dblclick | ||
| on:mousedown | ||
| on:mouseup | ||
| on:mouseover | ||
| on:mouseout | ||
| on:keydown | ||
| on:keyup | ||
| on:focus | ||
| on:blur | ||
| {type} | ||
@@ -107,16 +113,25 @@ {title} | ||
| bind:this={button} | ||
| {...$$restProps} | ||
| {...rest} | ||
| > | ||
| <ButtonContents | ||
| icon={computedIcon} | ||
| {wrap} | ||
| {textClass} | ||
| showText={!!$$slots.default} | ||
| {isLoading} | ||
| > | ||
| <slot /> | ||
| </ButtonContents> | ||
| {@render buttonContents()} | ||
| </button> | ||
| {/if} | ||
| {#snippet buttonContents()} | ||
| <span class:text-nowrap={!wrap}> | ||
| {#if computedIcon.icon || computedIcon.class} | ||
| <Icon | ||
| {...computedIcon} | ||
| aria-hidden | ||
| ></Icon> | ||
| {/if} | ||
| {#if children} | ||
| <span | ||
| id="buttonText" | ||
| class={textClass}>{@render children()}</span | ||
| > | ||
| {/if} | ||
| </span> | ||
| {/snippet} | ||
| <style> | ||
@@ -123,0 +138,0 @@ .btn-xs { |
+30
-57
@@ -1,60 +0,33 @@ | ||
| import { SvelteComponent } from "svelte"; | ||
| import type { ComponentProps, Snippet } from 'svelte'; | ||
| import Icon from '@isoftdata/svelte-icon'; | ||
| import type { IconName } from '@fortawesome/fontawesome-common-types'; | ||
| import type { ButtonColors } from '@isoftdata/utility-bootstrap'; | ||
| import type { AriaAttributes, DOMAttributes, HTMLButtonAttributes } from 'svelte/elements'; | ||
| declare const __propDef: { | ||
| props: Omit<HTMLButtonAttributes, "class" | "color" | "disabled" | "type" | keyof AriaAttributes | keyof DOMAttributes<HTMLButtonElement>> & { | ||
| block?: boolean | undefined; | ||
| button?: HTMLButtonElement | HTMLAnchorElement | undefined; | ||
| class?: string | undefined; | ||
| color?: ButtonColors | undefined; | ||
| colorGreyDisabled?: boolean | undefined; | ||
| disabled?: boolean | undefined; | ||
| download?: string | null | undefined; | ||
| href?: string | null | undefined; | ||
| icon?: { | ||
| [x: string]: any; | ||
| class?: string | undefined; | ||
| color?: string | null | undefined; | ||
| style?: string | null | undefined; | ||
| prefix?: import("@fortawesome/fontawesome-common-types").IconPrefix | undefined; | ||
| fixedWidth?: boolean | undefined; | ||
| icon?: IconName | null | undefined; | ||
| size?: "" | "2xs" | "xs" | "sm" | "lg" | "xl" | "2xl" | undefined; | ||
| } | undefined; | ||
| iconClass?: IconName | undefined; | ||
| id?: string | null | undefined; | ||
| outline?: boolean | undefined; | ||
| size?: "" | "xs" | "sm" | "lg" | undefined; | ||
| style?: string | null | undefined; | ||
| target?: string | null | undefined; | ||
| textClass?: string | null | undefined; | ||
| title?: string | null | undefined; | ||
| type?: "button" | "submit" | "reset" | undefined; | ||
| wrap?: boolean | undefined; | ||
| isLoading?: boolean | undefined; | ||
| }; | ||
| events: { | ||
| click: MouseEvent; | ||
| dblclick: MouseEvent; | ||
| mousedown: MouseEvent; | ||
| mouseup: MouseEvent; | ||
| mouseover: MouseEvent; | ||
| mouseout: MouseEvent; | ||
| keydown: KeyboardEvent; | ||
| keyup: KeyboardEvent; | ||
| focus: FocusEvent; | ||
| blur: FocusEvent; | ||
| } & { | ||
| [evt: string]: CustomEvent<any>; | ||
| }; | ||
| slots: { | ||
| default: {}; | ||
| }; | ||
| }; | ||
| export type ButtonProps = typeof __propDef.props; | ||
| export type ButtonEvents = typeof __propDef.events; | ||
| export type ButtonSlots = typeof __propDef.slots; | ||
| export default class Button extends SvelteComponent<ButtonProps, ButtonEvents, ButtonSlots> { | ||
| import type { AriaAttributes, ClassValue, HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements'; | ||
| type IconProps = ComponentProps<Icon>; | ||
| interface Props extends Omit<HTMLButtonAttributes & HTMLAnchorAttributes, 'class' | 'color' | 'disabled' | 'type' | keyof AriaAttributes | `bind:${string}` | `on:${string}`> { | ||
| block?: boolean; | ||
| button?: HTMLButtonElement | HTMLAnchorElement | undefined; | ||
| class?: ClassValue; | ||
| color?: ButtonColors; | ||
| colorGreyDisabled?: boolean; | ||
| disabled?: boolean; | ||
| download?: string | null; | ||
| href?: string | null; | ||
| icon?: IconName | IconProps; | ||
| /** @deprecated use the `icon` prop instead */ | ||
| iconClass?: IconName | null; | ||
| id?: string | null; | ||
| outline?: boolean; | ||
| size?: '' | 'xs' | 'sm' | 'lg'; | ||
| style?: string | null; | ||
| target?: string | null; | ||
| textClass?: string | null; | ||
| title?: string | null; | ||
| type?: 'button' | 'submit' | 'reset'; | ||
| wrap?: boolean; | ||
| isLoading?: boolean; | ||
| children?: Snippet; | ||
| } | ||
| export {}; | ||
| declare const Button: import("svelte").Component<Props, {}, "button">; | ||
| type Button = ReturnType<typeof Button>; | ||
| export default Button; |
+2
-2
@@ -1,2 +0,2 @@ | ||
| export { default } from "./Button.svelte"; | ||
| export { default as ButtonContents } from "./ButtonContents.svelte"; | ||
| export { default as default } from './Button.svelte'; | ||
| export { default as ButtonContents } from './ButtonContents.svelte'; |
+2
-2
| // Reexport your entry components here | ||
| export { default as default } from './Button.svelte' | ||
| export { default as ButtonContents } from './ButtonContents.svelte' | ||
| export { default as default } from './Button.svelte'; | ||
| export { default as ButtonContents } from './ButtonContents.svelte'; |
+15
-13
| { | ||
| "name": "@isoftdata/svelte-button", | ||
| "version": "1.4.1", | ||
| "version": "2.0.0", | ||
| "scripts": { | ||
@@ -28,3 +28,3 @@ "dev": "vite dev", | ||
| "peerDependencies": { | ||
| "svelte": "^4.0.0 || ^5.1.6" | ||
| "svelte": "^5.22.5" | ||
| }, | ||
@@ -34,5 +34,6 @@ "devDependencies": { | ||
| "@isoftdata/prettier-config": "^1.0.3", | ||
| "@sveltejs/adapter-auto": "^2.0.0", | ||
| "@sveltejs/kit": "^1.20.4", | ||
| "@sveltejs/package": "^2.0.0", | ||
| "@sveltejs/adapter-auto": "^4.0.0", | ||
| "@sveltejs/kit": "^2.5.27", | ||
| "@sveltejs/package": "^2.3.7", | ||
| "@sveltejs/vite-plugin-svelte": "^5.0.3", | ||
| "@typescript-eslint/eslint-plugin": "^5.45.0", | ||
@@ -42,11 +43,11 @@ "@typescript-eslint/parser": "^5.45.0", | ||
| "eslint-config-prettier": "^8.5.0", | ||
| "eslint-plugin-svelte": "^2.30.0", | ||
| "prettier": "^2.8.0", | ||
| "prettier-plugin-svelte": "^2.10.1", | ||
| "eslint-plugin-svelte": "^2.45.1", | ||
| "prettier": "^3.1.0", | ||
| "prettier-plugin-svelte": "^3.2.6", | ||
| "publint": "^0.1.9", | ||
| "svelte": "^4.0.5", | ||
| "svelte-check": "^3.4.3", | ||
| "svelte": "^5.22.5", | ||
| "svelte-check": "^4.0.0", | ||
| "tslib": "^2.4.1", | ||
| "typescript": "^5.0.0", | ||
| "vite": "^4.4.2" | ||
| "typescript": "^5.5.0", | ||
| "vite": "^6.2.0" | ||
| }, | ||
@@ -57,5 +58,6 @@ "svelte": "./dist/index.js", | ||
| "dependencies": { | ||
| "@isoftdata/svelte-icon": "^1.1.0", | ||
| "@isoftdata/svelte-bootstrap-version-switcher": "^1.0.3", | ||
| "@isoftdata/svelte-icon": "^1.6.0", | ||
| "@isoftdata/utility-bootstrap": "^2.2.0" | ||
| } | ||
| } |
+16
-7
@@ -10,2 +10,10 @@ # Svelte Button | ||
| ## Breaking changes | ||
| ### 2.0.0 | ||
| - Require Svelte 5 | ||
| - Slots -> Snippets | ||
| - Events -> Callbacks | ||
| - Deprecate `iconClass` prop. The `icon` prop can now accept an icon name or an object | ||
| ## Props | ||
@@ -15,3 +23,3 @@ | ||
| | --- | --- | --- | --- | | ||
| | `block` | `boolean` | Render the button as block, spanning the whole width of its parent. | `false` | ||
| | `block` | `boolean` | Render the button as block, spanning the whole width of its parent. | `false` | | ||
| | `button` | `HTMLButtonElement \| HTMLAnchorElement` | Either the `<button>` or `<a>`. Useful if you want to fire events directly on it. | (The button or anchor tag) | | ||
@@ -23,4 +31,3 @@ | `color` | `"primary" \| "secondary" \| "success" \| "danger" \| "warning" \| "info" \| "light" \| "dark"` | The bootstrap color of the button. | `"primary"` | | ||
| | `href` | `string \| null` | The URL to link to when the button is clicked. | `null` | | ||
| | `icon` | `object` | All options relating to the [Icon component](https://github.com/ISoft-Data-Systems/svelte-component-icon). | `{ class: "", color: null, style: null, prefix: "fas", fixedWidth: true, icon: null }` | | ||
| | `iconClass` | `string \| null` | The FontAwesome icon name, excluding the leading `fa-`, e.g. `pencil`. Either specify this prop, or `icon.icon`. | `null` | | ||
| | `icon` | `IconName \| ComponentProps<Icon>` | The name of a FontAwesome icon, or an object of [Icon component](https://github.com/ISoft-Data-Systems/svelte-component-icon) props. | `{ class: "", color: null, style: null, prefix: "fas", fixedWidth: true, icon: null }` | | ||
| | `id` | `string \| null` | The ID of the button. | `null` | | ||
@@ -35,7 +42,9 @@ | `outline` | `boolean` | Whether the button is outlined. | `false` | | ||
| | `wrap` | `boolean` | Whether the button should wrap its contents. | `false` | | ||
| | `isLoading` | `boolean` | Whether the button is showing a loading icon(and disabled) | `false` | | ||
| | `isLoading` | `boolean` | Whether the button is showing a loading icon (and disabled) | `false` | | ||
| Any extra props (such as `onclick`) are applied to the button/anchor tag as well. | ||
| ## Example | ||
| ```handlebars | ||
| ```svelte | ||
| <script> | ||
@@ -47,4 +56,4 @@ import Button from "@isoftdata/svelte-button" | ||
| color="primary" | ||
| iconClass="0" | ||
| on:click={() => alert("Clicked!")} | ||
| icon="0" | ||
| onclick={() => alert("Clicked!")} | ||
| > | ||
@@ -51,0 +60,0 @@ Click Me! |
| <script>import Icon from "@isoftdata/svelte-icon"; | ||
| export let wrap = false; | ||
| export let icon; | ||
| export let textClass = null; | ||
| export let isLoading = false; | ||
| export let showText = $$slots.default; | ||
| let loadingIcon = { ...icon, icon: "spinner" }; | ||
| $: | ||
| hasTextAndIcon = !!icon.icon && $$slots.default && showText; | ||
| $: | ||
| loadingIcon = { ...icon, icon: "spinner" }; | ||
| </script> | ||
| <span class:nowrap={!wrap}> | ||
| {#if icon.icon || icon.class} | ||
| {#if isLoading} | ||
| <Icon | ||
| {...loadingIcon} | ||
| aria-hidden | ||
| class="fa-spin {icon.class} {hasTextAndIcon ? 'mr-1' : ''}" | ||
| /> | ||
| {:else} | ||
| <Icon | ||
| {...icon} | ||
| aria-hidden | ||
| class="{icon.class} {hasTextAndIcon ? 'mr-1' : ''}" | ||
| /> | ||
| {/if} | ||
| {/if} | ||
| {#if showText} | ||
| <span | ||
| id="buttonText" | ||
| class={textClass}><slot /></span | ||
| > | ||
| {/if} | ||
| </span> | ||
| <style> | ||
| .nowrap { | ||
| white-space: nowrap; | ||
| } | ||
| </style> |
| import { SvelteComponent } from "svelte"; | ||
| declare const __propDef: { | ||
| props: { | ||
| wrap?: boolean | undefined; | ||
| icon: { | ||
| [x: string]: any; | ||
| class?: string | undefined; | ||
| color?: string | null | undefined; | ||
| style?: string | null | undefined; | ||
| prefix?: import("@fortawesome/fontawesome-common-types").IconPrefix | undefined; | ||
| fixedWidth?: boolean | undefined; | ||
| icon?: import("@fortawesome/fontawesome-common-types").IconName | null | undefined; | ||
| size?: "" | "2xs" | "xs" | "sm" | "lg" | "xl" | "2xl" | undefined; | ||
| }; | ||
| textClass?: string | null | undefined; | ||
| isLoading?: boolean | undefined; | ||
| showText?: boolean | undefined; | ||
| }; | ||
| events: { | ||
| [evt: string]: CustomEvent<any>; | ||
| }; | ||
| slots: { | ||
| default: {}; | ||
| }; | ||
| }; | ||
| export type ButtonContentsProps = typeof __propDef.props; | ||
| export type ButtonContentsEvents = typeof __propDef.events; | ||
| export type ButtonContentsSlots = typeof __propDef.slots; | ||
| export default class ButtonContents extends SvelteComponent<ButtonContentsProps, ButtonContentsEvents, ButtonContentsSlots> { | ||
| } | ||
| export {}; |
69
15%9808
-16.94%4
33.33%19
5.56%6
-25%38
-60.42%