Add <Render> to Switch

This commit is contained in:
Ryan Gossiaux
2021-12-20 18:03:48 -08:00
parent 25a4b0f6e5
commit 4388273b8b
2 changed files with 51 additions and 23 deletions

View File

@@ -5,6 +5,16 @@
import { useId } from "$lib/hooks/use-id"; import { useId } from "$lib/hooks/use-id";
import { Keys } from "$lib/utils/keyboard"; import { Keys } from "$lib/utils/keyboard";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { forwardEventsBuilder } from "$lib/internal/forwardEventsBuilder";
import { get_current_component } from "svelte/internal";
import type { SupportedAs } from "$lib/internal/elements";
import type { HTMLActionArray } from "$lib/hooks/use-actions";
import Render from "$lib/utils/Render.svelte";
const forwardEvents = forwardEventsBuilder(get_current_component(), [
"change",
]);
export let as: SupportedAs = "button";
export let use: HTMLActionArray = [];
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let checked = false; export let checked = false;
@@ -18,18 +28,21 @@
dispatch("change", !checked); dispatch("change", !checked);
} }
function handleClick(event: MouseEvent) { function handleClick(e: CustomEvent) {
let event = e as any as MouseEvent;
event.preventDefault(); event.preventDefault();
toggle(); toggle();
} }
function handleKeyUp(event: KeyboardEvent) { function handleKeyUp(e: CustomEvent) {
let event = e as any as KeyboardEvent;
if (event.key !== Keys.Tab) event.preventDefault(); if (event.key !== Keys.Tab) event.preventDefault();
if (event.key === Keys.Space) toggle(); if (event.key === Keys.Space) toggle();
} }
// This is needed so that we can "cancel" the click event when we use the `Enter` key on a button. // This is needed so that we can "cancel" the click event when we use the `Enter` key on a button.
function handleKeyPress(event: KeyboardEvent) { function handleKeyPress(e: CustomEvent) {
let event = e as any as KeyboardEvent;
event.preventDefault(); event.preventDefault();
} }
@@ -42,34 +55,36 @@
"aria-describedby": $descriptionContext?.descriptionIds, "aria-describedby": $descriptionContext?.descriptionIds,
}; };
$: classStyle = $$props.class $: slot = { checked };
? typeof $$props.class === "function"
? $$props.class({
checked,
})
: $$props.class
: "";
</script> </script>
<!-- TODO: I'm sure there's a better way of doing this -->
{#if switchStore} {#if switchStore}
<button <Render
{...{ ...$$restProps, ...propsWeControl }} {...{ ...$$restProps, ...propsWeControl }}
bind:this={$switchStore} {as}
class={classStyle} {slot}
use={[...use, forwardEvents]}
name={"Switch"}
bind:el={$switchStore}
on:click={handleClick} on:click={handleClick}
on:keyup={handleKeyUp} on:keyup={handleKeyUp}
on:keypress={handleKeyPress} on:keypress={handleKeyPress}
> >
<slot {checked} /> <slot {...slot} />
</button> </Render>
{:else} {:else}
<button <Render
{...{ ...$$restProps, ...propsWeControl }} {...{ ...$$restProps, ...propsWeControl }}
class={classStyle} {as}
{slot}
use={[...use, forwardEvents]}
name={"Switch"}
bind:el={$switchStore}
on:click={handleClick} on:click={handleClick}
on:keyup={handleKeyUp} on:keyup={handleKeyUp}
on:keypress={handleKeyPress} on:keypress={handleKeyPress}
> >
<slot {checked} /> <slot {...slot} />
</button> </Render>
{/if} {/if}

View File

@@ -14,6 +14,14 @@
import LabelProvider from "$lib/components/label/LabelProvider.svelte"; import LabelProvider from "$lib/components/label/LabelProvider.svelte";
import { getContext, setContext } from "svelte"; import { getContext, setContext } from "svelte";
import { Writable, writable } from "svelte/store"; import { Writable, writable } from "svelte/store";
import { forwardEventsBuilder } from "$lib/internal/forwardEventsBuilder";
import { get_current_component } from "svelte/internal";
import type { SupportedAs } from "$lib/internal/elements";
import type { HTMLActionArray } from "$lib/hooks/use-actions";
import Render from "$lib/utils/Render.svelte";
const forwardEvents = forwardEventsBuilder(get_current_component());
export let as: SupportedAs = "div";
export let use: HTMLActionArray = [];
let switchStore: StateDefinition["switchStore"] = writable(null); let switchStore: StateDefinition["switchStore"] = writable(null);
@@ -29,10 +37,15 @@
} }
</script> </script>
<div {...$$restProps}> <Render
<DescriptionProvider name="Switch.Description"> {...$$restProps}
<LabelProvider name="Switch.Label" {onClick}> {as}
use={[...use, forwardEvents]}
name={"SwitchGroup"}
>
<DescriptionProvider name="SwitchDescription">
<LabelProvider name="SwitchLabel" {onClick}>
<slot /> <slot />
</LabelProvider> </LabelProvider>
</DescriptionProvider> </DescriptionProvider>
</div> </Render>