Skip to content

Instantly share code, notes, and snippets.

@magick93
Last active November 16, 2023 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magick93/dcc6b76c7a913652cd441cfeefbfb196 to your computer and use it in GitHub Desktop.
Save magick93/dcc6b76c7a913652cd441cfeefbfb196 to your computer and use it in GitHub Desktop.
Re-creating Tailwind color radiobuttons
<script lang="ts">
import { createRadioGroup, melt } from '@melt-ui/svelte';
const {
elements: { root, item, hiddenInput },
helpers: { isChecked },
} = createRadioGroup({
defaultValue: 'default',
});
type Color = {
red: number;
green: number;
blue: number;
};
let colors: Color[] = [
{ red: 255, green: 255, blue: 255 },
{ red: 0, green: 0, blue: 0 },
{ red: 255, green: 0, blue: 0 },
{ red: 0, green: 255, blue: 0 },
{ red: 0, green: 0, blue: 255 },
{ red: 255, green: 255, blue: 0 },
{ red: 255, green: 0, blue: 255 },
{ red: 0, green: 255, blue: 255 }
];
function colorToCssBackground(color: Color) {
return `rgb(${color.red}, ${color.green}, ${color.blue})`;
}
function colorToStringHash(color: Color) {
return `${color.red}-${color.green}-${color.blue}`;
}
</script>
<fieldset>
<legend class="block text-sm font-medium leading-6 text-gray-900">Choose a label color</legend>
<div
{...$root} use:root
class="mt-4 flex items-center space-x-3 data-[orientation=horizontal]:flex-row"
aria-label="View density"
>
{#each colors as option}
<div class="flex items-center gap-3 bg-magnum-500">
<label
class="relative -m-0.5 flex cursor-pointer items-center justify-center rounded-full p-0.5 focus:outline-none ring-pink-500"
for={colorToStringHash(option)}
id="{colorToStringHash(option)}-label"
>
<button
{...$item(colorToStringHash(option))} use:item
class="sr-only"
id={colorToStringHash(option)}
aria-labelledby="color-choice-{colorToStringHash(option)}-label"
>
{#if $isChecked(colorToStringHash(option))}
<div class="ring ring-offset-1" />
{/if}
</button>
<span id="color-choice-{colorToStringHash(option)}-label" class="sr-only">{colorToStringHash(option)}</span>
<span
aria-hidden="true"
style="background-color: {colorToCssBackground(option)}"
class="h-8 w-8
{ $isChecked(colorToStringHash(option)) ? 'ring ring-offset-1' : ' '}
rounded-full border border-black border-opacity-10"></span>
</label>
</div>
{/each}
<input name="line-height" {...$hiddenInput} use:hiddenInput />
</div>
</fieldset>
function colorToCssBackground(color: Color) {
return `rgb(${color.red}, ${color.green}, ${color.blue})`;
}
function colorToStringHash(color: Color) {
return `${color.red}-${color.green}-${color.blue}`;
}
</script>
<fieldset>
<legend class="block text-sm font-medium leading-6 text-gray-900">Choose a label color</legend>
<div
{...$root} use:root
class="mt-4 flex items-center space-x-3 data-[orientation=horizontal]:flex-row"
aria-label="View density"
>
{#each colors as option}
<div class="flex items-center gap-3 bg-magnum-500">
<label
class="relative -m-0.5 flex cursor-pointer items-center justify-center rounded-full p-0.5 focus:outline-none ring-pink-500"
for={colorToStringHash(option)}
id="{colorToStringHash(option)}-label"
>
<button
{...$item(colorToStringHash(option))} use:item
class="sr-only"
id={colorToStringHash(option)}
aria-labelledby="color-choice-{colorToStringHash(option)}-label"
>
{#if $isChecked(colorToStringHash(option))}
<div class="ring ring-offset-1" />
{/if}
</button>
<span id="color-choice-{colorToStringHash(option)}-label" class="sr-only">{colorToStringHash(option)}</span>
<span aria-hidden="true"
style="background-color: {colorToCssBackground(option)}"
class="h-8 w-8
rounded-full border border-black border-opacity-10"></span>
</label>
</div>
{/each}
<input name="line-height" {...$hiddenInput} use:hiddenInput />
</div>
</fieldset>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment