diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index 6635cf5..9658236 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -1,3 +1,4 @@ +test-results .DS_Store node_modules /build @@ -8,3 +9,6 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* + +# Paraglide +src/lib/paraglide diff --git a/apps/docs/.prettierrc b/apps/docs/.prettierrc index ddc56a2..9cb2bec 100644 --- a/apps/docs/.prettierrc +++ b/apps/docs/.prettierrc @@ -10,5 +10,7 @@ "endOfLine": "lf", "jsxSingleQuote": false, "bracketSameLine": false, - "quoteProps": "as-needed" + "quoteProps": "as-needed", + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindStylesheet": "./src/app.css" } diff --git a/apps/docs/components.json b/apps/docs/components.json new file mode 100644 index 0000000..c5d91b4 --- /dev/null +++ b/apps/docs/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src/app.css", + "baseColor": "slate" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": true, + "registry": "https://shadcn-svelte.com/registry" +} diff --git a/apps/docs/e2e/demo.test.ts b/apps/docs/e2e/demo.test.ts new file mode 100644 index 0000000..4e8ffcc --- /dev/null +++ b/apps/docs/e2e/demo.test.ts @@ -0,0 +1,6 @@ +import { expect, test } from "@playwright/test"; + +test("home page has expected h1", async ({ page }) => { + await page.goto("/"); + await expect(page.locator("h1")).toBeVisible(); +}); diff --git a/apps/docs/messages/de.json b/apps/docs/messages/de.json new file mode 100644 index 0000000..4e4a635 --- /dev/null +++ b/apps/docs/messages/de.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from de!" +} diff --git a/apps/docs/messages/en.json b/apps/docs/messages/en.json new file mode 100644 index 0000000..97efb22 --- /dev/null +++ b/apps/docs/messages/en.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from en!" +} diff --git a/apps/docs/package.json b/apps/docs/package.json index b7af88a..41eeb3f 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,37 +1,71 @@ { - "name": "docs", - "version": "0.0.1", - "private": true, - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "svelte-kit sync && vite build", - "preview": "vite preview", - "test": "npm run test:integration && npm run test:unit", - "check-types": "tsc --noEmit", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "eslint .", - "test:integration": "playwright test", - "test:unit": "vitest" - }, - "dependencies": { - "@repo/ui": "workspace:*" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@sveltejs/adapter-auto": "^4.0.0", - "@sveltejs/kit": "^2.36.1", - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "prettier": "^3.6.0", - "eslint": "^9.34.0", - "prettier-plugin-svelte": "^3.4.0", - "svelte": "^5.38.0", - "svelte-check": "^4.3.0", - "tslib": "^2.8.1", - "typescript": "5.9.2", - "vite": "^6.3.2", - "vitest": "^3.2.0" - } + "name": "docs", + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "svelte-kit sync && vite build", + "preview": "vite preview", + "test": "npm run test:integration && npm run test:unit && npm run test:e2e && npm run test:unit -- --run", + "check-types": "tsc --noEmit", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "eslint .", + "test:integration": "playwright test", + "test:unit": "vitest", + "test:e2e": "playwright test" + }, + "devDependencies": { + "@inlang/paraglide-js": "^2.0.0", + "@internationalized/date": "^3.9.0", + "@lucide/svelte": "^0.544.0", + "@playwright/test": "^1.49.1", + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@shikijs/langs": "^3.13.0", + "@shikijs/themes": "^3.13.0", + "@sveltejs/adapter-node": "^5.2.12", + "@sveltejs/kit": "^2.36.1", + "@sveltejs/vite-plugin-svelte": "^5.1.0", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", + "@tailwindcss/vite": "^4.0.0", + "@tanstack/table-core": "^8.21.3", + "@vitest/browser": "^3.2.3", + "bits-ui": "^2.11.0", + "clsx": "^2.1.1", + "embla-carousel-svelte": "^8.6.0", + "eslint": "^9.34.0", + "formsnap": "^2.0.1", + "isomorphic-dompurify": "^2.28.0", + "layerchart": "2.0.0-next.27", + "mdsvex": "^0.12.3", + "mode-watcher": "^1.1.0", + "paneforge": "^1.0.2", + "playwright": "^1.53.0", + "prettier": "^3.6.0", + "prettier-plugin-svelte": "^3.4.0", + "prettier-plugin-tailwindcss": "^0.6.11", + "runed": "^0.31.1", + "shiki": "^3.13.0", + "svelte": "^5.38.0", + "svelte-check": "^4.3.0", + "svelte-sonner": "^1.0.5", + "svelte-toolbelt": "^0.9.3", + "sveltekit-superforms": "^2.27.1", + "tailwind-merge": "^3.3.1", + "tailwind-variants": "^3.1.1", + "tailwindcss": "^4.0.0", + "tslib": "^2.8.1", + "tw-animate-css": "^1.3.8", + "typescript": "5.9.2", + "vaul-svelte": "1.0.0-next.7", + "vite": "^6.3.2", + "vite-plugin-devtools-json": "^1.0.0", + "vitest": "^3.2.3", + "vitest-browser-svelte": "^0.1.0" + }, + "dependencies": { + "marked": "^12.0.2" + } } diff --git a/apps/docs/playwright.config.ts b/apps/docs/playwright.config.ts index 1c5d7a1..752c857 100644 --- a/apps/docs/playwright.config.ts +++ b/apps/docs/playwright.config.ts @@ -1,12 +1,12 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; +import type { PlaywrightTestConfig } from "@playwright/test"; const config: PlaywrightTestConfig = { - webServer: { - command: 'npm run build && npm run preview', - port: 4173 - }, - testDir: 'tests', - testMatch: /(.+\.)?(test|spec)\.[jt]s/ + webServer: { + command: "npm run build && npm run preview", + port: 4173 + }, + testDir: "e2e", + testMatch: /(.+\.)?(test|spec)\.[jt]s/ }; export default config; diff --git a/apps/docs/project.inlang/cache/plugins/2sy648wh9sugi b/apps/docs/project.inlang/cache/plugins/2sy648wh9sugi new file mode 100644 index 0000000..5b07e0d --- /dev/null +++ b/apps/docs/project.inlang/cache/plugins/2sy648wh9sugi @@ -0,0 +1 @@ +var Un=Object.create;var Xe=Object.defineProperty;var Pn=Object.getOwnPropertyDescriptor;var vn=Object.getOwnPropertyNames;var Nn=Object.getPrototypeOf,Sn=Object.prototype.hasOwnProperty;var Rn=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports);var xn=(s,e,i,u)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of vn(e))!Sn.call(s,p)&&p!==i&&Xe(s,p,{get:()=>e[p],enumerable:!(u=Pn(e,p))||u.enumerable});return s};var jn=(s,e,i)=>(i=s!=null?Un(Nn(s)):{},xn(e||!s||!s.__esModule?Xe(i,"default",{value:s,enumerable:!0}):i,s));var he=Rn(o=>{"use strict";Object.defineProperty(o,"__esModule",{value:!0});o.Type=o.JsonType=o.JavaScriptTypeBuilder=o.JsonTypeBuilder=o.TypeBuilder=o.TypeBuilderError=o.TransformEncodeBuilder=o.TransformDecodeBuilder=o.TemplateLiteralDslParser=o.TemplateLiteralGenerator=o.TemplateLiteralGeneratorError=o.TemplateLiteralFinite=o.TemplateLiteralFiniteError=o.TemplateLiteralParser=o.TemplateLiteralParserError=o.TemplateLiteralResolver=o.TemplateLiteralPattern=o.TemplateLiteralPatternError=o.UnionResolver=o.KeyArrayResolver=o.KeyArrayResolverError=o.KeyResolver=o.ObjectMap=o.Intrinsic=o.IndexedAccessor=o.TypeClone=o.TypeExtends=o.TypeExtendsResult=o.TypeExtendsError=o.ExtendsUndefined=o.TypeGuard=o.TypeGuardUnknownTypeError=o.ValueGuard=o.FormatRegistry=o.TypeBoxError=o.TypeRegistry=o.PatternStringExact=o.PatternNumberExact=o.PatternBooleanExact=o.PatternString=o.PatternNumber=o.PatternBoolean=o.Kind=o.Hint=o.Optional=o.Readonly=o.Transform=void 0;o.Transform=Symbol.for("TypeBox.Transform");o.Readonly=Symbol.for("TypeBox.Readonly");o.Optional=Symbol.for("TypeBox.Optional");o.Hint=Symbol.for("TypeBox.Hint");o.Kind=Symbol.for("TypeBox.Kind");o.PatternBoolean="(true|false)";o.PatternNumber="(0|[1-9][0-9]*)";o.PatternString="(.*)";o.PatternBooleanExact=`^${o.PatternBoolean}$`;o.PatternNumberExact=`^${o.PatternNumber}$`;o.PatternStringExact=`^${o.PatternString}$`;var Ve;(function(s){let e=new Map;function i(){return new Map(e)}s.Entries=i;function u(){return e.clear()}s.Clear=u;function p(y){return e.delete(y)}s.Delete=p;function l(y){return e.has(y)}s.Has=l;function c(y,b){e.set(y,b)}s.Set=c;function T(y){return e.get(y)}s.Get=T})(Ve||(o.TypeRegistry=Ve={}));var D=class extends Error{constructor(e){super(e)}};o.TypeBoxError=D;var Ze;(function(s){let e=new Map;function i(){return new Map(e)}s.Entries=i;function u(){return e.clear()}s.Clear=u;function p(y){return e.delete(y)}s.Delete=p;function l(y){return e.has(y)}s.Has=l;function c(y,b){e.set(y,b)}s.Set=c;function T(y){return e.get(y)}s.Get=T})(Ze||(o.FormatRegistry=Ze={}));var I;(function(s){function e(m){return Array.isArray(m)}s.IsArray=e;function i(m){return typeof m=="bigint"}s.IsBigInt=i;function u(m){return typeof m=="boolean"}s.IsBoolean=u;function p(m){return m instanceof globalThis.Date}s.IsDate=p;function l(m){return m===null}s.IsNull=l;function c(m){return typeof m=="number"}s.IsNumber=c;function T(m){return typeof m=="object"&&m!==null}s.IsObject=T;function y(m){return typeof m=="string"}s.IsString=y;function b(m){return m instanceof globalThis.Uint8Array}s.IsUint8Array=b;function g(m){return m===void 0}s.IsUndefined=g})(I||(o.ValueGuard=I={}));var ze=class extends D{};o.TypeGuardUnknownTypeError=ze;var a;(function(s){function e(r){try{return new RegExp(r),!0}catch{return!1}}function i(r){if(!I.IsString(r))return!1;for(let L=0;L=7&&B<=13||B===27||B===127)return!1}return!0}function u(r){return c(r)||C(r)}function p(r){return I.IsUndefined(r)||I.IsBigInt(r)}function l(r){return I.IsUndefined(r)||I.IsNumber(r)}function c(r){return I.IsUndefined(r)||I.IsBoolean(r)}function T(r){return I.IsUndefined(r)||I.IsString(r)}function y(r){return I.IsUndefined(r)||I.IsString(r)&&i(r)&&e(r)}function b(r){return I.IsUndefined(r)||I.IsString(r)&&i(r)}function g(r){return I.IsUndefined(r)||C(r)}function m(r){return S(r,"Any")&&T(r.$id)}s.TAny=m;function U(r){return S(r,"Array")&&r.type==="array"&&T(r.$id)&&C(r.items)&&l(r.minItems)&&l(r.maxItems)&&c(r.uniqueItems)&&g(r.contains)&&l(r.minContains)&&l(r.maxContains)}s.TArray=U;function d(r){return S(r,"AsyncIterator")&&r.type==="AsyncIterator"&&T(r.$id)&&C(r.items)}s.TAsyncIterator=d;function O(r){return S(r,"BigInt")&&r.type==="bigint"&&T(r.$id)&&p(r.exclusiveMaximum)&&p(r.exclusiveMinimum)&&p(r.maximum)&&p(r.minimum)&&p(r.multipleOf)}s.TBigInt=O;function v(r){return S(r,"Boolean")&&r.type==="boolean"&&T(r.$id)}s.TBoolean=v;function N(r){return S(r,"Constructor")&&r.type==="Constructor"&&T(r.$id)&&I.IsArray(r.parameters)&&r.parameters.every(L=>C(L))&&C(r.returns)}s.TConstructor=N;function j(r){return S(r,"Date")&&r.type==="Date"&&T(r.$id)&&l(r.exclusiveMaximumTimestamp)&&l(r.exclusiveMinimumTimestamp)&&l(r.maximumTimestamp)&&l(r.minimumTimestamp)&&l(r.multipleOfTimestamp)}s.TDate=j;function R(r){return S(r,"Function")&&r.type==="Function"&&T(r.$id)&&I.IsArray(r.parameters)&&r.parameters.every(L=>C(L))&&C(r.returns)}s.TFunction=R;function A(r){return S(r,"Integer")&&r.type==="integer"&&T(r.$id)&&l(r.exclusiveMaximum)&&l(r.exclusiveMinimum)&&l(r.maximum)&&l(r.minimum)&&l(r.multipleOf)}s.TInteger=A;function K(r){return S(r,"Intersect")&&!(I.IsString(r.type)&&r.type!=="object")&&I.IsArray(r.allOf)&&r.allOf.every(L=>C(L)&&!oe(L))&&T(r.type)&&(c(r.unevaluatedProperties)||g(r.unevaluatedProperties))&&T(r.$id)}s.TIntersect=K;function pe(r){return S(r,"Iterator")&&r.type==="Iterator"&&T(r.$id)&&C(r.items)}s.TIterator=pe;function S(r,L){return ee(r)&&r[o.Kind]===L}s.TKindOf=S;function ee(r){return I.IsObject(r)&&o.Kind in r&&I.IsString(r[o.Kind])}s.TKind=ee;function ne(r){return V(r)&&I.IsString(r.const)}s.TLiteralString=ne;function Te(r){return V(r)&&I.IsNumber(r.const)}s.TLiteralNumber=Te;function Ke(r){return V(r)&&I.IsBoolean(r.const)}s.TLiteralBoolean=Ke;function V(r){return S(r,"Literal")&&T(r.$id)&&(I.IsBoolean(r.const)||I.IsNumber(r.const)||I.IsString(r.const))}s.TLiteral=V;function fe(r){return S(r,"Never")&&I.IsObject(r.not)&&Object.getOwnPropertyNames(r.not).length===0}s.TNever=fe;function $(r){return S(r,"Not")&&C(r.not)}s.TNot=$;function te(r){return S(r,"Null")&&r.type==="null"&&T(r.$id)}s.TNull=te;function re(r){return S(r,"Number")&&r.type==="number"&&T(r.$id)&&l(r.exclusiveMaximum)&&l(r.exclusiveMinimum)&&l(r.maximum)&&l(r.minimum)&&l(r.multipleOf)}s.TNumber=re;function _(r){return S(r,"Object")&&r.type==="object"&&T(r.$id)&&I.IsObject(r.properties)&&u(r.additionalProperties)&&l(r.minProperties)&&l(r.maxProperties)&&Object.entries(r.properties).every(([L,B])=>i(L)&&C(B))}s.TObject=_;function ie(r){return S(r,"Promise")&&r.type==="Promise"&&T(r.$id)&&C(r.item)}s.TPromise=ie;function de(r){return S(r,"Record")&&r.type==="object"&&T(r.$id)&&u(r.additionalProperties)&&I.IsObject(r.patternProperties)&&(L=>{let B=Object.getOwnPropertyNames(L.patternProperties);return B.length===1&&e(B[0])&&I.IsObject(L.patternProperties)&&C(L.patternProperties[B[0]])})(r)}s.TRecord=de;function Ee(r){return I.IsObject(r)&&o.Hint in r&&r[o.Hint]==="Recursive"}s.TRecursive=Ee;function ye(r){return S(r,"Ref")&&T(r.$id)&&I.IsString(r.$ref)}s.TRef=ye;function me(r){return S(r,"String")&&r.type==="string"&&T(r.$id)&&l(r.minLength)&&l(r.maxLength)&&y(r.pattern)&&b(r.format)}s.TString=me;function ge(r){return S(r,"Symbol")&&r.type==="symbol"&&T(r.$id)}s.TSymbol=ge;function z(r){return S(r,"TemplateLiteral")&&r.type==="string"&&I.IsString(r.pattern)&&r.pattern[0]==="^"&&r.pattern[r.pattern.length-1]==="$"}s.TTemplateLiteral=z;function Ie(r){return S(r,"This")&&T(r.$id)&&I.IsString(r.$ref)}s.TThis=Ie;function oe(r){return I.IsObject(r)&&o.Transform in r}s.TTransform=oe;function F(r){return S(r,"Tuple")&&r.type==="array"&&T(r.$id)&&I.IsNumber(r.minItems)&&I.IsNumber(r.maxItems)&&r.minItems===r.maxItems&&(I.IsUndefined(r.items)&&I.IsUndefined(r.additionalItems)&&r.minItems===0||I.IsArray(r.items)&&r.items.every(L=>C(L)))}s.TTuple=F;function be(r){return S(r,"Undefined")&&r.type==="undefined"&&T(r.$id)}s.TUndefined=be;function Be(r){return q(r)&&r.anyOf.every(L=>ne(L)||Te(L))}s.TUnionLiteral=Be;function q(r){return S(r,"Union")&&T(r.$id)&&I.IsObject(r)&&I.IsArray(r.anyOf)&&r.anyOf.every(L=>C(L))}s.TUnion=q;function W(r){return S(r,"Uint8Array")&&r.type==="Uint8Array"&&T(r.$id)&&l(r.minByteLength)&&l(r.maxByteLength)}s.TUint8Array=W;function E(r){return S(r,"Unknown")&&T(r.$id)}s.TUnknown=E;function Oe(r){return S(r,"Unsafe")}s.TUnsafe=Oe;function se(r){return S(r,"Void")&&r.type==="void"&&T(r.$id)}s.TVoid=se;function Me(r){return I.IsObject(r)&&r[o.Readonly]==="Readonly"}s.TReadonly=Me;function De(r){return I.IsObject(r)&&r[o.Optional]==="Optional"}s.TOptional=De;function C(r){return I.IsObject(r)&&(m(r)||U(r)||v(r)||O(r)||d(r)||N(r)||j(r)||R(r)||A(r)||K(r)||pe(r)||V(r)||fe(r)||$(r)||te(r)||re(r)||_(r)||ie(r)||de(r)||ye(r)||me(r)||ge(r)||z(r)||Ie(r)||F(r)||be(r)||q(r)||W(r)||E(r)||Oe(r)||se(r)||ee(r)&&Ve.Has(r[o.Kind]))}s.TSchema=C})(a||(o.TypeGuard=a={}));var Ge;(function(s){function e(i){return i[o.Kind]==="Intersect"?i.allOf.every(u=>e(u)):i[o.Kind]==="Union"?i.anyOf.some(u=>e(u)):i[o.Kind]==="Undefined"?!0:i[o.Kind]==="Not"?!e(i.not):!1}s.Check=e})(Ge||(o.ExtendsUndefined=Ge={}));var Ue=class extends D{};o.TypeExtendsError=Ue;var f;(function(s){s[s.Union=0]="Union",s[s.True=1]="True",s[s.False=2]="False"})(f||(o.TypeExtendsResult=f={}));var J;(function(s){function e(n){return n===f.False?n:f.True}function i(n){throw new Ue(n)}function u(n){return a.TNever(n)||a.TIntersect(n)||a.TUnion(n)||a.TUnknown(n)||a.TAny(n)}function p(n,t){return a.TNever(t)?S(n,t):a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TUnknown(t)?Qe(n,t):a.TAny(t)?l(n,t):i("StructuralRight")}function l(n,t){return f.True}function c(n,t){return a.TIntersect(t)?R(n,t):a.TUnion(t)&&t.anyOf.some(x=>a.TAny(x)||a.TUnknown(x))?f.True:a.TUnion(t)?f.Union:a.TUnknown(t)||a.TAny(t)?f.True:f.Union}function T(n,t){return a.TUnknown(n)?f.False:a.TAny(n)?f.Union:a.TNever(n)?f.True:f.False}function y(n,t){return a.TObject(t)&&z(t)?f.True:u(t)?p(n,t):a.TArray(t)?e(w(n.items,t.items)):f.False}function b(n,t){return u(t)?p(n,t):a.TAsyncIterator(t)?e(w(n.items,t.items)):f.False}function g(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TBigInt(t)?f.True:f.False}function m(n,t){return a.TLiteral(n)&&I.IsBoolean(n.const)||a.TBoolean(n)?f.True:f.False}function U(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TBoolean(t)?f.True:f.False}function d(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TConstructor(t)?n.parameters.length>t.parameters.length?f.False:n.parameters.every((x,M)=>e(w(t.parameters[M],x))===f.True)?e(w(n.returns,t.returns)):f.False:f.False}function O(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TDate(t)?f.True:f.False}function v(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TFunction(t)?n.parameters.length>t.parameters.length?f.False:n.parameters.every((x,M)=>e(w(t.parameters[M],x))===f.True)?e(w(n.returns,t.returns)):f.False:f.False}function N(n,t){return a.TLiteral(n)&&I.IsNumber(n.const)||a.TNumber(n)||a.TInteger(n)?f.True:f.False}function j(n,t){return a.TInteger(t)||a.TNumber(t)?f.True:u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):f.False}function R(n,t){return t.allOf.every(x=>w(n,x)===f.True)?f.True:f.False}function A(n,t){return n.allOf.some(x=>w(x,t)===f.True)?f.True:f.False}function K(n,t){return u(t)?p(n,t):a.TIterator(t)?e(w(n.items,t.items)):f.False}function pe(n,t){return a.TLiteral(t)&&t.const===n.const?f.True:u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TString(t)?se(n,t):a.TNumber(t)?V(n,t):a.TInteger(t)?N(n,t):a.TBoolean(t)?m(n,t):f.False}function S(n,t){return f.False}function ee(n,t){return f.True}function ne(n){let[t,x]=[n,0];for(;a.TNot(t);)t=t.not,x+=1;return x%2===0?t:o.Type.Unknown()}function Te(n,t){return a.TNot(n)?w(ne(n),t):a.TNot(t)?w(n,ne(t)):i("Invalid fallthrough for Not")}function Ke(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TNull(t)?f.True:f.False}function V(n,t){return a.TLiteralNumber(n)||a.TNumber(n)||a.TInteger(n)?f.True:f.False}function fe(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TInteger(t)||a.TNumber(t)?f.True:f.False}function $(n,t){return Object.getOwnPropertyNames(n.properties).length===t}function te(n){return z(n)}function re(n){return $(n,0)||$(n,1)&&"description"in n.properties&&a.TUnion(n.properties.description)&&n.properties.description.anyOf.length===2&&(a.TString(n.properties.description.anyOf[0])&&a.TUndefined(n.properties.description.anyOf[1])||a.TString(n.properties.description.anyOf[1])&&a.TUndefined(n.properties.description.anyOf[0]))}function _(n){return $(n,0)}function ie(n){return $(n,0)}function de(n){return $(n,0)}function Ee(n){return $(n,0)}function ye(n){return z(n)}function me(n){let t=o.Type.Number();return $(n,0)||$(n,1)&&"length"in n.properties&&e(w(n.properties.length,t))===f.True}function ge(n){return $(n,0)}function z(n){let t=o.Type.Number();return $(n,0)||$(n,1)&&"length"in n.properties&&e(w(n.properties.length,t))===f.True}function Ie(n){let t=o.Type.Function([o.Type.Any()],o.Type.Any());return $(n,0)||$(n,1)&&"then"in n.properties&&e(w(n.properties.then,t))===f.True}function oe(n,t){return w(n,t)===f.False||a.TOptional(n)&&!a.TOptional(t)?f.False:f.True}function F(n,t){return a.TUnknown(n)?f.False:a.TAny(n)?f.Union:a.TNever(n)||a.TLiteralString(n)&&te(t)||a.TLiteralNumber(n)&&_(t)||a.TLiteralBoolean(n)&&ie(t)||a.TSymbol(n)&&re(t)||a.TBigInt(n)&&de(t)||a.TString(n)&&te(t)||a.TSymbol(n)&&re(t)||a.TNumber(n)&&_(t)||a.TInteger(n)&&_(t)||a.TBoolean(n)&&ie(t)||a.TUint8Array(n)&&ye(t)||a.TDate(n)&&Ee(t)||a.TConstructor(n)&&ge(t)||a.TFunction(n)&&me(t)?f.True:a.TRecord(n)&&a.TString(q(n))?t[o.Hint]==="Record"?f.True:f.False:a.TRecord(n)&&a.TNumber(q(n))?$(t,0)?f.True:f.False:f.False}function be(n,t){return u(t)?p(n,t):a.TRecord(t)?E(n,t):a.TObject(t)?(()=>{for(let x of Object.getOwnPropertyNames(t.properties)){if(!(x in n.properties)&&!a.TOptional(t.properties[x]))return f.False;if(a.TOptional(t.properties[x]))return f.True;if(oe(n.properties[x],t.properties[x])===f.False)return f.False}return f.True})():f.False}function Be(n,t){return u(t)?p(n,t):a.TObject(t)&&Ie(t)?f.True:a.TPromise(t)?e(w(n.item,t.item)):f.False}function q(n){return o.PatternNumberExact in n.patternProperties?o.Type.Number():o.PatternStringExact in n.patternProperties?o.Type.String():i("Unknown record key pattern")}function W(n){return o.PatternNumberExact in n.patternProperties?n.patternProperties[o.PatternNumberExact]:o.PatternStringExact in n.patternProperties?n.patternProperties[o.PatternStringExact]:i("Unable to get record value schema")}function E(n,t){let[x,M]=[q(t),W(t)];return a.TLiteralString(n)&&a.TNumber(x)&&e(w(n,M))===f.True?f.True:a.TUint8Array(n)&&a.TNumber(x)||a.TString(n)&&a.TNumber(x)||a.TArray(n)&&a.TNumber(x)?w(n,M):a.TObject(n)?(()=>{for(let On of Object.getOwnPropertyNames(n.properties))if(oe(M,n.properties[On])===f.False)return f.False;return f.True})():f.False}function Oe(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?w(W(n),W(t)):f.False}function se(n,t){return a.TLiteral(n)&&I.IsString(n.const)||a.TString(n)?f.True:f.False}function Me(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TString(t)?f.True:f.False}function De(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TSymbol(t)?f.True:f.False}function C(n,t){return a.TTemplateLiteral(n)?w(k.Resolve(n),t):a.TTemplateLiteral(t)?w(n,k.Resolve(t)):i("Invalid fallthrough for TemplateLiteral")}function r(n,t){return a.TArray(t)&&n.items!==void 0&&n.items.every(x=>w(x,t.items)===f.True)}function L(n,t){return a.TNever(n)?f.True:a.TUnknown(n)?f.False:a.TAny(n)?f.Union:f.False}function B(n,t){return u(t)?p(n,t):a.TObject(t)&&z(t)||a.TArray(t)&&r(n,t)?f.True:a.TTuple(t)?I.IsUndefined(n.items)&&!I.IsUndefined(t.items)||!I.IsUndefined(n.items)&&I.IsUndefined(t.items)?f.False:I.IsUndefined(n.items)&&!I.IsUndefined(t.items)||n.items.every((x,M)=>w(x,t.items[M])===f.True)?f.True:f.False:f.False}function fn(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TUint8Array(t)?f.True:f.False}function dn(n,t){return u(t)?p(n,t):a.TObject(t)?F(n,t):a.TRecord(t)?E(n,t):a.TVoid(t)?gn(n,t):a.TUndefined(t)?f.True:f.False}function ke(n,t){return t.anyOf.some(x=>w(n,x)===f.True)?f.True:f.False}function yn(n,t){return n.anyOf.every(x=>w(x,t)===f.True)?f.True:f.False}function Qe(n,t){return f.True}function mn(n,t){return a.TNever(t)?S(n,t):a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TAny(t)?l(n,t):a.TString(t)?se(n,t):a.TNumber(t)?V(n,t):a.TInteger(t)?N(n,t):a.TBoolean(t)?m(n,t):a.TArray(t)?T(n,t):a.TTuple(t)?L(n,t):a.TObject(t)?F(n,t):a.TUnknown(t)?f.True:f.False}function gn(n,t){return a.TUndefined(n)||a.TUndefined(n)?f.True:f.False}function In(n,t){return a.TIntersect(t)?R(n,t):a.TUnion(t)?ke(n,t):a.TUnknown(t)?Qe(n,t):a.TAny(t)?l(n,t):a.TObject(t)?F(n,t):a.TVoid(t)?f.True:f.False}function w(n,t){return a.TTemplateLiteral(n)||a.TTemplateLiteral(t)?C(n,t):a.TNot(n)||a.TNot(t)?Te(n,t):a.TAny(n)?c(n,t):a.TArray(n)?y(n,t):a.TBigInt(n)?g(n,t):a.TBoolean(n)?U(n,t):a.TAsyncIterator(n)?b(n,t):a.TConstructor(n)?d(n,t):a.TDate(n)?O(n,t):a.TFunction(n)?v(n,t):a.TInteger(n)?j(n,t):a.TIntersect(n)?A(n,t):a.TIterator(n)?K(n,t):a.TLiteral(n)?pe(n,t):a.TNever(n)?ee(n,t):a.TNull(n)?Ke(n,t):a.TNumber(n)?fe(n,t):a.TObject(n)?be(n,t):a.TRecord(n)?Oe(n,t):a.TString(n)?Me(n,t):a.TSymbol(n)?De(n,t):a.TTuple(n)?B(n,t):a.TPromise(n)?Be(n,t):a.TUint8Array(n)?fn(n,t):a.TUndefined(n)?dn(n,t):a.TUnion(n)?yn(n,t):a.TUnknown(n)?mn(n,t):a.TVoid(n)?In(n,t):i(`Unknown left type operand '${n[o.Kind]}'`)}function bn(n,t){return w(n,t)}s.Extends=bn})(J||(o.TypeExtends=J={}));var P;(function(s){function e(y){return y.map(b=>l(b))}function i(y){return new Date(y.getTime())}function u(y){return new Uint8Array(y)}function p(y){let b=Object.getOwnPropertyNames(y).reduce((m,U)=>({...m,[U]:l(y[U])}),{}),g=Object.getOwnPropertySymbols(y).reduce((m,U)=>({...m,[U]:l(y[U])}),{});return{...b,...g}}function l(y){return I.IsArray(y)?e(y):I.IsDate(y)?i(y):I.IsUint8Array(y)?u(y):I.IsObject(y)?p(y):y}function c(y){return y.map(b=>T(b))}s.Rest=c;function T(y,b={}){return{...l(y),...b}}s.Type=T})(P||(o.TypeClone=P={}));var qe;(function(s){function e(d){return d.map(O=>{let{[o.Optional]:v,...N}=P.Type(O);return N})}function i(d){return d.every(O=>a.TOptional(O))}function u(d){return d.some(O=>a.TOptional(O))}function p(d){return i(d.allOf)?o.Type.Optional(o.Type.Intersect(e(d.allOf))):d}function l(d){return u(d.anyOf)?o.Type.Optional(o.Type.Union(e(d.anyOf))):d}function c(d){return d[o.Kind]==="Intersect"?p(d):d[o.Kind]==="Union"?l(d):d}function T(d,O){let v=d.allOf.reduce((N,j)=>{let R=m(j,O);return R[o.Kind]==="Never"?N:[...N,R]},[]);return c(o.Type.Intersect(v))}function y(d,O){let v=d.anyOf.map(N=>m(N,O));return c(o.Type.Union(v))}function b(d,O){let v=d.properties[O];return I.IsUndefined(v)?o.Type.Never():o.Type.Union([v])}function g(d,O){let v=d.items;if(I.IsUndefined(v))return o.Type.Never();let N=v[O];return I.IsUndefined(N)?o.Type.Never():N}function m(d,O){return d[o.Kind]==="Intersect"?T(d,O):d[o.Kind]==="Union"?y(d,O):d[o.Kind]==="Object"?b(d,O):d[o.Kind]==="Tuple"?g(d,O):o.Type.Never()}function U(d,O,v={}){let N=O.map(j=>m(d,j.toString()));return c(o.Type.Union(N,v))}s.Resolve=U})(qe||(o.IndexedAccessor=qe={}));var Y;(function(s){function e(g){let[m,U]=[g.slice(0,1),g.slice(1)];return`${m.toLowerCase()}${U}`}function i(g){let[m,U]=[g.slice(0,1),g.slice(1)];return`${m.toUpperCase()}${U}`}function u(g){return g.toUpperCase()}function p(g){return g.toLowerCase()}function l(g,m){let U=X.ParseExact(g.pattern);if(!Z.Check(U))return{...g,pattern:c(g.pattern,m)};let v=[...G.Generate(U)].map(R=>o.Type.Literal(R)),N=T(v,m),j=o.Type.Union(N);return o.Type.TemplateLiteral([j])}function c(g,m){return typeof g=="string"?m==="Uncapitalize"?e(g):m==="Capitalize"?i(g):m==="Uppercase"?u(g):m==="Lowercase"?p(g):g:g.toString()}function T(g,m){if(g.length===0)return[];let[U,...d]=g;return[b(U,m),...T(d,m)]}function y(g,m){return a.TTemplateLiteral(g)?l(g,m):a.TUnion(g)?o.Type.Union(T(g.anyOf,m)):a.TLiteral(g)?o.Type.Literal(c(g.const,m)):g}function b(g,m){return y(g,m)}s.Map=b})(Y||(o.Intrinsic=Y={}));var Q;(function(s){function e(c,T){return o.Type.Intersect(c.allOf.map(y=>p(y,T)),{...c})}function i(c,T){return o.Type.Union(c.anyOf.map(y=>p(y,T)),{...c})}function u(c,T){return T(c)}function p(c,T){return c[o.Kind]==="Intersect"?e(c,T):c[o.Kind]==="Union"?i(c,T):c[o.Kind]==="Object"?u(c,T):c}function l(c,T,y){return{...p(P.Type(c),T),...y}}s.Map=l})(Q||(o.ObjectMap=Q={}));var Pe;(function(s){function e(b){return b[0]==="^"&&b[b.length-1]==="$"?b.slice(1,b.length-1):b}function i(b,g){return b.allOf.reduce((m,U)=>[...m,...c(U,g)],[])}function u(b,g){let m=b.anyOf.map(U=>c(U,g));return[...m.reduce((U,d)=>d.map(O=>m.every(v=>v.includes(O))?U.add(O):U)[0],new Set)]}function p(b,g){return Object.getOwnPropertyNames(b.properties)}function l(b,g){return g.includePatterns?Object.getOwnPropertyNames(b.patternProperties):[]}function c(b,g){return a.TIntersect(b)?i(b,g):a.TUnion(b)?u(b,g):a.TObject(b)?p(b,g):a.TRecord(b)?l(b,g):[]}function T(b,g){return[...new Set(c(b,g))]}s.ResolveKeys=T;function y(b){return`^(${T(b,{includePatterns:!0}).map(U=>`(${e(U)})`).join("|")})$`}s.ResolvePattern=y})(Pe||(o.KeyResolver=Pe={}));var ve=class extends D{};o.KeyArrayResolverError=ve;var ae;(function(s){function e(i){return Array.isArray(i)?i:a.TUnionLiteral(i)?i.anyOf.map(u=>u.const.toString()):a.TLiteral(i)?[i.const]:a.TTemplateLiteral(i)?(()=>{let u=X.ParseExact(i.pattern);if(!Z.Check(u))throw new ve("Cannot resolve keys from infinite template expression");return[...G.Generate(u)]})():[]}s.Resolve=e})(ae||(o.KeyArrayResolver=ae={}));var Je;(function(s){function*e(u){for(let p of u.anyOf)p[o.Kind]==="Union"?yield*e(p):yield p}function i(u){return o.Type.Union([...e(u)],{...u})}s.Resolve=i})(Je||(o.UnionResolver=Je={}));var Ne=class extends D{};o.TemplateLiteralPatternError=Ne;var Se;(function(s){function e(l){throw new Ne(l)}function i(l){return l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function u(l,c){return a.TTemplateLiteral(l)?l.pattern.slice(1,l.pattern.length-1):a.TUnion(l)?`(${l.anyOf.map(T=>u(T,c)).join("|")})`:a.TNumber(l)?`${c}${o.PatternNumber}`:a.TInteger(l)?`${c}${o.PatternNumber}`:a.TBigInt(l)?`${c}${o.PatternNumber}`:a.TString(l)?`${c}${o.PatternString}`:a.TLiteral(l)?`${c}${i(l.const.toString())}`:a.TBoolean(l)?`${c}${o.PatternBoolean}`:e(`Unexpected Kind '${l[o.Kind]}'`)}function p(l){return`^${l.map(c=>u(c,"")).join("")}$`}s.Create=p})(Se||(o.TemplateLiteralPattern=Se={}));var k;(function(s){function e(i){let u=X.ParseExact(i.pattern);if(!Z.Check(u))return o.Type.String();let p=[...G.Generate(u)].map(l=>o.Type.Literal(l));return o.Type.Union(p)}s.Resolve=e})(k||(o.TemplateLiteralResolver=k={}));var ue=class extends D{};o.TemplateLiteralParserError=ue;var X;(function(s){function e(d,O,v){return d[O]===v&&d.charCodeAt(O-1)!==92}function i(d,O){return e(d,O,"(")}function u(d,O){return e(d,O,")")}function p(d,O){return e(d,O,"|")}function l(d){if(!(i(d,0)&&u(d,d.length-1)))return!1;let O=0;for(let v=0;v0&&N.push(m(A)),v=R+1}let j=d.slice(v);return j.length>0&&N.push(m(j)),N.length===0?{type:"const",const:""}:N.length===1?N[0]:{type:"or",expr:N}}function g(d){function O(j,R){if(!i(j,R))throw new ue("TemplateLiteralParser: Index must point to open parens");let A=0;for(let K=R;K0&&N.push(m(K)),j=A-1}return N.length===0?{type:"const",const:""}:N.length===1?N[0]:{type:"and",expr:N}}function m(d){return l(d)?m(c(d)):T(d)?b(d):y(d)?g(d):{type:"const",const:d}}s.Parse=m;function U(d){return m(d.slice(1,d.length-1))}s.ParseExact=U})(X||(o.TemplateLiteralParser=X={}));var Re=class extends D{};o.TemplateLiteralFiniteError=Re;var Z;(function(s){function e(c){throw new Re(c)}function i(c){return c.type==="or"&&c.expr.length===2&&c.expr[0].type==="const"&&c.expr[0].const==="0"&&c.expr[1].type==="const"&&c.expr[1].const==="[1-9][0-9]*"}function u(c){return c.type==="or"&&c.expr.length===2&&c.expr[0].type==="const"&&c.expr[0].const==="true"&&c.expr[1].type==="const"&&c.expr[1].const==="false"}function p(c){return c.type==="const"&&c.const===".*"}function l(c){return u(c)?!0:i(c)||p(c)?!1:c.type==="and"?c.expr.every(T=>l(T)):c.type==="or"?c.expr.every(T=>l(T)):c.type==="const"?!0:e("Unknown expression type")}s.Check=l})(Z||(o.TemplateLiteralFinite=Z={}));var xe=class extends D{};o.TemplateLiteralGeneratorError=xe;var G;(function(s){function*e(c){if(c.length===1)return yield*c[0];for(let T of c[0])for(let y of e(c.slice(1)))yield`${T}${y}`}function*i(c){return yield*e(c.expr.map(T=>[...l(T)]))}function*u(c){for(let T of c.expr)yield*l(T)}function*p(c){return yield c.const}function*l(c){return c.type==="and"?yield*i(c):c.type==="or"?yield*u(c):c.type==="const"?yield*p(c):(()=>{throw new xe("Unknown expression")})()}s.Generate=l})(G||(o.TemplateLiteralGenerator=G={}));var He;(function(s){function*e(l){let c=l.trim().replace(/"|'/g,"");return c==="boolean"?yield o.Type.Boolean():c==="number"?yield o.Type.Number():c==="bigint"?yield o.Type.BigInt():c==="string"?yield o.Type.String():yield(()=>{let T=c.split("|").map(y=>o.Type.Literal(y.trim()));return T.length===0?o.Type.Never():T.length===1?T[0]:o.Type.Union(T)})()}function*i(l){if(l[1]!=="{"){let c=o.Type.Literal("$"),T=u(l.slice(1));return yield*[c,...T]}for(let c=2;c{let l={Encode:c=>i[o.Transform].Encode(e(c)),Decode:c=>this.decode(i[o.Transform].Decode(c))};return{...i,[o.Transform]:l}})():(()=>{let u={Decode:this.decode,Encode:e};return{...i,[o.Transform]:u}})()}};o.TransformEncodeBuilder=we;var wn=0,Le=class extends D{};o.TypeBuilderError=Le;var Ae=class{Create(e){return e}Throw(e){throw new Le(e)}Discard(e,i){return i.reduce((u,p)=>{let{[p]:l,...c}=u;return c},e)}Strict(e){return JSON.parse(JSON.stringify(e))}};o.TypeBuilder=Ae;var le=class extends Ae{ReadonlyOptional(e){return this.Readonly(this.Optional(e))}Readonly(e){return{...P.Type(e),[o.Readonly]:"Readonly"}}Optional(e){return{...P.Type(e),[o.Optional]:"Optional"}}Any(e={}){return this.Create({...e,[o.Kind]:"Any"})}Array(e,i={}){return this.Create({...i,[o.Kind]:"Array",type:"array",items:P.Type(e)})}Boolean(e={}){return this.Create({...e,[o.Kind]:"Boolean",type:"boolean"})}Capitalize(e,i={}){return{...Y.Map(P.Type(e),"Capitalize"),...i}}Composite(e,i){let u=o.Type.Intersect(e,{}),l=Pe.ResolveKeys(u,{includePatterns:!1}).reduce((c,T)=>({...c,[T]:o.Type.Index(u,[T])}),{});return o.Type.Object(l,i)}Enum(e,i={}){if(I.IsUndefined(e))return this.Throw("Enum undefined or empty");let u=Object.getOwnPropertyNames(e).filter(c=>isNaN(c)).map(c=>e[c]),l=[...new Set(u)].map(c=>o.Type.Literal(c));return this.Union(l,{...i,[o.Hint]:"Enum"})}Extends(e,i,u,p,l={}){switch(J.Extends(e,i)){case f.Union:return this.Union([P.Type(u,l),P.Type(p,l)]);case f.True:return P.Type(u,l);case f.False:return P.Type(p,l)}}Exclude(e,i,u={}){return a.TTemplateLiteral(e)?this.Exclude(k.Resolve(e),i,u):a.TTemplateLiteral(i)?this.Exclude(e,k.Resolve(i),u):a.TUnion(e)?(()=>{let p=e.anyOf.filter(l=>J.Extends(l,i)===f.False);return p.length===1?P.Type(p[0],u):this.Union(p,u)})():J.Extends(e,i)!==f.False?this.Never(u):P.Type(e,u)}Extract(e,i,u={}){return a.TTemplateLiteral(e)?this.Extract(k.Resolve(e),i,u):a.TTemplateLiteral(i)?this.Extract(e,k.Resolve(i),u):a.TUnion(e)?(()=>{let p=e.anyOf.filter(l=>J.Extends(l,i)!==f.False);return p.length===1?P.Type(p[0],u):this.Union(p,u)})():J.Extends(e,i)!==f.False?P.Type(e,u):this.Never(u)}Index(e,i,u={}){return a.TArray(e)&&a.TNumber(i)?P.Type(e.items,u):a.TTuple(e)&&a.TNumber(i)?(()=>{let l=(I.IsUndefined(e.items)?[]:e.items).map(c=>P.Type(c));return this.Union(l,u)})():(()=>{let p=ae.Resolve(i),l=P.Type(e);return qe.Resolve(l,p,u)})()}Integer(e={}){return this.Create({...e,[o.Kind]:"Integer",type:"integer"})}Intersect(e,i={}){if(e.length===0)return o.Type.Never();if(e.length===1)return P.Type(e[0],i);e.some(c=>a.TTransform(c))&&this.Throw("Cannot intersect transform types");let u=e.every(c=>a.TObject(c)),p=P.Rest(e),l=a.TSchema(i.unevaluatedProperties)?{unevaluatedProperties:P.Type(i.unevaluatedProperties)}:{};return i.unevaluatedProperties===!1||a.TSchema(i.unevaluatedProperties)||u?this.Create({...i,...l,[o.Kind]:"Intersect",type:"object",allOf:p}):this.Create({...i,...l,[o.Kind]:"Intersect",allOf:p})}KeyOf(e,i={}){return a.TRecord(e)?(()=>{let u=Object.getOwnPropertyNames(e.patternProperties)[0];return u===o.PatternNumberExact?this.Number(i):u===o.PatternStringExact?this.String(i):this.Throw("Unable to resolve key type from Record key pattern")})():a.TTuple(e)?(()=>{let p=(I.IsUndefined(e.items)?[]:e.items).map((l,c)=>o.Type.Literal(c.toString()));return this.Union(p,i)})():a.TArray(e)?this.Number(i):(()=>{let u=Pe.ResolveKeys(e,{includePatterns:!1});if(u.length===0)return this.Never(i);let p=u.map(l=>this.Literal(l));return this.Union(p,i)})()}Literal(e,i={}){return this.Create({...i,[o.Kind]:"Literal",const:e,type:typeof e})}Lowercase(e,i={}){return{...Y.Map(P.Type(e),"Lowercase"),...i}}Never(e={}){return this.Create({...e,[o.Kind]:"Never",not:{}})}Not(e,i){return this.Create({...i,[o.Kind]:"Not",not:P.Type(e)})}Null(e={}){return this.Create({...e,[o.Kind]:"Null",type:"null"})}Number(e={}){return this.Create({...e,[o.Kind]:"Number",type:"number"})}Object(e,i={}){let u=Object.getOwnPropertyNames(e),p=u.filter(y=>a.TOptional(e[y])),l=u.filter(y=>!p.includes(y)),c=a.TSchema(i.additionalProperties)?{additionalProperties:P.Type(i.additionalProperties)}:{},T=u.reduce((y,b)=>({...y,[b]:P.Type(e[b])}),{});return l.length>0?this.Create({...i,...c,[o.Kind]:"Object",type:"object",properties:T,required:l}):this.Create({...i,...c,[o.Kind]:"Object",type:"object",properties:T})}Omit(e,i,u={}){let p=ae.Resolve(i);return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),l=>{I.IsArray(l.required)&&(l.required=l.required.filter(c=>!p.includes(c)),l.required.length===0&&delete l.required);for(let c of Object.getOwnPropertyNames(l.properties))p.includes(c)&&delete l.properties[c];return this.Create(l)},u)}Partial(e,i={}){return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),u=>{let p=Object.getOwnPropertyNames(u.properties).reduce((l,c)=>({...l,[c]:this.Optional(u.properties[c])}),{});return this.Object(p,this.Discard(u,["required"]))},i)}Pick(e,i,u={}){let p=ae.Resolve(i);return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),l=>{I.IsArray(l.required)&&(l.required=l.required.filter(c=>p.includes(c)),l.required.length===0&&delete l.required);for(let c of Object.getOwnPropertyNames(l.properties))p.includes(c)||delete l.properties[c];return this.Create(l)},u)}Record(e,i,u={}){return a.TTemplateLiteral(e)?(()=>{let p=X.ParseExact(e.pattern);return Z.Check(p)?this.Object([...G.Generate(p)].reduce((l,c)=>({...l,[c]:P.Type(i)}),{}),u):this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[e.pattern]:P.Type(i)}})})():a.TUnion(e)?(()=>{let p=Je.Resolve(e);if(a.TUnionLiteral(p)){let l=p.anyOf.reduce((c,T)=>({...c,[T.const]:P.Type(i)}),{});return this.Object(l,{...u,[o.Hint]:"Record"})}else this.Throw("Record key of type union contains non-literal types")})():a.TLiteral(e)?I.IsString(e.const)||I.IsNumber(e.const)?this.Object({[e.const]:P.Type(i)},u):this.Throw("Record key of type literal is not of type string or number"):a.TInteger(e)||a.TNumber(e)?this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[o.PatternNumberExact]:P.Type(i)}}):a.TString(e)?(()=>{let p=I.IsUndefined(e.pattern)?o.PatternStringExact:e.pattern;return this.Create({...u,[o.Kind]:"Record",type:"object",patternProperties:{[p]:P.Type(i)}})})():this.Never()}Recursive(e,i={}){I.IsUndefined(i.$id)&&(i.$id=`T${wn++}`);let u=e({[o.Kind]:"This",$ref:`${i.$id}`});return u.$id=i.$id,this.Create({...i,[o.Hint]:"Recursive",...u})}Ref(e,i={}){return I.IsString(e)?this.Create({...i,[o.Kind]:"Ref",$ref:e}):(I.IsUndefined(e.$id)&&this.Throw("Reference target type must specify an $id"),this.Create({...i,[o.Kind]:"Ref",$ref:e.$id}))}Required(e,i={}){return Q.Map(this.Discard(P.Type(e),["$id",o.Transform]),u=>{let p=Object.getOwnPropertyNames(u.properties).reduce((l,c)=>({...l,[c]:this.Discard(u.properties[c],[o.Optional])}),{});return this.Object(p,u)},i)}Rest(e){return a.TTuple(e)&&!I.IsUndefined(e.items)?P.Rest(e.items):a.TIntersect(e)?P.Rest(e.allOf):a.TUnion(e)?P.Rest(e.anyOf):[]}String(e={}){return this.Create({...e,[o.Kind]:"String",type:"string"})}TemplateLiteral(e,i={}){let u=I.IsString(e)?Se.Create(He.Parse(e)):Se.Create(e);return this.Create({...i,[o.Kind]:"TemplateLiteral",type:"string",pattern:u})}Transform(e){return new je(e)}Tuple(e,i={}){let[u,p,l]=[!1,e.length,e.length],c=P.Rest(e),T=e.length>0?{...i,[o.Kind]:"Tuple",type:"array",items:c,additionalItems:u,minItems:p,maxItems:l}:{...i,[o.Kind]:"Tuple",type:"array",minItems:p,maxItems:l};return this.Create(T)}Uncapitalize(e,i={}){return{...Y.Map(P.Type(e),"Uncapitalize"),...i}}Union(e,i={}){return a.TTemplateLiteral(e)?k.Resolve(e):(()=>{let u=e;if(u.length===0)return this.Never(i);if(u.length===1)return this.Create(P.Type(u[0],i));let p=P.Rest(u);return this.Create({...i,[o.Kind]:"Union",anyOf:p})})()}Unknown(e={}){return this.Create({...e,[o.Kind]:"Unknown"})}Unsafe(e={}){return this.Create({...e,[o.Kind]:e[o.Kind]||"Unsafe"})}Uppercase(e,i={}){return{...Y.Map(P.Type(e),"Uppercase"),...i}}};o.JsonTypeBuilder=le;var Fe=class extends le{AsyncIterator(e,i={}){return this.Create({...i,[o.Kind]:"AsyncIterator",type:"AsyncIterator",items:P.Type(e)})}Awaited(e,i={}){let u=p=>p.length>0?(()=>{let[l,...c]=p;return[this.Awaited(l),...u(c)]})():p;return a.TIntersect(e)?o.Type.Intersect(u(e.allOf)):a.TUnion(e)?o.Type.Union(u(e.anyOf)):a.TPromise(e)?this.Awaited(e.item):P.Type(e,i)}BigInt(e={}){return this.Create({...e,[o.Kind]:"BigInt",type:"bigint"})}ConstructorParameters(e,i={}){return this.Tuple([...e.parameters],{...i})}Constructor(e,i,u){let[p,l]=[P.Rest(e),P.Type(i)];return this.Create({...u,[o.Kind]:"Constructor",type:"Constructor",parameters:p,returns:l})}Date(e={}){return this.Create({...e,[o.Kind]:"Date",type:"Date"})}Function(e,i,u){let[p,l]=[P.Rest(e),P.Type(i)];return this.Create({...u,[o.Kind]:"Function",type:"Function",parameters:p,returns:l})}InstanceType(e,i={}){return P.Type(e.returns,i)}Iterator(e,i={}){return this.Create({...i,[o.Kind]:"Iterator",type:"Iterator",items:P.Type(e)})}Parameters(e,i={}){return this.Tuple(e.parameters,{...i})}Promise(e,i={}){return this.Create({...i,[o.Kind]:"Promise",type:"Promise",item:P.Type(e)})}RegExp(e,i={}){let u=I.IsString(e)?e:e.source;return this.Create({...i,[o.Kind]:"String",type:"string",pattern:u})}RegEx(e,i={}){return this.RegExp(e,i)}ReturnType(e,i={}){return P.Type(e.returns,i)}Symbol(e){return this.Create({...e,[o.Kind]:"Symbol",type:"symbol"})}Undefined(e={}){return this.Create({...e,[o.Kind]:"Undefined",type:"undefined"})}Uint8Array(e={}){return this.Create({...e,[o.Kind]:"Uint8Array",type:"Uint8Array"})}Void(e={}){return this.Create({...e,[o.Kind]:"Void",type:"void"})}};o.JavaScriptTypeBuilder=Fe;o.JsonType=new le;o.Type=new Fe});var ce=jn(he(),1),en=ce.Type.String({pattern:".*\\{languageTag|locale\\}.*\\.json$",examples:["./messages/{locale}.json","./i18n/{locale}.json"],title:"Path to language files",description:"Specify the pathPattern to locate resource files in your repository. It must include `{locale}` and end with `.json`."}),Ln=ce.Type.Array(en,{title:"Paths to language files",description:"Specify multiple pathPatterns to locate resource files in your repository. Each must include `{locale}` and end with `.json`."}),Ce=ce.Type.Object({pathPattern:ce.Type.Union([en,Ln])});var nn=s=>s.map(e=>{switch(e.type){case"Text":return e.value;case"VariableReference":return`{${e.name}}`}}).join("");var tn=s=>{let e={};for(let i of s.variants){if(e[i.languageTag]!==void 0)throw new Error(`The message "${s.id}" has multiple variants for the language tag "${i.languageTag}". The inlang-message-format plugin does not support multiple variants for the same language tag at the moment.`);e[i.languageTag]=nn(i.pattern)}return e};var rn=s=>{let e=/\{([^}]+)\}/g,i,u=0,p=[];for(;(i=e.exec(s))!==null;){let c=i[1],T=s.slice(u,i.index);T.length>0&&p.push({type:"Text",value:T}),p.push({type:"VariableReference",name:c}),u=i.index+i[0].length}let l=s.slice(Math.max(0,u));return l.length>0&&p.push({type:"Text",value:l}),p};var _e=s=>({id:s.key,alias:{},selectors:[],variants:[{languageTag:s.languageTag,match:[],pattern:rn(s.value)}]});var An="plugin.inlang.messageFormat",H={id:An,displayName:"Inlang Message Format",description:"A plugin for the inlang SDK that uses a JSON file per language tag to store translations.",key:"inlang-message-format",settingsSchema:Ce,loadMessages:async({settings:s,nodeishFs:e})=>{await $n({settings:s,nodeishFs:e});let i={};for(let u of s.languageTags)try{let p=await e.readFile(s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",u),{encoding:"utf-8"}),l=JSON.parse(p);for(let c in l)c!=="$schema"&&(i[c]?i[c].variants=[...i[c].variants,..._e({key:c,value:l[c],languageTag:u}).variants]:i[c]=_e({key:c,value:l[c],languageTag:u}))}catch(p){if(p?.code!=="ENOENT")throw p}return Object.values(i)},saveMessages:async({settings:s,nodeishFs:e,messages:i})=>{let u={};for(let p of i){let l=tn(p);for(let[c,T]of Object.entries(l))u[c]===void 0&&(u[c]={}),u[c][p.id]=T}for(let[p,l]of Object.entries(u)){let c=s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",p);await Fn({path:c,nodeishFs:e}),await e.writeFile(s["plugin.inlang.messageFormat"].pathPattern.replace("{languageTag}",p),(T=>JSON.stringify(T,void 0," "))({$schema:"https://inlang.com/schema/inlang-message-format",...l}))}}},Fn=async s=>{try{await s.nodeishFs.mkdir(Cn(s.path),{recursive:!0})}catch{}};function Cn(s){if(s.length===0)return".";let e=s.charCodeAt(0),i=e===47,u=-1,p=!0;for(let l=s.length-1;l>=1;--l)if(e=s.charCodeAt(l),e===47){if(!p){u=l;break}}else p=!1;return u===-1?i?"/":".":i&&u===1?"//":s.slice(0,u)}var $n=async s=>{if(s.settings["plugin.inlang.messageFormat"].filePath!=null)try{let e=await s.nodeishFs.readFile(s.settings["plugin.inlang.messageFormat"].filePath,{encoding:"utf-8"});await H.saveMessages?.({messages:JSON.parse(e).data,nodeishFs:s.nodeishFs,settings:s.settings}),console.log("Migration to v2 of the inlang-message-format plugin was successful. Please delete the old messages.json file and the filePath property in the settings file of the project.")}catch{}};var on=async({settings:s})=>{let e=[],i=s[h]?.pathPattern?Array.isArray(s[h].pathPattern)?s[h].pathPattern:[s[h].pathPattern]:[];for(let u of i)for(let p of s.locales)e.push({locale:p,path:u.replace(/{(locale|languageTag)}/,p)});return e};function sn(s){return s&&s.constructor&&typeof s.constructor.isBuffer=="function"&&s.constructor.isBuffer(s)}function an(s){return s}function We(s,e){e=e||{};let i=e.delimiter||".",u=e.maxDepth,p=e.transformKey||an,l={};function c(T,y,b){b=b||1,Object.keys(T).forEach(function(g){let m=T[g],U=e.safe&&Array.isArray(m),d=Object.prototype.toString.call(m),O=sn(m),v=d==="[object Object]"||d==="[object Array]",N=y?y+i+p(g):p(g);if(!U&&!O&&v&&Object.keys(m).length&&(!e.maxDepth||b0&&(U=T(m.shift()),d=T(m[0]))}O[U]=Ye(s[g],e)}),l}var ln=async({files:s})=>{let e=[],i=[],u=[];for(let p of s){let l=JSON.parse(new TextDecoder().decode(p.content)),c=We(l,{safe:!0});for(let T in c){if(T==="$schema")continue;let y=Kn(T,p.locale,c[T]);i.push(y.message),u.push(...y.variants);let b=e.find(g=>g.id===y.bundle.id);b===void 0?e.push(y.bundle):b.declarations=$e([...b.declarations,...y.bundle.declarations])}}return{bundles:e,messages:i,variants:u}};function Kn(s,e,i){let u=En(s,e,i),p=$e(u.declarations),l=$e(u.selectors),c=l.filter(T=>p.find(y=>y.name===T.name)===void 0);for(let T of c)p.push({type:"input-variable",name:T.name});return{bundle:{id:s,declarations:p},message:{bundleId:s,selectors:l,locale:e},variants:u.variants}}function En(s,e,i){if(typeof i=="string"){let y=un(i);return{variants:[{messageBundleId:s,messageLocale:e,matches:[],pattern:y.pattern}],declarations:y.declarations,selectors:[]}}let u=i[0],p=[],l=(u.selectors??[]).map(y=>({type:"variable-reference",name:y})),c=new Set;for(let y of u.declarations??[])c.add(Mn(y));let T=new Set;for(let[y,b]of Object.entries(u.match)){let g=un(b),m=Bn(y);for(let U of g.declarations){let d=!1;for(let O of c)if(O.name===U.name){d=!0;break}if(d)break;c.add(U)}for(let U of m.selectors)T.add(U);p.push({messageBundleId:s,messageLocale:e,matches:m.matches,pattern:g.pattern})}return{variants:p,declarations:Array.from(c),selectors:$e([...l,...Array.from(T)])}}function un(s){let e=[],i=[],u=s.split(/(\{.*?\})/).filter(p=>p!=="");for(let p of u)if((p.startsWith("{")&&p.endsWith("}"))===!1)e.push({type:"text",value:p});else{let l=p.slice(1,-1);i.push({type:"input-variable",name:l}),e.push({type:"expression",arg:{type:"variable-reference",name:l}})}return{declarations:i,pattern:e}}function Bn(s){let e=s.replace(" ",""),i=[],u=[],p=e.split(",");for(let l of p){let[c,T]=l.split("=");!c||!T||(T==="*"?i.push({type:"catchall-match",key:c}):i.push({type:"literal-match",key:c,value:T}),u.push({type:"variable-reference",name:c}))}return{matches:i,selectors:u}}var $e=s=>[...new Set(s.map(e=>JSON.stringify(e)))].map(e=>JSON.parse(e));function Mn(s){if(s.startsWith("input"))return{type:"input-variable",name:s.slice(6).trim()};if(s.startsWith("local")){let e=s.match(/local (\w+) = (\w+): (\w+)(.*)/),[,i,u,p,l]=e,c=l?.trim().split(/\s+/).map(T=>{let[y,b]=T.split("=");return y&&b?{name:y,value:{type:"literal",value:b}}:null}).filter(Boolean);return{type:"local-variable",name:i.trim(),value:{type:"expression",arg:{type:"variable-reference",name:u.trim()},annotation:p?{type:"function-reference",name:p.trim(),options:c??[]}:void 0}}}throw new Error("Unsupported declaration type")}var pn=async({bundles:s,messages:e,variants:i})=>{let u={};for(let l of e){let c=s.find(y=>y.id===l.bundleId),T=[...i.reduce((y,b)=>(b.messageId===l.id&&y.set(JSON.stringify(b.matches),b),y),new Map).values()];u[l.locale]={...u[l.locale],...Dn(c,l,T)}}let p=[];for(let l in u)p.push({locale:l,content:new TextEncoder().encode(JSON.stringify(Ye({$schema:"https://inlang.com/schema/inlang-message-format",...u[l]}),void 0," ")),name:l+".json"});return p};function Dn(s,e,i){let u=e.bundleId,p=kn(s,e,i);return{[u]:p}}function kn(s,e,i){if(i.length===1&&e.selectors.length===0&&s.declarations.some(p=>p.type!=="input-variable")===!1)return cn(i[0].pattern);let u=[];for(let p of i){if(p.matches.length===0)for(let T of p.pattern)T.type==="expression"&&T.arg.type==="variable-reference"&&p.matches.push({key:T.arg.name,type:"catchall-match"});let l=cn(p.pattern),c=Vn(p.matches);u.push([c,l])}return[{declarations:s.declarations.sort((p,l)=>p.name.localeCompare(l.name)).map(zn).sort(),selectors:e.selectors.map(p=>p.name).sort(),match:Object.fromEntries(u)}]}function cn(s){let e="";for(let i of s)if(i.type==="text")e+=i.value;else if(i.arg.type==="variable-reference")e+=`{${i.arg.name}}`;else throw new Error("Unsupported expression type");return e}function Vn(s){return s.sort((i,u)=>i.key.localeCompare(u.key)).map(i=>i.type==="literal-match"?`${i.key}=${i.value}`:`${i.key}=*`).join(", ")}function zn(s){if(s.type==="input-variable")return`input ${s.name}`;if(s.type==="local-variable"){let e="";if(s.value.arg.type==="variable-reference"?e=`local ${s.name} = ${s.value.arg.name}`:s.value.arg.type==="literal"&&(e=`local ${s.name} = "${s.value.arg.value}"`),s.value.annotation&&(e+=`: ${s.value.annotation.name}`),s.value.annotation?.options)for(let i of s.value?.annotation?.options??[]){if(i.value.type!=="literal")throw new Error("Unsupported option type");e+=` ${i.name}=${i.value.value}`}return e}throw new Error("Unsupported declaration type")}var h="plugin.inlang.messageFormat",Tn={key:h,id:H.id,displayName:H.displayName,description:H.description,loadMessages:H.loadMessages,saveMessages:H.saveMessages,settingsSchema:Ce,toBeImportedFiles:on,importFiles:ln,exportFiles:pn};var It=Tn;export{It as default}; diff --git a/apps/docs/project.inlang/cache/plugins/ygx0uiahq6uw b/apps/docs/project.inlang/cache/plugins/ygx0uiahq6uw new file mode 100644 index 0000000..8ce3dc5 --- /dev/null +++ b/apps/docs/project.inlang/cache/plugins/ygx0uiahq6uw @@ -0,0 +1,16 @@ +var Vt=Object.create;var It=Object.defineProperty;var Ht=Object.getOwnPropertyDescriptor;var Xt=Object.getOwnPropertyNames;var Yt=Object.getPrototypeOf,tn=Object.prototype.hasOwnProperty;var nn=(l,c)=>()=>(c||l((c={exports:{}}).exports,c),c.exports);var rn=(l,c,p,u)=>{if(c&&typeof c=="object"||typeof c=="function")for(let f of Xt(c))!tn.call(l,f)&&f!==p&&It(l,f,{get:()=>c[f],enumerable:!(u=Ht(c,f))||u.enumerable});return l};var en=(l,c,p)=>(p=l!=null?Vt(Yt(l)):{},rn(c||!l||!l.__esModule?It(p,"default",{value:l,enumerable:!0}):p,l));var Lt=nn((J,gt)=>{(function(l,c){typeof J=="object"&&typeof gt=="object"?gt.exports=c():typeof define=="function"&&define.amd?define([],c):typeof J=="object"?J.Parsimmon=c():l.Parsimmon=c()})(typeof self<"u"?self:J,function(){return function(l){var c={};function p(u){if(c[u])return c[u].exports;var f=c[u]={i:u,l:!1,exports:{}};return l[u].call(f.exports,f,f.exports,p),f.l=!0,f.exports}return p.m=l,p.c=c,p.d=function(u,f,Z){p.o(u,f)||Object.defineProperty(u,f,{configurable:!1,enumerable:!0,get:Z})},p.r=function(u){Object.defineProperty(u,"__esModule",{value:!0})},p.n=function(u){var f=u&&u.__esModule?function(){return u.default}:function(){return u};return p.d(f,"a",f),f},p.o=function(u,f){return Object.prototype.hasOwnProperty.call(u,f)},p.p="",p(p.s=0)}([function(l,c,p){"use strict";function u(t){if(!(this instanceof u))return new u(t);this._=t}var f=u.prototype;function Z(t,n){for(var r=0;r>7),buf:function(o){var i=I(function(a,s,d,y){return a.concat(d===y.length-1?Buffer.from([s,0]).readUInt16BE(0):y.readUInt16BE(d))},[],o);return Buffer.from(j(function(a){return(a<<1&65535)>>8},i))}(r.buf)}}),r}function dt(){return typeof Buffer<"u"}function C(){if(!dt())throw new Error("Buffer global does not exist; please use webpack if you need to parse Buffers in the browser.")}function ht(t){C();var n=I(function(i,a){return i+a},0,t);if(n%8!=0)throw new Error("The bits ["+t.join(", ")+"] add up to "+n+" which is not an even number of bytes; the total should be divisible by 8");var r,e=n/8,o=(r=function(i){return i>48},I(function(i,a){return i||(r(a)?a:i)},null,t));if(o)throw new Error(o+" bit range requested exceeds 48 bit (6 byte) Number max.");return new u(function(i,a){var s=e+a;return s>i.length?b(a,e.toString()+" bytes"):h(s,I(function(d,y){var v=At(y,d.buf);return{coll:d.coll.concat(v.v),buf:v.buf}},{coll:[],buf:i.slice(a,s)},t).coll)})}function E(t,n){return new u(function(r,e){return C(),e+n>r.length?b(e,n+" bytes for "+t):h(e+n,r.slice(e,e+n))})}function K(t,n){if(typeof(r=n)!="number"||Math.floor(r)!==r||n<0||n>6)throw new Error(t+" requires integer length in range [0, 6].");var r}function V(t){return K("uintBE",t),E("uintBE("+t+")",t).map(function(n){return n.readUIntBE(0,t)})}function H(t){return K("uintLE",t),E("uintLE("+t+")",t).map(function(n){return n.readUIntLE(0,t)})}function X(t){return K("intBE",t),E("intBE("+t+")",t).map(function(n){return n.readIntBE(0,t)})}function Y(t){return K("intLE",t),E("intLE("+t+")",t).map(function(n){return n.readIntLE(0,t)})}function U(t){return t instanceof u}function q(t){return{}.toString.call(t)==="[object Array]"}function W(t){return dt()&&Buffer.isBuffer(t)}function h(t,n){return{status:!0,index:t,value:n,furthest:-1,expected:[]}}function b(t,n){return q(n)||(n=[n]),{status:!1,index:-1,value:null,furthest:t,expected:n}}function w(t,n){if(!n||t.furthest>n.furthest)return t;var r=t.furthest===n.furthest?function(e,o){if(function(){if(u._supportsSet!==void 0)return u._supportsSet;var S=typeof Set<"u";return u._supportsSet=S,S}()&&Array.from){for(var i=new Set(e),a=0;a=0;){if(a in r){e=r[a].line,i===0&&(i=r[a].lineStart);break}(t.charAt(a)===` +`||t.charAt(a)==="\r"&&t.charAt(a+1)!==` +`)&&(o++,i===0&&(i=a+1)),a--}var s=e+o,d=n-i;return r[n]={line:s,lineStart:i},{offset:n,line:s+1,column:d+1}}function A(t){if(!U(t))throw new Error("not a parser: "+t)}function nt(t,n){return typeof t=="string"?t.charAt(n):t[n]}function F(t){if(typeof t!="number")throw new Error("not a number: "+t)}function L(t){if(typeof t!="function")throw new Error("not a function: "+t)}function T(t){if(typeof t!="string")throw new Error("not a string: "+t)}var Ft=2,Nt=3,O=8,Rt=5*O,zt=4*O,vt=" ";function rt(t,n){return new Array(n+1).join(t)}function et(t,n,r){var e=n-t.length;return e<=0?t:rt(r,e)+t}function yt(t,n,r,e){return{from:t-n>0?t-n:0,to:t+r>e?e:t+r}}function Dt(t,n){var r,e,o,i,a,s=n.index,d=s.offset,y=1;if(d===t.length)return"Got the end of the input";if(W(t)){var v=d-d%O,_=d-v,x=yt(v,Rt,zt+O,t.length),S=j(function(m){return j(function(R){return et(R.toString(16),2,"0")},m)},function(m,R){var z=m.length,M=[],D=0;if(z<=R)return[m.slice()];for(var Q=0;Q=4&&(r+=1),y=2,o=j(function(m){return m.length<=4?m.join(" "):m.slice(0,4).join(" ")+" "+m.slice(4).join(" ")},S),(a=(8*(i.to>0?i.to-1:i.to)).toString(16).length)<2&&(a=2)}else{var N=t.split(/\r\n|[\n\r\u2028\u2029]/);r=s.column-1,e=s.line-1,i=yt(e,Ft,Nt,N.length),o=N.slice(i.from,i.to),a=i.to.toString().length}var Kt=e-i.from;return W(t)&&(a=(8*(i.to>0?i.to-1:i.to)).toString(16).length)<2&&(a=2),I(function(m,R,z){var M,D=z===Kt,Q=D?"> ":vt;return M=W(t)?et((8*(i.from+z)).toString(16),a,"0"):et((i.from+z+1).toString(),a," "),[].concat(m,[Q+M+" | "+R],D?[vt+rt(" ",a)+" | "+et("",r," ")+rt("^",y)]:[])},[],o).join(` +`)}function bt(t,n){return[` +`,"-- PARSING FAILED "+rt("-",50),` + +`,Dt(t,n),` + +`,(r=n.expected,r.length===1?`Expected: + +`+r[0]:`Expected one of the following: + +`+r.join(", ")),` +`].join("");var r}function xt(t){return t.flags!==void 0?t.flags:[t.global?"g":"",t.ignoreCase?"i":"",t.multiline?"m":"",t.unicode?"u":"",t.sticky?"y":""].join("")}function ut(){for(var t=[].slice.call(arguments),n=t.length,r=0;r=2?F(n):n=0;var r=function(o){return RegExp("^(?:"+o.source+")",xt(o))}(t),e=""+t;return u(function(o,i){var a=r.exec(o.slice(i));if(a){if(0<=n&&n<=a.length){var s=a[0],d=a[n];return h(i+s.length,d)}return b(i,"valid match group (0 to "+a.length+") in "+e)}return b(i,e)})}function P(t){return u(function(n,r){return h(r,t)})}function it(t){return u(function(n,r){return b(r,t)})}function at(t){if(U(t))return u(function(n,r){var e=t._(n,r);return e.index=r,e.value="",e});if(typeof t=="string")return at($(t));if(t instanceof RegExp)return at(B(t));throw new Error("not a string, regexp, or parser: "+t)}function Et(t){return A(t),u(function(n,r){var e=t._(n,r),o=n.slice(r,e.index);return e.status?b(r,'not "'+o+'"'):h(r,null)})}function ft(t){return L(t),u(function(n,r){var e=nt(n,r);return r=t.length?b(n,"any character/byte"):h(n+1,nt(t,n))}),Ut=u(function(t,n){return h(t.length,t.slice(n))}),pt=u(function(t,n){return n=0}).desc(n)},u.optWhitespace=Jt,u.Parser=u,u.range=function(t,n){return ft(function(r){return t<=r&&r<=n}).desc(t+"-"+n)},u.regex=B,u.regexp=B,u.sepBy=wt,u.sepBy1=st,u.seq=ut,u.seqMap=k,u.seqObj=function(){for(var t,n={},r=0,e=(t=arguments,Array.prototype.slice.call(t)),o=e.length,i=0;i255)throw new Error("Value specified to byte constructor ("+t+"=0x"+t.toString(16)+") is larger in value than a single byte.");var n=(t>15?"0x":"0x0")+t.toString(16);return u(function(r,e){var o=nt(r,e);return o===t?h(e+1,o):b(e,n)})},buffer:function(t){return E("buffer",t).map(function(n){return Buffer.from(n)})},encodedString:function(t,n){return E("string",n).map(function(r){return r.toString(t)})},uintBE:V,uint8BE:V(1),uint16BE:V(2),uint32BE:V(4),uintLE:H,uint8LE:H(1),uint16LE:H(2),uint32LE:H(4),intBE:X,int8BE:X(1),int16BE:X(2),int32BE:X(4),intLE:Y,int8LE:Y(1),int16LE:Y(2),int32LE:Y(4),floatBE:E("floatBE",4).map(function(t){return t.readFloatBE(0)}),floatLE:E("floatLE",4).map(function(t){return t.readFloatLE(0)}),doubleBE:E("doubleBE",8).map(function(t){return t.readDoubleBE(0)}),doubleLE:E("doubleLE",8).map(function(t){return t.readDoubleLE(0)})},l.exports=u}])})});var g=en(Lt(),1),un=()=>g.default.createLanguage({entry:l=>g.default.alt(l.findReference,g.default.any).many().map(c=>c.flatMap(p=>p)).map(c=>c.filter(p=>typeof p=="object").flat().filter(p=>p!==null)),findReference:function(l){return g.default.seq(g.default.regex(/(import \* as m)|(import { m })/),l.findMessage.many())},dotNotation:()=>g.default.seqMap(g.default.string("."),g.default.index,g.default.regex(/\w+/),g.default.index,(l,c,p,u)=>({messageId:p,start:c,end:u})),doubleQuote:()=>g.default.seqMap(g.default.string('"'),g.default.index,g.default.regex(/[\w.]+/),g.default.string('"'),(l,c,p)=>({messageId:p,start:c})),singleQuote:()=>g.default.seqMap(g.default.string("'"),g.default.index,g.default.regex(/[\w.]+/),g.default.string("'"),(l,c,p)=>({messageId:p,start:c})),bracketNotation:l=>g.default.seqMap(g.default.string("["),g.default.alt(l.doubleQuote,l.singleQuote),g.default.string("]"),g.default.index,(c,p,u,f)=>({messageId:p.messageId,start:p.start,end:f})),findMessage:l=>g.default.seqMap(g.default.regex(/.*?(?p===null?null:{messageId:`${p.messageId}`,position:{start:{line:p.start.line,character:p.start.column},end:{line:p.end.line,character:p.end.column+u.length}}})});function kt(l){try{return un().entry.tryParse(l)}catch{return[]}}function ct(l){let c=l.trim().replace(/[^a-zA-Z0-9\s_.]/g,"").replace(/[\s.]+/g,"_");return/^[0-9]/.test(c)&&(c="_"+c),c}var Pt={messageReferenceMatchers:[async l=>kt(l.documentText)],extractMessageOptions:[{callback:l=>{let c=ct(l.bundleId);return{bundleId:c,messageReplacement:`{m.${c}()}`}}},{callback:l=>{let c=ct(l.bundleId);return{bundleId:c,messageReplacement:`m.${c}()`}}}],documentSelectors:[{language:"typescriptreact"},{language:"javascript"},{language:"typescript"},{language:"svelte"},{language:"astro"},{language:"vue"}]};var Mt="plugin.inlang.mFunctionMatcher",qt={id:Mt,displayName:"Inlang M Function Matcher",description:"A plugin for the inlang SDK that uses a JSON file per language tag to store translations.",key:Mt,meta:{"app.inlang.ideExtension":Pt}};var yn=qt;export{yn as default}; diff --git a/apps/docs/project.inlang/project_id b/apps/docs/project.inlang/project_id new file mode 100644 index 0000000..d191e07 --- /dev/null +++ b/apps/docs/project.inlang/project_id @@ -0,0 +1 @@ +ppKjPEXEl4r1KIqH6g \ No newline at end of file diff --git a/apps/docs/project.inlang/settings.json b/apps/docs/project.inlang/settings.json new file mode 100644 index 0000000..df2d54f --- /dev/null +++ b/apps/docs/project.inlang/settings.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://inlang.com/schema/project-settings", + "modules": [ + "https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js", + "https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js" + ], + "plugin.inlang.messageFormat": { + "pathPattern": "./messages/{locale}.json" + }, + "baseLocale": "en", + "locales": ["en", "de"] +} diff --git a/apps/docs/src/app.css b/apps/docs/src/app.css new file mode 100644 index 0000000..64481cd --- /dev/null +++ b/apps/docs/src/app.css @@ -0,0 +1,175 @@ +@import "tailwindcss"; + +@import "tw-animate-css"; + +@plugin "@tailwindcss/typography"; + +@custom-variant dark (&:is(.dark *)); + + +:root { + --radius: 0.65rem; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.705 0.213 47.604); + --primary-foreground: oklch(0.98 0.016 73.684); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.705 0.213 47.604); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.705 0.213 47.604); + --sidebar-primary-foreground: oklch(0.98 0.016 73.684); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.705 0.213 47.604); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.646 0.222 41.116); + --primary-foreground: oklch(0.98 0.016 73.684); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.646 0.222 41.116); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.646 0.222 41.116); + --sidebar-primary-foreground: oklch(0.98 0.016 73.684); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.646 0.222 41.116); +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} + +@layer utilities { + /* Docs typography overrides */ + .prose { + --tw-prose-body: var(--foreground); + --tw-prose-headings: var(--foreground); + --tw-prose-bold: var(--foreground); + --tw-prose-links: color-mix(in oklch, var(--primary) 85%, black); + --tw-prose-counters: var(--muted-foreground); + --tw-prose-bullets: var(--muted-foreground); + --tw-prose-hr: var(--border); + --tw-prose-quotes: var(--foreground); + --tw-prose-quote-borders: var(--border); + --tw-prose-captions: var(--muted-foreground); + --tw-prose-code: var(--foreground); + --tw-prose-th-borders: var(--border); + --tw-prose-td-borders: var(--border); + } + + .prose :where(h1,h2,h3,h4){ + @apply scroll-mt-20 font-semibold tracking-tight; + } + .prose :where(h1){ @apply text-3xl md:text-4xl mb-4; } + .prose :where(h2){ @apply text-2xl md:text-3xl mt-10 mb-3; } + .prose :where(h3){ @apply text-xl md:text-2xl mt-8 mb-2; } + .prose :where(h4){ @apply text-lg md:text-xl mt-6 mb-2; } + + .prose :where(p){ @apply leading-7; } + .prose :where(ul,ol){ @apply my-4 pl-6; } + .prose :where(li){ @apply my-1; } + .prose :where(blockquote){ @apply border-l-4 border-border pl-4 italic text-muted-foreground; } + .prose :where(hr){ @apply my-8 border-border; } + + /* Links */ + .prose :where(a){ @apply text-primary underline decoration-from-font underline-offset-4 hover:opacity-90; } + + /* Code blocks */ + .prose :where(code){ @apply rounded bg-muted/60 px-1.5 py-0.5 text-sm; } + .prose :where(pre){ + @apply my-6 overflow-x-auto rounded-lg bg-muted/60 p-4 text-sm leading-6 shadow-sm; + } + .prose :where(pre code){ @apply bg-transparent p-0; } + + /* Tables */ + .prose :where(table){ @apply w-full table-auto border-collapse text-sm my-6; } + .prose :where(th){ @apply bg-muted/50 px-3 py-2 text-left font-medium; } + .prose :where(td){ @apply border-t border-border px-3 py-2 align-top; } + + /* Images */ + .prose :where(img){ @apply my-4 rounded-lg border border-border; } +} \ No newline at end of file diff --git a/apps/docs/src/app.html b/apps/docs/src/app.html index 6769ed5..2b28c87 100644 --- a/apps/docs/src/app.html +++ b/apps/docs/src/app.html @@ -1,12 +1,12 @@ - - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ diff --git a/apps/docs/src/content/docs/1.0.1/Building Your Application/Data Fetching.svx b/apps/docs/src/content/docs/1.0.1/Building Your Application/Data Fetching.svx new file mode 100644 index 0000000..c9836ad --- /dev/null +++ b/apps/docs/src/content/docs/1.0.1/Building Your Application/Data Fetching.svx @@ -0,0 +1,9 @@ +--- +title: Data Fetching lol +category: Building Your Application +slug: Data Fetching +--- + +# Data Fetching + +Content coming soon. diff --git a/apps/docs/src/content/docs/1.0.1/Building Your Application/Routing.svx b/apps/docs/src/content/docs/1.0.1/Building Your Application/Routing.svx new file mode 100644 index 0000000..69ac7f3 --- /dev/null +++ b/apps/docs/src/content/docs/1.0.1/Building Your Application/Routing.svx @@ -0,0 +1,18 @@ +--- +title: Routing +category: Building Your Application +slug: Routing +--- + + + +# Routing + +This page demonstrates a category page rendered through mdsvex. + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/1.0.1/main.svx b/apps/docs/src/content/docs/1.0.1/main.svx new file mode 100644 index 0000000..7810d50 --- /dev/null +++ b/apps/docs/src/content/docs/1.0.1/main.svx @@ -0,0 +1,10 @@ +--- +# Frontmatter is optional; you can put mdsvex content directly. +--- + +# Getting Started (1.0.1) + +This is the main page for version 1.0.1. + +- Use the sidebar to navigate categories. +- Titles and URLs can be overridden via frontmatter (title, slug, category). diff --git a/apps/docs/src/demo.spec.ts b/apps/docs/src/demo.spec.ts new file mode 100644 index 0000000..dadc7e4 --- /dev/null +++ b/apps/docs/src/demo.spec.ts @@ -0,0 +1,7 @@ +import { describe, it, expect } from "vitest"; + +describe("sum test", () => { + it("adds 1 + 2 to equal 3", () => { + expect(1 + 2).toBe(3); + }); +}); diff --git a/apps/docs/src/hooks.server.ts b/apps/docs/src/hooks.server.ts new file mode 100644 index 0000000..ef2bfcd --- /dev/null +++ b/apps/docs/src/hooks.server.ts @@ -0,0 +1,13 @@ +import type { Handle } from "@sveltejs/kit"; +import { paraglideMiddleware } from "$lib/paraglide/server"; + +const handleParaglide: Handle = ({ event, resolve }) => + paraglideMiddleware(event.request, ({ request, locale }) => { + event.request = request; + + return resolve(event, { + transformPageChunk: ({ html }) => html.replace("%paraglide.lang%", locale) + }); + }); + +export const handle: Handle = handleParaglide; diff --git a/apps/docs/src/hooks.ts b/apps/docs/src/hooks.ts new file mode 100644 index 0000000..7676f00 --- /dev/null +++ b/apps/docs/src/hooks.ts @@ -0,0 +1,3 @@ +import { deLocalizeUrl } from "$lib/paraglide/runtime"; + +export const reroute = (request) => deLocalizeUrl(request.url).pathname; diff --git a/apps/docs/src/lib/actions/typewriter.svelte.ts b/apps/docs/src/lib/actions/typewriter.svelte.ts new file mode 100644 index 0000000..861a955 --- /dev/null +++ b/apps/docs/src/lib/actions/typewriter.svelte.ts @@ -0,0 +1,34 @@ + + +import { createAttachmentKey } from "svelte/attachments"; +import type { TransitionConfig } from "svelte/transition"; + +export type Options = { + speed: number; + delay: number; + onComplete?: () => void; +}; + +export const typewriter = ( + node: HTMLElement, + { speed = 1, delay = 0, onComplete }: Partial +) => { + const text = node.textContent ?? ""; + const duration = text.length / (speed * 0.01); + + return { + delay, + duration, + tick: (t) => { + const i = Math.trunc(text.length * t); + node.textContent = text.slice(0, i); + if (node.textContent.length === text.length) onComplete?.(); + } + } satisfies TransitionConfig; +}; + +export function attachTypewriter(opts: Partial = {}) { + return { + [createAttachmentKey()]: (node: HTMLElement) => typewriter(node, opts) + }; +} diff --git a/apps/docs/src/lib/components/app-sidebar.svelte b/apps/docs/src/lib/components/app-sidebar.svelte new file mode 100644 index 0000000..513fc65 --- /dev/null +++ b/apps/docs/src/lib/components/app-sidebar.svelte @@ -0,0 +1,66 @@ + + + + + + + {#if navData} + + {/if} + + + + + {#if navData} + {#each navItems as item (item.title)} + + + + {#snippet child({ props })} + + {item.title} + + + {/snippet} + + + + + {#each (item.items ?? []) as subItem (subItem.title)} + + + {#snippet child({ props })} + {subItem.title} + {/snippet} + + + {/each} + + + + + + {/each} + {/if} + + + diff --git a/apps/docs/src/lib/components/markdown-renderer.svelte b/apps/docs/src/lib/components/markdown-renderer.svelte new file mode 100644 index 0000000..3e36616 --- /dev/null +++ b/apps/docs/src/lib/components/markdown-renderer.svelte @@ -0,0 +1,7 @@ + + +
+ {@html html} +
diff --git a/apps/docs/src/lib/components/search-form.svelte b/apps/docs/src/lib/components/search-form.svelte new file mode 100644 index 0000000..d232a9f --- /dev/null +++ b/apps/docs/src/lib/components/search-form.svelte @@ -0,0 +1,21 @@ + + +
+ + + + + + + +
diff --git a/apps/docs/src/lib/components/ui/accordion/accordion-content.svelte b/apps/docs/src/lib/components/ui/accordion/accordion-content.svelte new file mode 100644 index 0000000..cf7045e --- /dev/null +++ b/apps/docs/src/lib/components/ui/accordion/accordion-content.svelte @@ -0,0 +1,22 @@ + + + +
+ {@render children?.()} +
+
diff --git a/apps/docs/src/lib/components/ui/accordion/accordion-item.svelte b/apps/docs/src/lib/components/ui/accordion/accordion-item.svelte new file mode 100644 index 0000000..780545c --- /dev/null +++ b/apps/docs/src/lib/components/ui/accordion/accordion-item.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/accordion/accordion-trigger.svelte b/apps/docs/src/lib/components/ui/accordion/accordion-trigger.svelte new file mode 100644 index 0000000..0027cdd --- /dev/null +++ b/apps/docs/src/lib/components/ui/accordion/accordion-trigger.svelte @@ -0,0 +1,32 @@ + + + + svg]:rotate-180", + className + )} + {...restProps} + > + {@render children?.()} + + + diff --git a/apps/docs/src/lib/components/ui/accordion/accordion.svelte b/apps/docs/src/lib/components/ui/accordion/accordion.svelte new file mode 100644 index 0000000..117ee37 --- /dev/null +++ b/apps/docs/src/lib/components/ui/accordion/accordion.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/accordion/index.ts b/apps/docs/src/lib/components/ui/accordion/index.ts new file mode 100644 index 0000000..ac343a1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/accordion/index.ts @@ -0,0 +1,16 @@ +import Root from "./accordion.svelte"; +import Content from "./accordion-content.svelte"; +import Item from "./accordion-item.svelte"; +import Trigger from "./accordion-trigger.svelte"; + +export { + Root, + Content, + Item, + Trigger, + // + Root as Accordion, + Content as AccordionContent, + Item as AccordionItem, + Trigger as AccordionTrigger, +}; diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte new file mode 100644 index 0000000..a005691 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte new file mode 100644 index 0000000..a7b0cf7 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte new file mode 100644 index 0000000..6c3c604 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte @@ -0,0 +1,27 @@ + + + + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte new file mode 100644 index 0000000..2ec67dc --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte new file mode 100644 index 0000000..f78b97a --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte new file mode 100644 index 0000000..c8fa762 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte new file mode 100644 index 0000000..a64ee76 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte new file mode 100644 index 0000000..7ef2b5f --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte new file mode 100644 index 0000000..b22d1d5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/alert-dialog/index.ts b/apps/docs/src/lib/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..cc281c5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert-dialog/index.ts @@ -0,0 +1,39 @@ +import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; +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"; + +const Root = AlertDialogPrimitive.Root; +const Portal = AlertDialogPrimitive.Portal; + +export { + Root, + Title, + Action, + Cancel, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + // + Root as AlertDialog, + Title as AlertDialogTitle, + Action as AlertDialogAction, + Cancel as AlertDialogCancel, + Portal as AlertDialogPortal, + Footer as AlertDialogFooter, + Header as AlertDialogHeader, + Trigger as AlertDialogTrigger, + Overlay as AlertDialogOverlay, + Content as AlertDialogContent, + Description as AlertDialogDescription, +}; diff --git a/apps/docs/src/lib/components/ui/alert/alert-description.svelte b/apps/docs/src/lib/components/ui/alert/alert-description.svelte new file mode 100644 index 0000000..8b56aed --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert/alert-description.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/apps/docs/src/lib/components/ui/alert/alert-title.svelte b/apps/docs/src/lib/components/ui/alert/alert-title.svelte new file mode 100644 index 0000000..77e45ad --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert/alert-title.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/apps/docs/src/lib/components/ui/alert/alert.svelte b/apps/docs/src/lib/components/ui/alert/alert.svelte new file mode 100644 index 0000000..2b2eff9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert/alert.svelte @@ -0,0 +1,44 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/alert/index.ts b/apps/docs/src/lib/components/ui/alert/index.ts new file mode 100644 index 0000000..97e21b4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/alert/index.ts @@ -0,0 +1,14 @@ +import Root from "./alert.svelte"; +import Description from "./alert-description.svelte"; +import Title from "./alert-title.svelte"; +export { alertVariants, type AlertVariant } from "./alert.svelte"; + +export { + Root, + Description, + Title, + // + Root as Alert, + Description as AlertDescription, + Title as AlertTitle, +}; diff --git a/apps/docs/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte b/apps/docs/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte new file mode 100644 index 0000000..815aab0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/aspect-ratio/index.ts b/apps/docs/src/lib/components/ui/aspect-ratio/index.ts new file mode 100644 index 0000000..985c75f --- /dev/null +++ b/apps/docs/src/lib/components/ui/aspect-ratio/index.ts @@ -0,0 +1,3 @@ +import Root from "./aspect-ratio.svelte"; + +export { Root, Root as AspectRatio }; diff --git a/apps/docs/src/lib/components/ui/avatar/avatar-fallback.svelte b/apps/docs/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..249d4a4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/avatar/avatar-image.svelte b/apps/docs/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..2bb9db4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/avatar/avatar.svelte b/apps/docs/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..e37214d --- /dev/null +++ b/apps/docs/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/avatar/index.ts b/apps/docs/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..d06457b --- /dev/null +++ b/apps/docs/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,13 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; + +export { + Root, + Image, + Fallback, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback, +}; diff --git a/apps/docs/src/lib/components/ui/badge/badge.svelte b/apps/docs/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 0000000..5000457 --- /dev/null +++ b/apps/docs/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,50 @@ + + + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/badge/index.ts b/apps/docs/src/lib/components/ui/badge/index.ts new file mode 100644 index 0000000..64e0aa9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/badge/index.ts @@ -0,0 +1,2 @@ +export { default as Badge } from "./badge.svelte"; +export { badgeVariants, type BadgeVariant } from "./badge.svelte"; diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte new file mode 100644 index 0000000..a178cf5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte @@ -0,0 +1,23 @@ + + + diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte new file mode 100644 index 0000000..1a84c4c --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte @@ -0,0 +1,20 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte new file mode 100644 index 0000000..e6bc17d --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte @@ -0,0 +1,31 @@ + + +{#if child} + {@render child({ props: attrs })} +{:else} + + {@render children?.()} + +{/if} diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte new file mode 100644 index 0000000..b5458fa --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte @@ -0,0 +1,23 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte new file mode 100644 index 0000000..5fb6979 --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte new file mode 100644 index 0000000..84106a1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb.svelte new file mode 100644 index 0000000..8f8a3e6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/breadcrumb.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/docs/src/lib/components/ui/breadcrumb/index.ts b/apps/docs/src/lib/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..dc914ec --- /dev/null +++ b/apps/docs/src/lib/components/ui/breadcrumb/index.ts @@ -0,0 +1,25 @@ +import Root from "./breadcrumb.svelte"; +import Ellipsis from "./breadcrumb-ellipsis.svelte"; +import Item from "./breadcrumb-item.svelte"; +import Separator from "./breadcrumb-separator.svelte"; +import Link from "./breadcrumb-link.svelte"; +import List from "./breadcrumb-list.svelte"; +import Page from "./breadcrumb-page.svelte"; + +export { + Root, + Ellipsis, + Item, + Separator, + Link, + List, + Page, + // + Root as Breadcrumb, + Ellipsis as BreadcrumbEllipsis, + Item as BreadcrumbItem, + Separator as BreadcrumbSeparator, + Link as BreadcrumbLink, + List as BreadcrumbList, + Page as BreadcrumbPage, +}; diff --git a/apps/docs/src/lib/components/ui/button/button.svelte b/apps/docs/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..230e383 --- /dev/null +++ b/apps/docs/src/lib/components/ui/button/button.svelte @@ -0,0 +1,126 @@ + + + + + + + + { + onclick?.(e); + + if (type === undefined) return; + + if (onClickPromise) { + loading = true; + + await onClickPromise(e); + + loading = false; + } + }} +> + {#if type !== undefined && loading} +
    +
    + +
    +
    + Loading + {/if} + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/button/index.ts b/apps/docs/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..bf3620b --- /dev/null +++ b/apps/docs/src/lib/components/ui/button/index.ts @@ -0,0 +1,23 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + type AnchorElementProps, + type ButtonElementProps, + type ButtonPropsWithoutHTML, + buttonVariants +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, + type AnchorElementProps, + type ButtonElementProps, + type ButtonPropsWithoutHTML +}; diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-caption.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-caption.svelte new file mode 100644 index 0000000..5c93037 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-caption.svelte @@ -0,0 +1,76 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-cell.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-cell.svelte new file mode 100644 index 0000000..5f295d6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-day.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-day.svelte new file mode 100644 index 0000000..32e9c83 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-day.svelte @@ -0,0 +1,35 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-grid-body.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-grid-body.svelte new file mode 100644 index 0000000..8cd86de --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-grid-body.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-grid-head.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-grid-head.svelte new file mode 100644 index 0000000..333edc4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-grid-head.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-grid-row.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-grid-row.svelte new file mode 100644 index 0000000..9032236 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-grid.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-grid.svelte new file mode 100644 index 0000000..e0c8627 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-grid.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-head-cell.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-head-cell.svelte new file mode 100644 index 0000000..131807e --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-header.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-header.svelte new file mode 100644 index 0000000..5b7e397 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-header.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-heading.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-heading.svelte new file mode 100644 index 0000000..a9b9810 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-month-select.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-month-select.svelte new file mode 100644 index 0000000..e4b536a --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-month-select.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-month.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-month.svelte new file mode 100644 index 0000000..e747fae --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-month.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-months.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-months.svelte new file mode 100644 index 0000000..f717a9d --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-months.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-nav.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-nav.svelte new file mode 100644 index 0000000..27f33d7 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-nav.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-next-button.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-next-button.svelte new file mode 100644 index 0000000..d8eb4ef --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-next-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-prev-button.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-prev-button.svelte new file mode 100644 index 0000000..3e4471a --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-prev-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar-year-select.svelte b/apps/docs/src/lib/components/ui/calendar/calendar-year-select.svelte new file mode 100644 index 0000000..3842037 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar-year-select.svelte @@ -0,0 +1,43 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + diff --git a/apps/docs/src/lib/components/ui/calendar/calendar.svelte b/apps/docs/src/lib/components/ui/calendar/calendar.svelte new file mode 100644 index 0000000..29b6fff --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/calendar.svelte @@ -0,0 +1,115 @@ + + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + {#each weekdays as weekday (weekday)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/calendar/index.ts b/apps/docs/src/lib/components/ui/calendar/index.ts new file mode 100644 index 0000000..f3a16d2 --- /dev/null +++ b/apps/docs/src/lib/components/ui/calendar/index.ts @@ -0,0 +1,40 @@ +import Root from "./calendar.svelte"; +import Cell from "./calendar-cell.svelte"; +import Day from "./calendar-day.svelte"; +import Grid from "./calendar-grid.svelte"; +import Header from "./calendar-header.svelte"; +import Months from "./calendar-months.svelte"; +import GridRow from "./calendar-grid-row.svelte"; +import Heading from "./calendar-heading.svelte"; +import GridBody from "./calendar-grid-body.svelte"; +import GridHead from "./calendar-grid-head.svelte"; +import HeadCell from "./calendar-head-cell.svelte"; +import NextButton from "./calendar-next-button.svelte"; +import PrevButton from "./calendar-prev-button.svelte"; +import MonthSelect from "./calendar-month-select.svelte"; +import YearSelect from "./calendar-year-select.svelte"; +import Month from "./calendar-month.svelte"; +import Nav from "./calendar-nav.svelte"; +import Caption from "./calendar-caption.svelte"; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + Nav, + Month, + YearSelect, + MonthSelect, + Caption, + // + Root as Calendar, +}; diff --git a/apps/docs/src/lib/components/ui/card/card-action.svelte b/apps/docs/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..cc36c56 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/card-content.svelte b/apps/docs/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..bc90b83 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/card-description.svelte b/apps/docs/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..9b20ac7 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

    + {@render children?.()} +

    diff --git a/apps/docs/src/lib/components/ui/card/card-footer.svelte b/apps/docs/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..cf43353 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/card-header.svelte b/apps/docs/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..8a91abb --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/card-title.svelte b/apps/docs/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..22586e6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/card.svelte b/apps/docs/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..99448cc --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/card.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/card/index.ts b/apps/docs/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..4d3fce4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/card/index.ts @@ -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, +}; diff --git a/apps/docs/src/lib/components/ui/carousel/carousel-content.svelte b/apps/docs/src/lib/components/ui/carousel/carousel-content.svelte new file mode 100644 index 0000000..6b169be --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/carousel-content.svelte @@ -0,0 +1,43 @@ + + +
    +
    + {@render children?.()} +
    +
    diff --git a/apps/docs/src/lib/components/ui/carousel/carousel-item.svelte b/apps/docs/src/lib/components/ui/carousel/carousel-item.svelte new file mode 100644 index 0000000..8352833 --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/carousel-item.svelte @@ -0,0 +1,30 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/carousel/carousel-next.svelte b/apps/docs/src/lib/components/ui/carousel/carousel-next.svelte new file mode 100644 index 0000000..27bd383 --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/carousel-next.svelte @@ -0,0 +1,38 @@ + + + diff --git a/apps/docs/src/lib/components/ui/carousel/carousel-previous.svelte b/apps/docs/src/lib/components/ui/carousel/carousel-previous.svelte new file mode 100644 index 0000000..2f0973d --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/carousel-previous.svelte @@ -0,0 +1,38 @@ + + + diff --git a/apps/docs/src/lib/components/ui/carousel/carousel.svelte b/apps/docs/src/lib/components/ui/carousel/carousel.svelte new file mode 100644 index 0000000..0492805 --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/carousel.svelte @@ -0,0 +1,93 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/carousel/context.ts b/apps/docs/src/lib/components/ui/carousel/context.ts new file mode 100644 index 0000000..a5fd74f --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/context.ts @@ -0,0 +1,58 @@ +import type { WithElementRef } from "$lib/utils.js"; +import type { + EmblaCarouselSvelteType, + default as emblaCarouselSvelte, +} from "embla-carousel-svelte"; +import { getContext, hasContext, setContext } from "svelte"; +import type { HTMLAttributes } from "svelte/elements"; + +export type CarouselAPI = + NonNullable["on:emblaInit"]> extends ( + evt: CustomEvent + ) => void + ? CarouselAPI + : never; + +type EmblaCarouselConfig = NonNullable[1]>; + +export type CarouselOptions = EmblaCarouselConfig["options"]; +export type CarouselPlugins = EmblaCarouselConfig["plugins"]; + +//// + +export type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugins; + setApi?: (api: CarouselAPI | undefined) => void; + orientation?: "horizontal" | "vertical"; +} & WithElementRef>; + +const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT"); + +export type EmblaContext = { + api: CarouselAPI | undefined; + orientation: "horizontal" | "vertical"; + scrollNext: () => void; + scrollPrev: () => void; + canScrollNext: boolean; + canScrollPrev: boolean; + handleKeyDown: (e: KeyboardEvent) => void; + options: CarouselOptions; + plugins: CarouselPlugins; + onInit: (e: CustomEvent) => void; + scrollTo: (index: number, jump?: boolean) => void; + scrollSnaps: number[]; + selectedIndex: number; +}; + +export function setEmblaContext(config: EmblaContext): EmblaContext { + setContext(EMBLA_CAROUSEL_CONTEXT, config); + return config; +} + +export function getEmblaContext(name = "This component") { + if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) { + throw new Error(`${name} must be used within a component`); + } + return getContext>(EMBLA_CAROUSEL_CONTEXT); +} diff --git a/apps/docs/src/lib/components/ui/carousel/index.ts b/apps/docs/src/lib/components/ui/carousel/index.ts new file mode 100644 index 0000000..957fc74 --- /dev/null +++ b/apps/docs/src/lib/components/ui/carousel/index.ts @@ -0,0 +1,19 @@ +import Root from "./carousel.svelte"; +import Content from "./carousel-content.svelte"; +import Item from "./carousel-item.svelte"; +import Previous from "./carousel-previous.svelte"; +import Next from "./carousel-next.svelte"; + +export { + Root, + Content, + Item, + Previous, + Next, + // + Root as Carousel, + Content as CarouselContent, + Item as CarouselItem, + Previous as CarouselPrevious, + Next as CarouselNext, +}; diff --git a/apps/docs/src/lib/components/ui/chart/chart-container.svelte b/apps/docs/src/lib/components/ui/chart/chart-container.svelte new file mode 100644 index 0000000..563b25b --- /dev/null +++ b/apps/docs/src/lib/components/ui/chart/chart-container.svelte @@ -0,0 +1,80 @@ + + +
    + + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/chart/chart-style.svelte b/apps/docs/src/lib/components/ui/chart/chart-style.svelte new file mode 100644 index 0000000..864ecc3 --- /dev/null +++ b/apps/docs/src/lib/components/ui/chart/chart-style.svelte @@ -0,0 +1,37 @@ + + +{#if themeContents} + {#key id} + + {themeContents} + + {/key} +{/if} diff --git a/apps/docs/src/lib/components/ui/chart/chart-tooltip.svelte b/apps/docs/src/lib/components/ui/chart/chart-tooltip.svelte new file mode 100644 index 0000000..efef55c --- /dev/null +++ b/apps/docs/src/lib/components/ui/chart/chart-tooltip.svelte @@ -0,0 +1,159 @@ + + +{#snippet TooltipLabel()} + {#if formattedLabel} +
    + {#if typeof formattedLabel === "function"} + {@render formattedLabel()} + {:else} + {formattedLabel} + {/if} +
    + {/if} +{/snippet} + + +
    + {#if !nestLabel} + {@render TooltipLabel()} + {/if} +
    + {#each tooltipCtx.payload as item, i (item.key + i)} + {@const key = `${nameKey || item.key || item.name || "value"}`} + {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)} + {@const indicatorColor = color || item.payload?.color || item.color} +
    svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5", + indicator === "dot" && "items-center" + )} + > + {#if formatter && item.value !== undefined && item.name} + {@render formatter({ + value: item.value, + name: item.name, + item, + index: i, + payload: tooltipCtx.payload, + })} + {:else} + {#if itemConfig?.icon} + + {:else if !hideIndicator} +
    + {/if} +
    +
    + {#if nestLabel} + {@render TooltipLabel()} + {/if} + + {itemConfig?.label || item.name} + +
    + {#if item.value !== undefined} + + {item.value.toLocaleString()} + + {/if} +
    + {/if} +
    + {/each} +
    +
    +
    diff --git a/apps/docs/src/lib/components/ui/chart/chart-utils.ts b/apps/docs/src/lib/components/ui/chart/chart-utils.ts new file mode 100644 index 0000000..2decbbf --- /dev/null +++ b/apps/docs/src/lib/components/ui/chart/chart-utils.ts @@ -0,0 +1,66 @@ +import type { Tooltip } from "layerchart"; +import { getContext, setContext, type Component, type ComponentProps, type Snippet } from "svelte"; + +export const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: string; + icon?: Component; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never; + +export type TooltipPayload = ExtractSnippetParams< + ComponentProps["children"] +>["payload"][number]; + +// Helper to extract item config from a payload. +export function getPayloadConfigFromPayload( + config: ChartConfig, + payload: TooltipPayload, + key: string +) { + if (typeof payload !== "object" || payload === null) return undefined; + + const payloadPayload = + "payload" in payload && typeof payload.payload === "object" && payload.payload !== null + ? payload.payload + : undefined; + + let configLabelKey: string = key; + + if (payload.key === key) { + configLabelKey = payload.key; + } else if (payload.name === key) { + configLabelKey = payload.name; + } else if (key in payload && typeof payload[key as keyof typeof payload] === "string") { + configLabelKey = payload[key as keyof typeof payload] as string; + } else if ( + payloadPayload !== undefined && + key in payloadPayload && + typeof payloadPayload[key as keyof typeof payloadPayload] === "string" + ) { + configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string; + } + + return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]; +} + +type ChartContextValue = { + config: ChartConfig; +}; + +const chartContextKey = Symbol("chart-context"); + +export function setChartContext(value: ChartContextValue) { + return setContext(chartContextKey, value); +} + +export function useChart() { + return getContext(chartContextKey); +} diff --git a/apps/docs/src/lib/components/ui/chart/index.ts b/apps/docs/src/lib/components/ui/chart/index.ts new file mode 100644 index 0000000..f22375e --- /dev/null +++ b/apps/docs/src/lib/components/ui/chart/index.ts @@ -0,0 +1,6 @@ +import ChartContainer from "./chart-container.svelte"; +import ChartTooltip from "./chart-tooltip.svelte"; + +export { getPayloadConfigFromPayload, type ChartConfig } from "./chart-utils.js"; + +export { ChartContainer, ChartTooltip, ChartContainer as Container, ChartTooltip as Tooltip }; diff --git a/apps/docs/src/lib/components/ui/checkbox/checkbox.svelte b/apps/docs/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..1622e05 --- /dev/null +++ b/apps/docs/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,36 @@ + + + + {#snippet children({ checked, indeterminate })} +
    + {#if checked} + + {:else if indeterminate} + + {/if} +
    + {/snippet} +
    diff --git a/apps/docs/src/lib/components/ui/checkbox/index.ts b/apps/docs/src/lib/components/ui/checkbox/index.ts new file mode 100644 index 0000000..6d92d94 --- /dev/null +++ b/apps/docs/src/lib/components/ui/checkbox/index.ts @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; diff --git a/apps/docs/src/lib/components/ui/code/code-copy-button.svelte b/apps/docs/src/lib/components/ui/code/code-copy-button.svelte new file mode 100644 index 0000000..fca75fc --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/code-copy-button.svelte @@ -0,0 +1,24 @@ + + + diff --git a/apps/docs/src/lib/components/ui/code/code-overflow.svelte b/apps/docs/src/lib/components/ui/code/code-overflow.svelte new file mode 100644 index 0000000..b702e69 --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/code-overflow.svelte @@ -0,0 +1,45 @@ + + +
    + {@render children?.()} + {#if collapsed} +
    + {/if} + {#if collapsed} + + {/if} +
    diff --git a/apps/docs/src/lib/components/ui/code/code.svelte b/apps/docs/src/lib/components/ui/code/code.svelte new file mode 100644 index 0000000..a5045c4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/code.svelte @@ -0,0 +1,101 @@ + + +
    + {@html codeState.highlighted} + {@render children?.()} +
    + + diff --git a/apps/docs/src/lib/components/ui/code/code.svelte.ts b/apps/docs/src/lib/components/ui/code/code.svelte.ts new file mode 100644 index 0000000..dc500fc --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/code.svelte.ts @@ -0,0 +1,125 @@ +import { Context } from "runed"; +import type { ReadableBoxedValues, WritableBoxedValues } from "svelte-toolbelt"; +import type { CodeRootProps } from "./types"; +import { highlighter } from "./shiki"; +import DOMPurify from "isomorphic-dompurify"; +import type { HighlighterCore } from "shiki"; + +type CodeOverflowStateProps = WritableBoxedValues<{ + collapsed: boolean; +}>; + +class CodeOverflowState { + constructor(readonly opts: CodeOverflowStateProps) { + this.toggleCollapsed = this.toggleCollapsed.bind(this); + } + + toggleCollapsed() { + this.opts.collapsed.current = !this.opts.collapsed.current; + } + + get collapsed() { + return this.opts.collapsed.current; + } +} + +type CodeRootStateProps = ReadableBoxedValues<{ + code: string; + lang: NonNullable; + hideLines: boolean; + highlight: CodeRootProps["highlight"]; +}>; + +class CodeRootState { + highlighter: HighlighterCore | null = $state(null); + + constructor( + readonly opts: CodeRootStateProps, + readonly overflow?: CodeOverflowState + ) { + highlighter.then((hl) => (this.highlighter = hl)); + } + + highlight(code: string) { + return this.highlighter?.codeToHtml(code, { + lang: this.opts.lang.current, + themes: { + light: "github-light-default", + dark: "github-dark-default" + }, + transformers: [ + { + pre: (el) => { + el.properties.style = ""; + + if (!this.opts.hideLines.current) { + el.properties.class += " line-numbers"; + } + + return el; + }, + line: (node, line) => { + if (within(line, this.opts.highlight.current)) { + node.properties.class = node.properties.class + " line--highlighted"; + } + + return node; + } + } + ] + }); + } + + get code() { + return this.opts.code.current; + } + + highlighted = $derived(DOMPurify.sanitize(this.highlight(this.code) ?? "")); +} + +function within(num: number, range: CodeRootProps["highlight"]) { + if (!range) return false; + + let within = false; + + for (const r of range) { + if (typeof r === "number") { + if (num === r) { + within = true; + break; + } + continue; + } + + if (r[0] <= num && num <= r[1]) { + within = true; + break; + } + } + + return within; +} + +class CodeCopyButtonState { + constructor(readonly root: CodeRootState) {} + + get code() { + return this.root.opts.code.current; + } +} + +const overflowCtx = new Context("code-overflow-state"); + +const ctx = new Context("code-root-state"); + +export function useCodeOverflow(props: CodeOverflowStateProps) { + return overflowCtx.set(new CodeOverflowState(props)); +} + +export function useCode(props: CodeRootStateProps) { + return ctx.set(new CodeRootState(props, overflowCtx.getOr(undefined))); +} + +export function useCodeCopyButton() { + return new CodeCopyButtonState(ctx.get()); +} diff --git a/apps/docs/src/lib/components/ui/code/index.ts b/apps/docs/src/lib/components/ui/code/index.ts new file mode 100644 index 0000000..e97b63e --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/index.ts @@ -0,0 +1,25 @@ +import { tv, type VariantProps } from "tailwind-variants"; +import Root from "./code.svelte"; +import Overflow from "./code-overflow.svelte"; +import CopyButton from "./code-copy-button.svelte"; +import type { CodeCopyButtonProps, CodeRootProps } from "./types"; + +export const codeVariants = tv({ + base: "not-prose relative h-full rounded-lg border shadow-sm p-0", + variants: { + variant: { + default: "border-border bg-card", + secondary: "bg-secondary/50 border-transparent" + } + } +}); + +export type CodeVariant = VariantProps["variant"]; + +export { + Root, + CopyButton, + Overflow, + type CodeRootProps as RootProps, + type CodeCopyButtonProps as CopyButtonProps +}; diff --git a/apps/docs/src/lib/components/ui/code/shiki.ts b/apps/docs/src/lib/components/ui/code/shiki.ts new file mode 100644 index 0000000..60852f4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/shiki.ts @@ -0,0 +1,25 @@ +// Follows the best practices established in https://shiki.matsu.io/guide/best-performance +import { createJavaScriptRegexEngine } from "shiki/engine/javascript"; +import { createHighlighterCore } from "shiki/core"; + +const bundledLanguages = { + bash: () => import("@shikijs/langs/bash"), + diff: () => import("@shikijs/langs/diff"), + javascript: () => import("@shikijs/langs/javascript"), + json: () => import("@shikijs/langs/json"), + svelte: () => import("@shikijs/langs/svelte"), + typescript: () => import("@shikijs/langs/typescript") +}; + +/** The languages configured for the highlighter */ +export type SupportedLanguage = keyof typeof bundledLanguages; + +/** A preloaded highlighter instance. */ +export const highlighter = createHighlighterCore({ + themes: [ + import("@shikijs/themes/github-light-default"), + import("@shikijs/themes/github-dark-default") + ], + langs: Object.entries(bundledLanguages).map(([_, lang]) => lang), + engine: createJavaScriptRegexEngine() +}); diff --git a/apps/docs/src/lib/components/ui/code/types.ts b/apps/docs/src/lib/components/ui/code/types.ts new file mode 100644 index 0000000..1262282 --- /dev/null +++ b/apps/docs/src/lib/components/ui/code/types.ts @@ -0,0 +1,30 @@ +import type { WithChildren, WithoutChildren } from "bits-ui"; +import type { CodeVariant } from "."; +import type { SupportedLanguage } from "./shiki"; +import type { HTMLAttributes } from "svelte/elements"; +import type { CopyButtonPropsWithoutHTML } from "$lib/components/ui/copy-button/types"; + +export type CodeRootPropsWithoutHTML = WithChildren<{ + ref?: HTMLDivElement | null; + variant?: CodeVariant; + lang?: SupportedLanguage; + code: string; + class?: string; + hideLines?: boolean; + highlight?: (number | [number, number])[]; +}>; + +export type CodeRootProps = CodeRootPropsWithoutHTML & + WithoutChildren>; + +export type CodeCopyButtonPropsWithoutHTML = Omit; + +export type CodeCopyButtonProps = CodeCopyButtonPropsWithoutHTML & + WithoutChildren>; + +export type CodeOverflowPropsWithoutHTML = WithChildren<{ + collapsed?: boolean; +}>; + +export type CodeOverflowProps = CodeOverflowPropsWithoutHTML & + WithoutChildren>; diff --git a/apps/docs/src/lib/components/ui/collapsible/collapsible-content.svelte b/apps/docs/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..bdabb55 --- /dev/null +++ b/apps/docs/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/apps/docs/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..ece7ad6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/collapsible/collapsible.svelte b/apps/docs/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..39cdd4e --- /dev/null +++ b/apps/docs/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,11 @@ + + + diff --git a/apps/docs/src/lib/components/ui/collapsible/index.ts b/apps/docs/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..169b479 --- /dev/null +++ b/apps/docs/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,13 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; diff --git a/apps/docs/src/lib/components/ui/command/command-dialog.svelte b/apps/docs/src/lib/components/ui/command/command-dialog.svelte new file mode 100644 index 0000000..5c9a82a --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-dialog.svelte @@ -0,0 +1,40 @@ + + + + + {title} + {description} + + + + + diff --git a/apps/docs/src/lib/components/ui/command/command-empty.svelte b/apps/docs/src/lib/components/ui/command/command-empty.svelte new file mode 100644 index 0000000..6726cd8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-empty.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/command-group.svelte b/apps/docs/src/lib/components/ui/command/command-group.svelte new file mode 100644 index 0000000..104f817 --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-group.svelte @@ -0,0 +1,32 @@ + + + + {#if heading} + + {heading} + + {/if} + + diff --git a/apps/docs/src/lib/components/ui/command/command-input.svelte b/apps/docs/src/lib/components/ui/command/command-input.svelte new file mode 100644 index 0000000..611b00d --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-input.svelte @@ -0,0 +1,26 @@ + + +
    + + +
    diff --git a/apps/docs/src/lib/components/ui/command/command-item.svelte b/apps/docs/src/lib/components/ui/command/command-item.svelte new file mode 100644 index 0000000..d94d07f --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-item.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/command-link-item.svelte b/apps/docs/src/lib/components/ui/command/command-link-item.svelte new file mode 100644 index 0000000..944c22d --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-link-item.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/command-list.svelte b/apps/docs/src/lib/components/ui/command/command-list.svelte new file mode 100644 index 0000000..569f595 --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-list.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/command-separator.svelte b/apps/docs/src/lib/components/ui/command/command-separator.svelte new file mode 100644 index 0000000..35c4c95 --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/command-shortcut.svelte b/apps/docs/src/lib/components/ui/command/command-shortcut.svelte new file mode 100644 index 0000000..3d68bc5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/command/command.svelte b/apps/docs/src/lib/components/ui/command/command.svelte new file mode 100644 index 0000000..c64a77e --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/command.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/command/index.ts b/apps/docs/src/lib/components/ui/command/index.ts new file mode 100644 index 0000000..d3dbade --- /dev/null +++ b/apps/docs/src/lib/components/ui/command/index.ts @@ -0,0 +1,40 @@ +import { Command as CommandPrimitive } from "bits-ui"; + +import Root from "./command.svelte"; +import Dialog from "./command-dialog.svelte"; +import Empty from "./command-empty.svelte"; +import Group from "./command-group.svelte"; +import Item from "./command-item.svelte"; +import Input from "./command-input.svelte"; +import List from "./command-list.svelte"; +import Separator from "./command-separator.svelte"; +import Shortcut from "./command-shortcut.svelte"; +import LinkItem from "./command-link-item.svelte"; + +const Loading = CommandPrimitive.Loading; + +export { + Root, + Dialog, + Empty, + Group, + Item, + LinkItem, + Input, + List, + Separator, + Shortcut, + Loading, + // + Root as Command, + Dialog as CommandDialog, + Empty as CommandEmpty, + Group as CommandGroup, + Item as CommandItem, + LinkItem as CommandLinkItem, + Input as CommandInput, + List as CommandList, + Separator as CommandSeparator, + Shortcut as CommandShortcut, + Loading as CommandLoading, +}; diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte new file mode 100644 index 0000000..ccafce2 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-content.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-content.svelte new file mode 100644 index 0000000..e793938 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-content.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-group-heading.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-group-heading.svelte new file mode 100644 index 0000000..66a81b3 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-group-heading.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-group.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-group.svelte new file mode 100644 index 0000000..c7c1e06 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-item.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-item.svelte new file mode 100644 index 0000000..9193d18 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-label.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-label.svelte new file mode 100644 index 0000000..7d05037 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-group.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-group.svelte new file mode 100644 index 0000000..964cb55 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-item.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-item.svelte new file mode 100644 index 0000000..7673f01 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-separator.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-separator.svelte new file mode 100644 index 0000000..7f5b237 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-shortcut.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-shortcut.svelte new file mode 100644 index 0000000..7eca8e0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-content.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-content.svelte new file mode 100644 index 0000000..e0245b1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte new file mode 100644 index 0000000..ba00be9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/context-menu/context-menu-trigger.svelte b/apps/docs/src/lib/components/ui/context-menu/context-menu-trigger.svelte new file mode 100644 index 0000000..3efa857 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/context-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/context-menu/index.ts b/apps/docs/src/lib/components/ui/context-menu/index.ts new file mode 100644 index 0000000..fce8160 --- /dev/null +++ b/apps/docs/src/lib/components/ui/context-menu/index.ts @@ -0,0 +1,51 @@ +import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; + +import Trigger from "./context-menu-trigger.svelte"; +import Group from "./context-menu-group.svelte"; +import RadioGroup from "./context-menu-radio-group.svelte"; +import Item from "./context-menu-item.svelte"; +import GroupHeading from "./context-menu-group-heading.svelte"; +import Content from "./context-menu-content.svelte"; +import Shortcut from "./context-menu-shortcut.svelte"; +import RadioItem from "./context-menu-radio-item.svelte"; +import Separator from "./context-menu-separator.svelte"; +import SubContent from "./context-menu-sub-content.svelte"; +import SubTrigger from "./context-menu-sub-trigger.svelte"; +import CheckboxItem from "./context-menu-checkbox-item.svelte"; +import Label from "./context-menu-label.svelte"; +const Sub = ContextMenuPrimitive.Sub; +const Root = ContextMenuPrimitive.Root; + +export { + Sub, + Root, + Item, + GroupHeading, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as ContextMenu, + Sub as ContextMenuSub, + Item as ContextMenuItem, + GroupHeading as ContextMenuGroupHeading, + Group as ContextMenuGroup, + Content as ContextMenuContent, + Trigger as ContextMenuTrigger, + Shortcut as ContextMenuShortcut, + RadioItem as ContextMenuRadioItem, + Separator as ContextMenuSeparator, + RadioGroup as ContextMenuRadioGroup, + SubContent as ContextMenuSubContent, + SubTrigger as ContextMenuSubTrigger, + CheckboxItem as ContextMenuCheckboxItem, + Label as ContextMenuLabel, +}; diff --git a/apps/docs/src/lib/components/ui/copy-button/copy-button.svelte b/apps/docs/src/lib/components/ui/copy-button/copy-button.svelte new file mode 100644 index 0000000..9d5854e --- /dev/null +++ b/apps/docs/src/lib/components/ui/copy-button/copy-button.svelte @@ -0,0 +1,71 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/copy-button/index.ts b/apps/docs/src/lib/components/ui/copy-button/index.ts new file mode 100644 index 0000000..d46faf4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/copy-button/index.ts @@ -0,0 +1,5 @@ + + +import CopyButton from "./copy-button.svelte"; + +export { CopyButton }; diff --git a/apps/docs/src/lib/components/ui/copy-button/types.ts b/apps/docs/src/lib/components/ui/copy-button/types.ts new file mode 100644 index 0000000..3627784 --- /dev/null +++ b/apps/docs/src/lib/components/ui/copy-button/types.ts @@ -0,0 +1,20 @@ + + +import type { Snippet } from "svelte"; +import type { ButtonPropsWithoutHTML } from "$lib/components/ui/button"; +import type { UseClipboard } from "$lib/hooks/use-clipboard.svelte"; +import type { HTMLAttributes } from "svelte/elements"; +import type { WithChildren, WithoutChildren } from "bits-ui"; + +export type CopyButtonPropsWithoutHTML = WithChildren< + Pick & { + ref?: HTMLButtonElement | null; + text: string; + icon?: Snippet<[]>; + animationDuration?: number; + onCopy?: (status: UseClipboard["status"]) => void; + } +>; + +export type CopyButtonProps = CopyButtonPropsWithoutHTML & + WithoutChildren>; diff --git a/apps/docs/src/lib/components/ui/data-table/data-table.svelte.ts b/apps/docs/src/lib/components/ui/data-table/data-table.svelte.ts new file mode 100644 index 0000000..9e0b913 --- /dev/null +++ b/apps/docs/src/lib/components/ui/data-table/data-table.svelte.ts @@ -0,0 +1,141 @@ +import { + type RowData, + type TableOptions, + type TableOptionsResolved, + type TableState, + createTable, +} from "@tanstack/table-core"; + +/** + * Creates a reactive TanStack table object for Svelte. + * @param options Table options to create the table with. + * @returns A reactive table object. + * @example + * ```svelte + * + * + * + * + * {#each table.getHeaderGroups() as headerGroup} + * + * {#each headerGroup.headers as header} + * + * {/each} + * + * {/each} + * + * + *
    + * + *
    + * ``` + */ +export function createSvelteTable(options: TableOptions) { + const resolvedOptions: TableOptionsResolved = mergeObjects( + { + state: {}, + onStateChange() {}, + renderFallbackValue: null, + mergeOptions: ( + defaultOptions: TableOptions, + options: Partial> + ) => { + return mergeObjects(defaultOptions, options); + }, + }, + options + ); + + const table = createTable(resolvedOptions); + let state = $state>(table.initialState); + + function updateOptions() { + table.setOptions((prev) => { + return mergeObjects(prev, options, { + state: mergeObjects(state, options.state || {}), + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onStateChange: (updater: any) => { + if (updater instanceof Function) state = updater(state); + else state = mergeObjects(state, updater); + + options.onStateChange?.(updater); + }, + }); + }); + } + + updateOptions(); + + $effect.pre(() => { + updateOptions(); + }); + + return table; +} + +type MaybeThunk = T | (() => T | null | undefined); +type Intersection = (T extends [infer H, ...infer R] + ? H & Intersection + : unknown) & {}; + +/** + * Lazily merges several objects (or thunks) while preserving + * getter semantics from every source. + * + * Proxy-based to avoid known WebKit recursion issue. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function mergeObjects[]>( + ...sources: Sources +): Intersection<{ [K in keyof Sources]: Sources[K] }> { + const resolve = (src: MaybeThunk): T | undefined => + typeof src === "function" ? (src() ?? undefined) : src; + + const findSourceWithKey = (key: PropertyKey) => { + for (let i = sources.length - 1; i >= 0; i--) { + const obj = resolve(sources[i]); + if (obj && key in obj) return obj; + } + return undefined; + }; + + return new Proxy(Object.create(null), { + get(_, key) { + const src = findSourceWithKey(key); + + return src?.[key as never]; + }, + + has(_, key) { + return !!findSourceWithKey(key); + }, + + ownKeys(): (string | symbol)[] { + const all = new Set(); + for (const s of sources) { + const obj = resolve(s); + if (obj) { + for (const k of Reflect.ownKeys(obj) as (string | symbol)[]) { + all.add(k); + } + } + } + return [...all]; + }, + + getOwnPropertyDescriptor(_, key) { + const src = findSourceWithKey(key); + if (!src) return undefined; + return { + configurable: true, + enumerable: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: (src as any)[key], + writable: true, + }; + }, + }) as Intersection<{ [K in keyof Sources]: Sources[K] }>; +} diff --git a/apps/docs/src/lib/components/ui/data-table/flex-render.svelte b/apps/docs/src/lib/components/ui/data-table/flex-render.svelte new file mode 100644 index 0000000..12d2af1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/data-table/flex-render.svelte @@ -0,0 +1,36 @@ + + +{#if typeof content === "string"} + {content} +{:else if content instanceof Function} + + + {@const result = content(context as any)} + {#if result instanceof RenderComponentConfig} + {@const { component: Component, props } = result} + + {:else if result instanceof RenderSnippetConfig} + {@const { snippet, params } = result} + {@render snippet(params)} + {:else} + {result} + {/if} +{/if} diff --git a/apps/docs/src/lib/components/ui/data-table/index.ts b/apps/docs/src/lib/components/ui/data-table/index.ts new file mode 100644 index 0000000..5f4e77e --- /dev/null +++ b/apps/docs/src/lib/components/ui/data-table/index.ts @@ -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"; diff --git a/apps/docs/src/lib/components/ui/data-table/render-helpers.ts b/apps/docs/src/lib/components/ui/data-table/render-helpers.ts new file mode 100644 index 0000000..fa036d6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/data-table/render-helpers.ts @@ -0,0 +1,111 @@ +import type { Component, ComponentProps, Snippet } from "svelte"; + +/** + * A helper class to make it easy to identify Svelte components in + * `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderComponentConfig} + * {@const { component: Component, props } = result} + * + * {/if} + * ``` + */ +export class RenderComponentConfig { + component: TComponent; + props: ComponentProps | Record; + constructor( + component: TComponent, + props: ComponentProps | Record = {} + ) { + this.component = component; + this.props = props; + } +} + +/** + * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderSnippetConfig} + * {@const { snippet, params } = result} + * {@render snippet(params)} + * {/if} + * ``` + */ +export class RenderSnippetConfig { + snippet: Snippet<[TProps]>; + params: TProps; + constructor(snippet: Snippet<[TProps]>, params: TProps) { + this.snippet = snippet; + this.params = params; + } +} + +/** + * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. + * + * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. + * + * @param component A Svelte component + * @param props The props to pass to `component` + * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * header: header => renderComponent(SortHeader, { label: 'Name', header }), + * }), + * columnHelper.accessor('state', { + * header: header => renderComponent(SortHeader, { label: 'State', header }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderComponent< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends Component, + Props extends ComponentProps, +>(component: T, props: Props = {} as Props) { + return new RenderComponentConfig(component, props); +} + +/** + * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. + * + * The snippet must only take one parameter. + * + * This is only to be used with Snippets - use `renderComponent` for Svelte Components. + * + * @param snippet + * @param params + * @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), + * }), + * columnHelper.accessor('state', { + * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderSnippet(snippet: Snippet<[TProps]>, params: TProps = {} as TProps) { + return new RenderSnippetConfig(snippet, params); +} diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-close.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..840b2f6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-content.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..a647d56 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,43 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + + Close + + {/if} + + diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-description.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..3845023 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-footer.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..e7ff446 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-header.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..fc90cd9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-overlay.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..f81ad83 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-title.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..067e55e --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dialog/dialog-trigger.svelte b/apps/docs/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..9d1e801 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dialog/index.ts b/apps/docs/src/lib/components/ui/dialog/index.ts new file mode 100644 index 0000000..dce1d9d --- /dev/null +++ b/apps/docs/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,37 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +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"; + +const Root = DialogPrimitive.Root; +const Portal = DialogPrimitive.Portal; + +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, +}; diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-close.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-close.svelte new file mode 100644 index 0000000..95c2479 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-content.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-content.svelte new file mode 100644 index 0000000..f20e9ff --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-content.svelte @@ -0,0 +1,37 @@ + + + + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-description.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-description.svelte new file mode 100644 index 0000000..2763a1a --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-footer.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-footer.svelte new file mode 100644 index 0000000..1691f58 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-header.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-header.svelte new file mode 100644 index 0000000..65d2de5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-nested.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-nested.svelte new file mode 100644 index 0000000..834af94 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-nested.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-overlay.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-overlay.svelte new file mode 100644 index 0000000..53f78a2 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-title.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-title.svelte new file mode 100644 index 0000000..a2e5761 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer-trigger.svelte b/apps/docs/src/lib/components/ui/drawer/drawer-trigger.svelte new file mode 100644 index 0000000..f1877d8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/drawer.svelte b/apps/docs/src/lib/components/ui/drawer/drawer.svelte new file mode 100644 index 0000000..0cb57ff --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/drawer.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/drawer/index.ts b/apps/docs/src/lib/components/ui/drawer/index.ts new file mode 100644 index 0000000..cfbdb8b --- /dev/null +++ b/apps/docs/src/lib/components/ui/drawer/index.ts @@ -0,0 +1,41 @@ +import { Drawer as DrawerPrimitive } from "vaul-svelte"; + +import Root from "./drawer.svelte"; +import Content from "./drawer-content.svelte"; +import Description from "./drawer-description.svelte"; +import Overlay from "./drawer-overlay.svelte"; +import Footer from "./drawer-footer.svelte"; +import Header from "./drawer-header.svelte"; +import Title from "./drawer-title.svelte"; +import NestedRoot from "./drawer-nested.svelte"; +import Close from "./drawer-close.svelte"; +import Trigger from "./drawer-trigger.svelte"; + +const Portal: typeof DrawerPrimitive.Portal = DrawerPrimitive.Portal; + +export { + Root, + NestedRoot, + Content, + Description, + Overlay, + Footer, + Header, + Title, + Trigger, + Portal, + Close, + + // + Root as Drawer, + NestedRoot as DrawerNestedRoot, + Content as DrawerContent, + Description as DrawerDescription, + Overlay as DrawerOverlay, + Footer as DrawerFooter, + Header as DrawerHeader, + Title as DrawerTitle, + Trigger as DrawerTrigger, + Portal as DrawerPortal, + Close as DrawerClose, +}; diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..e03f949 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..907ef73 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,27 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..48d14a9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..aca1f7b --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..64bb283 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..f72e477 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..189aef4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..513170a --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..90f1b6f --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..6974947 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..10e14ca --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..f9b286a --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..cb05344 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/dropdown-menu/index.ts b/apps/docs/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..1cf9f70 --- /dev/null +++ b/apps/docs/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,49 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +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"; +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + 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, +}; diff --git a/apps/docs/src/lib/components/ui/form/form-button.svelte b/apps/docs/src/lib/components/ui/form/form-button.svelte new file mode 100644 index 0000000..cc0c590 --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-button.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/form/form-description.svelte b/apps/docs/src/lib/components/ui/form/form-description.svelte new file mode 100644 index 0000000..a5f42be --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/form/form-element-field.svelte b/apps/docs/src/lib/components/ui/form/form-element-field.svelte new file mode 100644 index 0000000..c3ba111 --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-element-field.svelte @@ -0,0 +1,24 @@ + + + + {#snippet children({ constraints, errors, tainted, value })} +
    + {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })} +
    + {/snippet} +
    diff --git a/apps/docs/src/lib/components/ui/form/form-field-errors.svelte b/apps/docs/src/lib/components/ui/form/form-field-errors.svelte new file mode 100644 index 0000000..b4c6fba --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-field-errors.svelte @@ -0,0 +1,30 @@ + + + + {#snippet children({ errors, errorProps })} + {#if childrenProp} + {@render childrenProp({ errors, errorProps })} + {:else} + {#each errors as error (error)} +
    {error}
    + {/each} + {/if} + {/snippet} +
    diff --git a/apps/docs/src/lib/components/ui/form/form-field.svelte b/apps/docs/src/lib/components/ui/form/form-field.svelte new file mode 100644 index 0000000..7481fda --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-field.svelte @@ -0,0 +1,29 @@ + + + + {#snippet children({ constraints, errors, tainted, value })} +
    + {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })} +
    + {/snippet} +
    diff --git a/apps/docs/src/lib/components/ui/form/form-fieldset.svelte b/apps/docs/src/lib/components/ui/form/form-fieldset.svelte new file mode 100644 index 0000000..2c85857 --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-fieldset.svelte @@ -0,0 +1,15 @@ + + + diff --git a/apps/docs/src/lib/components/ui/form/form-label.svelte b/apps/docs/src/lib/components/ui/form/form-label.svelte new file mode 100644 index 0000000..8749360 --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-label.svelte @@ -0,0 +1,24 @@ + + + + {#snippet child({ props })} + + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/form/form-legend.svelte b/apps/docs/src/lib/components/ui/form/form-legend.svelte new file mode 100644 index 0000000..9d52f6a --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/form-legend.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/form/index.ts b/apps/docs/src/lib/components/ui/form/index.ts new file mode 100644 index 0000000..0713927 --- /dev/null +++ b/apps/docs/src/lib/components/ui/form/index.ts @@ -0,0 +1,33 @@ +import * as FormPrimitive from "formsnap"; +import Description from "./form-description.svelte"; +import Label from "./form-label.svelte"; +import FieldErrors from "./form-field-errors.svelte"; +import Field from "./form-field.svelte"; +import Fieldset from "./form-fieldset.svelte"; +import Legend from "./form-legend.svelte"; +import ElementField from "./form-element-field.svelte"; +import Button from "./form-button.svelte"; + +const Control = FormPrimitive.Control; + +export { + Field, + Control, + Label, + Button, + FieldErrors, + Description, + Fieldset, + Legend, + ElementField, + // + Field as FormField, + Control as FormControl, + Description as FormDescription, + Label as FormLabel, + FieldErrors as FormFieldErrors, + Fieldset as FormFieldset, + Legend as FormLegend, + ElementField as FormElementField, + Button as FormButton, +}; diff --git a/apps/docs/src/lib/components/ui/hover-card/hover-card-content.svelte b/apps/docs/src/lib/components/ui/hover-card/hover-card-content.svelte new file mode 100644 index 0000000..e1d592a --- /dev/null +++ b/apps/docs/src/lib/components/ui/hover-card/hover-card-content.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/hover-card/hover-card-trigger.svelte b/apps/docs/src/lib/components/ui/hover-card/hover-card-trigger.svelte new file mode 100644 index 0000000..322172b --- /dev/null +++ b/apps/docs/src/lib/components/ui/hover-card/hover-card-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/hover-card/index.ts b/apps/docs/src/lib/components/ui/hover-card/index.ts new file mode 100644 index 0000000..85f3949 --- /dev/null +++ b/apps/docs/src/lib/components/ui/hover-card/index.ts @@ -0,0 +1,14 @@ +import { LinkPreview as HoverCardPrimitive } from "bits-ui"; +import Content from "./hover-card-content.svelte"; +import Trigger from "./hover-card-trigger.svelte"; + +const Root = HoverCardPrimitive.Root; + +export { + Root, + Content, + Trigger, + Root as HoverCard, + Content as HoverCardContent, + Trigger as HoverCardTrigger, +}; diff --git a/apps/docs/src/lib/components/ui/input-otp/index.ts b/apps/docs/src/lib/components/ui/input-otp/index.ts new file mode 100644 index 0000000..e9ae273 --- /dev/null +++ b/apps/docs/src/lib/components/ui/input-otp/index.ts @@ -0,0 +1,15 @@ +import Root from "./input-otp.svelte"; +import Group from "./input-otp-group.svelte"; +import Slot from "./input-otp-slot.svelte"; +import Separator from "./input-otp-separator.svelte"; + +export { + Root, + Group, + Slot, + Separator, + Root as InputOTP, + Group as InputOTPGroup, + Slot as InputOTPSlot, + Separator as InputOTPSeparator, +}; diff --git a/apps/docs/src/lib/components/ui/input-otp/input-otp-group.svelte b/apps/docs/src/lib/components/ui/input-otp/input-otp-group.svelte new file mode 100644 index 0000000..9b311bc --- /dev/null +++ b/apps/docs/src/lib/components/ui/input-otp/input-otp-group.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/input-otp/input-otp-separator.svelte b/apps/docs/src/lib/components/ui/input-otp/input-otp-separator.svelte new file mode 100644 index 0000000..3241295 --- /dev/null +++ b/apps/docs/src/lib/components/ui/input-otp/input-otp-separator.svelte @@ -0,0 +1,19 @@ + + +
    + {#if children} + {@render children?.()} + {:else} + + {/if} +
    diff --git a/apps/docs/src/lib/components/ui/input-otp/input-otp-slot.svelte b/apps/docs/src/lib/components/ui/input-otp/input-otp-slot.svelte new file mode 100644 index 0000000..34d2636 --- /dev/null +++ b/apps/docs/src/lib/components/ui/input-otp/input-otp-slot.svelte @@ -0,0 +1,31 @@ + + + + {cell.char} + {#if cell.hasFakeCaret} +
    + +
    + {/if} +
    diff --git a/apps/docs/src/lib/components/ui/input-otp/input-otp.svelte b/apps/docs/src/lib/components/ui/input-otp/input-otp.svelte new file mode 100644 index 0000000..e27cbcc --- /dev/null +++ b/apps/docs/src/lib/components/ui/input-otp/input-otp.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/input/index.ts b/apps/docs/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..f47b6d3 --- /dev/null +++ b/apps/docs/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; diff --git a/apps/docs/src/lib/components/ui/input/input.svelte b/apps/docs/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..19c6dae --- /dev/null +++ b/apps/docs/src/lib/components/ui/input/input.svelte @@ -0,0 +1,51 @@ + + +{#if type === "file"} + +{:else} + +{/if} diff --git a/apps/docs/src/lib/components/ui/label/index.ts b/apps/docs/src/lib/components/ui/label/index.ts new file mode 100644 index 0000000..8bfca0b --- /dev/null +++ b/apps/docs/src/lib/components/ui/label/index.ts @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; diff --git a/apps/docs/src/lib/components/ui/label/label.svelte b/apps/docs/src/lib/components/ui/label/label.svelte new file mode 100644 index 0000000..d0afda3 --- /dev/null +++ b/apps/docs/src/lib/components/ui/label/label.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/index.ts b/apps/docs/src/lib/components/ui/menubar/index.ts new file mode 100644 index 0000000..57a6cfb --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/index.ts @@ -0,0 +1,54 @@ +import { Menubar as MenubarPrimitive } from "bits-ui"; +import Root from "./menubar.svelte"; +import CheckboxItem from "./menubar-checkbox-item.svelte"; +import Content from "./menubar-content.svelte"; +import Item from "./menubar-item.svelte"; +import Group from "./menubar-group.svelte"; +import RadioItem from "./menubar-radio-item.svelte"; +import Separator from "./menubar-separator.svelte"; +import Shortcut from "./menubar-shortcut.svelte"; +import SubContent from "./menubar-sub-content.svelte"; +import SubTrigger from "./menubar-sub-trigger.svelte"; +import Trigger from "./menubar-trigger.svelte"; +import Label from "./menubar-label.svelte"; +import GroupHeading from "./menubar-group-heading.svelte"; + +const Menu = MenubarPrimitive.Menu; +const Sub = MenubarPrimitive.Sub; +const RadioGroup = MenubarPrimitive.RadioGroup; + +export { + Root, + CheckboxItem, + Content, + Item, + RadioItem, + Separator, + Shortcut, + SubContent, + SubTrigger, + Trigger, + Menu, + Group, + Sub, + RadioGroup, + Label, + GroupHeading, + // + Root as Menubar, + CheckboxItem as MenubarCheckboxItem, + Content as MenubarContent, + Item as MenubarItem, + RadioItem as MenubarRadioItem, + Separator as MenubarSeparator, + Shortcut as MenubarShortcut, + SubContent as MenubarSubContent, + SubTrigger as MenubarSubTrigger, + Trigger as MenubarTrigger, + Menu as MenubarMenu, + Group as MenubarGroup, + Sub as MenubarSub, + RadioGroup as MenubarRadioGroup, + Label as MenubarLabel, + GroupHeading as MenubarGroupHeading, +}; diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-checkbox-item.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-checkbox-item.svelte new file mode 100644 index 0000000..012d68b --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-content.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-content.svelte new file mode 100644 index 0000000..d193622 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-content.svelte @@ -0,0 +1,33 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-group-heading.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-group-heading.svelte new file mode 100644 index 0000000..024e742 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-group.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-group.svelte new file mode 100644 index 0000000..f75b75a --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-group.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-item.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-item.svelte new file mode 100644 index 0000000..8c20d42 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-label.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-label.svelte new file mode 100644 index 0000000..1b36f6c --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-label.svelte @@ -0,0 +1,25 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-radio-item.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-radio-item.svelte new file mode 100644 index 0000000..3da12d4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-separator.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-separator.svelte new file mode 100644 index 0000000..a2caf6e --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-shortcut.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-shortcut.svelte new file mode 100644 index 0000000..0e08313 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-sub-content.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-sub-content.svelte new file mode 100644 index 0000000..cb4d04c --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-sub-trigger.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-sub-trigger.svelte new file mode 100644 index 0000000..4f9f28a --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar-trigger.svelte b/apps/docs/src/lib/components/ui/menubar/menubar-trigger.svelte new file mode 100644 index 0000000..1c3dd6a --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar-trigger.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/menubar/menubar.svelte b/apps/docs/src/lib/components/ui/menubar/menubar.svelte new file mode 100644 index 0000000..37e0206 --- /dev/null +++ b/apps/docs/src/lib/components/ui/menubar/menubar.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/index.ts b/apps/docs/src/lib/components/ui/navigation-menu/index.ts new file mode 100644 index 0000000..bbc250f --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/index.ts @@ -0,0 +1,28 @@ +import Root from "./navigation-menu.svelte"; +import Content from "./navigation-menu-content.svelte"; +import Indicator from "./navigation-menu-indicator.svelte"; +import Item from "./navigation-menu-item.svelte"; +import Link from "./navigation-menu-link.svelte"; +import List from "./navigation-menu-list.svelte"; +import Trigger from "./navigation-menu-trigger.svelte"; +import Viewport from "./navigation-menu-viewport.svelte"; + +export { + Root, + Content, + Indicator, + Item, + Link, + List, + Trigger, + Viewport, + // + Root as NavigationMenuRoot, + Content as NavigationMenuContent, + Indicator as NavigationMenuIndicator, + Item as NavigationMenuItem, + Link as NavigationMenuLink, + List as NavigationMenuList, + Trigger as NavigationMenuTrigger, + Viewport as NavigationMenuViewport, +}; diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte new file mode 100644 index 0000000..9dbdb36 --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte new file mode 100644 index 0000000..6c9bdfd --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte @@ -0,0 +1,22 @@ + + + +
    +
    diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte new file mode 100644 index 0000000..b00b4b4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte new file mode 100644 index 0000000..867851e --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte new file mode 100644 index 0000000..c2c5880 --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte new file mode 100644 index 0000000..aad82a2 --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte @@ -0,0 +1,34 @@ + + + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte new file mode 100644 index 0000000..655741d --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte @@ -0,0 +1,22 @@ + + +
    + +
    diff --git a/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu.svelte b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu.svelte new file mode 100644 index 0000000..69c3d13 --- /dev/null +++ b/apps/docs/src/lib/components/ui/navigation-menu/navigation-menu.svelte @@ -0,0 +1,32 @@ + + + + {@render children?.()} + + {#if viewport} + + {/if} + diff --git a/apps/docs/src/lib/components/ui/pagination/index.ts b/apps/docs/src/lib/components/ui/pagination/index.ts new file mode 100644 index 0000000..d83c7a9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/index.ts @@ -0,0 +1,25 @@ +import Root from "./pagination.svelte"; +import Content from "./pagination-content.svelte"; +import Item from "./pagination-item.svelte"; +import Link from "./pagination-link.svelte"; +import PrevButton from "./pagination-prev-button.svelte"; +import NextButton from "./pagination-next-button.svelte"; +import Ellipsis from "./pagination-ellipsis.svelte"; + +export { + Root, + Content, + Item, + Link, + PrevButton, + NextButton, + Ellipsis, + // + Root as Pagination, + Content as PaginationContent, + Item as PaginationItem, + Link as PaginationLink, + PrevButton as PaginationPrevButton, + NextButton as PaginationNextButton, + Ellipsis as PaginationEllipsis, +}; diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-content.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-content.svelte new file mode 100644 index 0000000..e1124fc --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-content.svelte @@ -0,0 +1,20 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-ellipsis.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-ellipsis.svelte new file mode 100644 index 0000000..3be94c9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-ellipsis.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-item.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-item.svelte new file mode 100644 index 0000000..fd7ffc3 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-item.svelte @@ -0,0 +1,14 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-link.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-link.svelte new file mode 100644 index 0000000..58b1a5c --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-link.svelte @@ -0,0 +1,39 @@ + + +{#snippet Fallback()} + {page.value} +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-next-button.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-next-button.svelte new file mode 100644 index 0000000..d4b9553 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-next-button.svelte @@ -0,0 +1,33 @@ + + +{#snippet Fallback()} + Next + +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/pagination/pagination-prev-button.svelte b/apps/docs/src/lib/components/ui/pagination/pagination-prev-button.svelte new file mode 100644 index 0000000..2d3dc70 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination-prev-button.svelte @@ -0,0 +1,33 @@ + + +{#snippet Fallback()} + + Previous +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/pagination/pagination.svelte b/apps/docs/src/lib/components/ui/pagination/pagination.svelte new file mode 100644 index 0000000..60e3471 --- /dev/null +++ b/apps/docs/src/lib/components/ui/pagination/pagination.svelte @@ -0,0 +1,28 @@ + + + diff --git a/apps/docs/src/lib/components/ui/popover/index.ts b/apps/docs/src/lib/components/ui/popover/index.ts new file mode 100644 index 0000000..9f30922 --- /dev/null +++ b/apps/docs/src/lib/components/ui/popover/index.ts @@ -0,0 +1,17 @@ +import { Popover as PopoverPrimitive } from "bits-ui"; +import Content from "./popover-content.svelte"; +import Trigger from "./popover-trigger.svelte"; +const Root = PopoverPrimitive.Root; +const Close = PopoverPrimitive.Close; + +export { + Root, + Content, + Trigger, + Close, + // + Root as Popover, + Content as PopoverContent, + Trigger as PopoverTrigger, + Close as PopoverClose, +}; diff --git a/apps/docs/src/lib/components/ui/popover/popover-content.svelte b/apps/docs/src/lib/components/ui/popover/popover-content.svelte new file mode 100644 index 0000000..9bced7a --- /dev/null +++ b/apps/docs/src/lib/components/ui/popover/popover-content.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/popover/popover-trigger.svelte b/apps/docs/src/lib/components/ui/popover/popover-trigger.svelte new file mode 100644 index 0000000..586323c --- /dev/null +++ b/apps/docs/src/lib/components/ui/popover/popover-trigger.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/progress/index.ts b/apps/docs/src/lib/components/ui/progress/index.ts new file mode 100644 index 0000000..25eee61 --- /dev/null +++ b/apps/docs/src/lib/components/ui/progress/index.ts @@ -0,0 +1,7 @@ +import Root from "./progress.svelte"; + +export { + Root, + // + Root as Progress, +}; diff --git a/apps/docs/src/lib/components/ui/progress/progress.svelte b/apps/docs/src/lib/components/ui/progress/progress.svelte new file mode 100644 index 0000000..6833013 --- /dev/null +++ b/apps/docs/src/lib/components/ui/progress/progress.svelte @@ -0,0 +1,27 @@ + + + +
    +
    diff --git a/apps/docs/src/lib/components/ui/radio-group/index.ts b/apps/docs/src/lib/components/ui/radio-group/index.ts new file mode 100644 index 0000000..90b33fe --- /dev/null +++ b/apps/docs/src/lib/components/ui/radio-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./radio-group.svelte"; +import Item from "./radio-group-item.svelte"; + +export { + Root, + Item, + // + Root as RadioGroup, + Item as RadioGroupItem, +}; diff --git a/apps/docs/src/lib/components/ui/radio-group/radio-group-item.svelte b/apps/docs/src/lib/components/ui/radio-group/radio-group-item.svelte new file mode 100644 index 0000000..2cb0710 --- /dev/null +++ b/apps/docs/src/lib/components/ui/radio-group/radio-group-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} +
    + {#if checked} + + {/if} +
    + {/snippet} +
    diff --git a/apps/docs/src/lib/components/ui/radio-group/radio-group.svelte b/apps/docs/src/lib/components/ui/radio-group/radio-group.svelte new file mode 100644 index 0000000..da2912b --- /dev/null +++ b/apps/docs/src/lib/components/ui/radio-group/radio-group.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/index.ts b/apps/docs/src/lib/components/ui/range-calendar/index.ts new file mode 100644 index 0000000..262c49a --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/index.ts @@ -0,0 +1,42 @@ +import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui"; +import Root from "./range-calendar.svelte"; +import Cell from "./range-calendar-cell.svelte"; +import Day from "./range-calendar-day.svelte"; +import Grid from "./range-calendar-grid.svelte"; +import Header from "./range-calendar-header.svelte"; +import Months from "./range-calendar-months.svelte"; +import GridRow from "./range-calendar-grid-row.svelte"; +import Heading from "./range-calendar-heading.svelte"; +import HeadCell from "./range-calendar-head-cell.svelte"; +import NextButton from "./range-calendar-next-button.svelte"; +import PrevButton from "./range-calendar-prev-button.svelte"; +import MonthSelect from "./range-calendar-month-select.svelte"; +import YearSelect from "./range-calendar-year-select.svelte"; +import Caption from "./range-calendar-caption.svelte"; +import Nav from "./range-calendar-nav.svelte"; +import Month from "./range-calendar-month.svelte"; + +const GridHead = RangeCalendarPrimitive.GridHead; +const GridBody = RangeCalendarPrimitive.GridBody; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + MonthSelect, + YearSelect, + Caption, + Nav, + Month, + // + Root as RangeCalendar, +}; diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-caption.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-caption.svelte new file mode 100644 index 0000000..944654d --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-caption.svelte @@ -0,0 +1,76 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-cell.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-cell.svelte new file mode 100644 index 0000000..e658dbe --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-day.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-day.svelte new file mode 100644 index 0000000..5599ca0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-day.svelte @@ -0,0 +1,39 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte new file mode 100644 index 0000000..3286b2a --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid.svelte new file mode 100644 index 0000000..3d74b2f --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-grid.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte new file mode 100644 index 0000000..93a60c0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-header.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-header.svelte new file mode 100644 index 0000000..d113697 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-header.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-heading.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-heading.svelte new file mode 100644 index 0000000..3b3325f --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte new file mode 100644 index 0000000..5abd36d --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month.svelte new file mode 100644 index 0000000..e747fae --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-month.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-months.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-months.svelte new file mode 100644 index 0000000..f717a9d --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-months.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-nav.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-nav.svelte new file mode 100644 index 0000000..27f33d7 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-nav.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte new file mode 100644 index 0000000..d1158b8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte new file mode 100644 index 0000000..d711db1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte new file mode 100644 index 0000000..75cb0af --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte @@ -0,0 +1,43 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + diff --git a/apps/docs/src/lib/components/ui/range-calendar/range-calendar.svelte b/apps/docs/src/lib/components/ui/range-calendar/range-calendar.svelte new file mode 100644 index 0000000..4d917a6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/range-calendar/range-calendar.svelte @@ -0,0 +1,112 @@ + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + + {#each weekdays as weekday (weekday)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/resizable/index.ts b/apps/docs/src/lib/components/ui/resizable/index.ts new file mode 100644 index 0000000..2e37f11 --- /dev/null +++ b/apps/docs/src/lib/components/ui/resizable/index.ts @@ -0,0 +1,13 @@ +import { Pane } from "paneforge"; +import Handle from "./resizable-handle.svelte"; +import PaneGroup from "./resizable-pane-group.svelte"; + +export { + PaneGroup, + Pane, + Handle, + // + PaneGroup as ResizablePaneGroup, + Pane as ResizablePane, + Handle as ResizableHandle, +}; diff --git a/apps/docs/src/lib/components/ui/resizable/resizable-handle.svelte b/apps/docs/src/lib/components/ui/resizable/resizable-handle.svelte new file mode 100644 index 0000000..9c8da71 --- /dev/null +++ b/apps/docs/src/lib/components/ui/resizable/resizable-handle.svelte @@ -0,0 +1,30 @@ + + +div]:rotate-90", + className + )} + {...restProps} +> + {#if withHandle} +
    + +
    + {/if} +
    diff --git a/apps/docs/src/lib/components/ui/resizable/resizable-pane-group.svelte b/apps/docs/src/lib/components/ui/resizable/resizable-pane-group.svelte new file mode 100644 index 0000000..a810d7e --- /dev/null +++ b/apps/docs/src/lib/components/ui/resizable/resizable-pane-group.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/scroll-area/index.ts b/apps/docs/src/lib/components/ui/scroll-area/index.ts new file mode 100644 index 0000000..e86a25b --- /dev/null +++ b/apps/docs/src/lib/components/ui/scroll-area/index.ts @@ -0,0 +1,10 @@ +import Scrollbar from "./scroll-area-scrollbar.svelte"; +import Root from "./scroll-area.svelte"; + +export { + Root, + Scrollbar, + //, + Root as ScrollArea, + Scrollbar as ScrollAreaScrollbar, +}; diff --git a/apps/docs/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte b/apps/docs/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte new file mode 100644 index 0000000..4127444 --- /dev/null +++ b/apps/docs/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte @@ -0,0 +1,31 @@ + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/scroll-area/scroll-area.svelte b/apps/docs/src/lib/components/ui/scroll-area/scroll-area.svelte new file mode 100644 index 0000000..38a1847 --- /dev/null +++ b/apps/docs/src/lib/components/ui/scroll-area/scroll-area.svelte @@ -0,0 +1,40 @@ + + + + + {@render children?.()} + + {#if orientation === "vertical" || orientation === "both"} + + {/if} + {#if orientation === "horizontal" || orientation === "both"} + + {/if} + + diff --git a/apps/docs/src/lib/components/ui/select/index.ts b/apps/docs/src/lib/components/ui/select/index.ts new file mode 100644 index 0000000..9e8d3e9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/index.ts @@ -0,0 +1,37 @@ +import { Select as SelectPrimitive } from "bits-ui"; + +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"; + +const Root = SelectPrimitive.Root; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + // + 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, +}; diff --git a/apps/docs/src/lib/components/ui/select/select-content.svelte b/apps/docs/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..dc16d65 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,40 @@ + + + + + + + {@render children?.()} + + + + diff --git a/apps/docs/src/lib/components/ui/select/select-group-heading.svelte b/apps/docs/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..1fab5f0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/select/select-group.svelte b/apps/docs/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 0000000..5454fdb --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/select/select-item.svelte b/apps/docs/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..49dbbd7 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/select/select-label.svelte b/apps/docs/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 0000000..4696025 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/select/select-scroll-down-button.svelte b/apps/docs/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..3629205 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/select/select-scroll-up-button.svelte b/apps/docs/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..1aa2300 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/select/select-separator.svelte b/apps/docs/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..0eac3eb --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/docs/src/lib/components/ui/select/select-trigger.svelte b/apps/docs/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..d405187 --- /dev/null +++ b/apps/docs/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/docs/src/lib/components/ui/separator/index.ts b/apps/docs/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..82442d2 --- /dev/null +++ b/apps/docs/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/apps/docs/src/lib/components/ui/separator/separator.svelte b/apps/docs/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..09d88f4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sheet/index.ts b/apps/docs/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..01d40c8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,36 @@ +import { Dialog as SheetPrimitive } from "bits-ui"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +const Root = SheetPrimitive.Root; +const Portal = SheetPrimitive.Portal; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-close.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 0000000..ae382c1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-content.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..856922e --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,58 @@ + + + + + + + + {@render children?.()} + + + Close + + + diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-description.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..333b17a --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-footer.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..dd9ed84 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-header.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..757a6a5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-overlay.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..345e197 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-title.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..9fda327 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sheet/sheet-trigger.svelte b/apps/docs/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 0000000..e266975 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sidebar/constants.ts b/apps/docs/src/lib/components/ui/sidebar/constants.ts new file mode 100644 index 0000000..4de4435 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/constants.ts @@ -0,0 +1,6 @@ +export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; diff --git a/apps/docs/src/lib/components/ui/sidebar/context.svelte.ts b/apps/docs/src/lib/components/ui/sidebar/context.svelte.ts new file mode 100644 index 0000000..15248ad --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/context.svelte.ts @@ -0,0 +1,81 @@ +import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; +import { getContext, setContext } from "svelte"; +import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; + +type Getter = () => T; + +export type SidebarStateProps = { + /** + * A getter function that returns the current open state of the sidebar. + * We use a getter function here to support `bind:open` on the `Sidebar.Provider` + * component. + */ + open: Getter; + + /** + * A function that sets the open state of the sidebar. To support `bind:open`, we need + * a source of truth for changing the open state to ensure it will be synced throughout + * the sub-components and any `bind:` references. + */ + setOpen: (open: boolean) => void; +}; + +class SidebarState { + readonly props: SidebarStateProps; + open = $derived.by(() => this.props.open()); + openMobile = $state(false); + setOpen: SidebarStateProps["setOpen"]; + #isMobile: IsMobile; + state = $derived.by(() => (this.open ? "expanded" : "collapsed")); + + constructor(props: SidebarStateProps) { + this.setOpen = props.setOpen; + this.#isMobile = new IsMobile(); + this.props = props; + } + + // Convenience getter for checking if the sidebar is mobile + // without this, we would need to use `sidebar.isMobile.current` everywhere + get isMobile() { + return this.#isMobile.current; + } + + // Event handler to apply to the `` + handleShortcutKeydown = (e: KeyboardEvent) => { + if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + this.toggle(); + } + }; + + setOpenMobile = (value: boolean) => { + this.openMobile = value; + }; + + toggle = () => { + return this.#isMobile.current + ? (this.openMobile = !this.openMobile) + : this.setOpen(!this.open); + }; +} + +const SYMBOL_KEY = "scn-sidebar"; + +/** + * Instantiates a new `SidebarState` instance and sets it in the context. + * + * @param props The constructor props for the `SidebarState` class. + * @returns The `SidebarState` instance. + */ +export function setSidebar(props: SidebarStateProps): SidebarState { + return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); +} + +/** + * Retrieves the `SidebarState` instance from the context. This is a class instance, + * so you cannot destructure it. + * @returns The `SidebarState` instance. + */ +export function useSidebar(): SidebarState { + return getContext(Symbol.for(SYMBOL_KEY)); +} diff --git a/apps/docs/src/lib/components/ui/sidebar/index.ts b/apps/docs/src/lib/components/ui/sidebar/index.ts new file mode 100644 index 0000000..318a341 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/index.ts @@ -0,0 +1,75 @@ +import { useSidebar } from "./context.svelte.js"; +import Content from "./sidebar-content.svelte"; +import Footer from "./sidebar-footer.svelte"; +import GroupAction from "./sidebar-group-action.svelte"; +import GroupContent from "./sidebar-group-content.svelte"; +import GroupLabel from "./sidebar-group-label.svelte"; +import Group from "./sidebar-group.svelte"; +import Header from "./sidebar-header.svelte"; +import Input from "./sidebar-input.svelte"; +import Inset from "./sidebar-inset.svelte"; +import MenuAction from "./sidebar-menu-action.svelte"; +import MenuBadge from "./sidebar-menu-badge.svelte"; +import MenuButton from "./sidebar-menu-button.svelte"; +import MenuItem from "./sidebar-menu-item.svelte"; +import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; +import MenuSubButton from "./sidebar-menu-sub-button.svelte"; +import MenuSubItem from "./sidebar-menu-sub-item.svelte"; +import MenuSub from "./sidebar-menu-sub.svelte"; +import Menu from "./sidebar-menu.svelte"; +import Provider from "./sidebar-provider.svelte"; +import Rail from "./sidebar-rail.svelte"; +import Separator from "./sidebar-separator.svelte"; +import Trigger from "./sidebar-trigger.svelte"; +import Root from "./sidebar.svelte"; + +export { + Content, + Footer, + Group, + GroupAction, + GroupContent, + GroupLabel, + Header, + Input, + Inset, + Menu, + MenuAction, + MenuBadge, + MenuButton, + MenuItem, + MenuSkeleton, + MenuSub, + MenuSubButton, + MenuSubItem, + Provider, + Rail, + Root, + Separator, + // + Root as Sidebar, + Content as SidebarContent, + Footer as SidebarFooter, + Group as SidebarGroup, + GroupAction as SidebarGroupAction, + GroupContent as SidebarGroupContent, + GroupLabel as SidebarGroupLabel, + Header as SidebarHeader, + Input as SidebarInput, + Inset as SidebarInset, + Menu as SidebarMenu, + MenuAction as SidebarMenuAction, + MenuBadge as SidebarMenuBadge, + MenuButton as SidebarMenuButton, + MenuItem as SidebarMenuItem, + MenuSkeleton as SidebarMenuSkeleton, + MenuSub as SidebarMenuSub, + MenuSubButton as SidebarMenuSubButton, + MenuSubItem as SidebarMenuSubItem, + Provider as SidebarProvider, + Rail as SidebarRail, + Separator as SidebarSeparator, + Trigger as SidebarTrigger, + Trigger, + useSidebar, +}; diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-content.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-content.svelte new file mode 100644 index 0000000..f121800 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-content.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-footer.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-footer.svelte new file mode 100644 index 0000000..6259cb9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-footer.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-action.svelte new file mode 100644 index 0000000..fb84e4a --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-action.svelte @@ -0,0 +1,36 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-content.svelte new file mode 100644 index 0000000..415255f --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-content.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-label.svelte new file mode 100644 index 0000000..e292945 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-group-label.svelte @@ -0,0 +1,34 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-group.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-group.svelte new file mode 100644 index 0000000..ec18a69 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-group.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-header.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-header.svelte new file mode 100644 index 0000000..a1b2db1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-header.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-input.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-input.svelte new file mode 100644 index 0000000..19b3666 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-input.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-inset.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-inset.svelte new file mode 100644 index 0000000..d862761 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-action.svelte new file mode 100644 index 0000000..fa3fb0c --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-action.svelte @@ -0,0 +1,43 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte new file mode 100644 index 0000000..69e5a3c --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte @@ -0,0 +1,29 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-button.svelte new file mode 100644 index 0000000..4bef683 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-button.svelte @@ -0,0 +1,103 @@ + + + + +{#snippet Button({ props }: { props?: Record })} + {@const mergedProps = mergeProps(buttonProps, props)} + {#if child} + {@render child({ props: mergedProps })} + {:else} + + {/if} +{/snippet} + +{#if !tooltipContent} + {@render Button({})} +{:else} + + + {#snippet child({ props })} + {@render Button({ props })} + {/snippet} + + + +{/if} diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-item.svelte new file mode 100644 index 0000000..4db4453 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte new file mode 100644 index 0000000..cc63b04 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte @@ -0,0 +1,36 @@ + + +
    + {#if showIcon} + + {/if} + + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte new file mode 100644 index 0000000..987f104 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte @@ -0,0 +1,43 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + + {@render children?.()} + +{/if} diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte new file mode 100644 index 0000000..681d0f1 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte new file mode 100644 index 0000000..8ab1111 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte @@ -0,0 +1,25 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-menu.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu.svelte new file mode 100644 index 0000000..946ccce --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-menu.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-provider.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-provider.svelte new file mode 100644 index 0000000..5b0d0aa --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -0,0 +1,53 @@ + + + + + +
    + {@render children?.()} +
    +
    diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-rail.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-rail.svelte new file mode 100644 index 0000000..c180cf5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-rail.svelte @@ -0,0 +1,36 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-separator.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-separator.svelte new file mode 100644 index 0000000..5a7deda --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-separator.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar-trigger.svelte new file mode 100644 index 0000000..1825182 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar-trigger.svelte @@ -0,0 +1,35 @@ + + + diff --git a/apps/docs/src/lib/components/ui/sidebar/sidebar.svelte b/apps/docs/src/lib/components/ui/sidebar/sidebar.svelte new file mode 100644 index 0000000..3e9eba9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/sidebar/sidebar.svelte @@ -0,0 +1,104 @@ + + +{#if collapsible === "none"} +
    + {@render children?.()} +
    +{:else if sidebar.isMobile} + sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} + {...restProps} + > + + + Sidebar + Displays the mobile sidebar. + +
    + {@render children?.()} +
    +
    +
    +{:else} + +{/if} diff --git a/apps/docs/src/lib/components/ui/skeleton/index.ts b/apps/docs/src/lib/components/ui/skeleton/index.ts new file mode 100644 index 0000000..186db21 --- /dev/null +++ b/apps/docs/src/lib/components/ui/skeleton/index.ts @@ -0,0 +1,7 @@ +import Root from "./skeleton.svelte"; + +export { + Root, + // + Root as Skeleton, +}; diff --git a/apps/docs/src/lib/components/ui/skeleton/skeleton.svelte b/apps/docs/src/lib/components/ui/skeleton/skeleton.svelte new file mode 100644 index 0000000..c7e3d26 --- /dev/null +++ b/apps/docs/src/lib/components/ui/skeleton/skeleton.svelte @@ -0,0 +1,17 @@ + + +
    diff --git a/apps/docs/src/lib/components/ui/slider/index.ts b/apps/docs/src/lib/components/ui/slider/index.ts new file mode 100644 index 0000000..820f209 --- /dev/null +++ b/apps/docs/src/lib/components/ui/slider/index.ts @@ -0,0 +1,7 @@ +import Root from "./slider.svelte"; + +export { + Root, + // + Root as Slider, +}; diff --git a/apps/docs/src/lib/components/ui/slider/slider.svelte b/apps/docs/src/lib/components/ui/slider/slider.svelte new file mode 100644 index 0000000..b06e110 --- /dev/null +++ b/apps/docs/src/lib/components/ui/slider/slider.svelte @@ -0,0 +1,52 @@ + + + + + {#snippet children({ thumbs })} + + + + {#each thumbs as thumb (thumb)} + + {/each} + {/snippet} + diff --git a/apps/docs/src/lib/components/ui/sonner/index.ts b/apps/docs/src/lib/components/ui/sonner/index.ts new file mode 100644 index 0000000..1ad9f4a --- /dev/null +++ b/apps/docs/src/lib/components/ui/sonner/index.ts @@ -0,0 +1 @@ +export { default as Toaster } from "./sonner.svelte"; diff --git a/apps/docs/src/lib/components/ui/sonner/sonner.svelte b/apps/docs/src/lib/components/ui/sonner/sonner.svelte new file mode 100644 index 0000000..1f50e1e --- /dev/null +++ b/apps/docs/src/lib/components/ui/sonner/sonner.svelte @@ -0,0 +1,13 @@ + + + diff --git a/apps/docs/src/lib/components/ui/switch/index.ts b/apps/docs/src/lib/components/ui/switch/index.ts new file mode 100644 index 0000000..f5533db --- /dev/null +++ b/apps/docs/src/lib/components/ui/switch/index.ts @@ -0,0 +1,7 @@ +import Root from "./switch.svelte"; + +export { + Root, + // + Root as Switch, +}; diff --git a/apps/docs/src/lib/components/ui/switch/switch.svelte b/apps/docs/src/lib/components/ui/switch/switch.svelte new file mode 100644 index 0000000..78477dd --- /dev/null +++ b/apps/docs/src/lib/components/ui/switch/switch.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/table/index.ts b/apps/docs/src/lib/components/ui/table/index.ts new file mode 100644 index 0000000..14695c8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/index.ts @@ -0,0 +1,28 @@ +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, +}; diff --git a/apps/docs/src/lib/components/ui/table/table-body.svelte b/apps/docs/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 0000000..29e9687 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-caption.svelte b/apps/docs/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 0000000..4696cff --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-cell.svelte b/apps/docs/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 0000000..1a2f033 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-footer.svelte b/apps/docs/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 0000000..b9b14eb --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,20 @@ + + +tr]:last:border-b-0", className)} + {...restProps} +> + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-head.svelte b/apps/docs/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 0000000..e9dd237 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-header.svelte b/apps/docs/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 0000000..f47d259 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table-row.svelte b/apps/docs/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 0000000..0df769e --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,23 @@ + + +svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/table/table.svelte b/apps/docs/src/lib/components/ui/table/table.svelte new file mode 100644 index 0000000..a334956 --- /dev/null +++ b/apps/docs/src/lib/components/ui/table/table.svelte @@ -0,0 +1,22 @@ + + +
    + + {@render children?.()} +
    +
    diff --git a/apps/docs/src/lib/components/ui/tabs/index.ts b/apps/docs/src/lib/components/ui/tabs/index.ts new file mode 100644 index 0000000..12d4327 --- /dev/null +++ b/apps/docs/src/lib/components/ui/tabs/index.ts @@ -0,0 +1,16 @@ +import Root from "./tabs.svelte"; +import Content from "./tabs-content.svelte"; +import List from "./tabs-list.svelte"; +import Trigger from "./tabs-trigger.svelte"; + +export { + Root, + Content, + List, + Trigger, + // + Root as Tabs, + Content as TabsContent, + List as TabsList, + Trigger as TabsTrigger, +}; diff --git a/apps/docs/src/lib/components/ui/tabs/tabs-content.svelte b/apps/docs/src/lib/components/ui/tabs/tabs-content.svelte new file mode 100644 index 0000000..340d65c --- /dev/null +++ b/apps/docs/src/lib/components/ui/tabs/tabs-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/docs/src/lib/components/ui/tabs/tabs-list.svelte b/apps/docs/src/lib/components/ui/tabs/tabs-list.svelte new file mode 100644 index 0000000..08932b6 --- /dev/null +++ b/apps/docs/src/lib/components/ui/tabs/tabs-list.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/tabs/tabs-trigger.svelte b/apps/docs/src/lib/components/ui/tabs/tabs-trigger.svelte new file mode 100644 index 0000000..dced992 --- /dev/null +++ b/apps/docs/src/lib/components/ui/tabs/tabs-trigger.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/docs/src/lib/components/ui/tabs/tabs.svelte b/apps/docs/src/lib/components/ui/tabs/tabs.svelte new file mode 100644 index 0000000..ef6cada --- /dev/null +++ b/apps/docs/src/lib/components/ui/tabs/tabs.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/docs/src/lib/components/ui/terminal/index.ts b/apps/docs/src/lib/components/ui/terminal/index.ts new file mode 100644 index 0000000..2c77438 --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/index.ts @@ -0,0 +1,9 @@ + + +import Loop from "./terminal-loop.svelte"; +import Root from "./terminal.svelte"; +import TypingAnimation from "./terminal-typing-animation.svelte"; +import AnimatedSpan from "./terminal-animated-span.svelte"; +import Loading from "./terminal-loading.svelte"; + +export { Loop, Root, TypingAnimation, AnimatedSpan, Loading }; diff --git a/apps/docs/src/lib/components/ui/terminal/terminal-animated-span.svelte b/apps/docs/src/lib/components/ui/terminal/terminal-animated-span.svelte new file mode 100644 index 0000000..86230fb --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal-animated-span.svelte @@ -0,0 +1,37 @@ + + + + +{#if playAnimation} + + {@render children?.()} + +{/if} diff --git a/apps/docs/src/lib/components/ui/terminal/terminal-loading.svelte b/apps/docs/src/lib/components/ui/terminal/terminal-loading.svelte new file mode 100644 index 0000000..01c6974 --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal-loading.svelte @@ -0,0 +1,67 @@ + + + + +{#if playAnimation && !complete} + + {frames[frameIndex]} + {@render loadingMessage()} + +{:else if playAnimation} + + {@render completeMessage()} + +{/if} diff --git a/apps/docs/src/lib/components/ui/terminal/terminal-loop.svelte b/apps/docs/src/lib/components/ui/terminal/terminal-loop.svelte new file mode 100644 index 0000000..f99d602 --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal-loop.svelte @@ -0,0 +1,24 @@ + + + + +{#key loopIndex} + {@render children?.()} +{/key} diff --git a/apps/docs/src/lib/components/ui/terminal/terminal-typing-animation.svelte b/apps/docs/src/lib/components/ui/terminal/terminal-typing-animation.svelte new file mode 100644 index 0000000..77094ef --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal-typing-animation.svelte @@ -0,0 +1,35 @@ + + + + +{#if playAnimation} + animation.onComplete?.() + }} + > + {@render children?.()} + +{/if} diff --git a/apps/docs/src/lib/components/ui/terminal/terminal.svelte b/apps/docs/src/lib/components/ui/terminal/terminal.svelte new file mode 100644 index 0000000..38c6eb5 --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal.svelte @@ -0,0 +1,32 @@ + + + + + + {@render children?.()} + diff --git a/apps/docs/src/lib/components/ui/terminal/terminal.svelte.ts b/apps/docs/src/lib/components/ui/terminal/terminal.svelte.ts new file mode 100644 index 0000000..85c15ed --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/terminal.svelte.ts @@ -0,0 +1,111 @@ + + +import { Context } from "runed"; + +export type Timeout = ReturnType | undefined; + +export type TerminalLoopProps = { + onComplete: () => void; +}; + +export class TerminalLoop { + constructor(readonly opts: TerminalLoopProps) { + this.onComplete = this.onComplete.bind(this); + } + + onComplete() { + this.opts.onComplete(); + } +} + +export type TerminalRootProps = { + delay: number; + speed: number; + onComplete: () => void; +}; + +export class TerminalSession { + #animations: AnimationState[] = $state([]); + #timeout: Timeout; + + constructor( + readonly opts: TerminalRootProps, + readonly loop?: TerminalLoop + ) { + this.onComplete = this.onComplete.bind(this); + } + + play() { + this.#timeout = setTimeout(() => { + this.#animations.sort((a, b) => a.delay - b.delay); + + for (let i = 0; i < this.#animations.length; i++) { + this.#animations[i].timeout = setTimeout(() => { + this.#animations[i].play(this.opts.speed); + + // when the most delayed animation is complete call onComplete + if (i === this.#animations.length - 1) { + this.#animations[i].onComplete = this.onComplete; + } + }, this.#animations[i].delay); + } + }, this.opts.delay); + } + + onComplete() { + this.opts.onComplete?.(); + + this.loop?.onComplete(); + } + + dispose() { + clearTimeout(this.#timeout); + } + + registerAnimation(animation: AnimationState) { + this.#animations.push(animation); + } +} + +export type AnimationStateProps = { + delay: number; + play: (speed: number) => void; +}; + +export class AnimationState { + delay: number; + timeout: Timeout; + onComplete = $state<() => void>(); + + constructor( + readonly rootState: TerminalSession, + readonly opts: AnimationStateProps + ) { + this.delay = opts.delay; + + rootState.registerAnimation(this); + } + + play(speed: number) { + this.opts.play(speed); + } + + dispose() { + clearTimeout(this.timeout); + } +} + +const TerminalLoopContext = new Context("Terminal.Loop"); +const TerminalRootContext = new Context("Terminal.Root"); + +export const useTerminalLoop = (props: TerminalLoopProps) => { + return TerminalLoopContext.set(new TerminalLoop(props)); +}; + +export const useTerminalRoot = (props: TerminalRootProps) => { + return TerminalRootContext.set(new TerminalSession(props, TerminalLoopContext.getOr(undefined))); +}; + +export const useAnimation = (props: AnimationStateProps) => { + return new AnimationState(TerminalRootContext.get(), props); +}; diff --git a/apps/docs/src/lib/components/ui/terminal/types.ts b/apps/docs/src/lib/components/ui/terminal/types.ts new file mode 100644 index 0000000..43af64a --- /dev/null +++ b/apps/docs/src/lib/components/ui/terminal/types.ts @@ -0,0 +1,26 @@ + + +import type { WithChildren } from "bits-ui"; +import type { Snippet } from "svelte"; + +export type TerminalRootProps = WithChildren<{ + class?: string; + delay?: number; + speed?: number; + onComplete?: () => void; +}>; + +export type TerminalLoopProps = WithChildren<{ + delay?: number; +}>; + +export type TerminalAnimationProps = WithChildren<{ + delay?: number; + class?: string; +}>; + +export type TerminalLoadingProps = Omit & { + loadingMessage: Snippet<[]>; + completeMessage: Snippet<[]>; + duration?: number; +}; diff --git a/apps/docs/src/lib/components/ui/textarea/index.ts b/apps/docs/src/lib/components/ui/textarea/index.ts new file mode 100644 index 0000000..ace797a --- /dev/null +++ b/apps/docs/src/lib/components/ui/textarea/index.ts @@ -0,0 +1,7 @@ +import Root from "./textarea.svelte"; + +export { + Root, + // + Root as Textarea, +}; diff --git a/apps/docs/src/lib/components/ui/textarea/textarea.svelte b/apps/docs/src/lib/components/ui/textarea/textarea.svelte new file mode 100644 index 0000000..545b377 --- /dev/null +++ b/apps/docs/src/lib/components/ui/textarea/textarea.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/docs/src/lib/components/ui/toggle-group/index.ts b/apps/docs/src/lib/components/ui/toggle-group/index.ts new file mode 100644 index 0000000..12b14b9 --- /dev/null +++ b/apps/docs/src/lib/components/ui/toggle-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./toggle-group.svelte"; +import Item from "./toggle-group-item.svelte"; + +export { + Root, + Item, + // + Root as ToggleGroup, + Item as ToggleGroupItem, +}; diff --git a/apps/docs/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/apps/docs/src/lib/components/ui/toggle-group/toggle-group-item.svelte new file mode 100644 index 0000000..a22a114 --- /dev/null +++ b/apps/docs/src/lib/components/ui/toggle-group/toggle-group-item.svelte @@ -0,0 +1,34 @@ + + + diff --git a/apps/docs/src/lib/components/ui/toggle-group/toggle-group.svelte b/apps/docs/src/lib/components/ui/toggle-group/toggle-group.svelte new file mode 100644 index 0000000..351fbd8 --- /dev/null +++ b/apps/docs/src/lib/components/ui/toggle-group/toggle-group.svelte @@ -0,0 +1,47 @@ + + + + + + diff --git a/apps/docs/src/lib/components/ui/toggle/index.ts b/apps/docs/src/lib/components/ui/toggle/index.ts new file mode 100644 index 0000000..8cb2936 --- /dev/null +++ b/apps/docs/src/lib/components/ui/toggle/index.ts @@ -0,0 +1,13 @@ +import Root from "./toggle.svelte"; +export { + toggleVariants, + type ToggleSize, + type ToggleVariant, + type ToggleVariants, +} from "./toggle.svelte"; + +export { + Root, + // + Root as Toggle, +}; diff --git a/apps/docs/src/lib/components/ui/toggle/toggle.svelte b/apps/docs/src/lib/components/ui/toggle/toggle.svelte new file mode 100644 index 0000000..d3b35f0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/toggle/toggle.svelte @@ -0,0 +1,52 @@ + + + + + diff --git a/apps/docs/src/lib/components/ui/tooltip/index.ts b/apps/docs/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 0000000..313a7f0 --- /dev/null +++ b/apps/docs/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,21 @@ +import { Tooltip as TooltipPrimitive } from "bits-ui"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; + +const Root = TooltipPrimitive.Root; +const Provider = TooltipPrimitive.Provider; +const Portal = TooltipPrimitive.Portal; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/apps/docs/src/lib/components/ui/tooltip/tooltip-content.svelte b/apps/docs/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..e495efe --- /dev/null +++ b/apps/docs/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,47 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    diff --git a/apps/docs/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/apps/docs/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..1acdaa4 --- /dev/null +++ b/apps/docs/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/docs/src/lib/components/ui/window/index.ts b/apps/docs/src/lib/components/ui/window/index.ts new file mode 100644 index 0000000..059202c --- /dev/null +++ b/apps/docs/src/lib/components/ui/window/index.ts @@ -0,0 +1,5 @@ + + +import Window from "./window.svelte"; + +export { Window }; diff --git a/apps/docs/src/lib/components/ui/window/window.svelte b/apps/docs/src/lib/components/ui/window/window.svelte new file mode 100644 index 0000000..2a24a8e --- /dev/null +++ b/apps/docs/src/lib/components/ui/window/window.svelte @@ -0,0 +1,29 @@ + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + {@render children?.()} +
    +
    diff --git a/apps/docs/src/lib/components/version-switcher.svelte b/apps/docs/src/lib/components/version-switcher.svelte new file mode 100644 index 0000000..d9e9c78 --- /dev/null +++ b/apps/docs/src/lib/components/version-switcher.svelte @@ -0,0 +1,54 @@ + + + + + + + {#snippet child({ props })} + +
    + +
    +
    + Documentation + v{selectedVersion} +
    + +
    + {/snippet} +
    + + {#each versions as version (version)} + onSelect(version)}> + v{version} + {#if version === selectedVersion} + + {/if} + + {/each} + +
    +
    +
    diff --git a/apps/docs/src/lib/content-index.ts b/apps/docs/src/lib/content-index.ts new file mode 100644 index 0000000..eae3272 --- /dev/null +++ b/apps/docs/src/lib/content-index.ts @@ -0,0 +1,111 @@ +// mdsvex-based content index using import.meta.glob +// Discover docs under src/content/docs/** + +export interface NavigationItem { + title: string; + url: string; + items?: NavigationItem[]; +} + +export interface NavigationData { + versions: string[]; + navMain: NavigationItem[]; +} + +type SvxModule = { + default: unknown; // Svelte component + metadata?: { + title?: string; + category?: string; + order?: number; + slug?: string; + }; +}; + +// Eagerly import all .svx modules to access metadata at build time (SSR-safe) +const modules = import.meta.glob('/src/content/docs/**/*.svx', { eager: true }) as Record; + +// Route index to map URLs to components +const routeIndex = new Map(); + +function pathToParts(pathname: string): { version: string; category?: string; slug?: string; isMain: boolean } | null { + // pathname like /src/content/docs/1.0.1/main.svx + // or /src/content/docs/1.0.1/Building Your Application/Routing.svx + const parts = pathname.split('/').filter(Boolean); + const idx = parts.indexOf('docs'); + if (idx === -1 || idx + 1 >= parts.length) return null; + const version = parts[idx + 1]; + if (parts.length === idx + 3) { + // main.svx + return { version, isMain: true }; + } + const category = decodeURIComponent(parts[idx + 2]); + const slugWithExt = parts[parts.length - 1]; + const slug = slugWithExt.replace(/\.svx$/, ''); + return { version, category, slug, isMain: false }; +} + +function titleFrom(module: SvxModule, fallback: string): string { + const t = module.metadata?.title; + if (t) return t; + // format fallback + return fallback.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); +} + +export function buildNavigation(): NavigationData { + const byVersion: Map; mains: string[] }> = new Map(); + + for (const [pathname, mod] of Object.entries(modules)) { + const parts = pathToParts(pathname); + if (!parts) continue; + const versionEntry: { categoryMap: Map; mains: string[] } = + byVersion.get(parts.version) ?? { categoryMap: new Map(), mains: [] as string[] }; + byVersion.set(parts.version, versionEntry); + + if (parts.isMain) { + versionEntry.mains.push(parts.version); + continue; + } + + const categoryFs = parts.category || 'General'; + const categoryTitle = titleFrom(mod, mod.metadata?.category || categoryFs); + const group = versionEntry.categoryMap.get(categoryTitle) ?? { title: categoryTitle, url: `/docs/${encodeURIComponent(parts.version)}`, items: [] as NavigationItem[] }; + versionEntry.categoryMap.set(categoryTitle, group); + + const itemSlug = mod.metadata?.slug || parts.slug || 'page'; + const itemTitle = titleFrom(mod, itemSlug); + const categorySegment = mod.metadata?.category || categoryFs; + const url = `/docs/${encodeURIComponent(parts.version)}/${encodeURIComponent(categorySegment)}/${encodeURIComponent(itemSlug)}`; + (group.items as NavigationItem[]).push({ title: itemTitle, url }); + + // Register in route index + routeIndex.set(url, mod.default); + } + + // Determine global versions list from discovered versions + const versions = Array.from(byVersion.keys()).sort((a, b) => a.localeCompare(b)); + + // By default, build navMain for the first version (can be extended to per-version switching later) + const defaultVersion = versions[0]; + const entry = defaultVersion ? byVersion.get(defaultVersion) : undefined; + const navMain: NavigationItem[] = entry ? Array.from(entry.categoryMap.values()).map((group) => ({ + title: group.title, + url: group.url, + items: (group.items ?? []).slice().sort((a, b) => a.title.localeCompare(b.title)) + })).sort((a, b) => a.title.localeCompare(b.title)) : []; + + return { versions, navMain }; +} + +export function resolveComponent(params: { version: string; category?: string; slug?: string }): unknown | null { + const { version, category, slug } = params; + if (!category && !slug) { + // map to main.svx by convention + const key = `/src/content/docs/${version}/main.svx`; + const mod = modules[key]; + return mod?.default ?? null; + } + const key = `/src/content/docs/${version}/${category}/${slug}.svx`; + const mod = modules[key]; + return mod?.default ?? null; +} diff --git a/apps/docs/src/lib/docs-parser.ts b/apps/docs/src/lib/docs-parser.ts new file mode 100644 index 0000000..491b54e --- /dev/null +++ b/apps/docs/src/lib/docs-parser.ts @@ -0,0 +1,140 @@ +import { promises as fs } from 'fs'; +import path from 'path'; + +export interface NavigationItem { + title: string; + url: string; + items?: NavigationItem[]; + isActive?: boolean; +} + +export interface NavigationData { + versions: string[]; + navMain: NavigationItem[]; +} + +export interface DocumentMetadata { + title: string; + url: string; + path: string; + category?: string; + version: string; +} + +function cleanTitle(filename: string): string { + // Remove file extension + let title = filename.replace(/\.(md|mdx)$/, ''); + + // Replace common separators with spaces + title = title.replace(/[-_]/g, ' '); + + // Title case the words + return title.replace(/\b\w/g, l => l.toUpperCase()); +} + +function generateUrl(version: string, category: string, filename: string): string { + const nameNoExt = filename.replace(/\.(md|mdx)$/, ''); + if (filename === 'main.md' || filename === 'main.mdx') { + return `/docs/${encodeURIComponent(version)}`; + } + return `/docs/${encodeURIComponent(version)}/${encodeURIComponent(category)}/${encodeURIComponent(nameNoExt)}`; +} + +async function scanDirectory(dirPath: string, version: string): Promise { + const entries = await fs.readdir(dirPath, { withFileTypes: true }); + const documents: DocumentMetadata[] = []; + + for (const entry of entries) { + if (entry.isDirectory()) { + const categoryPath = path.join(dirPath, entry.name); + const categoryDocuments = await scanDirectory(categoryPath, version); + documents.push(...categoryDocuments); + } else if (entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.mdx'))) { + const metadata: DocumentMetadata = { + title: cleanTitle(entry.name), + url: generateUrl(version, path.basename(dirPath), entry.name), + path: path.join(dirPath, entry.name), + category: path.basename(dirPath), + version + }; + documents.push(metadata); + } + } + + return documents; +} + +export async function getNavigationData(): Promise { + const docsPath = path.join(process.cwd(), 'static', 'docs'); + + try { + const entries = await fs.readdir(docsPath, { withFileTypes: true }); + + // Get versions (directory names) + const versions = entries + .filter(entry => entry.isDirectory()) + .map(entry => entry.name) + .sort((a, b) => { + // Simple version sorting - you might want to enhance this for semantic versioning + return a.localeCompare(b); + }); + + if (versions.length === 0) { + return { + versions: [], + navMain: [] + }; + } + + // Get documents for the first version (default) + const defaultVersion = versions[0]; + const versionPath = path.join(docsPath, defaultVersion); + const allDocuments = await scanDirectory(versionPath, defaultVersion); + + // Group documents by category + const categoriesMap = new Map(); + + for (const doc of allDocuments) { + const category = doc.category || 'General'; + if (!categoriesMap.has(category)) { + categoriesMap.set(category, []); + } + categoriesMap.get(category)!.push(doc); + } + + // Convert to navigation structure + const navMain: NavigationItem[] = Array.from(categoriesMap.entries()) + .map(([category, documents]) => ({ + title: category, + url: documents.find(doc => doc.path.endsWith('main.md') || doc.path.endsWith('main.mdx'))?.url || '#', + items: documents + .filter(doc => !doc.path.endsWith('main.md') && !doc.path.endsWith('main.mdx')) + .map(doc => ({ + title: doc.title, + url: doc.url + })) + .sort((a, b) => a.title.localeCompare(b.title)) + })) + .sort((a, b) => a.title.localeCompare(b.title)); + + return { + versions, + navMain + }; + } catch (error) { + console.error('Error scanning documentation directory:', error); + return { + versions: [], + navMain: [] + }; + } +} + +export async function getDocumentContent(filePath: string): Promise { + try { + return await fs.readFile(filePath, 'utf-8'); + } catch (error) { + console.error('Error reading document:', error); + return ''; + } +} diff --git a/apps/docs/src/lib/hooks/is-mobile.svelte.ts b/apps/docs/src/lib/hooks/is-mobile.svelte.ts new file mode 100644 index 0000000..4829c00 --- /dev/null +++ b/apps/docs/src/lib/hooks/is-mobile.svelte.ts @@ -0,0 +1,9 @@ +import { MediaQuery } from "svelte/reactivity"; + +const DEFAULT_MOBILE_BREAKPOINT = 768; + +export class IsMobile extends MediaQuery { + constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) { + super(`max-width: ${breakpoint - 1}px`); + } +} diff --git a/apps/docs/src/lib/hooks/use-clipboard.svelte.ts b/apps/docs/src/lib/hooks/use-clipboard.svelte.ts new file mode 100644 index 0000000..a4e0236 --- /dev/null +++ b/apps/docs/src/lib/hooks/use-clipboard.svelte.ts @@ -0,0 +1,83 @@ +type Options = { + /** The time before the copied status is reset. */ + delay: number; +}; + +/** Use this hook to copy text to the clipboard and show a copied state. + * + * ## Usage + * ```svelte + * + * + * + * ``` + * + */ +export class UseClipboard { + #copiedStatus = $state<"success" | "failure">(); + private delay: number; + private timeout: ReturnType | undefined = undefined; + + constructor({ delay = 500 }: Partial = {}) { + this.delay = delay; + } + + /** Copies the given text to the users clipboard. + * + * ## Usage + * ```ts + * clipboard.copy('Hello, World!'); + * ``` + * + * @param text + * @returns + */ + async copy(text: string) { + if (this.timeout) { + this.#copiedStatus = undefined; + clearTimeout(this.timeout); + } + + try { + await navigator.clipboard.writeText(text); + + this.#copiedStatus = "success"; + + this.timeout = setTimeout(() => { + this.#copiedStatus = undefined; + }, this.delay); + } catch { + // an error can occur when not in the browser or if the user hasn't given clipboard access + this.#copiedStatus = "failure"; + + this.timeout = setTimeout(() => { + this.#copiedStatus = undefined; + }, this.delay); + } + + return this.#copiedStatus; + } + + /** true when the user has just copied to the clipboard. */ + get copied() { + return this.#copiedStatus === "success"; + } + + /** Indicates whether a copy has occurred + * and gives a status of either `success` or `failure`. */ + get status() { + return this.#copiedStatus; + } +} diff --git a/apps/docs/src/lib/utils.ts b/apps/docs/src/lib/utils.ts new file mode 100644 index 0000000..55b3a91 --- /dev/null +++ b/apps/docs/src/lib/utils.ts @@ -0,0 +1,13 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChild = T extends { child?: any } ? Omit : T; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChildren = T extends { children?: any } ? Omit : T; +export type WithoutChildrenOrChild = WithoutChildren>; +export type WithElementRef = T & { ref?: U | null }; diff --git a/apps/docs/src/routes/+error.svelte b/apps/docs/src/routes/+error.svelte new file mode 100644 index 0000000..cd282ed --- /dev/null +++ b/apps/docs/src/routes/+error.svelte @@ -0,0 +1,220 @@ + + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +

    Error {status}

    +

    + {status === 404 ? '404 – Page Not Found' : 'Something Went Wrong'} +

    +
    +
    + +

    + {#if status === 404} + We couldn't find that page. It may have moved, been renamed, or never existed. + {:else} + {error?.message ?? 'An unexpected error occurred.'} + {/if} +

    + + +
    + {meme} +
    + + +
    + + +
    +
    + + +
    + + + + + > git add . + + + + {#snippet loadingMessage()} staging files... {/snippet} + {#snippet completeMessage()} ✔ staged {/snippet} + + + + + > git commit -m "{commitMsg}" + + + + {#snippet loadingMessage()} creating snapshot... {/snippet} + {#snippet completeMessage()} ✔ 1 file changed, 1 insertion(+) {/snippet} + + + + + + > git push -u origin master --force + + + + {#snippet loadingMessage()} pushing to remote... {/snippet} + {#snippet completeMessage()} ✔ done (totally safe) {/snippet} + + + + + ✔ All done. Now let's head back. + + + +
    +
    +
    diff --git a/apps/docs/src/routes/+layout.server.ts b/apps/docs/src/routes/+layout.server.ts new file mode 100644 index 0000000..c1ca5d1 --- /dev/null +++ b/apps/docs/src/routes/+layout.server.ts @@ -0,0 +1,8 @@ +import type { LayoutServerLoad } from './$types'; +import { buildNavigation } from '$lib/content-index'; + +export const load: LayoutServerLoad = async () => { + // Build navigation at request time from mdsvex glob (already eagerly imported) + const navData = buildNavigation(); + return { navData }; +}; diff --git a/apps/docs/src/routes/+layout.svelte b/apps/docs/src/routes/+layout.svelte new file mode 100644 index 0000000..73f7568 --- /dev/null +++ b/apps/docs/src/routes/+layout.svelte @@ -0,0 +1,95 @@ + + + + + + +{#if isErrorPage} + + {#if children} + {@render children()} + {/if} +{:else} + + + + + +
    + + + + + + {#if breadcrumb().length > 1} + + + +
    + +
    + {#if children} + {@render children()} + {:else} + {#each Array.from({ length: 24 }) as _, index (index)} +
    + {/each} + {/if} +
    +
    +
    +{/if} diff --git a/apps/docs/src/routes/+page.svelte b/apps/docs/src/routes/+page.svelte index e9034fe..53ee071 100644 --- a/apps/docs/src/routes/+page.svelte +++ b/apps/docs/src/routes/+page.svelte @@ -1,7 +1,5 @@

    Docs

    -

    Visit kit.svelte.dev to read the documentation

    diff --git a/apps/docs/src/routes/demo/+page.svelte b/apps/docs/src/routes/demo/+page.svelte new file mode 100644 index 0000000..a815390 --- /dev/null +++ b/apps/docs/src/routes/demo/+page.svelte @@ -0,0 +1 @@ +paraglide diff --git a/apps/docs/src/routes/demo/paraglide/+page.svelte b/apps/docs/src/routes/demo/paraglide/+page.svelte new file mode 100644 index 0000000..b75986c --- /dev/null +++ b/apps/docs/src/routes/demo/paraglide/+page.svelte @@ -0,0 +1,16 @@ + + + + +

    {m.hello_world({ name: 'SvelteKit User' })}

    +
    + + +

    +If you use VSCode, install the Sherlock i18n extension for a better i18n experience. +

    diff --git a/apps/docs/src/routes/docs/+page.server.ts b/apps/docs/src/routes/docs/+page.server.ts new file mode 100644 index 0000000..123c150 --- /dev/null +++ b/apps/docs/src/routes/docs/+page.server.ts @@ -0,0 +1,14 @@ +import type { PageServerLoad } from './$types'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { redirect } from '@sveltejs/kit'; + +export const load: PageServerLoad = async () => { + const docsPath = path.join(process.cwd(), 'static', 'docs'); + const entries = await fs.readdir(docsPath, { withFileTypes: true }).catch(() => []); + const versions = entries.filter((e) => e.isDirectory()).map((e) => e.name).sort((a, b) => a.localeCompare(b)); + if (versions.length === 0) { + return { missing: true } as any; + } + throw redirect(302, `/docs/${encodeURIComponent(versions[0])}`); +}; diff --git a/apps/docs/src/routes/docs/[version]/+page.server.ts b/apps/docs/src/routes/docs/[version]/+page.server.ts new file mode 100644 index 0000000..c05cf5b --- /dev/null +++ b/apps/docs/src/routes/docs/[version]/+page.server.ts @@ -0,0 +1,12 @@ +import type { PageServerLoad } from './$types'; +import { error } from '@sveltejs/kit'; +import { resolveComponent } from '$lib/content-index'; + +export const load: PageServerLoad = async ({ params }) => { + const version = decodeURIComponent(params.version ?? ''); + const component = resolveComponent({ version }); + if (!component) { + throw error(404, 'Version page not found'); + } + return {}; +}; diff --git a/apps/docs/src/routes/docs/[version]/+page.svelte b/apps/docs/src/routes/docs/[version]/+page.svelte new file mode 100644 index 0000000..04fc988 --- /dev/null +++ b/apps/docs/src/routes/docs/[version]/+page.svelte @@ -0,0 +1,18 @@ + + +
    + {#if Component()} + {@const C = Component() as any} +
    + +
    + {:else} +

    Main documentation not found for this version.

    + {/if} + +
    diff --git a/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.server.ts b/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.server.ts new file mode 100644 index 0000000..ef42cdb --- /dev/null +++ b/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.server.ts @@ -0,0 +1,14 @@ +import type { PageServerLoad } from './$types'; +import { error } from '@sveltejs/kit'; +import { resolveComponent } from '$lib/content-index'; + +export const load: PageServerLoad = async ({ params }) => { + const version = decodeURIComponent(params.version ?? ''); + const category = decodeURIComponent(params.category ?? ''); + const slug = decodeURIComponent(params.slug ?? ''); + const component = resolveComponent({ version, category, slug }); + if (!component) { + throw error(404, 'Documentation page not found'); + } + return {}; +}; diff --git a/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.svelte b/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.svelte new file mode 100644 index 0000000..c9674a0 --- /dev/null +++ b/apps/docs/src/routes/docs/[version]/[category]/[slug]/+page.svelte @@ -0,0 +1,24 @@ + + +
    + {#if Component()} + {@const C = Component() as any} +
    + +
    + {:else} +

    Documentation page not found.

    + {/if} +
    diff --git a/apps/docs/src/routes/page.svelte.spec.ts b/apps/docs/src/routes/page.svelte.spec.ts new file mode 100644 index 0000000..5371604 --- /dev/null +++ b/apps/docs/src/routes/page.svelte.spec.ts @@ -0,0 +1,13 @@ +import { page } from "@vitest/browser/context"; +import { describe, expect, it } from "vitest"; +import { render } from "vitest-browser-svelte"; +import Page from "./+page.svelte"; + +describe("/+page.svelte", () => { + it("should render h1", async () => { + render(Page); + + const heading = page.getByRole("heading", { level: 1 }); + await expect.element(heading).toBeInTheDocument(); + }); +}); diff --git a/apps/docs/svelte.config.js b/apps/docs/svelte.config.js index 186735e..b53c4e8 100644 --- a/apps/docs/svelte.config.js +++ b/apps/docs/svelte.config.js @@ -1,17 +1,33 @@ -import adapter from '@sveltejs/adapter-auto'; -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; +import { mdsvex } from "mdsvex"; +import rehypeShiki from "@shikijs/rehype"; +import adapter from "@sveltejs/adapter-node"; +import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; /** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://kit.svelte.dev/docs/integrations#preprocessors - // for more information about preprocessors - preprocess: vitePreprocess(), - kit: { - // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. - // If your environment is not supported or you settled on a specific environment, switch out the adapter. - // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter() - } + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: [ + vitePreprocess(), + mdsvex({ + rehypePlugins: [ + [ + rehypeShiki, + { + themes: { + light: "github-light-default", + dark: "github-dark-default" + } + } + ] + ] + }) + ], + kit: { + adapter: adapter(), + alias: { "@/*": "./src/lib/*" } + }, + extensions: [".svelte", ".svx"] }; export default config; diff --git a/apps/docs/vite.config.ts b/apps/docs/vite.config.ts index bbf8c7d..791170e 100644 --- a/apps/docs/vite.config.ts +++ b/apps/docs/vite.config.ts @@ -1,6 +1,46 @@ -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; +import { paraglideVitePlugin } from "@inlang/paraglide-js"; +import devtoolsJson from "vite-plugin-devtools-json"; +import tailwindcss from "@tailwindcss/vite"; +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; export default defineConfig({ - plugins: [sveltekit()] + plugins: [ + tailwindcss(), + sveltekit(), + devtoolsJson(), + paraglideVitePlugin({ + project: "./project.inlang", + outdir: "./src/lib/paraglide" + }) + ], + test: { + expect: { requireAssertions: true }, + projects: [ + { + extends: "./vite.config.ts", + test: { + name: "client", + environment: "browser", + browser: { + enabled: true, + provider: "playwright", + instances: [{ browser: "chromium" }] + }, + include: ["src/**/*.svelte.{test,spec}.{js,ts}"], + exclude: ["src/lib/server/**"], + setupFiles: ["./vitest-setup-client.ts"] + } + }, + { + extends: "./vite.config.ts", + test: { + name: "server", + environment: "node", + include: ["src/**/*.{test,spec}.{js,ts}"], + exclude: ["src/**/*.svelte.{test,spec}.{js,ts}"] + } + } + ] + } }); diff --git a/apps/docs/vitest-setup-client.ts b/apps/docs/vitest-setup-client.ts new file mode 100644 index 0000000..570b9f0 --- /dev/null +++ b/apps/docs/vitest-setup-client.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/apps/web/.prettierrc b/apps/web/.prettierrc index ddc56a2..9cb2bec 100644 --- a/apps/web/.prettierrc +++ b/apps/web/.prettierrc @@ -10,5 +10,7 @@ "endOfLine": "lf", "jsxSingleQuote": false, "bracketSameLine": false, - "quoteProps": "as-needed" + "quoteProps": "as-needed", + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindStylesheet": "./src/app.css" } diff --git a/apps/web/components.json b/apps/web/components.json new file mode 100644 index 0000000..c5d91b4 --- /dev/null +++ b/apps/web/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src/app.css", + "baseColor": "slate" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": true, + "registry": "https://shadcn-svelte.com/registry" +} diff --git a/apps/web/package.json b/apps/web/package.json index 70c3963..f8d74af 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,37 +1,65 @@ { - "name": "web", - "version": "0.0.1", - "private": true, - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "svelte-kit sync && vite build", - "preview": "vite preview", - "test": "npm run test:integration && npm run test:unit", - "check-types": "tsc --noEmit", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "eslint .", - "test:integration": "playwright test", - "test:unit": "vitest" - }, - "dependencies": { - "@repo/ui": "workspace:*" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@sveltejs/adapter-auto": "^4.0.0", - "@sveltejs/kit": "^2.36.1", - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "prettier": "^3.6.0", - "eslint": "^9.34.0", - "prettier-plugin-svelte": "^3.4.0", - "svelte": "^5.38.0", - "svelte-check": "^4.3.0", - "tslib": "^2.8.1", - "typescript": "5.9.2", - "vite": "^6.3.2", - "vitest": "^3.2.0" - } + "name": "web", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "svelte-kit sync && vite build", + "preview": "vite preview", + "test": "npm run test:integration && npm run test:unit", + "check-types": "tsc --noEmit", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "eslint .", + "test:integration": "playwright test", + "test:unit": "vitest" + }, + "devDependencies": { + "@internationalized/date": "^3.9.0", + "@lucide/svelte": "^0.544.0", + "@repo/eslint-config": "workspace:*", + "@repo/typescript-config": "workspace:*", + "@shikijs/langs": "^3.13.0", + "@shikijs/themes": "^3.13.0", + "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/kit": "^2.36.1", + "@sveltejs/vite-plugin-svelte": "^5.1.0", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/typography": "^0.5.15", + "@tailwindcss/vite": "^4.0.0", + "@tanstack/table-core": "^8.21.3", + "@zxcvbn-ts/core": "^3.0.4", + "@zxcvbn-ts/language-common": "^3.0.4", + "@zxcvbn-ts/language-en": "^3.0.2", + "bits-ui": "^2.11.0", + "clsx": "^2.1.1", + "embla-carousel-svelte": "^8.6.0", + "eslint": "^9.34.0", + "formsnap": "^2.0.1", + "isomorphic-dompurify": "^2.28.0", + "layerchart": "2.0.0-next.27", + "mode-watcher": "^1.1.0", + "paneforge": "^1.0.2", + "prettier": "^3.6.0", + "prettier-plugin-svelte": "^3.4.0", + "prettier-plugin-tailwindcss": "^0.6.11", + "runed": "^0.31.1", + "shiki": "^3.13.0", + "svelte": "^5.38.0", + "svelte-check": "^4.3.0", + "svelte-easy-crop": "^5.0.0", + "svelte-sonner": "^1.0.5", + "svelte-toolbelt": "^0.9.3", + "sveltekit-superforms": "^2.27.1", + "tailwind-merge": "^3.3.1", + "tailwind-variants": "^3.1.1", + "tailwindcss": "^4.0.0", + "tslib": "^2.8.1", + "tw-animate-css": "^1.3.8", + "typescript": "5.9.2", + "vaul-svelte": "1.0.0-next.7", + "vite": "^6.3.2", + "vitest": "^3.2.0" + } } diff --git a/apps/web/src/app.css b/apps/web/src/app.css new file mode 100644 index 0000000..e48f5f0 --- /dev/null +++ b/apps/web/src/app.css @@ -0,0 +1,121 @@ +@import "tailwindcss"; + +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.129 0.042 264.695); + --card: oklch(1 0 0); + --card-foreground: oklch(0.129 0.042 264.695); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.129 0.042 264.695); + --primary: oklch(0.208 0.042 265.755); + --primary-foreground: oklch(0.984 0.003 247.858); + --secondary: oklch(0.968 0.007 247.896); + --secondary-foreground: oklch(0.208 0.042 265.755); + --muted: oklch(0.968 0.007 247.896); + --muted-foreground: oklch(0.554 0.046 257.417); + --accent: oklch(0.968 0.007 247.896); + --accent-foreground: oklch(0.208 0.042 265.755); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.929 0.013 255.508); + --input: oklch(0.929 0.013 255.508); + --ring: oklch(0.704 0.04 256.788); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.984 0.003 247.858); + --sidebar-foreground: oklch(0.129 0.042 264.695); + --sidebar-primary: oklch(0.208 0.042 265.755); + --sidebar-primary-foreground: oklch(0.984 0.003 247.858); + --sidebar-accent: oklch(0.968 0.007 247.896); + --sidebar-accent-foreground: oklch(0.208 0.042 265.755); + --sidebar-border: oklch(0.929 0.013 255.508); + --sidebar-ring: oklch(0.704 0.04 256.788); +} + +.dark { + --background: oklch(0.129 0.042 264.695); + --foreground: oklch(0.984 0.003 247.858); + --card: oklch(0.208 0.042 265.755); + --card-foreground: oklch(0.984 0.003 247.858); + --popover: oklch(0.208 0.042 265.755); + --popover-foreground: oklch(0.984 0.003 247.858); + --primary: oklch(0.929 0.013 255.508); + --primary-foreground: oklch(0.208 0.042 265.755); + --secondary: oklch(0.279 0.041 260.031); + --secondary-foreground: oklch(0.984 0.003 247.858); + --muted: oklch(0.279 0.041 260.031); + --muted-foreground: oklch(0.704 0.04 256.788); + --accent: oklch(0.279 0.041 260.031); + --accent-foreground: oklch(0.984 0.003 247.858); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.551 0.027 264.364); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.208 0.042 265.755); + --sidebar-foreground: oklch(0.984 0.003 247.858); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.984 0.003 247.858); + --sidebar-accent: oklch(0.279 0.041 260.031); + --sidebar-accent-foreground: oklch(0.984 0.003 247.858); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.551 0.027 264.364); +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/apps/web/src/lib/actions/shortcut.svelte.ts b/apps/web/src/lib/actions/shortcut.svelte.ts new file mode 100644 index 0000000..2e6fe9c --- /dev/null +++ b/apps/web/src/lib/actions/shortcut.svelte.ts @@ -0,0 +1,207 @@ +import { createAttachmentKey } from "svelte/attachments"; + +export type Options = { + /** Event to use to detect the shortcut @default 'keydown' */ + event?: "keydown" | "keyup" | "keypress"; + /** Function to be called when the shortcut is pressed */ + callback: (e: KeyboardEvent) => void; + /** Should the `Shift` key be pressed */ + shift?: boolean; + /** Should the `Ctrl` / `Command` key be pressed */ + ctrl?: boolean; + /** Should the `Alt` key be pressed */ + alt?: boolean; + /** Which key should be pressed */ + key: Key; + /** Control whether or not the shortcut prevents default behavior @default true */ + preventDefault?: boolean; + /** Control whether or not the shortcut stops propagation @default false */ + stopPropagation?: boolean; +}; + +/** Allows you to configure one or more shortcuts based on the key events of an element. + * + * ## Usage + * ```svelte + * + * + * ``` + */ +export const shortcut = (node: HTMLElement, options: Options[] | Options) => { + const handleKeydown = (e: KeyboardEvent, options: Options) => { + if (options.ctrl && !e.ctrlKey && !e.metaKey) return; + + if (options.alt && !e.altKey) return; + + if (options.shift && !e.shiftKey) return; + + if (e.key.toLocaleLowerCase() !== options.key.toLocaleLowerCase()) return; + + if (options.preventDefault === undefined || options.preventDefault) { + e.preventDefault(); + } + + if (options.stopPropagation) { + e.stopPropagation(); + } + + options.callback(e); + }; + + $effect(() => { + let optionsArr: Options[] = []; + if (Array.isArray(options)) { + optionsArr = options; + } else { + optionsArr = [options]; + } + + for (const opt of optionsArr) { + node.addEventListener(opt.event ?? "keydown", (e) => handleKeydown(e, opt)); + } + + return () => { + for (const opt of optionsArr) { + node.removeEventListener(opt.event ?? "keydown", (e) => handleKeydown(e, opt)); + } + }; + }); +}; + +/** Allows you to configure one or more shortcuts based on the key events of an element. + * + * ## Usage + * ```svelte + * + * + * ``` + */ +export function attachShortcut(opts: Options[] | Options) { + return { + [createAttachmentKey()]: (node: HTMLElement) => shortcut(node, opts) + }; +} + +export type Key = + | "backspace" + | "tab" + | "enter" + | "shift(left)" + | "shift(right)" + | "ctrl(left)" + | "ctrl(right)" + | "alt(left)" + | "alt(right)" + | "pause/break" + | "caps lock" + | "escape" + | "space" + | "page up" + | "page down" + | "end" + | "home" + | "left arrow" + | "up arrow" + | "right arrow" + | "down arrow" + | "print screen" + | "insert" + | "delete" + | "0" + | "1" + | "2" + | "3" + | "4" + | "5" + | "6" + | "7" + | "8" + | "9" + | "a" + | "b" + | "c" + | "d" + | "e" + | "f" + | "g" + | "h" + | "i" + | "j" + | "k" + | "l" + | "m" + | "n" + | "o" + | "p" + | "q" + | "r" + | "s" + | "t" + | "u" + | "v" + | "w" + | "x" + | "y" + | "z" + | "left window key" + | "right window key" + | "select key (Context Menu)" + | "numpad 0" + | "numpad 1" + | "numpad 2" + | "numpad 3" + | "numpad 4" + | "numpad 5" + | "numpad 6" + | "numpad 7" + | "numpad 8" + | "numpad 9" + | "multiply" + | "add" + | "subtract" + | "decimal point" + | "divide" + | "f1" + | "f2" + | "f3" + | "f4" + | "f5" + | "f6" + | "f7" + | "f8" + | "f9" + | "f10" + | "f11" + | "f12" + | "num lock" + | "scroll lock" + | "audio volume mute" + | "audio volume down" + | "audio volume up" + | "media player" + | "launch application 1" + | "launch application 2" + | "semi-colon" + | "equal sign" + | "comma" + | "dash" + | "period" + | "forward slash" + | "Backquote/Grave accent" + | "open bracket" + | "back slash" + | "close bracket" + | "single quote"; diff --git a/apps/web/src/lib/actions/typewriter.svelte.ts b/apps/web/src/lib/actions/typewriter.svelte.ts new file mode 100644 index 0000000..0fe0461 --- /dev/null +++ b/apps/web/src/lib/actions/typewriter.svelte.ts @@ -0,0 +1,32 @@ +import { createAttachmentKey } from "svelte/attachments"; +import type { TransitionConfig } from "svelte/transition"; + +export type Options = { + speed: number; + delay: number; + onComplete?: () => void; +}; + +export const typewriter = ( + node: HTMLElement, + { speed = 1, delay = 0, onComplete }: Partial +) => { + const text = node.textContent ?? ""; + const duration = text.length / (speed * 0.01); + + return { + delay, + duration, + tick: (t) => { + const i = Math.trunc(text.length * t); + node.textContent = text.slice(0, i); + if (node.textContent.length === text.length) onComplete?.(); + } + } satisfies TransitionConfig; +}; + +export function attachTypewriter(opts: Partial = {}) { + return { + [createAttachmentKey()]: (node: HTMLElement) => typewriter(node, opts) + }; +} diff --git a/apps/web/src/lib/components/ui/accordion/accordion-content.svelte b/apps/web/src/lib/components/ui/accordion/accordion-content.svelte new file mode 100644 index 0000000..cf7045e --- /dev/null +++ b/apps/web/src/lib/components/ui/accordion/accordion-content.svelte @@ -0,0 +1,22 @@ + + + +
    + {@render children?.()} +
    +
    diff --git a/apps/web/src/lib/components/ui/accordion/accordion-item.svelte b/apps/web/src/lib/components/ui/accordion/accordion-item.svelte new file mode 100644 index 0000000..780545c --- /dev/null +++ b/apps/web/src/lib/components/ui/accordion/accordion-item.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/accordion/accordion-trigger.svelte b/apps/web/src/lib/components/ui/accordion/accordion-trigger.svelte new file mode 100644 index 0000000..0027cdd --- /dev/null +++ b/apps/web/src/lib/components/ui/accordion/accordion-trigger.svelte @@ -0,0 +1,32 @@ + + + + svg]:rotate-180", + className + )} + {...restProps} + > + {@render children?.()} + + + diff --git a/apps/web/src/lib/components/ui/accordion/accordion.svelte b/apps/web/src/lib/components/ui/accordion/accordion.svelte new file mode 100644 index 0000000..117ee37 --- /dev/null +++ b/apps/web/src/lib/components/ui/accordion/accordion.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/accordion/index.ts b/apps/web/src/lib/components/ui/accordion/index.ts new file mode 100644 index 0000000..ac343a1 --- /dev/null +++ b/apps/web/src/lib/components/ui/accordion/index.ts @@ -0,0 +1,16 @@ +import Root from "./accordion.svelte"; +import Content from "./accordion-content.svelte"; +import Item from "./accordion-item.svelte"; +import Trigger from "./accordion-trigger.svelte"; + +export { + Root, + Content, + Item, + Trigger, + // + Root as Accordion, + Content as AccordionContent, + Item as AccordionItem, + Trigger as AccordionTrigger, +}; diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte new file mode 100644 index 0000000..a005691 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte new file mode 100644 index 0000000..a7b0cf7 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte new file mode 100644 index 0000000..6c3c604 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte @@ -0,0 +1,27 @@ + + + + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte new file mode 100644 index 0000000..2ec67dc --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte new file mode 100644 index 0000000..f78b97a --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte new file mode 100644 index 0000000..c8fa762 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte new file mode 100644 index 0000000..a64ee76 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte new file mode 100644 index 0000000..7ef2b5f --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte new file mode 100644 index 0000000..b22d1d5 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/alert-dialog/index.ts b/apps/web/src/lib/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..cc281c5 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert-dialog/index.ts @@ -0,0 +1,39 @@ +import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; +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"; + +const Root = AlertDialogPrimitive.Root; +const Portal = AlertDialogPrimitive.Portal; + +export { + Root, + Title, + Action, + Cancel, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + // + Root as AlertDialog, + Title as AlertDialogTitle, + Action as AlertDialogAction, + Cancel as AlertDialogCancel, + Portal as AlertDialogPortal, + Footer as AlertDialogFooter, + Header as AlertDialogHeader, + Trigger as AlertDialogTrigger, + Overlay as AlertDialogOverlay, + Content as AlertDialogContent, + Description as AlertDialogDescription, +}; diff --git a/apps/web/src/lib/components/ui/alert/alert-description.svelte b/apps/web/src/lib/components/ui/alert/alert-description.svelte new file mode 100644 index 0000000..8b56aed --- /dev/null +++ b/apps/web/src/lib/components/ui/alert/alert-description.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/alert/alert-title.svelte b/apps/web/src/lib/components/ui/alert/alert-title.svelte new file mode 100644 index 0000000..77e45ad --- /dev/null +++ b/apps/web/src/lib/components/ui/alert/alert-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/alert/alert.svelte b/apps/web/src/lib/components/ui/alert/alert.svelte new file mode 100644 index 0000000..2b2eff9 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert/alert.svelte @@ -0,0 +1,44 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/alert/index.ts b/apps/web/src/lib/components/ui/alert/index.ts new file mode 100644 index 0000000..97e21b4 --- /dev/null +++ b/apps/web/src/lib/components/ui/alert/index.ts @@ -0,0 +1,14 @@ +import Root from "./alert.svelte"; +import Description from "./alert-description.svelte"; +import Title from "./alert-title.svelte"; +export { alertVariants, type AlertVariant } from "./alert.svelte"; + +export { + Root, + Description, + Title, + // + Root as Alert, + Description as AlertDescription, + Title as AlertTitle, +}; diff --git a/apps/web/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte b/apps/web/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte new file mode 100644 index 0000000..815aab0 --- /dev/null +++ b/apps/web/src/lib/components/ui/aspect-ratio/aspect-ratio.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/aspect-ratio/index.ts b/apps/web/src/lib/components/ui/aspect-ratio/index.ts new file mode 100644 index 0000000..985c75f --- /dev/null +++ b/apps/web/src/lib/components/ui/aspect-ratio/index.ts @@ -0,0 +1,3 @@ +import Root from "./aspect-ratio.svelte"; + +export { Root, Root as AspectRatio }; diff --git a/apps/web/src/lib/components/ui/avatar/avatar-fallback.svelte b/apps/web/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..d729e73 --- /dev/null +++ b/apps/web/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/avatar/avatar-image.svelte b/apps/web/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..93fac99 --- /dev/null +++ b/apps/web/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/avatar/avatar.svelte b/apps/web/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..25a95d9 --- /dev/null +++ b/apps/web/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/avatar/index.ts b/apps/web/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..1efa894 --- /dev/null +++ b/apps/web/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,13 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; + +export { + Root, + Image, + Fallback, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback +}; diff --git a/apps/web/src/lib/components/ui/badge/badge.svelte b/apps/web/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 0000000..5000457 --- /dev/null +++ b/apps/web/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,50 @@ + + + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/badge/index.ts b/apps/web/src/lib/components/ui/badge/index.ts new file mode 100644 index 0000000..64e0aa9 --- /dev/null +++ b/apps/web/src/lib/components/ui/badge/index.ts @@ -0,0 +1,2 @@ +export { default as Badge } from "./badge.svelte"; +export { badgeVariants, type BadgeVariant } from "./badge.svelte"; diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte new file mode 100644 index 0000000..a178cf5 --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte @@ -0,0 +1,23 @@ + + + diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte new file mode 100644 index 0000000..1a84c4c --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte @@ -0,0 +1,20 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte new file mode 100644 index 0000000..e6bc17d --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte @@ -0,0 +1,31 @@ + + +{#if child} + {@render child({ props: attrs })} +{:else} + + {@render children?.()} + +{/if} diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte new file mode 100644 index 0000000..b5458fa --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte @@ -0,0 +1,23 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte new file mode 100644 index 0000000..5fb6979 --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte new file mode 100644 index 0000000..84106a1 --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/web/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb.svelte new file mode 100644 index 0000000..8f8a3e6 --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/breadcrumb.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/web/src/lib/components/ui/breadcrumb/index.ts b/apps/web/src/lib/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..dc914ec --- /dev/null +++ b/apps/web/src/lib/components/ui/breadcrumb/index.ts @@ -0,0 +1,25 @@ +import Root from "./breadcrumb.svelte"; +import Ellipsis from "./breadcrumb-ellipsis.svelte"; +import Item from "./breadcrumb-item.svelte"; +import Separator from "./breadcrumb-separator.svelte"; +import Link from "./breadcrumb-link.svelte"; +import List from "./breadcrumb-list.svelte"; +import Page from "./breadcrumb-page.svelte"; + +export { + Root, + Ellipsis, + Item, + Separator, + Link, + List, + Page, + // + Root as Breadcrumb, + Ellipsis as BreadcrumbEllipsis, + Item as BreadcrumbItem, + Separator as BreadcrumbSeparator, + Link as BreadcrumbLink, + List as BreadcrumbList, + Page as BreadcrumbPage, +}; diff --git a/apps/web/src/lib/components/ui/button/button.svelte b/apps/web/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..7b7adf3 --- /dev/null +++ b/apps/web/src/lib/components/ui/button/button.svelte @@ -0,0 +1,124 @@ + + + + + + { + onclick?.(e); + + if (type === undefined) return; + + if (onClickPromise) { + loading = true; + + await onClickPromise(e); + + loading = false; + } + }} +> + {#if type !== undefined && loading} +
    +
    + +
    +
    + Loading + {/if} + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/button/index.ts b/apps/web/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..bf3620b --- /dev/null +++ b/apps/web/src/lib/components/ui/button/index.ts @@ -0,0 +1,23 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + type AnchorElementProps, + type ButtonElementProps, + type ButtonPropsWithoutHTML, + buttonVariants +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, + type AnchorElementProps, + type ButtonElementProps, + type ButtonPropsWithoutHTML +}; diff --git a/apps/web/src/lib/components/ui/calendar/calendar-caption.svelte b/apps/web/src/lib/components/ui/calendar/calendar-caption.svelte new file mode 100644 index 0000000..5c93037 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-caption.svelte @@ -0,0 +1,76 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} diff --git a/apps/web/src/lib/components/ui/calendar/calendar-cell.svelte b/apps/web/src/lib/components/ui/calendar/calendar-cell.svelte new file mode 100644 index 0000000..5f295d6 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-day.svelte b/apps/web/src/lib/components/ui/calendar/calendar-day.svelte new file mode 100644 index 0000000..32e9c83 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-day.svelte @@ -0,0 +1,35 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> diff --git a/apps/web/src/lib/components/ui/calendar/calendar-grid-body.svelte b/apps/web/src/lib/components/ui/calendar/calendar-grid-body.svelte new file mode 100644 index 0000000..8cd86de --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-grid-body.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-grid-head.svelte b/apps/web/src/lib/components/ui/calendar/calendar-grid-head.svelte new file mode 100644 index 0000000..333edc4 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-grid-head.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-grid-row.svelte b/apps/web/src/lib/components/ui/calendar/calendar-grid-row.svelte new file mode 100644 index 0000000..9032236 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-grid.svelte b/apps/web/src/lib/components/ui/calendar/calendar-grid.svelte new file mode 100644 index 0000000..e0c8627 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-grid.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-head-cell.svelte b/apps/web/src/lib/components/ui/calendar/calendar-head-cell.svelte new file mode 100644 index 0000000..131807e --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-header.svelte b/apps/web/src/lib/components/ui/calendar/calendar-header.svelte new file mode 100644 index 0000000..5b7e397 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-header.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-heading.svelte b/apps/web/src/lib/components/ui/calendar/calendar-heading.svelte new file mode 100644 index 0000000..a9b9810 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-month-select.svelte b/apps/web/src/lib/components/ui/calendar/calendar-month-select.svelte new file mode 100644 index 0000000..e4b536a --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-month-select.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-month.svelte b/apps/web/src/lib/components/ui/calendar/calendar-month.svelte new file mode 100644 index 0000000..e747fae --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-month.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/calendar/calendar-months.svelte b/apps/web/src/lib/components/ui/calendar/calendar-months.svelte new file mode 100644 index 0000000..f717a9d --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-months.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/calendar/calendar-nav.svelte b/apps/web/src/lib/components/ui/calendar/calendar-nav.svelte new file mode 100644 index 0000000..27f33d7 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-nav.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-next-button.svelte b/apps/web/src/lib/components/ui/calendar/calendar-next-button.svelte new file mode 100644 index 0000000..d8eb4ef --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-next-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-prev-button.svelte b/apps/web/src/lib/components/ui/calendar/calendar-prev-button.svelte new file mode 100644 index 0000000..3e4471a --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-prev-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar-year-select.svelte b/apps/web/src/lib/components/ui/calendar/calendar-year-select.svelte new file mode 100644 index 0000000..3842037 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar-year-select.svelte @@ -0,0 +1,43 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + diff --git a/apps/web/src/lib/components/ui/calendar/calendar.svelte b/apps/web/src/lib/components/ui/calendar/calendar.svelte new file mode 100644 index 0000000..29b6fff --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/calendar.svelte @@ -0,0 +1,115 @@ + + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + {#each weekdays as weekday (weekday)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + diff --git a/apps/web/src/lib/components/ui/calendar/index.ts b/apps/web/src/lib/components/ui/calendar/index.ts new file mode 100644 index 0000000..f3a16d2 --- /dev/null +++ b/apps/web/src/lib/components/ui/calendar/index.ts @@ -0,0 +1,40 @@ +import Root from "./calendar.svelte"; +import Cell from "./calendar-cell.svelte"; +import Day from "./calendar-day.svelte"; +import Grid from "./calendar-grid.svelte"; +import Header from "./calendar-header.svelte"; +import Months from "./calendar-months.svelte"; +import GridRow from "./calendar-grid-row.svelte"; +import Heading from "./calendar-heading.svelte"; +import GridBody from "./calendar-grid-body.svelte"; +import GridHead from "./calendar-grid-head.svelte"; +import HeadCell from "./calendar-head-cell.svelte"; +import NextButton from "./calendar-next-button.svelte"; +import PrevButton from "./calendar-prev-button.svelte"; +import MonthSelect from "./calendar-month-select.svelte"; +import YearSelect from "./calendar-year-select.svelte"; +import Month from "./calendar-month.svelte"; +import Nav from "./calendar-nav.svelte"; +import Caption from "./calendar-caption.svelte"; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + Nav, + Month, + YearSelect, + MonthSelect, + Caption, + // + Root as Calendar, +}; diff --git a/apps/web/src/lib/components/ui/card/card-action.svelte b/apps/web/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..cc36c56 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/card-content.svelte b/apps/web/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..bc90b83 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/card-description.svelte b/apps/web/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..9b20ac7 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

    + {@render children?.()} +

    diff --git a/apps/web/src/lib/components/ui/card/card-footer.svelte b/apps/web/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..cf43353 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/card-header.svelte b/apps/web/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..8a91abb --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/card-title.svelte b/apps/web/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..22586e6 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/card.svelte b/apps/web/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..99448cc --- /dev/null +++ b/apps/web/src/lib/components/ui/card/card.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/card/index.ts b/apps/web/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..4d3fce4 --- /dev/null +++ b/apps/web/src/lib/components/ui/card/index.ts @@ -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, +}; diff --git a/apps/web/src/lib/components/ui/carousel/carousel-content.svelte b/apps/web/src/lib/components/ui/carousel/carousel-content.svelte new file mode 100644 index 0000000..6b169be --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/carousel-content.svelte @@ -0,0 +1,43 @@ + + +
    +
    + {@render children?.()} +
    +
    diff --git a/apps/web/src/lib/components/ui/carousel/carousel-item.svelte b/apps/web/src/lib/components/ui/carousel/carousel-item.svelte new file mode 100644 index 0000000..8352833 --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/carousel-item.svelte @@ -0,0 +1,30 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/carousel/carousel-next.svelte b/apps/web/src/lib/components/ui/carousel/carousel-next.svelte new file mode 100644 index 0000000..27bd383 --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/carousel-next.svelte @@ -0,0 +1,38 @@ + + + diff --git a/apps/web/src/lib/components/ui/carousel/carousel-previous.svelte b/apps/web/src/lib/components/ui/carousel/carousel-previous.svelte new file mode 100644 index 0000000..2f0973d --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/carousel-previous.svelte @@ -0,0 +1,38 @@ + + + diff --git a/apps/web/src/lib/components/ui/carousel/carousel.svelte b/apps/web/src/lib/components/ui/carousel/carousel.svelte new file mode 100644 index 0000000..0492805 --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/carousel.svelte @@ -0,0 +1,93 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/carousel/context.ts b/apps/web/src/lib/components/ui/carousel/context.ts new file mode 100644 index 0000000..a5fd74f --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/context.ts @@ -0,0 +1,58 @@ +import type { WithElementRef } from "$lib/utils.js"; +import type { + EmblaCarouselSvelteType, + default as emblaCarouselSvelte, +} from "embla-carousel-svelte"; +import { getContext, hasContext, setContext } from "svelte"; +import type { HTMLAttributes } from "svelte/elements"; + +export type CarouselAPI = + NonNullable["on:emblaInit"]> extends ( + evt: CustomEvent + ) => void + ? CarouselAPI + : never; + +type EmblaCarouselConfig = NonNullable[1]>; + +export type CarouselOptions = EmblaCarouselConfig["options"]; +export type CarouselPlugins = EmblaCarouselConfig["plugins"]; + +//// + +export type CarouselProps = { + opts?: CarouselOptions; + plugins?: CarouselPlugins; + setApi?: (api: CarouselAPI | undefined) => void; + orientation?: "horizontal" | "vertical"; +} & WithElementRef>; + +const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT"); + +export type EmblaContext = { + api: CarouselAPI | undefined; + orientation: "horizontal" | "vertical"; + scrollNext: () => void; + scrollPrev: () => void; + canScrollNext: boolean; + canScrollPrev: boolean; + handleKeyDown: (e: KeyboardEvent) => void; + options: CarouselOptions; + plugins: CarouselPlugins; + onInit: (e: CustomEvent) => void; + scrollTo: (index: number, jump?: boolean) => void; + scrollSnaps: number[]; + selectedIndex: number; +}; + +export function setEmblaContext(config: EmblaContext): EmblaContext { + setContext(EMBLA_CAROUSEL_CONTEXT, config); + return config; +} + +export function getEmblaContext(name = "This component") { + if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) { + throw new Error(`${name} must be used within a component`); + } + return getContext>(EMBLA_CAROUSEL_CONTEXT); +} diff --git a/apps/web/src/lib/components/ui/carousel/index.ts b/apps/web/src/lib/components/ui/carousel/index.ts new file mode 100644 index 0000000..957fc74 --- /dev/null +++ b/apps/web/src/lib/components/ui/carousel/index.ts @@ -0,0 +1,19 @@ +import Root from "./carousel.svelte"; +import Content from "./carousel-content.svelte"; +import Item from "./carousel-item.svelte"; +import Previous from "./carousel-previous.svelte"; +import Next from "./carousel-next.svelte"; + +export { + Root, + Content, + Item, + Previous, + Next, + // + Root as Carousel, + Content as CarouselContent, + Item as CarouselItem, + Previous as CarouselPrevious, + Next as CarouselNext, +}; diff --git a/apps/web/src/lib/components/ui/chart/chart-container.svelte b/apps/web/src/lib/components/ui/chart/chart-container.svelte new file mode 100644 index 0000000..563b25b --- /dev/null +++ b/apps/web/src/lib/components/ui/chart/chart-container.svelte @@ -0,0 +1,80 @@ + + +
    + + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/chart/chart-style.svelte b/apps/web/src/lib/components/ui/chart/chart-style.svelte new file mode 100644 index 0000000..864ecc3 --- /dev/null +++ b/apps/web/src/lib/components/ui/chart/chart-style.svelte @@ -0,0 +1,37 @@ + + +{#if themeContents} + {#key id} + + {themeContents} + + {/key} +{/if} diff --git a/apps/web/src/lib/components/ui/chart/chart-tooltip.svelte b/apps/web/src/lib/components/ui/chart/chart-tooltip.svelte new file mode 100644 index 0000000..efef55c --- /dev/null +++ b/apps/web/src/lib/components/ui/chart/chart-tooltip.svelte @@ -0,0 +1,159 @@ + + +{#snippet TooltipLabel()} + {#if formattedLabel} +
    + {#if typeof formattedLabel === "function"} + {@render formattedLabel()} + {:else} + {formattedLabel} + {/if} +
    + {/if} +{/snippet} + + +
    + {#if !nestLabel} + {@render TooltipLabel()} + {/if} +
    + {#each tooltipCtx.payload as item, i (item.key + i)} + {@const key = `${nameKey || item.key || item.name || "value"}`} + {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)} + {@const indicatorColor = color || item.payload?.color || item.color} +
    svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5", + indicator === "dot" && "items-center" + )} + > + {#if formatter && item.value !== undefined && item.name} + {@render formatter({ + value: item.value, + name: item.name, + item, + index: i, + payload: tooltipCtx.payload, + })} + {:else} + {#if itemConfig?.icon} + + {:else if !hideIndicator} +
    + {/if} +
    +
    + {#if nestLabel} + {@render TooltipLabel()} + {/if} + + {itemConfig?.label || item.name} + +
    + {#if item.value !== undefined} + + {item.value.toLocaleString()} + + {/if} +
    + {/if} +
    + {/each} +
    +
    +
    diff --git a/apps/web/src/lib/components/ui/chart/chart-utils.ts b/apps/web/src/lib/components/ui/chart/chart-utils.ts new file mode 100644 index 0000000..2decbbf --- /dev/null +++ b/apps/web/src/lib/components/ui/chart/chart-utils.ts @@ -0,0 +1,66 @@ +import type { Tooltip } from "layerchart"; +import { getContext, setContext, type Component, type ComponentProps, type Snippet } from "svelte"; + +export const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: string; + icon?: Component; + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record } + ); +}; + +export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never; + +export type TooltipPayload = ExtractSnippetParams< + ComponentProps["children"] +>["payload"][number]; + +// Helper to extract item config from a payload. +export function getPayloadConfigFromPayload( + config: ChartConfig, + payload: TooltipPayload, + key: string +) { + if (typeof payload !== "object" || payload === null) return undefined; + + const payloadPayload = + "payload" in payload && typeof payload.payload === "object" && payload.payload !== null + ? payload.payload + : undefined; + + let configLabelKey: string = key; + + if (payload.key === key) { + configLabelKey = payload.key; + } else if (payload.name === key) { + configLabelKey = payload.name; + } else if (key in payload && typeof payload[key as keyof typeof payload] === "string") { + configLabelKey = payload[key as keyof typeof payload] as string; + } else if ( + payloadPayload !== undefined && + key in payloadPayload && + typeof payloadPayload[key as keyof typeof payloadPayload] === "string" + ) { + configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string; + } + + return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]; +} + +type ChartContextValue = { + config: ChartConfig; +}; + +const chartContextKey = Symbol("chart-context"); + +export function setChartContext(value: ChartContextValue) { + return setContext(chartContextKey, value); +} + +export function useChart() { + return getContext(chartContextKey); +} diff --git a/apps/web/src/lib/components/ui/chart/index.ts b/apps/web/src/lib/components/ui/chart/index.ts new file mode 100644 index 0000000..f22375e --- /dev/null +++ b/apps/web/src/lib/components/ui/chart/index.ts @@ -0,0 +1,6 @@ +import ChartContainer from "./chart-container.svelte"; +import ChartTooltip from "./chart-tooltip.svelte"; + +export { getPayloadConfigFromPayload, type ChartConfig } from "./chart-utils.js"; + +export { ChartContainer, ChartTooltip, ChartContainer as Container, ChartTooltip as Tooltip }; diff --git a/apps/web/src/lib/components/ui/checkbox/checkbox.svelte b/apps/web/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..1622e05 --- /dev/null +++ b/apps/web/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,36 @@ + + + + {#snippet children({ checked, indeterminate })} +
    + {#if checked} + + {:else if indeterminate} + + {/if} +
    + {/snippet} +
    diff --git a/apps/web/src/lib/components/ui/checkbox/index.ts b/apps/web/src/lib/components/ui/checkbox/index.ts new file mode 100644 index 0000000..6d92d94 --- /dev/null +++ b/apps/web/src/lib/components/ui/checkbox/index.ts @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; diff --git a/apps/web/src/lib/components/ui/code/code-copy-button.svelte b/apps/web/src/lib/components/ui/code/code-copy-button.svelte new file mode 100644 index 0000000..fca75fc --- /dev/null +++ b/apps/web/src/lib/components/ui/code/code-copy-button.svelte @@ -0,0 +1,24 @@ + + + diff --git a/apps/web/src/lib/components/ui/code/code-overflow.svelte b/apps/web/src/lib/components/ui/code/code-overflow.svelte new file mode 100644 index 0000000..b702e69 --- /dev/null +++ b/apps/web/src/lib/components/ui/code/code-overflow.svelte @@ -0,0 +1,45 @@ + + +
    + {@render children?.()} + {#if collapsed} +
    + {/if} + {#if collapsed} + + {/if} +
    diff --git a/apps/web/src/lib/components/ui/code/code.svelte b/apps/web/src/lib/components/ui/code/code.svelte new file mode 100644 index 0000000..a5045c4 --- /dev/null +++ b/apps/web/src/lib/components/ui/code/code.svelte @@ -0,0 +1,101 @@ + + +
    + {@html codeState.highlighted} + {@render children?.()} +
    + + diff --git a/apps/web/src/lib/components/ui/code/code.svelte.ts b/apps/web/src/lib/components/ui/code/code.svelte.ts new file mode 100644 index 0000000..dc500fc --- /dev/null +++ b/apps/web/src/lib/components/ui/code/code.svelte.ts @@ -0,0 +1,125 @@ +import { Context } from "runed"; +import type { ReadableBoxedValues, WritableBoxedValues } from "svelte-toolbelt"; +import type { CodeRootProps } from "./types"; +import { highlighter } from "./shiki"; +import DOMPurify from "isomorphic-dompurify"; +import type { HighlighterCore } from "shiki"; + +type CodeOverflowStateProps = WritableBoxedValues<{ + collapsed: boolean; +}>; + +class CodeOverflowState { + constructor(readonly opts: CodeOverflowStateProps) { + this.toggleCollapsed = this.toggleCollapsed.bind(this); + } + + toggleCollapsed() { + this.opts.collapsed.current = !this.opts.collapsed.current; + } + + get collapsed() { + return this.opts.collapsed.current; + } +} + +type CodeRootStateProps = ReadableBoxedValues<{ + code: string; + lang: NonNullable; + hideLines: boolean; + highlight: CodeRootProps["highlight"]; +}>; + +class CodeRootState { + highlighter: HighlighterCore | null = $state(null); + + constructor( + readonly opts: CodeRootStateProps, + readonly overflow?: CodeOverflowState + ) { + highlighter.then((hl) => (this.highlighter = hl)); + } + + highlight(code: string) { + return this.highlighter?.codeToHtml(code, { + lang: this.opts.lang.current, + themes: { + light: "github-light-default", + dark: "github-dark-default" + }, + transformers: [ + { + pre: (el) => { + el.properties.style = ""; + + if (!this.opts.hideLines.current) { + el.properties.class += " line-numbers"; + } + + return el; + }, + line: (node, line) => { + if (within(line, this.opts.highlight.current)) { + node.properties.class = node.properties.class + " line--highlighted"; + } + + return node; + } + } + ] + }); + } + + get code() { + return this.opts.code.current; + } + + highlighted = $derived(DOMPurify.sanitize(this.highlight(this.code) ?? "")); +} + +function within(num: number, range: CodeRootProps["highlight"]) { + if (!range) return false; + + let within = false; + + for (const r of range) { + if (typeof r === "number") { + if (num === r) { + within = true; + break; + } + continue; + } + + if (r[0] <= num && num <= r[1]) { + within = true; + break; + } + } + + return within; +} + +class CodeCopyButtonState { + constructor(readonly root: CodeRootState) {} + + get code() { + return this.root.opts.code.current; + } +} + +const overflowCtx = new Context("code-overflow-state"); + +const ctx = new Context("code-root-state"); + +export function useCodeOverflow(props: CodeOverflowStateProps) { + return overflowCtx.set(new CodeOverflowState(props)); +} + +export function useCode(props: CodeRootStateProps) { + return ctx.set(new CodeRootState(props, overflowCtx.getOr(undefined))); +} + +export function useCodeCopyButton() { + return new CodeCopyButtonState(ctx.get()); +} diff --git a/apps/web/src/lib/components/ui/code/index.ts b/apps/web/src/lib/components/ui/code/index.ts new file mode 100644 index 0000000..3f18671 --- /dev/null +++ b/apps/web/src/lib/components/ui/code/index.ts @@ -0,0 +1,25 @@ +import { tv, type VariantProps } from "tailwind-variants"; +import Root from "./code.svelte"; +import Overflow from "./code-overflow.svelte"; +import CopyButton from "./code-copy-button.svelte"; +import type { CodeCopyButtonProps, CodeRootProps } from "./types"; + +export const codeVariants = tv({ + base: "not-prose relative h-full overflow-auto rounded-lg border", + variants: { + variant: { + default: "border-border bg-card", + secondary: "bg-secondary/50 border-transparent" + } + } +}); + +export type CodeVariant = VariantProps["variant"]; + +export { + Root, + CopyButton, + Overflow, + type CodeRootProps as RootProps, + type CodeCopyButtonProps as CopyButtonProps +}; diff --git a/apps/web/src/lib/components/ui/code/shiki.ts b/apps/web/src/lib/components/ui/code/shiki.ts new file mode 100644 index 0000000..60852f4 --- /dev/null +++ b/apps/web/src/lib/components/ui/code/shiki.ts @@ -0,0 +1,25 @@ +// Follows the best practices established in https://shiki.matsu.io/guide/best-performance +import { createJavaScriptRegexEngine } from "shiki/engine/javascript"; +import { createHighlighterCore } from "shiki/core"; + +const bundledLanguages = { + bash: () => import("@shikijs/langs/bash"), + diff: () => import("@shikijs/langs/diff"), + javascript: () => import("@shikijs/langs/javascript"), + json: () => import("@shikijs/langs/json"), + svelte: () => import("@shikijs/langs/svelte"), + typescript: () => import("@shikijs/langs/typescript") +}; + +/** The languages configured for the highlighter */ +export type SupportedLanguage = keyof typeof bundledLanguages; + +/** A preloaded highlighter instance. */ +export const highlighter = createHighlighterCore({ + themes: [ + import("@shikijs/themes/github-light-default"), + import("@shikijs/themes/github-dark-default") + ], + langs: Object.entries(bundledLanguages).map(([_, lang]) => lang), + engine: createJavaScriptRegexEngine() +}); diff --git a/apps/web/src/lib/components/ui/code/types.ts b/apps/web/src/lib/components/ui/code/types.ts new file mode 100644 index 0000000..1262282 --- /dev/null +++ b/apps/web/src/lib/components/ui/code/types.ts @@ -0,0 +1,30 @@ +import type { WithChildren, WithoutChildren } from "bits-ui"; +import type { CodeVariant } from "."; +import type { SupportedLanguage } from "./shiki"; +import type { HTMLAttributes } from "svelte/elements"; +import type { CopyButtonPropsWithoutHTML } from "$lib/components/ui/copy-button/types"; + +export type CodeRootPropsWithoutHTML = WithChildren<{ + ref?: HTMLDivElement | null; + variant?: CodeVariant; + lang?: SupportedLanguage; + code: string; + class?: string; + hideLines?: boolean; + highlight?: (number | [number, number])[]; +}>; + +export type CodeRootProps = CodeRootPropsWithoutHTML & + WithoutChildren>; + +export type CodeCopyButtonPropsWithoutHTML = Omit; + +export type CodeCopyButtonProps = CodeCopyButtonPropsWithoutHTML & + WithoutChildren>; + +export type CodeOverflowPropsWithoutHTML = WithChildren<{ + collapsed?: boolean; +}>; + +export type CodeOverflowProps = CodeOverflowPropsWithoutHTML & + WithoutChildren>; diff --git a/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte b/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..de3fc11 --- /dev/null +++ b/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..9f49f01 --- /dev/null +++ b/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/collapsible/collapsible.svelte b/apps/web/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..11a7013 --- /dev/null +++ b/apps/web/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/collapsible/index.ts b/apps/web/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..88de73b --- /dev/null +++ b/apps/web/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,15 @@ + + +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger +}; diff --git a/apps/web/src/lib/components/ui/command/command-dialog.svelte b/apps/web/src/lib/components/ui/command/command-dialog.svelte new file mode 100644 index 0000000..5c9a82a --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-dialog.svelte @@ -0,0 +1,40 @@ + + + + + {title} + {description} + + + + + diff --git a/apps/web/src/lib/components/ui/command/command-empty.svelte b/apps/web/src/lib/components/ui/command/command-empty.svelte new file mode 100644 index 0000000..6726cd8 --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-empty.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/command-group.svelte b/apps/web/src/lib/components/ui/command/command-group.svelte new file mode 100644 index 0000000..104f817 --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-group.svelte @@ -0,0 +1,32 @@ + + + + {#if heading} + + {heading} + + {/if} + + diff --git a/apps/web/src/lib/components/ui/command/command-input.svelte b/apps/web/src/lib/components/ui/command/command-input.svelte new file mode 100644 index 0000000..611b00d --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-input.svelte @@ -0,0 +1,26 @@ + + +
    + + +
    diff --git a/apps/web/src/lib/components/ui/command/command-item.svelte b/apps/web/src/lib/components/ui/command/command-item.svelte new file mode 100644 index 0000000..d94d07f --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-item.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/command-link-item.svelte b/apps/web/src/lib/components/ui/command/command-link-item.svelte new file mode 100644 index 0000000..944c22d --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-link-item.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/command-list.svelte b/apps/web/src/lib/components/ui/command/command-list.svelte new file mode 100644 index 0000000..569f595 --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-list.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/command-separator.svelte b/apps/web/src/lib/components/ui/command/command-separator.svelte new file mode 100644 index 0000000..35c4c95 --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/command-shortcut.svelte b/apps/web/src/lib/components/ui/command/command-shortcut.svelte new file mode 100644 index 0000000..3d68bc5 --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/command/command.svelte b/apps/web/src/lib/components/ui/command/command.svelte new file mode 100644 index 0000000..c64a77e --- /dev/null +++ b/apps/web/src/lib/components/ui/command/command.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/web/src/lib/components/ui/command/index.ts b/apps/web/src/lib/components/ui/command/index.ts new file mode 100644 index 0000000..d3dbade --- /dev/null +++ b/apps/web/src/lib/components/ui/command/index.ts @@ -0,0 +1,40 @@ +import { Command as CommandPrimitive } from "bits-ui"; + +import Root from "./command.svelte"; +import Dialog from "./command-dialog.svelte"; +import Empty from "./command-empty.svelte"; +import Group from "./command-group.svelte"; +import Item from "./command-item.svelte"; +import Input from "./command-input.svelte"; +import List from "./command-list.svelte"; +import Separator from "./command-separator.svelte"; +import Shortcut from "./command-shortcut.svelte"; +import LinkItem from "./command-link-item.svelte"; + +const Loading = CommandPrimitive.Loading; + +export { + Root, + Dialog, + Empty, + Group, + Item, + LinkItem, + Input, + List, + Separator, + Shortcut, + Loading, + // + Root as Command, + Dialog as CommandDialog, + Empty as CommandEmpty, + Group as CommandGroup, + Item as CommandItem, + LinkItem as CommandLinkItem, + Input as CommandInput, + List as CommandList, + Separator as CommandSeparator, + Shortcut as CommandShortcut, + Loading as CommandLoading, +}; diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte new file mode 100644 index 0000000..ccafce2 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-content.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-content.svelte new file mode 100644 index 0000000..e793938 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-content.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-group-heading.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-group-heading.svelte new file mode 100644 index 0000000..66a81b3 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-group-heading.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-group.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-group.svelte new file mode 100644 index 0000000..c7c1e06 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-item.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-item.svelte new file mode 100644 index 0000000..9193d18 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-label.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-label.svelte new file mode 100644 index 0000000..7d05037 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-radio-group.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-radio-group.svelte new file mode 100644 index 0000000..964cb55 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-radio-item.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-radio-item.svelte new file mode 100644 index 0000000..7673f01 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-separator.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-separator.svelte new file mode 100644 index 0000000..7f5b237 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-shortcut.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-shortcut.svelte new file mode 100644 index 0000000..7eca8e0 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-sub-content.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-sub-content.svelte new file mode 100644 index 0000000..e0245b1 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte new file mode 100644 index 0000000..ba00be9 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/context-menu/context-menu-trigger.svelte b/apps/web/src/lib/components/ui/context-menu/context-menu-trigger.svelte new file mode 100644 index 0000000..3efa857 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/context-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/context-menu/index.ts b/apps/web/src/lib/components/ui/context-menu/index.ts new file mode 100644 index 0000000..fce8160 --- /dev/null +++ b/apps/web/src/lib/components/ui/context-menu/index.ts @@ -0,0 +1,51 @@ +import { ContextMenu as ContextMenuPrimitive } from "bits-ui"; + +import Trigger from "./context-menu-trigger.svelte"; +import Group from "./context-menu-group.svelte"; +import RadioGroup from "./context-menu-radio-group.svelte"; +import Item from "./context-menu-item.svelte"; +import GroupHeading from "./context-menu-group-heading.svelte"; +import Content from "./context-menu-content.svelte"; +import Shortcut from "./context-menu-shortcut.svelte"; +import RadioItem from "./context-menu-radio-item.svelte"; +import Separator from "./context-menu-separator.svelte"; +import SubContent from "./context-menu-sub-content.svelte"; +import SubTrigger from "./context-menu-sub-trigger.svelte"; +import CheckboxItem from "./context-menu-checkbox-item.svelte"; +import Label from "./context-menu-label.svelte"; +const Sub = ContextMenuPrimitive.Sub; +const Root = ContextMenuPrimitive.Root; + +export { + Sub, + Root, + Item, + GroupHeading, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as ContextMenu, + Sub as ContextMenuSub, + Item as ContextMenuItem, + GroupHeading as ContextMenuGroupHeading, + Group as ContextMenuGroup, + Content as ContextMenuContent, + Trigger as ContextMenuTrigger, + Shortcut as ContextMenuShortcut, + RadioItem as ContextMenuRadioItem, + Separator as ContextMenuSeparator, + RadioGroup as ContextMenuRadioGroup, + SubContent as ContextMenuSubContent, + SubTrigger as ContextMenuSubTrigger, + CheckboxItem as ContextMenuCheckboxItem, + Label as ContextMenuLabel, +}; diff --git a/apps/web/src/lib/components/ui/copy-button/copy-button.svelte b/apps/web/src/lib/components/ui/copy-button/copy-button.svelte new file mode 100644 index 0000000..e3e3ce3 --- /dev/null +++ b/apps/web/src/lib/components/ui/copy-button/copy-button.svelte @@ -0,0 +1,69 @@ + + + diff --git a/apps/web/src/lib/components/ui/copy-button/index.ts b/apps/web/src/lib/components/ui/copy-button/index.ts new file mode 100644 index 0000000..93a5e8d --- /dev/null +++ b/apps/web/src/lib/components/ui/copy-button/index.ts @@ -0,0 +1,3 @@ +import CopyButton from "./copy-button.svelte"; + +export { CopyButton }; diff --git a/apps/web/src/lib/components/ui/copy-button/types.ts b/apps/web/src/lib/components/ui/copy-button/types.ts new file mode 100644 index 0000000..ad4fe7d --- /dev/null +++ b/apps/web/src/lib/components/ui/copy-button/types.ts @@ -0,0 +1,18 @@ +import type { Snippet } from "svelte"; +import type { ButtonPropsWithoutHTML } from "$lib/components/ui/button"; +import type { UseClipboard } from "$lib/hooks/use-clipboard.svelte"; +import type { HTMLAttributes } from "svelte/elements"; +import type { WithChildren, WithoutChildren } from "bits-ui"; + +export type CopyButtonPropsWithoutHTML = WithChildren< + Pick & { + ref?: HTMLButtonElement | null; + text: string; + icon?: Snippet<[]>; + animationDuration?: number; + onCopy?: (status: UseClipboard["status"]) => void; + } +>; + +export type CopyButtonProps = CopyButtonPropsWithoutHTML & + WithoutChildren>; diff --git a/apps/web/src/lib/components/ui/data-table/data-table.svelte.ts b/apps/web/src/lib/components/ui/data-table/data-table.svelte.ts new file mode 100644 index 0000000..9e0b913 --- /dev/null +++ b/apps/web/src/lib/components/ui/data-table/data-table.svelte.ts @@ -0,0 +1,141 @@ +import { + type RowData, + type TableOptions, + type TableOptionsResolved, + type TableState, + createTable, +} from "@tanstack/table-core"; + +/** + * Creates a reactive TanStack table object for Svelte. + * @param options Table options to create the table with. + * @returns A reactive table object. + * @example + * ```svelte + * + * + * + * + * {#each table.getHeaderGroups() as headerGroup} + * + * {#each headerGroup.headers as header} + * + * {/each} + * + * {/each} + * + * + *
    + * + *
    + * ``` + */ +export function createSvelteTable(options: TableOptions) { + const resolvedOptions: TableOptionsResolved = mergeObjects( + { + state: {}, + onStateChange() {}, + renderFallbackValue: null, + mergeOptions: ( + defaultOptions: TableOptions, + options: Partial> + ) => { + return mergeObjects(defaultOptions, options); + }, + }, + options + ); + + const table = createTable(resolvedOptions); + let state = $state>(table.initialState); + + function updateOptions() { + table.setOptions((prev) => { + return mergeObjects(prev, options, { + state: mergeObjects(state, options.state || {}), + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onStateChange: (updater: any) => { + if (updater instanceof Function) state = updater(state); + else state = mergeObjects(state, updater); + + options.onStateChange?.(updater); + }, + }); + }); + } + + updateOptions(); + + $effect.pre(() => { + updateOptions(); + }); + + return table; +} + +type MaybeThunk = T | (() => T | null | undefined); +type Intersection = (T extends [infer H, ...infer R] + ? H & Intersection + : unknown) & {}; + +/** + * Lazily merges several objects (or thunks) while preserving + * getter semantics from every source. + * + * Proxy-based to avoid known WebKit recursion issue. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function mergeObjects[]>( + ...sources: Sources +): Intersection<{ [K in keyof Sources]: Sources[K] }> { + const resolve = (src: MaybeThunk): T | undefined => + typeof src === "function" ? (src() ?? undefined) : src; + + const findSourceWithKey = (key: PropertyKey) => { + for (let i = sources.length - 1; i >= 0; i--) { + const obj = resolve(sources[i]); + if (obj && key in obj) return obj; + } + return undefined; + }; + + return new Proxy(Object.create(null), { + get(_, key) { + const src = findSourceWithKey(key); + + return src?.[key as never]; + }, + + has(_, key) { + return !!findSourceWithKey(key); + }, + + ownKeys(): (string | symbol)[] { + const all = new Set(); + for (const s of sources) { + const obj = resolve(s); + if (obj) { + for (const k of Reflect.ownKeys(obj) as (string | symbol)[]) { + all.add(k); + } + } + } + return [...all]; + }, + + getOwnPropertyDescriptor(_, key) { + const src = findSourceWithKey(key); + if (!src) return undefined; + return { + configurable: true, + enumerable: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: (src as any)[key], + writable: true, + }; + }, + }) as Intersection<{ [K in keyof Sources]: Sources[K] }>; +} diff --git a/apps/web/src/lib/components/ui/data-table/flex-render.svelte b/apps/web/src/lib/components/ui/data-table/flex-render.svelte new file mode 100644 index 0000000..12d2af1 --- /dev/null +++ b/apps/web/src/lib/components/ui/data-table/flex-render.svelte @@ -0,0 +1,36 @@ + + +{#if typeof content === "string"} + {content} +{:else if content instanceof Function} + + + {@const result = content(context as any)} + {#if result instanceof RenderComponentConfig} + {@const { component: Component, props } = result} + + {:else if result instanceof RenderSnippetConfig} + {@const { snippet, params } = result} + {@render snippet(params)} + {:else} + {result} + {/if} +{/if} diff --git a/apps/web/src/lib/components/ui/data-table/index.ts b/apps/web/src/lib/components/ui/data-table/index.ts new file mode 100644 index 0000000..5f4e77e --- /dev/null +++ b/apps/web/src/lib/components/ui/data-table/index.ts @@ -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"; diff --git a/apps/web/src/lib/components/ui/data-table/render-helpers.ts b/apps/web/src/lib/components/ui/data-table/render-helpers.ts new file mode 100644 index 0000000..fa036d6 --- /dev/null +++ b/apps/web/src/lib/components/ui/data-table/render-helpers.ts @@ -0,0 +1,111 @@ +import type { Component, ComponentProps, Snippet } from "svelte"; + +/** + * A helper class to make it easy to identify Svelte components in + * `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderComponentConfig} + * {@const { component: Component, props } = result} + * + * {/if} + * ``` + */ +export class RenderComponentConfig { + component: TComponent; + props: ComponentProps | Record; + constructor( + component: TComponent, + props: ComponentProps | Record = {} + ) { + this.component = component; + this.props = props; + } +} + +/** + * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderSnippetConfig} + * {@const { snippet, params } = result} + * {@render snippet(params)} + * {/if} + * ``` + */ +export class RenderSnippetConfig { + snippet: Snippet<[TProps]>; + params: TProps; + constructor(snippet: Snippet<[TProps]>, params: TProps) { + this.snippet = snippet; + this.params = params; + } +} + +/** + * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. + * + * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. + * + * @param component A Svelte component + * @param props The props to pass to `component` + * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * header: header => renderComponent(SortHeader, { label: 'Name', header }), + * }), + * columnHelper.accessor('state', { + * header: header => renderComponent(SortHeader, { label: 'State', header }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderComponent< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends Component, + Props extends ComponentProps, +>(component: T, props: Props = {} as Props) { + return new RenderComponentConfig(component, props); +} + +/** + * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. + * + * The snippet must only take one parameter. + * + * This is only to be used with Snippets - use `renderComponent` for Svelte Components. + * + * @param snippet + * @param params + * @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), + * }), + * columnHelper.accessor('state', { + * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderSnippet(snippet: Snippet<[TProps]>, params: TProps = {} as TProps) { + return new RenderSnippetConfig(snippet, params); +} diff --git a/apps/web/src/lib/components/ui/dialog/dialog-close.svelte b/apps/web/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..e8a96a7 --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/dialog/dialog-content.svelte b/apps/web/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..e37987e --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,43 @@ + + + + + + {@render children?.()} + {#if !hideClose} + + + Close + + {/if} + + diff --git a/apps/web/src/lib/components/ui/dialog/dialog-description.svelte b/apps/web/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..1337d2e --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/dialog/dialog-footer.svelte b/apps/web/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..808ff1d --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/dialog/dialog-header.svelte b/apps/web/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..e1000b0 --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/dialog/dialog-overlay.svelte b/apps/web/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..0f23226 --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/dialog/dialog-title.svelte b/apps/web/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..3fdd53b --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/dialog/dialog-trigger.svelte b/apps/web/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..ac04d9f --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/dialog/index.ts b/apps/web/src/lib/components/ui/dialog/index.ts new file mode 100644 index 0000000..358c234 --- /dev/null +++ b/apps/web/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,37 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +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"; + +const Root = DialogPrimitive.Root; +const Portal = DialogPrimitive.Portal; + +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 +}; diff --git a/apps/web/src/lib/components/ui/drawer/drawer-close.svelte b/apps/web/src/lib/components/ui/drawer/drawer-close.svelte new file mode 100644 index 0000000..95c2479 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-content.svelte b/apps/web/src/lib/components/ui/drawer/drawer-content.svelte new file mode 100644 index 0000000..f20e9ff --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-content.svelte @@ -0,0 +1,37 @@ + + + + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-description.svelte b/apps/web/src/lib/components/ui/drawer/drawer-description.svelte new file mode 100644 index 0000000..2763a1a --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-footer.svelte b/apps/web/src/lib/components/ui/drawer/drawer-footer.svelte new file mode 100644 index 0000000..1691f58 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/drawer/drawer-header.svelte b/apps/web/src/lib/components/ui/drawer/drawer-header.svelte new file mode 100644 index 0000000..65d2de5 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/drawer/drawer-nested.svelte b/apps/web/src/lib/components/ui/drawer/drawer-nested.svelte new file mode 100644 index 0000000..834af94 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-nested.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-overlay.svelte b/apps/web/src/lib/components/ui/drawer/drawer-overlay.svelte new file mode 100644 index 0000000..53f78a2 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-title.svelte b/apps/web/src/lib/components/ui/drawer/drawer-title.svelte new file mode 100644 index 0000000..a2e5761 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer-trigger.svelte b/apps/web/src/lib/components/ui/drawer/drawer-trigger.svelte new file mode 100644 index 0000000..f1877d8 --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/drawer.svelte b/apps/web/src/lib/components/ui/drawer/drawer.svelte new file mode 100644 index 0000000..0cb57ff --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/drawer.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/drawer/index.ts b/apps/web/src/lib/components/ui/drawer/index.ts new file mode 100644 index 0000000..cfbdb8b --- /dev/null +++ b/apps/web/src/lib/components/ui/drawer/index.ts @@ -0,0 +1,41 @@ +import { Drawer as DrawerPrimitive } from "vaul-svelte"; + +import Root from "./drawer.svelte"; +import Content from "./drawer-content.svelte"; +import Description from "./drawer-description.svelte"; +import Overlay from "./drawer-overlay.svelte"; +import Footer from "./drawer-footer.svelte"; +import Header from "./drawer-header.svelte"; +import Title from "./drawer-title.svelte"; +import NestedRoot from "./drawer-nested.svelte"; +import Close from "./drawer-close.svelte"; +import Trigger from "./drawer-trigger.svelte"; + +const Portal: typeof DrawerPrimitive.Portal = DrawerPrimitive.Portal; + +export { + Root, + NestedRoot, + Content, + Description, + Overlay, + Footer, + Header, + Title, + Trigger, + Portal, + Close, + + // + Root as Drawer, + NestedRoot as DrawerNestedRoot, + Content as DrawerContent, + Description as DrawerDescription, + Overlay as DrawerOverlay, + Footer as DrawerFooter, + Header as DrawerHeader, + Title as DrawerTitle, + Trigger as DrawerTrigger, + Portal as DrawerPortal, + Close as DrawerClose, +}; diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..63685e9 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..f26de15 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,29 @@ + + + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..3771dbc --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,24 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..c5ac264 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..b6dba87 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..f81cbd2 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,26 @@ + + + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..8e98957 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..82d82a2 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,33 @@ + + + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..3791de4 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..e7716b9 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,22 @@ + + + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..f98188f --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..d8d475c --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,31 @@ + + + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..3dcc922 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/dropdown-menu/index.ts b/apps/web/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..dfd9631 --- /dev/null +++ b/apps/web/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,51 @@ + + +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +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"; +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + 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 +}; diff --git a/apps/web/src/lib/components/ui/file-drop-zone/file-drop-zone.svelte b/apps/web/src/lib/components/ui/file-drop-zone/file-drop-zone.svelte new file mode 100644 index 0000000..7bb1297 --- /dev/null +++ b/apps/web/src/lib/components/ui/file-drop-zone/file-drop-zone.svelte @@ -0,0 +1,172 @@ + + + diff --git a/apps/web/src/lib/components/ui/file-drop-zone/index.ts b/apps/web/src/lib/components/ui/file-drop-zone/index.ts new file mode 100644 index 0000000..6d64600 --- /dev/null +++ b/apps/web/src/lib/components/ui/file-drop-zone/index.ts @@ -0,0 +1,25 @@ +import FileDropZone from "./file-drop-zone.svelte"; +import { type FileRejectedReason, type FileDropZoneProps } from "./types"; + +export const displaySize = (bytes: number): string => { + if (bytes < KILOBYTE) return `${bytes.toFixed(0)} B`; + + if (bytes < MEGABYTE) return `${(bytes / KILOBYTE).toFixed(0)} KB`; + + if (bytes < GIGABYTE) return `${(bytes / MEGABYTE).toFixed(0)} MB`; + + return `${(bytes / GIGABYTE).toFixed(0)} GB`; +}; + +// Utilities for working with file sizes +export const BYTE = 1; +export const KILOBYTE = 1024; +export const MEGABYTE = 1024 * KILOBYTE; +export const GIGABYTE = 1024 * MEGABYTE; + +// utilities for limiting accepted files +export const ACCEPT_IMAGE = "image/*"; +export const ACCEPT_VIDEO = "video/*"; +export const ACCEPT_AUDIO = "audio/*"; + +export { FileDropZone, type FileRejectedReason, type FileDropZoneProps }; diff --git a/apps/web/src/lib/components/ui/file-drop-zone/types.ts b/apps/web/src/lib/components/ui/file-drop-zone/types.ts new file mode 100644 index 0000000..3b97808 --- /dev/null +++ b/apps/web/src/lib/components/ui/file-drop-zone/types.ts @@ -0,0 +1,47 @@ +import type { WithChildren } from "bits-ui"; +import type { HTMLInputAttributes } from "svelte/elements"; + +export type FileRejectedReason = + | "Maximum file size exceeded" + | "File type not allowed" + | "Maximum files uploaded"; + +export type FileDropZonePropsWithoutHTML = WithChildren<{ + ref?: HTMLInputElement | null; + /** Called with the uploaded files when the user drops or clicks and selects their files. + * + * @param files + */ + onUpload: (files: File[]) => Promise; + /** The maximum amount files allowed to be uploaded */ + maxFiles?: number; + fileCount?: number; + /** The maximum size of a file in bytes */ + maxFileSize?: number; + /** Called when a file does not meet the upload criteria (size, or type) */ + onFileRejected?: (opts: { reason: FileRejectedReason; file: File }) => void; + + // just for extra documentation + /** Takes a comma separated list of one or more file types. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept) + * + * ### Usage + * ```svelte + * + * ``` + * + * ### Common Values + * ```svelte + * + * + * + * ``` + */ + accept?: string; +}>; + +export type FileDropZoneProps = FileDropZonePropsWithoutHTML & + Omit; diff --git a/apps/web/src/lib/components/ui/form/form-button.svelte b/apps/web/src/lib/components/ui/form/form-button.svelte new file mode 100644 index 0000000..cc0c590 --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-button.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/form/form-description.svelte b/apps/web/src/lib/components/ui/form/form-description.svelte new file mode 100644 index 0000000..a5f42be --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/form/form-element-field.svelte b/apps/web/src/lib/components/ui/form/form-element-field.svelte new file mode 100644 index 0000000..c3ba111 --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-element-field.svelte @@ -0,0 +1,24 @@ + + + + {#snippet children({ constraints, errors, tainted, value })} +
    + {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })} +
    + {/snippet} +
    diff --git a/apps/web/src/lib/components/ui/form/form-field-errors.svelte b/apps/web/src/lib/components/ui/form/form-field-errors.svelte new file mode 100644 index 0000000..b4c6fba --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-field-errors.svelte @@ -0,0 +1,30 @@ + + + + {#snippet children({ errors, errorProps })} + {#if childrenProp} + {@render childrenProp({ errors, errorProps })} + {:else} + {#each errors as error (error)} +
    {error}
    + {/each} + {/if} + {/snippet} +
    diff --git a/apps/web/src/lib/components/ui/form/form-field.svelte b/apps/web/src/lib/components/ui/form/form-field.svelte new file mode 100644 index 0000000..7481fda --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-field.svelte @@ -0,0 +1,29 @@ + + + + {#snippet children({ constraints, errors, tainted, value })} +
    + {@render childrenProp?.({ constraints, errors, tainted, value: value as T[U] })} +
    + {/snippet} +
    diff --git a/apps/web/src/lib/components/ui/form/form-fieldset.svelte b/apps/web/src/lib/components/ui/form/form-fieldset.svelte new file mode 100644 index 0000000..2c85857 --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-fieldset.svelte @@ -0,0 +1,15 @@ + + + diff --git a/apps/web/src/lib/components/ui/form/form-label.svelte b/apps/web/src/lib/components/ui/form/form-label.svelte new file mode 100644 index 0000000..8749360 --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-label.svelte @@ -0,0 +1,24 @@ + + + + {#snippet child({ props })} + + {/snippet} + diff --git a/apps/web/src/lib/components/ui/form/form-legend.svelte b/apps/web/src/lib/components/ui/form/form-legend.svelte new file mode 100644 index 0000000..9d52f6a --- /dev/null +++ b/apps/web/src/lib/components/ui/form/form-legend.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/form/index.ts b/apps/web/src/lib/components/ui/form/index.ts new file mode 100644 index 0000000..0713927 --- /dev/null +++ b/apps/web/src/lib/components/ui/form/index.ts @@ -0,0 +1,33 @@ +import * as FormPrimitive from "formsnap"; +import Description from "./form-description.svelte"; +import Label from "./form-label.svelte"; +import FieldErrors from "./form-field-errors.svelte"; +import Field from "./form-field.svelte"; +import Fieldset from "./form-fieldset.svelte"; +import Legend from "./form-legend.svelte"; +import ElementField from "./form-element-field.svelte"; +import Button from "./form-button.svelte"; + +const Control = FormPrimitive.Control; + +export { + Field, + Control, + Label, + Button, + FieldErrors, + Description, + Fieldset, + Legend, + ElementField, + // + Field as FormField, + Control as FormControl, + Description as FormDescription, + Label as FormLabel, + FieldErrors as FormFieldErrors, + Fieldset as FormFieldset, + Legend as FormLegend, + ElementField as FormElementField, + Button as FormButton, +}; diff --git a/apps/web/src/lib/components/ui/hover-card/hover-card-content.svelte b/apps/web/src/lib/components/ui/hover-card/hover-card-content.svelte new file mode 100644 index 0000000..e1d592a --- /dev/null +++ b/apps/web/src/lib/components/ui/hover-card/hover-card-content.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/hover-card/hover-card-trigger.svelte b/apps/web/src/lib/components/ui/hover-card/hover-card-trigger.svelte new file mode 100644 index 0000000..322172b --- /dev/null +++ b/apps/web/src/lib/components/ui/hover-card/hover-card-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/hover-card/index.ts b/apps/web/src/lib/components/ui/hover-card/index.ts new file mode 100644 index 0000000..85f3949 --- /dev/null +++ b/apps/web/src/lib/components/ui/hover-card/index.ts @@ -0,0 +1,14 @@ +import { LinkPreview as HoverCardPrimitive } from "bits-ui"; +import Content from "./hover-card-content.svelte"; +import Trigger from "./hover-card-trigger.svelte"; + +const Root = HoverCardPrimitive.Root; + +export { + Root, + Content, + Trigger, + Root as HoverCard, + Content as HoverCardContent, + Trigger as HoverCardTrigger, +}; diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-cancel.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-cancel.svelte new file mode 100644 index 0000000..00fe531 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-cancel.svelte @@ -0,0 +1,34 @@ + + + diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-controls.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-controls.svelte new file mode 100644 index 0000000..bb3bb30 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-controls.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-crop.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-crop.svelte new file mode 100644 index 0000000..5a1e6c1 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-crop.svelte @@ -0,0 +1,34 @@ + + + diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-cropper.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-cropper.svelte new file mode 100644 index 0000000..1092edc --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-cropper.svelte @@ -0,0 +1,26 @@ + + + +
    + +
    diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-dialog.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-dialog.svelte new file mode 100644 index 0000000..3f6cc41 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-dialog.svelte @@ -0,0 +1,25 @@ + + + + +
    + {@render children?.()} +
    +
    +
    diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-preview.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-preview.svelte new file mode 100644 index 0000000..f571a66 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-preview.svelte @@ -0,0 +1,25 @@ + + +{#if child} + {@render child({ src: previewState.rootState.src })} +{:else} + + + + + Upload image + + +{/if} diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper-upload-trigger.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper-upload-trigger.svelte new file mode 100644 index 0000000..a57c7c7 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper-upload-trigger.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte b/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte new file mode 100644 index 0000000..9043f6c --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte @@ -0,0 +1,43 @@ + + +{@render children?.()} + { + const file = e.currentTarget.files?.[0]; + if (!file) return; + rootState.onUpload(file); + // reset so that we can reupload the same file + (e.target! as HTMLInputElement).value = ''; + }} + type="file" + {id} + style="display: none;" +/> diff --git a/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte.ts b/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte.ts new file mode 100644 index 0000000..d1241e2 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/image-cropper.svelte.ts @@ -0,0 +1,167 @@ +import type { ReadableBoxedValues, WritableBoxedValues } from "svelte-toolbelt"; +import { Context } from "runed"; +import type { CropArea, DispatchEvents } from "svelte-easy-crop"; +import { getCroppedImg } from "./utils"; + +// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/img#supported_image_formats +export const VALID_IMAGE_TYPES = [ + "image/apng", + "image/avif", + "image/gif", + "image/jpeg", + "image/png", + "image/svg+xml", + "image/webp" +]; + +export type ImageCropperRootProps = WritableBoxedValues<{ + src: string; +}> & + ReadableBoxedValues<{ + id: string; + onCropped: (url: string) => void; + onUnsupportedFile: (file: File) => void; + }>; + +class ImageCropperRootState { + #createdUrls = $state([]); + open = $state(false); + tempUrl = $state(); + pixelCrop = $state(); + + constructor(readonly opts: ImageCropperRootProps) { + this.onUpload = this.onUpload.bind(this); + this.onCancel = this.onCancel.bind(this); + this.onCrop = this.onCrop.bind(this); + this.dispose = this.dispose.bind(this); + } + + onUpload(file: File) { + if (!VALID_IMAGE_TYPES.includes(file.type)) { + this.opts.onUnsupportedFile.current(file); + return; + } + + this.tempUrl = URL.createObjectURL(file); + this.#createdUrls.push(this.tempUrl); + this.open = true; + } + + onCancel() { + this.tempUrl = undefined; + this.open = false; + this.pixelCrop = undefined; + } + + async onCrop() { + if (!this.pixelCrop || !this.tempUrl) return; + + this.opts.src.current = await getCroppedImg(this.tempUrl, this.pixelCrop); + + this.open = false; + + this.opts.onCropped.current(this.opts.src.current); + } + + get src() { + return this.opts.src.current; + } + + get id() { + return this.opts.id.current; + } + + dispose() { + for (const url of this.#createdUrls) { + URL.revokeObjectURL(url); + } + } +} + +export type ImageCropperTriggerProps = ReadableBoxedValues<{ + id?: string; +}>; + +class ImageCropperTriggerState { + constructor(readonly rootState: ImageCropperRootState) {} +} + +class ImageCropperPreviewState { + constructor(readonly rootState: ImageCropperRootState) {} +} + +class ImageCropperDialogState { + constructor(readonly rootState: ImageCropperRootState) {} +} + +class ImageCropperCropperState { + constructor(readonly rootState: ImageCropperRootState) { + this.onCropComplete = this.onCropComplete.bind(this); + } + + onCropComplete(e: DispatchEvents["cropcomplete"]) { + this.rootState.pixelCrop = e.pixels; + } +} + +class ImageCropperCropState { + constructor(readonly rootState: ImageCropperRootState) { + this.onclick = this.onclick.bind(this); + } + + onclick() { + this.rootState.onCrop(); + } +} + +class ImageCropperCancelState { + constructor(readonly rootState: ImageCropperRootState) { + this.onclick = this.onclick.bind(this); + } + + onclick() { + this.rootState.onCancel(); + } +} + +const ImageCropperRootContext = new Context("ImageCropper.Root"); + +export const useImageCropperRoot = (props: ImageCropperRootProps) => { + return ImageCropperRootContext.set(new ImageCropperRootState(props)); +}; + +export const useImageCropperTrigger = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperTriggerState(rootState); +}; + +export const useImageCropperPreview = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperPreviewState(rootState); +}; + +export const useImageCropperDialog = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperDialogState(rootState); +}; + +export const useImageCropperCropper = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperCropperState(rootState); +}; + +export const useImageCropperCrop = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperCropState(rootState); +}; + +export const useImageCropperCancel = () => { + const rootState = ImageCropperRootContext.get(); + + return new ImageCropperCancelState(rootState); +}; diff --git a/apps/web/src/lib/components/ui/image-cropper/index.ts b/apps/web/src/lib/components/ui/image-cropper/index.ts new file mode 100644 index 0000000..81e5ca9 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/index.ts @@ -0,0 +1,13 @@ +import Root from "./image-cropper.svelte"; +import UploadTrigger from "./image-cropper-upload-trigger.svelte"; +import Preview from "./image-cropper-preview.svelte"; +import Dialog from "./image-cropper-dialog.svelte"; +import Cropper from "./image-cropper-cropper.svelte"; +import Controls from "./image-cropper-controls.svelte"; +import Crop from "./image-cropper-crop.svelte"; +import Cancel from "./image-cropper-cancel.svelte"; +import { getFileFromUrl } from "./utils"; + +export { Root, UploadTrigger, Preview, Dialog, Cropper, Controls, Crop, Cancel, getFileFromUrl }; + +export type * from "./types"; diff --git a/apps/web/src/lib/components/ui/image-cropper/types.ts b/apps/web/src/lib/components/ui/image-cropper/types.ts new file mode 100644 index 0000000..3fb43a1 --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/types.ts @@ -0,0 +1,44 @@ +import type { + AvatarRootProps, + DialogContentProps, + WithChildren, + WithoutChild, + WithoutChildren +} from "bits-ui"; +import type { Snippet } from "svelte"; +import type { CropperProps } from "svelte-easy-crop"; +import type { HTMLAttributes, HTMLInputAttributes } from "svelte/elements"; + +export type ImageCropperRootPropsWithoutHTML = WithChildren<{ + id?: string; + src?: string; + onCropped?: (url: string) => void; + onUnsupportedFile?: (file: File) => void; +}>; + +export type ImageCropperRootProps = ImageCropperRootPropsWithoutHTML & HTMLInputAttributes; + +export type ImageCropperDialogProps = DialogContentProps; + +export type ImageCropperCropperProps = Omit, "oncropcomplete" | "image">; + +export type ImageCropperControlsWithoutHTML = WithChildren<{ + ref?: HTMLDivElement | null; +}>; + +export type ImageCropperControlsProps = ImageCropperControlsWithoutHTML & + WithoutChildren>; + +export type ImageCropperPreviewPropsWithoutHTML = { + child?: Snippet<[{ src: string }]>; +}; + +export type ImageCropperPreviewProps = ImageCropperPreviewPropsWithoutHTML & + WithoutChild; + +export type ImageCropperUploadTriggerPropsWithoutHTML = WithChildren<{ + ref?: HTMLLabelElement | null; +}>; + +export type ImageCropperUploadTriggerProps = ImageCropperUploadTriggerPropsWithoutHTML & + WithoutChildren>; diff --git a/apps/web/src/lib/components/ui/image-cropper/utils.ts b/apps/web/src/lib/components/ui/image-cropper/utils.ts new file mode 100644 index 0000000..98b74bb --- /dev/null +++ b/apps/web/src/lib/components/ui/image-cropper/utils.ts @@ -0,0 +1,85 @@ +import type { CropArea } from "svelte-easy-crop"; + +export const getFileFromUrl = async (url: string, fileName = "cropped.png"): Promise => { + // Fetch the file data from the URL + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Failed to fetch resource: ${response.status} ${response.statusText}`); + } + + // Convert the response into a Blob + const blob = await response.blob(); + + // Create and return a File. You can set a custom type if needed. + return new File([blob], fileName, { type: blob.type }); +}; + +const createImage = (url: string): Promise => { + return new Promise((resolve, reject) => { + const image = new Image(); + image.addEventListener("load", () => resolve(image)); + image.addEventListener("error", (error) => reject(error)); + image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox + image.src = url; + }); +}; + +const getRadianAngle = (degreeValue: number) => { + return (degreeValue * Math.PI) / 180; +}; + +/** Gets the cropped image from the src using the cropped area + * + * @param imageSrc + * @param pixelCrop + * @param rotation + * @returns + */ +export const getCroppedImg = async ( + imageSrc: string, + pixelCrop: CropArea, + rotation = 0 +): Promise => { + const image = await createImage(imageSrc); + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + + if (!ctx) { + throw new Error("Error getting 2d rendering context"); + } + + const maxSize = Math.max(image.width, image.height); + const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2)); + + // set each dimensions to double largest dimension to allow for a safe area for the + // image to rotate in without being clipped by canvas context + canvas.width = safeArea; + canvas.height = safeArea; + + // translate canvas context to a central location on image to allow rotating around the center. + ctx.translate(safeArea / 2, safeArea / 2); + ctx.rotate(getRadianAngle(rotation)); + ctx.translate(-safeArea / 2, -safeArea / 2); + + // draw rotated image and store data. + ctx.drawImage(image, safeArea / 2 - image.width * 0.5, safeArea / 2 - image.height * 0.5); + const data = ctx.getImageData(0, 0, safeArea, safeArea); + + // set canvas width to final desired crop size - this will clear existing context + canvas.width = pixelCrop.width; + canvas.height = pixelCrop.height; + + // paste generated rotate image with correct offsets for x,y crop values. + ctx.putImageData( + data, + Math.round(0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x), + Math.round(0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y) + ); + + return new Promise((resolve) => { + canvas.toBlob((file) => { + resolve(URL.createObjectURL(file!)); + }, "image/png"); + }); +}; diff --git a/apps/web/src/lib/components/ui/input-otp/index.ts b/apps/web/src/lib/components/ui/input-otp/index.ts new file mode 100644 index 0000000..e9ae273 --- /dev/null +++ b/apps/web/src/lib/components/ui/input-otp/index.ts @@ -0,0 +1,15 @@ +import Root from "./input-otp.svelte"; +import Group from "./input-otp-group.svelte"; +import Slot from "./input-otp-slot.svelte"; +import Separator from "./input-otp-separator.svelte"; + +export { + Root, + Group, + Slot, + Separator, + Root as InputOTP, + Group as InputOTPGroup, + Slot as InputOTPSlot, + Separator as InputOTPSeparator, +}; diff --git a/apps/web/src/lib/components/ui/input-otp/input-otp-group.svelte b/apps/web/src/lib/components/ui/input-otp/input-otp-group.svelte new file mode 100644 index 0000000..9b311bc --- /dev/null +++ b/apps/web/src/lib/components/ui/input-otp/input-otp-group.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/input-otp/input-otp-separator.svelte b/apps/web/src/lib/components/ui/input-otp/input-otp-separator.svelte new file mode 100644 index 0000000..3241295 --- /dev/null +++ b/apps/web/src/lib/components/ui/input-otp/input-otp-separator.svelte @@ -0,0 +1,19 @@ + + +
    + {#if children} + {@render children?.()} + {:else} + + {/if} +
    diff --git a/apps/web/src/lib/components/ui/input-otp/input-otp-slot.svelte b/apps/web/src/lib/components/ui/input-otp/input-otp-slot.svelte new file mode 100644 index 0000000..34d2636 --- /dev/null +++ b/apps/web/src/lib/components/ui/input-otp/input-otp-slot.svelte @@ -0,0 +1,31 @@ + + + + {cell.char} + {#if cell.hasFakeCaret} +
    + +
    + {/if} +
    diff --git a/apps/web/src/lib/components/ui/input-otp/input-otp.svelte b/apps/web/src/lib/components/ui/input-otp/input-otp.svelte new file mode 100644 index 0000000..e27cbcc --- /dev/null +++ b/apps/web/src/lib/components/ui/input-otp/input-otp.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/web/src/lib/components/ui/input/index.ts b/apps/web/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..33d3bff --- /dev/null +++ b/apps/web/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input +}; diff --git a/apps/web/src/lib/components/ui/input/input.svelte b/apps/web/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..fb45819 --- /dev/null +++ b/apps/web/src/lib/components/ui/input/input.svelte @@ -0,0 +1,51 @@ + + +{#if type === 'file'} + +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/ipv4address-input/index.ts b/apps/web/src/lib/components/ui/ipv4address-input/index.ts new file mode 100644 index 0000000..0eeaa3d --- /dev/null +++ b/apps/web/src/lib/components/ui/ipv4address-input/index.ts @@ -0,0 +1,49 @@ +import { isNumber } from "$lib/utils/is-number"; +import IPv4AddressInput from "./ipv4address-input.svelte"; + +/** Attempts to parse the provided address into a valid IP. Returns undefined for + * undefined returns a valid IP in array form for a valid IP and returns a 0 filled array for a incomplete IP. + * + * **This is used only for parsing the placeholder** + * + * @param ipv4Address IP Address string to be parsed can be `0.0.0.0` or `0 0 0 0` or `0_0_0_0` or `0 0 0` (partially complete) + * @returns + */ +export const safeParseIPv4Address = ( + ipv4Address: string | undefined +): [string | null, string | null, string | null, string | null] | undefined => { + if (ipv4Address === undefined) return undefined; + let ip = ipv4Address.trim(); + + ip = ip.replaceAll("_", "."); + ip = ip.replaceAll(" ", "."); + + const segments: (string | null)[] = ip.split("."); + + while (segments.length < 4) { + segments.push(null); + } + + for (let i = 0; i < segments.length; i++) { + if (!isNumber(segments[i]) || segments[i] === null) { + segments[i] = null; + continue; + } + + const num = Number.parseInt(segments[i]!); + + if (num < 0 || num > 255) { + segments[i] = null; + continue; + } + + segments[i] = num.toString(); + } + + // @ts-expect-error We know this is 4 we just made sure + return segments; +}; + +export { IPv4AddressInput }; + +export type * from "./types"; diff --git a/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input-input.svelte b/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input-input.svelte new file mode 100644 index 0000000..be23cba --- /dev/null +++ b/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input-input.svelte @@ -0,0 +1,133 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input.svelte b/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input.svelte new file mode 100644 index 0000000..1784f09 --- /dev/null +++ b/apps/web/src/lib/components/ui/ipv4address-input/ipv4address-input.svelte @@ -0,0 +1,159 @@ + + +
    + secondInput?.focus()} + bind:value={ + () => octets[0], + (v) => { + const tempOctets = octets; + + if (v == null || v === '') { + tempOctets[0] = null; + } else { + tempOctets[0] = v; + } + + value = format(tempOctets); + } + } + placeholder={parsedPlaceholder ? parsedPlaceholder[0] : undefined} + onpaste={paste} + /> + {separator} + thirdInput?.focus()} + goPrevious={() => firstInput?.focus()} + bind:value={ + () => octets[1], + (v) => { + const tempOctets = octets; + + if (v == null || v === '') { + tempOctets[1] = null; + } else { + tempOctets[1] = v; + } + + value = format(tempOctets); + } + } + placeholder={parsedPlaceholder ? parsedPlaceholder[1] : undefined} + onpaste={paste} + /> + {separator} + fourthInput?.focus()} + goPrevious={() => secondInput?.focus()} + bind:value={ + () => octets[2], + (v) => { + const tempOctets = octets; + + if (v == null || v === '') { + tempOctets[2] = null; + } else { + tempOctets[2] = v; + } + + value = format(tempOctets); + } + } + placeholder={parsedPlaceholder ? parsedPlaceholder[2] : undefined} + onpaste={paste} + /> + {separator} + thirdInput?.focus()} + bind:value={ + () => octets[3], + (v) => { + const tempOctets = octets; + + if (v == null || v === '') { + tempOctets[3] = null; + } else { + tempOctets[3] = v; + } + + value = format(tempOctets); + } + } + placeholder={parsedPlaceholder ? parsedPlaceholder[3] : undefined} + onpaste={paste} + /> +
    + diff --git a/apps/web/src/lib/components/ui/ipv4address-input/types.ts b/apps/web/src/lib/components/ui/ipv4address-input/types.ts new file mode 100644 index 0000000..86ca81e --- /dev/null +++ b/apps/web/src/lib/components/ui/ipv4address-input/types.ts @@ -0,0 +1,11 @@ +export type IPv4AddressInputProps = { + separator?: "." | " " | "_"; + /** An IP Address placeholder `0.0.0.0` or `0_0_0_0` or `0 0 0 0` */ + placeholder?: string; + value?: string | null; + class?: string; + valid?: boolean; + name?: string; +}; + +export type IPv4AddressInputPropsWithoutHTML = IPv4AddressInputProps; diff --git a/apps/web/src/lib/components/ui/label/index.ts b/apps/web/src/lib/components/ui/label/index.ts new file mode 100644 index 0000000..8bfca0b --- /dev/null +++ b/apps/web/src/lib/components/ui/label/index.ts @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; diff --git a/apps/web/src/lib/components/ui/label/label.svelte b/apps/web/src/lib/components/ui/label/label.svelte new file mode 100644 index 0000000..d0afda3 --- /dev/null +++ b/apps/web/src/lib/components/ui/label/label.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/link/index.ts b/apps/web/src/lib/components/ui/link/index.ts new file mode 100644 index 0000000..f998b51 --- /dev/null +++ b/apps/web/src/lib/components/ui/link/index.ts @@ -0,0 +1,5 @@ + + +import Link from "./link.svelte"; + +export { Link }; diff --git a/apps/web/src/lib/components/ui/link/link.svelte b/apps/web/src/lib/components/ui/link/link.svelte new file mode 100644 index 0000000..d86bf26 --- /dev/null +++ b/apps/web/src/lib/components/ui/link/link.svelte @@ -0,0 +1,12 @@ + + + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/menubar/index.ts b/apps/web/src/lib/components/ui/menubar/index.ts new file mode 100644 index 0000000..57a6cfb --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/index.ts @@ -0,0 +1,54 @@ +import { Menubar as MenubarPrimitive } from "bits-ui"; +import Root from "./menubar.svelte"; +import CheckboxItem from "./menubar-checkbox-item.svelte"; +import Content from "./menubar-content.svelte"; +import Item from "./menubar-item.svelte"; +import Group from "./menubar-group.svelte"; +import RadioItem from "./menubar-radio-item.svelte"; +import Separator from "./menubar-separator.svelte"; +import Shortcut from "./menubar-shortcut.svelte"; +import SubContent from "./menubar-sub-content.svelte"; +import SubTrigger from "./menubar-sub-trigger.svelte"; +import Trigger from "./menubar-trigger.svelte"; +import Label from "./menubar-label.svelte"; +import GroupHeading from "./menubar-group-heading.svelte"; + +const Menu = MenubarPrimitive.Menu; +const Sub = MenubarPrimitive.Sub; +const RadioGroup = MenubarPrimitive.RadioGroup; + +export { + Root, + CheckboxItem, + Content, + Item, + RadioItem, + Separator, + Shortcut, + SubContent, + SubTrigger, + Trigger, + Menu, + Group, + Sub, + RadioGroup, + Label, + GroupHeading, + // + Root as Menubar, + CheckboxItem as MenubarCheckboxItem, + Content as MenubarContent, + Item as MenubarItem, + RadioItem as MenubarRadioItem, + Separator as MenubarSeparator, + Shortcut as MenubarShortcut, + SubContent as MenubarSubContent, + SubTrigger as MenubarSubTrigger, + Trigger as MenubarTrigger, + Menu as MenubarMenu, + Group as MenubarGroup, + Sub as MenubarSub, + RadioGroup as MenubarRadioGroup, + Label as MenubarLabel, + GroupHeading as MenubarGroupHeading, +}; diff --git a/apps/web/src/lib/components/ui/menubar/menubar-checkbox-item.svelte b/apps/web/src/lib/components/ui/menubar/menubar-checkbox-item.svelte new file mode 100644 index 0000000..012d68b --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-checkbox-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-content.svelte b/apps/web/src/lib/components/ui/menubar/menubar-content.svelte new file mode 100644 index 0000000..d193622 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-content.svelte @@ -0,0 +1,33 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-group-heading.svelte b/apps/web/src/lib/components/ui/menubar/menubar-group-heading.svelte new file mode 100644 index 0000000..024e742 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-group.svelte b/apps/web/src/lib/components/ui/menubar/menubar-group.svelte new file mode 100644 index 0000000..f75b75a --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-group.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-item.svelte b/apps/web/src/lib/components/ui/menubar/menubar-item.svelte new file mode 100644 index 0000000..8c20d42 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-label.svelte b/apps/web/src/lib/components/ui/menubar/menubar-label.svelte new file mode 100644 index 0000000..1b36f6c --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-label.svelte @@ -0,0 +1,25 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/menubar/menubar-radio-item.svelte b/apps/web/src/lib/components/ui/menubar/menubar-radio-item.svelte new file mode 100644 index 0000000..3da12d4 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-radio-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-separator.svelte b/apps/web/src/lib/components/ui/menubar/menubar-separator.svelte new file mode 100644 index 0000000..a2caf6e --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-shortcut.svelte b/apps/web/src/lib/components/ui/menubar/menubar-shortcut.svelte new file mode 100644 index 0000000..0e08313 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-sub-content.svelte b/apps/web/src/lib/components/ui/menubar/menubar-sub-content.svelte new file mode 100644 index 0000000..cb4d04c --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-sub-trigger.svelte b/apps/web/src/lib/components/ui/menubar/menubar-sub-trigger.svelte new file mode 100644 index 0000000..4f9f28a --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar-trigger.svelte b/apps/web/src/lib/components/ui/menubar/menubar-trigger.svelte new file mode 100644 index 0000000..1c3dd6a --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar-trigger.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/menubar/menubar.svelte b/apps/web/src/lib/components/ui/menubar/menubar.svelte new file mode 100644 index 0000000..37e0206 --- /dev/null +++ b/apps/web/src/lib/components/ui/menubar/menubar.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/meter/index.ts b/apps/web/src/lib/components/ui/meter/index.ts new file mode 100644 index 0000000..5dbd837 --- /dev/null +++ b/apps/web/src/lib/components/ui/meter/index.ts @@ -0,0 +1 @@ +export { default as Meter } from "./meter.svelte"; diff --git a/apps/web/src/lib/components/ui/meter/meter.svelte b/apps/web/src/lib/components/ui/meter/meter.svelte new file mode 100644 index 0000000..bd90a6c --- /dev/null +++ b/apps/web/src/lib/components/ui/meter/meter.svelte @@ -0,0 +1,30 @@ + + + + + +
    +
    diff --git a/apps/web/src/lib/components/ui/navigation-menu/index.ts b/apps/web/src/lib/components/ui/navigation-menu/index.ts new file mode 100644 index 0000000..bbc250f --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/index.ts @@ -0,0 +1,28 @@ +import Root from "./navigation-menu.svelte"; +import Content from "./navigation-menu-content.svelte"; +import Indicator from "./navigation-menu-indicator.svelte"; +import Item from "./navigation-menu-item.svelte"; +import Link from "./navigation-menu-link.svelte"; +import List from "./navigation-menu-list.svelte"; +import Trigger from "./navigation-menu-trigger.svelte"; +import Viewport from "./navigation-menu-viewport.svelte"; + +export { + Root, + Content, + Indicator, + Item, + Link, + List, + Trigger, + Viewport, + // + Root as NavigationMenuRoot, + Content as NavigationMenuContent, + Indicator as NavigationMenuIndicator, + Item as NavigationMenuItem, + Link as NavigationMenuLink, + List as NavigationMenuList, + Trigger as NavigationMenuTrigger, + Viewport as NavigationMenuViewport, +}; diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte new file mode 100644 index 0000000..9dbdb36 --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-content.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte new file mode 100644 index 0000000..6c9bdfd --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-indicator.svelte @@ -0,0 +1,22 @@ + + + +
    +
    diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte new file mode 100644 index 0000000..b00b4b4 --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-item.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte new file mode 100644 index 0000000..867851e --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-link.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte new file mode 100644 index 0000000..c2c5880 --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-list.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte new file mode 100644 index 0000000..aad82a2 --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-trigger.svelte @@ -0,0 +1,34 @@ + + + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte new file mode 100644 index 0000000..655741d --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu-viewport.svelte @@ -0,0 +1,22 @@ + + +
    + +
    diff --git a/apps/web/src/lib/components/ui/navigation-menu/navigation-menu.svelte b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu.svelte new file mode 100644 index 0000000..69c3d13 --- /dev/null +++ b/apps/web/src/lib/components/ui/navigation-menu/navigation-menu.svelte @@ -0,0 +1,32 @@ + + + + {@render children?.()} + + {#if viewport} + + {/if} + diff --git a/apps/web/src/lib/components/ui/pagination/index.ts b/apps/web/src/lib/components/ui/pagination/index.ts new file mode 100644 index 0000000..d83c7a9 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/index.ts @@ -0,0 +1,25 @@ +import Root from "./pagination.svelte"; +import Content from "./pagination-content.svelte"; +import Item from "./pagination-item.svelte"; +import Link from "./pagination-link.svelte"; +import PrevButton from "./pagination-prev-button.svelte"; +import NextButton from "./pagination-next-button.svelte"; +import Ellipsis from "./pagination-ellipsis.svelte"; + +export { + Root, + Content, + Item, + Link, + PrevButton, + NextButton, + Ellipsis, + // + Root as Pagination, + Content as PaginationContent, + Item as PaginationItem, + Link as PaginationLink, + PrevButton as PaginationPrevButton, + NextButton as PaginationNextButton, + Ellipsis as PaginationEllipsis, +}; diff --git a/apps/web/src/lib/components/ui/pagination/pagination-content.svelte b/apps/web/src/lib/components/ui/pagination/pagination-content.svelte new file mode 100644 index 0000000..e1124fc --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-content.svelte @@ -0,0 +1,20 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte b/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte new file mode 100644 index 0000000..3be94c9 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/web/src/lib/components/ui/pagination/pagination-item.svelte b/apps/web/src/lib/components/ui/pagination/pagination-item.svelte new file mode 100644 index 0000000..fd7ffc3 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-item.svelte @@ -0,0 +1,14 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/web/src/lib/components/ui/pagination/pagination-link.svelte b/apps/web/src/lib/components/ui/pagination/pagination-link.svelte new file mode 100644 index 0000000..58b1a5c --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-link.svelte @@ -0,0 +1,39 @@ + + +{#snippet Fallback()} + {page.value} +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte b/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte new file mode 100644 index 0000000..d4b9553 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte @@ -0,0 +1,33 @@ + + +{#snippet Fallback()} + Next + +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte b/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte new file mode 100644 index 0000000..2d3dc70 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte @@ -0,0 +1,33 @@ + + +{#snippet Fallback()} + + Previous +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/pagination/pagination.svelte b/apps/web/src/lib/components/ui/pagination/pagination.svelte new file mode 100644 index 0000000..60e3471 --- /dev/null +++ b/apps/web/src/lib/components/ui/pagination/pagination.svelte @@ -0,0 +1,28 @@ + + + diff --git a/apps/web/src/lib/components/ui/password/index.ts b/apps/web/src/lib/components/ui/password/index.ts new file mode 100644 index 0000000..85d1e1b --- /dev/null +++ b/apps/web/src/lib/components/ui/password/index.ts @@ -0,0 +1,7 @@ +import Root from "./password.svelte"; +import Input from "./password-input.svelte"; +import Strength from "./password-strength.svelte"; +import Copy from "./password-copy.svelte"; +import ToggleVisibility from "./password-toggle-visibility.svelte"; + +export { Root, Input, Strength, Copy, ToggleVisibility }; diff --git a/apps/web/src/lib/components/ui/password/password-copy.svelte b/apps/web/src/lib/components/ui/password/password-copy.svelte new file mode 100644 index 0000000..83dc9fd --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password-copy.svelte @@ -0,0 +1,23 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/password/password-input.svelte b/apps/web/src/lib/components/ui/password/password-input.svelte new file mode 100644 index 0000000..c55d9a5 --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password-input.svelte @@ -0,0 +1,46 @@ + + +
    + + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/password/password-strength.svelte b/apps/web/src/lib/components/ui/password/password-strength.svelte new file mode 100644 index 0000000..df8a43f --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password-strength.svelte @@ -0,0 +1,48 @@ + + + +
    + +
    + {#each Array.from({ length: 4 }) as _, i (i)} +
    + {/each} +
    +
    diff --git a/apps/web/src/lib/components/ui/password/password-toggle-visibility.svelte b/apps/web/src/lib/components/ui/password/password-toggle-visibility.svelte new file mode 100644 index 0000000..287e7cf --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password-toggle-visibility.svelte @@ -0,0 +1,34 @@ + + + + + + {#if state.root.opts.hidden.current} + + {:else} + + {/if} + diff --git a/apps/web/src/lib/components/ui/password/password.svelte b/apps/web/src/lib/components/ui/password/password.svelte new file mode 100644 index 0000000..4413796 --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password.svelte @@ -0,0 +1,27 @@ + + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/password/password.svelte.ts b/apps/web/src/lib/components/ui/password/password.svelte.ts new file mode 100644 index 0000000..069bae3 --- /dev/null +++ b/apps/web/src/lib/components/ui/password/password.svelte.ts @@ -0,0 +1,159 @@ + + +import { Context, watch } from "runed"; +import type { ReadableBoxedValues, WritableBoxedValues } from "svelte-toolbelt"; +import { zxcvbn, zxcvbnOptions } from "@zxcvbn-ts/core"; +import * as zxcvbnCommonPackage from "@zxcvbn-ts/language-common"; +import * as zxcvbnEnPackage from "@zxcvbn-ts/language-en"; + +const passwordOptions = { + translations: zxcvbnEnPackage.translations, + graphs: zxcvbnCommonPackage.adjacencyGraphs, + dictionary: { + ...zxcvbnCommonPackage.dictionary, + ...zxcvbnEnPackage.dictionary + } +}; + +zxcvbnOptions.setOptions(passwordOptions); + +type PasswordRootStateProps = WritableBoxedValues<{ + hidden: boolean; +}> & + ReadableBoxedValues<{ + minScore: number; + }>; + +type PasswordState = { + value: string; + copyMounted: boolean; + toggleMounted: boolean; + strengthMounted: boolean; + tainted: boolean; +}; + +const defaultPasswordState: PasswordState = { + value: "", + copyMounted: false, + toggleMounted: false, + strengthMounted: false, + tainted: false +}; + +class PasswordRootState { + passwordState = $state(defaultPasswordState); + + constructor(readonly opts: PasswordRootStateProps) {} + + // only re-run when the password changes + strength = $derived.by(() => zxcvbn(this.passwordState.value)); +} + +type PasswordInputStateProps = WritableBoxedValues<{ + value: string; +}> & + ReadableBoxedValues<{ + ref: HTMLInputElement | null; + }>; + +class PasswordInputState { + constructor( + readonly root: PasswordRootState, + readonly opts: PasswordInputStateProps + ) { + watch( + () => this.opts.value.current, + () => { + if (this.root.passwordState.value !== this.opts.value.current) { + this.root.passwordState.tainted = true; + this.root.passwordState.value = this.opts.value.current; + } + } + ); + + $effect(() => { + if (!this.root.passwordState.strengthMounted) return; + + // if the password is empty, we let the `required` attribute handle the validation + if ( + this.root.passwordState.value !== "" && + this.root.strength.score < this.root.opts.minScore.current + ) { + this.opts.ref.current?.setCustomValidity("Password is too weak"); + } else { + this.opts.ref.current?.setCustomValidity(""); + } + }); + } + + props = $derived.by(() => ({ + "aria-invalid": + this.root.strength.score < this.root.opts.minScore.current && + this.root.passwordState.tainted && + this.root.passwordState.strengthMounted + })); +} + +class PasswordToggleVisibilityState { + constructor(readonly root: PasswordRootState) { + this.root.passwordState.toggleMounted = true; + + // this way we go back to the correct padding when toggle is unmounted + $effect(() => { + return () => { + this.root.passwordState.toggleMounted = false; + }; + }); + } +} + +class PasswordCopyState { + constructor(readonly root: PasswordRootState) { + this.root.passwordState.copyMounted = true; + + // this way we go back to the correct padding when copy is unmounted + $effect(() => { + return () => { + this.root.passwordState.copyMounted = false; + }; + }); + } +} + +class PasswordStrengthState { + constructor(readonly root: PasswordRootState) { + this.root.passwordState.strengthMounted = true; + + $effect(() => { + return () => { + this.root.passwordState.strengthMounted = false; + }; + }); + } + + get strength() { + return this.root.strength; + } +} + +const ctx = new Context("password-root-state"); + +export function usePassword(props: PasswordRootStateProps) { + return ctx.set(new PasswordRootState(props)); +} + +export function usePasswordInput(props: PasswordInputStateProps) { + return new PasswordInputState(ctx.get(), props); +} + +export function usePasswordToggleVisibility() { + return new PasswordToggleVisibilityState(ctx.get()); +} + +export function usePasswordCopy() { + return new PasswordCopyState(ctx.get()); +} + +export function usePasswordStrength() { + return new PasswordStrengthState(ctx.get()); +} diff --git a/apps/web/src/lib/components/ui/password/types.ts b/apps/web/src/lib/components/ui/password/types.ts new file mode 100644 index 0000000..f39952c --- /dev/null +++ b/apps/web/src/lib/components/ui/password/types.ts @@ -0,0 +1,47 @@ +import type { + WithChildren, + WithoutChildren, + Meter as MeterPrimitive, + Toggle as TogglePrimitive +} from "bits-ui"; +import type { HTMLAttributes, HTMLInputAttributes } from "svelte/elements"; +import type { CopyButtonProps } from "$lib/components/ui/copy-button/types"; +import type { ZxcvbnResult } from "@zxcvbn-ts/core"; + +export type PasswordRootPropsWithoutHTML = WithChildren<{ + ref?: HTMLDivElement | null; + hidden?: boolean; + /** The minimum acceptable score for a password. (0-4) + * + * @default 3 + */ + minScore?: 0 | 1 | 2 | 3 | 4; +}>; + +export type PasswordRootProps = WithoutChildren> & + PasswordRootPropsWithoutHTML; + +export type PasswordInputPropsWithoutHTML = WithChildren<{ + ref?: HTMLInputElement | null; + value?: string; +}>; + +export type PasswordInputProps = Omit< + WithoutChildren, + "type" | "files" | "aria-invalid" | "value" +> & + PasswordInputPropsWithoutHTML; + +export type PasswordToggleVisibilityProps = Omit< + TogglePrimitive.RootProps, + "children" | "pressed" | "aria-label" | "tabindex" +>; + +export type PasswordCopyButtonProps = Omit; + +export type PasswordStrengthPropsWithoutHTML = { + strength?: ZxcvbnResult; +}; + +export type PasswordStrengthProps = PasswordStrengthPropsWithoutHTML & + WithoutChildren; diff --git a/apps/web/src/lib/components/ui/popover/index.ts b/apps/web/src/lib/components/ui/popover/index.ts new file mode 100644 index 0000000..9f30922 --- /dev/null +++ b/apps/web/src/lib/components/ui/popover/index.ts @@ -0,0 +1,17 @@ +import { Popover as PopoverPrimitive } from "bits-ui"; +import Content from "./popover-content.svelte"; +import Trigger from "./popover-trigger.svelte"; +const Root = PopoverPrimitive.Root; +const Close = PopoverPrimitive.Close; + +export { + Root, + Content, + Trigger, + Close, + // + Root as Popover, + Content as PopoverContent, + Trigger as PopoverTrigger, + Close as PopoverClose, +}; diff --git a/apps/web/src/lib/components/ui/popover/popover-content.svelte b/apps/web/src/lib/components/ui/popover/popover-content.svelte new file mode 100644 index 0000000..9bced7a --- /dev/null +++ b/apps/web/src/lib/components/ui/popover/popover-content.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/popover/popover-trigger.svelte b/apps/web/src/lib/components/ui/popover/popover-trigger.svelte new file mode 100644 index 0000000..586323c --- /dev/null +++ b/apps/web/src/lib/components/ui/popover/popover-trigger.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/progress/index.ts b/apps/web/src/lib/components/ui/progress/index.ts new file mode 100644 index 0000000..25eee61 --- /dev/null +++ b/apps/web/src/lib/components/ui/progress/index.ts @@ -0,0 +1,7 @@ +import Root from "./progress.svelte"; + +export { + Root, + // + Root as Progress, +}; diff --git a/apps/web/src/lib/components/ui/progress/progress.svelte b/apps/web/src/lib/components/ui/progress/progress.svelte new file mode 100644 index 0000000..6833013 --- /dev/null +++ b/apps/web/src/lib/components/ui/progress/progress.svelte @@ -0,0 +1,27 @@ + + + +
    +
    diff --git a/apps/web/src/lib/components/ui/radio-group/index.ts b/apps/web/src/lib/components/ui/radio-group/index.ts new file mode 100644 index 0000000..90b33fe --- /dev/null +++ b/apps/web/src/lib/components/ui/radio-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./radio-group.svelte"; +import Item from "./radio-group-item.svelte"; + +export { + Root, + Item, + // + Root as RadioGroup, + Item as RadioGroupItem, +}; diff --git a/apps/web/src/lib/components/ui/radio-group/radio-group-item.svelte b/apps/web/src/lib/components/ui/radio-group/radio-group-item.svelte new file mode 100644 index 0000000..2cb0710 --- /dev/null +++ b/apps/web/src/lib/components/ui/radio-group/radio-group-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} +
    + {#if checked} + + {/if} +
    + {/snippet} +
    diff --git a/apps/web/src/lib/components/ui/radio-group/radio-group.svelte b/apps/web/src/lib/components/ui/radio-group/radio-group.svelte new file mode 100644 index 0000000..da2912b --- /dev/null +++ b/apps/web/src/lib/components/ui/radio-group/radio-group.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/index.ts b/apps/web/src/lib/components/ui/range-calendar/index.ts new file mode 100644 index 0000000..262c49a --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/index.ts @@ -0,0 +1,42 @@ +import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui"; +import Root from "./range-calendar.svelte"; +import Cell from "./range-calendar-cell.svelte"; +import Day from "./range-calendar-day.svelte"; +import Grid from "./range-calendar-grid.svelte"; +import Header from "./range-calendar-header.svelte"; +import Months from "./range-calendar-months.svelte"; +import GridRow from "./range-calendar-grid-row.svelte"; +import Heading from "./range-calendar-heading.svelte"; +import HeadCell from "./range-calendar-head-cell.svelte"; +import NextButton from "./range-calendar-next-button.svelte"; +import PrevButton from "./range-calendar-prev-button.svelte"; +import MonthSelect from "./range-calendar-month-select.svelte"; +import YearSelect from "./range-calendar-year-select.svelte"; +import Caption from "./range-calendar-caption.svelte"; +import Nav from "./range-calendar-nav.svelte"; +import Month from "./range-calendar-month.svelte"; + +const GridHead = RangeCalendarPrimitive.GridHead; +const GridBody = RangeCalendarPrimitive.GridBody; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + MonthSelect, + YearSelect, + Caption, + Nav, + Month, + // + Root as RangeCalendar, +}; diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-caption.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-caption.svelte new file mode 100644 index 0000000..944654d --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-caption.svelte @@ -0,0 +1,76 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-cell.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-cell.svelte new file mode 100644 index 0000000..e658dbe --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-day.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-day.svelte new file mode 100644 index 0000000..5599ca0 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-day.svelte @@ -0,0 +1,39 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte new file mode 100644 index 0000000..3286b2a --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid.svelte new file mode 100644 index 0000000..3d74b2f --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-grid.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte new file mode 100644 index 0000000..93a60c0 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-header.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-header.svelte new file mode 100644 index 0000000..d113697 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-header.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-heading.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-heading.svelte new file mode 100644 index 0000000..3b3325f --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte new file mode 100644 index 0000000..5abd36d --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-month-select.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-month.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-month.svelte new file mode 100644 index 0000000..e747fae --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-month.svelte @@ -0,0 +1,15 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-months.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-months.svelte new file mode 100644 index 0000000..f717a9d --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-months.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-nav.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-nav.svelte new file mode 100644 index 0000000..27f33d7 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-nav.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte new file mode 100644 index 0000000..d1158b8 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte new file mode 100644 index 0000000..d711db1 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte @@ -0,0 +1,31 @@ + + +{#snippet Fallback()} + +{/snippet} + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte new file mode 100644 index 0000000..75cb0af --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar-year-select.svelte @@ -0,0 +1,43 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + diff --git a/apps/web/src/lib/components/ui/range-calendar/range-calendar.svelte b/apps/web/src/lib/components/ui/range-calendar/range-calendar.svelte new file mode 100644 index 0000000..4d917a6 --- /dev/null +++ b/apps/web/src/lib/components/ui/range-calendar/range-calendar.svelte @@ -0,0 +1,112 @@ + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + + {#each weekdays as weekday (weekday)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + diff --git a/apps/web/src/lib/components/ui/rename/index.ts b/apps/web/src/lib/components/ui/rename/index.ts new file mode 100644 index 0000000..fc4f523 --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/index.ts @@ -0,0 +1,34 @@ + +import Root from "./rename.svelte"; +import Provider from "./rename-provider.svelte"; +import Cancel from "./rename-cancel.svelte"; +import Save from "./rename-save.svelte"; +import Edit from "./rename-edit.svelte"; + +/** + * This can be consumed one of two ways: + * ```svelte + * + * + * + * ``` + * + * or + * + * ```svelte + * + * + * + * + * + * + * + * + * ``` + */ + +export { Root as Rename, Provider, Root, Cancel, Save, Edit }; diff --git a/apps/web/src/lib/components/ui/rename/rename-cancel.svelte b/apps/web/src/lib/components/ui/rename/rename-cancel.svelte new file mode 100644 index 0000000..0ec4b49 --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename-cancel.svelte @@ -0,0 +1,27 @@ + + + + +{#if child} + {@render child({ cancel: cancelState.cancel })} +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/rename/rename-edit.svelte b/apps/web/src/lib/components/ui/rename/rename-edit.svelte new file mode 100644 index 0000000..6c5c4fd --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename-edit.svelte @@ -0,0 +1,27 @@ + + + + +{#if child} + {@render child({ edit: editState.edit })} +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/rename/rename-provider.svelte b/apps/web/src/lib/components/ui/rename/rename-provider.svelte new file mode 100644 index 0000000..a1c7b9a --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename-provider.svelte @@ -0,0 +1,12 @@ + + + + +{@render children?.()} diff --git a/apps/web/src/lib/components/ui/rename/rename-save.svelte b/apps/web/src/lib/components/ui/rename/rename-save.svelte new file mode 100644 index 0000000..224a595 --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename-save.svelte @@ -0,0 +1,27 @@ + + + + +{#if child} + {@render child({ save: saveState.save })} +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/rename/rename.svelte b/apps/web/src/lib/components/ui/rename/rename.svelte new file mode 100644 index 0000000..b901230 --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename.svelte @@ -0,0 +1,108 @@ + + + + +{#if mode === 'edit'} + +{:else if mode === 'view'} + + + {value} + +{/if} diff --git a/apps/web/src/lib/components/ui/rename/rename.svelte.ts b/apps/web/src/lib/components/ui/rename/rename.svelte.ts new file mode 100644 index 0000000..7120d7b --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/rename.svelte.ts @@ -0,0 +1,205 @@ + + +import { tick, untrack } from "svelte"; +import type { ReadableBoxedValues, WritableBoxedValues } from "svelte-toolbelt"; +import { Context } from "runed"; + +class RenameProviderState { + inputState = $state(null); + constructor() {} + + /** Allows us to call functions on the input state from the provider */ + registerInputState(inputState: RenameInputState) { + this.inputState = inputState; + } +} + +class RenameEditState { + constructor(readonly providerState: RenameProviderState) { + this.edit = this.edit.bind(this); + } + + edit() { + this.providerState.inputState?.startEditing(); + } +} + +class RenameCancelState { + constructor(readonly providerState: RenameProviderState) { + this.cancel = this.cancel.bind(this); + } + + cancel() { + this.providerState.inputState?.cancel(); + } +} + +class RenameSaveState { + constructor(readonly providerState: RenameProviderState) { + this.save = this.save.bind(this); + } + + save() { + this.providerState.inputState?.save(); + } +} + +type RenameInputStateProps = WritableBoxedValues<{ + mode: "edit" | "view"; + value: string; + inputRef: HTMLInputElement | null; + textRef: HTMLElement | null; +}> & + ReadableBoxedValues<{ + blurBehavior?: "exit" | "none"; + fallbackSelectionBehavior: "start" | "end" | "all"; + }> & { + id: string; + onSave?: (value: string) => void; + onCancel?: () => void; + validate: (value: string) => boolean; + }; + +class RenameInputState { + mode = $state<"edit" | "view">("view"); + editingValue = $state(""); + invalid = $derived.by(() => !this.opts.validate(this.editingValue)); + + get blurBehavior() { + if (this.opts.blurBehavior !== undefined && this.opts.blurBehavior.current !== undefined) + return this.opts.blurBehavior.current; + // if the blur behavior is provided, use it + // otherwise if the provider state is provided we assume that the user does not want to blur when the input loses focus + return this.providerState ? "none" : "exit"; + } + + constructor( + readonly opts: RenameInputStateProps, + readonly providerState?: RenameProviderState + ) { + this.mode = this.opts.mode.current; + this.editingValue = this.opts.value.current; + + // function bindings + this.onInputKeydown = this.onInputKeydown.bind(this); + this.onInputBlur = this.onInputBlur.bind(this); + this.onTextClick = this.onTextClick.bind(this); + this.save = this.save.bind(this); + this.cancel = this.cancel.bind(this); + this.startEditing = this.startEditing.bind(this); + + this.providerState?.registerInputState(this); + + // we do this so that we can detect changes to the mode from the outside + // this allows consumers to start edit mode and ensures that the state if kept in sync + $effect(() => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + this.opts.mode.current; + + untrack(() => { + if (this.mode !== this.opts.mode.current) { + this.mode = this.opts.mode.current; + + if (this.mode === "edit") { + this.startEditing(); + } else { + this.cancel(); + } + } + }); + }); + + $effect(() => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + this.mode; + + untrack(() => { + this.opts.mode.current = this.mode; + }); + }); + } + + async startEditing(selection?: { start: number; end?: number }) { + this.mode = "edit"; + this.editingValue = this.opts.value.current; + await tick(); + this.opts.inputRef.current?.focus(); + if (selection !== undefined) { + this.opts.inputRef.current?.setSelectionRange( + selection.start, + selection.end ?? selection.start + ); + } else { + if (this.opts.fallbackSelectionBehavior.current === "start") { + this.opts.inputRef.current?.setSelectionRange(0, 0); + } else if (this.opts.fallbackSelectionBehavior.current === "end") { + this.opts.inputRef.current?.setSelectionRange( + this.editingValue.length, + this.editingValue.length + ); + } else if (this.opts.fallbackSelectionBehavior.current === "all") { + this.opts.inputRef.current?.setSelectionRange(0, this.editingValue.length); + } + } + } + + async save() { + if (this.invalid) return; + await this.opts.onSave?.(this.editingValue); + this.opts.value.current = this.editingValue; + this.mode = "view"; + } + + cancel() { + this.mode = "view"; + this.opts.onCancel?.(); + this.editingValue = this.opts.value.current; + } + + async onInputKeydown(e: KeyboardEvent) { + if (e.key === "Enter") { + await this.save(); + } + + if (e.key === "Escape") { + this.cancel(); + } + } + + onInputBlur() { + if (this.blurBehavior === "none") return; + this.cancel(); + } + + async onTextClick() { + // do nothing if the provider state is defined + if (this.providerState !== undefined) return; + await new Promise((res) => setTimeout(res, 0)); + // this is how we make sure the selection starts where the user clicked + const selected = window.getSelection(); + const focusOffset = selected?.focusOffset; + await this.startEditing(focusOffset ? { start: focusOffset } : undefined); + } +} + +const providerCtx = new Context("rename-provider-state"); + +export function useRename() { + return providerCtx.set(new RenameProviderState()); +} + +export function useRenameEdit() { + return new RenameEditState(providerCtx.get()); +} + +export function useRenameCancel() { + return new RenameCancelState(providerCtx.get()); +} + +export function useRenameSave() { + return new RenameSaveState(providerCtx.get()); +} + +export function useRenameInput(opts: RenameInputStateProps) { + return new RenameInputState(opts, providerCtx.getOr(undefined)); +} diff --git a/apps/web/src/lib/components/ui/rename/types.ts b/apps/web/src/lib/components/ui/rename/types.ts new file mode 100644 index 0000000..c3ab286 --- /dev/null +++ b/apps/web/src/lib/components/ui/rename/types.ts @@ -0,0 +1,57 @@ + + +export type TextElementTagNames = + | "a" + | "abbr" + | "address" + | "b" + | "bdi" + | "bdo" + | "blockquote" + | "cite" + | "code" + | "data" + | "dd" + | "del" + | "dfn" + | "dt" + | "em" + | "figcaption" + | "h1" + | "h2" + | "h3" + | "h4" + | "h5" + | "h6" + | "header" + | "hgroup" + | "i" + | "ins" + | "kbd" + | "label" + | "legend" + | "li" + | "main" + | "mark" + | "nav" + | "noscript" + | "p" + | "pre" + | "q" + | "rp" + | "rt" + | "ruby" + | "s" + | "samp" + | "search" + | "section" + | "small" + | "span" + | "strong" + | "sub" + | "summary" + | "sup" + | "time" + | "title" + | "u" + | "var"; diff --git a/apps/web/src/lib/components/ui/resizable/index.ts b/apps/web/src/lib/components/ui/resizable/index.ts new file mode 100644 index 0000000..2e37f11 --- /dev/null +++ b/apps/web/src/lib/components/ui/resizable/index.ts @@ -0,0 +1,13 @@ +import { Pane } from "paneforge"; +import Handle from "./resizable-handle.svelte"; +import PaneGroup from "./resizable-pane-group.svelte"; + +export { + PaneGroup, + Pane, + Handle, + // + PaneGroup as ResizablePaneGroup, + Pane as ResizablePane, + Handle as ResizableHandle, +}; diff --git a/apps/web/src/lib/components/ui/resizable/resizable-handle.svelte b/apps/web/src/lib/components/ui/resizable/resizable-handle.svelte new file mode 100644 index 0000000..9c8da71 --- /dev/null +++ b/apps/web/src/lib/components/ui/resizable/resizable-handle.svelte @@ -0,0 +1,30 @@ + + +div]:rotate-90", + className + )} + {...restProps} +> + {#if withHandle} +
    + +
    + {/if} +
    diff --git a/apps/web/src/lib/components/ui/resizable/resizable-pane-group.svelte b/apps/web/src/lib/components/ui/resizable/resizable-pane-group.svelte new file mode 100644 index 0000000..a810d7e --- /dev/null +++ b/apps/web/src/lib/components/ui/resizable/resizable-pane-group.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/scroll-area/index.ts b/apps/web/src/lib/components/ui/scroll-area/index.ts new file mode 100644 index 0000000..e86a25b --- /dev/null +++ b/apps/web/src/lib/components/ui/scroll-area/index.ts @@ -0,0 +1,10 @@ +import Scrollbar from "./scroll-area-scrollbar.svelte"; +import Root from "./scroll-area.svelte"; + +export { + Root, + Scrollbar, + //, + Root as ScrollArea, + Scrollbar as ScrollAreaScrollbar, +}; diff --git a/apps/web/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte b/apps/web/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte new file mode 100644 index 0000000..4127444 --- /dev/null +++ b/apps/web/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte @@ -0,0 +1,31 @@ + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/scroll-area/scroll-area.svelte b/apps/web/src/lib/components/ui/scroll-area/scroll-area.svelte new file mode 100644 index 0000000..38a1847 --- /dev/null +++ b/apps/web/src/lib/components/ui/scroll-area/scroll-area.svelte @@ -0,0 +1,40 @@ + + + + + {@render children?.()} + + {#if orientation === "vertical" || orientation === "both"} + + {/if} + {#if orientation === "horizontal" || orientation === "both"} + + {/if} + + diff --git a/apps/web/src/lib/components/ui/select/index.ts b/apps/web/src/lib/components/ui/select/index.ts new file mode 100644 index 0000000..9e8d3e9 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/index.ts @@ -0,0 +1,37 @@ +import { Select as SelectPrimitive } from "bits-ui"; + +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"; + +const Root = SelectPrimitive.Root; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + // + 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, +}; diff --git a/apps/web/src/lib/components/ui/select/select-content.svelte b/apps/web/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..dc16d65 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,40 @@ + + + + + + + {@render children?.()} + + + + diff --git a/apps/web/src/lib/components/ui/select/select-group-heading.svelte b/apps/web/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..1fab5f0 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/select/select-group.svelte b/apps/web/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 0000000..5454fdb --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/select/select-item.svelte b/apps/web/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..49dbbd7 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/select/select-label.svelte b/apps/web/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 0000000..4696025 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/select/select-scroll-down-button.svelte b/apps/web/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..3629205 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/select/select-scroll-up-button.svelte b/apps/web/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..1aa2300 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,20 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/select/select-separator.svelte b/apps/web/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..0eac3eb --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,18 @@ + + + diff --git a/apps/web/src/lib/components/ui/select/select-trigger.svelte b/apps/web/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..d405187 --- /dev/null +++ b/apps/web/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/apps/web/src/lib/components/ui/separator/index.ts b/apps/web/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..82442d2 --- /dev/null +++ b/apps/web/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/apps/web/src/lib/components/ui/separator/separator.svelte b/apps/web/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..09d88f4 --- /dev/null +++ b/apps/web/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/sheet/index.ts b/apps/web/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..01d40c8 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,36 @@ +import { Dialog as SheetPrimitive } from "bits-ui"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +const Root = SheetPrimitive.Root; +const Portal = SheetPrimitive.Portal; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; diff --git a/apps/web/src/lib/components/ui/sheet/sheet-close.svelte b/apps/web/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 0000000..ae382c1 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/sheet/sheet-content.svelte b/apps/web/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..856922e --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,58 @@ + + + + + + + + {@render children?.()} + + + Close + + + diff --git a/apps/web/src/lib/components/ui/sheet/sheet-description.svelte b/apps/web/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..333b17a --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte b/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..dd9ed84 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sheet/sheet-header.svelte b/apps/web/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..757a6a5 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte b/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..345e197 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/sheet/sheet-title.svelte b/apps/web/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..9fda327 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte b/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 0000000..e266975 --- /dev/null +++ b/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/sidebar/constants.ts b/apps/web/src/lib/components/ui/sidebar/constants.ts new file mode 100644 index 0000000..4de4435 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/constants.ts @@ -0,0 +1,6 @@ +export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; diff --git a/apps/web/src/lib/components/ui/sidebar/context.svelte.ts b/apps/web/src/lib/components/ui/sidebar/context.svelte.ts new file mode 100644 index 0000000..15248ad --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/context.svelte.ts @@ -0,0 +1,81 @@ +import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; +import { getContext, setContext } from "svelte"; +import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; + +type Getter = () => T; + +export type SidebarStateProps = { + /** + * A getter function that returns the current open state of the sidebar. + * We use a getter function here to support `bind:open` on the `Sidebar.Provider` + * component. + */ + open: Getter; + + /** + * A function that sets the open state of the sidebar. To support `bind:open`, we need + * a source of truth for changing the open state to ensure it will be synced throughout + * the sub-components and any `bind:` references. + */ + setOpen: (open: boolean) => void; +}; + +class SidebarState { + readonly props: SidebarStateProps; + open = $derived.by(() => this.props.open()); + openMobile = $state(false); + setOpen: SidebarStateProps["setOpen"]; + #isMobile: IsMobile; + state = $derived.by(() => (this.open ? "expanded" : "collapsed")); + + constructor(props: SidebarStateProps) { + this.setOpen = props.setOpen; + this.#isMobile = new IsMobile(); + this.props = props; + } + + // Convenience getter for checking if the sidebar is mobile + // without this, we would need to use `sidebar.isMobile.current` everywhere + get isMobile() { + return this.#isMobile.current; + } + + // Event handler to apply to the `` + handleShortcutKeydown = (e: KeyboardEvent) => { + if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + this.toggle(); + } + }; + + setOpenMobile = (value: boolean) => { + this.openMobile = value; + }; + + toggle = () => { + return this.#isMobile.current + ? (this.openMobile = !this.openMobile) + : this.setOpen(!this.open); + }; +} + +const SYMBOL_KEY = "scn-sidebar"; + +/** + * Instantiates a new `SidebarState` instance and sets it in the context. + * + * @param props The constructor props for the `SidebarState` class. + * @returns The `SidebarState` instance. + */ +export function setSidebar(props: SidebarStateProps): SidebarState { + return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); +} + +/** + * Retrieves the `SidebarState` instance from the context. This is a class instance, + * so you cannot destructure it. + * @returns The `SidebarState` instance. + */ +export function useSidebar(): SidebarState { + return getContext(Symbol.for(SYMBOL_KEY)); +} diff --git a/apps/web/src/lib/components/ui/sidebar/index.ts b/apps/web/src/lib/components/ui/sidebar/index.ts new file mode 100644 index 0000000..318a341 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/index.ts @@ -0,0 +1,75 @@ +import { useSidebar } from "./context.svelte.js"; +import Content from "./sidebar-content.svelte"; +import Footer from "./sidebar-footer.svelte"; +import GroupAction from "./sidebar-group-action.svelte"; +import GroupContent from "./sidebar-group-content.svelte"; +import GroupLabel from "./sidebar-group-label.svelte"; +import Group from "./sidebar-group.svelte"; +import Header from "./sidebar-header.svelte"; +import Input from "./sidebar-input.svelte"; +import Inset from "./sidebar-inset.svelte"; +import MenuAction from "./sidebar-menu-action.svelte"; +import MenuBadge from "./sidebar-menu-badge.svelte"; +import MenuButton from "./sidebar-menu-button.svelte"; +import MenuItem from "./sidebar-menu-item.svelte"; +import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; +import MenuSubButton from "./sidebar-menu-sub-button.svelte"; +import MenuSubItem from "./sidebar-menu-sub-item.svelte"; +import MenuSub from "./sidebar-menu-sub.svelte"; +import Menu from "./sidebar-menu.svelte"; +import Provider from "./sidebar-provider.svelte"; +import Rail from "./sidebar-rail.svelte"; +import Separator from "./sidebar-separator.svelte"; +import Trigger from "./sidebar-trigger.svelte"; +import Root from "./sidebar.svelte"; + +export { + Content, + Footer, + Group, + GroupAction, + GroupContent, + GroupLabel, + Header, + Input, + Inset, + Menu, + MenuAction, + MenuBadge, + MenuButton, + MenuItem, + MenuSkeleton, + MenuSub, + MenuSubButton, + MenuSubItem, + Provider, + Rail, + Root, + Separator, + // + Root as Sidebar, + Content as SidebarContent, + Footer as SidebarFooter, + Group as SidebarGroup, + GroupAction as SidebarGroupAction, + GroupContent as SidebarGroupContent, + GroupLabel as SidebarGroupLabel, + Header as SidebarHeader, + Input as SidebarInput, + Inset as SidebarInset, + Menu as SidebarMenu, + MenuAction as SidebarMenuAction, + MenuBadge as SidebarMenuBadge, + MenuButton as SidebarMenuButton, + MenuItem as SidebarMenuItem, + MenuSkeleton as SidebarMenuSkeleton, + MenuSub as SidebarMenuSub, + MenuSubButton as SidebarMenuSubButton, + MenuSubItem as SidebarMenuSubItem, + Provider as SidebarProvider, + Rail as SidebarRail, + Separator as SidebarSeparator, + Trigger as SidebarTrigger, + Trigger, + useSidebar, +}; diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte new file mode 100644 index 0000000..f121800 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte new file mode 100644 index 0000000..6259cb9 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte new file mode 100644 index 0000000..fb84e4a --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte @@ -0,0 +1,36 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte new file mode 100644 index 0000000..415255f --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte new file mode 100644 index 0000000..e292945 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte @@ -0,0 +1,34 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte new file mode 100644 index 0000000..ec18a69 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte new file mode 100644 index 0000000..a1b2db1 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte new file mode 100644 index 0000000..19b3666 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte @@ -0,0 +1,21 @@ + + + diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte new file mode 100644 index 0000000..d862761 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte new file mode 100644 index 0000000..fa3fb0c --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte @@ -0,0 +1,43 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte new file mode 100644 index 0000000..69e5a3c --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte @@ -0,0 +1,29 @@ + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte new file mode 100644 index 0000000..4bef683 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte @@ -0,0 +1,103 @@ + + + + +{#snippet Button({ props }: { props?: Record })} + {@const mergedProps = mergeProps(buttonProps, props)} + {#if child} + {@render child({ props: mergedProps })} + {:else} + + {/if} +{/snippet} + +{#if !tooltipContent} + {@render Button({})} +{:else} + + + {#snippet child({ props })} + {@render Button({ props })} + {/snippet} + + + +{/if} diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte new file mode 100644 index 0000000..4db4453 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte new file mode 100644 index 0000000..cc63b04 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte @@ -0,0 +1,36 @@ + + +
    + {#if showIcon} + + {/if} + + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte new file mode 100644 index 0000000..987f104 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte @@ -0,0 +1,43 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + + {@render children?.()} + +{/if} diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte new file mode 100644 index 0000000..681d0f1 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte new file mode 100644 index 0000000..8ab1111 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte @@ -0,0 +1,25 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte new file mode 100644 index 0000000..946ccce --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte new file mode 100644 index 0000000..5b0d0aa --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -0,0 +1,53 @@ + + + + + +
    + {@render children?.()} +
    +
    diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte new file mode 100644 index 0000000..c180cf5 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte @@ -0,0 +1,36 @@ + + + diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte new file mode 100644 index 0000000..5a7deda --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte new file mode 100644 index 0000000..1825182 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte @@ -0,0 +1,35 @@ + + + diff --git a/apps/web/src/lib/components/ui/sidebar/sidebar.svelte b/apps/web/src/lib/components/ui/sidebar/sidebar.svelte new file mode 100644 index 0000000..3e9eba9 --- /dev/null +++ b/apps/web/src/lib/components/ui/sidebar/sidebar.svelte @@ -0,0 +1,104 @@ + + +{#if collapsible === "none"} +
    + {@render children?.()} +
    +{:else if sidebar.isMobile} + sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} + {...restProps} + > + + + Sidebar + Displays the mobile sidebar. + +
    + {@render children?.()} +
    +
    +
    +{:else} + +{/if} diff --git a/apps/web/src/lib/components/ui/skeleton/index.ts b/apps/web/src/lib/components/ui/skeleton/index.ts new file mode 100644 index 0000000..186db21 --- /dev/null +++ b/apps/web/src/lib/components/ui/skeleton/index.ts @@ -0,0 +1,7 @@ +import Root from "./skeleton.svelte"; + +export { + Root, + // + Root as Skeleton, +}; diff --git a/apps/web/src/lib/components/ui/skeleton/skeleton.svelte b/apps/web/src/lib/components/ui/skeleton/skeleton.svelte new file mode 100644 index 0000000..c7e3d26 --- /dev/null +++ b/apps/web/src/lib/components/ui/skeleton/skeleton.svelte @@ -0,0 +1,17 @@ + + +
    diff --git a/apps/web/src/lib/components/ui/slider/index.ts b/apps/web/src/lib/components/ui/slider/index.ts new file mode 100644 index 0000000..820f209 --- /dev/null +++ b/apps/web/src/lib/components/ui/slider/index.ts @@ -0,0 +1,7 @@ +import Root from "./slider.svelte"; + +export { + Root, + // + Root as Slider, +}; diff --git a/apps/web/src/lib/components/ui/slider/slider.svelte b/apps/web/src/lib/components/ui/slider/slider.svelte new file mode 100644 index 0000000..b06e110 --- /dev/null +++ b/apps/web/src/lib/components/ui/slider/slider.svelte @@ -0,0 +1,52 @@ + + + + + {#snippet children({ thumbs })} + + + + {#each thumbs as thumb (thumb)} + + {/each} + {/snippet} + diff --git a/apps/web/src/lib/components/ui/snippet/index.ts b/apps/web/src/lib/components/ui/snippet/index.ts new file mode 100644 index 0000000..28789a3 --- /dev/null +++ b/apps/web/src/lib/components/ui/snippet/index.ts @@ -0,0 +1,5 @@ + + +import Snippet from "./snippet.svelte"; + +export { Snippet }; diff --git a/apps/web/src/lib/components/ui/snippet/snippet.svelte b/apps/web/src/lib/components/ui/snippet/snippet.svelte new file mode 100644 index 0000000..c59c719 --- /dev/null +++ b/apps/web/src/lib/components/ui/snippet/snippet.svelte @@ -0,0 +1,53 @@ + + + + + + +
    + {#if typeof text == 'string'} +
    +			{text}
    +		
    + {:else} + {#each text as line, i (i)} +
    +			{line}
    +		
    + {/each} + {/if} + + +
    diff --git a/apps/web/src/lib/components/ui/sonner/index.ts b/apps/web/src/lib/components/ui/sonner/index.ts new file mode 100644 index 0000000..1ad9f4a --- /dev/null +++ b/apps/web/src/lib/components/ui/sonner/index.ts @@ -0,0 +1 @@ +export { default as Toaster } from "./sonner.svelte"; diff --git a/apps/web/src/lib/components/ui/sonner/sonner.svelte b/apps/web/src/lib/components/ui/sonner/sonner.svelte new file mode 100644 index 0000000..1f50e1e --- /dev/null +++ b/apps/web/src/lib/components/ui/sonner/sonner.svelte @@ -0,0 +1,13 @@ + + + diff --git a/apps/web/src/lib/components/ui/switch/index.ts b/apps/web/src/lib/components/ui/switch/index.ts new file mode 100644 index 0000000..f5533db --- /dev/null +++ b/apps/web/src/lib/components/ui/switch/index.ts @@ -0,0 +1,7 @@ +import Root from "./switch.svelte"; + +export { + Root, + // + Root as Switch, +}; diff --git a/apps/web/src/lib/components/ui/switch/switch.svelte b/apps/web/src/lib/components/ui/switch/switch.svelte new file mode 100644 index 0000000..78477dd --- /dev/null +++ b/apps/web/src/lib/components/ui/switch/switch.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/table/index.ts b/apps/web/src/lib/components/ui/table/index.ts new file mode 100644 index 0000000..14695c8 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/index.ts @@ -0,0 +1,28 @@ +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, +}; diff --git a/apps/web/src/lib/components/ui/table/table-body.svelte b/apps/web/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 0000000..29e9687 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-caption.svelte b/apps/web/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 0000000..4696cff --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-cell.svelte b/apps/web/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 0000000..1a2f033 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-footer.svelte b/apps/web/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 0000000..b9b14eb --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,20 @@ + + +tr]:last:border-b-0", className)} + {...restProps} +> + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-head.svelte b/apps/web/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 0000000..e9dd237 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-header.svelte b/apps/web/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 0000000..f47d259 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table-row.svelte b/apps/web/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 0000000..0df769e --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,23 @@ + + +svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/table/table.svelte b/apps/web/src/lib/components/ui/table/table.svelte new file mode 100644 index 0000000..a334956 --- /dev/null +++ b/apps/web/src/lib/components/ui/table/table.svelte @@ -0,0 +1,22 @@ + + +
    + + {@render children?.()} +
    +
    diff --git a/apps/web/src/lib/components/ui/tabs/index.ts b/apps/web/src/lib/components/ui/tabs/index.ts new file mode 100644 index 0000000..12d4327 --- /dev/null +++ b/apps/web/src/lib/components/ui/tabs/index.ts @@ -0,0 +1,16 @@ +import Root from "./tabs.svelte"; +import Content from "./tabs-content.svelte"; +import List from "./tabs-list.svelte"; +import Trigger from "./tabs-trigger.svelte"; + +export { + Root, + Content, + List, + Trigger, + // + Root as Tabs, + Content as TabsContent, + List as TabsList, + Trigger as TabsTrigger, +}; diff --git a/apps/web/src/lib/components/ui/tabs/tabs-content.svelte b/apps/web/src/lib/components/ui/tabs/tabs-content.svelte new file mode 100644 index 0000000..340d65c --- /dev/null +++ b/apps/web/src/lib/components/ui/tabs/tabs-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/apps/web/src/lib/components/ui/tabs/tabs-list.svelte b/apps/web/src/lib/components/ui/tabs/tabs-list.svelte new file mode 100644 index 0000000..08932b6 --- /dev/null +++ b/apps/web/src/lib/components/ui/tabs/tabs-list.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/tabs/tabs-trigger.svelte b/apps/web/src/lib/components/ui/tabs/tabs-trigger.svelte new file mode 100644 index 0000000..dced992 --- /dev/null +++ b/apps/web/src/lib/components/ui/tabs/tabs-trigger.svelte @@ -0,0 +1,20 @@ + + + diff --git a/apps/web/src/lib/components/ui/tabs/tabs.svelte b/apps/web/src/lib/components/ui/tabs/tabs.svelte new file mode 100644 index 0000000..ef6cada --- /dev/null +++ b/apps/web/src/lib/components/ui/tabs/tabs.svelte @@ -0,0 +1,19 @@ + + + diff --git a/apps/web/src/lib/components/ui/terminal/index.ts b/apps/web/src/lib/components/ui/terminal/index.ts new file mode 100644 index 0000000..b600432 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/index.ts @@ -0,0 +1,9 @@ + + +import Loop from "./terminal-loop.svelte"; +import Root from "./terminal.svelte"; +import TypingAnimation from "./terminal-typing-animation.svelte"; +import AnimatedSpan from "./terminal-animated-span.svelte"; +import Loading from "./terminal-loading.svelte"; + +export { Loop, Root, TypingAnimation, AnimatedSpan, Loading }; diff --git a/apps/web/src/lib/components/ui/terminal/terminal-animated-span.svelte b/apps/web/src/lib/components/ui/terminal/terminal-animated-span.svelte new file mode 100644 index 0000000..beeea37 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal-animated-span.svelte @@ -0,0 +1,35 @@ + + +{#if playAnimation} + + {@render children?.()} + +{/if} diff --git a/apps/web/src/lib/components/ui/terminal/terminal-loading.svelte b/apps/web/src/lib/components/ui/terminal/terminal-loading.svelte new file mode 100644 index 0000000..b5b15a2 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal-loading.svelte @@ -0,0 +1,65 @@ + + +{#if playAnimation && !complete} + + {frames[frameIndex]} + {@render loadingMessage()} + +{:else if playAnimation} + + {@render completeMessage()} + +{/if} diff --git a/apps/web/src/lib/components/ui/terminal/terminal-loop.svelte b/apps/web/src/lib/components/ui/terminal/terminal-loop.svelte new file mode 100644 index 0000000..81c0206 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal-loop.svelte @@ -0,0 +1,22 @@ + + +{#key loopIndex} + {@render children?.()} +{/key} diff --git a/apps/web/src/lib/components/ui/terminal/terminal-typing-animation.svelte b/apps/web/src/lib/components/ui/terminal/terminal-typing-animation.svelte new file mode 100644 index 0000000..250acc5 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal-typing-animation.svelte @@ -0,0 +1,33 @@ + + +{#if playAnimation} + animation.onComplete?.() + }} + > + {@render children?.()} + +{/if} diff --git a/apps/web/src/lib/components/ui/terminal/terminal.svelte b/apps/web/src/lib/components/ui/terminal/terminal.svelte new file mode 100644 index 0000000..a712d62 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal.svelte @@ -0,0 +1,30 @@ + + + + {@render children?.()} + diff --git a/apps/web/src/lib/components/ui/terminal/terminal.svelte.ts b/apps/web/src/lib/components/ui/terminal/terminal.svelte.ts new file mode 100644 index 0000000..fc1d1e5 --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/terminal.svelte.ts @@ -0,0 +1,109 @@ +import { Context } from "runed"; + +export type Timeout = ReturnType | undefined; + +export type TerminalLoopProps = { + onComplete: () => void; +}; + +export class TerminalLoop { + constructor(readonly opts: TerminalLoopProps) { + this.onComplete = this.onComplete.bind(this); + } + + onComplete() { + this.opts.onComplete(); + } +} + +export type TerminalRootProps = { + delay: number; + speed: number; + onComplete: () => void; +}; + +export class TerminalSession { + #animations: AnimationState[] = $state([]); + #timeout: Timeout; + + constructor( + readonly opts: TerminalRootProps, + readonly loop?: TerminalLoop + ) { + this.onComplete = this.onComplete.bind(this); + } + + play() { + this.#timeout = setTimeout(() => { + this.#animations.sort((a, b) => a.delay - b.delay); + + for (let i = 0; i < this.#animations.length; i++) { + this.#animations[i].timeout = setTimeout(() => { + this.#animations[i].play(this.opts.speed); + + // when the most delayed animation is complete call onComplete + if (i === this.#animations.length - 1) { + this.#animations[i].onComplete = this.onComplete; + } + }, this.#animations[i].delay); + } + }, this.opts.delay); + } + + onComplete() { + this.opts.onComplete?.(); + + this.loop?.onComplete(); + } + + dispose() { + clearTimeout(this.#timeout); + } + + registerAnimation(animation: AnimationState) { + this.#animations.push(animation); + } +} + +export type AnimationStateProps = { + delay: number; + play: (speed: number) => void; +}; + +export class AnimationState { + delay: number; + timeout: Timeout; + onComplete = $state<() => void>(); + + constructor( + readonly rootState: TerminalSession, + readonly opts: AnimationStateProps + ) { + this.delay = opts.delay; + + rootState.registerAnimation(this); + } + + play(speed: number) { + this.opts.play(speed); + } + + dispose() { + clearTimeout(this.timeout); + } +} + +const TerminalLoopContext = new Context("Terminal.Loop"); +const TerminalRootContext = new Context("Terminal.Root"); + +export const useTerminalLoop = (props: TerminalLoopProps) => { + return TerminalLoopContext.set(new TerminalLoop(props)); +}; + +export const useTerminalRoot = (props: TerminalRootProps) => { + return TerminalRootContext.set(new TerminalSession(props, TerminalLoopContext.getOr(undefined))); +}; + +export const useAnimation = (props: AnimationStateProps) => { + return new AnimationState(TerminalRootContext.get(), props); +}; diff --git a/apps/web/src/lib/components/ui/terminal/types.ts b/apps/web/src/lib/components/ui/terminal/types.ts new file mode 100644 index 0000000..b72778d --- /dev/null +++ b/apps/web/src/lib/components/ui/terminal/types.ts @@ -0,0 +1,24 @@ +import type { WithChildren } from "bits-ui"; +import type { Snippet } from "svelte"; + +export type TerminalRootProps = WithChildren<{ + class?: string; + delay?: number; + speed?: number; + onComplete?: () => void; +}>; + +export type TerminalLoopProps = WithChildren<{ + delay?: number; +}>; + +export type TerminalAnimationProps = WithChildren<{ + delay?: number; + class?: string; +}>; + +export type TerminalLoadingProps = Omit & { + loadingMessage: Snippet<[]>; + completeMessage: Snippet<[]>; + duration?: number; +}; diff --git a/apps/web/src/lib/components/ui/textarea/index.ts b/apps/web/src/lib/components/ui/textarea/index.ts new file mode 100644 index 0000000..ace797a --- /dev/null +++ b/apps/web/src/lib/components/ui/textarea/index.ts @@ -0,0 +1,7 @@ +import Root from "./textarea.svelte"; + +export { + Root, + // + Root as Textarea, +}; diff --git a/apps/web/src/lib/components/ui/textarea/textarea.svelte b/apps/web/src/lib/components/ui/textarea/textarea.svelte new file mode 100644 index 0000000..545b377 --- /dev/null +++ b/apps/web/src/lib/components/ui/textarea/textarea.svelte @@ -0,0 +1,22 @@ + + + diff --git a/apps/web/src/lib/components/ui/theme-selector/index.ts b/apps/web/src/lib/components/ui/theme-selector/index.ts new file mode 100644 index 0000000..e1341fd --- /dev/null +++ b/apps/web/src/lib/components/ui/theme-selector/index.ts @@ -0,0 +1,5 @@ + + +import ThemeSelector from "./theme-selector.svelte"; + +export { ThemeSelector }; diff --git a/apps/web/src/lib/components/ui/theme-selector/theme-selector.svelte b/apps/web/src/lib/components/ui/theme-selector/theme-selector.svelte new file mode 100644 index 0000000..87889ea --- /dev/null +++ b/apps/web/src/lib/components/ui/theme-selector/theme-selector.svelte @@ -0,0 +1,30 @@ + + + + + + + + + + + Toggle theme + + + setMode('light')}>Light + setMode('dark')}>Dark + resetMode()}>System + + diff --git a/apps/web/src/lib/components/ui/toggle-group/index.ts b/apps/web/src/lib/components/ui/toggle-group/index.ts new file mode 100644 index 0000000..12b14b9 --- /dev/null +++ b/apps/web/src/lib/components/ui/toggle-group/index.ts @@ -0,0 +1,10 @@ +import Root from "./toggle-group.svelte"; +import Item from "./toggle-group-item.svelte"; + +export { + Root, + Item, + // + Root as ToggleGroup, + Item as ToggleGroupItem, +}; diff --git a/apps/web/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/apps/web/src/lib/components/ui/toggle-group/toggle-group-item.svelte new file mode 100644 index 0000000..a22a114 --- /dev/null +++ b/apps/web/src/lib/components/ui/toggle-group/toggle-group-item.svelte @@ -0,0 +1,34 @@ + + + diff --git a/apps/web/src/lib/components/ui/toggle-group/toggle-group.svelte b/apps/web/src/lib/components/ui/toggle-group/toggle-group.svelte new file mode 100644 index 0000000..351fbd8 --- /dev/null +++ b/apps/web/src/lib/components/ui/toggle-group/toggle-group.svelte @@ -0,0 +1,47 @@ + + + + + + diff --git a/apps/web/src/lib/components/ui/toggle/index.ts b/apps/web/src/lib/components/ui/toggle/index.ts new file mode 100644 index 0000000..e90cc5d --- /dev/null +++ b/apps/web/src/lib/components/ui/toggle/index.ts @@ -0,0 +1,13 @@ +import Root from "./toggle.svelte"; +export { + toggleVariants, + type ToggleSize, + type ToggleVariant, + type ToggleVariants +} from "./toggle.svelte"; + +export { + Root, + // + Root as Toggle +}; diff --git a/apps/web/src/lib/components/ui/toggle/toggle.svelte b/apps/web/src/lib/components/ui/toggle/toggle.svelte new file mode 100644 index 0000000..e8beb82 --- /dev/null +++ b/apps/web/src/lib/components/ui/toggle/toggle.svelte @@ -0,0 +1,52 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/tooltip/index.ts b/apps/web/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 0000000..313a7f0 --- /dev/null +++ b/apps/web/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,21 @@ +import { Tooltip as TooltipPrimitive } from "bits-ui"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; + +const Root = TooltipPrimitive.Root; +const Provider = TooltipPrimitive.Provider; +const Portal = TooltipPrimitive.Portal; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/apps/web/src/lib/components/ui/tooltip/tooltip-content.svelte b/apps/web/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..e495efe --- /dev/null +++ b/apps/web/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,47 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    diff --git a/apps/web/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/apps/web/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..1acdaa4 --- /dev/null +++ b/apps/web/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/apps/web/src/lib/components/ui/tree-view/index.ts b/apps/web/src/lib/components/ui/tree-view/index.ts new file mode 100644 index 0000000..801cc6f --- /dev/null +++ b/apps/web/src/lib/components/ui/tree-view/index.ts @@ -0,0 +1,16 @@ + + +import TreeView from "./tree-view.svelte"; +import TreeViewFile from "./tree-view-file.svelte"; +import TreeViewFolder from "./tree-view-folder.svelte"; + +export { + TreeView, + TreeViewFile, + TreeViewFolder, + + // ... + TreeView as Root, + TreeViewFile as File, + TreeViewFolder as Folder +}; diff --git a/apps/web/src/lib/components/ui/tree-view/tree-view-file.svelte b/apps/web/src/lib/components/ui/tree-view/tree-view-file.svelte new file mode 100644 index 0000000..91ca072 --- /dev/null +++ b/apps/web/src/lib/components/ui/tree-view/tree-view-file.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/apps/web/src/lib/components/ui/tree-view/tree-view-folder.svelte b/apps/web/src/lib/components/ui/tree-view/tree-view-folder.svelte new file mode 100644 index 0000000..c09506e --- /dev/null +++ b/apps/web/src/lib/components/ui/tree-view/tree-view-folder.svelte @@ -0,0 +1,38 @@ + + + + + + + {#if icon} + {@render icon({ name, open })} + {:else if open} + + {:else} + + {/if} + {name} + + +
    +
    +
    + {@render children?.()} +
    +
    +
    +
    diff --git a/apps/web/src/lib/components/ui/tree-view/tree-view.svelte b/apps/web/src/lib/components/ui/tree-view/tree-view.svelte new file mode 100644 index 0000000..aeb7caa --- /dev/null +++ b/apps/web/src/lib/components/ui/tree-view/tree-view.svelte @@ -0,0 +1,12 @@ + + + + +
    + {@render children?.()} +
    diff --git a/apps/web/src/lib/components/ui/tree-view/types.ts b/apps/web/src/lib/components/ui/tree-view/types.ts new file mode 100644 index 0000000..6f647ee --- /dev/null +++ b/apps/web/src/lib/components/ui/tree-view/types.ts @@ -0,0 +1,22 @@ + + +import type { WithChildren, WithoutChildren } from "bits-ui"; +import type { Snippet } from "svelte"; +import type { HTMLAttributes, HTMLButtonAttributes } from "svelte/elements"; + +export type TreeViewRootProps = HTMLAttributes; + +export type TreeViewFolderProps = WithChildren<{ + name: string; + open?: boolean; + class?: string; + icon?: Snippet<[{ name: string; open: boolean }]>; +}>; + +export type TreeViewFilePropsWithoutHTML = WithChildren<{ + name: string; + icon?: Snippet<[{ name: string }]>; +}>; + +export type TreeViewFileProps = WithoutChildren & + TreeViewFilePropsWithoutHTML; diff --git a/apps/web/src/lib/components/ui/window/index.ts b/apps/web/src/lib/components/ui/window/index.ts new file mode 100644 index 0000000..b535558 --- /dev/null +++ b/apps/web/src/lib/components/ui/window/index.ts @@ -0,0 +1,5 @@ + + +import Window from "./window.svelte"; + +export { Window }; diff --git a/apps/web/src/lib/components/ui/window/window.svelte b/apps/web/src/lib/components/ui/window/window.svelte new file mode 100644 index 0000000..c0957b5 --- /dev/null +++ b/apps/web/src/lib/components/ui/window/window.svelte @@ -0,0 +1,27 @@ + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + {@render children?.()} +
    +
    diff --git a/apps/web/src/lib/hooks/is-mac.svelte.ts b/apps/web/src/lib/hooks/is-mac.svelte.ts new file mode 100644 index 0000000..0cbd96a --- /dev/null +++ b/apps/web/src/lib/hooks/is-mac.svelte.ts @@ -0,0 +1,7 @@ +/** Attempts to determine if a user is on a Mac using `navigator.userAgent`. */ +export const isMac = navigator.userAgent.includes("Mac"); + +/** `⌘` for mac or `Ctrl` for windows */ +export const cmdOrCtrl = isMac ? "⌘" : "Ctrl"; +/** `⌥` for mac or `Alt` for windows */ +export const optionOrAlt = isMac ? "⌥" : "Alt"; diff --git a/apps/web/src/lib/hooks/is-mobile.svelte.ts b/apps/web/src/lib/hooks/is-mobile.svelte.ts new file mode 100644 index 0000000..4829c00 --- /dev/null +++ b/apps/web/src/lib/hooks/is-mobile.svelte.ts @@ -0,0 +1,9 @@ +import { MediaQuery } from "svelte/reactivity"; + +const DEFAULT_MOBILE_BREAKPOINT = 768; + +export class IsMobile extends MediaQuery { + constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) { + super(`max-width: ${breakpoint - 1}px`); + } +} diff --git a/apps/web/src/lib/hooks/use-clipboard.svelte.ts b/apps/web/src/lib/hooks/use-clipboard.svelte.ts new file mode 100644 index 0000000..a4e0236 --- /dev/null +++ b/apps/web/src/lib/hooks/use-clipboard.svelte.ts @@ -0,0 +1,83 @@ +type Options = { + /** The time before the copied status is reset. */ + delay: number; +}; + +/** Use this hook to copy text to the clipboard and show a copied state. + * + * ## Usage + * ```svelte + * + * + * + * ``` + * + */ +export class UseClipboard { + #copiedStatus = $state<"success" | "failure">(); + private delay: number; + private timeout: ReturnType | undefined = undefined; + + constructor({ delay = 500 }: Partial = {}) { + this.delay = delay; + } + + /** Copies the given text to the users clipboard. + * + * ## Usage + * ```ts + * clipboard.copy('Hello, World!'); + * ``` + * + * @param text + * @returns + */ + async copy(text: string) { + if (this.timeout) { + this.#copiedStatus = undefined; + clearTimeout(this.timeout); + } + + try { + await navigator.clipboard.writeText(text); + + this.#copiedStatus = "success"; + + this.timeout = setTimeout(() => { + this.#copiedStatus = undefined; + }, this.delay); + } catch { + // an error can occur when not in the browser or if the user hasn't given clipboard access + this.#copiedStatus = "failure"; + + this.timeout = setTimeout(() => { + this.#copiedStatus = undefined; + }, this.delay); + } + + return this.#copiedStatus; + } + + /** true when the user has just copied to the clipboard. */ + get copied() { + return this.#copiedStatus === "success"; + } + + /** Indicates whether a copy has occurred + * and gives a status of either `success` or `failure`. */ + get status() { + return this.#copiedStatus; + } +} diff --git a/apps/web/src/lib/hooks/use-media.svelte.ts b/apps/web/src/lib/hooks/use-media.svelte.ts new file mode 100644 index 0000000..7161f63 --- /dev/null +++ b/apps/web/src/lib/hooks/use-media.svelte.ts @@ -0,0 +1,34 @@ +import { MediaQuery } from "svelte/reactivity"; + +export type Breakpoints = Record; + +/** Based on the default Tailwind CSS breakpoints https://tailwindcss.com/docs/responsive-design. + * A breakpoint is `true` when the width of the screen is greater than or equal to the breakpoint. */ +export const TAILWIND_BREAKPOINTS: Breakpoints<"sm" | "md" | "lg" | "xl" | "2xl"> = { + sm: "40rem", + md: "48rem", + lg: "64rem", + xl: "80rem", + "2xl": "96rem" +}; + +/** Dynamically creates media queries for the provided breakpoints allowing you to access them as `media.`. + * + * @param breakpoints + * @returns + */ +export function useMedia( + breakpoints: Breakpoints = TAILWIND_BREAKPOINTS as Breakpoints +): Record { + const queries = {}; + + for (const [name, size] of Object.entries(breakpoints)) { + const query = new MediaQuery(`min-width: ${size}`); + + Object.defineProperty(queries, name, { + get: () => query.current + }); + } + + return queries as Record; +} diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts new file mode 100644 index 0000000..55b3a91 --- /dev/null +++ b/apps/web/src/lib/utils.ts @@ -0,0 +1,13 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChild = T extends { child?: any } ? Omit : T; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChildren = T extends { children?: any } ? Omit : T; +export type WithoutChildrenOrChild = WithoutChildren>; +export type WithElementRef = T & { ref?: U | null }; diff --git a/apps/web/src/lib/utils/ipv4-address.ts b/apps/web/src/lib/utils/ipv4-address.ts new file mode 100644 index 0000000..6b9eacf --- /dev/null +++ b/apps/web/src/lib/utils/ipv4-address.ts @@ -0,0 +1,106 @@ +import { isNumber } from "$lib/utils/is-number"; +import { Err, Ok, type Result } from "$lib/utils/result"; + +export type Octets = [number, number, number, number]; + +export type IPv4Address = + | Octets + | `${number}.${number}.${number}.${number}` + | `${number} ${number} ${number} ${number}` + | `${number}_${number}_${number}_${number}`; + +export type ParseError = { + octet?: number; + message: string; +}; + +/** Parses the ip address from a string in the format of `0.0.0.0` or `0 0 0 0` or `0_0_0_0` into an array of octets + * + * @param address + * @returns + * + * ## Usage + * + * ```ts + * parse("192.168.100.10").unwrap(); // [192, 168, 100, 10] + * ``` + */ +export function parse(address: string): Result { + let newAddress = address.trim(); + + newAddress = newAddress.replaceAll(" ", "."); + newAddress = newAddress.replaceAll("_", "."); + + const octets = newAddress.split("."); + + if (octets.length !== 4) + return Err({ message: `'${address}' is invalid as it doesn't contain 4 octets.` }); + + const final: Octets = [0, 0, 0, 0]; + + for (let i = 0; i < octets.length; i++) { + const octet = octets[i]; + + if (!isNumber(octet)) return Err({ octet: i + 1, message: `'${octet}' is not a number.` }); + + const num = Number.parseInt(octet); + + if (num < 0 || num > 255) return Err({ octet: i + 1, message: `'${octet}' is out of range.` }); + + final[i] = num; + } + + return Ok(final); +} + +/** Validates the provided address + * + * @param address + * @returns + * + * ## Usage + * + * ```ts + * validate("192.168.100.10"); // true + * validate([192, 168, 100, 10]); // true + * + * validate("192.168.100.256"); // false + * validate([192, 168, 100, 256]); // false + * ``` + */ +export function validate(address: IPv4Address): boolean { + if (typeof address === "string") return parse(address).isOk(); + + for (let i = 0; i < address.length; i++) { + const octet = address[i]; + + if (octet < 0 || octet > 255) return false; + } + + return true; +} + +/** Formats the provided address to a string with the provided separator + * + * @param address + * @param separator @default "." + * @returns + * + * ## Usage + * + * ```ts + * formatToString([192, 168, 100, 10]); // "192.168.100.10" + * ``` + */ +export function formatToString( + address: IPv4Address, + separator: "." | "_" | " " = "." +): Result { + if (Array.isArray(address)) return Ok(address.join(separator)); + + const parsed = parse(address); + + if (parsed.isErr()) return Err(parsed.unwrapErr().message); + + return formatToString(parsed.unwrap(), separator); +} diff --git a/apps/web/src/lib/utils/is-number.ts b/apps/web/src/lib/utils/is-number.ts new file mode 100644 index 0000000..8d9d664 --- /dev/null +++ b/apps/web/src/lib/utils/is-number.ts @@ -0,0 +1,24 @@ +/** Checks if provided value is actually a number. + * + * @param num value to check + * @returns + * + * ## Usage + * + * ```ts + * isNumber("2"); // true + * isNumber("1.11"); // true + * isNumber("0xff"); // true + * + * isNumber("two"); // false + * isNumber({ two: 2 }); // false + * isNumber(Number.POSITIVE_INFINITY); // false + * ``` + */ +export function isNumber(num: unknown): boolean { + if (typeof num === "number") return num - num === 0; + + if (typeof num === "string" && num.trim() !== "") return Number.isFinite(+num); + + return false; +} diff --git a/apps/web/src/lib/utils/result.ts b/apps/web/src/lib/utils/result.ts new file mode 100644 index 0000000..fed72ac --- /dev/null +++ b/apps/web/src/lib/utils/result.ts @@ -0,0 +1,730 @@ +/** This is just a helper type used only within this file */ +type _Result = { ok: true; val: T } | { ok: false; err: E }; + +/** Result allows you to show to a consumer that a function might throw and force them to handle it. + * + * `T` Value type + * + * `E` Error type + * + * ## Usage + * + * ```ts + * function functionThatMightFail(): Result; + * ``` + * + * ## Usage + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello, World!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrap()); // "Hello, World!" + * ``` + */ +class Result { + private readonly _result: _Result; + + constructor(result: _Result) { + this._result = result; + } + + /** Allows you to run callbacks based on the result. + * + * @param success callback to be run when result is success + * @param failure callback to be run when result is failure + * @returns + * + * ## Usage + * + * ```ts + * result.match( + * (val) => val, + * () => { + * throw new Error('oops!') + * } + * ); + * ``` + * + * ## Usage + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello, World!"); + * + * const result = functionThatMightFail(); + * + * const val = result.match( + * (val) => val, + * () => { + * throw new Error('oops!') + * } + * ); + * + * console.log(val); // "Hello, World!" + * ``` + */ + match(success: (val: T) => A, failure: (err: E) => B): A | B { + if (!this._result.ok) { + return failure(this._result.err); + } + + return success(this._result.val); + } + + /** Maps `Result` to `Result` using the passed mapping function + * + * @param fn Mapping function + * @returns + * + * ## Usage + * + * ```ts + * result.map((val) => val.length); + * ``` + * + * ## Usage + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello, World!"); + * + * const result = functionThatMightFail(); + * + * const hello = result.map((val) => val.slice(0, 5)); + * + * console.log(hello.unwrap()); // "Hello" + * ``` + */ + map(fn: (val: T) => A): Result { + return this.match( + (val) => Ok(fn(val)), + (err) => Err(err) + ); + } + + /** In the `Ok` case returns the mapped value using the function else returns `defaultVal` + * + * @param defaultVal Value to be returned when `Err` + * @param fn Mapping function to map in case of `Ok` + * @returns + * + * ## Usage + * + * ```ts + * result.mapOr(1, (val) => val.length); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("foo"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapOr(1, (val) => val.length); + * + * console.log(length); // 3 + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapOr(1, (val) => val.length); + * + * console.log(length); // 1 + * ``` + */ + mapOr(defaultVal: A, fn: (val: T) => A): A { + return this.match( + (val) => fn(val), + (_) => defaultVal + ); + } + + /** In the `Ok` case returns the mapped value using `fn` else returns value of `def` + * + * @param def Mapping function called when `Err` + * @param fn Mapping function called when `Ok` + * @returns + * + * ## Usage + * + * ```ts + * result.mapOrElse(() => 1, (val) => val.length); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("foo"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapOrElse(() => 1, (val) => val.length); + * + * console.log(length); // 3 + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapOr(() => 1, (val) => val.length); + * + * console.log(length); // 1 + * ``` + */ + mapOrElse(def: (err: E) => A, fn: (val: T) => A): A { + return this.match( + (val) => fn(val), + (err) => def(err) + ); + } + + /** Maps `Result` to `Result` using the passed mapping function + * + * @param fn Mapping function + * @returns + * + * ## Usage + * + * ```ts + * result.mapErr((err) => getCodeMsg(err)); + * ``` + * + * ## Usage + * + * ```ts + * const functionThatMightFail = (): Result => Err(10); + * + * const result = functionThatMightFail(); + * + * const message = result.mapErr(() => "Error"); + * + * console.log(message); // "Error" + * ``` + */ + mapErr(fn: (err: E) => A): Result { + return this.match( + (val) => Ok(val), + (err) => Err(fn(err)) + ); + } + + /** In the `Err` case returns the mapped value using the function else returns `defaultVal` + * + * @param defaultVal Value to be returned when `Ok` + * @param fn Mapping function to map in case of `Err` + * @returns + * + * ## Usage + * + * ```ts + * result.mapErrOr("Should've been error", (err) => getCodeMsg(err)); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("foo"); + * + * const result = functionThatMightFail(); + * + * const message = result.mapErrOr("Should've been error", () => "Error"); + * + * console.log(message); // "Should've been error" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err(10); + * + * const result = functionThatMightFail(); + * + * const message = result.mapErrOr("Should've been error", () => "Error"); + * + * console.log(message); // "Error" + * ``` + */ + mapErrOr(defaultVal: A, fn: (err: E) => A): A { + return this.match( + (_) => defaultVal, + (err) => fn(err) + ); + } + + /** In the `Err` case returns the mapped value using the function else returns value of `def` + * + * @param def Mapping function called when `Ok` + * @param fn Mapping function called when `Err` + * @returns + * + * ## Usage + * + * ```ts + * result.mapErrOrElse(() => "Value", (_) => "Error!"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("foo"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapErrOrElse(() => 1, (val) => val.length); + * + * console.log(length); // 1 + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * const length = result.mapOr(() => 1, (val) => val.length); + * + * console.log(length); // 4 + * ``` + */ + mapErrOrElse(def: (val: T) => A, fn: (err: E) => A): A { + return this.match( + (val) => def(val), + (err) => fn(err) + ); + } + + /** Returns true if result is `Ok` + * + * @returns + * + * ## Usage + * + * ```ts + * result.isOk(); + * ``` + */ + isOk(): boolean { + return this.match( + () => true, + () => false + ); + } + + /** Returns true if result is `Err` + * + * @returns + * + * ## Usage + * + * ```ts + * result.isErr(); + * ``` + */ + isErr(): boolean { + return this.match( + () => false, + () => true + ); + } + + /** Tries to return value if value is `Err` throws generic error message. + * + * @returns + * + * ## Usage + * + * ```ts + * result.unwrap(); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrap()); // "Hello!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * result.unwrap(); // Error: Attempted to call `.unwrap()` on a non `Ok` value. + * ``` + */ + unwrap(): T { + return this.match( + (val) => val, + () => { + throw new Error("Attempted to call `.unwrap()` on a non `Ok` value."); + } + ); + } + + /** Tries to return err if value is `Ok` throws generic error message. + * + * @returns + * + * ## Usage + * + * ```ts + * result.unwrapErr(); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * result.unwrapErr(); // Error: Attempted to call `.unwrapErr()` on a non `Err` value. + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapErr()); // "oops!" + * ``` + */ + unwrapErr(): E { + return this.match( + () => { + throw new Error("Attempted to call `.unwrapErr()` on a non `Err` value."); + }, + (err) => err + ); + } + + /** Tries to unwrap the value if value is `Err` returns `defaultVal` + * + * @param defaultVal Value to be returned if `Err` + * @returns + * + * ## Usage + * + * ```ts + * result.unwrapOr(7); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapOr("Yellow!")); // "Hello!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapOr("Yellow!")); // "Yellow!" + * ``` + */ + unwrapOr(defaultVal: T): T { + return this.match( + (val) => val, + (_) => defaultVal + ); + } + + /** Tries to unwrap the error if vale is `Ok` returns `defaultVal` + * + * @param defaultVal + * @returns + * + * ## Usage + * + * ```ts + * result.unwrapErrOr("Error"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapErrOr("Yellow!")); // "Yellow!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapErrOr("Yellow!")); // "oops!" + * ``` + */ + unwrapErrOr(defaultVal: E): E { + return this.match( + () => defaultVal, + (err) => err + ); + } + + /** Tries to return the value if value is `Err` calls `fn` + * + * @param fn Function called if `Err` + * + * ## Usage + * + * ```ts + * result.unwrapOrElse(() => "Hello!"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapOrElse(() => "oops!")); // "Hello!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapOrElse(() => "Hello!")); // "Hello!" + * ``` + * + */ + unwrapOrElse(fn: (err: E) => T): T { + return this.match( + (val) => val, + (err) => fn(err) + ); + } + + /** Tries to return the error if value is `Ok` calls `fn` + * + * @param fn Function called if `Ok` + * + * ## Usage + * + * ```ts + * result.unwrapErrOrElse(() => "Error!"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapErrOrElse(() => "oops!")); // "oops!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.unwrapErrOrElse(() => "Hello!")); // "oops!" + * ``` + * + */ + unwrapErrOrElse(fn: (val: T) => E): E { + return this.match( + (val) => fn(val), + (err) => err + ); + } + + /** Tries to return value if value is `Err` throws custom error message. + * + * @param message Message to show when value is `Err` + * @returns + * + * ## Usage + * + * ```ts + * result.expect("Custom message"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.expect("I failed!")); // "Hello!" + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * result.expect("I failed!"); // Error: I failed! + * ``` + */ + expect(message: string): T { + return this.match( + (val) => val, + () => { + throw new Error(message); + } + ); + } + + /** Tries to return error value if value is `Ok` throws custom error message + * + * @param message + * @returns + * + * ## Usage + * + * ```ts + * result.expectErr("Custom message"); + * ``` + * + * ## Usage + * + * ### When `Ok` + * + * ```ts + * const functionThatMightFail = (): Result => Ok("Hello!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.expectErr("I failed!")); // Error: I failed! + * ``` + * + * ### When `Err` + * + * ```ts + * const functionThatMightFail = (): Result => Err("oops!"); + * + * const result = functionThatMightFail(); + * + * console.log(result.expectErr("I failed!")); // "oops!" + * ``` + */ + expectErr(message: string): E { + return this.match( + () => { + throw new Error(message); + }, + (err) => err + ); + } +} + +/** Returns a new `Ok` result type with the provided value + * + * @param val Value of the result + * @returns + * + * ## Usage + * + * ```ts + * Ok(true); + * ``` + * + * ## Usage + * + * ```ts + * const functionThatCanFail = (condition) => { + * if (condition) { + * Ok("Success") + * } + * + * return Err("Failure"); + * } + * ``` + */ +export function Ok(val: T): Result { + return new Result({ ok: true, val }); +} + +/** Returns a new `Err` result type with the provided error + * + * @param err Error of the result + * @returns + * + * ## Usage + * + * ```ts + * Err("I failed!"); + * ``` + * + * ## Usage + * + * ```ts + * const functionThatCanFail = (condition) => { + * if (condition) { + * Ok("Success") + * } + * + * return Err("Failure"); + * } + * ``` + */ +export function Err(err: E): Result { + return new Result({ ok: false, err }); +} + +export type { Result }; diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte new file mode 100644 index 0000000..3153e95 --- /dev/null +++ b/apps/web/src/routes/+layout.svelte @@ -0,0 +1,7 @@ + + +{@render children()} diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte index 3b6d759..b13454e 100644 --- a/apps/web/src/routes/+page.svelte +++ b/apps/web/src/routes/+page.svelte @@ -1,7 +1,5 @@

    Web

    -

    Visit kit.svelte.dev to read the documentation

    diff --git a/apps/web/svelte.config.js b/apps/web/svelte.config.js index 9041ab6..4f01c27 100644 --- a/apps/web/svelte.config.js +++ b/apps/web/svelte.config.js @@ -10,7 +10,10 @@ const config = { // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. // If your environment is not supported or you settled on a specific environment, switch out the adapter. // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter() + adapter: adapter(), + alias: { + "@/*": "./src/lib/*" + } }, }; diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index bbf8c7d..ae739f9 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,6 +1,7 @@ -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; +import tailwindcss from "@tailwindcss/vite"; +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; export default defineConfig({ - plugins: [sveltekit()] + plugins: [tailwindcss(), sveltekit()] }); diff --git a/package.json b/package.json index a9bc0a5..3e3d512 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "name": "with-svelte", - "private": true, "scripts": { "build": "turbo run build", "dev": "turbo run dev", @@ -16,5 +15,10 @@ "packageManager": "pnpm@10.17.0+sha512.fce8a3dd29a4ed2ec566fb53efbb04d8c44a0f05bc6f24a73046910fb9c3ce7afa35a0980500668fa3573345bd644644fa98338fa168235c80f4aa17aa17fbef", "engines": { "node": ">=18" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "esbuild" + ] } -} +} \ No newline at end of file diff --git a/packages/ui/eslint.config.js b/packages/ui/eslint.config.js deleted file mode 100644 index b225ff4..0000000 --- a/packages/ui/eslint.config.js +++ /dev/null @@ -1,8 +0,0 @@ -import { config } from '@repo/eslint-config/index.js'; - -export default [ - ...config, - { - ignores: ['.svelte-kit/**', 'dist/**'] - } -]; diff --git a/packages/ui/index.ts b/packages/ui/index.ts deleted file mode 100644 index 6066c07..0000000 --- a/packages/ui/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as MyCounterButton } from './components/MyCounterButton.svelte'; diff --git a/packages/ui/package.json b/packages/ui/package.json deleted file mode 100644 index 70bfa3f..0000000 --- a/packages/ui/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@repo/ui", - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "svelte-kit sync && svelte-package --watch --input=src", - "build": "svelte-kit sync && svelte-package --input=src", - "lint": "eslint .", - "check-types": "svelte-check --tsconfig ./tsconfig.json" - }, - "files": [ - "dist", - "!dist/**/*.test.*", - "!dist/**/*.spec.*", - "src", - "!src/**/*.test.*", - "!src/**/*.spec.*" - ], - "sideEffects": [ - "**/*.css" - ], - "exports": { - ".": { - "types": "./dist/index.d.ts", - "svelte": "./dist/index.js" - } - }, - "peerDependencies": { - "svelte": "^5.0.0" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@sveltejs/kit": "^2.36.1", - "@sveltejs/package": "^2.5.0", - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "eslint": "^9.34.0", - "svelte": "^5.38.0", - "svelte-check": "^4.3.0", - "typescript": "5.9.2", - "vite": "^6.3.2" - } -} diff --git a/packages/ui/src/MyCounterButton.svelte b/packages/ui/src/MyCounterButton.svelte deleted file mode 100644 index 5531f5c..0000000 --- a/packages/ui/src/MyCounterButton.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts deleted file mode 100644 index ff044f2..0000000 --- a/packages/ui/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Counter } from './my-counter-class.svelte'; -export { default as MyCounterButton } from './MyCounterButton.svelte'; diff --git a/packages/ui/src/my-counter-class.svelte.ts b/packages/ui/src/my-counter-class.svelte.ts deleted file mode 100644 index 5b9c079..0000000 --- a/packages/ui/src/my-counter-class.svelte.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class Counter { - count = $state(0); - - increment = () => { - this.count++; - }; - - decrement = () => { - this.count--; - }; -} diff --git a/packages/ui/svelte.config.js b/packages/ui/svelte.config.js deleted file mode 100644 index 7f2cd0f..0000000 --- a/packages/ui/svelte.config.js +++ /dev/null @@ -1,10 +0,0 @@ -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - // Consult https://kit.svelte.dev/docs/integrations#preprocessors - // for more information about preprocessors - preprocess: vitePreprocess() -}; - -export default config; diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json deleted file mode 100644 index c8ef003..0000000 --- a/packages/ui/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": ["@repo/typescript-config/svelte.json", "./.svelte-kit/tsconfig.json"], - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "allowArbitraryExtensions": true - }, - "include": ["dist", "./src/**/*.svelte", "./src/**/*.ts"], - "exclude": ["node_modules", ".svelte-kit"] -} diff --git a/packages/ui/vite.config.js b/packages/ui/vite.config.js deleted file mode 100644 index 7e8682a..0000000 --- a/packages/ui/vite.config.js +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from 'vite'; -import { svelte } from '@sveltejs/vite-plugin-svelte'; - -export default defineConfig({ - plugins: [ - svelte() - ] -}); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1ccaaa..8a20ef3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,101 +22,292 @@ importers: apps/docs: dependencies: - '@repo/ui': - specifier: workspace:* - version: link:../../packages/ui + marked: + specifier: ^12.0.2 + version: 12.0.2 devDependencies: + '@inlang/paraglide-js': + specifier: ^2.0.0 + version: 2.3.2 + '@internationalized/date': + specifier: ^3.9.0 + version: 3.9.0 + '@lucide/svelte': + specifier: ^0.544.0 + version: 0.544.0(svelte@5.38.0) + '@playwright/test': + specifier: ^1.49.1 + version: 1.55.0 '@repo/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../../packages/typescript-config - '@sveltejs/adapter-auto': - specifier: ^4.0.0 - version: 4.0.0(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))) + '@shikijs/langs': + specifier: ^3.13.0 + version: 3.13.0 + '@shikijs/themes': + specifier: ^3.13.0 + version: 3.13.0 + '@sveltejs/adapter-node': + specifier: ^5.2.12 + version: 5.3.2(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))) '@sveltejs/kit': specifier: ^2.36.1 - version: 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + version: 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) '@sveltejs/vite-plugin-svelte': specifier: ^5.1.0 - version: 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + version: 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@tailwindcss/forms': + specifier: ^0.5.9 + version: 0.5.10(tailwindcss@4.1.13) + '@tailwindcss/typography': + specifier: ^0.5.15 + version: 0.5.18(tailwindcss@4.1.13) + '@tailwindcss/vite': + specifier: ^4.0.0 + version: 4.1.13(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@tanstack/table-core': + specifier: ^8.21.3 + version: 8.21.3 + '@vitest/browser': + specifier: ^3.2.3 + version: 3.2.4(playwright@1.55.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))(vitest@3.2.4) + bits-ui: + specifier: ^2.11.0 + version: 2.11.0(@internationalized/date@3.9.0)(svelte@5.38.0) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + embla-carousel-svelte: + specifier: ^8.6.0 + version: 8.6.0(svelte@5.38.0) eslint: specifier: ^9.34.0 - version: 9.34.0 + version: 9.34.0(jiti@2.5.1) + formsnap: + specifier: ^2.0.1 + version: 2.0.1(svelte@5.38.0)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2)) + isomorphic-dompurify: + specifier: ^2.28.0 + version: 2.28.0(postcss@8.5.6) + layerchart: + specifier: 2.0.0-next.27 + version: 2.0.0-next.27(svelte@5.38.0) + mdsvex: + specifier: ^0.12.3 + version: 0.12.6(svelte@5.38.0) + mode-watcher: + specifier: ^1.1.0 + version: 1.1.0(svelte@5.38.0) + paneforge: + specifier: ^1.0.2 + version: 1.0.2(svelte@5.38.0) + playwright: + specifier: ^1.53.0 + version: 1.55.0 prettier: specifier: ^3.6.0 version: 3.6.0 prettier-plugin-svelte: specifier: ^3.4.0 version: 3.4.0(prettier@3.6.0)(svelte@5.38.0) + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.14(prettier-plugin-svelte@3.4.0(prettier@3.6.0)(svelte@5.38.0))(prettier@3.6.0) + runed: + specifier: ^0.31.1 + version: 0.31.1(svelte@5.38.0) + shiki: + specifier: ^3.13.0 + version: 3.13.0 svelte: specifier: ^5.38.0 version: 5.38.0 svelte-check: specifier: ^4.3.0 - version: 4.3.0(picomatch@4.0.2)(svelte@5.38.0)(typescript@5.9.2) + version: 4.3.0(picomatch@4.0.3)(svelte@5.38.0)(typescript@5.9.2) + svelte-sonner: + specifier: ^1.0.5 + version: 1.0.5(svelte@5.38.0) + svelte-toolbelt: + specifier: ^0.9.3 + version: 0.9.3(svelte@5.38.0) + sveltekit-superforms: + specifier: ^2.27.1 + version: 2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2) + tailwind-merge: + specifier: ^3.3.1 + version: 3.3.1 + tailwind-variants: + specifier: ^3.1.1 + version: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.13) + tailwindcss: + specifier: ^4.0.0 + version: 4.1.13 tslib: specifier: ^2.8.1 version: 2.8.1 + tw-animate-css: + specifier: ^1.3.8 + version: 1.3.8 typescript: specifier: 5.9.2 version: 5.9.2 + vaul-svelte: + specifier: 1.0.0-next.7 + version: 1.0.0-next.7(svelte@5.38.0) vite: specifier: ^6.3.2 - version: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + version: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + vite-plugin-devtools-json: + specifier: ^1.0.0 + version: 1.0.0(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) vitest: - specifier: ^3.2.0 - version: 3.2.0(@types/node@24.5.2)(tsx@4.20.5) + specifier: ^3.2.3 + version: 3.2.4(@types/node@24.5.2)(@vitest/browser@3.2.4)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5) + vitest-browser-svelte: + specifier: ^0.1.0 + version: 0.1.0(@vitest/browser@3.2.4)(svelte@5.38.0)(vitest@3.2.4) apps/web: - dependencies: - '@repo/ui': - specifier: workspace:* - version: link:../../packages/ui devDependencies: + '@internationalized/date': + specifier: ^3.9.0 + version: 3.9.0 + '@lucide/svelte': + specifier: ^0.544.0 + version: 0.544.0(svelte@5.38.0) '@repo/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../../packages/typescript-config + '@shikijs/langs': + specifier: ^3.13.0 + version: 3.13.0 + '@shikijs/themes': + specifier: ^3.13.0 + version: 3.13.0 '@sveltejs/adapter-auto': specifier: ^4.0.0 - version: 4.0.0(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))) + version: 4.0.0(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))) '@sveltejs/kit': specifier: ^2.36.1 - version: 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + version: 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) '@sveltejs/vite-plugin-svelte': specifier: ^5.1.0 - version: 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + version: 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@tailwindcss/forms': + specifier: ^0.5.9 + version: 0.5.10(tailwindcss@4.1.13) + '@tailwindcss/typography': + specifier: ^0.5.15 + version: 0.5.18(tailwindcss@4.1.13) + '@tailwindcss/vite': + specifier: ^4.0.0 + version: 4.1.13(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@tanstack/table-core': + specifier: ^8.21.3 + version: 8.21.3 + '@zxcvbn-ts/core': + specifier: ^3.0.4 + version: 3.0.4 + '@zxcvbn-ts/language-common': + specifier: ^3.0.4 + version: 3.0.4 + '@zxcvbn-ts/language-en': + specifier: ^3.0.2 + version: 3.0.2 + bits-ui: + specifier: ^2.11.0 + version: 2.11.0(@internationalized/date@3.9.0)(svelte@5.38.0) + clsx: + specifier: ^2.1.1 + version: 2.1.1 + embla-carousel-svelte: + specifier: ^8.6.0 + version: 8.6.0(svelte@5.38.0) eslint: specifier: ^9.34.0 - version: 9.34.0 + version: 9.34.0(jiti@2.5.1) + formsnap: + specifier: ^2.0.1 + version: 2.0.1(svelte@5.38.0)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2)) + isomorphic-dompurify: + specifier: ^2.28.0 + version: 2.28.0(postcss@8.5.6) + layerchart: + specifier: 2.0.0-next.27 + version: 2.0.0-next.27(svelte@5.38.0) + mode-watcher: + specifier: ^1.1.0 + version: 1.1.0(svelte@5.38.0) + paneforge: + specifier: ^1.0.2 + version: 1.0.2(svelte@5.38.0) prettier: specifier: ^3.6.0 version: 3.6.0 prettier-plugin-svelte: specifier: ^3.4.0 version: 3.4.0(prettier@3.6.0)(svelte@5.38.0) + prettier-plugin-tailwindcss: + specifier: ^0.6.11 + version: 0.6.14(prettier-plugin-svelte@3.4.0(prettier@3.6.0)(svelte@5.38.0))(prettier@3.6.0) + runed: + specifier: ^0.31.1 + version: 0.31.1(svelte@5.38.0) + shiki: + specifier: ^3.13.0 + version: 3.13.0 svelte: specifier: ^5.38.0 version: 5.38.0 svelte-check: specifier: ^4.3.0 - version: 4.3.0(picomatch@4.0.2)(svelte@5.38.0)(typescript@5.9.2) + version: 4.3.0(picomatch@4.0.3)(svelte@5.38.0)(typescript@5.9.2) + svelte-easy-crop: + specifier: ^5.0.0 + version: 5.0.0(svelte@5.38.0) + svelte-sonner: + specifier: ^1.0.5 + version: 1.0.5(svelte@5.38.0) + svelte-toolbelt: + specifier: ^0.9.3 + version: 0.9.3(svelte@5.38.0) + sveltekit-superforms: + specifier: ^2.27.1 + version: 2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2) + tailwind-merge: + specifier: ^3.3.1 + version: 3.3.1 + tailwind-variants: + specifier: ^3.1.1 + version: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.13) + tailwindcss: + specifier: ^4.0.0 + version: 4.1.13 tslib: specifier: ^2.8.1 version: 2.8.1 + tw-animate-css: + specifier: ^1.3.8 + version: 1.3.8 typescript: specifier: 5.9.2 version: 5.9.2 + vaul-svelte: + specifier: 1.0.0-next.7 + version: 1.0.0-next.7(svelte@5.38.0) vite: specifier: ^6.3.2 - version: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + version: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) vitest: specifier: ^3.2.0 - version: 3.2.0(@types/node@24.5.2)(tsx@4.20.5) + version: 3.2.0(@types/node@24.5.2)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5) packages/eslint-config: devDependencies: @@ -128,61 +319,96 @@ importers: version: 9.34.0 eslint-config-prettier: specifier: ^10.1.1 - version: 10.1.5(eslint@9.34.0) + version: 10.1.5(eslint@9.34.0(jiti@2.5.1)) eslint-config-turbo: specifier: ^2.5.0 - version: 2.5.3(eslint@9.34.0)(turbo@2.5.6) + version: 2.5.3(eslint@9.34.0(jiti@2.5.1))(turbo@2.5.6) eslint-plugin-svelte: specifier: ^2.46.1 - version: 2.46.1(eslint@9.34.0)(svelte@5.38.0) + version: 2.46.1(eslint@9.34.0(jiti@2.5.1))(svelte@5.38.0) globals: specifier: ^15.15.0 version: 15.15.0 typescript-eslint: specifier: ^8.40.0 - version: 8.40.0(eslint@9.34.0)(typescript@5.9.2) + version: 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) packages/typescript-config: {} - packages/ui: - devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config - '@repo/typescript-config': - specifier: workspace:* - version: link:../typescript-config - '@sveltejs/kit': - specifier: ^2.36.1 - version: 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) - '@sveltejs/package': - specifier: ^2.5.0 - version: 2.5.0(svelte@5.38.0)(typescript@5.9.2) - '@sveltejs/vite-plugin-svelte': - specifier: ^5.1.0 - version: 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) - eslint: - specifier: ^9.34.0 - version: 9.34.0 - svelte: - specifier: ^5.38.0 - version: 5.38.0 - svelte-check: - specifier: ^4.3.0 - version: 4.3.0(picomatch@4.0.2)(svelte@5.38.0)(typescript@5.9.2) - typescript: - specifier: 5.9.2 - version: 5.9.2 - vite: - specifier: ^6.3.2 - version: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) - packages: '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@ark/schema@0.49.0': + resolution: {integrity: sha512-GphZBLpW72iS0v4YkeUtV3YIno35Gimd7+ezbPO9GwEi9kzdUrPVjvf6aXSBAfHikaFc/9pqZOpv3pOXnC71tw==} + + '@ark/util@0.49.0': + resolution: {integrity: sha512-/BtnX7oCjNkxi2vi6y1399b+9xd1jnCrDYhZ61f0a+3X8x8DxlK52VgEEzyuC2UQMPACIfYrmHkhD3lGt2GaMA==} + + '@asamuzakjp/css-color@4.0.4': + resolution: {integrity: sha512-cKjSKvWGmAziQWbCouOsFwb14mp1betm8Y7Fn+yglDMUUu3r9DCbJ9iJbeFDenLMqFbIMC0pQP8K+B8LAxX3OQ==} + + '@asamuzakjp/dom-selector@6.5.5': + resolution: {integrity: sha512-kI2MX9pmImjxWT8nxDZY+MuN6r1jJGe7WxizEbsAEPB/zxfW5wYLIiPG1v3UKgEOOP8EsDkp0ZL99oRFAdPM8g==} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.14': + resolution: {integrity: sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@dagrejs/dagre@1.1.5': + resolution: {integrity: sha512-Ghgrh08s12DCL5SeiR6AoyE80mQELTWhJBRmXfFoqDiFkR458vPEdgTbbjA0T+9ETNxUblnD0QW55tfdvi5pjQ==} + + '@dagrejs/graphlib@2.2.4': + resolution: {integrity: sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==} + engines: {node: '>17.0.0'} + '@esbuild/aix-ppc64@0.25.5': resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} @@ -371,6 +597,28 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@exodus/schemasafe@1.3.0': + resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} + + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@gcornut/valibot-json-schema@0.42.0': + resolution: {integrity: sha512-4Et4AN6wmqeA0PfU5Clkv/IS27wiefsWf6TemAZrb75uzkClYEFavim7SboeKwbll9Nbsn2Iv0LT/HS5H7orZg==} + hasBin: true + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -391,9 +639,30 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@inlang/paraglide-js@2.3.2': + resolution: {integrity: sha512-mF7ku1AaXQxa6fnbBczXiEAM7lxhYzaAH7FnDVvAbpzNtgRJESi11KN0bzpCH0YhsKLdimFrQlzjaSVlo9Uh+Q==} + hasBin: true + + '@inlang/recommend-sherlock@0.2.1': + resolution: {integrity: sha512-ckv8HvHy/iTqaVAEKrr+gnl+p3XFNwe5D2+6w6wJk2ORV2XkcRkKOJ/XsTUJbPSiyi4PI+p+T3bqbmNx/rDUlg==} + + '@inlang/sdk@2.4.9': + resolution: {integrity: sha512-cvz/C1rF5WBxzHbEoiBoI6Sz6q6M+TdxfWkEGBYTD77opY8i8WN01prUWXEM87GPF4SZcyIySez9U0Ccm12oFQ==} + engines: {node: '>=18.0.0'} + + '@internationalized/date@3.9.0': + resolution: {integrity: sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.12': resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -410,6 +679,30 @@ packages: '@jridgewell/trace-mapping@0.3.29': resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@layerstack/svelte-actions@1.0.1-next.12': + resolution: {integrity: sha512-dndWTlYu8b1u6vw2nrO7NssccoACArGG75WoNlyVC13KuENZlWdKE9Q79/wlnbq00NeQMNKMjJwRMsrKQj2ULA==} + + '@layerstack/svelte-state@0.1.0-next.17': + resolution: {integrity: sha512-z7e6mPJnypD80LEI/UDuH0bI6s8/nut06MB7rEkRcEfHJekhKSJgFhMnrYzLED7Mc2gTTD0X/wcYlakauWlU8A==} + + '@layerstack/tailwind@2.0.0-next.15': + resolution: {integrity: sha512-7tqKE3OV7/ybeDOORX++USYYCBJa7IgTya2czFpzbgXGo7CQDVyuv+0J1DggjRcEqhhXQA4MUhgnhcRaZvHxWg==} + + '@layerstack/utils@2.0.0-next.12': + resolution: {integrity: sha512-fhGZUlSr3N+D44BYm37WKMGSEFyZBW+dwIqtGU8Cl54mR4TLQ/UwyGhdpgIHyH/x/8q1abE0fP0Dn6ZsrDE3BA==} + + '@lix-js/sdk@0.4.7': + resolution: {integrity: sha512-pRbW+joG12L0ULfMiWYosIW0plmW4AsUdiPCp+Z8rAsElJ+wJ6in58zhD3UwUcd4BNcpldEGjg6PdA7e0RgsDQ==} + engines: {node: '>=18'} + + '@lix-js/server-protocol-schema@0.1.1': + resolution: {integrity: sha512-jBeALB6prAbtr5q4vTuxnRZZv1M2rKe8iNqRQhFJ4Tv7150unEa0vKyz0hs8Gl3fUGsWaNJBh3J8++fpbrpRBQ==} + + '@lucide/svelte@0.544.0': + resolution: {integrity: sha512-9f9O6uxng2pLB01sxNySHduJN3HTl5p0HDu4H26VR51vhZfiMzyOMe9Mhof3XAk4l813eTtl+/DYRvGyoRR+yw==} + peerDependencies: + svelte: ^5 + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -422,59 +715,158 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@playwright/test@1.55.0': + resolution: {integrity: sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==} + engines: {node: '>=18'} + hasBin: true + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@poppinss/macroable@1.1.0': + resolution: {integrity: sha512-y/YKzZDuG8XrpXpM7Z1RdQpiIc0MAKyva24Ux1PB4aI7RiSI/79K8JVDcdyubriTm7vJ1LhFs8CrZpmPnx/8Pw==} + + '@rollup/plugin-commonjs@28.0.6': + resolution: {integrity: sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.1': + resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.41.1': resolution: {integrity: sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==} cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.52.0': + resolution: {integrity: sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.41.1': resolution: {integrity: sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.52.0': + resolution: {integrity: sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.41.1': resolution: {integrity: sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.52.0': + resolution: {integrity: sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.41.1': resolution: {integrity: sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.52.0': + resolution: {integrity: sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.41.1': resolution: {integrity: sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==} cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.52.0': + resolution: {integrity: sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.41.1': resolution: {integrity: sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==} cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.52.0': + resolution: {integrity: sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.41.1': resolution: {integrity: sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-gnueabihf@4.52.0': + resolution: {integrity: sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.41.1': resolution: {integrity: sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.52.0': + resolution: {integrity: sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.41.1': resolution: {integrity: sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.52.0': + resolution: {integrity: sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-arm64-musl@4.41.1': resolution: {integrity: sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-musl@4.52.0': + resolution: {integrity: sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.52.0': + resolution: {integrity: sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-loongarch64-gnu@4.41.1': resolution: {integrity: sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==} cpu: [loong64] @@ -485,46 +877,141 @@ packages: cpu: [ppc64] os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.52.0': + resolution: {integrity: sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==} + cpu: [ppc64] + os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.41.1': resolution: {integrity: sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.52.0': + resolution: {integrity: sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.41.1': resolution: {integrity: sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.52.0': + resolution: {integrity: sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.41.1': resolution: {integrity: sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==} cpu: [s390x] os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.52.0': + resolution: {integrity: sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==} + cpu: [s390x] + os: [linux] + '@rollup/rollup-linux-x64-gnu@4.41.1': resolution: {integrity: sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-gnu@4.52.0': + resolution: {integrity: sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==} + cpu: [x64] + os: [linux] + '@rollup/rollup-linux-x64-musl@4.41.1': resolution: {integrity: sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-musl@4.52.0': + resolution: {integrity: sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.52.0': + resolution: {integrity: sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.41.1': resolution: {integrity: sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.52.0': + resolution: {integrity: sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.41.1': resolution: {integrity: sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.52.0': + resolution: {integrity: sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.52.0': + resolution: {integrity: sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.41.1': resolution: {integrity: sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.52.0': + resolution: {integrity: sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==} + cpu: [x64] + os: [win32] + + '@shikijs/core@3.13.0': + resolution: {integrity: sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==} + + '@shikijs/engine-javascript@3.13.0': + resolution: {integrity: sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==} + + '@shikijs/engine-oniguruma@3.13.0': + resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==} + + '@shikijs/langs@3.13.0': + resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==} + + '@shikijs/themes@3.13.0': + resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==} + + '@shikijs/types@3.13.0': + resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sinclair/typebox@0.31.28': + resolution: {integrity: sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ==} + + '@sinclair/typebox@0.34.41': + resolution: {integrity: sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==} + + '@sqlite.org/sqlite-wasm@3.48.0-build4': + resolution: {integrity: sha512-hI6twvUkzOmyGZhQMza1gpfqErZxXRw6JEsiVjUbo7tFanVD+8Oil0Ih3l2nGzHdxPI41zFmfUQG7GHqhciKZQ==} + hasBin: true + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -538,6 +1025,11 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 + '@sveltejs/adapter-node@5.3.2': + resolution: {integrity: sha512-nBJSipMb1KLjnAM7uzb+YpnA1VWKb+WdR+0mXEnXI6K1A3XYWbjkcjnW20ubg07sicK8XaGY/FAX3PItw39qBQ==} + peerDependencies: + '@sveltejs/kit': ^2.4.0 + '@sveltejs/kit@2.36.1': resolution: {integrity: sha512-dldNCtSIpaGxQMEfHaUxSPH/k3uU28pTZwtKzfkn8fqpOjWufKlMBeIL7FJ/s93dOrhEq41zaQYkXh+XTgEgVw==} engines: {node: '>=18.13'} @@ -551,13 +1043,6 @@ packages: '@opentelemetry/api': optional: true - '@sveltejs/package@2.5.0': - resolution: {integrity: sha512-qpB91oWEraOXA4l1ldpGtMc/rLCthbf1ACw/1oroKxvT3sd2NXPd/+NLhIk5FCvd0IUSEZGYa86K+D94GWW2Zw==} - engines: {node: ^16.14 || >=18} - hasBin: true - peerDependencies: - svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1 - '@sveltejs/vite-plugin-svelte-inspector@4.0.1': resolution: {integrity: sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22} @@ -573,50 +1058,207 @@ packages: svelte: ^5.0.0 vite: ^6.0.0 - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@tailwindcss/forms@0.5.10': + resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@tailwindcss/node@4.1.13': + resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} - '@types/estree@1.0.7': - resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@tailwindcss/oxide-android-arm64@4.1.13': + resolution: {integrity: sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@tailwindcss/oxide-darwin-arm64@4.1.13': + resolution: {integrity: sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@tailwindcss/oxide-darwin-x64@4.1.13': + resolution: {integrity: sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@tailwindcss/oxide-freebsd-x64@4.1.13': + resolution: {integrity: sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] - '@typescript-eslint/eslint-plugin@8.40.0': - resolution: {integrity: sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.40.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + resolution: {integrity: sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] - '@typescript-eslint/parser@8.40.0': - resolution: {integrity: sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + resolution: {integrity: sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@typescript-eslint/project-service@8.40.0': - resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + resolution: {integrity: sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@typescript-eslint/scope-manager@8.40.0': - resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + resolution: {integrity: sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + resolution: {integrity: sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + resolution: {integrity: sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + resolution: {integrity: sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + resolution: {integrity: sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.13': + resolution: {integrity: sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==} + engines: {node: '>= 10'} + + '@tailwindcss/typography@0.5.18': + resolution: {integrity: sha512-dDIgwZOlf+tVkZ7A029VvQ1+ngKATENDjMEx2N35s2yPjfTS05RWSM8ilhEWSa5DMJ6ci2Ha9WNZEd2GQjrdQg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@tailwindcss/vite@4.1.13': + resolution: {integrity: sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + + '@tanstack/table-core@8.21.3': + resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} + engines: {node: '>=12'} + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/validator@13.15.3': + resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==} + + '@typeschema/class-validator@0.3.0': + resolution: {integrity: sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww==} + peerDependencies: + class-validator: ^0.14.1 + peerDependenciesMeta: + class-validator: + optional: true + + '@typeschema/core@0.14.0': + resolution: {integrity: sha512-Ia6PtZHcL3KqsAWXjMi5xIyZ7XMH4aSnOQes8mfMLx+wGFGtGRNlwe6Y7cYvX+WfNK67OL0/HSe9t8QDygV0/w==} + peerDependencies: + '@types/json-schema': ^7.0.15 + peerDependenciesMeta: + '@types/json-schema': + optional: true + + '@typescript-eslint/eslint-plugin@8.40.0': + resolution: {integrity: sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.40.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.40.0': + resolution: {integrity: sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.40.0': + resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.40.0': + resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.40.0': @@ -653,9 +1295,38 @@ packages: resolution: {integrity: sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vinejs/compiler@3.0.0': + resolution: {integrity: sha512-v9Lsv59nR56+bmy2p0+czjZxsLHwaibJ+SV5iK9JJfehlJMa501jUJQqqz4X/OqKXrxtE3uTQmSqjUqzF3B2mw==} + engines: {node: '>=18.0.0'} + + '@vinejs/vine@3.0.1': + resolution: {integrity: sha512-ZtvYkYpZOYdvbws3uaOAvTFuvFXoQGAtmzeiXu+XSMGxi5GVsODpoI9Xu9TplEMuD/5fmAtBbKb9cQHkWkLXDQ==} + engines: {node: '>=18.16.0'} + + '@vitest/browser@3.2.4': + resolution: {integrity: sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==} + peerDependencies: + playwright: '*' + safaridriver: '*' + vitest: 3.2.4 + webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 + peerDependenciesMeta: + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + '@vitest/expect@3.2.0': resolution: {integrity: sha512-0v4YVbhDKX3SKoy0PHWXpKhj44w+3zZkIoVES9Ex2pq+u6+Bijijbi2ua5kE+h3qT6LBWFTNZSCOEU37H8Y5sA==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/mocker@3.2.0': resolution: {integrity: sha512-HFcW0lAMx3eN9vQqis63H0Pscv0QcVMo1Kv8BNysZbxcmHu3ZUYv59DS6BGYiGQ8F5lUkmsfMMlPm4DJFJdf/A==} peerDependencies: @@ -667,21 +1338,56 @@ packages: vite: optional: true + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + '@vitest/pretty-format@3.2.0': resolution: {integrity: sha512-gUUhaUmPBHFkrqnOokmfMGRBMHhgpICud9nrz/xpNV3/4OXCn35oG+Pl8rYYsKaTNd/FAIrqRHnwpDpmYxCYZw==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.2.0': resolution: {integrity: sha512-bXdmnHxuB7fXJdh+8vvnlwi/m1zvu+I06i1dICVcDQFhyV4iKw2RExC/acavtDn93m/dRuawUObKsrNE1gJacA==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/snapshot@3.2.0': resolution: {integrity: sha512-z7P/EneBRMe7hdvWhcHoXjhA6at0Q4ipcoZo6SqgxLyQQ8KSMMCmvw1cSt7FHib3ozt0wnRHc37ivuUMbxzG/A==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/spy@3.2.0': resolution: {integrity: sha512-s3+TkCNUIEOX99S0JwNDfsHRaZDDZZR/n8F0mop0PmsEbQGKZikCGpTGZ6JRiHuONKew3Fb5//EPwCP+pUX9cw==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/utils@3.2.0': resolution: {integrity: sha512-gXXOe7Fj6toCsZKVQouTRLJftJwmvbhH5lKOBR6rlP950zUq9AitTUjnFoXS/CqjBC2aoejAztLPzzuva++XBw==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@zxcvbn-ts/core@3.0.4': + resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==} + + '@zxcvbn-ts/language-common@3.0.4': + resolution: {integrity: sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==} + + '@zxcvbn-ts/language-en@3.0.2': + resolution: {integrity: sha512-Zp+zL+I6Un2Bj0tRXNs6VUBq3Djt+hwTwUz4dkt2qgsQz47U0/XthZ4ULrT/RxjwJRl5LwiaKOOZeOtmixHnjg==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -697,20 +1403,41 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + arktype@2.1.22: + resolution: {integrity: sha512-xdzl6WcAhrdahvRRnXaNwsipCgHuNoLobRqhiP8RjnfL9Gp947abGlo68GAIyLtxbD+MLzNyH2YR4kEqioMmYQ==} + + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -722,6 +1449,16 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + bits-ui@2.11.0: + resolution: {integrity: sha512-j/lOFHz6ZDWwj9sOUb6zYSJQdvPc7kr1IRyAdPjln4wOw9UVvKCosbRFEyP4JEzvNFX7HksMG4naDrDHta5bSA==} + engines: {node: '>=20'} + peerDependencies: + '@internationalized/date': ^3.8.1 + svelte: ^5.33.0 + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -732,6 +1469,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -740,6 +1480,13 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.2.0: resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} @@ -748,6 +1495,12 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -756,6 +1509,13 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + class-validator@0.14.2: + resolution: {integrity: sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -767,22 +1527,165 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + comment-json@4.2.5: + resolution: {integrity: sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==} + engines: {node: '>= 6'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssstyle@5.3.1: + resolution: {integrity: sha512-g5PC9Aiph9eiczFpcgUhd9S4UUO3F+LHGRIi5NUMZ+4xtoIYbHNZwZnWA2JsFGe8OU8nl4WyaEFiZuGuxlutJQ==} + engines: {node: '>=20'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo-voronoi@2.1.0: + resolution: {integrity: sha512-kqE4yYuOjPbKdBXG0xztCacPwkVSK2REF1opSNrnqqtXJmNcM++UbwQ8SxvwP6IQTj9RvIjjK4qeiVsEfj0Z2Q==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate-path@2.3.0: + resolution: {integrity: sha512-tZYtGXxBmbgHsIc9Wms6LS5u4w6KbP8C09a4/ZYc4KLMYYqub57rRBUgpUr2CIarIrJEpdAWWxWQvofgaMpbKQ==} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-tile@1.0.0: + resolution: {integrity: sha512-79fnTKpPMPDS5xQ0xuS9ir0165NEwwkFpe/DSOmc2Gl9ldYzKKRDWogmTTE8wAJ8NA7PMapNfEcyKhI9Lxdu5Q==} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-tricontour@1.0.2: + resolution: {integrity: sha512-HIRxHzHagPtUPNabjOlfcyismJYIsc+Xlq4mlsts4e8eAcwyq9Tgk/sYdyhlBpQ0MHwVquc/8j+e29YjXnmxeA==} + engines: {node: '>=12'} + + data-urls@6.0.0: + resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} + engines: {node: '>=20'} + + dayjs@1.11.18: + resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -792,8 +1695,16 @@ packages: supports-color: optional: true - dedent-js@1.0.1: - resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} @@ -806,16 +1717,69 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.0: + resolution: {integrity: sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==} + engines: {node: '>=8'} + devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dompurify@3.2.7: + resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} + dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} + effect@3.17.14: + resolution: {integrity: sha512-VpIZz72+cg3357vLkNHN8CG+Uq2X0QHNv3qkyGInvG3lG5K7Ala1JliGIAdgNvwzaN37J27FuzVD8m0kEiv2Ig==} + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel-svelte@8.6.0: + resolution: {integrity: sha512-ZDsKk8Sdv+AUTygMYcwZjfRd1DTh+JSUzxkOo8b9iKAkYjg+39mzbY/lwHsE3jXSpKxdKWS69hPSNuzlOGtR2Q==} + peerDependencies: + svelte: ^3.49.0 || ^4.0.0 || ^5.0.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} + engines: {node: '>=10.13.0'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild-runner@2.2.2: + resolution: {integrity: sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw==} + hasBin: true + peerDependencies: + esbuild: '*' + esbuild@0.25.5: resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} @@ -904,6 +1868,11 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -919,6 +1888,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -930,6 +1902,10 @@ packages: resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -943,6 +1919,10 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -962,6 +1942,15 @@ packages: picomatch: optional: true + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -981,11 +1970,26 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + formsnap@2.0.1: + resolution: {integrity: sha512-iJSe4YKd/W6WhLwKDVJU9FQeaJRpEFuolhju7ZXlRpUVyDdqFdMP8AUBICgnVvQPyP41IPAlBa/v0Eo35iE6wQ==} + engines: {node: '>=18', pnpm: '>=8.7.0'} + peerDependencies: + svelte: ^5.0.0 + sveltekit-superforms: ^2.19.0 + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} @@ -1005,6 +2009,9 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1012,16 +2019,53 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-id@4.1.1: + resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} + hasBin: true + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} import-meta-resolve@4.1.0: @@ -1031,6 +2075,20 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1039,29 +2097,76 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isomorphic-dompurify@2.28.0: + resolution: {integrity: sha512-9G5v8g4tYoix5odskjG704Khm1zNrqqqOC4YjCwEUhx0OvuaijRCprAV2GwJ9iw/01c6H1R+rs/2AXPZLlgDaQ==} + engines: {node: '>=18'} + + jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} + hasBin: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + js-sha256@0.11.1: + resolution: {integrity: sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdom@27.0.0: + resolution: {integrity: sha512-lIHeR1qlIRrIN5VMccd8tI2Sgw6ieYXSVktcSHaNe3Z5nE/tcPQYQWOq00wxMvYOsz+73eAkNenVvmPC6bba9A==} + engines: {node: '>=20'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1072,10 +2177,86 @@ packages: known-css-properties@0.35.0: resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} + kysely@0.27.6: + resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==} + engines: {node: '>=14.0.0'} + + layerchart@2.0.0-next.27: + resolution: {integrity: sha512-yt28xU8WzXq0AliX7eiC0JKZGQtO8M9FmHvt8sESNitSc/yC+fYeTghaO9lMRwcYCmi6D1NjbFyD9mWFeazNIQ==} + peerDependencies: + svelte: ^5.0.0 + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.12.17: + resolution: {integrity: sha512-bsxi8FoceAYR/bjHcLYc2ShJ/aVAzo5jaxAYiMHF0BD+NTp47405CGuPNKYpw+lHadN9k/ClFGc9X5vaZswIrA==} + + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -1087,14 +2268,25 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} + engines: {node: 20 || >=22} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -1102,14 +2294,60 @@ packages: magic-string@0.30.18: resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} + marked@12.0.2: + resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==} + engines: {node: '>= 18'} + hasBin: true + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + + mdsvex@0.12.6: + resolution: {integrity: sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg==} + peerDependencies: + svelte: ^3.56.0 || ^4.0.0 || ^5.0.0-next.120 + + memoize-weak@1.0.2: + resolution: {integrity: sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ==} + + memoize@10.1.0: + resolution: {integrity: sha512-MMbFhJzh4Jlg/poq1si90XRlTZRDHVqdlz2mPyGJ6kqMpyHUyVpDd5gpFAvVehW64+RA1eKE9Yt8aSLY7w2Kgg==} + engines: {node: '>=18'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + mini-svg-data-uri@1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1117,6 +2355,24 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mode-watcher@1.1.0: + resolution: {integrity: sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==} + peerDependencies: + svelte: ^5.27.0 + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -1136,8 +2392,15 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + normalize-url@8.1.0: + resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} + engines: {node: '>=14.16'} + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.3: + resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -1151,12 +2414,17 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + paneforge@1.0.2: + resolution: {integrity: sha512-KzmIXQH1wCfwZ4RsMohD/IUtEjVhteR+c+ulb/CHYJHX8SuDXoJmChtsc/Xs5Wl8NHS4L5Q7cxL8MG40gSU1bA==} + peerDependencies: + svelte: ^5.29.0 + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} - pascal-case@3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -1166,6 +2434,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -1184,6 +2455,20 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + playwright-core@1.55.0: + resolution: {integrity: sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.55.0: + resolution: {integrity: sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==} + engines: {node: '>=18'} + hasBin: true + postcss-load-config@3.1.4: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -1208,6 +2493,10 @@ packages: peerDependencies: postcss: ^8.4.29 + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} @@ -1216,6 +2505,10 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1226,22 +2519,123 @@ packages: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + prettier-plugin-tailwindcss@0.6.14: + resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-hermes': '*' + '@prettier/plugin-oxc': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-hermes': + optional: true + '@prettier/plugin-oxc': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + prettier@3.6.0: resolution: {integrity: sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==} engines: {node: '>=14'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + prism-svelte@0.4.7: + resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1249,22 +2643,73 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + rollup@4.41.1: resolution: {integrity: sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.52.0: + resolution: {integrity: sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + runed@0.23.4: + resolution: {integrity: sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==} + peerDependencies: + svelte: ^5.7.0 + + runed@0.25.0: + resolution: {integrity: sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg==} + peerDependencies: + svelte: ^5.7.0 + + runed@0.28.0: + resolution: {integrity: sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==} + peerDependencies: + svelte: ^5.7.0 + + runed@0.29.2: + resolution: {integrity: sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==} + peerDependencies: + svelte: ^5.7.0 + + runed@0.31.1: + resolution: {integrity: sha512-v3czcTnO+EJjiPvD4dwIqfTdHLZ8oH0zJheKqAHh9QMViY7Qb29UlAMRpX7ZtHh7AFqV60KmfxaJ9QMy+L1igQ==} + peerDependencies: + svelte: ^5.7.0 + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} @@ -1281,6 +2726,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@3.13.0: + resolution: {integrity: sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1292,20 +2740,52 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + sqlite-wasm-kysely@0.3.0: + resolution: {integrity: sha512-TzjBNv7KwRw6E3pdKdlRyZiTmUIE0UttT/Sl56MVwVARl/u5gp978KepazCJZewFUnlWHz9i3NQd4kOtP/Afdg==} + peerDependencies: + kysely: '*' + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + style-to-object@1.0.9: + resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + svelte-check@4.3.0: resolution: {integrity: sha512-Iz8dFXzBNAM7XlEIsUjUGQhbEE+Pvv9odb9+0+ITTgFWZBGeJRRYqHUUglwe2EkLD5LIsQaAc4IUJyvtKuOO5w==} engines: {node: '>= 18.0.0'} @@ -1314,6 +2794,11 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' + svelte-easy-crop@5.0.0: + resolution: {integrity: sha512-niWtner+qYVas6ypIOQ277NKNACVz9qz6wfpEW7t+x5Lhv6nOjpv3S1WhEPO+SnDaW3VZv+0bmm6jVDHK2GMAg==} + peerDependencies: + svelte: ^5.0.0 + svelte-eslint-parser@0.43.0: resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1323,16 +2808,78 @@ packages: svelte: optional: true - svelte2tsx@0.7.42: - resolution: {integrity: sha512-PSNrKS16aVdAajoFjpF5M0t6TA7ha7GcKbBajD9RG3M+vooAuvLnWAGUSC6eJL4zEOVbOWKtcS2BuY4rxPljoA==} + svelte-sonner@1.0.5: + resolution: {integrity: sha512-9dpGPFqKb/QWudYqGnEz93vuY+NgCEvyNvxoCLMVGw6sDN/3oVeKV1xiEirW2E1N3vJEyj5imSBNOGltQHA7mg==} + peerDependencies: + svelte: ^5.0.0 + + svelte-toolbelt@0.10.5: + resolution: {integrity: sha512-8e+eWTgxw1aiLxhDE8Rb1X6AoLitqpJz+WhAul2W7W58C8KoLoJQf1TgQdFPBiCPJ0Jg5y0Zi1uyua9em4VS0w==} + engines: {node: '>=18', pnpm: '>=8.7.0'} + peerDependencies: + svelte: ^5.30.2 + + svelte-toolbelt@0.5.0: + resolution: {integrity: sha512-t3tenZcnfQoIeRuQf/jBU7bvTeT3TGkcEE+1EUr5orp0lR7NEpprflpuie3x9Dn0W9nOKqs3HwKGJeeN5Ok1sQ==} + engines: {node: '>=18', pnpm: '>=8.7.0'} + peerDependencies: + svelte: ^5.0.0-next.126 + + svelte-toolbelt@0.7.1: + resolution: {integrity: sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==} + engines: {node: '>=18', pnpm: '>=8.7.0'} + peerDependencies: + svelte: ^5.0.0 + + svelte-toolbelt@0.9.3: + resolution: {integrity: sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==} + engines: {node: '>=18', pnpm: '>=8.7.0'} peerDependencies: - svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 - typescript: ^4.9.4 || ^5.0.0 + svelte: ^5.30.2 svelte@5.38.0: resolution: {integrity: sha512-cWF1Oc2IM/QbktdK89u5lt9MdKxRtQnRKnf2tq6KOhYuhLOd2hbMuTiJ+vWMzAeMDe81AzbCgLd4GVtOJ4fDRg==} engines: {node: '>=18'} + sveltekit-superforms@2.27.1: + resolution: {integrity: sha512-cvq2AevkZ0Zrk0w0gNM3kjcnJMtJ0jzu+2zqDoM9a+lZa+8bGpNl4YqxVkemiJNkGnFgNC8xr5xF5BlMzjookQ==} + peerDependencies: + '@sveltejs/kit': 1.x || 2.x + svelte: 3.x || 4.x || >=5.0.0-next.51 + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + + tailwind-variants@3.1.1: + resolution: {integrity: sha512-ftLXe3krnqkMHsuBTEmaVUXYovXtPyTK7ckEfDRXS8PBZx0bAUas+A0jYxuKA5b8qg++wvQ3d2MQ7l/xeZxbZQ==} + engines: {node: '>=16.x', pnpm: '>=7.x'} + peerDependencies: + tailwind-merge: '>=3.0.0' + tailwindcss: '*' + peerDependenciesMeta: + tailwind-merge: + optional: true + + tailwindcss@4.1.13: + resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} + + tapable@2.2.3: + resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1343,10 +2890,18 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + tinypool@1.1.0: resolution: {integrity: sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==} engines: {node: ^18.0.0 || >=20.0.0} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} @@ -1355,20 +2910,51 @@ packages: resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} + tldts-core@7.0.15: + resolution: {integrity: sha512-YBkp2VfS9VTRMPNL2PA6PMESmxV1JEVoAr5iBlZnB5JG3KUrWzNCB3yNNkRa2FZkqClaBgfNYCp8PgpYmpjkZw==} + + tldts@7.0.15: + resolution: {integrity: sha512-heYRCiGLhtI+U/D0V8YM3QRwPfsLJiP+HX+YwiHZTnWzjIKC+ZCxQRYlzvOoTEc6KIP62B1VeAN63diGCng2hg==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' + ts-deepmerge@7.0.3: + resolution: {integrity: sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA==} + engines: {node: '>=14.13.1'} + + tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1411,10 +2997,17 @@ packages: resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} hasBin: true + tw-animate-css@1.3.8: + resolution: {integrity: sha512-Qrk3PZ7l7wUcGYhwZloqfkWCmaXZAoqjkdbIDvzfGshwGtexa/DAs9koXxIkrpEasyevandomzCBAV1Yyop5rw==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + typescript-eslint@8.40.0: resolution: {integrity: sha512-Xvd2l+ZmFDPEt4oj1QEXzA4A2uUK6opvKu3eGN9aGjB8au02lIVcLyi375w94hHyejTOmzIU77L8ol2sRg9n7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1430,16 +3023,103 @@ packages: undici-types@7.12.0: resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - vite-node@3.2.0: - resolution: {integrity: sha512-8Fc5Ko5Y4URIJkmMF/iFP1C0/OJyY+VGVe9Nw6WAdZyw4bTO+eVg9mwxWkQp/y8NnAoQY3o9KAvE1ZdA2v+Vmg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + unplugin@2.3.10: + resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} + engines: {node: '>=18.12.0'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + valibot@0.42.1: + resolution: {integrity: sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + valibot@1.1.0: + resolution: {integrity: sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + validator@13.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} + engines: {node: '>= 0.10'} + + vaul-svelte@1.0.0-next.7: + resolution: {integrity: sha512-7zN7Bi3dFQixvvbUJY9uGDe7Ws/dGZeBQR2pXdXmzQiakjrxBvWo0QrmsX3HK+VH+SZOltz378cmgmCS9f9rSg==} + engines: {node: '>=18', pnpm: '>=8.7.0'} + peerDependencies: + svelte: ^5.0.0 + + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-node@3.2.0: + resolution: {integrity: sha512-8Fc5Ko5Y4URIJkmMF/iFP1C0/OJyY+VGVe9Nw6WAdZyw4bTO+eVg9mwxWkQp/y8NnAoQY3o9KAvE1ZdA2v+Vmg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-plugin-devtools-json@1.0.0: + resolution: {integrity: sha512-MobvwqX76Vqt/O4AbnNMNWoXWGrKUqZbphCUle/J2KXH82yKQiunOeKnz/nqEPosPsoWWPP9FtNuPBSYpiiwkw==} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vite@6.3.5: resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} @@ -1481,6 +3161,46 @@ packages: yaml: optional: true + vite@7.1.6: + resolution: {integrity: sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitefu@1.0.6: resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} peerDependencies: @@ -1489,6 +3209,14 @@ packages: vite: optional: true + vitest-browser-svelte@0.1.0: + resolution: {integrity: sha512-YB6ZUZZQNqU1T9NzvTEDpwpPv35Ng1NZMPBh81zDrLEdOgROGE6nJb79NWb1Eu/a8VkHifqArpOZfJfALge6xQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + '@vitest/browser': ^2.1.0 || ^3.0.0-0 + svelte: '>3.0.0' + vitest: ^2.1.0 || ^3.0.0-0 + vitest@3.2.0: resolution: {integrity: sha512-P7Nvwuli8WBNmeMHHek7PnGW4oAZl9za1fddfRVidZar8wDZRi7hpznLKQePQ8JPLwSBEYDK11g+++j7uFJV8Q==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -1517,6 +3245,57 @@ packages: jsdom: optional: true + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@8.0.0: + resolution: {integrity: sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==} + engines: {node: '>=20'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@15.1.0: + resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + engines: {node: '>=20'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1531,6 +3310,29 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -1539,9 +3341,23 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yup@1.7.0: + resolution: {integrity: sha512-VJce62dBd+JQvoc+fCVq+KZfPHr+hXaxCcVgotfwWvlR0Ja3ffYKaJBT8rptPOSKOGJDCUnW2C2JWpud7aRP6Q==} + zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} + zod-to-json-schema@3.24.6: + resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} + peerDependencies: + zod: ^3.24.1 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@ampproject/remapping@2.3.0': @@ -1549,6 +3365,71 @@ snapshots: '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 + '@ark/schema@0.49.0': + dependencies: + '@ark/util': 0.49.0 + optional: true + + '@ark/util@0.49.0': + optional: true + + '@asamuzakjp/css-color@4.0.4': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 11.2.1 + + '@asamuzakjp/dom-selector@6.5.5': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/runtime@7.28.4': {} + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.14(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/css-tokenizer@3.0.4': {} + + '@dagrejs/dagre@1.1.5': + dependencies: + '@dagrejs/graphlib': 2.2.4 + + '@dagrejs/graphlib@2.2.4': {} + '@esbuild/aix-ppc64@0.25.5': optional: true @@ -1624,9 +3505,9 @@ snapshots: '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0)': + '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0(jiti@2.5.1))': dependencies: - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -1668,6 +3549,39 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 + '@exodus/schemasafe@1.3.0': + optional: true + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + + '@gcornut/valibot-json-schema@0.42.0(esbuild@0.25.5)(typescript@5.9.2)': + dependencies: + valibot: 0.42.1(typescript@5.9.2) + optionalDependencies: + '@types/json-schema': 7.0.15 + esbuild-runner: 2.2.2(esbuild@0.25.5) + transitivePeerDependencies: + - esbuild + - typescript + optional: true + + '@hapi/hoek@9.3.0': + optional: true + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + optional: true + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -1681,9 +3595,48 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@inlang/paraglide-js@2.3.2': + dependencies: + '@inlang/recommend-sherlock': 0.2.1 + '@inlang/sdk': 2.4.9 + commander: 11.1.0 + consola: 3.4.0 + json5: 2.2.3 + unplugin: 2.3.10 + urlpattern-polyfill: 10.1.0 + transitivePeerDependencies: + - babel-plugin-macros + + '@inlang/recommend-sherlock@0.2.1': + dependencies: + comment-json: 4.2.5 + + '@inlang/sdk@2.4.9': + dependencies: + '@lix-js/sdk': 0.4.7 + '@sinclair/typebox': 0.31.28 + kysely: 0.27.6 + sqlite-wasm-kysely: 0.3.0(kysely@0.27.6) + uuid: 10.0.0 + transitivePeerDependencies: + - babel-plugin-macros + + '@internationalized/date@3.9.0': + dependencies: + '@swc/helpers': 0.5.17 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.29 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/resolve-uri@3.1.2': {} @@ -1699,6 +3652,49 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.4 + '@layerstack/svelte-actions@1.0.1-next.12': + dependencies: + '@floating-ui/dom': 1.7.4 + '@layerstack/utils': 2.0.0-next.12 + d3-scale: 4.0.2 + + '@layerstack/svelte-state@0.1.0-next.17': + dependencies: + '@layerstack/utils': 2.0.0-next.12 + + '@layerstack/tailwind@2.0.0-next.15': + dependencies: + '@layerstack/utils': 2.0.0-next.12 + clsx: 2.1.1 + d3-array: 3.2.4 + lodash-es: 4.17.21 + tailwind-merge: 3.3.1 + + '@layerstack/utils@2.0.0-next.12': + dependencies: + d3-array: 3.2.4 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + lodash-es: 4.17.21 + + '@lix-js/sdk@0.4.7': + dependencies: + '@lix-js/server-protocol-schema': 0.1.1 + dedent: 1.5.1 + human-id: 4.1.1 + js-sha256: 0.11.1 + kysely: 0.27.6 + sqlite-wasm-kysely: 0.3.0(kysely@0.27.6) + uuid: 10.0.0 + transitivePeerDependencies: + - babel-plugin-macros + + '@lix-js/server-protocol-schema@0.1.1': {} + + '@lucide/svelte@0.544.0(svelte@5.38.0)': + dependencies: + svelte: 5.38.0 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1711,84 +3707,252 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@playwright/test@1.55.0': + dependencies: + playwright: 1.55.0 + '@polka/url@1.0.0-next.29': {} + '@poppinss/macroable@1.1.0': + optional: true + + '@rollup/plugin-commonjs@28.0.6(rollup@4.52.0)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.3) + is-reference: 1.2.1 + magic-string: 0.30.18 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.52.0 + + '@rollup/plugin-json@6.1.0(rollup@4.52.0)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.0) + optionalDependencies: + rollup: 4.52.0 + + '@rollup/plugin-node-resolve@16.0.1(rollup@4.52.0)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.52.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.52.0 + + '@rollup/pluginutils@5.3.0(rollup@4.52.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.52.0 + '@rollup/rollup-android-arm-eabi@4.41.1': optional: true + '@rollup/rollup-android-arm-eabi@4.52.0': + optional: true + '@rollup/rollup-android-arm64@4.41.1': optional: true + '@rollup/rollup-android-arm64@4.52.0': + optional: true + '@rollup/rollup-darwin-arm64@4.41.1': optional: true + '@rollup/rollup-darwin-arm64@4.52.0': + optional: true + '@rollup/rollup-darwin-x64@4.41.1': optional: true + '@rollup/rollup-darwin-x64@4.52.0': + optional: true + '@rollup/rollup-freebsd-arm64@4.41.1': optional: true + '@rollup/rollup-freebsd-arm64@4.52.0': + optional: true + '@rollup/rollup-freebsd-x64@4.41.1': optional: true + '@rollup/rollup-freebsd-x64@4.52.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.41.1': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.52.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.41.1': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.52.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.41.1': optional: true + '@rollup/rollup-linux-arm64-gnu@4.52.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.41.1': optional: true + '@rollup/rollup-linux-arm64-musl@4.52.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.52.0': + optional: true + '@rollup/rollup-linux-loongarch64-gnu@4.41.1': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.41.1': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.52.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.41.1': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.52.0': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.41.1': optional: true + '@rollup/rollup-linux-riscv64-musl@4.52.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.41.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.41.1': + '@rollup/rollup-linux-s390x-gnu@4.52.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.41.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.52.0': optional: true '@rollup/rollup-linux-x64-musl@4.41.1': optional: true + '@rollup/rollup-linux-x64-musl@4.52.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.41.1': optional: true + '@rollup/rollup-win32-arm64-msvc@4.52.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.41.1': optional: true + '@rollup/rollup-win32-ia32-msvc@4.52.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.41.1': optional: true + '@rollup/rollup-win32-x64-msvc@4.52.0': + optional: true + + '@shikijs/core@3.13.0': + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.13.0': + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.3 + + '@shikijs/engine-oniguruma@3.13.0': + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.13.0': + dependencies: + '@shikijs/types': 3.13.0 + + '@shikijs/themes@3.13.0': + dependencies: + '@shikijs/types': 3.13.0 + + '@shikijs/types@3.13.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + optional: true + + '@sideway/formula@3.0.1': + optional: true + + '@sideway/pinpoint@2.0.0': + optional: true + + '@sinclair/typebox@0.31.28': {} + + '@sinclair/typebox@0.34.41': + optional: true + + '@sqlite.org/sqlite-wasm@3.48.0-build4': {} + '@standard-schema/spec@1.0.0': {} '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': dependencies: acorn: 8.15.0 - '@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))': + '@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))': dependencies: - '@sveltejs/kit': 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + '@sveltejs/kit': 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) import-meta-resolve: 4.1.0 - '@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))': + '@sveltejs/adapter-node@5.3.2(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))': + dependencies: + '@rollup/plugin-commonjs': 28.0.6(rollup@4.52.0) + '@rollup/plugin-json': 6.1.0(rollup@4.52.0) + '@rollup/plugin-node-resolve': 16.0.1(rollup@4.52.0) + '@sveltejs/kit': 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + rollup: 4.52.0 + + '@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -1801,41 +3965,134 @@ snapshots: set-cookie-parser: 2.7.1 sirv: 3.0.1 svelte: 5.38.0 - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) - - '@sveltejs/package@2.5.0(svelte@5.38.0)(typescript@5.9.2)': - dependencies: - chokidar: 4.0.3 - kleur: 4.1.5 - sade: 1.8.1 - semver: 7.7.2 - svelte: 5.38.0 - svelte2tsx: 0.7.42(svelte@5.38.0)(typescript@5.9.2) - transitivePeerDependencies: - - typescript + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) debug: 4.4.1 svelte: 5.38.0 - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))': + '@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) debug: 4.4.1 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.38.0 - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) - vitefu: 1.0.6(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + vitefu: 1.0.6(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) transitivePeerDependencies: - supports-color + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/forms@0.5.10(tailwindcss@4.1.13)': + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 4.1.13 + + '@tailwindcss/node@4.1.13': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.3 + jiti: 2.5.1 + lightningcss: 1.30.1 + magic-string: 0.30.18 + source-map-js: 1.2.1 + tailwindcss: 4.1.13 + + '@tailwindcss/oxide-android-arm64@4.1.13': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.13': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.13': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + optional: true + + '@tailwindcss/oxide@4.1.13': + dependencies: + detect-libc: 2.1.0 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-x64': 4.1.13 + '@tailwindcss/oxide-freebsd-x64': 4.1.13 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.13 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.13 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-x64-musl': 4.1.13 + '@tailwindcss/oxide-wasm32-wasi': 4.1.13 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.13 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.13 + + '@tailwindcss/typography@0.5.18(tailwindcss@4.1.13)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 4.1.13 + + '@tailwindcss/vite@4.1.13(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': + dependencies: + '@tailwindcss/node': 4.1.13 + '@tailwindcss/oxide': 4.1.13 + tailwindcss: 4.1.13 + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + + '@tanstack/table-core@8.21.3': {} + + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.28.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + + '@types/aria-query@5.0.4': {} + '@types/chai@5.2.2': dependencies: '@types/deep-eql': 4.0.2 @@ -1848,22 +4105,56 @@ snapshots: '@types/estree@1.0.8': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/json-schema@7.0.15': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/node@24.5.2': dependencies: undici-types: 7.12.0 optional: true - '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2)': + '@types/resolve@1.20.2': {} + + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/validator@13.15.3': + optional: true + + '@typeschema/class-validator@0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.2)': + dependencies: + '@typeschema/core': 0.14.0(@types/json-schema@7.0.15) + optionalDependencies: + class-validator: 0.14.2 + transitivePeerDependencies: + - '@types/json-schema' + optional: true + + '@typeschema/core@0.14.0(@types/json-schema@7.0.15)': + optionalDependencies: + '@types/json-schema': 7.0.15 + optional: true + + '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.40.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/type-utils': 8.40.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/type-utils': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.40.0 - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -1872,14 +4163,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.40.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/parser@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.40.0 '@typescript-eslint/types': 8.40.0 '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.40.0 debug: 4.4.1 - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -1902,13 +4193,13 @@ snapshots: dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.40.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.40.0 '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) debug: 4.4.1 - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -1932,13 +4223,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.40.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/utils@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) '@typescript-eslint/scope-manager': 8.40.0 '@typescript-eslint/types': 8.40.0 '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -1948,6 +4239,42 @@ snapshots: '@typescript-eslint/types': 8.40.0 eslint-visitor-keys: 4.2.1 + '@ungap/structured-clone@1.3.0': {} + + '@vinejs/compiler@3.0.0': + optional: true + + '@vinejs/vine@3.0.1': + dependencies: + '@poppinss/macroable': 1.1.0 + '@types/validator': 13.15.3 + '@vinejs/compiler': 3.0.0 + camelcase: 8.0.0 + dayjs: 1.11.18 + dlv: 1.1.3 + normalize-url: 8.1.0 + validator: 13.15.15 + optional: true + + '@vitest/browser@3.2.4(playwright@1.55.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))(vitest@3.2.4)': + dependencies: + '@testing-library/dom': 10.4.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@vitest/utils': 3.2.4 + magic-string: 0.30.18 + sirv: 3.0.1 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/node@24.5.2)(@vitest/browser@3.2.4)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5) + ws: 8.18.3 + optionalDependencies: + playwright: 1.55.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + '@vitest/expect@3.2.0': dependencies: '@types/chai': 5.2.2 @@ -1956,39 +4283,89 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.0(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5))': + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.0(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': dependencies: '@vitest/spy': 3.2.0 estree-walker: 3.0.3 magic-string: 0.30.18 optionalDependencies: - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.18 + optionalDependencies: + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) '@vitest/pretty-format@3.2.0': dependencies: tinyrainbow: 2.0.0 + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@3.2.0': dependencies: '@vitest/utils': 3.2.0 pathe: 2.0.3 + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.0.0 + '@vitest/snapshot@3.2.0': dependencies: '@vitest/pretty-format': 3.2.0 magic-string: 0.30.18 pathe: 2.0.3 + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.18 + pathe: 2.0.3 + '@vitest/spy@3.2.0': dependencies: tinyspy: 4.0.3 + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.3 + '@vitest/utils@3.2.0': dependencies: '@vitest/pretty-format': 3.2.0 loupe: 3.1.3 tinyrainbow: 2.0.0 + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@zxcvbn-ts/core@3.0.4': + dependencies: + fastest-levenshtein: 1.0.16 + + '@zxcvbn-ts/language-common@3.0.4': {} + + '@zxcvbn-ts/language-en@3.0.2': {} + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -2001,6 +4378,8 @@ snapshots: acorn@8.15.0: {} + agent-base@7.1.4: {} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -2008,20 +4387,51 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + aria-query@5.3.2: {} + arktype@2.1.22: + dependencies: + '@ark/schema': 0.49.0 + '@ark/util': 0.49.0 + optional: true + + array-timsort@1.0.3: {} + assertion-error@2.0.1: {} axobject-query@4.1.0: {} balanced-match@1.0.2: {} + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + bits-ui@2.11.0(@internationalized/date@3.9.0)(svelte@5.38.0): + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/dom': 1.7.4 + '@internationalized/date': 3.9.0 + esm-env: 1.2.2 + runed: 0.31.1(svelte@5.38.0) + svelte: 5.38.0 + svelte-toolbelt: 0.10.5(svelte@5.38.0) + tabbable: 6.2.0 + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -2035,10 +4445,18 @@ snapshots: dependencies: fill-range: 7.1.1 + buffer-from@1.1.2: + optional: true + cac@6.7.14: {} callsites@3.1.0: {} + camelcase@8.0.0: + optional: true + + ccount@2.0.1: {} + chai@5.2.0: dependencies: assertion-error: 2.0.1 @@ -2052,12 +4470,25 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + check-error@2.1.1: {} chokidar@4.0.3: dependencies: readdirp: 4.1.2 + chownr@3.0.0: {} + + class-validator@0.14.2: + dependencies: + '@types/validator': 13.15.3 + libphonenumber-js: 1.12.17 + validator: 13.15.15 + optional: true + clsx@2.1.1: {} color-convert@2.0.1: @@ -2066,92 +4497,288 @@ snapshots: color-name@1.1.4: {} + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + commander@7.2.0: {} + + comment-json@4.2.5: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + + commondir@1.0.1: {} + concat-map@0.0.1: {} + consola@3.4.0: {} + cookie@0.6.0: {} + core-util-is@1.0.3: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + cssesc@3.0.0: {} - debug@4.4.1: + cssstyle@5.3.1(postcss@8.5.6): dependencies: - ms: 2.1.3 + '@asamuzakjp/css-color': 4.0.4 + '@csstools/css-syntax-patches-for-csstree': 1.0.14(postcss@8.5.6) + css-tree: 3.1.0 + transitivePeerDependencies: + - postcss - dedent-js@1.0.1: {} + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 - deep-eql@5.0.2: {} + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 - deep-is@0.1.4: {} + d3-color@3.1.0: {} - deepmerge@4.3.1: {} + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 - devalue@5.1.1: {} + d3-dispatch@3.0.1: {} - dotenv@16.0.3: {} + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 - es-module-lexer@1.7.0: {} + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 - esbuild@0.25.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.5 - '@esbuild/android-arm': 0.25.5 - '@esbuild/android-arm64': 0.25.5 - '@esbuild/android-x64': 0.25.5 - '@esbuild/darwin-arm64': 0.25.5 - '@esbuild/darwin-x64': 0.25.5 - '@esbuild/freebsd-arm64': 0.25.5 - '@esbuild/freebsd-x64': 0.25.5 - '@esbuild/linux-arm': 0.25.5 - '@esbuild/linux-arm64': 0.25.5 - '@esbuild/linux-ia32': 0.25.5 - '@esbuild/linux-loong64': 0.25.5 - '@esbuild/linux-mips64el': 0.25.5 - '@esbuild/linux-ppc64': 0.25.5 - '@esbuild/linux-riscv64': 0.25.5 - '@esbuild/linux-s390x': 0.25.5 - '@esbuild/linux-x64': 0.25.5 - '@esbuild/netbsd-arm64': 0.25.5 - '@esbuild/netbsd-x64': 0.25.5 - '@esbuild/openbsd-arm64': 0.25.5 - '@esbuild/openbsd-x64': 0.25.5 - '@esbuild/sunos-x64': 0.25.5 - '@esbuild/win32-arm64': 0.25.5 - '@esbuild/win32-ia32': 0.25.5 - '@esbuild/win32-x64': 0.25.5 + d3-format@3.1.0: {} - escape-string-regexp@4.0.0: {} + d3-geo-voronoi@2.1.0: + dependencies: + d3-array: 3.2.4 + d3-delaunay: 6.0.4 + d3-geo: 3.1.1 + d3-tricontour: 1.0.2 - eslint-compat-utils@0.5.1(eslint@9.34.0): + d3-geo@3.1.1: dependencies: - eslint: 9.34.0 - semver: 7.7.2 + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} - eslint-config-prettier@10.1.5(eslint@9.34.0): + d3-interpolate-path@2.3.0: {} + + d3-interpolate@3.0.1: dependencies: - eslint: 9.34.0 + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-quadtree@3.0.1: {} - eslint-config-turbo@2.5.3(eslint@9.34.0)(turbo@2.5.6): + d3-random@3.0.1: {} + + d3-sankey@0.12.3: dependencies: - eslint: 9.34.0 - eslint-plugin-turbo: 2.5.3(eslint@9.34.0)(turbo@2.5.6) - turbo: 2.5.6 + d3-array: 2.12.1 + d3-shape: 1.3.7 - eslint-plugin-svelte@2.46.1(eslint@9.34.0)(svelte@5.38.0): + d3-scale-chromatic@3.1.0: dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) - '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.34.0 - eslint-compat-utils: 0.5.1(eslint@9.34.0) - esutils: 2.0.3 - known-css-properties: 0.35.0 - postcss: 8.5.3 - postcss-load-config: 3.1.4(postcss@8.5.3) - postcss-safe-parser: 6.0.0(postcss@8.5.3) + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-tile@1.0.0: {} + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-tricontour@1.0.2: + dependencies: + d3-delaunay: 6.0.4 + d3-scale: 4.0.2 + + data-urls@6.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + + dayjs@1.11.18: + optional: true + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + dedent@1.5.1: {} + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + dequal@2.0.3: {} + + detect-libc@2.1.0: {} + + devalue@5.1.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dlv@1.1.3: + optional: true + + dom-accessibility-api@0.5.16: {} + + dompurify@3.2.7: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + dotenv@16.0.3: {} + + effect@3.17.14: + dependencies: + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 + optional: true + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel-svelte@8.6.0(svelte@5.38.0): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + svelte: 5.38.0 + + embla-carousel@8.6.0: {} + + enhanced-resolve@5.18.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.3 + + entities@6.0.1: {} + + es-module-lexer@1.7.0: {} + + esbuild-runner@2.2.2(esbuild@0.25.5): + dependencies: + esbuild: 0.25.5 + source-map-support: 0.5.21 + tslib: 2.4.0 + optional: true + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.34.0(jiti@2.5.1)): + dependencies: + eslint: 9.34.0(jiti@2.5.1) + semver: 7.7.2 + + eslint-config-prettier@10.1.5(eslint@9.34.0(jiti@2.5.1)): + dependencies: + eslint: 9.34.0(jiti@2.5.1) + + eslint-config-turbo@2.5.3(eslint@9.34.0(jiti@2.5.1))(turbo@2.5.6): + dependencies: + eslint: 9.34.0(jiti@2.5.1) + eslint-plugin-turbo: 2.5.3(eslint@9.34.0(jiti@2.5.1))(turbo@2.5.6) + turbo: 2.5.6 + + eslint-plugin-svelte@2.46.1(eslint@9.34.0(jiti@2.5.1))(svelte@5.38.0): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) + '@jridgewell/sourcemap-codec': 1.5.0 + eslint: 9.34.0(jiti@2.5.1) + eslint-compat-utils: 0.5.1(eslint@9.34.0(jiti@2.5.1)) + esutils: 2.0.3 + known-css-properties: 0.35.0 + postcss: 8.5.3 + postcss-load-config: 3.1.4(postcss@8.5.3) + postcss-safe-parser: 6.0.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 semver: 7.7.2 svelte-eslint-parser: 0.43.0(svelte@5.38.0) @@ -2160,10 +4787,10 @@ snapshots: transitivePeerDependencies: - ts-node - eslint-plugin-turbo@2.5.3(eslint@9.34.0)(turbo@2.5.6): + eslint-plugin-turbo@2.5.3(eslint@9.34.0(jiti@2.5.1))(turbo@2.5.6): dependencies: dotenv: 16.0.3 - eslint: 9.34.0 + eslint: 9.34.0(jiti@2.5.1) turbo: 2.5.6 eslint-scope@7.2.2: @@ -2182,9 +4809,9 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.34.0: + eslint@9.34.0(jiti@2.5.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 @@ -2219,6 +4846,8 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.5.1 transitivePeerDependencies: - supports-color @@ -2242,6 +4871,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -2256,6 +4887,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -2264,6 +4897,11 @@ snapshots: expect-type@1.2.1: {} + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + optional: true + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -2278,6 +4916,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fastest-levenshtein@1.0.16: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -2290,6 +4930,14 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.6(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -2310,9 +4958,20 @@ snapshots: flatted@3.3.3: {} + formsnap@2.0.1(svelte@5.38.0)(sveltekit-superforms@2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2)): + dependencies: + svelte: 5.38.0 + svelte-toolbelt: 0.5.0(svelte@5.38.0) + sveltekit-superforms: 2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2) + + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -2330,10 +4989,62 @@ snapshots: globals@15.15.0: {} + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} has-flag@4.0.0: {} + has-own-prop@2.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + html-void-elements@3.0.0: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + human-id@4.1.1: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ignore@5.3.2: {} ignore@7.0.5: {} @@ -2347,30 +5058,112 @@ snapshots: imurmurhash@0.1.4: {} + inline-style-parser@0.2.4: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + is-extglob@2.1.1: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-module@1.0.0: {} + is-number@7.0.0: {} + is-potential-custom-element-name@1.0.1: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 isexe@2.0.0: {} + isomorphic-dompurify@2.28.0(postcss@8.5.6): + dependencies: + dompurify: 3.2.7 + jsdom: 27.0.0(postcss@8.5.6) + transitivePeerDependencies: + - bufferutil + - canvas + - postcss + - supports-color + - utf-8-validate + + jiti@2.5.1: {} + + joi@17.13.3: + 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 + optional: true + + js-sha256@0.11.1: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 + jsdom@27.0.0(postcss@8.5.6): + dependencies: + '@asamuzakjp/dom-selector': 6.5.5 + cssstyle: 5.3.1(postcss@8.5.6) + data-urls: 6.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + ws: 8.18.3 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - postcss + - supports-color + - utf-8-validate + json-buffer@3.0.1: {} + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.28.4 + ts-algebra: 2.0.0 + optional: true + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -2379,11 +5172,92 @@ snapshots: known-css-properties@0.35.0: {} + kysely@0.27.6: {} + + layerchart@2.0.0-next.27(svelte@5.38.0): + dependencies: + '@dagrejs/dagre': 1.1.5 + '@layerstack/svelte-actions': 1.0.1-next.12 + '@layerstack/svelte-state': 0.1.0-next.17 + '@layerstack/tailwind': 2.0.0-next.15 + '@layerstack/utils': 2.0.0-next.12 + d3-array: 3.2.4 + d3-color: 3.1.0 + d3-delaunay: 6.0.4 + d3-dsv: 3.0.1 + d3-force: 3.0.0 + d3-geo: 3.1.1 + d3-geo-voronoi: 2.1.0 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-interpolate-path: 2.3.0 + d3-path: 3.1.0 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-sankey: 0.12.3 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-shape: 3.2.0 + d3-tile: 1.0.0 + d3-time: 3.1.0 + lodash-es: 4.17.21 + memoize: 10.1.0 + runed: 0.28.0(svelte@5.38.0) + svelte: 5.38.0 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.12.17: + optional: true + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.1.0 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + lilconfig@2.1.0: {} locate-character@3.0.0: {} @@ -2392,13 +5266,17 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.17.21: {} + lodash.merge@4.6.2: {} loupe@3.1.3: {} - lower-case@2.0.2: - dependencies: - tslib: 2.8.1 + loupe@3.2.1: {} + + lru-cache@11.2.1: {} + + lz-string@1.5.0: {} magic-string@0.30.17: dependencies: @@ -2408,13 +5286,66 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + marked@12.0.2: {} + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdn-data@2.12.2: {} + + mdsvex@0.12.6(svelte@5.38.0): + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 2.0.11 + prism-svelte: 0.4.7 + prismjs: 1.30.0 + svelte: 5.38.0 + unist-util-visit: 2.0.3 + vfile-message: 2.0.4 + + memoize-weak@1.0.2: {} + + memoize@10.1.0: + dependencies: + mimic-function: 5.0.1 + merge2@1.4.1: {} + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 + mimic-function@5.0.1: {} + + mini-svg-data-uri@1.4.4: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -2423,6 +5354,20 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minipass@7.1.2: {} + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + + mode-watcher@1.1.0(svelte@5.38.0): + dependencies: + runed: 0.25.0(svelte@5.38.0) + svelte: 5.38.0 + svelte-toolbelt: 0.7.1(svelte@5.38.0) + mri@1.2.0: {} mrmime@2.0.1: {} @@ -2433,10 +5378,16 @@ snapshots: natural-compare@1.4.0: {} - no-case@3.0.4: + normalize-url@8.1.0: + optional: true + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.3: dependencies: - lower-case: 2.0.2 - tslib: 2.8.1 + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 optionator@0.9.4: dependencies: @@ -2455,19 +5406,26 @@ snapshots: dependencies: p-limit: 3.1.0 + paneforge@1.0.2(svelte@5.38.0): + dependencies: + runed: 0.23.4(svelte@5.38.0) + svelte: 5.38.0 + svelte-toolbelt: 0.9.3(svelte@5.38.0) + parent-module@1.0.1: dependencies: callsites: 3.1.0 - pascal-case@3.1.2: + parse5@7.3.0: dependencies: - no-case: 3.0.4 - tslib: 2.8.1 + entities: 6.0.1 path-exists@4.0.0: {} path-key@3.1.1: {} + path-parse@1.0.7: {} + pathe@2.0.3: {} pathval@2.0.0: {} @@ -2478,6 +5436,16 @@ snapshots: picomatch@4.0.2: {} + picomatch@4.0.3: {} + + playwright-core@1.55.0: {} + + playwright@1.55.0: + dependencies: + playwright-core: 1.55.0 + optionalDependencies: + fsevents: 2.3.2 + postcss-load-config@3.1.4(postcss@8.5.3): dependencies: lilconfig: 2.1.0 @@ -2489,16 +5457,27 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-scss@4.0.9(postcss@8.5.3): + postcss-scss@4.0.9(postcss@8.5.6): dependencies: - postcss: 8.5.3 + postcss: 8.5.6 - postcss-selector-parser@6.1.2: + postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.3: + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -2511,21 +5490,69 @@ snapshots: prettier: 3.6.0 svelte: 5.38.0 + prettier-plugin-tailwindcss@0.6.14(prettier-plugin-svelte@3.4.0(prettier@3.6.0)(svelte@5.38.0))(prettier@3.6.0): + dependencies: + prettier: 3.6.0 + optionalDependencies: + prettier-plugin-svelte: 3.4.0(prettier@3.6.0)(svelte@5.38.0) + prettier@3.6.0: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + prism-svelte@0.4.7: {} + + prismjs@1.30.0: {} + + property-expr@2.0.6: + optional: true + + property-information@7.1.0: {} + punycode@2.3.1: {} + pure-rand@6.1.0: + optional: true + queue-microtask@1.2.3: {} + react-is@17.0.2: {} + readdirp@4.1.2: {} + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + + repeat-string@1.6.1: {} + + require-from-string@2.0.2: {} + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: optional: true + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + reusify@1.1.0: {} + robust-predicates@3.0.2: {} + rollup@4.41.1: dependencies: '@types/estree': 1.0.7 @@ -2552,14 +5579,77 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.41.1 fsevents: 2.3.3 + rollup@4.52.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.0 + '@rollup/rollup-android-arm64': 4.52.0 + '@rollup/rollup-darwin-arm64': 4.52.0 + '@rollup/rollup-darwin-x64': 4.52.0 + '@rollup/rollup-freebsd-arm64': 4.52.0 + '@rollup/rollup-freebsd-x64': 4.52.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.0 + '@rollup/rollup-linux-arm-musleabihf': 4.52.0 + '@rollup/rollup-linux-arm64-gnu': 4.52.0 + '@rollup/rollup-linux-arm64-musl': 4.52.0 + '@rollup/rollup-linux-loong64-gnu': 4.52.0 + '@rollup/rollup-linux-ppc64-gnu': 4.52.0 + '@rollup/rollup-linux-riscv64-gnu': 4.52.0 + '@rollup/rollup-linux-riscv64-musl': 4.52.0 + '@rollup/rollup-linux-s390x-gnu': 4.52.0 + '@rollup/rollup-linux-x64-gnu': 4.52.0 + '@rollup/rollup-linux-x64-musl': 4.52.0 + '@rollup/rollup-openharmony-arm64': 4.52.0 + '@rollup/rollup-win32-arm64-msvc': 4.52.0 + '@rollup/rollup-win32-ia32-msvc': 4.52.0 + '@rollup/rollup-win32-x64-gnu': 4.52.0 + '@rollup/rollup-win32-x64-msvc': 4.52.0 + fsevents: 2.3.3 + + rrweb-cssom@0.8.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + runed@0.23.4(svelte@5.38.0): + dependencies: + esm-env: 1.2.2 + svelte: 5.38.0 + + runed@0.25.0(svelte@5.38.0): + dependencies: + esm-env: 1.2.2 + svelte: 5.38.0 + + runed@0.28.0(svelte@5.38.0): + dependencies: + esm-env: 1.2.2 + svelte: 5.38.0 + + runed@0.29.2(svelte@5.38.0): + dependencies: + esm-env: 1.2.2 + svelte: 5.38.0 + + runed@0.31.1(svelte@5.38.0): + dependencies: + esm-env: 1.2.2 + svelte: 5.38.0 + + rw@1.3.3: {} + sade@1.8.1: dependencies: mri: 1.2.0 + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + semver@7.7.2: {} set-cookie-parser@2.7.1: {} @@ -2570,6 +5660,17 @@ snapshots: shebang-regex@3.0.0: {} + shiki@3.13.0: + dependencies: + '@shikijs/core': 3.13.0 + '@shikijs/engine-javascript': 3.13.0 + '@shikijs/engine-oniguruma': 3.13.0 + '@shikijs/langs': 3.13.0 + '@shikijs/themes': 3.13.0 + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + siginfo@2.0.0: {} sirv@3.0.1: @@ -2580,21 +5681,55 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + optional: true + + source-map@0.6.1: + optional: true + + space-separated-tokens@2.0.2: {} + + sqlite-wasm-kysely@0.3.0(kysely@0.27.6): + dependencies: + '@sqlite.org/sqlite-wasm': 3.48.0-build4 + kysely: 0.27.6 + stackback@0.0.2: {} std-env@3.9.0: {} + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-json-comments@3.1.1: {} + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + style-to-object@1.0.9: + dependencies: + inline-style-parser: 0.2.4 + + superstruct@2.0.2: + optional: true + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - svelte-check@4.3.0(picomatch@4.0.2)(svelte@5.38.0)(typescript@5.9.2): + supports-preserve-symlinks-flag@1.0.0: {} + + svelte-check@4.3.0(picomatch@4.0.3)(svelte@5.38.0)(typescript@5.9.2): dependencies: '@jridgewell/trace-mapping': 0.3.29 chokidar: 4.0.3 - fdir: 6.4.6(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 svelte: 5.38.0 @@ -2602,22 +5737,51 @@ snapshots: transitivePeerDependencies: - picomatch + svelte-easy-crop@5.0.0(svelte@5.38.0): + dependencies: + svelte: 5.38.0 + svelte-eslint-parser@0.43.0(svelte@5.38.0): dependencies: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - postcss: 8.5.3 - postcss-scss: 4.0.9(postcss@8.5.3) + postcss: 8.5.6 + postcss-scss: 4.0.9(postcss@8.5.6) optionalDependencies: svelte: 5.38.0 - svelte2tsx@0.7.42(svelte@5.38.0)(typescript@5.9.2): + svelte-sonner@1.0.5(svelte@5.38.0): dependencies: - dedent-js: 1.0.1 - pascal-case: 3.1.2 + runed: 0.28.0(svelte@5.38.0) + svelte: 5.38.0 + + svelte-toolbelt@0.10.5(svelte@5.38.0): + dependencies: + clsx: 2.1.1 + runed: 0.29.2(svelte@5.38.0) + style-to-object: 1.0.9 + svelte: 5.38.0 + + svelte-toolbelt@0.5.0(svelte@5.38.0): + dependencies: + clsx: 2.1.1 + style-to-object: 1.0.9 + svelte: 5.38.0 + + svelte-toolbelt@0.7.1(svelte@5.38.0): + dependencies: + clsx: 2.1.1 + runed: 0.23.4(svelte@5.38.0) + style-to-object: 1.0.9 + svelte: 5.38.0 + + svelte-toolbelt@0.9.3(svelte@5.38.0): + dependencies: + clsx: 2.1.1 + runed: 0.29.2(svelte@5.38.0) + style-to-object: 1.0.9 svelte: 5.38.0 - typescript: 5.9.2 svelte@5.38.0: dependencies: @@ -2636,6 +5800,62 @@ snapshots: magic-string: 0.30.17 zimmerframe: 1.1.2 + sveltekit-superforms@2.27.1(@sveltejs/kit@2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.38.0)(typescript@5.9.2): + dependencies: + '@sveltejs/kit': 2.36.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)))(svelte@5.38.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + devalue: 5.1.1 + memoize-weak: 1.0.2 + svelte: 5.38.0 + ts-deepmerge: 7.0.3 + optionalDependencies: + '@exodus/schemasafe': 1.3.0 + '@gcornut/valibot-json-schema': 0.42.0(esbuild@0.25.5)(typescript@5.9.2) + '@sinclair/typebox': 0.34.41 + '@typeschema/class-validator': 0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.2) + '@vinejs/vine': 3.0.1 + arktype: 2.1.22 + class-validator: 0.14.2 + effect: 3.17.14 + joi: 17.13.3 + json-schema-to-ts: 3.1.1 + superstruct: 2.0.2 + valibot: 1.1.0(typescript@5.9.2) + yup: 1.7.0 + zod: 3.25.76 + zod-to-json-schema: 3.24.6(zod@3.25.76) + transitivePeerDependencies: + - '@types/json-schema' + - esbuild + - typescript + + symbol-tree@3.2.4: {} + + tabbable@6.2.0: {} + + tailwind-merge@3.3.1: {} + + tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.13): + dependencies: + tailwindcss: 4.1.13 + optionalDependencies: + tailwind-merge: 3.3.1 + + tailwindcss@4.1.13: {} + + tapable@2.2.3: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tiny-case@1.0.3: + optional: true + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -2645,22 +5865,56 @@ snapshots: fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tinypool@1.1.0: {} + tinypool@1.1.1: {} + tinyrainbow@2.0.0: {} tinyspy@4.0.3: {} + tldts-core@7.0.15: {} + + tldts@7.0.15: + dependencies: + tldts-core: 7.0.15 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + toposort@2.0.2: + optional: true + totalist@3.0.1: {} + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.15 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + + trim-lines@3.0.1: {} + + ts-algebra@2.0.0: + optional: true + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: typescript: 5.9.2 + ts-deepmerge@7.0.3: {} + + tslib@2.4.0: + optional: true + tslib@2.8.1: {} tsx@4.20.5: @@ -2698,17 +5952,22 @@ snapshots: turbo-windows-64: 2.5.6 turbo-windows-arm64: 2.5.6 + tw-animate-css@1.3.8: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.40.0(eslint@9.34.0)(typescript@5.9.2): + type-fest@2.19.0: + optional: true + + typescript-eslint@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/parser': 8.40.0(eslint@9.34.0)(typescript@5.9.2) + '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.34.0)(typescript@5.9.2) - eslint: 9.34.0 + '@typescript-eslint/utils': 8.40.0(eslint@9.34.0(jiti@2.5.1))(typescript@5.9.2) + eslint: 9.34.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -2718,19 +5977,127 @@ snapshots: undici-types@7.12.0: optional: true + unist-util-is@4.1.0: {} + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@3.1.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@2.0.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + unplugin@2.3.10: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + uri-js@4.4.1: dependencies: punycode: 2.3.1 + urlpattern-polyfill@10.1.0: {} + util-deprecate@1.0.2: {} - vite-node@3.2.0(@types/node@24.5.2)(tsx@4.20.5): + uuid@10.0.0: {} + + uuid@11.1.0: {} + + valibot@0.42.1(typescript@5.9.2): + optionalDependencies: + typescript: 5.9.2 + optional: true + + valibot@1.1.0(typescript@5.9.2): + optionalDependencies: + typescript: 5.9.2 + optional: true + + validator@13.15.15: + optional: true + + vaul-svelte@1.0.0-next.7(svelte@5.38.0): + dependencies: + runed: 0.23.4(svelte@5.38.0) + svelte: 5.38.0 + svelte-toolbelt: 0.7.1(svelte@5.38.0) + + vfile-message@2.0.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 2.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-node@3.2.0(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-node@3.2.4(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) transitivePeerDependencies: - '@types/node' - jiti @@ -2745,7 +6112,12 @@ snapshots: - tsx - yaml - vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5): + vite-plugin-devtools-json@1.0.0(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)): + dependencies: + uuid: 11.1.0 + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + + vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5): dependencies: esbuild: 0.25.5 fdir: 6.4.5(picomatch@4.0.2) @@ -2756,17 +6128,40 @@ snapshots: optionalDependencies: '@types/node': 24.5.2 fsevents: 2.3.3 + jiti: 2.5.1 + lightningcss: 1.30.1 tsx: 4.20.5 - vitefu@1.0.6(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)): + vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5): + dependencies: + esbuild: 0.25.5 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.0 + tinyglobby: 0.2.15 optionalDependencies: - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) + '@types/node': 24.5.2 + fsevents: 2.3.3 + jiti: 2.5.1 + lightningcss: 1.30.1 + tsx: 4.20.5 + + vitefu@1.0.6(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)): + optionalDependencies: + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + + vitest-browser-svelte@0.1.0(@vitest/browser@3.2.4)(svelte@5.38.0)(vitest@3.2.4): + dependencies: + '@vitest/browser': 3.2.4(playwright@1.55.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))(vitest@3.2.4) + svelte: 5.38.0 + vitest: 3.2.4(@types/node@24.5.2)(@vitest/browser@3.2.4)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5) - vitest@3.2.0(@types/node@24.5.2)(tsx@4.20.5): + vitest@3.2.0(@types/node@24.5.2)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.0 - '@vitest/mocker': 3.2.0(vite@6.3.5(@types/node@24.5.2)(tsx@4.20.5)) + '@vitest/mocker': 3.2.0(vite@7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) '@vitest/pretty-format': 3.2.0 '@vitest/runner': 3.2.0 '@vitest/snapshot': 3.2.0 @@ -2784,11 +6179,12 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.0 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@24.5.2)(tsx@4.20.5) - vite-node: 3.2.0(@types/node@24.5.2)(tsx@4.20.5) + vite: 7.1.6(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + vite-node: 3.2.0(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.5.2 + jsdom: 27.0.0(postcss@8.5.6) transitivePeerDependencies: - jiti - less @@ -2803,6 +6199,68 @@ snapshots: - tsx - yaml + vitest@3.2.4(@types/node@24.5.2)(@vitest/browser@3.2.4)(jiti@2.5.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.1)(tsx@4.20.5): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.18 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + vite-node: 3.2.4(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.5.2 + '@vitest/browser': 3.2.4(playwright@1.55.0)(vite@6.3.5(@types/node@24.5.2)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.5))(vitest@3.2.4) + jsdom: 27.0.0(postcss@8.5.6) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@8.0.0: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@15.1.0: + dependencies: + tr46: 6.0.0 + webidl-conversions: 8.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -2814,8 +6272,34 @@ snapshots: word-wrap@1.2.5: {} + ws@8.18.3: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + yallist@5.0.0: {} + yaml@1.10.2: {} yocto-queue@0.1.0: {} + yup@1.7.0: + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + optional: true + zimmerframe@1.1.2: {} + + zod-to-json-schema@3.24.6(zod@3.25.76): + dependencies: + zod: 3.25.76 + optional: true + + zod@3.25.76: + optional: true + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 240f4aa..cef1d1c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - "apps/docs" - "apps/web" - "apps/api" + - "packages/ui" - "packages/eslint-config" - "packages/typescript-config" - "packages/ui"