refactor(composed-modal): register buttonRef directly

This commit is contained in:
Eric Liu 2019-12-24 09:37:35 -08:00
commit ffb6f477b9
2 changed files with 59 additions and 75 deletions

View file

@ -4,7 +4,6 @@
export let as = undefined; export let as = undefined;
export let disabled = false; export let disabled = false;
export let size = 'default'; export let size = 'default';
export let small = false;
export let kind = 'primary'; export let kind = 'primary';
export let href = undefined; export let href = undefined;
export let tabindex = '0'; export let tabindex = '0';
@ -18,79 +17,66 @@
import { getContext } from 'svelte'; import { getContext } from 'svelte';
import { cx } from '../../lib'; import { cx } from '../../lib';
const hasIconOnly = !!icon && !$$props.$$slots;
const ctx = getContext('ComposedModal'); const ctx = getContext('ComposedModal');
let buttonRef = undefined; let buttonRef = undefined;
$: if (ctx && buttonRef) { $: if (ctx && buttonRef) {
ctx.declareRef({ name: 'buttonRef', ref: buttonRef }); ctx.declareRef(buttonRef);
} }
$: _class = cx( $: hasIconOnly = !!icon && !$$props.$$slots;
'--btn',
size === 'field' && '--btn--field',
(size === 'small' || small) && '--btn--sm',
kind === 'primary' && '--btn--primary',
kind === 'danger' && '--btn--danger',
kind === 'secondary' && '--btn--secondary',
kind === 'ghost' && '--btn--ghost',
kind === 'danger--primary' && '--btn--danger--primary',
kind === 'tertiary' && '--btn--tertiary',
disabled && '--btn--disabled',
hasIconOnly && '--btn--icon-only',
hasIconOnly && '--tooltip__trigger',
hasIconOnly && '--tooltip--a11y',
hasIconOnly && tooltipPosition && `--tooltip--${tooltipPosition}`,
hasIconOnly && tooltipAlignment && `--tooltip--align-${tooltipAlignment}`,
className
);
$: buttonProps = { $: buttonProps = {
role: 'button', role: 'button',
type: href && !disabled ? undefined : type, type: href && !disabled ? undefined : type,
tabindex, tabindex,
class: _class,
disabled, disabled,
href, href,
style style,
class: cx(
'--btn',
size === 'field' && '--btn--field',
size === 'small' && '--btn--sm',
kind && `--btn--${kind}`,
disabled && '--btn--disabled',
hasIconOnly && '--btn--icon-only',
hasIconOnly && '--tooltip__trigger',
hasIconOnly && '--tooltip--a11y',
hasIconOnly && tooltipPosition && `--tooltip--${tooltipPosition}`,
hasIconOnly && tooltipAlignment && `--tooltip--align-${tooltipAlignment}`,
className
)
}; };
</script> </script>
{#if as} {#if as}
<slot props={buttonProps} /> <slot props={buttonProps} />
{:else if href && !disabled}
<!-- svelte-ignore a11y-missing-attribute -->
<a {...buttonProps} on:click on:mouseover on:mouseenter on:mouseleave>
{#if hasIconOnly}
<span class={cx('--assistive-text')}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class={cx('--btn__icon')}
aria-label={iconDescription} />
{/if}
</a>
{:else} {:else}
{#if href && !disabled} <button {...buttonProps} bind:this={buttonRef} on:click on:mouseover on:mouseenter on:mouseleave>
<a {...buttonProps} on:click on:mouseover on:mouseenter on:mouseleave {href}> {#if hasIconOnly}
{#if hasIconOnly} <span class={cx('--assistive-text')}>{iconDescription}</span>
<span class={cx('--assistive-text')}>{iconDescription}</span> {/if}
{/if} <slot />
<slot /> {#if icon}
{#if icon} <svelte:component
<svelte:component this={icon}
this={icon} aria-hidden="true"
aria-hidden="true" class={cx('--btn__icon')}
class={cx('--btn__icon')} aria-label={iconDescription} />
aria-label={iconDescription} /> {/if}
{/if} </button>
</a>
{:else}
<button
{...buttonProps}
bind:this={buttonRef}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly}
<span class={cx('--assistive-text')}>{iconDescription}</span>
{/if}
<slot />
{#if icon}
<svelte:component
this={icon}
aria-hidden="true"
class={cx('--btn__icon')}
aria-label={iconDescription} />
{/if}
</button>
{/if}
{/if} {/if}

View file

@ -13,7 +13,8 @@
import { cx } from '../../lib'; import { cx } from '../../lib';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
const refs = {};
let buttonRef = undefined;
let outerModal = undefined; let outerModal = undefined;
let innerModal = undefined; let innerModal = undefined;
@ -24,8 +25,8 @@
submit: () => { submit: () => {
dispatch('submit'); dispatch('submit');
}, },
declareRef: ({ name, ref }) => { declareRef: ref => {
refs[name] = ref; buttonRef = ref;
} }
}); });
@ -38,22 +39,17 @@
return focusElement.focus(); return focusElement.focus();
} }
if (refs.buttonRef) { if (buttonRef) {
refs.buttonRef.focus(); buttonRef.focus();
} }
} }
const _containerClass = cx(
'--modal-container',
size && `--modal-container--${size}`,
containerClass
);
$: didOpen = open; $: didOpen = open;
$: _class = cx('--modal', open && 'is-visible', danger && '--modal--danger', className);
$: if (innerModal) {
focus(innerModal);
}
$: { $: {
if (innerModal) {
focus(innerModal);
}
if (open) { if (open) {
document.body.classList.add(cx('--body--with-modal-open')); document.body.classList.add(cx('--body--with-modal-open'));
} else { } else {
@ -64,10 +60,10 @@
</script> </script>
<div <div
bind:this={outerModal}
role="presentation" role="presentation"
tabindex="-1" tabindex="-1"
bind:this={outerModal} class={cx('--modal', open && 'is-visible', danger && '--modal--danger', className)}
class={_class}
on:click on:click
on:click={({ target }) => { on:click={({ target }) => {
if (!innerModal.contains(target)) { if (!innerModal.contains(target)) {
@ -85,7 +81,9 @@
} }
}} }}
{style}> {style}>
<div bind:this={innerModal} class={_containerClass}> <div
bind:this={innerModal}
class={cx('--modal-container', size && `--modal-container--${size}`, containerClass)}>
<slot /> <slot />
</div> </div>
</div> </div>