[READ-ONLY] Mirror of https://github.com/flo-bit/ui-kit. 🦊 fox ui, svelte 5 and tailwind 4 flo-bit.dev/ui-kit/
svelte tailwindcss ui-components
0

Configure Feed

Select the types of activity you want to include in your feed.

add color select

Florian (Mar 20, 2025, 12:43 AM +0100) 0d91bd4c 6ad9201b

+169 -79
+1 -1
package.json
··· 1 1 { 2 2 "name": "fuchs", 3 - "version": "0.0.7", 3 + "version": "0.0.8", 4 4 "type": "module", 5 5 "description": "Beautiful UI components built with Tailwind 4 and Svelte 5", 6 6 "homepage": "https://flo-bit.dev/ui-kit",
+5
src/docs/cards/extras/CardColorPicker.svelte
··· 14 14 const theme = new ThemeWatcher(); 15 15 const color = theme.getCSSVar('--color-accent-500'); 16 16 rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 17 + 18 + theme.subscribe(() => { 19 + const color = theme.getCSSVar('--color-accent-500'); 20 + rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 21 + }); 17 22 }); 18 23 </script> 19 24
+14
src/docs/cards/extras/CardColorSelect.svelte
··· 1 + <div class={'group flex flex-wrap items-center gap-2'}> 2 + <div class="rounded-full flex items-center justify-center text-accent-700"> 3 + <div class="size-8 rounded-full bg-current"></div> 4 + </div> 5 + <div class="rounded-full flex items-center justify-center text-accent-500 ring-accent-500 p-0.5 ring-3"> 6 + <div class="size-8 rounded-full bg-current"></div> 7 + </div> 8 + <div class="rounded-full flex items-center justify-center text-accent-300"> 9 + <div class="size-8 rounded-full bg-current"></div> 10 + </div> 11 + <div class="rounded-full flex items-center justify-center text-accent-100"> 12 + <div class="size-8 rounded-full bg-current"></div> 13 + </div> 14 + </div>
-27
src/docs/preview/ColorSelectPreview.svelte
··· 1 - <script> 2 - import ColorSelect from '$lib/components/extra/color-select/ColorSelect.svelte'; 3 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 - import Text from '$lib/components/base/text/Text.svelte'; 5 - </script> 6 - 7 - <Subheading>Color Select</Subheading> 8 - 9 - <Text class="mt-4 mb-2">Tailwind Classes</Text> 10 - <ColorSelect 11 - colors={[ 12 - { class: 'bg-red-500', label: 'red' }, 13 - { class: 'bg-green-500', label: 'green' }, 14 - { class: 'bg-blue-500', label: 'blue' }, 15 - { class: 'bg-yellow-500', label: 'yellow' } 16 - ]} 17 - /> 18 - 19 - <Text class="mt-4 mb-2">Custom Colors</Text> 20 - <ColorSelect 21 - colors={[ 22 - { value: '#690B22', label: 'red' }, 23 - { value: '#E07A5F', label: 'green' }, 24 - { value: '#F1E3D3', label: 'blue' }, 25 - { value: '#1B4D3E', label: 'yellow' } 26 - ]} 27 - />
+22 -22
src/docs/preview/SelectTheme.svelte
··· 17 17 import { onMount } from 'svelte'; 18 18 19 19 let accentColors = [ 20 - { class: 'bg-red-500', label: 'red' }, 21 - { class: 'bg-orange-500', label: 'orange' }, 22 - { class: 'bg-amber-500', label: 'amber' }, 23 - { class: 'bg-yellow-500', label: 'yellow' }, 24 - { class: 'bg-lime-500', label: 'lime' }, 25 - { class: 'bg-green-500', label: 'green' }, 26 - { class: 'bg-emerald-500', label: 'emerald' }, 27 - { class: 'bg-teal-500', label: 'teal' }, 28 - { class: 'bg-cyan-500', label: 'cyan' }, 29 - { class: 'bg-sky-500', label: 'sky' }, 30 - { class: 'bg-blue-500', label: 'blue' }, 31 - { class: 'bg-indigo-500', label: 'indigo' }, 32 - { class: 'bg-violet-500', label: 'violet' }, 33 - { class: 'bg-purple-500', label: 'purple' }, 34 - { class: 'bg-fuchsia-500', label: 'fuchsia' }, 35 - { class: 'bg-pink-500', label: 'pink' }, 36 - { class: 'bg-rose-500', label: 'rose' } 20 + { class: 'text-red-500', label: 'red' }, 21 + { class: 'text-orange-500', label: 'orange' }, 22 + { class: 'text-amber-500', label: 'amber' }, 23 + { class: 'text-yellow-500', label: 'yellow' }, 24 + { class: 'text-lime-500', label: 'lime' }, 25 + { class: 'text-green-500', label: 'green' }, 26 + { class: 'text-emerald-500', label: 'emerald' }, 27 + { class: 'text-teal-500', label: 'teal' }, 28 + { class: 'text-cyan-500', label: 'cyan' }, 29 + { class: 'text-sky-500', label: 'sky' }, 30 + { class: 'text-blue-500', label: 'blue' }, 31 + { class: 'text-indigo-500', label: 'indigo' }, 32 + { class: 'text-violet-500', label: 'violet' }, 33 + { class: 'text-purple-500', label: 'purple' }, 34 + { class: 'text-fuchsia-500', label: 'fuchsia' }, 35 + { class: 'text-pink-500', label: 'pink' }, 36 + { class: 'text-rose-500', label: 'rose' } 37 37 ]; 38 38 39 39 let baseColors = [ 40 - { class: 'bg-gray-500', label: 'gray' }, 41 - { class: 'bg-stone-500', label: 'stone' }, 42 - { class: 'bg-zinc-500', label: 'zinc' }, 43 - { class: 'bg-neutral-500', label: 'neutral' }, 44 - { class: 'bg-slate-500', label: 'slate' } 40 + { class: 'text-gray-500', label: 'gray' }, 41 + { class: 'text-stone-500', label: 'stone' }, 42 + { class: 'text-zinc-500', label: 'zinc' }, 43 + { class: 'text-neutral-500', label: 'neutral' }, 44 + { class: 'text-slate-500', label: 'slate' } 45 45 ]; 46 46 47 47 onMount(() => {
+2 -2
src/docs/site-components/Container.svelte
··· 1 1 <script lang="ts"> 2 - let { children } = $props(); 2 + let { children, ...restProps } = $props(); 3 3 </script> 4 4 5 - <div class="h-[100dvh] px-4 lg:ml-72 xl:ml-80"> 5 + <div class="h-[100dvh] px-4 lg:ml-72 xl:ml-80" {...restProps}> 6 6 <div class="mx-auto flex w-full max-w-2xl flex-col items-start justify-center gap-2 py-24"> 7 7 {@render children?.()} 8 8 </div>
+7
src/docs/site-components/components_extra.ts
··· 1 1 import CardExcalidraw from '$docs/cards/extras/CardExcalidraw.svelte'; 2 2 import CardUndraw from '$docs/cards/extras/CardUndraw.svelte'; 3 3 import CardColorPicker from '$docs/cards/extras/CardColorPicker.svelte'; 4 + import CardColorSelect from '$docs/cards/extras/CardColorSelect.svelte'; 4 5 5 6 export const extraComponents = [ 6 7 { ··· 20 21 className: '', 21 22 label: 'Color Picker', 22 23 href: 'color-picker' 24 + }, 25 + { 26 + component: CardColorSelect, 27 + className: '', 28 + label: 'Color Select', 29 + href: 'color-select' 23 30 } 24 31 ].sort((a, b) => a.label.localeCompare(b.label));
+11 -5
src/lib/components/base/select/Select.svelte
··· 21 21 selected?: string; 22 22 items: Item[]; 23 23 } = $props(); 24 + 25 + if (!selected) { 26 + selected = typeof items[0] === 'string' ? items[0] : items[0].value; 27 + } 24 28 </script> 25 29 26 30 <Toolbar.Root 27 31 bind:ref 28 - class={cn( 29 - 'border-accent-300/10 bg-accent-300/5 dark:border-accent-600/5 dark:bg-accent-700/5 flex min-w-max items-center justify-center gap-4 rounded-full border', 30 - className 31 - )} 32 + class={cn('flex min-w-max items-center justify-center gap-4 rounded-full', className)} 32 33 {...restProps} 33 34 > 34 35 <Toolbar.Group bind:value={selected} type="single" class="flex items-center gap-x-1 text-sm"> ··· 36 37 <Toolbar.GroupItem 37 38 aria-label="align left" 38 39 value={typeof item === 'string' ? item : item.value} 39 - class="text-base-600 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 outline-accent-200 dark:outline-accent-900/50 data-[state=on]:text-accent-600 dark:data-[state=on]:text-accent-400 dark:data-[state=on]:bg-accent-700/10 data-[state=on]:bg-accent-500/10 inline-flex cursor-pointer items-center justify-center rounded-2xl p-1 px-2 transition-all data-[state=on]:outline" 40 + class={[ 41 + 'inline-flex cursor-pointer items-center justify-center rounded-2xl p-1 px-2 transition-all', 42 + 'text-base-600 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 outline-accent-500', 43 + 'dark:outline-accent-500/30 data-[state=on]:text-accent-600 dark:data-[state=on]:text-accent-400', 44 + 'dark:data-[state=on]:bg-accent-700/10 data-[state=on]:bg-accent-500/10 data-[state=on]:outline' 45 + ]} 40 46 > 41 47 {typeof item === 'string' ? item : item.label} 42 48 </Toolbar.GroupItem>
+30 -17
src/lib/components/extra/color-select/ColorSelect.svelte
··· 13 13 colors = $bindable([]), 14 14 selected = $bindable(colors[0]), 15 15 16 + name = $bindable(crypto.randomUUID()), 17 + 16 18 onselected, 17 19 ...restProps 18 20 }: WithElementRef<WithoutChildrenOrChild<HTMLAttributes<HTMLDivElement>>> & { ··· 21 23 selected?: Color; 22 24 23 25 colorsClass?: string; 26 + 27 + name?: string; 24 28 25 29 onselected?: (color: Color, previous: Color) => void; 26 30 } = $props(); ··· 42 46 </script> 43 47 44 48 <div 45 - class={cn('group flex flex-wrap items-center gap-2.5', className)} 49 + class={cn('group flex flex-wrap items-center gap-2', className)} 46 50 {...restProps} 47 51 bind:this={ref} 48 52 > 49 53 {#each colors as color} 50 - <button 54 + <label 55 + aria-label={getLabel(color)} 51 56 class={cn( 52 - 'peer outline-base-900 focus:outline-base-900 dark:outline-base-100 dark:focus:outline-base-100 cursor-pointer items-center justify-center rounded-full p-0.5 outline-offset-2 transition-all duration-100 focus:outline-2 focus:outline-offset-2', 53 - 'border-base-600 border-opacity-30 dark:border-base-400 dark:border-opacity-30 size-8 rounded-full border transition-all', 54 - getLabel(selected) === getLabel(color) 55 - ? 'bg-opacity-100 group-focus-within:outline-base-500 focus:group-focus-within:outline-base-900 dark:group-focus-within:outline-base-400 dark:focus:group-focus-within:outline-base-100 outline-2' 56 - : 'opacity-90 outline-0 hover:opacity-100 focus:opacity-100', 57 + 'group relative flex cursor-pointer items-center justify-center rounded-full p-0.5 ring-current', 58 + 'has-focus-visible:outline-base-900 dark:has-focus-visible:outline-base-100 has-focus-visible:outline-2 has-focus-visible:outline-offset-0', 59 + 'has-checked:ring-3', 57 60 colorsClass, 58 61 getColorClass(color) 59 62 )} 60 - style={getValue(color) ? `background-color: ${getValue(color)}` : undefined} 61 - onclick={() => { 62 - if (selected === color) return; 63 - let previous = selected; 64 - selected = color; 63 + style={getValue(color) ? `color: ${getValue(color)}` : undefined} 64 + > 65 + <input 66 + type="radio" 67 + {name} 68 + value={getLabel(color)} 69 + class="sr-only" 70 + onchange={() => { 71 + let previous = selected; 72 + selected = color; 73 + 74 + if (onselected) onselected(color, previous); 75 + }} 76 + checked={getLabel(selected) === getLabel(color)} 77 + /> 65 78 66 - if (onselected) onselected(color, previous); 67 - }} 68 - > 69 - <span class="sr-only">{getLabel(color)}</span> 70 - </button> 79 + <span 80 + aria-hidden="true" 81 + class="size-8 rounded-full bg-current" 82 + ></span> 83 + </label> 71 84 {/each} 72 85 </div>
+1
src/lib/index.ts
··· 31 31 export { ColorPicker, PopoverColorPicker } from '$lib/components/extra/color-picker/'; 32 32 export { default as Excalidraw } from '$lib/components/extra/excalidraw/Excalidraw.svelte'; 33 33 export { default as Undraw } from '$lib/components/extra/undraw/Undraw.svelte'; 34 + export { ColorSelect } from '$lib/components/extra/color-select'; 34 35 35 36 // 3d components 36 37 export { default as ModelPicker } from '$lib/components/3d/model-picker/ModelPicker.svelte';
+8 -1
src/routes/components/+layout.svelte
··· 2 2 import Navbar from '$docs/site-components/Navbar.svelte'; 3 3 import Sidebar from '$docs/site-components/Sidebar.svelte'; 4 4 import Container from '$docs/site-components/Container.svelte'; 5 + import { Button } from '$lib'; 5 6 6 7 let { children } = $props(); 7 8 </script> 8 9 10 + 11 + <Button class="fixed -top-96 left-4 z-[1000] focus-visible:top-8" href="#content"> 12 + skip to content 13 + </Button> 14 + 15 + 9 16 <Navbar hasSidebar showLogo={false} /> 10 17 <Sidebar /> 11 18 12 - <Container> 19 + <Container id="content"> 13 20 {@render children()} 14 21 </Container>
+5
src/routes/components/extras/color-picker/Example.svelte
··· 19 19 const theme = new ThemeWatcher(); 20 20 const color = theme.getCSSVar('--color-accent-500'); 21 21 rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 22 + 23 + theme.subscribe(() => { 24 + const color = theme.getCSSVar('--color-accent-500'); 25 + rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 26 + }); 22 27 }); 23 28 </script> 24 29
+6 -3
src/routes/components/extras/color-select/+page.svelte
··· 1 - <script> 2 - import ColorSelectPreview from '$docs/preview/ColorSelectPreview.svelte'; 1 + <script lang="ts"> 2 + import ColorSelectDocs from './ColorSelect.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 3 4 </script> 4 5 5 - <ColorSelectPreview /> 6 + <Prose> 7 + <ColorSelectDocs /> 8 + </Prose>
+36
src/routes/components/extras/color-select/ColorSelect.md
··· 1 + <script lang="ts"> 2 + import ColorSelectExample from './Example.svelte'; 3 + </script> 4 + 5 + # Color Select 6 + 7 + ## Example 8 + 9 + <ColorSelectExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script> 15 + import ColorSelect from 'fuchs'; 16 + </script> 17 + 18 + <ColorSelect 19 + colors={[ 20 + { class: 'text-accent-700', label: 'dark' }, 21 + { class: 'text-accent-500', label: 'medium' }, 22 + { class: 'text-accent-300', label: 'light' }, 23 + { class: 'text-accent-100', label: 'lightest' } 24 + ]} 25 + /> 26 + 27 + <!-- with custom colors --> 28 + <ColorSelect 29 + colors={[ 30 + { value: '#ff0000', label: 'red' }, 31 + { value: '#00ff00', label: 'green' }, 32 + { value: '#0000ff', label: 'blue' }, 33 + { value: '#ffff00', label: 'yellow' } 34 + ]} 35 + /> 36 + ```
+12
src/routes/components/extras/color-select/Example.svelte
··· 1 + <script> 2 + import ColorSelect from '$lib/components/extra/color-select/ColorSelect.svelte'; 3 + </script> 4 + 5 + <ColorSelect 6 + colors={[ 7 + { class: 'text-accent-700', label: 'dark' }, 8 + { class: 'text-accent-500', label: 'medium' }, 9 + { class: 'text-accent-300', label: 'light' }, 10 + { class: 'text-accent-100', label: 'lightest' } 11 + ]} 12 + />
+9 -1
src/routes/docs/+layout.svelte
··· 2 2 import Navbar from '$docs/site-components/Navbar.svelte'; 3 3 import Sidebar from '$docs/site-components/Sidebar.svelte'; 4 4 import Container from '$docs/site-components/Container.svelte'; 5 + import { Button } from '$lib'; 5 6 6 7 let { children } = $props(); 7 8 </script> 8 9 10 + <Button class="fixed bottom-4 right-4 z-[1000]" onclick={() => { 11 + // go to id content 12 + window.location.href = '#content'; 13 + }}> 14 + skip to content 15 + </Button> 16 + 9 17 <Navbar hasSidebar showLogo={false} /> 10 18 <Sidebar /> 11 19 12 - <Container> 20 + <Container id="content"> 13 21 {@render children()} 14 22 </Container>