|
|
|
@ -10,7 +10,7 @@ import { EDITABLE_LANGS } from './langs';
|
|
|
|
import { editableMorfo } from '../../../morfo/components/editable';
|
|
|
|
import { editableMorfo } from '../../../morfo/components/editable';
|
|
|
|
|
|
|
|
|
|
|
|
const attrs = createAttrs(editableMorfo);
|
|
|
|
const attrs = createAttrs(editableMorfo);
|
|
|
|
import type { SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export type ActivationMode = 'focus' | 'click' | 'dblclick' | 'none';
|
|
|
|
export type ActivationMode = 'focus' | 'click' | 'dblclick' | 'none';
|
|
|
|
@ -41,6 +41,8 @@ interface EditableOpts
|
|
|
|
export class EditableProvider {
|
|
|
|
export class EditableProvider {
|
|
|
|
readonly opts: EditableOpts;
|
|
|
|
readonly opts: EditableOpts;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
readonly runtimePart: SomaRuntimePart;
|
|
|
|
|
|
|
|
readonly soma: Soma;
|
|
|
|
|
|
|
|
readonly runtime: SomaRuntime;
|
|
|
|
static readonly ctx = context<EditableProvider>('Editable');
|
|
|
|
static readonly ctx = context<EditableProvider>('Editable');
|
|
|
|
static get(): EditableProvider | undefined {
|
|
|
|
static get(): EditableProvider | undefined {
|
|
|
|
return this.ctx.getOr(undefined) as EditableProvider | undefined;
|
|
|
|
return this.ctx.getOr(undefined) as EditableProvider | undefined;
|
|
|
|
@ -53,8 +55,6 @@ export class EditableProvider {
|
|
|
|
return new EditableProvider(opts);
|
|
|
|
return new EditableProvider(opts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly soma = Soma.get();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Draft value (in-progress edit)
|
|
|
|
// Draft value (in-progress edit)
|
|
|
|
draft = $state('');
|
|
|
|
draft = $state('');
|
|
|
|
inputRef = state<HTMLElement | null>(null);
|
|
|
|
inputRef = state<HTMLElement | null>(null);
|
|
|
|
@ -62,9 +62,14 @@ export class EditableProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableOpts) {
|
|
|
|
private constructor(opts: EditableOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
this.soma = Soma.require();
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
this.runtime = this.soma.runtime(editableMorfo, {});
|
|
|
|
.part('provider', { id: opts.id, ref: opts.ref, owner: this, context: EditableProvider.ctx });
|
|
|
|
this.runtimePart = this.runtime.part('provider', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this,
|
|
|
|
|
|
|
|
context: EditableProvider.ctx
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
this.draft = opts.value.current;
|
|
|
|
this.draft = opts.value.current;
|
|
|
|
|
|
|
|
|
|
|
|
@ -149,10 +154,12 @@ export class EditableAreaProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableAreaOpts) {
|
|
|
|
private constructor(opts: EditableAreaOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
|
|
|
|
.part('area', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('area', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
readonly props = $derived.by(() =>
|
|
|
|
@ -180,10 +187,12 @@ export class EditablePreviewProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditablePreviewOpts) {
|
|
|
|
private constructor(opts: EditablePreviewOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
|
|
|
|
.part('preview', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('preview', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly displayValue = $derived.by(
|
|
|
|
readonly displayValue = $derived.by(
|
|
|
|
@ -244,9 +253,8 @@ export class EditableInputProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableInputOpts) {
|
|
|
|
private constructor(opts: EditableInputOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
this.runtimePart = this.provider.runtime.part('input', {
|
|
|
|
.part('input', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
id: opts.id,
|
|
|
|
ref: opts.ref,
|
|
|
|
ref: opts.ref,
|
|
|
|
owner: this,
|
|
|
|
owner: this,
|
|
|
|
@ -254,7 +262,6 @@ export class EditableInputProvider {
|
|
|
|
this.provider.inputRef.current = el;
|
|
|
|
this.provider.inputRef.current = el;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly oninput = (e: Event) => {
|
|
|
|
readonly oninput = (e: Event) => {
|
|
|
|
@ -335,10 +342,12 @@ export class EditableEditTriggerProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableEditTriggerOpts) {
|
|
|
|
private constructor(opts: EditableEditTriggerOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
|
|
|
|
.part('edit-trigger', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('edit-trigger', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
@ -350,7 +359,7 @@ export class EditableEditTriggerProvider {
|
|
|
|
...this.runtimePart.props,
|
|
|
|
...this.runtimePart.props,
|
|
|
|
type: 'button' as const,
|
|
|
|
type: 'button' as const,
|
|
|
|
hidden: this.provider.isEditing || undefined,
|
|
|
|
hidden: this.provider.isEditing || undefined,
|
|
|
|
'aria-label': this.provider.soma?.langs.ts(EDITABLE_LANGS.EDIT),
|
|
|
|
'aria-label': this.provider.soma.langs.ts(EDITABLE_LANGS.EDIT),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
disabled:
|
|
|
|
disabled:
|
|
|
|
@ -375,10 +384,12 @@ export class EditableSubmitTriggerProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableSubmitTriggerOpts) {
|
|
|
|
private constructor(opts: EditableSubmitTriggerOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
|
|
|
|
.part('submit-trigger', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('submit-trigger', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
@ -390,7 +401,7 @@ export class EditableSubmitTriggerProvider {
|
|
|
|
...this.runtimePart.props,
|
|
|
|
...this.runtimePart.props,
|
|
|
|
type: 'button' as const,
|
|
|
|
type: 'button' as const,
|
|
|
|
hidden: !this.provider.isEditing || undefined,
|
|
|
|
hidden: !this.provider.isEditing || undefined,
|
|
|
|
'aria-label': this.provider.soma?.langs.ts(EDITABLE_LANGS.SUBMIT),
|
|
|
|
'aria-label': this.provider.soma.langs.ts(EDITABLE_LANGS.SUBMIT),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
disabled:
|
|
|
|
disabled:
|
|
|
|
@ -415,10 +426,12 @@ export class EditableCancelTriggerProvider {
|
|
|
|
|
|
|
|
|
|
|
|
private constructor(opts: EditableCancelTriggerOpts) {
|
|
|
|
private constructor(opts: EditableCancelTriggerOpts) {
|
|
|
|
this.opts = opts;
|
|
|
|
this.opts = opts;
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
|
|
|
.runtime(editableMorfo, {})
|
|
|
|
|
|
|
|
.part('cancel-trigger', { id: opts.id, ref: opts.ref, owner: this });
|
|
|
|
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
this.provider = EditableProvider.require();
|
|
|
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('cancel-trigger', {
|
|
|
|
|
|
|
|
id: opts.id,
|
|
|
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
|
|
|
owner: this
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
|
|
|
|
@ -430,7 +443,7 @@ export class EditableCancelTriggerProvider {
|
|
|
|
...this.runtimePart.props,
|
|
|
|
...this.runtimePart.props,
|
|
|
|
type: 'button' as const,
|
|
|
|
type: 'button' as const,
|
|
|
|
hidden: !this.provider.isEditing || undefined,
|
|
|
|
hidden: !this.provider.isEditing || undefined,
|
|
|
|
'aria-label': this.provider.soma?.langs.ts(EDITABLE_LANGS.CANCEL),
|
|
|
|
'aria-label': this.provider.soma.langs.ts(EDITABLE_LANGS.CANCEL),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-disabled': boolToEmptyStrOrUndef(this.provider.opts.disabled.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
'data-readonly': boolToEmptyStrOrUndef(this.provider.opts.readonly.current),
|
|
|
|
disabled: this.provider.opts.disabled.current || undefined,
|
|
|
|
disabled: this.provider.opts.disabled.current || undefined,
|
|
|
|
|