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

Merge pull request #4 from flo-bit/main

color gradient picker

authored by

Florian and committed by
GitHub
(Mar 22, 2025, 5:58 AM +0100) 179f988d 468773c9

+2906 -2230
+18 -2
package-lock.json
··· 1 1 { 2 2 "name": "fuchs", 3 - "version": "0.0.9", 3 + "version": "0.0.11", 4 4 "lockfileVersion": 3, 5 5 "requires": true, 6 6 "packages": { 7 7 "": { 8 8 "name": "fuchs", 9 - "version": "0.0.9", 9 + "version": "0.0.11", 10 10 "license": "MIT", 11 11 "dependencies": { 12 12 "@atproto/api": "^0.14.7", ··· 17 17 "@threlte/core": "^8.0.1", 18 18 "@threlte/extras": "^9.0.1", 19 19 "@types/three": "^0.173.0", 20 + "@use-gesture/vanilla": "^10.3.1", 20 21 "bits-ui": "^1.3.4", 21 22 "cheerio": "^1.0.0", 22 23 "hls.js": "^1.5.20", ··· 2790 2791 "funding": { 2791 2792 "type": "opencollective", 2792 2793 "url": "https://opencollective.com/typescript-eslint" 2794 + } 2795 + }, 2796 + "node_modules/@use-gesture/core": { 2797 + "version": "10.3.1", 2798 + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", 2799 + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", 2800 + "license": "MIT" 2801 + }, 2802 + "node_modules/@use-gesture/vanilla": { 2803 + "version": "10.3.1", 2804 + "resolved": "https://registry.npmjs.org/@use-gesture/vanilla/-/vanilla-10.3.1.tgz", 2805 + "integrity": "sha512-lT4scGLu59ovA3zmtUonukAGcA0AdOOh+iwNDS05Bsu7Lq9aZToDHhI6D8Q2qvsVraovtsLLYwPrWdG/noMAKw==", 2806 + "license": "MIT", 2807 + "dependencies": { 2808 + "@use-gesture/core": "10.3.1" 2793 2809 } 2794 2810 }, 2795 2811 "node_modules/@webgpu/types": {
+2 -1
package.json
··· 1 1 { 2 2 "name": "fuchs", 3 - "version": "0.0.11", 3 + "version": "0.0.12", 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", ··· 82 82 "@threlte/core": "^8.0.1", 83 83 "@threlte/extras": "^9.0.1", 84 84 "@types/three": "^0.173.0", 85 + "@use-gesture/vanilla": "^10.3.1", 85 86 "bits-ui": "^1.3.4", 86 87 "cheerio": "^1.0.0", 87 88 "hls.js": "^1.5.20",
+1 -1
src/app.html
··· 45 45 </head> 46 46 <body 47 47 data-sveltekit-preload-data="hover" 48 - class="bg-base-50 dark:bg-base-950 motion-safe:transition-colors" 48 + class="bg-base-50 dark:bg-base-950 overflow-x-hidden motion-safe:transition-colors" 49 49 > 50 50 <div style="display: contents">%sveltekit.body%</div> 51 51 </body>
+1
src/lib/index.ts
··· 31 31 export { Tooltip } from '$lib/components/base/tooltip'; 32 32 33 33 // extra components 34 + export { default as ColorGradientPicker } from '$lib/components/extra/color-gradient-picker/ColorGradientPicker.svelte'; 34 35 export { ColorPicker, PopoverColorPicker } from '$lib/components/extra/color-picker/'; 35 36 export { default as Excalidraw } from '$lib/components/extra/excalidraw/Excalidraw.svelte'; 36 37 export { default as Undraw } from '$lib/components/extra/undraw/Undraw.svelte';
+2 -2
src/docs/site-components/Cards.svelte
··· 44 44 </script> 45 45 46 46 <h2 class="text-base-800 dark:text-base-200 mb-4 text-xl font-semibold">Base components</h2> 47 - <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 md:gap-8 lg:grid-cols-4"> 47 + <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 lg:gap-8 xl:grid-cols-4"> 48 48 {#each baseComponents as card} 49 49 <div 50 50 class="group relative flex flex-col items-start gap-3 transition-opacity duration-150 hover:opacity-90 md:gap-4" ··· 76 76 77 77 78 78 <h2 class="text-base-800 dark:text-base-200 mb-4 text-xl font-semibold mt-24">Extra components</h2> 79 - <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 md:gap-8 lg:grid-cols-4"> 79 + <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 lg:gap-8 xl:grid-cols-4"> 80 80 {#each extraComponents as card} 81 81 <div 82 82 class="group relative flex flex-col items-start gap-3 transition-opacity duration-150 hover:opacity-90 md:gap-4"
+1 -1
src/docs/site-components/Navbar.svelte
··· 29 29 30 30 <Logo class={showLogo ? 'lg:ml-5' : 'lg:hidden'} /> 31 31 </div> 32 - <div class="flex items-end gap-4"> 32 + <div class="flex items-end gap-3"> 33 33 <ThemeSelectDropdown /> 34 34 <ThemeToggle /> 35 35
+7
src/docs/site-components/components_extra.ts
··· 6 6 import CardTimer from '$docs/cards/extras/CardTimer.svelte'; 7 7 import CardPhone from '$docs/cards/extras/CardPhone.svelte'; 8 8 import CardQuote from '$docs/cards/extras/CardQuote.svelte'; 9 + import CardColorGradientPicker from '$docs/cards/extras/CardColorGradientPicker.svelte'; 9 10 10 11 export const extraComponents = [ 11 12 { ··· 55 56 className: '', 56 57 label: 'Quote', 57 58 href: 'quote' 59 + }, 60 + { 61 + component: CardColorGradientPicker, 62 + className: '', 63 + label: 'Color Gradient Picker', 64 + href: 'color-gradient-picker' 58 65 } 59 66 ].sort((a, b) => a.label.localeCompare(b.label));
+14
src/routes/(main)/+layout.svelte
··· 1 + <script lang="ts"> 2 + import Navbar from '$docs/site-components/Navbar.svelte'; 3 + import Sidebar from '$docs/site-components/Sidebar.svelte'; 4 + import Container from '$docs/site-components/Container.svelte'; 5 + 6 + let { children } = $props(); 7 + </script> 8 + 9 + <Navbar hasSidebar showLogo={false} /> 10 + <Sidebar /> 11 + 12 + <Container id="content"> 13 + {@render children()} 14 + </Container>
-14
src/routes/components/+layout.svelte
··· 1 - <script lang="ts"> 2 - import Navbar from '$docs/site-components/Navbar.svelte'; 3 - import Sidebar from '$docs/site-components/Sidebar.svelte'; 4 - import Container from '$docs/site-components/Container.svelte'; 5 - 6 - let { children } = $props(); 7 - </script> 8 - 9 - <Navbar hasSidebar showLogo={false} /> 10 - <Sidebar /> 11 - 12 - <Container id="content"> 13 - {@render children()} 14 - </Container>
-15
src/routes/docs/+layout.svelte
··· 1 - <script lang="ts"> 2 - import Navbar from '$docs/site-components/Navbar.svelte'; 3 - import Sidebar from '$docs/site-components/Sidebar.svelte'; 4 - import Container from '$docs/site-components/Container.svelte'; 5 - import { Button } from '$lib'; 6 - 7 - let { children } = $props(); 8 - </script> 9 - 10 - <Navbar hasSidebar showLogo={false} /> 11 - <Sidebar /> 12 - 13 - <Container id="content"> 14 - {@render children()} 15 - </Container>
src/docs/assets/profiles/0.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/1.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/10.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/11.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/12.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/13.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/2.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/3.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/4.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/5.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/6.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/7.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/8.webp

This is a binary file and will not be displayed.

src/docs/assets/profiles/9.webp

This is a binary file and will not be displayed.

+17
src/docs/cards/extras/CardColorGradientPicker.svelte
··· 1 + <div class="gradient-background h-4 w-full rounded-2xl relative border border-base-500"> 2 + <div class="absolute size-6 bg-accent-500 rounded-full border border-base-500 -top-3" style="left: calc(0% - 12px);"></div> 3 + <div class="absolute size-6 bg-accent-500 rounded-full border border-base-500 -top-3" style="left: calc(50% - 12px); background: oklch(from var(--color-accent-500) l c calc(h + 30));"></div> 4 + <div class="absolute size-6 bg-accent-500 rounded-full border border-base-500 -top-3" style="left: calc(100% - 12px); background: oklch(from var(--color-accent-500) l c calc(h + 60));"></div> 5 + </div> 6 + 7 + <style> 8 + /* background gradient */ 9 + .gradient-background { 10 + background: linear-gradient( 11 + to right, 12 + var(--color-accent-500), 13 + oklch(from var(--color-accent-500) l c calc(h + 30)), 14 + oklch(from var(--color-accent-500) l c calc(h + 60)) 15 + ); 16 + } 17 + </style>
-8
src/routes/docs/philosophy/+page.svelte
··· 1 - <script> 2 - import Prose from '$lib/components/base/prose/Prose.svelte'; 3 - import Philosophy from './Philosophy.md'; 4 - </script> 5 - 6 - <Prose> 7 - <Philosophy /> 8 - </Prose>
-97
src/routes/docs/philosophy/Philosophy.md
··· 1 - <script> 2 - import PublicAlphaAlert from '$docs/site-components/PublicAlphaAlert.svelte'; 3 - </script> 4 - 5 - # Philosophy 6 - 7 - <PublicAlphaAlert /> 8 - 9 - ## Build apps fast 10 - 11 - This ui kit's main aim is to help you build webapps that look good very fast. 12 - 13 - It's not designed to be super customizable, but instead offers you a 14 - bunch of good-looking-by-default components. 15 - 16 - ## Two colors 17 - 18 - Still all apps looking the same is kinda boring, so there are is one easy and quick way to customize all components. 19 - 20 - The main idea is having two colors (in all tailwind shades from 50 up to 950): 21 - 22 - - base color (usually one of the 5 tailwind gray tones) 23 - - accent color (usually one of the not-gray tailwind colors) 24 - 25 - You can try it out by setting the current theme colors in the navbar for this documentation site. 26 - 27 - ## Copying components vs installing packages 28 - 29 - I'm a big fan of the philosophy of copying components (shadcn-style) for better customization, 30 - but also I think the quickest way to build something is to just install the package and use it. 31 - 32 - So the plan is to have both options (currently only installing as a package is available, 33 - but you can copy what you need from the [source code](https://github.com/flo-bit/ui-kit/tree/main/src/lib/components/base) 34 - though some imports might need to be adjusted). 35 - 36 - ## Lots of components 37 - 38 - While currently only the base and some extra components are visible, there are lots of components in the pipeline. 39 - The aim is to have a component library that has lots of components that are useful for building 40 - webapps/websites/games, all in a consistent style/theme. 41 - 42 - See here for a few examples of work in progress components (some may be partially broken): 43 - 44 - ### graphs 45 - 46 - - [ring chart](/ui-kit/components/graphs/ring-chart/) 47 - - [heatmap](/ui-kit/components/graphs/heatmap/) 48 - - [line chart](/ui-kit/components/graphs/line-graph/) 49 - 50 - ### extras 51 - 52 - - [quote](/ui-kit/components/extras/quote/) 53 - 54 - ### social 55 - 56 - - [github-corner](/ui-kit/components/social/github-corner/) 57 - - [star rating](/ui-kit/components/social/star-rating/) 58 - - [social media post](/ui-kit/components/social/post/) 59 - 60 - ### 3d 61 - 62 - - [depth 3d](/ui-kit/components/3d/depth-3d/) 63 - - [model-picker](/ui-kit/components/3d/model-picker/) 64 - - [voxel-art](/ui-kit/components/3d/voxel-art/) 65 - 66 - ## Works without javascript when possible & is accessible 67 - 68 - Whenever possible components should work without javascript. 69 - Also all components should be accessible (to the best of my knowledge). 70 - Please let me know [if you find any issues there](https://github.com/flo-bit/ui-kit/issues). 71 - 72 - ## Dark mode 73 - 74 - This ui kit is designed to be used in both light and dark mode 75 - (and switch automatically depending on system settings). 76 - If you want to disable dark mode, add the following to your app.css: 77 - 78 - ```css 79 - @custom-variant dark (&:is(.dark *)); 80 - ``` 81 - 82 - Similarly you can disable light mode: 83 - 84 - 1. Add the above code to your app.css 85 - 2. Add the `dark` class to the `html` element in your app. 86 - 87 - ## Contributing/Feedback 88 - 89 - If you have any suggestions for components or feedback in general, please open an issue on [github](https://github.com/flo-bit/ui-kit/issues). 90 - 91 - Also feel free to contribute yourself, preferably by first opening an issue about the component/feature you want to add! 92 - 93 - You can also reach me on [bluesky](https://bsky.app/profile/flo-bit.dev). 94 - 95 - ## Credits 96 - 97 - This ui kit is largely based on [bits-ui](https://bits-ui.com/).
-8
src/routes/docs/quick-start/+page.svelte
··· 1 - <script> 2 - import Prose from '$lib/components/base/prose/Prose.svelte'; 3 - import QuickStart from './QuickStart.md'; 4 - </script> 5 - 6 - <Prose> 7 - <QuickStart /> 8 - </Prose>
-65
src/routes/docs/quick-start/QuickStart.md
··· 1 - <script> 2 - import PublicAlphaAlert from '$docs/site-components/PublicAlphaAlert.svelte'; 3 - </script> 4 - 5 - # Quick Start 6 - 7 - <PublicAlphaAlert /> 8 - 9 - ## 1. Create a new svelte project with tailwind css 10 - 11 - ```bash 12 - npx sv create my-project 13 - ``` 14 - 15 - Also add the `@tailwindcss/typography` and `@tailwindcss/forms` plugins. 16 - 17 - ## 2. Install fuchs 18 - 19 - ```bash 20 - npm install fuchs 21 - ``` 22 - 23 - ## 3. Set theme variables in your `app.css` 24 - 25 - You can change the colors to your liking. 26 - 27 - ```css 28 - @source "../node_modules/fuchs"; 29 - 30 - @theme { 31 - --color-base-50: var(--color-gray-50); 32 - --color-base-100: var(--color-gray-100); 33 - --color-base-200: var(--color-gray-200); 34 - --color-base-300: var(--color-gray-300); 35 - --color-base-400: var(--color-gray-400); 36 - --color-base-500: var(--color-gray-500); 37 - --color-base-600: var(--color-gray-600); 38 - --color-base-700: var(--color-gray-700); 39 - --color-base-800: var(--color-gray-800); 40 - --color-base-900: var(--color-gray-900); 41 - --color-base-950: var(--color-gray-950); 42 - 43 - --color-accent-50: var(--color-blue-50); 44 - --color-accent-100: var(--color-blue-100); 45 - --color-accent-200: var(--color-blue-200); 46 - --color-accent-300: var(--color-blue-300); 47 - --color-accent-400: var(--color-blue-400); 48 - --color-accent-500: var(--color-blue-500); 49 - --color-accent-600: var(--color-blue-600); 50 - --color-accent-700: var(--color-blue-700); 51 - --color-accent-800: var(--color-blue-800); 52 - --color-accent-900: var(--color-blue-900); 53 - --color-accent-950: var(--color-blue-950); 54 - } 55 - ``` 56 - 57 - ## 4. Use a component 58 - 59 - ```svelte 60 - <script> 61 - import { Button } from 'fuchs'; 62 - </script> 63 - 64 - <Button>Click me</Button> 65 - ```
-5
src/routes/docs/theme/+page.svelte
··· 1 - <script> 2 - import SelectTheme from '$docs/preview/SelectTheme.svelte'; 3 - </script> 4 - 5 - <SelectTheme />
+1 -1
src/lib/components/base/button/Button.svelte
··· 5 5 import { cn } from '$lib/utils'; 6 6 7 7 export const buttonVariants = tv({ 8 - base: 'touch-manipulation hover:cursor-pointer motion-safe:focus-visible:transition-transform focus-visible:outline-2 outline-offset-2 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-2xl active:scale-95 text-sm font-medium motion-safe:transition-all disabled:pointer-events-none disabled:opacity-50 duration-300 active:duration-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 8 + base: 'touch-manipulation hover:cursor-pointer backdrop-blur-md motion-safe:focus-visible:transition-transform focus-visible:outline-2 outline-offset-2 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-2xl active:scale-95 text-sm font-medium motion-safe:transition-all disabled:pointer-events-none disabled:opacity-50 duration-300 active:duration-100 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 9 9 variants: { 10 10 variant: { 11 11 primary:
+1 -1
src/lib/components/base/copy-code-button/CopyCodeButton.svelte
··· 24 24 {#if !copied} 25 25 <button 26 26 class={cn( 27 - 'not-prose focus-visible:outline-base-600 dark:focus-visible:outline-base-400 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2', 27 + 'not-prose cursor-pointer focus-visible:outline-base-600 dark:focus-visible:outline-base-400 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2', 28 28 'bg-base-200 inline-flex size-8 items-center justify-center p-1 transition-opacity duration-150 group-hover:opacity-100 [@media(pointer:fine)]:opacity-0', 29 29 'dark:bg-base-800 border-base-400 dark:border-base-700 dark:hover:bg-base-700 hover:bg-base-300 absolute top-3 right-3 rounded-2xl border' 30 30 )}
+3 -2
src/lib/components/base/theme-toggle/ThemeToggle.svelte
··· 61 61 className 62 62 )} 63 63 {...restProps} 64 + size="icon" 64 65 > 65 66 <svg 66 67 xmlns="http://www.w3.org/2000/svg" ··· 68 69 viewBox="0 0 24 24" 69 70 stroke-width="1.5" 70 71 stroke="currentColor" 71 - class="block size-6! transition-colors duration-500 dark:hidden" 72 + class="block size-5! transition-colors duration-500 dark:hidden" 72 73 > 73 74 <path 74 75 stroke-linecap="round" ··· 82 83 viewBox="0 0 24 24" 83 84 stroke-width="1.5" 84 85 stroke="currentColor" 85 - class="hidden size-6! transition-colors duration-500 dark:block dark:text-white" 86 + class="hidden size-5! transition-colors duration-500 dark:block dark:text-white" 86 87 > 87 88 <path 88 89 stroke-linecap="round"
+200
src/lib/components/extra/color-gradient-picker/ColorGradientPicker.svelte
··· 1 + <script lang="ts"> 2 + import { cn } from '$lib'; 3 + import * as Popover from '$lib/components/base/popover'; 4 + import { 5 + ColorPicker, 6 + type OKhsv, 7 + type OKlab, 8 + type RGB 9 + } from '$lib/components/extra/color-picker/base'; 10 + import { onMount } from 'svelte'; 11 + import { type OKlch } from '../color-picker/base/color'; 12 + import { DragGesture } from '@use-gesture/vanilla'; 13 + import Button from '$lib/components/base/button/Button.svelte'; 14 + 15 + 16 + type ColorStop = { rgb: RGB; position: number }; 17 + 18 + let initialColors: ColorStop[] = $state([ 19 + { rgb: { r: 0, g: 0, b: 0 }, position: 0 }, 20 + { rgb: { r: 1, g: 0, b: 0 }, position: 0.25 }, 21 + { rgb: { r: 0, g: 1, b: 0 }, position: 0.5 }, 22 + { rgb: { r: 0, g: 0, b: 1 }, position: 0.75 }, 23 + { rgb: { r: 1, g: 1, b: 0 }, position: 1 } 24 + ]); 25 + 26 + let { 27 + colors = $bindable(initialColors), 28 + class: className, 29 + onchange 30 + }: { 31 + rgb?: RGB; 32 + 33 + colors?: ColorStop[]; 34 + 35 + class?: string; 36 + 37 + onchange?: (color: { hex: string; rgb: RGB; oklab: OKlab; okhsv: OKhsv; oklch: OKlch }) => void; 38 + } = $props(); 39 + 40 + const gradientString = $derived( 41 + `linear-gradient(to right, ${colors 42 + .toSorted((a, b) => a.position - b.position) 43 + .map( 44 + ({ rgb, position }) => 45 + `rgb(${rgb.r * 255}, ${rgb.g * 255}, ${rgb.b * 255}) ${position * 100}%` 46 + ) 47 + .join(', ')})` 48 + ); 49 + 50 + $inspect(gradientString); 51 + 52 + let colorsRef = $state<(HTMLDivElement | null)[]>(new Array(colors.length).fill(null)); 53 + let gradientRef = $state<HTMLDivElement | undefined>(undefined); 54 + let isDragging = $state(new Array(colors.length).fill(false)); 55 + 56 + $effect(() => { 57 + let gestures: DragGesture[] = []; 58 + 59 + colorsRef.forEach((ref, i) => { 60 + if (!ref) return; 61 + 62 + gestures.push( 63 + new DragGesture(ref, (state) => { 64 + console.log(state); 65 + const { delta } = state; 66 + 67 + const newPosition = delta[0] / (gradientRef?.clientWidth ?? 1); 68 + 69 + colors[i].position += newPosition; 70 + colors[i].position = Math.max(0, Math.min(1, colors[i].position)); 71 + 72 + if (Math.abs(state.offset[0]) > 10) { 73 + isDragging[i] = state.active; 74 + } else { 75 + isDragging[i] = state.active; 76 + } 77 + 78 + // let offset = Math.hypot(state.movement[0], state.movement[1]); 79 + if (state.tap) { 80 + allOpen[i] = !allOpen[i]; 81 + } 82 + }) 83 + ); 84 + }); 85 + 86 + return () => { 87 + gestures.forEach((gesture) => gesture.destroy()); 88 + }; 89 + }); 90 + 91 + let allOpen = $state(new Array(colors.length).fill(false)); 92 + 93 + function getOpen(i: number) { 94 + if (isDragging[i]) { 95 + return false; 96 + } 97 + return allOpen[i]; 98 + } 99 + </script> 100 + 101 + <!-- svelte-ignore a11y_no_static_element_interactions --> 102 + <!-- svelte-ignore a11y_click_events_have_key_events --> 103 + <div 104 + class={cn( 105 + 'border-base-400 dark:border-base-600 relative h-8 w-full cursor-pointer touch-none rounded-2xl border', 106 + className 107 + )} 108 + style={'background: ' + gradientString} 109 + bind:this={gradientRef} 110 + onclick={(e) => { 111 + // get target 112 + const target = e.target as HTMLDivElement; 113 + // if target is not the gradient itself return 114 + if (target !== gradientRef) { 115 + return; 116 + } 117 + let rect = gradientRef?.getBoundingClientRect(); 118 + // get the position of the click 119 + const position = (e.clientX - rect.left) / (gradientRef?.clientWidth ?? 1); 120 + // add a new color 121 + colors.push({ rgb: { r: 0, g: 0, b: 0 }, position: position }); 122 + colorsRef.push(null); 123 + allOpen.push(true); 124 + }} 125 + onkeydown={(e) => { 126 + if (e.key === '+') { 127 + colors.push({ rgb: { r: 0, g: 0, b: 0 }, position: 0.5 }); 128 + colorsRef.push(null); 129 + allOpen.push(true); 130 + } 131 + }} 132 + > 133 + {#each colors as color, i} 134 + <Popover.Root bind:open={() => getOpen(i), (open) => {}}> 135 + <Popover.Trigger 136 + class={cn( 137 + 'absolute -top-4 left-0 touch-none', 138 + 'focus-visible:outline-base-900 dark:focus-visible:outline-base-100 cursor-pointer rounded-full focus-visible:outline-2 focus-visible:outline-offset-2' 139 + )} 140 + style={`left: calc(${color.position * 100}% - 16px)`} 141 + bind:ref={colorsRef[i]} 142 + tabindex={Math.floor(color.position * 100 + 10)} 143 + onkeydown={(e) => { 144 + if (e.key === 'Enter') { 145 + allOpen[i] = !allOpen[i]; 146 + } else if (e.key === 'Backspace' && colors.length > 2) { 147 + colors.splice(i, 1); 148 + } 149 + }} 150 + > 151 + <div 152 + 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" 153 + style={`background-color: rgb(${color.rgb.r * 255}, ${color.rgb.g * 255}, ${color.rgb.b * 255});`} 154 + ></div> 155 + </Popover.Trigger> 156 + <Popover.Content 157 + side="bottom" 158 + sideOffset={10} 159 + onInteractOutside={() => { 160 + allOpen[i] = false; 161 + }} 162 + onEscapeKeydown={() => { 163 + allOpen[i] = false; 164 + }} 165 + onkeydown={(e) => { 166 + if (e.key === 'Backspace' && colors.length > 2) { 167 + colors.splice(i, 1); 168 + } 169 + }} 170 + > 171 + <ColorPicker bind:rgb={colors[i].rgb} class={className} /> 172 + 173 + {#if colors.length > 2} 174 + <Button 175 + class="mt-4" 176 + onclick={() => { 177 + colors.splice(i, 1); 178 + }} 179 + size="sm" 180 + > 181 + <svg 182 + xmlns="http://www.w3.org/2000/svg" 183 + viewBox="0 0 24 24" 184 + fill="currentColor" 185 + class="size-6" 186 + > 187 + <path 188 + fill-rule="evenodd" 189 + d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z" 190 + clip-rule="evenodd" 191 + /> 192 + </svg> 193 + 194 + Delete Gradient Stop</Button 195 + > 196 + {/if} 197 + </Popover.Content> 198 + </Popover.Root> 199 + {/each} 200 + </div>
+49
src/lib/components/extra/countdown/Countdown.svelte
··· 1 + <script lang="ts"> 2 + import NumberFlow, { NumberFlowGroup } from '@number-flow/svelte'; 3 + import { TimerState } from '$lib'; 4 + import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui'; 5 + import type { HTMLAttributes } from 'svelte/elements'; 6 + import { cn } from '$lib/utils.js'; 7 + 8 + let { 9 + timer = $bindable(), 10 + class: className, 11 + ref = $bindable(null), 12 + showHours = false, 13 + showMinutes = true, 14 + showSeconds = true, 15 + ...restProps 16 + }: WithElementRef<WithoutChildrenOrChild<HTMLAttributes<HTMLDivElement>>> & { 17 + timer?: TimerState; 18 + showHours?: boolean; 19 + showMinutes?: boolean; 20 + showSeconds?: boolean; 21 + } = $props(); 22 + 23 + if (!timer) { 24 + timer = new TimerState(1000 * 5); 25 + } 26 + 27 + const ss = $derived(Math.floor(timer.remaining / 1000)); 28 + </script> 29 + 30 + <NumberFlowGroup> 31 + <div 32 + bind:this={ref} 33 + class={cn( 34 + 'text-base-900 dark:text-base-100 flex w-full justify-center text-5xl font-bold', 35 + className 36 + )} 37 + style="font-variant-numeric: tabular-nums;" 38 + {...restProps} 39 + > 40 + 41 + {#if showSeconds} 42 + <NumberFlow 43 + value={ss} 44 + trend={-1} 45 + digits={{ 1: { max: 5 } }} 46 + /> 47 + {/if} 48 + </div> 49 + </NumberFlowGroup>
+1 -1
src/lib/components/extra/social-icons/Github.svelte
··· 30 30 xmlns="http://www.w3.org/2000/svg" 31 31 fill="currentColor" 32 32 aria-hidden="true" 33 - class={['size-6', svgClasses]} 33 + class={['size-5', svgClasses]} 34 34 ><path 35 35 d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" 36 36 /></svg
+1
src/lib/components/extra/stopwatch/StopwatchState.svelte.ts
··· 65 65 } 66 66 this.#dispose(); 67 67 68 + this.status = 'stopped'; 68 69 this.time = new Date(); 69 70 this.startAt = this.time; 70 71 this.elapsed = 0;
+235
src/lib/components/extra/swiper-cards/CardSwiper.svelte
··· 1 + <script lang="ts"> 2 + // TODO: fix types 3 + 4 + import { onMount, type Snippet } from 'svelte'; 5 + import { DragGesture, type FullGestureState } from '@use-gesture/vanilla'; 6 + import type { CardData, Direction, SwipeEventData } from '.'; 7 + import { Image } from '$lib'; 8 + 9 + let { 10 + card = DefaultCard, 11 + cardData, 12 + onswipe, 13 + swipe = $bindable(), 14 + 15 + minSwipeDistance = 0.5, 16 + minSwipeVelocity = 0.5, 17 + arrowKeys = true, 18 + thresholdPassed = $bindable(0), 19 + anchor = null, 20 + rotate = true, 21 + cardCount = 10 22 + }: { 23 + card?: Snippet<[CardData]>; 24 + 25 + cardData: (index: number) => CardData; 26 + onswipe?: (cardInfo: SwipeEventData) => void; 27 + swipe?: (direction: Direction) => void; 28 + 29 + minSwipeDistance?: number; 30 + minSwipeVelocity?: number; 31 + arrowKeys?: boolean; 32 + thresholdPassed?: number; 33 + anchor?: number | null; 34 + rotate?: boolean; 35 + cardCount?: number; 36 + } = $props(); 37 + 38 + swipe = (direction: Direction = 'right') => { 39 + if (thresholdPassed !== 0) return; 40 + 41 + let dir = direction === 'left' ? -1 : 1; 42 + 43 + if (!topCard) throw new Error('No top card found'); 44 + cardSwiped(topCard, [dir, 0.1], [dir, 1]); 45 + }; 46 + 47 + let container: HTMLElement; 48 + 49 + let cardIndex = 0; 50 + let topCard: HTMLElement | undefined = $state(); 51 + let topCardIndex = 0; 52 + 53 + let currentZ = 100000; 54 + 55 + let cards: HTMLElement[] = $state(new Array(cardCount)); 56 + let cardsData: CardData[] = $state([]); 57 + 58 + onMount(() => { 59 + for (let i = 0; i < cardCount; i++) { 60 + cardsData.push(cardData(cardIndex++)); 61 + cards.push(); 62 + } 63 + 64 + let gestures: DragGesture[] = []; 65 + 66 + cards.forEach((el) => { 67 + if (!el) return; 68 + 69 + el.style.zIndex = currentZ.toString(); 70 + currentZ--; 71 + 72 + let gesture = new DragGesture(el, (state) => { 73 + ondrag(el, state); 74 + }); 75 + 76 + gestures.push(gesture); 77 + }); 78 + 79 + topCardIndex = 0; 80 + topCard = cards[topCardIndex]; 81 + 82 + container.classList.remove('hidden'); 83 + 84 + return () => { 85 + gestures.forEach((gesture) => gesture.destroy()); 86 + }; 87 + }); 88 + 89 + const cardSwiped = (el: HTMLElement, velocity: [number, number], movement: [number, number]) => { 90 + el.classList.add('transition-transform', 'duration-300'); 91 + let index = cards.indexOf(el); 92 + 93 + let direction: Direction = movement[0] > 0 ? 'right' : 'left'; 94 + let data = cardsData[index]; 95 + 96 + onswipe?.({ direction, element: el, data, index: cardIndex - 2 }); 97 + 98 + thresholdPassed = movement[0] > 0 ? 1 : -1; 99 + 100 + let moveOutWidth = document.body.clientWidth; 101 + 102 + let endX = Math.max(Math.abs(velocity[0]) * moveOutWidth, moveOutWidth); 103 + let toX = movement[0] > 0 ? endX : -endX; 104 + let endY = Math.abs(velocity[1]) * moveOutWidth; 105 + let toY = movement[1] > 0 ? endY : -endY; 106 + 107 + let rotate = movement[0] * 0.03 * (movement[1] / 80); 108 + 109 + el.style.transform = `translate(${toX}px, ${toY + movement[1]}px) rotate(${rotate}deg)`; 110 + 111 + setTimeout(async () => { 112 + thresholdPassed = 0; 113 + 114 + cardsData[index] = cardData(cardIndex++); 115 + 116 + // next card 117 + topCardIndex = (topCardIndex + 1) % cardCount; 118 + topCard = cards[topCardIndex]; 119 + 120 + currentZ--; 121 + el.style.zIndex = currentZ.toString(); 122 + 123 + el.classList.remove('transition-transform', 'duration-300'); 124 + el.style.transform = ''; 125 + }, 350); 126 + }; 127 + 128 + const ondrag = ( 129 + el: HTMLElement, 130 + state: Omit<FullGestureState<'drag'>, 'event'> & { 131 + event: PointerEvent | MouseEvent | TouchEvent | KeyboardEvent; 132 + } 133 + ) => { 134 + let elWidth = el.offsetWidth; 135 + 136 + if (state.active) { 137 + let angle = state.movement[0] * 0.03 * (state.movement[1] / 80); 138 + 139 + // fix movement on a curved path if anchor is set 140 + if (anchor) { 141 + let vec = [state.movement[0], state.movement[1] - anchor]; 142 + let len = Math.sqrt(vec[0] ** 2 + vec[1] ** 2); 143 + vec = [(vec[0] / len) * anchor, (vec[1] / len) * anchor]; 144 + 145 + state.movement[0] = vec[0]; 146 + state.movement[1] = vec[1] + anchor; 147 + } 148 + 149 + el.style.transform = `translate(${state.movement[0]}px, ${state.movement[1]}px)`; 150 + 151 + if (rotate) { 152 + el.style.transform += ` rotate(${angle}deg)`; 153 + } 154 + 155 + if (Math.abs(state.movement[0]) / elWidth > minSwipeDistance) { 156 + thresholdPassed = state.movement[0] > 0 ? 1 : -1; 157 + } else { 158 + thresholdPassed = 0; 159 + } 160 + return; 161 + } 162 + // if dragging is finished 163 + let keep = 164 + Math.abs(state.movement[0]) / elWidth < minSwipeDistance && 165 + Math.abs(state.velocity[0]) < minSwipeVelocity; 166 + 167 + if (keep) { 168 + thresholdPassed = 0; 169 + el.classList.add('transition-transform', 'duration-300'); 170 + el.style.transform = ''; 171 + setTimeout(() => { 172 + el.classList.remove('transition-transform', 'duration-300'); 173 + }, 300); 174 + } else { 175 + cardSwiped(el, state.velocity, state.movement); 176 + } 177 + }; 178 + </script> 179 + 180 + <svelte:body 181 + onkeydown={(e) => { 182 + if (!arrowKeys) return; 183 + if (e.key === 'ArrowLeft') { 184 + swipe('left'); 185 + } else if (e.key === 'ArrowRight') { 186 + swipe('right'); 187 + } 188 + }} 189 + /> 190 + 191 + {#snippet DefaultCard({ image, title, description }: CardData)} 192 + <div 193 + class="border-base-400 dark:border-base-600 bg-base-50 dark:bg-base-900 relative h-full w-full overflow-hidden rounded-2xl border" 194 + > 195 + {#key image} 196 + {#if image} 197 + <Image 198 + containerClasses="absolute inset-0 h-full w-full rounded-2xl" 199 + src={image} 200 + alt={title ?? ''} 201 + loading="eager" 202 + class="h-full w-full object-cover" 203 + /> 204 + {/if} 205 + {/key} 206 + <div 207 + class="from-base-50/80 dark:from-base-950/80 absolute inset-0 rounded-b-xl bg-gradient-to-t via-transparent" 208 + ></div> 209 + <div class="absolute bottom-0 flex w-full justify-start px-3 sm:px-12 py-16"> 210 + <div class="flex flex-col"> 211 + <h3 class="text-base-900 dark:text-base-50 pb-2 text-3xl font-bold">{title}</h3> 212 + <p class="text-base-800 dark:text-base-200 text-sm">{description}</p> 213 + </div> 214 + </div> 215 + </div> 216 + {/snippet} 217 + 218 + <div class="isolate h-full w-full touch-none select-none"> 219 + <div class="relative z-0 hidden h-full w-full" bind:this={container}> 220 + {#each cards as _, i} 221 + <div 222 + bind:this={cards[i]} 223 + class="absolute h-full w-full cursor-grab touch-none overflow-hidden ease-in-out select-none" 224 + > 225 + {#if cardsData[i]} 226 + {@render card({ 227 + image: cardsData[i].image, 228 + title: cardsData[i].title, 229 + description: cardsData[i].description 230 + })} 231 + {/if} 232 + </div> 233 + {/each} 234 + </div> 235 + </div>
+20
src/lib/components/extra/swiper-cards/index.ts
··· 1 + /** 2 + * change this to your own data structure, that each card will use 3 + * then change the Card.svelte file to use your data structure 4 + */ 5 + export type CardData = { 6 + title?: string; 7 + description?: string; 8 + image?: string; 9 + }; 10 + 11 + export type SwipeEventData = { 12 + direction: Direction; 13 + data: CardData; 14 + index: number; 15 + element: HTMLElement; 16 + }; 17 + 18 + export type Direction = 'left' | 'right'; 19 + 20 + export { default as CardSwiper } from './CardSwiper.svelte';
+8
src/routes/(main)/docs/philosophy/+page.svelte
··· 1 + <script> 2 + import Prose from '$lib/components/base/prose/Prose.svelte'; 3 + import Philosophy from './Philosophy.md'; 4 + </script> 5 + 6 + <Prose> 7 + <Philosophy /> 8 + </Prose>
+98
src/routes/(main)/docs/philosophy/Philosophy.md
··· 1 + <script> 2 + import PublicAlphaAlert from '$docs/site-components/PublicAlphaAlert.svelte'; 3 + </script> 4 + 5 + # Philosophy 6 + 7 + <PublicAlphaAlert /> 8 + 9 + ## Build apps fast 10 + 11 + This ui kit's main aim is to help you build webapps that look good very fast. 12 + 13 + It's not designed to be super customizable, but instead offers you a 14 + bunch of good-looking-by-default components. 15 + 16 + ## Two colors 17 + 18 + Still all apps looking the same is kinda boring, so there are is one easy and quick way to customize all components. 19 + 20 + The main idea is having two colors (in all tailwind shades from 50 up to 950): 21 + 22 + - base color (usually one of the 5 tailwind gray tones) 23 + - accent color (usually one of the not-gray tailwind colors) 24 + 25 + You can try it out by setting the current theme colors in the navbar for this documentation site. 26 + 27 + ## Copying components vs installing packages 28 + 29 + I'm a big fan of the philosophy of copying components (shadcn-style) for better customization, 30 + but also I think the quickest way to build something is to just install the package and use it. 31 + 32 + So the plan is to have both options (currently only installing as a package is available, 33 + but you can copy what you need from the [source code](https://github.com/flo-bit/ui-kit/tree/main/src/lib/components/base) 34 + though some imports might need to be adjusted). 35 + 36 + ## Lots of components 37 + 38 + While currently only the base and some extra components are visible, there are lots of components in the pipeline. 39 + The aim is to have a component library that has lots of components that are useful for building 40 + webapps/websites/games, all in a consistent style/theme. 41 + 42 + See here for a few examples of work in progress components (some may be partially broken): 43 + 44 + ### graphs 45 + 46 + - [ring chart](/ui-kit/components/graphs/ring-chart/) 47 + - [heatmap](/ui-kit/components/graphs/heatmap/) 48 + - [line chart](/ui-kit/components/graphs/line-graph/) 49 + 50 + ### extras 51 + 52 + - [quote](/ui-kit/components/extras/quote/) 53 + - [swiper cards](/ui-kit/components/extras/swiper-cards/) 54 + 55 + ### social 56 + 57 + - [github-corner](/ui-kit/components/social/github-corner/) 58 + - [star rating](/ui-kit/components/social/star-rating/) 59 + - [social media post](/ui-kit/components/social/post/) 60 + 61 + ### 3d 62 + 63 + - [depth 3d](/ui-kit/components/3d/depth-3d/) 64 + - [model-picker](/ui-kit/components/3d/model-picker/) 65 + - [voxel-art](/ui-kit/components/3d/voxel-art/) 66 + 67 + ## Works without javascript when possible & is accessible 68 + 69 + Whenever possible components should work without javascript. 70 + Also all components should be accessible (to the best of my knowledge). 71 + Please let me know [if you find any issues there](https://github.com/flo-bit/ui-kit/issues). 72 + 73 + ## Dark mode 74 + 75 + This ui kit is designed to be used in both light and dark mode 76 + (and switch automatically depending on system settings). 77 + If you want to disable dark mode, add the following to your app.css: 78 + 79 + ```css 80 + @custom-variant dark (&:is(.dark *)); 81 + ``` 82 + 83 + Similarly you can disable light mode: 84 + 85 + 1. Add the above code to your app.css 86 + 2. Add the `dark` class to the `html` element in your app. 87 + 88 + ## Contributing/Feedback 89 + 90 + If you have any suggestions for components or feedback in general, please open an issue on [github](https://github.com/flo-bit/ui-kit/issues). 91 + 92 + Also feel free to contribute yourself, preferably by first opening an issue about the component/feature you want to add! 93 + 94 + You can also reach me on [bluesky](https://bsky.app/profile/flo-bit.dev). 95 + 96 + ## Credits 97 + 98 + This ui kit is largely based on [bits-ui](https://bits-ui.com/).
+8
src/routes/(main)/docs/quick-start/+page.svelte
··· 1 + <script> 2 + import Prose from '$lib/components/base/prose/Prose.svelte'; 3 + import QuickStart from './QuickStart.md'; 4 + </script> 5 + 6 + <Prose> 7 + <QuickStart /> 8 + </Prose>
+65
src/routes/(main)/docs/quick-start/QuickStart.md
··· 1 + <script> 2 + import PublicAlphaAlert from '$docs/site-components/PublicAlphaAlert.svelte'; 3 + </script> 4 + 5 + # Quick Start 6 + 7 + <PublicAlphaAlert /> 8 + 9 + ## 1. Create a new svelte project with tailwind css 10 + 11 + ```bash 12 + npx sv create my-project 13 + ``` 14 + 15 + Also add the `@tailwindcss/typography` and `@tailwindcss/forms` plugins. 16 + 17 + ## 2. Install fuchs 18 + 19 + ```bash 20 + npm install fuchs 21 + ``` 22 + 23 + ## 3. Set theme variables in your `app.css` 24 + 25 + You can change the colors to your liking. 26 + 27 + ```css 28 + @source "../node_modules/fuchs"; 29 + 30 + @theme { 31 + --color-base-50: var(--color-gray-50); 32 + --color-base-100: var(--color-gray-100); 33 + --color-base-200: var(--color-gray-200); 34 + --color-base-300: var(--color-gray-300); 35 + --color-base-400: var(--color-gray-400); 36 + --color-base-500: var(--color-gray-500); 37 + --color-base-600: var(--color-gray-600); 38 + --color-base-700: var(--color-gray-700); 39 + --color-base-800: var(--color-gray-800); 40 + --color-base-900: var(--color-gray-900); 41 + --color-base-950: var(--color-gray-950); 42 + 43 + --color-accent-50: var(--color-blue-50); 44 + --color-accent-100: var(--color-blue-100); 45 + --color-accent-200: var(--color-blue-200); 46 + --color-accent-300: var(--color-blue-300); 47 + --color-accent-400: var(--color-blue-400); 48 + --color-accent-500: var(--color-blue-500); 49 + --color-accent-600: var(--color-blue-600); 50 + --color-accent-700: var(--color-blue-700); 51 + --color-accent-800: var(--color-blue-800); 52 + --color-accent-900: var(--color-blue-900); 53 + --color-accent-950: var(--color-blue-950); 54 + } 55 + ``` 56 + 57 + ## 4. Use a component 58 + 59 + ```svelte 60 + <script> 61 + import { Button } from 'fuchs'; 62 + </script> 63 + 64 + <Button>Click me</Button> 65 + ```
+5
src/routes/(main)/docs/theme/+page.svelte
··· 1 + <script> 2 + import SelectTheme from '$docs/preview/SelectTheme.svelte'; 3 + </script> 4 + 5 + <SelectTheme />
-5
src/routes/components/3d/depth-3d/+page.svelte
··· 1 - <script> 2 - import Depth3DPreview from '$docs/preview/Depth3DPreview.svelte'; 3 - </script> 4 - 5 - <Depth3DPreview />
-95
src/routes/components/3d/model-picker/+page.svelte
··· 1 - <script lang="ts"> 2 - import { base } from '$app/paths'; 3 - import { ModelPicker } from '$lib'; 4 - import Button from '$lib/components/base/button/Button.svelte'; 5 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 6 - import { toast } from 'svelte-sonner'; 7 - 8 - let open = $state(false); 9 - </script> 10 - 11 - <Subheading class="mb-4">Model Picker</Subheading> 12 - 13 - <ModelPicker 14 - items={[ 15 - { 16 - path: base + '/models/gltf/Barrel_A.gltf', 17 - label: 'Barrel A' 18 - }, 19 - { 20 - path: base + '/models/gltf/Barrel_B.gltf', 21 - label: 'Barrel B' 22 - }, 23 - { 24 - path: base + '/models/gltf/Box_A.gltf', 25 - label: 'Box A' 26 - }, 27 - { 28 - path: base + '/models/gltf/Box_B.gltf', 29 - label: 'Box B' 30 - }, 31 - { 32 - path: base + '/models/gltf/Coin_A.gltf', 33 - label: 'Coin A' 34 - }, 35 - { 36 - path: base + '/models/gltf/Coin_B.gltf', 37 - label: 'Coin B' 38 - }, 39 - { 40 - path: base + '/models/gltf/Coin_C.gltf', 41 - label: 'Coin C' 42 - }, 43 - { 44 - path: base + '/models/gltf/Cube_Prototype_Large_A.gltf', 45 - label: 'Cube Prototype Large A' 46 - }, 47 - { 48 - path: base + '/models/gltf/Cube_Prototype_Large_B.gltf', 49 - label: 'Cube Prototype Large B' 50 - }, 51 - { 52 - path: base + '/models/gltf/Cube_Prototype_Small.gltf', 53 - label: 'Cube Prototype Small' 54 - }, 55 - { 56 - path: base + '/models/gltf/Door_A_Decorated.gltf', 57 - label: 'Door A Decorated' 58 - }, 59 - { 60 - path: base + '/models/gltf/Door_A.gltf', 61 - label: 'Door A' 62 - }, 63 - { 64 - path: base + '/models/gltf/Door_B.gltf', 65 - label: 'Door B' 66 - }, 67 - { 68 - path: base + '/models/gltf/Dummy_Base.gltf', 69 - label: 'Dummy Base' 70 - }, 71 - { 72 - path: base + '/models/gltf/Pallet_Large.gltf', 73 - label: 'Pallet Large' 74 - }, 75 - { 76 - path: base + '/models/gltf/Pillar_A.gltf', 77 - label: 'Pillar A' 78 - }, 79 - { 80 - path: base + '/models/gltf/Pillar_B.gltf', 81 - label: 'Pillar B' 82 - }, 83 - { 84 - path: base + '/models/gltf/Primitive_Slope_Half.gltf', 85 - label: 'Primitive Slope Half' 86 - } 87 - ]} 88 - bind:open 89 - onselect={(item) => { 90 - toast.success(`Selected ${item.label}`); 91 - }} 92 - title="Select a model" 93 - /> 94 - 95 - <Button onclick={() => (open = true)}>Open</Button>
-5
src/routes/components/3d/voxel-art/+page.svelte
··· 1 - <script> 2 - import VoxelArtPreview from '$docs/preview/VoxelArtPreview.svelte'; 3 - </script> 4 - 5 - <VoxelArtPreview />
-5
src/routes/components/audio-video/audio-visualizer/+page.svelte
··· 1 - <script> 2 - import AudioVisualizerPreview from '$docs/preview/AudioVisualizerPreview.svelte'; 3 - </script> 4 - 5 - <AudioVisualizerPreview />
-5
src/routes/components/audio-video/video-player/+page.svelte
··· 1 - <script> 2 - import VideoPlayerPreview from '$docs/preview/VideoPlayerPreview.svelte'; 3 - </script> 4 - 5 - <VideoPlayerPreview />
-5
src/routes/components/audio-video/waveform-audio-player/+page.svelte
··· 1 - <script> 2 - import WaveformAudioPlayerPreview from '$docs/preview/WaveformAudioPlayerPreview.svelte'; 3 - </script> 4 - 5 - <WaveformAudioPlayerPreview />
-8
src/routes/components/base/accordion/+page.svelte
··· 1 - <script> 2 - import Prose from '$lib/components/base/prose/Prose.svelte'; 3 - import AccordionDocs from './Accordion.md'; 4 - </script> 5 - 6 - <Prose> 7 - <AccordionDocs /> 8 - </Prose>
-31
src/routes/components/base/accordion/Accordion.md
··· 1 - <script lang="ts"> 2 - import { Accordion, AccordionItem } from '$lib/components/base/accordion'; 3 - </script> 4 - 5 - # Accordion 6 - 7 - ## Example 8 - 9 - <Accordion type="single"> 10 - <AccordionItem value="item-1" title="Is it accessible?"> 11 - Yes. It adheres to the WAI-ARIA design pattern. 12 - </AccordionItem> 13 - <AccordionItem value="item-2" title="Are you sure?"> 14 - I mean, I hope so? 15 - </AccordionItem> 16 - </Accordion> 17 - 18 - ## Usage 19 - 20 - ```svelte 21 - <script lang="ts"> 22 - import { Accordion, AccordionItem } from 'fuchs'; 23 - </script> 24 - 25 - <Accordion type="single"> 26 - <AccordionItem value="item-1" title="Is it accessible?"> 27 - Yes. It adheres to the WAI-ARIA design pattern. 28 - </AccordionItem> 29 - <AccordionItem value="item-2" title="Are you sure?">I mean, I hope so?</AccordionItem> 30 - </Accordion> 31 - ```
-8
src/routes/components/base/alert/+page.svelte
··· 1 - <script lang="ts"> 2 - import AlertDocs from './Alert.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <AlertDocs /> 8 - </Prose>
-72
src/routes/components/base/alert/Alert.md
··· 1 - <script> 2 - import { Alert, AlertDescription, AlertTitle } from '$lib/components/base/alert'; 3 - </script> 4 - 5 - # Alert 6 - 7 - ## Examples 8 - 9 - <Alert class="mb-2"> 10 - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 11 - <path 12 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 13 - /> 14 - <path 15 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 16 - /> 17 - <path 18 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 19 - /> 20 - </svg> 21 - <AlertTitle class="text-rose-500 dark:text-rose-500">Default Alert</AlertTitle> 22 - <AlertDescription>Alert Description</AlertDescription> 23 - </Alert> 24 - 25 - <Alert variant="secondary" class="mb-4"> 26 - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 27 - <path 28 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 29 - /> 30 - <path 31 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 32 - /> 33 - <path 34 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 35 - /> 36 - </svg> 37 - <AlertTitle>Secondary Alert</AlertTitle> 38 - <AlertDescription>Alert Description</AlertDescription> 39 - </Alert> 40 - 41 - ### Preset Alerts 42 - 43 - <div class="grid grid-cols-1 md:grid-cols-2 gap-2"> 44 - <Alert title="Warning alert" type="warning"> 45 - <span>Alert Description</span> 46 - </Alert> 47 - 48 - <Alert title="Error alert" type="error"> 49 - <span>Alert Description</span> 50 - </Alert> 51 - 52 - <Alert title="Success alert" type="success"> 53 - <span>Alert Description</span> 54 - </Alert> 55 - 56 - <Alert title="Info alert" type="info"> 57 - <span>Alert Description</span> 58 - </Alert> 59 - 60 - </div> 61 - 62 - ## Usage 63 - 64 - ```svelte 65 - <script> 66 - import { Alert } from 'fuchs'; 67 - </script> 68 - 69 - <Alert title="Alert Title" type="info"> 70 - <span>Alert Description</span> 71 - </Alert> 72 - ```
-8
src/routes/components/base/avatar/+page.svelte
··· 1 - <script lang="ts"> 2 - import AvatarDocs from './Avatar.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <AvatarDocs /> 8 - </Prose>
-66
src/routes/components/base/avatar/Avatar.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Text } from '$lib/components/base/text'; 4 - import { Avatar, AvatarGroup } from '$lib/components/base/avatar'; 5 - </script> 6 - 7 - # Avatar 8 - 9 - ## Examples 10 - 11 - Single Avatar 12 - 13 - <div class="flex items-center gap-2"> 14 - <Avatar fallback="AB" /> 15 - <Avatar /> 16 - <Avatar src="https://github.com/flo-bit.png" alt="flo-bit" fallback="FB" class="not-prose" /> 17 - </div> 18 - 19 - Avatars Group 20 - 21 - <AvatarGroup 22 - users={[ 23 - { 24 - src: 'https://github.com/flo-bit.png', 25 - alt: 'flo-bit', 26 - fallback: 'FB' 27 - }, 28 - { 29 - src: 'https://github.com/rich-harris.png', 30 - alt: 'rich-harris', 31 - }, 32 - { 33 - src: 'https://github.com/huntabyte.png', 34 - alt: 'huntabyte', 35 - }, 36 - { 37 - fallback: '+5' 38 - } 39 - ]} 40 - class="not-prose" 41 - /> 42 - 43 - ## Usage 44 - 45 - ```svelte 46 - <script> 47 - import { Avatar, AvatarGroup } from 'fuchs'; 48 - </script> 49 - 50 - <Avatar src="https://github.com/flo-bit.png" alt="flo-bit" fallback="FB" /> 51 - 52 - <AvatarGroup 53 - users={[ 54 - { 55 - src: 'https://github.com/flo-bit.png', 56 - alt: 'flo-bit', 57 - fallback: 'FB' 58 - }, 59 - { 60 - src: 'https://github.com/rich-harris.png', 61 - alt: 'rich-harris', 62 - fallback: 'RH' 63 - } 64 - ]} 65 - /> 66 - ```
-8
src/routes/components/base/badge/+page.svelte
··· 1 - <script lang="ts"> 2 - import BadgeDocs from './Badge.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <BadgeDocs /> 8 - </Prose>
-93
src/routes/components/base/badge/Badge.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import Badge from '$lib/components/base/badge/Badge.svelte'; 4 - import { Text } from '$lib/components/base/text'; 5 - </script> 6 - 7 - # Badge 8 - 9 - ## Examples 10 - 11 - Primary 12 - 13 - <div class="flex items-center gap-2"> 14 - <Badge size="sm" 15 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 16 - <path 17 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 18 - /> 19 - <path 20 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 21 - /> 22 - <path 23 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 24 - /> 25 - </svg>default</Badge 26 - > 27 - <Badge size="md" 28 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 29 - <path 30 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 31 - /> 32 - <path 33 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 34 - /> 35 - <path 36 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 37 - /> 38 - </svg>md</Badge 39 - > 40 - <Badge size="lg" 41 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 42 - <path 43 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 44 - /> 45 - <path 46 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 47 - /> 48 - <path 49 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 50 - /> 51 - </svg>lg</Badge 52 - > 53 - </div> 54 - 55 - Secondary 56 - 57 - <div class="flex items-center gap-2"> 58 - <Badge size="sm" variant="secondary">Badge</Badge> 59 - <Badge size="md" variant="secondary">Badge</Badge> 60 - <Badge size="lg" variant="secondary">Badge</Badge> 61 - </div> 62 - 63 - Colors 64 - 65 - <div class="flex flex-wrap items-center gap-2"> 66 - <Badge variant="red">Red</Badge> 67 - <Badge variant="yellow">Yellow</Badge> 68 - <Badge variant="green">Green</Badge> 69 - <Badge variant="blue">Blue</Badge> 70 - <Badge variant="indigo">Indigo</Badge> 71 - <Badge variant="violet">Violet</Badge> 72 - <Badge variant="purple">Purple</Badge> 73 - <Badge variant="fuchsia">Fuchsia</Badge> 74 - <Badge variant="pink">Pink</Badge> 75 - <Badge variant="rose">Rose</Badge> 76 - <Badge variant="orange">Orange</Badge> 77 - <Badge variant="amber">Amber</Badge> 78 - <Badge variant="lime">Lime</Badge> 79 - <Badge variant="emerald">Emerald</Badge> 80 - <Badge variant="teal">Teal</Badge> 81 - <Badge variant="cyan">Cyan</Badge> 82 - <Badge variant="sky">Sky</Badge> 83 - </div> 84 - 85 - ## Usage 86 - 87 - ```svelte 88 - <script> 89 - import { Badge } from 'fuchs'; 90 - </script> 91 - 92 - <Badge size="sm" variant="primary">Badge</Badge> 93 - ```
-8
src/routes/components/base/box/+page.svelte
··· 1 - <script lang="ts"> 2 - import BoxDocs from './Box.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <BoxDocs /> 8 - </Prose>
-20
src/routes/components/base/box/Box.md
··· 1 - <script> 2 - import Box from '$lib/components/base/box/Box.svelte'; 3 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 - </script> 5 - 6 - # Box 7 - 8 - ## Examples 9 - 10 - <Box class="text-sm">This is a box, put your stuff here.</Box> 11 - 12 - ## Usage 13 - 14 - ```svelte 15 - <script> 16 - import { Box } from 'fuchs'; 17 - </script> 18 - 19 - <Box class="text-sm">This is a box, put your stuff here.</Box> 20 - ```
-8
src/routes/components/base/button/+page.svelte
··· 1 - <script lang="ts"> 2 - import ButtonDocs from './Button.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ButtonDocs /> 8 - </Prose>
-187
src/routes/components/base/button/Button.md
··· 1 - <script> 2 - import { Button } from '$lib/components/base/button'; 3 - import { Subheading } from '$lib/components/base/heading'; 4 - import { Text } from '$lib/components/base/text'; 5 - </script> 6 - 7 - # Buttons 8 - 9 - ## Examples 10 - 11 - Primary 12 - 13 - <div class="flex items-center gap-2"> 14 - <Button size="sm" 15 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 16 - <path 17 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 18 - /> 19 - <path 20 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 21 - /> 22 - <path 23 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 24 - /> 25 - </svg>small</Button 26 - > 27 - 28 - <Button 29 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 30 - <path 31 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 32 - /> 33 - <path 34 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 35 - /> 36 - <path 37 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 38 - /> 39 - </svg>normal</Button 40 - > 41 - 42 - <Button size="lg" 43 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 44 - <path 45 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 46 - /> 47 - <path 48 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 49 - /> 50 - <path 51 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 52 - /> 53 - </svg>large</Button 54 - > 55 - 56 - </div> 57 - 58 - Secondary 59 - 60 - <div class="flex items-center gap-2"> 61 - <Button variant="secondary" size="sm">small</Button> 62 - <Button variant="secondary">normal</Button> 63 - <Button variant="secondary" size="lg">large</Button> 64 - </div> 65 - 66 - Link 67 - 68 - <div class="flex items-center gap-2"> 69 - <Button variant="link" size="sm" 70 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 71 - <path 72 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 73 - /> 74 - <path 75 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 76 - /> 77 - <path 78 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 79 - /> 80 - </svg>small</Button 81 - > 82 - <Button variant="link" 83 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 84 - <path 85 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 86 - /> 87 - <path 88 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 89 - /> 90 - <path 91 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 92 - /> 93 - </svg>normal</Button 94 - > 95 - <Button variant="link" size="lg" 96 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 97 - <path 98 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 99 - /> 100 - <path 101 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 102 - /> 103 - <path 104 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 105 - /> 106 - </svg>large</Button 107 - > 108 - </div> 109 - 110 - Icons 111 - 112 - <div> 113 - <Button size="iconSm" 114 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 115 - <path 116 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 117 - /> 118 - <path 119 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 120 - /> 121 - <path 122 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 123 - /> 124 - </svg></Button 125 - > 126 - 127 - <Button size="icon" 128 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 129 - <path 130 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 131 - /> 132 - <path 133 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 134 - /> 135 - <path 136 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 137 - /> 138 - </svg></Button 139 - > 140 - 141 - <Button size="iconLg" 142 - ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 143 - <path 144 - d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 145 - /> 146 - <path 147 - d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 148 - /> 149 - <path 150 - d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 151 - /> 152 - </svg></Button 153 - > 154 - 155 - </div> 156 - 157 - Colors 158 - 159 - <div class="flex flex-wrap items-center gap-2"> 160 - <Button variant="red">Red</Button> 161 - <Button variant="yellow">Yellow</Button> 162 - <Button variant="green">Green</Button> 163 - <Button variant="blue">Blue</Button> 164 - <Button variant="indigo">Indigo</Button> 165 - <Button variant="violet">Violet</Button> 166 - <Button variant="purple">Purple</Button> 167 - <Button variant="fuchsia">Fuchsia</Button> 168 - <Button variant="pink">Pink</Button> 169 - <Button variant="rose">Rose</Button> 170 - <Button variant="orange">Orange</Button> 171 - <Button variant="amber">Amber</Button> 172 - <Button variant="lime">Lime</Button> 173 - <Button variant="emerald">Emerald</Button> 174 - <Button variant="teal">Teal</Button> 175 - <Button variant="cyan">Cyan</Button> 176 - <Button variant="sky">Sky</Button> 177 - </div> 178 - 179 - ## Usage 180 - 181 - ```svelte 182 - <script> 183 - import { Button } from 'fuchs'; 184 - </script> 185 - 186 - <Button variant="primary" size="sm">Button</Button> 187 - ```
-8
src/routes/components/base/cards/+page.svelte
··· 1 - <script lang="ts"> 2 - import CardsDocs from './Cards.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <CardsDocs /> 8 - </Prose>
-60
src/routes/components/base/cards/Cards.md
··· 1 - <script> 2 - import ImageCard from '$lib/components/base/card/ImageCard.svelte'; 3 - import { Subheading } from '$lib/components/base/heading'; 4 - import { Text } from '$lib/components/base/text'; 5 - 6 - import nature1 from '$docs/assets/images/nature1.jpg?as=run'; 7 - import nature2 from '$docs/assets/images/nature2.jpg?as=run'; 8 - import nature3 from '$docs/assets/images/nature3.jpg?as=run'; 9 - import { toast } from 'svelte-sonner'; 10 - </script> 11 - 12 - # Image card 13 - 14 - ## Examples 15 - 16 - ### Full width 17 - 18 - <ImageCard 19 - src={nature1} 20 - alt="Nature 1" 21 - title="Hello World" 22 - description="Just wanted to say hello to everyone on this beautiful planet, been traveling a lot lately and wanted to share some of the places I've been to." 23 - href="#" 24 - class="not-prose mb-16" 25 - /> 26 - 27 - ### In a grid 28 - 29 - <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 not-prose"> 30 - <ImageCard 31 - src={nature1} 32 - alt="Nature 1" 33 - title="Best places to visit" 34 - description="This is such a long description, that it will probably be cut off and truncated after the first two lines." 35 - href="#" 36 - /> 37 - <ImageCard 38 - src={nature2} 39 - alt="Nature 2" 40 - title="This is a beautiful place" 41 - description="This card will show a toast when clicked" 42 - onclick={() => toast('Hello World')} 43 - /> 44 - <ImageCard 45 - src={nature3} 46 - alt="Nature 3" 47 - title="Traveling is fun" 48 - description="But this card is not clickable" 49 - /> 50 - </div> 51 - 52 - ## Usage 53 - 54 - ```svelte 55 - <script> 56 - import { ImageCard } from 'fuchs'; 57 - </script> 58 - 59 - <ImageCard src={'/image.jpg'} alt="" title="Card title" description="Card description" href="#" /> 60 - ```
-8
src/routes/components/base/chat-bubble/+page.svelte
··· 1 - <script lang="ts"> 2 - import ChatBubbleDocs from './ChatBubble.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ChatBubbleDocs /> 8 - </Prose>
-55
src/routes/components/base/chat-bubble/ChatBubble.md
··· 1 - <script> 2 - import Box from '$lib/components/base/box/Box.svelte'; 3 - import ChatBubble from '$lib/components/base/chat-bubble/ChatBubble.svelte'; 4 - import Heading from '$lib/components/base/heading/Heading.svelte'; 5 - 6 - import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 7 - 8 - import cute from '$docs/assets/images/cute.jpg?as=run'; 9 - </script> 10 - 11 - # Chat Bubble 12 - 13 - ## Example 14 - 15 - <Box class="flex flex-col gap-3 not-prose"> 16 - <ChatBubble side="right" variant="secondary"> 17 - <p>Hello there</p> 18 - </ChatBubble> 19 - 20 - <ChatBubble> 21 - <p>General Kenobi</p> 22 - </ChatBubble> 23 - 24 - <ChatBubble side="right" variant="secondary"> 25 - <p>This is a really long message that should wrap around the chat bubble and not overflow</p> 26 - </ChatBubble> 27 - <ChatBubble> 28 - <p> 29 - This is another really long message that should wrap around the chat bubble and not overflow 30 - </p> 31 - </ChatBubble> 32 - 33 - <ChatBubble side="right" variant="secondary"> 34 - <p>This is me sending you an image</p> 35 - 36 - <ImageContainer src={cute} alt="cute cat" containerClasses="-mx-1.5 rounded-xl" /> 37 - </ChatBubble> 38 - 39 - </Box> 40 - 41 - ## Usage 42 - 43 - ```svelte 44 - <script> 45 - import { ChatBubble } from 'fuchs'; 46 - </script> 47 - 48 - <ChatBubble side="right" variant="secondary"> 49 - <p>Hello there</p> 50 - </ChatBubble> 51 - 52 - <ChatBubble> 53 - <p>General Kenobi</p> 54 - </ChatBubble> 55 - ```
-8
src/routes/components/base/checkbox/+page.svelte
··· 1 - <script lang="ts"> 2 - import CheckboxDocs from './Checkbox.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <CheckboxDocs /> 8 - </Prose>
-51
src/routes/components/base/checkbox/Checkbox.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Text } from '$lib/components/base/text'; 4 - import { Checkbox } from '$lib/components/base/checkbox'; 5 - import { Label } from '$lib/components/base/label'; 6 - </script> 7 - 8 - # Checkbox 9 - 10 - ## Examples 11 - 12 - Primary 13 - 14 - <div class="flex items-center gap-2"> 15 - <Checkbox sizeVariant="sm" variant="primary" /> 16 - <Checkbox sizeVariant="default" variant="primary" /> 17 - <Checkbox sizeVariant="lg" variant="primary" /> 18 - </div> 19 - 20 - Secondary 21 - 22 - <div class="flex items-center gap-2"> 23 - <Checkbox sizeVariant="sm" variant="secondary" /> 24 - <Checkbox sizeVariant="default" variant="secondary" /> 25 - <Checkbox sizeVariant="lg" variant="secondary" /> 26 - </div> 27 - 28 - With Label 29 - 30 - <div class="flex items-center space-x-2 not-prose"> 31 - <Checkbox id="terms" aria-labelledby="terms-label" variant="secondary" /> 32 - <Label 33 - id="terms-label" 34 - for="terms" 35 - class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 36 - > 37 - Yes, I agree to the terms and sell my soul (and no I didn't read the terms) 38 - </Label> 39 - </div> 40 - 41 - ## Usage 42 - 43 - ```svelte 44 - <script> 45 - import { Checkbox } from 'fuchs'; 46 - 47 - let checked = $state(false); 48 - </script> 49 - 50 - <Checkbox sizeVariant="sm" variant="primary" bind:checked /> 51 - ```
-8
src/routes/components/base/head/+page.svelte
··· 1 - <script lang="ts"> 2 - import HeadDocs from './Head.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <HeadDocs /> 8 - </Prose>
-21
src/routes/components/base/head/Head.md
··· 1 - # Head 2 - 3 - Sets title, description, open graph image, url and emoji favicon. 4 - 5 - It's recommended to add this to your root layout. 6 - 7 - ## Usage 8 - 9 - ```svelte 10 - <script> 11 - import { Head } from 'fuchs'; 12 - </script> 13 - 14 - <Head 15 - title="Website Title" 16 - description="Website Description" 17 - image="open-graph-image.png" 18 - url="https://website-url.com" 19 - emojiFavicon="🦊" 20 - /> 21 - ```
-8
src/routes/components/base/image/+page.svelte
··· 1 - <script lang="ts"> 2 - import ImageDocs from './Image.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ImageDocs /> 8 - </Prose>
-40
src/routes/components/base/image/Image.md
··· 1 - <script> 2 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 - import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 4 - import Text from '$lib/components/base/text/Text.svelte'; 5 - 6 - import cute from '$docs/assets/images/cute.jpg?as=run'; 7 - import cute2 from '$docs/assets/images/cute2.jpg?as=run'; 8 - </script> 9 - 10 - # Image 11 - 12 - ## Examples 13 - 14 - <ImageContainer src={cute} alt="Such a cute animal" containerClasses="not-prose max-w-64" /> 15 - 16 - Overlay theme color: 17 - 18 - <ImageContainer src={cute2} alt="Another cute animal" useThemeColor={true} containerClasses="max-w-44 not-prose" /> 19 - 20 - Show normal image on hover: 21 - 22 - <ImageContainer 23 - src={cute2} 24 - alt="Another cute animal" 25 - useThemeColor={true} 26 - containerClasses="max-w-44 not-prose" 27 - showNormalOnHover={true} 28 - /> 29 - 30 - ## Usage 31 - 32 - ```svelte 33 - <script> 34 - import { ImageContainer } from 'fuchs'; 35 - </script> 36 - 37 - <ImageContainer src="/image.jpg" alt="Alt tag" /> 38 - 39 - <ImageContainer src="/image.jpg" alt="Alt tag" useThemeColor showNormalOnHover /> 40 - ```
-8
src/routes/components/base/input/+page.svelte
··· 1 - <script lang="ts"> 2 - import InputDocs from './Input.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <InputDocs /> 8 - </Prose>
-37
src/routes/components/base/input/Input.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Input } from '$lib/components/base/input'; 4 - import { Text } from '$lib/components/base/text'; 5 - </script> 6 - 7 - # Input 8 - 9 - ## Examples 10 - 11 - Primary 12 - 13 - <div class="flex flex-col gap-4 w-fit"> 14 - <Input sizeVariant="sm" placeholder="Enter text here (small)" /> 15 - <Input placeholder="Enter text here (default)" /> 16 - <Input sizeVariant="lg" placeholder="Enter text here (large)" /> 17 - </div> 18 - 19 - Secondary 20 - 21 - <div class="flex flex-col gap-4 w-fit"> 22 - <Input variant="secondary" sizeVariant="sm" placeholder="Enter text here (small)" /> 23 - <Input variant="secondary" placeholder="Enter text here (default)" /> 24 - <Input variant="secondary" sizeVariant="lg" placeholder="Enter text here (large)" /> 25 - </div> 26 - 27 - ## Usage 28 - 29 - ```svelte 30 - <script> 31 - import { Input } from 'fuchs'; 32 - 33 - let value = $state(''); 34 - </script> 35 - 36 - <Input sizeVariant="sm" placeholder="Enter text here" bind:value /> 37 - ```
-8
src/routes/components/base/modal/+page.svelte
··· 1 - <script lang="ts"> 2 - import ModalDocs from './Modal.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ModalDocs /> 8 - </Prose>
-71
src/routes/components/base/modal/Modal.md
··· 1 - <script> 2 - import Button from '$lib/components/base/button/Button.svelte'; 3 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 - import Modal from '$lib/components/base/modal/Modal.svelte'; 5 - import Text from '$lib/components/base/text/Text.svelte'; 6 - import { toast } from 'svelte-sonner'; 7 - 8 - import cute from '$docs/assets/images/cute.jpg?as=run'; 9 - import BlueskyLoginModal, { 10 - blueskyLoginModalState 11 - } from '$lib/components/base/modal/BlueskyLoginModal.svelte'; 12 - import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 13 - 14 - let openDefault = $state(false); 15 - let openCustom = $state(false); 16 - </script> 17 - 18 - # Modal 19 - 20 - ## Examples 21 - 22 - <Button onclick={() => (openDefault = true)}>Default Modal</Button> 23 - 24 - <Button onclick={() => (openCustom = true)} variant="secondary">Custom Modal</Button> 25 - 26 - <Modal 27 - bind:open={openDefault} 28 - title="This is the default modal" 29 - description="It has a title, description, and two buttons (yes and no)" 30 - yesButton={{ onclick: () => toast('Yes', { description: 'Smart choice' }) }} 31 - noButton={{ onclick: () => toast('No', { description: 'Why not though?' }) }} 32 - /> 33 - 34 - <Modal bind:open={openCustom} closeButton={false}> 35 - <Subheading>Custom modal</Subheading> 36 - 37 - <Text>You can put anything in here... Like an image:</Text> 38 - 39 - <ImageContainer src={cute} alt="image in modal" useThemeColor containerClasses="max-w-64 mx-auto" /> 40 - 41 - <Button onclick={() => (openCustom = false)}>Cool</Button> 42 - 43 - </Modal> 44 - 45 - ## Usage 46 - 47 - ```svelte 48 - <script> 49 - import { Modal, Button } from 'fuchs'; 50 - 51 - let open = $state(false); 52 - 53 - function yesClicked() { 54 - console.log('yes'); 55 - } 56 - 57 - function noClicked() { 58 - console.log('no'); 59 - } 60 - </script> 61 - 62 - <Modal bind:open title="This is the default modal" /> 63 - 64 - <Button 65 - onclick={() => (open = true)} 66 - yesButton={{ onclick: yesClicked }} 67 - noButton={{ onclick: noClicked }} 68 - > 69 - Open modal 70 - </Button> 71 - ```
-8
src/routes/components/base/number-input/+page.svelte
··· 1 - <script lang="ts"> 2 - import NumberInputDocs from './NumberInput.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <NumberInputDocs /> 8 - </Prose>
-26
src/routes/components/base/number-input/NumberInput.md
··· 1 - <script> 2 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 - import NumberInput from '$lib/components/base/number-input/NumberInput.svelte'; 4 - </script> 5 - 6 - # Number Input 7 - 8 - ## Examples 9 - 10 - <NumberInput /> 11 - 12 - ## Usage 13 - 14 - ```svelte 15 - <script> 16 - import { NumberInput } from 'fuchs'; 17 - 18 - let value = $state(0); 19 - </script> 20 - 21 - <NumberInput min={0} max={100} bind:value /> 22 - ``` 23 - 24 - ## Credits 25 - 26 - - Adapted from an example of [number-flow](https://number-flow.barvian.me/)
-16
src/routes/components/base/progress/+page.svelte
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Progress } from '$lib/components/extra/progress'; 4 - 5 - let progress = $state(20); 6 - 7 - $effect(() => { 8 - setInterval(() => { 9 - progress = progress > 100 ? 0 : progress + Math.random() * 40; 10 - }, 1000); 11 - }); 12 - </script> 13 - 14 - <Subheading class="mb-8">Progress</Subheading> 15 - 16 - <Progress {progress} />
-8
src/routes/components/base/prose/+page.svelte
··· 1 - <script lang="ts"> 2 - import ProseDocs from './Prose.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ProseDocs /> 8 - </Prose>
-29
src/routes/components/base/prose/Prose.md
··· 1 - <script> 2 - import Box from '$lib/components/base/box/Box.svelte'; 3 - </script> 4 - 5 - # Prose 6 - 7 - ## Example 8 - 9 - <Box> 10 - <h1>Prose</h1> 11 - <p>Prose is a component that renders html tags with automatic styles applied.</p> 12 - <p>It is useful for rendering markdown content.</p> 13 - 14 - <p>This is a link: <a href="https://google.com">Google</a></p> 15 - </Box> 16 - 17 - ## Usage 18 - 19 - ```svelte 20 - <script> 21 - import Prose from 'fuchs'; 22 - </script> 23 - 24 - <Prose> 25 - <h1>Prose</h1> 26 - 27 - <p>Prose is a component</p> 28 - </Prose> 29 - ```
-8
src/routes/components/base/scroll-area/+page.svelte
··· 1 - <script lang="ts"> 2 - import ScrollAreaDocs from './ScrollArea.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ScrollAreaDocs /> 8 - </Prose>
-57
src/routes/components/base/scroll-area/ScrollArea.md
··· 1 - <script> 2 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 - import ScrollArea from '$lib/components/base/scroll-area/ScrollArea.svelte'; 4 - import Text from '$lib/components/base/text/Text.svelte'; 5 - 6 - let content = `Doggo ipsum puggorino shoob I am bekom fat. Clouds such treat big ol pupper vvv, porgo. Aqua 7 - doggo ur givin me a spook corgo heckin good boys heck much ruin diet, ur givin me a spook doggo 8 - such treat ur givin me a spook. What a nice floof extremely cuuuuuute waggy wags floofs dat 9 - tungg tho puggorino, smol aqua doggo dat tungg tho h*ck, sub woofer long doggo snoot you are 10 - doing me a frighten. Boofers heck porgo adorable doggo, many pats heckin good boys. Big ol blop 11 - very good spot aqua doggo, dat tungg tho pats smol borking doggo with a long snoot for pats, 12 - long bois smol. Lotsa pats borkf stop it fren heckin pupperino woofer, such treat very hand that 13 - feed shibe doge fluffer. what a nice floof vvv you are doin me a concern. Ruff you are doing me 14 - the shock boofers borkf smol borking doggo with a long snoot for pats, fluffer stop it fren many 15 - pats, doing me a frighten mlem ur givin me a spook. Stop it fren smol wow such tempt blep long 16 - woofer boofers, lotsa pats shooberino doge. corgo maximum borkdrive shibe. Many pats shoob 17 - heckin good boys I am bekom fat woofer, sub woofer long woofer. Very taste wow boof you are 18 - doing me a frighten very good spot boofers, stop it fren mlem. Length boy lotsa pats wow very 19 - biscit, blop. Snoot doggo length boy blep, length boy doing me a frighten. Big ol smol very 20 - taste wow adorable doggo, extremely cuuuuuute. borking doggo boofers. Long woofer porgo dat 21 - tungg tho boofers, blop borkdrive, h*ck mlem. Doing me a frighten long doggo blep such treat, 22 - adorable doggo smol. Such treat smol long bois most angery pupper I have ever seen, big ol 23 - pupper. Tungg much ruin diet fluffer shooberino blep aqua doggo, very taste wow very good spot 24 - aqua doggo big ol pupper pupper, long doggo very taste wow borking doggo puggo. Much ruin diet 25 - corgo you are doing me a frighten doing me a frighten, pupperino. Tungg waggy wags porgo heckin 26 - angery woofer ruff smol borking doggo with a long snoot for pats I am bekom fat, noodle horse 27 - thicc porgo many pats very hand that feed shibe, boof stop it fren heckin good boys and girls 28 - length boy super chub. Blop long water shoob puggorino yapper borkf, long woofer blep. I am 29 - bekom fat aqua doggo heck blep doggorino most angery pupper I have ever seen, pupper shoob 30 - floofs. Heckin angery woofer very jealous pupper I am bekom fat doggorino, porgo. Aqua doggo 31 - length boy ruff long bois shooberino, dat tungg tho very taste wow pupper. Clouds many pats doge 32 - heckin snoot, maximum borkdrive wow such tempt you are doin me a concern. Corgo puggorino smol 33 - borking doggo with a long snoot for pats super chub, fat boi h*ck. Dat tungg tho shoob much ruin 34 - diet very jealous pupper, floofs shibe he made many woofs woofer, heckin good boys pupperino.`; 35 - </script> 36 - 37 - # Scroll Area 38 - 39 - ## Example 40 - 41 - <ScrollArea class='h-52 w-96 max-w-full rounded-2xl border border-base-200 dark:border-base-800 text-base-900 dark:text-base-100 bg-base-100 dark:bg-base-900'> 42 - <div class="p-4"> 43 - {content} 44 - </div> 45 - </ScrollArea> 46 - 47 - ## Usage 48 - 49 - ```svelte 50 - <script> 51 - import { ScrollArea } from 'fuchs'; 52 - </script> 53 - 54 - <ScrollArea class="h-52 w-96"> 55 - <div>Your content here</div> 56 - </ScrollArea> 57 - ```
-8
src/routes/components/base/select/+page.svelte
··· 1 - <script lang="ts"> 2 - import SelectDocs from './Select.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <SelectDocs /> 8 - </Prose>
-7
src/routes/components/base/select/Example.svelte
··· 1 - <script lang="ts"> 2 - import { Select } from '$lib'; 3 - 4 - let selected = $state('Banana'); 5 - </script> 6 - 7 - <Select bind:selected items={['Apple', 'Orange', 'Banana']} />
-21
src/routes/components/base/select/Select.md
··· 1 - <script lang="ts"> 2 - import SelectExample from './Example.svelte'; 3 - </script> 4 - 5 - # Select 6 - 7 - ## Example 8 - 9 - <SelectExample /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script lang="ts"> 15 - import { Select } from 'fuchs'; 16 - 17 - let selected = $state('Apple'); 18 - </script> 19 - 20 - <Select bind:selected items={['Apple', 'Orange', 'Banana']} /> 21 - ```
-8
src/routes/components/base/slider/+page.svelte
··· 1 - <script lang="ts"> 2 - import SliderDocs from './Slider.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <SliderDocs /> 8 - </Prose>
-13
src/routes/components/base/slider/Example.svelte
··· 1 - <script lang="ts"> 2 - import { Slider } from '$lib'; 3 - import SliderNumber from '$lib/components/base/slider/SliderNumber.svelte'; 4 - 5 - let value = $state(50); 6 - 7 - let value2 = $state(42); 8 - </script> 9 - 10 - <Slider bind:value /> 11 - 12 - <h3>With Number</h3> 13 - <SliderNumber bind:value={value2} />
-24
src/routes/components/base/slider/Slider.md
··· 1 - <script lang="ts"> 2 - import SliderExample from './Example.svelte'; 3 - </script> 4 - 5 - # Sliders 6 - 7 - ## Example 8 - 9 - <SliderExample /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script> 15 - import { Slider, SliderNumber } from 'fuchs'; 16 - 17 - let value = $state(50); 18 - </script> 19 - 20 - <Slider bind:value min={0} max={100} /> 21 - 22 - <!-- With Number --> 23 - <SliderNumber bind:value={value} /> 24 - ```
-8
src/routes/components/base/sonner/+page.svelte
··· 1 - <script lang="ts"> 2 - import SonnerDocs from './Sonner.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <SonnerDocs /> 8 - </Prose>
-67
src/routes/components/base/sonner/Sonner.md
··· 1 - <script lang="ts"> 2 - import { Button } from '$lib/components/base/button'; 3 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 - import { toast } from 'svelte-sonner'; 5 - </script> 6 - 7 - # Sonner 8 - 9 - ## Example 10 - 11 - <div class="flex flex-wrap gap-4"> 12 - <Button 13 - onclick={() => 14 - toast('Hello there', { 15 - description: 'General Kenobi!' 16 - })}>Default</Button 17 - > 18 - 19 - <Button 20 - variant="green" 21 - onclick={() => 22 - toast.success('Success!', { 23 - description: "You are strong and wise and I'm very proud of you!" 24 - })}>Success</Button 25 - > 26 - <Button 27 - variant="red" 28 - onclick={() => 29 - toast.error('Error!', { 30 - description: 'These are not the droids you are looking for.' 31 - })}>Error</Button 32 - > 33 - <Button 34 - variant="blue" 35 - onclick={() => 36 - toast.info('Info!', { 37 - description: 'I heard spinning is a good trick.' 38 - })}>Info</Button 39 - > 40 - 41 - </div> 42 - 43 - ## Usage 44 - 45 - In your root layout: 46 - 47 - ```svelte 48 - <script> 49 - import { Toaster } from 'fuchs'; 50 - </script> 51 - 52 - <Toaster /> 53 - ``` 54 - 55 - In your page: 56 - 57 - ```svelte 58 - <script> 59 - import { Button, toast } from 'fuchs'; 60 - 61 - function handleClick() { 62 - toast('Hello there', { description: 'General Kenobi!' }); 63 - } 64 - </script> 65 - 66 - <Button onclick={handleClick}>Default</Button> 67 - ```
-8
src/routes/components/base/switch/+page.svelte
··· 1 - <script lang="ts"> 2 - import SwitchDocs from './Switch.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <SwitchDocs /> 8 - </Prose>
-45
src/routes/components/base/switch/Switch.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Switch } from '$lib/components/base/switch'; 4 - import { Label } from '$lib/components/base/label'; 5 - import { Text } from '$lib/components/base/text'; 6 - 7 - let checked = $state(false); 8 - 9 - let checked2 = $state(true); 10 - </script> 11 - 12 - # Switch 13 - 14 - ## Example 15 - 16 - <div class="flex flex-col gap-2"> 17 - <Switch bind:checked onCheckedChange={() => (checked2 = !checked2)} /> 18 - <Switch bind:checked={checked2} onCheckedChange={() => (checked = !checked)} /> 19 - <Switch disabled /> 20 - </div> 21 - 22 - With Label 23 - 24 - <div class="flex items-center space-x-2"> 25 - <Switch id="terms-switch" aria-labelledby="terms-switch-label" /> 26 - <Label 27 - id="terms-switch-label" 28 - for="terms-switch" 29 - class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 30 - > 31 - Yes, I agree to the terms and sell my soul (and no I didn't read the terms) 32 - </Label> 33 - </div> 34 - 35 - ## Usage 36 - 37 - ```svelte 38 - <script> 39 - import { Switch } from 'fuchs'; 40 - 41 - let checked = $state(false); 42 - </script> 43 - 44 - <Switch bind:checked /> 45 - ```
-8
src/routes/components/base/textarea/+page.svelte
··· 1 - <script lang="ts"> 2 - import TextareaDocs from './Textarea.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <TextareaDocs /> 8 - </Prose>
-37
src/routes/components/base/textarea/Textarea.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Text } from '$lib/components/base/text'; 4 - import { Textarea } from '$lib/components/base/textarea'; 5 - </script> 6 - 7 - # Textarea 8 - 9 - ## Example 10 - 11 - Primary 12 - 13 - <div class="flex flex-col md:flex-row gap-2"> 14 - <Textarea placeholder="Enter text here (small)" sizeVariant="sm" /> 15 - <Textarea placeholder="Enter text here (default)" /> 16 - <Textarea placeholder="Enter text here (large)" sizeVariant="lg" /> 17 - </div> 18 - 19 - Secondary 20 - 21 - <div class="flex flex-col md:flex-row gap-2"> 22 - <Textarea placeholder="Enter text here (small)" variant="secondary" sizeVariant="sm" /> 23 - <Textarea placeholder="Enter text here (default)" variant="secondary" /> 24 - <Textarea placeholder="Enter text here (large)" variant="secondary" sizeVariant="lg" /> 25 - </div> 26 - 27 - ## Usage 28 - 29 - ```svelte 30 - <script> 31 - import { Textarea } from 'fuchs'; 32 - 33 - let value = $state(''); 34 - </script> 35 - 36 - <Textarea placeholder="Enter text here" bind:value /> 37 - ```
-8
src/routes/components/base/tooltip/+page.svelte
··· 1 - <script lang="ts"> 2 - import TooltipDocs from './Tooltip.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <TooltipDocs /> 8 - </Prose>
-41
src/routes/components/base/tooltip/Tooltip.md
··· 1 - <script> 2 - import { Subheading } from '$lib/components/base/heading'; 3 - import { Tooltip } from '$lib/components/base/tooltip'; 4 - import { Text } from '$lib/components/base/text'; 5 - import { Button } from '$lib/components/base/button'; 6 - import { toast } from 'svelte-sonner'; 7 - 8 - function handleClick() { 9 - toast.error('Don\'t click, just hover!') 10 - } 11 - </script> 12 - 13 - # Tooltip 14 - 15 - ## Example 16 - 17 - <div class="flex w-full flex-col items-start gap-2 py-12"> 18 - <Tooltip text="Hello there!" withContext> 19 - {#snippet child({ props })} 20 - <Button {...props} onclick={handleClick}>Hover me</Button> 21 - {/snippet} 22 - </Tooltip> 23 - </div> 24 - 25 - ## Usage 26 - 27 - ```svelte 28 - <script> 29 - import { Tooltip, Button } from 'fuchs'; 30 - 31 - function handleClick() { 32 - console.log('clicked'); 33 - } 34 - </script> 35 - 36 - <Tooltip text="Hello there!" withContext> 37 - {#snippet child({ props })} 38 - <Button {...props} onclick={handleClick}>Hover me</Button> 39 - {/snippet} 40 - </Tooltip> 41 - ```
-8
src/routes/components/extras/color-picker/+page.svelte
··· 1 - <script lang="ts"> 2 - import ColorPickerDocs from './ColorPicker.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ColorPickerDocs /> 8 - </Prose>
-33
src/routes/components/extras/color-picker/ColorPicker.md
··· 1 - <script lang="ts"> 2 - import ColorPickerExample from './Example.svelte'; 3 - </script> 4 - 5 - # Color Picker 6 - 7 - ## Example 8 - 9 - <ColorPickerExample /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script lang="ts"> 15 - import { ColorPicker, PopoverColorPicker } from 'fuchs'; 16 - 17 - let rgb = $state({ 18 - r: 0, 19 - g: 0, 20 - b: 0 21 - }); 22 - </script> 23 - 24 - <!-- inline version --> 25 - <ColorPicker bind:rgb /> 26 - 27 - <!-- popover version --> 28 - <PopoverColorPicker bind:rgb /> 29 - ``` 30 - 31 - ### Credits 32 - 33 - - Adapted from [svelte-color-select](https://github.com/CaptainCodeman/svelte-color-select).
-45
src/routes/components/extras/color-picker/Example.svelte
··· 1 - <script lang="ts"> 2 - import { ColorPicker } from '$lib/components/extra/color-picker/base'; 3 - import * as Popover from '$lib/components/base/popover'; 4 - import { cn } from '$lib/utils'; 5 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 6 - import Button from '$lib/components/base/button/Button.svelte'; 7 - import PopoverColorPicker from '$lib/components/extra/color-picker/popover/PopoverColorPicker.svelte'; 8 - import { ThemeWatcher } from '$lib/helper/ThemeWatcher.svelte'; 9 - import { hex_to_rgb, oklch_string_to_oklch, oklch_to_rgb } from '$lib/components/extra/color-picker/base/color'; 10 - import { onMount } from 'svelte'; 11 - 12 - let rgb = $state({ 13 - r: 0, 14 - g: 0, 15 - b: 0 16 - }); 17 - 18 - onMount(() => { 19 - const theme = new ThemeWatcher(); 20 - const color = theme.getCSSVar('--color-accent-500'); 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 - }); 27 - }); 28 - </script> 29 - 30 - <h3>Inline Color Picker</h3> 31 - 32 - <ColorPicker bind:rgb /> 33 - 34 - <h3>Popover Color Picker</h3> 35 - 36 - <PopoverColorPicker bind:rgb /> 37 - <!-- 38 - <Button 39 - onclick={() => { 40 - // themewatcher 41 - const theme = new ThemeWatcher(); 42 - const color = theme.getCSSVar('--color-accent-500'); 43 - rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 44 - }}>Reset Color</Button 45 - > -->
-8
src/routes/components/extras/color-select/+page.svelte
··· 1 - <script lang="ts"> 2 - import ColorSelectDocs from './ColorSelect.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 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-red-700', label: 'red' }, 21 - { class: 'text-green-700', label: 'green' }, 22 - { class: 'text-blue-700', label: 'blue' }, 23 - { class: 'text-yellow-700', label: 'yellow' } 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-500', label: '1' }, 8 - { label: '2', value: 'oklch(from var(--color-accent-500) l c calc(h + 20))' }, 9 - { label: '3', value: 'oklch(from var(--color-accent-500) l c calc(h + 40))' }, 10 - { label: '4', value: 'oklch(from var(--color-accent-500) l c calc(h + 60))' }, 11 - ]} 12 - />
-8
src/routes/components/extras/excalidraw/+page.svelte
··· 1 - <script lang="ts"> 2 - import ExcalidrawDocs from './Excalidraw.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <ExcalidrawDocs /> 8 - </Prose>
-7
src/routes/components/extras/excalidraw/Example.svelte
··· 1 - <script> 2 - import Excalidraw from '$lib/components/extra/excalidraw/Excalidraw.svelte'; 3 - 4 - import svg from '$docs/assets/demo.svg?raw'; 5 - </script> 6 - 7 - <Excalidraw {svg} alt="Excalidraw Demo" caption="This is a demo of the Excalidraw component." />
-25
src/routes/components/extras/excalidraw/Excalidraw.md
··· 1 - <script lang="ts"> 2 - import ExcalidrawExample from './Example.svelte'; 3 - </script> 4 - 5 - # Excalidraw 6 - 7 - ## Example 8 - 9 - <ExcalidrawExample /> 10 - 11 - ## Usage 12 - 13 - 1. Draw a diagram in [excalidraw](https://excalidraw.com/) with the default colors and export it as a svg without a background. 14 - 15 - 2. Import that svg and use it with the excalidraw component, colors will be automatically changed to your theme colors. 16 - 17 - ```svelte 18 - <script lang="ts"> 19 - import { Excalidraw } from 'fuchs'; 20 - 21 - import svg from '$docs/assets/demo.svg?raw'; 22 - </script> 23 - 24 - <Excalidraw {svg} alt="Excalidraw Demo" caption="This is a demo of the Excalidraw component." /> 25 - ```
-4
src/routes/components/extras/pdf-viewer/+page.svelte
··· 1 - <script> 2 - import PdfViewer from "$docs/wip/pdf-viewer/PDFViewer.svelte"; 3 - </script> 4 - <PdfViewer />
-8
src/routes/components/extras/phone/+page.svelte
··· 1 - <script lang="ts"> 2 - import PhoneDocs from './Phone.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <PhoneDocs /> 8 - </Prose>
-11
src/routes/components/extras/phone/Example.svelte
··· 1 - <script> 2 - import { Phone } from '$lib'; 3 - </script> 4 - 5 - <Phone> 6 - <div 7 - class="from-accent-200 to-accent-300 flex h-full w-full items-center justify-center bg-gradient-to-b p-8" 8 - > 9 - <div class="text-3xl font-bold text-black">Hello there</div> 10 - </div> 11 - </Phone>
-23
src/routes/components/extras/phone/Phone.md
··· 1 - <script lang="ts"> 2 - import Example from './Example.svelte'; 3 - </script> 4 - 5 - # Phone 6 - 7 - ## Example 8 - 9 - <Example /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script lang="ts"> 15 - import { Phone } from 'fuchs'; 16 - </script> 17 - 18 - <Phone> 19 - <div class="bg-accent-200 flex h-full w-full items-center justify-center p-8"> 20 - <div class="text-3xl font-bold text-black">Hello there</div> 21 - </div> 22 - </Phone> 23 - ```
-8
src/routes/components/extras/quote/+page.svelte
··· 1 - <script lang="ts"> 2 - import QuoteDocs from './Quote.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <QuoteDocs /> 8 - </Prose>
-15
src/routes/components/extras/quote/Example.svelte
··· 1 - <script> 2 - import { Quote } from '$lib'; 3 - import einstein from '$docs/assets/images/einstein.png?as=run'; 4 - </script> 5 - 6 - <Quote 7 - quote="Two things are infinite, the universe and the number of javascript frameworks, and I am not yet completely sure about the universe." 8 - author={{ 9 - name: 'Albert Einstein', 10 - role: 'Scientist', 11 - src: einstein, 12 - }} 13 - useThemeColor 14 - class="not-prose" 15 - />
-27
src/routes/components/extras/quote/Quote.md
··· 1 - <script lang="ts"> 2 - import Example from './Example.svelte'; 3 - </script> 4 - 5 - # Quote 6 - 7 - ## Example 8 - 9 - <Example /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script> 15 - import { Quote } from 'fuchs'; 16 - </script> 17 - 18 - <Quote 19 - quote="Two things are infinite, the universe and the number of javascript frameworks, and I am not yet completely sure about the universe." 20 - author={{ 21 - name: 'Albert Einstein', 22 - role: 'Scientist', 23 - src: './einstein.png', 24 - }} 25 - useThemeColor 26 - /> 27 - ```
-8
src/routes/components/extras/stopwatch/+page.svelte
··· 1 - <script lang="ts"> 2 - import StopwatchDocs from './Stopwatch.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <StopwatchDocs /> 8 - </Prose>
-27
src/routes/components/extras/stopwatch/Example.svelte
··· 1 - <script lang="ts"> 2 - import { Box, Button, Stopwatch, StopwatchState } from '$lib'; 3 - import { onMount } from 'svelte'; 4 - 5 - let stopwatch: StopwatchState | undefined = $state(undefined); 6 - 7 - onMount(() => { 8 - stopwatch?.start(); 9 - }); 10 - </script> 11 - 12 - <Box class="min-h-0"> 13 - <Stopwatch bind:stopwatch class="sm:text-7xl" /> 14 - </Box> 15 - 16 - <div class="flex w-full justify-center gap-2 mt-2"> 17 - <Button 18 - onclick={() => { 19 - if (stopwatch?.isRunning) { 20 - stopwatch?.pause(); 21 - } else { 22 - stopwatch?.resume(); 23 - } 24 - }}>{stopwatch?.isRunning ? 'Pause' : 'Start'}</Button 25 - > 26 - <Button onclick={() => stopwatch?.reset()}>Reset</Button> 27 - </div>
-28
src/routes/components/extras/stopwatch/Stopwatch.md
··· 1 - <script lang="ts"> 2 - import Example from './Example.svelte'; 3 - </script> 4 - 5 - # Stopwatch 6 - 7 - ## Example 8 - 9 - <Example /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script lang="ts"> 15 - import { Button, Stopwatch, StopwatchState } from 'fuchs'; 16 - 17 - let stopwatch: StopwatchState | undefined = $state(); 18 - </script> 19 - 20 - <Stopwatch bind:stopwatch /> 21 - 22 - <Button onclick={() => stopwatch?.start()}>Start</Button> 23 - ``` 24 - 25 - ## Credits 26 - 27 - - Stopwatch state based on [svelte-reactive-timer](https://github.com/joshnuss/svelte-reactive-timer) 28 - - Moving numbers component from [number-flow](https://number-flow.barvian.me/)
-8
src/routes/components/extras/timer/+page.svelte
··· 1 - <script lang="ts"> 2 - import TimerDocs from './Timer.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <TimerDocs /> 8 - </Prose>
-27
src/routes/components/extras/timer/Example.svelte
··· 1 - <script lang="ts"> 2 - import { Box, Button, Timer, TimerState } from '$lib'; 3 - import { onMount } from 'svelte'; 4 - 5 - let timer: TimerState | undefined = $state(undefined); 6 - 7 - onMount(() => { 8 - timer?.start(); 9 - }); 10 - </script> 11 - 12 - <Box class="min-h-0"> 13 - <Timer bind:timer class="sm:text-7xl" /> 14 - </Box> 15 - 16 - <div class="flex w-full justify-center gap-2 mt-2"> 17 - <Button 18 - onclick={() => { 19 - if (timer?.isRunning) { 20 - timer?.pause(); 21 - } else { 22 - timer?.resume(); 23 - } 24 - }}>{timer?.isRunning ? 'Pause' : 'Start'}</Button 25 - > 26 - <Button onclick={() => timer?.reset()}>Reset</Button> 27 - </div>
-28
src/routes/components/extras/timer/Timer.md
··· 1 - <script lang="ts"> 2 - import Example from './Example.svelte'; 3 - </script> 4 - 5 - # Timer 6 - 7 - ## Example 8 - 9 - <Example /> 10 - 11 - ## Usage 12 - 13 - ```svelte 14 - <script lang="ts"> 15 - import { Button, Timer, TimerState } from 'fuchs'; 16 - 17 - let timer = $state(new TimerState(1000 * 60 * 60)); 18 - </script> 19 - 20 - <Timer bind:timer /> 21 - 22 - <Button onclick={() => timer.start()}>Start</Button> 23 - ``` 24 - 25 - ## Credits 26 - 27 - - Timer state based on [svelte-reactive-timer](https://github.com/joshnuss/svelte-reactive-timer) 28 - - Moving numbers component from [number-flow](https://number-flow.barvian.me/)
-8
src/routes/components/extras/undraw/+page.svelte
··· 1 - <script lang="ts"> 2 - import UndrawDocs from './Undraw.md'; 3 - import Prose from '$lib/components/base/prose/Prose.svelte'; 4 - </script> 5 - 6 - <Prose> 7 - <UndrawDocs /> 8 - </Prose>
-19
src/routes/components/extras/undraw/Example.svelte
··· 1 - <script lang="ts"> 2 - import Undraw from '$lib/components/extra/undraw/Undraw.svelte'; 3 - 4 - import svg from '$docs/assets/undraw_yoga.svg?raw'; 5 - </script> 6 - 7 - <div class="w-full max-w-md mx-auto"> 8 - <Undraw 9 - {svg} 10 - alt="Undraw" 11 - colorMap={{ 12 - '#090814': 'fill-base-950 dark:fill-accent-950', 13 - '#d6d6e3': 'fill-base-300 dark:fill-base-700', 14 - '#cacaca': 'fill-base-400 dark:fill-base-600', 15 - '#cfcce0': 'fill-base-500 dark:fill-base-500', 16 - '#f2f2f2': 'fill-base-200 dark:fill-base-800' 17 - }} 18 - /> 19 - </div>
-42
src/routes/components/extras/undraw/Undraw.md
··· 1 - <script lang="ts"> 2 - import UndrawExample from './Example.svelte'; 3 - import {Alert} from '$lib'; 4 - </script> 5 - 6 - # Undraw 7 - 8 - ## Example 9 - 10 - <UndrawExample /> 11 - 12 - ## Usage 13 - 14 - <Alert variant="default" type="warning" title="Doesn't work automatically in dark mode"> 15 - <span> 16 - Use the `colorMap` prop to change the colors of the illustration like in the example below to make it work in both light and dark mode. 17 - </span> 18 - </Alert> 19 - 20 - 21 - 1. Download a svg illustration from [undraw](https://undraw.co/illustrations) leaving the theme color as it is (#6c63ff). 22 - 2. Import that svg with the `?raw` extension and use it with the undraw component. The theme color will automatically change to your theme color, all other colors will have to be manually changed using the `colorMap` prop (or if not using dark mode, leave as is). 23 - 24 - ```svelte 25 - <script lang="ts"> 26 - import { Undraw } from 'fuchs'; 27 - 28 - import svg from './your-illustration.svg?raw'; 29 - </script> 30 - 31 - <Undraw 32 - {svg} 33 - alt="Undraw" 34 - colorMap={{ 35 - '#090814': 'fill-base-950 dark:fill-accent-950', 36 - '#d6d6e3': 'fill-base-300 dark:fill-base-700', 37 - '#cacaca': 'fill-base-400 dark:fill-base-600', 38 - '#cfcce0': 'fill-base-500 dark:fill-base-500', 39 - '#f2f2f2': 'fill-base-200 dark:fill-base-800' 40 - }} 41 - /> 42 - ```
-5
src/routes/components/graphs/heatmap/+page.svelte
··· 1 - <script> 2 - import HeatmapPreview from '$docs/preview/HeatmapPreview.svelte'; 3 - </script> 4 - 5 - <HeatmapPreview />
-5
src/routes/components/graphs/line-graph/+page.svelte
··· 1 - <script> 2 - import LineGraphPreview from '$docs/preview/LineGraphPreview.svelte'; 3 - </script> 4 - 5 - <LineGraphPreview />
-5
src/routes/components/graphs/ring-chart/+page.svelte
··· 1 - <script> 2 - import RingChartPreview from '$docs/preview/RingChartPreview.svelte'; 3 - </script> 4 - 5 - <RingChartPreview />
-5
src/routes/components/social/following-pointer/+page.svelte
··· 1 - <script> 2 - import FollowingPointerPreview from '$docs/preview/FollowingPointerPreview.svelte'; 3 - </script> 4 - 5 - <FollowingPointerPreview />
-5
src/routes/components/social/github-corner/+page.svelte
··· 1 - <script> 2 - import GithubCornerPreview from '$docs/preview/GithubCornerPreview.svelte'; 3 - </script> 4 - 5 - <GithubCornerPreview />
-5
src/routes/components/social/post/+page.svelte
··· 1 - <script> 2 - import PostPreview from '$docs/preview/PostPreview.svelte'; 3 - </script> 4 - 5 - <PostPreview />
-5
src/routes/components/social/social-icons/+page.svelte
··· 1 - <script> 2 - import SocialIconsPreview from '$docs/preview/SocialIconsPreview.svelte'; 3 - </script> 4 - 5 - <SocialIconsPreview />
-5
src/routes/components/social/star-rating/+page.svelte
··· 1 - <script> 2 - import StarRatingPreview from '$docs/preview/StarRatingPreview.svelte'; 3 - </script> 4 - 5 - <StarRatingPreview />
-8
src/routes/components/visual/gradient/+page.svelte
··· 1 - <script> 2 - import Gradient from '$lib/components/extra/gradient/Gradient.svelte'; 3 - import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 - </script> 5 - 6 - <Subheading>Gradient</Subheading> 7 - 8 - <Gradient />
+6 -2
src/lib/components/extra/color-picker/popover/PopoverColorPicker.svelte
··· 13 13 rgb = $bindable(), 14 14 oklab = $bindable(), 15 15 okhsv = $bindable(), 16 + sideOffset = 10, 17 + side = 'bottom', 16 18 class: className, 17 19 onchange 18 20 }: { ··· 20 22 oklab?: OKlab; 21 23 okhsv?: OKhsv; 22 24 class?: string; 25 + sideOffset?: number; 26 + side?: 'top' | 'right' | 'bottom' | 'left'; 23 27 onchange?: (color: { hex: string; rgb: RGB; oklab: OKlab; okhsv: OKhsv; oklch: OKlch }) => void; 24 28 } = $props(); 25 29 ··· 57 61 style={`background-color: rgb(${internalColor.r * 255}, ${internalColor.g * 255}, ${internalColor.b * 255});`} 58 62 ></div> 59 63 </Popover.Trigger> 60 - <Popover.Content side="bottom" sideOffset={10}> 61 - <ColorPicker bind:rgb class={className} /> 64 + <Popover.Content side={side} sideOffset={sideOffset}> 65 + <ColorPicker bind:rgb bind:oklab bind:okhsv class={className} onchange={onchange} /> 62 66 </Popover.Content> 63 67 </Popover.Root>
+5
src/routes/(main)/components/3d/depth-3d/+page.svelte
··· 1 + <script> 2 + import Depth3DPreview from '$docs/preview/Depth3DPreview.svelte'; 3 + </script> 4 + 5 + <Depth3DPreview />
+95
src/routes/(main)/components/3d/model-picker/+page.svelte
··· 1 + <script lang="ts"> 2 + import { base } from '$app/paths'; 3 + import { ModelPicker } from '$lib'; 4 + import Button from '$lib/components/base/button/Button.svelte'; 5 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 6 + import { toast } from 'svelte-sonner'; 7 + 8 + let open = $state(false); 9 + </script> 10 + 11 + <Subheading class="mb-4">Model Picker</Subheading> 12 + 13 + <ModelPicker 14 + items={[ 15 + { 16 + path: base + '/models/gltf/Barrel_A.gltf', 17 + label: 'Barrel A' 18 + }, 19 + { 20 + path: base + '/models/gltf/Barrel_B.gltf', 21 + label: 'Barrel B' 22 + }, 23 + { 24 + path: base + '/models/gltf/Box_A.gltf', 25 + label: 'Box A' 26 + }, 27 + { 28 + path: base + '/models/gltf/Box_B.gltf', 29 + label: 'Box B' 30 + }, 31 + { 32 + path: base + '/models/gltf/Coin_A.gltf', 33 + label: 'Coin A' 34 + }, 35 + { 36 + path: base + '/models/gltf/Coin_B.gltf', 37 + label: 'Coin B' 38 + }, 39 + { 40 + path: base + '/models/gltf/Coin_C.gltf', 41 + label: 'Coin C' 42 + }, 43 + { 44 + path: base + '/models/gltf/Cube_Prototype_Large_A.gltf', 45 + label: 'Cube Prototype Large A' 46 + }, 47 + { 48 + path: base + '/models/gltf/Cube_Prototype_Large_B.gltf', 49 + label: 'Cube Prototype Large B' 50 + }, 51 + { 52 + path: base + '/models/gltf/Cube_Prototype_Small.gltf', 53 + label: 'Cube Prototype Small' 54 + }, 55 + { 56 + path: base + '/models/gltf/Door_A_Decorated.gltf', 57 + label: 'Door A Decorated' 58 + }, 59 + { 60 + path: base + '/models/gltf/Door_A.gltf', 61 + label: 'Door A' 62 + }, 63 + { 64 + path: base + '/models/gltf/Door_B.gltf', 65 + label: 'Door B' 66 + }, 67 + { 68 + path: base + '/models/gltf/Dummy_Base.gltf', 69 + label: 'Dummy Base' 70 + }, 71 + { 72 + path: base + '/models/gltf/Pallet_Large.gltf', 73 + label: 'Pallet Large' 74 + }, 75 + { 76 + path: base + '/models/gltf/Pillar_A.gltf', 77 + label: 'Pillar A' 78 + }, 79 + { 80 + path: base + '/models/gltf/Pillar_B.gltf', 81 + label: 'Pillar B' 82 + }, 83 + { 84 + path: base + '/models/gltf/Primitive_Slope_Half.gltf', 85 + label: 'Primitive Slope Half' 86 + } 87 + ]} 88 + bind:open 89 + onselect={(item) => { 90 + toast.success(`Selected ${item.label}`); 91 + }} 92 + title="Select a model" 93 + /> 94 + 95 + <Button onclick={() => (open = true)}>Open</Button>
+5
src/routes/(main)/components/3d/voxel-art/+page.svelte
··· 1 + <script> 2 + import VoxelArtPreview from '$docs/preview/VoxelArtPreview.svelte'; 3 + </script> 4 + 5 + <VoxelArtPreview />
+5
src/routes/(main)/components/audio-video/audio-visualizer/+page.svelte
··· 1 + <script> 2 + import AudioVisualizerPreview from '$docs/preview/AudioVisualizerPreview.svelte'; 3 + </script> 4 + 5 + <AudioVisualizerPreview />
+5
src/routes/(main)/components/audio-video/video-player/+page.svelte
··· 1 + <script> 2 + import VideoPlayerPreview from '$docs/preview/VideoPlayerPreview.svelte'; 3 + </script> 4 + 5 + <VideoPlayerPreview />
+5
src/routes/(main)/components/audio-video/waveform-audio-player/+page.svelte
··· 1 + <script> 2 + import WaveformAudioPlayerPreview from '$docs/preview/WaveformAudioPlayerPreview.svelte'; 3 + </script> 4 + 5 + <WaveformAudioPlayerPreview />
+8
src/routes/(main)/components/base/accordion/+page.svelte
··· 1 + <script> 2 + import Prose from '$lib/components/base/prose/Prose.svelte'; 3 + import AccordionDocs from './Accordion.md'; 4 + </script> 5 + 6 + <Prose> 7 + <AccordionDocs /> 8 + </Prose>
+31
src/routes/(main)/components/base/accordion/Accordion.md
··· 1 + <script lang="ts"> 2 + import { Accordion, AccordionItem } from '$lib/components/base/accordion'; 3 + </script> 4 + 5 + # Accordion 6 + 7 + ## Example 8 + 9 + <Accordion type="single"> 10 + <AccordionItem value="item-1" title="Is it accessible?"> 11 + Yes. It adheres to the WAI-ARIA design pattern. 12 + </AccordionItem> 13 + <AccordionItem value="item-2" title="Are you sure?"> 14 + I mean, I hope so? 15 + </AccordionItem> 16 + </Accordion> 17 + 18 + ## Usage 19 + 20 + ```svelte 21 + <script lang="ts"> 22 + import { Accordion, AccordionItem } from 'fuchs'; 23 + </script> 24 + 25 + <Accordion type="single"> 26 + <AccordionItem value="item-1" title="Is it accessible?"> 27 + Yes. It adheres to the WAI-ARIA design pattern. 28 + </AccordionItem> 29 + <AccordionItem value="item-2" title="Are you sure?">I mean, I hope so?</AccordionItem> 30 + </Accordion> 31 + ```
+8
src/routes/(main)/components/base/alert/+page.svelte
··· 1 + <script lang="ts"> 2 + import AlertDocs from './Alert.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <AlertDocs /> 8 + </Prose>
+72
src/routes/(main)/components/base/alert/Alert.md
··· 1 + <script> 2 + import { Alert, AlertDescription, AlertTitle } from '$lib/components/base/alert'; 3 + </script> 4 + 5 + # Alert 6 + 7 + ## Examples 8 + 9 + <Alert class="mb-2"> 10 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 11 + <path 12 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 13 + /> 14 + <path 15 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 16 + /> 17 + <path 18 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 19 + /> 20 + </svg> 21 + <AlertTitle class="text-rose-500 dark:text-rose-500">Default Alert</AlertTitle> 22 + <AlertDescription>Alert Description</AlertDescription> 23 + </Alert> 24 + 25 + <Alert variant="secondary" class="mb-4"> 26 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 27 + <path 28 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 29 + /> 30 + <path 31 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 32 + /> 33 + <path 34 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 35 + /> 36 + </svg> 37 + <AlertTitle>Secondary Alert</AlertTitle> 38 + <AlertDescription>Alert Description</AlertDescription> 39 + </Alert> 40 + 41 + ### Preset Alerts 42 + 43 + <div class="grid grid-cols-1 md:grid-cols-2 gap-2"> 44 + <Alert title="Warning alert" type="warning"> 45 + <span>Alert Description</span> 46 + </Alert> 47 + 48 + <Alert title="Error alert" type="error"> 49 + <span>Alert Description</span> 50 + </Alert> 51 + 52 + <Alert title="Success alert" type="success"> 53 + <span>Alert Description</span> 54 + </Alert> 55 + 56 + <Alert title="Info alert" type="info"> 57 + <span>Alert Description</span> 58 + </Alert> 59 + 60 + </div> 61 + 62 + ## Usage 63 + 64 + ```svelte 65 + <script> 66 + import { Alert } from 'fuchs'; 67 + </script> 68 + 69 + <Alert title="Alert Title" type="info"> 70 + <span>Alert Description</span> 71 + </Alert> 72 + ```
+8
src/routes/(main)/components/base/avatar/+page.svelte
··· 1 + <script lang="ts"> 2 + import AvatarDocs from './Avatar.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <AvatarDocs /> 8 + </Prose>
+66
src/routes/(main)/components/base/avatar/Avatar.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Text } from '$lib/components/base/text'; 4 + import { Avatar, AvatarGroup } from '$lib/components/base/avatar'; 5 + </script> 6 + 7 + # Avatar 8 + 9 + ## Examples 10 + 11 + Single Avatar 12 + 13 + <div class="flex items-center gap-2"> 14 + <Avatar fallback="AB" /> 15 + <Avatar /> 16 + <Avatar src="https://github.com/flo-bit.png" alt="flo-bit" fallback="FB" class="not-prose" /> 17 + </div> 18 + 19 + Avatars Group 20 + 21 + <AvatarGroup 22 + users={[ 23 + { 24 + src: 'https://github.com/flo-bit.png', 25 + alt: 'flo-bit', 26 + fallback: 'FB' 27 + }, 28 + { 29 + src: 'https://github.com/rich-harris.png', 30 + alt: 'rich-harris', 31 + }, 32 + { 33 + src: 'https://github.com/huntabyte.png', 34 + alt: 'huntabyte', 35 + }, 36 + { 37 + fallback: '+5' 38 + } 39 + ]} 40 + class="not-prose" 41 + /> 42 + 43 + ## Usage 44 + 45 + ```svelte 46 + <script> 47 + import { Avatar, AvatarGroup } from 'fuchs'; 48 + </script> 49 + 50 + <Avatar src="https://github.com/flo-bit.png" alt="flo-bit" fallback="FB" /> 51 + 52 + <AvatarGroup 53 + users={[ 54 + { 55 + src: 'https://github.com/flo-bit.png', 56 + alt: 'flo-bit', 57 + fallback: 'FB' 58 + }, 59 + { 60 + src: 'https://github.com/rich-harris.png', 61 + alt: 'rich-harris', 62 + fallback: 'RH' 63 + } 64 + ]} 65 + /> 66 + ```
+8
src/routes/(main)/components/base/badge/+page.svelte
··· 1 + <script lang="ts"> 2 + import BadgeDocs from './Badge.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <BadgeDocs /> 8 + </Prose>
+93
src/routes/(main)/components/base/badge/Badge.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import Badge from '$lib/components/base/badge/Badge.svelte'; 4 + import { Text } from '$lib/components/base/text'; 5 + </script> 6 + 7 + # Badge 8 + 9 + ## Examples 10 + 11 + Primary 12 + 13 + <div class="flex items-center gap-2"> 14 + <Badge size="sm" 15 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 16 + <path 17 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 18 + /> 19 + <path 20 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 21 + /> 22 + <path 23 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 24 + /> 25 + </svg>default</Badge 26 + > 27 + <Badge size="md" 28 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 29 + <path 30 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 31 + /> 32 + <path 33 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 34 + /> 35 + <path 36 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 37 + /> 38 + </svg>md</Badge 39 + > 40 + <Badge size="lg" 41 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 42 + <path 43 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 44 + /> 45 + <path 46 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 47 + /> 48 + <path 49 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 50 + /> 51 + </svg>lg</Badge 52 + > 53 + </div> 54 + 55 + Secondary 56 + 57 + <div class="flex items-center gap-2"> 58 + <Badge size="sm" variant="secondary">Badge</Badge> 59 + <Badge size="md" variant="secondary">Badge</Badge> 60 + <Badge size="lg" variant="secondary">Badge</Badge> 61 + </div> 62 + 63 + Colors 64 + 65 + <div class="flex flex-wrap items-center gap-2"> 66 + <Badge variant="red">Red</Badge> 67 + <Badge variant="yellow">Yellow</Badge> 68 + <Badge variant="green">Green</Badge> 69 + <Badge variant="blue">Blue</Badge> 70 + <Badge variant="indigo">Indigo</Badge> 71 + <Badge variant="violet">Violet</Badge> 72 + <Badge variant="purple">Purple</Badge> 73 + <Badge variant="fuchsia">Fuchsia</Badge> 74 + <Badge variant="pink">Pink</Badge> 75 + <Badge variant="rose">Rose</Badge> 76 + <Badge variant="orange">Orange</Badge> 77 + <Badge variant="amber">Amber</Badge> 78 + <Badge variant="lime">Lime</Badge> 79 + <Badge variant="emerald">Emerald</Badge> 80 + <Badge variant="teal">Teal</Badge> 81 + <Badge variant="cyan">Cyan</Badge> 82 + <Badge variant="sky">Sky</Badge> 83 + </div> 84 + 85 + ## Usage 86 + 87 + ```svelte 88 + <script> 89 + import { Badge } from 'fuchs'; 90 + </script> 91 + 92 + <Badge size="sm" variant="primary">Badge</Badge> 93 + ```
+8
src/routes/(main)/components/base/box/+page.svelte
··· 1 + <script lang="ts"> 2 + import BoxDocs from './Box.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <BoxDocs /> 8 + </Prose>
+20
src/routes/(main)/components/base/box/Box.md
··· 1 + <script> 2 + import Box from '$lib/components/base/box/Box.svelte'; 3 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 + </script> 5 + 6 + # Box 7 + 8 + ## Examples 9 + 10 + <Box class="text-sm">This is a box, put your stuff here.</Box> 11 + 12 + ## Usage 13 + 14 + ```svelte 15 + <script> 16 + import { Box } from 'fuchs'; 17 + </script> 18 + 19 + <Box class="text-sm">This is a box, put your stuff here.</Box> 20 + ```
+8
src/routes/(main)/components/base/button/+page.svelte
··· 1 + <script lang="ts"> 2 + import ButtonDocs from './Button.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ButtonDocs /> 8 + </Prose>
+187
src/routes/(main)/components/base/button/Button.md
··· 1 + <script> 2 + import { Button } from '$lib/components/base/button'; 3 + import { Subheading } from '$lib/components/base/heading'; 4 + import { Text } from '$lib/components/base/text'; 5 + </script> 6 + 7 + # Buttons 8 + 9 + ## Examples 10 + 11 + Primary 12 + 13 + <div class="flex items-center gap-2"> 14 + <Button size="sm" 15 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 16 + <path 17 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 18 + /> 19 + <path 20 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 21 + /> 22 + <path 23 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 24 + /> 25 + </svg>small</Button 26 + > 27 + 28 + <Button 29 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 30 + <path 31 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 32 + /> 33 + <path 34 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 35 + /> 36 + <path 37 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 38 + /> 39 + </svg>normal</Button 40 + > 41 + 42 + <Button size="lg" 43 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 44 + <path 45 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 46 + /> 47 + <path 48 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 49 + /> 50 + <path 51 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 52 + /> 53 + </svg>large</Button 54 + > 55 + 56 + </div> 57 + 58 + Secondary 59 + 60 + <div class="flex items-center gap-2"> 61 + <Button variant="secondary" size="sm">small</Button> 62 + <Button variant="secondary">normal</Button> 63 + <Button variant="secondary" size="lg">large</Button> 64 + </div> 65 + 66 + Link 67 + 68 + <div class="flex items-center gap-2"> 69 + <Button variant="link" size="sm" 70 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 71 + <path 72 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 73 + /> 74 + <path 75 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 76 + /> 77 + <path 78 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 79 + /> 80 + </svg>small</Button 81 + > 82 + <Button variant="link" 83 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 84 + <path 85 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 86 + /> 87 + <path 88 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 89 + /> 90 + <path 91 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 92 + /> 93 + </svg>normal</Button 94 + > 95 + <Button variant="link" size="lg" 96 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 97 + <path 98 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 99 + /> 100 + <path 101 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 102 + /> 103 + <path 104 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 105 + /> 106 + </svg>large</Button 107 + > 108 + </div> 109 + 110 + Icons 111 + 112 + <div> 113 + <Button size="iconSm" 114 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 115 + <path 116 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 117 + /> 118 + <path 119 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 120 + /> 121 + <path 122 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 123 + /> 124 + </svg></Button 125 + > 126 + 127 + <Button size="icon" 128 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 129 + <path 130 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 131 + /> 132 + <path 133 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 134 + /> 135 + <path 136 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 137 + /> 138 + </svg></Button 139 + > 140 + 141 + <Button size="iconLg" 142 + ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> 143 + <path 144 + d="M11.7 2.805a.75.75 0 0 1 .6 0A60.65 60.65 0 0 1 22.83 8.72a.75.75 0 0 1-.231 1.337 49.948 49.948 0 0 0-9.902 3.912l-.003.002c-.114.06-.227.119-.34.18a.75.75 0 0 1-.707 0A50.88 50.88 0 0 0 7.5 12.173v-.224c0-.131.067-.248.172-.311a54.615 54.615 0 0 1 4.653-2.52.75.75 0 0 0-.65-1.352 56.123 56.123 0 0 0-4.78 2.589 1.858 1.858 0 0 0-.859 1.228 49.803 49.803 0 0 0-4.634-1.527.75.75 0 0 1-.231-1.337A60.653 60.653 0 0 1 11.7 2.805Z" 145 + /> 146 + <path 147 + d="M13.06 15.473a48.45 48.45 0 0 1 7.666-3.282c.134 1.414.22 2.843.255 4.284a.75.75 0 0 1-.46.711 47.87 47.87 0 0 0-8.105 4.342.75.75 0 0 1-.832 0 47.87 47.87 0 0 0-8.104-4.342.75.75 0 0 1-.461-.71c.035-1.442.121-2.87.255-4.286.921.304 1.83.634 2.726.99v1.27a1.5 1.5 0 0 0-.14 2.508c-.09.38-.222.753-.397 1.11.452.213.901.434 1.346.66a6.727 6.727 0 0 0 .551-1.607 1.5 1.5 0 0 0 .14-2.67v-.645a48.549 48.549 0 0 1 3.44 1.667 2.25 2.25 0 0 0 2.12 0Z" 148 + /> 149 + <path 150 + d="M4.462 19.462c.42-.419.753-.89 1-1.395.453.214.902.435 1.347.662a6.742 6.742 0 0 1-1.286 1.794.75.75 0 0 1-1.06-1.06Z" 151 + /> 152 + </svg></Button 153 + > 154 + 155 + </div> 156 + 157 + Colors 158 + 159 + <div class="flex flex-wrap items-center gap-2"> 160 + <Button variant="red">Red</Button> 161 + <Button variant="yellow">Yellow</Button> 162 + <Button variant="green">Green</Button> 163 + <Button variant="blue">Blue</Button> 164 + <Button variant="indigo">Indigo</Button> 165 + <Button variant="violet">Violet</Button> 166 + <Button variant="purple">Purple</Button> 167 + <Button variant="fuchsia">Fuchsia</Button> 168 + <Button variant="pink">Pink</Button> 169 + <Button variant="rose">Rose</Button> 170 + <Button variant="orange">Orange</Button> 171 + <Button variant="amber">Amber</Button> 172 + <Button variant="lime">Lime</Button> 173 + <Button variant="emerald">Emerald</Button> 174 + <Button variant="teal">Teal</Button> 175 + <Button variant="cyan">Cyan</Button> 176 + <Button variant="sky">Sky</Button> 177 + </div> 178 + 179 + ## Usage 180 + 181 + ```svelte 182 + <script> 183 + import { Button } from 'fuchs'; 184 + </script> 185 + 186 + <Button variant="primary" size="sm">Button</Button> 187 + ```
+8
src/routes/(main)/components/base/cards/+page.svelte
··· 1 + <script lang="ts"> 2 + import CardsDocs from './Cards.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <CardsDocs /> 8 + </Prose>
+60
src/routes/(main)/components/base/cards/Cards.md
··· 1 + <script> 2 + import ImageCard from '$lib/components/base/card/ImageCard.svelte'; 3 + import { Subheading } from '$lib/components/base/heading'; 4 + import { Text } from '$lib/components/base/text'; 5 + 6 + import nature1 from '$docs/assets/images/nature1.jpg?as=run'; 7 + import nature2 from '$docs/assets/images/nature2.jpg?as=run'; 8 + import nature3 from '$docs/assets/images/nature3.jpg?as=run'; 9 + import { toast } from 'svelte-sonner'; 10 + </script> 11 + 12 + # Image card 13 + 14 + ## Examples 15 + 16 + ### Full width 17 + 18 + <ImageCard 19 + src={nature1} 20 + alt="Nature 1" 21 + title="Hello World" 22 + description="Just wanted to say hello to everyone on this beautiful planet, been traveling a lot lately and wanted to share some of the places I've been to." 23 + href="#" 24 + class="not-prose mb-16" 25 + /> 26 + 27 + ### In a grid 28 + 29 + <div class="grid w-full grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 not-prose"> 30 + <ImageCard 31 + src={nature1} 32 + alt="Nature 1" 33 + title="Best places to visit" 34 + description="This is such a long description, that it will probably be cut off and truncated after the first two lines." 35 + href="#" 36 + /> 37 + <ImageCard 38 + src={nature2} 39 + alt="Nature 2" 40 + title="This is a beautiful place" 41 + description="This card will show a toast when clicked" 42 + onclick={() => toast('Hello World')} 43 + /> 44 + <ImageCard 45 + src={nature3} 46 + alt="Nature 3" 47 + title="Traveling is fun" 48 + description="But this card is not clickable" 49 + /> 50 + </div> 51 + 52 + ## Usage 53 + 54 + ```svelte 55 + <script> 56 + import { ImageCard } from 'fuchs'; 57 + </script> 58 + 59 + <ImageCard src={'/image.jpg'} alt="" title="Card title" description="Card description" href="#" /> 60 + ```
+8
src/routes/(main)/components/base/chat-bubble/+page.svelte
··· 1 + <script lang="ts"> 2 + import ChatBubbleDocs from './ChatBubble.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ChatBubbleDocs /> 8 + </Prose>
+55
src/routes/(main)/components/base/chat-bubble/ChatBubble.md
··· 1 + <script> 2 + import Box from '$lib/components/base/box/Box.svelte'; 3 + import ChatBubble from '$lib/components/base/chat-bubble/ChatBubble.svelte'; 4 + import Heading from '$lib/components/base/heading/Heading.svelte'; 5 + 6 + import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 7 + 8 + import cute from '$docs/assets/images/cute.jpg?as=run'; 9 + </script> 10 + 11 + # Chat Bubble 12 + 13 + ## Example 14 + 15 + <Box class="flex flex-col gap-3 not-prose"> 16 + <ChatBubble side="right" variant="secondary"> 17 + <p>Hello there</p> 18 + </ChatBubble> 19 + 20 + <ChatBubble> 21 + <p>General Kenobi</p> 22 + </ChatBubble> 23 + 24 + <ChatBubble side="right" variant="secondary"> 25 + <p>This is a really long message that should wrap around the chat bubble and not overflow</p> 26 + </ChatBubble> 27 + <ChatBubble> 28 + <p> 29 + This is another really long message that should wrap around the chat bubble and not overflow 30 + </p> 31 + </ChatBubble> 32 + 33 + <ChatBubble side="right" variant="secondary"> 34 + <p>This is me sending you an image</p> 35 + 36 + <ImageContainer src={cute} alt="cute cat" containerClasses="-mx-1.5 rounded-xl" /> 37 + </ChatBubble> 38 + 39 + </Box> 40 + 41 + ## Usage 42 + 43 + ```svelte 44 + <script> 45 + import { ChatBubble } from 'fuchs'; 46 + </script> 47 + 48 + <ChatBubble side="right" variant="secondary"> 49 + <p>Hello there</p> 50 + </ChatBubble> 51 + 52 + <ChatBubble> 53 + <p>General Kenobi</p> 54 + </ChatBubble> 55 + ```
+8
src/routes/(main)/components/base/checkbox/+page.svelte
··· 1 + <script lang="ts"> 2 + import CheckboxDocs from './Checkbox.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <CheckboxDocs /> 8 + </Prose>
+51
src/routes/(main)/components/base/checkbox/Checkbox.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Text } from '$lib/components/base/text'; 4 + import { Checkbox } from '$lib/components/base/checkbox'; 5 + import { Label } from '$lib/components/base/label'; 6 + </script> 7 + 8 + # Checkbox 9 + 10 + ## Examples 11 + 12 + Primary 13 + 14 + <div class="flex items-center gap-2"> 15 + <Checkbox sizeVariant="sm" variant="primary" /> 16 + <Checkbox sizeVariant="default" variant="primary" /> 17 + <Checkbox sizeVariant="lg" variant="primary" /> 18 + </div> 19 + 20 + Secondary 21 + 22 + <div class="flex items-center gap-2"> 23 + <Checkbox sizeVariant="sm" variant="secondary" /> 24 + <Checkbox sizeVariant="default" variant="secondary" /> 25 + <Checkbox sizeVariant="lg" variant="secondary" /> 26 + </div> 27 + 28 + With Label 29 + 30 + <div class="flex items-center space-x-2 not-prose"> 31 + <Checkbox id="terms" aria-labelledby="terms-label" variant="secondary" /> 32 + <Label 33 + id="terms-label" 34 + for="terms" 35 + class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 36 + > 37 + Yes, I agree to the terms and sell my soul (and no I didn't read the terms) 38 + </Label> 39 + </div> 40 + 41 + ## Usage 42 + 43 + ```svelte 44 + <script> 45 + import { Checkbox } from 'fuchs'; 46 + 47 + let checked = $state(false); 48 + </script> 49 + 50 + <Checkbox sizeVariant="sm" variant="primary" bind:checked /> 51 + ```
+8
src/routes/(main)/components/base/head/+page.svelte
··· 1 + <script lang="ts"> 2 + import HeadDocs from './Head.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <HeadDocs /> 8 + </Prose>
+21
src/routes/(main)/components/base/head/Head.md
··· 1 + # Head 2 + 3 + Sets title, description, open graph image, url and emoji favicon. 4 + 5 + It's recommended to add this to your root layout. 6 + 7 + ## Usage 8 + 9 + ```svelte 10 + <script> 11 + import { Head } from 'fuchs'; 12 + </script> 13 + 14 + <Head 15 + title="Website Title" 16 + description="Website Description" 17 + image="open-graph-image.png" 18 + url="https://website-url.com" 19 + emojiFavicon="🦊" 20 + /> 21 + ```
+8
src/routes/(main)/components/base/image/+page.svelte
··· 1 + <script lang="ts"> 2 + import ImageDocs from './Image.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ImageDocs /> 8 + </Prose>
+40
src/routes/(main)/components/base/image/Image.md
··· 1 + <script> 2 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 + import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 4 + import Text from '$lib/components/base/text/Text.svelte'; 5 + 6 + import cute from '$docs/assets/images/cute.jpg?as=run'; 7 + import cute2 from '$docs/assets/images/cute2.jpg?as=run'; 8 + </script> 9 + 10 + # Image 11 + 12 + ## Examples 13 + 14 + <ImageContainer src={cute} alt="Such a cute animal" containerClasses="not-prose max-w-64" /> 15 + 16 + Overlay theme color: 17 + 18 + <ImageContainer src={cute2} alt="Another cute animal" useThemeColor={true} containerClasses="max-w-44 not-prose" /> 19 + 20 + Show normal image on hover: 21 + 22 + <ImageContainer 23 + src={cute2} 24 + alt="Another cute animal" 25 + useThemeColor={true} 26 + containerClasses="max-w-44 not-prose" 27 + showNormalOnHover={true} 28 + /> 29 + 30 + ## Usage 31 + 32 + ```svelte 33 + <script> 34 + import { ImageContainer } from 'fuchs'; 35 + </script> 36 + 37 + <ImageContainer src="/image.jpg" alt="Alt tag" /> 38 + 39 + <ImageContainer src="/image.jpg" alt="Alt tag" useThemeColor showNormalOnHover /> 40 + ```
+8
src/routes/(main)/components/base/input/+page.svelte
··· 1 + <script lang="ts"> 2 + import InputDocs from './Input.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <InputDocs /> 8 + </Prose>
+37
src/routes/(main)/components/base/input/Input.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Input } from '$lib/components/base/input'; 4 + import { Text } from '$lib/components/base/text'; 5 + </script> 6 + 7 + # Input 8 + 9 + ## Examples 10 + 11 + Primary 12 + 13 + <div class="flex flex-col gap-4 w-fit"> 14 + <Input sizeVariant="sm" placeholder="Enter text here (small)" /> 15 + <Input placeholder="Enter text here (default)" /> 16 + <Input sizeVariant="lg" placeholder="Enter text here (large)" /> 17 + </div> 18 + 19 + Secondary 20 + 21 + <div class="flex flex-col gap-4 w-fit"> 22 + <Input variant="secondary" sizeVariant="sm" placeholder="Enter text here (small)" /> 23 + <Input variant="secondary" placeholder="Enter text here (default)" /> 24 + <Input variant="secondary" sizeVariant="lg" placeholder="Enter text here (large)" /> 25 + </div> 26 + 27 + ## Usage 28 + 29 + ```svelte 30 + <script> 31 + import { Input } from 'fuchs'; 32 + 33 + let value = $state(''); 34 + </script> 35 + 36 + <Input sizeVariant="sm" placeholder="Enter text here" bind:value /> 37 + ```
+8
src/routes/(main)/components/base/modal/+page.svelte
··· 1 + <script lang="ts"> 2 + import ModalDocs from './Modal.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ModalDocs /> 8 + </Prose>
+71
src/routes/(main)/components/base/modal/Modal.md
··· 1 + <script> 2 + import Button from '$lib/components/base/button/Button.svelte'; 3 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 + import Modal from '$lib/components/base/modal/Modal.svelte'; 5 + import Text from '$lib/components/base/text/Text.svelte'; 6 + import { toast } from 'svelte-sonner'; 7 + 8 + import cute from '$docs/assets/images/cute.jpg?as=run'; 9 + import BlueskyLoginModal, { 10 + blueskyLoginModalState 11 + } from '$lib/components/base/modal/BlueskyLoginModal.svelte'; 12 + import ImageContainer from '$lib/components/base/image-container/ImageContainer.svelte'; 13 + 14 + let openDefault = $state(false); 15 + let openCustom = $state(false); 16 + </script> 17 + 18 + # Modal 19 + 20 + ## Examples 21 + 22 + <Button onclick={() => (openDefault = true)}>Default Modal</Button> 23 + 24 + <Button onclick={() => (openCustom = true)} variant="secondary">Custom Modal</Button> 25 + 26 + <Modal 27 + bind:open={openDefault} 28 + title="This is the default modal" 29 + description="It has a title, description, and two buttons (yes and no)" 30 + yesButton={{ onclick: () => toast('Yes', { description: 'Smart choice' }) }} 31 + noButton={{ onclick: () => toast('No', { description: 'Why not though?' }) }} 32 + /> 33 + 34 + <Modal bind:open={openCustom} closeButton={false}> 35 + <Subheading>Custom modal</Subheading> 36 + 37 + <Text>You can put anything in here... Like an image:</Text> 38 + 39 + <ImageContainer src={cute} alt="image in modal" useThemeColor containerClasses="max-w-64 mx-auto" /> 40 + 41 + <Button onclick={() => (openCustom = false)}>Cool</Button> 42 + 43 + </Modal> 44 + 45 + ## Usage 46 + 47 + ```svelte 48 + <script> 49 + import { Modal, Button } from 'fuchs'; 50 + 51 + let open = $state(false); 52 + 53 + function yesClicked() { 54 + console.log('yes'); 55 + } 56 + 57 + function noClicked() { 58 + console.log('no'); 59 + } 60 + </script> 61 + 62 + <Modal bind:open title="This is the default modal" /> 63 + 64 + <Button 65 + onclick={() => (open = true)} 66 + yesButton={{ onclick: yesClicked }} 67 + noButton={{ onclick: noClicked }} 68 + > 69 + Open modal 70 + </Button> 71 + ```
+8
src/routes/(main)/components/base/number-input/+page.svelte
··· 1 + <script lang="ts"> 2 + import NumberInputDocs from './NumberInput.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <NumberInputDocs /> 8 + </Prose>
+26
src/routes/(main)/components/base/number-input/NumberInput.md
··· 1 + <script> 2 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 + import NumberInput from '$lib/components/base/number-input/NumberInput.svelte'; 4 + </script> 5 + 6 + # Number Input 7 + 8 + ## Examples 9 + 10 + <NumberInput /> 11 + 12 + ## Usage 13 + 14 + ```svelte 15 + <script> 16 + import { NumberInput } from 'fuchs'; 17 + 18 + let value = $state(0); 19 + </script> 20 + 21 + <NumberInput min={0} max={100} bind:value /> 22 + ``` 23 + 24 + ## Credits 25 + 26 + - Adapted from an example of [number-flow](https://number-flow.barvian.me/)
+16
src/routes/(main)/components/base/progress/+page.svelte
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Progress } from '$lib/components/extra/progress'; 4 + 5 + let progress = $state(20); 6 + 7 + $effect(() => { 8 + setInterval(() => { 9 + progress = progress > 100 ? 0 : progress + Math.random() * 40; 10 + }, 1000); 11 + }); 12 + </script> 13 + 14 + <Subheading class="mb-8">Progress</Subheading> 15 + 16 + <Progress {progress} />
+8
src/routes/(main)/components/base/prose/+page.svelte
··· 1 + <script lang="ts"> 2 + import ProseDocs from './Prose.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ProseDocs /> 8 + </Prose>
+29
src/routes/(main)/components/base/prose/Prose.md
··· 1 + <script> 2 + import Box from '$lib/components/base/box/Box.svelte'; 3 + </script> 4 + 5 + # Prose 6 + 7 + ## Example 8 + 9 + <Box> 10 + <h1>Prose</h1> 11 + <p>Prose is a component that renders html tags with automatic styles applied.</p> 12 + <p>It is useful for rendering markdown content.</p> 13 + 14 + <p>This is a link: <a href="https://google.com">Google</a></p> 15 + </Box> 16 + 17 + ## Usage 18 + 19 + ```svelte 20 + <script> 21 + import Prose from 'fuchs'; 22 + </script> 23 + 24 + <Prose> 25 + <h1>Prose</h1> 26 + 27 + <p>Prose is a component</p> 28 + </Prose> 29 + ```
+8
src/routes/(main)/components/base/scroll-area/+page.svelte
··· 1 + <script lang="ts"> 2 + import ScrollAreaDocs from './ScrollArea.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ScrollAreaDocs /> 8 + </Prose>
+57
src/routes/(main)/components/base/scroll-area/ScrollArea.md
··· 1 + <script> 2 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 3 + import ScrollArea from '$lib/components/base/scroll-area/ScrollArea.svelte'; 4 + import Text from '$lib/components/base/text/Text.svelte'; 5 + 6 + let content = `Doggo ipsum puggorino shoob I am bekom fat. Clouds such treat big ol pupper vvv, porgo. Aqua 7 + doggo ur givin me a spook corgo heckin good boys heck much ruin diet, ur givin me a spook doggo 8 + such treat ur givin me a spook. What a nice floof extremely cuuuuuute waggy wags floofs dat 9 + tungg tho puggorino, smol aqua doggo dat tungg tho h*ck, sub woofer long doggo snoot you are 10 + doing me a frighten. Boofers heck porgo adorable doggo, many pats heckin good boys. Big ol blop 11 + very good spot aqua doggo, dat tungg tho pats smol borking doggo with a long snoot for pats, 12 + long bois smol. Lotsa pats borkf stop it fren heckin pupperino woofer, such treat very hand that 13 + feed shibe doge fluffer. what a nice floof vvv you are doin me a concern. Ruff you are doing me 14 + the shock boofers borkf smol borking doggo with a long snoot for pats, fluffer stop it fren many 15 + pats, doing me a frighten mlem ur givin me a spook. Stop it fren smol wow such tempt blep long 16 + woofer boofers, lotsa pats shooberino doge. corgo maximum borkdrive shibe. Many pats shoob 17 + heckin good boys I am bekom fat woofer, sub woofer long woofer. Very taste wow boof you are 18 + doing me a frighten very good spot boofers, stop it fren mlem. Length boy lotsa pats wow very 19 + biscit, blop. Snoot doggo length boy blep, length boy doing me a frighten. Big ol smol very 20 + taste wow adorable doggo, extremely cuuuuuute. borking doggo boofers. Long woofer porgo dat 21 + tungg tho boofers, blop borkdrive, h*ck mlem. Doing me a frighten long doggo blep such treat, 22 + adorable doggo smol. Such treat smol long bois most angery pupper I have ever seen, big ol 23 + pupper. Tungg much ruin diet fluffer shooberino blep aqua doggo, very taste wow very good spot 24 + aqua doggo big ol pupper pupper, long doggo very taste wow borking doggo puggo. Much ruin diet 25 + corgo you are doing me a frighten doing me a frighten, pupperino. Tungg waggy wags porgo heckin 26 + angery woofer ruff smol borking doggo with a long snoot for pats I am bekom fat, noodle horse 27 + thicc porgo many pats very hand that feed shibe, boof stop it fren heckin good boys and girls 28 + length boy super chub. Blop long water shoob puggorino yapper borkf, long woofer blep. I am 29 + bekom fat aqua doggo heck blep doggorino most angery pupper I have ever seen, pupper shoob 30 + floofs. Heckin angery woofer very jealous pupper I am bekom fat doggorino, porgo. Aqua doggo 31 + length boy ruff long bois shooberino, dat tungg tho very taste wow pupper. Clouds many pats doge 32 + heckin snoot, maximum borkdrive wow such tempt you are doin me a concern. Corgo puggorino smol 33 + borking doggo with a long snoot for pats super chub, fat boi h*ck. Dat tungg tho shoob much ruin 34 + diet very jealous pupper, floofs shibe he made many woofs woofer, heckin good boys pupperino.`; 35 + </script> 36 + 37 + # Scroll Area 38 + 39 + ## Example 40 + 41 + <ScrollArea class='h-52 w-96 max-w-full rounded-2xl border border-base-200 dark:border-base-800 text-base-900 dark:text-base-100 bg-base-100 dark:bg-base-900'> 42 + <div class="p-4"> 43 + {content} 44 + </div> 45 + </ScrollArea> 46 + 47 + ## Usage 48 + 49 + ```svelte 50 + <script> 51 + import { ScrollArea } from 'fuchs'; 52 + </script> 53 + 54 + <ScrollArea class="h-52 w-96"> 55 + <div>Your content here</div> 56 + </ScrollArea> 57 + ```
+8
src/routes/(main)/components/base/select/+page.svelte
··· 1 + <script lang="ts"> 2 + import SelectDocs from './Select.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <SelectDocs /> 8 + </Prose>
+7
src/routes/(main)/components/base/select/Example.svelte
··· 1 + <script lang="ts"> 2 + import { Select } from '$lib'; 3 + 4 + let selected = $state('Banana'); 5 + </script> 6 + 7 + <Select bind:selected items={['Apple', 'Orange', 'Banana']} />
+21
src/routes/(main)/components/base/select/Select.md
··· 1 + <script lang="ts"> 2 + import SelectExample from './Example.svelte'; 3 + </script> 4 + 5 + # Select 6 + 7 + ## Example 8 + 9 + <SelectExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { Select } from 'fuchs'; 16 + 17 + let selected = $state('Apple'); 18 + </script> 19 + 20 + <Select bind:selected items={['Apple', 'Orange', 'Banana']} /> 21 + ```
+8
src/routes/(main)/components/base/slider/+page.svelte
··· 1 + <script lang="ts"> 2 + import SliderDocs from './Slider.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <SliderDocs /> 8 + </Prose>
+13
src/routes/(main)/components/base/slider/Example.svelte
··· 1 + <script lang="ts"> 2 + import { Slider } from '$lib'; 3 + import SliderNumber from '$lib/components/base/slider/SliderNumber.svelte'; 4 + 5 + let value = $state(50); 6 + 7 + let value2 = $state(42); 8 + </script> 9 + 10 + <Slider bind:value /> 11 + 12 + <h3>With Number</h3> 13 + <SliderNumber bind:value={value2} />
+24
src/routes/(main)/components/base/slider/Slider.md
··· 1 + <script lang="ts"> 2 + import SliderExample from './Example.svelte'; 3 + </script> 4 + 5 + # Sliders 6 + 7 + ## Example 8 + 9 + <SliderExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script> 15 + import { Slider, SliderNumber } from 'fuchs'; 16 + 17 + let value = $state(50); 18 + </script> 19 + 20 + <Slider bind:value min={0} max={100} /> 21 + 22 + <!-- With Number --> 23 + <SliderNumber bind:value={value} /> 24 + ```
+8
src/routes/(main)/components/base/sonner/+page.svelte
··· 1 + <script lang="ts"> 2 + import SonnerDocs from './Sonner.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <SonnerDocs /> 8 + </Prose>
+67
src/routes/(main)/components/base/sonner/Sonner.md
··· 1 + <script lang="ts"> 2 + import { Button } from '$lib/components/base/button'; 3 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 + import { toast } from 'svelte-sonner'; 5 + </script> 6 + 7 + # Sonner 8 + 9 + ## Example 10 + 11 + <div class="flex flex-wrap gap-4"> 12 + <Button 13 + onclick={() => 14 + toast('Hello there', { 15 + description: 'General Kenobi!' 16 + })}>Default</Button 17 + > 18 + 19 + <Button 20 + variant="green" 21 + onclick={() => 22 + toast.success('Success!', { 23 + description: "You are strong and wise and I'm very proud of you!" 24 + })}>Success</Button 25 + > 26 + <Button 27 + variant="red" 28 + onclick={() => 29 + toast.error('Error!', { 30 + description: 'These are not the droids you are looking for.' 31 + })}>Error</Button 32 + > 33 + <Button 34 + variant="blue" 35 + onclick={() => 36 + toast.info('Info!', { 37 + description: 'I heard spinning is a good trick.' 38 + })}>Info</Button 39 + > 40 + 41 + </div> 42 + 43 + ## Usage 44 + 45 + In your root layout: 46 + 47 + ```svelte 48 + <script> 49 + import { Toaster } from 'fuchs'; 50 + </script> 51 + 52 + <Toaster /> 53 + ``` 54 + 55 + In your page: 56 + 57 + ```svelte 58 + <script> 59 + import { Button, toast } from 'fuchs'; 60 + 61 + function handleClick() { 62 + toast('Hello there', { description: 'General Kenobi!' }); 63 + } 64 + </script> 65 + 66 + <Button onclick={handleClick}>Default</Button> 67 + ```
+8
src/routes/(main)/components/base/switch/+page.svelte
··· 1 + <script lang="ts"> 2 + import SwitchDocs from './Switch.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <SwitchDocs /> 8 + </Prose>
+45
src/routes/(main)/components/base/switch/Switch.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Switch } from '$lib/components/base/switch'; 4 + import { Label } from '$lib/components/base/label'; 5 + import { Text } from '$lib/components/base/text'; 6 + 7 + let checked = $state(false); 8 + 9 + let checked2 = $state(true); 10 + </script> 11 + 12 + # Switch 13 + 14 + ## Example 15 + 16 + <div class="flex flex-col gap-2"> 17 + <Switch bind:checked onCheckedChange={() => (checked2 = !checked2)} /> 18 + <Switch bind:checked={checked2} onCheckedChange={() => (checked = !checked)} /> 19 + <Switch disabled /> 20 + </div> 21 + 22 + With Label 23 + 24 + <div class="flex items-center space-x-2"> 25 + <Switch id="terms-switch" aria-labelledby="terms-switch-label" /> 26 + <Label 27 + id="terms-switch-label" 28 + for="terms-switch" 29 + class="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 30 + > 31 + Yes, I agree to the terms and sell my soul (and no I didn't read the terms) 32 + </Label> 33 + </div> 34 + 35 + ## Usage 36 + 37 + ```svelte 38 + <script> 39 + import { Switch } from 'fuchs'; 40 + 41 + let checked = $state(false); 42 + </script> 43 + 44 + <Switch bind:checked /> 45 + ```
+8
src/routes/(main)/components/base/textarea/+page.svelte
··· 1 + <script lang="ts"> 2 + import TextareaDocs from './Textarea.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <TextareaDocs /> 8 + </Prose>
+37
src/routes/(main)/components/base/textarea/Textarea.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Text } from '$lib/components/base/text'; 4 + import { Textarea } from '$lib/components/base/textarea'; 5 + </script> 6 + 7 + # Textarea 8 + 9 + ## Example 10 + 11 + Primary 12 + 13 + <div class="flex flex-col md:flex-row gap-2"> 14 + <Textarea placeholder="Enter text here (small)" sizeVariant="sm" /> 15 + <Textarea placeholder="Enter text here (default)" /> 16 + <Textarea placeholder="Enter text here (large)" sizeVariant="lg" /> 17 + </div> 18 + 19 + Secondary 20 + 21 + <div class="flex flex-col md:flex-row gap-2"> 22 + <Textarea placeholder="Enter text here (small)" variant="secondary" sizeVariant="sm" /> 23 + <Textarea placeholder="Enter text here (default)" variant="secondary" /> 24 + <Textarea placeholder="Enter text here (large)" variant="secondary" sizeVariant="lg" /> 25 + </div> 26 + 27 + ## Usage 28 + 29 + ```svelte 30 + <script> 31 + import { Textarea } from 'fuchs'; 32 + 33 + let value = $state(''); 34 + </script> 35 + 36 + <Textarea placeholder="Enter text here" bind:value /> 37 + ```
+8
src/routes/(main)/components/base/tooltip/+page.svelte
··· 1 + <script lang="ts"> 2 + import TooltipDocs from './Tooltip.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <TooltipDocs /> 8 + </Prose>
+41
src/routes/(main)/components/base/tooltip/Tooltip.md
··· 1 + <script> 2 + import { Subheading } from '$lib/components/base/heading'; 3 + import { Tooltip } from '$lib/components/base/tooltip'; 4 + import { Text } from '$lib/components/base/text'; 5 + import { Button } from '$lib/components/base/button'; 6 + import { toast } from 'svelte-sonner'; 7 + 8 + function handleClick() { 9 + toast.error('Don\'t click, just hover!') 10 + } 11 + </script> 12 + 13 + # Tooltip 14 + 15 + ## Example 16 + 17 + <div class="flex w-full flex-col items-start gap-2 py-12"> 18 + <Tooltip text="Hello there!" withContext> 19 + {#snippet child({ props })} 20 + <Button {...props} onclick={handleClick}>Hover me</Button> 21 + {/snippet} 22 + </Tooltip> 23 + </div> 24 + 25 + ## Usage 26 + 27 + ```svelte 28 + <script> 29 + import { Tooltip, Button } from 'fuchs'; 30 + 31 + function handleClick() { 32 + console.log('clicked'); 33 + } 34 + </script> 35 + 36 + <Tooltip text="Hello there!" withContext> 37 + {#snippet child({ props })} 38 + <Button {...props} onclick={handleClick}>Hover me</Button> 39 + {/snippet} 40 + </Tooltip> 41 + ```
+8
src/routes/(main)/components/extras/color-gradient-picker/+page.svelte
··· 1 + <script lang="ts"> 2 + import ColorGradientPickerDocs from './ColorGradientPicker.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ColorGradientPickerDocs /> 8 + </Prose>
+26
src/routes/(main)/components/extras/color-gradient-picker/ColorGradientPicker.md
··· 1 + <script lang="ts"> 2 + import ColorGradientPickerExample from './Example.svelte'; 3 + </script> 4 + 5 + # Color Gradient Picker 6 + 7 + ## Example 8 + 9 + <ColorGradientPickerExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import ColorGradientPicker from 'fuchs'; 16 + 17 + let colors = $state([ 18 + { rgb: { r: 0, g: 0, b: 1 }, position: 0 }, // blue 19 + { rgb: { r: 1, g: 0, b: 0 }, position: 0.5 }, // red 20 + { rgb: { r: 1, g: 1, b: 0 }, position: 1 } // yellow 21 + ]); 22 + </script> 23 + 24 + <ColorGradientPicker bind:colors /> 25 + ``` 26 +
+42
src/routes/(main)/components/extras/color-gradient-picker/Example.svelte
··· 1 + <script lang="ts"> 2 + import ColorGradientPicker from '$lib/components/extra/color-gradient-picker/ColorGradientPicker.svelte'; 3 + import type { OKlch } from '$lib/components/extra/color-picker/base/color'; 4 + import { 5 + oklch_string_to_oklch, 6 + oklch_to_rgb 7 + } from '$lib/components/extra/color-picker/base/color'; 8 + import { ThemeWatcher } from '$lib/helper/ThemeWatcher.svelte'; 9 + import { onMount } from 'svelte'; 10 + 11 + let colors = $state([ 12 + { rgb: { r: 0, g: 0, b: 0 }, position: 0 }, 13 + { rgb: { r: 0, g: 0, b: 0 }, position: 0.5 }, 14 + { rgb: { r: 0, g: 0, b: 0 }, position: 1 } 15 + ]); 16 + 17 + onMount(() => { 18 + const theme = new ThemeWatcher(); 19 + const accentColor = theme.getCSSVar('--color-accent-500'); 20 + let oklch = oklch_string_to_oklch(accentColor); 21 + updateColors(oklch); 22 + 23 + theme.subscribe(() => { 24 + const accentColor = theme.getCSSVar('--color-accent-500'); 25 + let oklch = oklch_string_to_oklch(accentColor); 26 + updateColors(oklch); 27 + }); 28 + }); 29 + 30 + function updateColors(theme: OKlch) { 31 + colors = [ 32 + { rgb: { r: 0, g: 0, b: 0 }, position: 0 }, 33 + { rgb: { r: 0, g: 0, b: 0 }, position: 0.5 }, 34 + { rgb: { r: 0, g: 0, b: 0 }, position: 1 } 35 + ]; 36 + colors.forEach((color, index) => { 37 + colors[index].rgb = oklch_to_rgb({ ...theme, h: theme.h + index * 30 }); 38 + }); 39 + } 40 + </script> 41 + 42 + <ColorGradientPicker class="mt-8" bind:colors />
+8
src/routes/(main)/components/extras/color-picker/+page.svelte
··· 1 + <script lang="ts"> 2 + import ColorPickerDocs from './ColorPicker.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ColorPickerDocs /> 8 + </Prose>
+33
src/routes/(main)/components/extras/color-picker/ColorPicker.md
··· 1 + <script lang="ts"> 2 + import ColorPickerExample from './Example.svelte'; 3 + </script> 4 + 5 + # Color Picker 6 + 7 + ## Example 8 + 9 + <ColorPickerExample /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { ColorPicker, PopoverColorPicker } from 'fuchs'; 16 + 17 + let rgb = $state({ 18 + r: 0, 19 + g: 0, 20 + b: 0 21 + }); 22 + </script> 23 + 24 + <!-- inline version --> 25 + <ColorPicker bind:rgb /> 26 + 27 + <!-- popover version --> 28 + <PopoverColorPicker bind:rgb /> 29 + ``` 30 + 31 + ### Credits 32 + 33 + - Adapted from [svelte-color-select](https://github.com/CaptainCodeman/svelte-color-select).
+45
src/routes/(main)/components/extras/color-picker/Example.svelte
··· 1 + <script lang="ts"> 2 + import { ColorPicker } from '$lib/components/extra/color-picker/base'; 3 + import * as Popover from '$lib/components/base/popover'; 4 + import { cn } from '$lib/utils'; 5 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 6 + import Button from '$lib/components/base/button/Button.svelte'; 7 + import PopoverColorPicker from '$lib/components/extra/color-picker/popover/PopoverColorPicker.svelte'; 8 + import { ThemeWatcher } from '$lib/helper/ThemeWatcher.svelte'; 9 + import { hex_to_rgb, oklch_string_to_oklch, oklch_to_rgb } from '$lib/components/extra/color-picker/base/color'; 10 + import { onMount } from 'svelte'; 11 + 12 + let rgb = $state({ 13 + r: 0, 14 + g: 0, 15 + b: 0 16 + }); 17 + 18 + onMount(() => { 19 + const theme = new ThemeWatcher(); 20 + const color = theme.getCSSVar('--color-accent-500'); 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 + }); 27 + }); 28 + </script> 29 + 30 + <h3>Inline Color Picker</h3> 31 + 32 + <ColorPicker bind:rgb /> 33 + 34 + <h3>Popover Color Picker</h3> 35 + 36 + <PopoverColorPicker bind:rgb /> 37 + <!-- 38 + <Button 39 + onclick={() => { 40 + // themewatcher 41 + const theme = new ThemeWatcher(); 42 + const color = theme.getCSSVar('--color-accent-500'); 43 + rgb = oklch_to_rgb(oklch_string_to_oklch(color)); 44 + }}>Reset Color</Button 45 + > -->
+8
src/routes/(main)/components/extras/color-select/+page.svelte
··· 1 + <script lang="ts"> 2 + import ColorSelectDocs from './ColorSelect.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ColorSelectDocs /> 8 + </Prose>
+36
src/routes/(main)/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-red-700', label: 'red' }, 21 + { class: 'text-green-700', label: 'green' }, 22 + { class: 'text-blue-700', label: 'blue' }, 23 + { class: 'text-yellow-700', label: 'yellow' } 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/(main)/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-500', label: '1' }, 8 + { label: '2', value: 'oklch(from var(--color-accent-500) l c calc(h + 20))' }, 9 + { label: '3', value: 'oklch(from var(--color-accent-500) l c calc(h + 40))' }, 10 + { label: '4', value: 'oklch(from var(--color-accent-500) l c calc(h + 60))' }, 11 + ]} 12 + />
+13
src/routes/(main)/components/extras/countdown/+page.svelte
··· 1 + <script lang="ts"> 2 + import type { TimerState } from '$lib'; 3 + import Countdown from '$lib/components/extra/countdown/Countdown.svelte'; 4 + import { onMount } from 'svelte'; 5 + 6 + let timer: TimerState | undefined = $state(); 7 + 8 + onMount(() => { 9 + timer?.start(); 10 + }); 11 + </script> 12 + 13 + <Countdown bind:timer />
+8
src/routes/(main)/components/extras/excalidraw/+page.svelte
··· 1 + <script lang="ts"> 2 + import ExcalidrawDocs from './Excalidraw.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <ExcalidrawDocs /> 8 + </Prose>
+7
src/routes/(main)/components/extras/excalidraw/Example.svelte
··· 1 + <script> 2 + import Excalidraw from '$lib/components/extra/excalidraw/Excalidraw.svelte'; 3 + 4 + import svg from '$docs/assets/demo.svg?raw'; 5 + </script> 6 + 7 + <Excalidraw {svg} alt="Excalidraw Demo" caption="This is a demo of the Excalidraw component." />
+25
src/routes/(main)/components/extras/excalidraw/Excalidraw.md
··· 1 + <script lang="ts"> 2 + import ExcalidrawExample from './Example.svelte'; 3 + </script> 4 + 5 + # Excalidraw 6 + 7 + ## Example 8 + 9 + <ExcalidrawExample /> 10 + 11 + ## Usage 12 + 13 + 1. Draw a diagram in [excalidraw](https://excalidraw.com/) with the default colors and export it as a svg without a background. 14 + 15 + 2. Import that svg and use it with the excalidraw component, colors will be automatically changed to your theme colors. 16 + 17 + ```svelte 18 + <script lang="ts"> 19 + import { Excalidraw } from 'fuchs'; 20 + 21 + import svg from '$docs/assets/demo.svg?raw'; 22 + </script> 23 + 24 + <Excalidraw {svg} alt="Excalidraw Demo" caption="This is a demo of the Excalidraw component." /> 25 + ```
+4
src/routes/(main)/components/extras/pdf-viewer/+page.svelte
··· 1 + <script> 2 + import PdfViewer from "$docs/wip/pdf-viewer/PDFViewer.svelte"; 3 + </script> 4 + <PdfViewer />
+8
src/routes/(main)/components/extras/phone/+page.svelte
··· 1 + <script lang="ts"> 2 + import PhoneDocs from './Phone.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <PhoneDocs /> 8 + </Prose>
+11
src/routes/(main)/components/extras/phone/Example.svelte
··· 1 + <script> 2 + import { Phone } from '$lib'; 3 + </script> 4 + 5 + <Phone> 6 + <div 7 + class="from-accent-200 to-accent-300 flex h-full w-full items-center justify-center bg-gradient-to-b p-8" 8 + > 9 + <div class="text-3xl font-bold text-black">Hello there</div> 10 + </div> 11 + </Phone>
+23
src/routes/(main)/components/extras/phone/Phone.md
··· 1 + <script lang="ts"> 2 + import Example from './Example.svelte'; 3 + </script> 4 + 5 + # Phone 6 + 7 + ## Example 8 + 9 + <Example /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { Phone } from 'fuchs'; 16 + </script> 17 + 18 + <Phone> 19 + <div class="bg-accent-200 flex h-full w-full items-center justify-center p-8"> 20 + <div class="text-3xl font-bold text-black">Hello there</div> 21 + </div> 22 + </Phone> 23 + ```
+8
src/routes/(main)/components/extras/quote/+page.svelte
··· 1 + <script lang="ts"> 2 + import QuoteDocs from './Quote.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <QuoteDocs /> 8 + </Prose>
+15
src/routes/(main)/components/extras/quote/Example.svelte
··· 1 + <script> 2 + import { Quote } from '$lib'; 3 + import einstein from '$docs/assets/images/einstein.png?as=run'; 4 + </script> 5 + 6 + <Quote 7 + quote="Two things are infinite, the universe and the number of javascript frameworks, and I am not yet completely sure about the universe." 8 + author={{ 9 + name: 'Albert Einstein', 10 + role: 'Scientist', 11 + src: einstein, 12 + }} 13 + useThemeColor 14 + class="not-prose" 15 + />
+27
src/routes/(main)/components/extras/quote/Quote.md
··· 1 + <script lang="ts"> 2 + import Example from './Example.svelte'; 3 + </script> 4 + 5 + # Quote 6 + 7 + ## Example 8 + 9 + <Example /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script> 15 + import { Quote } from 'fuchs'; 16 + </script> 17 + 18 + <Quote 19 + quote="Two things are infinite, the universe and the number of javascript frameworks, and I am not yet completely sure about the universe." 20 + author={{ 21 + name: 'Albert Einstein', 22 + role: 'Scientist', 23 + src: './einstein.png', 24 + }} 25 + useThemeColor 26 + /> 27 + ```
+8
src/routes/(main)/components/extras/stopwatch/+page.svelte
··· 1 + <script lang="ts"> 2 + import StopwatchDocs from './Stopwatch.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <StopwatchDocs /> 8 + </Prose>
+27
src/routes/(main)/components/extras/stopwatch/Example.svelte
··· 1 + <script lang="ts"> 2 + import { Box, Button, Stopwatch, StopwatchState } from '$lib'; 3 + import { onMount } from 'svelte'; 4 + 5 + let stopwatch: StopwatchState | undefined = $state(undefined); 6 + 7 + onMount(() => { 8 + stopwatch?.start(); 9 + }); 10 + </script> 11 + 12 + <Box class="min-h-0"> 13 + <Stopwatch bind:stopwatch class="sm:text-7xl" /> 14 + </Box> 15 + 16 + <div class="flex w-full justify-center gap-2 mt-2"> 17 + <Button 18 + onclick={() => { 19 + if (stopwatch?.isRunning) { 20 + stopwatch?.pause(); 21 + } else { 22 + stopwatch?.resume(); 23 + } 24 + }}>{stopwatch?.isRunning ? 'Pause' : 'Start'}</Button 25 + > 26 + <Button onclick={() => stopwatch?.reset()}>Reset</Button> 27 + </div>
+28
src/routes/(main)/components/extras/stopwatch/Stopwatch.md
··· 1 + <script lang="ts"> 2 + import Example from './Example.svelte'; 3 + </script> 4 + 5 + # Stopwatch 6 + 7 + ## Example 8 + 9 + <Example /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { Button, Stopwatch, StopwatchState } from 'fuchs'; 16 + 17 + let stopwatch: StopwatchState | undefined = $state(); 18 + </script> 19 + 20 + <Stopwatch bind:stopwatch /> 21 + 22 + <Button onclick={() => stopwatch?.start()}>Start</Button> 23 + ``` 24 + 25 + ## Credits 26 + 27 + - Stopwatch state based on [svelte-reactive-timer](https://github.com/joshnuss/svelte-reactive-timer) 28 + - Moving numbers component from [number-flow](https://number-flow.barvian.me/)
+49
src/routes/(main)/components/extras/swiper-cards/+page.svelte
··· 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 = [profile1, profile2, profile3, profile4, profile5, profile6, profile7, profile8, profile9, profile10]; 19 + 20 + let swipe: (direction: 'left' | 'right') => void; 21 + </script> 22 + 23 + <div class="h-[70vh] w-full relative"> 24 + <CardSwiper 25 + cardData={(i) => ({ 26 + title: `Card ${i}`, 27 + description: `Card ${i} description`, 28 + image: profiles[i % profiles.length] 29 + })} 30 + bind:swipe 31 + > 32 + </CardSwiper> 33 + 34 + <div class="w-full flex justify-between absolute bottom-2 px-2"> 35 + <Button onclick={() => swipe('left')} size="iconLg"> 36 + <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor" class="size-6"> 37 + <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 38 + </svg> 39 + 40 + 41 + </Button> 42 + <Button onclick={() => swipe('right')} size="iconLg"> 43 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 44 + <path 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" /> 45 + </svg> 46 + 47 + </Button> 48 + </div> 49 + </div>
+8
src/routes/(main)/components/extras/timer/+page.svelte
··· 1 + <script lang="ts"> 2 + import TimerDocs from './Timer.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <TimerDocs /> 8 + </Prose>
+27
src/routes/(main)/components/extras/timer/Example.svelte
··· 1 + <script lang="ts"> 2 + import { Box, Button, Timer, TimerState } from '$lib'; 3 + import { onMount } from 'svelte'; 4 + 5 + let timer: TimerState | undefined = $state(undefined); 6 + 7 + onMount(() => { 8 + timer?.start(); 9 + }); 10 + </script> 11 + 12 + <Box class="min-h-0"> 13 + <Timer bind:timer class="sm:text-7xl" /> 14 + </Box> 15 + 16 + <div class="flex w-full justify-center gap-2 mt-2"> 17 + <Button 18 + onclick={() => { 19 + if (timer?.isRunning) { 20 + timer?.pause(); 21 + } else { 22 + timer?.resume(); 23 + } 24 + }}>{timer?.isRunning ? 'Pause' : 'Start'}</Button 25 + > 26 + <Button onclick={() => timer?.reset()}>Reset</Button> 27 + </div>
+28
src/routes/(main)/components/extras/timer/Timer.md
··· 1 + <script lang="ts"> 2 + import Example from './Example.svelte'; 3 + </script> 4 + 5 + # Timer 6 + 7 + ## Example 8 + 9 + <Example /> 10 + 11 + ## Usage 12 + 13 + ```svelte 14 + <script lang="ts"> 15 + import { Button, Timer, TimerState } from 'fuchs'; 16 + 17 + let timer = $state(new TimerState(1000 * 60 * 60)); 18 + </script> 19 + 20 + <Timer bind:timer /> 21 + 22 + <Button onclick={() => timer.start()}>Start</Button> 23 + ``` 24 + 25 + ## Credits 26 + 27 + - Timer state based on [svelte-reactive-timer](https://github.com/joshnuss/svelte-reactive-timer) 28 + - Moving numbers component from [number-flow](https://number-flow.barvian.me/)
+8
src/routes/(main)/components/extras/undraw/+page.svelte
··· 1 + <script lang="ts"> 2 + import UndrawDocs from './Undraw.md'; 3 + import Prose from '$lib/components/base/prose/Prose.svelte'; 4 + </script> 5 + 6 + <Prose> 7 + <UndrawDocs /> 8 + </Prose>
+19
src/routes/(main)/components/extras/undraw/Example.svelte
··· 1 + <script lang="ts"> 2 + import Undraw from '$lib/components/extra/undraw/Undraw.svelte'; 3 + 4 + import svg from '$docs/assets/undraw_yoga.svg?raw'; 5 + </script> 6 + 7 + <div class="w-full max-w-md mx-auto"> 8 + <Undraw 9 + {svg} 10 + alt="Undraw" 11 + colorMap={{ 12 + '#090814': 'fill-base-950 dark:fill-accent-950', 13 + '#d6d6e3': 'fill-base-300 dark:fill-base-700', 14 + '#cacaca': 'fill-base-400 dark:fill-base-600', 15 + '#cfcce0': 'fill-base-500 dark:fill-base-500', 16 + '#f2f2f2': 'fill-base-200 dark:fill-base-800' 17 + }} 18 + /> 19 + </div>
+42
src/routes/(main)/components/extras/undraw/Undraw.md
··· 1 + <script lang="ts"> 2 + import UndrawExample from './Example.svelte'; 3 + import {Alert} from '$lib'; 4 + </script> 5 + 6 + # Undraw 7 + 8 + ## Example 9 + 10 + <UndrawExample /> 11 + 12 + ## Usage 13 + 14 + <Alert variant="default" type="warning" title="Doesn't work automatically in dark mode"> 15 + <span> 16 + Use the `colorMap` prop to change the colors of the illustration like in the example below to make it work in both light and dark mode. 17 + </span> 18 + </Alert> 19 + 20 + 21 + 1. Download a svg illustration from [undraw](https://undraw.co/illustrations) leaving the theme color as it is (#6c63ff). 22 + 2. Import that svg with the `?raw` extension and use it with the undraw component. The theme color will automatically change to your theme color, all other colors will have to be manually changed using the `colorMap` prop (or if not using dark mode, leave as is). 23 + 24 + ```svelte 25 + <script lang="ts"> 26 + import { Undraw } from 'fuchs'; 27 + 28 + import svg from './your-illustration.svg?raw'; 29 + </script> 30 + 31 + <Undraw 32 + {svg} 33 + alt="Undraw" 34 + colorMap={{ 35 + '#090814': 'fill-base-950 dark:fill-accent-950', 36 + '#d6d6e3': 'fill-base-300 dark:fill-base-700', 37 + '#cacaca': 'fill-base-400 dark:fill-base-600', 38 + '#cfcce0': 'fill-base-500 dark:fill-base-500', 39 + '#f2f2f2': 'fill-base-200 dark:fill-base-800' 40 + }} 41 + /> 42 + ```
+5
src/routes/(main)/components/graphs/heatmap/+page.svelte
··· 1 + <script> 2 + import HeatmapPreview from '$docs/preview/HeatmapPreview.svelte'; 3 + </script> 4 + 5 + <HeatmapPreview />
+5
src/routes/(main)/components/graphs/line-graph/+page.svelte
··· 1 + <script> 2 + import LineGraphPreview from '$docs/preview/LineGraphPreview.svelte'; 3 + </script> 4 + 5 + <LineGraphPreview />
+5
src/routes/(main)/components/graphs/ring-chart/+page.svelte
··· 1 + <script> 2 + import RingChartPreview from '$docs/preview/RingChartPreview.svelte'; 3 + </script> 4 + 5 + <RingChartPreview />
+5
src/routes/(main)/components/social/following-pointer/+page.svelte
··· 1 + <script> 2 + import FollowingPointerPreview from '$docs/preview/FollowingPointerPreview.svelte'; 3 + </script> 4 + 5 + <FollowingPointerPreview />
+5
src/routes/(main)/components/social/github-corner/+page.svelte
··· 1 + <script> 2 + import GithubCornerPreview from '$docs/preview/GithubCornerPreview.svelte'; 3 + </script> 4 + 5 + <GithubCornerPreview />
+5
src/routes/(main)/components/social/post/+page.svelte
··· 1 + <script> 2 + import PostPreview from '$docs/preview/PostPreview.svelte'; 3 + </script> 4 + 5 + <PostPreview />
+5
src/routes/(main)/components/social/social-icons/+page.svelte
··· 1 + <script> 2 + import SocialIconsPreview from '$docs/preview/SocialIconsPreview.svelte'; 3 + </script> 4 + 5 + <SocialIconsPreview />
+5
src/routes/(main)/components/social/star-rating/+page.svelte
··· 1 + <script> 2 + import StarRatingPreview from '$docs/preview/StarRatingPreview.svelte'; 3 + </script> 4 + 5 + <StarRatingPreview />
+8
src/routes/(main)/components/visual/gradient/+page.svelte
··· 1 + <script> 2 + import Gradient from '$lib/components/extra/gradient/Gradient.svelte'; 3 + import Subheading from '$lib/components/base/heading/Subheading.svelte'; 4 + </script> 5 + 6 + <Subheading>Gradient</Subheading> 7 + 8 + <Gradient />