diff --git a/packages/bits-ui/src/lib/bits/context-menu/index.ts b/packages/bits-ui/src/lib/bits/context-menu/index.ts
index 4e5ec7739..a3f352acf 100644
--- a/packages/bits-ui/src/lib/bits/context-menu/index.ts
+++ b/packages/bits-ui/src/lib/bits/context-menu/index.ts
@@ -2,7 +2,7 @@ export { default as Root } from "$lib/bits/menu/components/menu.svelte";
export { default as Sub } from "$lib/bits/menu/components/menu-sub.svelte";
export { default as Item } from "$lib/bits/menu/components/menu-item.svelte";
export { default as Group } from "$lib/bits/menu/components/menu-group.svelte";
-export { default as Label } from "$lib/bits/menu/components/menu-label.svelte";
+export { default as Label } from "$lib/bits/menu/components/menu-group-label.svelte";
export { default as Arrow } from "$lib/bits/menu/components/menu-arrow.svelte";
export { default as Content } from "./components/context-menu-content.svelte";
export { default as Trigger } from "./components/context-menu-trigger.svelte";
@@ -19,7 +19,7 @@ export type {
ContextMenuCheckboxItemProps as CheckboxItemProps,
ContextMenuGroupProps as GroupProps,
ContextMenuItemProps as ItemProps,
- ContextMenuLabelProps as LabelProps,
+ ContextMenuGroupLabelProps as GroupLabelProps,
ContextMenuRootProps as RootProps,
ContextMenuRadioGroupProps as RadioGroupProps,
ContextMenuRadioItemProps as RadioItemProps,
diff --git a/packages/bits-ui/src/lib/bits/context-menu/types.ts b/packages/bits-ui/src/lib/bits/context-menu/types.ts
index 6e73f6282..8463ba88e 100644
--- a/packages/bits-ui/src/lib/bits/context-menu/types.ts
+++ b/packages/bits-ui/src/lib/bits/context-menu/types.ts
@@ -25,7 +25,7 @@ export type {
CheckboxItemProps as ContextMenuCheckboxItemProps,
GroupProps as ContextMenuGroupProps,
ItemProps as ContextMenuItemProps,
- LabelProps as ContextMenuLabelProps,
+ GroupLabelProps as ContextMenuGroupLabelProps,
RootProps as ContextMenuRootProps,
RadioGroupProps as ContextMenuRadioGroupProps,
RadioItemProps as ContextMenuRadioItemProps,
@@ -42,7 +42,7 @@ export type {
MenuCheckboxItemPropsWithoutHTML as ContextMenuCheckboxItemPropsWithoutHTML,
MenuGroupPropsWithoutHTML as ContextMenuGroupPropsWithoutHTML,
MenuItemPropsWithoutHTML as ContextMenuItemPropsWithoutHTML,
- MenuLabelPropsWithoutHTML as ContextMenuLabelPropsWithoutHTML,
+ MenuGroupLabelPropsWithoutHTML as ContextMenuLabelPropsWithoutHTML,
MenuRadioGroupPropsWithoutHTML as ContextMenuRadioGroupPropsWithoutHTML,
MenuRadioItemPropsWithoutHTML as ContextMenuRadioItemPropsWithoutHTML,
MenuSeparatorPropsWithoutHTML as ContextMenuSeparatorPropsWithoutHTML,
diff --git a/packages/bits-ui/src/lib/bits/dropdown-menu/index.ts b/packages/bits-ui/src/lib/bits/dropdown-menu/index.ts
index db8eb7702..ebc2427bd 100644
--- a/packages/bits-ui/src/lib/bits/dropdown-menu/index.ts
+++ b/packages/bits-ui/src/lib/bits/dropdown-menu/index.ts
@@ -2,7 +2,7 @@ export { default as Root } from "$lib/bits/menu/components/menu.svelte";
export { default as Sub } from "$lib/bits/menu/components/menu-sub.svelte";
export { default as Item } from "$lib/bits/menu/components/menu-item.svelte";
export { default as Group } from "$lib/bits/menu/components/menu-group.svelte";
-export { default as Label } from "$lib/bits/menu/components/menu-label.svelte";
+export { default as GroupLabel } from "$lib/bits/menu/components/menu-group-label.svelte";
export { default as Arrow } from "$lib/bits/menu/components/menu-arrow.svelte";
export { default as Content } from "./components/dropdown-menu-content.svelte";
export { default as Trigger } from "$lib/bits/menu/components/menu-trigger.svelte";
@@ -20,7 +20,7 @@ export type {
DropdownMenuContentProps as ContentProps,
DropdownMenuGroupProps as GroupProps,
DropdownMenuItemProps as ItemProps,
- DropdownMenuLabelProps as LabelProps,
+ DropdownMenuGroupLabelProps as GroupLabelProps,
DropdownMenuRootProps as RootProps,
DropdownMenuRadioGroupProps as RadioGroupProps,
DropdownMenuRadioItemProps as RadioItemProps,
diff --git a/packages/bits-ui/src/lib/bits/dropdown-menu/types.ts b/packages/bits-ui/src/lib/bits/dropdown-menu/types.ts
index 96cd15353..8e5b729a4 100644
--- a/packages/bits-ui/src/lib/bits/dropdown-menu/types.ts
+++ b/packages/bits-ui/src/lib/bits/dropdown-menu/types.ts
@@ -4,7 +4,7 @@ export type {
ContentProps as DropdownMenuContentProps,
GroupProps as DropdownMenuGroupProps,
ItemProps as DropdownMenuItemProps,
- LabelProps as DropdownMenuLabelProps,
+ GroupLabelProps as DropdownMenuGroupLabelProps,
RootProps as DropdownMenuRootProps,
RadioGroupProps as DropdownMenuRadioGroupProps,
RadioItemProps as DropdownMenuRadioItemProps,
@@ -23,7 +23,7 @@ export type {
MenuContentPropsWithoutHTML as DropdownMenuContentPropsWithoutHTML,
MenuGroupPropsWithoutHTML as DropdownMenuGroupPropsWithoutHTML,
MenuItemPropsWithoutHTML as DropdownMenuItemPropsWithoutHTML,
- MenuLabelPropsWithoutHTML as DropdownMenuLabelPropsWithoutHTML,
+ MenuGroupLabelPropsWithoutHTML as DropdownMenuLabelPropsWithoutHTML,
MenuRadioGroupPropsWithoutHTML as DropdownMenuRadioGroupPropsWithoutHTML,
MenuRadioItemPropsWithoutHTML as DropdownMenuRadioItemPropsWithoutHTML,
MenuSeparatorPropsWithoutHTML as DropdownMenuSeparatorPropsWithoutHTML,
diff --git a/packages/bits-ui/src/lib/bits/menu/components/menu-label.svelte b/packages/bits-ui/src/lib/bits/menu/components/menu-group-label.svelte
similarity index 72%
rename from packages/bits-ui/src/lib/bits/menu/components/menu-label.svelte
rename to packages/bits-ui/src/lib/bits/menu/components/menu-group-label.svelte
index 7ef3ac847..023464753 100644
--- a/packages/bits-ui/src/lib/bits/menu/components/menu-label.svelte
+++ b/packages/bits-ui/src/lib/bits/menu/components/menu-group-label.svelte
@@ -1,6 +1,6 @@
{#if child}
diff --git a/packages/bits-ui/src/lib/bits/menu/index.ts b/packages/bits-ui/src/lib/bits/menu/index.ts
index 1ab2e66ef..204dec8a8 100644
--- a/packages/bits-ui/src/lib/bits/menu/index.ts
+++ b/packages/bits-ui/src/lib/bits/menu/index.ts
@@ -4,7 +4,7 @@ export { default as CheckboxItem } from "./components/menu-checkbox-item.svelte"
export { default as Content } from "./components/menu-content.svelte";
export { default as Group } from "./components/menu-group.svelte";
export { default as Item } from "./components/menu-item.svelte";
-export { default as Label } from "./components/menu-label.svelte";
+export { default as GroupLabel } from "./components/menu-group-label.svelte";
export { default as Portal } from "$lib/bits/utilities/portal/portal.svelte";
export { default as RadioGroup } from "./components/menu-radio-group.svelte";
export { default as RadioItem } from "./components/menu-radio-item.svelte";
@@ -24,7 +24,7 @@ export type {
MenuSeparatorProps as SeparatorProps,
MenuArrowProps as ArrowProps,
MenuCheckboxItemProps as CheckboxItemProps,
- MenuLabelProps as LabelProps,
+ MenuGroupLabelProps as GroupLabelProps,
MenuGroupProps as GroupProps,
MenuRadioGroupProps as RadioGroupProps,
MenuRadioItemProps as RadioItemProps,
diff --git a/packages/bits-ui/src/lib/bits/menu/menu.svelte.ts b/packages/bits-ui/src/lib/bits/menu/menu.svelte.ts
index 557f94257..aa822bd9e 100644
--- a/packages/bits-ui/src/lib/bits/menu/menu.svelte.ts
+++ b/packages/bits-ui/src/lib/bits/menu/menu.svelte.ts
@@ -20,7 +20,7 @@ import { addEventListener } from "$lib/internal/events.js";
import type { AnyFn, WithRefProps } from "$lib/internal/types.js";
import { executeCallbacks } from "$lib/internal/callbacks.js";
import { useTypeahead } from "$lib/internal/useTypeahead.svelte.js";
-import { isBrowser, isElement, isHTMLElement } from "$lib/internal/is.js";
+import { isElement, isHTMLElement } from "$lib/internal/is.js";
import { useRovingFocus } from "$lib/internal/useRovingFocus.svelte.js";
import { kbd } from "$lib/internal/kbd.js";
import {
@@ -61,6 +61,8 @@ const [setMenuMenuContext, getMenuMenuContext] = createContext(
const [setMenuContentContext, getMenuContentContext] =
createContext("Menu.Content");
+const [setMenuGroupContext, getMenuGroupContext] = createContext("Menu.Group");
+
const [setMenuRadioGroupContext, getMenuRadioGroupContext] =
createContext("Menu.RadioGroup");
@@ -698,6 +700,7 @@ type MenuGroupStateProps = WithRefProps;
class MenuGroupState {
#id: MenuGroupStateProps["id"];
#ref: MenuGroupStateProps["ref"];
+ labelNode = $state(null);
constructor(props: MenuGroupStateProps) {
this.#id = props.id;
@@ -714,23 +717,33 @@ class MenuGroupState {
({
id: this.#id.current,
role: "group",
+ "aria-labelledby": this.labelNode?.id ?? undefined,
[GROUP_ATTR]: "",
}) as const
);
+
+ createGroupLabel(props: MenuGroupLabelStateProps) {
+ return new MenuGroupLabelState(props, this);
+ }
}
-type MenuLabelStateProps = WithRefProps;
-class MenuLabelState {
- #id: MenuLabelStateProps["id"];
- #ref: MenuLabelStateProps["ref"];
+type MenuGroupLabelStateProps = WithRefProps;
+class MenuGroupLabelState {
+ #id: MenuGroupLabelStateProps["id"];
+ #ref: MenuGroupLabelStateProps["ref"];
+ #group: MenuGroupState;
- constructor(props: MenuLabelStateProps) {
+ constructor(props: MenuGroupLabelStateProps, group: MenuGroupState) {
this.#id = props.id;
this.#ref = props.ref;
+ this.#group = group;
useRefById({
id: this.#id,
ref: this.#ref,
+ onRefChange: (node) => {
+ this.#group.labelNode = node;
+ },
});
}
@@ -1114,11 +1127,11 @@ export function useMenuRadioItem(props: MenuRadioItemStateProps & MenuItemCombin
}
export function useMenuGroup(props: MenuGroupStateProps) {
- return new MenuGroupState(props);
+ return setMenuGroupContext(new MenuGroupState(props));
}
-export function useMenuLabel(props: MenuLabelStateProps) {
- return new MenuLabelState(props);
+export function useMenuLabel(props: MenuGroupLabelStateProps) {
+ return getMenuGroupContext().createGroupLabel(props);
}
export function useMenuSeparator(props: MenuSeparatorStateProps) {
diff --git a/packages/bits-ui/src/lib/bits/menu/types.ts b/packages/bits-ui/src/lib/bits/menu/types.ts
index c90c37085..150faf253 100644
--- a/packages/bits-ui/src/lib/bits/menu/types.ts
+++ b/packages/bits-ui/src/lib/bits/menu/types.ts
@@ -125,9 +125,9 @@ export type MenuGroupPropsWithoutHTML = WithChild;
export type MenuGroupProps = MenuGroupPropsWithoutHTML &
Without;
-export type MenuLabelPropsWithoutHTML = WithChild;
-export type MenuLabelProps = MenuLabelPropsWithoutHTML &
- Without;
+export type MenuGroupLabelPropsWithoutHTML = WithChild;
+export type MenuGroupLabelProps = MenuGroupLabelPropsWithoutHTML &
+ Without;
export type MenuRadioGroupPropsWithoutHTML = WithChild<{
/**
diff --git a/packages/bits-ui/src/lib/bits/menubar/index.ts b/packages/bits-ui/src/lib/bits/menubar/index.ts
index ee7ec284f..6ce7763aa 100644
--- a/packages/bits-ui/src/lib/bits/menubar/index.ts
+++ b/packages/bits-ui/src/lib/bits/menubar/index.ts
@@ -5,7 +5,7 @@ export { default as Trigger } from "./components/menubar-trigger.svelte";
export { default as Sub } from "$lib/bits/menu/components/menu-sub.svelte";
export { default as Item } from "$lib/bits/menu/components/menu-item.svelte";
export { default as Group } from "$lib/bits/menu/components/menu-group.svelte";
-export { default as Label } from "$lib/bits/menu/components/menu-label.svelte";
+export { default as Label } from "$lib/bits/menu/components/menu-group-label.svelte";
export { default as Arrow } from "$lib/bits/menu/components/menu-arrow.svelte";
export { default as RadioItem } from "$lib/bits/menu/components/menu-radio-item.svelte";
export { default as Separator } from "$lib/bits/menu/components/menu-separator.svelte";
@@ -25,7 +25,7 @@ export type {
MenuSubPropsWithoutHTML as SubProps,
MenuItemProps as ItemProps,
MenuGroupProps as GroupProps,
- MenuLabelProps as LabelProps,
+ MenuGroupLabelProps as LabelProps,
MenuArrowProps as ArrowProps,
MenuRadioItemProps as RadioItemProps,
MenuSeparatorProps as SeparatorProps,
diff --git a/packages/bits-ui/src/lib/bits/menubar/types.ts b/packages/bits-ui/src/lib/bits/menubar/types.ts
index dfb728945..dde65b005 100644
--- a/packages/bits-ui/src/lib/bits/menubar/types.ts
+++ b/packages/bits-ui/src/lib/bits/menubar/types.ts
@@ -1,7 +1,8 @@
-import type { MenuContentProps, MenuContentPropsWithoutHTML } from "../menu/types.js";
import type { OnChangeFn, WithChild, WithChildren, Without } from "$lib/internal/types.js";
import type { PrimitiveButtonAttributes, PrimitiveDivAttributes } from "$lib/shared/attributes.js";
import type { Direction } from "$lib/shared/index.js";
+import type { ArrowPropsWithoutHTML } from "../utilities/arrow/types.js";
+import type { ArrowProps } from "../menu/index.js";
export type MenubarRootPropsWithoutHTML = WithChild<{
/**
@@ -51,6 +52,30 @@ export type MenubarTriggerPropsWithoutHTML = WithChild<{
export type MenubarTriggerProps = MenubarTriggerPropsWithoutHTML &
Without;
-export type MenubarContentPropsWithoutHTML = MenuContentPropsWithoutHTML;
+export type {
+ MenuContentPropsWithoutHTML as MenubarContentPropsWithoutHTML,
+ MenuContentProps as MenubarContentProps,
+ MenuItemPropsWithoutHTML as MenubarItemPropsWithoutHTML,
+ MenuItemProps as MenubarItemProps,
+ MenuGroupPropsWithoutHTML as MenubarGroupPropsWithoutHTML,
+ MenuGroupProps as MenubarGroupProps,
+ MenuGroupLabelPropsWithoutHTML as MenubarGroupLabelPropsWithoutHTML,
+ MenuGroupLabelProps as MenubarGroupLabelProps,
+ MenuCheckboxItemPropsWithoutHTML as MenubarCheckboxItemPropsWithoutHTML,
+ MenuCheckboxItemProps as MenubarCheckboxItemProps,
+ MenuRadioGroupPropsWithoutHTML as MenubarRadioGroupPropsWithoutHTML,
+ MenuRadioGroupProps as MenubarRadioGroupProps,
+ MenuRadioItemPropsWithoutHTML as MenubarRadioItemPropsWithoutHTML,
+ MenuRadioItemProps as MenubarRadioItemProps,
+ MenuSeparatorPropsWithoutHTML as MenubarSeparatorPropsWithoutHTML,
+ MenuSeparatorProps as MenubarSeparatorProps,
+ MenuSubContentPropsWithoutHTML as MenubarSubContentPropsWithoutHTML,
+ MenuSubContentProps as MenubarSubContentProps,
+ MenuSubTriggerPropsWithoutHTML as MenubarSubTriggerPropsWithoutHTML,
+ MenuSubTriggerProps as MenubarSubTriggerProps,
+ MenuSubPropsWithoutHTML as MenubarSubPropsWithoutHTML,
+} from "../menu/types.js";
-export type MenubarContentProps = MenuContentProps;
+export type MenubarArrowPropsWithoutHTML = ArrowPropsWithoutHTML;
+
+export type MenubarArrowProps = ArrowProps;
diff --git a/packages/bits-ui/src/lib/bits/navigation-menu/types.ts b/packages/bits-ui/src/lib/bits/navigation-menu/types.ts
index 485131c8e..a1506a7de 100644
--- a/packages/bits-ui/src/lib/bits/navigation-menu/types.ts
+++ b/packages/bits-ui/src/lib/bits/navigation-menu/types.ts
@@ -25,16 +25,22 @@ export type NavigationMenuRootPropsWithoutHTML = WithChild<{
/**
* The duration from when the mouse enters a trigger until the content opens.
+ *
+ * @defaultValue 200
*/
delayDuration?: number;
/**
* How much time a user has to enter another trigger without incurring a delay again.
+ *
+ * @defaultValue 300
*/
skipDelayDuration?: number;
/**
* The reading direction of the content.
+ *
+ * @defaultValue "ltr"
*/
dir?: Direction;
diff --git a/packages/bits-ui/src/lib/bits/select/types.ts b/packages/bits-ui/src/lib/bits/select/types.ts
index bf59c11c9..e3228585f 100644
--- a/packages/bits-ui/src/lib/bits/select/types.ts
+++ b/packages/bits-ui/src/lib/bits/select/types.ts
@@ -64,7 +64,7 @@ export type SelectRootPropsWithoutHTML = WithChildren<{
export type SelectRootProps = SelectRootPropsWithoutHTML;
export type SelectContentImplPropsWithoutHTML = WithChild<
- PopperLayerProps & {
+ Omit & {
/**
* The positioning mode to use
*
diff --git a/packages/bits-ui/src/lib/bits/switch/types.ts b/packages/bits-ui/src/lib/bits/switch/types.ts
index 20e8bb132..3027bfc38 100644
--- a/packages/bits-ui/src/lib/bits/switch/types.ts
+++ b/packages/bits-ui/src/lib/bits/switch/types.ts
@@ -47,10 +47,6 @@ export type SwitchRootPropsWithoutHTML = WithChild<
* A callback function called when the checked state changes.
*/
onCheckedChange?: OnChangeFn;
-
- onclick?: EventCallback;
-
- onkeydown?: EventCallback;
},
SwitchRootSnippetProps
>;
diff --git a/packages/bits-ui/src/lib/bits/tabs/types.ts b/packages/bits-ui/src/lib/bits/tabs/types.ts
index 4897791e3..fa909a844 100644
--- a/packages/bits-ui/src/lib/bits/tabs/types.ts
+++ b/packages/bits-ui/src/lib/bits/tabs/types.ts
@@ -35,7 +35,7 @@ export type TabsRootPropsWithoutHTML = WithChild<{
* will be activated when the trigger is focused. If set to `'manual'`,
* the tabs will be activated when the trigger is pressed.
*
- * @defaultValue true
+ * @defaultValue "automatic"
*/
activationMode?: TabsActivationMode;
diff --git a/packages/bits-ui/src/lib/bits/utilities/focus-scope/types.ts b/packages/bits-ui/src/lib/bits/utilities/focus-scope/types.ts
index e7e3c8cb3..352885b5f 100644
--- a/packages/bits-ui/src/lib/bits/utilities/focus-scope/types.ts
+++ b/packages/bits-ui/src/lib/bits/utilities/focus-scope/types.ts
@@ -14,6 +14,13 @@ export type FocusScopeProps = {
* Can be prevented.
*/
onDestroyAutoFocus?: EventCallback;
+
+ /**
+ * When `true` will loop through the tabbable elements in the focus scope.
+ *
+ * @defaultValue false
+ */
+ loop?: boolean;
};
export type FocusScopeImplProps = {
@@ -29,12 +36,5 @@ export type FocusScopeImplProps = {
*/
trapped?: boolean;
- /**
- * When `true` will loop through the tabbable elements in the focus scope.
- *
- * @defaultValue false
- */
- loop?: boolean;
-
focusScope?: Snippet<[{ props: FocusScopeContainerProps }]>;
} & FocusScopeProps;
diff --git a/packages/bits-ui/src/tests/dropdown-menu/DropdownMenuTest.svelte b/packages/bits-ui/src/tests/dropdown-menu/DropdownMenuTest.svelte
index 508b34383..2163c1520 100644
--- a/packages/bits-ui/src/tests/dropdown-menu/DropdownMenuTest.svelte
+++ b/packages/bits-ui/src/tests/dropdown-menu/DropdownMenuTest.svelte
@@ -35,7 +35,7 @@
- Stuff
+ Stuff
item
diff --git a/sites/docs/src/lib/content/api-reference/helpers.ts b/sites/docs/src/lib/content/api-reference/helpers.ts
index 37432fed6..3ccf7288c 100644
--- a/sites/docs/src/lib/content/api-reference/helpers.ts
+++ b/sites/docs/src/lib/content/api-reference/helpers.ts
@@ -21,6 +21,8 @@ type ElementKind =
| "HTMLHeadingElement"
| "HTMLImageElement"
| "HTMLInputElement"
+ | "HTMLUListElement"
+ | "HTMLLiElement"
| "HTMLElement";
export function domElProps(elType: ElementKind) {
diff --git a/sites/docs/src/lib/content/api-reference/index.ts b/sites/docs/src/lib/content/api-reference/index.ts
index ebb16fff5..285f112ec 100644
--- a/sites/docs/src/lib/content/api-reference/index.ts
+++ b/sites/docs/src/lib/content/api-reference/index.ts
@@ -16,6 +16,7 @@ import { dialog } from "./dialog.js";
import { dropdownMenu } from "./dropdown-menu.js";
import { label } from "./label.js";
import { linkPreview } from "./link-preview.js";
+import { navigationMenu } from "./navigation-menu.js";
import { pagination } from "./pagination.js";
import { pinInput } from "./pin-input.js";
import { popover } from "./popover.js";
@@ -33,6 +34,7 @@ import { toggle } from "./toggle.js";
import { toolbar } from "./toolbar.js";
import { tooltip } from "./tooltip.js";
import type { APISchema } from "$lib/types/index.js";
+import { menubar } from "./menubar.js";
export const bits = [
"accordion",
@@ -53,7 +55,6 @@ export const bits = [
"dropdown-menu",
"label",
"link-preview",
- "listbox",
"menubar",
"navigation-menu",
"pagination",
@@ -101,7 +102,8 @@ export const apiSchemas: Record = {
"dropdown-menu": dropdownMenu,
label,
"link-preview": linkPreview,
- listbox: linkPreview,
+ menubar: menubar,
+ "navigation-menu": navigationMenu,
pagination,
"pin-input": pinInput,
popover,
diff --git a/sites/docs/src/lib/content/api-reference/menu.ts b/sites/docs/src/lib/content/api-reference/menu.ts
index fafa5ebfe..027e2427d 100644
--- a/sites/docs/src/lib/content/api-reference/menu.ts
+++ b/sites/docs/src/lib/content/api-reference/menu.ts
@@ -93,20 +93,18 @@ const contentProps = {
forceMount: forceMountProp,
preventOverflowTextSelection: preventOverflowTextSelectionProp,
dir: dirProp,
+ loop: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description:
+ "Whether or not to loop through the menu items in when navigating with the keyboard.",
+ },
...withChildProps({ elType: "HTMLDivElement" }),
} satisfies PropObj;
-const subContentProps = {
- ...floatingProps(),
- ...escapeLayerProps,
- ...dismissableLayerProps,
- ...focusScopeProps,
- forceMount: forceMountProp,
- preventScroll: preventScrollProp(),
- preventOverflowTextSelection: preventOverflowTextSelectionProp,
- ...withChildProps({ elType: "HTMLDivElement" }),
- dir: dirProp,
-} satisfies PropObj>;
+const subContentProps = contentProps satisfies PropObj<
+ Omit
+>;
const checkboxItemProps = {
disabled: {
diff --git a/sites/docs/src/lib/content/api-reference/menubar.ts b/sites/docs/src/lib/content/api-reference/menubar.ts
index 4f08d0424..a4cff4672 100644
--- a/sites/docs/src/lib/content/api-reference/menubar.ts
+++ b/sites/docs/src/lib/content/api-reference/menubar.ts
@@ -1,172 +1,165 @@
-// import type {
-// MenubarArrowPropsWithoutHTML,
-// MenubarCheckboxIndicatorPropsWithoutHTML,
-// MenubarCheckboxItemPropsWithoutHTML,
-// MenubarContentPropsWithoutHTML,
-// MenubarGroupPropsWithoutHTML,
-// MenubarItemPropsWithoutHTML,
-// MenubarLabelPropsWithoutHTML,
-// MenubarMenuPropsWithoutHTML,
-// MenubarPropsWithoutHTML,
-// MenubarRadioGroupPropsWithoutHTML,
-// MenubarRadioIndicatorPropsWithoutHTML,
-// MenubarRadioItemPropsWithoutHTML,
-// MenubarSeparatorPropsWithoutHTML,
-// MenubarSubContentPropsWithoutHTML,
-// MenubarSubPropsWithoutHTML,
-// MenubarSubTriggerPropsWithoutHTML,
-// MenubarTriggerPropsWithoutHTML,
-// } from "bits-ui";
-// import { builderAndAttrsSlotProps, domElProps } from "./helpers.js";
-// import { menu as m } from "./menu.js";
-// import { idsSlotProp } from "$lib/content/api-reference/helpers.js";
-// import * as C from "$lib/content/constants.js";
-// import type { APISchema } from "$lib/types/index.js";
-
-// export const root: APISchema = {
-// title: "Root",
-// description: "The root menubar component which manages & scopes the state of the menubar.",
-// props: {
-// closeOnEscape: {
-// default: C.TRUE,
-// type: C.BOOLEAN,
-// description: "Whether to close the open menubar menu when the escape key is pressed.",
-// },
-// loop: {
-// default: C.TRUE,
-// type: C.BOOLEAN,
-// description:
-// "Whether or not to loop through the menubar menu triggers when navigating with the keyboard.",
-// },
-// preventScroll: {
-// default: C.FALSE,
-// type: C.BOOLEAN,
-// description:
-// "Whether or not to prevent scrolling the body while a menu in the menubar is open.",
-// },
-// ...domElProps("HTMLDivElement"),
-// },
-// slotProps: { ...builderAndAttrsSlotProps, ids: idsSlotProp },
-// };
-
-// export const menu: APISchema = {
-// title: "Menu",
-// description: "A menu within the menubar.",
-// ...m.root,
-// };
-
-// export const trigger: APISchema = {
-// title: "Trigger",
-// description: "The button element which toggles the dropdown menu.",
-// ...m.trigger,
-// };
-
-// export const content: APISchema = {
-// title: "Content",
-// description: "The content displayed when the dropdown menu is open.",
-// ...m.content,
-// };
-
-// export const item: APISchema = {
-// title: "Item",
-// description: "A menu item within the dropdown menu.",
-// ...m.item,
-// };
-
-// export const separator: APISchema = {
-// title: "Separator",
-// description: "A horizontal line to visually separate menu items.",
-// ...m.separator,
-// };
-
-// export const arrow: APISchema = {
-// title: "Arrow",
-// description: "An optional arrow which points to the dropdown menu's anchor/trigger point.",
-// ...m.arrow,
-// };
-
-// export const checkboxItem: APISchema = {
-// title: "CheckboxItem",
-// description: "A menu item that can be controlled and toggled like a checkbox.",
-// ...m.checkboxItem,
-// };
-
-// export const checkboxIndicator: APISchema = {
-// title: "CheckboxIndicator",
-// description:
-// "A visual indicator of the checkbox menu item's checked state. It passed the item's checked state as a slot prop `checked` and can be used to render a custom indicator.",
-// ...m.checkboxIndicator,
-// };
-
-// export const radioGroup: APISchema = {
-// title: "RadioGroup",
-// description: "A group of radio menu items, where only one can be checked at a time.",
-// ...m.radioGroup,
-// };
-
-// export const radioItem: APISchema = {
-// title: "RadioItem",
-// description:
-// "A menu item that can be controlled and toggled like a radio button. It must be a child of a `RadioGroup`.",
-// ...m.radioItem,
-// };
-
-// export const radioIndicator: APISchema = {
-// title: "RadioIndicator",
-// description:
-// "A visual indicator helper for `RadioItem`s. It only renders it's children when the radio item is checked.",
-// ...m.radioIndicator,
-// };
-
-// export const sub: APISchema = {
-// title: "Sub",
-// description:
-// "A submenu belonging to the parent dropdown menu. Responsible for managing the state of the submenu.",
-// ...m.sub,
-// };
-
-// export const subTrigger: APISchema = {
-// title: "SubTrigger",
-// description: "A menu item which when pressed or hovered, opens the submenu.",
-// ...m.subTrigger,
-// };
-
-// export const subContent: APISchema = {
-// title: "SubContent",
-// description: "The submenu content displayed when the parent submenu is open.",
-// ...m.subContent,
-// };
-
-// export const group: APISchema = {
-// title: "Group",
-// description:
-// "A group of menu items. It can be used along with the `Menu.Label` component to provide a visual label for a group of menu items. When a label is within a group, appropriate aria attributes will be applied to the group.",
-// ...m.group,
-// };
-
-// export const label: APISchema = {
-// title: "Label",
-// description:
-// "A label which will be skipped when navigating with the keyboard. It is used to provide a visual label for a group of menu items. When a label is within a `Menu.Group`, appropriate aria attributes will be applied to the group.",
-// ...m.label,
-// };
-
-// export const menubar = [
-// root,
-// menu,
-// trigger,
-// content,
-// item,
-// checkboxItem,
-// checkboxIndicator,
-// radioGroup,
-// radioItem,
-// radioIndicator,
-// separator,
-// arrow,
-// group,
-// label,
-// sub,
-// subTrigger,
-// subContent,
-// ];
+import type {
+ MenubarArrowPropsWithoutHTML,
+ MenubarCheckboxItemPropsWithoutHTML,
+ MenubarContentPropsWithoutHTML,
+ MenubarGroupPropsWithoutHTML,
+ MenubarItemPropsWithoutHTML,
+ MenubarGroupLabelPropsWithoutHTML,
+ MenubarMenuPropsWithoutHTML,
+ MenubarRootPropsWithoutHTML,
+ MenubarRadioGroupPropsWithoutHTML,
+ MenubarRadioItemPropsWithoutHTML,
+ MenubarSeparatorPropsWithoutHTML,
+ MenubarSubContentPropsWithoutHTML,
+ MenubarSubPropsWithoutHTML,
+ MenubarSubTriggerPropsWithoutHTML,
+ MenubarTriggerPropsWithoutHTML,
+} from "bits-ui";
+import { builderAndAttrsSlotProps, dirProp, domElProps, withChildProps } from "./helpers.js";
+import { menu as m } from "./menu.js";
+import { idsSlotProp } from "$lib/content/api-reference/helpers.js";
+import * as C from "$lib/content/constants.js";
+import type { APISchema } from "$lib/types/index.js";
+
+export const root: APISchema = {
+ title: "Root",
+ description: "The root menubar component which manages & scopes the state of the menubar.",
+ props: {
+ value: {
+ type: C.STRING,
+ description: "The value of the currently active menu.",
+ bindable: true,
+ },
+ dir: dirProp,
+ onValueChange: {
+ type: {
+ type: C.FUNCTION,
+ definition: "(value: string | undefined) => void",
+ },
+ description: "A callback function called when the active menu value changes.",
+ },
+ loop: {
+ default: C.TRUE,
+ type: C.BOOLEAN,
+ description:
+ "Whether or not to loop through the menubar menu triggers when navigating with the keyboard.",
+ },
+
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
+ slotProps: { ...builderAndAttrsSlotProps, ids: idsSlotProp },
+};
+
+export const menu: APISchema = {
+ title: "Menu",
+ description: "A menu within the menubar.",
+ ...m.root,
+ props: {
+ value: {
+ type: C.STRING,
+ description:
+ "The value of this menu within the menubar, used to identify it when determining which menu is active.",
+ },
+ ...m.root.props,
+ },
+};
+
+export const trigger: APISchema = {
+ title: "Trigger",
+ description: "The button element which toggles the dropdown menu.",
+ ...m.trigger,
+};
+
+export const content: APISchema = {
+ title: "Content",
+ description: "The content displayed when the dropdown menu is open.",
+ ...m.content,
+};
+
+export const item: APISchema = {
+ title: "Item",
+ description: "A menu item within the dropdown menu.",
+ ...m.item,
+};
+
+export const separator: APISchema = {
+ title: "Separator",
+ description: "A horizontal line to visually separate menu items.",
+ ...m.separator,
+};
+
+export const arrow: APISchema = {
+ title: "Arrow",
+ description: "An optional arrow which points to the dropdown menu's anchor/trigger point.",
+ ...m.arrow,
+};
+
+export const checkboxItem: APISchema = {
+ title: "CheckboxItem",
+ description: "A menu item that can be controlled and toggled like a checkbox.",
+ ...m.checkboxItem,
+};
+
+export const radioGroup: APISchema = {
+ title: "RadioGroup",
+ description: "A group of radio menu items, where only one can be checked at a time.",
+ ...m.radioGroup,
+};
+
+export const radioItem: APISchema = {
+ title: "RadioItem",
+ description:
+ "A menu item that can be controlled and toggled like a radio button. It must be a child of a `RadioGroup`.",
+ ...m.radioItem,
+};
+
+export const sub: APISchema = {
+ title: "Sub",
+ description:
+ "A submenu belonging to the parent dropdown menu. Responsible for managing the state of the submenu.",
+ ...m.sub,
+};
+
+export const subTrigger: APISchema = {
+ title: "SubTrigger",
+ description: "A menu item which when pressed or hovered, opens the submenu.",
+ ...m.subTrigger,
+};
+
+export const subContent: APISchema = {
+ title: "SubContent",
+ description: "The submenu content displayed when the parent submenu is open.",
+ ...m.subContent,
+};
+
+export const group: APISchema = {
+ title: "Group",
+ description:
+ "A group of menu items. It can be used along with the `Menu.Label` component to provide a visual label for a group of menu items. When a label is within a group, appropriate aria attributes will be applied to the group.",
+ ...m.group,
+};
+
+export const groupLabel: APISchema = {
+ title: "GroupLabel",
+ description:
+ "A label which will be skipped when navigating with the keyboard. It is used to provide a visual label for a group of menu items. When a label is within a `Menu.Group`, appropriate aria attributes will be applied to the group.",
+ ...m.label,
+};
+
+export const menubar = [
+ root,
+ menu,
+ trigger,
+ content,
+ item,
+ checkboxItem,
+ radioGroup,
+ radioItem,
+ separator,
+ arrow,
+ group,
+ groupLabel,
+ sub,
+ subTrigger,
+ subContent,
+];
diff --git a/sites/docs/src/lib/content/api-reference/navigation-menu.ts b/sites/docs/src/lib/content/api-reference/navigation-menu.ts
new file mode 100644
index 000000000..2b0d5d8d6
--- /dev/null
+++ b/sites/docs/src/lib/content/api-reference/navigation-menu.ts
@@ -0,0 +1,150 @@
+import type {
+ NavigationMenuRootPropsWithoutHTML,
+ NavigationMenuContentPropsWithoutHTML,
+ NavigationMenuIndicatorPropsWithoutHTML,
+ NavigationMenuItemPropsWithoutHTML,
+ NavigationMenuLinkPropsWithoutHTML,
+ NavigationMenuListPropsWithoutHTML,
+ NavigationMenuTriggerPropsWithoutHTML,
+ NavigationMenuViewportPropsWithoutHTML,
+} from "bits-ui";
+import {
+ dirProp,
+ dismissableLayerProps,
+ enums,
+ escapeLayerProps,
+ floatingProps,
+ forceMountProp,
+ withChildProps,
+} from "./helpers.js";
+import * as C from "$lib/content/constants.js";
+import type { APISchema } from "$lib/types/index.js";
+
+export const root: APISchema = {
+ title: "Root",
+ description:
+ "The root navigation menu component which manages & scopes the state of the navigation menu.",
+ props: {
+ value: {
+ type: C.STRING,
+ description: "The value of the currently active menu.",
+ bindable: true,
+ },
+ onValueChange: {
+ type: {
+ type: C.FUNCTION,
+ definition: "(value: string | undefined) => void",
+ },
+ description: "A callback function called when the active menu value changes.",
+ },
+ dir: dirProp,
+ skipDelayDuration: {
+ type: C.NUMBER,
+ default: "300",
+ description:
+ "How much time a user has to enter another trigger without incurring a delay again.",
+ },
+ delayDuration: {
+ type: C.NUMBER,
+ default: "200",
+ description:
+ "The duration from when the mouse enters a trigger until the content opens.",
+ },
+ orientation: {
+ type: {
+ type: C.ENUM,
+ definition: enums("horizontal", "vertical"),
+ },
+ default: "horizontal",
+ description: "The orientation of the menu.",
+ },
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
+};
+
+export const list: APISchema = {
+ title: "List",
+ description: "A menu within the menubar.",
+ props: {
+ ...withChildProps({ elType: "HTMLUListElement" }),
+ },
+};
+
+export const item: APISchema = {
+ title: "Item",
+ description: "A list item within the navigation menu.",
+ props: {
+ value: {
+ type: C.STRING,
+ description: "The value of the item.",
+ },
+ ...withChildProps({ elType: "HTMLLiElement" }),
+ },
+};
+
+export const trigger: APISchema = {
+ title: "Trigger",
+ description: "The button element which toggles the dropdown menu.",
+ props: {
+ disabled: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description: "Whether or not the trigger is disabled.",
+ },
+ ...withChildProps({ elType: "HTMLButtonElement" }),
+ },
+};
+
+export const content: APISchema = {
+ title: "Content",
+ description: "The content displayed when the dropdown menu is open.",
+ props: {
+ ...floatingProps(),
+ ...dismissableLayerProps,
+ ...escapeLayerProps,
+ forceMount: forceMountProp,
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
+};
+
+export const link: APISchema = {
+ title: "Link",
+ description: "A link within the navigation menu.",
+ props: {
+ active: {
+ type: C.BOOLEAN,
+ default: C.FALSE,
+ description: "Whether or not the link is active.",
+ },
+ onSelect: {
+ type: {
+ type: C.FUNCTION,
+ definition: "() => void",
+ },
+ description: "A callback function called when the link is selected.",
+ },
+ ...withChildProps({ elType: "HTMLAnchorElement" }),
+ },
+};
+
+export const indicator: APISchema = {
+ title: "Indicator",
+ description:
+ "The indicator element for the navigation menu, which is used to indicate the current active item.",
+ props: {
+ forceMount: forceMountProp,
+ ...withChildProps({ elType: "HTMLSpanElement" }),
+ },
+};
+
+export const viewport: APISchema = {
+ title: "Viewport",
+ description:
+ "The viewport element for the navigation menu, which is used to contain the menu items.",
+ props: {
+ forceMount: forceMountProp,
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
+};
+
+export const navigationMenu = [root, list, item, trigger, content, link, viewport, indicator];
diff --git a/sites/docs/src/lib/content/api-reference/select.ts b/sites/docs/src/lib/content/api-reference/select.ts
index 7bd9519a0..d855efd06 100644
--- a/sites/docs/src/lib/content/api-reference/select.ts
+++ b/sites/docs/src/lib/content/api-reference/select.ts
@@ -1,24 +1,30 @@
import type {
SelectArrowPropsWithoutHTML,
SelectContentPropsWithoutHTML,
+ SelectGroupLabelPropsWithoutHTML,
SelectGroupPropsWithoutHTML,
SelectItemPropsWithoutHTML,
SelectRootPropsWithoutHTML,
SelectSeparatorPropsWithoutHTML,
SelectTriggerPropsWithoutHTML,
} from "bits-ui";
-import { floatingPositioning } from "./floating.js";
import {
arrowProps,
asChild,
attrsSlotProp,
builderAndAttrsSlotProps,
- domElProps,
+ childrenSnippet,
+ dirProp,
+ dismissableLayerProps,
enums,
+ escapeLayerProps,
+ floatingProps,
+ focusScopeProps,
+ forceMountProp,
idsSlotProp,
- onOutsideClickProp,
- portalProp,
- transitionProps,
+ preventOverflowTextSelectionProp,
+ preventScrollProp,
+ withChildProps,
} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
@@ -32,31 +38,25 @@ export const root: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the select menu is disabled.",
},
- multiple: {
- default: C.FALSE,
- type: C.BOOLEAN,
- description: "Whether or not the select menu allows multiple selections.",
- },
- preventScroll: {
- default: C.TRUE,
- type: C.BOOLEAN,
- description: "Whether or not to prevent scrolling the body when the menu is open.",
+ autocomplete: {
+ type: C.STRING,
+ description: "The autocomplete attribute of the select.",
},
- closeOnEscape: {
- default: C.TRUE,
- type: C.BOOLEAN,
- description: "Whether to close the select menu when the escape key is pressed.",
+ dir: dirProp,
+ form: {
+ type: C.STRING,
+ description: "The form attribute of the select.",
},
- closeOnOutsideClick: {
- type: C.BOOLEAN,
- default: C.TRUE,
- description: "Whether to close the select menu when a click occurs outside of it.",
+ value: {
+ type: C.STRING,
+ description: "The value of the currently selected select item.",
},
- loop: {
- type: C.BOOLEAN,
- default: C.FALSE,
- description:
- "Whether or not to loop through the menu items when navigating with the keyboard.",
+ onValueChange: {
+ type: {
+ type: C.FUNCTION,
+ definition: "(value: string | undefined) => void",
+ },
+ description: "A callback that is fired when the select menu's value changes.",
},
open: {
type: C.BOOLEAN,
@@ -70,26 +70,6 @@ export const root: APISchema = {
},
description: "A callback that is fired when the select menu's open state changes.",
},
- selected: {
- type: {
- type: C.OBJECT,
- definition: "{ value: unknown; label?: string }",
- },
- description: "The value of the currently selected item.",
- },
- onSelectedChange: {
- type: {
- type: C.FUNCTION,
- definition: "(value: unknown | undefined) => void",
- },
- description: "A callback that is fired when the select menu's value changes.",
- },
- portal: { ...portalProp("select menu") },
- highlightOnHover: {
- type: C.BOOLEAN,
- default: C.TRUE,
- description: "Whether or not to highlight the currently hovered item.",
- },
name: {
type: C.STRING,
description: "The name to apply to the hidden input element for form submission.",
@@ -99,28 +79,7 @@ export const root: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the select menu is required.",
},
- scrollAlignment: {
- default: "'nearest'",
- type: {
- type: C.ENUM,
- definition: enums("nearest", "center"),
- },
- description: "The alignment of the highlighted item when scrolling.",
- },
- typeahead: {
- type: C.BOOLEAN,
- default: C.TRUE,
- description:
- "Whether or not to enable typeahead functionality. When enabled, the user can type to navigate to menu items.",
- },
- items: {
- type: {
- type: "Selected[]",
- definition: "Array<{ value: T; label?: string }>",
- },
- description: "An array of items to add type-safety to the `onSelectedChange` callback.",
- },
- onOutsideClick: onOutsideClickProp,
+ children: childrenSnippet(),
},
slotProps: { ids: idsSlotProp },
};
@@ -128,7 +87,14 @@ export const root: APISchema = {
export const trigger: APISchema = {
title: "Trigger",
description: "The button element which toggles the select menu's open state.",
- props: domElProps("HTMLButtonElement"),
+ props: {
+ disabled: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description: "Whether or not the select menu trigger is disabled.",
+ },
+ ...withChildProps({ elType: "HTMLButtonElement" }),
+ },
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -151,7 +117,26 @@ export const trigger: APISchema = {
export const content: APISchema = {
title: "Content",
description: "The content/menu element which contains the select menu's items.",
- props: { ...transitionProps, ...floatingPositioning, ...domElProps("HTMLDivElement") },
+ props: {
+ position: {
+ type: {
+ type: C.ENUM,
+ definition: enums("floating", "item-aligned"),
+ },
+ default: "floating",
+ description:
+ "The positioning strategy to use for the content. If set to 'item-aligned', the content will be positioned relative to the trigger, similar to a native select. If set to `floating`, the content will use Floating UI to position itself similar to other popover-like components.",
+ },
+ dir: dirProp,
+ ...floatingProps(),
+ ...dismissableLayerProps,
+ ...escapeLayerProps,
+ ...focusScopeProps,
+ preventOverflowTextSelection: preventOverflowTextSelectionProp,
+ preventScroll: preventScrollProp(),
+ forceMount: forceMountProp,
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -165,13 +150,14 @@ export const item: APISchema = {
title: "Item",
description: "A select item, which must be a child of the `Select.Content` component.",
props: {
- label: {
+ textValue: {
type: C.STRING,
- description: "The label of the select item, which is displayed in the menu.",
+ description: "The text value of the select item, which is used for typeahead purposes.",
},
value: {
- type: C.UNKNOWN,
+ type: C.STRING,
description: "The value of the select item.",
+ required: true,
},
disabled: {
type: C.BOOLEAN,
@@ -179,7 +165,7 @@ export const item: APISchema = {
description:
"Whether or not the select item is disabled. This will prevent interaction/selection.",
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: {
isSelected: {
@@ -241,18 +227,10 @@ export const value: APISchema = {
],
};
-export const input: APISchema = {
- title: "Input",
- description:
- "A hidden input element which is used to store the select menu's value, used for form submission. It receives the same value as the `Select.Value` component and can receive any props that a normal input element can receive.",
- props: domElProps("HTMLInputElement"),
- slotProps: { ...builderAndAttrsSlotProps },
-};
-
export const group: APISchema = {
title: "Group",
description: "An accessible group of select menu items.",
- props: domElProps("HTMLDivElement"),
+ props: withChildProps({ elType: "HTMLDivElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -262,11 +240,11 @@ export const group: APISchema = {
],
};
-export const label: APISchema = {
- title: "Label",
+export const groupLabel: APISchema = {
+ title: "GroupLabel",
description:
"A label for the select menu which will be skipped when navigating with the keyboard. This must be a child of the `Select.Group` component to be accessible.",
- props: domElProps("HTMLLabelElement"),
+ props: withChildProps({ elType: "HTMLDivElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -279,7 +257,7 @@ export const label: APISchema = {
export const separator: APISchema = {
title: "Separator",
description: "A visual separator for use between select items or groups.",
- props: domElProps("HTMLDivElement"),
+ props: withChildProps({ elType: "HTMLDivElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -289,25 +267,6 @@ export const separator: APISchema = {
],
};
-export const indicator: APISchema = {
- title: "Separator",
- description: "A visual separator for use between select items or groups.",
- props: domElProps("HTMLDivElement"),
- slotProps: {
- attrs: attrsSlotProp,
- isSelected: {
- type: C.BOOLEAN,
- description: "Whether or not the item is selected.",
- },
- },
- dataAttributes: [
- {
- name: "select-indicator",
- description: "Present on the indicator element.",
- },
- ],
-};
-
export const arrow: APISchema = {
title: "Arrow",
description: "An optional arrow element which points to the trigger when open.",
@@ -321,4 +280,4 @@ export const arrow: APISchema = {
],
};
-export const select = [root, trigger, content, item, value, group, label, input, separator, arrow];
+export const select = [root, trigger, content, item, value, group, groupLabel, separator, arrow];
diff --git a/sites/docs/src/lib/content/api-reference/separator.ts b/sites/docs/src/lib/content/api-reference/separator.ts
index fcc91e697..9aee8df00 100644
--- a/sites/docs/src/lib/content/api-reference/separator.ts
+++ b/sites/docs/src/lib/content/api-reference/separator.ts
@@ -1,9 +1,14 @@
-import type { SeparatorPropsWithoutHTML } from "bits-ui";
-import { builderAndAttrsSlotProps, domElProps, enums } from "$lib/content/api-reference/helpers.js";
+import type { SeparatorRootPropsWithoutHTML } from "bits-ui";
+import {
+ builderAndAttrsSlotProps,
+ domElProps,
+ enums,
+ withChildProps,
+} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-export const root: APISchema = {
+export const root: APISchema = {
title: "Root",
description: "An element used to separate content.",
props: {
@@ -21,7 +26,7 @@ export const root: APISchema = {
description:
"Whether the separator is decorative or not, which will determine if it is announce by screen readers.",
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/slider.ts b/sites/docs/src/lib/content/api-reference/slider.ts
index 524bd37f3..e56cb6930 100644
--- a/sites/docs/src/lib/content/api-reference/slider.ts
+++ b/sites/docs/src/lib/content/api-reference/slider.ts
@@ -1,14 +1,18 @@
import type {
- SliderPropsWithoutHTML,
+ SliderRootPropsWithoutHTML,
SliderRangePropsWithoutHTML,
SliderThumbPropsWithoutHTML,
SliderTickPropsWithoutHTML,
} from "bits-ui";
-import { builderAndAttrsSlotProps, domElProps, enums } from "$lib/content/api-reference/helpers.js";
+import {
+ builderAndAttrsSlotProps,
+ enums,
+ withChildProps,
+} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema = {
+const root: APISchema = {
title: "Root",
description: "The root slider component which contains the remaining slider components.",
props: {
@@ -16,6 +20,7 @@ const root: APISchema = {
default: "[]",
type: "number[]",
description: "The current value of the slider.",
+ bindable: true,
},
onValueChange: {
type: {
@@ -24,6 +29,14 @@ const root: APISchema = {
},
description: "A callback function called when the value state of the slider changes.",
},
+ onValueChangeEnd: {
+ type: {
+ type: C.FUNCTION,
+ definition: "(value: number[]) => void",
+ },
+ description:
+ "A callback function called when the user finishes dragging the thumb and the value changes. This is different than the `onValueChange` callback because it waits until the user stops dragging before calling the callback, where the `onValueChange` callback is called immediately after the user starts dragging.",
+ },
disabled: {
default: C.FALSE,
type: C.BOOLEAN,
@@ -61,7 +74,14 @@ const root: APISchema = {
description:
"The reading direction of the slider. If set to 'rtl', the slider will be reversed for both `'horizontal'` and `'vertical'` orientations.",
},
- ...domElProps("HTMLSpanElement"),
+ autoSort: {
+ type: C.BOOLEAN,
+ default: C.TRUE,
+ description:
+ "Whether to automatically sort the values in the array when moving thumbs past one another.",
+ },
+
+ ...withChildProps({ elType: "HTMLSpanElement" }),
},
slotProps: {
ticks: {
@@ -92,12 +112,17 @@ const thumb: APISchema = {
title: "Thumb",
description: "A thumb on the slider.",
props: {
- thumb: {
- type: "Thumb",
+ index: {
+ type: C.NUMBER,
description:
- "An individual thumb builder from the `thumbs` slot prop provided by the `Slider.Root` component.",
+ "The index of the thumb in the array of thumbs provided by the `thumbs` `children` snippet prop.",
+ },
+ disabled: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description: "Whether or not the thumb is disabled.",
},
- ...domElProps("HTMLSpanElement"),
+ ...withChildProps({ elType: "HTMLSpanElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
@@ -111,7 +136,7 @@ const thumb: APISchema = {
const range: APISchema = {
title: "Range",
description: "The range of the slider.",
- props: domElProps("HTMLSpanElement"),
+ props: withChildProps({ elType: "HTMLSpanElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -125,12 +150,12 @@ const tick: APISchema = {
title: "Tick",
description: "A tick mark on the slider.",
props: {
- tick: {
- type: "Tick",
+ index: {
+ type: "number",
description:
- "An individual tick builder from the `ticks` slot prop provided by the `Slider.Root` component.",
+ "The index of the tick in the array of ticks provided by the `ticks` `children` snippet prop.",
},
- ...domElProps("HTMLSpanElement"),
+ ...withChildProps({ elType: "HTMLSpanElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/switch.ts b/sites/docs/src/lib/content/api-reference/switch.ts
index 4c4ef152e..905bfba50 100644
--- a/sites/docs/src/lib/content/api-reference/switch.ts
+++ b/sites/docs/src/lib/content/api-reference/switch.ts
@@ -1,10 +1,10 @@
-import type { SwitchPropsWithoutHTML, SwitchThumbPropsWithoutHTML } from "bits-ui";
-import { builderAndAttrsSlotProps, domElProps } from "./helpers.js";
+import type { SwitchRootPropsWithoutHTML, SwitchThumbPropsWithoutHTML } from "bits-ui";
+import { builderAndAttrsSlotProps, withChildProps } from "./helpers.js";
import { attrsSlotProp, enums } from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema = {
+const root: APISchema = {
title: "Root",
description: "The root switch component used to set and manage the state of the switch.",
props: {
@@ -12,6 +12,7 @@ const root: APISchema = {
default: C.FALSE,
type: C.BOOLEAN,
description: "Whether or not the switch is checked.",
+ bindable: true,
},
onCheckedChange: {
type: {
@@ -25,16 +26,6 @@ const root: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the switch is disabled.",
},
- includeInput: {
- default: C.FALSE,
- type: C.BOOLEAN,
- description:
- "Whether or not to include the input element in the switch. This will automatically add a hidden input element to the switch that will be checked when the switch is checked.",
- },
- inputAttrs: {
- type: C.OBJECT,
- description: "Attributes to be spread onto the hidden input element.",
- },
name: {
type: C.STRING,
description:
@@ -50,7 +41,7 @@ const root: APISchema = {
description:
"The value of the hidden input element to be used in form submissions when the switch is checked.",
},
- ...domElProps("HTMLButtonElement"),
+ ...withChildProps({ elType: "HTMLButtonElement" }),
},
slotProps: {
...builderAndAttrsSlotProps,
@@ -80,7 +71,7 @@ const root: APISchema = {
const thumb: APISchema = {
title: "Thumb",
description: "The thumb on the switch used to indicate the switch's state.",
- props: domElProps("HTMLSpanElement"),
+ props: withChildProps({ elType: "HTMLSpanElement" }),
slotProps: {
attrs: attrsSlotProp,
checked: {
diff --git a/sites/docs/src/lib/content/api-reference/tabs.ts b/sites/docs/src/lib/content/api-reference/tabs.ts
index 768143a58..d47c95db7 100644
--- a/sites/docs/src/lib/content/api-reference/tabs.ts
+++ b/sites/docs/src/lib/content/api-reference/tabs.ts
@@ -1,7 +1,7 @@
import type {
TabsContentPropsWithoutHTML,
TabsListPropsWithoutHTML,
- TabsPropsWithoutHTML,
+ TabsRootPropsWithoutHTML,
TabsTriggerPropsWithoutHTML,
} from "bits-ui";
import {
@@ -9,11 +9,12 @@ import {
domElProps,
enums,
union,
+ withChildProps,
} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema = {
+const root: APISchema = {
title: "Root",
description: "The root tabs component which contains the other tab components.",
props: {
@@ -23,6 +24,7 @@ const root: APISchema = {
definition: union("string", "undefined"),
},
description: "The active tab value.",
+ bindable: true,
},
onValueChange: {
type: {
@@ -31,17 +33,21 @@ const root: APISchema = {
},
description: "A callback function called when the active tab value changes.",
},
- activateOnFocus: {
- default: C.TRUE,
- type: C.BOOLEAN,
- description: "Whether or not to activate the tab when it receives focus.",
+ activationMode: {
+ type: {
+ type: C.ENUM,
+ definition: enums("manual", "automatic"),
+ },
+ description:
+ "How the activation of tabs should be handled. If set to `'automatic'`, the tab will be activated when the trigger is focused. If set to `'manual'`, the tab will be activated when the trigger is pressed.",
+ default: "automatic",
},
- autoSet: {
- default: C.TRUE,
+ disabled: {
+ default: C.FALSE,
type: C.BOOLEAN,
- description:
- "Whether or not to automatically set the tab value when it receives focus.",
+ description: "Whether or not the tabs are disabled.",
},
+
loop: {
default: C.TRUE,
type: C.BOOLEAN,
@@ -55,7 +61,7 @@ const root: APISchema = {
},
description: "The orientation of the tabs.",
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: {
...builderAndAttrsSlotProps,
@@ -80,7 +86,7 @@ const root: APISchema = {
const list: APISchema = {
title: "List",
description: "The component containing the tab triggers.",
- props: domElProps("HTMLDivElement"),
+ props: withChildProps({ elType: "HTMLDivElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -109,7 +115,7 @@ const trigger: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the tab is disabled.",
},
- ...domElProps("HTMLButtonElement"),
+ ...withChildProps({ elType: "HTMLButtonElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
@@ -149,7 +155,7 @@ const content: APISchema = {
type: "string",
description: "The value of the tab this content represents.",
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/toggle-group.ts b/sites/docs/src/lib/content/api-reference/toggle-group.ts
index 58a1b716a..d07dc886a 100644
--- a/sites/docs/src/lib/content/api-reference/toggle-group.ts
+++ b/sites/docs/src/lib/content/api-reference/toggle-group.ts
@@ -1,14 +1,15 @@
-import type { ToggleGroupItemPropsWithoutHTML, ToggleGroupPropsWithoutHTML } from "bits-ui";
+import type { ToggleGroupItemPropsWithoutHTML, ToggleGroupRootPropsWithoutHTML } from "bits-ui";
import {
builderAndAttrsSlotProps,
domElProps,
enums,
union,
+ withChildProps,
} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema> = {
+const root: APISchema = {
title: "Root",
description: "The root component which contains the toggle group items.",
props: {
@@ -16,6 +17,7 @@ const root: APISchema> = {
type: union(C.STRING, "string[]"),
description:
"The value of the toggle group. If the type is multiple, this will be an array of strings, otherwise it will be a string.",
+ bindable: true,
},
onValueChange: {
type: {
@@ -50,7 +52,7 @@ const root: APISchema> = {
description: "The type of toggle group.",
type: enums("single", "multiple"),
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
@@ -78,7 +80,7 @@ const item: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the switch is disabled.",
},
- ...domElProps("HTMLButtonElement"),
+ ...withChildProps({ elType: "HTMLButtonElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/toggle.ts b/sites/docs/src/lib/content/api-reference/toggle.ts
index 8c13a1919..a4fd1f9d8 100644
--- a/sites/docs/src/lib/content/api-reference/toggle.ts
+++ b/sites/docs/src/lib/content/api-reference/toggle.ts
@@ -1,9 +1,13 @@
-import type { TogglePropsWithoutHTML } from "bits-ui";
-import { builderAndAttrsSlotProps, domElProps, enums } from "$lib/content/api-reference/helpers.js";
+import type { ToggleRootPropsWithoutHTML } from "bits-ui";
+import {
+ builderAndAttrsSlotProps,
+ enums,
+ withChildProps,
+} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema = {
+const root: APISchema = {
title: "Root",
description: "The toggle button.",
props: {
@@ -11,6 +15,7 @@ const root: APISchema = {
default: C.FALSE,
type: C.BOOLEAN,
description: "Whether or not the toggle button is pressed.",
+ bindable: true,
},
onPressedChange: {
type: {
@@ -24,7 +29,7 @@ const root: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the switch is disabled.",
},
- ...domElProps("HTMLButtonElement"),
+ ...withChildProps({ elType: "HTMLButtonElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/toolbar.ts b/sites/docs/src/lib/content/api-reference/toolbar.ts
index 5fc8d5021..3ca9fa0bb 100644
--- a/sites/docs/src/lib/content/api-reference/toolbar.ts
+++ b/sites/docs/src/lib/content/api-reference/toolbar.ts
@@ -3,18 +3,19 @@ import type {
ToolbarGroupItemPropsWithoutHTML,
ToolbarGroupPropsWithoutHTML,
ToolbarLinkPropsWithoutHTML,
- ToolbarPropsWithoutHTML,
+ ToolbarRootPropsWithoutHTML,
} from "bits-ui";
import {
builderAndAttrsSlotProps,
domElProps,
enums,
union,
+ withChildProps,
} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
import type { APISchema } from "$lib/types/index.js";
-const root: APISchema = {
+const root: APISchema = {
title: "Root",
description: "The root component which contains the toolbar.",
props: {
@@ -31,7 +32,7 @@ const root: APISchema = {
},
description: "The orientation of the toolbar.",
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
@@ -49,7 +50,14 @@ const root: APISchema = {
const button: APISchema = {
title: "Button",
description: "A button in the toolbar.",
- props: domElProps("HTMLButtonElement"),
+ props: {
+ disabled: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description: "Whether or not the button is disabled.",
+ },
+ ...withChildProps({ elType: "HTMLButtonElement" }),
+ },
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -62,7 +70,7 @@ const button: APISchema = {
const link: APISchema = {
title: "Link",
description: "A link in the toolbar.",
- props: domElProps("HTMLAnchorElement"),
+ props: withChildProps({ elType: "HTMLAnchorElement" }),
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -72,7 +80,7 @@ const link: APISchema = {
],
};
-const group: APISchema> = {
+const group: APISchema = {
title: "Group",
description: "A group of toggle items in the toolbar.",
props: {
@@ -83,6 +91,7 @@ const group: APISchema> = {
},
description:
"The value of the toggle group. If the type is multiple, this will be an array of strings, otherwise it will be a string.",
+ bindable: true,
},
onValueChange: {
type: C.FUNCTION,
@@ -101,7 +110,7 @@ const group: APISchema> = {
definition: enums("single", "multiple"),
},
},
- ...domElProps("HTMLDivElement"),
+ ...withChildProps({ elType: "HTMLDivElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
@@ -126,7 +135,7 @@ const groupItem: APISchema = {
type: C.BOOLEAN,
description: "Whether or not the item is disabled.",
},
- ...domElProps("HTMLButtonElement"),
+ ...withChildProps({ elType: "HTMLButtonElement" }),
},
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
diff --git a/sites/docs/src/lib/content/api-reference/tooltip.ts b/sites/docs/src/lib/content/api-reference/tooltip.ts
index c9ba0f0e9..ffdc8da9f 100644
--- a/sites/docs/src/lib/content/api-reference/tooltip.ts
+++ b/sites/docs/src/lib/content/api-reference/tooltip.ts
@@ -1,63 +1,95 @@
import type {
TooltipArrowPropsWithoutHTML,
TooltipContentPropsWithoutHTML,
- TooltipPropsWithoutHTML,
+ TooltipProviderPropsWithoutHTML,
+ TooltipRootPropsWithoutHTML,
TooltipTriggerPropsWithoutHTML,
} from "bits-ui";
import { floatingPositioning } from "./floating.js";
import {
arrowProps,
builderAndAttrsSlotProps,
+ childrenSnippet,
+ dirProp,
+ dismissableLayerProps,
domElProps,
enums,
+ escapeLayerProps,
+ floatingProps,
+ forceMountProp,
idsSlotProp,
portalProp,
transitionProps,
+ withChildProps,
} from "$lib/content/api-reference/helpers.js";
import * as C from "$lib/content/constants.js";
-import type { APISchema } from "$lib/types/index.js";
+import type { APISchema, PropSchema } from "$lib/types/index.js";
-export const root: APISchema = {
+const delayDuration: PropSchema = {
+ type: C.NUMBER,
+ default: "700",
+ description:
+ "The amount of time in milliseconds to delay opening the tooltip when hovering over the trigger.",
+};
+
+const disableHoverableContent: PropSchema = {
+ type: C.BOOLEAN,
+ default: C.FALSE,
+ description:
+ "Whether or not to disable the hoverable content. This is useful when the content contains interactive elements.",
+};
+
+const disabled: PropSchema = {
+ type: C.BOOLEAN,
+ default: C.FALSE,
+ description: "Whether or not the tooltip is disabled.",
+};
+
+const disableCloseOnTriggerClick: PropSchema = {
+ type: C.BOOLEAN,
+ default: C.FALSE,
+ description:
+ "Whether or not to close the tooltip when pressing the escape key. This is useful when the content contains interactive elements.",
+};
+
+const skipDelayDuration: PropSchema = {
+ type: C.NUMBER,
+ default: "300",
+ description:
+ "The amount of time in milliseconds to delay opening the tooltip when the user has used their mouse to hover over the trigger.",
+};
+
+const ignoreNonKeyboardFocus: PropSchema = {
+ type: C.BOOLEAN,
+ default: C.FALSE,
+ description:
+ "Whether or not to ignore the tooltip when the focus is not on the trigger. This is useful when the content contains interactive elements.",
+};
+
+export const provider: APISchema = {
+ title: "Provider",
+ description:
+ "A provider component which contains shared state and logic for the tooltips within its subtree.",
+ props: {
+ delayDuration,
+ disableHoverableContent,
+ disabled,
+ disableCloseOnTriggerClick,
+ skipDelayDuration,
+ ignoreNonKeyboardFocus,
+ children: childrenSnippet(),
+ },
+};
+
+export const root: APISchema = {
title: "Root",
description: "The root component containing the parts of the tooltip.",
props: {
- openDelay: {
- type: C.NUMBER,
- default: "700",
- description:
- "The amount of time in milliseconds to delay opening the tooltip when hovering over the trigger.",
- },
- closeDelay: {
- type: C.NUMBER,
- default: "300",
- description:
- "The amount of time in milliseconds to delay closing the tooltip when the mouse leaves the trigger.",
- },
- closeOnEscape: {
- type: C.BOOLEAN,
- default: C.TRUE,
- description: "Whether or not to close the tooltip when pressing the escape key.",
- },
- closeOnPointerDown: {
- type: C.BOOLEAN,
- default: C.TRUE,
- description:
- "Whether or not to close the tooltip when clicking outside of the tooltip.",
- },
- disableHoverableContent: {
- type: C.BOOLEAN,
- default: C.FALSE,
- description:
- "Whether or not to disable the hoverable content. This is useful when the content contains interactive elements.",
- },
- group: {
- type: C.STRING,
- description: "The group the tooltip belongs to.",
- },
open: {
type: C.BOOLEAN,
default: "false",
description: "The open state of the tooltip component.",
+ bindable: true,
},
onOpenChange: {
type: {
@@ -66,7 +98,12 @@ export const root: APISchema = {
},
description: "A callback that fires when the open state changes.",
},
- portal: { ...portalProp("tooltip") },
+ disabled,
+ delayDuration,
+ disableHoverableContent,
+ disableCloseOnTriggerClick,
+ ignoreNonKeyboardFocus,
+ children: childrenSnippet(),
},
slotProps: {
ids: idsSlotProp,
@@ -77,7 +114,14 @@ export const trigger: APISchema = {
title: "Trigger",
description:
"A component which triggers the opening and closing of the tooltip on hover or focus.",
- props: domElProps("HTMLButtonElement"),
+ props: {
+ disabled: {
+ default: C.FALSE,
+ type: C.BOOLEAN,
+ description: "Whether or not the tooltip trigger is disabled.",
+ },
+ ...withChildProps({ elType: "HTMLButtonElement" }),
+ },
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
@@ -96,7 +140,14 @@ export const trigger: APISchema = {
export const content: APISchema = {
title: "Content",
description: "The contents of the tooltip which are displayed when the tooltip is open.",
- props: { ...transitionProps, ...floatingPositioning, ...domElProps("HTMLDivElement") },
+ props: {
+ ...floatingProps(),
+ ...dismissableLayerProps,
+ ...escapeLayerProps,
+ forceMount: forceMountProp,
+ dir: dirProp,
+ ...withChildProps({ elType: "HTMLDivElement" }),
+ },
slotProps: { ...builderAndAttrsSlotProps },
dataAttributes: [
{
diff --git a/sites/docs/src/lib/types/api.ts b/sites/docs/src/lib/types/api.ts
index 33554887f..5be75a2e9 100644
--- a/sites/docs/src/lib/types/api.ts
+++ b/sites/docs/src/lib/types/api.ts
@@ -8,6 +8,7 @@ export type PropSchema = {
type: PropType | string;
description: string;
required?: boolean;
+ bindable?: boolean;
};
export type PropObj> = {