Skip to content

Commit

Permalink
Added DisabledProvider to replace hardcoded
Browse files Browse the repository at this point in the history
  • Loading branch information
sureshjoshi committed Dec 9, 2024
1 parent bee514e commit 94282fd
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 50 deletions.
3 changes: 2 additions & 1 deletion src/lib/button/Button.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { type Component, type Snippet } from "svelte";
import { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the button should render as. */
Expand Down Expand Up @@ -30,7 +31,7 @@
let {
as = "button",
autofocus = false,
disabled = false,
disabled = useDisabled() || false,
type = "button",
children,
...theirProps
Expand Down
3 changes: 2 additions & 1 deletion src/lib/checkbox/Checkbox.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import type { Component, Snippet } from "svelte";
import { useId } from "../../hooks/use-id";
import { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the checkbox should render as. */
Expand Down Expand Up @@ -54,7 +55,7 @@
as = "span",
autofocus = false,
checked = false,
disabled = false,
disabled = useDisabled() || false,
indeterminate = false,
children,
...theirProps
Expand Down
41 changes: 24 additions & 17 deletions src/lib/field/Field.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { type Component, getContext, setContext, type Snippet } from "svelte";
import { useId } from "../../hooks/use-id";
import LabelProvider from "$lib/label/LabelProvider.svelte";
import DisabledProvider, { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the checkbox should render as. */
Expand All @@ -15,7 +16,8 @@
/** Whether or not the field is disabled. */
disabled?: boolean;
};
let providedDisabled = getContext<boolean>("headlessui-disabled-context");
let providedDisabled = useDisabled();
let {
id = `headlessui-control-${useId()}`,
Expand All @@ -26,8 +28,8 @@
}: Props & Record<string, any> = $props();
let ourProps = $derived({
disabled,
"aria-disabled": disabled,
disabled: disabled || undefined,
"aria-disabled": disabled || undefined,
});
let snippetProps: SnippetProps = $derived({
Expand All @@ -38,19 +40,24 @@
let dataAttributes: DataAttributes<SnippetProps> = $derived({
"data-disabled": disabled || undefined,
});
setContext("headlessui-disabled-context", disabled);
</script>

<LabelProvider name="FieldLabel">
{#if typeof as === "string"}
<svelte:element this={as} {...theirProps} {...ourProps} {...dataAttributes}>
{@render children?.(snippetProps)}
</svelte:element>
{:else}
{@const AsComponent = as}
<AsComponent {...theirProps} {...ourProps} {...dataAttributes}>
{@render children?.(snippetProps)}
</AsComponent>
{/if}
</LabelProvider>
<DisabledProvider {disabled}>
<LabelProvider name="FieldLabel">
{#if typeof as === "string"}
<svelte:element
this={as}
{...theirProps}
{...ourProps}
{...dataAttributes}
>
{@render children?.(snippetProps)}
</svelte:element>
{:else}
{@const AsComponent = as}
<AsComponent {...theirProps} {...ourProps} {...dataAttributes}>
{@render children?.(snippetProps)}
</AsComponent>
{/if}
</LabelProvider>
</DisabledProvider>
56 changes: 29 additions & 27 deletions src/lib/fieldset/Fieldset.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { type Component, getContext, setContext, type Snippet } from "svelte";
import LabelProvider from "$lib/label/LabelProvider.svelte";
import DisabledProvider, { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the fieldset should render as. */
Expand All @@ -15,7 +16,7 @@
disabled?: boolean;
};
let providedDisabled = getContext<boolean>("headlessui-disabled-context");
let providedDisabled = useDisabled();
let {
as = "fieldset",
Expand All @@ -38,31 +39,32 @@
let dataAttributes: DataAttributes<SnippetProps> = $derived({
"data-disabled": disabled || undefined,
});
setContext("headlessui-disabled-context", disabled);
</script>

<LabelProvider name="FieldsetLabel">
{#snippet labelledBy({ labelIds })}
{#if typeof as === "string"}
<svelte:element
this={as}
{...theirProps}
{...ourProps}
{...dataAttributes}
aria-labelledby={labelIds[0]}
>
{@render children?.(snippetProps)}
</svelte:element>
{:else}
{@const AsComponent = as}
<AsComponent
{...theirProps}
{...ourProps}
{...dataAttributes}
aria-labelledby={labelIds}
>
{@render children?.(snippetProps)}
</AsComponent>
{/if}
{/snippet}
</LabelProvider>
<DisabledProvider {disabled}>
<LabelProvider name="FieldsetLabel">
{#snippet labelledBy({ labelIds })}
{#if typeof as === "string"}
<svelte:element
this={as}
{...theirProps}
{...ourProps}
{...dataAttributes}
aria-labelledby={labelIds[0]}
>
{@render children?.(snippetProps)}
</svelte:element>
{:else}
{@const AsComponent = as}
<AsComponent
{...theirProps}
{...ourProps}
{...dataAttributes}
aria-labelledby={labelIds}
>
{@render children?.(snippetProps)}
</AsComponent>
{/if}
{/snippet}
</LabelProvider>
</DisabledProvider>
3 changes: 2 additions & 1 deletion src/lib/input/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { type Component, type Snippet } from "svelte";
import { useId } from "../../hooks/use-id";
import { useLabelledBy } from "$lib/label/LabelProvider.svelte";
import { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the input should render as. */
Expand Down Expand Up @@ -32,7 +33,7 @@
id = `headlessui-input-${useId()}`,
as = "input",
autofocus = false,
disabled = false,
disabled = useDisabled() || false,
invalid = false,
children,
...theirProps
Expand Down
28 changes: 28 additions & 0 deletions src/lib/internal/DisabledProvider.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script module lang="ts">
import { getContext, type Snippet } from "svelte";
export const DISABLED_CONTEXT_NAME = Symbol("headlessui-disabled-context");
export function useDisabled(): boolean {
return getContext<boolean>(DISABLED_CONTEXT_NAME);
}
</script>

<script lang="ts">
import { setContext } from "svelte";
type Props = {
/** Whether or not the children should be disabled. */
disabled?: boolean;
children?: Snippet<[SnippetProps]>;
};
type SnippetProps = {
disabled?: boolean;
};
let { disabled, children }: Props = $props();
setContext(DISABLED_CONTEXT_NAME, disabled);
</script>

<!-- TODO: I hate this snippet children vs non-children naming convention so much -->
{@render children?.({ disabled })}
3 changes: 2 additions & 1 deletion src/lib/label/Label.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { type Component, onMount, type Snippet } from "svelte";
import { useId } from "../../hooks/use-id";
import { useLabelContext } from "./LabelProvider.svelte";
import { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the input should render as. */
Expand Down Expand Up @@ -40,7 +41,7 @@
onclick,
});
let disabled = false;
let disabled = useDisabled() || false;
let snippetProps: SnippetProps = $derived({
disabled,
Expand Down
3 changes: 2 additions & 1 deletion src/lib/switch/Switch.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { Component, Snippet } from "svelte";
import { resolveButtonType } from "../../utils/resolve-button-type";
import { useId } from "../../hooks/use-id";
import { useDisabled } from "$lib/internal/DisabledProvider.svelte";
type Props = {
/** The element or component the Switch should render as. */
Expand Down Expand Up @@ -53,7 +54,7 @@
as = "button",
// checked = $bindable(false),
checked = false,
disabled = false,
disabled = useDisabled() || false,
tabIndex = 0,
type = undefined,
children,
Expand Down
2 changes: 1 addition & 1 deletion src/routes/examples/fieldset/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</script>

<div class="w-full max-w-lg px-4">
<Fieldset class="space-y-6 rounded-xl bg-white/5 p-6 sm:p-10">
<Fieldset class="space-y-6 rounded-xl bg-white/5 p-6 sm:p-10" disabled>
<Legend class="text-base/7 font-semibold text-white">Shipping details</Legend>
<Field>
<Label class="text-sm/6 font-medium text-white">Street address</Label>
Expand Down

0 comments on commit 94282fd

Please sign in to comment.