Merge 'main' in feat-blog-pagination, fix conflicts.

This commit is contained in:
ItzNotABug
2024-08-29 17:48:12 +05:30
329 changed files with 8027 additions and 7685 deletions

View File

@@ -2,7 +2,7 @@ name: Mark stale issues
on:
schedule:
- cron: "0 0 * * *" # Midnight Runtime
- cron: '0 0 * * *' # Midnight Runtime
jobs:
stale:
@@ -13,11 +13,11 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue has been labeled as a 'question', indicating that it requires additional information from the requestor. It has been inactive for 7 days. If no further activity occurs, this issue will be closed in 14 days."
stale-issue-label: "stale"
stale-issue-label: 'stale'
days-before-stale: 7
days-before-close: 14
remove-stale-when-updated: true
close-issue-message: "This issue has been closed due to inactivity. If you still require assistance, please provide the requested information."
close-issue-reason: "not_planned"
close-issue-message: 'This issue has been closed due to inactivity. If you still require assistance, please provide the requested information.'
close-issue-reason: 'not_planned'
operations-per-run: 100
only-labels: "question"
only-labels: 'question'

View File

@@ -7,5 +7,3 @@
tasks:
- init: pnpm install && pnpm run build
command: pnpm run dev

View File

@@ -4,7 +4,7 @@
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

View File

@@ -129,14 +129,20 @@ Alternatively, use markdoc tables.
```md
{% table %}
* Heading 1
* Heading 2
- Heading 1
- Heading 2
---
* Row 1 Cell 1
* Row 1 Cell 2
- Row 1 Cell 1
- Row 1 Cell 2
---
* Row 2 Cell 1
* Row 2 cell 2
- Row 2 Cell 1
- Row 2 cell 2
{% /table %}
```
@@ -186,7 +192,9 @@ print('test');
</pre>
#### Sections
Use sections when there is a clear step-by-step format to a page. This is used mainly in journey pages and tutorials.
```md
{% section #featured-products-1 step=1 title="Title" %}
Lorem ipsum dolor sit amet consectetur.
@@ -243,6 +251,7 @@ Available sizes are `s`, `m`, `l` and `xl`. Default: `s`.
```
#### Cards
We use cards when we reference a list of links for navigation
```
@@ -268,6 +277,7 @@ Get started with Appwrite and SvelteKit
```
#### Cards with icons
We use cards when we reference a list of links for navigation, this variation has icons for extra hints visually.
```
@@ -285,6 +295,7 @@ Configure FCM for push notification to Android and Apple devices.
```
#### Accordions
Use accordions to reduce page size and collapse information that's not important when a reader is skilling the page.
```

View File

@@ -180,17 +180,23 @@ It should contain all the pages and headings with in them, maintainers may reque
```md
# page 1
## heading a
## heading b
...
# page 2
## heading a
## heading b
...
# page 3
## heading a
## heading b
...
...
```
@@ -283,9 +289,11 @@ Like sentences, important information always comes first.
This makes it easier to scan through the page.
✅ Clear, important information such as actions come first
> Store secrets as environment variables in vaults by navigating to **settings** > **security** > **vault**. Your secrets should never be shared. You must ensure data privacy, sharing secrets can compromise security during development.
❌ Unclear, important information is in the middle of the paragraph
> Security is important in development. That's why you should take care to protect secrets. Secrets should be safely stored as a environment variable in a vault. You can find vaults under **settings** > **security** > **vault**. Don't share this with anyone!
If there are multiple important actions or pieces of information, **break up the paragraph**.

View File

@@ -40,12 +40,15 @@
"@sveltejs/enhanced-img": "^0.1.9",
"@sveltejs/kit": "^2.5.17",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tailwindcss/postcss": "4.0.0-alpha.17",
"@types/compression": "^1.7.5",
"@types/glob": "^8.1.0",
"@types/markdown-it": "^13.0.8",
"@types/morgan": "^1.9.9",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"clsx": "^2.1.1",
"cva": "npm:class-variance-authority@^0.7.0",
"date-fns": "^3.6.0",
"dequal": "^2.0.3",
"embla-carousel": "^8.1.5",
@@ -62,8 +65,10 @@
"node-html-parser": "^6.1.13",
"openapi-types": "^12.1.3",
"oslllo-svg-fixer": "^3.0.0",
"prettier": "^3.3.2",
"postcss": "^8.4.39",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.6.5",
"remeda": "^2.10.0",
"sass": "^1.77.6",
"svelte": "^4.2.18",
@@ -71,6 +76,8 @@
"svelte-markdoc-preprocess": "^2.0.0",
"svelte-markdown": "^0.4.1",
"svgtofont": "^4.2.1",
"tailwind-merge": "^2.5.2",
"tailwindcss": "4.0.0-alpha.17",
"tslib": "^2.6.3",
"typescript": "^5.5.2",
"vite": "^5.3.1",

290
pnpm-lock.yaml generated
View File

@@ -54,6 +54,9 @@ importers:
'@sveltejs/vite-plugin-svelte':
specifier: ^3.1.1
version: 3.1.1(svelte@4.2.18)(vite@5.3.5(@types/node@22.1.0)(lightningcss@1.25.1)(sass@1.77.8))
'@tailwindcss/postcss':
specifier: 4.0.0-alpha.17
version: 4.0.0-alpha.17(postcss@8.4.39)
'@types/compression':
specifier: ^1.7.5
version: 1.7.5
@@ -72,6 +75,12 @@ importers:
'@typescript-eslint/parser':
specifier: ^7.13.1
version: 7.18.0(eslint@8.57.0)(typescript@5.5.4)
clsx:
specifier: ^2.1.1
version: 2.1.1
cva:
specifier: npm:class-variance-authority@^0.7.0
version: class-variance-authority@0.7.0
date-fns:
specifier: ^3.6.0
version: 3.6.0
@@ -120,12 +129,18 @@ importers:
oslllo-svg-fixer:
specifier: ^3.0.0
version: 3.0.0
postcss:
specifier: ^8.4.39
version: 8.4.39
prettier:
specifier: ^3.3.2
specifier: ^3.3.3
version: 3.3.3
prettier-plugin-svelte:
specifier: ^3.2.5
version: 3.2.6(prettier@3.3.3)(svelte@4.2.18)
prettier-plugin-tailwindcss:
specifier: ^0.6.5
version: 0.6.5(prettier-plugin-svelte@3.2.6(prettier@3.3.3)(svelte@4.2.18))(prettier@3.3.3)
remeda:
specifier: ^2.10.0
version: 2.10.0
@@ -137,7 +152,7 @@ importers:
version: 4.2.18
svelte-check:
specifier: ^3.8.1
version: 3.8.5(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.41))(postcss@8.4.41)(sass@1.77.8)(svelte@4.2.18)
version: 3.8.5(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.39))(postcss@8.4.39)(sass@1.77.8)(svelte@4.2.18)
svelte-markdoc-preprocess:
specifier: ^2.0.0
version: 2.0.0
@@ -147,6 +162,12 @@ importers:
svgtofont:
specifier: ^4.2.1
version: 4.2.2
tailwind-merge:
specifier: ^2.5.2
version: 2.5.2
tailwindcss:
specifier: 4.0.0-alpha.17
version: 4.0.0-alpha.17
tslib:
specifier: ^2.6.3
version: 2.6.3
@@ -1391,6 +1412,73 @@ packages:
'@swc/helpers@0.5.12':
resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==}
'@tailwindcss/oxide-android-arm64@4.0.0-alpha.17':
resolution: {integrity: sha512-IBOd4/iQW8tq8YJJgoEECy+wVPnJcAx/kwS45uKTbq5GVK9l8siBEnTiJ7VPnuoo2vQfLlJjshA7ar8nMX589w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [android]
'@tailwindcss/oxide-darwin-arm64@4.0.0-alpha.17':
resolution: {integrity: sha512-JiV0oe6QmeL/6dDQkk12H+sa/BmH4p7KbaW2/PPOTfFVZjIbM9Qj3drsFwWRuwPTI9mSpJQFxWtdbMYarLVK1w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.0.0-alpha.17':
resolution: {integrity: sha512-39zvOSxFfiVcQQp1/4dD5kMH6bwKagRO2PLLmlH6EAM7LuIyVsKJwFK5Z+ZYTLoG3hUGUxvCPOjgbqMYvRLJ3w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.0.0-alpha.17':
resolution: {integrity: sha512-KplmR3Md+B5W0ocH4N3ArLowABlKHKqV6mImURrGriqDhwfVeJyarugx+Uo811D2qSYTqLkQXW7u0esIxBM69w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-alpha.17':
resolution: {integrity: sha512-2GZ91U2fkqY9ohaPiQr1UJt0yAaZq7/5tFXvtRUY72PDYfz1PlnvxyDlQ16roepxi+Si52svLmzm7E9g4kVz/g==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.0.0-alpha.17':
resolution: {integrity: sha512-11do1KeInnJo7vVJgI2bTJ3YHQ6jirbJB4KcfHS1sn9ArKUFJrgk+32QQGj+Gv39krgzSReNb84Xr+Oi6iCcyA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.0.0-alpha.17':
resolution: {integrity: sha512-qB0XX8iGafq7IJa7yDPVaDLQC2QhjtMgXgKggpgxjtLaSQDVJ53hHmmjglgLSghlHpZ0+mNfQDT8EOzRdhvj7Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.0.0-alpha.17':
resolution: {integrity: sha512-iTsqmqxdcrLf77SagBIygip656YLEtl2wO5VMoeK3omYviM/ipNH2Vu5HZ6fB/qotX9gVzyz4iQovFAWvp6Azg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.0.0-alpha.17':
resolution: {integrity: sha512-2bHxD8yXy36dpIFUbDW7LRDKYpZXRcOC0PTVukobmkp+F0p8rEnTcI36DPLGEA8W3+FDIKbGQM4aMb1r/BbGZg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@tailwindcss/oxide-win32-x64-msvc@4.0.0-alpha.17':
resolution: {integrity: sha512-qNFwdHYQoJDfObko0WyutVrFPoaZB5pVkJ6FlR7M/0ylLvx/BR7kfyWZYmivi3DGXZmm4eMFLLYZjBjLHWbvUg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@tailwindcss/oxide@4.0.0-alpha.17':
resolution: {integrity: sha512-5FciVkCRpYRsVRyu8+ldiiOxGgXDJQLMzd5fjPCt7JZWhSZjS/QkXQdBc41Bcice3sgxTtKpKA4ef3sEcOfG/A==}
engines: {node: '>= 10'}
'@tailwindcss/postcss@4.0.0-alpha.17':
resolution: {integrity: sha512-N0DQOSy+5c1/JkKt1yPja5Kb0QqpkYFFEcV5SK+Cnko+ncsDYOesEfIm00qAtb/9S9SWy5PGNHP7s0U21pWGyA==}
'@tokenizer/token@0.3.0':
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
@@ -1840,6 +1928,9 @@ packages:
cjs-module-lexer@1.3.1:
resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==}
class-variance-authority@0.7.0:
resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==}
clean-stack@2.2.0:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
@@ -1855,6 +1946,14 @@ packages:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
clsx@2.0.0:
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
engines: {node: '>=6'}
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
code-red@1.0.4:
resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
@@ -3238,6 +3337,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
@@ -3266,6 +3369,12 @@ packages:
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
engines: {node: '>=4.0.0'}
postcss-import@16.1.0:
resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==}
engines: {node: '>=18.0.0'}
peerDependencies:
postcss: ^8.0.0
postcss-load-config@3.1.4:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
@@ -3306,6 +3415,13 @@ packages:
resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==}
engines: {node: '>=4'}
postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
postcss@8.4.39:
resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
engines: {node: ^10 || ^12 || >=14}
postcss@8.4.41:
resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==}
engines: {node: ^10 || ^12 || >=14}
@@ -3336,6 +3452,58 @@ packages:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
prettier-plugin-tailwindcss@0.6.5:
resolution: {integrity: sha512-axfeOArc/RiGHjOIy9HytehlC0ZLeMaqY09mm8YCkMzznKiDkwFzOpBvtuhuv3xG5qB73+Mj7OCe2j/L1ryfuQ==}
engines: {node: '>=14.21.3'}
peerDependencies:
'@ianvs/prettier-plugin-sort-imports': '*'
'@prettier/plugin-pug': '*'
'@shopify/prettier-plugin-liquid': '*'
'@trivago/prettier-plugin-sort-imports': '*'
'@zackad/prettier-plugin-twig-melody': '*'
prettier: ^3.0
prettier-plugin-astro: '*'
prettier-plugin-css-order: '*'
prettier-plugin-import-sort: '*'
prettier-plugin-jsdoc: '*'
prettier-plugin-marko: '*'
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-pug':
optional: true
'@shopify/prettier-plugin-liquid':
optional: true
'@trivago/prettier-plugin-sort-imports':
optional: true
'@zackad/prettier-plugin-twig-melody':
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-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.3.3:
resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
engines: {node: '>=14'}
@@ -3397,6 +3565,9 @@ packages:
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
@@ -3768,6 +3939,12 @@ packages:
tabbable@6.2.0:
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
tailwind-merge@2.5.2:
resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==}
tailwindcss@4.0.0-alpha.17:
resolution: {integrity: sha512-wWr6kvH40Hp1LQVcD738ojwU6+muJnpIUZw3J2EqjOdqHpg3iUIkrrQszP5HP4nwi4qBsoCoHPWVJ3Qw4f1IZw==}
tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
@@ -5574,6 +5751,58 @@ snapshots:
dependencies:
tslib: 2.6.3
'@tailwindcss/oxide-android-arm64@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-darwin-arm64@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-darwin-x64@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-freebsd-x64@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-linux-x64-musl@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.0.0-alpha.17':
optional: true
'@tailwindcss/oxide@4.0.0-alpha.17':
optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.0.0-alpha.17
'@tailwindcss/oxide-darwin-arm64': 4.0.0-alpha.17
'@tailwindcss/oxide-darwin-x64': 4.0.0-alpha.17
'@tailwindcss/oxide-freebsd-x64': 4.0.0-alpha.17
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.0-alpha.17
'@tailwindcss/oxide-linux-arm64-gnu': 4.0.0-alpha.17
'@tailwindcss/oxide-linux-arm64-musl': 4.0.0-alpha.17
'@tailwindcss/oxide-linux-x64-gnu': 4.0.0-alpha.17
'@tailwindcss/oxide-linux-x64-musl': 4.0.0-alpha.17
'@tailwindcss/oxide-win32-x64-msvc': 4.0.0-alpha.17
'@tailwindcss/postcss@4.0.0-alpha.17(postcss@8.4.39)':
dependencies:
'@tailwindcss/oxide': 4.0.0-alpha.17
lightningcss: 1.25.1
postcss-import: 16.1.0(postcss@8.4.39)
tailwindcss: 4.0.0-alpha.17
transitivePeerDependencies:
- postcss
'@tokenizer/token@0.3.0': {}
'@tootallnate/once@2.0.0': {}
@@ -6108,6 +6337,10 @@ snapshots:
cjs-module-lexer@1.3.1: {}
class-variance-authority@0.7.0:
dependencies:
clsx: 2.0.0
clean-stack@2.2.0: {}
cli-progress@3.12.0:
@@ -6126,6 +6359,10 @@ snapshots:
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
clsx@2.0.0: {}
clsx@2.1.1: {}
code-red@1.0.4:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
@@ -6283,8 +6520,7 @@ snapshots:
detect-indent@6.1.0: {}
detect-libc@1.0.3:
optional: true
detect-libc@1.0.3: {}
detect-libc@2.0.3: {}
@@ -7098,7 +7334,6 @@ snapshots:
lightningcss-linux-x64-gnu: 1.25.1
lightningcss-linux-x64-musl: 1.25.1
lightningcss-win32-x64-msvc: 1.25.1
optional: true
lilconfig@2.1.0: {}
@@ -7596,6 +7831,8 @@ snapshots:
picomatch@2.3.1: {}
pify@2.3.0: {}
pirates@4.0.6: {}
piscina@4.6.1:
@@ -7622,6 +7859,13 @@ snapshots:
pngjs@3.4.0: {}
postcss-import@16.1.0(postcss@8.4.39):
dependencies:
postcss: 8.4.39
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.8
postcss-load-config@3.1.4(postcss@8.4.41):
dependencies:
lilconfig: 2.1.0
@@ -7629,12 +7873,12 @@ snapshots:
optionalDependencies:
postcss: 8.4.41
postcss-load-config@4.0.2(postcss@8.4.41):
postcss-load-config@4.0.2(postcss@8.4.39):
dependencies:
lilconfig: 3.1.2
yaml: 2.5.0
optionalDependencies:
postcss: 8.4.41
postcss: 8.4.39
optional: true
postcss-safe-parser@6.0.0(postcss@8.4.41):
@@ -7650,6 +7894,14 @@ snapshots:
cssesc: 3.0.0
util-deprecate: 1.0.2
postcss-value-parser@4.2.0: {}
postcss@8.4.39:
dependencies:
nanoid: 3.3.7
picocolors: 1.0.1
source-map-js: 1.2.0
postcss@8.4.41:
dependencies:
nanoid: 3.3.7
@@ -7673,6 +7925,12 @@ snapshots:
prettier: 3.3.3
svelte: 4.2.18
prettier-plugin-tailwindcss@0.6.5(prettier-plugin-svelte@3.2.6(prettier@3.3.3)(svelte@4.2.18))(prettier@3.3.3):
dependencies:
prettier: 3.3.3
optionalDependencies:
prettier-plugin-svelte: 3.2.6(prettier@3.3.3)(svelte@4.2.18)
prettier@3.3.3: {}
pretty-format@29.7.0:
@@ -7715,6 +7973,10 @@ snapshots:
react-is@18.3.1: {}
read-cache@1.0.0:
dependencies:
pify: 2.3.0
readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
@@ -8018,14 +8280,14 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
svelte-check@3.8.5(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.41))(postcss@8.4.41)(sass@1.77.8)(svelte@4.2.18):
svelte-check@3.8.5(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.39))(postcss@8.4.39)(sass@1.77.8)(svelte@4.2.18):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 3.6.0
picocolors: 1.0.1
sade: 1.8.1
svelte: 4.2.18
svelte-preprocess: 5.1.4(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.41))(postcss@8.4.41)(sass@1.77.8)(svelte@4.2.18)(typescript@5.5.4)
svelte-preprocess: 5.1.4(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.39))(postcss@8.4.39)(sass@1.77.8)(svelte@4.2.18)(typescript@5.5.4)
typescript: 5.5.4
transitivePeerDependencies:
- '@babel/core'
@@ -8074,7 +8336,7 @@ snapshots:
dependencies:
svelte: 4.2.18
svelte-preprocess@5.1.4(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.41))(postcss@8.4.41)(sass@1.77.8)(svelte@4.2.18)(typescript@5.5.4):
svelte-preprocess@5.1.4(@babel/core@7.25.2)(postcss-load-config@4.0.2(postcss@8.4.39))(postcss@8.4.39)(sass@1.77.8)(svelte@4.2.18)(typescript@5.5.4):
dependencies:
'@types/pug': 2.0.10
detect-indent: 6.1.0
@@ -8084,8 +8346,8 @@ snapshots:
svelte: 4.2.18
optionalDependencies:
'@babel/core': 7.25.2
postcss: 8.4.41
postcss-load-config: 4.0.2(postcss@8.4.41)
postcss: 8.4.39
postcss-load-config: 4.0.2(postcss@8.4.39)
sass: 1.77.8
typescript: 5.5.4
@@ -8162,6 +8424,10 @@ snapshots:
tabbable@6.2.0: {}
tailwind-merge@2.5.2: {}
tailwindcss@4.0.0-alpha.17: {}
tar@6.2.1:
dependencies:
chownr: 2.0.0

5
postcss.config.js Normal file
View File

@@ -0,0 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {}
}
};

View File

@@ -4,11 +4,13 @@ const perPage = 100;
const outputFile = `./src/lib/contributors.ts`;
const headers = process.env.GITHUB_TOKEN ? {
const headers = process.env.GITHUB_TOKEN
? {
Authorization: `token ${process.env.GITHUB_TOKEN}`
} : {}
}
: {};
console.log(`using github token: ${!!process.env.GITHUB_TOKEN}`)
console.log(`using github token: ${!!process.env.GITHUB_TOKEN}`);
async function fetchRepositories() {
let page = 1;

124
src/app.css Normal file
View File

@@ -0,0 +1,124 @@
@import 'tailwindcss';
@theme {
/* Colors */
--color-*: initial;
/* base */
--color-primary: hsl(var(--color-primary));
--color-secondary: hsl(var(--color-secondary));
--color-accent: var(--color-secondary);
/* pink */
--color-pink-200: hsl(var(--color-pink-hue) 98% 84%);
--color-pink-500: hsl(var(--color-pink-hue) 98% 60%);
--color-pink-600: hsl(var(--color-pink-hue) 65% 48%);
--color-pink-700: hsl(var(--color-pink-hue) 65% 36%);
/* red */
--color-red-200: calc(hsl(var(--color-red-hue) - 2) 100% 92%);
--color-red-500: hsl(var(--color-red-hue) 100% 61%);
--color-red-700: calc(hsl(var(--color-red-hue) - 3) 82% 39%);
/* orange */
--color-orange-200: hsl(var(--color-orange-hue) 100% 88%);
--color-orange-500: hsl(var(--color-orange-hue) 99% 70%);
--color-orange-700: hsl(var(--color-orange-hue) 42% 42%);
/* mint */
--color-mint-200: hsl(var(--color-mint-hue) 56% 88%);
--color-mint-500: calc(hsl(var(--color-mint-hue) + 1) 54% 69%);
--color-mint-700: calc(hsl(var(--color-mint-hue) + 2) 24% 41%);
/* purple */
--color-purple-200: hsl(var(--color-purple-hue) 100% 88%);
--color-purple-500: calc(hsl(var(--color-purple-hue) - 1) 99% 70%);
--color-purple-700: calc(hsl(var(--color-purple-hue) - 1) 42% 42%);
/* yellow */
--color-yellow-200: hsl(var(--color-yellow-hue) 100% 88%);
--color-yellow-500: hsl(var(--color-yellow-hue) 99% 70%);
--color-yellow-700: calc(hsl(var(--color-yellow-hue) + 1) 42% 42%);
/* blue */
--color-blue-200: hsl(var(--color-blue-hue) 100% 88%);
--color-blue-500: calc(hsl(var(--color-blue-hue) - 1) 99% 70%);
--color-blue-700: calc(hsl(var(--color-blue-hue) - 1) 42% 42%);
/* secondary */
--color-secondary-100: hsl(var(--color-secondary-hue) 99% 66%);
/* greyscale */
--color-white: hsl(0 0% 100%);
--color-black: hsl(0 0% 0%);
--color-transparent: rgba(0, 0, 0, 0);
--color-greyscale-25: hsl(var(--color-greyscale-hue) 11% 98%);
--color-greyscale-50: hsl(var(--color-greyscale-hue) 11% 94%);
--color-greyscale-100: hsl(var(--color-greyscale-hue) 6% 90%);
--color-greyscale-200: hsl(var(--color-greyscale-hue) 4% 85%);
--color-greyscale-250: hsl(var(--color-greyscale-hue) 3% 77%);
--color-greyscale-300: hsl(var(--color-greyscale-hue) 2% 68%);
--color-greyscale-400: hsl(var(--color-greyscale-hue) 2% 60%);
--color-greyscale-500: hsl(var(--color-greyscale-hue) 2% 52%);
--color-greyscale-600: hsl(var(--color-greyscale-hue) 2% 43%);
--color-greyscale-700: hsl(var(--color-greyscale-hue) 3% 35%);
--color-greyscale-750: hsl(var(--color-greyscale-hue) 4% 26%);
--color-greyscale-800: hsl(var(--color-greyscale-hue) 4% 18%);
--color-greyscale-850: hsl(var(--color-greyscale-hue) 3% 14%);
--color-greyscale-900: hsl(var(--color-greyscale-hue) 5.7% 10.4%);
/* Animations */
--animate-scale-in: scale-in 200ms ease-out forwards;
/* Pink polyfills */
--transition: 0.2s;
/* Keyframes */
@keyframes scale-in {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
/* Fonts */
--font-family-sans: 'Inter', arial, sans-serif;
--font-family-mono: 'Fira Code', monospace;
--font-family-aeonik-fono: 'Aenoik Fono', monospace;
--font-family-aeonik-pro: 'Aeonik Pro', var(--font-family-sans);
--font-family-archia: 'Archia', arial, sans-serif;
}
/* Themes */
:root,
.light {
--color-pink-hue: 343;
--color-secondary-hue: 351;
--color-red-hue: 3;
--color-orange-hue: 18;
--color-mint-hue: 177;
--color-purple-hue: 249;
--color-yellow-hue: 42;
--color-blue-hue: 217;
--color-greyscale-hue: 240;
/* base */
--color-primary: var(--color-greyscale-900);
--color-secondary: var(--color-greyscale-700);
--color-accent: var(--color-pink-600);
}
/* dark theme */
.dark {
--color-primary: var(--color-greyscale-100);
--color-secondary: var(--color-greyscale-300);
}
/* Container */
@layer components {
.container {
@apply mx-auto box-content max-w-[75rem] px-8;
}
}

View File

@@ -17,22 +17,22 @@
%sveltekit.head%
</head>
<body class="theme-dark" data-sveltekit-preload-data="hover">
<body class="dark theme-dark group/body" data-sveltekit-preload-data="hover">
<script>
// Theme
const isDocs = window.location.pathname.startsWith('/docs');
if (isDocs) {
const theme = localStorage.getItem('theme');
if (theme) {
document.body.classList.remove('theme-dark', 'theme-light');
document.body.classList.remove('dark', 'light');
if (theme === 'system') {
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)')
.matches
? 'dark'
: 'light';
document.body.classList.add(`theme-${systemTheme}`);
document.body.classList.add(`${systemTheme}`);
} else {
document.body.classList.add(`theme-${theme}`);
document.body.classList.add(`${theme}`);
// Color scheme in html
document.documentElement.style.setProperty('color-scheme', theme);
}

View File

@@ -18,11 +18,13 @@ Sentry.init({
replaysOnErrorSampleRate: 1.0,
// If you don't want to use Session Replay, just remove the line below:
integrations: [replayIntegration({
integrations: [
replayIntegration({
maskAllInputs: true,
maskAllText: false,
blockAllMedia: false,
})]
blockAllMedia: false
})
]
});
// If you have a custom error handler, pass it to `handleErrorWithSentry`

View File

@@ -10,7 +10,7 @@ Sentry.init({
dsn: SENTRY_DSN,
tracesSampleRate: 1,
allowUrls: [/appwrite\.io/]
})
});
const redirectMap = new Map(redirects.map(({ link, redirect }) => [link, redirect]));

View File

@@ -1,3 +1,3 @@
import { generateIcons } from "./scripts.js";
import { generateIcons } from './scripts.js';
generateIcons();

View File

@@ -1 +0,0 @@
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M12.467 11.058 C 12.375 11.089,12.180 11.176,12.033 11.252 C 11.646 11.454,4.391 18.744,4.191 19.133 C 3.977 19.550,3.974 20.303,4.186 20.735 C 4.293 20.953,5.393 22.094,8.150 24.846 C 11.945 28.635,11.969 28.657,12.359 28.769 C 12.842 28.908,13.335 28.876,13.737 28.680 C 13.954 28.575,16.126 26.443,21.866 20.702 L 29.699 12.868 28.966 12.129 C 28.531 11.691,28.101 11.322,27.908 11.223 C 27.463 10.994,26.981 10.953,26.491 11.101 C 26.102 11.219,26.069 11.251,18.211 19.093 L 10.322 26.967 11.189 25.233 L 12.056 23.500 10.278 21.716 L 8.501 19.933 10.717 17.717 L 12.933 15.501 14.700 17.267 L 16.467 19.033 17.783 17.716 L 19.099 16.400 16.566 13.866 C 14.733 12.032,13.950 11.293,13.733 11.191 C 13.410 11.039,12.740 10.968,12.467 11.058 M28.844 14.711 L 27.989 16.422 29.761 18.195 L 31.533 19.967 28.532 22.967 C 26.392 25.105,25.489 26.053,25.385 26.266 C 25.191 26.665,25.188 27.313,25.379 27.739 C 25.681 28.413,26.326 28.829,27.067 28.829 C 27.884 28.829,27.776 28.919,31.907 24.780 C 36.005 20.674,35.947 20.743,35.953 19.967 C 35.959 19.197,35.961 19.199,32.715 15.950 C 31.094 14.327,29.752 13.000,29.733 13.000 C 29.714 13.000,29.314 13.770,28.844 14.711 " stroke="none" fill-rule="evenodd" fill="black"></path></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,15 +1,18 @@
@font-face {
font-family: "web-icon";
font-family: 'web-icon';
font-display: swap;
src: url('web-icon.eot'); /* IE9*/
src: url('web-icon.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
url("web-icon.woff2") format("woff2"),
url("web-icon.woff") format("woff"),
url('web-icon.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('web-icon.svg#web-icon') format('svg'); /* iOS 4.1- */
src:
url('web-icon.eot#iefix') format('embedded-opentype'),
/* IE6-IE8 */ url('web-icon.woff2') format('woff2'),
url('web-icon.woff') format('woff'),
url('web-icon.ttf') format('truetype'),
/* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('web-icon.svg#web-icon')
format('svg'); /* iOS 4.1- */
}
[class^="web-icon-"], [class*=" web-icon-"] {
[class^='web-icon-'],
[class*=' web-icon-'] {
font-family: 'web-icon' !important;
font-size: 20px;
font-style: normal;
@@ -17,55 +20,159 @@
-moz-osx-font-smoothing: grayscale;
}
.web-icon-apple:before { content: "\ea01"; }
.web-icon-appwrite:before { content: "\ea02"; }
.web-icon-arrow-down:before { content: "\ea03"; }
.web-icon-arrow-ext-link:before { content: "\ea04"; }
.web-icon-arrow-left:before { content: "\ea05"; }
.web-icon-arrow-right:before { content: "\ea06"; }
.web-icon-arrow-up:before { content: "\ea07"; }
.web-icon-calendar:before { content: "\ea08"; }
.web-icon-check:before { content: "\ea09"; }
.web-icon-chevron-down:before { content: "\ea0a"; }
.web-icon-chevron-left:before { content: "\ea0b"; }
.web-icon-chevron-right:before { content: "\ea0c"; }
.web-icon-chevron-up:before { content: "\ea0d"; }
.web-icon-close:before { content: "\ea0e"; }
.web-icon-command:before { content: "\ea0f"; }
.web-icon-copy:before { content: "\ea10"; }
.web-icon-daily-dev:before { content: "\ea11"; }
.web-icon-dark:before { content: "\ea12"; }
.web-icon-discord:before { content: "\ea13"; }
.web-icon-divider-vertical:before { content: "\ea14"; }
.web-icon-download:before { content: "\ea15"; }
.web-icon-ext-link:before { content: "\ea16"; }
.web-icon-firebase:before { content: "\ea17"; }
.web-icon-github:before { content: "\ea18"; }
.web-icon-google:before { content: "\ea19"; }
.web-icon-hamburger-menu:before { content: "\ea1a"; }
.web-icon-light:before { content: "\ea1b"; }
.web-icon-linkedin:before { content: "\ea1c"; }
.web-icon-location:before { content: "\ea1d"; }
.web-icon-logout-left:before { content: "\ea1e"; }
.web-icon-logout-right:before { content: "\ea1f"; }
.web-icon-mailgun:before { content: "\ea20"; }
.web-icon-message:before { content: "\ea21"; }
.web-icon-microsoft:before { content: "\ea22"; }
.web-icon-minus:before { content: "\ea23"; }
.web-icon-nuxt:before { content: "\ea24"; }
.web-icon-platform:before { content: "\ea25"; }
.web-icon-play:before { content: "\ea26"; }
.web-icon-plus:before { content: "\ea27"; }
.web-icon-product-hunt:before { content: "\ea28"; }
.web-icon-refine:before { content: "\ea29"; }
.web-icon-rest:before { content: "\ea2a"; }
.web-icon-search:before { content: "\ea2b"; }
.web-icon-sendgrid:before { content: "\ea2c"; }
.web-icon-star:before { content: "\ea2d"; }
.web-icon-system:before { content: "\ea2e"; }
.web-icon-textmagic:before { content: "\ea2f"; }
.web-icon-twitter:before { content: "\ea30"; }
.web-icon-vue:before { content: "\ea31"; }
.web-icon-x:before { content: "\ea32"; }
.web-icon-ycombinator:before { content: "\ea33"; }
.web-icon-youtube:before { content: "\ea34"; }
.web-icon-apple:before {
content: '\ea01';
}
.web-icon-appwrite:before {
content: '\ea02';
}
.web-icon-arrow-down:before {
content: '\ea03';
}
.web-icon-arrow-ext-link:before {
content: '\ea04';
}
.web-icon-arrow-left:before {
content: '\ea05';
}
.web-icon-arrow-right:before {
content: '\ea06';
}
.web-icon-arrow-up:before {
content: '\ea07';
}
.web-icon-calendar:before {
content: '\ea08';
}
.web-icon-check:before {
content: '\ea09';
}
.web-icon-chevron-down:before {
content: '\ea0a';
}
.web-icon-chevron-left:before {
content: '\ea0b';
}
.web-icon-chevron-right:before {
content: '\ea0c';
}
.web-icon-chevron-up:before {
content: '\ea0d';
}
.web-icon-close:before {
content: '\ea0e';
}
.web-icon-command:before {
content: '\ea0f';
}
.web-icon-copy:before {
content: '\ea10';
}
.web-icon-daily-dev:before {
content: '\ea11';
}
.web-icon-dark:before {
content: '\ea12';
}
.web-icon-discord:before {
content: '\ea13';
}
.web-icon-divider-vertical:before {
content: '\ea14';
}
.web-icon-download:before {
content: '\ea15';
}
.web-icon-ext-link:before {
content: '\ea16';
}
.web-icon-firebase:before {
content: '\ea17';
}
.web-icon-github:before {
content: '\ea18';
}
.web-icon-google:before {
content: '\ea19';
}
.web-icon-hamburger-menu:before {
content: '\ea1a';
}
.web-icon-light:before {
content: '\ea1b';
}
.web-icon-linkedin:before {
content: '\ea1c';
}
.web-icon-location:before {
content: '\ea1d';
}
.web-icon-logout-left:before {
content: '\ea1e';
}
.web-icon-logout-right:before {
content: '\ea1f';
}
.web-icon-mailgun:before {
content: '\ea20';
}
.web-icon-message:before {
content: '\ea21';
}
.web-icon-microsoft:before {
content: '\ea22';
}
.web-icon-minus:before {
content: '\ea23';
}
.web-icon-nuxt:before {
content: '\ea24';
}
.web-icon-platform:before {
content: '\ea25';
}
.web-icon-play:before {
content: '\ea26';
}
.web-icon-plus:before {
content: '\ea27';
}
.web-icon-product-hunt:before {
content: '\ea28';
}
.web-icon-refine:before {
content: '\ea29';
}
.web-icon-rest:before {
content: '\ea2a';
}
.web-icon-search:before {
content: '\ea2b';
}
.web-icon-sendgrid:before {
content: '\ea2c';
}
.web-icon-star:before {
content: '\ea2d';
}
.web-icon-system:before {
content: '\ea2e';
}
.web-icon-textmagic:before {
content: '\ea2f';
}
.web-icon-twitter:before {
content: '\ea30';
}
.web-icon-vue:before {
content: '\ea31';
}
.web-icon-x:before {
content: '\ea32';
}
.web-icon-ycombinator:before {
content: '\ea33';
}
.web-icon-youtube:before {
content: '\ea34';
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Logo/Dark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon" transform="translate(4.000000, 11.000000)" fill="#151618">
<g id="Secound" opacity="0.56" transform="translate(21.000000, 0.930000)">
<path d="M6.47910463,8.01371418 L2.94663391,4.48124347 L4.71194884,0.95 L10.4515234,6.68957458 C11.1828255,7.42087669 11.1828255,8.60655167 10.4515234,9.33785378 L3.38719562,16.4021816 C2.65589351,17.1334837 1.47021853,17.1334837 0.738916421,16.4021816 C0.00761431424,15.6708795 0.00761431424,14.4852045 0.738916421,13.7539024 L6.47910463,8.01371418 Z" id="Combined-Shape"></path>
</g>
<path d="M21.7402327,0.548323198 C22.4715349,-0.182978908 23.6575166,-0.182672097 24.3888188,0.54863001 L25.7132652,1.87307642 L10.2610836,17.325258 C9.52978147,18.0565601 8.34379968,18.0562533 7.61249757,17.3249512 L6.28805116,16.0005048 L21.7402327,0.548323198 Z M15.1176939,5.40493351 L12.4688011,8.05382633 L8.93633036,4.52135561 L4.52089537,8.9367906 L8.05336609,12.4692613 L6.28805116,16.0005048 L0.54847658,10.2609302 C-0.182825527,9.52962809 -0.182825527,8.34395311 0.54847658,7.612651 L7.61249757,0.54863001 C8.34379968,-0.182672097 9.52978147,-0.182978908 10.2610836,0.548323198 L15.1176939,5.40493351 Z" id="Main"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -16,9 +16,9 @@
<ul class="web-secondary-tabs {className}" use:melt={$list} {style}>
{#each tabs as tab}
<li class="web-secondary-tabs-item" class:u-stretch={stretch}>
<li class="web-secondary-tabs-item" class:flex-1={stretch}>
<button
class="web-secondary-tabs-button u-width-full-line"
class="web-secondary-tabs-button w-full"
class:is-selected={$value === tab}
use:melt={$trigger(tab)}
>

View File

@@ -4,7 +4,11 @@
import { animation, createScrollHandler, scroll, type Animation } from '.';
import { GITHUB_STARS } from '$lib/constants';
const springOptions: SpringOptions = { stiffness: 58.78, mass: 1, damping: 17.14 };
const springOptions: SpringOptions = {
stiffness: 58.78,
mass: 1,
damping: 17.14
};
const animationOptions: AnimationListOptions = {
x: { easing: spring(springOptions) },
y: { easing: spring(springOptions) }
@@ -172,84 +176,86 @@
}}
>
<div class="sticky-wrapper">
<h3 class="web-display web-u-color-text-primary">Powered by Open Source</h3>
<h3 class="web-display !text-primary">Powered by Open Source</h3>
<div class="cards-wrapper">
<a
href="/discord"
target="_blank"
rel="noopener noreferrer"
class="web-card is-white web-u-min-block-size-320 u-flex-vertical oss-card"
class="web-card is-white web-u-min-block-size-320 oss-card flex flex-col"
id="oss-discord"
>
<div class="u-flex-vertical u-main-space-between u-gap-32">
<div class="flex flex-col justify-between gap-8">
<span
class="web-icon-discord web-u-font-size-40"
aria-hidden="true"
aria-label="Discord"
/>
</div>
<div class="web-title u-margin-block-start-auto">17k+ Discord Members</div>
<div class="web-title mt-auto">17k+ Discord Members</div>
</a>
<a
class="web-card is-white web-u-min-block-size-320 u-flex-vertical oss-card"
class="web-card is-white web-u-min-block-size-320 oss-card flex flex-col"
id="oss-github"
href="https://github.com/appwrite/appwrite"
>
<div class="u-flex-vertical u-main-space-between u-gap-32">
<div class="flex flex-col justify-between gap-8">
<span
class="web-icon-github web-u-font-size-40"
aria-hidden="true"
aria-label="GitHub"
/>
</div>
<div class="web-title u-margin-block-start-auto">{GITHUB_STARS}+ GitHub Stars</div>
<div class="web-title mt-auto">
{GITHUB_STARS}+ GitHub Stars
</div>
</a>
<a
href="https://twitter.com/appwrite"
class="web-card is-white web-u-min-block-size-320 u-flex-vertical oss-card"
class="web-card is-white web-u-min-block-size-320 oss-card flex flex-col"
id="oss-twitter"
>
<div class="u-flex-vertical u-main-space-between u-gap-32">
<div class="flex flex-col justify-between gap-8">
<span
class="web-icon-x web-u-font-size-40"
aria-hidden="true"
aria-label="Twitter"
/>
</div>
<div class="web-title u-margin-block-start-auto">128k+ Twitter Followers</div>
<div class="web-title mt-auto">128k+ Twitter Followers</div>
</a>
<a
href="https://www.youtube.com/@Appwrite"
class="web-card is-white web-u-min-block-size-320 u-flex-vertical oss-card"
class="web-card is-white web-u-min-block-size-320 oss-card flex flex-col"
id="oss-youtube"
>
<div class="u-flex-vertical u-main-space-between u-gap-32">
<div class="flex flex-col justify-between gap-8">
<span
class="web-icon-youtube web-u-font-size-40"
aria-hidden="true"
aria-label="YouTube"
/>
</div>
<div class="web-title u-margin-block-start-auto">7k+ Youtube Subscribers</div>
<div class="web-title mt-auto">7k+ Youtube Subscribers</div>
</a>
<a
class="web-card is-white web-u-min-block-size-320 u-flex-vertical oss-card"
class="web-card is-white web-u-min-block-size-320 oss-card flex flex-col"
id="oss-commits"
href="https://github.com/appwrite/appwrite"
>
<div class="u-flex-vertical u-main-space-between u-gap-32">
<div class="flex flex-col justify-between gap-8">
<span
class="web-icon-github web-u-font-size-40"
aria-hidden="true"
aria-label="GitHub"
/>
</div>
<div class="web-title u-margin-block-start-auto">21k+ Code Commits</div>
<div class="web-title mt-auto">21k+ Code Commits</div>
</a>
</div>
</div>

View File

@@ -236,8 +236,9 @@
in:fly={{ duration: 250, delay: 250, y: -300 }}
>
{#if scrollInfo.percentage > -0.1}
<span class="web-badges web-eyebrow" transition:slide={{ axis: 'x' }}
>Products_</span
<span
class="web-badges web-eyebrow !text-white"
transition:slide={{ axis: 'x' }}>Products_</span
>
<h2
@@ -247,7 +248,7 @@
Your backend, minus the hassle
</h2>
<p
class="web-description web-u-max-width-700 u-margin-inline-auto"
class="web-description mx-auto max-w-[700px]"
transition:fly={{
y: 16,
delay: 400

View File

@@ -5,13 +5,11 @@
<div class="outside">
<div class="wrapper">
<span class="web-badges web-eyebrow">Products_</span>
<span class="web-badges web-eyebrow !text-white">Products_</span>
<h2 class="web-display web-u-color-text-primary u-margin-block-start-16">
Your backend, minus the hassle
</h2>
<h2 class="web-display web-u-color-text-primary mt-4">Your backend, minus the hassle</h2>
<p class="web-description u-margin-block-start-16">
<p class="web-description mt-4">
Build secure and scalable applications with less code. Add authentication, databases,
storage, and more using Appwrite's development platform.
</p>

View File

@@ -54,7 +54,7 @@
out:fly={{ duration: 100, x: -16 }}
animate:flip={{ duration: 150 }}
>
<div class="u-flex u-cross-center u-gap-12">
<div class="flex items-center gap-3">
<div class="avatar is-size-small">{user.avatar}</div>
<span class="truncated">{user.name}</span>
</div>

View File

@@ -9,7 +9,7 @@
$: controlsEnabled = $state.showControls && Object.values($state.controls).some(Boolean);
</script>
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<p class="title">Create an Account</p>
<p class="subtitle">Please enter your details</p>
<div class="inputs">
@@ -19,7 +19,12 @@
</fieldset>
<fieldset>
<label for="email">Your Email</label>
<input type="email" id="email" placeholder="Enter your email" bind:value={$state.email} />
<input
type="email"
id="email"
placeholder="Enter your email"
bind:value={$state.email}
/>
</fieldset>
<fieldset>
<label for="password">Create Password</label>
@@ -36,7 +41,11 @@
<span class="with-sep" transition:fade={{ duration: 100 }}>or sign up with</span>
<div class="oauth-btns" transition:fade={{ duration: 100 }}>
{#each objectKeys($state.controls).filter((p) => $state.controls[p]) as provider (provider)}
<button class="oauth" transition:fade={{ duration: 100 }} animate:flip={{ duration: 250 }}>
<button
class="oauth"
transition:fade={{ duration: 100 }}
animate:flip={{ duration: 250 }}
>
<div class="inner">
<span class="web-icon-{provider.toLowerCase()}" />
<span>{provider}</span>

View File

@@ -6,7 +6,7 @@
const { state } = databasesController;
</script>
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<div class="header">
<p class="title">Your tasks</p>
<span class="icon-menu" aria-label="menu" />

View File

@@ -30,7 +30,7 @@
].filter(Boolean) as Method[];
</script>
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<div class="header">
<p class="title">Upgrade plan</p>
<span class="icon-menu" aria-label="menu" />

View File

@@ -19,7 +19,7 @@
</div>
{/if}
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<div class="header">
<p class="title">Your tasks</p>
<span class="icon-menu" aria-label="menu" />

View File

@@ -16,26 +16,29 @@
</script>
<div class="gradient-box auth" id="post-auth-{$elId}">
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<p class="icon-user-group" />
<p class="f-eyebrow">Authentication</p>
</div>
<p class="f-display mbs-16">{formatK(toScale($authentication, [0, 1], [0, 4000]))}</p>
<div class="u-flex u-cross-center justify-between mbs-4">
<p class="f-display mbs-16">
{formatK(toScale($authentication, [0, 1], [0, 4000]))}
</p>
<div class="mbs-4 flex items-center justify-between">
<p class="f-sub">Users</p>
<p class="f-idk">Sessions: 20K</p>
</div>
</div>
<div class="gradient-box storage" id="post-storage-{$elId}">
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<p class="icon-folder" />
<p class="f-eyebrow">Storage</p>
</div>
<p class="f-display mbs-16">
{toScale($storage, [0, 1], [0, 8]).toFixed(1)} <span class="f-tiny-display">GB</span>
{toScale($storage, [0, 1], [0, 8]).toFixed(1)}
<span class="f-tiny-display">GB</span>
</p>
<div class="u-flex u-cross-center justify-between mbs-4">
<div class="mbs-4 flex items-center justify-between">
<p class="f-sub">Storage</p>
<p class="f-idk">Buckets: 44</p>
</div>
@@ -43,30 +46,35 @@
<div class="gradient-box bandwidth" id="post-bandwidth-{$elId}">
<p class="f-display">
{toScale($bandwidth, [0, 1], [0, 1.2]).toFixed(2)} <span class="f-tiny-display">GB</span>
{toScale($bandwidth, [0, 1], [0, 1.2]).toFixed(2)}
<span class="f-tiny-display">GB</span>
</p>
<p class="f-sub">Bandwidth</p>
<img class="mbs-16" src="./images/animations/bandwidth-graph.svg" alt="" />
</div>
<div class="gradient-box functions" id="post-functions-{$elId}">
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<p class="icon-lightning-bolt" />
<p class="f-eyebrow">Functions</p>
</div>
<p class="f-display mbs-16">{toScale($executions, [0, 1], [0, 846]).toFixed(0)}</p>
<div class="u-flex u-cross-center justify-between mbs-4">
<p class="f-display mbs-16">
{toScale($executions, [0, 1], [0, 846]).toFixed(0)}
</p>
<div class="mbs-4 flex items-center justify-between">
<p class="f-sub">Executions</p>
</div>
</div>
<div class="gradient-box databases" id="post-databases-{$elId}">
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<p class="icon-database" />
<p class="f-eyebrow">Databases</p>
</div>
<p class="f-display mbs-16">{toScale($databases, [0, 1], [0, 8]).toFixed(0)}</p>
<div class="u-flex u-cross-center justify-between mbs-4">
<p class="f-display mbs-16">
{toScale($databases, [0, 1], [0, 8]).toFixed(0)}
</p>
<div class="mbs-4 flex items-center justify-between">
<p class="f-sub">Databases</p>
<p class="f-idk">Documents: 20</p>
</div>
@@ -84,7 +92,7 @@
<img class="mbs-16" src="./images/animations/realtime-graph.svg" alt="" />
</div>
<div class="gradient-overlay u-flex u-flex-vertical">
<div class="gradient-overlay flex flex-col">
<h3>See your products grow</h3>
<p>
Keep track of your projects progress on the Appwrite Console and see them grow into products
@@ -171,9 +179,13 @@
position: absolute;
background: var(--card, rgba(35, 35, 37, 0.9));
box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.06), -2px 4px 9px 0px rgba(0, 0, 0, 0.06),
-8px 15px 17px 0px rgba(0, 0, 0, 0.05), -19px 34px 23px 0px rgba(0, 0, 0, 0.03),
-33px 60px 27px 0px rgba(0, 0, 0, 0.01), -52px 94px 30px 0px rgba(0, 0, 0, 0);
box-shadow:
0px 0px 0px 0px rgba(0, 0, 0, 0.06),
-2px 4px 9px 0px rgba(0, 0, 0, 0.06),
-8px 15px 17px 0px rgba(0, 0, 0, 0.05),
-19px 34px 23px 0px rgba(0, 0, 0, 0.03),
-33px 60px 27px 0px rgba(0, 0, 0, 0.01),
-52px 94px 30px 0px rgba(0, 0, 0, 0);
backdrop-filter: blur(8px);
padding: 1.5rem;
@@ -217,7 +229,6 @@
//filter: blur(125px); // break Safari
background: #19191dcc;
filter: blur(67px);
}
h3 {

View File

@@ -43,7 +43,7 @@
</script>
<div class="wrapper">
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<div class="header">
<div class="row">
<p class="title">My Team's tasks</p>
@@ -89,7 +89,11 @@
<span class="text">New Task</span>
</button>
{#each tasks as task (task.title)}
<div class="task" animate:flip={{ duration: 250 }} in:scale={{ delay: 150 }}>
<div
class="task"
animate:flip={{ duration: 250 }}
in:scale={{ delay: 150 }}
>
{#if task.images}
<ul class="flow gap-8">
{#each task.images as image}
@@ -609,9 +613,13 @@
bottom: -10rem;
background: var(--card, rgba(35, 35, 37, 0.9));
box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.06), -2px 4px 9px 0px rgba(0, 0, 0, 0.06),
-8px 15px 17px 0px rgba(0, 0, 0, 0.05), -19px 34px 23px 0px rgba(0, 0, 0, 0.03),
-33px 60px 27px 0px rgba(0, 0, 0, 0.01), -52px 94px 30px 0px rgba(0, 0, 0, 0);
box-shadow:
0px 0px 0px 0px rgba(0, 0, 0, 0.06),
-2px 4px 9px 0px rgba(0, 0, 0, 0.06),
-8px 15px 17px 0px rgba(0, 0, 0, 0.05),
-19px 34px 23px 0px rgba(0, 0, 0, 0.03),
-33px 60px 27px 0px rgba(0, 0, 0, 0.01),
-52px 94px 30px 0px rgba(0, 0, 0, 0);
backdrop-filter: blur(8px);
padding-block: 1.5rem;

View File

@@ -80,7 +80,8 @@ const execute = async () => {
await safeAnimate(box, { x: 300, y: 300 }, { duration: 0 })?.finished;
await Promise.all([
safeAnimate(uploadImg, { x: [64, 48], y: [80, 64], opacity: 1 }, { duration: 0.5 })?.finished,
safeAnimate(uploadImg, { x: [64, 48], y: [80, 64], opacity: 1 }, { duration: 0.5 })
?.finished,
safeAnimate(box, { y: [300 - 16, 300], opacity: 1 }, { duration: 1 })?.finished
]);

View File

@@ -11,7 +11,7 @@
const { state } = storageController;
</script>
<div data-theme-ignore class="inner-phone theme-light">
<div data-theme-ignore class="inner-phone light">
<div class="header">
<p class="title">Your tasks</p>
<span class="icon-menu" aria-label="menu" />

View File

@@ -63,7 +63,9 @@ export type ScrollCallback = {
};
export function createScrollHandler(callbacks: ScrollCallback[]) {
const states: ScrollCallbackState[] = callbacks.map(() => ({ executedCount: 0 }));
const states: ScrollCallbackState[] = callbacks.map(() => ({
executedCount: 0
}));
const handler = function (scrollPercentage: number) {
callbacks.forEach((callback, i) => {

View File

@@ -25,34 +25,21 @@
</script>
<div
class="scroll-indicator"
class="scroll-indicator relative h-full w-px shrink-0 rounded-full"
use:rect={elRect}
style:--y={`${y}px`}
style:--percentage={`${easedPercentage * 100}%`}
>
<div class="web-dot" />
<div class="absolute -top-[8px] left-1/2" />
</div>
<style lang="scss">
.scroll-indicator {
position: relative;
width: 1px;
flex-shrink: 0;
height: 100%;
background: linear-gradient(
to bottom,
hsl(var(--web-color-accent)) 0%,
hsl(var(--web-color-greyscale-700)) var(--percentage),
hsl(var(--web-color-greyscale-700)) 100%
);
border-radius: 100%;
}
.web-dot {
position: absolute;
left: 50%;
translate: -50% var(--y, 0);
top: -8px;
}
</style>

View File

@@ -11,7 +11,7 @@
<span class="icon-cheveron-down" aria-hidden="true" />
</div>
</summary>
<div class="collapsible-content u-flex-vertical">
<div class="collapsible-content flex flex-col">
<slot />
</div>
</details>

View File

@@ -1,4 +1,4 @@
<ul class="collapsible u-width-full-line" style="--p-toggle-border-color: var(--web-color-border);">
<ul class="collapsible w-full" style="--p-toggle-border-color: var(--web-color-border);">
<slot />
</ul>

View File

@@ -1,7 +1,4 @@
import Root from "./Root.svelte";
import Item from "./Item.svelte";
import Root from './Root.svelte';
import Item from './Item.svelte';
export {
Root as Accordion,
Item as AccordionItem
}
export { Root as Accordion, Item as AccordionItem };

View File

@@ -27,8 +27,15 @@
{title}
</h4>
<div class="web-author">
<div class="u-flex u-cross-center u-gap-8">
<img class="web-author-image" loading="lazy" src={avatar} width="24" height="24" alt={author} />
<div class="flex items-center gap-2">
<img
class="web-author-image"
loading="lazy"
src={avatar}
width="24"
height="24"
alt={author}
/>
<div class="web-author-info">
<h4 class="web-sub-body-400 web-u-color-text-primary">{author}</h4>
<ul class="web-metadata web-caption-400 web-is-not-mobile">

View File

@@ -42,9 +42,9 @@
</script>
<div>
<div class="u-flex u-flex-wrap u-cross-center u-margin-block-start-8">
<div class="mt-2 flex flex-wrap items-center">
<slot name="header" />
<div class="nav u-flex u-gap-12 u-cross-end u-margin-inline-start-auto">
<div class="nav ml-auto flex items-end gap-3">
<button
class="web-icon-button"
aria-label="Move carousel backward"
@@ -66,7 +66,7 @@
<div class="carousel-wrapper" data-state={isStart ? 'start' : isEnd ? 'end' : 'middle'}>
<ul
class="web-grid-articles u-margin-block-start-32 carousel"
class="web-grid-articles carousel mt-8"
class:is-medium={size === 'medium'}
class:is-big={size === 'big'}
style:gap="{gap}px"

View File

@@ -47,14 +47,14 @@
</script>
<section class="web-content-footer">
<header class="web-content-footer-header u-width-full-line">
<header class="web-content-footer-header w-full">
<div
class="u-flex u-gap-32 u-main-space-between u-cross-center u-width-full-line"
class="flex w-full items-center justify-between gap-8"
style="flex-wrap: wrap-reverse;"
>
<div class="u-flex u-gap-16 u-cross-center">
<div class="flex items-center gap-4">
<h5 class="web-main-body-600 web-u-color-text-primary">Was this page helpful?</h5>
<div class="u-flex u-gap-8">
<div class="flex gap-2">
<button
class="web-radio-button"
aria-label="helpful"
@@ -88,9 +88,9 @@
href="https://github.com/appwrite/website"
target="_blank"
rel="noopener noreferrer"
class="web-link u-flex u-gap-4 u-cross-baseline"
class="web-link flex items-baseline gap-1"
>
<span class="icon-pencil-alt u-contents" aria-hidden="true" />
<span class="icon-pencil-alt contents" aria-hidden="true" />
<span>Update on GitHub</span>
</a>
</li>
@@ -104,7 +104,7 @@
class="web-card is-normal"
style="--card-padding:1rem"
>
<div class="u-flex-vertical u-gap-8">
<div class="flex flex-col gap-2">
<label for="message">
<span class="web-u-color-text-primary">
What did you {feedbackType === 'negative' ? 'dislike' : 'like'}? (optional)
@@ -116,7 +116,7 @@
placeholder="Write your message"
bind:value={comment}
/>
<label for="message" class="u-margin-block-start-8">
<label for="message" class="mt-2">
<span class="web-u-color-text-primary">Email</span>
</label>
<input
@@ -129,17 +129,17 @@
/>
</div>
{#if submitted}
<p class="web-u-color-text-primary u-margin-block-start-16">
<p class="web-u-color-text-primary mt-4">
Your message has been sent successfully. We appreciate your feedback.
</p>
{/if}
{#if error}
<p class="web-u-color-text-primary u-margin-block-start-16">
<p class="web-u-color-text-primary mt-4">
There was an error submitting your feedback. Please try again later.
</p>
{/if}
<div class="u-flex u-main-end u-margin-block-start-16 u-gap-8">
<div class="mt-4 flex justify-end gap-2">
<button class="web-button is-text" on:click={() => (showFeedback = false)}>
<span>Cancel</span>
</button>

View File

@@ -23,7 +23,7 @@
export let images: Array<string>;
</script>
<div class="u-position-absolute web-u-hide-mobile root">
<div class="web-u-hide-mobile root absolute">
{#each headPositions as [size, top, left], i}
{@const image = clamp(0, images.length - 1, i % images.length)}
<FloatingHead
@@ -33,7 +33,7 @@
{size}
/>
<div style:margin-block-end="0" style:padding="10%">
<img style:border-radius="50%" class="u-block" alt="" />
<img style:border-radius="50%" class="block" alt="" />
</div>
{/each}
</div>

View File

@@ -37,7 +37,7 @@
{ label: 'Functions', href: '/docs/products/functions' },
{ label: 'Messaging', href: '/products/messaging' },
{ label: 'Storage', href: '/docs/products/storage' },
{ label: 'Realtime', href: '/docs/apis/realtime' },
{ label: 'Realtime', href: '/docs/apis/realtime' }
],
Learn: [
{ label: 'Docs', href: '/docs' },
@@ -93,7 +93,7 @@
<nav
aria-label="Footer"
class="web-footer-nav u-margin-block-start-100 u-position-relative"
class="web-footer-nav relative mt-24"
class:web-u-sep-block-start={!noBorder}
>
<img class="web-logo" src="/images/logos/appwrite.svg" alt="appwrite" height="24" width="130" />

View File

@@ -1,27 +1,11 @@
<script lang="ts">
import Button from './ui/Button.svelte';
import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public';
export let classes = '';
</script>
<a href={PUBLIC_APPWRITE_DASHBOARD} class={`web-button ${classes}`}>
<span class="logged-in"><slot name="isLoggedIn">Go to Console</slot></span>
<span class="not-logged-in"><slot name="isNotLoggedIn">Get started</slot></span>
</a>
<style lang="scss">
:global(body[data-logged-in]) {
.logged-in {
display: block;
}
.not-logged-in {
display: none;
}
}
.not-logged-in {
display: block;
}
.logged-in {
display: none;
}
</style>
<Button class={classes} href={PUBLIC_APPWRITE_DASHBOARD}>
<span class="hidden group-[&[data-logged-in]]/body:block">Go to Console</span>
<span class="block group-[&[data-logged-in]]/body:hidden">Get started</span>
</Button>

View File

@@ -0,0 +1,97 @@
<script lang="ts">
export let title = "Trusted by developers from the world's leading organizations";
const logos = [
{
src: '/images/logos/trusted-by/apple.svg',
alt: 'Apple',
width: 42,
height: 48
},
{
src: '/images/logos/trusted-by/oracle.svg',
alt: 'ORACLE',
width: 136,
height: 17
},
{
src: '/images/logos/trusted-by/tiktok.svg',
alt: 'TikTok',
width: 133,
height: 32
},
{
src: '/images/logos/trusted-by/intel.svg',
alt: 'intel',
width: 76,
height: 30
},
{
src: '/images/logos/trusted-by/ibm.svg',
alt: 'IBM',
width: 74,
height: 30
},
{
src: '/images/logos/trusted-by/american-airlines.svg',
alt: 'American Airlines',
width: 147,
height: 24
},
{
src: '/images/logos/trusted-by/deloitte.svg',
alt: 'Deloitte.',
width: 103,
height: 20
},
{
src: '/images/logos/trusted-by/gm.svg',
alt: 'GM',
width: 48,
height: 48
},
{
src: '/images/logos/trusted-by/ey.svg',
alt: 'EY',
width: 46,
height: 48
},
{
src: '/images/logos/trusted-by/nestle.svg',
alt: 'Nestle',
width: 119,
height: 34
},
{
src: '/images/logos/trusted-by/bosch.svg',
alt: 'BOSCH',
width: 110,
height: 37
},
{
src: '/images/logos/trusted-by/decathlon.svg',
alt: 'DECATHLON',
width: 127,
height: 32
}
];
</script>
<div class="my-32">
<div class="container">
<h2
class="font-aeonik-pro text-greyscale-100 mx-auto max-w-xl text-center text-4xl leading-10"
>
{title}
</h2>
<ul
class="web-u-padding-block-start-80 grid grid-cols-3 text-center md:grid-cols-6 md:gap-10"
>
{#each logos as { src, alt, width, height }, i}
<li class="grid place-content-center">
<img {src} {alt} {width} {height} />
</li>
{/each}
</ul>
</div>
</div>

View File

@@ -8,8 +8,8 @@
</script>
{#if variant === 'homepage'}
<footer class="web-main-footer u-position-relative u-margin-block-start-48">
<ul class="u-flex u-gap-8">
<footer class="web-main-footer relative mt-12">
<ul class="flex gap-2">
{#each socials as social}
<li>
<a
@@ -28,18 +28,17 @@
<div>Copyright © {year} Appwrite</div>
<iframe
class="status"
class="status max-w-[230px]"
title="Appwrite Status"
src="https://status.appwrite.online/badge?theme=dark"
width="190"
height="30"
height="35"
frameborder="0"
scrolling="no"
style:color-scheme="none"
style:margin-top="-4px"
/>
<ul class="u-flex u-gap-16">
<ul class="flex gap-4">
<li><a class="web-link" href="/terms">Terms</a></li>
<li><a class="web-link" href="/privacy">Privacy</a></li>
<li><a class="web-link" href="/cookies">Cookies</a></li>
@@ -47,11 +46,9 @@
</div>
</footer>
{:else if variant === 'docs'}
<footer
class="web-main-footer is-with-bg-color u-margin-block-start-32 u-small u-position-relative"
>
<footer class="web-main-footer is-with-bg-color relative mt-8 text-sm">
<div class="web-main-footer-grid-1">
<ul class="web-main-footer-grid-1-column-1 u-flex u-gap-8">
<ul class="web-main-footer-grid-1-column-1 flex gap-2">
{#each socials as social}
<li>
<a
@@ -69,7 +66,7 @@
<div class="web-main-footer-grid-1-column-2">
<ThemeSelect />
</div>
<ul class="web-main-footer-grid-1-column-3 u-cross-center web-main-footer-links">
<ul class="web-main-footer-grid-1-column-3 web-main-footer-links items-center">
<li>
<a href="/discord" target="_blank" rel="noopener noreferrer">Support</a>
</li>

View File

@@ -1,6 +1,5 @@
<script lang="ts">
import { afterNavigate } from '$app/navigation';
import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public';
import { IsLoggedIn } from '$lib/components';
import { GITHUB_STARS } from '$lib/constants';
import type { NavLink } from '$lib/layouts/Main.svelte';
@@ -15,16 +14,13 @@
<svelte:window on:resize={() => open && (open = false)} />
<nav class="web-side-nav web-is-not-desktop" class:u-hide={!open}>
<div class="web-side-nav-wrapper web-u-padding-inline-16">
<div class="u-flex items-center u-gap-8">
<a
href={`${PUBLIC_APPWRITE_DASHBOARD}/register`}
class="web-button is-secondary web-u-flex-1"
>
<nav class="web-side-nav web-is-not-desktop" class:hidden={!open}>
<div class="web-side-nav-wrapper ps-4 pe-4">
<div class="flex items-center gap-2">
<a href="https://cloud.appwrite.io/register" class="web-button is-secondary flex-1">
Sign up
</a>
<IsLoggedIn classes="web-u-flex-1" />
<IsLoggedIn classes="flex-1" />
</div>
<div class="web-side-nav-scroll">
<section>

View File

@@ -80,24 +80,29 @@
</div>
<div class="web-big-padding-section">
<div class="web-big-padding-section-level-1">
<div class="py-10">
<div class="web-big-padding-section-level-2">
<div class="web-container">
<div class="web-grid-1-1-opt-2 u-gap-32">
<div class="container">
<div class="grid gap-8 md:grid-cols-2">
<div class="">
<div class="web-u-max-inline-size-none-mobile" class:web-u-max-width-380={!submitted}>
<section class="u-flex-vertical web-u-gap-20">
<h1 class="web-title web-u-color-text-primary">Subscribe to our newsletter</h1>
<div
class="web-u-max-inline-size-none-mobile"
class:max-w-[380px]={!submitted}
>
<section class="web-gap-5 flex flex-col">
<h1 class="web-title web-u-color-text-primary">
Subscribe to our newsletter
</h1>
<p class="web-description web-u-padding-block-end-40">
Sign up to our company blog and get the latest insights from Appwrite. Learn more
about engineering, product design, building community, and tips & tricks for using
Appwrite.
Sign up to our company blog and get the latest insights from
Appwrite. Learn more about engineering, product design, building
community, and tips & tricks for using Appwrite.
</p>
</section>
</div>
</div>
{#if submitted}
<div class="u-flex u-gap-8 u-cross-center">
<div class="flex items-center gap-2">
<svg
width="18"
height="18"
@@ -131,8 +136,12 @@
</span>
</div>
{:else}
<form method="post" on:submit|preventDefault={submit} class="u-flex-vertical u-gap-16">
<div class="u-flex u-flex-vertical u-gap-4">
<form
method="post"
on:submit|preventDefault={submit}
class="flex flex-col gap-4"
>
<div class="flex flex-col gap-1">
<label for="name">Your name</label>
<input
class="web-input-text"
@@ -144,7 +153,7 @@
bind:value={name}
/>
</div>
<div class="u-flex u-flex-vertical u-gap-4">
<div class="flex flex-col gap-1">
<label for="email">Your email</label>
<input
class="web-input-text"
@@ -156,9 +165,13 @@
bind:value={email}
/>
</div>
<button type="submit" class="web-button" disabled={submitting}>Sign up</button>
<button type="submit" class="web-button" disabled={submitting}
>Sign up</button
>
{#if error}
<span class="text"> Something went wrong. Please try again later. </span>
<span class="text">
Something went wrong. Please try again later.
</span>
{/if}
</form>
{/if}

View File

@@ -4,20 +4,17 @@
<img src="/images/bgs/pre-footer.png" alt="" class="web-pre-footer-bg" style="z-index:-1" />
<div class="web-grid-1-1 u-gap-32 web-u-row-gap-80 u-position-relative">
<section class="web-hero u-flex web-u-row-gap-32 u-main-center u-cross-center">
<h2 class="web-display u-max-width-500 web-u-text-align-center web-u-color-text-primary">
<div class="web-u-row-gap-80 relative grid md:grid-cols-2 gap-8">
<section class="web-hero flex items-center justify-center gap-y-8">
<h2 class="web-display web-u-color-text-primary max-w-[500px] text-center">
Start building today
</h2>
<a
href={PUBLIC_APPWRITE_DASHBOARD}
class="web-button is-transparent web-u-cross-child-center"
>
<a href={PUBLIC_APPWRITE_DASHBOARD} class="web-button is-transparent web-self-center">
<span class="text">Get started</span>
</a>
</section>
<section
class="web-card is-transparent has-border-gradient web-u-max-inline-width-584-mobile web-u-margin-inline-auto-mobile web-u-inline-width-100-percent-mobile"
class="web-card is-transparent has-border-gradient web-u-max-inline-width-584-mobile web-mx-auto-mobile web-u-inline-width-100-percent-mobile"
>
<header class="web-strip-plans-header">
<div class="web-strip-plans-header-wrapper web-u-row-gap-24">

View File

@@ -1,16 +1,16 @@
<div class="web-big-padding-section-level-2">
<div class="web-container">
<h3 class="web-label web-u-color-text-primary u-text-center">
<div class="container">
<h3 class="web-label web-u-color-text-primary text-center">
Keep exploring similar integrations
</h3>
<ul class="u-margin-block-start-32 l-grid-1">
<ul class="l-grid-1 mt-8">
<li>
<a
href="/docs/products/auth"
class="web-card product-card is-transparent u-block u-height-100-percent"
class="web-card product-card is-transparent block h-full"
style="--card-padding:1.5rem; --card-padding-mobile:1.5rem;"
>
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<img
src="/images/icons/illustrated/dark/auth.png"
alt=""
@@ -19,10 +19,9 @@
height="32"
/>
<h4 class="web-main-body-400 web-u-color-text-primary">Auth</h4>
<span class="icon-arrow-right u-margin-inline-start-auto" aria-hidden="true"
></span>
<span class="icon-arrow-right ml-0" aria-hidden="true"></span>
</div>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 ml-1">
Build secure authentication and manage your users.
</p>
</a>
@@ -30,10 +29,10 @@
<li>
<a
href="/docs/products/functions"
class="web-card product-card is-transparent u-block u-height-100-percent"
class="web-card product-card is-transparent block h-full"
style="--card-padding:1.5rem; --card-padding-mobile:1.5rem;"
>
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<img
src="/images/icons/illustrated/dark/functions.png"
alt=""
@@ -42,10 +41,9 @@
height="32"
/>
<h4 class="web-main-body-400 web-u-color-text-primary">Functions</h4>
<span class="icon-arrow-right u-margin-inline-start-auto" aria-hidden="true"
></span>
<span class="icon-arrow-right ml-0" aria-hidden="true"></span>
</div>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 ml-1">
Scale big and unlock limitless potential with Appwrite functions.
</p>
</a>
@@ -53,10 +51,10 @@
<li>
<a
href="/docs/products/databases"
class="web-card product-card is-transparent u-block u-height-100-percent"
class="web-card product-card is-transparent block h-full"
style="--card-padding:1.5rem; --card-padding-mobile:1.5rem;"
>
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<img
src="/images/icons/illustrated/dark/databases.png"
alt=""
@@ -65,10 +63,9 @@
height="32"
/>
<h4 class="web-main-body-400 web-u-color-text-primary">Databases</h4>
<span class="icon-arrow-right u-margin-inline-start-auto" aria-hidden="true"
></span>
<span class="icon-arrow-right ml-0" aria-hidden="true"></span>
</div>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 ml-1">
Store and query structured data, ensuring scalable storage.
</p>
</a>
@@ -76,10 +73,10 @@
<li>
<a
href="/docs/products/messaging"
class="web-card product-card is-transparent u-block u-height-100-percent"
class="web-card product-card is-transparent block h-full"
style="--card-padding:1.5rem;--card-padding-mobile:1.5rem;"
>
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<img
src="/images/icons/illustrated/dark/messaging.png"
alt=""
@@ -88,10 +85,9 @@
height="32"
/>
<h4 class="web-main-body-400 web-u-color-text-primary">Messaging</h4>
<span class="icon-arrow-right u-margin-inline-start-auto" aria-hidden="true"
></span>
<span class="icon-arrow-right ml-0" aria-hidden="true"></span>
</div>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 ml-1">
Manage your files project, using convenient APIs and utilities.
</p>
</a>
@@ -99,10 +95,10 @@
<li>
<a
href="/docs/apis/realtime"
class="web-card product-card is-transparent u-block u-height-100-percent"
class="web-card product-card is-transparent block h-full"
style="--card-padding:1.5rem; --card-padding-mobile:1.5rem;"
>
<div class="u-flex u-cross-center u-gap-8">
<div class="flex items-center gap-2">
<img
src="/images/icons/illustrated/dark/realtime.png"
alt=""
@@ -111,10 +107,9 @@
height="32"
/>
<h4 class="web-main-body-400 web-u-color-text-primary">Realtime</h4>
<span class="icon-arrow-right u-margin-inline-start-auto" aria-hidden="true"
></span>
<span class="icon-arrow-right ml-0" aria-hidden="true"></span>
</div>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 ml-1">
Utilize realtime information from all Appwrite services.
</p>
</a>

View File

@@ -61,7 +61,7 @@
}
function createHref(hit: Hit<Props>): string {
const anchor = hit.anchor === '#' ? '' : hit.anchor ?? '';
const anchor = hit.anchor === '#' ? '' : (hit.anchor ?? '');
const target = hit.url + anchor;
return target.toString();
@@ -147,7 +147,7 @@
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="wrapper u-position-fixed u-padding-0 u-inset-0 u-flex u-main-center u-cross-center"
class="wrapper fixed inset-0 flex items-center justify-center p-0"
data-visible={open ? true : undefined}
style:z-index="100"
style:background="hsl(var(--web-color-black) / 0.3)"
@@ -156,23 +156,16 @@
bind:this={container}
on:click={handleExit}
>
<div
class="web-input-text-search-wrapper web-u-max-width-680 web-u-margin-inline-20 u-width-full-line"
>
<span
class="web-icon-search u-z-index-5"
aria-hidden="true"
style="inset-block-start:0.9rem"
/>
<div class="web-input-text-search-wrapper web-u-margin-inline-20 w-full max-w-[680px]">
<span class="web-icon-search z-[5]" aria-hidden="true" style="inset-block-start:0.9rem" />
<div id="searchbox" />
<input
class="web-input-button -u-padding-block-0 u-position-relative u-z-index-1"
class="web-input-button relative z-1 !rounded-b-none !pl-10"
type="text"
id="search"
bind:value
placeholder="Search in docs"
style="border-end-start-radius:0; border-end-end-radius:0;"
style:inline-size="100%"
use:melt={$input}
bind:this={inputEl}
@@ -184,7 +177,7 @@
}}
/>
<div
class="web-card is-normal u-flex-vertical u-gap-24"
class="web-card is-normal flex flex-col gap-6"
use:melt={$menu}
style="--card-padding-mobile:1rem; border-radius:0 0 0.5rem 0.5rem;"
>
@@ -192,15 +185,15 @@
<section>
{#if results.length > 0}
<h6 class="web-eyebrow">{results.length} results found</h6>
<ul class="u-flex-vertical u-gap-4 u-margin-block-start-8">
<ul class="mt-2 flex flex-col gap-1">
{#each results as hit, i (hit.uid)}
{@const relevantSubtitle = getRelevantSubtitle(hit)}
<li>
<a
data-hit={i}
href={createHref(hit)}
class="web-button web-caption-400 is-text u-flex-vertical u-gap-8 u-min-width-100-percent
web-u-padding-block-8 web-padding-inline-12 web-u-cross-start u-max-width-100-percent"
class="web-button web-caption-400 is-text web-u-padding-block-8 web-padding-inline-12 web-u-cross-start flex
max-w-full min-w-full flex-col gap-2"
use:melt={$option({
value: hit,
label: hit.title ?? i.toString()
@@ -216,9 +209,7 @@
{/if}
</div>
{#if hit.p}
<div
class="web-u-color-text-secondary web-u-trim-1"
>
<div class="web-u-color-text-secondary web-u-trim-1">
{hit.p}
</div>
{/if}
@@ -228,14 +219,14 @@
</ul>
{:else}
<p class="web-caption-400">
No results found for <span class="u-bold">{value}</span>
No results found for <span class="font-bold">{value}</span>
</p>
{/if}
</section>
{/if}
<section>
<h6 class="web-eyebrow">Recommended</h6>
<ul class="u-flex-vertical u-gap-4 u-margin-block-start-8">
<ul class="mt-2 flex flex-col gap-1">
{#each recommended as hit, i (hit.uid)}
{@const index = i + (results.length ? results.length : 0)}
<li>
@@ -246,7 +237,7 @@
value: hit,
label: hit.title ?? i.toString()
})}
class="web-button web-caption-400 is-text u-flex-vertical u-gap-8 u-min-width-100-percent web-u-padding-block-4 web-u-cross-start"
class="web-button web-caption-400 is-text web-u-padding-block-4 web-u-cross-start flex min-w-full flex-col gap-2"
>
<div class="web-u-trim-1">
<span class="web-u-color-text-secondary">{hit.h1}</span>

View File

@@ -70,7 +70,10 @@
return carry;
}, {});
return Object.entries(groups).map(([label, options]) => ({ label, options }));
return Object.entries(groups).map(([label, options]) => ({
label,
options
}));
})();
$: flyParams = {
@@ -106,7 +109,7 @@
{#each groups as group}
{@const isDefault = group.label === DEFAULT_GROUP}
{#if isDefault}
<div class="u-flex u-flex-vertical u-gap-2">
<div class="flex flex-col gap-0.5">
{#each group.options as option}
<button class="web-select-option" use:melt={$optionEl(option)}>
{#if option.icon}

View File

@@ -57,8 +57,7 @@
name: 'React Native',
href: '/docs/quick-starts/react-native',
image: `/images/platforms/${$themeInUse}/react-native.svg`
},
}
] as Array<{
name: string;
href: string;
@@ -66,12 +65,17 @@
}>;
</script>
<ul class="u-flex u-flex-wrap u-gap-16 web-u-margin-block-32-mobile web-u-margin-block-40-not-mobile">
<ul class="web-u-margin-block-32-mobile web-u-margin-block-40-not-mobile flex flex-wrap gap-4">
{#each platforms as platform}
<Tooltip>
<li>
<a href={platform.href} class="web-icon-button web-box-icon has-border-gradient">
<img src={platform.image} alt="{platform.name} quick start" width="32" height="32" />
<img
src={platform.image}
alt="{platform.name} quick start"
width="32"
height="32"
/>
</a>
</li>
<svelte:fragment slot="tooltip">{platform.name}</svelte:fragment>

View File

@@ -16,7 +16,10 @@
<aside class="web-grid-120-1fr-auto-side" class:web-is-mobile-closed={!showToc}>
<div class="web-page-steps">
<div class="web-page-steps-location web-is-not-mobile" style="--location:{progress * 100}%;">
<div
class="web-page-steps-location web-is-not-mobile"
style="--location:{progress * 100}%;"
>
<span class="web-page-steps-location-button">
<svg
xmlns="http://www.w3.org/2000/svg"

View File

@@ -122,7 +122,7 @@
};
</script>
<div class="embla web-carousel">
<div class="embla relative overflow-hidden">
{#if hasPrev}
<button class="web-carousel-button web-carousel-button-start" on:click={onPrev}>
<span class="web-icon-arrow-left" aria-hidden="true"></span>
@@ -135,7 +135,7 @@
{/if}
<div class="embla__viewport" use:embla={{ options, plugins }} on:emblaInit={onEmblaInit}>
<ul class="embla__container">
<ul class="embla__container flex">
<slot />
</ul>
</div>
@@ -155,14 +155,3 @@
{/each}
</ul>
</div>
<style>
.embla {
overflow: hidden;
position: relative;
}
.embla__container {
display: flex;
}
</style>

View File

@@ -0,0 +1,93 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from 'svelte/elements';
import { cva, type VariantProps } from 'cva';
const button = cva(
[
'flex w-fit min-h-10 items-center justify-center gap-2 rounded-lg px-4 text-white transition-all select-none'
],
{
variants: {
variant: {
primary: [
'bg-gradient-to-br from-pink-500 via-pink-500 to-secondary-100',
'hover:shadow-[0_0_2rem_#fd366e52] active:not:disabled:shadow-[0_0_2rem_#fd366e52]'
],
secondary: [
'bg-[#fd366e0a] relative',
'hover:shadow-[0_-6px_10px_0px_rgba(253,54,110,0.08)_inset]'
],
text: [
'bg-transparent border-transparent',
'hover:bg-gradient-to-b from-[#ffffff0f] via-[#ffffff1a] to-[#ffffff0f];'
]
}
}
}
);
type ButtonProps =
| (HTMLButtonAttributes & { href?: undefined })
| (HTMLAnchorAttributes & { href: string });
type $$Props = ButtonProps & VariantProps<typeof button>;
export let href: $$Props['href'] = undefined;
export let variant: $$Props['variant'] = 'primary';
const { class: classes, ...props } = $$restProps;
const buttonClasses = classNames(button({ variant }), classes, {
secondary: variant === 'secondary',
'leading-tight': $$slots.icon
});
</script>
{#if href}
<a {...props} {href} class={buttonClasses}>
<slot name="icon" />
<slot />
</a>
{:else}
<button {...props} class={buttonClasses}>
<slot name="icon" />
<slot />
</button>
{/if}
<style>
.secondary {
--border-gradient-before: linear-gradient(
to bottom,
rgba(253, 54, 110, 0.48) 0%,
rgba(253, 54, 110, 0) 180%
);
--border-gradient-after: radial-gradient(
42.86% 42.86% at 50.55% -0%,
rgba(255, 255, 255, 0.2) 0%,
rgba(255, 255, 255, 0) 100%
);
&::before {
background: var(--border-gradient-before) border-box;
}
&::after {
background: var(--border-gradient-after);
}
&::before,
&::after {
content: '';
position: absolute;
inset: 0;
border-radius: var(--radius-lg);
border: 1px solid transparent;
mask:
linear-gradient(#fff 0 0) padding-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
pointer-events: none;
}
}
</style>

View File

@@ -0,0 +1,85 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from 'svelte/elements';
import { cva, type VariantProps } from 'cva';
const card = cva(
[
'flex w-fit min-h-10 items-center justify-center gap-2 rounded-2xl px-6 text-white transition-all select-none'
],
{
variants: {
variant: {
primary: [
'to-secondary-100 bg-gradient-to-br from-pink-500 via-pink-500',
'hover:shadow-[0_0_2rem_#fd366e52]'
],
secondary: ['bg-[#fd366e0a] relative'],
text: [
'bg-transparent border-transparent',
'hover:bg-gradient-to-b from-[#ffffff0f] via-[#ffffff1a] to-[#ffffff0f];'
]
}
}
}
);
type ButtonProps =
| (HTMLButtonAttributes & { href?: undefined })
| (HTMLAnchorAttributes & { href: string });
type $$Props = ButtonProps & VariantProps<typeof card>;
export let href: $$Props['href'] = undefined;
export let variant: $$Props['variant'] = 'primary';
const { class: classes, ...props } = $$restProps;
const buttonClasses = classNames(card({ variant }), classes);
</script>
{#if href}
<a {...props} {href} class={buttonClasses} class:has-border-gradient={variant === 'secondary'}>
<slot />
</a>
{:else}
<button {...props} class={buttonClasses} class:has-border-gradient={variant === 'secondary'}>
<slot />
</button>
{/if}
<style>
.has-border-gradient {
--border-gradient-before: linear-gradient(
to bottom,
rgba(253, 54, 110, 0.48) 0%,
rgba(253, 54, 110, 0) 180%
);
--border-gradient-after: radial-gradient(
42.86% 42.86% at 50.55% -0%,
rgba(255, 255, 255, 0.2) 0%,
rgba(255, 255, 255, 0) 100%
);
&::before {
background: var(--border-gradient-before) border-box;
}
&::after {
background: var(--border-gradient-after);
}
&::before,
&::after {
content: '';
position: absolute;
inset: 0;
border-radius: var(--radius-lg);
border: 1px solid transparent;
mask:
linear-gradient(#fff 0 0) padding-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
pointer-events: none;
}
}
</style>

View File

@@ -0,0 +1,3 @@
<span class="block bg-[linear-gradient(6deg,_#f8a1ba,_#fff_35%)] bg-clip-text text-transparent">
<slot />
</span>

View File

View File

@@ -0,0 +1,51 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import { cva, type VariantProps } from 'cva';
import type { SvelteHTMLElements } from 'svelte/elements';
type HeroProps = SvelteHTMLElements['div'];
const hero = cva(['flex', 'gap-8', 'relative'], {
variants: {
layout: {
vertical: ['flex-col', 'max-w-[600px]'],
horizontal: ['flex-col', 'md:flex-row']
}
},
defaultVariants: {
layout: 'vertical'
}
});
const styles = cva('tracking-[-0.022em] text-white', {
variants: {
size: {
title: ['text-[5.5rem]', 'leading-[5.5rem]', 'flex-[1.3]'],
display: 'text-[4rem] leading-[4.25rem] w-full'
}
},
defaultVariants: {
size: 'title'
}
});
type $$Props = HeroProps & VariantProps<typeof hero> & VariantProps<typeof styles>;
export let layout: $$Props['layout'] = 'horizontal';
export let size: $$Props['size'] = 'title';
const { class: classes, ...props } = $$restProps;
</script>
<section class={classNames(hero({ layout }), classes)} {...props}>
<h1 class={classNames(styles({ size }), 'font-aeonik-pro')}>
<slot name="title" />
</h1>
{#if $$slots.description}
<div class="flex-[1] self-end">
<p class="text-secondary mt-5 text-xl font-medium tracking-[-0.018em]">
<slot name="description" />
</p>
<slot name="cta" />
</div>
{/if}
</section>

View File

@@ -0,0 +1,49 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import type { HTMLInputAttributes } from 'svelte/elements';
type $$Props = {
label: string;
} & HTMLInputAttributes;
export let label: $$Props['label'] = '';
export let value: $$Props['value'] = '';
const { class: classes, name, ...props } = $$restProps;
</script>
{#if $$slots.icon}
<label
class={classNames(
'focus:border-greyscale-100 bg-greyscale-800 border-greyscale-700 flex items-center gap-1 rounded-lg border py-2 px-3 text-sm font-light transition-colors focus-within:border-white active:shadow-sm active:shadow-black/30',
classes
)}
>
<slot name="icon" />
<input
on:input
on:change
on:focus
on:blur
{name}
bind:value
class="w-full border-0 ring-0 outline-none"
{...props}
/>
</label>
{:else}
<label for={name}>
{label}
</label>
<input
on:input
on:change
on:focus
on:blur
bind:value
class={classNames(
'focus:border-greyscale-100 bg-greyscale-800 border-greyscale-700 mt-2 flex w-full items-center gap-1 rounded-lg border py-2 px-3 text-sm font-light transition-colors focus-within:border-white active:shadow-sm active:shadow-black/30',
classes
)}
{...props}
/>
{/if}

View File

@@ -0,0 +1,28 @@
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import type { HTMLTextareaAttributes } from 'svelte/elements';
type $$Props = {
label: string;
} & HTMLTextareaAttributes;
export let label: $$Props['label'] = '';
export let value: $$Props['value'] = '';
const { class: classes, name, ...props } = $$restProps;
</script>
<label for={name}>
{label}
</label>
<textarea
on:input
on:change
on:focus
on:blur
bind:value
class={classNames(
'focus:border-greyscale-100 bg-greyscale-800 border-greyscale-700 flex items-center gap-1 rounded-lg border py-2 px-3 text-sm font-light transition-colors focus-within:border-white active:shadow-sm active:shadow-black/30',
classes
)}
{...props}
/>

View File

@@ -11,8 +11,7 @@ export const BLOG_POSTS_PER_PAGE = 12;
* init-banner-02
* pricing-banner-01
*/
type Banners = 'discord-banner-01' | 'init-banner-02' | 'pricing-banner-01'
type Banners = 'discord-banner-01' | 'init-banner-02' | 'pricing-banner-01';
export type Social = {
icon: string;
@@ -52,7 +51,7 @@ export const socialSharingOptions: Array<SocialShareOption> = [
link: '',
type: 'copy'
}
]
];
export const socials: Array<Social> = [
{
@@ -79,10 +78,5 @@ export const socials: Array<Social> = [
icon: 'web-icon-youtube',
label: 'YouTube',
link: 'https://www.youtube.com/c/appwrite?sub_confirmation=1'
},
{
icon: 'web-icon-daily-dev',
label: 'Daily.dev',
link: 'https://app.daily.dev/squads/appwrite'
}
];

View File

@@ -48,7 +48,7 @@
export let isReferences = false;
const variantClasses: Record<DocsLayoutVariant, string> = {
default: 'web-grid-side-nav web-container u-padding-inline-0',
default: 'web-grid-side-nav max-w-[90rem] !px-0',
expanded: 'web-grid-huge-navs',
'two-side-navs': 'web-grid-two-side-navs'
};
@@ -79,19 +79,19 @@
<svelte:window on:keydown={handleKeydown} />
<div class="u-position-relative">
<div class="relative">
<section class="web-mobile-header is-transparent">
<div class="web-mobile-header-start">
<a href="/" aria-label="homepage">
<img
class="web-logo u-only-dark"
class="web-logo hidden dark:block"
src="/images/logos/appwrite.svg"
alt="appwrite"
height="24"
width="130"
/>
<img
class="web-logo u-only-light"
class="web-logo block dark:hidden"
src="/images/logos/appwrite-light.svg"
alt="appwrite"
height="24"
@@ -121,17 +121,17 @@
class:is-transparent={variant !== 'expanded'}
>
<div class="web-main-header-wrapper">
<div class="web-main-header-start u-stretch">
<div class="web-main-header-start flex-1">
<a href="/" aria-label="homepage">
<img
class="web-logo u-only-dark"
class="web-logo hidden dark:block"
src="/images/logos/appwrite.svg"
alt="appwrite"
height="24"
width="130"
/>
<img
class="web-logo u-only-light"
class="web-logo block dark:hidden"
src="/images/logos/appwrite-light.svg"
alt="appwrite"
height="24"
@@ -145,7 +145,7 @@
</li>
</ul>
</nav>
<div class="u-flex u-stretch web-u-margin-inline-start-48">
<div class="web-u-margin-inline-start-48 flex flex-1">
<button
class="web-input-button web-u-flex-basis-400"
on:click={() => ($layoutState.showSearch = true)}
@@ -153,7 +153,7 @@
<span class="web-icon-search" aria-hidden="true" />
<span class="text">Search in docs</span>
<div class="u-flex u-gap-4 u-margin-inline-start-auto">
<div class="ml-auto flex gap-1">
{#if isMac()}
<span class="web-kbd" aria-label="command"></span>
{:else}
@@ -165,7 +165,7 @@
</div>
</div>
<div class="web-main-header-end">
<div class="u-flex u-gap-8">
<div class="flex gap-2">
<a
href="https://github.com/appwrite/appwrite/stargazers"
target="_blank"

View File

@@ -23,10 +23,10 @@
export let date: string | undefined = undefined;
</script>
<main class="u-contents" id="main">
<article class="web-article u-contents">
<main class="contents" id="main">
<article class="web-article contents">
<header class="web-article-header">
<div class="web-article-header-start u-flex-vertical web-u-cross-start">
<div class="web-article-header-start web-u-cross-start flex flex-col">
{#if back}
<a
href={back}
@@ -39,13 +39,13 @@
<ul class="web-metadata web-caption-400">
<slot name="metadata" />
</ul>
<div class="u-position-relative u-flex u-cross-center">
<div class="relative flex items-center">
{#if back}
<a
href={back}
class="
web-button is-text is-icon web-u-cross-center web-u-size-40
u-position-absolute u-inset-inline-start-0 web-u-translate-x-negative"
web-button is-text is-icon web-items-center web-u-size-40
web-u-translate-x-negative absolute top-0"
aria-label="previous page"
>
<span
@@ -63,17 +63,15 @@
<slot />
<Feedback {date} />
</div>
<aside class="web-references-menu web-u-padding-inline-start-24">
<aside class="web-references-menu ps-6">
<div class="web-references-menu-content">
{#if toc && toc.length > 0}
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<div class="flex items-center justify-between gap-4">
<h5 class="web-references-menu-title web-eyebrow">On This Page</h5>
</div>
<ol class="web-references-menu-list">
{#each toc as parent (parent.href)}
<li
class="web-references-menu-item"
>
<li class="web-references-menu-item">
<a
href={parent.href}
class="web-references-menu-link"
@@ -85,16 +83,15 @@
<span class="web-caption-400">{parent.title}</span>
</a>
{#if parent.children}
<ol
class="web-references-menu-list u-margin-block-start-16 u-margin-inline-start-32"
>
<ol class="web-references-menu-list mt-4 ml-8">
{#each parent.children as child}
<li class="web-references-menu-item">
<a
href={child.href}
class="web-references-menu-link"
>
<span class="web-caption-400">{child.title}</span
<span class="web-caption-400"
>{child.title}</span
>
</a>
</li>
@@ -104,11 +101,8 @@
</li>
{/each}
</ol>
<div class="u-sep-block-start u-padding-block-start-20">
<button
class="web-link u-inline-flex u-cross-center u-gap-8"
use:scrollToTop
>
<div class="border-greyscale-900/[0.04] border-t pt-5">
<button class="web-link inline-flex items-center gap-2" use:scrollToTop>
<span class="web-icon-arrow-up" aria-hidden="true" />
<span class="web-caption-400">Back to top</span>
</button>

View File

@@ -16,26 +16,23 @@
$: prevStep = tutorials.find((tutorial) => tutorial.step === currentStep - 1);
</script>
<main class="u-contents" id="main">
<article class="web-article u-contents">
<main class="contents" id="main">
<article class="web-article contents">
<header class="web-article-header">
<div class="web-article-header-start u-flex-vertical web-u-cross-start">
<button
class="web-icon-button web-is-only-mobile"
aria-label="previous page"
>
<div class="web-article-header-start web-u-cross-start flex flex-col">
<button class="web-icon-button web-is-only-mobile" aria-label="previous page">
<span class="icon-cheveron-left" aria-hidden="true" />
</button>
<ul class="web-metadata web-caption-400">
<slot name="metadata" />
</ul>
<div class="u-position-relative u-flex u-cross-center">
<div class="relative flex items-center">
{#if back}
<a
href={back}
class="
web-button is-text is-only-icon web-u-cross-center web-u-size-40
u-position-absolute u-inset-inline-start-0 web-u-translate-x-negative"
web-button is-text is-only-icon web-items-center web-u-size-40
web-u-translate-x-negative absolute top-0"
aria-label="previous page"
>
<span
@@ -51,7 +48,7 @@
</header>
<div class="web-article-content">
<slot />
<div class="u-flex u-main-space-between">
<div class="flex justify-between">
{#if prevStep}
<a href={prevStep.href} class="web-button is-text">
<span class="icon-cheveron-left" aria-hidden="true" />
@@ -80,9 +77,9 @@
<Feedback {date} />
</div>
<aside class="web-references-menu web-u-padding-inline-start-24">
<aside class="web-references-menu ps-6">
<div class="web-references-menu-content">
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<div class="flex items-center justify-between gap-4">
<h5 class="web-references-menu-title web-eyebrow">Tutorial Steps</h5>
</div>
<ol class="web-references-menu-list">
@@ -99,9 +96,7 @@
<span class="web-caption-400">{tutorial.title}</span>
</a>
{#if isCurrentStep}
<ol
class="web-references-menu-list u-margin-block-start-16 u-margin-inline-start-32"
>
<ol class="web-references-menu-list mt-4 ml-8">
{#each toc as parent}
<li class="web-references-menu-item">
<a
@@ -118,9 +113,7 @@
<span class="web-caption-400">{parent.title}</span>
</a>
{#if parent.children}
<ol
class="web-references-menu-list u-margin-block-start-16 u-margin-inline-start-32"
>
<ol class="web-references-menu-list mt-4 ml-8">
{#each parent.children as child}
<li class="web-references-menu-item">
<a
@@ -142,8 +135,8 @@
</li>
{/each}
</ol>
<div class="u-sep-block-start u-padding-block-start-20">
<button class="web-link u-inline-flex u-cross-center u-gap-8" use:scrollToTop>
<div class="border-greyscale-900/[0.04] border-t pt-5">
<button class="web-link inline-flex items-center gap-2" use:scrollToTop>
<span class="web-icon-arrow-up" aria-hidden="true" />
<span class="web-caption-400">Back to top</span>
</button>
@@ -152,5 +145,3 @@
</aside>
</article>
</main>

View File

@@ -8,8 +8,6 @@
};
export const isHeaderHidden = writable(false);
export const isMobileNavOpen = writable(false);
const initialized = writable(false);
</script>
<script lang="ts">
@@ -22,33 +20,11 @@
import { addEventListener } from '@melt-ui/svelte/internal/helpers';
import { onMount } from 'svelte';
import { page } from '$app/stores';
import { loggedIn } from '$lib/utils/console';
import { PUBLIC_APPWRITE_DASHBOARD } from '$env/static/public';
import AnnouncementBanner from '$lib/components/AnnouncementBanner.svelte';
import InitBanner from '$lib/components/InitBanner.svelte';
import { classNames } from '$lib/utils/classnames';
export let omitMainId = false;
let theme: 'light' | 'dark' | null = 'dark';
function setupThemeObserver() {
const handleVisibility = () => {
theme = getVisibleTheme();
};
const observer = new MutationObserver(handleVisibility);
observer.observe(document.body, { childList: true, subtree: true });
const callbacks = [
addEventListener(window, 'scroll', handleVisibility),
addEventListener(window, 'resize', handleVisibility)
];
return () => {
observer.disconnect();
callbacks.forEach((callback) => callback());
};
}
function isInViewport(element: Element): boolean {
const mobileHeader = document.querySelector('.aw-mobile-header');
const isMobile =
@@ -71,8 +47,7 @@
}
function getVisibleTheme() {
const themes = Array.from(document.querySelectorAll('.theme-dark, .theme-light')).filter(
(element) => {
const themes = Array.from(document.querySelectorAll('.dark, .light')).filter((element) => {
const { classList, dataset } = element as HTMLElement;
if (
classList.contains('web-mobile-header') ||
@@ -83,26 +58,18 @@
return false;
}
return true;
}
);
});
for (const theme of themes) {
if (isInViewport(theme)) {
return theme.classList.contains('theme-light') ? 'light' : 'dark';
return theme.classList.contains('light') ? 'light' : 'dark';
}
}
return 'dark';
}
onMount(() => {
setTimeout(() => {
$initialized = true;
}, 1000);
return setupThemeObserver();
});
let navLinks: NavLink[] = [
const navLinks: NavLink[] = [
{
label: 'Docs',
href: '/docs'
@@ -115,10 +82,6 @@
label: 'Blog',
href: '/blog'
},
{
label: 'Integrations',
href: '/integrations'
},
{
label: 'Changelog',
href: '/changelog',
@@ -144,25 +107,30 @@
return $scrollInfo.deltaDirChange < 200;
})();
const hideTopBanner = () => {
document.body.dataset.bannerHidden = '';
localStorage.setItem(BANNER_KEY, 'true');
};
</script>
<div class="u-position-relative">
<div class="relative">
<section
class="web-mobile-header theme-{resolvedTheme}"
class:is-transparent={browser && !$isMobileNavOpen}
class="web-mobile-header {resolvedTheme}"
class:transparent={browser && !$isMobileNavOpen}
class:is-hidden={$isHeaderHidden}
>
<div class="web-mobile-header-start">
<a href="/">
<img
class="web-logo web-u-only-dark"
class="web-logo block dark:hidden"
src="/images/logos/appwrite.svg"
alt="appwrite"
height="24"
width="130"
/>
<img
class="web-logo web-u-only-light"
class="web-logo hidden dark:block"
src="/images/logos/appwrite-light.svg"
alt="appwrite"
height="24"
@@ -172,7 +140,7 @@
</div>
<div class="web-mobile-header-end">
{#if !$isMobileNavOpen}
<a href={PUBLIC_APPWRITE_DASHBOARD} class="web-button">
<a href="https://cloud.appwrite.io" class="web-button">
<span class="text">Get started</span>
</a>
{/if}
@@ -190,38 +158,40 @@
</div>
</section>
<header
class="web-main-header is-special-padding theme-{resolvedTheme} is-transparent"
class="web-main-header is-special-padding {resolvedTheme} is-transparent"
class:is-hidden={$isHeaderHidden}
class:is-special-padding={!BANNER_KEY.startsWith('init-banner-')}
style={BANNER_KEY === 'init-banner-02' ? 'padding-inline: 0' : ''}
>
{#if BANNER_KEY.startsWith('init-banner-')}
<InitBanner />
{:else}
<AnnouncementBanner>
<div class="web-top-banner">
<div class="web-top-banner-content web-u-color-text-primary">
<a href="/discord" target="_blank" rel="noopener noreferrer">
<span class="web-caption-500">We are having lots of fun on</span>
<span class="web-icon-discord" aria-hidden="true" />
<span class="web-caption-500">Discord. Come and join us!</span>
</a>
</AnnouncementBanner>
{/if}
<div
class="web-main-header-wrapper"
class:is-special-padding={BANNER_KEY.startsWith('init-banner-')}
{#if browser}
<button
class="web-top-banner-button"
aria-label="close discord message"
on:click={hideTopBanner}
>
<span class="web-icon-close" aria-hidden="true" />
</button>
{/if}
</div>
</div>
<div class="web-main-header-wrapper">
<div class="web-main-header-start">
<a href="/">
<img
class="web-logo web-u-only-dark"
class="web-logo hidden dark:block"
src="/images/logos/appwrite.svg"
alt="appwrite"
height="24"
width="130"
/>
<img
class="web-logo web-u-only-light"
class="web-logo block dark:hidden"
src="/images/logos/appwrite-light.svg"
alt="appwrite"
height="24"
@@ -231,11 +201,12 @@
<nav class="web-main-header-nav" aria-label="Main">
<ul class="web-main-header-nav-list">
{#each navLinks as navLink}
<li class="web-main-header-nav-item">
<li class="web-main-header-nav-item text-primary hover:text-accent">
<a
class="web-link"
class={classNames(
'data-[badge]:after:animate-scale-in data-[badge]:relative data-[badge]:after:absolute data-[badge]:after:size-1.5 data-[badge]:after:translate-full data-[badge]:after:rounded-full'
)}
href={navLink.href}
data-initialized={$initialized ? '' : undefined}
data-badge={navLink.showBadge ? '' : undefined}
>{navLink.label}
</a>
@@ -249,23 +220,20 @@
href="https://github.com/appwrite/appwrite/stargazers"
target="_blank"
rel="noopener noreferrer"
class="web-button is-text"
class="web-button is-text web-u-inline-width-100-percent-mobile"
>
<span aria-hidden="true" class="web-icon-star" />
<span class="web-icon-star" aria-hidden="true" />
<span class="text">Star on GitHub</span>
<span class="web-inline-tag web-sub-body-400">{GITHUB_STARS}</span>
</a>
<IsLoggedIn />
</div>
</div>
</header>
<MobileNav bind:open={$isMobileNavOpen} links={navLinks} />
<main
class="web-main-section"
class:web-u-hide-mobile={$isMobileNavOpen}
id={omitMainId ? undefined : 'main'}
>
<main class:web-u-hide-mobile={$isMobileNavOpen} id={omitMainId ? undefined : 'main'}>
<slot />
</main>
</div>
@@ -276,37 +244,12 @@
padding-inline: 0.375rem;
}
@keyframes scale-in {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
.is-special-padding {
padding-inline: clamp(1.25rem, 4vw, 120rem);
}
[data-badge] {
position: relative;
&::after {
content: '';
position: absolute;
background-color: hsl(var(--web-color-accent));
border-radius: 100%;
width: 0.375rem;
height: 0.375rem;
inset-block-start: -2px;
inset-inline-end: -4px;
translate: 100%;
}
&:not([data-initialized])::after {
animation: scale-in 0.2s ease-out;
}
}
</style>

View File

@@ -36,7 +36,7 @@
</script>
<nav
class="web-side-nav"
class="web-side-nav !border-greyscale-800 !border-r"
use:clickOutside={(e) => {
const el = e.target;
if (!(el instanceof HTMLElement)) return;
@@ -59,7 +59,8 @@
<a href={parent.href} aria-label="go back">
<span class="icon-cheveron-left" aria-hidden="true" />
</a>
<span class="web-side-nav-wrapper-parent-title web-eyebrow">{parent.label}</span>
<span class="web-side-nav-wrapper-parent-title web-eyebrow">{parent.label}</span
>
</section>
{/if}
{#each navigation as navGroup}
@@ -75,7 +76,7 @@
{/if}
{:else}
{#if navGroup.label}
<h2 class="web-side-nav-header web-eyebrow u-un-break-text">
<h2 class="web-side-nav-header web-eyebrow whitespace-nowrap">
{navGroup.label}
</h2>
{/if}
@@ -102,7 +103,7 @@
{#if expandable}
<button
on:click={toggleSidenav}
class="web-icon-button u-margin-inline-start-auto"
class="web-icon-button ml-auto"
style:margin-bottom="1rem"
aria-label="toggle nav"
>

View File

@@ -15,7 +15,7 @@
{/if}
<span class="web-caption-400">{groupItem.label} </span>
{#if groupItem.isParent}
<span class="icon-cheveron-right u-margin-inline-start-auto" aria-hidden="true" />
<span class="icon-cheveron-right ml-auto" aria-hidden="true" />
{/if}
</a>

View File

@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
export const classNames = (...inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
};

View File

@@ -1,8 +1,8 @@
import type { AuthorData, PostsData } from "$routes/blog/content";
import type { AuthorData, PostsData } from '$routes/blog/content';
export const DEFAULT_HOST = 'https://appwrite.io';
export const DEFAULT_DESCRIPTION = 'Appwrite is an open-source backend platform offering essential APIs for building web and mobile applications.';
export const DEFAULT_DESCRIPTION =
'Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools.';
export function buildOpenGraphImage(title: string, description: string): string {
return `https://og.appwrite.global/image.png?title=${encodeURIComponent(
title

View File

@@ -30,7 +30,7 @@ export enum Service {
Locale = 'locale',
Storage = 'storage',
Teams = 'teams',
Users = 'users',
Users = 'users'
}
export enum Platform {
@@ -54,7 +54,7 @@ export enum Platform {
ServerKotlin = 'server-kotlin',
ServerJava = 'server-java',
ServerGraphql = 'server-graphql',
ServerRest = 'server-rest',
ServerRest = 'server-rest'
}
export const platformMap: Record<Language | string, string> = {
@@ -114,7 +114,7 @@ export const platformMap: Record<Language | string, string> = {
vue: 'Vue',
svelte: 'Svelte',
groovy: 'Groovy',
go: 'Go',
go: 'Go'
};
export const serviceMap: Record<Service, string> = {
@@ -127,7 +127,7 @@ export const serviceMap: Record<Service, string> = {
[Service.Locale]: 'Locale',
[Service.Storage]: 'Storage',
[Service.Teams]: 'Teams',
[Service.Users]: 'Users',
[Service.Users]: 'Users'
};
export const preferredVersion = writable<Version | null>(

View File

@@ -112,7 +112,11 @@ function getExamples(version: string) {
function* iterateAllMethods(
api: OpenAPIV3.Document,
service: string
): Generator<{ method: OpenAPIV3.HttpMethods; value: OpenAPIV3.OperationObject; url: string }> {
): Generator<{
method: OpenAPIV3.HttpMethods;
value: OpenAPIV3.OperationObject;
url: string;
}> {
for (const url in api.paths) {
const methods = api.paths[url];
if (methods?.get?.tags?.includes(service)) {
@@ -128,7 +132,11 @@ function* iterateAllMethods(
yield { method: OpenAPIV3.HttpMethods.PATCH, value: methods.patch, url };
}
if (methods?.delete?.tags?.includes(service)) {
yield { method: OpenAPIV3.HttpMethods.DELETE, value: methods.delete, url };
yield {
method: OpenAPIV3.HttpMethods.DELETE,
value: methods.delete,
url
};
}
}
}
@@ -187,7 +195,8 @@ export function getSchema(id: string, api: OpenAPIV3.Document): OpenAPIV3.Schema
if (schema) {
return schema;
}
throw new Error(`Schema doesn't exist for id: ${id}`);}
throw new Error(`Schema doesn't exist for id: ${id}`);
}
const specs = import.meta.glob(
'$appwrite/app/config/specs/open-api3*-(client|server|console).json',
@@ -359,15 +368,18 @@ export function resolveReference(
throw new Error("Schema doesn't exist");
}
export const generateExample = (schema: OpenAPIV3.SchemaObject, api: OpenAPIV3.Document<{}>, modelType: ModelType = ModelType.REST): Object => {
export const generateExample = (
schema: OpenAPIV3.SchemaObject,
api: OpenAPIV3.Document<{}>,
modelType: ModelType = ModelType.REST
): Object => {
const properties = Object.keys(schema.properties ?? {}).map((key) => {
const name = key;
const fields = schema.properties?.[key];
return {
name,
...fields
}
};
});
const example = properties.reduce((carry, currentValue) => {
@@ -391,13 +403,16 @@ export const generateExample = (schema: OpenAPIV3.SchemaObject, api: OpenAPIV3.D
return {
...carry,
[propertyName]: property['x-example']
}
};
}
if (property.items && 'anyOf' in property.items) {
// default to first child type if multiple available
const firstSchema = (property.items as unknown as AppwriteSchemaObject)?.anyOf?.[0];
const schema = getSchema(getIdFromReference(firstSchema as OpenAPIV3.ReferenceObject), api)
const schema = getSchema(
getIdFromReference(firstSchema as OpenAPIV3.ReferenceObject),
api
);
return {
...carry,
@@ -406,22 +421,28 @@ export const generateExample = (schema: OpenAPIV3.SchemaObject, api: OpenAPIV3.D
}
// if an array of objects without child types
const schema = getSchema(getIdFromReference(property.items as OpenAPIV3.ReferenceObject), api);
const schema = getSchema(
getIdFromReference(property.items as OpenAPIV3.ReferenceObject),
api
);
return {
...carry,
[propertyName]: [generateExample(schema, api, modelType)]
}
};
}
// If it's an object type, but not in an array.
if (property.type === 'object') {
if (property.items?.oneOf) {
// default to first child type if multiple available
const schema = getSchema(getIdFromReference(property.items.oneOf[0] as OpenAPIV3.ReferenceObject), api);
const schema = getSchema(
getIdFromReference(property.items.oneOf[0] as OpenAPIV3.ReferenceObject),
api
);
return {
...carry,
[propertyName]: generateExample(schema, api, modelType)
}
};
}
if (property.items) {
@@ -429,14 +450,14 @@ export const generateExample = (schema: OpenAPIV3.SchemaObject, api: OpenAPIV3.D
return {
...carry,
[propertyName]: generateExample(schema, api, modelType)
}
};
}
}
return {
...carry,
[propertyName]: property['x-example']
}
};
}, {});
return example;
}
};

View File

@@ -45,10 +45,8 @@
</svelte:head>
<Main>
<div class="web-big-padding-section-level-1 u-position-relative u-overflow-hidden">
<div
class="u-position-absolute u-inset-inline-start-0 u-inset-block-end-0 web-u-pointer-events-none"
>
<div class="relative overflow-hidden py-10">
<div class="web-u-pointer-events-none absolute inset-y-0">
<svg
xmlns="http://www.w3.org/2000/svg"
width="660"
@@ -102,16 +100,16 @@
</svg>
</div>
<div class="web-big-padding-section-level-2 u-position-relative">
<div class="web-container">
<div class="web-author-section u-block">
<div class="web-big-padding-section-level-2 relative">
<div class="container">
<div class="web-author-section block">
{#if avatar}
<FloatingHead --position="relative" src={avatar} alt={name} size={112} />
{/if}
<div>
<h1 class="web-title web-u-color-text-primary">{name}</h1>
{#if role}
<div class="web-label u-margin-block-start-8">{role}</div>
<div class="web-label mt-2">{role}</div>
{/if}
</div>
{#if bio}
@@ -119,7 +117,7 @@
{bio}
</p>
{/if}
<ul class="u-flex u-main-center u-gap-8 u-margin-block-start-16">
<ul class="mt-4 flex justify-center gap-2">
{#if github}
<li>
<a
@@ -165,13 +163,13 @@
</div>
</div>
<div class="web-big-padding-section-level-1">
<div class="py-10">
<div class="web-big-padding-section-level-2">
<div class="web-container">
<div class="container">
<h2 class="web-title web-u-color-text-primary">Articles</h2>
<!-- <div class="web-is-only-mobile u-margin-block-start-32">
<label class="u-block web-select is-colored" for="articles">
<!-- <div class="web-is-only-mobile mt-8">
<label class="blockweb-select is-colored" for="articles">
<select id="articles">
<option>Latest</option>
<option>News</option>
@@ -183,7 +181,7 @@
</label>
</div> -->
<!--<div class="web-is-not-mobile">
<div class="u-flex u-main-space-between u-gap-16 u-margin-block-start-24">
<div class="flex justify-between gap-4 mt-6">
<ul
class="web-secondary-tabs is-transparent"
role="tablist"
@@ -193,7 +191,7 @@
>
<li class="web-secondary-tabs-item">
<button
class="web-secondary-tabs-button u-width-full-line is-selected"
class="web-secondary-tabs-button w-full is-selected"
type="button"
role="tab"
data-state="active"
@@ -207,7 +205,7 @@
</li>
<li class="web-secondary-tabs-item">
<button
class="web-secondary-tabs-button u-width-full-line"
class="web-secondary-tabs-button w-full"
type="button"
role="tab"
data-state="inactive"
@@ -221,7 +219,7 @@
</li>
<li class="web-secondary-tabs-item">
<button
class="web-secondary-tabs-button u-width-full-line"
class="web-secondary-tabs-button w-full"
type="button"
role="tab"
data-state="inactive"
@@ -235,7 +233,7 @@
</li>
<li class="web-secondary-tabs-item">
<button
class="web-secondary-tabs-button u-width-full-line"
class="web-secondary-tabs-button w-full"
type="button"
role="tab"
data-state="inactive"
@@ -249,7 +247,7 @@
</li>
<li class="web-secondary-tabs-item">
<button
class="web-secondary-tabs-button u-width-full-line"
class="web-secondary-tabs-button w-full"
type="button"
role="tab"
data-state="inactive"
@@ -269,7 +267,7 @@
</div>
</div>-->
<div class="u-margin-block-start-48">
<div class="mt-12">
<ul class="web-grid-articles">
{#each posts.filter((p) => p.author === author?.slug) as post}
<Article
@@ -287,9 +285,9 @@
</div>
</div>
<div
class="web-big-padding-section-level-2 is-margin-replace-padding u-position-relative u-overflow-hidden"
class="web-big-padding-section-level-2 is-margin-replace-padding relative overflow-hidden"
>
<div class="web-container">
<div class="container">
<FooterNav />
<MainFooter />
</div>

View File

@@ -37,27 +37,23 @@
</svelte:head>
<Main>
<div class="web-big-padding-section-level-1">
<div class="py-10">
<div class="web-big-padding-section-level-2">
<div class="web-container">
<a class="web-link web-u-color-text-secondary u-cross-baseline" href="/blog">
<div class="container">
<a class="web-link web-u-color-text-secondary items-baseline" href="/blog">
<span class="web-icon-chevron-left" aria-hidden="true" />
<span>Back to blog</span>
</a>
<div class="web-category-header u-margin-block-start-24">
<div class="web-category-header mt-6">
<div class="web-category-header-content">
<h1 class="web-display web-u-color-text-primary">{name}</h1>
<p class="web-category-header-description web-description">
{description}
</p>
</div>
<!-- <div class="web-input-text-search-wrapper u-inline-width-100-percent-mobile">
<span class="icon-search" aria-hidden="true" />
<input class="web-input-text web-u-block-size-48" type="search" placeholder="Search" />
</div> -->
</div>
<div class="u-margin-block-start-48">
<div class="mt-12">
<ul class="web-grid-articles">
{#each posts as post}
{@const author = authors.find((a) => a.slug.includes(post.author))}
@@ -76,9 +72,9 @@
</ul>
</div>
<div
class="web-big-padding-section-level-2 is-margin-replace-padding u-position-relative u-overflow-hidden"
class="web-big-padding-section-level-2 is-margin-replace-padding relative overflow-hidden"
>
<div class="web-container">
<div class="container">
<FooterNav />
<MainFooter />
</div>

View File

@@ -41,13 +41,13 @@
<Main>
<div
class="web-u-sep-block-end u-padding-block-end-0"
class="web-u-sep-block-end pb-0"
style="background-color:rgba(23, 23, 26, 1); margin-block-end: 2.5rem"
>
<div class="web-container">
<div class="container">
<div class="web-integrations-top-section">
<div class="web-carousel-wrapper">
<a href="/integrations" class="web-button is-text u-margin-block-end-48">
<a href="/integrations" class="web-button is-text mb-12">
<span class="icon-cheveron-left" aria-hidden="true"></span>
<span>Back to catalog</span>
</a>
@@ -83,12 +83,12 @@
</div>
</div>
</div>
<div class="web-big-padding-section-level-1">
<div class="web-container">
<article class="u-flex-vertical web-u-gap-60-not-mobile web-u-gap-40-mobile">
<div class="py-10">
<div class="container">
<article class="web-u-gap-60-not-mobile web-u-gap-40-mobile flex flex-col">
<div class="l-grid-2-1 web-u-row-gap-56 web-u-gap-40-mobile">
<div class="l-grid-content">
<div class="u-flex u-cross-start u-gap-20">
<div class="flex items-start gap-5">
<img
class="web-author-image"
src={product.avatar}
@@ -98,7 +98,7 @@
height="40"
/>
<h1
class="web-title web-u-color-text-primary"
class="web-title web-u-color-text-primary justif"
style="max-width: 28.15rem;"
>
{title}
@@ -113,22 +113,22 @@
</div>
<div class="l-grid-sidebar">
<dl
class="u-flex-vertical u-gap-20 sidebar-desc"
class="flex-vertical sidebar-desc gap-5"
style:top={$isHeaderHidden ? '4rem' : '9rem'}
>
<div class="u-flex u-main-space-between u-gap-8">
<div class="flex justify-between gap-2">
<dt>Vendor</dt>
<dd class="web-u-color-text-primary">{product.vendor}</dd>
</div>
<div class="web-u-sep-block-end"></div>
{#if isPartner}
<div class="u-flex u-main-space-between u-gap-8">
<div class="flex justify-between gap-2">
<dt>Partner</dt>
<dd><div class="web-inline-tag">Verified</div></dd>
</div>
{/if}
<div class="web-u-sep-block-end"></div>
<div class="u-flex u-main-space-between u-gap-8">
<div class="flex justify-between gap-2">
<dt>Category</dt>
<dd class="web-u-color-text-primary">{category}</dd>
</div>
@@ -139,13 +139,11 @@
</div>
</div>
<div
class="web-big-padding-section-level-1 u-overflow-hidden web-u-sep-block-start u-margin-block-start-48"
>
<div class="web-u-sep-block-start mt-12 overflow-hidden py-10">
<!-- <ProductsGrid /> -->
<div class="web-container">
<div class="web-big-padding-section-level-2 u-position-relative">
<div class="container">
<div class="web-big-padding-section-level-2 relative">
<img
src="/images/bgs/pre-footer.png"
alt=""
@@ -153,13 +151,13 @@
style="z-index:-1"
/>
<!-- <div class="u-position-relative cta"> -->
<div class="u-position-relative">
<!-- <div class="relative cta"> -->
<div class="relative">
<section
class="web-hero u-flex u-row-gap-16 u-main-center u-cross-center web-u-max-width-580"
class="web-hero web-u-max-width-580 flex items-center justify-center gap-y-4"
>
<h2
class="web-display u-max-width-600 web-u-text-align-center web-u-color-text-primary"
class="web-display web-u-text-align-center web-u-color-text-primary max-w-[600px]"
>
Become a Technology Partner
</h2>
@@ -169,7 +167,7 @@
</p>
<a
href="/integrations/technology-partner"
class="web-button is-primary web-u-cross-child-center u-margin-block-start-16"
class="web-button is-primary mt-4 self-center"
>
<span class="text">Get Started</span>
</a>

View File

@@ -67,15 +67,15 @@
<Main omitMainId>
<TocRoot>
<div class="web-container">
<div class="container">
<div class="web-grid-120-1fr-auto">
<header class="web-grid-120-1fr-auto-header">
<h1 class="web-title web-u-color-text-primary">{title}</h1>
</header>
<button
class="toc-btn u-position-sticky u-flex u-width-full-line u-main-space-between u-cross-center
web-u-padding-20 web-u-margin-inline-20-negative web-u-color-text-primary web-is-only-mobile
u-margin-block-start-24 web-u-sep-block web-u-filter-blur-8"
class="toc-btn web-u-padding-20 web-u-margin-inline-20-negative web-u-color-text-primary web-is-only-mobile web-u-sep-block
web-u-filter-blur-8 sticky mt-6 flex
w-full items-center justify-between"
style:--inset-block-start="4.5rem"
style:inline-size="100vw"
style:background-color="hsl(var(--p-body-bg-color) / 0.1)"

View File

@@ -44,7 +44,7 @@
let copyText = CopyStatus.Copy;
async function handleCopy() {
const blogPostUrl = encodeURI(`https://appwrite.io${$page.url.pathname}`)
const blogPostUrl = encodeURI(`https://appwrite.io${$page.url.pathname}`);
await copy(blogPostUrl);
@@ -55,7 +55,7 @@
}
function getShareLink(shareOption: SocialShareOption): string {
const blogPostUrl = encodeURI(`https://appwrite.io${$page.url.pathname}`)
const blogPostUrl = encodeURI(`https://appwrite.io${$page.url.pathname}`);
const shareableLink = shareOption.link
.replace('{TITLE}', title + '.')
.replace('{URL}', blogPostUrl);
@@ -90,13 +90,13 @@
}}
>
<div class="web-big-padding-section">
<div class="web-big-padding-section-level-1">
<div class="py-10">
<div class="web-big-padding-section-level-2">
<div class="web-container" style="--container-size:42.5rem">
<div class="container" style="--container-size:42.5rem">
<article class="web-main-article">
<header class="web-main-article-header">
<a
class="web-link is-secondary web-u-color-text-secondary u-cross-baseline"
class="web-link is-secondary web-u-color-text-secondary items-baseline"
href="/blog"
>
<span class="web-icon-chevron-left" aria-hidden="true" />
@@ -112,16 +112,13 @@
</ul>
<h1 class="web-title web-u-color-text-primary">{title}</h1>
{#if description}
<p class="web-description u-margin-block-start-8">
<p class="web-description mt-2">
{description}
</p>
{/if}
{#if authorData}
<div class="web-author u-margin-block-start-16">
<a
href={authorData.href}
class="u-flex u-cross-center u-gap-8"
>
<div class="web-author mt-4">
<a href={authorData.href} class="flex items-center gap-2">
{#if authorData.avatar}
<img
class="web-author-image"
@@ -132,66 +129,30 @@
height="44"
/>
{/if}
<div class="u-flex-vertical">
<h4 class="web-sub-body-400 web-u-color-text-primary">
<div class="flex flex-col">
<h4
class="web-sub-body-400 web-u-color-text-primary"
>
{authorData.name}
</h4>
<p class="web-caption-400">{authorData.role}</p>
</div>
</a>
<!-- <ul class="u-flex u-gap-8 u-margin-inline-start-auto u-cross-child-center">
{#if authorData.twitter}
<li>
<a
href={authorData.twitter}
class="web-icon-button"
aria-label="Author twitter"
target="_blank" rel="noopener noreferrer"
>
<span class="web-icon-x" aria-hidden="true" />
</a>
</li>
{/if}
{#if authorData.linkedin}
<li>
<a
href={authorData.linkedin}
class="web-icon-button"
aria-label="Author LinkedIn"
target="_blank" rel="noopener noreferrer"
>
<span class="web-icon-linkedin" aria-hidden="true" />
</a>
</li>
{/if}
{#if authorData.github}
<li>
<a
href={authorData.github}
class="web-icon-button"
aria-label="Author GitHub"
target="_blank" rel="noopener noreferrer"
>
<span class="web-icon-github" aria-hidden="true" />
</a>
</li>
{/if}
</ul> -->
</div>
{/if}
<div class="share-post-section u-flex u-gap-16 u-margin-block-start-16 u-cross-center">
<span class="web-eyebrow u-padding-inline-end-8" style:color="#adadb0">
<div class="share-post-section mt-4 flex items-center gap-4">
<span class="web-eyebrow pr-2" style:color="#adadb0">
SHARE
</span>
<ul class="u-flex u-gap-8">
<ul class="flex gap-2">
{#each socialSharingOptions as sharingOption}
<li class="share-list-item">
<Tooltip placement="bottom" disableHoverableContent={true}>
<Tooltip
placement="bottom"
disableHoverableContent={true}
>
{#if sharingOption.type === 'link'}
<a
class="web-icon-button"
@@ -200,24 +161,28 @@
target="_blank"
rel="noopener, noreferrer"
>
<span class={sharingOption.icon} aria-hidden="true" />
<span
class={sharingOption.icon}
aria-hidden="true"
/>
</a>
{:else}
<button
class="web-icon-button"
aria-label={sharingOption.label}
on:click="{() => handleCopy()}"
on:click={() => handleCopy()}
>
<span class={sharingOption.icon} aria-hidden="true" />
<span
class={sharingOption.icon}
aria-hidden="true"
/>
</button>
{/if}
<svelte:fragment slot="tooltip">
{
sharingOption.type === 'copy'
{sharingOption.type === 'copy'
? copyText
: `Share on ${sharingOption.label}`
}
: `Share on ${sharingOption.label}`}
</svelte:fragment>
</Tooltip>
</li>
@@ -227,11 +192,11 @@
</header>
{#if cover}
<div class="web-media-container">
<Media class="u-block" src={cover} />
<Media class="block" src={cover} />
</div>
{/if}
<div class="web-article-content u-margin-block-start-32">
<div class="web-article-content mt-8">
{#if lastUpdated}
<span class="web-main-body-500 last-updated-text">
Updated:
@@ -245,7 +210,7 @@
</div>
</article>
<!-- {#if categories?.length}
<div class="u-flex u-gap-16">
<div class="flex gap-4">
{#each categories as cat}
<a href={cat.href} class="web-tag">{cat.name}</a>
{/each}
@@ -257,11 +222,11 @@
</div>
</div>
<div class="web-big-padding-section-level-1 web-u-sep-block-start">
<div class="web-u-sep-block-start py-10">
<div class="web-big-padding-section-level-2">
<div class="web-container">
<div class="container">
<h3 class="web-label web-u-color-text-primary">Read next</h3>
<section class="u-margin-block-start-32">
<section class="mt-8">
<ul class="web-grid-articles">
{#each posts.filter((p) => p.title !== title).slice(0, 3) as post}
{@const author = authors.find((a) => a.slug === post.author)}
@@ -281,8 +246,8 @@
</section>
</div>
</div>
<div class="web-big-padding-section-level-2 u-position-relative u-overflow-hidden">
<div class="web-container">
<div class="web-big-padding-section-level-2 relative overflow-hidden">
<div class="container">
<Newsletter />
<FooterNav />
<MainFooter />
@@ -324,9 +289,9 @@
.web-icon-copy {
font-size: 24px;
}
}
.last-updated-text {
color: var(--primary, #e4e4e7);
}
}
</style>

View File

@@ -1,8 +1,9 @@
<script lang="ts">
import { setContext } from "svelte";
import { setContext } from 'svelte';
setContext("no-paragraph", true);
setContext('no-paragraph', true);
</script>
<blockquote class="web-blockquote">
<p class="web-description">
<slot />

View File

@@ -61,18 +61,18 @@
{@html result}
{/if}
{:else}
<section class="theme-dark web-code-snippet" aria-label="code-snippet panel">
<section class="dark web-code-snippet" aria-label="code-snippet panel">
<header class="web-code-snippet-header">
<div class="web-code-snippet-header-start">
{#if badgeValue}
<div class="u-flex u-gap-16">
<div class="flex gap-4">
<div class="web-tag"><span class="text">{badgeValue}</span></div>
</div>
{/if}
</div>
<div class="web-code-snippet-header-end">
<ul class="buttons-list u-flex u-gap-8">
<li class="buttons-list-item web-u-padding-inline-start-20">
<ul class="buttons-list flex gap-2">
<li class="buttons-list-item ps-5">
<Tooltip>
<button
slot="asChild"

View File

@@ -22,7 +22,7 @@
{#if inTable || isAudio}
{#if isAudio}
<audio {src} controls class="u-width-full-line">
<audio {src} controls class="w-full">
Your browser does not support the audio element.
</audio>
{:else}
@@ -30,7 +30,7 @@
{/if}
{:else}
<div class="web-media main">
<img {src} {alt} {title} loading="lazy" class="web-u-media-ratio-16-9 u-width-full-line" />
<img {src} {alt} {title} loading="lazy" class="web-u-media-ratio-16-9 w-full" />
<div class="abs">
<Tooltip closeOnPointerDown>
<button class="web-button is-secondary" use:melt={$trigger}>

View File

@@ -1 +1 @@
<strong class="u-bold"><slot /></strong>
<strong class="font-bold"><slot /></strong>

View File

@@ -11,12 +11,12 @@
<li>
<a {href} class="web-card is-normal" style:margin-block-end="0">
<img src={dark} alt="" class="u-only-dark" width="32" height="32" />
<img src={light} alt="" class="u-only-light" width="32" height="32" />
<h4 class="web-sub-body-500 web-u-color-text-primary u-margin-block-start-8">
<img src={dark} alt="" class="hidden dark:block" width="32" height="32" />
<img src={light} alt="" class="block dark:hidden" width="32" height="32" />
<h4 class="web-sub-body-500 web-u-color-text-primary mt-2">
{title}
</h4>
<p class="web-sub-body-400 u-margin-block-start-4">
<p class="web-sub-body-400 mt-1">
<slot />
</p>
</a>

View File

@@ -10,18 +10,15 @@
<li>
<a {href} class="web-card is-normal" style:margin-block-end="0">
<header class="u-flex u-cross-baseline u-gap-4">
<header class="flex items-baseline gap-1">
{#if icon}
<span
class="{icon} web-u-font-size-24"
aria-hidden="true"
/>
<span class="{icon} web-u-font-size-24" aria-hidden="true" />
{/if}
<h4 class="web-sub-body-500 web-u-color-text-primary">
{title}
</h4>
</header>
<p class="web-sub-body-400 u-margin-block-start-4" style:margin-block="0">
<p class="web-sub-body-400 mt-1" style:margin-block="0">
<slot />
</p>
</a>

View File

@@ -44,16 +44,16 @@
}
</script>
<section class="theme-dark web-code-snippet" aria-label="code-snippet panel">
<section class="dark web-code-snippet" aria-label="code-snippet panel">
<header class="web-code-snippet-header">
<div class="web-code-snippet-header-start">
<div class="u-flex u-gap-16">
<div class="flex gap-4">
<!-- <div class="web-tag"><span class="text">Default</span></div> -->
</div>
</div>
<div class="web-code-snippet-header-end">
<ul class="buttons-list u-flex u-gap-12">
<li class="buttons-list-item u-flex u-cross-child-scenter">
<ul class="buttons-list flex gap-3">
<li class="buttons-list-item flex self-center">
<Select
bind:value={$selected}
options={Array.from($snippets).map((language) => ({

View File

@@ -1 +1 @@
<span class="u-only-dark"><slot /></span>
<span class="hidden dark:block"><slot /></span>

View File

@@ -1 +1 @@
<span class="u-only-light"><slot /></span>
<span class="block dark:hidden"><slot /></span>

View File

@@ -25,8 +25,8 @@
);
</script>
<div class="web-card is-normal u-margin-block-start-16" {...$root} use:root>
<div class="tabs u-flex u-gap-16">
<div class="web-card is-normal mt-4" {...$root} use:root>
<div class="tabs flex gap-4">
<ul class="tabs-list" {...$list} use:list>
{#each $ctx.triggers.entries() as [id, title]}
<li class="tabs-item">
@@ -36,7 +36,6 @@
{...$trigger(id)}
use:trigger>{title}</button
>
</li>
{/each}
</ul>

View File

@@ -15,6 +15,6 @@
});
</script>
<div class="web-u-sep-block-start u-padding-block-start-16" {...$content(id)} use:content>
<div class="web-u-sep-block-start pt-4" {...$content(id)} use:content>
<slot />
</div>

View File

@@ -9,7 +9,7 @@
<div class="web-media">
<!-- svelte-ignore a11y-media-has-caption -->
<video {src} class="web-u-media-ratio-16-9 u-width-full-line" controls {autoplay} {loop}>
<video {src} class="web-u-media-ratio-16-9 w-full" controls {autoplay} {loop}>
<source {src} {type} />
</video>
</div>

View File

@@ -6,9 +6,5 @@
</script>
<div class="web-media">
<Video
{thumbnail}
src={src}
--p-aspect-ratio="16/9"
/>
<Video {thumbnail} {src} --p-aspect-ratio="16/9" />
</div>

View File

@@ -1,4 +1,3 @@
{% info title="Account vs Users API" %}
The Account API is the API you should use in your **client applications** with [Client SDKs](/docs/sdks#client) like web, Flutter, mobile, and native apps.
Account API creates sessions, which represent an authenticated user and is attached to a user's [account](/docs/products/auth/accounts).

View File

@@ -1,144 +1,174 @@
{% table %}
* Name
* Description
- Name
- Description
---
* `teams.*`
*
This event triggers on any teams event.
- `teams.*`
- This event triggers on any teams event.
Returns [Team Object](/docs/references/cloud/models/team)
---
* `teams.*.create`
*
This event triggers when a team is created.
- `teams.*.create`
- This event triggers when a team is created.
Returns [Team Object](/docs/references/cloud/models/team)
---
* `teams.*.delete`
*
This event triggers when a team is deleted.
- `teams.*.delete`
- This event triggers when a team is deleted.
Returns [Team Object](/docs/references/cloud/models/team)
---
* `teams.*.memberships.*`
*
This event triggers on any team memberships event.
- `teams.*.memberships.*`
- This event triggers on any team memberships event.
Returns [Membership Object](/docs/references/cloud/models/membership)
---
* `teams.*.memberships.*.create`
*
This event triggers when a membership is created.
- `teams.*.memberships.*.create`
- This event triggers when a membership is created.
Returns [Membership Object](/docs/references/cloud/models/membership)
---
* `teams.*.memberships.*.delete`
*
This event triggers when a membership is deleted.
- `teams.*.memberships.*.delete`
- This event triggers when a membership is deleted.
Returns [Membership Object](/docs/references/cloud/models/membership)
---
* `teams.*.memberships.*.update`
*
This event triggers when a membership is updated.
- `teams.*.memberships.*.update`
- This event triggers when a membership is updated.
Returns [Membership Object](/docs/references/cloud/models/membership)
---
* `teams.*.memberships.*.update.status`
*
This event triggers when a team memberships status is updated.
- `teams.*.memberships.*.update.status`
- This event triggers when a team memberships status is updated.
Returns [Membership Object](/docs/references/cloud/models/membership)
---
* `teams.*.update`
*
This event triggers when a team is updated.
- `teams.*.update`
- This event triggers when a team is updated.
Returns [Team Object](/docs/references/cloud/models/team)
---
* `teams.*.update.prefs`
*
This event triggers when a team's preferences are updated.
- `teams.*.update.prefs`
- This event triggers when a team's preferences are updated.
Returns [Team Object](/docs/references/cloud/models/team)
---
* `users.*`
*
This event triggers on any user's event.
- `users.*`
- This event triggers on any user's event.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.create`
*
This event triggers when a user is created.
- `users.*.create`
- This event triggers when a user is created.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.delete`
*
This event triggers when a user is deleted.
- `users.*.delete`
- This event triggers when a user is deleted.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.recovery.*`
*
This event triggers on any user's recovery token event.
- `users.*.recovery.*`
- This event triggers on any user's recovery token event.
Returns [Token Object](/docs/references/cloud/models/token)
---
* `users.*.recovery.*.create`
*
This event triggers when a recovery token for a user is created.
- `users.*.recovery.*.create`
- This event triggers when a recovery token for a user is created.
Returns [Token Object](/docs/references/cloud/models/token)
---
* `users.*.recovery.*.update`
*
This event triggers when a recovery token for a user is validated.
- `users.*.recovery.*.update`
- This event triggers when a recovery token for a user is validated.
Returns [Token Object](/docs/references/cloud/models/token)
---
* `users.*.sessions.*`
*
This event triggers on any user's sessions event.
- `users.*.sessions.*`
- This event triggers on any user's sessions event.
Returns [Session Object](/docs/references/cloud/models/session)
---
* `users.*.sessions.*.create`
*
This event triggers when a session for a user is created.
- `users.*.sessions.*.create`
- This event triggers when a session for a user is created.
Returns [Session Object](/docs/references/cloud/models/session)
---
* `users.*.sessions.*.delete`
*
This event triggers when a session for a user is deleted.
- `users.*.sessions.*.delete`
- This event triggers when a session for a user is deleted.
Returns [Session Object](/docs/references/cloud/models/session)
---
* `users.*.update`
*
This event triggers when a user is updated.
- `users.*.update`
- This event triggers when a user is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.update.email`
*
This event triggers when a user's email address is updated.
- `users.*.update.email`
- This event triggers when a user's email address is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.update.name`
*
This event triggers when a user's name is updated.
- `users.*.update.name`
- This event triggers when a user's name is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.update.password`
*
This event triggers when a user's password is updated.
- `users.*.update.password`
- This event triggers when a user's password is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.update.prefs`
*
This event triggers when a user's preferences is updated.
- `users.*.update.prefs`
- This event triggers when a user's preferences is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.update.status`
*
This event triggers when a user's status is updated.
- `users.*.update.status`
- This event triggers when a user's status is updated.
Returns [User Object](/docs/references/cloud/models/user)
---
* `users.*.verification.*`
*
This event triggers on any user's verification token event.
- `users.*.verification.*`
- This event triggers on any user's verification token event.
Returns [Token Object](/docs/references/cloud/models/token)
---
* `users.*.verification.*.create`
*
This event triggers when a verification token for a user is created.
- `users.*.verification.*.create`
- This event triggers when a verification token for a user is created.
Returns [Token Object](/docs/references/cloud/models/token)
---
* `users.*.verification.*.update`
*
This event triggers when a verification token for a user is validated.
- `users.*.verification.*.update`
- This event triggers when a verification token for a user is validated.
Returns [Token Object](/docs/references/cloud/models/token)
{% /table %}

View File

@@ -11,6 +11,7 @@ Password dictionary protects users from using bad passwords. It compares the use
Password dictionary can be enabled in the Auth service's **Security** tab on the Appwrite Console.
# Password hashing {% #password-hashing %}
Appwrite protects passwords by using the [Argon2](https://github.com/P-H-C/phc-winner-argon2) password-hashing algorithm.
Argon 2 is a resilient and secure password hashing algorithm that is also the winner of the [Password Hashing Competition](https://www.password-hashing.net/).

View File

@@ -7,6 +7,7 @@ To deploy your function with the Appwrite CLI, use the `appwrite init functions`
```sh
appwrite init functions
```
To deploy the generated code, add any dependencies and push the function using the following command:
```sh

View File

@@ -1,93 +1,112 @@
{% table %}
* Name
* Description
- Name
- Description
---
* `databases.*`
*
This event triggers on any database event.
- `databases.*`
- This event triggers on any database event.
Returns [Database Object](/docs/references/cloud/models/database)
---
* `databases.*.collections.*`
*
This event triggers on any collection event.
- `databases.*.collections.*`
- This event triggers on any collection event.
Returns [Collection Object](/docs/references/cloud/models/collection)
---
* `databases.*.collections.*.attributes.*`
*
This event triggers on any attributes event.
- `databases.*.collections.*.attributes.*`
- This event triggers on any attributes event.
Returns [Attribute Object](/docs/references/cloud/models/attributeList)
---
* `databases.*.collections.*.attributes.*.create`
*
This event triggers when an attribute is created.
- `databases.*.collections.*.attributes.*.create`
- This event triggers when an attribute is created.
Returns [Attribute Object](/docs/references/cloud/models/attributeList)
---
* `databases.*.collections.*.attributes.*.delete`
*
This event triggers when an attribute is deleted.
- `databases.*.collections.*.attributes.*.delete`
- This event triggers when an attribute is deleted.
Returns [Attribute Object](/docs/references/cloud/models/attributeList)
---
* `databases.*.collections.*.create`
*
This event triggers when a collection is created.
- `databases.*.collections.*.create`
- This event triggers when a collection is created.
Returns [Collection Object](/docs/references/cloud/models/collection)
---
* `databases.*.collections.*.delete`
*
This event triggers when a collection is deleted.
- `databases.*.collections.*.delete`
- This event triggers when a collection is deleted.
Returns [Collection Object](/docs/references/cloud/models/collection)
---
* `databases.*.collections.*.documents.*`
*
This event triggers on any documents event.
- `databases.*.collections.*.documents.*`
- This event triggers on any documents event.
Returns [Document Object](/docs/references/cloud/models/document)
---
* `databases.*.collections.*.documents.*.create`
*
This event triggers when a document is created.
- `databases.*.collections.*.documents.*.create`
- This event triggers when a document is created.
Returns [Document Object](/docs/references/cloud/models/document)
---
* `databases.*.collections.*.documents.*.delete`
*
This event triggers when a document is deleted.
- `databases.*.collections.*.documents.*.delete`
- This event triggers when a document is deleted.
Returns [Document Object](/docs/references/cloud/models/document)
---
* `databases.*.collections.*.documents.*.update`
*
This event triggers when a document is updated.
- `databases.*.collections.*.documents.*.update`
- This event triggers when a document is updated.
Returns [Document Object](/docs/references/cloud/models/document)
---
* `databases.*.collections.*.indexes.*`
*
This event triggers on any indexes event.
- `databases.*.collections.*.indexes.*`
- This event triggers on any indexes event.
Returns [Index Object](/docs/references/cloud/models/index)
---
* `databases.*.collections.*.indexes.*.create`
*
This event triggers when an index is created.
- `databases.*.collections.*.indexes.*.create`
- This event triggers when an index is created.
Returns [Index Object](/docs/references/cloud/models/index)
---
* `databases.*.collections.*.indexes.*.delete`
*
This event triggers when an index is deleted.
- `databases.*.collections.*.indexes.*.delete`
- This event triggers when an index is deleted.
Returns [Index Object](/docs/references/cloud/models/index)
---
* `databases.*.collections.*.update`
*
This event triggers when a collection is updated.
- `databases.*.collections.*.update`
- This event triggers when a collection is updated.
Returns [Collection Object](/docs/references/cloud/models/collection)
---
* `databases.*.create`
*
This event triggers when a database is created.
- `databases.*.create`
- This event triggers when a database is created.
Returns [Database Object](/docs/references/cloud/models/database)
---
* `databases.*.delete`
*
This event triggers when a database is deleted.
- `databases.*.delete`
- This event triggers when a database is deleted.
Returns [Database Object](/docs/references/cloud/models/database)
---
* `databases.*.update`
*
This event triggers when a database is updated.
- `databases.*.update`
- This event triggers when a database is updated.
Returns [Database Object](/docs/references/cloud/models/database){% /table %}

View File

@@ -1,64 +1,78 @@
{% table %}
* Name
* Description
- Name
- Description
---
* `functions.*`
*
This event triggers on any functions event.
- `functions.*`
- This event triggers on any functions event.
Returns [Function Object](/docs/references/cloud/models/function)
---
* `functions.*.create`
*
This event triggers when a function is created.
- `functions.*.create`
- This event triggers when a function is created.
Returns [Function Object](/docs/references/cloud/models/function)
---
* `functions.*.delete`
*
This event triggers when a function is deleted.
- `functions.*.delete`
- This event triggers when a function is deleted.
Returns [Function Object](/docs/references/cloud/models/function)
---
* `functions.*.deployments.*`
*
This event triggers on any deployments event.
- `functions.*.deployments.*`
- This event triggers on any deployments event.
Returns [Deployment Object](/docs/references/cloud/models/deployment)
---
* `functions.*.deployments.*.create`
*
This event triggers when a deployment is created.
- `functions.*.deployments.*.create`
- This event triggers when a deployment is created.
Returns [Deployment Object](/docs/references/cloud/models/deployment)
---
* `functions.*.deployments.*.delete`
*
This event triggers when a deployment is deleted.
- `functions.*.deployments.*.delete`
- This event triggers when a deployment is deleted.
Returns [Deployment Object](/docs/references/cloud/models/deployment)
---
* `functions.*.deployments.*.update`
*
This event triggers when a deployment is updated.
- `functions.*.deployments.*.update`
- This event triggers when a deployment is updated.
Returns [Deployment Object](/docs/references/cloud/models/deployment)
---
* `functions.*.executions.*`
*
This event triggers on any executions event.
- `functions.*.executions.*`
- This event triggers on any executions event.
Returns [Execution Object](/docs/references/cloud/models/execution)
---
* `functions.*.executions.*.create`
*
This event triggers when an execution is created.
- `functions.*.executions.*.create`
- This event triggers when an execution is created.
Returns [Execution Object](/docs/references/cloud/models/execution)
---
* `functions.*.executions.*.delete`
*
This event triggers when an execution is deleted.
- `functions.*.executions.*.delete`
- This event triggers when an execution is deleted.
Returns [Execution Object](/docs/references/cloud/models/execution)
---
* `functions.*.executions.*.update`
*
This event triggers when an execution is updated.
- `functions.*.executions.*.update`
- This event triggers when an execution is updated.
Returns [Execution Object](/docs/references/cloud/models/execution)
---
* `functions.*.update`
*
This event triggers when a function is updated.
- `functions.*.update`
- This event triggers when a function is updated.
Returns [Function Object](/docs/references/cloud/models/function)
{% /table %}

View File

@@ -1,74 +1,90 @@
{% table %}
* Name
* Description
- Name
- Description
---
* `providers.*`
*
This event triggers on any providers event.
- `providers.*`
- This event triggers on any providers event.
Returns [Provider Object](/docs/references/cloud/models/provider)
---
* `providers.*.create`
*
This event triggers when a provider is created.
- `providers.*.create`
- This event triggers when a provider is created.
Returns [Provider Object](/docs/references/cloud/models/provider)
---
* `providers.*.delete`
*
This event triggers when a provider is deleted.
- `providers.*.delete`
- This event triggers when a provider is deleted.
Returns [Provider Object](/docs/references/cloud/models/provider)
---
* `providers.*.update`
*
This event triggers when a provider is updated.
- `providers.*.update`
- This event triggers when a provider is updated.
Returns [Provider Object](/docs/references/cloud/models/provider)
---
* `topics.*`
*
This event triggers on any topic event.
- `topics.*`
- This event triggers on any topic event.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `topics.*.create`
*
This event triggers when a topic is created.
- `topics.*.create`
- This event triggers when a topic is created.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `topics.*.delete`
*
This event triggers when a topic is deleted.
- `topics.*.delete`
- This event triggers when a topic is deleted.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `topics.*.update`
*
This event triggers when a topic is updated.
- `topics.*.update`
- This event triggers when a topic is updated.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `topics.*.subscribers.*.create`
*
This event triggers when a subscriber to a topic is created.
- `topics.*.subscribers.*.create`
- This event triggers when a subscriber to a topic is created.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `topics.*.subscribers.*.delete`
*
This event triggers when a subscriber to a topic is deleted.
- `topics.*.subscribers.*.delete`
- This event triggers when a subscriber to a topic is deleted.
Returns [Topic Object](/docs/references/cloud/models/topic)
---
* `messages.*`
*
This event triggers on any message event.
- `messages.*`
- This event triggers on any message event.
Returns [Message Object](/docs/references/cloud/models/message)
---
* `messages.*.create`
*
This event triggers when a message is created.
- `messages.*.create`
- This event triggers when a message is created.
Returns [Message Object](/docs/references/cloud/models/message)
---
* `messages.*.delete`
*
This event triggers when a message is deleted.
- `messages.*.delete`
- This event triggers when a message is deleted.
Returns [Message Object](/docs/references/cloud/models/message)
---
* `messages.*.update`
*
This event triggers when a message is updated.
- `messages.*.update`
- This event triggers when a message is updated.
Returns [Message Object](/docs/references/cloud/models/message)
{% /table %}

View File

@@ -42,6 +42,7 @@ Reaching your organization's resource limits will have the following effects unt
- **Storage**
- File uploads are disabled. Persists across billing periods until the amount of storage used is below the plan limit.
{% /table %}
## Switching to Free plan and reaching limits {% #switching-to-free-plan-reaching-resource-limits %}
@@ -86,4 +87,5 @@ The following consequences should also apply at the project level if the Free pl
- **Functions**
- If more than 5 functions have been created, disable them in order of date created (oldest ones first).
{% /table %}

View File

@@ -1,44 +1,54 @@
{% table %}
* Name
* Description
- Name
- Description
---
* `buckets.*`
*
This event triggers on any buckets event.
- `buckets.*`
- This event triggers on any buckets event.
Returns [Bucket Object](/docs/references/cloud/models/bucket)
---
* `buckets.*.create`
*
This event triggers when a bucket is created.
- `buckets.*.create`
- This event triggers when a bucket is created.
Returns [Bucket Object](/docs/references/cloud/models/bucket)
---
* `buckets.*.delete`
*
This event triggers when a bucket is deleted.
- `buckets.*.delete`
- This event triggers when a bucket is deleted.
Returns [Bucket Object](/docs/references/cloud/models/bucket)
---
* `buckets.*.files.*`
*
This event triggers on any files event.
- `buckets.*.files.*`
- This event triggers on any files event.
Returns [File Object](/docs/references/cloud/models/file)
---
* `buckets.*.files.*.create`
*
This event triggers when a file is created.
- `buckets.*.files.*.create`
- This event triggers when a file is created.
Returns [File Object](/docs/references/cloud/models/file)
---
* `buckets.*.files.*.delete`
*
This event triggers when a file is deleted.
- `buckets.*.files.*.delete`
- This event triggers when a file is deleted.
Returns [File Object](/docs/references/cloud/models/file)
---
* `buckets.*.files.*.update`
*
This event triggers when a file is updated.
- `buckets.*.files.*.update`
- This event triggers when a file is updated.
Returns [File Object](/docs/references/cloud/models/file)
---
* `buckets.*.update`
*
This event triggers when a bucket is updated.
- `buckets.*.update`
- This event triggers when a bucket is updated.
Returns [Bucket Object](/docs/references/cloud/models/bucket)
{% /table %}

View File

@@ -1,12 +1,15 @@
{% info title="Applying changes" %}
After editing your `docker-compose.yml` or `.env` files, you will need to recreate your Appwrite stack by running the following compose command in your terminal.
```sh
docker compose up -d
```
You can verify if the changes have been successfully applied by running this command:
```sh
docker compose exec appwrite vars
```
{% /info %}

View File

@@ -13,26 +13,25 @@
<Main>
<div class="web-big-padding-section">
<div class="web-big-padding-section-level-2">
<div class="web-container">
<div class="container">
<div class="web-hero" style="--hero-gap:1.25rem;">
<span class="web-badges web-eyebrow">{$page.status}</span>
<span class="web-badges web-eyebrow !text-white">{$page.status}</span>
<h1 class="web-headline web-u-color-text-primary">
{$page.error?.message ?? 'An error has occured'}
</h1>
{#if $page.status === 404}
<p class="web-description">
Sorry, it seems that the page you are looking for does not exist. Feel free to use
our navigation menu or the button below to explore more of Appwrite's documentation.
Sorry, it seems that the page you are looking for does not exist.
Feel free to use our navigation menu or the button below to explore
more of Appwrite's documentation.
</p>
{/if}
<a href="/" class="web-button is-secondary u-cross-child-center u-margin-block-start-12">
<span>Back to homepage</span>
</a>
<a href="/" class="web-button self-center">Back to homepage</a>
</div>
</div>
</div>
<div class="web-big-padding-section-level-2 u-position-relative">
<div class="web-container">
<div class="web-big-padding-section-level-2 relative">
<div class="container">
<FooterNav />
<MainFooter />
</div>

Some files were not shown because too many files have changed in this diff Show More