Consolidate Soma dropdown menu runtime

active-uix
dev 5 months ago
parent 5581f548cd
commit aa5581121d

@ -36,7 +36,7 @@ import {
import { SafePolygon } from '../../layers/floating/safe-polygon'; import { SafePolygon } from '../../layers/floating/safe-polygon';
import { dropdownMenuMorfo } from '../../../morfo/components/dropdown-menu'; import { dropdownMenuMorfo } from '../../../morfo/components/dropdown-menu';
import type { SomaRuntimePart } from '../../runtime.svelte'; import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
const attrs = createAttrs(dropdownMenuMorfo); const attrs = createAttrs(dropdownMenuMorfo);
@ -93,6 +93,8 @@ interface MenuOpts
export class MenuProvider { export class MenuProvider {
readonly opts: MenuOpts; readonly opts: MenuOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
static readonly ctx = context<MenuProvider>('DropdownMenu'); static readonly ctx = context<MenuProvider>('DropdownMenu');
static get(): MenuProvider | undefined { static get(): MenuProvider | undefined {
return this.ctx.getOr(undefined) as MenuProvider | undefined; return this.ctx.getOr(undefined) as MenuProvider | undefined;
@ -105,7 +107,6 @@ export class MenuProvider {
return new MenuProvider(opts); return new MenuProvider(opts);
} }
readonly config = Soma.get();
readonly floatingProvider: FloatingProvider; readonly floatingProvider: FloatingProvider;
readonly contentPresence: Presence; readonly contentPresence: Presence;
readonly typeahead = new Typeahead(); readonly typeahead = new Typeahead();
@ -116,9 +117,14 @@ export class MenuProvider {
private constructor(opts: MenuOpts) { private constructor(opts: MenuOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.soma = Soma.require();
.runtime(dropdownMenuMorfo, {}) this.runtime = this.soma.runtime(dropdownMenuMorfo, {});
.part('provider', { id: opts.id, ref: opts.ref, owner: this, context: MenuProvider.ctx }); this.runtimePart = this.runtime.part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: MenuProvider.ctx
});
this.floatingProvider = FloatingProvider.create(); this.floatingProvider = FloatingProvider.create();
@ -178,10 +184,12 @@ export class MenuTriggerProvider {
private constructor(opts: MenuTriggerOpts) { private constructor(opts: MenuTriggerOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('trigger', { id: opts.id, ref: opts.ref, owner: this });
this.provider = MenuProvider.require(); this.provider = MenuProvider.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;
FloatingAnchor.create({ FloatingAnchor.create({
@ -264,17 +272,15 @@ export class MenuContentProvider {
private constructor(opts: MenuContentOpts) { private constructor(opts: MenuContentOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('content', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.provider.setContentRef(el);
}
});
this.provider = MenuProvider.require(); this.provider = MenuProvider.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
@ -342,7 +348,7 @@ export class MenuContentProvider {
// Text selection // Text selection
this.textSelection = TextSelection.use({ this.textSelection = TextSelection.use({
ref: readableActive(() => opts.ref.current), ref: readableActive(() => opts.ref.current),
dom: Soma.require().dom, dom: this.provider.soma.dom,
enabled: readableActive(() => this.provider.opts.open.current), enabled: readableActive(() => this.provider.opts.open.current),
onPointerDown: readableActive(() => () => {}), onPointerDown: readableActive(() => () => {}),
onPointerUp: readableActive(() => () => {}) onPointerUp: readableActive(() => () => {})
@ -432,9 +438,12 @@ export class MenuArrowProvider {
private constructor(opts: MenuArrowOpts) { private constructor(opts: MenuArrowOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() const provider = MenuProvider.require();
.runtime(dropdownMenuMorfo, {}) 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);
} }
@ -466,10 +475,12 @@ export class MenuItemProvider {
private constructor(opts: MenuItemOpts) { private constructor(opts: MenuItemOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('item', { id: opts.id, ref: opts.ref, owner: this });
this.provider = MenuProvider.require(); this.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('item', {
id: opts.id,
ref: opts.ref,
owner: this
});
} }
readonly onclick = (_e: SomaMouseEvent<HTMLElement>) => { readonly onclick = (_e: SomaMouseEvent<HTMLElement>) => {
@ -527,9 +538,13 @@ export class MenuGroupProvider {
private constructor(opts: MenuGroupOpts) { private constructor(opts: MenuGroupOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() const provider = MenuProvider.require();
.runtime(dropdownMenuMorfo, {}) this.runtimePart = provider.runtime.part('group', {
.part('group', { id: opts.id, ref: opts.ref, owner: this, context: MenuGroupProvider.ctx }); id: opts.id,
ref: opts.ref,
owner: this,
context: MenuGroupProvider.ctx
});
} }
readonly props = $derived.by(() => readonly props = $derived.by(() =>
@ -554,9 +569,12 @@ export class MenuGroupHeadingProvider {
private constructor(opts: MenuGroupHeadingOpts) { private constructor(opts: MenuGroupHeadingOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() const provider = MenuProvider.require();
.runtime(dropdownMenuMorfo, {}) this.runtimePart = provider.runtime.part('group-heading', {
.part('group-heading', { id: opts.id, ref: opts.ref, owner: this }); id: opts.id,
ref: opts.ref,
owner: this
});
// Register with parent group if available // Register with parent group if available
const group = MenuGroupProvider.get() as MenuGroupProvider | undefined; const group = MenuGroupProvider.get() as MenuGroupProvider | undefined;
if (group) { if (group) {
@ -582,9 +600,12 @@ export class MenuSeparatorProvider {
private constructor(opts: MenuSeparatorOpts) { private constructor(opts: MenuSeparatorOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() const provider = MenuProvider.require();
.runtime(dropdownMenuMorfo, {}) 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(() =>
@ -657,10 +678,12 @@ export class MenuCheckboxItemProvider {
private constructor(opts: MenuCheckboxItemOpts) { private constructor(opts: MenuCheckboxItemOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('checkbox-item', { id: opts.id, ref: opts.ref, owner: this });
this.provider = MenuProvider.require(); this.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('checkbox-item', {
id: opts.id,
ref: opts.ref,
owner: this
});
this.group = MenuCheckboxGroupProvider.get(); this.group = MenuCheckboxGroupProvider.get();
} }
@ -735,7 +758,8 @@ export class MenuRadioGroupProvider {
private constructor(opts: MenuRadioGroupOpts) { private constructor(opts: MenuRadioGroupOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require().runtime(dropdownMenuMorfo, {}).part('radio-group', { const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('radio-group', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -776,10 +800,12 @@ export class MenuRadioItemProvider {
private constructor(opts: MenuRadioItemOpts) { private constructor(opts: MenuRadioItemOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('radio-item', { id: opts.id, ref: opts.ref, owner: this });
this.provider = MenuProvider.require(); this.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('radio-item', {
id: opts.id,
ref: opts.ref,
owner: this
});
this.radioGroup = MenuRadioGroupProvider.require(); this.radioGroup = MenuRadioGroupProvider.require();
} }
@ -905,17 +931,15 @@ export class MenuSubTriggerProvider {
// A30: register subTriggerRef via `onRefChange` (attachRef fires at // A30: register subTriggerRef via `onRefChange` (attachRef fires at
// mount/unmount inside `untrack`), avoiding the `$effect` feedback. // mount/unmount inside `untrack`), avoiding the `$effect` feedback.
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('sub-trigger', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.subTriggerRef.current = el;
}
});
this.sub = MenuSubProvider.require(); this.sub = MenuSubProvider.require();
this.runtimePart = this.sub.provider.runtime.part('sub-trigger', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.subTriggerRef.current = el;
}
});
this.sub.subTriggerId.current = opts.id.current; this.sub.subTriggerId.current = opts.id.current;
FloatingAnchor.create({ FloatingAnchor.create({
@ -1032,17 +1056,15 @@ export class MenuSubContentProvider {
private constructor(opts: MenuSubContentOpts) { private constructor(opts: MenuSubContentOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(dropdownMenuMorfo, {})
.part('sub-content', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.setContentRef(el);
}
});
this.sub = MenuSubProvider.require(); this.sub = MenuSubProvider.require();
this.runtimePart = this.sub.provider.runtime.part('sub-content', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.setContentRef(el);
}
});
this.sub.contentId.current = opts.id.current; this.sub.contentId.current = opts.id.current;
this.floating = FloatingContent.create({ this.floating = FloatingContent.create({

Loading…
Cancel
Save

Powered by TurnKey Linux.