Switching ui lib & refactoring (#80)
switch to shadcn ui bump runtime versions (node, pnpm, etc) refactor gui
This commit is contained in:

committed by
GitHub

parent
12365282a3
commit
353ec976d5
@@ -5,7 +5,7 @@
|
||||
"fixed": [],
|
||||
"linked": [],
|
||||
"access": "restricted",
|
||||
"baseBranch": "dev",
|
||||
"baseBranch": "release",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": []
|
||||
}
|
||||
|
5
.changeset/poor-falcons-buy.md
Normal file
5
.changeset/poor-falcons-buy.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"svelte-tauri": minor
|
||||
---
|
||||
|
||||
Switching ui to shadcn-svelte
|
@@ -1,38 +1,76 @@
|
||||
/** @type { import("eslint").Linter.FlatConfig } */
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:json/recommended',
|
||||
'plugin:svelte/recommended',
|
||||
'prettier'
|
||||
],
|
||||
rules: {
|
||||
'no-unused-vars': 'off', // or "@typescript-eslint/no-unused-vars": "off",
|
||||
'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')
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020
|
||||
ecmaVersion: 'latest',
|
||||
extraFileExtensions: ['.svelte']
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2017: true,
|
||||
es2024: 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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
BIN
.github/app.jpeg
vendored
BIN
.github/app.jpeg
vendored
Binary file not shown.
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 53 KiB |
35
.github/workflows/clippy.yml
vendored
35
.github/workflows/clippy.yml
vendored
@@ -1,17 +1,47 @@
|
||||
name: Build and publish
|
||||
name: Clippy
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
publish-tauri:
|
||||
runs-on: 'ubuntu-20.04'
|
||||
runs-on: 'ubuntu-22.04'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8.10.0
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build frontend
|
||||
run: pnpm svelte:build
|
||||
- uses: rui314/setup-mold@v1
|
||||
with:
|
||||
make-default: false
|
||||
@@ -22,7 +52,6 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
@@ -24,13 +24,13 @@ jobs:
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8.5.0
|
||||
version: 8.10.0
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
|
16
.github/workflows/test.yml
vendored
16
.github/workflows/test.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [macos-latest, ubuntu-20.04, windows-latest]
|
||||
platform: [macos-latest, ubuntu-22.04, windows-latest]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
@@ -17,16 +17,16 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js
|
||||
- name: Install Node.js 20
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
|
||||
- uses: pnpm/action-setup@v2
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 8.5.0
|
||||
version: 8.10.0
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
@@ -46,6 +46,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build frontend
|
||||
run: pnpm svelte:build
|
||||
|
||||
- uses: rui314/setup-mold@v1
|
||||
with:
|
||||
make-default: false
|
||||
@@ -56,14 +59,11 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: matrix.platform == 'ubuntu-20.04'
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Build frontend
|
||||
run: pnpm svelte:build
|
||||
|
||||
- uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
|
@@ -1,84 +1,13 @@
|
||||
# v 0.2
|
||||
# Minified files
|
||||
*.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
|
||||
.DS_Store
|
||||
node_modules
|
||||
build
|
||||
release
|
||||
dist
|
||||
|
||||
# Rust
|
||||
target
|
||||
|
||||
# Svelte-Kit
|
||||
.svelte-kit
|
||||
package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# 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*
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
12
.prettierrc
Normal file
12
.prettierrc
Normal 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" } }]
|
||||
}
|
@@ -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'
|
||||
};
|
@@ -1,5 +1,11 @@
|
||||
# svelte-tauri
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 98b1df2: Switching ui to shadcn-svelte
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
11
README.md
11
README.md
@@ -5,25 +5,28 @@
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
- Typescript
|
||||
- UI:
|
||||
- Snap form
|
||||
- Tailwind
|
||||
- DaisyUI
|
||||
- Shedcn-svelte
|
||||
- Fontawesome
|
||||
- Lucide-svelte
|
||||
- Roboto Font
|
||||
- Code Quality
|
||||
- Prettier
|
||||
- Eslint
|
||||
- Lint-staged
|
||||
- Tauri
|
||||
- Tauri window state manager plugin
|
||||
- Tauri store plugin
|
||||
- Husky
|
||||
- Automation
|
||||
- Husky
|
||||
- Changeset
|
||||
- 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.
|
||||
- (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
13
components.json
Normal 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"
|
||||
}
|
||||
}
|
@@ -1,12 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Svelte-Tauri</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<body id="app">
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
96
package.json
96
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "svelte-tauri",
|
||||
"version": "0.0.2",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -25,52 +25,68 @@
|
||||
"changeset": "changeset"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,ts,svelte}": "eslint --cache --fix",
|
||||
"src/**/*.{js,ts,svelte,css,scss,postcss,md,json}": "prettier --write --ignore-unknown"
|
||||
"*.{ts,svelte}": [
|
||||
"eslint --cache --fix",
|
||||
"prettier --write --ignore-unknown"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.26.1",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.2.0",
|
||||
"@tauri-apps/api": "^1.3.0",
|
||||
"@tauri-apps/cli": "^1.3.1",
|
||||
"@tsconfig/svelte": "^4.0.1",
|
||||
"@types/node": "18.15.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
||||
"@typescript-eslint/parser": "^5.59.6",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"daisyui": "^2.51.6",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"@changesets/cli": "^2.27.1",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.1",
|
||||
"@tauri-apps/api": "^1.5.3",
|
||||
"@tauri-apps/cli": "^1.5.9",
|
||||
"@tsconfig/svelte": "^5.0.2",
|
||||
"@types/node": "20.11.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
||||
"@typescript-eslint/parser": "^6.19.1",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-svelte": "2.35.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-json": "^3.1.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",
|
||||
"lint-staged": "^13.2.2",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.10.0",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"svelte": "^3.59.1",
|
||||
"svelte-check": "^3.3.2",
|
||||
"svelte-fa": "^3.0.3",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"svelte-spa-router": "^3.3.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"lint-staged": "^15.2.0",
|
||||
"postcss": "^8.4.33",
|
||||
"postcss-load-config": "^5.0.2",
|
||||
"prettier": "^3.2.4",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||
"svelte": "^4.2.9",
|
||||
"svelte-check": "^3.6.3",
|
||||
"svelte-fa": "^4.0.2",
|
||||
"svelte-preprocess": "^5.1.3",
|
||||
"svelte-spa-router": "^4.0.1",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"tailwindcss-hero-patterns": "^0.1.2",
|
||||
"tslib": "^2.5.1",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.7"
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"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",
|
||||
"engineStrict": true,
|
||||
"packageManager": "pnpm@8.10.0",
|
||||
"engineStrict": false,
|
||||
"engines": {
|
||||
"pnpm": ">=8.5.0",
|
||||
"node": ">18.0.0 <19.0.0"
|
||||
"pnpm": ">=8.10.0",
|
||||
"node": ">20.0.0 <21.0.0"
|
||||
}
|
||||
}
|
||||
|
2283
pnpm-lock.yaml
generated
2283
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
const tailwindcss = require('tailwindcss');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const tailwindcss = require('tailwindcss')
|
||||
const autoprefixer = require('autoprefixer')
|
||||
|
||||
const config = {
|
||||
plugins: [
|
||||
@@ -8,6 +8,6 @@ const config = {
|
||||
//But others, like autoprefixer, need to run after,
|
||||
autoprefixer
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
module.exports = config
|
||||
|
@@ -1,3 +1,3 @@
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]
|
||||
# [target.x86_64-unknown-linux-gnu]
|
||||
# linker = "clang"
|
||||
# rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]
|
||||
|
2080
src-tauri/Cargo.lock
generated
2080
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -7,22 +7,22 @@ license = "MIT"
|
||||
repository = "https://github.com/Fractal-Tess/Svelte-Tauri"
|
||||
default-run = "svelte-tauri"
|
||||
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
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.3.0", features = [] }
|
||||
tauri-build = { version = "1.5.1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
sha2 = "0.10.6"
|
||||
serde_json = "1.0.111"
|
||||
sha2 = "0.10.8"
|
||||
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.2.3", features = ["api-all", "devtools", "updater"] }
|
||||
thiserror = "1.0.40"
|
||||
specta = "1.0.4"
|
||||
tauri-specta = { version = "1.0.0", features = ["javascript", "typescript"] }
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
tauri = { version = "1.5.4", features = ["api-all", "devtools", "updater"] }
|
||||
thiserror = "1.0.56"
|
||||
specta = "1.0.5"
|
||||
tauri-specta = { version = "1.0.2", features = ["javascript", "typescript"] }
|
||||
[features]
|
||||
# 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
|
||||
|
@@ -1,14 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { theme } from '$lib/stores/theme';
|
||||
import Router from '$lib/router/Router.svelte';
|
||||
import BaseLayout from '$lib/layout/BaseLayout.svelte';
|
||||
|
||||
$: {
|
||||
document.documentElement.setAttribute('data-theme', $theme);
|
||||
document.documentElement.classList.value = $theme;
|
||||
}
|
||||
import Router from '$router/Router.svelte'
|
||||
import { ModeWatcher, mode } from 'mode-watcher'
|
||||
import Header from '$lib/components/HeaderNav.svelte'
|
||||
import { Toaster } from 'svelte-sonner'
|
||||
</script>
|
||||
|
||||
<BaseLayout>
|
||||
<Router />
|
||||
</BaseLayout>
|
||||
<ModeWatcher defaultMode="dark" />
|
||||
<Toaster theme={$mode} />
|
||||
|
||||
<div class="relative flex flex-col h-screen" data-vaul-drawer-wrapper id="page">
|
||||
<Header />
|
||||
<main class="flex-1">
|
||||
<Router />
|
||||
</main>
|
||||
</div>
|
||||
|
83
src/lib/components/HeaderNav.svelte
Normal file
83
src/lib/components/HeaderNav.svelte
Normal 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>
|
23
src/lib/components/IPC/CallTauri.svelte
Normal file
23
src/lib/components/IPC/CallTauri.svelte
Normal 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>
|
27
src/lib/components/IPC/HashString.svelte
Normal file
27
src/lib/components/IPC/HashString.svelte
Normal 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>
|
56
src/lib/components/IPC/KeyValuePair.svelte
Normal file
56
src/lib/components/IPC/KeyValuePair.svelte
Normal 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>
|
@@ -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>
|
25
src/lib/components/ui/accordion/accordion-content.svelte
Normal file
25
src/lib/components/ui/accordion/accordion-content.svelte
Normal 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>
|
18
src/lib/components/ui/accordion/accordion-item.svelte
Normal file
18
src/lib/components/ui/accordion/accordion-item.svelte
Normal 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>
|
26
src/lib/components/ui/accordion/accordion-trigger.svelte
Normal file
26
src/lib/components/ui/accordion/accordion-trigger.svelte
Normal 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>
|
17
src/lib/components/ui/accordion/index.ts
Normal file
17
src/lib/components/ui/accordion/index.ts
Normal 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
|
||||
}
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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}
|
||||
/>
|
@@ -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>
|
18
src/lib/components/ui/alert-dialog/alert-dialog-title.svelte
Normal file
18
src/lib/components/ui/alert-dialog/alert-dialog-title.svelte
Normal 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>
|
40
src/lib/components/ui/alert-dialog/index.ts
Normal file
40
src/lib/components/ui/alert-dialog/index.ts
Normal 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
|
||||
}
|
13
src/lib/components/ui/alert/alert-description.svelte
Normal file
13
src/lib/components/ui/alert/alert-description.svelte
Normal 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>
|
21
src/lib/components/ui/alert/alert-title.svelte
Normal file
21
src/lib/components/ui/alert/alert-title.svelte
Normal 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>
|
21
src/lib/components/ui/alert/alert.svelte
Normal file
21
src/lib/components/ui/alert/alert.svelte
Normal 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>
|
33
src/lib/components/ui/alert/index.ts
Normal file
33
src/lib/components/ui/alert/index.ts
Normal 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
|
||||
}
|
11
src/lib/components/ui/aspect-ratio/aspect-ratio.svelte
Normal file
11
src/lib/components/ui/aspect-ratio/aspect-ratio.svelte
Normal 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>
|
3
src/lib/components/ui/aspect-ratio/index.ts
Normal file
3
src/lib/components/ui/aspect-ratio/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import Root from './aspect-ratio.svelte'
|
||||
|
||||
export { Root, Root as AspectRatio }
|
19
src/lib/components/ui/avatar/avatar-fallback.svelte
Normal file
19
src/lib/components/ui/avatar/avatar-fallback.svelte
Normal 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>
|
18
src/lib/components/ui/avatar/avatar-image.svelte
Normal file
18
src/lib/components/ui/avatar/avatar-image.svelte
Normal 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}
|
||||
/>
|
21
src/lib/components/ui/avatar/avatar.svelte
Normal file
21
src/lib/components/ui/avatar/avatar.svelte
Normal 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>
|
13
src/lib/components/ui/avatar/index.ts
Normal file
13
src/lib/components/ui/avatar/index.ts
Normal 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
|
||||
}
|
18
src/lib/components/ui/badge/badge.svelte
Normal file
18
src/lib/components/ui/badge/badge.svelte
Normal 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>
|
22
src/lib/components/ui/badge/index.ts
Normal file
22
src/lib/components/ui/badge/index.ts
Normal 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']
|
25
src/lib/components/ui/button/button.svelte
Normal file
25
src/lib/components/ui/button/button.svelte
Normal 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>
|
50
src/lib/components/ui/button/index.ts
Normal file
50
src/lib/components/ui/button/index.ts
Normal 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
|
||||
}
|
21
src/lib/components/ui/calendar/calendar-cell.svelte
Normal file
21
src/lib/components/ui/calendar/calendar-cell.svelte
Normal 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>
|
42
src/lib/components/ui/calendar/calendar-day.svelte
Normal file
42
src/lib/components/ui/calendar/calendar-day.svelte
Normal 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>
|
13
src/lib/components/ui/calendar/calendar-grid-body.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-body.svelte
Normal 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>
|
13
src/lib/components/ui/calendar/calendar-grid-head.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-head.svelte
Normal 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>
|
13
src/lib/components/ui/calendar/calendar-grid-row.svelte
Normal file
13
src/lib/components/ui/calendar/calendar-grid-row.svelte
Normal 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>
|
16
src/lib/components/ui/calendar/calendar-grid.svelte
Normal file
16
src/lib/components/ui/calendar/calendar-grid.svelte
Normal 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>
|
19
src/lib/components/ui/calendar/calendar-head-cell.svelte
Normal file
19
src/lib/components/ui/calendar/calendar-head-cell.svelte
Normal 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>
|
19
src/lib/components/ui/calendar/calendar-header.svelte
Normal file
19
src/lib/components/ui/calendar/calendar-header.svelte
Normal 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>
|
19
src/lib/components/ui/calendar/calendar-heading.svelte
Normal file
19
src/lib/components/ui/calendar/calendar-heading.svelte
Normal 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>
|
19
src/lib/components/ui/calendar/calendar-months.svelte
Normal file
19
src/lib/components/ui/calendar/calendar-months.svelte
Normal 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>
|
27
src/lib/components/ui/calendar/calendar-next-button.svelte
Normal file
27
src/lib/components/ui/calendar/calendar-next-button.svelte
Normal 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>
|
27
src/lib/components/ui/calendar/calendar-prev-button.svelte
Normal file
27
src/lib/components/ui/calendar/calendar-prev-button.svelte
Normal 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>
|
59
src/lib/components/ui/calendar/calendar.svelte
Normal file
59
src/lib/components/ui/calendar/calendar.svelte
Normal 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>
|
30
src/lib/components/ui/calendar/index.ts
Normal file
30
src/lib/components/ui/calendar/index.ts
Normal 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
|
||||
}
|
13
src/lib/components/ui/card/card-content.svelte
Normal file
13
src/lib/components/ui/card/card-content.svelte
Normal 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>
|
13
src/lib/components/ui/card/card-description.svelte
Normal file
13
src/lib/components/ui/card/card-description.svelte
Normal 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>
|
13
src/lib/components/ui/card/card-footer.svelte
Normal file
13
src/lib/components/ui/card/card-footer.svelte
Normal 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>
|
13
src/lib/components/ui/card/card-header.svelte
Normal file
13
src/lib/components/ui/card/card-header.svelte
Normal 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>
|
21
src/lib/components/ui/card/card-title.svelte
Normal file
21
src/lib/components/ui/card/card-title.svelte
Normal 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>
|
19
src/lib/components/ui/card/card.svelte
Normal file
19
src/lib/components/ui/card/card.svelte
Normal 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>
|
24
src/lib/components/ui/card/index.ts
Normal file
24
src/lib/components/ui/card/index.ts
Normal 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'
|
26
src/lib/components/ui/carousel/carousel-content.svelte
Normal file
26
src/lib/components/ui/carousel/carousel-content.svelte
Normal 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>
|
25
src/lib/components/ui/carousel/carousel-item.svelte
Normal file
25
src/lib/components/ui/carousel/carousel-item.svelte
Normal 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>
|
39
src/lib/components/ui/carousel/carousel-next.svelte
Normal file
39
src/lib/components/ui/carousel/carousel-next.svelte
Normal 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>
|
40
src/lib/components/ui/carousel/carousel-previous.svelte
Normal file
40
src/lib/components/ui/carousel/carousel-previous.svelte
Normal 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>
|
98
src/lib/components/ui/carousel/carousel.svelte
Normal file
98
src/lib/components/ui/carousel/carousel.svelte
Normal 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>
|
52
src/lib/components/ui/carousel/context.ts
Normal file
52
src/lib/components/ui/carousel/context.ts
Normal 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)
|
||||
}
|
5
src/lib/components/ui/carousel/index.ts
Normal file
5
src/lib/components/ui/carousel/index.ts
Normal 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'
|
34
src/lib/components/ui/checkbox/checkbox.svelte
Normal file
34
src/lib/components/ui/checkbox/checkbox.svelte
Normal 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>
|
6
src/lib/components/ui/checkbox/index.ts
Normal file
6
src/lib/components/ui/checkbox/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import Root from './checkbox.svelte'
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Checkbox
|
||||
}
|
15
src/lib/components/ui/collapsible/collapsible-content.svelte
Normal file
15
src/lib/components/ui/collapsible/collapsible-content.svelte
Normal 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>
|
15
src/lib/components/ui/collapsible/index.ts
Normal file
15
src/lib/components/ui/collapsible/index.ts
Normal 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
|
||||
}
|
23
src/lib/components/ui/command/command-dialog.svelte
Normal file
23
src/lib/components/ui/command/command-dialog.svelte
Normal 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>
|
15
src/lib/components/ui/command/command-empty.svelte
Normal file
15
src/lib/components/ui/command/command-empty.svelte
Normal 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>
|
18
src/lib/components/ui/command/command-group.svelte
Normal file
18
src/lib/components/ui/command/command-group.svelte
Normal 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>
|
23
src/lib/components/ui/command/command-input.svelte
Normal file
23
src/lib/components/ui/command/command-input.svelte
Normal 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>
|
19
src/lib/components/ui/command/command-item.svelte
Normal file
19
src/lib/components/ui/command/command-item.svelte
Normal 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>
|
15
src/lib/components/ui/command/command-list.svelte
Normal file
15
src/lib/components/ui/command/command-list.svelte
Normal 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>
|
13
src/lib/components/ui/command/command-separator.svelte
Normal file
13
src/lib/components/ui/command/command-separator.svelte
Normal 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}
|
||||
/>
|
16
src/lib/components/ui/command/command-shortcut.svelte
Normal file
16
src/lib/components/ui/command/command-shortcut.svelte
Normal 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>
|
22
src/lib/components/ui/command/command.svelte
Normal file
22
src/lib/components/ui/command/command.svelte
Normal 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>
|
37
src/lib/components/ui/command/index.ts
Normal file
37
src/lib/components/ui/command/index.ts
Normal 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
|
||||
}
|
@@ -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>
|
@@ -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>
|
31
src/lib/components/ui/context-menu/context-menu-item.svelte
Normal file
31
src/lib/components/ui/context-menu/context-menu-item.svelte
Normal 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>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user