Skip to content

Commit 6840bac

Browse files
committed
[form] Fix icons rendering during SSR
1 parent fe35ad2 commit 6840bac

File tree

9 files changed

+53
-50
lines changed

9 files changed

+53
-50
lines changed

packages/form/src/form/context/context.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getContext, setContext, type Snippet } from "svelte";
1+
import { getContext, setContext, type Component, type Snippet } from "svelte";
22

33
import type { SchedulerYield } from "@/lib/scheduler.js";
44

@@ -14,7 +14,11 @@ import type { Errors } from "../errors.js";
1414
import type { FormValidator } from "../validator.js";
1515
import type { Icons } from "../icons.js";
1616
import { type IdSchema, toIdSchema2 } from "../id-schema.js";
17-
import type { FormMerger } from '../merger.js';
17+
import type { FormMerger } from "../merger.js";
18+
19+
export type IconOrTranslationData = {
20+
[L in Label]: [L, ...Labels[L]];
21+
}[Label]
1822

1923
export interface FormContext {
2024
isSubmitted: boolean;
@@ -34,11 +38,9 @@ export interface FormContext {
3438
idSeparator: string;
3539
errors: Errors;
3640
schedulerYield: SchedulerYield;
37-
iconOrTranslation: Snippet<
38-
{
39-
[L in Label]: [[L, ...Labels[L]]];
40-
}[Label]
41-
>;
41+
/** @deprecated use `IconOrTranslation` instead */
42+
iconOrTranslation: Snippet<[IconOrTranslationData]>;
43+
IconOrTranslation: Component<{ data: IconOrTranslationData }>;
4244
}
4345

4446
const FORM_CONTEXT = Symbol("form-context");

packages/form/src/form/fields/array/array-item-field.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
arr[index - 1] = tmp
5454
}}
5555
>
56-
{@render ctx.iconOrTranslation(["move-array-item-up"])}
56+
<ctx.IconOrTranslation data={["move-array-item-up"]} />
5757
</Button>
5858
<Button
5959
{errors}
@@ -67,7 +67,7 @@
6767
arr[index + 1] = tmp
6868
}}
6969
>
70-
{@render ctx.iconOrTranslation(["move-array-item-down"])}
70+
<ctx.IconOrTranslation data={["move-array-item-down"]} />
7171
</Button>
7272
{/if}
7373
{#if canCopy}
@@ -81,7 +81,7 @@
8181
arr.splice(index, 0, $state.snapshot(value))
8282
}}
8383
>
84-
{@render ctx.iconOrTranslation(["copy-array-item"])}
84+
<ctx.IconOrTranslation data={["copy-array-item"]} />
8585
</Button>
8686
{/if}
8787
{#if canRemove}
@@ -95,7 +95,7 @@
9595
arr.splice(index, 1)
9696
}}
9797
>
98-
{@render ctx.iconOrTranslation(["remove-array-item"])}
98+
<ctx.IconOrTranslation data={["remove-array-item"]} />
9999
</Button>
100100
{/if}
101101
{/snippet}

packages/form/src/form/fields/array/fixed-array-field.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
value.push(getDefaultFieldState(ctx, schemaAdditionalItems, undefined))
6767
}}
6868
>
69-
{@render ctx.iconOrTranslation(["add-array-item"])}
69+
<ctx.IconOrTranslation data={["add-array-item"]} />
7070
</Button>
7171
{/snippet}
7272
<Template

packages/form/src/form/fields/array/normal-array-field.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
value?.push(getDefaultFieldState(ctx, schemaItems, undefined))
5353
}}
5454
>
55-
{@render ctx.iconOrTranslation(["add-array-item"])}
55+
<ctx.IconOrTranslation data={["add-array-item"]} />
5656
</Button>
5757
{/snippet}
5858
<Template

packages/form/src/form/fields/object/object-field.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
?? getDefaultValueForType(getSimpleSchemaType(schemaAdditionalProperties))
107107
}}
108108
>
109-
{@render ctx.iconOrTranslation(["add-object-property"])}
109+
<ctx.IconOrTranslation data={["add-object-property"]} />
110110
</Button>
111111
{/snippet}
112112
<Template

packages/form/src/form/fields/object/object-property-field.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
delete obj[property]
5252
}}
5353
>
54-
{@render ctx.iconOrTranslation(["remove-object-property"])}
54+
<ctx.IconOrTranslation data={["remove-object-property"]} />
5555
</Button>
5656
{/snippet}
5757
<Template

packages/form/src/form/form-base.svelte

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,13 @@
9191
getUiOptions,
9292
retrieveSchema,
9393
makeIdSchema,
94+
type IconOrTranslationData,
9495
} from './context/index.js';
9596
import { fields as defaultFields } from './fields/index.js';
9697
import { templates as defaultTemplates } from './templates/index.js';
9798
import { DEFAULT_ID_PREFIX, DEFAULT_ID_SEPARATOR } from './id-schema.js';
98-
import { DefaultFormMerger } from './merger.js'
99+
import { DefaultFormMerger } from './merger.js';
100+
import IconOrTranslation from './icon-or-translation.svelte';
99101
import SubmitButton from './submit-button.svelte';
100102
101103
let {
@@ -206,10 +208,9 @@
206208
},
207209
get schedulerYield() {
208210
return schedulerYield
209-
},
210-
get iconOrTranslation() {
211-
return iconOrTranslation
212-
}
211+
},
212+
iconOrTranslation,
213+
IconOrTranslation,
213214
}
214215
setFromContext(ctx)
215216
@@ -256,15 +257,8 @@
256257
} : onsubmit)
257258
</script>
258259

259-
{#snippet iconOrTranslation(params: {
260-
[L in Label]: [L, ...Labels[L]]
261-
}[Label])}
262-
{@const icon = icons[params[0]]}
263-
{#if icon}
264-
{@render icon(params as never)}
265-
{:else}
266-
{translation.apply(null, params)}
267-
{/if}
260+
{#snippet iconOrTranslation(data: IconOrTranslationData)}
261+
<IconOrTranslation {data} />
268262
{/snippet}
269263

270264
<Form bind:form {attributes} onsubmit={submitHandler} {config} errors={NO_ERRORS} >
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
<script lang="ts" generics="L extends Label" >
2-
import { getFormContext } from './context/context.js';
3-
import type { Label, Labels } from './translation.js'
1+
<script lang="ts">
2+
import { getFormContext, type IconOrTranslationData } from './context/context.js';
43
54
const ctx = getFormContext()
65
7-
const { data }: { data: [L, ...Labels[L]] } = $props();
6+
const { data }: { data: IconOrTranslationData } = $props();
87
98
const icon = $derived(ctx.icons[data[0]])
109
</script>
1110

1211
{#if icon}
13-
{@render icon(data)}
12+
{@render icon(data as never)}
1413
{:else}
15-
{ctx.translation.apply(null, data as never)}
14+
{ctx.translation.apply(null, data)}
1615
{/if}

packages/form/src/form/use-form.svelte.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import type { Templates } from "./templates/index.js";
1515
import type { Icons } from "./icons.js";
1616
import type { InputsValidationMode } from "./validation.js";
1717
import type { Errors } from "./errors.js";
18-
import { setFromContext, type FormContext } from "./context/index.js";
18+
import {
19+
setFromContext,
20+
type FormContext,
21+
type IconOrTranslationData,
22+
} from "./context/index.js";
1923
import { DefaultFormMerger, type FormMerger } from "./merger.js";
2024
import { fields as defaultFields } from "./fields/index.js";
2125
import { templates as defaultTemplates } from "./templates/index.js";
@@ -227,22 +231,26 @@ export function createForm<T, E>(
227231
get schedulerYield() {
228232
return schedulerYield;
229233
},
230-
iconOrTranslation: (<L extends Label>(
234+
IconOrTranslation,
235+
iconOrTranslation: ((
231236
internals: ComponentInternals,
232-
data: () => [L, ...Labels[L]]
237+
data: IconOrTranslationData | (() => IconOrTranslationData)
233238
) => {
234-
IconOrTranslation(internals, {
235-
get data() {
236-
return data();
237-
},
238-
});
239-
}) as unknown as Snippet<
240-
[
241-
{
242-
[L in Label]: [L, ...Labels[L]];
243-
}[Label],
244-
]
245-
>,
239+
IconOrTranslation(
240+
internals,
241+
// Looks like during SSR the `data` is not a getter function
242+
// TODO: Clarify how to detect SSR in Svelte (not SvelteKit)
243+
typeof data === "function"
244+
? {
245+
get data() {
246+
return data();
247+
},
248+
}
249+
: {
250+
data,
251+
}
252+
);
253+
}) as unknown as Snippet<[IconOrTranslationData]>,
246254
},
247255
{
248256
get value() {

0 commit comments

Comments
 (0)