Assorted fixes

Type fixes, support a couple more classes as functions for the examples, and switch TabPanels to registering ids instead of refs
This commit is contained in:
Ryan Gossiaux
2021-12-17 14:22:19 -08:00
parent 6076a60837
commit c5ed870827
6 changed files with 37 additions and 19 deletions

View File

@@ -18,7 +18,7 @@
FocusResult, FocusResult,
focusIn, focusIn,
} from "$lib/utils/focus-management"; } from "$lib/utils/focus-management";
import { getContext, setContext, onMount } from "svelte"; import { getContext, setContext } from "svelte";
import type { Writable } from "svelte/store"; import type { Writable } from "svelte/store";
import { import {
PopoverStates, PopoverStates,

View File

@@ -44,25 +44,35 @@
"aria-labelledby": $labelContext?.labelIds, "aria-labelledby": $labelContext?.labelIds,
"aria-describedby": $descriptionContext?.descriptionIds, "aria-describedby": $descriptionContext?.descriptionIds,
}; };
$: classStyle = $$props.class
? typeof $$props.class === "function"
? $$props.class({
checked,
})
: $$props.class
: "";
</script> </script>
{#if switchStore} {#if switchStore}
<button <button
{...{ ...$$restProps, ...propsWeControl }} {...{ ...$$restProps, ...propsWeControl }}
bind:this={$switchStore} bind:this={$switchStore}
class={classStyle}
on:click={handleClick} on:click={handleClick}
on:keyup={handleKeyUp} on:keyup={handleKeyUp}
on:keypress={handleKeyPress} on:keypress={handleKeyPress}
> >
<slot /> <slot {checked} />
</button> </button>
{:else} {:else}
<button <button
{...{ ...$$restProps, ...propsWeControl }} {...{ ...$$restProps, ...propsWeControl }}
class={classStyle}
on:click={handleClick} on:click={handleClick}
on:keyup={handleKeyUp} on:keyup={handleKeyUp}
on:keypress={handleKeyPress} on:keypress={handleKeyPress}
> >
<slot /> <slot {checked} />
</button> </button>
{/if} {/if}

View File

@@ -1,4 +1,4 @@
export { default as Switch } from "./Switch.svelte"; export { default as Switch } from "./Switch.svelte";
export { default as SwitchGroup } from "./SwitchGroup.svelte"; export { default as SwitchGroup } from "./SwitchGroup.svelte";
export { default as SwitchGroupLabel } from "../label/Label.svelte"; export { default as SwitchLabel } from "../label/Label.svelte";
export { default as SwitchGroupDescription } from "../description/Description.svelte"; export { default as SwitchDescription } from "../description/Description.svelte";

View File

@@ -11,7 +11,7 @@
let api = useTabsContext("Tab"); let api = useTabsContext("Tab");
let id = `headlessui-tabs-tab-${useId()}`; let id = `headlessui-tabs-tab-${useId()}`;
let tabRef = null; let tabRef: HTMLElement | null = null;
onMount(() => { onMount(() => {
$api.registerTab(tabRef); $api.registerTab(tabRef);
@@ -80,19 +80,28 @@
$: propsWeControl = { $: propsWeControl = {
id, id,
role: "tab", role: "tab",
"aria-controls": $api.panels[myIndex]?.id, "aria-controls": $api.panels[myIndex],
"aria-selected": selected, "aria-selected": selected,
tabIndex: selected ? 0 : -1, tabIndex: selected ? 0 : -1,
disabled: disabled ? true : undefined, disabled: disabled ? true : undefined,
}; };
$: classStyle = $$props.class
? typeof $$props.class === "function"
? $$props.class({
selected,
})
: $$props.class
: "";
</script> </script>
<button <button
{...{ ...$$restProps, ...propsWeControl }} {...{ ...$$restProps, ...propsWeControl }}
bind:this={tabRef} bind:this={tabRef}
class={classStyle}
on:keydown={handleKeyDown} on:keydown={handleKeyDown}
on:click={handleSelection} on:click={handleSelection}
on:focus={$api.activation === "manual" ? handleFocus : handleSelection} on:focus={$api.activation === "manual" ? handleFocus : handleSelection}
> >
<slot /> <slot {selected} />
</button> </button>

View File

@@ -15,14 +15,14 @@
activation: "auto" | "manual"; activation: "auto" | "manual";
tabs: (HTMLElement | null)[]; tabs: (HTMLElement | null)[];
panels: (HTMLElement | null)[]; panels: string[];
// State mutators // State mutators
setSelectedIndex(index: number): void; setSelectedIndex(index: number): void;
registerTab(tab: HTMLElement | null): void; registerTab(tab: HTMLElement | null): void;
unregisterTab(tab: HTMLElement | null): void; unregisterTab(tab: HTMLElement | null): void;
registerPanel(panel: HTMLElement | null): void; registerPanel(panel: string): void;
unregisterPanel(panel: HTMLElement | null): void; unregisterPanel(panel: string): void;
}; };
const TABS_CONTEXT_NAME = "TabsContext"; const TABS_CONTEXT_NAME = "TabsContext";

View File

@@ -5,14 +5,13 @@
let api = useTabsContext("TabPanel"); let api = useTabsContext("TabPanel");
let id = `headlessui-tabs-panel-${useId()}`; let id = `headlessui-tabs-panel-${useId()}`;
let panelRef = null;
onMount(() => { onMount(() => {
$api.registerPanel(panelRef); $api.registerPanel(id);
return () => $api.unregisterPanel(panelRef); return () => $api.unregisterPanel(id);
}); });
$: myIndex = $api.panels.indexOf(panelRef); $: myIndex = $api.panels.indexOf(id);
$: selected = myIndex === $api.selectedIndex; $: selected = myIndex === $api.selectedIndex;
$: propsWeControl = { $: propsWeControl = {
@@ -23,8 +22,8 @@
}; };
</script> </script>
<div {...{ ...$$restProps, ...propsWeControl }} bind:this={panelRef}>
{#if selected} {#if selected}
<div {...{ ...$$restProps, ...propsWeControl }}>
<slot /> <slot />
{/if}
</div> </div>
{/if}