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,24 +17,26 @@
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;
$: buttonProps = {
role: 'button',
type: href && !disabled ? undefined : type,
tabindex,
disabled,
href,
style,
class: cx(
'--btn', '--btn',
size === 'field' && '--btn--field', size === 'field' && '--btn--field',
(size === 'small' || small) && '--btn--sm', size === 'small' && '--btn--sm',
kind === 'primary' && '--btn--primary', kind && `--btn--${kind}`,
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', disabled && '--btn--disabled',
hasIconOnly && '--btn--icon-only', hasIconOnly && '--btn--icon-only',
hasIconOnly && '--tooltip__trigger', hasIconOnly && '--tooltip__trigger',
@ -43,23 +44,15 @@
hasIconOnly && tooltipPosition && `--tooltip--${tooltipPosition}`, hasIconOnly && tooltipPosition && `--tooltip--${tooltipPosition}`,
hasIconOnly && tooltipAlignment && `--tooltip--align-${tooltipAlignment}`, hasIconOnly && tooltipAlignment && `--tooltip--align-${tooltipAlignment}`,
className className
); )
$: buttonProps = {
role: 'button',
type: href && !disabled ? undefined : type,
tabindex,
class: _class,
disabled,
href,
style
}; };
</script> </script>
{#if as} {#if as}
<slot props={buttonProps} /> <slot props={buttonProps} />
{:else} {:else if href && !disabled}
{#if href && !disabled} <!-- svelte-ignore a11y-missing-attribute -->
<a {...buttonProps} on:click on:mouseover on:mouseenter on:mouseleave {href}> <a {...buttonProps} on:click on:mouseover on:mouseenter on:mouseleave>
{#if hasIconOnly} {#if hasIconOnly}
<span class={cx('--assistive-text')}>{iconDescription}</span> <span class={cx('--assistive-text')}>{iconDescription}</span>
{/if} {/if}
@ -73,13 +66,7 @@
{/if} {/if}
</a> </a>
{:else} {:else}
<button <button {...buttonProps} bind:this={buttonRef} on:click on:mouseover on:mouseenter on:mouseleave>
{...buttonProps}
bind:this={buttonRef}
on:click
on:mouseover
on:mouseenter
on:mouseleave>
{#if hasIconOnly} {#if hasIconOnly}
<span class={cx('--assistive-text')}>{iconDescription}</span> <span class={cx('--assistive-text')}>{iconDescription}</span>
{/if} {/if}
@ -93,4 +80,3 @@
{/if} {/if}
</button> </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) { if (innerModal) {
focus(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>