carbon-components-svelte/src/Button/Button.svelte
2020-10-04 18:27:01 +02:00

205 lines
4.9 KiB
Svelte
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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}