Completes the headless layer of the GradientBuilder (still ACTIVE_DEV_TRACK): - Providers expose `.props` (renderProps() + handlers) and register per-part sources for the morfo's value-bound aria (aria-valuenow / valuetext / label on each stop) — every stop is a keyboard-accessible role=slider thumb. - Svelte wrappers: Provider (the editor root, bindable `value: Gradient`), Track (click-empty-to-add drag surface), Stop (the slider thumb) + types + barrel. The eidos composes Preview / AddStop / AngleDial / KindSwitch over these via GradientBuilderProvider.require(). check: 0 new errors, type-clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>active-uix
parent
c474fc6bae
commit
8ddd55309a
@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { GradientStopProvider } from '../gradient-builder-provider.svelte';
|
||||
import type { GradientStopProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'gradient-builder-stop'),
|
||||
index = 0,
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: GradientStopProps = $props();
|
||||
|
||||
const state = GradientStopProvider.create({
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
),
|
||||
index: readableActive(() => index)
|
||||
});
|
||||
|
||||
const mergedProps = $derived(mergeProps(restProps, state.props));
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<div {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
{/if}
|
||||
@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { GradientTrackProvider } from '../gradient-builder-provider.svelte';
|
||||
import type { GradientTrackProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'gradient-builder-track'),
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: GradientTrackProps = $props();
|
||||
|
||||
const state = GradientTrackProvider.create({
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
)
|
||||
});
|
||||
|
||||
const mergedProps = $derived(mergeProps(restProps, state.props));
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<div {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
{/if}
|
||||
@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { GradientBuilderProvider } from '../gradient-builder-provider.svelte';
|
||||
import type { GradientBuilderProps } from '../types';
|
||||
import type { Gradient } from '$libs/gradient';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
const DEFAULT_GRADIENT: Gradient = {
|
||||
kind: 'linear',
|
||||
angle: 90,
|
||||
stops: [
|
||||
{ color: { kind: 'css', value: '#000000' } },
|
||||
{ color: { kind: 'css', value: '#ffffff' } }
|
||||
]
|
||||
};
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'gradient-builder'),
|
||||
value = $bindable(DEFAULT_GRADIENT),
|
||||
onValueCommit = () => {},
|
||||
disabled = false,
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: GradientBuilderProps = $props();
|
||||
|
||||
const state = GradientBuilderProvider.create({
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
),
|
||||
value: writableActive(
|
||||
() => value,
|
||||
(v) => (value = v)
|
||||
),
|
||||
onValueCommit: readableActive(() => onValueCommit),
|
||||
disabled: readableActive(() => disabled)
|
||||
});
|
||||
|
||||
const mergedProps = $derived(mergeProps(restProps, state.props));
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<div {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
{/if}
|
||||
@ -0,0 +1,15 @@
|
||||
export { default as Provider } from './components/gradient-builder.svelte';
|
||||
export { default as Track } from './components/gradient-builder-track.svelte';
|
||||
export { default as Stop } from './components/gradient-builder-stop.svelte';
|
||||
|
||||
export {
|
||||
GradientBuilderProvider,
|
||||
GradientStopProvider,
|
||||
GradientTrackProvider
|
||||
} from './gradient-builder-provider.svelte';
|
||||
|
||||
export type {
|
||||
GradientBuilderProps as ProviderProps,
|
||||
GradientTrackProps as TrackProps,
|
||||
GradientStopProps as StopProps
|
||||
} from './types';
|
||||
@ -0,0 +1 @@
|
||||
export * from './exports';
|
||||
@ -0,0 +1,28 @@
|
||||
import type { WithChild, Without, OnChangeFn, PrimitiveDivAttributes } from '../../types';
|
||||
import type { Gradient } from '$libs/gradient';
|
||||
|
||||
export type GradientBuilderProps = WithChild<{
|
||||
/** Unique identifier. Auto-generated if omitted. */
|
||||
id?: string;
|
||||
/** The gradient being edited. Bindable. */
|
||||
value?: Gradient;
|
||||
/** Called on every settled change (stop add / move / remove / recolor, kind, angle). */
|
||||
onValueCommit?: OnChangeFn<Gradient>;
|
||||
/** @default false */
|
||||
disabled?: boolean;
|
||||
}> &
|
||||
Without<PrimitiveDivAttributes, {}>;
|
||||
|
||||
export type GradientTrackProps = WithChild<{
|
||||
/** Unique identifier. Auto-generated if omitted. */
|
||||
id?: string;
|
||||
}> &
|
||||
Without<PrimitiveDivAttributes, {}>;
|
||||
|
||||
export type GradientStopProps = WithChild<{
|
||||
/** Unique identifier. Auto-generated if omitted. */
|
||||
id?: string;
|
||||
/** This stop's index in the gradient's stop list. @default 0 */
|
||||
index?: number;
|
||||
}> &
|
||||
Without<PrimitiveDivAttributes, {}>;
|
||||
Loading…
Reference in new issue