Compare commits
305 Commits
jazz-tools
...
perf/skip-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0eb3d3096 | ||
|
|
6f0f8c0cd0 | ||
|
|
9f6079b6c6 | ||
|
|
4033d78fa6 | ||
|
|
83af94c850 | ||
|
|
70fe856713 | ||
|
|
42e4afc42b | ||
|
|
0e6797b222 | ||
|
|
3634eaf8e9 | ||
|
|
58dfda3d0f | ||
|
|
d304b0bcb5 | ||
|
|
44f5a3f5a2 | ||
|
|
ebb3ce1c25 | ||
|
|
a67bba0dcf | ||
|
|
4a72c26e42 | ||
|
|
2e0aefaeb8 | ||
|
|
084cb5936d | ||
|
|
8a3be85e97 | ||
|
|
1a7f2b7379 | ||
|
|
caac82dffd | ||
|
|
27b48378e5 | ||
|
|
cfd3c3ca5c | ||
|
|
41f26b7a4f | ||
|
|
c57ebb1cea | ||
|
|
259aded5cc | ||
|
|
1f5e091dd7 | ||
|
|
bbb1c44977 | ||
|
|
4327ecbfdf | ||
|
|
114c10bc77 | ||
|
|
cecdf29721 | ||
|
|
bd717fc0d7 | ||
|
|
739fff68b3 | ||
|
|
d49cab0afa | ||
|
|
ffebb4fdaf | ||
|
|
32565f0e53 | ||
|
|
61a5889bea | ||
|
|
82bd3e1ea6 | ||
|
|
b800a6fba2 | ||
|
|
1b6dbfdfff | ||
|
|
061a70f1b3 | ||
|
|
f1c1e0dafd | ||
|
|
c3912fdb37 | ||
|
|
356bfa4860 | ||
|
|
38446668c4 | ||
|
|
e2bb3b8015 | ||
|
|
11dcfd703d | ||
|
|
0b09d23bd1 | ||
|
|
879b726537 | ||
|
|
66bbd03262 | ||
|
|
c09b63698f | ||
|
|
bed7db0a33 | ||
|
|
8ff3e234c1 | ||
|
|
296da5a5c4 | ||
|
|
700a4f1ba1 | ||
|
|
6f6663d825 | ||
|
|
844cdc907f | ||
|
|
9e32d4cb92 | ||
|
|
85dc6ba148 | ||
|
|
16c4d27e00 | ||
|
|
69170fe0e0 | ||
|
|
a646ba54b3 | ||
|
|
45d60fc3c8 | ||
|
|
6f0c399ccd | ||
|
|
40e1ca7cb1 | ||
|
|
80cf21e453 | ||
|
|
48c8a3d219 | ||
|
|
31bb1201fc | ||
|
|
08d1b05607 | ||
|
|
d64a14210d | ||
|
|
7e53d33e9b | ||
|
|
ea2b39cc30 | ||
|
|
6b835f95cf | ||
|
|
a229ae5f70 | ||
|
|
84fdc1d8fd | ||
|
|
9b1d52d183 | ||
|
|
14a8b32522 | ||
|
|
ddc09a0d6b | ||
|
|
3b45a3f2fd | ||
|
|
9034a45da0 | ||
|
|
6247fac6c5 | ||
|
|
a5ceaffb0c | ||
|
|
dcee2f9b4e | ||
|
|
f27a2c541e | ||
|
|
83fdc504ff | ||
|
|
2317a23fd4 | ||
|
|
a34c0675cd | ||
|
|
5a8a62b4a3 | ||
|
|
325a554bd1 | ||
|
|
7422943e83 | ||
|
|
23bfea5861 | ||
|
|
605a54eb11 | ||
|
|
a7aaee51e6 | ||
|
|
4b8983858a | ||
|
|
8a8c4d11e1 | ||
|
|
26994684d7 | ||
|
|
14a5e036a4 | ||
|
|
5b1c1ca522 | ||
|
|
a9c8458c51 | ||
|
|
5f31d6cbe1 | ||
|
|
b774bb345d | ||
|
|
7fd891d7b9 | ||
|
|
27cac4a6d7 | ||
|
|
2b71ef1181 | ||
|
|
ae169c7b3a | ||
|
|
d888c99d9a | ||
|
|
0b54917f19 | ||
|
|
c87b215b75 | ||
|
|
e4ba23cbef | ||
|
|
98c005a6e0 | ||
|
|
477fd8a62d | ||
|
|
90999ee709 | ||
|
|
38065f0cdf | ||
|
|
c77d16cdb3 | ||
|
|
9410084e6a | ||
|
|
8528db4de4 | ||
|
|
e0fe5a20b7 | ||
|
|
e16e4d53d1 | ||
|
|
d904fae506 | ||
|
|
f67c0b3db3 | ||
|
|
283d7c6bf0 | ||
|
|
e67c5838a9 | ||
|
|
0e7a7dbbc0 | ||
|
|
63c69b6b95 | ||
|
|
a141cbc7f7 | ||
|
|
6a5352cf3a | ||
|
|
27762637ee | ||
|
|
dcebe34891 | ||
|
|
99d510815f | ||
|
|
928962c08b | ||
|
|
cdadd6db1d | ||
|
|
d45b8ae70b | ||
|
|
445a58c864 | ||
|
|
1895b474ea | ||
|
|
fd02627069 | ||
|
|
827adc991d | ||
|
|
651b69e5af | ||
|
|
277e4d49e8 | ||
|
|
8990ff39a5 | ||
|
|
71e4c97255 | ||
|
|
577e960e28 | ||
|
|
f232f75d40 | ||
|
|
cfa44f32eb | ||
|
|
ef920435e9 | ||
|
|
87d05404dd | ||
|
|
535c460f5a | ||
|
|
e1a7f829b4 | ||
|
|
fa1b302474 | ||
|
|
45f73a774c | ||
|
|
2a9e271dc3 | ||
|
|
3d96d9c829 | ||
|
|
844051405d | ||
|
|
625eff2333 | ||
|
|
59e2871065 | ||
|
|
acdc88fb91 | ||
|
|
05eab4e2a9 | ||
|
|
efcd65ae38 | ||
|
|
f82177b9da | ||
|
|
ad60fa942a | ||
|
|
c1c553bad0 | ||
|
|
5272d3cd2a | ||
|
|
588ea02f63 | ||
|
|
d837811813 | ||
|
|
2b4aba2d1b | ||
|
|
50b4da18d9 | ||
|
|
df22f2617e | ||
|
|
ddc69f2268 | ||
|
|
7c62689319 | ||
|
|
280495c533 | ||
|
|
d5c6fbdc3c | ||
|
|
57776a1400 | ||
|
|
156c45aa0e | ||
|
|
2d0dba6bbc | ||
|
|
7241d2ad95 | ||
|
|
4a9eeace00 | ||
|
|
4f9c91f6ff | ||
|
|
7ff13a8f55 | ||
|
|
5741d7f09c | ||
|
|
766d2c8846 | ||
|
|
70a43d0c39 | ||
|
|
cf44258848 | ||
|
|
4db5ec2dd8 | ||
|
|
4983e57e62 | ||
|
|
5b2fc70ca1 | ||
|
|
53af54570c | ||
|
|
e0b4626c22 | ||
|
|
a273a0db58 | ||
|
|
277104ebba | ||
|
|
434e59d5c4 | ||
|
|
bb20907774 | ||
|
|
282425575f | ||
|
|
75501a9051 | ||
|
|
c114cf4029 | ||
|
|
03da7dc994 | ||
|
|
12d5c68f98 | ||
|
|
ec1e359621 | ||
|
|
44fb13ddd7 | ||
|
|
4fd4c5bbed | ||
|
|
a1d31566ed | ||
|
|
dcde3aa811 | ||
|
|
a621141d76 | ||
|
|
0e1fbd7dfc | ||
|
|
27efdf9b8e | ||
|
|
83068b33e9 | ||
|
|
769d9b0517 | ||
|
|
b0ffe5ed7e | ||
|
|
c67a0cd3ce | ||
|
|
48e11a243f | ||
|
|
de904698d8 | ||
|
|
7c8180dcb4 | ||
|
|
da3e101c50 | ||
|
|
7605d228f2 | ||
|
|
3063d74ab9 | ||
|
|
2a4e3fc0cd | ||
|
|
7cc6d63d40 | ||
|
|
d574bbc521 | ||
|
|
6388a7272b | ||
|
|
cd358888d8 | ||
|
|
f427f2324b | ||
|
|
d0e2041b10 | ||
|
|
edce59d238 | ||
|
|
7f75d852c1 | ||
|
|
2683af7d28 | ||
|
|
4223720010 | ||
|
|
1b4508fea7 | ||
|
|
776fa09279 | ||
|
|
5c200aa60d | ||
|
|
9fc6c5f6c8 | ||
|
|
7e06cd4a77 | ||
|
|
c43191d97b | ||
|
|
5706b5eb81 | ||
|
|
5eed930997 | ||
|
|
35e5e50508 | ||
|
|
e88a3d0712 | ||
|
|
13b64af5b2 | ||
|
|
9804c6a729 | ||
|
|
937d415cc2 | ||
|
|
9196154207 | ||
|
|
c907b2aac2 | ||
|
|
b5a9dfa7ec | ||
|
|
113c77b416 | ||
|
|
cad5444400 | ||
|
|
b2b350e4d0 | ||
|
|
80d5d62852 | ||
|
|
75f8833c1a | ||
|
|
99d1f3f28b | ||
|
|
4066cfe011 | ||
|
|
e5f8b06af1 | ||
|
|
485b5a238d | ||
|
|
c42ee6d6e2 | ||
|
|
1fb2fd0f50 | ||
|
|
0fce4adfc5 | ||
|
|
b59086c808 | ||
|
|
fe91463652 | ||
|
|
b9065db109 | ||
|
|
d13da295ed | ||
|
|
0291389c3b | ||
|
|
f417f518cb | ||
|
|
f69f99a209 | ||
|
|
31c4fd7c07 | ||
|
|
613aadd775 | ||
|
|
0f969b4be4 | ||
|
|
f7ac1015b2 | ||
|
|
d7c5d4a03d | ||
|
|
8384c55cce | ||
|
|
be947d1086 | ||
|
|
3924bb2ede | ||
|
|
2e3003c2fc | ||
|
|
5ec15ba0a2 | ||
|
|
c7ccf5c5d7 | ||
|
|
9e8c81a1a6 | ||
|
|
c563e2547f | ||
|
|
00cb697bc7 | ||
|
|
a6a0560059 | ||
|
|
55fa5977c2 | ||
|
|
8b4bc1bc97 | ||
|
|
df403ccbc6 | ||
|
|
1f490d2aae | ||
|
|
1b766b6369 | ||
|
|
3f54da98f8 | ||
|
|
05b98c0f8b | ||
|
|
928e63620b | ||
|
|
ea9b1eb88e | ||
|
|
83a88252e2 | ||
|
|
7a61c19135 | ||
|
|
a2f87f304c | ||
|
|
f9f24d2ad2 | ||
|
|
ed3197a7fd | ||
|
|
772a88e98f | ||
|
|
e22a7f46ad | ||
|
|
f890f2f460 | ||
|
|
e9c17e12dc | ||
|
|
4b908e3024 | ||
|
|
90fd2b5da0 | ||
|
|
d7b4360f11 | ||
|
|
df7011167c | ||
|
|
28a785acb0 | ||
|
|
3ee557bfbe | ||
|
|
af94255166 | ||
|
|
4a0dea3f75 | ||
|
|
6a42bc9655 | ||
|
|
c6c8a7f6b7 | ||
|
|
133dd0e26d | ||
|
|
815339272f | ||
|
|
9c1f340029 | ||
|
|
b72ea9608d |
@@ -6,7 +6,6 @@
|
||||
"fixed": [
|
||||
[
|
||||
"cojson",
|
||||
"cojson-storage",
|
||||
"cojson-storage-indexeddb",
|
||||
"cojson-storage-sqlite",
|
||||
"cojson-transport-ws",
|
||||
|
||||
23
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Description
|
||||
<!-- Please include a summary of the change and which issue is fixed -->
|
||||
<!-- Please also include relevant motivation and context -->
|
||||
<!-- Include any links to documentation like RFC’s if necessary -->
|
||||
<!-- Add a link to to relevant preview environments or anything that would simplify visual review process -->
|
||||
<!-- Supplemental screenshots and video are encouraged, but the primary description should be in text -->
|
||||
|
||||
## Manual testing instructions
|
||||
|
||||
<!-- Add any actions required to manually test the changes -->
|
||||
|
||||
## Tests
|
||||
|
||||
- [ ] Tests have been added and/or updated
|
||||
- [ ] Tests have not been updated, because: <!-- Insert reason for not updating tests here -->
|
||||
- [ ] I need help with writing tests
|
||||
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I've updated the part of the docs that are affected the PR changes
|
||||
- [ ] I've generated a changeset, if a version bump is required
|
||||
- [ ] I've updated the jsDoc comments to the public APIs I've modified, or added them when missing
|
||||
6
.github/workflows/code-quality.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: Code quality
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
||||
8
.github/workflows/e2e-rn-test.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: End-to-End Tests for React Native
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
@@ -61,7 +67,7 @@ jobs:
|
||||
disable-animations: true
|
||||
working-directory: ./examples/chat-rn-expo/
|
||||
# killall due to this issue: https://github.com/ReactiveCircus/android-emulator-runner/issues/385
|
||||
script: ./test/e2e/run.sh && killall -INT crashpad_handler || true
|
||||
script: ./test/e2e/run.sh && ( killall -INT crashpad_handler || true )
|
||||
|
||||
- name: Copy Maestro Output
|
||||
if: steps.e2e_test.outcome != 'success'
|
||||
|
||||
6
.github/workflows/jazz-run.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: Jazz Run Tests
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
46
.github/workflows/playwright-homepage.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: Playwright Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Install root dependencies
|
||||
run: pnpm install && pnpm exec turbo build --filter="./packages/*"
|
||||
|
||||
- name: Install project dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm exec turbo build
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm exec playwright test
|
||||
working-directory: ./homepage/homepage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: homepage-playwright-report
|
||||
path: ./homepage/homepage/playwright-report/
|
||||
retention-days: 30
|
||||
164
.github/workflows/playwright.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: Playwright Tests
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
@@ -13,21 +19,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
project: [
|
||||
"tests/e2e",
|
||||
"examples/chat",
|
||||
"examples/chat-svelte",
|
||||
"examples/clerk",
|
||||
"examples/betterauth",
|
||||
"examples/file-share-svelte",
|
||||
"examples/form",
|
||||
"examples/inspector",
|
||||
"examples/music-player",
|
||||
"examples/organization",
|
||||
"starters/react-passkey-auth",
|
||||
"starters/svelte-passkey-auth",
|
||||
"tests/jazz-svelte"
|
||||
]
|
||||
shard: ["1/2", "2/2"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -37,25 +29,129 @@ jobs:
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Pnpm Build
|
||||
run: |
|
||||
if [ -f .env.test ]; then
|
||||
cp .env.test .env
|
||||
fi
|
||||
pnpm turbo build
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm exec playwright test
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ hashFiles(format('{0}/package.json', matrix.project)) }}-playwright-report
|
||||
path: ./${{ matrix.project }}/playwright-report/
|
||||
retention-days: 30
|
||||
- name: Run Playwright tests for shard ${{ matrix.shard }}
|
||||
run: |
|
||||
# Parse shard information (e.g., "1/2" -> shard_num=1, total_shards=2)
|
||||
IFS='/' read -r shard_num total_shards <<< "${{ matrix.shard }}"
|
||||
shard_index=$((shard_num - 1)) # Convert to 0-based index
|
||||
|
||||
# Debug: Print parsed values
|
||||
echo "Parsed shard_num: $shard_num"
|
||||
echo "Parsed total_shards: $total_shards"
|
||||
echo "Calculated shard_index: $shard_index"
|
||||
|
||||
# Define all projects to test
|
||||
all_projects=(
|
||||
"tests/e2e"
|
||||
"examples/chat"
|
||||
"examples/chat-svelte"
|
||||
"examples/clerk"
|
||||
"examples/betterauth"
|
||||
"examples/file-share-svelte"
|
||||
"examples/form"
|
||||
"examples/inspector"
|
||||
"examples/music-player"
|
||||
"examples/organization"
|
||||
"starters/react-passkey-auth"
|
||||
"starters/svelte-passkey-auth"
|
||||
"tests/jazz-svelte"
|
||||
)
|
||||
|
||||
# Calculate which projects this shard should run
|
||||
shard_projects=()
|
||||
for i in "${!all_projects[@]}"; do
|
||||
if [ $((i % total_shards)) -eq $shard_index ]; then
|
||||
shard_projects+=("${all_projects[i]}")
|
||||
fi
|
||||
done
|
||||
|
||||
# Track project results
|
||||
overall_exit_code=0
|
||||
failed_projects=()
|
||||
passed_projects=()
|
||||
|
||||
echo "=== Running tests for shard ${{ matrix.shard }} ==="
|
||||
echo "Projects in this shard:"
|
||||
printf '%s\n' "${shard_projects[@]}"
|
||||
echo
|
||||
|
||||
# Run tests for each project
|
||||
for project in "${shard_projects[@]}"; do
|
||||
echo "=== Testing project: $project ==="
|
||||
|
||||
# Check if project directory exists
|
||||
if [ ! -d "$project" ]; then
|
||||
echo "❌ FAILED: Project directory $project does not exist"
|
||||
failed_projects+=("$project (directory not found)")
|
||||
overall_exit_code=1
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if project has package.json
|
||||
if [ ! -f "$project/package.json" ]; then
|
||||
echo "❌ FAILED: No package.json found in $project"
|
||||
failed_projects+=("$project (no package.json)")
|
||||
overall_exit_code=1
|
||||
continue
|
||||
fi
|
||||
|
||||
# Build the project
|
||||
echo "🔨 Building $project..."
|
||||
cd "$project"
|
||||
|
||||
if [ -f .env.test ]; then
|
||||
cp .env.test .env
|
||||
fi
|
||||
|
||||
if ! pnpm turbo build; then
|
||||
echo "❌ BUILD FAILED: $project"
|
||||
failed_projects+=("$project (build failed)")
|
||||
overall_exit_code=1
|
||||
cd - > /dev/null
|
||||
continue
|
||||
fi
|
||||
|
||||
# Run Playwright tests
|
||||
echo "🧪 Running Playwright tests for $project..."
|
||||
if ! pnpm exec playwright test; then
|
||||
echo "❌ TESTS FAILED: $project"
|
||||
failed_projects+=("$project (tests failed)")
|
||||
overall_exit_code=1
|
||||
else
|
||||
echo "✅ TESTS PASSED: $project"
|
||||
passed_projects+=("$project")
|
||||
fi
|
||||
|
||||
cd - > /dev/null
|
||||
echo "=== Finished testing $project ==="
|
||||
echo
|
||||
done
|
||||
|
||||
# Print summary report
|
||||
echo "=========================================="
|
||||
echo "📊 TEST SUMMARY FOR SHARD ${{ matrix.shard }}"
|
||||
echo "=========================================="
|
||||
|
||||
if [ ${#passed_projects[@]} -gt 0 ]; then
|
||||
echo "✅ PASSED (${#passed_projects[@]}):"
|
||||
printf ' - %s\n' "${passed_projects[@]}"
|
||||
echo
|
||||
fi
|
||||
|
||||
if [ ${#failed_projects[@]} -gt 0 ]; then
|
||||
echo "❌ FAILED (${#failed_projects[@]}):"
|
||||
printf ' - %s\n' "${failed_projects[@]}"
|
||||
echo
|
||||
fi
|
||||
|
||||
|
||||
echo "Total projects in shard: ${#shard_projects[@]}"
|
||||
echo "Passed: ${#passed_projects[@]}"
|
||||
echo "Failed: ${#failed_projects[@]}"
|
||||
echo "=========================================="
|
||||
|
||||
# Exit with overall status
|
||||
exit $overall_exit_code
|
||||
|
||||
7
.github/workflows/pre-release.yml
vendored
@@ -1,4 +1,11 @@
|
||||
name: Pre-Publish tagged Pull Requests
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
6
.github/workflows/unit-test.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: Unit Tests
|
||||
|
||||
concurrency:
|
||||
# For pushes, this lets concurrent runs happen, so each push gets a result.
|
||||
# But for other events (e.g. PRs), we can cancel the previous runs.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
@@ -63,7 +63,7 @@ You'll need Node.js 22.x installed (we're working on support for 23.x), and pnpm
|
||||
4. **Build the packages**:
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
pnpm build:packages
|
||||
```
|
||||
|
||||
5. **Run tests** to verify everything is working:
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": ["packages/cojson-storage*/**", "cojson-transport-ws/**"],
|
||||
"include": ["packages/cojson/src/storage/*/**", "cojson-transport-ws/**"],
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
"@bacons/text-decoder": "^0.0.0",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"expo": "~53.0.9",
|
||||
"expo": "54.0.0-canary-20250701-6a945c5",
|
||||
"expo-clipboard": "^7.1.4",
|
||||
"expo-secure-store": "~14.2.3",
|
||||
"expo-sqlite": "~15.2.10",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
"react": "19.1.0",
|
||||
"react-native": "0.80.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"readable-stream": "^4.7.0"
|
||||
},
|
||||
@@ -29,4 +29,4 @@
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,11 @@ react {
|
||||
// The root of your project, i.e. where "package.json" lives. Default is '../..'
|
||||
// root = file("../../")
|
||||
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
|
||||
// reactNativeDir = file("../../node_modules/react-native")
|
||||
reactNativeDir = file("../../../../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../../node_modules/@react-native/codegen")
|
||||
codegenDir = file("../../../../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
|
||||
// cliFile = file("../../node_modules/react-native/cli.js")
|
||||
cliFile = file("../../../../node_modules/react-native/cli.js")
|
||||
|
||||
/* Variants */
|
||||
// The list of variants to that are debuggable. For those we're going to
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
|
||||
pluginManagement { includeBuild("../../../node_modules/@react-native/gradle-plugin") }
|
||||
plugins { id("com.facebook.react.settings") }
|
||||
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
|
||||
rootProject.name = 'ChatRN'
|
||||
include ':app'
|
||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
||||
includeBuild('../../../node_modules/@react-native/gradle-plugin')
|
||||
|
||||
@@ -380,7 +380,7 @@
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
||||
USE_HERMES = true;
|
||||
@@ -452,7 +452,7 @@
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
USE_HERMES = true;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
|
||||
@@ -2370,87 +2370,87 @@ PODS:
|
||||
- Yoga (0.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- fast_float (from `../node_modules/react-native/third-party-podspecs/fast_float.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- boost (from `../../../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- fast_float (from `../../../node_modules/react-native/third-party-podspecs/fast_float.podspec`)
|
||||
- FBLazyVector (from `../../../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- fmt (from `../../../node_modules/react-native/third-party-podspecs/fmt.podspec`)
|
||||
- glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- hermes-engine (from `../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- "op-sqlite (from `../../../node_modules/@op-engineering/op-sqlite`)"
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/Required`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-debug (from `../node_modules/react-native/ReactCommon/react/debug`)
|
||||
- React-defaultsnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/defaults`)
|
||||
- React-domnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/dom`)
|
||||
- React-Fabric (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-FabricComponents (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-FabricImage (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-featureflags (from `../node_modules/react-native/ReactCommon/react/featureflags`)
|
||||
- React-featureflagsnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/featureflags`)
|
||||
- React-graphics (from `../node_modules/react-native/ReactCommon/react/renderer/graphics`)
|
||||
- React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
|
||||
- React-idlecallbacksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks`)
|
||||
- React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
|
||||
- React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`)
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`)
|
||||
- React-jsinspectorcdp (from `../node_modules/react-native/ReactCommon/jsinspector-modern/cdp`)
|
||||
- React-jsinspectornetwork (from `../node_modules/react-native/ReactCommon/jsinspector-modern/network`)
|
||||
- React-jsinspectortracing (from `../node_modules/react-native/ReactCommon/jsinspector-modern/tracing`)
|
||||
- React-jsitooling (from `../node_modules/react-native/ReactCommon/jsitooling`)
|
||||
- React-jsitracing (from `../node_modules/react-native/ReactCommon/hermes/executor/`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
|
||||
- RCT-Folly (from `../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTDeprecation (from `../../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
||||
- RCTRequired (from `../../../node_modules/react-native/Libraries/Required`)
|
||||
- RCTTypeSafety (from `../../../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../../../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../../../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Core (from `../../../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../../../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../../../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../../../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-debug (from `../../../node_modules/react-native/ReactCommon/react/debug`)
|
||||
- React-defaultsnativemodule (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/defaults`)
|
||||
- React-domnativemodule (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/dom`)
|
||||
- React-Fabric (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- React-FabricComponents (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- React-FabricImage (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- React-featureflags (from `../../../node_modules/react-native/ReactCommon/react/featureflags`)
|
||||
- React-featureflagsnativemodule (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/featureflags`)
|
||||
- React-graphics (from `../../../node_modules/react-native/ReactCommon/react/renderer/graphics`)
|
||||
- React-hermes (from `../../../node_modules/react-native/ReactCommon/hermes`)
|
||||
- React-idlecallbacksnativemodule (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks`)
|
||||
- React-ImageManager (from `../../../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
|
||||
- React-jserrorhandler (from `../../../node_modules/react-native/ReactCommon/jserrorhandler`)
|
||||
- React-jsi (from `../../../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../../../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../../../node_modules/react-native/ReactCommon/jsinspector-modern`)
|
||||
- React-jsinspectorcdp (from `../../../node_modules/react-native/ReactCommon/jsinspector-modern/cdp`)
|
||||
- React-jsinspectornetwork (from `../../../node_modules/react-native/ReactCommon/jsinspector-modern/network`)
|
||||
- React-jsinspectortracing (from `../../../node_modules/react-native/ReactCommon/jsinspector-modern/tracing`)
|
||||
- React-jsitooling (from `../../../node_modules/react-native/ReactCommon/jsitooling`)
|
||||
- React-jsitracing (from `../../../node_modules/react-native/ReactCommon/hermes/executor/`)
|
||||
- React-logger (from `../../../node_modules/react-native/ReactCommon/logger`)
|
||||
- React-Mapbuffer (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- React-microtasksnativemodule (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
|
||||
- react-native-get-random-values (from `../../../node_modules/react-native-get-random-values`)
|
||||
- react-native-mmkv (from `../../../node_modules/react-native-mmkv`)
|
||||
- "react-native-netinfo (from `../../../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||
- React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
- React-performancetimeline (from `../node_modules/react-native/ReactCommon/react/performance/timeline`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
- React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
|
||||
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
|
||||
- React-RCTFabric (from `../node_modules/react-native/React`)
|
||||
- React-RCTFBReactNativeSpec (from `../node_modules/react-native/React`)
|
||||
- React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
|
||||
- React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
|
||||
- React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
|
||||
- React-RCTRuntime (from `../node_modules/react-native/React/Runtime`)
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-rendererconsistency (from `../node_modules/react-native/ReactCommon/react/renderer/consistency`)
|
||||
- React-renderercss (from `../node_modules/react-native/ReactCommon/react/renderer/css`)
|
||||
- React-rendererdebug (from `../node_modules/react-native/ReactCommon/react/renderer/debug`)
|
||||
- React-rncore (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-RuntimeApple (from `../node_modules/react-native/ReactCommon/react/runtime/platform/ios`)
|
||||
- React-RuntimeCore (from `../node_modules/react-native/ReactCommon/react/runtime`)
|
||||
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
||||
- React-RuntimeHermes (from `../node_modules/react-native/ReactCommon/react/runtime`)
|
||||
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
||||
- React-timing (from `../node_modules/react-native/ReactCommon/react/timing`)
|
||||
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
|
||||
- react-native-safe-area-context (from `../../../node_modules/react-native-safe-area-context`)
|
||||
- React-NativeModulesApple (from `../../../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
|
||||
- React-oscompat (from `../../../node_modules/react-native/ReactCommon/oscompat`)
|
||||
- React-perflogger (from `../../../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
- React-performancetimeline (from `../../../node_modules/react-native/ReactCommon/react/performance/timeline`)
|
||||
- React-RCTActionSheet (from `../../../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../../../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
- React-RCTAppDelegate (from `../../../node_modules/react-native/Libraries/AppDelegate`)
|
||||
- React-RCTBlob (from `../../../node_modules/react-native/Libraries/Blob`)
|
||||
- React-RCTFabric (from `../../../node_modules/react-native/React`)
|
||||
- React-RCTFBReactNativeSpec (from `../../../node_modules/react-native/React`)
|
||||
- React-RCTImage (from `../../../node_modules/react-native/Libraries/Image`)
|
||||
- React-RCTLinking (from `../../../node_modules/react-native/Libraries/LinkingIOS`)
|
||||
- React-RCTNetwork (from `../../../node_modules/react-native/Libraries/Network`)
|
||||
- React-RCTRuntime (from `../../../node_modules/react-native/React/Runtime`)
|
||||
- React-RCTSettings (from `../../../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../../../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../../../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-rendererconsistency (from `../../../node_modules/react-native/ReactCommon/react/renderer/consistency`)
|
||||
- React-renderercss (from `../../../node_modules/react-native/ReactCommon/react/renderer/css`)
|
||||
- React-rendererdebug (from `../../../node_modules/react-native/ReactCommon/react/renderer/debug`)
|
||||
- React-rncore (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- React-RuntimeApple (from `../../../node_modules/react-native/ReactCommon/react/runtime/platform/ios`)
|
||||
- React-RuntimeCore (from `../../../node_modules/react-native/ReactCommon/react/runtime`)
|
||||
- React-runtimeexecutor (from `../../../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
||||
- React-RuntimeHermes (from `../../../node_modules/react-native/ReactCommon/react/runtime`)
|
||||
- React-runtimescheduler (from `../../../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
||||
- React-timing (from `../../../node_modules/react-native/ReactCommon/react/timing`)
|
||||
- React-utils (from `../../../node_modules/react-native/ReactCommon/react/utils`)
|
||||
- ReactAppDependencyProvider (from `build/generated/ios`)
|
||||
- ReactCodegen (from `build/generated/ios`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- ReactCommon/turbomodule/core (from `../../../node_modules/react-native/ReactCommon`)
|
||||
- "RNCClipboard (from `../../../node_modules/@react-native-clipboard/clipboard`)"
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNScreens (from `../../../node_modules/react-native-screens`)
|
||||
- SocketRocket (~> 0.7.1)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
- Yoga (from `../../../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
@@ -2458,88 +2458,88 @@ SPEC REPOS:
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
fast_float:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/fast_float.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/fast_float.podspec"
|
||||
FBLazyVector:
|
||||
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
:path: "../../../node_modules/react-native/Libraries/FBLazyVector"
|
||||
fmt:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/fmt.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/fmt.podspec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
hermes-engine:
|
||||
:podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
|
||||
:podspec: "../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
|
||||
:tag: hermes-2025-05-06-RNv0.80.0-4eb6132a5bf0450bf4c6c91987675381d7ac8bca
|
||||
op-sqlite:
|
||||
:path: "../../../node_modules/@op-engineering/op-sqlite"
|
||||
RCT-Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
:podspec: "../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
RCTDeprecation:
|
||||
:path: "../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
|
||||
:path: "../../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/Required"
|
||||
:path: "../../../node_modules/react-native/Libraries/Required"
|
||||
RCTTypeSafety:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
:path: "../../../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
:path: "../../../node_modules/react-native/"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/"
|
||||
:path: "../../../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
:path: "../node_modules/react-native/React/CoreModules"
|
||||
:path: "../../../node_modules/react-native/React/CoreModules"
|
||||
React-cxxreact:
|
||||
:path: "../node_modules/react-native/ReactCommon/cxxreact"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/cxxreact"
|
||||
React-debug:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/debug"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/debug"
|
||||
React-defaultsnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/defaults"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/defaults"
|
||||
React-domnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/dom"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/dom"
|
||||
React-Fabric:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
React-FabricComponents:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
React-FabricImage:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
React-featureflags:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/featureflags"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/featureflags"
|
||||
React-featureflagsnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/featureflags"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/featureflags"
|
||||
React-graphics:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/graphics"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/graphics"
|
||||
React-hermes:
|
||||
:path: "../node_modules/react-native/ReactCommon/hermes"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/hermes"
|
||||
React-idlecallbacksnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks"
|
||||
React-ImageManager:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios"
|
||||
React-jserrorhandler:
|
||||
:path: "../node_modules/react-native/ReactCommon/jserrorhandler"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jserrorhandler"
|
||||
React-jsi:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsi"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsi"
|
||||
React-jsiexecutor:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector-modern"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsinspector-modern"
|
||||
React-jsinspectorcdp:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector-modern/cdp"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsinspector-modern/cdp"
|
||||
React-jsinspectornetwork:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector-modern/network"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsinspector-modern/network"
|
||||
React-jsinspectortracing:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector-modern/tracing"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsinspector-modern/tracing"
|
||||
React-jsitooling:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsitooling"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/jsitooling"
|
||||
React-jsitracing:
|
||||
:path: "../node_modules/react-native/ReactCommon/hermes/executor/"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/hermes/executor/"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/logger"
|
||||
React-Mapbuffer:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
React-microtasksnativemodule:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
|
||||
react-native-get-random-values:
|
||||
:path: "../../../node_modules/react-native-get-random-values"
|
||||
react-native-mmkv:
|
||||
@@ -2547,75 +2547,75 @@ EXTERNAL SOURCES:
|
||||
react-native-netinfo:
|
||||
:path: "../../../node_modules/@react-native-community/netinfo"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
:path: "../../../node_modules/react-native-safe-area-context"
|
||||
React-NativeModulesApple:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
|
||||
React-oscompat:
|
||||
:path: "../node_modules/react-native/ReactCommon/oscompat"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/oscompat"
|
||||
React-perflogger:
|
||||
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/reactperflogger"
|
||||
React-performancetimeline:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/performance/timeline"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/performance/timeline"
|
||||
React-RCTActionSheet:
|
||||
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
|
||||
:path: "../../../node_modules/react-native/Libraries/ActionSheetIOS"
|
||||
React-RCTAnimation:
|
||||
:path: "../node_modules/react-native/Libraries/NativeAnimation"
|
||||
:path: "../../../node_modules/react-native/Libraries/NativeAnimation"
|
||||
React-RCTAppDelegate:
|
||||
:path: "../node_modules/react-native/Libraries/AppDelegate"
|
||||
:path: "../../../node_modules/react-native/Libraries/AppDelegate"
|
||||
React-RCTBlob:
|
||||
:path: "../node_modules/react-native/Libraries/Blob"
|
||||
:path: "../../../node_modules/react-native/Libraries/Blob"
|
||||
React-RCTFabric:
|
||||
:path: "../node_modules/react-native/React"
|
||||
:path: "../../../node_modules/react-native/React"
|
||||
React-RCTFBReactNativeSpec:
|
||||
:path: "../node_modules/react-native/React"
|
||||
:path: "../../../node_modules/react-native/React"
|
||||
React-RCTImage:
|
||||
:path: "../node_modules/react-native/Libraries/Image"
|
||||
:path: "../../../node_modules/react-native/Libraries/Image"
|
||||
React-RCTLinking:
|
||||
:path: "../node_modules/react-native/Libraries/LinkingIOS"
|
||||
:path: "../../../node_modules/react-native/Libraries/LinkingIOS"
|
||||
React-RCTNetwork:
|
||||
:path: "../node_modules/react-native/Libraries/Network"
|
||||
:path: "../../../node_modules/react-native/Libraries/Network"
|
||||
React-RCTRuntime:
|
||||
:path: "../node_modules/react-native/React/Runtime"
|
||||
:path: "../../../node_modules/react-native/React/Runtime"
|
||||
React-RCTSettings:
|
||||
:path: "../node_modules/react-native/Libraries/Settings"
|
||||
:path: "../../../node_modules/react-native/Libraries/Settings"
|
||||
React-RCTText:
|
||||
:path: "../node_modules/react-native/Libraries/Text"
|
||||
:path: "../../../node_modules/react-native/Libraries/Text"
|
||||
React-RCTVibration:
|
||||
:path: "../node_modules/react-native/Libraries/Vibration"
|
||||
:path: "../../../node_modules/react-native/Libraries/Vibration"
|
||||
React-rendererconsistency:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/consistency"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/consistency"
|
||||
React-renderercss:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/css"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/css"
|
||||
React-rendererdebug:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/debug"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/debug"
|
||||
React-rncore:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
React-RuntimeApple:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/runtime/platform/ios"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/runtime/platform/ios"
|
||||
React-RuntimeCore:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/runtime"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/runtime"
|
||||
React-runtimeexecutor:
|
||||
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/runtimeexecutor"
|
||||
React-RuntimeHermes:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/runtime"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/runtime"
|
||||
React-runtimescheduler:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler"
|
||||
React-timing:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/timing"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/timing"
|
||||
React-utils:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/utils"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/react/utils"
|
||||
ReactAppDependencyProvider:
|
||||
:path: build/generated/ios
|
||||
ReactCodegen:
|
||||
:path: build/generated/ios
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
:path: "../../../node_modules/react-native/ReactCommon"
|
||||
RNCClipboard:
|
||||
:path: "../../../node_modules/@react-native-clipboard/clipboard"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
:path: "../../../node_modules/react-native-screens"
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
:path: "../../../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
|
||||
@@ -2692,7 +2692,7 @@ SPEC CHECKSUMS:
|
||||
React-timing: a275a1c2e6112dba17f8f7dd496d439213bbea0d
|
||||
React-utils: 449a6e1fd53886510e284e80bdbb1b1c6db29452
|
||||
ReactAppDependencyProvider: 3267432b637c9b38e86961b287f784ee1b08dde0
|
||||
ReactCodegen: 5d41e1df061200130dd326e55cdfdf94b0289c6e
|
||||
ReactCodegen: d82f538f70f00484d418803f74b5a0ea09cc8689
|
||||
ReactCommon: b028d09a66e60ebd83ca59d8cc9a1216360db147
|
||||
RNCClipboard: 54ff19965d7c816febbafe5f520c2c3e7b677a49
|
||||
RNScreens: ee2abe7e0c548eed14e92742e81ed991165c56aa
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bacons/text-decoder": "0.0.0",
|
||||
"@op-engineering/op-sqlite": "14.1.0",
|
||||
"@react-native-clipboard/clipboard": "1.16.2",
|
||||
"@react-native-clipboard/clipboard": "1.16.3",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"@react-navigation/native": "7.1.14",
|
||||
"@react-navigation/native-stack": "7.3.19",
|
||||
@@ -40,7 +40,7 @@
|
||||
"@react-native/typescript-config": "0.80.0",
|
||||
"@rnx-kit/metro-config": "^2.0.1",
|
||||
"@rnx-kit/metro-resolver-symlinks": "^0.2.5",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react": "^19.1.0",
|
||||
"eslint": "^8.19.0",
|
||||
"pod-install": "^0.3.5",
|
||||
"prettier": "2.8.8",
|
||||
|
||||
@@ -1,5 +1,55 @@
|
||||
# passkey-svelte
|
||||
|
||||
## 0.0.98
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [27b4837]
|
||||
- jazz-tools@0.15.9
|
||||
|
||||
## 0.0.97
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3844666]
|
||||
- jazz-tools@0.15.8
|
||||
|
||||
## 0.0.96
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c09b636]
|
||||
- jazz-tools@0.15.7
|
||||
|
||||
## 0.0.95
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a5ceaff]
|
||||
- jazz-tools@0.15.6
|
||||
|
||||
## 0.0.94
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [23bfea5]
|
||||
- Updated dependencies [e4ba23c]
|
||||
- Updated dependencies [4b89838]
|
||||
- jazz-tools@0.15.5
|
||||
|
||||
## 0.0.93
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- jazz-tools@0.15.4
|
||||
|
||||
## 0.0.92
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [45f73a7]
|
||||
- jazz-tools@0.15.3
|
||||
|
||||
## 0.0.91
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chat-svelte",
|
||||
"version": "0.0.91",
|
||||
"version": "0.0.98",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"zod": "3.25.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"is-ci": "^3.0.1",
|
||||
"postcss": "^8.4.40",
|
||||
@@ -32,4 +32,4 @@
|
||||
"typescript": "5.6.2",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,15 @@
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@clerk/clerk-expo": "^2.13.1",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"expo": "~53.0.9",
|
||||
"expo": "54.0.0-canary-20250701-6a945c5",
|
||||
"expo-crypto": "~14.1.5",
|
||||
"expo-linking": "~7.1.5",
|
||||
"expo-secure-store": "~14.2.3",
|
||||
"expo-sqlite": "~15.2.10",
|
||||
"expo-web-browser": "~14.2.0",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
"react": "19.1.0",
|
||||
"react-native": "0.80.0",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"readable-stream": "^4.7.0"
|
||||
},
|
||||
@@ -32,4 +32,4 @@
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,17 @@
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
"dependencies": {
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
"cojson-transport-ws": "workspace:*",
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-use": "^17.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"postcss": "^8.4.40",
|
||||
"tailwindcss": "^4.1.10",
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"dependencies": {
|
||||
"jazz-tools": "workspace:*",
|
||||
"next": "15.3.2",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
@@ -21,4 +21,4 @@
|
||||
"tailwindcss": "^4.1.10",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,15 +24,15 @@
|
||||
"clsx": "^2.1.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.485.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"tailwind-merge": "^3.0.2",
|
||||
"tailwindcss": "^4.0.17",
|
||||
"tw-animate-css": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"jazz-run": "workspace:*",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
"dependencies": {
|
||||
"@react-spring/web": "^9.7.5",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"zod": "3.25.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"tailwindcss": "^4.1.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
"clsx": "^2.1.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-router": "^6.16.0",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"tailwind-merge": "^1.14.0"
|
||||
@@ -32,8 +32,8 @@
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^4.1.10",
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"dependencies": {
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-router": "^6.16.0",
|
||||
"react-router-dom": "^6.16.0"
|
||||
},
|
||||
@@ -24,8 +24,8 @@
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"postcss": "^8.4.40",
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"tailwindcss": "^4.1.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
"dependencies": {
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"tailwindcss": "^4.1.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"typescript": "5.6.2",
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
"prosemirror-schema-list": "^1.5.1",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-view": "^1.39.1",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
"clsx": "^2.1.1",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.509.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"is-ci": "^3.0.1",
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@faker-js/faker": "^9.7.0",
|
||||
"@radix-ui/react-checkbox": "^1.3.2",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
"@radix-ui/react-toast": "^1.2.14",
|
||||
@@ -19,8 +18,8 @@
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-router": "^6.16.0",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
@@ -30,8 +29,8 @@
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/qrcode": "^1.5.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
"postcss": "^8.4.27",
|
||||
"tailwindcss": "^4.1.10",
|
||||
|
||||
@@ -58,7 +58,7 @@ export const TodoAccount = co
|
||||
/** The account migration is run on account creation and on every log-in.
|
||||
* You can use it to set up the account root and any other initial CoValues you need.
|
||||
*/
|
||||
if (!account.root) {
|
||||
if (account.root === undefined) {
|
||||
account.root = TodoAccountRoot.create({
|
||||
projects: co.list(TodoProject).create([], { owner: account }),
|
||||
});
|
||||
|
||||
@@ -17,13 +17,12 @@ import React from "react";
|
||||
import { TodoAccount, TodoProject } from "./1_schema.ts";
|
||||
import { NewProjectForm } from "./3_NewProjectForm.tsx";
|
||||
import { ProjectTodoTable } from "./4_ProjectTodoTable.tsx";
|
||||
import { apiKey } from "./apiKey";
|
||||
import { apiKey } from "./apiKey.ts";
|
||||
import {
|
||||
Button,
|
||||
ThemeProvider,
|
||||
TitleAndLogo,
|
||||
} from "./basicComponents/index.ts";
|
||||
import { TaskGenerator } from "./components/TaskGenerator.tsx";
|
||||
import { wordlist } from "./wordlist.ts";
|
||||
|
||||
/**
|
||||
@@ -53,6 +52,8 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
);
|
||||
}
|
||||
|
||||
// http://localhost:5173/#/project/co_znUD6vciCQazKwAKi4hFwRodxEk
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<JazzAndAuth>
|
||||
@@ -91,10 +92,6 @@ export default function App() {
|
||||
path: "/invite/*",
|
||||
element: <p>Accepting invite...</p>,
|
||||
},
|
||||
{
|
||||
path: "/generate",
|
||||
element: <TaskGenerator />,
|
||||
},
|
||||
]);
|
||||
|
||||
// `useAcceptInvite()` is a hook that accepts an invite link from the URL hash,
|
||||
|
||||
@@ -11,7 +11,9 @@ import { useNavigate } from "react-router";
|
||||
export function NewProjectForm() {
|
||||
// `me` represents the current user account, which will determine
|
||||
// access rights to CoValues. We get it from the top-level provider `<WithJazz/>`.
|
||||
const { me } = useAccount(TodoAccount);
|
||||
const { me } = useAccount(TodoAccount, {
|
||||
resolve: { root: { projects: { $each: { $onError: null } } } },
|
||||
});
|
||||
const navigate = useNavigate();
|
||||
|
||||
const createProject = useCallback(
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
import { TodoAccount } from "@/1_schema";
|
||||
import { FormEvent, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { generateRandomProject } from "../generate";
|
||||
|
||||
export function TaskGenerator() {
|
||||
const [isGenerating, setIsGenerating] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
const numTasks = Math.max(
|
||||
1,
|
||||
parseInt(formData.get("numTasks") as string) || 1,
|
||||
);
|
||||
|
||||
setIsGenerating(true);
|
||||
const project = generateRandomProject(numTasks);
|
||||
|
||||
const { root } = await TodoAccount.getMe().ensureLoaded({
|
||||
resolve: {
|
||||
root: {
|
||||
projects: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
root.projects.push(project.value);
|
||||
|
||||
await project.done;
|
||||
|
||||
navigate(`/project/${project.value.id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-4 border rounded-lg shadow-xs bg-white">
|
||||
<h2 className="text-lg font-semibold mb-4">Generate Random Tasks</h2>
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<label htmlFor="numTasks" className="text-sm font-medium">
|
||||
Number of tasks:
|
||||
</label>
|
||||
<input
|
||||
id="numTasks"
|
||||
name="numTasks"
|
||||
type="number"
|
||||
min="1"
|
||||
defaultValue={5}
|
||||
className="w-20 px-2 py-1 border rounded"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isGenerating}
|
||||
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-blue-300"
|
||||
>
|
||||
{isGenerating ? "Generating..." : "Generate Tasks"}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -12,14 +12,14 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@tailwindcss/postcss": "^4.1.10",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@types/react": "19.1.0",
|
||||
"@types/react-dom": "19.1.0",
|
||||
"@vitejs/plugin-react": "^4.5.1",
|
||||
"globals": "^15.11.0",
|
||||
"tailwindcss": "^4.1.10",
|
||||
|
||||
@@ -5,6 +5,7 @@ export const COLORS = {
|
||||
GREEN: "#8BDA27",
|
||||
PINK: "#EF478E",
|
||||
PURPLE: "#B441EB",
|
||||
YELLOW: "#FBC400",
|
||||
YELLOW: "#FCAE00",
|
||||
RED: "#FF601C",
|
||||
ORANGE: "#FF601C",
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"radix-ui": "^1.4.2",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"resend": "^4.0.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
||||
|
Before Width: | Height: | Size: 629 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -1,47 +1,46 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--color-primary: #146aff;
|
||||
--color-primary-dark: lch(
|
||||
from var(--color-primary) calc(l - 15) calc(c - 1) calc(h + 10)
|
||||
from var(--color-primary) calc(l - 10) calc(c - 1) calc(h + 5)
|
||||
);
|
||||
--color-primary-light: lch(
|
||||
from var(--color-primary) calc(l + 15) calc(c + 1) calc(h - 10)
|
||||
from var(--color-primary) calc(l + 10) calc(c + 1) calc(h - 5)
|
||||
);
|
||||
|
||||
--color-secondary: var(--color-primary-dark);
|
||||
--color-highlight: #2dc9c9;
|
||||
--color-success: #42bb69;
|
||||
--color-info: #fbc400;
|
||||
--color-info: #b441eb;
|
||||
--color-warning: #ff601c;
|
||||
--color-tip: #b441eb;
|
||||
--color-success: #8bda27;
|
||||
--color-alert: #fcae00;
|
||||
--color-tip: #2dc9c9;
|
||||
--color-pink: #ef478e;
|
||||
--color-danger: #ee494c;
|
||||
|
||||
--color-default: theme("colors.stone.700");
|
||||
--color-highlight: theme("colors.stone.900");
|
||||
--color-strong: theme("colors.stone.800");
|
||||
--color-muted: theme("colors.stone.300");
|
||||
|
||||
--color-transparent-white: rgba(255, 255, 255, 0.1);
|
||||
--color-transparent-primary: lch(from var(--color-primary-dark) l c h / 0.1);
|
||||
--color-transparent-primary: lch(from var(--color-primary) l c h / 0.1);
|
||||
|
||||
--color-border-default: theme("colors.stone.200");
|
||||
--color-background-highlight: lch(from var(--color-primary) l c h / 0.25);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--color-secondary: var(--color-primary-light);
|
||||
|
||||
--color-default: theme("colors.stone.400");
|
||||
--color-highlight: theme("colors.white");
|
||||
--color-strong: theme("colors.stone.100");
|
||||
--color-muted: theme("colors.stone.700");
|
||||
|
||||
--color-transparent-primary: lch(from var(--color-primary-light) l c h / 0.2);
|
||||
--color-transparent-primary: lch(from var(--color-primary) l c h / 0.3);
|
||||
|
||||
--color-border-default: theme("colors.stone.900");
|
||||
--color-background-highlight: lch(from var(--color-primary) l c h / 0.5);
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { ThemeProvider } from "../components/organisms/ThemeProvider";
|
||||
import { fontClasses } from "../fonts";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -13,7 +15,7 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en" className="h-full">
|
||||
<html lang="en" className="h-full" suppressHydrationWarning>
|
||||
<body
|
||||
className={[
|
||||
...fontClasses,
|
||||
@@ -21,7 +23,15 @@ export default function RootLayout({
|
||||
"bg-white dark:bg-stone-950 text-default",
|
||||
].join(" ")}
|
||||
>
|
||||
{children}
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<Toaster position="bottom-right" />
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -1,74 +1,14 @@
|
||||
import { Prose } from "@components/molecules/Prose";
|
||||
import { NewsletterForm } from "@components/organisms/NewsletterForm";
|
||||
import { ViewsLayout } from "./views/ViewsLayout";
|
||||
import Colors from "./views/colors/page";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="container flex flex-col gap-8 py-8 lg:py-16">
|
||||
<h1 className="text-2xl font-semibold font-display">
|
||||
Jazz Design System
|
||||
</h1>
|
||||
|
||||
<h2>Typography (Prose)</h2>
|
||||
|
||||
<div className="grid gap-4">
|
||||
<div>
|
||||
Heading 1
|
||||
<Prose className="p-3 border">
|
||||
<h1>Ship top-tier apps at high tempo</h1>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 2
|
||||
<Prose className="p-3 border">
|
||||
<h2>Ship top-tier apps at high tempo</h2>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 3
|
||||
<Prose className="p-3 border">
|
||||
<h3>Ship top-tier apps at high tempo</h3>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 4
|
||||
<Prose className="p-3 border">
|
||||
<h4>Ship top-tier apps at high tempo</h4>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Paragraph
|
||||
<Prose className="p-3 border">
|
||||
<p>
|
||||
<strong>Jazz is a framework for building local-first apps</strong>{" "}
|
||||
— an architecture that lets companies like Figma and Linear play
|
||||
in a league of their own.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Open source. Self-host or use Jazz Cloud for zero-config magic.
|
||||
</p>
|
||||
</Prose>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Link
|
||||
<Prose className="p-3 border">
|
||||
This is a <a href="https://jazz.tools">link</a>
|
||||
</Prose>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Code
|
||||
<Prose className="p-3 border">
|
||||
This is a one-line <code>piece of code</code>
|
||||
</Prose>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Newsletter Subscription Form</h2>
|
||||
|
||||
<div className="p-3 border">
|
||||
<NewsletterForm />
|
||||
<main>
|
||||
<div className="col-span-8 overflow-y-scroll">
|
||||
<ViewsLayout>
|
||||
<h1 className="text-2xl font-bold mt-4">Colors</h1>
|
||||
<Colors />
|
||||
</ViewsLayout>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
18
homepage/design-system/src/app/views/ViewsLayout.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { ViewsSideMenu } from "./ViewsSideMenu";
|
||||
|
||||
export function ViewsLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="container py-8 lg:py-16 relative h-full overflow-hidden flex flex-row gap-2">
|
||||
<ViewsSideMenu />
|
||||
<div className="flex-1 overflow-y-scroll overflow-x-hidden pr-8">
|
||||
<h1 className="text-2xl font-semibold font-display">
|
||||
Jazz Design System
|
||||
</h1>
|
||||
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
46
homepage/design-system/src/app/views/ViewsSideMenu.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import clsx from "clsx";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { Button } from "../../components/atoms/Button";
|
||||
|
||||
const designSystemTopics = [
|
||||
"Colors",
|
||||
"Typography",
|
||||
"Buttons",
|
||||
"Components",
|
||||
"Inputs",
|
||||
"Icons",
|
||||
];
|
||||
|
||||
export function ViewsSideMenu() {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const router = useRouter();
|
||||
return (
|
||||
<div className={clsx("sticky top-0", mobileMenuOpen ? "w-32" : "w-7")}>
|
||||
<Button
|
||||
intent="default"
|
||||
variant="link"
|
||||
icon={mobileMenuOpen ? "close" : "chevronRight"}
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
size="sm"
|
||||
/>
|
||||
{mobileMenuOpen && (
|
||||
<div className="flex flex-col gap-2">
|
||||
{designSystemTopics.map((topic) => (
|
||||
<div key={topic}>
|
||||
<Button
|
||||
intent="default"
|
||||
variant="link"
|
||||
onClick={() => router.push(`/views/${topic.toLowerCase()}`)}
|
||||
>
|
||||
{topic}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
237
homepage/design-system/src/app/views/buttons/page.tsx
Normal file
@@ -0,0 +1,237 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/atoms/Button";
|
||||
import { Icon } from "@/components/atoms/Icon";
|
||||
import { Table } from "@/components/molecules/Table";
|
||||
import {
|
||||
Dropdown,
|
||||
DropdownButton,
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
} from "@/components/organisms/Dropdown";
|
||||
import { useState } from "react";
|
||||
import { Style } from "../../../utils/tailwindClassesMap";
|
||||
export default function ButtonsPage() {
|
||||
const variants = [
|
||||
"default",
|
||||
"primary",
|
||||
"tip",
|
||||
"info",
|
||||
"success",
|
||||
"warning",
|
||||
"alert",
|
||||
"danger",
|
||||
"muted",
|
||||
"strong",
|
||||
] as const;
|
||||
const [selectedVariant, setSelectedVariant] = useState<Style>("default");
|
||||
return (
|
||||
<>
|
||||
<h3 className="text-lg mt-5 mb-2 font-bold">Variants</h3>
|
||||
|
||||
<p className="my-3">Buttons are styled with the variant prop.</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Button variant="default">default</Button>
|
||||
<Button variant="link">link</Button>
|
||||
<Button variant="ghost">ghost</Button>
|
||||
<Button variant="outline">outline</Button>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg mt-5 font-bold">Intents</h3>
|
||||
<p className="my-3">
|
||||
We have extended the variants to include more styles via the intent
|
||||
prop.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Button intent="default">default</Button>
|
||||
<Button intent="muted">muted</Button>
|
||||
<Button intent="strong">strong</Button>
|
||||
<Button intent="primary">primary</Button>
|
||||
<Button intent="tip">tip</Button>
|
||||
<Button intent="info">info</Button>
|
||||
<Button intent="success">success</Button>
|
||||
<Button intent="warning">warning</Button>
|
||||
<Button intent="alert">alert</Button>
|
||||
<Button intent="danger">danger</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center w-48 mt-10">
|
||||
<h3 className="text-lg font-bold min-w-52">Variants & Intents</h3>
|
||||
<div className="max-w-xs ml-3">
|
||||
<Dropdown>
|
||||
<DropdownButton
|
||||
className="w-full justify-between"
|
||||
as={Button}
|
||||
intent="default"
|
||||
variant="inverted"
|
||||
>
|
||||
{selectedVariant}
|
||||
<Icon name="chevronDown" size="sm" />
|
||||
</DropdownButton>
|
||||
<DropdownMenu>
|
||||
{variants.map((variant) => (
|
||||
<DropdownItem
|
||||
key={variant}
|
||||
onClick={() => setSelectedVariant(variant)}
|
||||
>
|
||||
{variant}
|
||||
</DropdownItem>
|
||||
))}
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-sm mt-2 mb-5">
|
||||
<strong>NB:</strong> Variants and styles are interchangeable. See the
|
||||
intent on each variant with the dropdown.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Button intent={selectedVariant} variant="outline">
|
||||
outline
|
||||
</Button>
|
||||
<Button intent={selectedVariant} variant="inverted">
|
||||
inverted
|
||||
</Button>
|
||||
<Button intent={selectedVariant} variant="ghost">
|
||||
ghost
|
||||
</Button>
|
||||
<Button intent={selectedVariant} variant="link">
|
||||
link
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<p className="my-3">
|
||||
For compatibility the shadcn/ui variants are mapped to the design
|
||||
system.
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Button variant="secondary">secondary</Button>
|
||||
<Button variant="destructive">destructive</Button>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-bold mt-5">Icons</h3>
|
||||
|
||||
<p className="my-3">Buttons can also contain an icon and text.</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Button
|
||||
icon="delete"
|
||||
intent="danger"
|
||||
variant="link"
|
||||
iconPosition="right"
|
||||
className="col-span-2 md:col-span-1"
|
||||
>
|
||||
text danger with icon
|
||||
</Button>
|
||||
<Button
|
||||
icon="info"
|
||||
iconPosition="left"
|
||||
intent="info"
|
||||
variant="outline"
|
||||
className="col-span-2 md:col-span-1"
|
||||
>
|
||||
outline info with icon
|
||||
</Button>
|
||||
<p className="col-span-2 my-2">
|
||||
Or just use the icon prop with any of the button variants, style
|
||||
variants and colors.
|
||||
</p>
|
||||
<Button icon="newsletter" intent="tip" variant="inverted" />
|
||||
<Button icon="check" intent="success" />
|
||||
</div>
|
||||
<div className="overflow-auto">
|
||||
<h3 className="text-xl mt-5 mb-2 font-bold">Props Table</h3>
|
||||
<Table tableData={buttonPropsTableData} copyable={true} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const buttonPropsTableData = {
|
||||
headers: ["prop", "types", "default"],
|
||||
data: [
|
||||
{
|
||||
prop: "intent?",
|
||||
types: [
|
||||
"default",
|
||||
"primary",
|
||||
"tip",
|
||||
"info",
|
||||
"success",
|
||||
"warning",
|
||||
"alert",
|
||||
"danger",
|
||||
"muted",
|
||||
"strong",
|
||||
],
|
||||
default: "default",
|
||||
},
|
||||
{
|
||||
prop: "variant?",
|
||||
types: [
|
||||
"default",
|
||||
"outline",
|
||||
"inverted",
|
||||
"ghost",
|
||||
"link",
|
||||
"secondary",
|
||||
"destructive",
|
||||
],
|
||||
default: "default",
|
||||
},
|
||||
{
|
||||
prop: "icon?",
|
||||
types: "Lucide icon name",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "iconPosition?",
|
||||
types: ["left", "right"],
|
||||
default: "left",
|
||||
},
|
||||
{
|
||||
prop: "loading?",
|
||||
types: "boolean",
|
||||
default: "false",
|
||||
},
|
||||
{
|
||||
prop: "loadingText?",
|
||||
types: "string",
|
||||
default: "Loading...",
|
||||
},
|
||||
{
|
||||
prop: "disabled?",
|
||||
types: "boolean",
|
||||
default: "false",
|
||||
},
|
||||
{
|
||||
prop: "href?",
|
||||
types: "string",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "newTab?",
|
||||
types: "boolean",
|
||||
default: "false",
|
||||
},
|
||||
{
|
||||
prop: "size?",
|
||||
types: ["sm", "md", "lg"],
|
||||
default: "md",
|
||||
},
|
||||
{
|
||||
prop: "className?",
|
||||
types: "string",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "children?",
|
||||
types: "React.ReactNode",
|
||||
default: "undefined",
|
||||
},
|
||||
],
|
||||
};
|
||||
85
homepage/design-system/src/app/views/colors/page.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Colors() {
|
||||
return (
|
||||
<>
|
||||
<p className="p-1">
|
||||
Jazz uses a color palette which extends tailwind classes, with some
|
||||
modifications, see{" "}
|
||||
<Link
|
||||
href="https://tailwindcss.com/docs/colors#using-color-utilities"
|
||||
className="text-highlight"
|
||||
>
|
||||
Tailwind Color Utilities
|
||||
</Link>{" "}
|
||||
for more infomation on basic usage.
|
||||
</p>
|
||||
<p className="mt-1 p-1">
|
||||
Nearly all use cases are encapsulated by harnessing variables which have
|
||||
a baked in light & dark mode; meaning there are only a limited number of
|
||||
variables which are required for most development.
|
||||
<span className="italic">
|
||||
To see light/dark mode toggle your system settings.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<h3 id="color-variables" className="text-md mt-6 mb-1 font-bold">
|
||||
Color Variables
|
||||
</h3>
|
||||
|
||||
<p className="mb-2 p-1">
|
||||
The following variables are available and should be used as a preference
|
||||
to tailwind classes:
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2 p-3">
|
||||
<div className="bg-primary text-white p-3 rounded-md">Primary</div>
|
||||
<div className="bg-highlight text-white p-3 rounded-md">Highlight</div>
|
||||
<div className="bg-tip text-white p-3 rounded-md">Tip</div>
|
||||
<div className="bg-info text-white p-3 rounded-md">Info</div>
|
||||
<div className="bg-success text-white p-3 rounded-md">Success</div>
|
||||
<div className="bg-warning text-white p-3 rounded-md">Warning</div>
|
||||
<div className="bg-alert text-white p-3 rounded-md">Alert</div>
|
||||
<div className="bg-danger text-white p-3 rounded-md">Danger</div>
|
||||
<div className="bg-muted text-white p-3 rounded-md">Muted</div>
|
||||
<div className="bg-strong text-white dark:text-stone-900 p-3 rounded-md">
|
||||
Strong
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs mt-1 mb-4">
|
||||
NB: These classes should be used across all apps as the primary an
|
||||
secondary colour are updated per app.
|
||||
<br />
|
||||
<br />
|
||||
For full custimisation, the default colours on tailwind are programmed
|
||||
to be the tailwind semantic colours, so you can achieve a transparent
|
||||
primary with `blue/20`.
|
||||
</p>
|
||||
|
||||
<h3 id="text-color-variables" className="text-md mt-6 font-bold">
|
||||
Text Color Variables
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 my-3 px-3">
|
||||
<ColorTypography />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const ColorTypography = () => {
|
||||
return (
|
||||
<div className={clsx("text-default rounded-md")}>
|
||||
<div className="text-default mb-1">text-default</div>
|
||||
<div className="text-muted mb-1">text-muted</div>
|
||||
<div className="text-strong mb-1">text-strong</div>
|
||||
{/* <div>
|
||||
<span className="text-default bg-highlight">bg-highlight*</span>
|
||||
</div> */}
|
||||
<div className="text-strong my-1">
|
||||
<span className="bg-highlight">text-strong bg-highlight*</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
33
homepage/design-system/src/app/views/components/page.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { Switch } from "@/components/atoms/Switch";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Components() {
|
||||
const [checked, setChecked] = useState({
|
||||
md: true,
|
||||
sm: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="p-3">
|
||||
<div className="pb-4 flex gap-6 flex-col md:flex-row">
|
||||
<h3 className="text-md font-semibold">Switches</h3>
|
||||
<Switch
|
||||
label="Switch default (md) (Primary)"
|
||||
id="switch-md"
|
||||
checked={checked.md}
|
||||
onChange={() => setChecked({ ...checked, md: !checked.md })}
|
||||
/>
|
||||
<Switch
|
||||
label="Switch (sm) success"
|
||||
id="switch-sm"
|
||||
checked={checked.sm}
|
||||
onChange={() => setChecked({ ...checked, sm: !checked.sm })}
|
||||
size="sm"
|
||||
intent="success"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
82
homepage/design-system/src/app/views/icons/page.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Icon } from "@/components/atoms/Icon";
|
||||
import { Table } from "@/components/molecules/Table";
|
||||
|
||||
export default function IconsView() {
|
||||
return (
|
||||
<div className="p-3">
|
||||
<div className="flex gap-2">
|
||||
<Icon name="search" size="xs" intent="primary" />
|
||||
<Icon name="zip" size="md" intent="info" />
|
||||
<Icon name="docs" size="lg" intent="success" />
|
||||
<Icon name="file" size="xl" intent="warning" />
|
||||
<Icon name="hash" size="2xl" intent="danger" />
|
||||
<Icon name="help" size="3xl" intent="alert" />
|
||||
<Icon name="image" size="4xl" intent="tip" />
|
||||
<Icon name="corecord" size="5xl" intent="default" />
|
||||
<Icon name="corecord" size="6xl" intent="muted" />
|
||||
<Icon name="corecord" size="7xl" intent="strong" />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Icon name="search" size="xs" intent="primary" hasBackground />
|
||||
<Icon name="zip" size="md" intent="info" hasBackground />
|
||||
<Icon name="docs" size="lg" intent="success" hasBackground />
|
||||
<Icon name="file" size="xl" intent="warning" hasBackground />
|
||||
<Icon name="hash" size="2xl" intent="danger" hasBackground />
|
||||
<Icon name="help" size="3xl" intent="alert" hasBackground />
|
||||
<Icon name="image" size="4xl" intent="tip" hasBackground />
|
||||
<Icon name="corecord" size="5xl" intent="default" hasBackground />
|
||||
<Icon name="corecord" size="6xl" intent="muted" hasBackground />
|
||||
<Icon name="corecord" size="7xl" intent="strong" hasBackground />
|
||||
</div>
|
||||
<Table className="mt-6" tableData={iconPropsTable} copyable />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const iconPropsTable = {
|
||||
headers: ["prop", "types", "default"],
|
||||
data: [
|
||||
{
|
||||
prop: "name",
|
||||
types: "string",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "icon",
|
||||
types: "LucideIcon",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "size",
|
||||
types: ["xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl"],
|
||||
default: "md",
|
||||
},
|
||||
{
|
||||
prop: "intent",
|
||||
types: [
|
||||
"default",
|
||||
"primary",
|
||||
"info",
|
||||
"success",
|
||||
"warning",
|
||||
"danger",
|
||||
"alert",
|
||||
"tip",
|
||||
"muted",
|
||||
"strong",
|
||||
"white",
|
||||
],
|
||||
default: "default",
|
||||
},
|
||||
{
|
||||
prop: "hasBackground",
|
||||
types: "boolean",
|
||||
default: "false",
|
||||
},
|
||||
{
|
||||
prop: "className",
|
||||
types: "string",
|
||||
default: "undefined",
|
||||
},
|
||||
],
|
||||
};
|
||||
146
homepage/design-system/src/app/views/inputs/page.tsx
Normal file
@@ -0,0 +1,146 @@
|
||||
"use client";
|
||||
|
||||
import { Input } from "@/components/molecules/Input";
|
||||
import { InputWithButton } from "@/components/molecules/InputWithButton";
|
||||
import { Table } from "@/components/molecules/Table";
|
||||
import { NewsletterForm } from "@/components/organisms/NewsletterForm";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function InputsView() {
|
||||
const [checked, setChecked] = useState({
|
||||
md: true,
|
||||
sm: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="p-3">
|
||||
<p>
|
||||
Inputs consist of a combintion of atoms which can be used to create a
|
||||
variety of inputs. These atoms include:
|
||||
<br />
|
||||
<br />
|
||||
<code>Icon</code>, <code>Label</code> and <code>Button</code>, and also
|
||||
may be styled with the <code>variant</code> prop.
|
||||
</p>
|
||||
<div className="flex flex-col gap-2 mt-3">
|
||||
<h3 className="text-lg font-semibold my-2">Icons</h3>
|
||||
<Input
|
||||
icon="search"
|
||||
label="Search [label hidden]"
|
||||
iconPosition="left"
|
||||
placeholder="Search"
|
||||
labelHidden={true}
|
||||
/>
|
||||
<Input
|
||||
icon="check"
|
||||
label="Email"
|
||||
iconPosition="left"
|
||||
placeholder="Email"
|
||||
/>
|
||||
<Input
|
||||
icon="file"
|
||||
label="Password"
|
||||
iconPosition="right"
|
||||
placeholder="Password"
|
||||
/>
|
||||
<Input
|
||||
icon="eye"
|
||||
label="Password"
|
||||
iconPosition="right"
|
||||
labelPosition="row"
|
||||
placeholder="Password"
|
||||
/>
|
||||
<h3 className="text-lg font-semibold my-2">Variants</h3>
|
||||
<Input label="Muted" placeholder="Muted" intent="muted" />
|
||||
<Input label="Strong" placeholder="Strong" intent="strong" />
|
||||
<Input label="Default" placeholder="Default" intent="default" />
|
||||
<h3 className="text-lg font-semibold my-2">Buttons</h3>
|
||||
<InputWithButton
|
||||
inputProps={{
|
||||
label: "Input with button [label visible]",
|
||||
labelHidden: false,
|
||||
placeholder: "Input with button",
|
||||
intent: "success",
|
||||
}}
|
||||
buttonProps={{
|
||||
children: "Let's go",
|
||||
intent: "success",
|
||||
variant: "inverted",
|
||||
icon: "check",
|
||||
iconPosition: "left",
|
||||
}}
|
||||
/>
|
||||
<InputWithButton
|
||||
inputProps={{
|
||||
label: "Input with button [label visible]",
|
||||
labelHidden: false,
|
||||
labelPosition: "row",
|
||||
placeholder: "Input with button",
|
||||
}}
|
||||
buttonProps={{
|
||||
children: "Learn more",
|
||||
intent: "tip",
|
||||
variant: "outline",
|
||||
icon: "corecord",
|
||||
iconPosition: "right",
|
||||
}}
|
||||
/>
|
||||
<NewsletterForm />
|
||||
</div>
|
||||
<Table className="mt-6" tableData={inputPropsTable} copyable />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const inputPropsTable = {
|
||||
headers: ["prop", "types", "default"],
|
||||
data: [
|
||||
{
|
||||
prop: "label",
|
||||
types: "string",
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "labelHidden?",
|
||||
types: "boolean",
|
||||
default: "false",
|
||||
},
|
||||
{
|
||||
prop: "labelPosition?",
|
||||
types: ["column", "row"],
|
||||
default: "column",
|
||||
},
|
||||
{
|
||||
prop: "icon?",
|
||||
types: ["LucideIcon"],
|
||||
default: "undefined",
|
||||
},
|
||||
{
|
||||
prop: "iconPosition?",
|
||||
types: ["left", "right"],
|
||||
default: "left",
|
||||
},
|
||||
{
|
||||
prop: "intent?",
|
||||
types: [
|
||||
"primary",
|
||||
"secondary",
|
||||
"info",
|
||||
"success",
|
||||
"warning",
|
||||
"danger",
|
||||
"alert",
|
||||
"tip",
|
||||
"muted",
|
||||
"strong",
|
||||
"default",
|
||||
],
|
||||
default: "default",
|
||||
},
|
||||
{
|
||||
prop: "buttonProps?",
|
||||
types: "see Button Props",
|
||||
default: "undefined",
|
||||
},
|
||||
],
|
||||
};
|
||||
16
homepage/design-system/src/app/views/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ViewsLayout } from "./ViewsLayout";
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const pathname = usePathname();
|
||||
const viewName = pathname.split("/").pop();
|
||||
|
||||
return (
|
||||
<ViewsLayout>
|
||||
<h2 className="text-2xl font-bold capitalize my-3">{viewName}</h2>
|
||||
{children}
|
||||
</ViewsLayout>
|
||||
);
|
||||
}
|
||||
56
homepage/design-system/src/app/views/typography/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Prose } from "@/components/molecules/Prose";
|
||||
|
||||
export default function Typography() {
|
||||
return (
|
||||
<div className="grid gap-4">
|
||||
<div>
|
||||
Heading 1
|
||||
<Prose className="p-3">
|
||||
<h1>Ship top-tier apps at high tempo</h1>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 2
|
||||
<Prose className="p-3">
|
||||
<h2>Ship top-tier apps at high tempo</h2>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 3
|
||||
<Prose className="p-3">
|
||||
<h3>Ship top-tier apps at high tempo</h3>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Heading 4
|
||||
<Prose className="p-3">
|
||||
<h4>Ship top-tier apps at high tempo</h4>
|
||||
</Prose>
|
||||
</div>
|
||||
<div>
|
||||
Paragraph
|
||||
<p className="text-xs text-highlight my-1">
|
||||
NB: That text can be styled with colour classes, including{" "}
|
||||
<code>text-muted</code> and <code>text-highlight</code>, see{" "}
|
||||
<a href="#text-color-variables">Text Color Variables</a>.
|
||||
</p>
|
||||
<Prose className="p-3">
|
||||
<p>
|
||||
<strong>Jazz is a framework for building local-first apps</strong> —
|
||||
an architecture that lets companies like Figma and Linear play in a
|
||||
league of their own.
|
||||
</p>
|
||||
|
||||
<p>Open source. Self-host or use Jazz Cloud for zero-config magic.</p>
|
||||
</Prose>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Code
|
||||
<Prose className="p-3">
|
||||
This is a one-line <code>piece of code</code>
|
||||
</Prose>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,16 +1,42 @@
|
||||
import { clsx } from "clsx";
|
||||
import Link from "next/link";
|
||||
import { forwardRef } from "react";
|
||||
import {
|
||||
Style,
|
||||
Variant,
|
||||
VariantColor,
|
||||
colorToBgActiveMap25,
|
||||
colorToBgActiveMap50,
|
||||
colorToBgHoverMap10,
|
||||
colorToBgHoverMap30,
|
||||
colorToBgMap,
|
||||
shadowClassesBase,
|
||||
sizeClasses,
|
||||
styleToBgGradientColorMap,
|
||||
styleToBgGradientHoverMap,
|
||||
styleToBgTransparentActiveMap,
|
||||
styleToBorderMap,
|
||||
styleToButtonStateMap,
|
||||
styleToColorMap,
|
||||
styleToHoverShadowMap,
|
||||
styleToTextActiveMap,
|
||||
styleToTextHoverMap,
|
||||
styleToTextMap,
|
||||
} from "../../utils/tailwindClassesMap";
|
||||
import { Icon } from "./Icon";
|
||||
import type { IconName } from "./Icon";
|
||||
import { Spinner } from "./Spinner";
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: "primary" | "secondary" | "tertiary" | "destructive" | "plain";
|
||||
export interface ButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
intent?: Style;
|
||||
variant?: Variant;
|
||||
state?: "hover" | "active" | "focus" | "disabled";
|
||||
size?: "sm" | "md" | "lg";
|
||||
href?: string;
|
||||
newTab?: boolean;
|
||||
icon?: IconName;
|
||||
iconPosition?: "left" | "right" | "center";
|
||||
loading?: boolean;
|
||||
loadingText?: string;
|
||||
children?: React.ReactNode;
|
||||
@@ -18,63 +44,44 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
function ButtonIcon({ icon, loading }: ButtonProps) {
|
||||
if (!Icon) return null;
|
||||
|
||||
const className = "size-5";
|
||||
|
||||
if (loading) return <Spinner className={className} />;
|
||||
|
||||
if (icon) {
|
||||
return <Icon name={icon} className={className} />;
|
||||
}
|
||||
}
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
size = "md",
|
||||
variant = "primary",
|
||||
intent = "default",
|
||||
variant,
|
||||
href,
|
||||
disabled,
|
||||
newTab,
|
||||
loading,
|
||||
loadingText,
|
||||
icon,
|
||||
iconPosition = "left",
|
||||
type = "button",
|
||||
...buttonProps
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const sizeClasses = {
|
||||
sm: "text-sm py-1 px-2",
|
||||
md: "py-1.5 px-3",
|
||||
lg: "md:text-lg py-2 px-3 md:px-8 md:py-3",
|
||||
const styleClass =
|
||||
styleClasses(intent, variant)[variant as keyof typeof styleClasses] || "";
|
||||
|
||||
const getClasses = ({ variant }: { variant: string | undefined }) => {
|
||||
return {
|
||||
[sizeClasses[size as keyof typeof sizeClasses]]: size,
|
||||
[variantClass(intent)]: !variant,
|
||||
[styleClass]: variant,
|
||||
};
|
||||
};
|
||||
|
||||
const variantClasses = {
|
||||
primary:
|
||||
"bg-primary border border-primary text-white font-medium hover:bg-highlight hover:border-primary hover:text-primary dark:hover:bg-highlight dark:hover:text-primary",
|
||||
secondary:
|
||||
"text-stone-900 border font-medium hover:border-primary hover:text-primary hover:bg-highlight hover:dark:border-primary dark:text-white dark:hover:text-primary",
|
||||
tertiary: "text-primary underline underline-offset-4",
|
||||
destructive:
|
||||
"bg-red-600 border-red-600 text-white font-medium hover:bg-red-700 hover:border-red-700",
|
||||
};
|
||||
|
||||
const classNames =
|
||||
variant === "plain"
|
||||
? className
|
||||
: clsx(
|
||||
className,
|
||||
"inline-flex items-center justify-center gap-2 rounded-lg text-center transition-colors",
|
||||
"disabled:pointer-events-none disabled:opacity-70",
|
||||
sizeClasses[size],
|
||||
variantClasses[variant],
|
||||
disabled && "opacity-50 cursor-not-allowed pointer-events-none",
|
||||
);
|
||||
const classNames = clsx(
|
||||
"inline-flex items-center justify-center gap-2 rounded-lg text-center transition-colors w-fit text-nowrap",
|
||||
getClasses({ variant }),
|
||||
"disabled:pointer-events-none disabled:opacity-70",
|
||||
disabled && "opacity-50 cursor-not-allowed pointer-events-none",
|
||||
className,
|
||||
);
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
@@ -83,10 +90,17 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
target={newTab ? "_blank" : undefined}
|
||||
className={classNames}
|
||||
>
|
||||
<ButtonIcon icon={icon} loading={loading} />
|
||||
{icon && (
|
||||
<Icon
|
||||
name={icon}
|
||||
className={`size-5 ${iconPosition === "left" ? "mr-2" : iconPosition === "right" ? "ml-2" : ""}, ${iconVariant(intent, variant)}`}
|
||||
/>
|
||||
)}
|
||||
{children}
|
||||
{newTab ? (
|
||||
<span className="inline-block text-muted relative -top-0.5 -left-2 -mr-2">
|
||||
<span
|
||||
className={`inline-block relative -top-0.5 -left-2 -mr-2 ${styleToTextMap[intent as keyof typeof styleToTextMap]}`}
|
||||
>
|
||||
⌝
|
||||
</span>
|
||||
) : (
|
||||
@@ -104,10 +118,49 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
className={classNames}
|
||||
type={type}
|
||||
>
|
||||
<ButtonIcon icon={icon} loading={loading} />
|
||||
|
||||
{loading ? (
|
||||
<Spinner className="size-5" />
|
||||
) : (
|
||||
icon &&
|
||||
iconPosition === "left" && (
|
||||
<Icon name={icon} intent={iconVariant(intent, variant)} />
|
||||
)
|
||||
)}
|
||||
{loading && loadingText ? loadingText : children}
|
||||
{icon && iconPosition === "right" && (
|
||||
<Icon
|
||||
name={icon}
|
||||
intent={iconVariant(intent, variant)}
|
||||
hasHover={true}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const iconVariant = (intent: Style, variant: Variant | undefined) => {
|
||||
return variant ? intent : intent === "default" ? "default" : "white";
|
||||
};
|
||||
const textColorVariant = (style: Style) => {
|
||||
return style === "default"
|
||||
? "text-stone-700 dark:text-white hover:text-stone-800 active:text-stone-700 dark:hover:text-stone-100 dark:active:text-stone-200"
|
||||
: style === "strong"
|
||||
? "text-stone-100 dark:text-stone-900"
|
||||
: "text-white";
|
||||
};
|
||||
|
||||
const variantClass = (intent: Style) =>
|
||||
`${styleToBgGradientColorMap[intent]} ${styleToBgGradientHoverMap[intent]} ${textColorVariant(intent)} ${styleToButtonStateMap[intent]} ${shadowClassesBase} shadow-stone-400/20`;
|
||||
|
||||
const styleClasses = (intent: Style, variant: Variant | undefined) => {
|
||||
return {
|
||||
outline: `border ${styleToBorderMap[intent]} ${styleToTextMap[intent]} ${styleToTextHoverMap[intent]} ${styleToHoverShadowMap[intent]} ${styleToBgTransparentActiveMap[intent]} shadow-[5px_0px]`,
|
||||
inverted: `${styleToTextMap[intent]} ${colorToBgHoverMap30[styleToColorMap[intent] as VariantColor]} ${colorToBgMap[styleToColorMap[intent] as VariantColor]} ${colorToBgActiveMap50[styleToColorMap[intent] as VariantColor]} ${shadowClassesBase}`,
|
||||
ghost: `bg-transparent ${styleToTextMap[intent]} ${colorToBgHoverMap10[styleToColorMap[intent] as VariantColor]} ${colorToBgActiveMap25[styleToColorMap[intent] as VariantColor]}`,
|
||||
link: `bg-transparent ${styleToTextMap[intent]} underline underline-offset-2 p-0 hover:bg-transparent ${styleToTextHoverMap[intent]} ${styleToTextActiveMap[intent]} active:underline-stone-500`,
|
||||
secondary: variantClass("muted"),
|
||||
destructive: variantClass("danger"),
|
||||
default: `${styleToBgGradientColorMap["default"]} ${styleToBgGradientHoverMap["default"]} ${textColorVariant("default")} ${styleToButtonStateMap["default"]} ${shadowClassesBase} shadow-stone-400/20`,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -12,8 +12,10 @@ import {
|
||||
ChevronLeftIcon,
|
||||
ChevronRight,
|
||||
ChevronRightIcon,
|
||||
ClipboardCheckIcon,
|
||||
ClipboardIcon,
|
||||
CodeIcon,
|
||||
Eye,
|
||||
FileLock2Icon,
|
||||
FileTextIcon,
|
||||
FingerprintIcon,
|
||||
@@ -46,9 +48,15 @@ import {
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
Style,
|
||||
styleToTextHoverMap,
|
||||
styleToTextMap,
|
||||
} from "../../utils/tailwindClassesMap";
|
||||
import { GcmpIcons } from "./icons";
|
||||
|
||||
const icons = {
|
||||
export const icons = {
|
||||
arrowDown: ArrowDownIcon,
|
||||
arrowRight: ArrowRightIcon,
|
||||
auth: UserIcon,
|
||||
@@ -59,6 +67,7 @@ const icons = {
|
||||
close: XIcon,
|
||||
code: CodeIcon,
|
||||
copy: ClipboardIcon,
|
||||
copySuccess: ClipboardCheckIcon,
|
||||
cursor: MousePointer2Icon,
|
||||
darkTheme: MoonIcon,
|
||||
delete: TrashIcon,
|
||||
@@ -100,6 +109,7 @@ const icons = {
|
||||
// text editor icons
|
||||
bold: BoldIcon,
|
||||
italic: ItalicIcon,
|
||||
eye: Eye,
|
||||
};
|
||||
|
||||
// copied from tailwind line height https://tailwindcss.com/docs/font-size
|
||||
@@ -107,8 +117,8 @@ const sizes = {
|
||||
"2xs": 14,
|
||||
xs: 16,
|
||||
sm: 20,
|
||||
md: 24,
|
||||
lg: 28,
|
||||
md: 22,
|
||||
lg: 26,
|
||||
xl: 28,
|
||||
"2xl": 32,
|
||||
"3xl": 36,
|
||||
@@ -143,13 +153,19 @@ export function Icon({
|
||||
name,
|
||||
icon,
|
||||
size = "md",
|
||||
intent = "default",
|
||||
hasBackground = false,
|
||||
className,
|
||||
hasHover = false,
|
||||
...svgProps
|
||||
}: {
|
||||
name?: IconName;
|
||||
icon?: LucideIcon;
|
||||
size?: keyof typeof sizes;
|
||||
intent?: Style | "white";
|
||||
hasBackground?: boolean;
|
||||
className?: string;
|
||||
hasHover?: boolean;
|
||||
} & React.SVGProps<SVGSVGElement>) {
|
||||
if (!icon && (!name || !icons.hasOwnProperty(name))) {
|
||||
throw new Error(`Icon not found: ${name}`);
|
||||
@@ -158,13 +174,52 @@ export function Icon({
|
||||
// @ts-ignore
|
||||
const IconComponent = icons?.hasOwnProperty(name) ? icons[name] : icon;
|
||||
|
||||
const iconClass = {
|
||||
...styleToTextMap,
|
||||
white: "text-white",
|
||||
};
|
||||
|
||||
const iconHoverClass = {
|
||||
...styleToTextHoverMap,
|
||||
white: "hover:text-white/90",
|
||||
};
|
||||
|
||||
const backgroundClasses = {
|
||||
default: "bg-stone-200/30 dark:bg-stone-900/30",
|
||||
primary: "bg-primary-transparent",
|
||||
secondary: "bg-secondary-transparent",
|
||||
info: "bg-info-transparent",
|
||||
success: "bg-success-transparent",
|
||||
warning: "bg-warning-transparent",
|
||||
danger: "bg-danger-transparent",
|
||||
alert: "bg-alert-transparent",
|
||||
tip: "bg-tip-transparent",
|
||||
muted: "bg-stone-300/30 dark:bg-stone-700/30",
|
||||
strong: "bg-stone-900/30 dark:bg-stone-100/30",
|
||||
};
|
||||
|
||||
const roundedClasses = {
|
||||
xs: "rounded-xs",
|
||||
sm: "rounded-sm",
|
||||
md: "rounded-md",
|
||||
lg: "rounded-lg",
|
||||
xl: "rounded-xl",
|
||||
};
|
||||
|
||||
return (
|
||||
<IconComponent
|
||||
aria-hidden="true"
|
||||
size={sizes[size]}
|
||||
strokeWidth={strokeWidths[size]}
|
||||
strokeLinecap="round"
|
||||
className={className}
|
||||
className={clsx(
|
||||
roundedClasses[size as keyof typeof roundedClasses] || "rounded-lg",
|
||||
iconClass[intent as keyof typeof iconClass],
|
||||
hasBackground &&
|
||||
backgroundClasses[intent as keyof typeof backgroundClasses],
|
||||
hasHover && iconHoverClass[intent as keyof typeof iconHoverClass],
|
||||
className,
|
||||
)}
|
||||
{...svgProps}
|
||||
/>
|
||||
);
|
||||
|
||||
13
homepage/design-system/src/components/atoms/Label.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Label as LabelRadix } from "radix-ui";
|
||||
|
||||
export function Label({
|
||||
label,
|
||||
htmlFor,
|
||||
className,
|
||||
}: { label: string; htmlFor: string; className?: string }) {
|
||||
return (
|
||||
<LabelRadix.Root className={className} htmlFor={htmlFor}>
|
||||
{label}
|
||||
</LabelRadix.Root>
|
||||
);
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export function Spinner({ className }: { className?: string }) {
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
strokeWidth="4"
|
||||
></circle>
|
||||
<path
|
||||
className="opacity-75"
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
import clsx from "clsx";
|
||||
import { Switch as RadixSwitch } from "radix-ui";
|
||||
import { Style, styleToBgMap } from "../../utils/tailwindClassesMap";
|
||||
|
||||
export function Switch({
|
||||
id,
|
||||
size = "sm",
|
||||
size = "md",
|
||||
intent = "primary",
|
||||
checked,
|
||||
onChange,
|
||||
label,
|
||||
}: {
|
||||
id: string;
|
||||
size?: "sm" | "md";
|
||||
intent?: Style;
|
||||
checked: boolean;
|
||||
onChange: (checked: boolean) => void;
|
||||
label?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 w-content">
|
||||
<div className="flex items-center w-content">
|
||||
<label
|
||||
className={clsx("text-xs text-gray-500", labelSizeClass[size])}
|
||||
className={clsx("text-gray-500 mr-2", labelSizeClass[size])}
|
||||
htmlFor={id}
|
||||
>
|
||||
{label}
|
||||
@@ -25,18 +28,21 @@ export function Switch({
|
||||
<RadixSwitch.Root
|
||||
id={id}
|
||||
className={clsx(
|
||||
"min-w-10 h-6 rounded-full relative",
|
||||
size === "sm" && "min-w-6 h-3.5",
|
||||
checked ? "bg-primary" : "bg-stone-200",
|
||||
"rounded-full relative",
|
||||
size === "sm" ? "min-w-6 h-4" : "min-w-10 h-6",
|
||||
checked ? styleToBgMap[intent] : "bg-stone-200",
|
||||
)}
|
||||
checked={checked}
|
||||
onCheckedChange={onChange}
|
||||
>
|
||||
<RadixSwitch.Thumb
|
||||
className={clsx(
|
||||
"block w-4 h-4 bg-white rounded-full transition-transform duration-300 translate-x-0 ml-[0.06rem]",
|
||||
size === "sm" && "w-3 h-3",
|
||||
checked && "translate-x-[0.6rem]",
|
||||
"block bg-white rounded-full transition-transform duration-300 translate-x-0 ml-[0.1em]",
|
||||
size === "sm" ? "w-3 h-3" : "w-5 h-5",
|
||||
checked &&
|
||||
(size === "sm"
|
||||
? "translate-x-[0.5rem]"
|
||||
: "translate-x-[1.01rem]"),
|
||||
)}
|
||||
/>
|
||||
</RadixSwitch.Root>
|
||||
|
||||
@@ -11,7 +11,7 @@ export function CopyButton({
|
||||
onCopy,
|
||||
}: {
|
||||
code: string;
|
||||
size: "md" | "lg";
|
||||
size: "sm" | "md" | "lg";
|
||||
className?: string;
|
||||
onCopy?: () => void;
|
||||
}) {
|
||||
@@ -32,13 +32,13 @@ export function CopyButton({
|
||||
type="button"
|
||||
className={clsx(
|
||||
className,
|
||||
"group/button absolute overflow-hidden rounded text-2xs font-medium md:opacity-0 backdrop-blur transition md:focus:opacity-100 group-hover:opacity-100",
|
||||
"group/button absolute overflow-hidden rounded text-2xs font-medium md:opacity-0 backdrop-blur transition md:focus:opacity-100 group-hover:opacity-100 items-center align-middle p-0",
|
||||
copied
|
||||
? "bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20"
|
||||
? "bg-blue-400/10 ring-1 ring-inset ring-blue-400/20"
|
||||
: "bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5",
|
||||
size == "md"
|
||||
size === "md"
|
||||
? "right-[8.5px] top-[8.5px] py-[2px] pl-1 pr-2"
|
||||
: "right-2 top-2 py-1 pl-2 pr-3",
|
||||
: "right-2 top-2 py-1 pl-2 pr-2",
|
||||
)}
|
||||
onClick={() => {
|
||||
window.navigator.clipboard.writeText(code).then(() => {
|
||||
@@ -60,18 +60,22 @@ export function CopyButton({
|
||||
className={clsx(
|
||||
size === "md" ? "size-3" : "size-4",
|
||||
"stroke-stone-500 transition-colors group-hover/button:stroke-stone-600 dark:group-hover/button:stroke-stone-400",
|
||||
copied && "stroke-primary",
|
||||
)}
|
||||
/>
|
||||
Copy
|
||||
{size !== "sm" && "Copy"}
|
||||
</span>
|
||||
<span
|
||||
aria-hidden={!copied}
|
||||
className={clsx(
|
||||
"pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-600 transition duration-300 dark:text-emerald-400",
|
||||
"pointer-events-none absolute inset-0 flex items-center justify-center text-primary transition duration-300",
|
||||
!copied && "translate-y-1.5 opacity-0",
|
||||
)}
|
||||
>
|
||||
Copied!
|
||||
{size === "sm" && (
|
||||
<Icon name="copySuccess" size="xs" className="stroke-primary" />
|
||||
)}
|
||||
{size !== "sm" && "Copied!"}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -21,7 +21,9 @@ export function FeatureCard({
|
||||
{icon && (
|
||||
<Icon
|
||||
name={icon}
|
||||
className="text-primary p-1.5 rounded-lg bg-blue-50 dark:bg-stone-900 mb-2.5"
|
||||
intent="primary"
|
||||
hasBackground
|
||||
className="p-1.5 rounded-lg mb-2.5"
|
||||
size="3xl"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,32 +1,101 @@
|
||||
import { clsx } from "clsx";
|
||||
import { forwardRef, useId } from "react";
|
||||
import { Style, styleToActiveBorderMap } from "../../utils/tailwindClassesMap";
|
||||
import { Button, ButtonProps } from "../atoms/Button";
|
||||
import { Icon, icons } from "../atoms/Icon";
|
||||
import { Label } from "../atoms/Label";
|
||||
|
||||
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
// label can be hidden with a "label:sr-only" className
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label: string;
|
||||
className?: string;
|
||||
id?: string;
|
||||
placeholder?: string;
|
||||
icon?: keyof typeof icons;
|
||||
iconPosition?: "left" | "right";
|
||||
labelHidden?: boolean;
|
||||
labelPosition?: "column" | "row";
|
||||
button?: ButtonProps;
|
||||
intent?: Style;
|
||||
}
|
||||
|
||||
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
({ label, className, id: customId, ...inputProps }, ref) => {
|
||||
(
|
||||
{
|
||||
label,
|
||||
className,
|
||||
id: customId,
|
||||
placeholder,
|
||||
icon,
|
||||
iconPosition = "left",
|
||||
labelHidden,
|
||||
labelPosition,
|
||||
button,
|
||||
intent = "default",
|
||||
...inputProps
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const generatedId = useId();
|
||||
const id = customId || generatedId;
|
||||
const inputIconClassName =
|
||||
icon && iconPosition === "left"
|
||||
? "pl-9"
|
||||
: icon && iconPosition === "right";
|
||||
|
||||
const inputClassName = clsx(
|
||||
"w-full rounded-md border px-3.5 py-2 shadow-sm",
|
||||
"w-full rounded-md border px-2.5 py-1 shadow-sm h-[36px]",
|
||||
"font-medium text-stone-900",
|
||||
"dark:text-white dark:bg-stone-925",
|
||||
);
|
||||
|
||||
const containerClassName = clsx("grid gap-1", className);
|
||||
|
||||
return (
|
||||
<div className={containerClassName}>
|
||||
<label htmlFor={id} className="text-stone-600 dark:text-stone-300">
|
||||
{label}
|
||||
</label>
|
||||
|
||||
<input ref={ref} {...inputProps} id={id} className={inputClassName} />
|
||||
<div
|
||||
className={clsx(
|
||||
"relative w-full",
|
||||
labelPosition === "row" ? "flex flex-row items-center" : "",
|
||||
)}
|
||||
>
|
||||
<Label
|
||||
label={label}
|
||||
htmlFor={id}
|
||||
className={clsx(
|
||||
labelPosition === "row" ? "mr-2" : "w-full",
|
||||
labelHidden ? "sr-only" : "",
|
||||
)}
|
||||
/>
|
||||
<div className={clsx("flex gap-2 w-full items-center")}>
|
||||
<input
|
||||
ref={ref}
|
||||
{...inputProps}
|
||||
id={id}
|
||||
className={clsx(
|
||||
inputClassName,
|
||||
inputIconClassName,
|
||||
className,
|
||||
"px-2",
|
||||
styleToActiveBorderMap[
|
||||
intent as keyof typeof styleToActiveBorderMap
|
||||
],
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
{icon && (
|
||||
<Icon
|
||||
name={icon}
|
||||
className={clsx(
|
||||
"absolute",
|
||||
iconPosition === "left"
|
||||
? "left-2"
|
||||
: iconPosition === "right"
|
||||
? "right-2"
|
||||
: "",
|
||||
)}
|
||||
intent={intent}
|
||||
/>
|
||||
)}
|
||||
{button && <Button {...button} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ButtonProps } from "../atoms/Button";
|
||||
import { Input, InputProps } from "./Input";
|
||||
|
||||
export function InputWithButton({
|
||||
inputProps,
|
||||
buttonProps,
|
||||
}: {
|
||||
inputProps: InputProps;
|
||||
buttonProps: ButtonProps;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-2 w-full">
|
||||
<Input {...inputProps} button={buttonProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
110
homepage/design-system/src/components/molecules/Table.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
"use client";
|
||||
import { clsx } from "clsx";
|
||||
import { toast } from "react-hot-toast";
|
||||
|
||||
export interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
|
||||
className?: string;
|
||||
tableData: {
|
||||
headers: string[];
|
||||
data: {
|
||||
[key: string]: string | string[];
|
||||
}[];
|
||||
};
|
||||
copyable?: boolean;
|
||||
}
|
||||
|
||||
export function Table({
|
||||
className,
|
||||
tableData,
|
||||
copyable,
|
||||
...tableProps
|
||||
}: TableProps) {
|
||||
return (
|
||||
<table
|
||||
className={clsx(
|
||||
"w-full border border-gray-200 rounded-lg overflow-hidden overflow-x-scroll",
|
||||
className,
|
||||
)}
|
||||
{...tableProps}
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
{tableData.headers.map((header) => (
|
||||
<th key={header} className="text-left pl-1 capitalize">
|
||||
{header}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="border-t border-gray-200">
|
||||
{tableData.data.map((row, index) => (
|
||||
<tr
|
||||
key={`${row.id as string}-${index}=${tableData.headers.join("-")}`}
|
||||
className={clsx(
|
||||
index % 2 === 0
|
||||
? "bg-stone-200/20 dark:bg-stone-800/40 hover:bg-stone-200/70 dark:hover:bg-stone-800/90"
|
||||
: "hover:bg-stone-200/50 dark:hover:bg-stone-100/20",
|
||||
"border-b border-stone-200 text-stone-800 hover:text-black dark:text-stone-200 dark:hover:text-white",
|
||||
)}
|
||||
>
|
||||
{tableData.headers.map((header, index) => (
|
||||
<td
|
||||
key={header}
|
||||
className={clsx(
|
||||
index === 0 && "pl-1",
|
||||
typeof row[header] !== "string" && "flex",
|
||||
)}
|
||||
>
|
||||
{typeof row[header] !== "string" ? (
|
||||
<TableDataContainer>
|
||||
{row[header]?.map((item) => (
|
||||
<div
|
||||
className={clsx(
|
||||
"hover:underline",
|
||||
copyable && "cursor-pointer",
|
||||
)}
|
||||
key={item}
|
||||
onClick={() => {
|
||||
if (copyable) {
|
||||
navigator.clipboard.writeText(item.toString());
|
||||
toast.success("Copied to clipboard");
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
))}
|
||||
</TableDataContainer>
|
||||
) : (
|
||||
<TableDataContainer isCopyable={copyable}>
|
||||
{row[header as keyof typeof row]}
|
||||
</TableDataContainer>
|
||||
)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
const TableDataContainer = ({
|
||||
children,
|
||||
className,
|
||||
isCopyable,
|
||||
}: { children: React.ReactNode; className?: string; isCopyable?: boolean }) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx("flex gap-2", className, isCopyable && "cursor-pointer")}
|
||||
onClick={() => {
|
||||
if (isCopyable && children) {
|
||||
navigator.clipboard.writeText(children.toString());
|
||||
toast.success("Copied to clipboard");
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -60,7 +60,7 @@ export function DropdownItem({
|
||||
let classes = clsx(
|
||||
className,
|
||||
// Base styles
|
||||
"group rounded-md space-x-2 focus:outline-none px-2.5 py-1.5",
|
||||
"group rounded-md space-x-2 focus:outline-none px-2.5 py-1.5",
|
||||
// Text styles
|
||||
"text-left text-sm/6 dark:text-white forced-colors:text-[CanvasText]",
|
||||
// Focus
|
||||
|
||||
@@ -170,6 +170,7 @@ export function MobileNav({
|
||||
{item.title}
|
||||
</NavLink>
|
||||
))}
|
||||
{cta}
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
@@ -200,7 +201,6 @@ export function MobileNav({
|
||||
<NavLinkLogo prominent href="/" className="mr-auto">
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
{cta}
|
||||
<button
|
||||
className="flex gap-2 p-3 rounded-xl items-center"
|
||||
onClick={() => {
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
import { useState } from "react";
|
||||
import { ErrorResponse } from "resend";
|
||||
import { subscribe } from "../../actions/resend";
|
||||
import { Button } from "../atoms/Button";
|
||||
import { Icon } from "../atoms/Icon";
|
||||
import { Input } from "../molecules/Input";
|
||||
import { InputWithButton } from "../molecules/InputWithButton";
|
||||
|
||||
export function NewsletterForm() {
|
||||
const [email, setEmail] = useState("");
|
||||
// const [subscribed, setSubscribed] = useState(false);
|
||||
const [error, setError] = useState<ErrorResponse | undefined>();
|
||||
|
||||
const [state, setState] = useState<"ready" | "loading" | "success" | "error">(
|
||||
@@ -41,32 +39,37 @@ export function NewsletterForm() {
|
||||
}
|
||||
|
||||
if (state === "error" && error?.message) {
|
||||
return <p className="text-red-700">Error: {error.message}</p>;
|
||||
return <p className="text-danger">Error: {error.message}</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<form action="" onSubmit={submit} className="flex gap-x-4 w-120 max-w-md">
|
||||
<Input
|
||||
id="email-address"
|
||||
name="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
placeholder="Enter your email"
|
||||
autoComplete="email"
|
||||
className="flex-1 label:sr-only"
|
||||
label="Email address"
|
||||
<InputWithButton
|
||||
inputProps={{
|
||||
id: "email-address",
|
||||
name: "email",
|
||||
type: "email",
|
||||
value: email,
|
||||
onChange: (e) => setEmail(e.target.value),
|
||||
required: true,
|
||||
placeholder: "Enter your email",
|
||||
autoComplete: "email",
|
||||
className: "flex-1",
|
||||
label: "Email address",
|
||||
labelHidden: true,
|
||||
intent: "primary",
|
||||
}}
|
||||
buttonProps={{
|
||||
type: "submit",
|
||||
intent: "primary",
|
||||
variant: "outline",
|
||||
loadingText: "Subscribing...",
|
||||
loading: state === "loading",
|
||||
icon: "newsletter",
|
||||
iconPosition: "right",
|
||||
children: "Subscribe",
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="secondary"
|
||||
loadingText="Subscribing..."
|
||||
loading={state === "loading"}
|
||||
icon="newsletter"
|
||||
>
|
||||
Subscribe
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider as NextThemesProvider, useTheme } from "next-themes";
|
||||
import { type ThemeProviderProps } from "next-themes/dist/types";
|
||||
import * as React from "react";
|
||||
import { useEffect } from "react";
|
||||
|
||||
function ThemeWatcher() {
|
||||
let { resolvedTheme, setTheme } = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
let media = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
function onMediaChange() {
|
||||
let systemTheme = media.matches ? "dark" : "light";
|
||||
if (resolvedTheme === systemTheme) {
|
||||
setTheme("system");
|
||||
}
|
||||
}
|
||||
|
||||
onMediaChange();
|
||||
media.addEventListener("change", onMediaChange);
|
||||
|
||||
return () => {
|
||||
media.removeEventListener("change", onMediaChange);
|
||||
};
|
||||
}, [resolvedTheme, setTheme]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||
return (
|
||||
<NextThemesProvider {...props}>
|
||||
<ThemeWatcher />
|
||||
{children}
|
||||
</NextThemesProvider>
|
||||
);
|
||||
}
|
||||
13
homepage/design-system/src/covalues/schema.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { co, z } from "jazz-tools";
|
||||
|
||||
// Example CoMap class
|
||||
export const Person = co.map({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
height: z.number().optional(),
|
||||
weight: z.number().optional(),
|
||||
});
|
||||
|
||||
export const ListOfPeople = co.list(Person);
|
||||
|
||||
export const PersonFeed = co.feed(Person);
|
||||
308
homepage/design-system/src/utils/tailwindClassesMap.ts
Normal file
@@ -0,0 +1,308 @@
|
||||
export type Variant =
|
||||
| "default"
|
||||
| "secondary"
|
||||
| "destructive"
|
||||
| "ghost"
|
||||
| "outline"
|
||||
| "link"
|
||||
| "inverted";
|
||||
|
||||
export type Style =
|
||||
| "default"
|
||||
| "primary"
|
||||
| "tip"
|
||||
| "info"
|
||||
| "success"
|
||||
| "warning"
|
||||
| "alert"
|
||||
| "danger"
|
||||
| "muted"
|
||||
| "strong";
|
||||
|
||||
export const sizeClasses = {
|
||||
sm: "text-sm py-1 px-2",
|
||||
md: "py-1.5 px-3 h-[36px]",
|
||||
lg: "py-2 px-5 md:px-6 md:py-2.5",
|
||||
};
|
||||
|
||||
export const styleToBorderMap = {
|
||||
primary: "border-primary",
|
||||
info: "border-info",
|
||||
success: "border-success",
|
||||
warning: "border-warning",
|
||||
danger: "border-danger",
|
||||
alert: "border-alert",
|
||||
tip: "border-tip",
|
||||
muted: "border-stone-200 dark:border-stone-700",
|
||||
strong: "border-stone-900 dark:border-stone-100",
|
||||
default: "border-stone-600 dark:border-stone-200",
|
||||
};
|
||||
|
||||
export const styleToActiveBorderMap = {
|
||||
primary: "active:border-primary-transparent focus:border-primary-transparent",
|
||||
info: "active:border-info-transparent focus:border-info-transparent",
|
||||
success: "active:border-success-transparent focus:border-success-transparent",
|
||||
warning: "active:border-warning-transparent focus:border-warning-transparent",
|
||||
danger: "active:border-danger-transparent focus:border-danger-transparent",
|
||||
alert: "active:border-alert-transparent focus:border-alert-transparent",
|
||||
tip: "active:border-tip-transparent focus:border-tip-transparent",
|
||||
muted:
|
||||
"active:border-stone-200/30 focus:border-stone-200/30 dark:active:border-stone-900/30 dark:focus:border-stone-900/30",
|
||||
strong:
|
||||
"active:border-stone-900/30 focus:border-stone-900/30 dark:active:border-stone-200/30 dark:focus:border-stone-200/30",
|
||||
default:
|
||||
"active:border-stone-600/30 dark:active:border-stone-100/30 focus:border-stone-600/30 dark:focus:border-stone-100/30",
|
||||
};
|
||||
|
||||
export const styleToBgMap = {
|
||||
primary: "bg-primary",
|
||||
info: "bg-info",
|
||||
success: "bg-success",
|
||||
warning: "bg-warning",
|
||||
danger: "bg-danger",
|
||||
alert: "bg-alert",
|
||||
tip: "bg-tip",
|
||||
muted: "bg-stone-200 dark:bg-stone-900",
|
||||
strong: "bg-stone-900 dark:bg-stone-200",
|
||||
default: "bg-stone-700 dark:bg-stone-100",
|
||||
};
|
||||
|
||||
export const styleToBgTransparentHoverMap = {
|
||||
primary: "hover:bg-primary-transparent",
|
||||
info: "hover:bg-info-transparent",
|
||||
success: "hover:bg-success-transparent",
|
||||
warning: "hover:bg-warning-transparent",
|
||||
danger: "hover:bg-danger-transparent",
|
||||
alert: "hover:bg-alert-transparent",
|
||||
tip: "hover:bg-tip-transparent",
|
||||
muted: "hover:bg-stone-100/20 dark:hover:bg-stone-900/20",
|
||||
strong: "hover:bg-stone-900/20 dark:hover:bg-stone-100/20",
|
||||
default: "hover:bg-stone-600/20 dark:hover:bg-stone-100/20",
|
||||
};
|
||||
|
||||
export const styleToBgTransparentActiveMap = {
|
||||
primary: "active:bg-blue/20",
|
||||
info: "active:bg-purple/20",
|
||||
success: "active:bg-green/20",
|
||||
warning: "active:bg-orange/20",
|
||||
danger: "active:bg-red/20",
|
||||
alert: "active:bg-yellow/20",
|
||||
tip: "active:bg-cyan/20",
|
||||
muted: "active:bg-stone-400/20",
|
||||
strong: "active:bg-stone-900/20",
|
||||
default: "active:bg-stone-600/20 dark:active:bg-stone-100/20",
|
||||
};
|
||||
|
||||
export const styleToTextMap = {
|
||||
primary: "text-primary",
|
||||
info: "text-info",
|
||||
success: "text-success",
|
||||
warning: "text-warning",
|
||||
danger: "text-danger",
|
||||
alert: "text-alert",
|
||||
tip: "text-tip",
|
||||
muted: "text-stone-500 dark:text-stone-400",
|
||||
strong: "text-stone-900 dark:text-white",
|
||||
default: "text-stone-700 dark:text-stone-100",
|
||||
};
|
||||
|
||||
export const styleToTextHoverMap = {
|
||||
primary: "hover:text-primary-light",
|
||||
info: "hover:text-info-light",
|
||||
success: "hover:text-success-light",
|
||||
warning: "hover:text-warning-light",
|
||||
danger: "hover:text-danger-light",
|
||||
alert: "hover:text-alert-light",
|
||||
tip: "hover:text-tip-light",
|
||||
muted: "hover:text-stone-400 dark:hover:text-stone-500",
|
||||
strong: "hover:text-stone-700 dark:hover:text-stone-300",
|
||||
default: "hover:text-stone-600 dark:hover:text-stone-200",
|
||||
};
|
||||
|
||||
export const styleToTextActiveMap = {
|
||||
primary: "active:text-primary-dark",
|
||||
info: "active:text-info-dark",
|
||||
success: "active:text-success-dark",
|
||||
warning: "active:text-warning-dark",
|
||||
danger: "active:text-danger-dark",
|
||||
alert: "active:text-alert-dark",
|
||||
tip: "active:text-tip-dark",
|
||||
muted: "active:text-stone-400 dark:active:text-stone-500",
|
||||
strong: "active:text-stone-700 dark:active:text-stone-300",
|
||||
default: "active:text-stone-800 dark:active:text-stone-400",
|
||||
};
|
||||
|
||||
export type VariantColor =
|
||||
| "blue"
|
||||
| "indigo"
|
||||
| "purple"
|
||||
| "green"
|
||||
| "orange"
|
||||
| "red"
|
||||
| "yellow"
|
||||
| "cyan"
|
||||
| "muted"
|
||||
| "strong"
|
||||
| "default";
|
||||
|
||||
export const styleToColorMap = {
|
||||
primary: "blue",
|
||||
info: "purple",
|
||||
success: "green",
|
||||
warning: "orange",
|
||||
danger: "red",
|
||||
alert: "yellow",
|
||||
tip: "cyan",
|
||||
muted: "muted",
|
||||
strong: "strong",
|
||||
default: "default",
|
||||
};
|
||||
|
||||
export const colorToBgMap = {
|
||||
blue: "bg-blue/20",
|
||||
indigo: "bg-indigo-500/20",
|
||||
purple: "bg-purple/20",
|
||||
green: "bg-green/20",
|
||||
orange: "bg-orange/20",
|
||||
red: "bg-red/20",
|
||||
yellow: "bg-yellow/20",
|
||||
cyan: "bg-cyan/20",
|
||||
muted: "bg-stone-200/20 dark:bg-stone-900/50",
|
||||
strong: "bg-stone-900/20 dark:bg-stone-100/50",
|
||||
default: "bg-stone-600/20 dark:bg-white/20",
|
||||
};
|
||||
|
||||
export const colorToBgHoverMap30 = {
|
||||
blue: "hover:bg-blue/30",
|
||||
indigo: "hover:bg-indigo-500/30",
|
||||
purple: "hover:bg-purple/30",
|
||||
green: "hover:bg-green/30",
|
||||
orange: "hover:bg-orange/30",
|
||||
red: "hover:bg-red/30",
|
||||
yellow: "hover:bg-yellow/30",
|
||||
cyan: "hover:bg-cyan/30",
|
||||
muted: "hover:bg-stone-200/30 dark:hover:bg-stone-900/30",
|
||||
strong: "hover:bg-stone-900/30 dark:hover:bg-stone-100/30",
|
||||
default: "hover:bg-stone-600/30 dark:hover:bg-white/30",
|
||||
};
|
||||
|
||||
export const colorToBgHoverMap10 = {
|
||||
blue: "hover:bg-blue/10",
|
||||
indigo: "hover:bg-indigo-500/10",
|
||||
purple: "hover:bg-purple/10",
|
||||
green: "hover:bg-green/10",
|
||||
orange: "hover:bg-orange/10",
|
||||
red: "hover:bg-red/10",
|
||||
yellow: "hover:bg-yellow/10",
|
||||
cyan: "hover:bg-cyan/10",
|
||||
muted: "hover:bg-stone-200/30 dark:hover:bg-stone-800/30",
|
||||
strong: "hover:bg-stone-900/10 dark:hover:bg-stone-100/10",
|
||||
default: "hover:bg-stone-600/10 dark:hover:bg-white/10",
|
||||
};
|
||||
|
||||
export const colorToBgActiveMap50 = {
|
||||
blue: "active:bg-blue/50",
|
||||
indigo: "active:bg-indigo-500/50",
|
||||
purple: "active:bg-purple/50",
|
||||
green: "active:bg-green/50",
|
||||
orange: "active:bg-orange/50",
|
||||
red: "active:bg-red/50",
|
||||
yellow: "active:bg-yellow/50",
|
||||
cyan: "active:bg-cyan/50",
|
||||
muted: "active:bg-stone-100/50 dark:active:bg-stone-900/50",
|
||||
strong: "active:bg-stone-800/40 dark:active:bg-stone-200/40",
|
||||
default: "active:bg-stone-900/40 dark:active:bg-white/50",
|
||||
};
|
||||
|
||||
export const colorToBgActiveMap25 = {
|
||||
blue: "active:bg-blue/25",
|
||||
indigo: "active:bg-indigo-500/25",
|
||||
purple: "active:bg-purple/25",
|
||||
green: "active:bg-green/25",
|
||||
orange: "active:bg-orange/25",
|
||||
red: "active:bg-red/25",
|
||||
yellow: "active:bg-yellow/25",
|
||||
cyan: "active:bg-cyan/25",
|
||||
muted: "active:bg-stone-100/25 dark:active:bg-stone-900/25",
|
||||
strong: "active:bg-stone-900/25 dark:active:bg-stone-100/25",
|
||||
default: "active:bg-black/25 dark:active:bg-white/25",
|
||||
};
|
||||
|
||||
const gradiantClassesBase = "bg-gradient-to-t from-7% via-50% to-95%";
|
||||
|
||||
export const styleToBgGradientColorMap = {
|
||||
primary: `from-primary-dark via-primary to-primary-light ${gradiantClassesBase}`,
|
||||
info: `from-info-dark via-info to-info-light ${gradiantClassesBase}`,
|
||||
success: `from-success-dark via-success to-success-light ${gradiantClassesBase}`,
|
||||
warning: `from-warning-dark via-warning to-warning-light ${gradiantClassesBase}`,
|
||||
danger: `from-danger-dark via-danger to-danger-light ${gradiantClassesBase}`,
|
||||
alert: `from-alert-dark via-alert to-alert-light ${gradiantClassesBase}`,
|
||||
tip: `from-tip-dark via-tip to-tip-light ${gradiantClassesBase}`,
|
||||
muted: `from-stone-200 via-stone-300 to-stone-400 ${gradiantClassesBase} dark:from-stone-900 dark:via-stone-900 dark:to-stone-800`,
|
||||
strong: `from-stone-700 via-stone-800 to-stone-900 ${gradiantClassesBase} dark:from-stone-100 dark:via-stone-200 dark:to-stone-300`,
|
||||
default: `from-stone-200/40 via-white to-stone-100 ${gradiantClassesBase} dark:from-stone-900 dark:via-black dark:to-stone-950`,
|
||||
};
|
||||
|
||||
export const styleToBgGradientHoverMap = {
|
||||
primary: `hover:from-primary-brightLight hover:to-primary-light ${gradiantClassesBase}`,
|
||||
info: `hover:from-info-brightLight hover:to-info-light ${gradiantClassesBase}`,
|
||||
success: `hover:from-success-brightLight hover:to-success-light ${gradiantClassesBase}`,
|
||||
warning: `hover:from-warning-brightLight hover:to-warning-light ${gradiantClassesBase}`,
|
||||
danger: `hover:from-danger-brightLight hover:to-danger-light ${gradiantClassesBase}`,
|
||||
alert: `hover:from-alert-brightLight hover:to-alert-light ${gradiantClassesBase}`,
|
||||
tip: `hover:from-tip-brightLight hover:to-tip-light ${gradiantClassesBase}`,
|
||||
muted: `hover:from-stone-200 hover:to-stone-300 ${gradiantClassesBase} dark:hover:from-stone-900 dark:hover:to-stone-700/70`,
|
||||
strong: `hover:from-stone-700 hover:to-stone-800 ${gradiantClassesBase} dark:hover:from-stone-100 dark:hover:to-stone-200`,
|
||||
default: `hover:from-stone-100/50 hover:to-stone-100/50 dark:hover:from-stone-950 dark:hover:to-stone-900 ${gradiantClassesBase} border border-stone-100 dark:border-stone-900`,
|
||||
};
|
||||
|
||||
export const styleToBgGradientActiveMap = {
|
||||
primary: `active:from-primary-brightDark active:to-primary-light ${gradiantClassesBase}`,
|
||||
info: `active:from-info-brightDark active:to-info-light ${gradiantClassesBase}`,
|
||||
success: `active:from-success-brightDark active:to-success-light ${gradiantClassesBase}`,
|
||||
warning: `active:from-warning-brightDark active:to-warning-light ${gradiantClassesBase}`,
|
||||
danger: `active:from-danger-brightDark active:to-danger-light ${gradiantClassesBase}`,
|
||||
alert: `active:from-alert-brightDark active:to-alert-light ${gradiantClassesBase}`,
|
||||
tip: `active:from-tip-brightDark active:to-tip-light ${gradiantClassesBase}`,
|
||||
muted: `active:from-stone-300 active:to-stone-300 ${gradiantClassesBase} dark:active:from-stone-900 dark:active:to-stone-800`,
|
||||
strong: `active:from-stone-950 active:to-stone-900 ${gradiantClassesBase} dark:active:from-stone-100 dark:active:to-stone-200`,
|
||||
default: `active:from-stone-200/50 active:to-stone-100/50 dark:active:from-stone-950 dark:active:to-black ${gradiantClassesBase}`,
|
||||
};
|
||||
|
||||
export const shadowClassesBase = "shadow-sm";
|
||||
|
||||
export const styleToHoverShadowMap = {
|
||||
primary: `${shadowClassesBase} shadow-blue/20 hover:shadow-blue/40`,
|
||||
info: `${shadowClassesBase} shadow-purple/20 hover:shadow-purple/30`,
|
||||
success: `${shadowClassesBase} shadow-green/20 hover:shadow-green/30`,
|
||||
warning: `${shadowClassesBase} shadow-orange/20 hover:shadow-orange/30`,
|
||||
danger: `${shadowClassesBase} shadow-red/20 hover:shadow-red/30`,
|
||||
alert: `${shadowClassesBase} shadow-yellow/20 hover:shadow-yellow/30`,
|
||||
tip: `${shadowClassesBase} shadow-cyan/20 hover:shadow-cyan/30`,
|
||||
muted: `${shadowClassesBase} shadow-stone-200/20 hover:shadow-stone-200/30 dark:shadow-stone-600/20 dark:hover:shadow-stone-600/30`,
|
||||
strong: `${shadowClassesBase} shadow-stone-900/20 hover:shadow-stone-900/30 dark:shadow-white/20 dark:hover:shadow-white/30`,
|
||||
default: `${shadowClassesBase} shadow-stone-600/20 hover:shadow-stone-600/30 dark:shadow-stone-200/20 dark:hover:shadow-stone-200/30`,
|
||||
};
|
||||
|
||||
const focusRingClassesBase =
|
||||
"focus:outline-none focus-visible:ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-opacity-10";
|
||||
|
||||
export const styleToButtonStateMap = {
|
||||
primary: `${styleToBgGradientActiveMap.primary} ${focusRingClassesBase} focus:ring-primary`,
|
||||
info: `${styleToBgGradientActiveMap.info} ${focusRingClassesBase} focus:ring-info`,
|
||||
success: `${styleToBgGradientActiveMap.success} ${focusRingClassesBase} focus:ring-success`,
|
||||
warning: `${styleToBgGradientActiveMap.warning} ${focusRingClassesBase} focus:ring-warning`,
|
||||
danger: `${styleToBgGradientActiveMap.danger} ${focusRingClassesBase} focus:ring-danger`,
|
||||
alert: `${styleToBgGradientActiveMap.alert} ${focusRingClassesBase} focus:ring-alert`,
|
||||
tip: `${styleToBgGradientActiveMap.tip} ${focusRingClassesBase} focus:ring-tip`,
|
||||
muted: `${styleToBgGradientActiveMap.muted} ${focusRingClassesBase} focus:ring-stone-200 dark:focus:ring-stone-900`,
|
||||
strong: `${styleToBgGradientActiveMap.strong} ${focusRingClassesBase} focus:ring-stone-800 dark:focus:ring-stone-200`,
|
||||
default: `${styleToBgGradientActiveMap.default} ${focusRingClassesBase} focus:ring-black dark:focus:ring-white`,
|
||||
};
|
||||
|
||||
export const variantStyleToButtonStateMap = {
|
||||
outline: `${focusRingClassesBase}`,
|
||||
inverted: `${focusRingClassesBase}`,
|
||||
ghost: `${focusRingClassesBase}`,
|
||||
text: `${focusRingClassesBase}`,
|
||||
};
|
||||
@@ -30,6 +30,36 @@ const jazzBlue = {
|
||||
DEFAULT: COLORS.BLUE,
|
||||
};
|
||||
|
||||
const green = {
|
||||
...colors.green,
|
||||
DEFAULT: COLORS.FOREST,
|
||||
};
|
||||
|
||||
const cyan = {
|
||||
...colors.cyan,
|
||||
DEFAULT: COLORS.TURQUOISE,
|
||||
};
|
||||
|
||||
const red = {
|
||||
...colors.red,
|
||||
DEFAULT: COLORS.RED,
|
||||
};
|
||||
|
||||
const yellow = {
|
||||
...colors.yellow,
|
||||
DEFAULT: COLORS.YELLOW,
|
||||
};
|
||||
|
||||
const orange = {
|
||||
...colors.orange,
|
||||
DEFAULT: COLORS.ORANGE,
|
||||
};
|
||||
|
||||
const purple = {
|
||||
...colors.purple,
|
||||
DEFAULT: COLORS.PURPLE,
|
||||
};
|
||||
|
||||
const stonePaletteWithAlpha = { ...stonePalette };
|
||||
|
||||
Object.keys(stonePalette).forEach((key) => {
|
||||
@@ -40,11 +70,12 @@ Object.keys(stonePalette).forEach((key) => {
|
||||
});
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
export const preset = {
|
||||
content: [
|
||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./src/utils/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
@@ -52,28 +83,103 @@ const config = {
|
||||
...harmonyPalette,
|
||||
stone: stonePaletteWithAlpha,
|
||||
blue: jazzBlue,
|
||||
primary: "var(--color-primary)",
|
||||
secondary: "var(--color-secondary)",
|
||||
highlight: "var(--color-transparent-primary)",
|
||||
success: "var(--color-success)",
|
||||
info: "var(--color-info)",
|
||||
warning: "var(--color-warning)",
|
||||
tip: "var(--color-tip)",
|
||||
green: {
|
||||
DEFAULT: "var(--color-green)",
|
||||
green,
|
||||
cyan,
|
||||
red,
|
||||
yellow,
|
||||
purple,
|
||||
orange,
|
||||
muted: "var(--color-muted)",
|
||||
strong: "var(--color-strong)",
|
||||
primary: {
|
||||
DEFAULT: "var(--color-primary)",
|
||||
transparent: "var(--color-transparent-primary)",
|
||||
dark: "var(--color-primary-dark)",
|
||||
light:
|
||||
"lch(from var(--color-primary) calc(l + 10) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-primary) calc(l - 1) calc(c + 20) calc(h + 5))",
|
||||
brightDark:
|
||||
"lch(from var(--color-primary) calc(l - 6) calc(c + 20) calc(h + 5))",
|
||||
},
|
||||
success: {
|
||||
DEFAULT: "var(--color-success)",
|
||||
transparent: "lch(from var(--color-success) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-success) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-success) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-success) calc(l - 1) calc(c + 20) calc(h + 10))",
|
||||
brightDark:
|
||||
"lch(from var(--color-success) calc(l - 6) calc(c + 20) calc(h + 10))",
|
||||
},
|
||||
info: {
|
||||
DEFAULT: "var(--color-info)",
|
||||
transparent: "lch(from var(--color-info) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-info) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-info) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-info) calc(l - 1) calc(c + 20) calc(h + 5))",
|
||||
brightDark:
|
||||
"lch(from var(--color-info) calc(l - 4) calc(c + 20) calc(h + 5))",
|
||||
},
|
||||
warning: {
|
||||
DEFAULT: "var(--color-warning)",
|
||||
transparent: "lch(from var(--color-warning) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-warning) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-warning) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-warning) calc(l - 1) calc(c + 30) calc(h + 15))",
|
||||
brightDark:
|
||||
"lch(from var(--color-warning) calc(l - 4) calc(c + 30) calc(h + 15))",
|
||||
},
|
||||
danger: {
|
||||
DEFAULT: "var(--color-danger)",
|
||||
transparent: "lch(from var(--color-danger) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-danger) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-danger) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-danger) calc(l - 2) calc(c + 20) calc(h + 10))",
|
||||
brightDark:
|
||||
"lch(from var(--color-danger) calc(l - 6) calc(c + 10) calc(h + 10))",
|
||||
},
|
||||
tip: {
|
||||
DEFAULT: "var(--color-tip)",
|
||||
transparent: "lch(from var(--color-tip) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-tip) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-tip) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-tip) calc(l - 1) calc(c + 20) calc(h + 10))",
|
||||
brightDark:
|
||||
"lch(from var(--color-tip) calc(l - 4) calc(c + 20) calc(h + 10))",
|
||||
},
|
||||
alert: {
|
||||
DEFAULT: "var(--color-alert)",
|
||||
transparent: "lch(from var(--color-alert) l c h / 0.3)",
|
||||
dark: "lch(from var(--color-alert) calc(l - 7) calc(c - 1) calc(h + 5))",
|
||||
light:
|
||||
"lch(from var(--color-alert) calc(l + 4) calc(c + 1) calc(h - 5))",
|
||||
brightLight:
|
||||
"lch(from var(--color-alert) calc(l - 1) calc(c + 50) calc(h + 15))",
|
||||
brightDark:
|
||||
"lch(from var(--color-alert) calc(l - 5) calc(c + 50) calc(h + 15))",
|
||||
},
|
||||
},
|
||||
textColor: {
|
||||
default: "var(--color-default)",
|
||||
highlight: "var(--color-highlight)",
|
||||
strong: "var(--color-strong)",
|
||||
muted: "var(--color-muted)",
|
||||
},
|
||||
borderColor: {
|
||||
DEFAULT: "var(--color-border-default)",
|
||||
},
|
||||
backgroundColor: {
|
||||
highlight: "var(--color-transparent-primary)",
|
||||
muted: "var(--color-bg-muted)",
|
||||
highlight: "var(--color-background-highlight)",
|
||||
},
|
||||
fontFamily: {
|
||||
display: ["var(--font-manrope)"],
|
||||
@@ -195,4 +301,10 @@ const config = {
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
const config = {
|
||||
presets: [preset],
|
||||
darkMode: ["class"],
|
||||
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -42,15 +42,6 @@ export const team: Array<TeamMember> = [
|
||||
linkedin: "giordanoricci",
|
||||
image: "gio.jpg",
|
||||
},
|
||||
{
|
||||
name: "Trisha Lim",
|
||||
slug: "trisha",
|
||||
titles: ["Frontend Dev", "Marketing"],
|
||||
image: "trisha.png",
|
||||
location: "Lisbon, Portugal ",
|
||||
github: "trishalim",
|
||||
website: "https://trishalim.com",
|
||||
},
|
||||
{
|
||||
name: "Meg Culotta",
|
||||
slug: "meg",
|
||||
@@ -73,7 +64,7 @@ export const team: Array<TeamMember> = [
|
||||
name: "Sammii Kellow",
|
||||
slug: "sammii",
|
||||
location: "London, UK",
|
||||
titles: ["Design Engineer", "Marketing"],
|
||||
titles: ["Frontend & Design Engineer", "Marketing"],
|
||||
x: "SammiiHaylock",
|
||||
github: "sammii-hk",
|
||||
website: "https://sammii.dev",
|
||||
@@ -91,4 +82,25 @@ export const team: Array<TeamMember> = [
|
||||
linkedin: "boorad",
|
||||
image: "brad.png",
|
||||
},
|
||||
{
|
||||
name: "Divya S",
|
||||
slug: "div",
|
||||
location: "New York, US",
|
||||
titles: ["Platform Engineer"],
|
||||
x: "shortdiv",
|
||||
github: "shortdiv",
|
||||
website: "https://shortdiv.com",
|
||||
bluesky: "shortdiv.bsky.social",
|
||||
linkedin: "shortdiv",
|
||||
image: "div.jpg",
|
||||
},
|
||||
{
|
||||
name: "Nico Rainhart",
|
||||
slug: "nico",
|
||||
location: "Buenos Aires, Argentina",
|
||||
titles: ["Full-Stack Dev", "Framework Engineer"],
|
||||
image: "nico.jpeg",
|
||||
github: "nrainhart",
|
||||
linkedin: "nicolás-rainhart",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -4,7 +4,12 @@ import { GcmpLogo } from "@garden-co/design-system/src/components/atoms/logos/Gc
|
||||
import { Nav } from "@garden-co/design-system/src/components/organisms/Nav";
|
||||
export function GcmpNav() {
|
||||
const cta = (
|
||||
<Button variant="secondary" className="ml-3" href="mailto:hello@garden.co">
|
||||
<Button
|
||||
intent="success"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
href="mailto:hello@garden.co"
|
||||
>
|
||||
Contact us
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,11 @@ export default function Products() {
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<JazzLogo className="h-10 w-auto" />
|
||||
<div>
|
||||
<Button href="https://jazz.tools" variant="secondary">
|
||||
<Button
|
||||
href="https://jazz.tools"
|
||||
intent="primary"
|
||||
variant="outline"
|
||||
>
|
||||
Go to jazz.tools
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
BIN
homepage/gcmp/public/team/div.jpg
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
homepage/gcmp/public/team/nico.jpeg
Normal file
|
After Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 186 KiB |
@@ -1,7 +1,7 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
presets: [require("@garden-co/design-system/tailwind.config.js")],
|
||||
presets: [require("@garden-co/design-system/tailwind.config.js").preset],
|
||||
darkMode: ["class"],
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ComingSoonSection } from "@/components/home/ComingSoonSection";
|
||||
import { EarlyAdopterSection } from "@/components/home/EarlyAdopterSection";
|
||||
import { EncryptionSection } from "@/components/home/EncryptionSection";
|
||||
import { FeaturesSection } from "@/components/home/FeaturesSection";
|
||||
import { GetStartedSnippetSelect } from "@/components/home/GetStartedSnippetSelect";
|
||||
import { HeroSection } from "@/components/home/HeroSection";
|
||||
import { HowJazzWorksSection } from "@/components/home/HowJazzWorksSection";
|
||||
import { LocalFirstFeaturesSection } from "@/components/home/LocalFirstFeaturesSection";
|
||||
@@ -16,7 +17,8 @@ export default function Home() {
|
||||
<>
|
||||
<HeroSection />
|
||||
|
||||
<div className="container flex flex-col gap-12 mt-12 lg:gap-20 lg:mt-20">
|
||||
<div className="container flex flex-col gap-12 lg:gap-20">
|
||||
<GetStartedSnippetSelect />
|
||||
<SupportedEnvironmentsSection />
|
||||
<HowJazzWorksSection />
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ export function FakeGetStartedButton({ tier }: { tier: "starter" | "indie" }) {
|
||||
);
|
||||
window.location.pathname = "/docs";
|
||||
}}
|
||||
variant={tier === "starter" ? "secondary" : "primary"}
|
||||
intent="primary"
|
||||
variant={tier === "starter" ? "outline" : undefined}
|
||||
>
|
||||
Get {tier === "starter" ? "Starter" : "Indie"} API Key
|
||||
</Button>
|
||||
|
||||
@@ -180,7 +180,7 @@ export function Pricing() {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<Button href="https://cal.com/anselm-io/cloud-pro-intro">
|
||||
<Button href="https://cal.com/anselm-io/cloud-pro-intro" intent="primary">
|
||||
Schedule intro call
|
||||
</Button>
|
||||
|
||||
|
||||
@@ -37,7 +37,10 @@ export function SideNavSectionList({ items }: { items?: SideNavItem[] }) {
|
||||
{items.map(({ name, href, items, done }) => (
|
||||
<li key={name}>
|
||||
<SideNavItem href={href}>
|
||||
<span className={done === 0 ? "text-muted" : ""}>{name}</span>
|
||||
<span className={done === 0 ? "text-muted" : ""}>
|
||||
{name}
|
||||
{done === 0 && <span className="text-stone-800 text-[0.5rem]"> (docs coming soon)</span>}
|
||||
</span>
|
||||
</SideNavItem>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function SideNavItem({
|
||||
}) {
|
||||
const classes = clsx(
|
||||
className,
|
||||
"py-1 px-2 -mx-2 group rounded-md flex items-center transition-colors",
|
||||
"py-1 px-2 group rounded-md flex items-center transition-colors",
|
||||
);
|
||||
const path = usePathname();
|
||||
|
||||
@@ -28,7 +28,7 @@ export function SideNavItem({
|
||||
className={clsx(
|
||||
classes,
|
||||
path === href
|
||||
? "text-stone-900 font-medium bg-stone-100 dark:text-white dark:bg-stone-900"
|
||||
? "text-stone-900 font-medium bg-stone-200/50 dark:text-white dark:bg-stone-800/50"
|
||||
: "hover:text-stone-900 dark:hover:text-stone-200",
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -10,10 +10,21 @@ import {
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
} from "@garden-co/design-system/src/components/organisms/Dropdown";
|
||||
import clsx from "clsx";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export function FrameworkSelect() {
|
||||
export function FrameworkSelect({
|
||||
onSelect,
|
||||
size = "md",
|
||||
routerPush = true,
|
||||
className,
|
||||
}: {
|
||||
onSelect?: (framework: Framework) => void;
|
||||
size?: "sm" | "md";
|
||||
routerPush?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const defaultFramework = useFramework();
|
||||
const [selectedFramework, setSelectedFramework] =
|
||||
@@ -23,25 +34,26 @@ export function FrameworkSelect() {
|
||||
|
||||
const selectFramework = (newFramework: Framework) => {
|
||||
setSelectedFramework(newFramework);
|
||||
router.push(path.replace(defaultFramework, newFramework));
|
||||
onSelect && onSelect(newFramework);
|
||||
routerPush && router.push(path.replace(defaultFramework, newFramework));
|
||||
};
|
||||
|
||||
return (
|
||||
<Dropdown>
|
||||
<DropdownButton
|
||||
className="w-full justify-between"
|
||||
className={clsx("w-full justify-between overflow-hidden text-nowrap", size === "sm" && "text-sm", className)}
|
||||
as={Button}
|
||||
variant="secondary"
|
||||
variant="outline"
|
||||
intent="default"
|
||||
>
|
||||
{frameworkNames[selectedFramework].label}
|
||||
<Icon name="chevronDown" size="sm" className="text-muted" />
|
||||
<span className="text-nowrap max-w-full overflow-hidden text-ellipsis">{frameworkNames[selectedFramework].label}</span>
|
||||
<Icon name="chevronDown" size="sm" />
|
||||
</DropdownButton>
|
||||
<DropdownMenu className="w-[--button-width] z-50" anchor="bottom start">
|
||||
{Object.entries(frameworkNames)
|
||||
.filter(([_, framework]) => !framework.hidden)
|
||||
.map(([key, framework]) => (
|
||||
<DropdownItem
|
||||
className="items-baseline"
|
||||
className={clsx("items-baseline", size === "sm" && "text-xs text-nowrap", selectedFramework === key && "text-primary dark:text-primary")}
|
||||
key={key}
|
||||
onClick={() => selectFramework(key as Framework)}
|
||||
>
|
||||
|
||||
@@ -19,9 +19,6 @@ export function HelpLinks({ className }: { className?: string }) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const linkClassName =
|
||||
"inline-flex items-center gap-2 py-1 text-sm text-stone-600 dark:text-stone-400 hover:text-highlight";
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
@@ -29,15 +26,16 @@ export function HelpLinks({ className }: { className?: string }) {
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Button href={issueUrl} variant="plain" newTab className={linkClassName}>
|
||||
<Button href={issueUrl} intent="strong" variant="ghost" newTab>
|
||||
<SiGithub className="size-4" />
|
||||
Docs issue?
|
||||
</Button>
|
||||
<Button
|
||||
href="https://discord.gg/utDMjHYg42"
|
||||
variant="plain"
|
||||
intent="strong"
|
||||
variant="ghost"
|
||||
newTab
|
||||
className={linkClassName}
|
||||
className="lg:mt-3"
|
||||
>
|
||||
<SiDiscord className="size-4" />
|
||||
Join Discord
|
||||
|
||||
@@ -25,16 +25,16 @@ export function ExampleLinks({ example }: { example: Example }) {
|
||||
return (
|
||||
<>
|
||||
<div className="flex gap-2">
|
||||
<Button variant="secondary" size="sm" onClick={() => setIsOpen(true)}>
|
||||
<Button intent="primary" variant="inverted" size="sm" onClick={() => setIsOpen(true)}>
|
||||
Use as template
|
||||
</Button>
|
||||
<Button href={githubUrl} newTab variant="secondary" size="sm">
|
||||
<Button href={githubUrl} newTab intent="primary" variant="inverted" size="sm">
|
||||
<span className="md:hidden">Code</span>
|
||||
<span className="hidden md:inline">View code</span>
|
||||
</Button>
|
||||
|
||||
{demoUrl && (
|
||||
<Button href={demoUrl} newTab variant="secondary" size="sm">
|
||||
<Button href={demoUrl} newTab intent="primary" variant="inverted" size="sm">
|
||||
<span className="md:hidden">Demo</span>
|
||||
<span className="hidden md:inline">View demo</span>
|
||||
</Button>
|
||||
|
||||
@@ -6,7 +6,10 @@ import { Testimonial } from "@garden-co/design-system/src/components/molecules/T
|
||||
function TheoTestimonial({
|
||||
size,
|
||||
className,
|
||||
}: { size?: "sm" | "md"; className?: string }) {
|
||||
}: {
|
||||
size?: "sm" | "md";
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<Testimonial
|
||||
size={size}
|
||||
@@ -31,7 +34,7 @@ function TheoTestimonial({
|
||||
|
||||
export function EarlyAdopterSection() {
|
||||
return (
|
||||
<div className="grid grid grid-cols-3 items-center gap-y-12">
|
||||
<div className="grid grid-cols-3 items-center gap-y-12">
|
||||
<TheoTestimonial size="md" className="col-span-3 lg:hidden" />
|
||||
<div className="col-span-3 lg:col-span-2">
|
||||
<div className="max-w-3xl space-y-6">
|
||||
@@ -53,10 +56,14 @@ export function EarlyAdopterSection() {
|
||||
</Prose>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Button href="/docs" variant="primary">
|
||||
<Button href="/docs" intent="primary">
|
||||
Read docs
|
||||
</Button>
|
||||
<Button href="https://discord.gg/utDMjHYg42" variant="secondary">
|
||||
<Button
|
||||
href="https://discord.gg/utDMjHYg42"
|
||||
intent="primary"
|
||||
variant="outline"
|
||||
>
|
||||
Join Discord
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,9 @@ function Illustration() {
|
||||
<Icon
|
||||
name="encryption"
|
||||
size="3xl"
|
||||
className="z-30 text-primary p-1.5 rounded-lg bg-highlight dark:bg-stone-900"
|
||||
className="z-30 p-1.5 rounded-lg"
|
||||
intent="primary"
|
||||
hasBackground
|
||||
/>
|
||||
|
||||
{/*<LockKeyholeIcon*/}
|
||||
@@ -72,7 +74,7 @@ function Illustration() {
|
||||
export function EncryptionSection() {
|
||||
return (
|
||||
<Card className="overflow-hidden dark:bg-stone-925">
|
||||
<div className="flex grid md:grid-cols-3 md:gap-3">
|
||||
<div className="grid md:grid-cols-3 md:gap-3">
|
||||
<div className="md:col-span-2 px-4 pb-4 md:p-8">
|
||||
<H3 className="mb-0 text-balance">
|
||||
End-to-end encrypted and tamper-proof
|
||||
|
||||
@@ -139,7 +139,7 @@ export function FeaturesSection() {
|
||||
</p>
|
||||
</Prose>
|
||||
<div className="flex items-center flex-wrap gap-3">
|
||||
<Button href="/cloud" variant="primary">
|
||||
<Button href="/cloud" intent="primary">
|
||||
View free tier & pricing
|
||||
</Button>
|
||||
|
||||
@@ -161,8 +161,8 @@ export function FeaturesSection() {
|
||||
key={feature}
|
||||
className="flex items-center gap-1.5 whitespace-nowrap"
|
||||
>
|
||||
<span className="text-primary p-1 rounded-full bg-highlight">
|
||||
<Icon name="check" size="xs" />
|
||||
<span className="p-1 rounded-full bg-primary-transparent">
|
||||
<Icon name="check" size="xs" intent="primary" />
|
||||
</span>
|
||||
{feature}
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
'use client'
|
||||
|
||||
import { Framework } from "@/content/framework";
|
||||
import { useFramework } from "@/lib/use-framework";
|
||||
import NpxCreateJazzApp from "@/components/home/NpxCreateJazzApp.mdx";
|
||||
import { CopyButton } from "@garden-co/design-system/src/components/molecules/CodeGroup";
|
||||
import { useState } from "react";
|
||||
import { Button } from "@garden-co/design-system/src/components/atoms/Button";
|
||||
import Link from "next/link";
|
||||
import { FrameworkSelect } from "../docs/FrameworkSelect";
|
||||
import clsx from "clsx";
|
||||
import { track } from "@vercel/analytics";
|
||||
import { GappedGrid } from "@garden-co/design-system/src/components/molecules/GappedGrid";
|
||||
|
||||
export function GetStartedSnippetSelect() {
|
||||
const defaultFramework = useFramework();
|
||||
const [selectedFramework, setSelectedFramework] =
|
||||
useState<Framework>(defaultFramework);
|
||||
|
||||
return (
|
||||
<GappedGrid>
|
||||
<div className="relative w-full col-span-2 lg:col-span-3 border-2 border-primary rounded-lg overflow-hidden">
|
||||
<CopyButton
|
||||
code="npx create-jazz-app@latest"
|
||||
size="sm"
|
||||
className={clsx("mt-0.5 mr-0.5 z-100 md:opacity-100 hidden md:block")}
|
||||
onCopy={() => track("create-jazz-app command copied from hero")}
|
||||
/>
|
||||
<NpxCreateJazzApp />
|
||||
</div>
|
||||
<div className="col-span-2 lg:col-span-3 flex flex-row gap-2">
|
||||
<div className="h-full items-center w-[175px]">
|
||||
<FrameworkSelect onSelect={setSelectedFramework} size="md" routerPush={false} className="h-full md:px-4" />
|
||||
</div>
|
||||
<div className="flex h-full items-center">
|
||||
<Button intent="primary" size="lg" className="w-full">
|
||||
<Link className="my-[0.11rem]" href={`/docs/${selectedFramework}`}>Get started</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</GappedGrid>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import CreateJazzApp from "@/components/home/CreateJazzApp.mdx";
|
||||
import { marketingCopy } from "@/content/marketingCopy";
|
||||
import { H1 } from "@garden-co/design-system/src/components/atoms/Headings";
|
||||
import {
|
||||
@@ -8,11 +7,10 @@ import {
|
||||
type IconName,
|
||||
} from "@garden-co/design-system/src/components/atoms/Icon";
|
||||
import { Kicker } from "@garden-co/design-system/src/components/atoms/Kicker";
|
||||
import { CopyButton } from "@garden-co/design-system/src/components/molecules/CodeGroup";
|
||||
import { Prose } from "@garden-co/design-system/src/components/molecules/Prose";
|
||||
import { SectionHeader } from "@garden-co/design-system/src/components/molecules/SectionHeader";
|
||||
import { track } from "@vercel/analytics";
|
||||
import Link from "next/link";
|
||||
import { GetStartedSnippetSelect } from "./GetStartedSnippetSelect";
|
||||
|
||||
|
||||
const features: Array<{
|
||||
title: string;
|
||||
@@ -54,8 +52,8 @@ const features: Array<{
|
||||
|
||||
export function HeroSection() {
|
||||
return (
|
||||
<div className="container grid items-center gap-x-8 gap-y-12 my-12 md:my-16 lg:my-24 lg:gap-x-10 lg:grid-cols-3">
|
||||
<div className="flex flex-col justify-center gap-5 lg:col-span-2 lg:gap-8">
|
||||
<div className="container grid items-center gap-x-8 gap-y-12 my-12 md:my-16 lg:my-24 lg:gap-x-10 lg:grid-cols-12">
|
||||
<div className="flex flex-col justify-center gap-5 lg:col-span-11 lg:gap-8">
|
||||
<Kicker>Toolkit for backendless apps</Kicker>
|
||||
<H1>
|
||||
<span className="inline-block text-highlight">
|
||||
@@ -86,39 +84,14 @@ export function HeroSection() {
|
||||
key={title}
|
||||
className="flex text-xs sm:text-sm gap-2 items-center"
|
||||
>
|
||||
<span className="text-primary p-1.5 rounded-lg bg-highlight dark:bg-stone-900">
|
||||
<Icon size="xs" name={icon} />
|
||||
<span className="p-1.5 rounded-lg bg-primary-transparent">
|
||||
<Icon size="xs" name={icon} intent="primary" />
|
||||
</span>
|
||||
<p>{title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="h-full group grid md:grid-cols-2 items-center lg:grid-cols-1 lg:pt-36">
|
||||
<SectionHeader
|
||||
className="md:col-span-2 lg:sr-only"
|
||||
title="Get a Jazz app running in minutes."
|
||||
/>
|
||||
<div className="overflow-hidden sm:rounded-xl sm:border h-full sm:px-8 sm:pt-6 bg-stone-50 dark:bg-stone-950">
|
||||
<div className="rounded-lg bg-white dark:bg-stone-925 sm:ring-4 ring-stone-400/20 sm:shadow-xl sm:shadow-blue/20 border relative sm:top-2 h-full w-full">
|
||||
<div className="py-4 flex items-center gap-2.5 px-6 border-b">
|
||||
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
|
||||
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
|
||||
<span className="rounded-full size-3 bg-stone-200 dark:bg-stone-900" />
|
||||
<CopyButton
|
||||
code="npx create-jazz-app@latest"
|
||||
size="md"
|
||||
className="mt-0.5 mr-0.5"
|
||||
onCopy={() => track("create-jazz-app command copied from hero")}
|
||||
/>
|
||||
</div>
|
||||
<div className="p-3">
|
||||
<CreateJazzApp />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,9 +63,8 @@ function Step({
|
||||
<div className="flex gap-3 px-4 sm:px-6">
|
||||
<p
|
||||
className={clsx(
|
||||
"bg-highlight size-6 rounded-full text-primary text-sm font-semibold font-mono",
|
||||
"bg-primary-transparent text-primary size-6 rounded-full text-sm font-semibold font-mono",
|
||||
"inline-flex items-center justify-center text-center shrink-0",
|
||||
"dark:bg-blue dark:text-white",
|
||||
)}
|
||||
>
|
||||
<span className="sr-only">Step</span>
|
||||
|
||||
3
homepage/homepage/components/home/NpxCreateJazzApp.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
```sh
|
||||
npx create-jazz-app@latest
|
||||
```
|
||||
@@ -15,15 +15,16 @@ export function QuickSearch() {
|
||||
|
||||
return (
|
||||
<Button
|
||||
className="group xl:min-w-48 text-stone-600 md:mr-5"
|
||||
variant="secondary"
|
||||
className="group xl:min-w-48 md:mr-5"
|
||||
intent="muted"
|
||||
variant="outline"
|
||||
onClick={() => setOpen((open) => !open)}
|
||||
>
|
||||
<Icon name="search" size="xs" className=" text-stone-600" />
|
||||
<span className="font-normal flex-1 text-left text-sm text-stone-600 group-hover:text-blue xl:not-sr-only">
|
||||
<Icon name="search" size="xs" intent="default" />
|
||||
<span className="font-normal flex-1 text-left text-sm xl:not-sr-only">
|
||||
Search docs
|
||||
</span>
|
||||
<kbd className="hidden gap-0.5 xl:text-sm text-stone-600 lg:inline-flex">
|
||||
<kbd className="hidden gap-0.5 xl:text-sm lg:inline-flex">
|
||||
<kbd className="font-sans">{isMac ? "⌘" : "Ctrl"}</kbd>
|
||||
<kbd className="font-sans">K</kbd>
|
||||
</kbd>
|
||||
|
||||
@@ -118,7 +118,7 @@ To use it, install the following Packages:
|
||||
|
||||
<CodeGroup>
|
||||
```bash
|
||||
pnpm add react-native-quick-crypto@1.0.0-beta.18 react-native-nitro-modules
|
||||
pnpm add react-native-quick-crypto@1.0.0-beta.18 react-native-nitro-modules react-native-fast-encoder
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||