RadioGroup.svelte 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. <script lang="ts">
  2. import type { BaseComponentProps } from "@json-render/svelte";
  3. import { getBoundProp } from "@json-render/svelte";
  4. import * as RadioGroup from "$lib/components/ui/radio-group";
  5. import { Label } from "$lib/components/ui/label";
  6. interface Props extends BaseComponentProps<{
  7. label?: string | null;
  8. value?: string | null;
  9. options: Array<{ value: string; label: string }>;
  10. }> {}
  11. let { props, bindings }: Props = $props();
  12. function valueBinding() {
  13. return getBoundProp<string>(
  14. () => (props.value ?? undefined) as string | undefined,
  15. () => bindings?.value,
  16. );
  17. }
  18. let value = $derived(
  19. valueBinding().current ?? ""
  20. );
  21. function handleChange(newValue: string) {
  22. valueBinding().current = newValue;
  23. }
  24. </script>
  25. <div class="flex flex-col gap-2">
  26. {#if props.label}
  27. <Label class="text-sm font-medium">{props.label}</Label>
  28. {/if}
  29. <RadioGroup.Root value={value} onValueChange={handleChange}>
  30. {#each props.options ?? [] as opt}
  31. <div class="flex items-center gap-2">
  32. <RadioGroup.Item value={opt.value} id="rg-{opt.value}" />
  33. <Label for="rg-{opt.value}" class="font-normal cursor-pointer">
  34. {opt.label}
  35. </Label>
  36. </div>
  37. {/each}
  38. </RadioGroup.Root>
  39. </div>