Consolidate Soma overlay runtimes

active-uix
dev 5 months ago
parent cac7e89232
commit c7527fc107

@ -19,7 +19,7 @@ import {
import { linkPreviewMorfo } from '../../../morfo/components/link-preview'; import { linkPreviewMorfo } from '../../../morfo/components/link-preview';
import { Soma } from '../../core/soma.svelte'; import { Soma } from '../../core/soma.svelte';
import type { SomaRuntimePart } from '../../runtime.svelte'; import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
// ── Root ───────────────────────────────────────────────────────────────────── // ── Root ─────────────────────────────────────────────────────────────────────
@ -38,6 +38,8 @@ interface LinkPreviewOpts
export class LinkPreviewProvider { export class LinkPreviewProvider {
readonly opts: LinkPreviewOpts; readonly opts: LinkPreviewOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
static readonly ctx = context<LinkPreviewProvider>('LinkPreview'); static readonly ctx = context<LinkPreviewProvider>('LinkPreview');
static get(): LinkPreviewProvider | undefined { static get(): LinkPreviewProvider | undefined {
return this.ctx.getOr(undefined) as LinkPreviewProvider | undefined; return this.ctx.getOr(undefined) as LinkPreviewProvider | undefined;
@ -63,9 +65,9 @@ export class LinkPreviewProvider {
private constructor(opts: LinkPreviewOpts) { private constructor(opts: LinkPreviewOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.soma = Soma.require();
.runtime(linkPreviewMorfo, {}) this.runtime = this.soma.runtime(linkPreviewMorfo, {});
.part('provider', { this.runtimePart = this.runtime.part('provider', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -164,9 +166,8 @@ export class LinkPreviewTriggerProvider {
private constructor(opts: LinkPreviewTriggerOpts) { private constructor(opts: LinkPreviewTriggerOpts) {
// A30: mirror trigger element to provider via `onRefChange`. // A30: mirror trigger element to provider via `onRefChange`.
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = LinkPreviewProvider.require();
.runtime(linkPreviewMorfo, {}) this.runtimePart = this.provider.runtime.part('trigger', {
.part('trigger', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -174,7 +175,6 @@ export class LinkPreviewTriggerProvider {
this.provider.triggerRef.current = el; this.provider.triggerRef.current = el;
} }
}); });
this.provider = LinkPreviewProvider.require();
this.provider.triggerId.current = opts.id.current; this.provider.triggerId.current = opts.id.current;
FloatingAnchor.create({ FloatingAnchor.create({
@ -245,9 +245,8 @@ export class LinkPreviewContentProvider {
private constructor(opts: LinkPreviewContentOpts) { private constructor(opts: LinkPreviewContentOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = LinkPreviewProvider.require();
.runtime(linkPreviewMorfo, {}) this.runtimePart = this.provider.runtime.part('content', {
.part('content', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -255,7 +254,6 @@ export class LinkPreviewContentProvider {
this.provider.setContentRef(el); this.provider.setContentRef(el);
} }
}); });
this.provider = LinkPreviewProvider.require();
this.provider.contentId.current = opts.id.current; this.provider.contentId.current = opts.id.current;
this.floating = FloatingContent.create({ this.floating = FloatingContent.create({
@ -344,6 +342,7 @@ interface LinkPreviewArrowOpts extends WithRefOpts {}
export class LinkPreviewArrowProvider { export class LinkPreviewArrowProvider {
readonly opts: LinkPreviewArrowOpts; readonly opts: LinkPreviewArrowOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly provider: LinkPreviewProvider;
static create(opts: LinkPreviewArrowOpts) { static create(opts: LinkPreviewArrowOpts) {
return new LinkPreviewArrowProvider(opts); return new LinkPreviewArrowProvider(opts);
} }
@ -352,9 +351,12 @@ export class LinkPreviewArrowProvider {
private constructor(opts: LinkPreviewArrowOpts) { private constructor(opts: LinkPreviewArrowOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = LinkPreviewProvider.require();
.runtime(linkPreviewMorfo, {}) this.runtimePart = this.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);
} }

@ -7,7 +7,7 @@ import { SCROLL_AREA_LANGS } from './langs';
import { isBrowser } from '$adom'; import { isBrowser } from '$adom';
import { scrollAreaMorfo } from '../../../morfo/components/scroll-area'; import { scrollAreaMorfo } from '../../../morfo/components/scroll-area';
import type { SomaRuntimePart } from '../../runtime.svelte'; import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
export type ScrollAreaType = 'hover' | 'scroll' | 'auto' | 'always'; export type ScrollAreaType = 'hover' | 'scroll' | 'auto' | 'always';
@ -26,6 +26,8 @@ interface ScrollAreaOpts
export class ScrollAreaProvider { export class ScrollAreaProvider {
readonly opts: ScrollAreaOpts; readonly opts: ScrollAreaOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
static readonly ctx = context<ScrollAreaProvider>('ScrollArea'); static readonly ctx = context<ScrollAreaProvider>('ScrollArea');
static get(): ScrollAreaProvider | undefined { static get(): ScrollAreaProvider | undefined {
return this.ctx.getOr(undefined) as ScrollAreaProvider | undefined; return this.ctx.getOr(undefined) as ScrollAreaProvider | undefined;
@ -38,8 +40,6 @@ export class ScrollAreaProvider {
return new ScrollAreaProvider(opts); return new ScrollAreaProvider(opts);
} }
readonly soma = Soma.get();
// Viewport tracking // Viewport tracking
viewportRef = state<HTMLElement | null>(null); viewportRef = state<HTMLElement | null>(null);
contentWidth = $state(0); contentWidth = $state(0);
@ -53,9 +53,9 @@ export class ScrollAreaProvider {
private constructor(opts: ScrollAreaOpts) { private constructor(opts: ScrollAreaOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.soma = Soma.require();
.runtime(scrollAreaMorfo, {}) this.runtime = this.soma.runtime(scrollAreaMorfo, {});
.part('provider', { this.runtimePart = this.runtime.part('provider', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -169,9 +169,8 @@ export class ScrollAreaViewportProvider {
private constructor(opts: ScrollAreaViewportOpts) { private constructor(opts: ScrollAreaViewportOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = ScrollAreaProvider.require();
.runtime(scrollAreaMorfo, {}) this.runtimePart = this.provider.runtime.part('viewport', {
.part('viewport', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
@ -179,7 +178,6 @@ export class ScrollAreaViewportProvider {
this.provider.setupViewport(el); this.provider.setupViewport(el);
} }
}); });
this.provider = ScrollAreaProvider.require();
} }
readonly onscroll = (e: Event) => { readonly onscroll = (e: Event) => {
@ -241,15 +239,13 @@ export class ScrollAreaScrollbarProvider {
private constructor(opts: ScrollAreaScrollbarOpts) { private constructor(opts: ScrollAreaScrollbarOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = ScrollAreaProvider.require();
.runtime(scrollAreaMorfo, {}) this.runtimePart = this.provider.runtime.part('scrollbar', {
.part('scrollbar', {
id: opts.id, id: opts.id,
ref: opts.ref, ref: opts.ref,
owner: this, owner: this,
context: ScrollAreaScrollbarProvider.ctx context: ScrollAreaScrollbarProvider.ctx
}); });
this.provider = ScrollAreaProvider.require();
// Skip initial-mount flash — defer mounted flag to next frame // Skip initial-mount flash — defer mounted flag to next frame
requestAnimationFrame(() => { requestAnimationFrame(() => {
@ -387,8 +383,8 @@ export class ScrollAreaScrollbarProvider {
'aria-valuemax': 100, 'aria-valuemax': 100,
'aria-orientation': this.opts.orientation.current, 'aria-orientation': this.opts.orientation.current,
'aria-label': this.isVertical 'aria-label': this.isVertical
? this.provider.soma?.langs.ts(SCROLL_AREA_LANGS.SCROLLBAR_VERTICAL) ? this.provider.soma.langs.ts(SCROLL_AREA_LANGS.SCROLLBAR_VERTICAL)
: this.provider.soma?.langs.ts(SCROLL_AREA_LANGS.SCROLLBAR_HORIZONTAL), : this.provider.soma.langs.ts(SCROLL_AREA_LANGS.SCROLLBAR_HORIZONTAL),
tabindex: -1, tabindex: -1,
'data-state': this.shouldShow ? 'visible' : 'hidden', 'data-state': this.shouldShow ? 'visible' : 'hidden',
'data-orientation': this.opts.orientation.current, 'data-orientation': this.opts.orientation.current,
@ -424,11 +420,13 @@ export class ScrollAreaThumbProvider {
private constructor(opts: ScrollAreaThumbOpts) { private constructor(opts: ScrollAreaThumbOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(scrollAreaMorfo, {})
.part('thumb', { id: opts.id, ref: opts.ref, owner: this });
this.scrollbar = ScrollAreaScrollbarProvider.require(); this.scrollbar = ScrollAreaScrollbarProvider.require();
this.provider = this.scrollbar.provider; this.provider = this.scrollbar.provider;
this.runtimePart = this.provider.runtime.part('thumb', {
id: opts.id,
ref: opts.ref,
owner: this
});
} }
private get isVertical(): boolean { private get isVertical(): boolean {
@ -561,10 +559,12 @@ export class ScrollAreaCornerProvider {
private constructor(opts: ScrollAreaCornerOpts) { private constructor(opts: ScrollAreaCornerOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require()
.runtime(scrollAreaMorfo, {})
.part('corner', { id: opts.id, ref: opts.ref, owner: this });
this.provider = ScrollAreaProvider.require(); this.provider = ScrollAreaProvider.require();
this.runtimePart = this.provider.runtime.part('corner', {
id: opts.id,
ref: opts.ref,
owner: this
});
} }
readonly shouldShow = $derived.by(() => this.provider.hasOverflowX && this.provider.hasOverflowY); readonly shouldShow = $derived.by(() => this.provider.hasOverflowX && this.provider.hasOverflowY);

@ -30,7 +30,7 @@ import {
import { tooltipMorfo } from '../../../morfo/components/tooltip'; import { tooltipMorfo } from '../../../morfo/components/tooltip';
import { Soma } from '../../core/soma.svelte'; import { Soma } from '../../core/soma.svelte';
import type { SomaRuntimePart } from '../../runtime.svelte'; import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
export type TooltipState = 'closed' | 'delayed-open' | 'instant-open'; export type TooltipState = 'closed' | 'delayed-open' | 'instant-open';
@ -93,6 +93,8 @@ interface TooltipOpts
export class TooltipProvider { export class TooltipProvider {
readonly opts: TooltipOpts; readonly opts: TooltipOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
static readonly ctx = context<TooltipProvider>('Tooltip'); static readonly ctx = context<TooltipProvider>('Tooltip');
static get(): TooltipProvider | undefined { static get(): TooltipProvider | undefined {
return this.ctx.getOr(undefined) as TooltipProvider | undefined; return this.ctx.getOr(undefined) as TooltipProvider | undefined;
@ -137,9 +139,14 @@ export class TooltipProvider {
private constructor(opts: TooltipOpts) { private constructor(opts: TooltipOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.soma = Soma.require();
.runtime(tooltipMorfo, {}) this.runtime = this.soma.runtime(tooltipMorfo, {});
.part('provider', { id: opts.id, ref: opts.ref, owner: this, context: TooltipProvider.ctx }); this.runtimePart = this.runtime.part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: TooltipProvider.ctx
});
this.group = TooltipGroupProvider.get(); this.group = TooltipGroupProvider.get();
this.floatingProvider = FloatingProvider.create(); this.floatingProvider = FloatingProvider.create();
@ -257,21 +264,16 @@ export class TooltipTriggerProvider {
// A30: mirror trigger element to provider via `onRefChange`. // A30: mirror trigger element to provider via `onRefChange`.
this.opts = opts; this.opts = opts;
this.provider = TooltipProvider.require(); this.provider = TooltipProvider.require();
this.runtimePart = Soma.require() this.runtimePart = this.provider.runtime.part('trigger', {
.runtime(tooltipMorfo, { id: opts.id,
ref: opts.ref,
states: { states: {
'instant-open': () => this.provider.tooltipState 'instant-open': () => this.provider.tooltipState
}, },
parts: { parts: {
content: () => content: () =>
this.provider.opts.open.current this.provider.opts.open.current ? this.provider.contentId.current || undefined : undefined
? this.provider.contentId.current || undefined },
: undefined
}
})
.part('trigger', {
id: opts.id,
ref: opts.ref,
owner: this, owner: this,
onRefChange: (el) => { onRefChange: (el) => {
this.provider.triggerRef.current = el; this.provider.triggerRef.current = el;
@ -353,18 +355,15 @@ export class TooltipContentProvider {
private constructor(opts: TooltipContentOpts) { private constructor(opts: TooltipContentOpts) {
this.opts = opts; this.opts = opts;
this.provider = TooltipProvider.require(); this.provider = TooltipProvider.require();
this.runtimePart = Soma.require() this.runtimePart = this.provider.runtime.part('content', {
.runtime(tooltipMorfo, { id: opts.id,
ref: opts.ref,
states: { states: {
'instant-open': () => this.provider.tooltipState 'instant-open': () => this.provider.tooltipState
}, },
props: { props: {
ariaLabel: () => this.opts.ariaLabel.current ariaLabel: () => this.opts.ariaLabel.current
} },
})
.part('content', {
id: opts.id,
ref: opts.ref,
owner: this, owner: this,
onRefChange: (el) => { onRefChange: (el) => {
this.provider.setContentRef(el); this.provider.setContentRef(el);
@ -453,6 +452,7 @@ interface TooltipArrowOpts extends WithRefOpts {}
export class TooltipArrowProvider { export class TooltipArrowProvider {
readonly opts: TooltipArrowOpts; readonly opts: TooltipArrowOpts;
readonly runtimePart: SomaRuntimePart; readonly runtimePart: SomaRuntimePart;
readonly provider: TooltipProvider;
static create(opts: TooltipArrowOpts) { static create(opts: TooltipArrowOpts) {
return new TooltipArrowProvider(opts); return new TooltipArrowProvider(opts);
} }
@ -461,9 +461,12 @@ export class TooltipArrowProvider {
private constructor(opts: TooltipArrowOpts) { private constructor(opts: TooltipArrowOpts) {
this.opts = opts; this.opts = opts;
this.runtimePart = Soma.require() this.provider = TooltipProvider.require();
.runtime(tooltipMorfo, {}) this.runtimePart = this.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);
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.