Na porta shadcn ui para svelte 5 - Select component (usando bitsui select ) bind:value pede state(string), mas Writable<string> também funciona, então bind:value={$theme or $language} está obtendo e definindo o valor corretamente. Mas meu componente settings funciona com configurações adicionais passadas a ele como props com store como um dos elementos do objeto e tenho problemas para fazer writable funcionar corretamente a partir do objeto.
<script lang="ts" module>
interface SelectItem {
label: string;
labelRu: string;
value: string;
}
export interface Setting {
store: Writable<string>;
name: string;
nameRu: string;
values: SelectItem[];
}
</script>
<script lang="ts">
import * as Select from '$shared/components/ui/select/index.js';
import { theme } from '$shared/stores/theme';
import { language } from '$shared/stores/language';
import { derived, type Writable } from 'svelte/store';
let { additionalSettings = null }: { additionalSettings?: { [key: string]: Setting } | null } =
$props();
let clazz = $state('');
export { clazz as class };
let settings: { [key: string]: Setting } = {
theme: {
store: theme,
name: 'Theme',
nameRu: 'Тема',
values: [
{ label: 'Light', labelRu: 'Светлая', value: 'light' },
{ label: 'Dark', labelRu: 'Темная', value: 'dark' }
]
},
language: {
store: language,
name: 'Lingo',
nameRu: 'Язык',
values: [
{ label: 'English', labelRu: 'Английский', value: 'en' },
{ label: 'Russian', labelRu: 'Русский', value: 'ru' }
]
}
};
settings = { ...settings, ...(additionalSettings ?? {}) };
const settingLabel = Object.fromEntries(
Object.entries(settings).map(([key, setting]) => [
key,
derived([setting.store, language], ([$store, $language]) => {
const selectedValue = setting.values.find((value) => value.value === $store);
return $language === 'ru' ? selectedValue?.labelRu : selectedValue?.label;
})
])
);
</script>
<div
class="{clazz !== '' ? clazz + ' ' : ''}flex min-w-[240px] flex-col space-y-4 px-2 py-4 text-sm"
>
{#each Object.entries(settings) as [key, setting]}
<div class="flex items-center space-x-2">
<p class="min-w-[48px]">{$language === 'ru' ? setting.nameRu : setting.name}:</p>
<Select.Root type="single" name={key} bind:value={$setting.store}>
<Select.Trigger>
{#await settingLabel[key] then label}
{(label ?? $language === 'ru')
? 'Выберите ' + setting.nameRu
: 'Select ' + setting.name}
{/await}
</Select.Trigger>
<Select.Content>
{#each setting.values as value}
<Select.Item value={value.value}>
{$language === 'ru' ? value.labelRu : value.label}
</Select.Item>
{/each}
</Select.Content>
</Select.Root>
</div>
{/each}
</div>
Sou novato na funcionalidade reativa do Svelte 5, então talvez eu esteja perguntando algo fácil de consertar. Desculpe por isso(