Compare commits
10
Commits
35ed79bdd6
...
87309cfcec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87309cfcec | ||
|
|
1f9930d467 | ||
|
|
9808aca44f | ||
|
|
3a3056ba76 | ||
|
|
57dcf306f3 | ||
|
|
b992301c99 | ||
|
|
77a2cfd426 | ||
|
|
ac635e91eb | ||
|
|
2d78c8156f | ||
|
|
00a2a44630 |
No files matched your search
+15
-31
@@ -1,44 +1,28 @@
|
||||
# sv
|
||||
# EvoBGP WebUI
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||
SvelteKit-приложение панели управления EvoBGP. Запуск — [docs/quickstart.md](../docs/quickstart.md).
|
||||
|
||||
Это веб-интерфейс **EvoBGP**. Запуск вместе с API, CORS и портами — в [../docs/quickstart.md](../docs/quickstart.md); доступ и ключи — [../docs/access.md](../docs/access.md).
|
||||
## UI-архитектура
|
||||
|
||||
## Creating a project
|
||||
| Путь | Назначение |
|
||||
|------|------------|
|
||||
| `src/lib/ui/core/` | shadcn-svelte (только через `npx shadcn-svelte@latest add … -y -o`) |
|
||||
| `src/lib/ui/app/` | Layout, PageHeader, toast (`notify`) |
|
||||
| `src/lib/ui/patterns/` | FormField, AppDataTable, ConfirmDialog, EmptyState |
|
||||
| `src/lib/components/ui/` | Re-export на `ui/core` (совместимость) |
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
Токены темы: `src/routes/layout.css`. Справочник: `src/lib/ui/app/tokens.md`.
|
||||
|
||||
```sh
|
||||
# create a new project
|
||||
npx sv create my-app
|
||||
```
|
||||
|
||||
To recreate this project with the same configuration:
|
||||
|
||||
```sh
|
||||
# recreate this project
|
||||
npx sv@0.14.0 create --template minimal --types ts --add tailwindcss="plugins:none" sveltekit-adapter="adapter:static" prettier --no-download-check --install npm web
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
## Разработка
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
npm run check
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
Добавление компонентов shadcn (из каталога `web/`):
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
npx shadcn-svelte@latest add <component> -y -o
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
"aliases": {
|
||||
"components": "$lib/components",
|
||||
"utils": "$lib/utils",
|
||||
"ui": "$lib/components/ui",
|
||||
"ui": "$lib/ui/core",
|
||||
"hooks": "$lib/hooks",
|
||||
"lib": "$lib"
|
||||
},
|
||||
|
||||
Generated
+641
-4
@@ -18,22 +18,54 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@internationalized/date": "^3.12.0",
|
||||
"@lucide/svelte": "^1.7.0",
|
||||
"@lucide/svelte": "^1.16.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.50.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"@types/node": "^22.15.0",
|
||||
"formsnap": "^2.0.1",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.4.1",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"svelte": "^5.54.0",
|
||||
"svelte-check": "^4.4.2",
|
||||
"sveltekit-superforms": "^2.30.1",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@ark/schema": {
|
||||
"version": "0.56.0",
|
||||
"resolved": "https://registry.npmjs.org/@ark/schema/-/schema-0.56.0.tgz",
|
||||
"integrity": "sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@ark/util": "0.56.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ark/util": {
|
||||
"version": "0.56.0",
|
||||
"resolved": "https://registry.npmjs.org/@ark/util/-/util-0.56.0.tgz",
|
||||
"integrity": "sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.29.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
|
||||
"integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
|
||||
@@ -450,6 +482,14 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@exodus/schemasafe": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz",
|
||||
"integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
|
||||
@@ -475,6 +515,25 @@
|
||||
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@hapi/hoek": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
||||
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@hapi/topo": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
|
||||
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@internationalized/date": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.0.tgz",
|
||||
@@ -530,9 +589,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lucide/svelte": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.7.0.tgz",
|
||||
"integrity": "sha512-YytBKOUBGox7yWcykZnYxOkn5WpR5G1qYXLYXV/j1B79SOTTEKzB+s5yF5Rq9l9OkweDStNH2b4yTqfvhEhV8g==",
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.16.0.tgz",
|
||||
"integrity": "sha512-AvvPJnaWxeiNkAljI5MsSEc84yHPLMaWQIAJOcbX7k9au/f9ITS7cxTTQiautDiOFKVOXiYdZ+d6mtl88J+Kbg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
@@ -546,6 +605,14 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@poppinss/macroable": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@poppinss/macroable/-/macroable-1.1.2.tgz",
|
||||
"integrity": "sha512-FAVBRzzWhYP5mA3lCwLH1A0fKBqq5anyjGet90Z81aRK5c/+LTGUE1zJhZrErjaenBSOOI9BVUs3WVmotneFQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz",
|
||||
@@ -871,6 +938,33 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
||||
"integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/formula": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
|
||||
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@sideway/pinpoint": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
|
||||
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@standard-schema/spec": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||
@@ -1301,6 +1395,49 @@
|
||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/validator": {
|
||||
"version": "13.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
|
||||
"integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@typeschema/class-validator": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@typeschema/class-validator/-/class-validator-0.3.0.tgz",
|
||||
"integrity": "sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@typeschema/core": "0.14.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"class-validator": "^0.14.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"class-validator": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typeschema/core": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@typeschema/core/-/core-0.14.0.tgz",
|
||||
"integrity": "sha512-Ia6PtZHcL3KqsAWXjMi5xIyZ7XMH4aSnOQes8mfMLx+wGFGtGRNlwe6Y7cYvX+WfNK67OL0/HSe9t8QDygV0/w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peerDependencies": {
|
||||
"@types/json-schema": "^7.0.15"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/json-schema": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.58.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz",
|
||||
@@ -1314,6 +1451,49 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@valibot/to-json-schema": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@valibot/to-json-schema/-/to-json-schema-1.7.0.tgz",
|
||||
"integrity": "sha512-Y3pPVibbIOHzohrlxSINvO7w/bvXkoYS3BQHoImV9ynE+bXKf171bdMucPurV2zp7gdmt0L1HCcNAsbo7cFRQw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peerDependencies": {
|
||||
"valibot": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vinejs/compiler": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@vinejs/compiler/-/compiler-3.0.0.tgz",
|
||||
"integrity": "sha512-v9Lsv59nR56+bmy2p0+czjZxsLHwaibJ+SV5iK9JJfehlJMa501jUJQqqz4X/OqKXrxtE3uTQmSqjUqzF3B2mw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vinejs/vine": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@vinejs/vine/-/vine-3.0.1.tgz",
|
||||
"integrity": "sha512-ZtvYkYpZOYdvbws3uaOAvTFuvFXoQGAtmzeiXu+XSMGxi5GVsODpoI9Xu9TplEMuD/5fmAtBbKb9cQHkWkLXDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@poppinss/macroable": "^1.0.4",
|
||||
"@types/validator": "^13.12.2",
|
||||
"@vinejs/compiler": "^3.0.0",
|
||||
"camelcase": "^8.0.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"dlv": "^1.1.3",
|
||||
"normalize-url": "^8.0.1",
|
||||
"validator": "^13.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
@@ -1335,6 +1515,30 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/arkregex": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/arkregex/-/arkregex-0.0.5.tgz",
|
||||
"integrity": "sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@ark/util": "0.56.0"
|
||||
}
|
||||
},
|
||||
"node_modules/arktype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/arktype/-/arktype-2.2.0.tgz",
|
||||
"integrity": "sha512-t54MZ7ti5BhOEvzEkgKnWvqj+UbDfWig+DHr5I34xatymPusKLS0lQpNJd8M6DzmIto2QGszHfNKoFIT8tMCZQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@ark/schema": "0.56.0",
|
||||
"@ark/util": "0.56.0",
|
||||
"arkregex": "0.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
|
||||
@@ -1368,6 +1572,20 @@
|
||||
"svelte": "^5.33.0"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
|
||||
"integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
@@ -1384,6 +1602,19 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/class-validator": {
|
||||
"version": "0.14.4",
|
||||
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.4.tgz",
|
||||
"integrity": "sha512-AwNusCCam51q703dW82x95tOqQp6oC9HNUl724KxJJOfnKscI8dOloXFgyez7LbTTKWuRBA37FScqVbJEoq8Yw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/validator": "^13.15.3",
|
||||
"libphonenumber-js": "^1.11.1",
|
||||
"validator": "^13.15.22"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
@@ -1403,6 +1634,14 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.20",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz",
|
||||
"integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
@@ -1438,6 +1677,26 @@
|
||||
"integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/effect": {
|
||||
"version": "3.21.2",
|
||||
"resolved": "https://registry.npmjs.org/effect/-/effect-3.21.2.tgz",
|
||||
"integrity": "sha512-rXd2FGDM8KdjSIrc+mqEELo7ScW7xTVxEf1iInmPSpIde9/nyGuFM710cjTo7/EreGXiUX2MOonPpprbz2XHCg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"fast-check": "^3.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.20.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
|
||||
@@ -1510,6 +1769,30 @@
|
||||
"@typescript-eslint/types": "^8.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
"version": "3.23.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
|
||||
"integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"pure-rand": "^6.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
@@ -1528,6 +1811,47 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/formsnap": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/formsnap/-/formsnap-2.0.1.tgz",
|
||||
"integrity": "sha512-iJSe4YKd/W6WhLwKDVJU9FQeaJRpEFuolhju7ZXlRpUVyDdqFdMP8AUBICgnVvQPyP41IPAlBa/v0Eo35iE6wQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"svelte-toolbelt": "^0.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8.7.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/huntabyte"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^5.0.0",
|
||||
"sveltekit-superforms": "^2.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/formsnap/node_modules/svelte-toolbelt": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.5.0.tgz",
|
||||
"integrity": "sha512-t3tenZcnfQoIeRuQf/jBU7bvTeT3TGkcEE+1EUr5orp0lR7NEpprflpuie3x9Dn0W9nOKqs3HwKGJeeN5Ok1sQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
"https://github.com/sponsors/huntabyte"
|
||||
],
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"style-to-object": "^1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^5.0.0-next.126"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@@ -1574,6 +1898,36 @@
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/joi": {
|
||||
"version": "17.13.3",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
|
||||
"integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@hapi/hoek": "^9.3.0",
|
||||
"@hapi/topo": "^5.1.0",
|
||||
"@sideway/address": "^4.1.5",
|
||||
"@sideway/formula": "^3.0.1",
|
||||
"@sideway/pinpoint": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-schema-to-ts": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
|
||||
"integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"ts-algebra": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/kleur": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
|
||||
@@ -1584,6 +1938,14 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/libphonenumber-js": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.13.2.tgz",
|
||||
"integrity": "sha512-S3kmBrptp3yRTm83NUcHy9g1vbwiWMzI8WvY22+koBJ6zkRteLnedBL2VX0MIAGwx2yiyxX4J85pceZyQ6ffgg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
||||
@@ -1858,6 +2220,13 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/memoize-weak": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/memoize-weak/-/memoize-weak-1.0.2.tgz",
|
||||
"integrity": "sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@@ -1897,6 +2266,20 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-url": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz",
|
||||
"integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/obug": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
|
||||
@@ -2063,6 +2446,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/property-expr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/pure-rand": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
|
||||
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
@@ -2200,6 +2609,17 @@
|
||||
"inline-style-parser": "0.2.7"
|
||||
}
|
||||
},
|
||||
"node_modules/superstruct": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz",
|
||||
"integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "5.55.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.1.tgz",
|
||||
@@ -2299,6 +2719,104 @@
|
||||
"svelte": "^5.30.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sveltekit-superforms": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmjs.org/sveltekit-superforms/-/sveltekit-superforms-2.30.1.tgz",
|
||||
"integrity": "sha512-wBzyqsE0idvEJWuNJ+HCiAtdxa7Z55GZ8jmtlVHJfonrk9bRYC49MoPaloYyFoYuU3QPy6Omna/Qzn1kaIkgew==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ciscoheat"
|
||||
},
|
||||
{
|
||||
"type": "ko-fi",
|
||||
"url": "https://ko-fi.com/ciscoheat"
|
||||
},
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://www.paypal.com/donate/?hosted_button_id=NY7F5ALHHSVQS"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"devalue": "^5.6.4",
|
||||
"memoize-weak": "^1.0.2",
|
||||
"ts-deepmerge": "^7.0.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@exodus/schemasafe": "^1.3.0",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
"@typeschema/class-validator": "^0.3.0",
|
||||
"@valibot/to-json-schema": "^1.6.0",
|
||||
"@vinejs/vine": "^3.0.1",
|
||||
"arktype": "^2.2.0",
|
||||
"class-validator": "^0.14.4",
|
||||
"effect": "^3.21.0",
|
||||
"joi": "^17.13.3",
|
||||
"json-schema-to-ts": "^3.1.1",
|
||||
"superstruct": "^2.0.2",
|
||||
"typebox": "^1.1.6",
|
||||
"valibot": "^1.3.1",
|
||||
"yup": "^1.7.1",
|
||||
"zod": "^4.3.6",
|
||||
"zod-v3-to-json-schema": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@exodus/schemasafe": "^1.3.0",
|
||||
"@sveltejs/kit": "1.x || 2.x",
|
||||
"@typeschema/class-validator": "^0.3.0",
|
||||
"@vinejs/vine": "^1.8.0 || ^2.0.0 || ^3.0.0",
|
||||
"arktype": ">=2.0.0-rc.23",
|
||||
"class-validator": "^0.14.1",
|
||||
"effect": "^3.21.0",
|
||||
"joi": "^17.13.1",
|
||||
"superstruct": "^2.0.2",
|
||||
"svelte": "3.x || 4.x || >=5.0.0-next.51",
|
||||
"typebox": "^1.0.36",
|
||||
"valibot": "^1.2.0",
|
||||
"yup": "^1.4.0",
|
||||
"zod": "^3.25.0 || ^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@exodus/schemasafe": {
|
||||
"optional": true
|
||||
},
|
||||
"@typeschema/class-validator": {
|
||||
"optional": true
|
||||
},
|
||||
"@vinejs/vine": {
|
||||
"optional": true
|
||||
},
|
||||
"arktype": {
|
||||
"optional": true
|
||||
},
|
||||
"class-validator": {
|
||||
"optional": true
|
||||
},
|
||||
"effect": {
|
||||
"optional": true
|
||||
},
|
||||
"joi": {
|
||||
"optional": true
|
||||
},
|
||||
"superstruct": {
|
||||
"optional": true
|
||||
},
|
||||
"typebox": {
|
||||
"optional": true
|
||||
},
|
||||
"valibot": {
|
||||
"optional": true
|
||||
},
|
||||
"yup": {
|
||||
"optional": true
|
||||
},
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tabbable": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz",
|
||||
@@ -2354,6 +2872,14 @@
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-case": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
@@ -2371,6 +2897,14 @@
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/totalist": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
|
||||
@@ -2381,6 +2915,24 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-algebra": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
|
||||
"integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/ts-deepmerge": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.3.tgz",
|
||||
"integrity": "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
@@ -2396,6 +2948,28 @@
|
||||
"url": "https://github.com/sponsors/Wombosvideo"
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||
"dev": true,
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typebox": {
|
||||
"version": "1.1.38",
|
||||
"resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz",
|
||||
"integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
@@ -2417,6 +2991,33 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/valibot": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.4.0.tgz",
|
||||
"integrity": "sha512-iC/x7fVcSyOwlm/VSt7RlHnzNGLGvR9GnxdifUeWoCJo0q4ZZvrVkIHC6faTlkxG47I2Y4UrFquPuVHCrOnrLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.15.35",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz",
|
||||
"integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
|
||||
@@ -2512,11 +3113,47 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/yup": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
|
||||
"integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"property-expr": "^2.0.5",
|
||||
"tiny-case": "^1.0.3",
|
||||
"toposort": "^2.0.2",
|
||||
"type-fest": "^2.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/zimmerframe": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
|
||||
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
||||
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"node_modules/zod-v3-to-json-schema": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/zod-v3-to-json-schema/-/zod-v3-to-json-schema-4.0.0.tgz",
|
||||
"integrity": "sha512-KixLrhX/uPmRFnDgsZrzrk4x5SSJA+PmaE5adbfID9+3KPJcdxqRobaHU397EfWBqfQircrjKqvEqZ/mW5QH6w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"peerDependencies": {
|
||||
"zod": "^3.25 || ^4.0.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -15,17 +15,19 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@internationalized/date": "^3.12.0",
|
||||
"@lucide/svelte": "^1.7.0",
|
||||
"@lucide/svelte": "^1.16.0",
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.50.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"@types/node": "^22.15.0",
|
||||
"formsnap": "^2.0.1",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-svelte": "^3.4.1",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"svelte": "^5.54.0",
|
||||
"svelte-check": "^4.4.2",
|
||||
"sveltekit-superforms": "^2.30.1",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.3.1"
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { Button } from '$lib/components/ui/button/index.js';
|
||||
import { buttonVariants } from '$lib/components/ui/button/button.svelte';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuTrigger
|
||||
} from '$lib/components/ui/dropdown-menu/index.js';
|
||||
import { Separator } from '$lib/components/ui/separator/index.js';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '$lib/components/ui/tooltip/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
|
||||
import Activity from '@lucide/svelte/icons/activity';
|
||||
import Boxes from '@lucide/svelte/icons/boxes';
|
||||
import BookOpen from '@lucide/svelte/icons/book-open';
|
||||
import LayoutDashboard from '@lucide/svelte/icons/layout-dashboard';
|
||||
import Network from '@lucide/svelte/icons/network';
|
||||
import Settings from '@lucide/svelte/icons/settings';
|
||||
import Gauge from '@lucide/svelte/icons/gauge';
|
||||
import Zap from '@lucide/svelte/icons/zap';
|
||||
import CalendarClock from '@lucide/svelte/icons/calendar-clock';
|
||||
import PanelLeftClose from '@lucide/svelte/icons/panel-left-close';
|
||||
import PanelLeftOpen from '@lucide/svelte/icons/panel-left-open';
|
||||
import Sun from '@lucide/svelte/icons/sun';
|
||||
import Moon from '@lucide/svelte/icons/moon';
|
||||
import Monitor from '@lucide/svelte/icons/monitor';
|
||||
|
||||
const nav = [
|
||||
{ href: '/', label: 'Обзор', icon: LayoutDashboard },
|
||||
{ href: '/modules', label: 'Модули', icon: Boxes },
|
||||
{ href: '/directories', label: 'Справочники', icon: BookOpen },
|
||||
{ href: '/network', label: 'Сеть', icon: Network },
|
||||
{ href: '/revisions', label: 'Ревизии', icon: Activity },
|
||||
{ href: '/operations', label: 'Операции', icon: Zap },
|
||||
{ href: '/schedule', label: 'Расписание', icon: CalendarClock },
|
||||
{ href: '/monitoring', label: 'Мониторинг', icon: Gauge },
|
||||
] as const;
|
||||
|
||||
const navBottom = [
|
||||
{ href: '/settings', label: 'Настройки', icon: Settings },
|
||||
] as const;
|
||||
|
||||
let collapsed = $state(false);
|
||||
let { children, theme = $bindable<ThemePreference>('system') } = $props();
|
||||
|
||||
function isActive(href: string) {
|
||||
const pathname = page.url.pathname;
|
||||
if (href === '/') return pathname === '/';
|
||||
return pathname === href || pathname.startsWith(href + '/');
|
||||
}
|
||||
</script>
|
||||
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<div class="bg-background flex min-h-screen">
|
||||
<aside
|
||||
class={cn(
|
||||
'border-border bg-sidebar sticky top-0 flex h-screen shrink-0 flex-col overflow-hidden border-r transition-all duration-200',
|
||||
collapsed ? 'w-14' : 'w-56'
|
||||
)}
|
||||
aria-label="Основная навигация"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div class={cn('flex items-center gap-2 p-3', collapsed && 'justify-center')}>
|
||||
{#if !collapsed}
|
||||
<div class="min-w-0 flex-1">
|
||||
<a href={resolve('/')} class="text-sidebar-foreground block truncate font-semibold tracking-tight">EvoBGP</a>
|
||||
<p class="text-sidebar-foreground/50 truncate text-xs">Панель управления</p>
|
||||
</div>
|
||||
{/if}
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'ghost', size: 'icon-sm' }),
|
||||
'text-sidebar-foreground/60 hover:text-sidebar-foreground shrink-0'
|
||||
)}
|
||||
aria-label="Тема оформления"
|
||||
>
|
||||
<span class="flex size-4 items-center justify-center">
|
||||
<Sun class="size-4 dark:hidden" />
|
||||
<Moon class="hidden size-4 dark:block" />
|
||||
</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" class="w-44">
|
||||
<DropdownMenuLabel>Тема</DropdownMenuLabel>
|
||||
<DropdownMenuRadioGroup bind:value={theme}>
|
||||
<DropdownMenuRadioItem value="light" class="gap-2">
|
||||
<Sun class="size-4" />
|
||||
Светлая
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="dark" class="gap-2">
|
||||
<Moon class="size-4" />
|
||||
Тёмная
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="system" class="gap-2">
|
||||
<Monitor class="size-4" />
|
||||
Как в системе
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<button
|
||||
onclick={() => (collapsed = !collapsed)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'ghost', size: 'icon-sm' }),
|
||||
'text-sidebar-foreground/60 hover:text-sidebar-foreground shrink-0'
|
||||
)}
|
||||
aria-label={collapsed ? 'Развернуть меню' : 'Свернуть меню'}
|
||||
>
|
||||
{#if collapsed}
|
||||
<PanelLeftOpen class="size-4" />
|
||||
{:else}
|
||||
<PanelLeftClose class="size-4" />
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
<Separator />
|
||||
|
||||
<!-- Main nav -->
|
||||
<nav class="flex flex-1 flex-col gap-0.5 overflow-y-auto p-2">
|
||||
{#each nav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
{@const active = isActive(item.href)}
|
||||
{#if collapsed}
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<a
|
||||
href={resolve(item.href)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: active ? 'secondary' : 'ghost', size: 'icon-sm' }),
|
||||
'w-full no-underline flex items-center justify-center',
|
||||
active && 'ring-sidebar-primary/50 bg-sidebar-accent/90 text-sidebar-accent-foreground ring-1'
|
||||
)}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">{item.label}</TooltipContent>
|
||||
</Tooltip>
|
||||
{:else}
|
||||
<a
|
||||
href={resolve(item.href)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: active ? 'secondary' : 'ghost', size: 'sm' }),
|
||||
'w-full justify-start gap-2 no-underline',
|
||||
active &&
|
||||
'border-l-sidebar-primary bg-sidebar-accent/80 text-sidebar-accent-foreground border-l-2 shadow-sm'
|
||||
)}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
{item.label}
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<!-- Bottom nav -->
|
||||
<div class="flex flex-col gap-0.5 p-2">
|
||||
<Separator class="mb-2" />
|
||||
{#each navBottom as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
{@const active = isActive(item.href)}
|
||||
{#if collapsed}
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<a
|
||||
href={resolve(item.href)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: active ? 'secondary' : 'ghost', size: 'icon-sm' }),
|
||||
'w-full no-underline flex items-center justify-center',
|
||||
active && 'ring-sidebar-primary/50 bg-sidebar-accent/90 text-sidebar-accent-foreground ring-1'
|
||||
)}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">{item.label}</TooltipContent>
|
||||
</Tooltip>
|
||||
{:else}
|
||||
<a
|
||||
href={resolve(item.href)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: active ? 'secondary' : 'ghost', size: 'sm' }),
|
||||
'w-full justify-start gap-2 no-underline',
|
||||
active &&
|
||||
'border-l-sidebar-primary bg-sidebar-accent/80 text-sidebar-accent-foreground border-l-2 shadow-sm'
|
||||
)}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
{item.label}
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="min-w-0 flex-1 p-6">
|
||||
{@render children?.()}
|
||||
</main>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
@@ -1,40 +1 @@
|
||||
import Root from "./alert-dialog.svelte";
|
||||
import Portal from "./alert-dialog-portal.svelte";
|
||||
import Trigger from "./alert-dialog-trigger.svelte";
|
||||
import Title from "./alert-dialog-title.svelte";
|
||||
import Action from "./alert-dialog-action.svelte";
|
||||
import Cancel from "./alert-dialog-cancel.svelte";
|
||||
import Footer from "./alert-dialog-footer.svelte";
|
||||
import Header from "./alert-dialog-header.svelte";
|
||||
import Overlay from "./alert-dialog-overlay.svelte";
|
||||
import Content from "./alert-dialog-content.svelte";
|
||||
import Description from "./alert-dialog-description.svelte";
|
||||
import Media from "./alert-dialog-media.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Action,
|
||||
Cancel,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
Media,
|
||||
//
|
||||
Root as AlertDialog,
|
||||
Title as AlertDialogTitle,
|
||||
Action as AlertDialogAction,
|
||||
Cancel as AlertDialogCancel,
|
||||
Portal as AlertDialogPortal,
|
||||
Footer as AlertDialogFooter,
|
||||
Header as AlertDialogHeader,
|
||||
Trigger as AlertDialogTrigger,
|
||||
Overlay as AlertDialogOverlay,
|
||||
Content as AlertDialogContent,
|
||||
Description as AlertDialogDescription,
|
||||
Media as AlertDialogMedia,
|
||||
};
|
||||
export * from '$lib/ui/core/alert-dialog/index.js';
|
||||
@@ -1,17 +1 @@
|
||||
import Root from "./alert.svelte";
|
||||
import Description from "./alert-description.svelte";
|
||||
import Title from "./alert-title.svelte";
|
||||
import Action from "./alert-action.svelte";
|
||||
export { alertVariants, type AlertVariant } from "./alert.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Description,
|
||||
Title,
|
||||
Action,
|
||||
//
|
||||
Root as Alert,
|
||||
Description as AlertDescription,
|
||||
Title as AlertTitle,
|
||||
Action as AlertAction,
|
||||
};
|
||||
export * from '$lib/ui/core/alert/index.js';
|
||||
@@ -1,2 +1 @@
|
||||
export { default as Badge } from "./badge.svelte";
|
||||
export { badgeVariants, type BadgeVariant } from "./badge.svelte";
|
||||
export * from '$lib/ui/core/badge/index.js';
|
||||
@@ -1,17 +1 @@
|
||||
import Root, {
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
buttonVariants,
|
||||
} from "./button.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
type ButtonProps as Props,
|
||||
//
|
||||
Root as Button,
|
||||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
};
|
||||
export * from '$lib/ui/core/button/index.js';
|
||||
@@ -1,25 +1 @@
|
||||
import Root from "./card.svelte";
|
||||
import Content from "./card-content.svelte";
|
||||
import Description from "./card-description.svelte";
|
||||
import Footer from "./card-footer.svelte";
|
||||
import Header from "./card-header.svelte";
|
||||
import Title from "./card-title.svelte";
|
||||
import Action from "./card-action.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Description,
|
||||
Footer,
|
||||
Header,
|
||||
Title,
|
||||
Action,
|
||||
//
|
||||
Root as Card,
|
||||
Content as CardContent,
|
||||
Description as CardDescription,
|
||||
Footer as CardFooter,
|
||||
Header as CardHeader,
|
||||
Title as CardTitle,
|
||||
Action as CardAction,
|
||||
};
|
||||
export * from '$lib/ui/core/card/index.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '$lib/ui/core/checkbox/index.js';
|
||||
@@ -1,3 +1 @@
|
||||
export { default as FlexRender } from "./flex-render.svelte";
|
||||
export { renderComponent, renderSnippet } from "./render-helpers.js";
|
||||
export { createSvelteTable } from "./data-table.svelte.js";
|
||||
export * from '$lib/ui/core/data-table/index.js';
|
||||
@@ -1,34 +1 @@
|
||||
import Root from "./dialog.svelte";
|
||||
import Portal from "./dialog-portal.svelte";
|
||||
import Title from "./dialog-title.svelte";
|
||||
import Footer from "./dialog-footer.svelte";
|
||||
import Header from "./dialog-header.svelte";
|
||||
import Overlay from "./dialog-overlay.svelte";
|
||||
import Content from "./dialog-content.svelte";
|
||||
import Description from "./dialog-description.svelte";
|
||||
import Trigger from "./dialog-trigger.svelte";
|
||||
import Close from "./dialog-close.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
Close,
|
||||
//
|
||||
Root as Dialog,
|
||||
Title as DialogTitle,
|
||||
Portal as DialogPortal,
|
||||
Footer as DialogFooter,
|
||||
Header as DialogHeader,
|
||||
Trigger as DialogTrigger,
|
||||
Overlay as DialogOverlay,
|
||||
Content as DialogContent,
|
||||
Description as DialogDescription,
|
||||
Close as DialogClose,
|
||||
};
|
||||
export * from '$lib/ui/core/dialog/index.js';
|
||||
@@ -1,54 +1 @@
|
||||
import Root from "./dropdown-menu.svelte";
|
||||
import Sub from "./dropdown-menu-sub.svelte";
|
||||
import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte";
|
||||
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
|
||||
import Content from "./dropdown-menu-content.svelte";
|
||||
import Group from "./dropdown-menu-group.svelte";
|
||||
import Item from "./dropdown-menu-item.svelte";
|
||||
import Label from "./dropdown-menu-label.svelte";
|
||||
import RadioGroup from "./dropdown-menu-radio-group.svelte";
|
||||
import RadioItem from "./dropdown-menu-radio-item.svelte";
|
||||
import Separator from "./dropdown-menu-separator.svelte";
|
||||
import Shortcut from "./dropdown-menu-shortcut.svelte";
|
||||
import Trigger from "./dropdown-menu-trigger.svelte";
|
||||
import SubContent from "./dropdown-menu-sub-content.svelte";
|
||||
import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
|
||||
import GroupHeading from "./dropdown-menu-group-heading.svelte";
|
||||
import Portal from "./dropdown-menu-portal.svelte";
|
||||
|
||||
export {
|
||||
CheckboxGroup,
|
||||
CheckboxItem,
|
||||
Content,
|
||||
Portal,
|
||||
Root as DropdownMenu,
|
||||
CheckboxGroup as DropdownMenuCheckboxGroup,
|
||||
CheckboxItem as DropdownMenuCheckboxItem,
|
||||
Content as DropdownMenuContent,
|
||||
Portal as DropdownMenuPortal,
|
||||
Group as DropdownMenuGroup,
|
||||
Item as DropdownMenuItem,
|
||||
Label as DropdownMenuLabel,
|
||||
RadioGroup as DropdownMenuRadioGroup,
|
||||
RadioItem as DropdownMenuRadioItem,
|
||||
Separator as DropdownMenuSeparator,
|
||||
Shortcut as DropdownMenuShortcut,
|
||||
Sub as DropdownMenuSub,
|
||||
SubContent as DropdownMenuSubContent,
|
||||
SubTrigger as DropdownMenuSubTrigger,
|
||||
Trigger as DropdownMenuTrigger,
|
||||
GroupHeading as DropdownMenuGroupHeading,
|
||||
Group,
|
||||
GroupHeading,
|
||||
Item,
|
||||
Label,
|
||||
RadioGroup,
|
||||
RadioItem,
|
||||
Root,
|
||||
Separator,
|
||||
Shortcut,
|
||||
Sub,
|
||||
SubContent,
|
||||
SubTrigger,
|
||||
Trigger,
|
||||
};
|
||||
export * from '$lib/ui/core/dropdown-menu/index.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '$lib/ui/core/form/index.js';
|
||||
@@ -1,7 +1 @@
|
||||
import Root from "./input.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Input,
|
||||
};
|
||||
export * from '$lib/ui/core/input/index.js';
|
||||
@@ -1,7 +1 @@
|
||||
import Root from "./label.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Label,
|
||||
};
|
||||
export * from '$lib/ui/core/label/index.js';
|
||||
@@ -1,28 +1 @@
|
||||
import Root from "./popover.svelte";
|
||||
import Close from "./popover-close.svelte";
|
||||
import Content from "./popover-content.svelte";
|
||||
import Description from "./popover-description.svelte";
|
||||
import Header from "./popover-header.svelte";
|
||||
import Title from "./popover-title.svelte";
|
||||
import Trigger from "./popover-trigger.svelte";
|
||||
import Portal from "./popover-portal.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Description,
|
||||
Header,
|
||||
Title,
|
||||
Trigger,
|
||||
Close,
|
||||
Portal,
|
||||
//
|
||||
Root as Popover,
|
||||
Content as PopoverContent,
|
||||
Description as PopoverDescription,
|
||||
Header as PopoverHeader,
|
||||
Title as PopoverTitle,
|
||||
Trigger as PopoverTrigger,
|
||||
Close as PopoverClose,
|
||||
Portal as PopoverPortal,
|
||||
};
|
||||
export * from '$lib/ui/core/popover/index.js';
|
||||
@@ -1,10 +1 @@
|
||||
import Scrollbar from "./scroll-area-scrollbar.svelte";
|
||||
import Root from "./scroll-area.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Scrollbar,
|
||||
//,
|
||||
Root as ScrollArea,
|
||||
Scrollbar as ScrollAreaScrollbar,
|
||||
};
|
||||
export * from '$lib/ui/core/scroll-area/index.js';
|
||||
@@ -1,37 +1 @@
|
||||
import Root from "./select.svelte";
|
||||
import Group from "./select-group.svelte";
|
||||
import Label from "./select-label.svelte";
|
||||
import Item from "./select-item.svelte";
|
||||
import Content from "./select-content.svelte";
|
||||
import Trigger from "./select-trigger.svelte";
|
||||
import Separator from "./select-separator.svelte";
|
||||
import ScrollDownButton from "./select-scroll-down-button.svelte";
|
||||
import ScrollUpButton from "./select-scroll-up-button.svelte";
|
||||
import GroupHeading from "./select-group-heading.svelte";
|
||||
import Portal from "./select-portal.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Group,
|
||||
Label,
|
||||
Item,
|
||||
Content,
|
||||
Trigger,
|
||||
Separator,
|
||||
ScrollDownButton,
|
||||
ScrollUpButton,
|
||||
GroupHeading,
|
||||
Portal,
|
||||
//
|
||||
Root as Select,
|
||||
Group as SelectGroup,
|
||||
Label as SelectLabel,
|
||||
Item as SelectItem,
|
||||
Content as SelectContent,
|
||||
Trigger as SelectTrigger,
|
||||
Separator as SelectSeparator,
|
||||
ScrollDownButton as SelectScrollDownButton,
|
||||
ScrollUpButton as SelectScrollUpButton,
|
||||
GroupHeading as SelectGroupHeading,
|
||||
Portal as SelectPortal,
|
||||
};
|
||||
export * from '$lib/ui/core/select/index.js';
|
||||
@@ -1,7 +1 @@
|
||||
import Root from "./separator.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Separator,
|
||||
};
|
||||
export * from '$lib/ui/core/separator/index.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '$lib/ui/core/sheet/index.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from '$lib/ui/core/skeleton/index.js';
|
||||
@@ -1,7 +1 @@
|
||||
import Root from "./switch.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Switch,
|
||||
};
|
||||
export * from '$lib/ui/core/switch/index.js';
|
||||
@@ -1,28 +1 @@
|
||||
import Root from "./table.svelte";
|
||||
import Body from "./table-body.svelte";
|
||||
import Caption from "./table-caption.svelte";
|
||||
import Cell from "./table-cell.svelte";
|
||||
import Footer from "./table-footer.svelte";
|
||||
import Head from "./table-head.svelte";
|
||||
import Header from "./table-header.svelte";
|
||||
import Row from "./table-row.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Body,
|
||||
Caption,
|
||||
Cell,
|
||||
Footer,
|
||||
Head,
|
||||
Header,
|
||||
Row,
|
||||
//
|
||||
Root as Table,
|
||||
Body as TableBody,
|
||||
Caption as TableCaption,
|
||||
Cell as TableCell,
|
||||
Footer as TableFooter,
|
||||
Head as TableHead,
|
||||
Header as TableHeader,
|
||||
Row as TableRow,
|
||||
};
|
||||
export * from '$lib/ui/core/table/index.js';
|
||||
@@ -1,18 +1 @@
|
||||
import Root from "./tabs.svelte";
|
||||
import Content from "./tabs-content.svelte";
|
||||
import List, { tabsListVariants, type TabsListVariant } from "./tabs-list.svelte";
|
||||
import Trigger from "./tabs-trigger.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
List,
|
||||
Trigger,
|
||||
tabsListVariants,
|
||||
type TabsListVariant,
|
||||
//
|
||||
Root as Tabs,
|
||||
Content as TabsContent,
|
||||
List as TabsList,
|
||||
Trigger as TabsTrigger,
|
||||
};
|
||||
export * from '$lib/ui/core/tabs/index.js';
|
||||
@@ -1,7 +1 @@
|
||||
import Root from "./textarea.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Textarea,
|
||||
};
|
||||
export * from '$lib/ui/core/textarea/index.js';
|
||||
@@ -1,19 +1 @@
|
||||
import Root from "./tooltip.svelte";
|
||||
import Trigger from "./tooltip-trigger.svelte";
|
||||
import Content from "./tooltip-content.svelte";
|
||||
import Provider from "./tooltip-provider.svelte";
|
||||
import Portal from "./tooltip-portal.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Trigger,
|
||||
Content,
|
||||
Provider,
|
||||
Portal,
|
||||
//
|
||||
Root as Tooltip,
|
||||
Content as TooltipContent,
|
||||
Trigger as TooltipTrigger,
|
||||
Provider as TooltipProvider,
|
||||
Portal as TooltipPortal,
|
||||
};
|
||||
export * from '$lib/ui/core/tooltip/index.js';
|
||||
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { TooltipProvider } from '$lib/ui/core/tooltip/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
import AppSidebar from './app-sidebar.svelte';
|
||||
import AppMobileNav from './app-mobile-nav.svelte';
|
||||
|
||||
let {
|
||||
children,
|
||||
theme = $bindable<ThemePreference>('system')
|
||||
}: {
|
||||
children: Snippet;
|
||||
theme?: ThemePreference;
|
||||
} = $props();
|
||||
|
||||
let collapsed = $state(false);
|
||||
let mobileNavOpen = $state(false);
|
||||
</script>
|
||||
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<div class="bg-background flex min-h-screen">
|
||||
<AppSidebar bind:collapsed bind:theme />
|
||||
<div class="flex min-w-0 flex-1 flex-col">
|
||||
<div class="border-border flex items-center gap-2 border-b px-4 py-2 md:hidden">
|
||||
<AppMobileNav bind:open={mobileNavOpen} bind:theme />
|
||||
<span class="font-semibold tracking-tight">EvoBGP</span>
|
||||
</div>
|
||||
<main class="min-w-0 flex-1 p-4 md:p-6">
|
||||
{@render children()}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger
|
||||
} from '$lib/ui/core/sheet/index.js';
|
||||
import { Button } from '$lib/ui/core/button/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
import Menu from '@lucide/svelte/icons/menu';
|
||||
import AppNavLinks from './app-nav-links.svelte';
|
||||
import ThemeMenu from './theme-menu.svelte';
|
||||
|
||||
let {
|
||||
open = $bindable(false),
|
||||
theme = $bindable<ThemePreference>('system')
|
||||
}: {
|
||||
open?: boolean;
|
||||
theme?: ThemePreference;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<Sheet bind:open>
|
||||
<SheetTrigger>
|
||||
<Button variant="ghost" size="icon-sm" class="md:hidden" aria-label="Открыть меню">
|
||||
<Menu class="size-5" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" class="bg-sidebar text-sidebar-foreground flex w-72 flex-col gap-0 p-0">
|
||||
<SheetHeader class="border-border border-b p-4 text-left">
|
||||
<SheetTitle>
|
||||
<a href={resolve('/')} class="font-semibold tracking-tight no-underline">EvoBGP</a>
|
||||
</SheetTitle>
|
||||
<p class="text-sidebar-foreground/50 text-xs font-normal">Панель управления</p>
|
||||
</SheetHeader>
|
||||
<div class="flex items-center gap-2 px-4 py-2">
|
||||
<ThemeMenu bind:theme />
|
||||
</div>
|
||||
<div class="flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||
<AppNavLinks onNavigate={() => (open = false)} />
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
@@ -0,0 +1,91 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { buttonVariants } from '$lib/ui/core/button/index.js';
|
||||
import { Separator } from '$lib/ui/core/separator/index.js';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '$lib/ui/core/tooltip/index.js';
|
||||
import { bottomNav, mainNav } from './nav.js';
|
||||
|
||||
type Props = {
|
||||
collapsed?: boolean;
|
||||
onNavigate?: () => void;
|
||||
};
|
||||
|
||||
let { collapsed = false, onNavigate }: Props = $props();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const navHref = (href: string) => resolve(href as any);
|
||||
|
||||
function isActive(href: string) {
|
||||
const pathname = page.url.pathname;
|
||||
if (href === '/') return pathname === '/';
|
||||
return pathname === href || pathname.startsWith(href + '/');
|
||||
}
|
||||
|
||||
function linkClass(active: boolean, iconOnly: boolean) {
|
||||
return cn(
|
||||
buttonVariants({ variant: active ? 'secondary' : 'ghost', size: iconOnly ? 'icon-sm' : 'sm' }),
|
||||
iconOnly ? 'flex w-full items-center justify-center no-underline' : 'flex w-full items-center justify-start gap-2 no-underline',
|
||||
active &&
|
||||
(iconOnly
|
||||
? 'ring-sidebar-primary/50 bg-sidebar-accent/90 text-sidebar-accent-foreground ring-1'
|
||||
: 'border-l-sidebar-primary bg-sidebar-accent/80 text-sidebar-accent-foreground border-l-2 shadow-sm')
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav class="flex flex-1 flex-col gap-0.5 overflow-y-auto p-2">
|
||||
{#each mainNav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
{@const active = isActive(item.href)}
|
||||
{#if collapsed}
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<a
|
||||
href={navHref(item.href)}
|
||||
class={linkClass(active, true)}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
onclick={onNavigate}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">{item.label}</TooltipContent>
|
||||
</Tooltip>
|
||||
{:else}
|
||||
<a
|
||||
href={navHref(item.href)}
|
||||
class={linkClass(active, false)}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
onclick={onNavigate}
|
||||
>
|
||||
<Icon class="size-4" />
|
||||
{item.label}
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<div class="flex flex-col gap-0.5 p-2">
|
||||
<Separator class="mb-2" />
|
||||
{#each bottomNav as item (item.href)}
|
||||
{@const Icon = item.icon}
|
||||
{@const active = isActive(item.href)}
|
||||
{#if collapsed}
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<a href={navHref(item.href)} class={linkClass(active, true)} onclick={onNavigate}>
|
||||
<Icon class="size-4" />
|
||||
</a>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">{item.label}</TooltipContent>
|
||||
</Tooltip>
|
||||
{:else}
|
||||
<a href={navHref(item.href)} class={linkClass(active, false)} onclick={onNavigate}>
|
||||
<Icon class="size-4" />
|
||||
{item.label}
|
||||
</a>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
@@ -0,0 +1,56 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { buttonVariants } from '$lib/ui/core/button/index.js';
|
||||
import { Separator } from '$lib/ui/core/separator/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
import PanelLeftClose from '@lucide/svelte/icons/panel-left-close';
|
||||
import PanelLeftOpen from '@lucide/svelte/icons/panel-left-open';
|
||||
import AppNavLinks from './app-nav-links.svelte';
|
||||
import ThemeMenu from './theme-menu.svelte';
|
||||
|
||||
let {
|
||||
collapsed = $bindable(false),
|
||||
theme = $bindable<ThemePreference>('system')
|
||||
}: {
|
||||
collapsed?: boolean;
|
||||
theme?: ThemePreference;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<aside
|
||||
class={cn(
|
||||
'border-border bg-sidebar sticky top-0 hidden h-screen shrink-0 flex-col overflow-hidden border-r transition-all duration-200 md:flex',
|
||||
collapsed ? 'w-14' : 'w-56'
|
||||
)}
|
||||
aria-label="Основная навигация"
|
||||
>
|
||||
<div class={cn('flex items-center gap-2 p-3', collapsed && 'justify-center')}>
|
||||
{#if !collapsed}
|
||||
<div class="min-w-0 flex-1">
|
||||
<a href={resolve('/')} class="text-sidebar-foreground block truncate font-semibold tracking-tight"
|
||||
>EvoBGP</a
|
||||
>
|
||||
<p class="text-sidebar-foreground/50 truncate text-xs">Панель управления</p>
|
||||
</div>
|
||||
{/if}
|
||||
<ThemeMenu bind:theme />
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (collapsed = !collapsed)}
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'ghost', size: 'icon-sm' }),
|
||||
'text-sidebar-foreground/60 hover:text-sidebar-foreground shrink-0'
|
||||
)}
|
||||
aria-label={collapsed ? 'Развернуть меню' : 'Свернуть меню'}
|
||||
>
|
||||
{#if collapsed}
|
||||
<PanelLeftOpen class="size-4" />
|
||||
{:else}
|
||||
<PanelLeftClose class="size-4" />
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
<Separator />
|
||||
<AppNavLinks {collapsed} />
|
||||
</aside>
|
||||
@@ -0,0 +1,38 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
type Props = {
|
||||
title?: string;
|
||||
description?: string;
|
||||
actions?: Snippet;
|
||||
mobileNav?: Snippet;
|
||||
class?: string;
|
||||
};
|
||||
|
||||
let { title, description, actions, mobileNav, class: className }: Props = $props();
|
||||
</script>
|
||||
|
||||
<header
|
||||
class={cn(
|
||||
'border-border bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-30 flex flex-col gap-3 border-b px-4 py-3 backdrop-blur md:px-6',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
{#if mobileNav}
|
||||
<div class="shrink-0 pt-0.5 md:hidden">{@render mobileNav()}</div>
|
||||
{/if}
|
||||
<div class="min-w-0 flex-1">
|
||||
{#if title}
|
||||
<h1 class="text-lg font-semibold tracking-tight md:text-xl">{title}</h1>
|
||||
{/if}
|
||||
{#if description}
|
||||
<p class="text-muted-foreground mt-0.5 text-sm">{description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{#if actions}
|
||||
<div class="flex shrink-0 flex-wrap items-center gap-2">{@render actions()}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { Component } from 'svelte';
|
||||
import Activity from '@lucide/svelte/icons/activity';
|
||||
import Boxes from '@lucide/svelte/icons/boxes';
|
||||
import BookOpen from '@lucide/svelte/icons/book-open';
|
||||
import CalendarClock from '@lucide/svelte/icons/calendar-clock';
|
||||
import Gauge from '@lucide/svelte/icons/gauge';
|
||||
import LayoutDashboard from '@lucide/svelte/icons/layout-dashboard';
|
||||
import Network from '@lucide/svelte/icons/network';
|
||||
import Settings from '@lucide/svelte/icons/settings';
|
||||
import Zap from '@lucide/svelte/icons/zap';
|
||||
|
||||
export type NavItem = {
|
||||
href: string;
|
||||
label: string;
|
||||
icon: Component;
|
||||
};
|
||||
|
||||
export const mainNav: NavItem[] = [
|
||||
{ href: '/', label: 'Обзор', icon: LayoutDashboard },
|
||||
{ href: '/modules', label: 'Модули', icon: Boxes },
|
||||
{ href: '/directories', label: 'Справочники', icon: BookOpen },
|
||||
{ href: '/network', label: 'Сеть', icon: Network },
|
||||
{ href: '/revisions', label: 'Ревизии', icon: Activity },
|
||||
{ href: '/operations', label: 'Операции', icon: Zap },
|
||||
{ href: '/schedule', label: 'Расписание', icon: CalendarClock },
|
||||
{ href: '/monitoring', label: 'Мониторинг', icon: Gauge }
|
||||
];
|
||||
|
||||
export const bottomNav: NavItem[] = [{ href: '/settings', label: 'Настройки', icon: Settings }];
|
||||
@@ -0,0 +1,51 @@
|
||||
<script lang="ts">
|
||||
import { cn } from '$lib/utils.js';
|
||||
import { buttonVariants } from '$lib/ui/core/button/index.js';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
DropdownMenuTrigger
|
||||
} from '$lib/ui/core/dropdown-menu/index.js';
|
||||
import type { ThemePreference } from '$lib/theme.js';
|
||||
import Sun from '@lucide/svelte/icons/sun';
|
||||
import Moon from '@lucide/svelte/icons/moon';
|
||||
import Monitor from '@lucide/svelte/icons/monitor';
|
||||
|
||||
let { theme = $bindable<ThemePreference>('system'), class: className }: { theme?: ThemePreference; class?: string } = $props();
|
||||
</script>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
class={cn(
|
||||
buttonVariants({ variant: 'ghost', size: 'icon-sm' }),
|
||||
'text-sidebar-foreground/60 hover:text-sidebar-foreground shrink-0',
|
||||
className
|
||||
)}
|
||||
aria-label="Тема оформления"
|
||||
>
|
||||
<span class="flex size-4 items-center justify-center">
|
||||
<Sun class="size-4 dark:hidden" />
|
||||
<Moon class="hidden size-4 dark:block" />
|
||||
</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" class="w-44">
|
||||
<DropdownMenuLabel>Тема</DropdownMenuLabel>
|
||||
<DropdownMenuRadioGroup bind:value={theme}>
|
||||
<DropdownMenuRadioItem value="light" class="gap-2">
|
||||
<Sun class="size-4" />
|
||||
Светлая
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="dark" class="gap-2">
|
||||
<Moon class="size-4" />
|
||||
Тёмная
|
||||
</DropdownMenuRadioItem>
|
||||
<DropdownMenuRadioItem value="system" class="gap-2">
|
||||
<Monitor class="size-4" />
|
||||
Как в системе
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script lang="ts">
|
||||
import type { Component, Snippet } from 'svelte';
|
||||
import { cn } from '$lib/utils.js';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
description?: string;
|
||||
icon?: Component;
|
||||
iconClass?: string;
|
||||
actions?: Snippet;
|
||||
class?: string;
|
||||
};
|
||||
|
||||
let { title, description, icon: Icon, iconClass, actions, class: className }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn('flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between', className)}>
|
||||
<div class="flex min-w-0 items-start gap-3">
|
||||
{#if Icon}
|
||||
<div
|
||||
class={cn(
|
||||
'flex size-11 shrink-0 items-center justify-center rounded-xl',
|
||||
iconClass ?? 'bg-muted text-muted-foreground'
|
||||
)}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<Icon class="size-6" />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="min-w-0">
|
||||
<h1 class="text-2xl font-semibold tracking-tight">{title}</h1>
|
||||
{#if description}
|
||||
<p class="text-muted-foreground mt-1 text-sm">{description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if actions}
|
||||
<div class="flex shrink-0 flex-wrap items-center gap-2">{@render actions()}</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
export const notify = {
|
||||
success: (message: string, description?: string) =>
|
||||
toast.success(message, description ? { description } : undefined),
|
||||
error: (message: string, description?: string) =>
|
||||
toast.error(message, description ? { description } : undefined),
|
||||
info: (message: string, description?: string) =>
|
||||
toast.info(message, description ? { description } : undefined),
|
||||
warning: (message: string, description?: string) =>
|
||||
toast.warning(message, description ? { description } : undefined),
|
||||
promise: toast.promise,
|
||||
dismiss: toast.dismiss,
|
||||
message: toast.message
|
||||
};
|
||||
|
||||
export function notifyApiError(e: unknown, fallback = 'Ошибка запроса') {
|
||||
const message = e instanceof Error ? e.message : String(e);
|
||||
notify.error(message || fallback);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# Design tokens (EvoBGP WebUI)
|
||||
|
||||
Базовая тема — [shadcn-svelte](https://www.shadcn-svelte.com), переменные в [`src/routes/layout.css`](../../routes/layout.css).
|
||||
|
||||
## Layout
|
||||
|
||||
| Token | Значение | Tailwind |
|
||||
|-------|----------|----------|
|
||||
| `--page-padding` | 1.5rem | `p-page` через `p-[var(--page-padding)]` |
|
||||
| `--section-gap` | 1.5rem | `gap-section` |
|
||||
|
||||
## Радиусы
|
||||
|
||||
`--radius-sm` … `--radius-xl` — из `--radius` (shadcn).
|
||||
|
||||
## Семантика
|
||||
|
||||
`success`, `warning`, `info`, `destructive` — классы `text-success`, `bg-warning/10`, `border-info` и т.д.
|
||||
|
||||
## Размеры компонентов
|
||||
|
||||
Button/Input: `sm` | `default` | `lg` — через `buttonVariants` и классы input в `ui/core`.
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
buttonVariants,
|
||||
type ButtonVariant,
|
||||
type ButtonSize,
|
||||
} from "$lib/components/ui/button/index.js";
|
||||
} from "$lib/ui/core/button/index.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
buttonVariants,
|
||||
type ButtonVariant,
|
||||
type ButtonSize,
|
||||
} from "$lib/components/ui/button/index.js";
|
||||
} from "$lib/ui/core/button/index.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,40 @@
|
||||
import Root from "./alert-dialog.svelte";
|
||||
import Portal from "./alert-dialog-portal.svelte";
|
||||
import Trigger from "./alert-dialog-trigger.svelte";
|
||||
import Title from "./alert-dialog-title.svelte";
|
||||
import Action from "./alert-dialog-action.svelte";
|
||||
import Cancel from "./alert-dialog-cancel.svelte";
|
||||
import Footer from "./alert-dialog-footer.svelte";
|
||||
import Header from "./alert-dialog-header.svelte";
|
||||
import Overlay from "./alert-dialog-overlay.svelte";
|
||||
import Content from "./alert-dialog-content.svelte";
|
||||
import Description from "./alert-dialog-description.svelte";
|
||||
import Media from "./alert-dialog-media.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Action,
|
||||
Cancel,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
Media,
|
||||
//
|
||||
Root as AlertDialog,
|
||||
Title as AlertDialogTitle,
|
||||
Action as AlertDialogAction,
|
||||
Cancel as AlertDialogCancel,
|
||||
Portal as AlertDialogPortal,
|
||||
Footer as AlertDialogFooter,
|
||||
Header as AlertDialogHeader,
|
||||
Trigger as AlertDialogTrigger,
|
||||
Overlay as AlertDialogOverlay,
|
||||
Content as AlertDialogContent,
|
||||
Description as AlertDialogDescription,
|
||||
Media as AlertDialogMedia,
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,17 @@
|
||||
import Root from "./alert.svelte";
|
||||
import Description from "./alert-description.svelte";
|
||||
import Title from "./alert-title.svelte";
|
||||
import Action from "./alert-action.svelte";
|
||||
export { alertVariants, type AlertVariant } from "./alert.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Description,
|
||||
Title,
|
||||
Action,
|
||||
//
|
||||
Root as Alert,
|
||||
Description as AlertDescription,
|
||||
Title as AlertTitle,
|
||||
Action as AlertAction,
|
||||
};
|
||||
File renamed without changes.
@@ -0,0 +1,2 @@
|
||||
export { default as Badge } from "./badge.svelte";
|
||||
export { badgeVariants, type BadgeVariant } from "./badge.svelte";
|
||||
File renamed without changes.
@@ -0,0 +1,17 @@
|
||||
import Root, {
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
buttonVariants,
|
||||
} from "./button.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
type ButtonProps as Props,
|
||||
//
|
||||
Root as Button,
|
||||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,25 @@
|
||||
import Root from "./card.svelte";
|
||||
import Content from "./card-content.svelte";
|
||||
import Description from "./card-description.svelte";
|
||||
import Footer from "./card-footer.svelte";
|
||||
import Header from "./card-header.svelte";
|
||||
import Title from "./card-title.svelte";
|
||||
import Action from "./card-action.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Description,
|
||||
Footer,
|
||||
Header,
|
||||
Title,
|
||||
Action,
|
||||
//
|
||||
Root as Card,
|
||||
Content as CardContent,
|
||||
Description as CardDescription,
|
||||
Footer as CardFooter,
|
||||
Header as CardHeader,
|
||||
Title as CardTitle,
|
||||
Action as CardAction,
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { Checkbox as CheckboxPrimitive } from "bits-ui";
|
||||
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||
import CheckIcon from '@lucide/svelte/icons/check';
|
||||
import MinusIcon from '@lucide/svelte/icons/minus';
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
checked = $bindable(false),
|
||||
indeterminate = $bindable(false),
|
||||
class: className,
|
||||
...restProps
|
||||
}: WithoutChildrenOrChild<CheckboxPrimitive.RootProps> = $props();
|
||||
</script>
|
||||
|
||||
<CheckboxPrimitive.Root
|
||||
bind:ref
|
||||
data-slot="checkbox"
|
||||
class={cn(
|
||||
"border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-[4px] border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
bind:checked
|
||||
bind:indeterminate
|
||||
{...restProps}
|
||||
>
|
||||
{#snippet children({ checked, indeterminate })}
|
||||
<div
|
||||
data-slot="checkbox-indicator"
|
||||
class="[&>svg]:size-3.5 grid place-content-center text-current transition-none"
|
||||
>
|
||||
{#if checked}
|
||||
<CheckIcon />
|
||||
{:else if indeterminate}
|
||||
<MinusIcon />
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
</CheckboxPrimitive.Root>
|
||||
@@ -0,0 +1,6 @@
|
||||
import Root from "./checkbox.svelte";
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Checkbox,
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
||||
export { default as FlexRender } from "./flex-render.svelte";
|
||||
export { renderComponent, renderSnippet } from "./render-helpers.js";
|
||||
export { createSvelteTable } from "./data-table.svelte.js";
|
||||
File renamed without changes.
File renamed without changes.
+1
-1
@@ -5,7 +5,7 @@
|
||||
import * as Dialog from "./index.js";
|
||||
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||
import type { ComponentProps } from "svelte";
|
||||
import { Button } from "$lib/components/ui/button/index.js";
|
||||
import { Button } from "$lib/ui/core/button/index.js";
|
||||
import XIcon from '@lucide/svelte/icons/x';
|
||||
|
||||
let {
|
||||
File renamed without changes.
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { Dialog as DialogPrimitive } from "bits-ui";
|
||||
import { Button } from "$lib/components/ui/button/index.js";
|
||||
import { Button } from "$lib/ui/core/button/index.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,34 @@
|
||||
import Root from "./dialog.svelte";
|
||||
import Portal from "./dialog-portal.svelte";
|
||||
import Title from "./dialog-title.svelte";
|
||||
import Footer from "./dialog-footer.svelte";
|
||||
import Header from "./dialog-header.svelte";
|
||||
import Overlay from "./dialog-overlay.svelte";
|
||||
import Content from "./dialog-content.svelte";
|
||||
import Description from "./dialog-description.svelte";
|
||||
import Trigger from "./dialog-trigger.svelte";
|
||||
import Close from "./dialog-close.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
Close,
|
||||
//
|
||||
Root as Dialog,
|
||||
Title as DialogTitle,
|
||||
Portal as DialogPortal,
|
||||
Footer as DialogFooter,
|
||||
Header as DialogHeader,
|
||||
Trigger as DialogTrigger,
|
||||
Overlay as DialogOverlay,
|
||||
Content as DialogContent,
|
||||
Description as DialogDescription,
|
||||
Close as DialogClose,
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 200 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user