phonograph/svelte/src/form-transitions-editor.webc.svelte

88 lines
2.1 KiB
Svelte
Raw Normal View History

2025-10-01 22:36:19 -07:00
<svelte:options
customElement={{
props: {
identifier_hints: { attribute: "identifier-hints", type: "Array" },
portals: { type: "Array" },
value: { type: "Array" },
},
shadow: "none",
tag: "form-transitions-editor",
}}
/>
<!--
@component
Interactive island for configuring the form navigation that occurs when a user
submits a portal's form.
-->
<script lang="ts">
import { type PgExpressionAny } from "./expression.svelte";
import ExpressionEditor from "./expression-editor.webc.svelte";
type Props = {
identifier_hints: string[];
portals: {
id: string;
display_name: string;
}[];
value: {
condition?: PgExpressionAny;
dest?: string;
}[];
};
let {
identifier_hints = [],
portals = [],
value: initial_value = [],
}: Props = $props();
// Prop of this webc component cannot be bound to `<ExpressionEditor value>`
// without freezing up the child component.
let value = $state(initial_value);
function handle_add_transition_button_click() {
value = [...value, {}];
}
</script>
<div class="form-transitions-editor">
<ul class="form-transitions-editor__transitions-list">
{#each value as _, i}
<li class="form-transitions-editor__transition-item">
<div>
Continue to form:
<select name="dest" bind:value={value[i].dest}>
{#each portals as portal}
<option value={portal.id}>{portal.display_name}</option>
{/each}
</select>
</div>
<div>
if:
<ExpressionEditor
{identifier_hints}
bind:value={value[i].condition}
/>
<input
type="hidden"
name="condition"
value={JSON.stringify(value[i].condition)}
/>
</div>
</li>
{/each}
</ul>
<button
class="button--secondary"
onclick={handle_add_transition_button_click}
type="button"
>
Add Destination
</button>
<div>
If no destinations match, the user will be redirected to a success page.
</div>
</div>