This commit is contained in:
eewing
2026-02-17 14:10:16 -06:00
parent 2bca5834c5
commit cf73cd3b4c
11246 changed files with 1690552 additions and 0 deletions
@@ -0,0 +1,31 @@
<script lang="ts">
import { boxWith } from "svelte-toolbelt";
import { CommandLabelState } from "../command.svelte.js";
import type { WithChildren } from "../../../internal/types.js";
import { createId } from "../../../internal/create-id.js";
import { mergeProps } from "svelte-toolbelt";
import type { BitsPrimitiveLabelAttributes, WithElementRef } from "../../../shared/index.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
children,
...restProps
}: WithChildren<WithElementRef<BitsPrimitiveLabelAttributes>> = $props();
const labelState = CommandLabelState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, labelState.props));
</script>
<label {...mergedProps}>
{@render children?.()}
</label>
@@ -0,0 +1,5 @@
import type { WithChildren } from "../../../internal/types.js";
import type { BitsPrimitiveLabelAttributes, WithElementRef } from "../../../shared/index.js";
declare const CommandLabel: import("svelte").Component<WithChildren<WithElementRef<BitsPrimitiveLabelAttributes>>, {}, "ref">;
type CommandLabel = ReturnType<typeof CommandLabel>;
export default CommandLabel;
+38
View File
@@ -0,0 +1,38 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandEmptyProps } from "../types.js";
import { CommandEmptyState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
children,
child,
forceMount = false,
...restProps
}: CommandEmptyProps = $props();
const emptyState = CommandEmptyState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
forceMount: boxWith(() => forceMount),
});
const mergedProps = $derived(mergeProps(emptyState.props, restProps));
</script>
{#if emptyState.shouldRender}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
{/if}
@@ -0,0 +1,4 @@
import type { CommandEmptyProps } from "../types.js";
declare const CommandEmpty: import("svelte").Component<CommandEmptyProps, {}, "ref">;
type CommandEmpty = ReturnType<typeof CommandEmpty>;
export default CommandEmpty;
@@ -0,0 +1,34 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import { CommandGroupHeadingState } from "../command.svelte.js";
import type { CommandGroupHeadingProps } from "../types.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
children,
child,
...restProps
}: CommandGroupHeadingProps = $props();
const headingState = CommandGroupHeadingState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, headingState.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
@@ -0,0 +1,4 @@
import type { CommandGroupHeadingProps } from "../types.js";
declare const CommandGroupHeading: import("svelte").Component<CommandGroupHeadingProps, {}, "ref">;
type CommandGroupHeading = ReturnType<typeof CommandGroupHeading>;
export default CommandGroupHeading;
@@ -0,0 +1,36 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandGroupItemsProps } from "../types.js";
import { CommandGroupItemsState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
children,
child,
...restProps
}: CommandGroupItemsProps = $props();
const groupItemsState = CommandGroupItemsState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, groupItemsState.props));
</script>
<div style="display: contents;">
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
</div>
@@ -0,0 +1,4 @@
import type { CommandGroupItemsProps } from "../types.js";
declare const CommandGroupItems: import("svelte").Component<CommandGroupItemsProps, {}, "ref">;
type CommandGroupItems = ReturnType<typeof CommandGroupItems>;
export default CommandGroupItems;
+38
View File
@@ -0,0 +1,38 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandGroupProps } from "../types.js";
import { CommandGroupContainerState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
value = "",
forceMount = false,
children,
child,
...restProps
}: CommandGroupProps = $props();
const groupState = CommandGroupContainerState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
forceMount: boxWith(() => forceMount),
value: boxWith(() => value),
});
const mergedProps = $derived(mergeProps(restProps, groupState.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
@@ -0,0 +1,4 @@
import type { CommandGroupProps } from "../types.js";
declare const CommandGroup: import("svelte").Component<CommandGroupProps, {}, "ref">;
type CommandGroup = ReturnType<typeof CommandGroup>;
export default CommandGroup;
+40
View File
@@ -0,0 +1,40 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandInputProps } from "../types.js";
import { CommandInputState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
value = $bindable(""),
autofocus = false,
id = createId(uid),
ref = $bindable(null),
child,
...restProps
}: CommandInputProps = $props();
const inputState = CommandInputState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
value: boxWith(
() => value,
(v) => {
value = v;
}
),
autofocus: boxWith(() => autofocus ?? false),
});
const mergedProps = $derived(mergeProps(restProps, inputState.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<input {...mergedProps} bind:value />
{/if}
@@ -0,0 +1,4 @@
import type { CommandInputProps } from "../types.js";
declare const CommandInput: import("svelte").Component<CommandInputProps, {}, "value" | "ref">;
type CommandInput = ReturnType<typeof CommandInput>;
export default CommandInput;
+51
View File
@@ -0,0 +1,51 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandItemProps } from "../types.js";
import { CommandItemState } from "../command.svelte.js";
import { noop } from "../../../internal/noop.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
value = "",
disabled = false,
children,
child,
onSelect = noop,
forceMount = false,
keywords = [],
...restProps
}: CommandItemProps = $props();
const itemState = CommandItemState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
value: boxWith(() => value),
disabled: boxWith(() => disabled),
onSelect: boxWith(() => onSelect),
forceMount: boxWith(() => forceMount),
keywords: boxWith(() => keywords),
});
const mergedProps = $derived(mergeProps(restProps, itemState.props));
</script>
{#key itemState.root.key}
<div style="display: contents;" data-item-wrapper data-value={itemState.trueValue}>
{#if itemState.shouldRender}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
{/if}
</div>
{/key}
@@ -0,0 +1,4 @@
import type { CommandItemProps } from "../types.js";
declare const CommandItem: import("svelte").Component<CommandItemProps, {}, "ref">;
type CommandItem = ReturnType<typeof CommandItem>;
export default CommandItem;
@@ -0,0 +1,51 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandLinkItemProps } from "../types.js";
import { CommandItemState } from "../command.svelte.js";
import { noop } from "../../../internal/noop.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
value = "",
disabled = false,
children,
child,
onSelect = noop,
forceMount = false,
keywords = [],
...restProps
}: CommandLinkItemProps = $props();
const itemState = CommandItemState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
value: boxWith(() => value),
disabled: boxWith(() => disabled),
onSelect: boxWith(() => onSelect),
forceMount: boxWith(() => forceMount),
keywords: boxWith(() => keywords),
});
const mergedProps = $derived(mergeProps(restProps, itemState.props));
</script>
{#key itemState.root.key}
<div style="display: contents;">
{#if itemState.shouldRender}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<a {...mergedProps}>
{@render children?.()}
</a>
{/if}
{/if}
</div>
{/key}
@@ -0,0 +1,4 @@
import type { CommandLinkItemProps } from "../types.js";
declare const CommandLinkItem: import("svelte").Component<CommandLinkItemProps, {}, "ref">;
type CommandLinkItem = ReturnType<typeof CommandLinkItem>;
export default CommandLinkItem;
+38
View File
@@ -0,0 +1,38 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandListProps } from "../types.js";
import { CommandListState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
child,
children,
"aria-label": ariaLabel,
...restProps
}: CommandListProps = $props();
const listState = CommandListState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
ariaLabel: boxWith(() => ariaLabel ?? "Suggestions..."),
});
const mergedProps = $derived(mergeProps(restProps, listState.props));
</script>
{#key listState.root._commandState.search === ""}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
{/key}
@@ -0,0 +1,4 @@
import type { CommandListProps } from "../types.js";
declare const CommandList: import("svelte").Component<CommandListProps, {}, "ref">;
type CommandList = ReturnType<typeof CommandList>;
export default CommandList;
@@ -0,0 +1,36 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandLoadingProps } from "../types.js";
import { CommandLoadingState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
progress = 0,
id = createId(uid),
ref = $bindable(null),
children,
child,
...restProps
}: CommandLoadingProps = $props();
const loadingState = CommandLoadingState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
progress: boxWith(() => progress),
});
const mergedProps = $derived(mergeProps(restProps, loadingState.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
@@ -0,0 +1,4 @@
import type { CommandLoadingProps } from "../types.js";
declare const CommandLoading: import("svelte").Component<CommandLoadingProps, {}, "ref">;
type CommandLoading = ReturnType<typeof CommandLoading>;
export default CommandLoading;
@@ -0,0 +1,38 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import type { CommandSeparatorProps } from "../types.js";
import { CommandSeparatorState } from "../command.svelte.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
forceMount = false,
children,
child,
...restProps
}: CommandSeparatorProps = $props();
const separatorState = CommandSeparatorState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
forceMount: boxWith(() => forceMount),
});
const mergedProps = $derived(mergeProps(restProps, separatorState.props));
</script>
{#if separatorState.shouldRender}
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
{/if}
@@ -0,0 +1,4 @@
import type { CommandSeparatorProps } from "../types.js";
declare const CommandSeparator: import("svelte").Component<CommandSeparatorProps, {}, "ref">;
type CommandSeparator = ReturnType<typeof CommandSeparator>;
export default CommandSeparator;
@@ -0,0 +1,34 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import { CommandViewportState } from "../command.svelte.js";
import type { CommandViewportProps } from "../types.js";
import { createId } from "../../../internal/create-id.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
children,
child,
...restProps
}: CommandViewportProps = $props();
const listViewportState = CommandViewportState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
});
const mergedProps = $derived(mergeProps(restProps, listViewportState.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
@@ -0,0 +1,4 @@
import type { CommandViewportProps } from "../types.js";
declare const CommandViewport: import("svelte").Component<CommandViewportProps, {}, "ref">;
type CommandViewport = ReturnType<typeof CommandViewport>;
export default CommandViewport;
+137
View File
@@ -0,0 +1,137 @@
<script lang="ts">
import { boxWith, mergeProps } from "svelte-toolbelt";
import { CommandRootState } from "../command.svelte.js";
import type { CommandRootProps } from "../types.js";
import CommandLabel from "./_command-label.svelte";
import { noop } from "../../../internal/noop.js";
import { createId } from "../../../internal/create-id.js";
import { computeCommandScore } from "../index.js";
const uid = $props.id();
let {
id = createId(uid),
ref = $bindable(null),
value = $bindable(""),
onValueChange = noop,
onStateChange = noop,
loop = false,
shouldFilter = true,
filter = computeCommandScore,
label = "",
vimBindings = true,
disablePointerSelection = false,
disableInitialScroll = false,
columns = null,
children,
child,
...restProps
}: CommandRootProps = $props();
const rootState = CommandRootState.create({
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
filter: boxWith(() => filter),
shouldFilter: boxWith(() => shouldFilter),
loop: boxWith(() => loop),
value: boxWith(
() => value,
(v) => {
if (value !== v) {
value = v;
onValueChange(v);
}
}
),
vimBindings: boxWith(() => vimBindings),
disablePointerSelection: boxWith(() => disablePointerSelection),
disableInitialScroll: boxWith(() => disableInitialScroll),
onStateChange: boxWith(() => onStateChange),
columns: boxWith(() => columns),
});
// Imperative APIs - DO NOT REMOVE OR RENAME
/**
* Sets selection to item at specified index in valid items array.
* If index is out of bounds, does nothing.
*
* @param index - Zero-based index of item to select
* @remarks
* Uses `getValidItems()` to get selectable items, filtering out disabled/hidden ones.
* Access valid items directly via `getValidItems()` to check bounds before calling.
*
* @example
* // get valid items length for bounds check
* const items = getValidItems()
* if (index < items.length) {
* updateSelectedToIndex(index)
* }
*/
export const updateSelectedToIndex: (typeof rootState)["updateSelectedToIndex"] = (i) =>
rootState.updateSelectedToIndex(i);
/**
* Moves selection to the first valid item in the next/previous group.
* If no group is found, falls back to selecting the next/previous item globally.
*
* @param change - Direction to move: 1 for next group, -1 for previous group
* @example
* // move to first item in next group
* updateSelectedByGroup(1)
*
* // move to first item in previous group
* updateSelectedByGroup(-1)
*/
export const updateSelectedByGroup: (typeof rootState)["updateSelectedByGroup"] = (c) =>
rootState.updateSelectedByGroup(c);
/**
* Updates selected item by moving up/down relative to current selection.
* Handles wrapping when loop option is enabled.
*
* @param change - Direction to move: 1 for next item, -1 for previous item
* @remarks
* The loop behavior wraps:
* - From last item to first when moving next
* - From first item to last when moving previous
*
* Uses `getValidItems()` to get all selectable items, which filters out disabled/hidden items.
* You can call `getValidItems()` directly to get the current valid items array.
*
* @example
* // select next item
* updateSelectedByItem(1)
*
* // get all valid items
* const items = getValidItems()
*/
export const updateSelectedByItem: (typeof rootState)["updateSelectedByItem"] = (c) =>
rootState.updateSelectedByItem(c);
/**
* Gets all non-disabled, visible command items.
*
* @returns Array of valid item elements
* @remarks Exposed for direct item access and bound checking
*/
export const getValidItems = () => rootState.getValidItems();
const mergedProps = $derived(mergeProps(restProps, rootState.props));
</script>
{#snippet Label()}
<CommandLabel>
{label}
</CommandLabel>
{/snippet}
{#if child}
{@render Label()}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render Label()}
{@render children?.()}
</div>
{/if}
+59
View File
@@ -0,0 +1,59 @@
import type { CommandRootProps } from "../types.js";
declare const Command: import("svelte").Component<CommandRootProps, {
/**
* Sets selection to item at specified index in valid items array.
* If index is out of bounds, does nothing.
*
* @param index - Zero-based index of item to select
* @remarks
* Uses `getValidItems()` to get selectable items, filtering out disabled/hidden ones.
* Access valid items directly via `getValidItems()` to check bounds before calling.
*
* @example
* // get valid items length for bounds check
* const items = getValidItems()
* if (index < items.length) {
* updateSelectedToIndex(index)
* }
*/ updateSelectedToIndex: (index: number) => void;
/**
* Moves selection to the first valid item in the next/previous group.
* If no group is found, falls back to selecting the next/previous item globally.
*
* @param change - Direction to move: 1 for next group, -1 for previous group
* @example
* // move to first item in next group
* updateSelectedByGroup(1)
*
* // move to first item in previous group
* updateSelectedByGroup(-1)
*/ updateSelectedByGroup: (change: 1 | -1) => void;
/**
* Updates selected item by moving up/down relative to current selection.
* Handles wrapping when loop option is enabled.
*
* @param change - Direction to move: 1 for next item, -1 for previous item
* @remarks
* The loop behavior wraps:
* - From last item to first when moving next
* - From first item to last when moving previous
*
* Uses `getValidItems()` to get all selectable items, which filters out disabled/hidden items.
* You can call `getValidItems()` directly to get the current valid items array.
*
* @example
* // select next item
* updateSelectedByItem(1)
*
* // get all valid items
* const items = getValidItems()
*/ updateSelectedByItem: (change: number) => void;
/**
* Gets all non-disabled, visible command items.
*
* @returns Array of valid item elements
* @remarks Exposed for direct item access and bound checking
*/ getValidItems: () => HTMLElement[];
}, "value" | "ref">;
type Command = ReturnType<typeof Command>;
export default Command;