refactor(components): convert const to reactive where appropriate

- Inline class assignments to avoid script-level clutter
- Ignore a11y-missing-attribute instead of redundant href
This commit is contained in:
Eric Liu 2019-12-24 09:41:12 -08:00
commit c446fc74f4
94 changed files with 469 additions and 598 deletions

View file

@ -8,12 +8,15 @@
import ChevronRight16 from 'carbon-icons-svelte/lib/ChevronRight16';
import { cx, fillArray } from '../../lib';
import SkeletonText from '../SkeletonText';
const _class = cx('--accordion', '--skeleton', className);
const items = fillArray(open ? count - 1 : count);
</script>
<ul on:click on:mouseover on:mouseenter on:mouseleave {style} class={_class}>
<ul
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--accordion', '--skeleton', className)}
{style}>
{#if open}
<li class={cx('--accordion__item', '--accordion__item--active')}>
<span class={cx('--accordion__heading')}>
@ -27,7 +30,7 @@
</div>
</li>
{/if}
{#each items as item, i (item)}
{#each fillArray(open ? count - 1 : count) as item, i (item)}
<li class={cx('--accordion__item')}>
<span class={cx('--accordion__heading')}>
<ChevronRight16 class={cx('--accordion__arrow')} />

View file

@ -4,10 +4,8 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--accordion', className);
</script>
<ul on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<ul on:click on:mouseover on:mouseenter on:mouseleave class={cx('--accordion', className)} {style}>
<slot />
</ul>

View file

@ -10,17 +10,10 @@
import { cx } from '../../lib';
let animation = undefined;
$: _class = cx(
'--accordion__item',
open && '--accordion__item--active',
animation && `--accordion__item--${animation}`,
className
);
</script>
<li
class={_class}
class={cx('--accordion__item', open && '--accordion__item--active', animation && `--accordion__item--${animation}`, className)}
on:animationend
on:animationend={() => {
animation = undefined;
@ -40,8 +33,8 @@
on:mouseenter
on:mouseleave
on:keydown
on:keydown={event => {
if (open && event.key === 'Escape') {
on:keydown={({ key }) => {
if (open && key === 'Escape') {
open = false;
}
}}>

View file

@ -4,11 +4,15 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--breadcrumb', '--skeleton', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--breadcrumb', '--skeleton', className)}
{style}>
{#each [0, 1, 2] as item, i (item)}
<div class={cx('--breadcrumb-item')}>
<span class={cx('--link')}>&nbsp;</span>

View file

@ -5,9 +5,6 @@
export let style = undefined;
import { cx } from '../../lib';
const ariaLabel = $$props['aria-label'] || 'Breadcrumb';
const _class = cx('--breadcrumb', noTrailingSlash && '--breadcrumb--no-trailing-slash');
</script>
<nav
@ -15,10 +12,10 @@
on:mouseover
on:mouseenter
on:mouseleave
aria-label={ariaLabel}
aria-label={$$props['aria-label'] || 'Breadcrumb'}
class={className}
{style}>
<ol class={_class}>
<ol class={cx('--breadcrumb', noTrailingSlash && '--breadcrumb--no-trailing-slash')}>
<slot />
</ol>
</nav>

View file

@ -8,22 +8,21 @@
import { cx } from '../../lib';
import Link from '../Link';
const ariaCurrent = $$props['aria-current'];
const _class = cx(
'--breadcrumb-item',
isCurrentPage && ariaCurrent !== 'page' && '--breadcrumb-item--current',
className
);
$: ariaCurrent = $$props['aria-current'];
</script>
{#if href}
<li on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<li
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--breadcrumb-item', isCurrentPage && ariaCurrent !== 'page' && '--breadcrumb-item--current', className)}
{style}>
{#if href}
<Link {href} aria-current={ariaCurrent}>
<slot />
</Link>
</li>
{:else}
<li on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
{:else}
<slot props={{ 'aria-current': ariaCurrent, class: cx('--link') }} />
</li>
{/if}
{/if}
</li>

View file

@ -11,9 +11,23 @@
</script>
{#if href}
<a role="button" on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} {href}>
<a
role="button"
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton', '--btn', small && '--btn--sm', className)}
{style}
{href}>
{''}
</a>
{:else}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} />
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton', '--btn', small && '--btn--sm', className)}
{style} />
{/if}

View file

@ -66,7 +66,8 @@
</Button>
&nbsp;
<Button {...regularProps} as let:props>
<a href="#link" {...props}>Custom component</a>
<!-- svelte-ignore a11y-missing-attribute -->
<a {...props}>Custom component</a>
</Button>
{/if}
</div>

View file

@ -5,28 +5,22 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--snippet',
'--skeleton',
type === 'single' && '--snippet--single',
type === 'multi' && '--snippet--multi',
className
);
</script>
{#if type === 'single'}
<div on:click on:mouseover on:mouseenter on:mouseleave {style} class={_class}>
<div class={cx('--snippet-container')}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--snippet', '--skeleton', type === 'single' && '--snippet--single', type === 'multi' && '--snippet--multi', className)}
{style}>
<div class={cx('--snippet-container')}>
{#if type === 'single'}
<span />
</div>
{:else if type === 'multi'}
<span />
<span />
<span />
{/if}
</div>
{:else if type === 'multi'}
<div on:click on:mouseover on:mouseenter on:mouseleave {style} class={_class}>
<div class={cx('--snippet-container')}>
<span />
<span />
<span />
</div>
</div>
{/if}
</div>

View file

@ -26,14 +26,6 @@
$: if (codeRef) {
showMoreLess = type === 'multi' && codeRef.getBoundingClientRect().height > 255;
}
$: _class = cx(
'--snippet',
type && `--snippet--${type}`,
type === 'inline' && '--btn--copy',
expanded && '--snippet--expand',
light && '--snippet--light',
className
);
</script>
{#if type === 'inline'}
@ -44,7 +36,7 @@
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
class={cx('--snippet', type && `--snippet--${type}`, type === 'inline' && '--btn--copy', expanded && '--snippet--expand', light && '--snippet--light', className)}
{feedback}
{feedbackTimeout}
{style}>
@ -53,7 +45,13 @@
</code>
</Copy>
{:else}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--snippet', type && `--snippet--${type}`, type === 'inline' && '--btn--copy', expanded && '--snippet--expand', light && '--snippet--light', className)}
{style}>
<div
role="textbox"
tabindex="0"

View file

@ -6,14 +6,12 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--modal-content', hasForm && '--modal-content--with-form', className);
</script>
<div
tabindex={hasScrollingContent ? '0' : undefined}
role={hasScrollingContent ? 'region' : undefined}
class={_class}
class={cx('--modal-content', hasForm && '--modal-content--with-form', className)}
{style}>
<slot />
</div>

View file

@ -9,16 +9,14 @@
export let danger = false;
export let style = undefined;
import { createEventDispatcher, getContext } from 'svelte';
import { getContext } from 'svelte';
import { cx } from '../../lib';
import Button from '../Button';
const dispatch = createEventDispatcher();
const { closeModal, submit } = getContext('ComposedModal');
const _footerClass = cx('--modal-footer', className);
</script>
<div class={_footerClass} {style}>
<div class={cx('--modal-footer', className)} {style}>
{#if secondaryButtonText}
<Button kind="secondary" class={secondaryClass} on:click={closeModal}>
{secondaryButtonText}

View file

@ -10,34 +10,28 @@
export let iconDescription = 'Close';
export let style = undefined;
import Close20 from 'carbon-icons-svelte/lib/Close20';
import { getContext } from 'svelte';
import Close20 from 'carbon-icons-svelte/lib/Close20';
import { cx } from '../../lib';
const { closeModal } = getContext('ComposedModal');
const _class = cx('--modal-header', className);
const _labelClass = cx('--modal-header__label', '--type-delta', labelClass);
const _titleClass = cx('--modal-header__heading', '--type-beta', titleClass);
const _closeClass = cx('--modal-close', closeClass);
const _closeIconClass = cx('--modal-close__icon', closeIconClass);
</script>
<div class={_class} {style}>
<div class={cx('--modal-header', className)} {style}>
{#if label}
<p class={_labelClass}>{label}</p>
<p class={cx('--modal-header__label', '--type-delta', labelClass)}>{label}</p>
{/if}
{#if title}
<p class={_titleClass}>{title}</p>
<p class={cx('--modal-header__heading', '--type-beta', titleClass)}>{title}</p>
{/if}
<slot />
<button
type="button"
title={iconDescription}
aria-label={iconDescription}
class={_closeClass}
class={cx('--modal-close', closeClass)}
on:click
on:click={closeModal}>
<Close20 class={_closeIconClass} />
<Close20 class={cx('--modal-close__icon', closeIconClass)} />
</button>
</div>

View file

@ -9,7 +9,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--content-switcher', className);
let currentId = writable(null);
let currentIndex = selectedIndex;
let switches = [];
@ -49,6 +48,13 @@
}
</script>
<div role="tablist" on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
role="tablist"
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--content-switcher', className)}
{style}>
<slot />
</div>

View file

@ -3,8 +3,8 @@
export { className as class };
export let selected = false;
export let text = 'Provide text';
export let style = undefined;
export let disabled = false;
export let style = undefined;
import { cx } from '../../lib';
import { getContext } from 'svelte';
@ -20,7 +20,6 @@
$: if (selected && buttonRef) {
buttonRef.focus();
}
$: _class = cx('--content-switcher-btn', selected && '--content-switcher--selected', className);
</script>
<button
@ -28,7 +27,7 @@
role="tab"
tabindex={selected ? '0' : '-1'}
aria-selected={selected}
class={_class}
class={cx('--content-switcher-btn', selected && '--content-switcher--selected', className)}
on:click
on:click|preventDefault={() => {
update(id);

View file

@ -9,7 +9,6 @@
import { cx } from '../../lib';
let timeoutId = undefined;
let showFeedback = false;
onDestroy(() => {
if (timeoutId !== undefined) {
@ -18,7 +17,7 @@
}
});
$: _class = cx('--btn--copy__feedback', showFeedback && '--btn--copy__feedback--displayed');
$: showFeedback = timeoutId !== undefined;
</script>
<button
@ -26,9 +25,8 @@
class={className}
on:click
on:click={() => {
showFeedback = true;
timeoutId = window.setTimeout(() => {
showFeedback = false;
showFeedback = undefined;
}, feedbackTimeout);
}}
on:mouseover
@ -36,5 +34,7 @@
on:mouseleave
{style}>
<slot />
<div class={_class} data-feedback={feedback} />
<div
class={cx('--btn--copy__feedback', showFeedback && '--btn--copy__feedback--displayed')}
data-feedback={feedback} />
</button>

View file

@ -19,14 +19,6 @@
timeoutId = undefined;
}
});
$: _class = cx(
'--copy-btn',
animation && '--copy-btn--animating',
animation && `--copy-btn--${animation}`,
animation === 'fade-in' && '--btn--copy__feedback--displayed',
className
);
</script>
<button
@ -34,7 +26,7 @@
tabindex="0"
aria-label={iconDescription}
title={iconDescription}
class={_class}
class={cx('--copy-btn', animation && '--copy-btn--animating', animation && `--copy-btn--${animation}`, animation === 'fade-in' && '--btn--copy__feedback--displayed', className)}
on:click
on:click={() => {
animation = 'fade-in';

View file

@ -3,47 +3,41 @@
export { className as class };
export let zebra = false;
export let compact = false;
export let rowCount = 5;
export let columnCount = 5;
export let headers = [];
export let rows = 5;
export let columns = 5;
export let style = undefined;
import { cx, fillArray } from '../../lib';
const rows = fillArray(rowCount - 1);
const columns = fillArray(columnCount);
const _headers =
headers[0] === Object(headers[0]) && !Array.isArray(headers[0])
? headers.map(({ header }) => header)
: headers;
const _class = cx(
'--skeleton',
'--data-table',
zebra && '--data-table--zebra',
compact && '--data-table--compact',
className
);
$: cols = fillArray(headers.length > 0 ? headers.length : columns);
</script>
<table on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<table
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton', '--data-table', zebra && '--data-table--zebra', compact && '--data-table--compact', className)}
{style}>
<thead>
<tr>
{#each columns as column, i (column)}
<th>{_headers[column]}</th>
{#each cols as col, i (col)}
<th>{headers[col] || ''}</th>
{/each}
</tr>
</thead>
<tbody>
<tr>
{#each columns as column, i (column)}
{#each cols as col, i (col)}
<td>
<span />
</td>
{/each}
</tr>
{#each rows as row, i (row)}
{#each fillArray(rows - 1) as row, i (row)}
<tr>
{#each columns as column, j (column)}
{#each cols as col, j (col)}
<td />
{/each}
</tr>

View file

@ -6,11 +6,9 @@
import SkeletonText from '../SkeletonText';
import { ButtonSkeleton } from '../Button';
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<SkeletonText heading width="100px" />
<SkeletonText width="225px" class={cx('--label-description')} />
<ButtonSkeleton />

View file

@ -48,7 +48,7 @@
<Button
kind="secondary"
size="small"
style={'margin-top: 1rem'}
style="margin-top: 1rem"
{disabled}
on:click={() => {
files = [];

View file

@ -19,9 +19,7 @@
import FileUploaderButton from './FileUploaderButton.svelte';
const dispatch = createEventDispatcher();
const _class = cx('--form-item', className);
// let files = [];
let prevFiles = [];
$: {
@ -38,7 +36,7 @@
}
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<strong class={cx('--file--label')}>{labelTitle}</strong>
<p class={cx('--label-description')}>{labelDescription}</p>
<FileUploaderButton

View file

@ -15,15 +15,15 @@
import { cx } from '../../lib';
const _class = cx(
let inputRef = undefined;
$: _class = cx(
'--btn',
'--btn--sm',
kind && `--btn--${kind}`,
disabled && '--btn--disabled',
className
);
let inputRef = undefined;
</script>
<label

View file

@ -18,12 +18,12 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _labelClass = cx('--file-browse-btn', disabled && '--file-browse-btn--disabled');
let over = false;
let inputRef = undefined;
$: _class = cx('--file__drop-container', over && '--file__drop-container--drag-over', className);
$: _labelClass = cx('--file-browse-btn', disabled && '--file-browse-btn--disabled');
</script>
<div

View file

@ -15,14 +15,14 @@
import Filename from './Filename.svelte';
const dispatch = createEventDispatcher();
const _class = cx(
'--file__selected-file',
invalid && '--file__selected-file--invalid',
className
);
</script>
<span on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<span
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--file__selected-file', invalid && '--file__selected-file--invalid', className)}
{style}>
<p class={cx('--file-filename')}>{name}</p>
<span class={cx('--file__state-container')}>
<Filename

View file

@ -5,7 +5,7 @@
import { cx } from '../../lib';
const _class = cx('--form', className);
$: _class = cx('--form', className);
</script>
<form on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>

View file

@ -9,8 +9,8 @@
import { cx } from '../../lib';
const _class = cx('--fieldset', className);
const _legendClass = cx('--label', className);
$: _class = cx('--fieldset', className);
$: _legendClass = cx('--label', className);
</script>
<fieldset

View file

@ -4,10 +4,8 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<slot />
</div>

View file

@ -5,10 +5,15 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<label on:click on:mouseover on:mouseenter on:mouseleave for={id} class={_class} {style}>
<label
on:click
on:mouseover
on:mouseenter
on:mouseleave
for={id}
class={cx('--form-item', className)}
{style}>
<slot />
</label>

View file

@ -5,9 +5,12 @@
export let style = undefined;
import { cx, css } from '../../lib';
const _class = cx('--icon--skeleton', className);
const _style = css([style, ['width', `${size}px`], ['height', `${size}px`]]);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} style={_style} />
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--icon--skeleton', className)}
style={css([style, ['width', `${size}px`], ['height', `${size}px`]])} />

View file

@ -10,8 +10,8 @@
import IconSkeleton from './Icon.Skeleton.svelte';
const iconName = render.toString().split(' ')[1];
const size = parseInt(iconName.slice(-2), 10);
$: iconName = render.toString().split(' ')[1];
$: size = parseInt(iconName.slice(-2), 10);
</script>
{#if skeleton}
@ -20,18 +20,18 @@
on:mouseover
on:mouseenter
on:mouseleave
{size}
class={className}
{style} />
{style}
{size} />
{:else}
<svelte:component
this={render}
aria-label={$$props['aria-label']}
aria-labelledby={$$props['aria-labelledby']}
on:click
on:mouseover
on:mouseenter
on:mouseleave
aria-label={$$props['aria-label']}
aria-labelledby={$$props['aria-labelledby']}
class={className}
{tabindex}
{focusable}

View file

@ -14,7 +14,7 @@
import Loading from '../Loading';
const dispatch = createEventDispatcher();
const _class = cx('--inline-loading', className);
let timeoutId = undefined;
onDestroy(() => {
@ -33,11 +33,11 @@
<div
aria-live={$$props['aria-live'] || 'assertive'}
class={cx('--inline-loading', className)}
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
{style}>
<div class={cx('--inline-loading__animation')}>
{#if status === 'error'}

View file

@ -7,34 +7,27 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--link',
disabled && '--link--disabled',
inline && '--link--inline',
className
);
</script>
{#if disabled}
<p
aria-current={$$props['aria-current']}
class={cx('--link', disabled && '--link--disabled', inline && '--link--inline', className)}
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
{style}>
<slot />
</p>
{:else}
<a
aria-current={$$props['aria-current']}
class={cx('--link', disabled && '--link--disabled', inline && '--link--inline', className)}
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
{style}
{href}>
<slot />

View file

@ -4,10 +4,8 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--list__item', className);
</script>
<li on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<li on:click on:mouseover on:mouseenter on:mouseleave class={cx('--list__item', className)} {style}>
<slot />
</li>

View file

@ -9,24 +9,17 @@
import { cx } from '../../lib';
const loadingId = `loading-id-${Math.random()}`;
const spinnerRadius = small ? '26.8125' : '37.5';
const _class = cx(
'--loading',
small && '--loading--small',
!active && '--loading--stop',
className
);
const _overlayClass = cx('--loading-overlay', !active && '--loading-overlay--stop');
$: loadingId = `loading-${Math.random()}`;
$: spinnerRadius = small ? '26.8125' : '37.5';
</script>
{#if withOverlay}
<div class={_overlayClass}>
<div class={cx('--loading-overlay', !active && '--loading-overlay--stop')}>
<div
aria-atomic="true"
aria-labelledby={loadingId}
aria-live={active ? 'assertive' : 'off'}
class={_class}
class={cx('--loading', small && '--loading--small', !active && '--loading--stop', className)}
{style}>
<label id={loadingId} class={cx('--visually-hidden')}>{description}</label>
<svg class={cx('--loading__svg')} viewBox="-75 -75 150 150">
@ -43,7 +36,7 @@
aria-atomic="true"
aria-labelledby={loadingId}
aria-live={active ? 'assertive' : 'off'}
class={_class}
class={cx('--loading', small && '--loading--small', !active && '--loading--stop', className)}
{style}>
<label id={loadingId} class={cx('--visually-hidden')}>{description}</label>
<svg class={cx('--loading__svg')} viewBox="-75 -75 150 150">

View file

@ -18,13 +18,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx(
'--inline-notification',
lowContrast && '--inline-notification--low-contrast',
kind && `--inline-notification--${kind}`,
hideCloseButton && '--inline-notification--hide-close-button',
className
);
let open = true;
@ -34,7 +27,15 @@
</script>
{#if open}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} {role} {kind}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--inline-notification', lowContrast && '--inline-notification--low-contrast', kind && `--inline-notification--${kind}`, hideCloseButton && '--inline-notification--hide-close-button', className)}
{style}
{role}
{kind}>
<div class={cx('--inline-notification__details')}>
<NotificationIcon {notificationType} {kind} {iconDescription} />
<NotificationTextDetails {title} {subtitle} {notificationType}>

View file

@ -5,8 +5,6 @@
import Button from '../Button';
import { cx } from '../../lib';
const _class = cx('--inline-notification__action-button', className);
</script>
<Button
@ -16,7 +14,7 @@
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
class={cx('--inline-notification__action-button', className)}
{style}>
<slot />
</Button>

View file

@ -10,16 +10,6 @@
import Close20 from 'carbon-icons-svelte/lib/Close20';
import { cx } from '../../lib';
const _class = cx(
notificationType === 'toast' && '--toast-notification__close-button',
notificationType === 'inline' && '--inline-notification__close-button',
className
);
const _iconClass = cx(
notificationType === 'toast' && '--toast-notification__close-icon',
notificationType === 'inline' && '--inline-notification__close-icon'
);
</script>
<button
@ -29,8 +19,11 @@
on:mouseleave
aria-label={iconDescription}
title={iconDescription}
class={_class}
class={cx(notificationType === 'toast' && '--toast-notification__close-button', notificationType === 'inline' && '--inline-notification__close-button', className)}
{style}
{type}>
<svelte:component this={renderIcon} class={_iconClass} {title} />
<svelte:component
this={renderIcon}
class={cx(notificationType === 'toast' && '--toast-notification__close-icon', notificationType === 'inline' && '--inline-notification__close-icon')}
{title} />
</button>

View file

@ -20,12 +20,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx(
'--toast-notification',
lowContrast && '--toast-notification--low-contrast',
kind && `--toast-notification--${kind}`,
className
);
let open = true;
@ -43,18 +37,26 @@
</script>
{#if open}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} {role} {kind}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--toast-notification', lowContrast && '--toast-notification--low-contrast', kind && `--toast-notification--${kind}`, className)}
{style}
{role}
{kind}>
<NotificationIcon {notificationType} {kind} {iconDescription} />
<NotificationTextDetails {title} {subtitle} {caption} {notificationType}>
<slot />
</NotificationTextDetails>
{#if !hideCloseButton}
<NotificationButton
{iconDescription}
{notificationType}
on:click={() => {
open = false;
}} />
}}
{iconDescription}
{notificationType} />
{/if}
</div>
{/if}

View file

@ -5,10 +5,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--list--ordered', nested && '--list--nested', className);
</script>
<ol on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<ol
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--list--ordered', nested && '--list--nested', className)}
{style}>
<slot />
</ol>

View file

@ -5,11 +5,15 @@
import SkeletonText from '../SkeletonText';
import { cx } from '../../lib';
const _class = cx('--pagination', '--skeleton', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--pagination', '--skeleton', className)}
{style}>
<div class={cx('--pagination__left')}>
<SkeletonText width="70px" />
<SkeletonText width="35px" />

View file

@ -23,24 +23,13 @@
import Select, { SelectItem } from '../Select';
import { cx, fillArray } from '../../lib';
const _class = cx('--pagination', className);
$: totalPages = Math.max(Math.ceil(totalItems / pageSize), 1);
$: selectItems = fillArray(totalPages);
$: backButtonDisabled = disabled || page === 1;
$: _backButtonClass = cx(
'--pagination__button',
'--pagination__button--backward',
backButtonDisabled && '--pagination__button--no-index'
);
$: forwardButtonDisabled = disabled || page === totalPages;
$: _forwardButtonClass = cx(
'--pagination__button',
'--pagination__button--forward',
forwardButtonDisabled && '--pagination__button--no-index'
);
</script>
<div class={_class} {style}>
<div class={cx('--pagination', className)} {style}>
<div class={cx('--pagination__left')}>
<label
id={cx(`--pagination-select-${id}-count-label`)}
@ -93,7 +82,7 @@
{/if}
<button
type="button"
class={_backButtonClass}
class={cx('--pagination__button', '--pagination__button--backward', backButtonDisabled && '--pagination__button--no-index')}
on:click={() => {
page--;
}}
@ -103,7 +92,7 @@
</button>
<button
type="button"
class={_forwardButtonClass}
class={cx('--pagination__button', '--pagination__button--forward', forwardButtonDisabled && '--pagination__button--no-index')}
aria-label={forwardText}
on:click={() => {
page++;

View file

@ -5,11 +5,15 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--progress', vertical && '--progress--vertical', '--skeleton', className);
</script>
<ul on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<ul
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--progress', vertical && '--progress--vertical', '--skeleton', className)}
{style}>
{#each [0, 1, 2, 3] as item, i (item)}
<li class={cx('--progress-step', '--progress-step--incomplete')}>
<div class={cx('--progress-step-button', '--progress-step-button--unclickable')}>

View file

@ -10,7 +10,7 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--progress', vertical && '--progress--vertical', className);
let steps = writable([]);
let stepsById = derived(steps, $steps => $steps.reduce((a, c) => ({ ...a, [c.id]: c }), {}));
@ -34,6 +34,12 @@
});
</script>
<ul on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<ul
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--progress', vertical && '--progress--vertical', className)}
{style}>
<slot />
</ul>

View file

@ -26,22 +26,16 @@
current = step.current;
complete = step.complete;
}
$: _class = cx(
'--progress-step',
current && '--progress-step--current',
complete && '--progress-step--complete',
!complete && !current && '--progress-step--incomplete',
disabled && '--progress-step--disabled',
className
);
$: _buttonClass = cx('--progress-step-button', current && '--progress-step-button--unclickable');
</script>
<li aria-disabled={disabled} class={_class} {style}>
<li
aria-disabled={disabled}
class={cx('--progress-step', current && '--progress-step--current', complete && '--progress-step--complete', !complete && !current && '--progress-step--incomplete', disabled && '--progress-step--disabled', className)}
{style}>
<div
role="button"
class={_buttonClass}
tabindex={current ? '-1' : '0'}
class={cx('--progress-step-button', current && '--progress-step-button--unclickable')}
on:click={() => {
change(step.index);
}}

View file

@ -4,11 +4,15 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--radio-button-wrapper', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--radio-button-wrapper', className)}
{style}>
<div class={cx('--radio-button', '--skeleton')} />
<span class={cx('--radio-button__label', '--skeleton')} />
</div>

View file

@ -16,12 +16,6 @@
import { cx } from '../../lib';
const ctx = getContext('RadioButtonGroup');
const _class = cx(
'--radio-button-wrapper',
labelPosition !== 'right' && `--radio-button-wrapper--label-${labelPosition}`,
className
);
const _innerLabelClass = cx(hideLabel && '--visually-hidden');
let selected = ctx ? ctx.selected : writable(checked ? value : undefined);
@ -32,7 +26,9 @@
$: checked = $selected === value;
</script>
<div class={_class} {style}>
<div
class={cx('--radio-button-wrapper', labelPosition !== 'right' && `--radio-button-wrapper--label-${labelPosition}`, className)}
{style}>
<input
type="radio"
class={cx('--radio-button')}
@ -47,8 +43,8 @@
{checked}
{disabled}
{value} />
<label for={id} class={cx('--radio-button__label')}>
<label class={cx('--radio-button__label')} for={id}>
<span class={cx('--radio-button__appearance')} />
<span class={_innerLabelClass}>{labelText}</span>
<span class={cx(hideLabel && '--visually-hidden')}>{labelText}</span>
</label>
</div>

View file

@ -12,12 +12,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx(
'--radio-button-group',
orientation === 'vertical' && `--radio-button-group--${orientation}`,
labelPosition && `--radio-button-group--label-${labelPosition}`,
className
);
let selected = writable(defaultSelected);
@ -40,7 +34,9 @@
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item')} {style}>
<div class={_class} {disabled}>
<div
class={cx('--radio-button-group', orientation === 'vertical' && `--radio-button-group--${orientation}`, labelPosition && `--radio-button-group--label-${labelPosition}`, className)}
{disabled}>
<slot />
</div>
</div>

View file

@ -5,11 +5,15 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--skeleton', !small && '--search--xl', small && '--search--sm', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton', !small && '--search--xl', small && '--search--sm', className)}
{style}>
<span class={cx('--label')} />
<div class={cx('--search-input')} />
</div>

View file

@ -19,24 +19,13 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--search', size && `--search--${size}`, light && '--search--light', className);
let inputRef = undefined;
function clearInput() {
value = '';
dispatch('change', value);
if (inputRef) {
inputRef.focus();
}
}
$: _clearClass = cx('--search-close', value === '' && '--search-close--hidden');
</script>
<div class={_class} {style}>
<div
class={cx('--search', size && `--search--${size}`, light && '--search--light', className)}
{style}>
<Search16 class={cx('--search-magnifier')} />
<label for={id} class={cx('--label')}>{labelText}</label>
<input
@ -54,9 +43,13 @@
{value} />
<button
type="button"
class={_clearClass}
class={cx('--search-close', value === '' && '--search-close--hidden')}
on:click
on:click={clearInput}
on:click={() => {
value = '';
dispatch('change', value);
inputRef.focus();
}}
aria-label={closeButtonLabelText}>
<svelte:component this={size === 'xl' ? Close20 : Close16} />
</button>

View file

@ -5,11 +5,9 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
{#if !hideLabel}
<span class={cx('--label', '--skeleton')} />
{/if}

View file

@ -21,41 +21,33 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const errorId = `error-${id}`;
const _class = cx(
'--select',
inline && '--select--inline',
light && '--select--light',
invalid && '--select--invalid',
disabled && '--select--disabled',
className
);
const _labelClass = cx(
'--label',
hideLabel && '--visually-hidden',
disabled && '--label--disabled'
);
const _helperTextClass = cx('--form__helper-text', disabled && '--form__helper-text--disabled');
let selected = writable(defaultValue);
setContext('Select', { selected });
$: errorId = `error-${id}`;
$: {
selected.set(defaultValue);
dispatch('change', $selected);
}
$: defaultValue = $selected;
</script>
<div class={cx('--form-item')} {style}>
<div class={_class}>
<div
class={cx('--select', inline && '--select--inline', light && '--select--light', invalid && '--select--invalid', disabled && '--select--disabled', className)}>
{#if !noLabel}
<label for={id} class={_labelClass}>{labelText}</label>
<label
for={id}
class={cx('--label', hideLabel && '--visually-hidden', disabled && '--label--disabled')}>
{labelText}
</label>
{/if}
{#if !inline && helperText}
<div class={_helperTextClass}>{helperText}</div>
<div class={cx('--form__helper-text', disabled && '--form__helper-text--disabled')}>
{helperText}
</div>
{/if}
{#if inline}
<div class={cx('--select-input--inline__wrapper')}>
@ -81,7 +73,9 @@
{/if}
</div>
{#if helperText}
<div class={_helperTextClass}>{helperText}</div>
<div class={cx('--form__helper-text', disabled && '--form__helper-text--disabled')}>
{helperText}
</div>
{/if}
{/if}
{#if !inline}

View file

@ -11,9 +11,14 @@
import { cx } from '../../lib';
const { selected } = getContext('Select');
const _class = cx('--select-option', className);
</script>
<option class={_class} {value} {disabled} {hidden} {style} selected={$selected === value}>
<option
selected={$selected === value}
class={cx('--select-option', className)}
{value}
{disabled}
{hidden}
{style}>
{text}
</option>

View file

@ -6,10 +6,8 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--select-optgroup', className);
</script>
<optgroup class={_class} {label} {disabled} {style}>
<optgroup class={cx('--select-optgroup', className)} {label} {disabled} {style}>
<slot />
</optgroup>

View file

@ -4,8 +4,12 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--skeleton__placeholder', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave {style} class={_class} />
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton__placeholder', className)}
{style} />

View file

@ -10,13 +10,11 @@
import { cx } from '../../lib';
const randoms = [0.973051493507435, 0.15334737213558558, 0.5671034553053769];
const _class = cx('--skeleton__text', heading && '--skeleton__heading', className);
const widthNum = parseInt(width, 10);
const widthPx = width.includes('px');
const widthPercent = width.includes('%');
let lines = [];
$: widthNum = parseInt(width, 10);
$: widthPx = width.includes('px');
$: widthPercent = width.includes('%');
$: if (paragraph) {
for (let i = 0; i < lineCount; i++) {
const min = widthPx ? widthNum - 75 : 0;
@ -30,7 +28,9 @@
{#if paragraph}
<div on:click on:mouseover on:mouseenter on:mouseleave {style}>
{#each lines as { width }}
<p class={_class} style={`width: ${width};`} />
<p
class={cx('--skeleton__text', heading && '--skeleton__heading', className)}
style={`width: ${width};`} />
{/each}
</div>
{:else}
@ -39,7 +39,7 @@
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
class={cx('--skeleton__text', heading && '--skeleton__heading', className)}
style={`width: ${width};`}
{style} />
{/if}

View file

@ -2,21 +2,19 @@
let className = undefined;
export { className as class };
export let border = false;
export let rowCount = 5;
export let rows = 5;
export let style = undefined;
import { cx, fillArray } from '../../lib';
const _class = cx(
'--skeleton',
'--structured-list',
border && '--structured-list--border',
className
);
const rows = fillArray(rowCount - 1);
</script>
<section on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<section
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--skeleton', '--structured-list', border && '--structured-list--border', className)}
{style}>
<div class={cx('--structured-list-thead')}>
<div class={cx('--structured-list-row', '--structured-list-row--header-row')}>
<div class={cx('--structured-list-th')}>
@ -31,7 +29,7 @@
</div>
</div>
<div class={cx('--structured-list-tbody')}>
{#each rows as row, i (row)}
{#each fillArray(rows) as row, i (row)}
<div class={cx('--structured-list-row')}>
<div class={cx('--structured-list-td')} />
<div class={cx('--structured-list-td')} />

View file

@ -4,10 +4,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--structured-list-tbody', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--structured-list-tbody', className)}
{style}>
<slot />
</div>

View file

@ -6,15 +6,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
head && '--structured-list-th',
!head && '--structured-list-td',
noWrap && '--structured-list-content--nowrap',
className
);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx(head && '--structured-list-th', !head && '--structured-list-td', noWrap && '--structured-list-content--nowrap', className)}
{style}>
<slot />
</div>

View file

@ -4,10 +4,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--structured-list-thead', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--structured-list-thead', className)}
{style}>
<slot />
</div>

View file

@ -11,8 +11,6 @@
import { getContext } from 'svelte';
import { cx } from '../../lib';
const _class = cx('--structured-list-input', className);
const { selected, update } = getContext('StructuredListWrapper');
if (checked) {
@ -25,7 +23,7 @@
<input
type="radio"
tabindex="-1"
class={_class}
class={cx('--structured-list-input', className)}
on:change={() => {
update(value);
}}

View file

@ -7,12 +7,6 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--structured-list-row',
head && '--structured-list-row--header-row',
className
);
</script>
{#if label}
@ -23,14 +17,20 @@
on:mouseenter
on:mouseleave
on:keydown
class={_class}
class={cx('--structured-list-row', head && '--structured-list-row--header-row', className)}
for={$$props.for}
{tabindex}
{style}>
<slot />
</label>
{:else}
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--structured-list-row', head && '--structured-list-row--header-row', className)}
{style}>
<slot />
</div>
{/if}

View file

@ -11,12 +11,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx(
'--structured-list',
border && '--structured-list--border',
selection && '--structured-list--selection',
className
);
let selected = writable(defaultSelected);
@ -38,7 +32,7 @@
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
class={cx('--structured-list', border && '--structured-list--border', selection && '--structured-list--selection', className)}
aria-label={$$props['aria-label'] || 'Structured list section'}
{style}>
<slot />

View file

@ -1,5 +1,4 @@
<script>
// TODO: fix space not selecting
let className = undefined;
export { className as class };
export let role = 'presentation';
@ -23,17 +22,11 @@
$: if (selected && anchorRef) {
anchorRef.focus();
}
$: _class = cx(
'--tabs__nav-item',
disabled && '--tabs__nav-item--disabled',
selected && '--tabs__nav-item--selected',
className
);
</script>
<li
tabindex="-1"
class={_class}
class={cx('--tabs__nav-item', disabled && '--tabs__nav-item--disabled', selected && '--tabs__nav-item--selected', className)}
on:click|preventDefault={() => {
if (!disabled) {
update(id);
@ -42,16 +35,15 @@
on:mouseover
on:mouseenter
on:mouseleave
on:keydown={event => {
if (disabled) {
return;
}
if (event.key === 'ArrowRight') {
change(1);
} else if (event.key === 'ArrowLeft') {
change(-1);
} else if (event.key === ' ' || event.key === 'Enter') {
update(id);
on:keydown={({ key }) => {
if (!disabled) {
if (key === 'ArrowRight') {
change(1);
} else if (key === 'ArrowLeft') {
change(-1);
} else if (key === ' ' || key === 'Enter') {
update(id);
}
}
}}
{role}
@ -59,10 +51,10 @@
<a
bind:this={anchorRef}
role="tab"
class={cx('--tabs__nav-link')}
tabindex={disabled ? '-1' : tabindex}
aria-selected={selected}
aria-disabled={disabled}
class={cx('--tabs__nav-link')}
{href}>
{label}
</a>

View file

@ -6,7 +6,6 @@
import { getContext } from 'svelte';
import { cx } from '../../lib';
const _class = cx('--tab-content', className);
const id = Math.random();
const { selectedContent, addContent } = getContext('Tabs');
@ -15,6 +14,6 @@
$: selected = $selectedContent === id;
</script>
<div class={_class} aria-hidden={!selected} hidden={!selected} {style}>
<div aria-hidden={!selected} hidden={!selected} class={cx('--tab-content', className)} {style}>
<slot />
</div>

View file

@ -14,7 +14,7 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--tabs', type === 'container' && '--tabs--container', className);
let dropdownHidden = true;
let tabs = writable([]);
let tabsById = derived(tabs, _ => _.reduce((a, c) => ({ ...a, [c.id]: c }), {}));
@ -79,10 +79,9 @@
$: if ($selectedTab) {
dropdownHidden = true;
}
$: _listClass = cx('--tabs__nav', dropdownHidden && '--tabs__nav--hidden');
</script>
<div class={_class} {style} {role}>
<div class={cx('--tabs', type === 'container' && '--tabs--container', className)} {style} {role}>
<div
role="listbox"
tabindex="0"
@ -107,7 +106,7 @@
</a>
<ChevronDownGlyph aria-hidden="true" title={iconDescription} />
</div>
<ul role="tablist" class={_listClass}>
<ul role="tablist" class={cx('--tabs__nav', dropdownHidden && '--tabs__nav--hidden')}>
<slot />
</ul>
</div>

View file

@ -4,14 +4,18 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--tabs', '--skeleton', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--tabs', '--skeleton', className)}
{style}>
<div class={cx('--tabs-trigger')}>
<div class={cx('--tabs-trigger-text')}>&nbsp;</div>
<svg width="10" height="5" viewBox="0 0 10 5" fillRule="evenodd">
<svg width="10" height="5" viewBox="0 0 10 5" fill-rule="evenodd">
<path d="M10 0L5 5 0 0z" />
</svg>
</div>

View file

@ -4,8 +4,12 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--tag', '--skeleton', className);
</script>
<span on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} />
<span
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--tag', '--skeleton', className)}
{style} />

View file

@ -10,31 +10,19 @@
import Close16 from 'carbon-icons-svelte/lib/Close16';
import { cx } from '../../lib';
import { TYPES } from './constants';
const _class = cx(
'--tag',
type && `--tag--${type}`,
disabled && '--tag--disabled',
filter && '--tag--filter',
className
);
</script>
{#if filter}
<span
tabindex="0"
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_class}
{title}
{style}>
<slot>{TYPES[type]}</slot>
<span
tabindex={filter ? '0' : undefined}
title={filter ? title : undefined}
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--tag', type && `--tag--${type}`, disabled && '--tag--disabled', filter && '--tag--filter', className)}
{style}>
<slot>{TYPES[type]}</slot>
{#if filter}
<Close16 aria-label={title} />
</span>
{:else}
<span on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<slot>{TYPES[type]}</slot>
</span>
{/if}
{/if}
</span>

View file

@ -5,11 +5,9 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
{#if !hideLabel}
<span class={cx('--label', '--skeleton')} />
{/if}

View file

@ -20,27 +20,22 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const errorId = `${id}-error`;
const _labelClass = cx(
'--label',
hideLabel && '--visually-hidden',
disabled && '--label--disabled'
);
const _helperTextClass = cx('--form__helper-text', disabled && '--form__helper-text--disabled');
const _textAreaClass = cx(
'--text-area',
light && '--text-area--light',
invalid && '--text-area--invalid',
className
);
$: errorId = `error-${id}`;
</script>
<div on:mouseover on:mouseenter on:mouseleave class={cx('--form-item')} {style}>
{#if labelText && !hideLabel}
<label for={id} class={_labelClass}>{labelText}</label>
<label
for={id}
class={cx('--label', hideLabel && '--visually-hidden', disabled && '--label--disabled')}>
{labelText}
</label>
{/if}
{#if helperText}
<div class={_helperTextClass}>{helperText}</div>
<div class={cx('--form__helper-text', disabled && '--form__helper-text--disabled')}>
{helperText}
</div>
{/if}
<div class={cx('--text-area__wrapper')} data-invalid={invalid || undefined}>
{#if invalid}
@ -63,7 +58,7 @@
dispatch('input', event);
}
}}
class={_textAreaClass}
class={cx('--text-area', light && '--text-area--light', invalid && '--text-area--invalid', className)}
aria-invalid={invalid || undefined}
aria-describedby={invalid ? errorId : undefined}
{disabled}

View file

@ -23,45 +23,28 @@
import ViewOff16 from 'carbon-icons-svelte/lib/ViewOff16';
import { cx } from '../../lib';
const errorId = `${id}-error`;
const _labelClass = cx(
'--label',
hideLabel && '--visually-hidden',
disabled && '--label--disabled'
);
const _helperTextClass = cx('--form__helper-text', disabled && '--form__helper-text--disabled');
const _textInputClass = cx(
'--text-input',
'--password-input',
light && '--text-input--light',
invalid && '--text-input--invalid',
className
);
const _passwordVisibilityToggleClass = cx(
'--text-input--password__visibility__toggle',
'--btn--icon-only',
'--tooltip__trigger',
'--tooltip--a11y',
tooltipPosition && `--tooltip--${tooltipPosition}`,
tooltipAlignment && `--tooltip--align-${tooltipAlignment}`
);
$: passwordIsVisible = type === 'text';
$: errorId = `error-${id}`;
</script>
<div class={cx('--form-item', '--text-input-wrapper', '--password-input-wrapper')} {style}>
{#if labelText}
<label for={id} class={_labelClass}>{labelText}</label>
<label
for={id}
class={cx('--label', hideLabel && '--visually-hidden', disabled && '--label--disabled')}>
{labelText}
</label>
{/if}
{#if helperText}
<div class={_helperTextClass}>{helperText}</div>
<div class={cx('--form__helper-text', disabled && '--form__helper-text--disabled')}>
{helperText}
</div>
{/if}
<div class={cx('--text-input__field-wrapper')} data-invalid={invalid || undefined}>
{#if invalid}
<WarningFilled16 class={cx('--text-input__invalid-icon')} />
{/if}
<input
class={_textInputClass}
class={cx('--text-input', '--password-input', light && '--text-input--light', invalid && '--text-input--invalid', className)}
on:click
on:change
on:input
@ -78,15 +61,14 @@
{disabled} />
<button
type="button"
class={_passwordVisibilityToggleClass}
class={cx('--text-input--password__visibility__toggle', '--btn--icon-only', '--tooltip__trigger', '--tooltip--a11y', tooltipPosition && `--tooltip--${tooltipPosition}`, tooltipAlignment && `--tooltip--align-${tooltipAlignment}`)}
on:click={() => {
type = type === 'password' ? 'text' : 'password';
}}>
<span class={cx('--assistive-text')}>
{#if passwordIsVisible}{hidePasswordLabel}{:else}{showPasswordLabel}{/if}
{#if type === 'text'}{hidePasswordLabel}{:else}{showPasswordLabel}{/if}
</span>
{#if passwordIsVisible}
{#if type === 'text'}
<ViewOff16 class={cx('--icon-visibility-off')} />
{:else}
<View16 class={cx('--icon-visibility-on')} />

View file

@ -5,11 +5,9 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
{#if !hideLabel}
<span class={cx('--label', '--skeleton')} />
{/if}

View file

@ -17,34 +17,28 @@
import WarningFilled16 from 'carbon-icons-svelte/lib/WarningFilled16';
import { cx } from '../../lib';
const errorId = `${id}-error`;
const _labelClass = cx(
'--label',
hideLabel && '--visually-hidden',
disabled && '--label--disabled'
);
const _helperTextClass = cx('--form__helper-text', disabled && '--form__helper-text--disabled');
const _textInputClass = cx(
'--text-input',
light && '--text-input--light',
invalid && '--text-input--invalid',
className
);
$: errorId = `error-${id}`;
</script>
<div class={cx('--form-item', '--text-input-wrapper')} {style}>
{#if labelText}
<label for={id} class={_labelClass}>{labelText}</label>
<label
for={id}
class={cx('--label', hideLabel && '--visually-hidden', disabled && '--label--disabled')}>
{labelText}
</label>
{/if}
{#if helperText}
<div class={_helperTextClass}>{helperText}</div>
<div class={cx('--form__helper-text', disabled && '--form__helper-text--disabled')}>
{helperText}
</div>
{/if}
<div class={cx('--text-input__field-wrapper')} data-invalid={invalid || undefined}>
{#if invalid}
<WarningFilled16 class={cx('--text-input__invalid-icon')} />
{/if}
<input
class={_textInputClass}
class={cx('--text-input', light && '--text-input--light', invalid && '--text-input--invalid', className)}
on:click
on:change
on:input

View file

@ -8,26 +8,17 @@
export let style = undefined;
import { cx } from '../../lib';
$: _class = cx(
'--link',
'--tile',
'--tile--clickable',
clicked && '--tile--is-clicked',
light && '--tile--light',
className
);
</script>
<a
class={_class}
class={cx('--link', '--tile', '--tile--clickable', clicked && '--tile--is-clicked', light && '--tile--light', className)}
on:click
on:click={() => {
clicked = !clicked;
}}
on:keydown
on:keydown={event => {
if (event.key === ' ' || event.key === 'Enter') {
on:keydown={({ key }) => {
if (key === ' ' || key === 'Enter') {
clicked = !clicked;
}
}}

View file

@ -19,13 +19,6 @@
addTile({ id, value, checked });
$: checked = value === $selected.value;
$: _class = cx(
'--tile',
'--tile--selectable',
checked && '--tile--is-selected',
light && '--tile--light',
className
);
</script>
<input
@ -41,7 +34,7 @@
{checked} />
<label
for={id}
class={_class}
class={cx('--tile', '--tile--selectable', checked && '--tile--is-selected', light && '--tile--light', className)}
on:click
on:mouseover
on:mouseenter

View file

@ -20,13 +20,6 @@
$: if (selected) {
dispatch('select', id);
}
$: _class = cx(
'--tile',
'--tile--selectable',
selected && '--tile--is-selected',
light && '--tile--light',
className
);
</script>
<input
@ -41,7 +34,7 @@
{title} />
<label
for={id}
class={_class}
class={cx('--tile', '--tile--selectable', selected && '--tile--is-selected', light && '--tile--light', className)}
on:click
on:click|preventDefault={() => {
selected = !selected;

View file

@ -5,10 +5,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--tile', light && '--tile--light', className);
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--tile', light && '--tile--light', className)}
{style}>
<slot />
</div>

View file

@ -44,11 +44,9 @@
defaultSelected = $selected;
dispatch('select', $selected);
}
const _class = cx('--tile-group', className);
</script>
<fieldset class={_class} {disabled} {style}>
<fieldset class={cx('--tile-group', className)} {disabled} {style}>
{#if legend}
<legend>{legend}</legend>
{/if}

View file

@ -1,19 +1,19 @@
<script>
let className = undefined;
export { className as class };
export let id = undefined;
export let labelText = undefined;
export let id = Math.random();
export let labelText = '';
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
const ariaLabel = labelText ? null : $$props['aria-label'] || 'Toggle is loading';
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<input type="checkbox" class={cx('--toggle --skeleton')} {id} />
<label class={cx('--toggle__label', '--skeleton')} aria-label={ariaLabel} for={id}>
<label
aria-label={labelText ? null : $$props['aria-label'] || 'Toggle is loading'}
class={cx('--toggle__label', '--skeleton')}
for={id}>
{#if labelText}
<span class={cx('--toggle__label-text')}>{labelText}</span>
{/if}

View file

@ -13,8 +13,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--form-item', className);
const ariaLabel = labelText ? undefined : $$props['aria-label'] || 'Toggle';
let inputRef = undefined;
@ -27,7 +25,7 @@
}
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<input
bind:this={inputRef}
type="checkbox"
@ -46,7 +44,10 @@
}}
{disabled}
{id} />
<label class={cx('--toggle-input__label')} for={id} aria-label={ariaLabel}>
<label
aria-label={labelText ? undefined : $$props['aria-label'] || 'Toggle'}
class={cx('--toggle-input__label')}
for={id}>
{labelText}
<span class={cx('--toggle__switch')}>
<span aria-hidden="true" class={cx('--toggle__text--off')}>{labelA}</span>

View file

@ -1,19 +1,19 @@
<script>
let className = undefined;
export { className as class };
export let id = undefined;
export let labelText = undefined;
export let id = Math.random();
export let labelText = '';
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--form-item', className);
const ariaLabel = labelText ? undefined : $$props['aria-label'] || 'Toggle is loading';
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<input type="checkbox" class={cx('--toggle', '--toggle--small', '--skeleton')} {id} />
<label class={cx('--toggle__label --skeleton')} for={id}>
<label
aria-label={labelText ? undefined : $$props['aria-label'] || 'Toggle is loading'}
class={cx('--toggle__label --skeleton')}
for={id}>
{#if labelText}
<span class={cx('--toggle__label-text')}>{labelText}</span>
{/if}

View file

@ -13,8 +13,6 @@
import { cx } from '../../lib';
const dispatch = createEventDispatcher();
const _class = cx('--form-item', className);
const ariaLabel = labelText ? undefined : $$props['aria-label'] || 'Toggle';
let inputRef = undefined;
@ -27,7 +25,7 @@
}
</script>
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
<input
bind:this={inputRef}
type="checkbox"
@ -47,7 +45,10 @@
{disabled}
{id} />
<label class={cx('--toggle-input__label')} for={id} aria-label={ariaLabel}>
<label
aria-label={labelText ? undefined : $$props['aria-label'] || 'Toggle'}
class={cx('--toggle-input__label')}
for={id}>
{labelText}
<span class={cx('--toggle__switch')}>
<svg width="6" height="5" viewBox="0 0 6 5" class={cx('--toggle__check')}>

View file

@ -4,31 +4,20 @@
export let direction = 'bottom';
export let align = 'center';
export let id = Math.random();
export let triggerClassName = undefined;
export { triggerClassName as triggerClass };
export let triggerClass = undefined;
export let tooltipText = '';
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--tooltip--definition', '--tooltip--a11y', className);
const _triggerClass = cx(
'--tooltip__trigger',
'--tooltip--a11y',
'--tooltip__trigger--definition',
`--tooltip--${direction}`,
`--tooltip--align-${align}`,
triggerClassName
);
</script>
<div class={_class} {style}>
<div class={cx('--tooltip--definition', '--tooltip--a11y', className)} {style}>
<button
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={_triggerClass}
class={cx('--tooltip__trigger', '--tooltip--a11y', '--tooltip__trigger--definition', `--tooltip--${direction}`, `--tooltip--align-${align}`, triggerClass)}
aria-describedby={id}>
<slot />
</button>

View file

@ -8,14 +8,6 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx(
'--tooltip__trigger',
'--tooltip--a11y',
`--tooltip--${direction}`,
`--tooltip--align-${align}`,
className
);
</script>
<button
@ -24,7 +16,7 @@
on:mouseenter
on:mouseleave
aria-describedby={id}
class={_class}
class={cx('--tooltip__trigger', '--tooltip--a11y', `--tooltip--${direction}`, `--tooltip--align-${align}`, className)}
{style}>
<span class={cx('--assistive-text')} {id}>{tooltipText}</span>
<slot />

View file

@ -5,10 +5,14 @@
export let style = undefined;
import { cx } from '../../lib';
const _class = cx('--list--unordered', nested && '--list--nested', className);
</script>
<ul on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style}>
<ul
on:click
on:mouseover
on:mouseenter
on:mouseleave
class={cx('--list--unordered', nested && '--list--nested', className)}
{style}>
<slot />
</ul>