mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-18 11:36:36 +00:00
205 lines
4.9 KiB
Svelte
205 lines
4.9 KiB
Svelte
<script>
|
||
/**
|
||
* Specify the kind of button
|
||
* @type {"primary" | "secondary" | "tertiary" | "ghost" | "danger"} [kind="primary"]
|
||
*/
|
||
export let kind = "primary";
|
||
|
||
/**
|
||
* Specify the size of button
|
||
* @type {"default" | "field" | "small"} [size="default"]
|
||
*/
|
||
export let size = "default";
|
||
|
||
/**
|
||
* Set to `true` for the icon-only variant
|
||
* @type {boolean} [hasIconOnly=false]
|
||
*/
|
||
export let hasIconOnly = false;
|
||
|
||
/**
|
||
* Specify the icon from `carbon-icons-svelte` to render
|
||
* @type {typeof import("carbon-icons-svelte/lib/Add16").default} [icon]
|
||
*/
|
||
export let icon = undefined;
|
||
|
||
/**
|
||
* Specify the position of the icon
|
||
* @type {"left" | "right"} [iconPosition="right"]
|
||
*/
|
||
export let iconPosition = undefined;
|
||
|
||
/**
|
||
* Specify the ARIA label for the button icon
|
||
* @type {string} [iconDescription]
|
||
*/
|
||
export let iconDescription = undefined;
|
||
|
||
/**
|
||
* Set the alignment of the tooltip relative to the icon
|
||
* `hasIconOnly` must be set to `true`
|
||
* @type {"start" | "center" | "end"} [tooltipAlignment]
|
||
*/
|
||
export let tooltipAlignment = undefined;
|
||
|
||
/**
|
||
* Set the position of the tooltip relative to the icon
|
||
* @type {"top" | "right" | "bottom" | "left"} [tooltipPosition]
|
||
*/
|
||
export let tooltipPosition = undefined;
|
||
|
||
/**
|
||
* 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>)
|
||
* @type {boolean} [as=false]
|
||
*/
|
||
export let as = false;
|
||
|
||
/**
|
||
* Set to `true` to display the skeleton state
|
||
* @type {boolean} [skeleton=false]
|
||
*/
|
||
export let skeleton = false;
|
||
|
||
/**
|
||
* Set to `true` to disable the button
|
||
* @type {boolean} [disabled=false]
|
||
*/
|
||
export let disabled = false;
|
||
|
||
/**
|
||
* Set the `href` to use an anchor link
|
||
* @type {string} [href]
|
||
*/
|
||
export let href = undefined;
|
||
|
||
/**
|
||
* Specify the tabindex
|
||
* @type {string} [tabindex="0"]
|
||
*/
|
||
export let tabindex = "0";
|
||
|
||
/**
|
||
* Specify the `type` attribute for the button element
|
||
* @type {string} [type="button"]
|
||
*/
|
||
export let type = "button";
|
||
|
||
/**
|
||
* Obtain a reference to the HTML element
|
||
* @type {null | HTMLAnchorElement | HTMLButtonElement} [ref=null]
|
||
*/
|
||
export let ref = null;
|
||
|
||
import { getContext } from "svelte";
|
||
import ButtonSkeleton from "./Button.Skeleton.svelte";
|
||
|
||
const ctx = getContext("ComposedModal");
|
||
|
||
$: if (ctx && ref) {
|
||
ctx.declareRef(ref);
|
||
}
|
||
$: buttonProps = {
|
||
role: "button",
|
||
type: href && !disabled ? undefined : type,
|
||
tabindex,
|
||
disabled,
|
||
href,
|
||
...$$restProps,
|
||
class: [
|
||
"bx--btn",
|
||
size === "field" && "bx--btn--field",
|
||
size === "small" && "bx--btn--sm",
|
||
kind && `bx--btn--${kind}`,
|
||
disabled && "bx--btn--disabled",
|
||
hasIconOnly && "bx--btn--icon-only",
|
||
hasIconOnly && "bx--tooltip__trigger",
|
||
hasIconOnly && "bx--tooltip--a11y",
|
||
hasIconOnly && tooltipPosition && `bx--tooltip--${tooltipPosition}`,
|
||
hasIconOnly &&
|
||
tooltipAlignment &&
|
||
`bx--tooltip--align-${tooltipAlignment}`,
|
||
$$restProps.class,
|
||
]
|
||
.filter(Boolean)
|
||
.join(" "),
|
||
};
|
||
</script>
|
||
|
||
{#if skeleton}
|
||
<ButtonSkeleton
|
||
href="{href}"
|
||
small="{size === 'small'}"
|
||
{...$$restProps}
|
||
style="{hasIconOnly && 'width: 3rem;'}"
|
||
on:click
|
||
on:mouseover
|
||
on:mouseenter
|
||
on:mouseleave
|
||
/>
|
||
{:else}
|
||
{#if as}
|
||
<slot props="{buttonProps}" />
|
||
{:else if href && !disabled}
|
||
<!-- svelte-ignore a11y-missing-attribute -->
|
||
<a
|
||
bind:this="{ref}"
|
||
{...buttonProps}
|
||
on:click
|
||
on:mouseover
|
||
on:mouseenter
|
||
on:mouseleave
|
||
>
|
||
{#if icon && iconPosition === "left"}
|
||
<svelte:component
|
||
this="{icon}"
|
||
aria-hidden="true"
|
||
class="bx--btn__icon"
|
||
aria-label="{iconDescription}"
|
||
/>
|
||
{/if}
|
||
{#if hasIconOnly}
|
||
<span class:bx--assistive-text="{true}">{iconDescription}</span>
|
||
{/if}
|
||
<slot />
|
||
{#if icon && iconPosition === "right"}
|
||
<svelte:component
|
||
this="{icon}"
|
||
aria-hidden="true"
|
||
class="bx--btn__icon"
|
||
aria-label="{iconDescription}"
|
||
/>
|
||
{/if}
|
||
</a>
|
||
{:else}
|
||
<button
|
||
bind:this="{ref}"
|
||
{...buttonProps}
|
||
on:click
|
||
on:mouseover
|
||
on:mouseenter
|
||
on:mouseleave
|
||
>
|
||
{#if icon && iconPosition=== "left"}
|
||
<svelte:component
|
||
this="{icon}"
|
||
aria-hidden="true"
|
||
class="bx--btn__icon"
|
||
aria-label="{iconDescription}"
|
||
/>
|
||
{/if}
|
||
{#if hasIconOnly}
|
||
<span class:bx--assistive-text="{true}">{iconDescription}</span>
|
||
{/if}
|
||
<slot />
|
||
{#if icon && iconPosition=== "right"}
|
||
<svelte:component
|
||
this="{icon}"
|
||
aria-hidden="true"
|
||
class="bx--btn__icon"
|
||
aria-label="{iconDescription}"
|
||
/>
|
||
{/if}
|
||
</button>
|
||
{/if}
|
||
{/if}
|