|
|
|
@ -27,7 +27,7 @@ import {
|
|
|
|
} from '../../layers/floating';
|
|
|
|
} from '../../layers/floating';
|
|
|
|
|
|
|
|
|
|
|
|
import { comboboxMorfo } from '../../../morfo/components/combobox';
|
|
|
|
import { comboboxMorfo } from '../../../morfo/components/combobox';
|
|
|
|
import type { SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
|
|
|
|
|
|
|
|
const attrs = createAttrs(comboboxMorfo);
|
|
|
|
const attrs = createAttrs(comboboxMorfo);
|
|
|
|
|
|
|
|
|
|
|
|
@ -53,6 +53,8 @@ interface ComboboxOpts
|
|
|
|
export class ComboboxProvider {
|
|
|
|
export class ComboboxProvider {
|
|
|
|
readonly opts: ComboboxOpts;
|
|
|
|
readonly opts: ComboboxOpts;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
|
|
|
|
readonly soma: Soma;
|
|
|
|
|
|
|
|
readonly runtime: SomaRuntime;
|
|
|
|
static readonly ctx = context<ComboboxProvider>('Combobox');
|
|
|
|
static readonly ctx = context<ComboboxProvider>('Combobox');
|
|
|
|
static get(): ComboboxProvider | undefined {
|
|
|
|
static get(): ComboboxProvider | undefined {
|
|
|
|
return this.ctx.getOr(undefined) as ComboboxProvider | undefined;
|
|
|
|
return this.ctx.getOr(undefined) as ComboboxProvider | undefined;
|
|
|
|
@ -65,7 +67,6 @@ export class ComboboxProvider {
|
|
|
|
return new ComboboxProvider(opts);
|
|
|
|
return new ComboboxProvider(opts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly soma = Soma.get();
|
|
|
|
|
|
|
|
readonly floatingProvider: FloatingProvider;
|
|
|
|
readonly floatingProvider: FloatingProvider;
|
|
|
|
readonly contentPresence: Presence;
|
|
|
|
readonly contentPresence: Presence;
|
|
|
|
|
|
|
|
|
|
|
|
@ -98,9 +99,14 @@ export class ComboboxProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxOpts) {
|
|
|
|
private constructor(opts: ComboboxOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
this.soma = Soma.require();
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
this.runtime = this.soma.runtime(comboboxMorfo, {});
|
|
|
|
.part('provider', { id: opts.id, ref: opts.ref, owner: this, context: ComboboxProvider.ctx });
|
|
|
|
this.runtimePart = this.runtime.part('provider', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this,
|
|
|
|
|
|
|
|
context: ComboboxProvider.ctx
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
this.floatingProvider = FloatingProvider.create();
|
|
|
|
this.floatingProvider = FloatingProvider.create();
|
|
|
|
|
|
|
|
|
|
|
|
@ -191,10 +197,12 @@ export class ComboboxInputProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxInputOpts) {
|
|
|
|
private constructor(opts: ComboboxInputOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
|
|
|
|
.part('input', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('input', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
this.provider.inputId.current = opts.id.current;
|
|
|
|
this.provider.inputId.current = opts.id.current;
|
|
|
|
this.provider.inputRef = opts.ref;
|
|
|
|
this.provider.inputRef = opts.ref;
|
|
|
|
|
|
|
|
|
|
|
|
@ -297,10 +305,12 @@ export class ComboboxTriggerProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxTriggerOpts) {
|
|
|
|
private constructor(opts: ComboboxTriggerOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
|
|
|
|
.part('trigger', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('trigger', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
this.provider.triggerId.current = opts.id.current;
|
|
|
|
this.provider.triggerId.current = opts.id.current;
|
|
|
|
this.provider.triggerRef = opts.ref;
|
|
|
|
this.provider.triggerRef = opts.ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -314,7 +324,7 @@ export class ComboboxTriggerProvider {
|
|
|
|
...this.runtimePart.props,
|
|
|
|
...this.runtimePart.props,
|
|
|
|
type: 'button' as const,
|
|
|
|
type: 'button' as const,
|
|
|
|
tabindex: -1,
|
|
|
|
tabindex: -1,
|
|
|
|
'aria-label': this.provider.soma?.langs.ts(COMBOBOX_LANGS.TOGGLE),
|
|
|
|
'aria-label': this.provider.soma.langs.ts(COMBOBOX_LANGS.TOGGLE),
|
|
|
|
'aria-haspopup': 'listbox' as const,
|
|
|
|
'aria-haspopup': 'listbox' as const,
|
|
|
|
'aria-expanded': this.provider.opts.open.current,
|
|
|
|
'aria-expanded': this.provider.opts.open.current,
|
|
|
|
'aria-controls': this.provider.contentId.current || undefined,
|
|
|
|
'aria-controls': this.provider.contentId.current || undefined,
|
|
|
|
@ -364,17 +374,15 @@ export class ComboboxContentProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxContentOpts) {
|
|
|
|
private constructor(opts: ComboboxContentOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
|
|
|
|
.part('content', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this,
|
|
|
|
|
|
|
|
onRefChange: (el) => {
|
|
|
|
|
|
|
|
this.provider.setContentRef(el);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('content', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this,
|
|
|
|
|
|
|
|
onRefChange: (el) => {
|
|
|
|
|
|
|
|
this.provider.setContentRef(el);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
this.provider.contentId.current = opts.id.current;
|
|
|
|
this.provider.contentId.current = opts.id.current;
|
|
|
|
|
|
|
|
|
|
|
|
// Floating
|
|
|
|
// Floating
|
|
|
|
@ -528,9 +536,12 @@ export class ComboboxViewportProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxViewportOpts) {
|
|
|
|
private constructor(opts: ComboboxViewportOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
const provider = ComboboxProvider.require();
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
this.runtimePart = provider.runtime.part('viewport', {
|
|
|
|
.part('viewport', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
@ -563,10 +574,12 @@ export class ComboboxItemProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxItemOpts) {
|
|
|
|
private constructor(opts: ComboboxItemOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
|
|
|
|
.part('item', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('item', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Maintain value → label registry for display-text resolution without
|
|
|
|
// Maintain value → label registry for display-text resolution without
|
|
|
|
// relying on DOM queries (content may be unmounted or lazy-rendered).
|
|
|
|
// relying on DOM queries (content may be unmounted or lazy-rendered).
|
|
|
|
@ -617,6 +630,7 @@ interface ComboboxGroupOpts extends WithRefOpts {}
|
|
|
|
export class ComboboxGroupProvider {
|
|
|
|
export class ComboboxGroupProvider {
|
|
|
|
readonly opts: ComboboxGroupOpts;
|
|
|
|
readonly opts: ComboboxGroupOpts;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
|
|
|
|
readonly provider: ComboboxProvider;
|
|
|
|
static readonly ctx = context<ComboboxGroupProvider>('ComboboxGroup');
|
|
|
|
static readonly ctx = context<ComboboxGroupProvider>('ComboboxGroup');
|
|
|
|
static get(): ComboboxGroupProvider | undefined {
|
|
|
|
static get(): ComboboxGroupProvider | undefined {
|
|
|
|
return this.ctx.getOr(undefined) as ComboboxGroupProvider | undefined;
|
|
|
|
return this.ctx.getOr(undefined) as ComboboxGroupProvider | undefined;
|
|
|
|
@ -633,14 +647,13 @@ export class ComboboxGroupProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxGroupOpts) {
|
|
|
|
private constructor(opts: ComboboxGroupOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
this.provider = ComboboxProvider.require();
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
this.runtimePart = this.provider.runtime.part('group', {
|
|
|
|
.part('group', {
|
|
|
|
id: opts.id,
|
|
|
|
id: opts.id,
|
|
|
|
ref: opts.ref,
|
|
|
|
ref: opts.ref,
|
|
|
|
owner: this,
|
|
|
|
owner: this,
|
|
|
|
context: ComboboxGroupProvider.ctx
|
|
|
|
context: ComboboxGroupProvider.ctx
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
@ -667,10 +680,13 @@ export class ComboboxGroupHeadingProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxGroupHeadingOpts) {
|
|
|
|
private constructor(opts: ComboboxGroupHeadingOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
|
|
|
|
.part('group-heading', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.group = ComboboxGroupProvider.get() as ComboboxGroupProvider | undefined;
|
|
|
|
this.group = ComboboxGroupProvider.get() as ComboboxGroupProvider | undefined;
|
|
|
|
|
|
|
|
const provider = this.group?.provider ?? ComboboxProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = provider.runtime.part('group-heading', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
if (this.group) {
|
|
|
|
if (this.group) {
|
|
|
|
const group = this.group;
|
|
|
|
const group = this.group;
|
|
|
|
group.headingId.current = opts.id.current;
|
|
|
|
group.headingId.current = opts.id.current;
|
|
|
|
@ -695,9 +711,12 @@ export class ComboboxSeparatorProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxSeparatorOpts) {
|
|
|
|
private constructor(opts: ComboboxSeparatorOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
const provider = ComboboxProvider.require();
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
this.runtimePart = provider.runtime.part('separator', {
|
|
|
|
.part('separator', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
@ -723,9 +742,12 @@ export class ComboboxArrowProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: ComboboxArrowOpts) {
|
|
|
|
private constructor(opts: ComboboxArrowOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
const provider = ComboboxProvider.require();
|
|
|
|
.runtime(comboboxMorfo, {})
|
|
|
|
this.runtimePart = provider.runtime.part('arrow', {
|
|
|
|
.part('arrow', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
this.floatingArrow = FloatingArrow.create(opts);
|
|
|
|
this.floatingArrow = FloatingArrow.create(opts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|