|
|
|
|
@ -5,7 +5,7 @@ import { BREADCRUMB_LANGS } from './langs';
|
|
|
|
|
import type { BreadcrumbCurrent } from './types';
|
|
|
|
|
|
|
|
|
|
import { breadcrumbMorfo } from '../../../morfo/components/breadcrumb';
|
|
|
|
|
import type { SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
|
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ── Root ────────────────────────────────────────────────────────────────────
|
|
|
|
|
@ -21,6 +21,8 @@ interface BreadcrumbOpts
|
|
|
|
|
export class BreadcrumbProvider {
|
|
|
|
|
readonly opts: BreadcrumbOpts;
|
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
|
readonly soma: Soma;
|
|
|
|
|
readonly runtime: SomaRuntime;
|
|
|
|
|
static readonly ctx = context<BreadcrumbProvider>('Breadcrumb');
|
|
|
|
|
static get(): BreadcrumbProvider | undefined {
|
|
|
|
|
return this.ctx.getOr(undefined) as BreadcrumbProvider | undefined;
|
|
|
|
|
@ -33,30 +35,28 @@ export class BreadcrumbProvider {
|
|
|
|
|
return new BreadcrumbProvider(opts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly soma = Soma.get();
|
|
|
|
|
|
|
|
|
|
private constructor(opts: BreadcrumbOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {
|
|
|
|
|
props: {
|
|
|
|
|
ariaLabel: () => this.resolvedAriaLabel.current,
|
|
|
|
|
ariaLabelledby: () => this.opts.ariaLabelledby.current
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.part('provider', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
context: BreadcrumbProvider.ctx,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
this.soma = Soma.require();
|
|
|
|
|
this.runtime = this.soma.runtime(breadcrumbMorfo, {
|
|
|
|
|
props: {
|
|
|
|
|
ariaLabel: () => this.resolvedAriaLabel.current,
|
|
|
|
|
ariaLabelledby: () => this.opts.ariaLabelledby.current
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.runtimePart = this.runtime.part('provider', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
context: BreadcrumbProvider.ctx,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly resolvedAriaLabel: Active<string | undefined> = readableActive(() =>
|
|
|
|
|
this.opts.ariaLabelledby.current
|
|
|
|
|
? undefined
|
|
|
|
|
: this.opts.ariaLabel.current || this.soma?.langs.ts(BREADCRUMB_LANGS.LABEL) || undefined
|
|
|
|
|
: this.opts.ariaLabel.current || this.soma.langs.ts(BREADCRUMB_LANGS.LABEL) || undefined
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
|
@ -81,10 +81,12 @@ export class BreadcrumbListProvider {
|
|
|
|
|
|
|
|
|
|
private constructor(opts: BreadcrumbListOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {})
|
|
|
|
|
.part('list', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
this.provider = BreadcrumbProvider.require();
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('list', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
|
@ -117,20 +119,17 @@ export class BreadcrumbItemProvider {
|
|
|
|
|
|
|
|
|
|
private constructor(opts: BreadcrumbItemOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {
|
|
|
|
|
props: {
|
|
|
|
|
current: () => this.isCurrent
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.part('item', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
context: BreadcrumbItemProvider.ctx,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
this.provider = BreadcrumbProvider.require();
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('item', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
props: {
|
|
|
|
|
current: () => this.isCurrent
|
|
|
|
|
},
|
|
|
|
|
owner: this,
|
|
|
|
|
context: BreadcrumbItemProvider.ctx,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
|
@ -157,14 +156,16 @@ export class BreadcrumbLinkProvider {
|
|
|
|
|
|
|
|
|
|
private constructor(opts: BreadcrumbLinkOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {
|
|
|
|
|
props: {
|
|
|
|
|
current: () => this.ariaCurrent
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.part('link', { id: opts.id, ref: opts.ref, owner: this, syncAttrs: true });
|
|
|
|
|
this.provider = BreadcrumbProvider.require();
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('link', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
props: {
|
|
|
|
|
current: () => this.ariaCurrent
|
|
|
|
|
},
|
|
|
|
|
owner: this,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
this.item = BreadcrumbItemProvider.get();
|
|
|
|
|
|
|
|
|
|
// Mirror current state onto the parent Item (so `[data-breadcrumb-item]`
|
|
|
|
|
@ -216,10 +217,13 @@ export class BreadcrumbSeparatorProvider {
|
|
|
|
|
|
|
|
|
|
private constructor(opts: BreadcrumbSeparatorOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {})
|
|
|
|
|
.part('separator', { id: opts.id, ref: opts.ref, owner: this, syncAttrs: true });
|
|
|
|
|
this.provider = BreadcrumbProvider.require();
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('separator', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
|
@ -254,15 +258,17 @@ export class BreadcrumbEllipsisProvider {
|
|
|
|
|
private constructor(opts: BreadcrumbEllipsisOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.provider = BreadcrumbProvider.require();
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(breadcrumbMorfo, {
|
|
|
|
|
props: {
|
|
|
|
|
ariaLabel: () => this.resolvedAriaLabel.current,
|
|
|
|
|
interactive: () => this.isInteractive,
|
|
|
|
|
popupType: () => this.opts.popupType.current
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.part('ellipsis', { id: opts.id, ref: opts.ref, owner: this, syncAttrs: true });
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('ellipsis', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
props: {
|
|
|
|
|
ariaLabel: () => this.resolvedAriaLabel.current,
|
|
|
|
|
interactive: () => this.isInteractive,
|
|
|
|
|
popupType: () => this.opts.popupType.current
|
|
|
|
|
},
|
|
|
|
|
owner: this,
|
|
|
|
|
syncAttrs: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readonly isInteractive = $derived.by(() => this.opts.interactive.current);
|
|
|
|
|
@ -270,7 +276,7 @@ export class BreadcrumbEllipsisProvider {
|
|
|
|
|
readonly resolvedAriaLabel: Active<string | undefined> = readableActive(
|
|
|
|
|
() =>
|
|
|
|
|
this.opts.ariaLabel.current ||
|
|
|
|
|
this.provider.soma?.langs.ts(BREADCRUMB_LANGS.ELLIPSIS) ||
|
|
|
|
|
this.provider.soma.langs.ts(BREADCRUMB_LANGS.ELLIPSIS) ||
|
|
|
|
|
undefined
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|