phonograph/svelte/src/expression-editor.webc.svelte

105 lines
3.1 KiB
Svelte
Raw Normal View History

2025-08-24 23:24:01 -07:00
<svelte:options
customElement={{
props: {
identifier_hints: { attribute: "identifier-hints", type: "Array" },
value: { reflect: true, type: "Object" },
},
shadow: "none",
tag: "expression-editor",
}}
/>
<script lang="ts">
import DatumEditor from "./datum-editor.svelte";
2025-08-24 23:24:01 -07:00
import ExpressionSelector from "./expression-selector.svelte";
import { type PgExpressionAny } from "./expression.svelte";
import ExpressionEditor from "./expression-editor.webc.svelte";
2025-09-08 15:56:57 -07:00
import { type FieldInfo } from "./field.svelte";
import { type Presentation } from "./presentation.svelte";
2025-10-16 06:40:11 +00:00
import type { Datum } from "./datum.svelte";
2025-08-24 23:24:01 -07:00
2025-09-08 15:56:57 -07:00
const ASSIGNABLE_PRESENTATIONS: Presentation[] = [
{ t: "Text", c: { input_mode: { t: "MultiLine", c: {} } } },
2025-08-24 23:24:01 -07:00
{ t: "Timestamp", c: {} },
{ t: "Uuid", c: {} },
];
2025-09-08 15:56:57 -07:00
const ASSIGNABLE_FIELDS: FieldInfo[] = ASSIGNABLE_PRESENTATIONS.map(
(presentation) => ({
2025-08-24 23:24:01 -07:00
field: {
id: "",
table_label: "",
2025-08-24 23:24:01 -07:00
name: "",
2025-09-08 15:56:57 -07:00
presentation,
table_width_px: -1,
2025-08-24 23:24:01 -07:00
},
not_null: true,
has_default: false,
}),
);
type Props = {
identifier_hints?: string[];
value?: PgExpressionAny;
};
let { identifier_hints = [], value = $bindable() }: Props = $props();
2025-10-16 06:40:11 +00:00
// Dynamic state to bind to datum editor.
let editor_value = $state<Datum | undefined>();
2025-08-24 23:24:01 -07:00
let editor_field_info = $state<FieldInfo>(ASSIGNABLE_FIELDS[0]);
$effect(() => {
2025-10-16 06:40:11 +00:00
editor_value = value?.t === "Literal" ? value.c : undefined;
2025-08-24 23:24:01 -07:00
});
function handle_identifier_selector_change(
ev: Event & { currentTarget: HTMLSelectElement },
) {
if (value?.t === "Identifier") {
value.c.parts_raw = [ev.currentTarget.value];
}
}
2025-10-16 06:40:11 +00:00
function handle_editor_change(datum_value: Datum) {
if (value?.t === "Literal") {
value.c = datum_value;
}
}
2025-08-24 23:24:01 -07:00
</script>
<div class="expression-editor__container">
<div class="expression-editor__sidebar">
<ExpressionSelector bind:value />
</div>
{#if value !== undefined}
<div class="expression-editor__main">
<div class="expression-editor__params">
{#if value.t === "Comparison"}
{#if value.c.t === "Infix"}
<ExpressionEditor bind:value={value.c.c.lhs} {identifier_hints} />
<ExpressionEditor bind:value={value.c.c.rhs} {identifier_hints} />
{:else if value.c.t === "IsNull" || value.c.t === "IsNotNull"}
<ExpressionEditor bind:value={value.c.c.lhs} {identifier_hints} />
{/if}
{:else if value.t === "Identifier"}
<select
onchange={handle_identifier_selector_change}
value={value.c.parts_raw[0]}
>
{#each identifier_hints as hint}
<option value={hint}>{hint}</option>
{/each}
</select>
{:else if value.t === "Literal"}
<DatumEditor
2025-08-24 23:24:01 -07:00
bind:field_info={editor_field_info}
2025-10-16 06:40:11 +00:00
bind:value={editor_value}
2025-08-24 23:24:01 -07:00
assignable_fields={ASSIGNABLE_FIELDS}
2025-10-16 06:40:11 +00:00
on_change={handle_editor_change}
2025-08-24 23:24:01 -07:00
/>
{/if}
</div>
</div>
{/if}
</div>