Compare commits
27 Commits
24a9d53ccf
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f84f1a78a5 | |||
| 6fd01c917b | |||
| e6f79cd68a | |||
| 85441c0dfe | |||
| 85223bc3b2 | |||
| 193bce0cc9 | |||
| d892621e9b | |||
| b2cf967b78 | |||
| 1dcbe2e3fe | |||
| a3a7b59757 | |||
| d38d47051a | |||
| a6818607c8 | |||
| ead37e529e | |||
| e1e2e94bf2 | |||
| 3373762d97 | |||
| b71bb98389 | |||
| 4ee0a8f4ec | |||
| de08587b77 | |||
| 2b0bdda261 | |||
| 44165e39b1 | |||
| 3642ecfba6 | |||
| fe083ffaea | |||
| 29ff3265e8 | |||
| b1d0267bf1 | |||
| e42479a3c0 | |||
| 77cbb1d8d7 | |||
| 9f8675fb30 |
@@ -1,6 +1,3 @@
|
|||||||
# Drizzle
|
|
||||||
DATABASE_URL=file:local.db
|
|
||||||
|
|
||||||
ORIGIN=""
|
ORIGIN=""
|
||||||
|
|
||||||
# Better Auth
|
# Better Auth
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Clearity is a workspace, client, and contract management platform for managed office operations. It tracks clients, contacts, addresses, rooms, services, bookings, contracts, invoices, and workspace admins from a SvelteKit dashboard.
|
Clearity is a workspace, client, and contract management platform for managed office operations. It tracks clients, contacts, addresses, rooms, services, bookings, contracts, invoices, and workspace admins from a SvelteKit dashboard.
|
||||||
|
|
||||||
The app is built with SvelteKit, Svelte 5, shadcn-svelte, Superforms, Better Auth, Drizzle ORM, SQLite/libSQL, and Cloudflare Workers.
|
The app is built with SvelteKit, Svelte 5, shadcn-svelte, Superforms, Better Auth, Drizzle ORM, Cloudflare D1, and Cloudflare Workers.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ pnpm install
|
|||||||
Create a local `.env` file:
|
Create a local `.env` file:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
DATABASE_URL=file:local.db
|
|
||||||
ORIGIN=http://localhost:5173
|
ORIGIN=http://localhost:5173
|
||||||
BETTER_AUTH_SECRET=replace-with-a-long-random-secret
|
BETTER_AUTH_SECRET=replace-with-a-long-random-secret
|
||||||
```
|
```
|
||||||
@@ -29,7 +28,7 @@ openssl rand -base64 32
|
|||||||
Apply database migrations:
|
Apply database migrations:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
DATABASE_URL=file:local.db pnpm db:migrate
|
pnpm db:migrate:local
|
||||||
```
|
```
|
||||||
|
|
||||||
Start the development server:
|
Start the development server:
|
||||||
@@ -47,34 +46,36 @@ pnpm check # Wrangler types, SvelteKit sync, and svelte-check
|
|||||||
pnpm lint # Prettier check and ESLint
|
pnpm lint # Prettier check and ESLint
|
||||||
pnpm format # Format the codebase
|
pnpm format # Format the codebase
|
||||||
pnpm db:generate # Generate Drizzle migrations after schema changes
|
pnpm db:generate # Generate Drizzle migrations after schema changes
|
||||||
pnpm db:migrate # Apply Drizzle migrations to DATABASE_URL
|
pnpm db:migrate:local # Apply migrations to the local D1 database
|
||||||
pnpm db:studio # Open Drizzle Studio
|
pnpm db:migrate:remote # Apply migrations to the remote D1 database
|
||||||
pnpm gen # Regenerate Cloudflare Worker types
|
pnpm gen # Regenerate Cloudflare Worker types
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables And Bindings
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
|
||||||
- `DATABASE_URL`: SQLite/libSQL connection URL. Use `file:local.db` for local development.
|
|
||||||
- `ORIGIN`: Public app origin, for example `http://localhost:5173` locally or `https://clearity.example.com` in production.
|
- `ORIGIN`: Public app origin, for example `http://localhost:5173` locally or `https://clearity.example.com` in production.
|
||||||
- `BETTER_AUTH_SECRET`: Secret used by Better Auth.
|
- `BETTER_AUTH_SECRET`: Secret used by Better Auth.
|
||||||
|
- Cloudflare D1 binding `DB`, configured in `wrangler.jsonc`.
|
||||||
|
|
||||||
|
Local development uses the same `DB` binding shape as production. SvelteKit's Cloudflare adapter populates `platform.env.DB` from `wrangler.jsonc` during dev and preview, and Wrangler stores local D1 data in its local state directory.
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
The application schema lives in `src/lib/server/db`. Drizzle migration files live in `drizzle`.
|
The application schema lives in `src/lib/server/db`. Drizzle migration files live in `drizzle`.
|
||||||
|
|
||||||
Local development currently uses the libSQL client through `DATABASE_URL`, so the fastest local database is a SQLite file:
|
Clearity always uses Drizzle's Cloudflare D1 driver through the `DB` binding. Apply migrations to the local D1 database before starting the app:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
DATABASE_URL=file:local.db pnpm db:migrate
|
pnpm db:migrate:local
|
||||||
```
|
```
|
||||||
|
|
||||||
For schema changes:
|
For schema changes:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pnpm db:generate
|
pnpm db:generate
|
||||||
DATABASE_URL=file:local.db pnpm db:migrate
|
pnpm db:migrate:local
|
||||||
```
|
```
|
||||||
|
|
||||||
## Production Deployment
|
## Production Deployment
|
||||||
@@ -91,10 +92,10 @@ pnpm wrangler whoami
|
|||||||
Create a production D1 database:
|
Create a production D1 database:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pnpm wrangler d1 create clearity-production
|
pnpm wrangler d1 create clearity-production --binding DB
|
||||||
```
|
```
|
||||||
|
|
||||||
Wrangler prints a `database_id`. Add it to `wrangler.jsonc`:
|
Wrangler prints a `database_id`. Replace the placeholder in `wrangler.jsonc`:
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
@@ -102,7 +103,8 @@ Wrangler prints a `database_id`. Add it to `wrangler.jsonc`:
|
|||||||
{
|
{
|
||||||
"binding": "DB",
|
"binding": "DB",
|
||||||
"database_name": "clearity-production",
|
"database_name": "clearity-production",
|
||||||
"database_id": "<database_id>"
|
"database_id": "<database_id>",
|
||||||
|
"migrations_dir": "drizzle"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -117,9 +119,7 @@ pnpm gen
|
|||||||
Apply SQL migrations to the remote D1 database:
|
Apply SQL migrations to the remote D1 database:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
for file in drizzle/*.sql; do
|
pnpm wrangler d1 migrations apply clearity-production --remote
|
||||||
pnpm wrangler d1 execute clearity-production --remote --file "$file"
|
|
||||||
done
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Set production secrets:
|
Set production secrets:
|
||||||
@@ -129,12 +129,6 @@ pnpm wrangler secret put ORIGIN
|
|||||||
pnpm wrangler secret put BETTER_AUTH_SECRET
|
pnpm wrangler secret put BETTER_AUTH_SECRET
|
||||||
```
|
```
|
||||||
|
|
||||||
This codebase currently reads the database through `DATABASE_URL`. If production is deployed against Cloudflare D1, wire the runtime database client to the `DB` D1 binding before deploying. If production is deployed against a hosted libSQL database instead, set `DATABASE_URL` as a Worker secret:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
pnpm wrangler secret put DATABASE_URL
|
|
||||||
```
|
|
||||||
|
|
||||||
Build and deploy:
|
Build and deploy:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import { defineConfig } from 'drizzle-kit';
|
import { defineConfig } from 'drizzle-kit';
|
||||||
|
|
||||||
if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
schema: './src/lib/server/db/schema.ts',
|
schema: './src/lib/server/db/schema.ts',
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite',
|
||||||
dbCredentials: { url: process.env.DATABASE_URL },
|
|
||||||
verbose: true,
|
verbose: true,
|
||||||
strict: true
|
strict: true
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `invoices` ADD `status` text DEFAULT 'draft' NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `sent_at` integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `paid_at` integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE `invoices` ADD `voided_at` integer;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -113,6 +113,13 @@
|
|||||||
"when": 1782338642144,
|
"when": 1782338642144,
|
||||||
"tag": "0015_fuzzy_vampiro",
|
"tag": "0015_fuzzy_vampiro",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 16,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1782383895120,
|
||||||
|
"tag": "0016_outstanding_talkback",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+6
-4
@@ -13,9 +13,9 @@
|
|||||||
"lint": "prettier --check . && eslint .",
|
"lint": "prettier --check . && eslint .",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"gen": "wrangler types",
|
"gen": "wrangler types",
|
||||||
"db:push": "drizzle-kit push",
|
|
||||||
"db:generate": "drizzle-kit generate",
|
"db:generate": "drizzle-kit generate",
|
||||||
"db:migrate": "drizzle-kit migrate",
|
"db:migrate:local": "wrangler d1 migrations apply clearity-production --local",
|
||||||
|
"db:migrate:remote": "wrangler d1 migrations apply clearity-production --remote",
|
||||||
"auth:schema": "better-auth generate --config src/lib/server/auth.ts --output src/lib/server/db/auth.schema.ts --yes"
|
"auth:schema": "better-auth generate --config src/lib/server/auth.ts --output src/lib/server/db/auth.schema.ts --yes"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -24,8 +24,7 @@
|
|||||||
"@eslint/js": "latest",
|
"@eslint/js": "latest",
|
||||||
"@fontsource-variable/geist": "^5.2.9",
|
"@fontsource-variable/geist": "^5.2.9",
|
||||||
"@internationalized/date": "^3.12.1",
|
"@internationalized/date": "^3.12.1",
|
||||||
"@libsql/client": "^0.17.2",
|
"@lucide/svelte": "^1.21.0",
|
||||||
"@lucide/svelte": "^1.16.0",
|
|
||||||
"@sveltejs/adapter-cloudflare": "^7.2.8",
|
"@sveltejs/adapter-cloudflare": "^7.2.8",
|
||||||
"@sveltejs/kit": "^2.57.0",
|
"@sveltejs/kit": "^2.57.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
||||||
@@ -65,5 +64,8 @@
|
|||||||
"vite": "^8.0.7",
|
"vite": "^8.0.7",
|
||||||
"wrangler": "^4.81.0",
|
"wrangler": "^4.81.0",
|
||||||
"zod": "^4.4.3"
|
"zod": "^4.4.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"date-fns": "^4.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+30
-13
@@ -7,6 +7,10 @@ settings:
|
|||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
|
dependencies:
|
||||||
|
date-fns:
|
||||||
|
specifier: ^4.4.0
|
||||||
|
version: 4.4.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@better-auth/cli':
|
'@better-auth/cli':
|
||||||
specifier: ~1.4.21
|
specifier: ~1.4.21
|
||||||
@@ -23,12 +27,9 @@ importers:
|
|||||||
'@internationalized/date':
|
'@internationalized/date':
|
||||||
specifier: ^3.12.1
|
specifier: ^3.12.1
|
||||||
version: 3.12.1
|
version: 3.12.1
|
||||||
'@libsql/client':
|
|
||||||
specifier: ^0.17.2
|
|
||||||
version: 0.17.3
|
|
||||||
'@lucide/svelte':
|
'@lucide/svelte':
|
||||||
specifier: ^1.16.0
|
specifier: ^1.21.0
|
||||||
version: 1.16.0(svelte@5.55.9(@typescript-eslint/types@8.59.4))
|
version: 1.21.0(svelte@5.55.9(@typescript-eslint/types@8.59.4))
|
||||||
'@sveltejs/adapter-cloudflare':
|
'@sveltejs/adapter-cloudflare':
|
||||||
specifier: ^7.2.8
|
specifier: ^7.2.8
|
||||||
version: 7.2.8(@sveltejs/kit@2.61.0(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)))(wrangler@4.94.0(@cloudflare/workers-types@4.20260523.1))
|
version: 7.2.8(@sveltejs/kit@2.61.0(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)))(wrangler@4.94.0(@cloudflare/workers-types@4.20260523.1))
|
||||||
@@ -1385,8 +1386,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@lucide/svelte@1.16.0':
|
'@lucide/svelte@1.21.0':
|
||||||
resolution: {integrity: sha512-AvvPJnaWxeiNkAljI5MsSEc84yHPLMaWQIAJOcbX7k9au/f9ITS7cxTTQiautDiOFKVOXiYdZ+d6mtl88J+Kbg==}
|
resolution: {integrity: sha512-MEv//A7Jv3kHukZowv/DWp1MAtUzJKYwtJsmnQ7X98lCgtac3z3NbaToDl3Q6jO3gS9sougFpcD+t+YuxOkRMw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
svelte: ^5
|
svelte: ^5
|
||||||
|
|
||||||
@@ -2213,6 +2214,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-G7gHKj89n2owmkGb6WX6ixcnQ0Kf/0wpa9VIh9DGdbHu8wdrlaHU4ir3/bFNERl8N8nn4G7e7qbtBG8N9caihQ==}
|
resolution: {integrity: sha512-G7gHKj89n2owmkGb6WX6ixcnQ0Kf/0wpa9VIh9DGdbHu8wdrlaHU4ir3/bFNERl8N8nn4G7e7qbtBG8N9caihQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
date-fns@4.4.0:
|
||||||
|
resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==}
|
||||||
|
|
||||||
dayjs@1.11.20:
|
dayjs@1.11.20:
|
||||||
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
|
resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
|
||||||
|
|
||||||
@@ -4759,10 +4763,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@libsql/core@0.17.3':
|
'@libsql/core@0.17.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
js-base64: 3.7.8
|
js-base64: 3.7.8
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@libsql/darwin-arm64@0.5.29':
|
'@libsql/darwin-arm64@0.5.29':
|
||||||
optional: true
|
optional: true
|
||||||
@@ -4777,6 +4783,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@libsql/isomorphic-ws@0.1.5':
|
'@libsql/isomorphic-ws@0.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4785,6 +4792,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- bufferutil
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@libsql/linux-arm-gnueabihf@0.5.29':
|
'@libsql/linux-arm-gnueabihf@0.5.29':
|
||||||
optional: true
|
optional: true
|
||||||
@@ -4807,7 +4815,7 @@ snapshots:
|
|||||||
'@libsql/win32-x64-msvc@0.5.29':
|
'@libsql/win32-x64-msvc@0.5.29':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@lucide/svelte@1.16.0(svelte@5.55.9(@typescript-eslint/types@8.59.4))':
|
'@lucide/svelte@1.21.0(svelte@5.55.9(@typescript-eslint/types@8.59.4))':
|
||||||
dependencies:
|
dependencies:
|
||||||
svelte: 5.55.9(@typescript-eslint/types@8.59.4)
|
svelte: 5.55.9(@typescript-eslint/types@8.59.4)
|
||||||
|
|
||||||
@@ -4823,7 +4831,8 @@ snapshots:
|
|||||||
'@tybys/wasm-util': 0.10.2
|
'@tybys/wasm-util': 0.10.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@neon-rs/load@0.0.4': {}
|
'@neon-rs/load@0.0.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@noble/ciphers@2.2.0': {}
|
'@noble/ciphers@2.2.0': {}
|
||||||
|
|
||||||
@@ -5072,6 +5081,7 @@ snapshots:
|
|||||||
'@types/ws@8.18.1':
|
'@types/ws@8.18.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.12.4
|
'@types/node': 24.12.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@typeschema/class-validator@0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.4)':
|
'@typeschema/class-validator@0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.4)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5521,6 +5531,8 @@ snapshots:
|
|||||||
d3-delaunay: 6.0.4
|
d3-delaunay: 6.0.4
|
||||||
d3-scale: 4.0.2
|
d3-scale: 4.0.2
|
||||||
|
|
||||||
|
date-fns@4.4.0: {}
|
||||||
|
|
||||||
dayjs@1.11.20:
|
dayjs@1.11.20:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -5557,7 +5569,8 @@ snapshots:
|
|||||||
|
|
||||||
destr@2.0.5: {}
|
destr@2.0.5: {}
|
||||||
|
|
||||||
detect-libc@2.0.2: {}
|
detect-libc@2.0.2:
|
||||||
|
optional: true
|
||||||
|
|
||||||
detect-libc@2.1.2: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
@@ -5976,7 +5989,8 @@ snapshots:
|
|||||||
|
|
||||||
jose@6.2.3: {}
|
jose@6.2.3: {}
|
||||||
|
|
||||||
js-base64@3.7.8: {}
|
js-base64@3.7.8:
|
||||||
|
optional: true
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
@@ -6066,6 +6080,7 @@ snapshots:
|
|||||||
'@libsql/linux-x64-gnu': 0.5.29
|
'@libsql/linux-x64-gnu': 0.5.29
|
||||||
'@libsql/linux-x64-musl': 0.5.29
|
'@libsql/linux-x64-musl': 0.5.29
|
||||||
'@libsql/win32-x64-msvc': 0.5.29
|
'@libsql/win32-x64-msvc': 0.5.29
|
||||||
|
optional: true
|
||||||
|
|
||||||
lightningcss-android-arm64@1.32.0:
|
lightningcss-android-arm64@1.32.0:
|
||||||
optional: true
|
optional: true
|
||||||
@@ -6356,7 +6371,8 @@ snapshots:
|
|||||||
|
|
||||||
prettier@3.8.3: {}
|
prettier@3.8.3: {}
|
||||||
|
|
||||||
promise-limit@2.7.0: {}
|
promise-limit@2.7.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
prompts@2.4.2:
|
prompts@2.4.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -6878,7 +6894,8 @@ snapshots:
|
|||||||
|
|
||||||
ws@8.20.1: {}
|
ws@8.20.1: {}
|
||||||
|
|
||||||
ws@8.21.0: {}
|
ws@8.21.0:
|
||||||
|
optional: true
|
||||||
|
|
||||||
wsl-utils@0.1.0:
|
wsl-utils@0.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
import { Button } from '$lib/components/ui/button/index.js';
|
||||||
import { Input } from '$lib/components/ui/input/index.js';
|
import { Input } from '$lib/components/ui/input/index.js';
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from '$lib/utils/format.js';
|
||||||
import { firstFormError } from '$lib/form-feedback';
|
import { firstFormError } from '$lib/utils/feedback';
|
||||||
import { firstAdminSchema, type FirstAdminSchema } from '$lib/schemas/auth';
|
import { firstAdminSchema, type FirstAdminSchema } from '$lib/schemas/auth';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import { Button } from '$lib/components/ui/button/index.js';
|
import { Button } from '$lib/components/ui/button/index.js';
|
||||||
import * as Command from '$lib/components/ui/command/index.js';
|
import * as Command from '$lib/components/ui/command/index.js';
|
||||||
import * as Popover from '$lib/components/ui/popover/index.js';
|
import * as Popover from '$lib/components/ui/popover/index.js';
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from '$lib/utils/format.js';
|
||||||
|
|
||||||
type Option = {
|
type Option = {
|
||||||
value: string;
|
value: string;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ComponentProps } from 'svelte';
|
import type { ComponentProps } from 'svelte';
|
||||||
import * as Select from '$lib/components/ui/select/index.js';
|
import * as Select from '$lib/components/ui/select/index.js';
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from '$lib/utils/format.js';
|
||||||
|
|
||||||
type Option = {
|
type Option = {
|
||||||
value: string;
|
value: string;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
import { Input } from '$lib/components/ui/input/index.js';
|
import { Input } from '$lib/components/ui/input/index.js';
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
import { Button } from '$lib/components/ui/button/index.js';
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from '$lib/utils/format.js';
|
||||||
import { loginSchema, type LoginSchema } from '$lib/schemas/auth';
|
import { loginSchema, type LoginSchema } from '$lib/schemas/auth';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
|||||||
@@ -31,29 +31,26 @@
|
|||||||
|
|
||||||
<div class="grid gap-5">
|
<div class="grid gap-5">
|
||||||
<div class="grid gap-3">
|
<div class="grid gap-3">
|
||||||
<div class="grid gap-2 sm:grid-cols-2">
|
<Field.Field>
|
||||||
<Field.Field>
|
<Field.Label for={`${prefix}-name`}>Name</Field.Label>
|
||||||
<Field.Label for={`${prefix}-name`}>Name</Field.Label>
|
<Input
|
||||||
<Input
|
id={`${prefix}-name`}
|
||||||
id={`${prefix}-name`}
|
name="name"
|
||||||
name="name"
|
type="text"
|
||||||
type="text"
|
value={organization?.name ?? ''}
|
||||||
value={organization?.name ?? ''}
|
required
|
||||||
required
|
/>
|
||||||
/>
|
</Field.Field>
|
||||||
</Field.Field>
|
<Field.Field>
|
||||||
<Field.Field>
|
<Field.Label for={`${prefix}-address-line-1`}>Address line 1</Field.Label>
|
||||||
<Field.Label for={`${prefix}-address-line-1`}>Address line 1</Field.Label>
|
<Input
|
||||||
<Input
|
id={`${prefix}-address-line-1`}
|
||||||
id={`${prefix}-address-line-1`}
|
name="addressLine1"
|
||||||
name="addressLine1"
|
type="text"
|
||||||
type="text"
|
value={organization?.addressLine1 ?? ''}
|
||||||
value={organization?.addressLine1 ?? ''}
|
required
|
||||||
required
|
/>
|
||||||
/>
|
</Field.Field>
|
||||||
</Field.Field>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Field.Field>
|
<Field.Field>
|
||||||
<Field.Label for={`${prefix}-address-line-2`}>Address line 2</Field.Label>
|
<Field.Label for={`${prefix}-address-line-2`}>Address line 2</Field.Label>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Label } from '$lib/components/ui/label/index.js';
|
import { Label } from '$lib/components/ui/label/index.js';
|
||||||
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
|
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
|
||||||
import type { WithElementRef } from '$lib/utils.js';
|
import type { WithElementRef } from '$lib/utils/format.js';
|
||||||
import SearchIcon from '@lucide/svelte/icons/search';
|
import SearchIcon from '@lucide/svelte/icons/search';
|
||||||
import type { HTMLFormAttributes } from 'svelte/elements';
|
import type { HTMLFormAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||||
import { cn, type WithoutChild } from '$lib/utils.js';
|
import { cn, type WithoutChild } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,12 +13,12 @@
|
|||||||
<AccordionPrimitive.Content
|
<AccordionPrimitive.Content
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="accordion-content"
|
data-slot="accordion-content"
|
||||||
class="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
|
class="data-open:animate-accordion-down data-closed:animate-accordion-up text-sm overflow-hidden"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={cn(
|
class={cn(
|
||||||
'pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4',
|
"pt-0 pb-2.5 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3 [&_p:not(:last-child)]:mb-4",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,6 +12,6 @@
|
|||||||
<AccordionPrimitive.Item
|
<AccordionPrimitive.Item
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="accordion-item"
|
data-slot="accordion-item"
|
||||||
class={cn('not-last:border-b', className)}
|
class={cn("not-last:border-b", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||||
import { cn, type WithoutChild } from '$lib/utils.js';
|
import { cn, type WithoutChild } from "$lib/utils.js";
|
||||||
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
||||||
import ChevronUpIcon from '@lucide/svelte/icons/chevron-up';
|
import ChevronUpIcon from '@lucide/svelte/icons/chevron-up';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChild<AccordionPrimitive.TriggerProps> & {
|
}: WithoutChild<AccordionPrimitive.TriggerProps> & {
|
||||||
level?: AccordionPrimitive.HeaderProps['level'];
|
level?: AccordionPrimitive.HeaderProps["level"];
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -20,19 +20,13 @@
|
|||||||
data-slot="accordion-trigger"
|
data-slot="accordion-trigger"
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground',
|
"focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-lg py-2.5 text-left text-sm font-medium hover:underline focus-visible:ring-3 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-all outline-none disabled:pointer-events-none disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
<ChevronDownIcon
|
<ChevronDownIcon data-slot="accordion-trigger-icon" class="cn-accordion-trigger-icon pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden" />
|
||||||
data-slot="accordion-trigger-icon"
|
<ChevronUpIcon data-slot="accordion-trigger-icon" class="cn-accordion-trigger-icon pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline" />
|
||||||
class="cn-accordion-trigger-icon pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
|
|
||||||
/>
|
|
||||||
<ChevronUpIcon
|
|
||||||
data-slot="accordion-trigger-icon"
|
|
||||||
class="cn-accordion-trigger-icon pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
|
|
||||||
/>
|
|
||||||
</AccordionPrimitive.Trigger>
|
</AccordionPrimitive.Trigger>
|
||||||
</AccordionPrimitive.Header>
|
</AccordionPrimitive.Header>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Accordion as AccordionPrimitive } from 'bits-ui';
|
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
bind:ref
|
bind:ref
|
||||||
bind:value={value as never}
|
bind:value={value as never}
|
||||||
data-slot="accordion"
|
data-slot="accordion"
|
||||||
class={cn('cn-accordion flex w-full flex-col', className)}
|
class={cn("cn-accordion flex w-full flex-col", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Root from './accordion.svelte';
|
import Root from "./accordion.svelte";
|
||||||
import Content from './accordion-content.svelte';
|
import Content from "./accordion-content.svelte";
|
||||||
import Item from './accordion-item.svelte';
|
import Item from "./accordion-item.svelte";
|
||||||
import Trigger from './accordion-trigger.svelte';
|
import Trigger from "./accordion-trigger.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -12,5 +12,5 @@ export {
|
|||||||
Root as Accordion,
|
Root as Accordion,
|
||||||
Content as AccordionContent,
|
Content as AccordionContent,
|
||||||
Item as AccordionItem,
|
Item as AccordionItem,
|
||||||
Trigger as AccordionTrigger
|
Trigger as AccordionTrigger,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import {
|
import {
|
||||||
buttonVariants,
|
buttonVariants,
|
||||||
type ButtonVariant,
|
type ButtonVariant,
|
||||||
type ButtonSize
|
type ButtonSize,
|
||||||
} from '$lib/components/ui/button/index.js';
|
} from "$lib/components/ui/button/index.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = "default",
|
||||||
size = 'default',
|
size = "default",
|
||||||
...restProps
|
...restProps
|
||||||
}: AlertDialogPrimitive.ActionProps & {
|
}: AlertDialogPrimitive.ActionProps & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
@@ -22,6 +22,6 @@
|
|||||||
<AlertDialogPrimitive.Action
|
<AlertDialogPrimitive.Action
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="alert-dialog-action"
|
data-slot="alert-dialog-action"
|
||||||
class={cn(buttonVariants({ variant, size }), 'cn-alert-dialog-action', className)}
|
class={cn(buttonVariants({ variant, size }), "cn-alert-dialog-action", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import {
|
import {
|
||||||
buttonVariants,
|
buttonVariants,
|
||||||
type ButtonVariant,
|
type ButtonVariant,
|
||||||
type ButtonSize
|
type ButtonSize,
|
||||||
} from '$lib/components/ui/button/index.js';
|
} from "$lib/components/ui/button/index.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'outline',
|
variant = "outline",
|
||||||
size = 'default',
|
size = "default",
|
||||||
...restProps
|
...restProps
|
||||||
}: AlertDialogPrimitive.CancelProps & {
|
}: AlertDialogPrimitive.CancelProps & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
@@ -22,6 +22,6 @@
|
|||||||
<AlertDialogPrimitive.Cancel
|
<AlertDialogPrimitive.Cancel
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="alert-dialog-cancel"
|
data-slot="alert-dialog-cancel"
|
||||||
class={cn(buttonVariants({ variant, size }), 'cn-alert-dialog-cancel', className)}
|
class={cn(buttonVariants({ variant, size }), "cn-alert-dialog-cancel", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import AlertDialogPortal from './alert-dialog-portal.svelte';
|
import AlertDialogPortal from "./alert-dialog-portal.svelte";
|
||||||
import AlertDialogOverlay from './alert-dialog-overlay.svelte';
|
import AlertDialogOverlay from "./alert-dialog-overlay.svelte";
|
||||||
import { cn, type WithoutChild, type WithoutChildrenOrChild } from '$lib/utils.js';
|
import { cn, type WithoutChild, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||||
import type { ComponentProps } from 'svelte';
|
import type { ComponentProps } from "svelte";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
size = 'default',
|
size = "default",
|
||||||
portalProps,
|
portalProps,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChild<AlertDialogPrimitive.ContentProps> & {
|
}: WithoutChild<AlertDialogPrimitive.ContentProps> & {
|
||||||
size?: 'default' | 'sm';
|
size?: "default" | "sm";
|
||||||
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof AlertDialogPortal>>;
|
portalProps?: WithoutChildrenOrChild<ComponentProps<typeof AlertDialogPortal>>;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
data-slot="alert-dialog-content"
|
data-slot="alert-dialog-content"
|
||||||
data-size={size}
|
data-size={size}
|
||||||
class={cn(
|
class={cn(
|
||||||
'group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
|
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-popover text-popover-foreground ring-foreground/10 gap-4 rounded-xl p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,9 +12,6 @@
|
|||||||
<AlertDialogPrimitive.Description
|
<AlertDialogPrimitive.Description
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="alert-dialog-description"
|
data-slot="alert-dialog-description"
|
||||||
class={cn(
|
class={cn("text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3", className)}
|
||||||
'text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-dialog-footer"
|
data-slot="alert-dialog-footer"
|
||||||
class={cn(
|
class={cn(
|
||||||
'-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end',
|
"bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,10 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-dialog-header"
|
data-slot="alert-dialog-header"
|
||||||
class={cn(
|
class={cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className)}
|
||||||
'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,10 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-dialog-media"
|
data-slot="alert-dialog-media"
|
||||||
class={cn(
|
class={cn("bg-muted mb-2 inline-flex size-10 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6", className)}
|
||||||
"mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,9 +12,6 @@
|
|||||||
<AlertDialogPrimitive.Overlay
|
<AlertDialogPrimitive.Overlay
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="alert-dialog-overlay"
|
data-slot="alert-dialog-overlay"
|
||||||
class={cn(
|
class={cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50", className)}
|
||||||
'fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
|
|
||||||
let { ...restProps }: AlertDialogPrimitive.PortalProps = $props();
|
let { ...restProps }: AlertDialogPrimitive.PortalProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,9 +12,6 @@
|
|||||||
<AlertDialogPrimitive.Title
|
<AlertDialogPrimitive.Title
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="alert-dialog-title"
|
data-slot="alert-dialog-title"
|
||||||
class={cn(
|
class={cn("text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className)}
|
||||||
'text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
|
|
||||||
let { ref = $bindable(null), ...restProps }: AlertDialogPrimitive.TriggerProps = $props();
|
let { ref = $bindable(null), ...restProps }: AlertDialogPrimitive.TriggerProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||||
|
|
||||||
let { open = $bindable(false), ...restProps }: AlertDialogPrimitive.RootProps = $props();
|
let { open = $bindable(false), ...restProps }: AlertDialogPrimitive.RootProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import Root from './alert-dialog.svelte';
|
import Root from "./alert-dialog.svelte";
|
||||||
import Portal from './alert-dialog-portal.svelte';
|
import Portal from "./alert-dialog-portal.svelte";
|
||||||
import Trigger from './alert-dialog-trigger.svelte';
|
import Trigger from "./alert-dialog-trigger.svelte";
|
||||||
import Title from './alert-dialog-title.svelte';
|
import Title from "./alert-dialog-title.svelte";
|
||||||
import Action from './alert-dialog-action.svelte';
|
import Action from "./alert-dialog-action.svelte";
|
||||||
import Cancel from './alert-dialog-cancel.svelte';
|
import Cancel from "./alert-dialog-cancel.svelte";
|
||||||
import Footer from './alert-dialog-footer.svelte';
|
import Footer from "./alert-dialog-footer.svelte";
|
||||||
import Header from './alert-dialog-header.svelte';
|
import Header from "./alert-dialog-header.svelte";
|
||||||
import Overlay from './alert-dialog-overlay.svelte';
|
import Overlay from "./alert-dialog-overlay.svelte";
|
||||||
import Content from './alert-dialog-content.svelte';
|
import Content from "./alert-dialog-content.svelte";
|
||||||
import Description from './alert-dialog-description.svelte';
|
import Description from "./alert-dialog-description.svelte";
|
||||||
import Media from './alert-dialog-media.svelte';
|
import Media from "./alert-dialog-media.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -36,5 +36,5 @@ export {
|
|||||||
Overlay as AlertDialogOverlay,
|
Overlay as AlertDialogOverlay,
|
||||||
Content as AlertDialogContent,
|
Content as AlertDialogContent,
|
||||||
Description as AlertDialogDescription,
|
Description as AlertDialogDescription,
|
||||||
Media as AlertDialogMedia
|
Media as AlertDialogMedia,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-action"
|
data-slot="alert-action"
|
||||||
class={cn('absolute top-2 right-2', className)}
|
class={cn("absolute top-2 right-2", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-description"
|
data-slot="alert-description"
|
||||||
class={cn(
|
class={cn(
|
||||||
'text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4',
|
"text-muted-foreground text-sm text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="alert-title"
|
data-slot="alert-title"
|
||||||
class={cn(
|
class={cn(
|
||||||
'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground',
|
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,31 +1,30 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { type VariantProps, tv } from 'tailwind-variants';
|
import { type VariantProps, tv } from "tailwind-variants";
|
||||||
|
|
||||||
export const alertVariants = tv({
|
export const alertVariants = tv({
|
||||||
base: "grid gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 group/alert relative w-full",
|
base: "grid gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 group/alert relative w-full",
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-card text-card-foreground',
|
default: "bg-card text-card-foreground",
|
||||||
destructive:
|
destructive: "text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
|
||||||
'text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current'
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: 'default'
|
variant: "default",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type AlertVariant = VariantProps<typeof alertVariants>['variant'];
|
export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = "default",
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Root from './alert.svelte';
|
import Root from "./alert.svelte";
|
||||||
import Description from './alert-description.svelte';
|
import Description from "./alert-description.svelte";
|
||||||
import Title from './alert-title.svelte';
|
import Title from "./alert-title.svelte";
|
||||||
import Action from './alert-action.svelte';
|
import Action from "./alert-action.svelte";
|
||||||
export { alertVariants, type AlertVariant } from './alert.svelte';
|
export { alertVariants, type AlertVariant } from "./alert.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -13,5 +13,5 @@ export {
|
|||||||
Root as Alert,
|
Root as Alert,
|
||||||
Description as AlertDescription,
|
Description as AlertDescription,
|
||||||
Title as AlertTitle,
|
Title as AlertTitle,
|
||||||
Action as AlertAction
|
Action as AlertAction,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AspectRatio as AspectRatioPrimitive } from 'bits-ui';
|
import { AspectRatio as AspectRatioPrimitive } from "bits-ui";
|
||||||
|
|
||||||
let { ref = $bindable(null), ...restProps }: AspectRatioPrimitive.RootProps = $props();
|
let { ref = $bindable(null), ...restProps }: AspectRatioPrimitive.RootProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import Root from './aspect-ratio.svelte';
|
import Root from "./aspect-ratio.svelte";
|
||||||
|
|
||||||
export { Root, Root as AspectRatio };
|
export { Root, Root as AspectRatio };
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="avatar-badge"
|
data-slot="avatar-badge"
|
||||||
class={cn(
|
class={cn(
|
||||||
'absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none',
|
"bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none",
|
||||||
'group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden',
|
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
|
||||||
'group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2',
|
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
|
||||||
'group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2',
|
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
bind:ref
|
bind:ref
|
||||||
data-slot="avatar-fallback"
|
data-slot="avatar-fallback"
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs',
|
"bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="avatar-group-count"
|
data-slot="avatar-group-count"
|
||||||
class={cn(
|
class={cn(
|
||||||
'relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3',
|
"bg-muted text-muted-foreground size-8 rounded-full text-sm group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 ring-background relative flex shrink-0 items-center justify-center ring-2",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="avatar-group"
|
data-slot="avatar-group"
|
||||||
class={cn(
|
class={cn(
|
||||||
'cn-avatar-group group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background',
|
"cn-avatar-group *:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,6 +12,6 @@
|
|||||||
<AvatarPrimitive.Image
|
<AvatarPrimitive.Image
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="avatar-image"
|
data-slot="avatar-image"
|
||||||
class={cn('aspect-square size-full rounded-full object-cover', className)}
|
class={cn("rounded-full aspect-square size-full object-cover", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Avatar as AvatarPrimitive } from 'bits-ui';
|
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
loadingStatus = $bindable('loading'),
|
loadingStatus = $bindable("loading"),
|
||||||
size = 'default',
|
size = "default",
|
||||||
class: className,
|
class: className,
|
||||||
...restProps
|
...restProps
|
||||||
}: AvatarPrimitive.RootProps & {
|
}: AvatarPrimitive.RootProps & {
|
||||||
size?: 'default' | 'sm' | 'lg';
|
size?: "default" | "sm" | "lg";
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
data-slot="avatar"
|
data-slot="avatar"
|
||||||
data-size={size}
|
data-size={size}
|
||||||
class={cn(
|
class={cn(
|
||||||
'group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten',
|
"size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 after:border-border group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import Root from './avatar.svelte';
|
import Root from "./avatar.svelte";
|
||||||
import Image from './avatar-image.svelte';
|
import Image from "./avatar-image.svelte";
|
||||||
import Fallback from './avatar-fallback.svelte';
|
import Fallback from "./avatar-fallback.svelte";
|
||||||
import Badge from './avatar-badge.svelte';
|
import Badge from "./avatar-badge.svelte";
|
||||||
import Group from './avatar-group.svelte';
|
import Group from "./avatar-group.svelte";
|
||||||
import GroupCount from './avatar-group-count.svelte';
|
import GroupCount from "./avatar-group-count.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -18,5 +18,5 @@ export {
|
|||||||
Fallback as AvatarFallback,
|
Fallback as AvatarFallback,
|
||||||
Badge as AvatarBadge,
|
Badge as AvatarBadge,
|
||||||
Group as AvatarGroup,
|
Group as AvatarGroup,
|
||||||
GroupCount as AvatarGroupCount
|
GroupCount as AvatarGroupCount,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,36 +1,35 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { type VariantProps, tv } from 'tailwind-variants';
|
import { type VariantProps, tv } from "tailwind-variants";
|
||||||
|
|
||||||
export const badgeVariants = tv({
|
export const badgeVariants = tv({
|
||||||
base: 'h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-colors focus-visible:ring-[3px] [&>svg]:pointer-events-none',
|
base: "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-colors focus-visible:ring-[3px] [&>svg]:pointer-events-none",
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
|
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
||||||
secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80',
|
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
||||||
destructive:
|
destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
|
||||||
'bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20',
|
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
||||||
outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground',
|
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
||||||
ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50',
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
link: 'text-primary underline-offset-4 hover:underline'
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: 'default'
|
variant: "default",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type BadgeVariant = VariantProps<typeof badgeVariants>['variant'];
|
export type BadgeVariant = VariantProps<typeof badgeVariants>["variant"];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
import type { HTMLAnchorAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
href,
|
href,
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = "default",
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAnchorAttributes> & {
|
}: WithElementRef<HTMLAnchorAttributes> & {
|
||||||
@@ -39,7 +38,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:element
|
<svelte:element
|
||||||
this={href ? 'a' : 'span'}
|
this={href ? "a" : "span"}
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="badge"
|
data-slot="badge"
|
||||||
{href}
|
{href}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export { default as Badge } from './badge.svelte';
|
export { default as Badge } from "./badge.svelte";
|
||||||
export { badgeVariants, type BadgeVariant } from './badge.svelte';
|
export { badgeVariants, type BadgeVariant } from "./badge.svelte";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef, type WithoutChildren } from '$lib/utils.js';
|
import { cn, type WithElementRef, type WithoutChildren } from "$lib/utils.js";
|
||||||
import MoreHorizontalIcon from '@lucide/svelte/icons/more-horizontal';
|
import MoreHorizontalIcon from '@lucide/svelte/icons/more-horizontal';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
data-slot="breadcrumb-ellipsis"
|
data-slot="breadcrumb-ellipsis"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class={cn('flex size-5 items-center justify-center [&>svg]:size-4', className)}
|
class={cn("size-5 [&>svg]:size-4 flex items-center justify-center", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<MoreHorizontalIcon />
|
<MoreHorizontalIcon />
|
||||||
<span class="sr-only">More</span>
|
<span class="sr-only">More</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLLiAttributes } from 'svelte/elements';
|
import type { HTMLLiAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<li
|
<li
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="breadcrumb-item"
|
data-slot="breadcrumb-item"
|
||||||
class={cn('inline-flex items-center gap-1', className)}
|
class={cn("gap-1 inline-flex items-center", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
import type { HTMLAnchorAttributes } from "svelte/elements";
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from "svelte";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -15,10 +15,10 @@
|
|||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const attrs = $derived({
|
const attrs = $derived({
|
||||||
'data-slot': 'breadcrumb-link',
|
"data-slot": "breadcrumb-link",
|
||||||
class: cn('hover:text-foreground transition-colors', className),
|
class: cn("hover:text-foreground transition-colors", className),
|
||||||
href,
|
href,
|
||||||
...restProps
|
...restProps,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLOlAttributes } from 'svelte/elements';
|
import type { HTMLOlAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,10 +13,7 @@
|
|||||||
<ol
|
<ol
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="breadcrumb-list"
|
data-slot="breadcrumb-list"
|
||||||
class={cn(
|
class={cn("text-muted-foreground gap-1.5 text-sm flex flex-wrap items-center wrap-break-word", className)}
|
||||||
'flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
role="link"
|
role="link"
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
aria-current="page"
|
aria-current="page"
|
||||||
class={cn('font-normal text-foreground', className)}
|
class={cn("text-foreground font-normal", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLLiAttributes } from 'svelte/elements';
|
import type { HTMLLiAttributes } from "svelte/elements";
|
||||||
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -16,12 +16,12 @@
|
|||||||
data-slot="breadcrumb-separator"
|
data-slot="breadcrumb-separator"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class={cn('[&>svg]:size-3.5', className)}
|
class={cn("[&>svg]:size-3.5", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{#if children}
|
{#if children}
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
{:else}
|
{:else}
|
||||||
<ChevronRightIcon />
|
<ChevronRightIcon />
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { WithElementRef } from '$lib/utils.js';
|
import type { WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="breadcrumb"
|
data-slot="breadcrumb"
|
||||||
aria-label="breadcrumb"
|
aria-label="breadcrumb"
|
||||||
class={cn('cn-breadcrumb', className)}
|
class={cn("cn-breadcrumb", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import Root from './breadcrumb.svelte';
|
import Root from "./breadcrumb.svelte";
|
||||||
import Ellipsis from './breadcrumb-ellipsis.svelte';
|
import Ellipsis from "./breadcrumb-ellipsis.svelte";
|
||||||
import Item from './breadcrumb-item.svelte';
|
import Item from "./breadcrumb-item.svelte";
|
||||||
import Separator from './breadcrumb-separator.svelte';
|
import Separator from "./breadcrumb-separator.svelte";
|
||||||
import Link from './breadcrumb-link.svelte';
|
import Link from "./breadcrumb-link.svelte";
|
||||||
import List from './breadcrumb-list.svelte';
|
import List from "./breadcrumb-list.svelte";
|
||||||
import Page from './breadcrumb-page.svelte';
|
import Page from "./breadcrumb-page.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -21,5 +21,5 @@ export {
|
|||||||
Separator as BreadcrumbSeparator,
|
Separator as BreadcrumbSeparator,
|
||||||
Link as BreadcrumbLink,
|
Link as BreadcrumbLink,
|
||||||
List as BreadcrumbList,
|
List as BreadcrumbList,
|
||||||
Page as BreadcrumbPage
|
Page as BreadcrumbPage,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
import type { ComponentProps } from 'svelte';
|
import type { ComponentProps } from "svelte";
|
||||||
import { Separator } from '$lib/components/ui/separator/index.js';
|
import { Separator } from "$lib/components/ui/separator/index.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
orientation = 'vertical',
|
orientation = "vertical",
|
||||||
...restProps
|
...restProps
|
||||||
}: ComponentProps<typeof Separator> = $props();
|
}: ComponentProps<typeof Separator> = $props();
|
||||||
</script>
|
</script>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
data-slot="button-group-separator"
|
data-slot="button-group-separator"
|
||||||
{orientation}
|
{orientation}
|
||||||
class={cn(
|
class={cn(
|
||||||
'relative self-stretch bg-input data-[orientation=horizontal]:mx-px data-[orientation=horizontal]:w-auto data-[orientation=vertical]:my-px data-[orientation=vertical]:h-auto',
|
"bg-input relative self-stretch data-[orientation=horizontal]:mx-px data-[orientation=horizontal]:w-auto data-[orientation=vertical]:my-px data-[orientation=vertical]:h-auto",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from "svelte";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,11 +14,8 @@
|
|||||||
|
|
||||||
const mergedProps = $derived({
|
const mergedProps = $derived({
|
||||||
...restProps,
|
...restProps,
|
||||||
class: cn(
|
class: cn("bg-muted gap-2 rounded-lg border px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none", className),
|
||||||
"bg-muted gap-2 rounded-lg border px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none",
|
"data-slot": "button-group-text",
|
||||||
className
|
|
||||||
),
|
|
||||||
'data-slot': 'button-group-text'
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { tv, type VariantProps } from 'tailwind-variants';
|
import { tv, type VariantProps } from "tailwind-variants";
|
||||||
|
|
||||||
export const buttonGroupVariants = tv({
|
export const buttonGroupVariants = tv({
|
||||||
base: "has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
base: "has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
||||||
variants: {
|
variants: {
|
||||||
orientation: {
|
orientation: {
|
||||||
horizontal:
|
horizontal:
|
||||||
'[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! [&>[data-slot]]:rounded-r-none [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0',
|
"[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! [&>[data-slot]]:rounded-r-none [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0",
|
||||||
vertical:
|
vertical:
|
||||||
'[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! flex-col [&>[data-slot]]:rounded-b-none [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0'
|
"[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! flex-col [&>[data-slot]]:rounded-b-none [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
orientation: 'horizontal'
|
orientation: "horizontal",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ButtonGroupOrientation = VariantProps<typeof buttonGroupVariants>['orientation'];
|
export type ButtonGroupOrientation = VariantProps<typeof buttonGroupVariants>["orientation"];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
orientation = 'horizontal',
|
orientation = "horizontal",
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||||
orientation?: ButtonGroupOrientation;
|
orientation?: ButtonGroupOrientation;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Root, { buttonGroupVariants, type ButtonGroupOrientation } from './button-group.svelte';
|
import Root, { buttonGroupVariants, type ButtonGroupOrientation } from "./button-group.svelte";
|
||||||
import Text from './button-group-text.svelte';
|
import Text from "./button-group-text.svelte";
|
||||||
import Separator from './button-group-separator.svelte';
|
import Separator from "./button-group-separator.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -11,5 +11,5 @@ export {
|
|||||||
//
|
//
|
||||||
Root as ButtonGroup,
|
Root as ButtonGroup,
|
||||||
Text as ButtonGroupText,
|
Text as ButtonGroupText,
|
||||||
Separator as ButtonGroupSeparator
|
Separator as ButtonGroupSeparator,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,51 +1,41 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { resolve } from '$app/paths';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { PathnameWithSearchOrHash } from '$app/types';
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { type VariantProps, tv } from "tailwind-variants";
|
||||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
||||||
import { type VariantProps, tv } from 'tailwind-variants';
|
|
||||||
|
|
||||||
export const buttonVariants = tv({
|
export const buttonVariants = tv({
|
||||||
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 active:not-aria-[haspopup]:translate-y-px aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 active:not-aria-[haspopup]:translate-y-px aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
|
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
||||||
outline:
|
outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
||||||
'border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground',
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
||||||
secondary:
|
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
||||||
'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',
|
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
||||||
ghost:
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
'hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground',
|
|
||||||
destructive:
|
|
||||||
'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30',
|
|
||||||
link: 'text-primary underline-offset-4 hover:underline'
|
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default:
|
default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
||||||
'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
|
|
||||||
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
||||||
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||||
lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
|
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
||||||
icon: 'size-8',
|
icon: "size-8",
|
||||||
'icon-xs':
|
"icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
||||||
"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
"icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
||||||
'icon-sm':
|
"icon-lg": "size-9",
|
||||||
'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',
|
},
|
||||||
'icon-lg': 'size-9'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: 'default',
|
variant: "default",
|
||||||
size: 'default'
|
size: "default",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
||||||
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
|
||||||
|
|
||||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||||
Omit<WithElementRef<HTMLAnchorAttributes>, 'href'> & {
|
WithElementRef<HTMLAnchorAttributes> & {
|
||||||
href?: PathnameWithSearchOrHash;
|
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
size?: ButtonSize;
|
size?: ButtonSize;
|
||||||
};
|
};
|
||||||
@@ -54,35 +44,26 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let {
|
let {
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = "default",
|
||||||
size = 'default',
|
size = "default",
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
href = undefined,
|
href = undefined,
|
||||||
type = 'button',
|
type = "button",
|
||||||
disabled,
|
disabled,
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: ButtonProps = $props();
|
}: ButtonProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if href && disabled}
|
{#if href}
|
||||||
<a
|
<a
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="button"
|
data-slot="button"
|
||||||
class={cn(buttonVariants({ variant, size }), className)}
|
class={cn(buttonVariants({ variant, size }), className)}
|
||||||
aria-disabled="true"
|
href={disabled ? undefined : href}
|
||||||
role="link"
|
aria-disabled={disabled}
|
||||||
tabindex={-1}
|
role={disabled ? "link" : undefined}
|
||||||
{...restProps}
|
tabindex={disabled ? -1 : undefined}
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</a>
|
|
||||||
{:else if href}
|
|
||||||
<a
|
|
||||||
bind:this={ref}
|
|
||||||
data-slot="button"
|
|
||||||
class={cn(buttonVariants({ variant, size }), className)}
|
|
||||||
href={resolve(href as '/')}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import Root, {
|
|||||||
type ButtonProps,
|
type ButtonProps,
|
||||||
type ButtonSize,
|
type ButtonSize,
|
||||||
type ButtonVariant,
|
type ButtonVariant,
|
||||||
buttonVariants
|
buttonVariants,
|
||||||
} from './button.svelte';
|
} from "./button.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -13,5 +13,5 @@ export {
|
|||||||
buttonVariants,
|
buttonVariants,
|
||||||
type ButtonProps,
|
type ButtonProps,
|
||||||
type ButtonSize,
|
type ButtonSize,
|
||||||
type ButtonVariant
|
type ButtonVariant,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ComponentProps } from 'svelte';
|
import type { ComponentProps } from "svelte";
|
||||||
import type Calendar from './calendar.svelte';
|
import type Calendar from "./calendar.svelte";
|
||||||
import CalendarMonthSelect from './calendar-month-select.svelte';
|
import CalendarMonthSelect from "./calendar-month-select.svelte";
|
||||||
import CalendarYearSelect from './calendar-year-select.svelte';
|
import CalendarYearSelect from "./calendar-year-select.svelte";
|
||||||
import { DateFormatter, getLocalTimeZone, type DateValue } from '@internationalized/date';
|
import { DateFormatter, getLocalTimeZone, type DateValue } from "@internationalized/date";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
captionLayout,
|
captionLayout,
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
month,
|
month,
|
||||||
locale,
|
locale,
|
||||||
placeholder = $bindable(),
|
placeholder = $bindable(),
|
||||||
monthIndex = 0
|
monthIndex = 0,
|
||||||
}: {
|
}: {
|
||||||
captionLayout: ComponentProps<typeof Calendar>['captionLayout'];
|
captionLayout: ComponentProps<typeof Calendar>["captionLayout"];
|
||||||
months: ComponentProps<typeof CalendarMonthSelect>['months'];
|
months: ComponentProps<typeof CalendarMonthSelect>["months"];
|
||||||
monthFormat: ComponentProps<typeof CalendarMonthSelect>['monthFormat'];
|
monthFormat: ComponentProps<typeof CalendarMonthSelect>["monthFormat"];
|
||||||
years: ComponentProps<typeof CalendarYearSelect>['years'];
|
years: ComponentProps<typeof CalendarYearSelect>["years"];
|
||||||
yearFormat: ComponentProps<typeof CalendarYearSelect>['yearFormat'];
|
yearFormat: ComponentProps<typeof CalendarYearSelect>["yearFormat"];
|
||||||
month: DateValue;
|
month: DateValue;
|
||||||
placeholder: DateValue | undefined;
|
placeholder: DateValue | undefined;
|
||||||
locale: string;
|
locale: string;
|
||||||
@@ -29,13 +29,13 @@
|
|||||||
|
|
||||||
function formatYear(date: DateValue) {
|
function formatYear(date: DateValue) {
|
||||||
const dateObj = date.toDate(getLocalTimeZone());
|
const dateObj = date.toDate(getLocalTimeZone());
|
||||||
if (typeof yearFormat === 'function') return yearFormat(dateObj.getFullYear());
|
if (typeof yearFormat === "function") return yearFormat(dateObj.getFullYear());
|
||||||
return new DateFormatter(locale, { year: yearFormat }).format(dateObj);
|
return new DateFormatter(locale, { year: yearFormat }).format(dateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMonth(date: DateValue) {
|
function formatMonth(date: DateValue) {
|
||||||
const dateObj = date.toDate(getLocalTimeZone());
|
const dateObj = date.toDate(getLocalTimeZone());
|
||||||
if (typeof monthFormat === 'function') return monthFormat(dateObj.getMonth() + 1);
|
if (typeof monthFormat === "function") return monthFormat(dateObj.getMonth() + 1);
|
||||||
return new DateFormatter(locale, { month: monthFormat }).format(dateObj);
|
return new DateFormatter(locale, { month: monthFormat }).format(dateObj);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -58,15 +58,15 @@
|
|||||||
<CalendarYearSelect {years} {yearFormat} value={month.year} />
|
<CalendarYearSelect {years} {yearFormat} value={month.year} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
{#if captionLayout === 'dropdown'}
|
{#if captionLayout === "dropdown"}
|
||||||
{@render MonthSelect()}
|
{@render MonthSelect()}
|
||||||
{@render YearSelect()}
|
{@render YearSelect()}
|
||||||
{:else if captionLayout === 'dropdown-months'}
|
{:else if captionLayout === "dropdown-months"}
|
||||||
{@render MonthSelect()}
|
{@render MonthSelect()}
|
||||||
{#if placeholder}
|
{#if placeholder}
|
||||||
{formatYear(placeholder)}
|
{formatYear(placeholder)}
|
||||||
{/if}
|
{/if}
|
||||||
{:else if captionLayout === 'dropdown-years'}
|
{:else if captionLayout === "dropdown-years"}
|
||||||
{#if placeholder}
|
{#if placeholder}
|
||||||
{formatMonth(placeholder)}
|
{formatMonth(placeholder)}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<CalendarPrimitive.Cell
|
<CalendarPrimitive.Cell
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'relative size-(--cell-size) p-0 text-center text-sm focus-within:z-20 [&:first-child[data-selected]_[data-bits-day]]:rounded-s-(--cell-radius) [&:last-child[data-selected]_[data-bits-day]]:rounded-e-(--cell-radius)',
|
"relative size-(--cell-size) p-0 text-center text-sm focus-within:z-20 [&:first-child[data-selected]_[data-bits-day]]:rounded-s-(--cell-radius) [&:last-child[data-selected]_[data-bits-day]]:rounded-e-(--cell-radius)",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,21 +12,21 @@
|
|||||||
<CalendarPrimitive.Day
|
<CalendarPrimitive.Day
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex size-(--cell-size) flex-col items-center justify-center gap-1 rounded-(--cell-radius) p-0 leading-none font-normal whitespace-nowrap select-none',
|
"flex size-(--cell-size) flex-col items-center justify-center gap-1 rounded-(--cell-radius) p-0 leading-none font-normal whitespace-nowrap select-none",
|
||||||
'[&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)',
|
"[&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
|
||||||
'not-data-selected:hover:bg-accent/50 not-data-selected:hover:text-accent-foreground',
|
"not-data-selected:hover:bg-accent/50 not-data-selected:hover:text-accent-foreground",
|
||||||
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground [&[data-today][data-disabled]]:text-muted-foreground',
|
"[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground [&[data-today][data-disabled]]:text-muted-foreground",
|
||||||
'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:text-foreground',
|
"data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:text-foreground",
|
||||||
// Outside months
|
// Outside months
|
||||||
'[&[data-outside-month]:not([data-selected])]:text-muted-foreground [&[data-outside-month]:not([data-selected])]:hover:text-accent-foreground',
|
"[&[data-outside-month]:not([data-selected])]:text-muted-foreground [&[data-outside-month]:not([data-selected])]:hover:text-accent-foreground",
|
||||||
// Disabled
|
// Disabled
|
||||||
'data-[disabled]:pointer-events-none data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
|
"data-[disabled]:text-muted-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
// Unavailable
|
// Unavailable
|
||||||
'data-[unavailable]:text-muted-foreground data-[unavailable]:line-through',
|
"data-[unavailable]:text-muted-foreground data-[unavailable]:line-through",
|
||||||
// focus
|
// focus
|
||||||
'focus:relative focus:border-ring focus:ring-ring/50',
|
"focus:border-ring focus:ring-ring/50 focus:relative",
|
||||||
// inner spans
|
// inner spans
|
||||||
'[&>span]:text-xs [&>span]:opacity-70',
|
"[&>span]:text-xs [&>span]:opacity-70",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -9,4 +9,4 @@
|
|||||||
}: CalendarPrimitive.GridRowProps = $props();
|
}: CalendarPrimitive.GridRowProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CalendarPrimitive.GridRow bind:ref class={cn('flex', className)} {...restProps} />
|
<CalendarPrimitive.GridRow bind:ref class={cn("flex", className)} {...restProps} />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
|
|
||||||
<CalendarPrimitive.Grid
|
<CalendarPrimitive.Grid
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn('flex w-full border-collapse flex-col', className)}
|
class={cn("flex w-full border-collapse flex-col", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<CalendarPrimitive.HeadCell
|
<CalendarPrimitive.HeadCell
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'w-(--cell-size) rounded-md text-[0.8rem] font-normal text-muted-foreground',
|
"text-muted-foreground w-(--cell-size) rounded-md text-[0.8rem] font-normal",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<CalendarPrimitive.Header
|
<CalendarPrimitive.Header
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',
|
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
|
|
||||||
<CalendarPrimitive.Heading
|
<CalendarPrimitive.Heading
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn('px-(--cell-size) text-sm font-medium', className)}
|
class={cn("px-(--cell-size) text-sm font-medium", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||||
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
<span
|
<span
|
||||||
class={cn(
|
class={cn(
|
||||||
'relative flex rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50',
|
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<CalendarPrimitive.MonthSelect
|
<CalendarPrimitive.MonthSelect
|
||||||
bind:ref
|
bind:ref
|
||||||
class="absolute inset-0 bg-background opacity-0 dark:bg-popover dark:text-popover-foreground"
|
class="bg-background dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{#snippet child({ props, monthItems, selectedMonthItem })}
|
{#snippet child({ props, monthItems, selectedMonthItem })}
|
||||||
@@ -37,11 +37,11 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
<span
|
<span
|
||||||
class="flex h-(--cell-size) items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5 [&>svg]:text-muted-foreground"
|
class="[&>svg]:text-muted-foreground flex h-(--cell-size) items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
{monthItems.find((item) => item.value === value)?.label || selectedMonthItem.label}
|
{monthItems.find((item) => item.value === value)?.label || selectedMonthItem.label}
|
||||||
<ChevronDownIcon class={cn('size-4', className)} />
|
<ChevronDownIcon class={cn("size-4", className)} />
|
||||||
</span>
|
</span>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</CalendarPrimitive.MonthSelect>
|
</CalendarPrimitive.MonthSelect>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { type WithElementRef, cn } from '$lib/utils.js';
|
import { type WithElementRef, cn } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -10,6 +10,6 @@
|
|||||||
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
|
}: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div {...restProps} bind:this={ref} class={cn('flex w-full flex-col gap-4', className)}>
|
<div {...restProps} bind:this={ref} class={cn("flex w-full flex-col gap-4", className)}>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn('relative flex flex-col gap-4 md:flex-row', className)}
|
class={cn("relative flex flex-col gap-4 md:flex-row", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<nav
|
<nav
|
||||||
{...restProps}
|
{...restProps}
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn('absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', className)}
|
class={cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", className)}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
||||||
import { buttonVariants, type ButtonVariant } from '$lib/components/ui/button/index.js';
|
import { buttonVariants, type ButtonVariant } from "$lib/components/ui/button/index.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
variant = 'ghost',
|
variant = "ghost",
|
||||||
...restProps
|
...restProps
|
||||||
}: CalendarPrimitive.NextButtonProps & {
|
}: CalendarPrimitive.NextButtonProps & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
@@ -16,14 +16,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet Fallback()}
|
{#snippet Fallback()}
|
||||||
<ChevronRightIcon class={cn('size-4', className)} />
|
<ChevronRightIcon class={cn("size-4", className)} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<CalendarPrimitive.NextButton
|
<CalendarPrimitive.NextButton
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
buttonVariants({ variant }),
|
buttonVariants({ variant }),
|
||||||
'size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180',
|
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
|
import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
|
||||||
import { buttonVariants, type ButtonVariant } from '$lib/components/ui/button/index.js';
|
import { buttonVariants, type ButtonVariant } from "$lib/components/ui/button/index.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
variant = 'ghost',
|
variant = "ghost",
|
||||||
...restProps
|
...restProps
|
||||||
}: CalendarPrimitive.PrevButtonProps & {
|
}: CalendarPrimitive.PrevButtonProps & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
@@ -16,14 +16,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet Fallback()}
|
{#snippet Fallback()}
|
||||||
<ChevronLeftIcon class={cn('size-4', className)} />
|
<ChevronLeftIcon class={cn("size-4", className)} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<CalendarPrimitive.PrevButton
|
<CalendarPrimitive.PrevButton
|
||||||
bind:ref
|
bind:ref
|
||||||
class={cn(
|
class={cn(
|
||||||
buttonVariants({ variant }),
|
buttonVariants({ variant }),
|
||||||
'size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180',
|
"size-(--cell-size) bg-transparent p-0 select-none disabled:opacity-50 rtl:rotate-180",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||||
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
|
|
||||||
<span
|
<span
|
||||||
class={cn(
|
class={cn(
|
||||||
'relative flex rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50',
|
"has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<CalendarPrimitive.YearSelect
|
<CalendarPrimitive.YearSelect
|
||||||
bind:ref
|
bind:ref
|
||||||
class="absolute inset-0 opacity-0 dark:bg-popover dark:text-popover-foreground"
|
class="dark:bg-popover dark:text-popover-foreground absolute inset-0 opacity-0"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{#snippet child({ props, yearItems, selectedYearItem })}
|
{#snippet child({ props, yearItems, selectedYearItem })}
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
<span
|
<span
|
||||||
class="flex h-(--cell-size) items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5 [&>svg]:text-muted-foreground"
|
class="[&>svg]:text-muted-foreground flex h-(--cell-size) items-center gap-1 rounded-md ps-2 pe-1 text-sm font-medium select-none [&>svg]:size-3.5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
{yearItems.find((item) => item.value === value)?.label || selectedYearItem.label}
|
{yearItems.find((item) => item.value === value)?.label || selectedYearItem.label}
|
||||||
<ChevronDownIcon class={cn('size-4', className)} />
|
<ChevronDownIcon class={cn("size-4", className)} />
|
||||||
</span>
|
</span>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</CalendarPrimitive.YearSelect>
|
</CalendarPrimitive.YearSelect>
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Calendar as CalendarPrimitive } from 'bits-ui';
|
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||||
import * as Calendar from './index.js';
|
import * as Calendar from "./index.js";
|
||||||
import { cn, type WithoutChildrenOrChild } from '$lib/utils.js';
|
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||||
import type { ButtonVariant } from '../button/button.svelte';
|
import type { ButtonVariant } from "../button/button.svelte";
|
||||||
import { isEqualMonth, type DateValue } from '@internationalized/date';
|
import { isEqualMonth, type DateValue } from "@internationalized/date";
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from "svelte";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
value = $bindable(),
|
value = $bindable(),
|
||||||
placeholder = $bindable(),
|
placeholder = $bindable(),
|
||||||
class: className,
|
class: className,
|
||||||
weekdayFormat = 'short',
|
weekdayFormat = "short",
|
||||||
buttonVariant = 'ghost',
|
buttonVariant = "ghost",
|
||||||
captionLayout = 'label',
|
captionLayout = "label",
|
||||||
locale = 'en-US',
|
locale = "en-US",
|
||||||
months: monthsProp,
|
months: monthsProp,
|
||||||
years,
|
years,
|
||||||
monthFormat: monthFormatProp,
|
monthFormat: monthFormatProp,
|
||||||
yearFormat = 'numeric',
|
yearFormat = "numeric",
|
||||||
day,
|
day,
|
||||||
disableDaysOutsideMonth = false,
|
disableDaysOutsideMonth = false,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChildrenOrChild<CalendarPrimitive.RootProps> & {
|
}: WithoutChildrenOrChild<CalendarPrimitive.RootProps> & {
|
||||||
buttonVariant?: ButtonVariant;
|
buttonVariant?: ButtonVariant;
|
||||||
captionLayout?: 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label';
|
captionLayout?: "dropdown" | "dropdown-months" | "dropdown-years" | "label";
|
||||||
months?: CalendarPrimitive.MonthSelectProps['months'];
|
months?: CalendarPrimitive.MonthSelectProps["months"];
|
||||||
years?: CalendarPrimitive.YearSelectProps['years'];
|
years?: CalendarPrimitive.YearSelectProps["years"];
|
||||||
monthFormat?: CalendarPrimitive.MonthSelectProps['monthFormat'];
|
monthFormat?: CalendarPrimitive.MonthSelectProps["monthFormat"];
|
||||||
yearFormat?: CalendarPrimitive.YearSelectProps['yearFormat'];
|
yearFormat?: CalendarPrimitive.YearSelectProps["yearFormat"];
|
||||||
day?: Snippet<[{ day: DateValue; outsideMonth: boolean }]>;
|
day?: Snippet<[{ day: DateValue; outsideMonth: boolean }]>;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const monthFormat = $derived.by(() => {
|
const monthFormat = $derived.by(() => {
|
||||||
if (monthFormatProp) return monthFormatProp;
|
if (monthFormatProp) return monthFormatProp;
|
||||||
if (captionLayout.startsWith('dropdown')) return 'short';
|
if (captionLayout.startsWith("dropdown")) return "short";
|
||||||
return 'long';
|
return "long";
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ get along, so we shut typescript up by casting `value` to `never`.
|
|||||||
{weekdayFormat}
|
{weekdayFormat}
|
||||||
{disableDaysOutsideMonth}
|
{disableDaysOutsideMonth}
|
||||||
class={cn(
|
class={cn(
|
||||||
'group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent',
|
"p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] bg-background group/calendar in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{locale}
|
{locale}
|
||||||
@@ -97,7 +97,7 @@ get along, so we shut typescript up by casting `value` to `never`.
|
|||||||
{#if day}
|
{#if day}
|
||||||
{@render day({
|
{@render day({
|
||||||
day: date,
|
day: date,
|
||||||
outsideMonth: !isEqualMonth(date, month.value)
|
outsideMonth: !isEqualMonth(date, month.value),
|
||||||
})}
|
})}
|
||||||
{:else}
|
{:else}
|
||||||
<Calendar.Day />
|
<Calendar.Day />
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import Root from './calendar.svelte';
|
import Root from "./calendar.svelte";
|
||||||
import Cell from './calendar-cell.svelte';
|
import Cell from "./calendar-cell.svelte";
|
||||||
import Day from './calendar-day.svelte';
|
import Day from "./calendar-day.svelte";
|
||||||
import Grid from './calendar-grid.svelte';
|
import Grid from "./calendar-grid.svelte";
|
||||||
import Header from './calendar-header.svelte';
|
import Header from "./calendar-header.svelte";
|
||||||
import Months from './calendar-months.svelte';
|
import Months from "./calendar-months.svelte";
|
||||||
import GridRow from './calendar-grid-row.svelte';
|
import GridRow from "./calendar-grid-row.svelte";
|
||||||
import Heading from './calendar-heading.svelte';
|
import Heading from "./calendar-heading.svelte";
|
||||||
import GridBody from './calendar-grid-body.svelte';
|
import GridBody from "./calendar-grid-body.svelte";
|
||||||
import GridHead from './calendar-grid-head.svelte';
|
import GridHead from "./calendar-grid-head.svelte";
|
||||||
import HeadCell from './calendar-head-cell.svelte';
|
import HeadCell from "./calendar-head-cell.svelte";
|
||||||
import NextButton from './calendar-next-button.svelte';
|
import NextButton from "./calendar-next-button.svelte";
|
||||||
import PrevButton from './calendar-prev-button.svelte';
|
import PrevButton from "./calendar-prev-button.svelte";
|
||||||
import MonthSelect from './calendar-month-select.svelte';
|
import MonthSelect from "./calendar-month-select.svelte";
|
||||||
import YearSelect from './calendar-year-select.svelte';
|
import YearSelect from "./calendar-year-select.svelte";
|
||||||
import Month from './calendar-month.svelte';
|
import Month from "./calendar-month.svelte";
|
||||||
import Nav from './calendar-nav.svelte';
|
import Nav from "./calendar-nav.svelte";
|
||||||
import Caption from './calendar-caption.svelte';
|
import Caption from "./calendar-caption.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Day,
|
Day,
|
||||||
@@ -36,5 +36,5 @@ export {
|
|||||||
MonthSelect,
|
MonthSelect,
|
||||||
Caption,
|
Caption,
|
||||||
//
|
//
|
||||||
Root as Calendar
|
Root as Calendar,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-action"
|
data-slot="card-action"
|
||||||
class={cn(
|
class={cn(
|
||||||
'cn-card-action col-start-2 row-span-2 row-start-1 self-start justify-self-end',
|
"cn-card-action col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-content"
|
data-slot="card-content"
|
||||||
class={cn('px-4 group-data-[size=sm]/card:px-3', className)}
|
class={cn("px-4 group-data-[size=sm]/card:px-3", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<p
|
<p
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-description"
|
data-slot="card-description"
|
||||||
class={cn('text-sm text-muted-foreground', className)}
|
class={cn("text-muted-foreground text-sm", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,10 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-footer"
|
data-slot="card-footer"
|
||||||
class={cn(
|
class={cn("bg-muted/50 rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3 flex items-center", className)}
|
||||||
'flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-header"
|
data-slot="card-header"
|
||||||
class={cn(
|
class={cn(
|
||||||
'group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3',
|
"gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card-title"
|
data-slot="card-title"
|
||||||
class={cn('text-base leading-snug font-medium group-data-[size=sm]/card:text-sm', className)}
|
class={cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
size = 'default',
|
size = "default",
|
||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & { size?: 'default' | 'sm' } = $props();
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & { size?: "default" | "sm" } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="card"
|
data-slot="card"
|
||||||
data-size={size}
|
data-size={size}
|
||||||
class={cn(
|
class={cn("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)}
|
||||||
'group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import Root from './card.svelte';
|
import Root from "./card.svelte";
|
||||||
import Content from './card-content.svelte';
|
import Content from "./card-content.svelte";
|
||||||
import Description from './card-description.svelte';
|
import Description from "./card-description.svelte";
|
||||||
import Footer from './card-footer.svelte';
|
import Footer from "./card-footer.svelte";
|
||||||
import Header from './card-header.svelte';
|
import Header from "./card-header.svelte";
|
||||||
import Title from './card-title.svelte';
|
import Title from "./card-title.svelte";
|
||||||
import Action from './card-action.svelte';
|
import Action from "./card-action.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -21,5 +21,5 @@ export {
|
|||||||
Footer as CardFooter,
|
Footer as CardFooter,
|
||||||
Header as CardHeader,
|
Header as CardHeader,
|
||||||
Title as CardTitle,
|
Title as CardTitle,
|
||||||
Action as CardAction
|
Action as CardAction,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import emblaCarouselSvelte from 'embla-carousel-svelte';
|
import emblaCarouselSvelte from "embla-carousel-svelte";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { getEmblaContext } from './context.js';
|
import { getEmblaContext } from "./context.js";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
|
||||||
const emblaCtx = getEmblaContext('<Carousel.Content/>');
|
const emblaCtx = getEmblaContext("<Carousel.Content/>");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -19,20 +19,20 @@
|
|||||||
class="overflow-hidden"
|
class="overflow-hidden"
|
||||||
use:emblaCarouselSvelte={{
|
use:emblaCarouselSvelte={{
|
||||||
options: {
|
options: {
|
||||||
container: '[data-embla-container]',
|
container: "[data-embla-container]",
|
||||||
slides: '[data-embla-slide]',
|
slides: "[data-embla-slide]",
|
||||||
...emblaCtx.options,
|
...emblaCtx.options,
|
||||||
axis: emblaCtx.orientation === 'horizontal' ? 'x' : 'y'
|
axis: emblaCtx.orientation === "horizontal" ? "x" : "y",
|
||||||
},
|
},
|
||||||
plugins: emblaCtx.plugins
|
plugins: emblaCtx.plugins,
|
||||||
}}
|
}}
|
||||||
onemblaInit={emblaCtx.onInit}
|
onemblaInit={emblaCtx.onInit}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex',
|
"flex",
|
||||||
emblaCtx.orientation === 'horizontal' ? '-ms-4' : '-mt-4 flex-col',
|
emblaCtx.orientation === "horizontal" ? "-ms-4" : "-mt-4 flex-col",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
data-embla-container=""
|
data-embla-container=""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { getEmblaContext } from './context.js';
|
import { getEmblaContext } from "./context.js";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
...restProps
|
...restProps
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
|
||||||
const emblaCtx = getEmblaContext('<Carousel.Item/>');
|
const emblaCtx = getEmblaContext("<Carousel.Item/>");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
role="group"
|
role="group"
|
||||||
aria-roledescription="slide"
|
aria-roledescription="slide"
|
||||||
class={cn(
|
class={cn(
|
||||||
'min-w-0 shrink-0 grow-0 basis-full',
|
"min-w-0 shrink-0 grow-0 basis-full",
|
||||||
emblaCtx.orientation === 'horizontal' ? 'ps-4' : 'pt-4',
|
emblaCtx.orientation === "horizontal" ? "ps-4" : "pt-4",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
data-embla-slide=""
|
data-embla-slide=""
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { WithoutChildren } from 'bits-ui';
|
import type { WithoutChildren } from "bits-ui";
|
||||||
import { getEmblaContext } from './context.js';
|
import { getEmblaContext } from "./context.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
import { Button, type Props } from '$lib/components/ui/button/index.js';
|
import { Button, type Props } from "$lib/components/ui/button/index.js";
|
||||||
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'outline',
|
variant = "outline",
|
||||||
size = 'icon-sm',
|
size = "icon-sm",
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChildren<Props> = $props();
|
}: WithoutChildren<Props> = $props();
|
||||||
|
|
||||||
const emblaCtx = getEmblaContext('<Carousel.Next/>');
|
const emblaCtx = getEmblaContext("<Carousel.Next/>");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
aria-disabled={!emblaCtx.canScrollNext}
|
aria-disabled={!emblaCtx.canScrollNext}
|
||||||
disabled={!emblaCtx.canScrollNext}
|
disabled={!emblaCtx.canScrollNext}
|
||||||
class={cn(
|
class={cn(
|
||||||
'absolute touch-manipulation rounded-full',
|
"rounded-full absolute touch-manipulation",
|
||||||
emblaCtx.orientation === 'horizontal'
|
emblaCtx.orientation === "horizontal"
|
||||||
? '-end-12 top-1/2 -translate-y-1/2'
|
? "-end-12 top-1/2 -translate-y-1/2"
|
||||||
: 'start-1/2 -bottom-12 -translate-x-1/2 rotate-90',
|
: "start-1/2 -bottom-12 -translate-x-1/2 rotate-90",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
onclick={emblaCtx.scrollNext}
|
onclick={emblaCtx.scrollNext}
|
||||||
@@ -34,6 +34,6 @@
|
|||||||
bind:ref
|
bind:ref
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<ChevronRightIcon />
|
<ChevronRightIcon />
|
||||||
<span class="sr-only">Next slide</span>
|
<span class="sr-only">Next slide</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { WithoutChildren } from 'bits-ui';
|
import type { WithoutChildren } from "bits-ui";
|
||||||
import { getEmblaContext } from './context.js';
|
import { getEmblaContext } from "./context.js";
|
||||||
import { cn } from '$lib/utils.js';
|
import { cn } from "$lib/utils.js";
|
||||||
import { Button, type Props } from '$lib/components/ui/button/index.js';
|
import { Button, type Props } from "$lib/components/ui/button/index.js";
|
||||||
import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
|
import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'outline',
|
variant = "outline",
|
||||||
size = 'icon-sm',
|
size = "icon-sm",
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChildren<Props> = $props();
|
}: WithoutChildren<Props> = $props();
|
||||||
|
|
||||||
const emblaCtx = getEmblaContext('<Carousel.Previous/>');
|
const emblaCtx = getEmblaContext("<Carousel.Previous/>");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
aria-disabled={!emblaCtx.canScrollPrev}
|
aria-disabled={!emblaCtx.canScrollPrev}
|
||||||
disabled={!emblaCtx.canScrollPrev}
|
disabled={!emblaCtx.canScrollPrev}
|
||||||
class={cn(
|
class={cn(
|
||||||
'absolute touch-manipulation rounded-full',
|
"rounded-full absolute touch-manipulation",
|
||||||
emblaCtx.orientation === 'horizontal'
|
emblaCtx.orientation === "horizontal"
|
||||||
? '-start-12 top-1/2 -translate-y-1/2'
|
? "-start-12 top-1/2 -translate-y-1/2"
|
||||||
: 'start-1/2 -top-12 -translate-x-1/2 rotate-90',
|
: "start-1/2 -top-12 -translate-x-1/2 rotate-90",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
onclick={emblaCtx.scrollPrev}
|
onclick={emblaCtx.scrollPrev}
|
||||||
@@ -34,6 +34,6 @@
|
|||||||
{...restProps}
|
{...restProps}
|
||||||
bind:ref
|
bind:ref
|
||||||
>
|
>
|
||||||
<ChevronLeftIcon />
|
<ChevronLeftIcon />
|
||||||
<span class="sr-only">Previous slide</span>
|
<span class="sr-only">Previous slide</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
type CarouselAPI,
|
type CarouselAPI,
|
||||||
type CarouselProps,
|
type CarouselProps,
|
||||||
type EmblaContext,
|
type EmblaContext,
|
||||||
setEmblaContext
|
setEmblaContext,
|
||||||
} from './context.js';
|
} from "./context.js";
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
opts = {},
|
opts = {},
|
||||||
plugins = [],
|
plugins = [],
|
||||||
setApi = () => {},
|
setApi = () => {},
|
||||||
orientation = 'horizontal',
|
orientation = "horizontal",
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
onInit,
|
onInit,
|
||||||
scrollSnaps: [],
|
scrollSnaps: [],
|
||||||
selectedIndex: 0,
|
selectedIndex: 0,
|
||||||
scrollTo
|
scrollTo,
|
||||||
});
|
});
|
||||||
|
|
||||||
setEmblaContext(carouselState);
|
setEmblaContext(carouselState);
|
||||||
@@ -57,10 +57,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyDown(e: KeyboardEvent) {
|
function handleKeyDown(e: KeyboardEvent) {
|
||||||
if (e.key === 'ArrowLeft') {
|
if (e.key === "ArrowLeft") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
scrollPrev();
|
scrollPrev();
|
||||||
} else if (e.key === 'ArrowRight') {
|
} else if (e.key === "ArrowRight") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
scrollNext();
|
scrollNext();
|
||||||
}
|
}
|
||||||
@@ -71,13 +71,13 @@
|
|||||||
setApi(carouselState.api);
|
setApi(carouselState.api);
|
||||||
|
|
||||||
carouselState.scrollSnaps = carouselState.api.scrollSnapList();
|
carouselState.scrollSnaps = carouselState.api.scrollSnapList();
|
||||||
carouselState.api.on('select', onSelect);
|
carouselState.api.on("select", onSelect);
|
||||||
onSelect();
|
onSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
carouselState.api?.off('select', onSelect);
|
carouselState.api?.off("select", onSelect);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="carousel"
|
data-slot="carousel"
|
||||||
class={cn('relative', className)}
|
class={cn("relative", className)}
|
||||||
role="region"
|
role="region"
|
||||||
aria-roledescription="carousel"
|
aria-roledescription="carousel"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import type { WithElementRef } from '$lib/utils.js';
|
import type { WithElementRef } from "$lib/utils.js";
|
||||||
import type {
|
import type {
|
||||||
EmblaCarouselSvelteType,
|
EmblaCarouselSvelteType,
|
||||||
default as emblaCarouselSvelte
|
default as emblaCarouselSvelte,
|
||||||
} from 'embla-carousel-svelte';
|
} from "embla-carousel-svelte";
|
||||||
import { getContext, hasContext, setContext } from 'svelte';
|
import { getContext, hasContext, setContext } from "svelte";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
export type CarouselAPI =
|
export type CarouselAPI =
|
||||||
NonNullable<NonNullable<EmblaCarouselSvelteType['$$_attributes']>['on:emblaInit']> extends (
|
NonNullable<NonNullable<EmblaCarouselSvelteType["$$_attributes"]>["on:emblaInit"]> extends (
|
||||||
evt: CustomEvent<infer CarouselAPI>
|
evt: CustomEvent<infer CarouselAPI>
|
||||||
) => void
|
) => void
|
||||||
? CarouselAPI
|
? CarouselAPI
|
||||||
@@ -15,8 +15,8 @@ export type CarouselAPI =
|
|||||||
|
|
||||||
type EmblaCarouselConfig = NonNullable<Parameters<typeof emblaCarouselSvelte>[1]>;
|
type EmblaCarouselConfig = NonNullable<Parameters<typeof emblaCarouselSvelte>[1]>;
|
||||||
|
|
||||||
export type CarouselOptions = EmblaCarouselConfig['options'];
|
export type CarouselOptions = EmblaCarouselConfig["options"];
|
||||||
export type CarouselPlugins = EmblaCarouselConfig['plugins'];
|
export type CarouselPlugins = EmblaCarouselConfig["plugins"];
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
@@ -24,14 +24,14 @@ export type CarouselProps = {
|
|||||||
opts?: CarouselOptions;
|
opts?: CarouselOptions;
|
||||||
plugins?: CarouselPlugins;
|
plugins?: CarouselPlugins;
|
||||||
setApi?: (api: CarouselAPI | undefined) => void;
|
setApi?: (api: CarouselAPI | undefined) => void;
|
||||||
orientation?: 'horizontal' | 'vertical';
|
orientation?: "horizontal" | "vertical";
|
||||||
} & WithElementRef<HTMLAttributes<HTMLDivElement>>;
|
} & WithElementRef<HTMLAttributes<HTMLDivElement>>;
|
||||||
|
|
||||||
const EMBLA_CAROUSEL_CONTEXT = Symbol('EMBLA_CAROUSEL_CONTEXT');
|
const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT");
|
||||||
|
|
||||||
export type EmblaContext = {
|
export type EmblaContext = {
|
||||||
api: CarouselAPI | undefined;
|
api: CarouselAPI | undefined;
|
||||||
orientation: 'horizontal' | 'vertical';
|
orientation: "horizontal" | "vertical";
|
||||||
scrollNext: () => void;
|
scrollNext: () => void;
|
||||||
scrollPrev: () => void;
|
scrollPrev: () => void;
|
||||||
canScrollNext: boolean;
|
canScrollNext: boolean;
|
||||||
@@ -50,7 +50,7 @@ export function setEmblaContext(config: EmblaContext): EmblaContext {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEmblaContext(name = 'This component') {
|
export function getEmblaContext(name = "This component") {
|
||||||
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
|
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
|
||||||
throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Root from './carousel.svelte';
|
import Root from "./carousel.svelte";
|
||||||
import Content from './carousel-content.svelte';
|
import Content from "./carousel-content.svelte";
|
||||||
import Item from './carousel-item.svelte';
|
import Item from "./carousel-item.svelte";
|
||||||
import Previous from './carousel-previous.svelte';
|
import Previous from "./carousel-previous.svelte";
|
||||||
import Next from './carousel-next.svelte';
|
import Next from "./carousel-next.svelte";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Root,
|
Root,
|
||||||
@@ -15,5 +15,5 @@ export {
|
|||||||
Content as CarouselContent,
|
Content as CarouselContent,
|
||||||
Item as CarouselItem,
|
Item as CarouselItem,
|
||||||
Previous as CarouselPrevious,
|
Previous as CarouselPrevious,
|
||||||
Next as CarouselNext
|
Next as CarouselNext,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import ChartStyle from './chart-style.svelte';
|
import ChartStyle from "./chart-style.svelte";
|
||||||
import { setChartContext, type ChartConfig } from './chart-utils.js';
|
import { setChartContext, type ChartConfig } from "./chart-utils.js";
|
||||||
|
|
||||||
const uid = $props.id();
|
const uid = $props.id();
|
||||||
|
|
||||||
@@ -17,12 +17,12 @@
|
|||||||
config: ChartConfig;
|
config: ChartConfig;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const chartId = $derived(`chart-${id || uid.replace(/:/g, '')}`);
|
const chartId = $derived(`chart-${id || uid.replace(/:/g, "")}`);
|
||||||
|
|
||||||
setChartContext({
|
setChartContext({
|
||||||
get config() {
|
get config() {
|
||||||
return config;
|
return config;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -31,46 +31,46 @@
|
|||||||
data-chart={chartId}
|
data-chart={chartId}
|
||||||
data-slot="chart"
|
data-slot="chart"
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex aspect-video justify-center overflow-visible text-xs',
|
"flex aspect-video justify-center overflow-visible text-xs",
|
||||||
// Overrides
|
// Overrides
|
||||||
//
|
//
|
||||||
// Stroke around dots/marks when hovering
|
// Stroke around dots/marks when hovering
|
||||||
'[&_.lc-highlight-point]:stroke-transparent',
|
"[&_.lc-highlight-point]:stroke-transparent",
|
||||||
// override the default stroke color of lines
|
// override the default stroke color of lines
|
||||||
'[&_.lc-line]:stroke-border/50',
|
"[&_.lc-line]:stroke-border/50",
|
||||||
|
|
||||||
// by default, layerchart shows a line intersecting the point when hovering, this hides that
|
// by default, layerchart shows a line intersecting the point when hovering, this hides that
|
||||||
'[&_.lc-highlight-line]:stroke-0',
|
"[&_.lc-highlight-line]:stroke-0",
|
||||||
|
|
||||||
// by default, when you hover a point on a stacked series chart, it will drop the opacity
|
// by default, when you hover a point on a stacked series chart, it will drop the opacity
|
||||||
// of the other series, this overrides that
|
// of the other series, this overrides that
|
||||||
'[&_.lc-area-path]:opacity-100 [&_.lc-highlight-line]:opacity-100 [&_.lc-highlight-point]:opacity-100 [&_.lc-spline-path]:opacity-100 [&_.lc-text]:text-xs [&_.lc-text-svg]:overflow-visible',
|
"[&_.lc-area-path]:opacity-100 [&_.lc-highlight-line]:opacity-100 [&_.lc-highlight-point]:opacity-100 [&_.lc-spline-path]:opacity-100 [&_.lc-text]:text-xs [&_.lc-text-svg]:overflow-visible",
|
||||||
|
|
||||||
// We don't want the little tick lines between the axis labels and the chart, so we remove
|
// We don't want the little tick lines between the axis labels and the chart, so we remove
|
||||||
// the stroke. The alternative is to manually disable `tickMarks` on the x/y axis of every
|
// the stroke. The alternative is to manually disable `tickMarks` on the x/y axis of every
|
||||||
// chart.
|
// chart.
|
||||||
'[&_.lc-axis-tick]:stroke-0',
|
"[&_.lc-axis-tick]:stroke-0",
|
||||||
|
|
||||||
// We don't want to display the rule on the x/y axis, as there is already going to be
|
// We don't want to display the rule on the x/y axis, as there is already going to be
|
||||||
// a grid line there and rule ends up overlapping the marks because it is rendered after
|
// a grid line there and rule ends up overlapping the marks because it is rendered after
|
||||||
// the marks
|
// the marks
|
||||||
'[&_.lc-rule-x-line:not(.lc-grid-x-rule)]:stroke-0 [&_.lc-rule-y-line:not(.lc-grid-y-rule)]:stroke-0',
|
"[&_.lc-rule-x-line:not(.lc-grid-x-rule)]:stroke-0 [&_.lc-rule-y-line:not(.lc-grid-y-rule)]:stroke-0",
|
||||||
'[&_.lc-grid-x-radial-circle]:stroke-border [&_.lc-grid-x-radial-line]:stroke-border',
|
"[&_.lc-grid-x-radial-line]:stroke-border [&_.lc-grid-x-radial-circle]:stroke-border",
|
||||||
'[&_.lc-grid-y-radial-circle]:stroke-border [&_.lc-grid-y-radial-line]:stroke-border',
|
"[&_.lc-grid-y-radial-line]:stroke-border [&_.lc-grid-y-radial-circle]:stroke-border",
|
||||||
|
|
||||||
// Legend adjustments
|
// Legend adjustments
|
||||||
'[&_.lc-legend-swatch-button]:items-center [&_.lc-legend-swatch-button]:gap-1.5',
|
"[&_.lc-legend-swatch-button]:items-center [&_.lc-legend-swatch-button]:gap-1.5",
|
||||||
'[&_.lc-legend-swatch-group]:items-center [&_.lc-legend-swatch-group]:gap-4',
|
"[&_.lc-legend-swatch-group]:items-center [&_.lc-legend-swatch-group]:gap-4",
|
||||||
'[&_.lc-legend-swatch]:size-2.5 [&_.lc-legend-swatch]:rounded-[2px]',
|
"[&_.lc-legend-swatch]:size-2.5 [&_.lc-legend-swatch]:rounded-[2px]",
|
||||||
|
|
||||||
// Labels
|
// Labels
|
||||||
'[&_.lc-labels-text:not([fill])]:fill-foreground [&_text]:stroke-transparent',
|
"[&_.lc-labels-text:not([fill])]:fill-foreground [&_text]:stroke-transparent",
|
||||||
|
|
||||||
// Tick labels on th x/y axes
|
// Tick labels on th x/y axes
|
||||||
'[&_.lc-axis-tick-label]:fill-muted-foreground [&_.lc-axis-tick-label]:font-normal',
|
"[&_.lc-axis-tick-label]:fill-muted-foreground [&_.lc-axis-tick-label]:font-normal",
|
||||||
'[&_.lc-tooltip-rects-g]:fill-transparent',
|
"[&_.lc-tooltip-rects-g]:fill-transparent",
|
||||||
'[&_.lc-layout-svg-g]:fill-transparent',
|
"[&_.lc-layout-svg-g]:fill-transparent",
|
||||||
'[&_.lc-root-container]:w-full',
|
"[&_.lc-root-container]:w-full",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { THEMES, type ChartConfig } from './chart-utils.js';
|
import { THEMES, type ChartConfig } from "./chart-utils.js";
|
||||||
|
|
||||||
let { id, config }: { id: string; config: ChartConfig } = $props();
|
let { id, config }: { id: string; config: ChartConfig } = $props();
|
||||||
|
|
||||||
@@ -19,18 +19,18 @@
|
|||||||
return color ? `\t--color-${key}: ${color};` : null;
|
return color ? `\t--color-${key}: ${color};` : null;
|
||||||
});
|
});
|
||||||
|
|
||||||
content += color.join('\n') + '\n}';
|
content += color.join("\n") + "\n}";
|
||||||
|
|
||||||
themeContents.push(content);
|
themeContents.push(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return themeContents.join('\n');
|
return themeContents.join("\n");
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if themeContents}
|
{#if themeContents}
|
||||||
{#key id}
|
{#key id}
|
||||||
<svelte:element this={'style'}>
|
<svelte:element this={"style"}>
|
||||||
{themeContents}
|
{themeContents}
|
||||||
</svelte:element>
|
</svelte:element>
|
||||||
{/key}
|
{/key}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { cn, type WithElementRef, type WithoutChildren } from '$lib/utils.js';
|
import { cn, type WithElementRef, type WithoutChildren } from "$lib/utils.js";
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
import { getPayloadConfigFromPayload, useChart, type TooltipPayload } from './chart-utils.js';
|
import { getPayloadConfigFromPayload, useChart, type TooltipPayload } from "./chart-utils.js";
|
||||||
import { getChartContext, Tooltip as TooltipPrimitive } from 'layerchart';
|
import { getChartContext, Tooltip as TooltipPrimitive } from "layerchart";
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from "svelte";
|
||||||
|
|
||||||
function defaultFormatter(value: unknown) {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
function defaultFormatter(value: any, _payload: TooltipPayload[]) {
|
||||||
return `${value}`;
|
return `${value}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
hideLabel = false,
|
hideLabel = false,
|
||||||
indicator = 'dot',
|
indicator = "dot",
|
||||||
hideIndicator = false,
|
hideIndicator = false,
|
||||||
labelKey,
|
labelKey,
|
||||||
label,
|
label,
|
||||||
@@ -26,14 +27,13 @@
|
|||||||
}: WithoutChildren<WithElementRef<HTMLAttributes<HTMLDivElement>>> & {
|
}: WithoutChildren<WithElementRef<HTMLAttributes<HTMLDivElement>>> & {
|
||||||
hideLabel?: boolean;
|
hideLabel?: boolean;
|
||||||
label?: string;
|
label?: string;
|
||||||
indicator?: 'line' | 'dot' | 'dashed';
|
indicator?: "line" | "dot" | "dashed";
|
||||||
nameKey?: string;
|
nameKey?: string;
|
||||||
labelKey?: string;
|
labelKey?: string;
|
||||||
hideIndicator?: boolean;
|
hideIndicator?: boolean;
|
||||||
labelClassName?: string;
|
labelClassName?: string;
|
||||||
labelFormatter?:
|
labelFormatter?: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
| ((value: unknown, payload: TooltipPayload[]) => string | number | Snippet)
|
((value: any, payload: TooltipPayload[]) => string | number | Snippet) | null;
|
||||||
| null;
|
|
||||||
formatter?: Snippet<
|
formatter?: Snippet<
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
item: TooltipPayload;
|
item: TooltipPayload;
|
||||||
index: number;
|
index: number;
|
||||||
payload: TooltipPayload[];
|
payload: TooltipPayload[];
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
>;
|
>;
|
||||||
} = $props();
|
} = $props();
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
// Get the x-axis label value from the raw tooltip data (e.g. a Date or month string)
|
// Get the x-axis label value from the raw tooltip data (e.g. a Date or month string)
|
||||||
const dataLabel = tooltipData != null ? chartCtx.x(tooltipData) : undefined;
|
const dataLabel = tooltipData != null ? chartCtx.x(tooltipData) : undefined;
|
||||||
|
|
||||||
const key = labelKey ?? item?.label ?? item?.key ?? 'value';
|
const key = labelKey ?? item?.label ?? item?.key ?? "value";
|
||||||
const itemConfig = getPayloadConfigFromPayload(
|
const itemConfig = getPayloadConfigFromPayload(
|
||||||
chart.config,
|
chart.config,
|
||||||
item,
|
item,
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
let value: unknown;
|
let value: unknown;
|
||||||
if (!labelKey && typeof label === 'string') {
|
if (!labelKey && typeof label === "string") {
|
||||||
value = chart.config[label as keyof typeof chart.config]?.label ?? label;
|
value = chart.config[label as keyof typeof chart.config]?.label ?? label;
|
||||||
} else if (labelKey) {
|
} else if (labelKey) {
|
||||||
value = itemConfig?.label ?? dataLabel;
|
value = itemConfig?.label ?? dataLabel;
|
||||||
@@ -87,13 +87,13 @@
|
|||||||
return labelFormatter(value, visibleSeries);
|
return labelFormatter(value, visibleSeries);
|
||||||
});
|
});
|
||||||
|
|
||||||
const nestLabel = $derived(visibleSeries.length === 1 && indicator !== 'dot');
|
const nestLabel = $derived(visibleSeries.length === 1 && indicator !== "dot");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet TooltipLabel()}
|
{#snippet TooltipLabel()}
|
||||||
{#if formattedLabel}
|
{#if formattedLabel}
|
||||||
<div class={cn('font-medium', labelClassName)}>
|
<div class={cn("font-medium", labelClassName)}>
|
||||||
{#if typeof formattedLabel === 'function'}
|
{#if typeof formattedLabel === "function"}
|
||||||
{@render formattedLabel()}
|
{@render formattedLabel()}
|
||||||
{:else}
|
{:else}
|
||||||
{formattedLabel}
|
{formattedLabel}
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
<div
|
<div
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
class={cn(
|
class={cn(
|
||||||
'grid min-w-[9rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl',
|
"border-border/50 bg-background grid min-w-[9rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<div class="grid gap-1.5">
|
<div class="grid gap-1.5">
|
||||||
{#each visibleSeries as item, i (item.key + i)}
|
{#each visibleSeries as item, i (item.key + i)}
|
||||||
{@const key = `${nameKey || item.key || item.label || 'value'}`}
|
{@const key = `${nameKey || item.key || item.label || "value"}`}
|
||||||
{@const itemConfig = getPayloadConfigFromPayload(
|
{@const itemConfig = getPayloadConfigFromPayload(
|
||||||
chart.config,
|
chart.config,
|
||||||
item,
|
item,
|
||||||
@@ -126,8 +126,8 @@
|
|||||||
{@const indicatorColor = color || item.config?.color || item.color}
|
{@const indicatorColor = color || item.config?.color || item.color}
|
||||||
<div
|
<div
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5 [&>svg]:text-muted-foreground',
|
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5",
|
||||||
indicator === 'dot' && 'items-center'
|
indicator === "dot" && "items-center"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{#if formatter && item.value !== undefined && item.label}
|
{#if formatter && item.value !== undefined && item.label}
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
name: item.label,
|
name: item.label,
|
||||||
item,
|
item,
|
||||||
index: i,
|
index: i,
|
||||||
payload: visibleSeries
|
payload: visibleSeries,
|
||||||
})}
|
})}
|
||||||
{:else}
|
{:else}
|
||||||
{#if itemConfig?.icon}
|
{#if itemConfig?.icon}
|
||||||
@@ -144,18 +144,22 @@
|
|||||||
{:else if !hideIndicator}
|
{:else if !hideIndicator}
|
||||||
<div
|
<div
|
||||||
style="--color-bg: {indicatorColor}; --color-border: {indicatorColor};"
|
style="--color-bg: {indicatorColor}; --color-border: {indicatorColor};"
|
||||||
class={cn('shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)', {
|
class={cn(
|
||||||
'size-2.5': indicator === 'dot',
|
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
|
||||||
'h-full w-1': indicator === 'line',
|
{
|
||||||
'w-0 border-[1.5px] border-dashed bg-transparent': indicator === 'dashed',
|
"size-2.5": indicator === "dot",
|
||||||
'my-0.5': nestLabel && indicator === 'dashed'
|
"h-full w-1": indicator === "line",
|
||||||
})}
|
"w-0 border-[1.5px] border-dashed bg-transparent":
|
||||||
|
indicator === "dashed",
|
||||||
|
"my-0.5": nestLabel && indicator === "dashed",
|
||||||
|
}
|
||||||
|
)}
|
||||||
></div>
|
></div>
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
<div
|
||||||
class={cn(
|
class={cn(
|
||||||
'flex flex-1 shrink-0 justify-between leading-none',
|
"flex flex-1 shrink-0 justify-between leading-none",
|
||||||
nestLabel ? 'items-end' : 'items-center'
|
nestLabel ? "items-end" : "items-center"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div class="grid gap-1.5">
|
<div class="grid gap-1.5">
|
||||||
@@ -167,7 +171,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{#if item.value !== undefined}
|
{#if item.value !== undefined}
|
||||||
<span class="font-mono font-medium text-foreground tabular-nums">
|
<span class="text-foreground font-mono font-medium tabular-nums">
|
||||||
{item.value.toLocaleString()}
|
{item.value.toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Tooltip } from 'layerchart';
|
import type { Tooltip } from "layerchart";
|
||||||
import { getContext, setContext, type Component, type Snippet } from 'svelte';
|
import { getContext, setContext, type Component, type Snippet } from "svelte";
|
||||||
|
|
||||||
export const THEMES = { light: '', dark: '.dark' } as const;
|
export const THEMES = { light: "", dark: ".dark" } as const;
|
||||||
|
|
||||||
export type ChartConfig = {
|
export type ChartConfig = {
|
||||||
[k in string]: {
|
[k in string]: {
|
||||||
@@ -25,10 +25,10 @@ export function getPayloadConfigFromPayload(
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
data?: Record<string, any> | null
|
data?: Record<string, any> | null
|
||||||
) {
|
) {
|
||||||
if (typeof payload !== 'object' || payload === null) return undefined;
|
if (typeof payload !== "object" || payload === null) return undefined;
|
||||||
|
|
||||||
const payloadConfig =
|
const payloadConfig =
|
||||||
'config' in payload && typeof payload.config === 'object' && payload.config !== null
|
"config" in payload && typeof payload.config === "object" && payload.config !== null
|
||||||
? payload.config
|
? payload.config
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
@@ -38,15 +38,15 @@ export function getPayloadConfigFromPayload(
|
|||||||
configLabelKey = payload.key;
|
configLabelKey = payload.key;
|
||||||
} else if (payload.label === key) {
|
} else if (payload.label === key) {
|
||||||
configLabelKey = payload.label;
|
configLabelKey = payload.label;
|
||||||
} else if (key in payload && typeof payload[key as keyof typeof payload] === 'string') {
|
} else if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
|
||||||
configLabelKey = payload[key as keyof typeof payload] as string;
|
configLabelKey = payload[key as keyof typeof payload] as string;
|
||||||
} else if (
|
} else if (
|
||||||
payloadConfig !== undefined &&
|
payloadConfig !== undefined &&
|
||||||
key in payloadConfig &&
|
key in payloadConfig &&
|
||||||
typeof payloadConfig[key as keyof typeof payloadConfig] === 'string'
|
typeof payloadConfig[key as keyof typeof payloadConfig] === "string"
|
||||||
) {
|
) {
|
||||||
configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string;
|
configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string;
|
||||||
} else if (data != null && key in data && typeof data[key] === 'string') {
|
} else if (data != null && key in data && typeof data[key] === "string") {
|
||||||
configLabelKey = data[key] as string;
|
configLabelKey = data[key] as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ type ChartContextValue = {
|
|||||||
config: ChartConfig;
|
config: ChartConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
const chartContextKey = Symbol('chart-context');
|
const chartContextKey = Symbol("chart-context");
|
||||||
|
|
||||||
export function setChartContext(value: ChartContextValue) {
|
export function setChartContext(value: ChartContextValue) {
|
||||||
return setContext(chartContextKey, value);
|
return setContext(chartContextKey, value);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user