[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 swiper cards

Florian (Mar 24, 2025, 5:26 AM +0100) b0877061 eadc45dc

+208 -127
+1 -1
package.json
··· 1 1 { 2 2 "name": "fuchs", 3 - "version": "0.0.15", 3 + "version": "0.0.16", 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",
+2 -2
src/docs/cards/3d/CardModelPicker.svelte
··· 9 9 </script> 10 10 11 11 <div class="flex h-44 max-h-44 w-full max-w-full items-center justify-center gap-6"> 12 - <Image src={image} alt="Vehicle Monster Truck" class="scale-125" /> 13 - <Image src={image2} alt="Vehicle Racer" class="scale-125" /> 12 + <Image src={image} alt="Vehicle Monster Truck" class="scale-125" /> 13 + <Image src={image2} alt="Vehicle Racer" class="scale-125" containerClasses="bg-base-200 rounded-xl dark:bg-base-900" /> 14 14 <Image src={image3} alt="Vehicle Racer Low" class="scale-125" /> 15 15 </div>
+39
src/docs/cards/extras/CardSwiperCards.svelte
··· 1 + <script> 2 + 3 + import { Button } from "$lib"; 4 + 5 + </script> 6 + 7 + <div class="flex relative p-8"> 8 + <div class="bg-base-200/50 dark:bg-base-800/50 rounded-xl p-4 h-24 w-16 border border-base-300/50 dark:border-base-700/50"> 9 + </div> 10 + <div class="-ml-8 bg-base-200 dark:bg-base-800 rounded-xl p-4 h-24 w-16 rotate-12 border border-base-300 dark:border-base-700"> 11 + </div> 12 + 13 + <div class="absolute bottom-2 flex w-full justify-between px-2 -ml-10"> 14 + <Button size="iconSm"> 15 + <svg 16 + xmlns="http://www.w3.org/2000/svg" 17 + fill="none" 18 + viewBox="0 0 24 24" 19 + stroke-width="2.5" 20 + stroke="currentColor" 21 + class="size-6" 22 + > 23 + <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 24 + </svg> 25 + </Button> 26 + <Button size="iconSm"> 27 + <svg 28 + xmlns="http://www.w3.org/2000/svg" 29 + viewBox="0 0 24 24" 30 + fill="currentColor" 31 + class="size-6" 32 + > 33 + <path 34 + d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" 35 + /> 36 + </svg> 37 + </Button> 38 + </div> 39 + </div>
+5 -42
src/docs/site-components/Cards.svelte
··· 1 1 <script lang="ts"> 2 2 import { base } from '$app/paths'; 3 - import { cn } from '$lib/utils'; 3 + import { cn } from '$lib'; 4 4 5 - import CardGithubCorner from '$docs/cards/base/CardGithubCorner.svelte'; 6 - import CardHeatmap from '$docs/cards/graphs/CardHeatmap.svelte'; 7 - import CardLineGraph from '$docs/cards/graphs/CardLineGraph.svelte'; 8 - import CardRingChart from '$docs/cards/graphs/CardRingChart.svelte'; 9 5 import { components } from './components_all'; 10 - 11 - let graphCards = [ 12 - { 13 - component: CardHeatmap, 14 - className: '', 15 - label: 'Heatmap', 16 - href: 'heatmap' 17 - }, 18 - { 19 - component: CardLineGraph, 20 - className: '', 21 - label: 'Line Graph', 22 - href: 'line-graph' 23 - }, 24 - { 25 - component: CardRingChart, 26 - className: '', 27 - label: 'Ring Chart', 28 - href: 'ring-chart' 29 - } 30 - ]; 31 - 32 - // sort graphCards by label 33 - graphCards.sort((a, b) => a.label.localeCompare(b.label)); 34 - 35 - let socialCards = [ 36 - { 37 - component: CardGithubCorner, 38 - className: '', 39 - label: 'Github Corner', 40 - href: 'github-corner' 41 - } 42 - ]; 43 6 </script> 44 7 45 - <div class="flex w-full flex-col gap-16"> 8 + <div class="flex w-full flex-col gap-32"> 46 9 {#each components as category} 47 10 <div> 48 - <h2 class="text-base-800 dark:text-base-200 mb-6 text-xl font-semibold">{category.name}</h2> 49 - <div class="grid w-full grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"> 11 + <h2 class="text-base-800 dark:text-base-200 mb-12 text-xl font-semibold">{category.name}</h2> 12 + <div class="grid w-full grid-cols-1 gap-12 sm:grid-cols-2 lg:grid-cols-3"> 50 13 {#each category.components as card} 51 14 <div 52 15 class="group relative flex flex-col items-start gap-3 transition-opacity duration-150 hover:opacity-90 md:gap-4" ··· 69 32 href={base + `/components/${category.href}/${card.href}`} 70 33 class="focus-visible:outline-accent-500 rounded-xl focus-visible:outline-2 focus-visible:outline-offset-2" 71 34 > 72 - <span class="text-base-900 dark:text-base-50 mx-2 text-sm font-semibold" 35 + <span class="text-base-900 dark:text-base-50 mx-2 text-sm font-semibold group-hover:text-accent-600 group-hover:dark:text-accent-400 transition-colors duration-150" 73 36 >{card.label}</span 74 37 > 75 38 <span class="absolute inset-0"></span>
+5 -5
src/docs/site-components/components_all.ts
··· 19 19 href: 'colors' 20 20 }, 21 21 { 22 - name: '3D components', 23 - components: threeDComponents, 24 - href: '3d' 25 - }, 26 - { 27 22 name: 'Extra components', 28 23 components: extraComponents, 29 24 href: 'extras' 25 + }, 26 + { 27 + name: '3D components', 28 + components: threeDComponents, 29 + href: '3d' 30 30 } 31 31 ];
+8 -1
src/docs/site-components/components_extra.ts
··· 1 + import type { ComponentCard } from './components_base'; 2 + 1 3 import CardExcalidraw from '$docs/cards/extras/CardExcalidraw.svelte'; 2 4 import CardUndraw from '$docs/cards/extras/CardUndraw.svelte'; 3 5 import CardStopwatch from '$docs/cards/extras/CardStopwatch.svelte'; 4 6 import CardTimer from '$docs/cards/extras/CardTimer.svelte'; 5 7 import CardPhone from '$docs/cards/extras/CardPhone.svelte'; 6 8 import CardQuote from '$docs/cards/extras/CardQuote.svelte'; 7 - import type { ComponentCard } from './components_base'; 9 + import CardSwiperCards from '$docs/cards/extras/CardSwiperCards.svelte'; 8 10 9 11 export const extraComponents: ComponentCard[] = [ 10 12 { ··· 36 38 component: CardQuote, 37 39 label: 'Quote', 38 40 href: 'quote' 41 + }, 42 + { 43 + component: CardSwiperCards, 44 + label: 'Swiper Cards', 45 + href: 'swiper-cards' 39 46 } 40 47 ].sort((a, b) => a.label.localeCompare(b.label));
+24
src/docs/site-components/components_graphs.ts
··· 1 + import CardHeatmap from '$docs/cards/graphs/CardHeatmap.svelte'; 2 + import CardLineGraph from '$docs/cards/graphs/CardLineGraph.svelte'; 3 + import CardRingChart from '$docs/cards/graphs/CardRingChart.svelte'; 4 + 5 + export const graphComponents = [ 6 + { 7 + component: CardHeatmap, 8 + className: '', 9 + label: 'Heatmap', 10 + href: 'heatmap' 11 + }, 12 + { 13 + component: CardLineGraph, 14 + className: '', 15 + label: 'Line Graph', 16 + href: 'line-graph' 17 + }, 18 + { 19 + component: CardRingChart, 20 + className: '', 21 + label: 'Ring Chart', 22 + href: 'ring-chart' 23 + } 24 + ].sort((a, b) => a.label.localeCompare(b.label));
+10
src/docs/site-components/components_social.ts
··· 1 + import CardGithubCorner from '$docs/cards/base/CardGithubCorner.svelte'; 2 + 3 + export const socialCards = [ 4 + { 5 + component: CardGithubCorner, 6 + className: '', 7 + label: 'Github Corner', 8 + href: 'github-corner' 9 + } 10 + ];
+1 -1
src/lib/components/3d/depth3d/Scene.svelte
··· 27 27 cameraPosition = [0, 0, 10], 28 28 rotationScale = 0.2, 29 29 rotationSpeed = 2, 30 - detail = 200, 30 + detail = 50, 31 31 depthScale = 1.5, 32 32 mouseMovement = true 33 33 }: Props = $props();
+2 -2
src/lib/components/colors/color-gradient-picker/ColorGradientPicker.svelte
··· 153 153 }} 154 154 > 155 155 <div 156 - class="border-base-400 dark:border-base-500 focus-visible:outline-accent-500 shadow-base-900/50 z-10 size-8 rounded-full border shadow-lg" 156 + class="ring-base-400 dark:ring-base-500 focus-visible:outline-accent-500 shadow-base-900/50 z-10 size-8 rounded-full shadow-lg ring" 157 157 style={`background-color: rgb(${color.rgb.r * 255}, ${color.rgb.g * 255}, ${color.rgb.b * 255});`} 158 158 ></div> 159 159 </Popover.Trigger> ··· 172 172 } 173 173 }} 174 174 > 175 - <ColorPicker bind:rgb={colors[i].rgb} class={className} /> 175 + <ColorPicker bind:rgb={colors[i].rgb} /> 176 176 177 177 {#if colors.length > 2} 178 178 <Button
+1
src/lib/index.ts
··· 46 46 export { TimerState } from '$lib/components/extra/timer/TimerState.svelte'; 47 47 export { default as Phone } from '$lib/components/extra/phone/Phone.svelte'; 48 48 export { default as Quote } from '$lib/components/extra/quote/Quote.svelte'; 49 + export { default as CardSwiper } from '$lib/components/extra/swiper-cards/CardSwiper.svelte'; 49 50 50 51 // 3d components 51 52 export { default as ModelPicker } from '$lib/components/3d/model-picker/base/ModelPicker.svelte';
+1 -1
src/routes/(main)/components/colors/color-gradient-picker/Example.svelte
··· 39 39 } 40 40 </script> 41 41 42 - <ColorGradientPicker class="mt-8" bind:colors /> 42 + <ColorGradientPicker class="mt-8 not-prose" bind:colors />
+5 -67
src/routes/(main)/components/extras/swiper-cards/+page.svelte
··· 1 1 <script lang="ts"> 2 - import { Button, cn } from '$lib'; 3 - import { type CardData } from '$lib/components/extra/swiper-cards'; 4 - import CardSwiper from '$lib/components/extra/swiper-cards/CardSwiper.svelte'; 5 - 6 - import profile1 from '$docs/assets/profiles/0.webp?as=run'; 7 - import profile2 from '$docs/assets/profiles/1.webp?as=run'; 8 - import profile3 from '$docs/assets/profiles/2.webp?as=run'; 9 - import profile4 from '$docs/assets/profiles/3.webp?as=run'; 10 - import profile5 from '$docs/assets/profiles/4.webp?as=run'; 11 - import profile6 from '$docs/assets/profiles/5.webp?as=run'; 12 - import profile7 from '$docs/assets/profiles/6.webp?as=run'; 13 - import profile8 from '$docs/assets/profiles/7.webp?as=run'; 14 - import profile9 from '$docs/assets/profiles/8.webp?as=run'; 15 - import profile10 from '$docs/assets/profiles/9.webp?as=run'; 16 - import Image from '$lib/components/base/image/Image.svelte'; 17 - 18 - const profiles = [ 19 - profile1, 20 - profile2, 21 - profile3, 22 - profile4, 23 - profile5, 24 - profile6, 25 - profile7, 26 - profile8, 27 - profile9, 28 - profile10 29 - ]; 30 - 31 - let swipe: (direction: 'left' | 'right') => void; 2 + import SwiperCardsDocs from './SwiperCards.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 32 4 </script> 33 5 34 - <div class="relative h-[70vh] w-full"> 35 - <CardSwiper 36 - cardData={(i) => ({ 37 - title: `Card ${i}`, 38 - description: `Card ${i} description`, 39 - image: profiles[i % profiles.length] 40 - })} 41 - bind:swipe 42 - ></CardSwiper> 43 - 44 - <div class="absolute bottom-2 flex w-full justify-between px-2"> 45 - <Button onclick={() => swipe('left')} size="iconLg"> 46 - <svg 47 - xmlns="http://www.w3.org/2000/svg" 48 - fill="none" 49 - viewBox="0 0 24 24" 50 - stroke-width="2.5" 51 - stroke="currentColor" 52 - class="size-6" 53 - > 54 - <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 55 - </svg> 56 - </Button> 57 - <Button onclick={() => swipe('right')} size="iconLg"> 58 - <svg 59 - xmlns="http://www.w3.org/2000/svg" 60 - viewBox="0 0 24 24" 61 - fill="currentColor" 62 - class="size-6" 63 - > 64 - <path 65 - d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" 66 - /> 67 - </svg> 68 - </Button> 69 - </div> 70 - </div> 6 + <Prose> 7 + <SwiperCardsDocs /> 8 + </Prose>
+67
src/routes/(main)/components/extras/swiper-cards/Example.svelte
··· 1 + <script lang="ts"> 2 + import { Button, CardSwiper } from '$lib'; 3 + 4 + import profile1 from '$docs/assets/profiles/0.webp?as=run'; 5 + import profile2 from '$docs/assets/profiles/1.webp?as=run'; 6 + import profile3 from '$docs/assets/profiles/2.webp?as=run'; 7 + import profile4 from '$docs/assets/profiles/3.webp?as=run'; 8 + import profile5 from '$docs/assets/profiles/4.webp?as=run'; 9 + import profile6 from '$docs/assets/profiles/5.webp?as=run'; 10 + import profile7 from '$docs/assets/profiles/6.webp?as=run'; 11 + import profile8 from '$docs/assets/profiles/7.webp?as=run'; 12 + import profile9 from '$docs/assets/profiles/8.webp?as=run'; 13 + import profile10 from '$docs/assets/profiles/9.webp?as=run'; 14 + 15 + const profiles = [ 16 + profile1, 17 + profile2, 18 + profile3, 19 + profile4, 20 + profile5, 21 + profile6, 22 + profile7, 23 + profile8, 24 + profile9, 25 + profile10 26 + ]; 27 + 28 + let swipe: (direction: 'left' | 'right') => void; 29 + </script> 30 + 31 + <div class="relative h-[70vh] w-full not-prose"> 32 + <CardSwiper 33 + cardData={(i) => ({ 34 + title: `Card ${i}`, 35 + description: `Card ${i} description`, 36 + image: profiles[i % profiles.length] 37 + })} 38 + bind:swipe 39 + ></CardSwiper> 40 + 41 + <div class="absolute bottom-2 flex w-full justify-between px-2"> 42 + <Button onclick={() => swipe('left')} size="iconLg"> 43 + <svg 44 + xmlns="http://www.w3.org/2000/svg" 45 + fill="none" 46 + viewBox="0 0 24 24" 47 + stroke-width="2.5" 48 + stroke="currentColor" 49 + class="size-6" 50 + > 51 + <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 52 + </svg> 53 + </Button> 54 + <Button onclick={() => swipe('right')} size="iconLg"> 55 + <svg 56 + xmlns="http://www.w3.org/2000/svg" 57 + viewBox="0 0 24 24" 58 + fill="currentColor" 59 + class="size-6" 60 + > 61 + <path 62 + d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" 63 + /> 64 + </svg> 65 + </Button> 66 + </div> 67 + </div>
+33
src/routes/(main)/components/extras/swiper-cards/SwiperCards.md
··· 1 + <script lang="ts"> 2 + import SwiperCardsExample from './Example.svelte'; 3 + </script> 4 + 5 + # Swiper Cards 6 + 7 + ## Example 8 + 9 + <SwiperCardsExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { CardSwiper } from 'fuchs'; 16 + 17 + const profiles = [ 18 + 'image1.webp', 19 + 'image2.webp', 20 + 'image3.webp', 21 + ]; 22 + </script> 23 + 24 + <div class="h-[70vh] w-full"> 25 + <CardSwiper 26 + cardData={(i) => ({ 27 + title: `Card ${i}`, 28 + description: `Card ${i} description`, 29 + image: profiles[i % profiles.length] 30 + })} 31 + ></CardSwiper> 32 + </div> 33 + ```
+4 -5
src/routes/+page.svelte
··· 13 13 <Navbar /> 14 14 <Sidebar mobileOnly /> 15 15 16 - <div class="mx-auto flex w-full max-w-7xl flex-col items-start justify-center gap-2 px-8 py-24"> 16 + <div class="mx-auto flex w-full max-w-6xl flex-col items-start justify-center gap-8 px-8 py-24"> 17 17 <h1 18 - class="text-base-950 dark:text-base-50 my-8 mt-8 max-w-2xl text-4xl font-bold tracking-tight text-pretty md:text-5xl md:leading-14" 18 + class="text-base-950 dark:text-base-50 mb-4 mt-16 max-w-2xl text-4xl font-bold tracking-tight text-pretty md:text-5xl md:leading-14" 19 19 > 20 20 {count} UI components built with Tailwind 4 and Svelte 5 21 21 </h1> 22 22 23 - <PublicAlphaAlert class="w-fit" /> 24 - 25 - <div class="flex gap-2"> 23 + <div class="flex gap-2 mb-16"> 26 24 <Button href={base + '/docs/quick-start'} class="mb-8">Quick Start</Button> 27 25 <Button variant="link" href={base + '/docs/philosophy'} class="mb-8" 28 26 >Learn more <span>&rarr;</span></Button 29 27 > 30 28 </div> 29 + 31 30 <Cards /> 32 31 </div>