Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/react-create-toaster-generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/react': patch
---

Exposed the toast content generic on `createToaster` so `CreateToasterReturn<T>` can type custom toast data.
5 changes: 5 additions & 0 deletions .changeset/react-steps-root-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/react': patch
---

Fixed Steps `RootProvider` rendering children twice via both `mergedProps` and explicit `{props.children}`.
5 changes: 5 additions & 0 deletions .changeset/solid-create-toaster-generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/solid': patch
---

Exposed the toast content generic on `createToaster` so `CreateToasterReturn<T>` can type custom toast data.
8 changes: 8 additions & 0 deletions .changeset/solid-scroll-area-root-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@ark-ui/solid': patch
---

- **Scroll Area**: Fixed `RootProvider` throwing `useScrollAreaContext returned undefined` by evaluating children outside the provider, and merge `getRootProps()` onto the root element.
- **Password Input**: Fixed `RootProvider` spreading the machine `value` onto the root DOM element.
- **Steps**: Fixed `RootProvider` rendering children twice via both `mergedProps` and explicit `{props.children}`.
- **Marquee**: Fixed `Content` merging `children` into every cloned content element's props.
5 changes: 5 additions & 0 deletions .changeset/svelte-create-toaster-generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/svelte': patch
---

Exposed the toast content generic on `createToaster` so `CreateToasterReturn<T>` can type custom toast data.
7 changes: 7 additions & 0 deletions .changeset/svelte-scroll-area-root-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ark-ui/svelte': patch
---

- **Scroll Area**: Fixed `RootProvider` not merging `getRootProps()` onto the root element.
- **Password Input**: Fixed `RootProvider` spreading the machine `value` onto the root DOM element and rendering children twice.
- **Json Tree View**: Fixed `RootProvider` not stripping `options` from `value` before forwarding to `TreeView.RootProvider`, and rendering children twice.
5 changes: 5 additions & 0 deletions .changeset/vue-create-toaster-generic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/vue': patch
---

Exposed the toast content generic on `createToaster` so `CreateToasterReturn<T>` can type custom toast data.
5 changes: 5 additions & 0 deletions .changeset/vue-json-tree-view-root-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ark-ui/vue': patch
---

Fixed JsonTreeView `RootProvider` not forwarding root HTML props (such as `class` and `asChild`) to `TreeView.RootProvider`.
4 changes: 1 addition & 3 deletions packages/react/src/components/steps/steps-root-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ export const StepsRootProvider = forwardRef<HTMLDivElement, StepsRootProviderPro

return (
<StepsProvider value={steps}>
<ark.div {...mergedProps} ref={ref}>
{props.children}
</ark.div>
<ark.div {...mergedProps} ref={ref} />
</StepsProvider>
)
})
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/components/toast/create-toaster.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use client'

import * as toast from '@zag-js/toast'
import type { ReactNode } from 'react'

export interface CreateToasterProps extends toast.StoreProps {}

export interface CreateToasterReturn extends toast.Store {}
export type CreateToasterReturn<T = ReactNode> = toast.Store<T>

export const createToaster = (props: toast.StoreProps): toast.Store => {
export const createToaster = <T = ReactNode,>(props: CreateToasterProps): CreateToasterReturn<T> => {
return toast.createStore(props)
}
2 changes: 1 addition & 1 deletion packages/react/src/components/toast/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ToastProvider } from './use-toast-context.ts'
export type ToastOptions = toast.Options<ReactNode>

export interface ToasterBaseProps extends PolymorphicProps, Omit<toast.GroupProps, 'store' | 'id'> {
toaster: CreateToasterReturn
toaster: CreateToasterReturn<any>
children: (toast: ToastOptions) => ReactNode
}

Expand Down
13 changes: 8 additions & 5 deletions packages/solid/src/components/marquee/marquee-content.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { mergeProps } from '@zag-js/solid'
import { type FlowComponent, For } from 'solid-js'
import { type JSX, For, splitProps } from 'solid-js'
import { type HTMLProps, type PolymorphicProps, ark } from '../factory.tsx'
import { useMarqueeContext } from './use-marquee-context.ts'

export interface MarqueeContentBaseProps extends PolymorphicProps<'div'> {}
export interface MarqueeContentBaseProps extends PolymorphicProps<'div'> {
children?: JSX.Element
}
export interface MarqueeContentProps extends HTMLProps<'div'>, MarqueeContentBaseProps {}

export const MarqueeContent: FlowComponent<MarqueeContentProps> = (props) => {
export const MarqueeContent = (props: MarqueeContentProps) => {
const [localProps, restProps] = splitProps(props, ['children'])
const context = useMarqueeContext()

return (
<For each={Array.from({ length: context().contentCount })}>
{(_, index) => {
const mergedProps = mergeProps(() => context().getContentProps({ index: index() }), props)
return <ark.div {...mergedProps}>{props.children}</ark.div>
const mergedProps = mergeProps(() => context().getContentProps({ index: index() }), restProps)
return <ark.div {...mergedProps}>{localProps.children}</ark.div>
}}
</For>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { mergeProps } from '@zag-js/solid'
import type { JSX } from 'solid-js'
import { createSplitProps } from '../../utils/create-split-props.ts'
import { type HTMLProps, type PolymorphicProps, ark } from '../factory.tsx'
import { PasswordInputProvider, type UsePasswordInputContext } from './use-password-input-context.ts'
import type { UsePasswordInputReturn } from './use-password-input.ts'
import { PasswordInputProvider } from './use-password-input-context.ts'

export interface PasswordInputRootProviderBaseProps extends PolymorphicProps<'div'> {
value: UsePasswordInputContext
children?: JSX.Element
interface RootProviderProps {
value: UsePasswordInputReturn
}
export interface PasswordInputRootProviderProps extends HTMLProps<'div'>, PasswordInputRootProviderBaseProps {}

export interface PasswordInputRootProviderBaseProps extends PolymorphicProps<'div'> {}
export interface PasswordInputRootProviderProps
extends HTMLProps<'div'>, RootProviderProps, PasswordInputRootProviderBaseProps {}

export const PasswordInputRootProvider = (props: PasswordInputRootProviderProps) => {
const mergedProps = mergeProps(() => props.value().getRootProps(), props)
const [{ value: passwordInput }, localProps] = createSplitProps<RootProviderProps>()(props, ['value'])
const mergedProps = mergeProps(() => passwordInput().getRootProps(), localProps)

return (
<PasswordInputProvider value={props.value}>
<PasswordInputProvider value={passwordInput}>
<ark.div {...mergedProps} />
</PasswordInputProvider>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import type { Assign } from '../../types.ts'
import { mergeProps } from '@zag-js/solid'
import { createSplitProps } from '../../utils/create-split-props.ts'
import { type HTMLProps, type PolymorphicProps, ark } from '../factory.tsx'
import { type UseScrollAreaContext, ScrollAreaProvider } from './use-scroll-area-context.ts'
import type { UseScrollAreaReturn } from './use-scroll-area.ts'
import { ScrollAreaProvider } from './use-scroll-area-context.ts'

export interface ScrollAreaRootProviderBaseProps extends PolymorphicProps<'div'> {
value: UseScrollAreaContext
interface RootProviderProps {
value: UseScrollAreaReturn
}
export interface ScrollAreaRootProviderProps extends Assign<HTMLProps<'div'>, ScrollAreaRootProviderBaseProps> {}

export interface ScrollAreaRootProviderBaseProps extends PolymorphicProps<'div'> {}
export interface ScrollAreaRootProviderProps
extends HTMLProps<'div'>, RootProviderProps, ScrollAreaRootProviderBaseProps {}

export const ScrollAreaRootProvider = (props: ScrollAreaRootProviderProps) => {
const { value, children, ...localProps } = props
const [{ value: scrollArea }, localProps] = createSplitProps<RootProviderProps>()(props, ['value'])
const mergedProps = mergeProps(() => scrollArea().getRootProps(), localProps)

return (
<ScrollAreaProvider value={value}>
<ark.div {...localProps}>{children}</ark.div>
<ScrollAreaProvider value={scrollArea}>
<ark.div {...mergedProps} />
</ScrollAreaProvider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const StepsRootProvider = (props: StepsRootProviderProps) => {

return (
<StepsProvider value={steps}>
<ark.div {...mergedProps}>{props.children}</ark.div>
<ark.div {...mergedProps} />
</StepsProvider>
)
}
4 changes: 2 additions & 2 deletions packages/solid/src/components/toast/create-toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export interface CreateToasterProps extends Partial<toast.StoreProps> {
placement: toast.Placement
}

export interface CreateToasterReturn extends toast.Store<JSX.Element> {}
export type CreateToasterReturn<T = JSX.Element> = toast.Store<T>

export const createToaster = (props: CreateToasterProps): CreateToasterReturn => {
export const createToaster = <T = JSX.Element,>(props: CreateToasterProps): CreateToasterReturn<T> => {
return toast.createStore(props)
}
2 changes: 1 addition & 1 deletion packages/solid/src/components/toast/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ToastProvider } from './use-toast-context.ts'
export type ToastOptions = toast.Options<JSX.Element>

export interface ToasterBaseProps extends PolymorphicProps<'div'>, Omit<toast.GroupProps, 'id' | 'store'> {
toaster: CreateToasterReturn
toaster: CreateToasterReturn<any>
children: (toast: Accessor<ToastOptions>) => JSX.Element
}
export interface ToasterProps extends Assign<HTMLProps<'div'>, ToasterBaseProps> {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import { ChevronRightIcon } from 'lucide-svelte'
import styles from 'styles/json-tree-view.module.css'

const id = $props.id()
const jsonTreeView = useJsonTreeView({
id,
defaultExpandedDepth: 1,
data: {
name: 'John Doe',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
import { JsonTreeViewPropsProvider } from './json-tree-view-props-context.ts'
import type { UseJsonTreeViewReturn } from './use-json-tree-view.svelte.ts'

export interface JsonTreeViewRootProviderProps extends TreeViewRootProviderProps<JsonNode> {}
export interface JsonTreeViewRootProviderProps extends Omit<TreeViewRootProviderProps<JsonNode>, 'value'> {
value: UseJsonTreeViewReturn
}

const { value, ...props }: JsonTreeViewRootProviderProps = $props()
let { value, ...props }: JsonTreeViewRootProviderProps = $props()

const jsonTreeView = $derived(value() as unknown as UseJsonTreeViewReturn)
const treeView = () => {
const { options: _, ...rest } = value()
return rest
}

JsonTreeViewPropsProvider(() => jsonTreeView().options)
JsonTreeViewPropsProvider(() => value().options)
</script>

<TreeViewRootProvider data-scope="json-tree-view" value={jsonTreeView} {...props}>
{@render props.children?.()}
</TreeViewRootProvider>
<TreeViewRootProvider data-scope="json-tree-view" value={treeView} {...props} />
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
<script module lang="ts">
import type { Snippet } from 'svelte'
import type { Assign, HTMLProps, RefAttribute } from '$lib/types'
import type { Assign, HTMLProps, PolymorphicProps, RefAttribute } from '$lib/types'
import type { UsePasswordInputReturn } from './use-password-input.svelte.ts'

interface RootProviderProps {
export interface PasswordInputRootProviderBaseProps extends PolymorphicProps<'div'>, RefAttribute {
value: UsePasswordInputReturn
}

export interface PasswordInputRootProviderBaseProps extends RootProviderProps, RefAttribute {}
export interface PasswordInputRootProviderProps extends Assign<HTMLProps<'div'>, PasswordInputRootProviderBaseProps> {
children?: Snippet
}
export interface PasswordInputRootProviderProps extends Assign<HTMLProps<'div'>, PasswordInputRootProviderBaseProps> {}
</script>

<script lang="ts">
import { mergeProps } from '@zag-js/svelte'
import { Ark } from '../factory/index.ts'
import { PasswordInputProvider } from './use-password-input-context.ts'

let { ref = $bindable(null), ...props }: PasswordInputRootProviderProps = $props()
let { ref = $bindable(null), value, ...props }: PasswordInputRootProviderProps = $props()

const mergedProps = $derived(mergeProps(props.value().getRootProps(), props))
const mergedProps = $derived(mergeProps(value().getRootProps(), props))

PasswordInputProvider(() => props.value())
PasswordInputProvider(() => value())
</script>

<Ark as="div" bind:ref {...mergedProps}>
{@render props.children?.()}
</Ark>
<Ark as="div" bind:ref {...mergedProps} />
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
</script>

<script lang="ts">
import { mergeProps } from '@zag-js/svelte'
import { Ark } from '../factory/index.js'
import { ScrollAreaProvider } from './use-scroll-area-context.js'

let { value, ref = $bindable(null), ...props }: ScrollAreaRootProviderProps = $props()

const mergedProps = $derived(mergeProps(value().getRootProps(), props))

ScrollAreaProvider(() => value())
</script>

<Ark as="div" bind:ref {...props} />
<Ark as="div" bind:ref {...mergedProps} />
4 changes: 2 additions & 2 deletions packages/svelte/src/lib/components/toast/create-toaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as toast from '@zag-js/toast'

export interface CreateToasterProps extends toast.StoreProps {}

export interface CreateToasterReturn extends toast.Store {}
export type CreateToasterReturn<T = any> = toast.Store<T>

export const createToaster = (props: toast.StoreProps): toast.Store => {
export const createToaster = <T = any>(props: CreateToasterProps): CreateToasterReturn<T> => {
return toast.createStore(props)
}
2 changes: 1 addition & 1 deletion packages/svelte/src/lib/components/toast/toaster.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/**
* The toaster instance.
*/
toaster: CreateToasterReturn
toaster: CreateToasterReturn<any>
/**
* The children of the toaster.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
<script lang="ts">
import type { JsonNode } from '@zag-js/json-tree-utils'
import type { PropTypes } from '@zag-js/vue'
import type * as treeView from '@zag-js/tree-view'
import type { TreeViewRootProviderProps } from '../tree-view/index.ts'
import type { JsonTreeViewOptions } from './json-tree-view-props-context.ts'

export interface JsonTreeViewRootProviderProps extends TreeViewRootProviderProps<JsonNode> {}
export interface JsonTreeViewRootProviderProps extends Omit<TreeViewRootProviderProps<JsonNode>, 'value'> {
value: treeView.Api<PropTypes, JsonNode> & { options: JsonTreeViewOptions }
}
</script>

<script setup lang="ts">
import { computed } from 'vue'
import { computed, toValue } from 'vue'
import { TreeViewRootProvider } from '../tree-view/index.ts'
import { JsonTreeViewPropsProvider } from './json-tree-view-props-context.ts'
import type { UseJsonTreeViewReturn } from './use-json-tree-view.ts'

const props = defineProps<JsonTreeViewRootProviderProps>()

const jsonTreeView = props.value as unknown as UseJsonTreeViewReturn
const api = computed(() => toValue(props.value))

const treeView = computed(() => {
const { options: _, ...rest } = jsonTreeView.value
const { options: _, ...rest } = api.value
return rest
})

JsonTreeViewPropsProvider(computed(() => jsonTreeView.value.options))
const rootProps = computed(() => {
const { value: _, ...rest } = props
return rest
})

JsonTreeViewPropsProvider(computed(() => api.value.options))
</script>

<template>
<TreeViewRootProvider data-scope="json-tree-view" :value="treeView">
<TreeViewRootProvider data-scope="json-tree-view" v-bind="rootProps" :value="treeView">
<slot />
</TreeViewRootProvider>
</template>
4 changes: 2 additions & 2 deletions packages/vue/src/components/toast/create-toaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export interface CreateToasterProps extends Optional<Partial<toast.StoreProps>,
placement: toast.Placement
}

export interface CreateToasterReturn extends toast.Store<VNodeChild> {}
export type CreateToasterReturn<T = VNodeChild> = toast.Store<T>

export const createToaster = (props: CreateToasterProps): CreateToasterReturn => {
export const createToaster = <T = VNodeChild>(props: CreateToasterProps): CreateToasterReturn<T> => {
return toast.createStore(props)
}
2 changes: 1 addition & 1 deletion packages/vue/src/components/toast/toaster.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ToasterItem from './toaster-item.vue'
export type ToastOptions = toast.Options<VNodeChild>

export interface ToasterBaseProps extends PolymorphicProps {
toaster: CreateToasterReturn
toaster: CreateToasterReturn<any>
}

export interface ToasterProps
Expand Down
Binary file added website/public/images/hash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/public/images/reland.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading