[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.

fixes

Florian (May 4, 2025, 7:28 AM +0200) 102c3a5b 20881e05

+89 -34
+8
.changeset/some-ideas-smell.md
··· 1 + --- 2 + '@fuxui/colors': patch 3 + '@fuxui/social': patch 4 + '@fuxui/base': patch 5 + '@fuxui/3d': patch 6 + --- 7 + 8 + bump
+8
apps/docs/src/app.html
··· 5 5 <meta name="viewport" content="width=device-width, initial-scale=1" /> 6 6 %sveltekit.head% 7 7 8 + <script 9 + is:inline 10 + defer 11 + src="https://umami-wispy-dream-8048.fly.dev/script.js" 12 + data-website-id="e6166872-1b90-4b72-8f63-683b95fc010f" 13 + data-domains="flo-bit.dev" 14 + ></script> 15 + 8 16 <script> 9 17 let dark = localStorage.getItem('darkMode'); 10 18 if (dark) {
+2 -2
apps/docs/src/lib/site-components/Navbar.svelte
··· 10 10 11 11 <Navbar {hasSidebar}> 12 12 <div class="flex items-center gap-2"> 13 - <Button variant="link" class="block font-normal lg:hidden" popovertarget="mobile-menu"> 13 + <Button variant="link" class="block font-normal lg:hidden backdrop-blur-none" popovertarget="mobile-menu"> 14 14 <svg 15 15 xmlns="http://www.w3.org/2000/svg" 16 16 viewBox="0 0 24 24" ··· 29 29 </div> 30 30 <div class="flex items-end gap-3"> 31 31 <ThemeSelectDropdown /> 32 - <ThemeToggle /> 32 + <ThemeToggle class="backdrop-blur-none" /> 33 33 34 34 <Github href="https://github.com/flo-bit/ui-kit" class="mr-2 p-2" /> 35 35 </div>
+4 -4
apps/docs/src/lib/site-components/Sidebar.svelte
··· 28 28 variant="ghost" 29 29 onclick={handleClick} 30 30 href="{base}/docs/quick-start" 31 - class="mb-1 w-full justify-start">Quick Start</Button 31 + class="mb-1 w-full justify-start backdrop-blur-none">Quick Start</Button 32 32 > 33 33 <Button 34 34 data-current={page.url.pathname === `${base}/docs/philosophy`} ··· 36 36 variant="ghost" 37 37 onclick={handleClick} 38 38 href="{base}/docs/philosophy" 39 - class="mb-1 w-full justify-start">Philosophy</Button 39 + class="mb-1 w-full justify-start backdrop-blur-none">Philosophy</Button 40 40 > 41 41 <Button 42 42 data-sveltekit-keepfocus 43 43 variant="ghost" 44 44 onclick={handleClick} 45 45 href="{base}/docs/theme" 46 - class="mb-6 w-full justify-start">Theme</Button 46 + class="mb-6 w-full justify-start backdrop-blur-none">Theme</Button 47 47 > 48 48 49 49 <Accordion type="multiple" class="w-full" value={components.map((c) => c.href)}> ··· 62 62 variant="ghost" 63 63 onclick={handleClick} 64 64 href="{base}/components/{category.href}/{component.href}" 65 - class="w-full justify-start">{component.label}</Button 65 + class="w-full justify-start backdrop-blur-none">{component.label}</Button 66 66 > 67 67 {/each} 68 68 </AccordionItem>
+1 -1
apps/docs/src/lib/site-components/ThemeSelectDropdown.svelte
··· 8 8 <button {...props} 9 9 class={cn( 10 10 buttonVariants({ variant: 'link', size: 'default' }), 11 - 'flex cursor-pointer items-center gap-0 -space-x-2' 11 + 'flex cursor-pointer items-center gap-0 -space-x-2 backdrop-blur-none' 12 12 )} 13 13 > 14 14 <div
+1 -1
packages/base/src/lib/components/box/Box.svelte
··· 14 14 <div 15 15 bind:this={ref} 16 16 class={cn( 17 - 'border-base-300/50 bg-base-300/20 dark:border-base-800/50 dark:bg-base-900/30 text-base-900 dark:text-base-100 relative isolate w-full overflow-hidden rounded-2xl border p-4', 17 + 'border-base-300/50 bg-base-300/20 backdrop-blur-2xl dark:border-base-800/50 dark:bg-base-900/30 text-base-900 dark:text-base-100 relative isolate w-full overflow-hidden rounded-2xl border p-4', 18 18 className 19 19 )} 20 20 {...restProps}
+2 -2
packages/base/src/lib/components/modal/Modal.svelte
··· 76 76 {...contentProps} 77 77 class={cn( 78 78 'motion-safe:data-[state=open]:animate-in motion-safe:data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-bottom-1/2 data-[state=open]:slide-in-from-bottom-1/2', 79 - 'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-1rem)] max-w-lg translate-x-[-50%] translate-y-[-50%]', 80 - 'bg-base-50 dark:bg-base-900 border-base-200/80 dark:border-base-800 gap-4 rounded-2xl border p-6', 79 + 'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-1rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] shadow-lg', 80 + 'bg-base-50/60 dark:bg-base-900/60 backdrop-blur-xl border-base-200/80 dark:border-base-800 gap-4 rounded-2xl border p-6', 81 81 className 82 82 )} 83 83 >
+3 -3
packages/base/src/lib/components/navbar/Navbar.svelte
··· 13 13 14 14 <div 15 15 class={cn( 16 - 'header fixed top-0 right-0 left-0 z-50 flex h-16 items-center justify-between p-2', 17 - hasSidebar ? 'lg:left-72' : '', 16 + 'header fixed top-1 right-0 mx-1 left-0 z-50 flex h-16 items-center justify-between p-2 shadow-lg rounded-2xl border border-base-200 dark:border-base-300/10 overflow-hidden', 17 + hasSidebar ? 'lg:left-74' : '', 18 18 className 19 19 )} 20 20 {...restProps} 21 21 > 22 22 {@render children?.()} 23 23 <div 24 - class="backdrop from-base-50/90 via-base-50/0 dark:from-base-950/90 dark:via-base-950/0 pointer-events-none absolute inset-0 -z-10 bg-linear-to-b backdrop-blur-md" 24 + class="backdrop from-base-100/50 via-base-50/20 dark:from-base-900/30 dark:via-base-950/10 pointer-events-none absolute inset-0 -z-10 bg-linear-to-b backdrop-blur-md" 25 25 ></div> 26 26 27 27 <div
+1 -1
packages/base/src/lib/components/popover/popover-content.svelte
··· 20 20 {sideOffset} 21 21 {align} 22 22 class={cn( 23 - 'bg-base-100 dark:bg-base-900 border-base-200 dark:border-base-800 text-base-900 dark:text-base-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-2xl border p-4 shadow-md outline-none', 23 + 'bg-base-100/70 dark:bg-base-900/50 backdrop-blur-xl border-base-200 dark:border-base-800 text-base-900 dark:text-base-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-2xl border p-4 shadow-md outline-none', 24 24 className 25 25 )} 26 26 {...restProps}
+6 -5
packages/base/src/lib/components/sidebar/Sidebar.svelte
··· 3 3 import type { HTMLAttributes } from 'svelte/elements'; 4 4 import { cn } from '../../utils'; 5 5 import { ScrollArea } from '../scroll-area'; 6 - 6 + 7 7 const { 8 8 class: className, 9 9 mobileClasses, ··· 20 20 popover="auto" 21 21 id="mobile-menu" 22 22 class={cn( 23 - 'mobileMenuPopover border-base-200 bg-base-50 dark:border-base-300/10 dark:bg-base-950 my-2 ml-2 overflow-y-hidden rounded-2xl', 24 - 'inset-auto top-0 left-0 block h-[calc(100dvh-1rem)] w-72 border shadow-lg lg:hidden', 23 + 'mobileMenuPopover border-base-200 bg-white/70 dark:border-base-300/10 dark:bg-base-950/50 my-2 ml-2 overflow-y-hidden rounded-2xl', 24 + 'inset-auto left-0 top-0 block h-[calc(100dvh-1rem)] w-72 border shadow-lg lg:hidden backdrop-blur-xl', 25 25 className, 26 26 mobileClasses 27 27 )} ··· 35 35 {#if !mobileOnly} 36 36 <div 37 37 class={cn( 38 - 'border-base-200 bg-base-50 dark:border-base-300/10 dark:bg-base-950 fixed top-0 bottom-0 left-0 z-40', 39 - 'hidden -translate-x-72 border-r lg:block lg:w-72 lg:translate-x-0', 38 + 'border-base-200 bg-base-50/50 dark:border-base-300/10 dark:bg-base-950/50 backdrop-blur-xl fixed my-1 ml-0.5 overflow-y-hidden rounded-2xl', 39 + 'inset-auto left-1 top-0 z-50 block h-[calc(100dvh-0.5rem)] w-72 border shadow-lg lg:hidden', 40 + 'hidden -translate-x-72 border lg:block lg:w-72 lg:translate-x-0', 40 41 className 41 42 )} 42 43 {...restProps}
+5 -4
packages/base/src/lib/components/theme-toggle/ThemeToggle.svelte
··· 8 8 import { onMount } from 'svelte'; 9 9 import { Button, type ButtonProps } from '../button'; 10 10 import { cn } from '../../utils'; 11 - 11 + 12 12 onMount(() => { 13 13 // load from local storage 14 14 const savedDarkMode = localStorage.getItem('darkMode'); ··· 50 50 setTheme(theme.dark); 51 51 } 52 52 53 - const { class: className, ...restProps }: ButtonProps = $props(); 53 + let { class: className, ref = $bindable(null), ...restProps }: ButtonProps = $props(); 54 54 </script> 55 55 56 56 <Button ··· 60 60 'theme-toggle focus-visible:outline-base-900 dark:focus-visible:outline-base-100 flex items-center justify-center rounded-2xl focus-visible:outline-2', 61 61 className 62 62 )} 63 + bind:ref 63 64 {...restProps} 64 65 size="icon" 65 66 > ··· 69 70 viewBox="0 0 24 24" 70 71 stroke-width="1.5" 71 72 stroke="currentColor" 72 - class="block size-5! transition-colors duration-500 dark:hidden" 73 + class="size-5! block transition-colors duration-500 dark:hidden" 73 74 > 74 75 <path 75 76 stroke-linecap="round" ··· 83 84 viewBox="0 0 24 24" 84 85 stroke-width="1.5" 85 86 stroke="currentColor" 86 - class="hidden size-5! transition-colors duration-500 dark:block dark:text-white" 87 + class="size-5! hidden transition-colors duration-500 dark:block dark:text-white" 87 88 > 88 89 <path 89 90 stroke-linecap="round"
+42 -7
packages/social/src/lib/components/emoji-picker/EmojiPicker.svelte
··· 4 4 import { allGroups } from './emoji'; 5 5 import Database from 'emoji-picker-element/database'; 6 6 import type { NativeEmoji } from 'emoji-picker-element/shared'; 7 + import { fade } from 'svelte/transition'; 7 8 8 9 let currentGroup = $state(allGroups[0].id); 9 10 let db: Database | undefined = $state(); 10 11 11 - let { onpicked }: { onpicked?: (emoji: NativeEmoji) => void } = $props(); 12 + let { 13 + onpicked, 14 + height = 300, 15 + width = 344, 16 + columns = 8, 17 + class: className 18 + }: { 19 + onpicked?: (emoji: NativeEmoji) => void; 20 + height?: number; 21 + width?: number; 22 + columns?: number; 23 + class?: string; 24 + } = $props(); 12 25 13 26 $effect(() => { 14 27 if (db) return; 15 28 import('emoji-picker-element').then(({ Database }) => { 16 29 db = new Database(); 30 + 31 + // go through all groups and check if the emoji is supported (will be cached) 32 + // so that things appear faster when we select a group 33 + for (const group of allGroups) { 34 + db.getEmojiByGroup(group.id).then((emojis) => { 35 + for (const emoji of emojis) { 36 + isEmojiSupported(emoji.unicode); 37 + } 38 + }); 39 + } 17 40 }); 18 41 }); 19 42 </script> 20 43 21 - <div class="flex w-[344px] flex-col"> 22 - <ScrollArea class="grid h-[250px] w-full select-none grid-cols-8 space-y-3 px-2"> 44 + <div class={cn('flex flex-col', className)} style="height: {height}px; width: {width}px;"> 45 + <ScrollArea 46 + class="grid w-full select-none space-y-0 px-2" 47 + style="height: {height}px; grid-template-columns: repeat({columns}, minmax(0, 1fr));" 48 + > 23 49 {#await db?.getEmojiByGroup(currentGroup) then emojis} 24 50 {#if emojis} 25 51 {#each emojis as emoji} ··· 28 54 onclick={() => { 29 55 onpicked?.(emoji); 30 56 }} 31 - class="hover:bg-accent-300/20 dark:hover:bg-accent-700/20 size-10 cursor-pointer rounded-full text-center text-xl transition-transform duration-100 hover:scale-110" 57 + class="hover:bg-accent-300/20 dark:hover:bg-accent-700/20 size-10 cursor-pointer rounded-full text-center text-xl transition-transform duration-150 hover:scale-110" 32 58 >{emoji.unicode}</button 33 59 > 34 60 {/if} ··· 37 63 {/await} 38 64 </ScrollArea> 39 65 <div 40 - class="border-base-300/50 dark:border-base-700/50 flex justify-between gap-2 border-t px-3 py-2" 66 + class="border-base-300/50 dark:border-base-700/50 flex justify-between gap-2 border-t px-3" 67 + style="width: {width}px;" 41 68 > 42 69 {#each allGroups as group} 43 70 <button 44 71 onclick={() => (currentGroup = group.id)} 45 72 class={cn( 46 - '[&>svg]:size-4.5 cursor-pointer transition-all duration-100 hover:scale-105', 73 + '[&>svg]:size-4.5 relative cursor-pointer [&>svg]:transition-all [&>svg]:duration-100 [&>svg]:hover:scale-105 py-2', 47 74 group.id === currentGroup 48 75 ? 'text-accent-600 dark:text-accent-400' 49 76 : 'hover:text-accent-700 dark:hover:text-accent-300' 50 77 )} 51 - >{@html group.svg} 78 + > 79 + {@html group.svg} 52 80 <span class="sr-only">{group.name}</span> 81 + 82 + {#if group.id === currentGroup} 83 + <span 84 + transition:fade 85 + class="from-accent-500/0 via-accent-500/60 to-accent-500/0 dark:from-accent-400/0 dark:via-accent-400/60 dark:to-accent-400/0 absolute -inset-x-1 -top-px h-px bg-gradient-to-r" 86 + ></span> 87 + {/if} 53 88 </button> 54 89 {/each} 55 90 </div>
+1 -1
packages/social/src/lib/components/emoji-picker/PopoverEmojiPicker.svelte
··· 18 18 } & PopoverProps = $props(); 19 19 </script> 20 20 21 - <Popover {...props} bind:triggerRef bind:open class={cn('px-0 pb-0 pt-1', className)}> 21 + <Popover {...props} bind:triggerRef bind:open class={cn('p-0', className)}> 22 22 {@render children?.()} 23 23 <EmojiPicker {onpicked} /> 24 24 </Popover>
+2 -1
packages/3d/src/lib/components/model-picker/base/ModelPickerScene.svelte
··· 37 37 38 38 <T.PerspectiveCamera makeDefault position={[0, 0, 2]} fov={50} near={0.1} far={10} /> 39 39 40 - <T.DirectionalLight args={[0xffffff, 1]} position={[-1, 1, 1]} /> 40 + <T.DirectionalLight args={[0xffffff, 2]} position={[-1, 1, 1]} /> 41 + <T.AmbientLight args={[0xffffff, 0.7]} /> 41 42 42 43 <T.Group rotation={[0.5, rotation + 2.5, 0]}> 43 44 <T.Group bind:ref={group}>
+1 -1
packages/colors/src/lib/components/color-picker/popover/PopoverColorPicker.svelte
··· 51 51 } 52 52 </script> 53 53 54 - <Popover {side} {sideOffset}> 54 + <Popover {side} {sideOffset} class={cn('p-1 pr-0 pl-2')}> 55 55 {#snippet child({ props })} 56 56 <button 57 57 {...props}
+2 -1
apps/docs/src/routes/(main)/components/social/emoji-picker/EmojiPicker.md
··· 15 15 import { EmojiPicker } from '@fuxui/social'; 16 16 </script> 17 17 18 - <EmojiPicker /> 18 + <EmojiPicker 19 + onpicked={(emoji) => console.log('selected emoji: ' + emoji.unicode)} /> 19 20 ```