Merge branch 'dev' into release

This commit is contained in:
Fractal-Tess
2024-01-24 07:32:56 +02:00
259 changed files with 8888 additions and 2009 deletions

View File

@@ -5,7 +5,7 @@
"fixed": [], "fixed": [],
"linked": [], "linked": [],
"access": "restricted", "access": "restricted",
"baseBranch": "dev", "baseBranch": "release",
"updateInternalDependencies": "patch", "updateInternalDependencies": "patch",
"ignore": [] "ignore": []
} }

View File

@@ -0,0 +1,5 @@
---
"svelte-tauri": minor
---
Switching ui to shadcn-svelte

View File

@@ -1,38 +1,76 @@
/** @type { import("eslint").Linter.FlatConfig } */
module.exports = { module.exports = {
root: true, root: true,
parser: '@typescript-eslint/parser',
extends: [ extends: [
'eslint:recommended', 'eslint:recommended',
'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended',
'plugin:json/recommended', 'plugin:svelte/recommended',
'prettier' 'prettier'
], ],
rules: { parser: '@typescript-eslint/parser',
'no-unused-vars': 'off', // or "@typescript-eslint/no-unused-vars": "off", plugins: ['@typescript-eslint'],
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_'
}
]
},
plugins: ['svelte3', '@typescript-eslint', 'unused-imports'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: { parserOptions: {
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2020 ecmaVersion: 'latest',
extraFileExtensions: ['.svelte']
}, },
env: { env: {
browser: true, browser: true,
es2017: true, es2024: true,
node: true node: true
} },
}; globals: { $$Generic: 'readable', NodeJS: true },
rules: {
'no-console': 'warn',
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_'
}
],
'svelte/no-target-blank': 'error',
'svelte/no-immutable-reactive-statements': 'error',
'svelte/prefer-style-directive': 'error',
'svelte/no-reactive-literals': 'error',
'svelte/no-useless-mustaches': 'error',
'svelte/button-has-type': 'off',
'svelte/require-each-key': 'off',
'svelte/no-at-html-tags': 'off',
'svelte/no-unused-svelte-ignore': 'off',
'svelte/require-stores-init': 'off'
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
},
rules: {
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^\\$\\$(Props|Events|Slots|Generic)$'
}
]
}
},
{
files: ['*.ts'],
parser: '@typescript-eslint/parser',
rules: {
'@typescript-eslint/ban-types': [
'error',
{
extendDefaults: true,
types: {
'{}': false
}
}
]
}
}
]
}

View File

@@ -5,7 +5,7 @@ on:
jobs: jobs:
publish-tauri: publish-tauri:
runs-on: 'ubuntu-20.04' runs-on: 'ubuntu-22.04'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -22,7 +22,6 @@ jobs:
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: install dependencies (ubuntu only) - name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf

View File

@@ -24,13 +24,13 @@ jobs:
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 18 node-version: 20
- uses: pnpm/action-setup@v2 - uses: pnpm/action-setup@v2
name: Install pnpm name: Install pnpm
id: pnpm-install id: pnpm-install
with: with:
version: 8.5.0 version: 8.10.0
run_install: false run_install: false
- name: Get pnpm store directory - name: Get pnpm store directory

View File

@@ -1,84 +1,13 @@
# v 0.2 .DS_Store
# Minified files node_modules
*.min.*
*.min.*
# Husky
.husky/*
# Git
.gitignore
# Eslint
.eslintignore
# Prettier
.prettierignore
# Markdown files
*.md
# Pnpm
pnpm-lock.yaml
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# Runtime data
pids
*.pid
*.seed
*.pid.lock
## Build files
# Common
build build
release
dist
# Rust
target
# Svelte-Kit
.svelte-kit .svelte-kit
package
.env
.env.*
!.env.example
# Next.js build output # Ignore files for PNPM, NPM and YARN
.next pnpm-lock.yaml
out package-lock.json
yarn.lock
# Nuxt.js build / generate output
.nuxt
dist
# Docusaurus cache and generated files
.docusaurus
# Nodejs packages
node_modules/
# Package Managers
.npm
# Yarn
.yarn-integrity
# Output of 'npm pack'
*.tgz
# Serverless directories
.serverless/
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

12
.prettierrc Normal file
View File

@@ -0,0 +1,12 @@
{
"useTabs": false,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 80,
"arrowParens": "avoid",
"endOfLine": "lf",
"semi": false,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

View File

@@ -1,16 +0,0 @@
module.exports = {
singleQuote: true,
trailingComma: 'none',
printWidth: 80,
svelteStrictMode: false,
svelteAllowShorthand: true,
bracketSameLine: true,
arrowParens: 'avoid',
tabWidth: 2,
useTabs: false,
semi: true,
plugins: ['prettier-plugin-svelte', 'prettier-plugin-tailwindcss'],
overrides: [{ files: '*.svelte', options: { parser: 'svelte' } }],
pluginSearchDirs: ['./'],
endOfLine: 'lf'
};

View File

@@ -1,5 +1,11 @@
# svelte-tauri # svelte-tauri
## 0.1.0
### Minor Changes
- 98b1df2: Switching ui to shadcn-svelte
## 0.0.2 ## 0.0.2
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 Fractal-Tess Copyright (c) 2024 Fractal-Tess
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -4,26 +4,29 @@
<img src="https://raw.githubusercontent.com/Fractal-Tess/Svelte-Tauri/dev/.github/app.jpeg" width="580" style="border-radius:2rem"/> <img src="https://raw.githubusercontent.com/Fractal-Tess/Svelte-Tauri/dev/.github/app.jpeg" width="580" style="border-radius:2rem"/>
</div> </div>
## Overview ## Overview
- Typescript - Typescript
- UI: - UI:
- Snap form
- Tailwind - Tailwind
- DaisyUI - Shedcn-svelte
- Fontawesome - Fontawesome
- Lucide-svelte
- Roboto Font - Roboto Font
- Code Quality - Code Quality
- Prettier - Prettier
- Eslint - Eslint
- Lint-staged
- Tauri - Tauri
- Tauri window state manager plugin - Tauri window state manager plugin
- Tauri store plugin - Tauri store plugin
- Husky - Husky
- Automation - Automation
- Husky - Husky
- Changeset
- TODO: Testing - TODO: Testing
## Requirements
- (optional) - On linux you need to have installed the [mold](https://github.com/rui314/mold) linker. If you prefer not to do that, go ahead and remove the rust flags in the `/src-tauri/.cargo/config.toml` file.
## Requirements
* (optional) - On linux you need to have installed the [mold](https://github.com/rui314/mold) linker. If you prefer not to do that, go ahead and remove the rust flags in the `/src-tauri/.cargo/config.toml` file.

13
components.json Normal file
View File

@@ -0,0 +1,13 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"style": "default",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/styles.postcss",
"baseColor": "zinc"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils"
}
}

View File

@@ -1,12 +1,11 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Svelte-Tauri</title> <title>Svelte-Tauri</title>
</head> </head>
<body> <body id="app">
<div id="app"></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,6 @@
{ {
"name": "svelte-tauri", "name": "svelte-tauri",
"version": "0.0.2", "version": "0.1.0",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@@ -25,52 +25,68 @@
"changeset": "changeset" "changeset": "changeset"
}, },
"lint-staged": { "lint-staged": {
"src/**/*.{js,ts,svelte}": "eslint --cache --fix", "*.{ts,svelte}": [
"src/**/*.{js,ts,svelte,css,scss,postcss,md,json}": "prettier --write --ignore-unknown" "eslint --cache --fix",
"prettier --write --ignore-unknown"
]
}, },
"devDependencies": { "devDependencies": {
"@changesets/cli": "^2.26.1", "@changesets/cli": "^2.27.1",
"@fontsource/roboto": "^4.5.8", "@fontsource/roboto": "^5.0.8",
"@fortawesome/fontawesome-svg-core": "^6.4.0", "@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.4.0", "@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/free-solid-svg-icons": "^6.5.1",
"@sveltejs/vite-plugin-svelte": "^2.2.0", "@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tauri-apps/api": "^1.3.0", "@tauri-apps/api": "^1.5.3",
"@tauri-apps/cli": "^1.3.1", "@tauri-apps/cli": "^1.5.9",
"@tsconfig/svelte": "^4.0.1", "@tsconfig/svelte": "^5.0.2",
"@types/node": "18.15.3", "@types/node": "20.11.5",
"@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^5.59.6", "@typescript-eslint/parser": "^6.19.1",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.17",
"daisyui": "^2.51.6", "eslint": "^8.56.0",
"eslint": "^8.40.0", "eslint-plugin-svelte": "2.35.1",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-json": "^3.1.0", "eslint-plugin-json": "^3.1.0",
"eslint-plugin-svelte3": "^4.0.0", "eslint-plugin-svelte3": "^4.0.0",
"eslint-plugin-unused-imports": "^2.0.0", "eslint-plugin-unused-imports": "^3.0.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"lint-staged": "^13.2.2", "lint-staged": "^15.2.0",
"postcss": "^8.4.23", "postcss": "^8.4.33",
"postcss-load-config": "^4.0.1", "postcss-load-config": "^5.0.2",
"prettier": "^2.8.8", "prettier": "^3.2.4",
"prettier-plugin-svelte": "^2.10.0", "prettier-plugin-svelte": "^3.1.2",
"prettier-plugin-tailwindcss": "^0.3.0", "prettier-plugin-tailwindcss": "^0.5.11",
"svelte": "^3.59.1", "svelte": "^4.2.9",
"svelte-check": "^3.3.2", "svelte-check": "^3.6.3",
"svelte-fa": "^3.0.3", "svelte-fa": "^4.0.2",
"svelte-preprocess": "^5.0.3", "svelte-preprocess": "^5.1.3",
"svelte-spa-router": "^3.3.0", "svelte-spa-router": "^4.0.1",
"tailwindcss": "^3.3.2", "tailwindcss": "^3.4.1",
"tailwindcss-hero-patterns": "^0.1.2", "tailwindcss-hero-patterns": "^0.1.2",
"tslib": "^2.5.1", "tslib": "^2.6.2",
"typescript": "^5.0.4", "typescript": "^5.3.3",
"vite": "^4.3.7" "vite": "^5.0.12",
"@internationalized/date": "^3.5.1",
"bits-ui": "^0.15.1",
"clsx": "^2.1.0",
"cmdk-sv": "^0.0.13",
"embla-carousel-svelte": "8.0.0-rc20",
"formsnap": "^0.4.2",
"lucide-svelte": "^0.314.0",
"mode-watcher": "^0.1.2",
"svelte-sonner": "^0.3.11",
"sveltekit-superforms": "^1.13.4",
"tailwind-merge": "^2.2.1",
"tailwind-variants": "^0.1.20",
"vaul-svelte": "^0.1.0",
"zod": "^3.22.4"
}, },
"packageManager": "pnpm@8.5.0", "packageManager": "pnpm@8.5.0",
"engineStrict": true, "engineStrict": false,
"engines": { "engines": {
"pnpm": ">=8.5.0", "pnpm": ">=8.5.0",
"node": ">18.0.0 <19.0.0" "node": ">20.0.0 <21.0.0"
} }
} }

2520
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
const tailwindcss = require('tailwindcss'); const tailwindcss = require('tailwindcss')
const autoprefixer = require('autoprefixer'); const autoprefixer = require('autoprefixer')
const config = { const config = {
plugins: [ plugins: [
@@ -8,6 +8,6 @@ const config = {
//But others, like autoprefixer, need to run after, //But others, like autoprefixer, need to run after,
autoprefixer autoprefixer
] ]
}; }
module.exports = config; module.exports = config

View File

@@ -1,3 +1,3 @@
[target.x86_64-unknown-linux-gnu] # [target.x86_64-unknown-linux-gnu]
linker = "clang" # linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"] # rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]

2082
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,22 +7,22 @@ license = "MIT"
repository = "https://github.com/Fractal-Tess/Svelte-Tauri" repository = "https://github.com/Fractal-Tess/Svelte-Tauri"
default-run = "svelte-tauri" default-run = "svelte-tauri"
edition = "2021" edition = "2021"
rust-version = "1.68" rust-version = "1.71.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies] [build-dependencies]
tauri-build = { version = "1.3.0", features = [] } tauri-build = { version = "1.5.1", features = [] }
[dependencies] [dependencies]
serde_json = "1.0" serde_json = "1.0.111"
sha2 = "0.10.6" sha2 = "0.10.8"
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0.195", features = ["derive"] }
tauri = { version = "1.2.3", features = ["api-all", "devtools", "updater"] } tauri = { version = "1.5.4", features = ["api-all", "devtools", "updater"] }
thiserror = "1.0.40" thiserror = "1.0.56"
specta = "1.0.4" specta = "1.0.5"
tauri-specta = { version = "1.0.0", features = ["javascript", "typescript"] } tauri-specta = { version = "1.0.2", features = ["javascript", "typescript"] }
[features] [features]
# by default Tauri runs in production mode # by default Tauri runs in production mode
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL

View File

@@ -1,14 +1,16 @@
<script lang="ts"> <script lang="ts">
import { theme } from '$lib/stores/theme'; import Router from '$router/Router.svelte'
import Router from '$lib/router/Router.svelte'; import { ModeWatcher, mode } from 'mode-watcher'
import BaseLayout from '$lib/layout/BaseLayout.svelte'; import Header from '$lib/components/HeaderNav.svelte'
import { Toaster } from 'svelte-sonner'
$: {
document.documentElement.setAttribute('data-theme', $theme);
document.documentElement.classList.value = $theme;
}
</script> </script>
<BaseLayout> <ModeWatcher defaultMode="dark" />
<Router /> <Toaster theme={$mode} />
</BaseLayout>
<div class="relative flex flex-col h-screen" data-vaul-drawer-wrapper id="page">
<Header />
<main class="flex-1">
<Router />
</main>
</div>

View File

@@ -0,0 +1,83 @@
<script lang="ts">
import { appWindow } from '@tauri-apps/api/window'
import { faXmark, faWindowMinimize } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import Fa from 'svelte-fa'
import { link } from 'svelte-spa-router'
import { Button } from '$components/ui/button'
import { Sun, Moon } from 'lucide-svelte'
import { toggleMode } from 'mode-watcher'
import { cn } from '$lib/utils'
import { location } from 'svelte-spa-router'
// You can structure your links however you'd like, but I like to keep them in an array of objects
type Link = {
label: string
href: string
}
const links: Link[] = [
{
label: 'Home',
href: '/'
},
{
label: 'IPC',
href: '/#IPC'
},
{
label: 'Versions',
href: '/#versions'
}
]
</script>
<header
data-tauri-drag-region
class="flex h-14 items-center justify-between bg-base-100 shadow-lg sticky top-0 z-50 border-b
border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
>
<Button on:click={toggleMode} size="icon" variant="outline" class="ml-2">
<Sun
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<Moon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button>
<nav
class="flex space-x-4 text-xl font-bold select-none"
on:dragstart|preventDefault
>
{#each links as { href, label }}
<a
use:link
{href}
class={cn(
'transition-colors hover:text-foreground/80',
href === $location ? '' : 'text-foreground/60'
)}>{label}</a
>
{/each}
</nav>
<div class="flex h-full [&>*]:px-2 [&>*]:transition-all">
<a
on:dragstart|preventDefault
target="_blank"
href="https://github.com/Fractal-Tess/Svelte-Tauri"
class="flex items-center hover:text-secondary"
rel="noreferrer noopener"
>
<Fa icon={faGithub} size="lg" />
</a>
<button on:click={appWindow.minimize} class="text-xl hover:text-secondary">
<Fa icon={faWindowMinimize} />
</button>
<button on:click={appWindow.close} class="text-2xl hover:text-secondary">
<Fa icon={faXmark} />
</button>
</div>
</header>

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import { Button } from '$components/ui/button'
import { helloTauri } from '$lib/ipc'
import { cn } from '$lib/utils'
let message = ''
async function callTauri() {
message = await helloTauri()
}
</script>
<Button variant="outline" class="px-8 py-6" on:click={callTauri}
>Call Tauri</Button
>
<p
class={cn(
'text-2xl font-bold border-b-2 border-border transition-opacity min-h-10 duration-500',
message ? 'opacity-100' : 'opacity-0'
)}
>
{message}
</p>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { Input } from '$components/ui/input'
import { Label } from '$components/ui/label'
import { hash256sum } from '$lib/ipc'
let hashInput = 'String to hash'
let hashOutput = ''
$: hash256sum(hashInput).then(hash => (hashOutput = hash))
</script>
<section class="flex items-center justify-center flex-col gap-8">
<div class="flex flex-col w-full max-w-sm gap-1.5">
<Label for="hash">Hash string</Label>
<Input
placeholder="String to hash"
id="hash"
bind:value={hashInput}
type="text"
class="input-bordered input-secondary input focus:border-secondary
focus:outline-none focus:ring-secondary"
/>
</div>
<code class="border border-border rounded-md px-2 py-1 text-sm"
>{hashOutput}</code
>
</section>

View File

@@ -0,0 +1,56 @@
<script lang="ts">
import { storeReadKey, storeSetKey } from '$lib/ipc'
import { Input } from '$components/ui/input'
import { Label } from '$components/ui/label'
import { Button } from '$components/ui/button'
import { toast } from 'svelte-sonner'
let key = ''
let val = ''
async function setValueWithKey() {
await storeSetKey(key, val)
let id = (Math.random() + 1).toString(36).substring(16)
toast(`You have set the key '${key}' to be the value of '${val}'`, {
id,
action: {
label: 'X',
onClick: () => {
toast.dismiss(id)
}
}
})
}
async function readValFromKey() {
const val = await storeReadKey(key)
let id = (Math.random() + 1).toString(36).substring(16)
toast(`You have read the key '${key}' to be the value of '${val}'`, {
id,
action: {
label: 'X',
onClick: () => {
toast.dismiss(id)
}
}
})
}
</script>
<div class="flex flex-col gap-4 items-center justify-center">
<div class="flex gap-4">
<div class="flex-1 flex-col gap-y-2 flex">
<Label for="key">Key</Label>
<Input id="key" bind:value={key} />
</div>
<div class="flex-1 flex-col gap-y-2 flex">
<Label for="val">Value</Label>
<Input id="val" bind:value={val} />
</div>
</div>
<div class="flex w-full gap-4">
<Button class="w-full bg-primary" on:click={setValueWithKey}>Set</Button>
<Button class="w-full" on:click={readValFromKey}>Read</Button>
</div>
</div>

View File

@@ -1,28 +0,0 @@
<script lang="ts">
import type { Theme } from '$types';
export let theme: Theme = 'dark';
</script>
<div
class="{`${
theme === 'dark' ? 'swap-active' : 'swap-off'
} swap swap-rotate`} h-8 w-8"
>
<svg
class="swap-on fill-current h-full w-full"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"
/></svg
>
<svg
class="swap-off fill-current h-full w-full"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"
/></svg
>
</div>

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
import { slide } from 'svelte/transition'
type $$Props = AccordionPrimitive.ContentProps
let className: $$Props['class'] = undefined
export let transition: $$Props['transition'] = slide
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 200
}
export { className as class }
</script>
<AccordionPrimitive.Content
class={cn('overflow-hidden text-sm transition-all', className)}
{transition}
{transitionConfig}
{...$$restProps}
>
<div class="pb-4 pt-0">
<slot />
</div>
</AccordionPrimitive.Content>

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AccordionPrimitive.ItemProps
let className: $$Props['class'] = undefined
export let value: $$Props['value']
export { className as class }
</script>
<AccordionPrimitive.Item
{value}
class={cn('border-b', className)}
{...$$restProps}
>
<slot />
</AccordionPrimitive.Item>

View File

@@ -0,0 +1,26 @@
<script lang="ts">
import { Accordion as AccordionPrimitive } from 'bits-ui'
import { ChevronDown } from 'lucide-svelte'
import { cn } from '$lib/utils'
type $$Props = AccordionPrimitive.TriggerProps
type $$Events = AccordionPrimitive.TriggerEvents
let className: $$Props['class'] = undefined
export let level: AccordionPrimitive.HeaderProps['level'] = 3
export { className as class }
</script>
<AccordionPrimitive.Header {level} class="flex">
<AccordionPrimitive.Trigger
class={cn(
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
className
)}
{...$$restProps}
on:click
>
<slot />
<ChevronDown class="h-4 w-4 transition-transform duration-200" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>

View File

@@ -0,0 +1,17 @@
import { Accordion as AccordionPrimitive } from 'bits-ui'
import Content from './accordion-content.svelte'
import Item from './accordion-item.svelte'
import Trigger from './accordion-trigger.svelte'
const Root = AccordionPrimitive.Root
export {
Root,
Content,
Item,
Trigger,
//
Root as Accordion,
Content as AccordionContent,
Item as AccordionItem,
Trigger as AccordionTrigger
}

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import { buttonVariants } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
type $$Props = AlertDialogPrimitive.ActionProps
type $$Events = AlertDialogPrimitive.ActionEvents
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AlertDialogPrimitive.Action
class={cn(buttonVariants(), className)}
{...$$restProps}
on:click
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Action>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import { buttonVariants } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
type $$Props = AlertDialogPrimitive.CancelProps
type $$Events = AlertDialogPrimitive.CancelEvents
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AlertDialogPrimitive.Cancel
class={cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className)}
{...$$restProps}
on:click
on:keydown
let:builder
>
<slot {builder} />
</AlertDialogPrimitive.Cancel>

View File

@@ -0,0 +1,28 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import * as AlertDialog from '.'
import { cn, flyAndScale } from '$lib/utils'
type $$Props = AlertDialogPrimitive.ContentProps
export let transition: $$Props['transition'] = flyAndScale
export let transitionConfig: $$Props['transitionConfig'] = undefined
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AlertDialog.Portal>
<AlertDialog.Overlay />
<AlertDialogPrimitive.Content
{transition}
{transitionConfig}
class={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg md:w-full',
className
)}
{...$$restProps}
>
<slot />
</AlertDialogPrimitive.Content>
</AlertDialog.Portal>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AlertDialogPrimitive.DescriptionProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AlertDialogPrimitive.Description
class={cn('text-sm text-muted-foreground', className)}
{...$$restProps}
>
<slot />
</AlertDialogPrimitive.Description>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div
class={cn(
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
className
)}
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div
class={cn('flex flex-col space-y-2 text-center sm:text-left', className)}
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
import { fade } from 'svelte/transition'
type $$Props = AlertDialogPrimitive.OverlayProps
let className: $$Props['class'] = undefined
export let transition: $$Props['transition'] = fade
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 150
}
export { className as class }
</script>
<AlertDialogPrimitive.Overlay
{transition}
{transitionConfig}
class={cn('fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ', className)}
{...$$restProps}
/>

View File

@@ -0,0 +1,9 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
type $$Props = AlertDialogPrimitive.PortalProps
</script>
<AlertDialogPrimitive.Portal {...$$restProps}>
<slot />
</AlertDialogPrimitive.Portal>

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AlertDialogPrimitive.TitleProps
let className: $$Props['class'] = undefined
export let level: $$Props['level'] = 'h3'
export { className as class }
</script>
<AlertDialogPrimitive.Title
class={cn('text-lg font-semibold', className)}
{level}
{...$$restProps}
>
<slot />
</AlertDialogPrimitive.Title>

View File

@@ -0,0 +1,40 @@
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'
const Root = AlertDialogPrimitive.Root
const Trigger = AlertDialogPrimitive.Trigger
import Title from './alert-dialog-title.svelte'
import Action from './alert-dialog-action.svelte'
import Cancel from './alert-dialog-cancel.svelte'
import Portal from './alert-dialog-portal.svelte'
import Footer from './alert-dialog-footer.svelte'
import Header from './alert-dialog-header.svelte'
import Overlay from './alert-dialog-overlay.svelte'
import Content from './alert-dialog-content.svelte'
import Description from './alert-dialog-description.svelte'
export {
Root,
Title,
Action,
Cancel,
Portal,
Footer,
Header,
Trigger,
Overlay,
Content,
Description,
//
Root as AlertDialog,
Title as AlertDialogTitle,
Action as AlertDialogAction,
Cancel as AlertDialogCancel,
Portal as AlertDialogPortal,
Footer as AlertDialogFooter,
Header as AlertDialogHeader,
Trigger as AlertDialogTrigger,
Overlay as AlertDialogOverlay,
Content as AlertDialogContent,
Description as AlertDialogDescription
}

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div class={cn('text-sm [&_p]:leading-relaxed', className)} {...$$restProps}>
<slot />
</div>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
import type { HeadingLevel } from '.'
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
level?: HeadingLevel
}
let className: $$Props['class'] = undefined
export let level: $$Props['level'] = 'h5'
export { className as class }
</script>
<svelte:element
this={level}
class={cn('mb-1 font-medium leading-none tracking-tight', className)}
{...$$restProps}
>
<slot />
</svelte:element>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
import { alertVariants, type Variant } from '.'
type $$Props = HTMLAttributes<HTMLDivElement> & {
variant?: Variant
}
let className: $$Props['class'] = undefined
export let variant: $$Props['variant'] = 'default'
export { className as class }
</script>
<div
class={cn(alertVariants({ variant }), className)}
{...$$restProps}
role="alert"
>
<slot />
</div>

View File

@@ -0,0 +1,33 @@
import { tv, type VariantProps } from 'tailwind-variants'
import Root from './alert.svelte'
import Description from './alert-description.svelte'
import Title from './alert-title.svelte'
export const alertVariants = tv({
base: 'relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11',
variants: {
variant: {
default: 'bg-background text-foreground',
destructive:
'text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive'
}
},
defaultVariants: {
variant: 'default'
}
})
export type Variant = VariantProps<typeof alertVariants>['variant']
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
export {
Root,
Description,
Title,
//
Root as Alert,
Description as AlertDescription,
Title as AlertTitle
}

View File

@@ -0,0 +1,11 @@
<script lang="ts">
import { AspectRatio as AspectRatioPrimitive } from 'bits-ui'
type $$Props = AspectRatioPrimitive.Props
export let ratio: $$Props['ratio'] = 4 / 3
</script>
<AspectRatioPrimitive.Root {ratio} {...$$restProps}>
<slot />
</AspectRatioPrimitive.Root>

View File

@@ -0,0 +1,3 @@
import Root from './aspect-ratio.svelte'
export { Root, Root as AspectRatio }

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AvatarPrimitive.FallbackProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<AvatarPrimitive.Fallback
class={cn(
'flex h-full w-full items-center justify-center rounded-full bg-muted',
className
)}
{...$$restProps}
>
<slot />
</AvatarPrimitive.Fallback>

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AvatarPrimitive.ImageProps
let className: $$Props['class'] = undefined
export let src: $$Props['src'] = undefined
export let alt: $$Props['alt'] = undefined
export { className as class }
</script>
<AvatarPrimitive.Image
{src}
{alt}
class={cn('aspect-square h-full w-full', className)}
{...$$restProps}
/>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { Avatar as AvatarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = AvatarPrimitive.Props
let className: $$Props['class'] = undefined
export let delayMs: $$Props['delayMs'] = undefined
export { className as class }
</script>
<AvatarPrimitive.Root
{delayMs}
class={cn(
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
className
)}
{...$$restProps}
>
<slot />
</AvatarPrimitive.Root>

View File

@@ -0,0 +1,13 @@
import Root from './avatar.svelte'
import Image from './avatar-image.svelte'
import Fallback from './avatar-fallback.svelte'
export {
Root,
Image,
Fallback,
//
Root as Avatar,
Image as AvatarImage,
Fallback as AvatarFallback
}

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { cn } from '$lib/utils'
import { badgeVariants, type Variant } from '.'
let className: string | undefined | null = undefined
export let href: string | undefined = undefined
export let variant: Variant = 'default'
export { className as class }
</script>
<svelte:element
this={href ? 'a' : 'span'}
{href}
class={cn(badgeVariants({ variant, className }))}
{...$$restProps}
>
<slot />
</svelte:element>

View File

@@ -0,0 +1,22 @@
import { tv, type VariantProps } from 'tailwind-variants'
export { default as Badge } from './badge.svelte'
export const badgeVariants = tv({
base: 'inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none select-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
variants: {
variant: {
default:
'bg-primary hover:bg-primary/80 border-transparent text-primary-foreground',
secondary:
'bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground',
destructive:
'bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground',
outline: 'text-foreground'
}
},
defaultVariants: {
variant: 'default'
}
})
export type Variant = VariantProps<typeof badgeVariants>['variant']

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { Button as ButtonPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
import { buttonVariants, type Props, type Events } from '.'
type $$Props = Props
type $$Events = Events
let className: $$Props['class'] = undefined
export let variant: $$Props['variant'] = 'default'
export let size: $$Props['size'] = 'default'
export let builders: $$Props['builders'] = []
export { className as class }
</script>
<ButtonPrimitive.Root
{builders}
class={cn(buttonVariants({ variant, size, className }))}
type="button"
{...$$restProps}
on:click
on:keydown
>
<slot />
</ButtonPrimitive.Root>

View File

@@ -0,0 +1,50 @@
import Root from './button.svelte'
import { tv, type VariantProps } from 'tailwind-variants'
import type { Button as ButtonPrimitive } from 'bits-ui'
const buttonVariants = tv({
base: 'inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline'
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10'
}
},
defaultVariants: {
variant: 'default',
size: 'default'
}
})
type Variant = VariantProps<typeof buttonVariants>['variant']
type Size = VariantProps<typeof buttonVariants>['size']
type Props = ButtonPrimitive.Props & {
variant?: Variant
size?: Size
}
type Events = ButtonPrimitive.Events
export {
Root,
type Props,
type Events,
//
Root as Button,
type Props as ButtonProps,
type Events as ButtonEvents,
buttonVariants
}

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.CellProps
export let date: $$Props['date']
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Cell
{date}
class={cn(
'relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:bg-accent first:[&:has([data-selected])]:rounded-l-md last:[&:has([data-selected])]:rounded-r-md [&:has([data-selected][data-outside-month])]:bg-accent/50',
className
)}
{...$$restProps}
>
<slot />
</CalendarPrimitive.Cell>

View File

@@ -0,0 +1,42 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { buttonVariants } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.DayProps
type $$Events = CalendarPrimitive.DayEvents
export let date: $$Props['date']
export let month: $$Props['month']
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Day
on:click
{date}
{month}
class={cn(
buttonVariants({ variant: 'ghost' }),
'h-9 w-9 p-0 font-normal ',
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',
// Selected
'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
// Disabled
'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
// Unavailable
'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',
// Outside months
'data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30',
className
)}
{...$$restProps}
let:selected
let:disabled
let:unavailable
let:builder
>
<slot {selected} {disabled} {unavailable} {builder}>
{date.day}
</slot>
</CalendarPrimitive.Day>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.GridBodyProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.GridBody class={cn(className)} {...$$restProps}>
<slot />
</CalendarPrimitive.GridBody>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.GridHeadProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.GridHead class={cn(className)} {...$$restProps}>
<slot />
</CalendarPrimitive.GridHead>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.GridRowProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.GridRow class={cn('flex', className)} {...$$restProps}>
<slot />
</CalendarPrimitive.GridRow>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.GridProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Grid
class={cn('w-full border-collapse space-y-1', className)}
{...$$restProps}
>
<slot />
</CalendarPrimitive.Grid>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.HeadCellProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.HeadCell
class={cn(
'w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground',
className
)}
{...$$restProps}
>
<slot />
</CalendarPrimitive.HeadCell>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.HeaderProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Header
class={cn(
'relative flex w-full items-center justify-between pt-1',
className
)}
{...$$restProps}
>
<slot />
</CalendarPrimitive.Header>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.HeadingProps
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Heading
let:headingValue
class={cn('text-sm font-medium', className)}
{...$$restProps}
>
<slot {headingValue}>
{headingValue}
</slot>
</CalendarPrimitive.Heading>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div
class={cn(
'mt-4 flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0',
className
)}
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { ChevronRight } from 'lucide-svelte'
import { buttonVariants } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.NextButtonProps
type $$Events = CalendarPrimitive.NextButtonEvents
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.NextButton
on:click
class={cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
className
)}
{...$$restProps}
let:builder
>
<slot {builder}>
<ChevronRight class="h-4 w-4" />
</slot>
</CalendarPrimitive.NextButton>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import { ChevronLeft } from 'lucide-svelte'
import { buttonVariants } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.PrevButtonProps
type $$Events = CalendarPrimitive.PrevButtonEvents
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.PrevButton
on:click
class={cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
className
)}
{...$$restProps}
let:builder
>
<slot {builder}>
<ChevronLeft class="h-4 w-4" />
</slot>
</CalendarPrimitive.PrevButton>

View File

@@ -0,0 +1,59 @@
<script lang="ts">
import { Calendar as CalendarPrimitive } from 'bits-ui'
import * as Calendar from '.'
import { cn } from '$lib/utils'
type $$Props = CalendarPrimitive.Props
type $$Events = CalendarPrimitive.Events
export let value: $$Props['value'] = undefined
export let placeholder: $$Props['placeholder'] = undefined
export let weekdayFormat: $$Props['weekdayFormat'] = 'short'
let className: $$Props['class'] = undefined
export { className as class }
</script>
<CalendarPrimitive.Root
bind:value
bind:placeholder
{weekdayFormat}
class={cn('p-3', className)}
{...$$restProps}
on:keydown
let:months
let:weekdays
>
<Calendar.Header>
<Calendar.PrevButton />
<Calendar.Heading />
<Calendar.NextButton />
</Calendar.Header>
<Calendar.Months>
{#each months as month}
<Calendar.Grid>
<Calendar.GridHead>
<Calendar.GridRow class="flex">
{#each weekdays as weekday}
<Calendar.HeadCell>
{weekday.slice(0, 2)}
</Calendar.HeadCell>
{/each}
</Calendar.GridRow>
</Calendar.GridHead>
<Calendar.GridBody>
{#each month.weeks as weekDates}
<Calendar.GridRow class="mt-2 w-full">
{#each weekDates as date}
<Calendar.Cell {date}>
<Calendar.Day {date} month={month.value} />
</Calendar.Cell>
{/each}
</Calendar.GridRow>
{/each}
</Calendar.GridBody>
</Calendar.Grid>
{/each}
</Calendar.Months>
</CalendarPrimitive.Root>

View File

@@ -0,0 +1,30 @@
import Root from './calendar.svelte'
import Cell from './calendar-cell.svelte'
import Day from './calendar-day.svelte'
import Grid from './calendar-grid.svelte'
import Header from './calendar-header.svelte'
import Months from './calendar-months.svelte'
import GridRow from './calendar-grid-row.svelte'
import Heading from './calendar-heading.svelte'
import GridBody from './calendar-grid-body.svelte'
import GridHead from './calendar-grid-head.svelte'
import HeadCell from './calendar-head-cell.svelte'
import NextButton from './calendar-next-button.svelte'
import PrevButton from './calendar-prev-button.svelte'
export {
Day,
Cell,
Grid,
Header,
Months,
GridRow,
Heading,
GridBody,
GridHead,
HeadCell,
NextButton,
PrevButton,
//
Root as Calendar
}

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div class={cn('p-6 pt-0', className)} {...$$restProps}>
<slot />
</div>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
type $$Props = HTMLAttributes<HTMLParagraphElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<p class={cn('text-sm text-muted-foreground', className)} {...$$restProps}>
<slot />
</p>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div class={cn('flex items-center p-6 pt-0', className)} {...$$restProps}>
<slot />
</div>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div class={cn('flex flex-col space-y-1.5 p-6', className)} {...$$restProps}>
<slot />
</div>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
import type { HeadingLevel } from '.'
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
tag?: HeadingLevel
}
let className: $$Props['class'] = undefined
export let tag: $$Props['tag'] = 'h3'
export { className as class }
</script>
<svelte:element
this={tag}
class={cn('text-lg font-semibold leading-none tracking-tight', className)}
{...$$restProps}
>
<slot />
</svelte:element>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements'
import { cn } from '$lib/utils'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: $$Props['class'] = undefined
export { className as class }
</script>
<div
class={cn(
'rounded-lg border bg-card text-card-foreground shadow-sm',
className
)}
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,24 @@
import Root from './card.svelte'
import Content from './card-content.svelte'
import Description from './card-description.svelte'
import Footer from './card-footer.svelte'
import Header from './card-header.svelte'
import Title from './card-title.svelte'
export {
Root,
Content,
Description,
Footer,
Header,
Title,
//
Root as Card,
Content as CardContent,
Description as CardDescription,
Footer as CardFooter,
Header as CardHeader,
Title as CardTitle
}
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'

View File

@@ -0,0 +1,26 @@
<script lang="ts">
import { cn } from '$lib/utils.js'
import type { HTMLAttributes } from 'svelte/elements'
import { getEmblaContext } from './context.js'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: string | undefined | null = undefined
export { className as class }
const { orientation } = getEmblaContext('<Carousel.Content/>')
</script>
<div class="overflow-hidden">
<div
class={cn(
'flex',
$orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
className
)}
data-embla-container=""
{...$$restProps}
>
<slot />
</div>
</div>

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
import { getEmblaContext } from './context.js'
type $$Props = HTMLAttributes<HTMLDivElement>
let className: string | undefined | null = undefined
export { className as class }
const { orientation } = getEmblaContext('<Carousel.Item/>')
</script>
<div
role="group"
aria-roledescription="slide"
class={cn(
'min-w-0 shrink-0 grow-0 basis-full',
$orientation === 'horizontal' ? 'pl-4' : 'pt-4',
className
)}
data-embla-slide=""
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,39 @@
<script lang="ts">
import {
Button,
type Props,
buttonVariants
} from '$lib/components/ui/button/index.js'
import { cn } from '$lib/utils'
import { ArrowRight } from 'lucide-svelte'
import type { VariantProps } from 'tailwind-variants'
import { getEmblaContext } from './context.js'
type $$Props = Props
let className: $$Props['class'] = undefined
export { className as class }
export let variant: VariantProps<typeof buttonVariants>['variant'] = 'outline'
export let size: VariantProps<typeof buttonVariants>['size'] = 'icon'
const { orientation, canScrollNext, scrollNext, handleKeyDown } =
getEmblaContext('<Carousel.Next/>')
</script>
<Button
{variant}
{size}
class={cn(
'absolute h-8 w-8 rounded-full',
$orientation === 'horizontal'
? '-right-12 top-1/2 -translate-y-1/2'
: '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
className
)}
disabled={!$canScrollNext}
on:click={scrollNext}
on:keydown={handleKeyDown}
{...$$restProps}
>
<ArrowRight class="h-4 w-4" />
<span class="sr-only">Next slide</span>
</Button>

View File

@@ -0,0 +1,40 @@
<script lang="ts">
import {
Button,
type Props,
buttonVariants
} from '$lib/components/ui/button/index.js'
import { cn } from '$lib/utils.js'
import { ArrowLeft } from 'lucide-svelte'
import type { VariantProps } from 'tailwind-variants'
import { getEmblaContext } from './context.js'
type $$Props = Props
let className: $$Props['class'] = undefined
export { className as class }
export let variant: VariantProps<typeof buttonVariants>['variant'] = 'outline'
export let size: VariantProps<typeof buttonVariants>['size'] = 'icon'
const { orientation, canScrollPrev, scrollPrev, handleKeyDown } =
getEmblaContext('<Carousel.Previous/>')
</script>
<Button
{variant}
{size}
class={cn(
'absolute h-8 w-8 rounded-full',
$orientation === 'horizontal'
? '-left-12 top-1/2 -translate-y-1/2'
: '-top-12 left-1/2 -translate-x-1/2 rotate-90',
className
)}
disabled={!$canScrollPrev}
on:click={scrollPrev}
on:keydown={handleKeyDown}
{...$$restProps}
>
<ArrowLeft class="h-4 w-4" />
<span class="sr-only">Previous slide</span>
</Button>

View File

@@ -0,0 +1,98 @@
<script lang="ts">
import emblaCarouselSvelte from 'embla-carousel-svelte'
import {
setEmblaContex,
type CarouselProps,
type CarouselAPI
} from './context.js'
import { cn } from '$lib/utils.js'
import { writable } from 'svelte/store'
import { onDestroy } from 'svelte'
type $$Props = CarouselProps
export let opts = {}
export let plugins: NonNullable<$$Props['plugins']> = []
export let api: $$Props['api'] = undefined
export let orientation: NonNullable<$$Props['orientation']> = 'horizontal'
let className: $$Props['class'] = undefined
export { className as class }
const apiStore = writable<CarouselAPI | undefined>(undefined)
const orientationStore = writable(orientation)
const canScrollPrev = writable(false)
const canScrollNext = writable(false)
$: orientationStore.set(orientation)
function scrollPrev() {
api?.scrollPrev()
}
function scrollNext() {
api?.scrollNext()
}
function onSelect(api: CarouselAPI) {
if (!api) return
canScrollPrev.set(api.canScrollPrev())
canScrollNext.set(api.canScrollNext())
}
$: if (api) {
onSelect(api)
api.on('select', onSelect)
api.on('reInit', onSelect)
}
function handleKeyDown(e: KeyboardEvent) {
if (e.key === 'ArrowLeft') {
e.preventDefault()
scrollPrev()
} else if (e.key === 'ArrowRight') {
e.preventDefault()
scrollNext()
}
}
setEmblaContex({
api: apiStore,
scrollPrev,
scrollNext,
orientation: orientationStore,
canScrollNext,
canScrollPrev,
handleKeyDown
})
function onInit(event: CustomEvent<CarouselAPI>) {
api = event.detail
console.log(api.slideNodes())
apiStore.set(api)
}
onDestroy(() => {
api?.off('select', onSelect)
})
</script>
<div
class={cn('relative', className)}
use:emblaCarouselSvelte={{
options: {
container: '[data-embla-container]',
slides: '[data-embla-slide]',
...opts,
axis: $orientationStore === 'horizontal' ? 'x' : 'y'
},
plugins
}}
on:emblaInit={onInit}
on:mouseenter
on:mouseleave
role="region"
aria-roledescription="carousel"
{...$$restProps}
>
<slot />
</div>

View File

@@ -0,0 +1,52 @@
import type { EmblaCarouselSvelteType } from 'embla-carousel-svelte'
import type emblaCarouselSvelte from 'embla-carousel-svelte'
import { getContext, hasContext, setContext } from 'svelte'
import type { HTMLAttributes } from 'svelte/elements'
import type { Writable, Readable } from 'svelte/store'
export type CarouselAPI =
NonNullable<
NonNullable<EmblaCarouselSvelteType['$$_attributes']>['on:emblaInit']
> extends (evt: CustomEvent<infer CarouselAPI>) => void
? CarouselAPI
: never
type EmblaCarouselConfig = NonNullable<
Parameters<typeof emblaCarouselSvelte>[1]
>
export type CarouselOptions = EmblaCarouselConfig['options']
export type CarouselPlugins = EmblaCarouselConfig['plugins']
////
export type CarouselProps = {
opts?: CarouselOptions
plugins?: CarouselPlugins
api?: CarouselAPI
orientation?: 'horizontal' | 'vertical'
} & HTMLAttributes<HTMLDivElement>
const EMBLA_CAROUSEL_CONTEXT = Symbol('EMBLA_CAROUSEL_CONTEXT')
type EmblaContext = {
api: Writable<CarouselAPI | undefined>
orientation: Writable<'horizontal' | 'vertical'>
scrollNext: () => void
scrollPrev: () => void
canScrollNext: Readable<boolean>
canScrollPrev: Readable<boolean>
handleKeyDown: (e: KeyboardEvent) => void
}
export function setEmblaContex(config: EmblaContext): EmblaContext {
setContext(EMBLA_CAROUSEL_CONTEXT, config)
return config
}
export function getEmblaContext(name = 'This component') {
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
throw new Error(`${name} must be used within a <Carousel.Root> component`)
}
return getContext<ReturnType<typeof setEmblaContex>>(EMBLA_CAROUSEL_CONTEXT)
}

View File

@@ -0,0 +1,5 @@
export { default as Root } from './carousel.svelte'
export { default as Content } from './carousel-content.svelte'
export { default as Item } from './carousel-item.svelte'
export { default as Previous } from './carousel-previous.svelte'
export { default as Next } from './carousel-next.svelte'

View File

@@ -0,0 +1,34 @@
<script lang="ts">
import { Checkbox as CheckboxPrimitive } from 'bits-ui'
import { Check, Minus } from 'lucide-svelte'
import { cn } from '$lib/utils'
type $$Props = CheckboxPrimitive.Props
type $$Events = CheckboxPrimitive.Events
let className: $$Props['class'] = undefined
export let checked: $$Props['checked'] = false
export { className as class }
</script>
<CheckboxPrimitive.Root
class={cn(
'peer box-content h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:opacity-50',
className
)}
bind:checked
{...$$restProps}
on:click
>
<CheckboxPrimitive.Indicator
class={cn('flex h-4 w-4 items-center justify-center text-current')}
let:isChecked
let:isIndeterminate
>
{#if isChecked}
<Check class="h-3.5 w-3.5" />
{:else if isIndeterminate}
<Minus class="h-3.5 w-3.5" />
{/if}
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>

View File

@@ -0,0 +1,6 @@
import Root from './checkbox.svelte'
export {
Root,
//
Root as Checkbox
}

View File

@@ -0,0 +1,15 @@
<script lang="ts">
import { Collapsible as CollapsiblePrimitive } from 'bits-ui'
import { slide } from 'svelte/transition'
type $$Props = CollapsiblePrimitive.ContentProps
export let transition: $$Props['transition'] = slide
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 150
}
</script>
<CollapsiblePrimitive.Content {transition} {transitionConfig} {...$$restProps}>
<slot />
</CollapsiblePrimitive.Content>

View File

@@ -0,0 +1,15 @@
import { Collapsible as CollapsiblePrimitive } from 'bits-ui'
import Content from './collapsible-content.svelte'
const Root = CollapsiblePrimitive.Root
const Trigger = CollapsiblePrimitive.Trigger
export {
Root,
Content,
Trigger,
//
Root as Collapsible,
Content as CollapsibleContent,
Trigger as CollapsibleTrigger
}

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import Command from './command.svelte'
import * as Dialog from '$lib/components/ui/dialog'
import type { Dialog as DialogPrimitive } from 'bits-ui'
import type { Command as CommandPrimitive } from 'cmdk-sv'
type $$Props = DialogPrimitive.Props & CommandPrimitive.CommandProps
export let open: $$Props['open'] = false
export let value: $$Props['value'] = undefined
</script>
<Dialog.Root bind:open {...$$restProps}>
<Dialog.Content class="overflow-hidden p-0 shadow-lg">
<Command
class="[&_[data-cmdk-group-heading]]:px-2 [&_[data-cmdk-group-heading]]:font-medium [&_[data-cmdk-group-heading]]:text-muted-foreground [&_[data-cmdk-group]:not([hidden])_~[data-cmdk-group]]:pt-0 [&_[data-cmdk-group]]:px-2 [&_[data-cmdk-input-wrapper]_svg]:h-5 [&_[data-cmdk-input-wrapper]_svg]:w-5 [&_[data-cmdk-input]]:h-12 [&_[data-cmdk-item]]:px-2 [&_[data-cmdk-item]]:py-3 [&_[data-cmdk-item]_svg]:h-5 [&_[data-cmdk-item]_svg]:w-5"
{...$$restProps}
bind:value
>
<slot />
</Command>
</Dialog.Content>
</Dialog.Root>

View File

@@ -0,0 +1,15 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.EmptyProps
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.Empty
class={cn('py-6 text-center text-sm', className)}
{...$$restProps}
>
<slot />
</CommandPrimitive.Empty>

View File

@@ -0,0 +1,18 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.GroupProps
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.Group
class={cn(
'overflow-hidden p-1 text-foreground [&_[data-cmdk-group-heading]]:px-2 [&_[data-cmdk-group-heading]]:py-1.5 [&_[data-cmdk-group-heading]]:text-xs [&_[data-cmdk-group-heading]]:font-medium [&_[data-cmdk-group-heading]]:text-muted-foreground',
className
)}
{...$$restProps}
>
<slot />
</CommandPrimitive.Group>

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { Search } from 'lucide-svelte'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.InputProps
let className: string | undefined | null = undefined
export { className as class }
export let value: string = ''
</script>
<div class="flex items-center border-b px-2" data-cmdk-input-wrapper="">
<Search class="mr-2 h-4 w-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
class={cn(
'flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
className
)}
{...$$restProps}
bind:value
/>
</div>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.ItemProps
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.Item
class={cn(
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
className
)}
{...$$restProps}
>
<slot />
</CommandPrimitive.Item>

View File

@@ -0,0 +1,15 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.ListProps
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.List
class={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
{...$$restProps}
>
<slot />
</CommandPrimitive.List>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.SeparatorProps
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.Separator
class={cn('-mx-1 h-px bg-border', className)}
{...$$restProps}
/>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { cn } from '$lib/utils'
import type { HTMLAttributes } from 'svelte/elements'
type $$Props = HTMLAttributes<HTMLSpanElement>
let className: string | undefined | null = undefined
export { className as class }
</script>
<span
class={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}
{...$$restProps}
>
<slot />
</span>

View File

@@ -0,0 +1,22 @@
<script lang="ts">
import { Command as CommandPrimitive } from 'cmdk-sv'
import { cn } from '$lib/utils'
type $$Props = CommandPrimitive.CommandProps
export let value: $$Props['value'] = undefined
let className: string | undefined | null = undefined
export { className as class }
</script>
<CommandPrimitive.Root
class={cn(
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',
className
)}
bind:value
{...$$restProps}
>
<slot />
</CommandPrimitive.Root>

View File

@@ -0,0 +1,37 @@
import { Command as CommandPrimitive } from 'cmdk-sv'
import Root from './command.svelte'
import Dialog from './command-dialog.svelte'
import Empty from './command-empty.svelte'
import Group from './command-group.svelte'
import Item from './command-item.svelte'
import Input from './command-input.svelte'
import List from './command-list.svelte'
import Separator from './command-separator.svelte'
import Shortcut from './command-shortcut.svelte'
const Loading = CommandPrimitive.Loading
export {
Root,
Dialog,
Empty,
Group,
Item,
Input,
List,
Separator,
Shortcut,
Loading,
//
Root as Command,
Dialog as CommandDialog,
Empty as CommandEmpty,
Group as CommandGroup,
Item as CommandItem,
Input as CommandInput,
List as CommandList,
Separator as CommandSeparator,
Shortcut as CommandShortcut,
Loading as CommandLoading
}

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
import { Check } from 'lucide-svelte'
type $$Props = ContextMenuPrimitive.CheckboxItemProps
type $$Events = ContextMenuPrimitive.CheckboxItemEvents
let className: $$Props['class'] = undefined
export let checked: $$Props['checked'] = undefined
export { className as class }
</script>
<ContextMenuPrimitive.CheckboxItem
bind:checked
class={cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<ContextMenuPrimitive.CheckboxIndicator>
<Check class="h-4 w-4" />
</ContextMenuPrimitive.CheckboxIndicator>
</span>
<slot />
</ContextMenuPrimitive.CheckboxItem>

View File

@@ -0,0 +1,24 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui'
import { cn, flyAndScale } from '$lib/utils'
type $$Props = ContextMenuPrimitive.ContentProps
let className: $$Props['class'] = undefined
export let transition: $$Props['transition'] = flyAndScale
export let transitionConfig: $$Props['transitionConfig'] = undefined
export { className as class }
</script>
<ContextMenuPrimitive.Content
{transition}
{transitionConfig}
class={cn(
'z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none',
className
)}
{...$$restProps}
on:keydown
>
<slot />
</ContextMenuPrimitive.Content>

View File

@@ -0,0 +1,31 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = ContextMenuPrimitive.ItemProps & {
inset?: boolean
}
type $$Events = ContextMenuPrimitive.ItemEvents
let className: $$Props['class'] = undefined
export let inset: $$Props['inset'] = undefined
export { className as class }
</script>
<ContextMenuPrimitive.Item
class={cn(
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50',
inset && 'pl-8',
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<slot />
</ContextMenuPrimitive.Item>

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui'
import { cn } from '$lib/utils'
type $$Props = ContextMenuPrimitive.LabelProps & {
inset?: boolean
}
let className: $$Props['class'] = undefined
export let inset: $$Props['inset'] = undefined
export { className as class }
</script>
<ContextMenuPrimitive.Label
class={cn(
'px-2 py-1.5 text-sm font-semibold text-foreground',
inset && 'pl-8',
className
)}
{...$$restProps}
>
<slot />
</ContextMenuPrimitive.Label>

View File

@@ -0,0 +1,11 @@
<script lang="ts">
import { ContextMenu as ContextMenuPrimitive } from 'bits-ui'
type $$Props = ContextMenuPrimitive.RadioGroupProps
export let value: $$Props['value'] = undefined
</script>
<ContextMenuPrimitive.RadioGroup {...$$restProps} bind:value>
<slot />
</ContextMenuPrimitive.RadioGroup>

Some files were not shown because too many files have changed in this diff Show More