diff --git a/packages/core/src/components/combobox/combobox.props.ts b/packages/core/src/components/combobox/combobox.props.ts new file mode 100644 index 0000000..37a12a4 --- /dev/null +++ b/packages/core/src/components/combobox/combobox.props.ts @@ -0,0 +1,42 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const ComboboxRootPropsSchema = z.object({ + value: z.string().optional().describe("Controlled selected value"), + defaultValue: z.string().optional().describe("Initial selected value (uncontrolled)"), + inputValue: z.string().optional().describe("Controlled input text value"), + name: z.string().optional().describe("Form field name"), + placeholder: z.string().optional().describe("Placeholder text shown in the input when empty"), + disabled: z.boolean().optional().describe("Whether the combobox is disabled"), + required: z.boolean().optional().describe("Whether selection is required"), + allowCustomValue: z.boolean().optional().describe("Allow selecting a value not in the items list"), +}); + +export interface ComboboxRootProps extends z.infer { + items: string[]; + onValueChange?: (value: string) => void; + open?: boolean; + defaultOpen?: boolean; + onOpenChange?: (open: boolean) => void; + onInputChange?: (value: string) => void; + getLabel?: (value: string) => string; + children: JSX.Element; +} + +export const ComboboxItemPropsSchema = z.object({ + value: z.string().describe("The value this item represents"), + disabled: z.boolean().optional().describe("Whether this item is disabled"), + textValue: z.string().optional().describe("Accessible text used for typeahead matching"), +}); + +export interface ComboboxItemProps extends z.infer, JSX.HTMLAttributes { + children?: JSX.Element; +} + +export const ComboboxMeta: ComponentMeta = { + name: "Combobox", + description: "Searchable select that filters options as the user types, with keyboard navigation", + parts: ["Root", "Input", "Trigger", "Portal", "Content", "Listbox", "Item", "ItemLabel", "ItemIndicator", "Group", "GroupLabel"] as const, + requiredParts: ["Root", "Input", "Content", "Item"] as const, +} as const; diff --git a/packages/core/src/components/combobox/index.ts b/packages/core/src/components/combobox/index.ts index 7ff1bde..b0024f4 100644 --- a/packages/core/src/components/combobox/index.ts +++ b/packages/core/src/components/combobox/index.ts @@ -7,3 +7,5 @@ export { ComboboxEmpty } from "./combobox-empty"; export { ComboboxGroup } from "./combobox-group"; export { ComboboxGroupLabel } from "./combobox-group-label"; export { useComboboxContext } from "./combobox-context"; +export { ComboboxRootPropsSchema, ComboboxItemPropsSchema, ComboboxMeta } from "./combobox.props"; +export type { ComboboxRootProps, ComboboxItemProps } from "./combobox.props"; diff --git a/packages/core/src/components/dropdown-menu/dropdown-menu.props.ts b/packages/core/src/components/dropdown-menu/dropdown-menu.props.ts new file mode 100644 index 0000000..1aaaea6 --- /dev/null +++ b/packages/core/src/components/dropdown-menu/dropdown-menu.props.ts @@ -0,0 +1,32 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const DropdownMenuRootPropsSchema = z.object({ + open: z.boolean().optional().describe("Controlled open state"), + defaultOpen: z.boolean().optional().describe("Initial open state (uncontrolled)"), +}); + +export interface DropdownMenuRootProps extends z.infer { + onOpenChange?: (open: boolean) => void; + children: JSX.Element; +} + +export const DropdownMenuItemPropsSchema = z.object({ + disabled: z.boolean().optional().describe("Whether this item is disabled"), + textValue: z.string().optional().describe("Accessible text used for typeahead matching"), + closeOnSelect: z.boolean().optional().describe("Whether the menu closes when this item is selected"), +}); + +export interface DropdownMenuItemProps extends z.infer, JSX.HTMLAttributes { + value: string; + onSelect?: () => void; + children?: JSX.Element; +} + +export const DropdownMenuMeta: ComponentMeta = { + name: "DropdownMenu", + description: "Menu of actions triggered by a button, with keyboard navigation, grouping, and sub-menus", + parts: ["Root", "Trigger", "Portal", "Content", "Item", "Group", "GroupLabel", "Separator", "Sub", "SubTrigger", "SubContent"] as const, + requiredParts: ["Root", "Trigger", "Content"] as const, +} as const; diff --git a/packages/core/src/components/dropdown-menu/index.ts b/packages/core/src/components/dropdown-menu/index.ts index ce35fb9..8fa0eac 100644 --- a/packages/core/src/components/dropdown-menu/index.ts +++ b/packages/core/src/components/dropdown-menu/index.ts @@ -9,3 +9,5 @@ export { DropdownMenuCheckboxItem } from "./dropdown-menu-checkbox-item"; export { DropdownMenuRadioGroup } from "./dropdown-menu-radio-group"; export { DropdownMenuRadioItem } from "./dropdown-menu-radio-item"; export { useDropdownMenuContext } from "./dropdown-menu-context"; +export { DropdownMenuRootPropsSchema, DropdownMenuItemPropsSchema, DropdownMenuMeta } from "./dropdown-menu.props"; +export type { DropdownMenuRootProps, DropdownMenuItemProps } from "./dropdown-menu.props"; diff --git a/packages/core/src/components/listbox/index.ts b/packages/core/src/components/listbox/index.ts index e5bd745..0a49dba 100644 --- a/packages/core/src/components/listbox/index.ts +++ b/packages/core/src/components/listbox/index.ts @@ -11,8 +11,8 @@ export const Listbox = Object.assign(ListboxRoot, { useContext: useListboxContext, }); -export type { ListboxRootProps } from "./listbox-root"; -export type { ListboxItemProps } from "./listbox-item"; export type { ListboxGroupProps } from "./listbox-group"; export type { ListboxGroupLabelProps } from "./listbox-group-label"; export type { ListboxContextValue } from "./listbox-context"; +export { ListboxRootPropsSchema, ListboxItemPropsSchema, ListboxMeta } from "./listbox.props"; +export type { ListboxRootProps, ListboxItemProps } from "./listbox.props"; diff --git a/packages/core/src/components/listbox/listbox.props.ts b/packages/core/src/components/listbox/listbox.props.ts new file mode 100644 index 0000000..9fcf72e --- /dev/null +++ b/packages/core/src/components/listbox/listbox.props.ts @@ -0,0 +1,43 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const ListboxRootPropsSchema = z.object({ + value: z.union([z.string(), z.array(z.string())]).optional().describe("Controlled selected value or values"), + defaultValue: z.union([z.string(), z.array(z.string())]).optional().describe("Initial selected value or values (uncontrolled)"), + multiple: z.boolean().optional().describe("Whether multiple items can be selected"), + disabled: z.boolean().optional().describe("Whether the listbox is disabled"), + orientation: z.enum(["horizontal", "vertical"]).optional().describe("Navigation orientation. Defaults to vertical"), +}); + +export interface ListboxRootProps extends JSX.HTMLAttributes { + items: string[]; + value?: string; + defaultValue?: string; + onValueChange?: (value: string) => void; + selectionMode?: "single" | "multiple"; + values?: string[]; + defaultValues?: string[]; + onValuesChange?: (values: string[]) => void; + orientation?: "vertical" | "horizontal"; + loop?: boolean; + getLabel?: (value: string) => string; + disabled?: boolean; + children: JSX.Element; +} + +export const ListboxItemPropsSchema = z.object({ + value: z.string().describe("The value this item represents"), + disabled: z.boolean().optional().describe("Whether this item is disabled"), +}); + +export interface ListboxItemProps extends z.infer, JSX.HTMLAttributes { + children?: JSX.Element; +} + +export const ListboxMeta: ComponentMeta = { + name: "Listbox", + description: "Inline list of selectable options with keyboard navigation, not in a dropdown", + parts: ["Root", "Item", "ItemLabel", "ItemIndicator", "Group", "GroupLabel"] as const, + requiredParts: ["Root", "Item"] as const, +} as const; diff --git a/packages/core/src/components/pagination/index.ts b/packages/core/src/components/pagination/index.ts index 4c2f64a..df72434 100644 --- a/packages/core/src/components/pagination/index.ts +++ b/packages/core/src/components/pagination/index.ts @@ -1,17 +1,6 @@ -import { usePaginationContext } from "./pagination-context"; -import { PaginationEllipsis } from "./pagination-ellipsis"; -import { PaginationItems } from "./pagination-items"; -import { PaginationNext } from "./pagination-next"; -import { PaginationPrevious } from "./pagination-previous"; -import { PaginationRoot } from "./pagination-root"; -export const Pagination = Object.assign(PaginationRoot, { - Previous: PaginationPrevious, - Next: PaginationNext, - Items: PaginationItems, - Ellipsis: PaginationEllipsis, - useContext: usePaginationContext, -}); -export type { PaginationRootProps } from "./pagination-root"; +export { Pagination, PaginationRoot } from "./pagination-root"; +export { PaginationRootPropsSchema, PaginationMeta } from "./pagination.props"; +export type { PaginationRootProps } from "./pagination.props"; export type { PaginationPreviousProps } from "./pagination-previous"; export type { PaginationNextProps } from "./pagination-next"; export type { PaginationItemsProps, PaginationItemData } from "./pagination-items"; diff --git a/packages/core/src/components/pagination/pagination-root.tsx b/packages/core/src/components/pagination/pagination-root.tsx index 5881e22..17f409c 100644 --- a/packages/core/src/components/pagination/pagination-root.tsx +++ b/packages/core/src/components/pagination/pagination-root.tsx @@ -1,6 +1,11 @@ import type { JSX } from "solid-js"; import { splitProps } from "solid-js"; import { PaginationContextProvider, type PaginationContextValue } from "./pagination-context"; +import { PaginationEllipsis } from "./pagination-ellipsis"; +import { PaginationItems } from "./pagination-items"; +import { PaginationNext } from "./pagination-next"; +import { PaginationPrevious } from "./pagination-previous"; +import { usePaginationContext } from "./pagination-context"; /** Props for the Pagination root component. */ export interface PaginationRootProps extends JSX.HTMLAttributes { @@ -42,3 +47,12 @@ export function PaginationRoot(props: PaginationRootProps): JSX.Element { ); } + +/** Compound Pagination component with all sub-components as static properties. */ +export const Pagination = Object.assign(PaginationRoot, { + Previous: PaginationPrevious, + Next: PaginationNext, + Items: PaginationItems, + Ellipsis: PaginationEllipsis, + useContext: usePaginationContext, +}); diff --git a/packages/core/src/components/pagination/pagination.props.ts b/packages/core/src/components/pagination/pagination.props.ts new file mode 100644 index 0000000..ad8942f --- /dev/null +++ b/packages/core/src/components/pagination/pagination.props.ts @@ -0,0 +1,23 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const PaginationRootPropsSchema = z.object({ + page: z.number().optional().describe("Current page number (1-based)"), + defaultPage: z.number().optional().describe("Initial page number (uncontrolled)"), + count: z.number().describe("Total number of pages"), + siblingCount: z.number().optional().describe("Number of sibling pages shown around the current page. Defaults to 1"), + disabled: z.boolean().optional().describe("Whether the pagination controls are disabled"), +}); + +export interface PaginationRootProps extends z.infer, JSX.HTMLAttributes { + onPageChange?: (page: number) => void; + children?: JSX.Element; +} + +export const PaginationMeta: ComponentMeta = { + name: "Pagination", + description: "Navigation for paginated content with page numbers, previous/next controls", + parts: ["Root", "Previous", "Next", "Items", "Item", "Ellipsis"] as const, + requiredParts: ["Root"] as const, +} as const; diff --git a/packages/core/src/components/select/index.ts b/packages/core/src/components/select/index.ts index f5d2884..186ad92 100644 --- a/packages/core/src/components/select/index.ts +++ b/packages/core/src/components/select/index.ts @@ -7,3 +7,5 @@ export { SelectGroup } from "./select-group"; export { SelectGroupLabel } from "./select-group-label"; export { SelectHiddenSelect } from "./select-hidden-select"; export { useSelectContext } from "./select-context"; +export { SelectRootPropsSchema, SelectItemPropsSchema, SelectMeta } from "./select.props"; +export type { SelectRootProps, SelectItemProps } from "./select.props"; diff --git a/packages/core/src/components/select/select.props.ts b/packages/core/src/components/select/select.props.ts new file mode 100644 index 0000000..6690439 --- /dev/null +++ b/packages/core/src/components/select/select.props.ts @@ -0,0 +1,39 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const SelectRootPropsSchema = z.object({ + value: z.string().optional().describe("Controlled selected value"), + defaultValue: z.string().optional().describe("Initial selected value (uncontrolled)"), + name: z.string().optional().describe("Form field name for hidden input"), + placeholder: z.string().optional().describe("Placeholder text shown when no value is selected"), + disabled: z.boolean().optional().describe("Whether the select is disabled"), + required: z.boolean().optional().describe("Whether selection is required"), +}); + +export interface SelectRootProps extends z.infer { + items: string[]; + onValueChange?: (value: string) => void; + open?: boolean; + defaultOpen?: boolean; + onOpenChange?: (open: boolean) => void; + getLabel?: (value: string) => string; + children: JSX.Element; +} + +export const SelectItemPropsSchema = z.object({ + value: z.string().describe("The value this item represents"), + disabled: z.boolean().optional().describe("Whether this item is disabled"), + textValue: z.string().optional().describe("Accessible text used for typeahead matching"), +}); + +export interface SelectItemProps extends z.infer, JSX.HTMLAttributes { + children?: JSX.Element; +} + +export const SelectMeta: ComponentMeta = { + name: "Select", + description: "Dropdown for selecting a single option from a list, with keyboard navigation and typeahead", + parts: ["Root", "Trigger", "Value", "Portal", "Content", "Listbox", "Item", "ItemLabel", "ItemIndicator", "Group", "GroupLabel"] as const, + requiredParts: ["Root", "Trigger", "Content", "Item"] as const, +} as const; diff --git a/packages/core/src/components/separator/index.ts b/packages/core/src/components/separator/index.ts index 487149a..a6e9d63 100644 --- a/packages/core/src/components/separator/index.ts +++ b/packages/core/src/components/separator/index.ts @@ -1,2 +1,3 @@ export { Separator } from "./separator"; -export type { SeparatorProps } from "./separator"; +export { SeparatorPropsSchema, SeparatorMeta } from "./separator.props"; +export type { SeparatorProps } from "./separator.props"; diff --git a/packages/core/src/components/separator/separator.props.ts b/packages/core/src/components/separator/separator.props.ts new file mode 100644 index 0000000..451bdda --- /dev/null +++ b/packages/core/src/components/separator/separator.props.ts @@ -0,0 +1,17 @@ +import { z } from "zod/v4"; +import type { JSX } from "solid-js"; +import type { ComponentMeta } from "../../meta"; + +export const SeparatorPropsSchema = z.object({ + orientation: z.enum(["horizontal", "vertical"]).optional().describe("Visual and ARIA orientation. Defaults to horizontal"), + decorative: z.boolean().optional().describe("When true, renders role=none (purely visual, not announced). Defaults to false"), +}); + +export interface SeparatorProps extends z.infer, JSX.HTMLAttributes {} + +export const SeparatorMeta: ComponentMeta = { + name: "Separator", + description: "Visual divider between content sections or menu items", + parts: ["Separator"] as const, + requiredParts: ["Separator"] as const, +} as const;