-
-
Notifications
You must be signed in to change notification settings - Fork 7
Add source-first exports and SSR-safe packaging #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
48f0edf
9ce08f7
51e92dc
0e560db
eee3c0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,18 +28,49 @@ | |
| customDetails: viewModel.customizations, | ||
| }); | ||
|
|
||
| let languageTag = $derived(createTagFromOrthography(orthography)); | ||
| function safeCreateTagFromOrthography( | ||
| maybeOrthography: IOrthography | ||
| ): string | undefined { | ||
| const language = maybeOrthography?.language; | ||
|
|
||
| // During SSR/initial render, selectedLanguage can be partially populated. | ||
| // createTagFromOrthography expects language.scripts to be an array. | ||
| if (!language || !Array.isArray(language.scripts)) { | ||
| return undefined; | ||
| } | ||
|
|
||
| try { | ||
| return createTagFromOrthography(maybeOrthography); | ||
| } catch { | ||
| return undefined; | ||
| } | ||
| } | ||
|
Comment on lines
+31
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 safeCreateTagFromOrthography guards are correct but asymmetric with controller usage The Was this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| let languageTag = $derived(safeCreateTagFromOrthography(orthography)); | ||
|
|
||
| let listedLanguages = $derived( | ||
| Array.isArray(viewModel.listedLanguages) ? viewModel.listedLanguages : [] | ||
| ); | ||
| let listedScripts = $derived( | ||
| Array.isArray(viewModel.listedScripts) ? viewModel.listedScripts : [] | ||
| ); | ||
|
|
||
| let closeModal = $state(() => {}); | ||
| let scrollContainer: HTMLElement; | ||
|
|
||
| viewModel.promptForCustomTag = (_default?: string) => { | ||
| if (typeof window === "undefined") { | ||
| return; | ||
| } | ||
|
|
||
| const tag = window.prompt( | ||
| "If this user interface is not offering you a language tag that you know is valid ISO 639 code, you can enter it here:", | ||
| _default | ||
| ); | ||
| if (tag && !isValidBcp47Tag(tag)) { | ||
| alert(`This is not in a valid IETF BCP 47 format: ${tag}`); | ||
| if (typeof window !== "undefined") { | ||
| window.alert(`This is not in a valid IETF BCP 47 format: ${tag}`); | ||
| } | ||
| } else if (tag) { | ||
| viewModel.customLanguageTag = tag; | ||
| closeModal(); | ||
|
|
@@ -68,6 +99,14 @@ | |
| behavior: "smooth", | ||
| }); | ||
| } | ||
|
|
||
| function onSearchInput(event: Event) { | ||
| viewModel.searchString = (event.currentTarget as HTMLInputElement).value; | ||
| } | ||
|
|
||
| function onDisplayNameInput(event: Event) { | ||
| viewModel.displayName = (event.currentTarget as HTMLInputElement).value; | ||
| } | ||
| </script> | ||
|
|
||
| <div class="h-full flex flex-col"> | ||
|
|
@@ -83,27 +122,28 @@ | |
| <input | ||
| type="search" | ||
| placeholder="Search by name, code, or country" | ||
| bind:value={viewModel.searchString} | ||
| value={viewModel.searchString ?? ""} | ||
| oninput={onSearchInput} | ||
|
Comment on lines
+125
to
+126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Controlled input pattern replaces bind:value — subtle behavioral difference The Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| /> | ||
| </label> | ||
| </div> | ||
|
|
||
| <div class="flex-1 overflow-y-auto min-h-0" bind:this={scrollContainer}> | ||
| {#each viewModel.listedLanguages | ||
| <div class="flex-1 overflow-y-auto min-h-0" bind:this={scrollContainer}> | ||
| {#each listedLanguages | ||
| .slice(0, 100) | ||
| .map(svelteViewModel) as lang} | ||
| <LanguageCard | ||
| viewModel={lang} | ||
| searchText={viewModel.searchString} | ||
| onSelect={onLanguageSelected} | ||
| /> | ||
| {#if lang.isSelected && viewModel.listedScripts.length > 0} | ||
| {#if lang.isSelected && listedScripts.length > 0} | ||
| <div class="ml-8 mb-4"> | ||
| <div class="py-2"> | ||
| <p class="font-semibold text-sm">Select a script:</p> | ||
| </div> | ||
| <div class="grid grid-cols-3 gap-4"> | ||
| {#each viewModel.listedScripts.map(svelteViewModel) as script} | ||
| {#each listedScripts.map(svelteViewModel) as script} | ||
| <ScriptCard viewModel={script} /> | ||
| {/each} | ||
| </div> | ||
|
|
@@ -149,7 +189,8 @@ | |
| > | ||
| <input | ||
| class="input input-xl w-full" | ||
| bind:value={viewModel.displayName} | ||
| value={viewModel.displayName ?? ""} | ||
| oninput={onDisplayNameInput} | ||
| /> | ||
| </label> | ||
| <div class="font-mono opacity-70 p-2"> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.