This commit is contained in:
Torsten Dittmann
2024-09-05 15:21:31 +02:00
parent 0eac7d5023
commit 792a921e95
33 changed files with 618 additions and 1003 deletions
+4 -4
View File
@@ -22,10 +22,10 @@
"@appwrite.io/console": "1.0.1",
"@appwrite.io/pink": "0.25.0",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "1.0.0-next.3",
"@appwrite.io/pink-svelte": "1.0.0-next.22",
"@appwrite.io/pink-icons-svelte": "1.0.0-next.5",
"@appwrite.io/pink-svelte": "1.0.0-next.33",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.27.0",
"@sentry/sveltekit": "^8.28.0",
"@stripe/stripe-js": "^3.5.0",
"ai": "^2.2.37",
"analytics": "^0.8.14",
@@ -72,7 +72,7 @@
"svelte-sequential-preprocessor": "^2.0.1",
"tslib": "^2.7.0",
"typescript": "^5.5.4",
"vite": "^5.4.2",
"vite": "^5.4.3",
"vitest": "^1.6.0"
},
"type": "module",
+146 -146
View File
@@ -18,17 +18,17 @@ importers:
specifier: 0.25.0
version: 0.25.0
'@appwrite.io/pink-icons-svelte':
specifier: 1.0.0-next.3
version: 1.0.0-next.3(svelte@4.2.19)
specifier: 1.0.0-next.5
version: 1.0.0-next.5(svelte@4.2.19)
'@appwrite.io/pink-svelte':
specifier: 1.0.0-next.22
version: 1.0.0-next.22(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)
specifier: 1.0.0-next.33
version: 1.0.0-next.33(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)
'@popperjs/core':
specifier: ^2.11.8
version: 2.11.8
'@sentry/sveltekit':
specifier: ^8.27.0
version: 8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
specifier: ^8.28.0
version: 8.28.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
'@stripe/stripe-js':
specifier: ^3.5.0
version: 3.5.0
@@ -83,13 +83,13 @@ importers:
version: 1.46.1
'@sveltejs/adapter-static':
specifier: ^3.0.4
version: 3.0.4(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))
version: 3.0.4(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))
'@sveltejs/kit':
specifier: ^2.5.25
version: 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
version: 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte':
specifier: ^3.1.2
version: 3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
version: 3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
'@testing-library/dom':
specifier: ^10.4.0
version: 10.4.0
@@ -98,7 +98,7 @@ importers:
version: 6.5.0
'@testing-library/svelte':
specifier: ^5.2.1
version: 5.2.1(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))(vitest@1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8))
version: 5.2.1(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))(vitest@1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8))
'@testing-library/user-event':
specifier: ^14.5.2
version: 14.5.2(@testing-library/dom@10.4.0)
@@ -163,8 +163,8 @@ importers:
specifier: ^5.5.4
version: 5.5.4
vite:
specifier: ^5.4.2
version: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
specifier: ^5.4.3
version: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
vitest:
specifier: ^1.6.0
version: 1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8)
@@ -202,16 +202,16 @@ packages:
'@appwrite.io/console@1.0.1':
resolution: {integrity: sha512-9U7jG0XnRcxDhuma308z8XD/BF9cK6OpukxN87Tk0N/QGsNJBbH1it0LLCt6X7rPzNpOALT0LLTeMa0VEsQBow==}
'@appwrite.io/pink-icons-svelte@1.0.0-next.3':
resolution: {integrity: sha512-i3stfVVK8EoOQjXJNkwqUuH6DHCJas3aUK35wSMdS2j/6wLqdczEyaG4YsxqSjEuPqiz+8BCU0QHswhv33pZaw==}
'@appwrite.io/pink-icons-svelte@1.0.0-next.5':
resolution: {integrity: sha512-hihcDmAlVuXhhogPoUuuWPCtINzl+/HfjDdsFyvZsxf70O0PgczNSSICRJ/VQ8A87IsdEimpRcRb5OnFPUEXDA==}
peerDependencies:
svelte: ^4.0.0
'@appwrite.io/pink-icons@0.25.0':
resolution: {integrity: sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q==}
'@appwrite.io/pink-svelte@1.0.0-next.22':
resolution: {integrity: sha512-XmctdFOhYMO+/jGM0t78i83lL3iX53nP8ySoz7CUUge//kOR42Pt41bqTOlZ4+xqWqjYH/Cu1/KcWqfAQ6wXhA==}
'@appwrite.io/pink-svelte@1.0.0-next.33':
resolution: {integrity: sha512-vGd+ZMSB0PX/CiD2Nd2hSY9s6LxKdKu4kT4Whaiy+bMltF6GizPsH9iy1VeAmFdQFMM5qZOx0fDdhLSbd77kQA==}
peerDependencies:
react-dom: ^18.0.0
svelte: ^4.0.0
@@ -952,32 +952,32 @@ packages:
cpu: [x64]
os: [win32]
'@sentry-internal/browser-utils@8.27.0':
resolution: {integrity: sha512-YTIwQ1GM1NTRXgN4DvpFSQ2x4pjlqQ0FQAyHW5x2ZYv4z7VmqG4Xkid1P/srQUipECk6nxkebfD4WR19nLsvnQ==}
'@sentry-internal/browser-utils@8.28.0':
resolution: {integrity: sha512-tE9++KEy8SlqibTmYymuxFVAnutsXBqrwQ936WJbjaMfkqXiro7C1El0ybkprskd0rKS7kln20Q6nQlNlMEoTA==}
engines: {node: '>=14.18'}
'@sentry-internal/feedback@8.27.0':
resolution: {integrity: sha512-b71PQc9aK1X9b/SO1DiJlrnAEx4n0MzPZQ/tKd9oRWDyGit6pJWZfQns9r2rvc96kJPMOTxFAa/upXRCkA723A==}
'@sentry-internal/feedback@8.28.0':
resolution: {integrity: sha512-5vYunPCDBLCJ8QNnhepacdYheiN+UtYxpGAIaC/zjBC1nDuBgWs+TfKPo1UlO/1sesfgs9ibpxtShOweucL61g==}
engines: {node: '>=14.18'}
'@sentry-internal/replay-canvas@8.27.0':
resolution: {integrity: sha512-uuEfiWbjwugB9M4KxXxovHYiKRqg/R6U4EF8xM/Ub4laUuEcWsfRp7lQ3MxL3qYojbca8ncIFic2bIoKMPeejA==}
'@sentry-internal/replay-canvas@8.28.0':
resolution: {integrity: sha512-RfpYHDHMUKGeEdx41QtHITjEn6P3tGaDPHvatqdrD3yv4j+wbJ6laX1PrIxCpGFUtjdzkqi/KUcvUd2kzbH/FA==}
engines: {node: '>=14.18'}
'@sentry-internal/replay@8.27.0':
resolution: {integrity: sha512-Ofucncaon98dvlxte2L//hwuG9yILSxNrTz/PmO0k+HzB9q+oBic4667QF+azWR2qv4oKSWpc+vEovP3hVqveA==}
'@sentry-internal/replay@8.28.0':
resolution: {integrity: sha512-70jvzzOL5O74gahgXKyRkZgiYN93yly5gq+bbj4/6NRQ+EtPd285+ccy0laExdfyK0ugvvwD4v+1MQit52OAsg==}
engines: {node: '>=14.18'}
'@sentry/babel-plugin-component-annotate@2.22.0':
resolution: {integrity: sha512-UzH+NNhgnOo6UFku3C4TEz+pO/yDcIA5FKTJvLbJ7lQwAjsqLs3DZWm4cCA08skICb8mULArF6S/dn5/butVCA==}
'@sentry/babel-plugin-component-annotate@2.22.3':
resolution: {integrity: sha512-OlHA+i+vnQHRIdry4glpiS/xTOtgjmpXOt6IBOUqynx5Jd/iK1+fj+t8CckqOx9wRacO/hru2wfW/jFq0iViLg==}
engines: {node: '>= 14'}
'@sentry/browser@8.27.0':
resolution: {integrity: sha512-eL1eaHwoYUGkp4mpeYesH6WtCrm+0u9jYCW5Lm0MAeTmpx22BZKEmj0OljuUJXGnJwFbvPDlRjyz6QG11m8kZA==}
'@sentry/browser@8.28.0':
resolution: {integrity: sha512-i/gjMYzIGQiPFH1pCbdnTwH9xs9mTAqzN+goP3GWX5a58frc7h8vxyA/5z0yMd0aCW6U8mVxnoAT72vGbKbx0g==}
engines: {node: '>=14.18'}
'@sentry/bundler-plugin-core@2.22.0':
resolution: {integrity: sha512-/xXN8o7565WMsewBnQFfjm0E5wqhYsegg++HJ5RjrY/cTM4qcd/ven44GEMxqGFJitZizvkk3NHszaHylzcRUw==}
'@sentry/bundler-plugin-core@2.22.3':
resolution: {integrity: sha512-DeoUl0WffcqZZRl5Wy9aHvX4WfZbbWt0QbJ7NJrcEViq+dRAI2FQTYECFLwdZi5Gtb3oyqZICO+P7k8wDnzsjQ==}
engines: {node: '>= 14'}
'@sentry/cli-darwin@2.34.1':
@@ -1026,16 +1026,16 @@ packages:
engines: {node: '>= 10'}
hasBin: true
'@sentry/core@8.27.0':
resolution: {integrity: sha512-4frlXluHT3Du+Omw91K04jpvbfMtydvg4Bxj2+gt/DT19Swhm/fbEpzdUjgbAd3Jinj/n0qk/jFRXjr9JZKFjg==}
'@sentry/core@8.28.0':
resolution: {integrity: sha512-+If9uubvpZpvaQQw4HLiKPhrSS9/KcoA/AcdQkNm+5CVwAoOmDPtyYfkPBgfo2hLZnZQqR1bwkz/PrNoOm+gqA==}
engines: {node: '>=14.18'}
'@sentry/node@8.27.0':
resolution: {integrity: sha512-nE2VPSHOW/tzH/lB6CoBtYkmXqXncUuWMC56RLRiPyHEXDktZx8oFp364/3m117iKOjO0XHP57Kl5cdb90IM7g==}
'@sentry/node@8.28.0':
resolution: {integrity: sha512-444hx0S7EAYDdq3g2U37qHFC/WFErgf8ZvXqhWfoCI4RweHHntdFbz3azexYnO61iUsmSAnFAX6htJtAG2zNdA==}
engines: {node: '>=14.18'}
'@sentry/opentelemetry@8.27.0':
resolution: {integrity: sha512-FRz7ApnyZYDFmi2CWUhKBux2N/0WswRLHwHDZ31FYCajujw7vQKucgdsxDW2RIRPWDwcMxHY1kvt6EzM1hIsxQ==}
'@sentry/opentelemetry@8.28.0':
resolution: {integrity: sha512-xClK/fa2Y9AMoaV6f7sWfoHAz56actn2RN3UuYAfxlgmNEfZEa0tc78x4XygCT+2b83QbUb+qf1q4+1ft+HEsQ==}
engines: {node: '>=14.18'}
peerDependencies:
'@opentelemetry/api': ^1.9.0
@@ -1044,14 +1044,14 @@ packages:
'@opentelemetry/sdk-trace-base': ^1.25.1
'@opentelemetry/semantic-conventions': ^1.25.1
'@sentry/svelte@8.27.0':
resolution: {integrity: sha512-ZwrqtEK3Lg2AiW8gL4w5e2lUTEH/umSuuAUDrLJrfpXtUMPMwl9qnoJ1wBHhKcdf9jGkadAWI/cMsDonZHL64w==}
'@sentry/svelte@8.28.0':
resolution: {integrity: sha512-4J0KVT1FwUE4YafWAB1C5vwR4xve6l4Plvt7BFIedqU7B/bEbNdLIFRDIPWnE9VQn9kSOM0PzKpe6KMD1mXxdA==}
engines: {node: '>=14.18'}
peerDependencies:
svelte: 3.x || 4.x || 5.x
'@sentry/sveltekit@8.27.0':
resolution: {integrity: sha512-JR2srm6wrIEmcVzy155SwgFy8u9G/MSm7iFl0BV0iFcFX7PmEURO8fm1+pA+Qv3zTtQEkx13GUXEoDPy7SWW4g==}
'@sentry/sveltekit@8.28.0':
resolution: {integrity: sha512-xarKpr6oz6YiJL5MhIz+Nh83775hAPcdGEty9uX2osg1bChu2MaRSzxdRgbTBleHiI8n/YX9ADOAeP8COHMIFw==}
engines: {node: '>=16'}
peerDependencies:
'@sveltejs/kit': 1.x || 2.x
@@ -1060,16 +1060,16 @@ packages:
vite:
optional: true
'@sentry/types@8.27.0':
resolution: {integrity: sha512-B6lrP46+m2x0lfqWc9F4VcUbN893mVGnPEd7KIMRk95mPzkFJ3sNxggTQF5/ZfNO7lDQYQb22uysB5sj/BqFiw==}
'@sentry/types@8.28.0':
resolution: {integrity: sha512-hOfqfd92/AzBrEdMgmmV1VfOXJbIfleFTnerRl0mg/+CcNgP/6+Fdonp354TD56ouWNF2WkOM6sEKSXMWp6SEQ==}
engines: {node: '>=14.18'}
'@sentry/utils@8.27.0':
resolution: {integrity: sha512-gyJM3SyLQe0A3mkQVVNdKYvk3ZoikkYgyA/D+5StFNLKdyUgEbJgXOGXrQSSYPF7BSX6Sc5b0KHCglPII0KuKw==}
'@sentry/utils@8.28.0':
resolution: {integrity: sha512-smhk7PJpvDMQ2DB5p2qn9UeoUHdU41IgjMmS2xklZpa8tjzBTxDeWpGvrX2fuH67D9bAJuLC/XyZjJCHLoEW5g==}
engines: {node: '>=14.18'}
'@sentry/vite-plugin@2.22.0':
resolution: {integrity: sha512-U1dWldo3gb1oDqERgiSM7zexMwAuqiXO/YUO3xVSpWmhoHz2AqxOcfIX1SygW02NF7Ss3ay4qMAta8PbvdsrnQ==}
'@sentry/vite-plugin@2.22.3':
resolution: {integrity: sha512-+5bsLFRKOZzBp68XigoNE1pJ3tJ4gt2jXluApu54ui0N/yjfqGQ7LQTD7nL4tmJvB5Agwi0e7M7+fcxe9gSgBA==}
engines: {node: '>= 14'}
'@sinclair/typebox@0.27.8':
@@ -1114,8 +1114,8 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.0
'@swc/helpers@0.5.12':
resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==}
'@swc/helpers@0.5.13':
resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==}
'@testing-library/dom@10.4.0':
resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
@@ -2787,8 +2787,8 @@ packages:
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
engines: {node: '>=4'}
picocolors@1.0.1:
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
picocolors@1.1.0:
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
@@ -3485,8 +3485,8 @@ packages:
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
vite@5.4.2:
resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==}
vite@5.4.3:
resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -3727,15 +3727,15 @@ snapshots:
'@appwrite.io/console@1.0.1': {}
'@appwrite.io/pink-icons-svelte@1.0.0-next.3(svelte@4.2.19)':
'@appwrite.io/pink-icons-svelte@1.0.0-next.5(svelte@4.2.19)':
dependencies:
svelte: 4.2.19
'@appwrite.io/pink-icons@0.25.0': {}
'@appwrite.io/pink-svelte@1.0.0-next.22(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)':
'@appwrite.io/pink-svelte@1.0.0-next.33(react-dom@18.3.1(react@18.3.1))(svelte@4.2.19)':
dependencies:
'@appwrite.io/pink-icons-svelte': 1.0.0-next.3(svelte@4.2.19)
'@appwrite.io/pink-icons-svelte': 1.0.0-next.5(svelte@4.2.19)
'@floating-ui/dom': 1.6.10
'@melt-ui/svelte': 0.83.0(svelte@4.2.19)
react-dom: 18.3.1(react@18.3.1)
@@ -3750,7 +3750,7 @@ snapshots:
'@babel/code-frame@7.24.7':
dependencies:
'@babel/highlight': 7.24.7
picocolors: 1.0.1
picocolors: 1.1.0
'@babel/compat-data@7.25.4': {}
@@ -3831,7 +3831,7 @@ snapshots:
'@babel/helper-validator-identifier': 7.24.7
chalk: 2.4.2
js-tokens: 4.0.0
picocolors: 1.0.1
picocolors: 1.1.0
'@babel/parser@7.25.6':
dependencies:
@@ -4069,7 +4069,7 @@ snapshots:
'@internationalized/date@3.5.5':
dependencies:
'@swc/helpers': 0.5.12
'@swc/helpers': 0.5.13
'@istanbuljs/load-nyc-config@1.1.0':
dependencies:
@@ -4571,48 +4571,48 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.21.2':
optional: true
'@sentry-internal/browser-utils@8.27.0':
'@sentry-internal/browser-utils@8.28.0':
dependencies:
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry-internal/feedback@8.27.0':
'@sentry-internal/feedback@8.28.0':
dependencies:
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry-internal/replay-canvas@8.27.0':
'@sentry-internal/replay-canvas@8.28.0':
dependencies:
'@sentry-internal/replay': 8.27.0
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry-internal/replay': 8.28.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry-internal/replay@8.27.0':
'@sentry-internal/replay@8.28.0':
dependencies:
'@sentry-internal/browser-utils': 8.27.0
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry-internal/browser-utils': 8.28.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry/babel-plugin-component-annotate@2.22.0': {}
'@sentry/babel-plugin-component-annotate@2.22.3': {}
'@sentry/browser@8.27.0':
'@sentry/browser@8.28.0':
dependencies:
'@sentry-internal/browser-utils': 8.27.0
'@sentry-internal/feedback': 8.27.0
'@sentry-internal/replay': 8.27.0
'@sentry-internal/replay-canvas': 8.27.0
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry-internal/browser-utils': 8.28.0
'@sentry-internal/feedback': 8.28.0
'@sentry-internal/replay': 8.28.0
'@sentry-internal/replay-canvas': 8.28.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry/bundler-plugin-core@2.22.0':
'@sentry/bundler-plugin-core@2.22.3':
dependencies:
'@babel/core': 7.25.2
'@sentry/babel-plugin-component-annotate': 2.22.0
'@sentry/babel-plugin-component-annotate': 2.22.3
'@sentry/cli': 2.34.1
dotenv: 16.4.5
find-up: 5.0.0
@@ -4663,12 +4663,12 @@ snapshots:
- encoding
- supports-color
'@sentry/core@8.27.0':
'@sentry/core@8.28.0':
dependencies:
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry/node@8.27.0':
'@sentry/node@8.28.0':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/context-async-hooks': 1.26.0(@opentelemetry/api@1.9.0)
@@ -4694,51 +4694,51 @@ snapshots:
'@opentelemetry/sdk-trace-base': 1.26.0(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.27.0
'@prisma/instrumentation': 5.18.0
'@sentry/core': 8.27.0
'@sentry/opentelemetry': 8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/core': 8.28.0
'@sentry/opentelemetry': 8.28.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
import-in-the-middle: 1.11.0
optionalDependencies:
opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0)
transitivePeerDependencies:
- supports-color
'@sentry/opentelemetry@8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)':
'@sentry/opentelemetry@8.28.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.26.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.26.0(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.27.0
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry/svelte@8.27.0(svelte@4.2.19)':
'@sentry/svelte@8.28.0(svelte@4.2.19)':
dependencies:
'@sentry/browser': 8.27.0
'@sentry/core': 8.27.0
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/browser': 8.28.0
'@sentry/core': 8.28.0
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
magic-string: 0.30.7
svelte: 4.2.19
'@sentry/sveltekit@8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))':
'@sentry/sveltekit@8.28.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))':
dependencies:
'@sentry/core': 8.27.0
'@sentry/node': 8.27.0
'@sentry/opentelemetry': 8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)
'@sentry/svelte': 8.27.0(svelte@4.2.19)
'@sentry/types': 8.27.0
'@sentry/utils': 8.27.0
'@sentry/vite-plugin': 2.22.0
'@sveltejs/kit': 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
'@sentry/core': 8.28.0
'@sentry/node': 8.28.0
'@sentry/opentelemetry': 8.28.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.27.0)
'@sentry/svelte': 8.28.0(svelte@4.2.19)
'@sentry/types': 8.28.0
'@sentry/utils': 8.28.0
'@sentry/vite-plugin': 2.22.3
'@sveltejs/kit': 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
magic-string: 0.30.7
magicast: 0.2.8
sorcery: 0.11.0
optionalDependencies:
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
transitivePeerDependencies:
- '@opentelemetry/api'
- '@opentelemetry/core'
@@ -4749,15 +4749,15 @@ snapshots:
- supports-color
- svelte
'@sentry/types@8.27.0': {}
'@sentry/types@8.28.0': {}
'@sentry/utils@8.27.0':
'@sentry/utils@8.28.0':
dependencies:
'@sentry/types': 8.27.0
'@sentry/types': 8.28.0
'@sentry/vite-plugin@2.22.0':
'@sentry/vite-plugin@2.22.3':
dependencies:
'@sentry/bundler-plugin-core': 2.22.0
'@sentry/bundler-plugin-core': 2.22.3
unplugin: 1.0.1
transitivePeerDependencies:
- encoding
@@ -4775,13 +4775,13 @@ snapshots:
'@stripe/stripe-js@3.5.0': {}
'@sveltejs/adapter-static@3.0.4(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))':
'@sveltejs/adapter-static@3.0.4(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))':
dependencies:
'@sveltejs/kit': 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/kit': 2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))':
'@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.0.0
@@ -4795,32 +4795,32 @@ snapshots:
sirv: 2.0.4
svelte: 4.2.19
tiny-glob: 0.2.9
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))':
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
debug: 4.3.6
svelte: 4.2.19
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
transitivePeerDependencies:
- supports-color
'@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))':
'@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))':
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)))(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
debug: 4.3.6
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.11
svelte: 4.2.19
svelte-hmr: 0.16.0(svelte@4.2.19)
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vitefu: 0.2.5(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
vitefu: 0.2.5(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))
transitivePeerDependencies:
- supports-color
'@swc/helpers@0.5.12':
'@swc/helpers@0.5.13':
dependencies:
tslib: 2.7.0
@@ -4845,12 +4845,12 @@ snapshots:
lodash: 4.17.21
redent: 3.0.0
'@testing-library/svelte@5.2.1(svelte@4.2.19)(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8))(vitest@1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8))':
'@testing-library/svelte@5.2.1(svelte@4.2.19)(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8))(vitest@1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8))':
dependencies:
'@testing-library/dom': 10.4.0
svelte: 4.2.19
optionalDependencies:
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
vitest: 1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8)
'@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)':
@@ -5052,7 +5052,7 @@ snapshots:
fflate: 0.8.2
flatted: 3.3.1
pathe: 1.1.2
picocolors: 1.0.1
picocolors: 1.1.0
sirv: 2.0.4
vitest: 1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8)
@@ -6813,7 +6813,7 @@ snapshots:
postgres-date: 1.0.7
postgres-interval: 1.2.0
picocolors@1.0.1: {}
picocolors@1.1.0: {}
picomatch@2.3.1: {}
@@ -6864,7 +6864,7 @@ snapshots:
postcss@8.4.44:
dependencies:
nanoid: 3.3.7
picocolors: 1.0.1
picocolors: 1.1.0
source-map-js: 1.2.0
postgres-array@2.0.0: {}
@@ -7215,7 +7215,7 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 3.6.0
picocolors: 1.0.1
picocolors: 1.1.0
sade: 1.8.1
svelte: 4.2.19
svelte-preprocess: 5.1.4(@babel/core@7.25.2)(postcss-load-config@3.1.4(postcss@8.4.44))(postcss@8.4.44)(sass@1.77.8)(svelte@4.2.19)(typescript@5.5.4)
@@ -7411,7 +7411,7 @@ snapshots:
dependencies:
browserslist: 4.23.3
escalade: 3.2.0
picocolors: 1.0.1
picocolors: 1.1.0
uri-js@4.4.1:
dependencies:
@@ -7439,8 +7439,8 @@ snapshots:
cac: 6.7.14
debug: 4.3.6
pathe: 1.1.2
picocolors: 1.0.1
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
picocolors: 1.1.0
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
transitivePeerDependencies:
- '@types/node'
- less
@@ -7452,7 +7452,7 @@ snapshots:
- supports-color
- terser
vite@5.4.2(@types/node@22.5.2)(sass@1.77.8):
vite@5.4.3(@types/node@22.5.2)(sass@1.77.8):
dependencies:
esbuild: 0.21.5
postcss: 8.4.44
@@ -7462,9 +7462,9 @@ snapshots:
fsevents: 2.3.3
sass: 1.77.8
vitefu@0.2.5(vite@5.4.2(@types/node@22.5.2)(sass@1.77.8)):
vitefu@0.2.5(vite@5.4.3(@types/node@22.5.2)(sass@1.77.8)):
optionalDependencies:
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
vitest@1.6.0(@types/node@22.5.2)(@vitest/ui@1.6.0)(jsdom@22.1.0)(sass@1.77.8):
dependencies:
@@ -7480,12 +7480,12 @@ snapshots:
local-pkg: 0.5.0
magic-string: 0.30.11
pathe: 1.1.2
picocolors: 1.0.1
picocolors: 1.1.0
std-env: 3.7.0
strip-literal: 2.1.0
tinybench: 2.9.0
tinypool: 0.8.4
vite: 5.4.2(@types/node@22.5.2)(sass@1.77.8)
vite: 5.4.3(@types/node@22.5.2)(sass@1.77.8)
vite-node: 1.6.0(@types/node@22.5.2)(sass@1.77.8)
why-is-node-running: 2.3.0
optionalDependencies:
+21 -26
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
import { Card, Layout } from '@appwrite.io/pink-svelte';
type BaseProps = {
isTile?: boolean;
@@ -30,30 +30,25 @@
export { classes as class };
export let style = '';
function getElement() {
switch (true) {
case !!href:
return 'a';
case isButton:
return 'button';
default:
return 'article';
}
}
$: resolvedClasses = [!isTile && 'common-section', classes].filter(Boolean).join(' ');
</script>
<svelte:element
this={getElement()}
class="card {classes}"
class:common-section={!isTile}
class:is-border-dashed={isDashed}
class:is-danger={danger}
class:is-allowed-focus={href}
{...$$restProps}
{style}
on:click
on:keyup={clickOnEnter}
role={href || isButton ? 'button' : 'presentation'}
{href}>
<slot />
</svelte:element>
{#if href}
<Card.Link class={resolvedClasses} on:click {href} {style}>
<Layout.Stack gap="xl">
<slot />
</Layout.Stack>
</Card.Link>
{:else if isButton}
<Card.Button class={resolvedClasses} {style} on:click>
<Layout.Stack gap="xl">
<slot />
</Layout.Stack>
</Card.Button>
{:else}
<Card.Base class={resolvedClasses} {style}>
<Layout.Stack gap="xl">
<slot />
</Layout.Stack>
</Card.Base>
{/if}
+21 -15
View File
@@ -1,26 +1,32 @@
<script lang="ts">
import { Card } from './';
import { Divider, Layout, Card } from '@appwrite.io/pink-svelte';
export let danger = false;
export let hideOverflow = false;
export let hideFooter = false;
</script>
<Card {danger} class={danger ? 'u-padding-inline-start-32' : ''}>
<div class="common-section grid-1-2" class:hideOverflow>
<div class="grid-1-2-col-1 u-flex u-flex-vertical u-gap-16">
<slot />
<Card.Base>
<Layout.Stack gap="xl" justifyContent="space-around">
<div class="common-section grid-1-2" class:hideOverflow>
<div class="grid-1-2-col-1 u-flex u-flex-vertical u-gap-16">
<slot />
</div>
<div class="grid-1-2-col-2 u-flex u-flex-vertical u-gap-16 u-min-width-0">
<slot name="aside" />
</div>
</div>
<div class="grid-1-2-col-2 u-flex u-flex-vertical u-gap-16 u-min-width-0">
<slot name="aside" />
</div>
</div>
{#if $$slots.actions && !hideFooter}
<div class="common-section card-separator u-flex u-main-end">
<slot name="actions" />
</div>
{/if}
</Card>
{#if $$slots.actions && !hideFooter}
<span
style="margin-left: calc(-1* var(--space-9));margin-right: calc(-1* var(--space-9));width:auto;">
<Divider />
</span>
<Layout.Stack direction="row-reverse">
<slot name="actions" />
</Layout.Stack>
{/if}
</Layout.Stack>
</Card.Base>
<style lang="scss">
.hideOverflow > * {
+5 -7
View File
@@ -28,12 +28,10 @@
Enter a custom {name} ID. Leave blank for a randomly generated one.
</svelte:fragment>
<svelte:fragment slot="content">
<div class="form">
{#if isProject}
<InputProjectId bind:value={id} {autofocus} />
{:else}
<InputId bind:value={id} {autofocus} />
{/if}
</div>
{#if isProject}
<InputProjectId bind:value={id} {autofocus} />
{:else}
<InputId bind:value={id} {autofocus} />
{/if}
</svelte:fragment>
</InnerModal>
+20 -45
View File
@@ -1,11 +1,7 @@
<script lang="ts">
import { app } from '$lib/stores/app';
import { Button } from '$lib/elements/forms';
import EmptyLight from '$lib/images/empty-light.svg';
import EmptyDark from '$lib/images/empty-dark.svg';
import { Heading } from '.';
import { trackEvent } from '$lib/actions/analytics';
import { Empty, Card } from '@appwrite.io/pink-svelte';
import { Button } from '$lib/elements/forms';
export let single = false;
export let noMedia = false;
export let target: string = null;
@@ -22,45 +18,24 @@
</script>
{#if single}
<article class="card u-grid u-cross-center u-width-full-line common-section">
<div
class="u-flex u-flex-vertical u-cross-center u-gap-24 u-width-full-line u-overflow-hidden u-padding-block-8">
{#if !noMedia}
<button
type="button"
on:click|preventDefault
on:click={track}
aria-label="create {target}">
{#if $app.themeInUse === 'dark'}
<img src={EmptyDark} alt="create" aria-hidden="true" height="242" />
{:else}
<img src={EmptyLight} alt="create" aria-hidden="true" height="242" />
{/if}
</button>
{/if}
<slot>
<div class="u-text-center">
<Heading size="7" tag="h2" trimmed={false}>
Create a {target} to get started.
</Heading>
<p class="body-text-2 u-bold u-margin-block-start-4">
Need a hand? Learn more in our documentation.
</p>
</div>
<div class="u-flex u-flex-wrap u-gap-16 u-main-center">
<Button
external
{href}
text
event="empty_documentation"
ariaLabel="create {target}">Documentation</Button>
<Button secondary on:click on:click={track}>
Create {target}
</Button>
</div>
</slot>
</div>
</article>
<Card.Base padding="none" class="common-section">
<Empty
title={`Create your first ${target}`}
description="Need a hand? Learn more in our documentation.">
<svelte:fragment slot="actions">
<Button
external
{href}
text
event="empty_documentation"
size="small"
ariaLabel="create {target}">Documentation</Button>
<Button secondary on:mousedown on:click on:click={track} size="small">
Create {target}
</Button>
</svelte:fragment>
</Empty>
</Card.Base>
{:else}
<button
on:click|preventDefault
+13 -14
View File
@@ -1,23 +1,22 @@
<script lang="ts">
import { app } from '$lib/stores/app';
import Light from '$lib/images/search-light.svg';
import Dark from '$lib/images/search-dark.svg';
import PaginationInline from './paginationInline.svelte';
import { Card, Empty } from '@appwrite.io/pink-svelte';
export let hidePagination = false;
export let hidePages = false;
export let target = '';
export let search = '';
</script>
<article class="card u-grid u-cross-center u-width-full-line common-section">
<div class="u-flex u-flex-vertical u-cross-center u-gap-24 u-overflow-hidden">
{#if $app.themeInUse === 'dark'}
<img src={Dark} height="175" alt="create" aria-hidden="true" />
{:else}
<img src={Light} height="175" alt="create" aria-hidden="true" />
{/if}
<slot />
</div>
</article>
<Card.Base padding="none" class="common-section">
<Empty
title={`Sorry, we couldn't find ${search}`}
description={`There are no ${target} that match your search.`}
type="secondary">
<svelte:fragment slot="actions">
<slot />
</svelte:fragment>
</Empty>
</Card.Base>
{#if !hidePagination}
<div class="u-flex u-margin-block-start-32 u-main-space-between u-cross-center">
+27 -31
View File
@@ -1,41 +1,37 @@
<script>
import { FormItem } from '$lib/elements/forms';
export let show = false;
export let closable = true;
export let fullWidth = false;
</script>
{#if show}
<FormItem>
<section class="modal is-inner-modal" class:u-width-full-line={fullWidth}>
<div class="modal-form">
<header class="modal-header">
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<h4 class="modal-title body-text-1 u-bold">
<slot name="title" />
</h4>
{#if closable}
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close"
title="Close"
on:click={() => (show = false)}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
</div>
<p class="u-flex-basis-100-percent text u-small">
<slot name="subtitle" />
</p>
</header>
<div class="modal-content">
<slot name="content" />
<section class="modal is-inner-modal" class:u-width-full-line={fullWidth}>
<div class="modal-form">
<header class="modal-header">
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<h4 class="modal-title body-text-1 u-bold">
<slot name="title" />
</h4>
{#if closable}
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close"
title="Close"
on:click={() => (show = false)}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
</div>
<p class="u-flex-basis-100-percent text u-small">
<slot name="subtitle" />
</p>
</header>
<div class="modal-content">
<slot name="content" />
</div>
</section>
</FormItem>
</div>
</section>
{/if}
+2 -2
View File
@@ -55,11 +55,11 @@
style="--button-size:1.5rem;"
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
on:mousedown={() =>
trackEvent('click_close_modal', {
from: 'button'
})}
on:click={close}>
on:mousedown={close}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
+9 -19
View File
@@ -4,6 +4,8 @@
import { trackEvent } from '$lib/actions/analytics';
import { onMount } from 'svelte';
import { onDestroy } from 'svelte';
import { Input } from '@appwrite.io/pink-svelte';
import { IconX } from '@appwrite.io/pink-icons-svelte';
export let search = '';
export let placeholder = '';
@@ -60,25 +62,13 @@
<div class="u-flex u-gap-12 common-section u-main-space-between">
<div class={fullWidth ? 'u-width-full-line' : 'u-flex-basis-50-percent'}>
<div class="input-text-wrapper" class:is-with-end-button={isWithEndButton}>
<input
{placeholder}
{disabled}
{required}
type="search"
class="input-text"
bind:value={search} />
<span class="icon-search" aria-hidden="true" />
{#if isWithEndButton && search}
<button
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Clear search"
on:click={() => (search = '')}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
</div>
<Input.Text {placeholder} {disabled} {required} type="search" bind:value={search}>
<svelte:fragment slot="end">
{#if search}
<Input.Action icon={IconX} on:click={() => (search = '')} />
{/if}
</svelte:fragment>
</Input.Text>
</div>
<slot />
</div>
+4 -2
View File
@@ -55,6 +55,7 @@
{#if href}
<Button.Anchor
on:click
on:mousedown
on:click={track}
{href}
{download}
@@ -65,12 +66,13 @@
rel={external ? 'noopener noreferrer' : ''}
class={resolvedClasses}
aria-label={ariaLabel}
--button-width={fullWidth ? '100%' : 'fit-content'}>
--button-width={fullWidth ? '100%' : undefined}>
<slot />
</Button.Anchor>
{:else}
<Button.Button
on:click
on:mousedown
on:click={track}
{size}
disabled={internalDisabled}
@@ -78,7 +80,7 @@
class={resolvedClasses}
aria-label={ariaLabel}
type={submit ? 'submit' : 'button'}
--button-width={fullWidth ? '100%' : 'fit-content'}>
--button-width={fullWidth ? '100%' : undefined}>
{#if $isSubmitting && submissionLoader}
<span
class="loader is-small"
+1 -1
View File
@@ -26,6 +26,7 @@
export function checkValidity() {
return form.checkValidity();
}
export function triggerSubmit() {
form.requestSubmit();
}
@@ -41,7 +42,6 @@
bind:this={form}
class={classes}
class:form={!noStyle}
class:common-section={!noMargin}
class:modal-form={isModal}
on:submit|preventDefault={submit}>
<slot />
+5 -6
View File
@@ -1,13 +1,12 @@
<script lang="ts">
import { Layout } from '@appwrite.io/pink-svelte';
export let isCommonSection = false;
export let gap = 24;
export let gap = null;
let classes = '';
export { classes as class };
</script>
<ul
class="form-list {classes}"
class:common-section={isCommonSection}
style={`--form-list-gap: ${gap / 16}rem;`}>
<Layout.Stack gap="l">
<slot />
</ul>
</Layout.Stack>
+43 -45
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { tooltip as tooltipAction } from '$lib/actions/tooltip';
import { FormItem, Helper } from '.';
import { Helper } from '.';
export let type: 'checkbox' | 'switchbox' = 'checkbox';
export let label: string;
@@ -29,48 +29,46 @@
}
</script>
<FormItem>
<label class="choice-item" for={id}>
<input
{id}
{disabled}
{required}
type="checkbox"
class:switch={type === 'switchbox'}
aria-checked={value}
bind:this={element}
bind:checked={value}
on:change
on:invalid={handleInvalid} />
<label class="choice-item" for={id}>
<input
{id}
{disabled}
{required}
type="checkbox"
class:switch={type === 'switchbox'}
aria-checked={value}
bind:this={element}
bind:checked={value}
on:change
on:invalid={handleInvalid} />
<div class="choice-item-content" class:u-width-full-line={fullWidth}>
{#if (label && showLabel) || tooltip}
<div class="u-flex u-gap-4">
{#if label}
<span class:u-hide={!showLabel} class="choice-item-title">
{label}
</span>
{/if}
{#if tooltip}
<button
type="button"
class="tooltip"
aria-label="variables info"
use:tooltipAction={{ content: tooltip }}>
<span
class="icon-info"
aria-hidden="true"
style="font-size: var(--icon-size-small)" />
</button>
{/if}
</div>
{/if}
{#if $$slots.default}
<p class="choice-item-paragraph"><slot /></p>
{/if}
</div>
</label>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<div class="choice-item-content" class:u-width-full-line={fullWidth}>
{#if (label && showLabel) || tooltip}
<div class="u-flex u-gap-4">
{#if label}
<span class:u-hide={!showLabel} class="choice-item-title">
{label}
</span>
{/if}
{#if tooltip}
<button
type="button"
class="tooltip"
aria-label="variables info"
use:tooltipAction={{ content: tooltip }}>
<span
class="icon-info"
aria-hidden="true"
style="font-size: var(--icon-size-small)" />
</button>
{/if}
</div>
{/if}
{#if $$slots.default}
<p class="choice-item-paragraph"><slot /></p>
{/if}
</div>
</label>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
+24 -42
View File
@@ -1,45 +1,36 @@
<script lang="ts">
import { onMount } from 'svelte';
import { FormItem, Helper, Label } from '.';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string;
export let showLabel = true;
export let id: string;
export let name = id;
export let value: string = null;
export let placeholder = '* * * * *';
export let required = false;
export let disabled = false;
export let readonly = false;
export let nullable = false;
export let autofocus = false;
export let maxlength: number = null;
export let minlength: number = null;
export let step: number | 'any' = 1;
let element: HTMLInputElement;
let error: string;
const pattern = String.raw`^.*\s+.*\s+.*\s+.*\s+.*`;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
if (element.validity.patternMismatch) {
if (event.currentTarget.validity.patternMismatch) {
error = 'Please enter a valid Cron expression';
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
@@ -47,29 +38,20 @@
}
</script>
<FormItem>
<Label {required} hide={!showLabel} for={id}>
{label}
</Label>
<div class="input-text-wrapper">
<input
{id}
{placeholder}
{disabled}
{required}
{minlength}
{maxlength}
{readonly}
{step}
{pattern}
type="text"
class="input-text"
bind:value
bind:this={element}
on:invalid={handleInvalid} />
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<Input.Text
{id}
{name}
{placeholder}
{disabled}
{readonly}
{required}
{label}
{nullable}
{pattern}
on:input
on:invalid={handleInvalid}
type="email"
helper={error}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
bind:value />
+25 -61
View File
@@ -1,15 +1,16 @@
<script lang="ts">
import { SvelteComponent, onMount } from 'svelte';
import { FormItem, Helper, Label } from '.';
import { Drop } from '$lib/components';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string;
export let showLabel = true;
export let id: string;
export let name = id;
export let value = '';
export let placeholder = '';
export let required = false;
export let disabled = false;
export let nullable = false;
export let readonly = false;
export let autofocus = false;
export let autocomplete = false;
@@ -21,29 +22,21 @@
// https://www.geeksforgeeks.org/how-to-validate-a-domain-name-using-regular-expression/
const pattern = String.raw`(?!-)[A-Za-z0-9\-]+([\-\.]{1}[a-z0-9]+)*\.[A-Za-z]{2,18}`;
let element: HTMLInputElement;
let error: string;
let show = false;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.patternMismatch) {
if (event.currentTarget.validity.patternMismatch) {
error = 'Must be a valid domain';
return;
}
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
@@ -51,50 +44,21 @@
}
</script>
<FormItem {fullWidth}>
<Label {required} hide={!showLabel} for={id}>
{label}{#if popover}
<Drop isPopover bind:show display="inline-block">
<!-- TODO: make unclicked icon greyed out and hover and clicked filled -->
&nbsp;<button
type="button"
on:click={() => (show = !show)}
class="tooltip"
aria-label="input tooltip">
<span
class="icon-info"
aria-hidden="true"
style="font-size: var(--icon-size-small)" />
</button>
<svelte:fragment slot="list">
<div
class="dropped card u-max-width-250"
style:--card-border-radius="var(--border-radius-small)"
style:--p-card-padding=".75rem"
style:box-shadow="var(--shadow-large)">
<svelte:component this={popover} {...popoverProps} />
</div>
</svelte:fragment>
</Drop>
{/if}
</Label>
<div class="input-text-wrapper">
<input
{id}
{placeholder}
{disabled}
{required}
{maxlength}
{pattern}
{readonly}
type="text"
autocomplete={autocomplete ? 'on' : 'off'}
bind:value
bind:this={element}
on:invalid={handleInvalid} />
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<Input.Text
{id}
{name}
{placeholder}
{disabled}
{readonly}
{required}
{label}
{nullable}
{pattern}
on:input
on:invalid={handleInvalid}
type="text"
helper={error}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
bind:value />
+4 -5
View File
@@ -1,8 +1,5 @@
<script lang="ts">
import { SvelteComponent, onMount } from 'svelte';
import { FormItem, Helper, Label } from '.';
import NullCheckbox from './nullCheckbox.svelte';
import { Drop } from '$lib/components';
import { SvelteComponent } from 'svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string;
@@ -27,6 +24,7 @@
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (event.currentTarget.validity.typeMismatch) {
error = 'Emails should be formatted as: name@example.com';
return;
@@ -51,10 +49,11 @@
{required}
{label}
{nullable}
{autofocus}
on:input
on:invalid={handleInvalid}
type="email"
helper={error}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
bind:value />
+17 -43
View File
@@ -1,60 +1,34 @@
<script lang="ts">
import { onMount } from 'svelte';
import { FormItem } from '.';
import TextCounter from './textCounter.svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let value = '';
export let autofocus = true;
let element: HTMLInputElement;
let icon = 'info';
let error = false;
const pattern = String.raw`^[a-zA-Z0-9][a-zA-Z0-9._\-]*$`;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.patternMismatch) {
icon = 'exclamation';
if (event.currentTarget.validity.patternMismatch) {
error = true;
return;
}
};
$: if (value) {
icon = 'info';
error = false;
}
</script>
<FormItem>
<div class="input-text-wrapper">
<input
id="id"
placeholder="Enter ID"
maxlength={36}
{pattern}
autocomplete="off"
type="text"
class="input-text"
bind:value
bind:this={element}
on:invalid={handleInvalid} />
<TextCounter count={value?.length ?? 0} max={36} />
</div>
</FormItem>
<div
class="u-flex u-gap-4 u-margin-block-start-8 u-small"
class:u-color-text-warning={icon === 'exclamation'}>
<span
class:icon-info={icon === 'info'}
class:icon-exclamation={icon === 'exclamation'}
class="u-cross-center u-line-height-1 u-color-text-gray"
aria-hidden="true" />
<span class="text u-line-height-1-5">
Allowed characters: alphanumeric, non-leading hyphen, underscore, period
</span>
</div>
<Input.Text
{pattern}
{autofocus}
id="id"
placeholder="Enter ID"
maxlength={36}
autocomplete="off"
bind:value
on:invalid={handleInvalid}
state={error ? 'error' : 'default'}
helper="Allowed characters: alphanumeric, non-leading hyphen, underscore, period" />
+24 -64
View File
@@ -1,12 +1,11 @@
<script lang="ts">
import { onMount } from 'svelte';
import { FormItem, FormItemPart, Helper, Label } from '.';
import NullCheckbox from './nullCheckbox.svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string | undefined = undefined;
export let optionalText: string | undefined = undefined;
export let showLabel = true;
export let id: string;
export let name = id;
export let value: number = null;
export let placeholder = '';
export let required = false;
@@ -20,87 +19,48 @@
export let isMultiple = false;
export let fullWidth = false;
let element: HTMLInputElement;
let error: string;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
if (element.validity.rangeOverflow) {
if (event.currentTarget.validity.rangeOverflow) {
error = `The value must be less than or equal to ${max}`;
return;
}
if (element.validity.rangeUnderflow) {
if (event.currentTarget.validity.rangeUnderflow) {
error = `The value must be greater than or equal to ${min}`;
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
error = null;
}
let prevValue = 0;
function handleNullChange(e: CustomEvent<boolean>) {
const isNull = e.detail;
if (isNull) {
prevValue = value;
value = null;
} else {
value = prevValue;
}
}
$: wrapper = isMultiple ? FormItemPart : FormItem;
</script>
<svelte:component this={wrapper} {fullWidth}>
{#if label}
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
{/if}
<div class="input-text-wrapper">
<input
{id}
{placeholder}
{disabled}
{required}
{min}
{max}
{readonly}
{step}
type="number"
class="input-text u-remove-input-number-buttons"
bind:value
bind:this={element}
on:invalid={handleInvalid}
style:--amount-of-buttons={nullable && !required ? 1.75 : 0} />
<ul
class="buttons-list u-cross-center u-gap-8 u-position-absolute u-inset-block-start-8 u-inset-block-end-8 u-inset-inline-end-12">
{#if nullable && !required}
<li class="buttons-list-item">
<NullCheckbox checked={value === null} on:change={handleNullChange} />
</li>
{/if}
</ul>
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</svelte:component>
<Input.Number
{id}
{name}
{placeholder}
{readonly}
{disabled}
{required}
{min}
{max}
{label}
{step}
{nullable}
autofocus={autofocus || undefined}
helper={error}
state={error ? 'error' : 'default'}
on:invalid={handleInvalid}
on:input />
+3 -2
View File
@@ -45,11 +45,12 @@
{label}
{required}
{disabled}
{autofocus}
{minlength}
{maxlength}
autocomplete={autocomplete ? 'on' : 'off'}
{placeholder}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
helper={error}
on:invalid={handleInvalid}
bind:value />
+27 -69
View File
@@ -1,11 +1,12 @@
<script lang="ts">
import { SvelteComponent, onMount } from 'svelte';
import { FormItem, Helper, Label } from '.';
import { Drop } from '$lib/components';
import { Input } from '@appwrite.io/pink-svelte';
import type { States } from '@appwrite.io/pink-svelte/dist/input/types';
export let label: string;
export let showLabel = true;
export let id: string;
export let name: string = id;
export let value = '';
export let placeholder = '';
export let required = false;
@@ -14,42 +15,35 @@
export let autofocus = false;
export let autocomplete = false;
export let minlength: number = null;
export let maxlength: number = null;
export let maxlength: number = 15;
export let nullable = false;
export let popover: typeof SvelteComponent<unknown> = null;
export let popoverProps: Record<string, unknown> = {};
export let fullWidth = false;
const pattern = String.raw`^\+[1-9]\d{1,14}$`;
let element: HTMLInputElement;
let error: string;
let show = false;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
if (element.validity.patternMismatch) {
if (event.currentTarget.validity.patternMismatch) {
error = `Allowed characters: leading '+' and maximum of ${maxlength - 1} digits`;
return;
}
if (element.validity.tooShort) {
if (event.currentTarget.validity.tooShort) {
error = `The value must contain leading + and at least ${minlength - 1} digits `;
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
@@ -57,56 +51,20 @@
}
</script>
<FormItem {fullWidth}>
<Label {required} hide={!showLabel} for={id}>
{label}{#if popover}
<Drop isPopover bind:show display="inline-block">
<!-- TODO: make unclicked icon greyed out and hover and clicked filled -->
&nbsp;<button
type="button"
on:click={() => (show = !show)}
class="tooltip"
aria-label="input tooltip">
<span
class="icon-info"
aria-hidden="true"
style="font-size: var(--icon-size-small)" />
</button>
<svelte:fragment slot="list">
<div
class="dropped card u-max-width-250"
style:--card-border-radius="var(--border-radius-small)"
style:--p-card-padding=".75rem"
style:box-shadow="var(--shadow-large)">
<svelte:component this={popover} {...popoverProps} />
</div>
</svelte:fragment>
</Drop>
{/if}
</Label>
<div class="input-text-wrapper">
<input
{id}
{placeholder}
{disabled}
{required}
{minlength}
{maxlength}
{pattern}
{readonly}
type="text"
autocomplete={autocomplete ? 'on' : 'off'}
bind:value
bind:this={element}
style:--amount-of-buttons={$$slots.options ? 1 : 0}
on:invalid={handleInvalid} />
{#if $$slots.options}
<div class="options-list">
<slot name="options" />
</div>
{/if}
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<Input.Text
{id}
{name}
{placeholder}
{disabled}
{required}
{label}
{nullable}
{pattern}
on:input
on:invalid={handleInvalid}
type="text"
helper={error}
state={error ? 'error' : 'default'}
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
bind:value />
+19 -43
View File
@@ -1,59 +1,35 @@
<script lang="ts">
import { onMount } from 'svelte';
import { FormItem } from '.';
import TextCounter from './textCounter.svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let value = '';
export let autofocus = true;
let element: HTMLInputElement;
let icon = 'info';
const pattern = String.raw`^[a-z0-9][a-z0-9\-]*$`;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
let error = false;
const handleInvalid = (event: Event) => {
const pattern = String.raw`^[a-z0-9][a-z0-9\-]*$`;
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.patternMismatch) {
icon = 'exclamation';
if (event.currentTarget.validity.patternMismatch) {
error = true;
return;
}
};
$: if (value) {
icon = 'info';
error = false;
}
</script>
<FormItem>
<div class="input-text-wrapper">
<input
id="id"
placeholder="Enter ID"
maxlength={36}
{pattern}
autocomplete="off"
type="text"
class="input-text"
bind:value
bind:this={element}
on:invalid={handleInvalid} />
<TextCounter count={value?.length ?? 0} max={36} />
</div>
</FormItem>
<div
class="u-flex u-gap-4 u-margin-block-start-8 u-small"
class:u-color-text-warning={icon === 'exclamation'}>
<span
class:icon-info={icon === 'info'}
class:icon-exclamation={icon === 'exclamation'}
class="u-cross-center u-line-height-1 u-color-text-gray"
aria-hidden="true" />
<span class="text u-line-height-1-5">
Allowed characters: lowercase alphanumeric and non-leading hyphen
</span>
</div>
<Input.Text
{pattern}
{autofocus}
id="id"
placeholder="Enter ID"
maxlength={36}
autocomplete="off"
bind:value
on:invalid={handleInvalid}
state={error ? 'error' : 'default'}
helper="Allowed characters: lowercase alphanumeric and non-leading hyphen" />
+20 -33
View File
@@ -1,5 +1,7 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { IconX } from '@appwrite.io/pink-icons-svelte';
import { Input } from '@appwrite.io/pink-svelte';
import { createEventDispatcher } from 'svelte';
import { onDestroy } from 'svelte';
export let value = '';
@@ -15,12 +17,6 @@
let element: HTMLInputElement;
let timer: ReturnType<typeof setTimeout>;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
onDestroy(() => {
value = '';
if (timer) {
@@ -28,14 +24,13 @@
}
});
function valueChange(event: Event) {
const valueChange = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
clearTimeout(timer);
timer = setTimeout(() => {
const target = event.target as HTMLInputElement;
value = target.value;
value = event.currentTarget.value;
dispatch('change', value);
}, debounce);
}
};
function clearSearch() {
value = '';
@@ -49,25 +44,17 @@
}
</script>
<div class="input-text-wrapper" class:is-with-end-button={isWithEndButton}>
<input
{placeholder}
{disabled}
{required}
{style}
type="search"
class="input-text"
bind:this={element}
on:input={valueChange} />
<span class="icon-search" aria-hidden="true" />
{#if isWithEndButton && value}
<button
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Clear search"
type="button"
on:click={clearSearch}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
</div>
<Input.Text
{placeholder}
{disabled}
{required}
{autofocus}
type="search"
bind:value
on:input={valueChange}>
<svelte:fragment slot="end">
{#if value}
<Input.Action icon={IconX} on:click={clearSearch} />
{/if}
</svelte:fragment>
</Input.Text>
+2 -39
View File
@@ -1,48 +1,11 @@
<script lang="ts">
import { FormItem, Label } from '.';
import { Input } from '@appwrite.io/pink-svelte';
export let id: string;
export let label: string;
export let showLabel = true;
export let value = '';
export let placeholder = '';
let showInPlainText = false;
</script>
<FormItem>
<Label hide={!showLabel} for={id}>
{label}
</Label>
<div class="input-text-wrapper" style=" --amount-of-buttons: 1;">
{#if showInPlainText}
<div
contenteditable="true"
role="textbox"
{id}
aria-placeholder={placeholder}
class="input-text is-resizable"
bind:textContent={value} />
{:else}
<input
{id}
{placeholder}
name={id}
type="password"
class="input-text"
autocomplete="off"
bind:value />
{/if}
<button
type="button"
on:click={() => (showInPlainText = !showInPlainText)}
class="show-password-button"
aria-label="show / hide password">
<span
class:icon-eye={!showInPlainText}
class:icon-eye-off={showInPlainText}
aria-hidden="true" />
</button>
</div>
</FormItem>
<Input.Password {id} {label} {value} {placeholder} readonly />
+2 -11
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import { FormItem, Helper } from '.';
import { Selector } from '@appwrite.io/pink-svelte';
export let label: string;
export let id: string;
@@ -23,17 +24,7 @@
<FormItem>
<label class="choice-item" for={id}>
<div class="input-text-wrapper">
<input
{id}
{disabled}
type="checkbox"
class="switch"
role="switch"
aria-checked={value}
bind:this={element}
bind:checked={value}
on:change
on:invalid={handleInvalid} />
<Selector.Switch {disabled} bind:checked={value} on:invalid={handleInvalid} />
</div>
<div class="choice-item-content">
<div class="choice-item-title">{label}</div>
+6 -11
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { SvelteComponent, onMount } from 'svelte';
import { SvelteComponent } from 'svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string = undefined;
@@ -36,15 +36,9 @@
error = event.currentTarget.validationMessage;
};
$: {
if (value) {
error = null;
}
$: if (value) {
error = null;
}
type $$Events = {
input: Event & { target: HTMLInputElement };
};
</script>
<Input.Text
@@ -56,9 +50,10 @@
{maxlength}
{label}
{nullable}
{autofocus}
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
helper={error}
state={error ? 'error' : 'default'}
on:invalid={handleInvalid}
on:input
autocomplete={autocomplete ? 'on' : 'off'}
bind:value />
+20 -66
View File
@@ -4,6 +4,7 @@
import NullCheckbox from './nullCheckbox.svelte';
import TextCounter from './textCounter.svelte';
import { clickOnEnter } from '$lib/helpers/a11y';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string;
export let showLabel = true;
@@ -20,82 +21,35 @@
export let optionalText: string | undefined = undefined;
export let tooltip: string = null;
let element: HTMLTextAreaElement;
let error: string;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLTextAreaElement }) => {
event.preventDefault();
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
error = null;
}
let prevValue = null;
function handleNullChange(e: CustomEvent<boolean>) {
const isNull = e.detail;
if (isNull) {
prevValue = value;
value = null;
} else {
value = prevValue;
}
}
$: showTextCounter = !!maxlength;
$: showNullCheckbox = nullable && !required;
</script>
<FormItem>
<Label {required} {tooltip} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
<div class="input-text-wrapper" on:click on:keyup={clickOnEnter} role="textbox" tabindex="-1">
<textarea
{id}
{name}
{placeholder}
{disabled}
{readonly}
{required}
{maxlength}
class="input-text"
class:u-padding-block-end-32={maxlength}
bind:value
bind:this={element}
on:invalid={handleInvalid}
style:--amount-of-buttons={maxlength ? 0.25 : required ? undefined : 0.25} />
{#if showTextCounter || showNullCheckbox}
<ul
class="buttons-list u-gap-8 u-cross-center u-position-absolute d u-inset-block-end-1 u-inset-inline-end-1 u-padding-block-8 u-padding-inline-12"
style="border-end-end-radius:0.0625rem;">
{#if showTextCounter}
<li class="buttons-list-item">
<TextCounter max={maxlength} count={value?.length ?? 0} />
</li>
{/if}
{#if showNullCheckbox}
<li class="buttons-list-item">
<NullCheckbox checked={value === null} on:change={handleNullChange} />
</li>
{/if}
</ul>
{/if}
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<Input.Textarea
{id}
{name}
{placeholder}
{disabled}
{readonly}
{required}
{maxlength}
{label}
{nullable}
autofocus={autofocus || undefined}
helper={error}
state={error ? 'error' : 'default'}
on:invalid={handleInvalid}
on:input
bind:value />
+24 -61
View File
@@ -1,13 +1,12 @@
<script lang="ts">
import { onMount } from 'svelte';
import { FormItem, Helper, Label } from '.';
import NullCheckbox from './nullCheckbox.svelte';
import TextCounter from './textCounter.svelte';
import { Input } from '@appwrite.io/pink-svelte';
export let label: string;
export let optionalText: string | undefined = undefined;
export let showLabel = true;
export let id: string;
export let name = id;
export let value = '';
export let placeholder = '';
export let required = false;
@@ -18,79 +17,43 @@
export let autocomplete = false;
export let maxlength: number = null;
let element: HTMLInputElement;
let error: string;
onMount(() => {
if (element && autofocus) {
element.focus();
}
});
const handleInvalid = (event: Event) => {
const handleInvalid = (event: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
event.preventDefault();
if (element.validity.patternMismatch) {
if (event.currentTarget.validity.patternMismatch) {
error = 'Must be a valid URL';
return;
}
if (element.validity.valueMissing) {
if (event.currentTarget.validity.valueMissing) {
error = 'This field is required';
return;
}
error = element.validationMessage;
error = event.currentTarget.validationMessage;
};
$: if (value) {
error = null;
}
let prevValue = '';
function handleNullChange(e: CustomEvent<boolean>) {
const isNull = e.detail;
if (isNull) {
prevValue = value;
value = null;
} else {
value = prevValue;
}
}
</script>
<FormItem>
<Label {required} {optionalText} hide={!showLabel} for={id}>
{label}
</Label>
<div class="input-text-wrapper">
<input
{id}
{placeholder}
{disabled}
{required}
{maxlength}
{readonly}
type="url"
autocomplete={autocomplete ? 'on' : 'off'}
bind:value
bind:this={element}
on:invalid={handleInvalid} />
<ul
class="buttons-list u-cross-center u-gap-8 u-position-absolute u-inset-block-start-8 u-inset-block-end-8 u-inset-inline-end-12">
{#if maxlength}
<li class="buttons-list-item">
<TextCounter max={maxlength} count={value?.length ?? 0} />
</li>
{/if}
{#if nullable && !required}
<li class="buttons-list-item">
<NullCheckbox checked={value === null} on:change={handleNullChange} />
</li>
{/if}
</ul>
</div>
{#if error}
<Helper type="warning">{error}</Helper>
{/if}
</FormItem>
<Input.Text
{id}
{name}
{placeholder}
{disabled}
{readonly}
{required}
{maxlength}
{label}
{nullable}
type="url"
autofocus={autofocus || undefined}
autocomplete={autocomplete ? 'on' : 'off'}
helper={error}
state={error ? 'error' : 'default'}
on:invalid={handleInvalid}
on:input
bind:value />
+4 -1
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { Layout } from '@appwrite.io/pink-svelte';
export let overlapCover = false;
export let size: 'small' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl' = null;
@@ -12,5 +13,7 @@
{style}
class:u-margin-block-start-24={!overlapCover}
class:u-margin-block-start-negative-56={overlapCover}>
<slot />
<Layout.Stack gap="xl">
<slot />
</Layout.Stack>
</div>
@@ -16,15 +16,6 @@
} from '$lib/components';
import { Pill } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import {
Table,
TableBody,
TableCell,
TableCellHead,
TableCellText,
TableHeader,
TableRowLink
} from '$lib/elements/table';
import { toLocaleDate, toLocaleDateTime } from '$lib/helpers/date';
import { Container, ContainerHeader } from '$lib/layout';
import type { Models } from '@appwrite.io/console';
@@ -32,6 +23,7 @@
import type { PageData } from './$types';
import Create from './createUser.svelte';
import { tooltip } from '$lib/actions/tooltip';
import { Table } from '@appwrite.io/pink-svelte';
export let data: PageData;
@@ -50,88 +42,87 @@
disabled: !isButtonDisabled
}}>
<Button
on:click={() => ($showCreateUser = true)}
on:mousedown={() => ($showCreateUser = true)}
event="create_user"
disabled={isButtonDisabled}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Create user</span>
</Button>
</div></SearchQuery>
</div>
</SearchQuery>
</ContainerHeader>
{#if data.users.total}
<Table>
<TableHeader>
<TableCellHead>Name</TableCellHead>
<TableCellHead onlyDesktop>Identifiers</TableCellHead>
<TableCellHead onlyDesktop width={130}>Status</TableCellHead>
<TableCellHead onlyDesktop width={100}>ID</TableCellHead>
<TableCellHead onlyDesktop width={100}>Labels</TableCellHead>
<TableCellHead onlyDesktop>Joined</TableCellHead>
<TableCellHead onlyDesktop>Last Activity</TableCellHead>
</TableHeader>
<TableBody>
{#each data.users.users as user}
<TableRowLink href={`${base}/project-${projectId}/auth/user-${user.$id}`}>
<TableCell title="Name">
<div class="u-flex u-gap-12 u-cross-center">
{#if user.email || user.phone}
{#if user.name}
<AvatarInitials size={32} name={user.name} />
<span class="text u-trim">{user.name}</span>
{:else}
<div class="avatar is-size-small">
<span class="icon-minus-sm" aria-hidden="true" />
</div>
{/if}
<Table.Root>
<svelte:fragment slot="header">
<Table.Header.Cell>Name</Table.Header.Cell>
<Table.Header.Cell onlyDesktop>Identifiers</Table.Header.Cell>
<Table.Header.Cell onlyDesktop width={130}>Status</Table.Header.Cell>
<Table.Header.Cell onlyDesktop width={100}>ID</Table.Header.Cell>
<Table.Header.Cell onlyDesktop width={100}>Labels</Table.Header.Cell>
<Table.Header.Cell onlyDesktop>Joined</Table.Header.Cell>
<Table.Header.Cell onlyDesktop>Last Activity</Table.Header.Cell>
</svelte:fragment>
{#each data.users.users as user}
<Table.Link href={`${base}/project-${projectId}/auth/user-${user.$id}`}>
<Table.Cell title="Name">
<div class="u-flex u-gap-12 u-cross-center">
{#if user.email || user.phone}
{#if user.name}
<AvatarInitials size={32} name={user.name} />
<span class="text u-trim">{user.name}</span>
{:else}
<div class="avatar is-size-small">
<span class="icon-anonymous" aria-hidden="true" />
<span class="icon-minus-sm" aria-hidden="true" />
</div>
<span class="text u-trim">{user.name}</span>
{/if}
</div>
</TableCell>
<TableCellText onlyDesktop title="Identifiers">
{user.email && user.phone
? [user.email, user.phone].join(',')
: user.email || user.phone}
</TableCellText>
<TableCell onlyDesktop title="Status">
{#if user.status}
<Pill success={user.emailVerification || user.phoneVerification}>
{user.emailVerification && user.phoneVerification
? 'verified'
: user.emailVerification
? 'verified email'
: user.phoneVerification
? 'verified phone'
: 'unverified'}
</Pill>
{:else}
<Pill danger>blocked</Pill>
<div class="avatar is-size-small">
<span class="icon-anonymous" aria-hidden="true" />
</div>
<span class="text u-trim">{user.name}</span>
{/if}
</TableCell>
<TableCell onlyDesktop showOverflow title="ID">
<Copy value={user.$id} event="user">
<Pill button>
<span class="icon-duplicate" aria-hidden="true" />
<span class="text">User ID</span>
</Pill>
</Copy>
</TableCell>
<TableCellText onlyDesktop title="Labels">
{user.labels.join(', ')}
</TableCellText>
<TableCellText onlyDesktop title="Joined">
{toLocaleDateTime(user.registration)}
</TableCellText>
<TableCellText onlyDesktop title="Last Activity">
{user.accessedAt ? toLocaleDate(user.accessedAt) : 'never'}
</TableCellText>
</TableRowLink>
{/each}
</TableBody>
</Table>
</div>
</Table.Cell>
<Table.Cell onlyDesktop title="Identifiers">
{user.email && user.phone
? [user.email, user.phone].join(',')
: user.email || user.phone}
</Table.Cell>
<Table.Cell onlyDesktop title="Status">
{#if user.status}
<Pill success={user.emailVerification || user.phoneVerification}>
{user.emailVerification && user.phoneVerification
? 'verified'
: user.emailVerification
? 'verified email'
: user.phoneVerification
? 'verified phone'
: 'unverified'}
</Pill>
{:else}
<Pill danger>blocked</Pill>
{/if}
</Table.Cell>
<Table.Cell onlyDesktop showOverflow title="ID">
<Copy value={user.$id} event="user">
<Pill button>
<span class="icon-duplicate" aria-hidden="true" />
<span class="text">User ID</span>
</Pill>
</Copy>
</Table.Cell>
<Table.Cell onlyDesktop title="Labels">
{user.labels.join(', ')}
</Table.Cell>
<Table.Cell onlyDesktop title="Joined">
{toLocaleDateTime(user.registration)}
</Table.Cell>
<Table.Cell onlyDesktop title="Last Activity">
{user.accessedAt ? toLocaleDate(user.accessedAt) : 'never'}
</Table.Cell>
</Table.Link>
{/each}
</Table.Root>
<PaginationWithLimit
name="Users"
@@ -151,7 +142,7 @@
single
href="https://appwrite.io/docs/references/cloud/server-nodejs/users"
target="user"
on:click={() => showCreateUser.set(true)} />
on:mousedown={() => showCreateUser.set(true)} />
{/if}
</Container>
@@ -88,7 +88,7 @@
{/if}
</FormList>
<svelte:fragment slot="footer">
<Button text on:click={() => (showCreate = false)}>Cancel</Button>
<Button text on:mousedown={() => (showCreate = false)}>Cancel</Button>
<Button submit>Create</Button>
</svelte:fragment>
</Modal>
@@ -97,12 +97,8 @@
offset={data.offset}
total={data.teams.total} />
{:else if data.search}
<EmptySearch>
<div class="u-text-center">
<b>Sorry, we couldn't find {data.search}'</b>
<p>There are no teams that match your search.</p>
</div>
<Button secondary href={`${base}/project-${$page.params.project}/auth/teams`}>
<EmptySearch target="teams" search={data.search} hidePagination={data.teams.total === 0}>
<Button secondary size="small" href={`${base}/project-${$page.params.project}/auth/teams`}>
Clear Search
</Button>
</EmptySearch>
@@ -130,9 +130,6 @@
</svelte:fragment>
<svelte:fragment slot="actions">
<Button text={$user.status} secondary={!$user.status} on:click={() => updateStatus()}>
{$user.status ? 'Block account' : 'Unblock account'}
</Button>
{#if $user.status}
{#if $user.phone && $user.email}
<DropList bind:show={showVerifcationDropdown} placement="top-start">
@@ -161,5 +158,8 @@
</Button>
{/if}
{/if}
<Button text={$user.status} secondary={!$user.status} on:click={() => updateStatus()}>
{$user.status ? 'Block account' : 'Unblock account'}
</Button>
</svelte:fragment>
</CardGrid>