chore: cleanup, shadcn
This commit is contained in:
parent
230dca64ca
commit
ea68d4f02f
38 changed files with 1073 additions and 1378 deletions
668
package-lock.json
generated
668
package-lock.json
generated
|
@ -17,7 +17,9 @@
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@fontsource/geist-mono": "^5.0.3",
|
"@fontsource/geist-mono": "^5.0.3",
|
||||||
"@fontsource/geist-sans": "^5.0.3",
|
"@fontsource/geist-sans": "^5.0.3",
|
||||||
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@types/react": "^18.3.5",
|
"@types/react": "^18.3.5",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"astro": "^4.11.3",
|
"astro": "^4.11.3",
|
||||||
|
@ -1130,6 +1132,40 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@floating-ui/core": {
|
||||||
|
"version": "1.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz",
|
||||||
|
"integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/utils": "^0.2.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/dom": {
|
||||||
|
"version": "1.6.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz",
|
||||||
|
"integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/core": "^1.6.0",
|
||||||
|
"@floating-ui/utils": "^0.2.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/react-dom": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/dom": "^1.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/utils": {
|
||||||
|
"version": "0.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz",
|
||||||
|
"integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA=="
|
||||||
|
},
|
||||||
"node_modules/@fontsource/geist-mono": {
|
"node_modules/@fontsource/geist-mono": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/geist-mono/-/geist-mono-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@fontsource/geist-mono/-/geist-mono-5.0.3.tgz",
|
||||||
|
@ -1760,6 +1796,192 @@
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/primitive": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-arrow": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-primitive": "2.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-collection": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-slot": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-compose-refs": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-context": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-direction": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-dismissable-layer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.0",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-escape-keydown": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-dropdown-menu": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.0",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-id": "1.1.0",
|
||||||
|
"@radix-ui/react-menu": "2.1.1",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-focus-guards": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-focus-scope": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-icons": {
|
"node_modules/@radix-ui/react-icons": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
|
||||||
|
@ -1768,6 +1990,309 @@
|
||||||
"react": "^16.x || ^17.x || ^18.x"
|
"react": "^16.x || ^17.x || ^18.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-id": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-menu": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.0",
|
||||||
|
"@radix-ui/react-collection": "1.1.0",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-direction": "1.1.0",
|
||||||
|
"@radix-ui/react-dismissable-layer": "1.1.0",
|
||||||
|
"@radix-ui/react-focus-guards": "1.1.0",
|
||||||
|
"@radix-ui/react-focus-scope": "1.1.0",
|
||||||
|
"@radix-ui/react-id": "1.1.0",
|
||||||
|
"@radix-ui/react-popper": "1.2.0",
|
||||||
|
"@radix-ui/react-portal": "1.1.1",
|
||||||
|
"@radix-ui/react-presence": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-roving-focus": "1.1.0",
|
||||||
|
"@radix-ui/react-slot": "1.1.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"aria-hidden": "^1.1.1",
|
||||||
|
"react-remove-scroll": "2.5.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-popper": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/react-dom": "^2.0.0",
|
||||||
|
"@radix-ui/react-arrow": "1.1.0",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0",
|
||||||
|
"@radix-ui/react-use-rect": "1.1.0",
|
||||||
|
"@radix-ui/react-use-size": "1.1.0",
|
||||||
|
"@radix-ui/rect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-portal": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-presence": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-primitive": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-slot": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-roving-focus": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.0",
|
||||||
|
"@radix-ui/react-collection": "1.1.0",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0",
|
||||||
|
"@radix-ui/react-context": "1.1.0",
|
||||||
|
"@radix-ui/react-direction": "1.1.0",
|
||||||
|
"@radix-ui/react-id": "1.1.0",
|
||||||
|
"@radix-ui/react-primitive": "2.0.0",
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-slot": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-callback-ref": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-controllable-state": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-escape-keydown": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-layout-effect": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-rect": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/rect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/react-use-size": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@radix-ui/rect": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.18.1",
|
"version": "4.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
|
||||||
|
@ -2444,6 +2969,17 @@
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/aria-hidden": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/aria-query": {
|
"node_modules/aria-query": {
|
||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||||
|
@ -3296,6 +3832,11 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/detect-node-es": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
||||||
|
},
|
||||||
"node_modules/deterministic-object-hash": {
|
"node_modules/deterministic-object-hash": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz",
|
||||||
|
@ -3792,6 +4333,14 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-nonce": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-stream": {
|
"node_modules/get-stream": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||||
|
@ -4242,6 +4791,14 @@
|
||||||
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==",
|
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/invariant": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-alphabetical": {
|
"node_modules/is-alphabetical": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
|
||||||
|
@ -6869,6 +7426,73 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-remove-scroll": {
|
||||||
|
"version": "2.5.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
|
||||||
|
"integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-remove-scroll-bar": "^2.3.4",
|
||||||
|
"react-style-singleton": "^2.2.1",
|
||||||
|
"tslib": "^2.1.0",
|
||||||
|
"use-callback-ref": "^1.3.0",
|
||||||
|
"use-sidecar": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-remove-scroll-bar": {
|
||||||
|
"version": "2.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz",
|
||||||
|
"integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==",
|
||||||
|
"dependencies": {
|
||||||
|
"react-style-singleton": "^2.2.1",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-style-singleton": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
|
||||||
|
"dependencies": {
|
||||||
|
"get-nonce": "^1.0.0",
|
||||||
|
"invariant": "^2.2.4",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
@ -7949,8 +8573,7 @@
|
||||||
"version": "2.6.3",
|
"version": "2.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
|
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
|
||||||
"license": "0BSD",
|
"license": "0BSD"
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
|
@ -8196,6 +8819,47 @@
|
||||||
"browserslist": ">= 4.21.0"
|
"browserslist": ">= 4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-callback-ref": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz",
|
||||||
|
"integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/use-sidecar": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"detect-node-es": "^1.1.0",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@fontsource/geist-mono": "^5.0.3",
|
"@fontsource/geist-mono": "^5.0.3",
|
||||||
"@fontsource/geist-sans": "^5.0.3",
|
"@fontsource/geist-sans": "^5.0.3",
|
||||||
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@types/react": "^18.3.5",
|
"@types/react": "^18.3.5",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"astro": "^4.11.3",
|
"astro": "^4.11.3",
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { entry } = Astro.props as {
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={`/${entry.collection}/${entry.slug}`}
|
href={`/${entry.collection}/${entry.slug}`}
|
||||||
class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
class="not-prose group relative flex flex-nowrap rounded-lg border px-4 py-3 pr-10 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<div class="flex flex-1 flex-col truncate">
|
<div class="flex flex-1 flex-col truncate">
|
||||||
<div class="font-semibold">
|
<div class="font-semibold">
|
||||||
|
@ -32,11 +32,11 @@ const { entry } = Astro.props as {
|
||||||
y1="12"
|
y1="12"
|
||||||
x2="19"
|
x2="19"
|
||||||
y2="12"
|
y2="12"
|
||||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||||
></line>
|
></line>
|
||||||
<polyline
|
<polyline
|
||||||
points="12 5 19 12 12 19"
|
points="12 5 19 12 12 19"
|
||||||
class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
class="-translate-x-1 transition-transform duration-300 ease-in-out group-focus-visible:translate-x-0"
|
||||||
></polyline>
|
></polyline>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -8,7 +8,7 @@ const { href } = Astro.props
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={href}
|
href={href}
|
||||||
class="not-prose group relative flex w-fit flex-nowrap rounded border border-black/15 py-1.5 pl-7 pr-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
class="not-prose group relative flex w-fit flex-nowrap rounded border py-1.5 pl-7 pr-3 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -20,11 +20,11 @@ const { href } = Astro.props
|
||||||
y1="12"
|
y1="12"
|
||||||
x2="19"
|
x2="19"
|
||||||
y2="12"
|
y2="12"
|
||||||
class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out"
|
||||||
></line>
|
></line>
|
||||||
<polyline
|
<polyline
|
||||||
points="12 5 5 12 12 19"
|
points="12 5 5 12 12 19"
|
||||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
class="translate-x-1 transition-transform duration-300 ease-in-out"
|
||||||
></polyline>
|
></polyline>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="text-sm">
|
<div class="text-sm">
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<button
|
|
||||||
id="back-to-top"
|
|
||||||
class="group relative flex w-fit flex-nowrap rounded border border-black/15 py-1.5 pl-8 pr-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
class="absolute left-2 top-1/2 size-4 -translate-y-1/2 rotate-90 fill-none stroke-current stroke-2"
|
|
||||||
>
|
|
||||||
<line
|
|
||||||
x1="5"
|
|
||||||
y1="12"
|
|
||||||
x2="19"
|
|
||||||
y2="12"
|
|
||||||
class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
|
||||||
></line>
|
|
||||||
<polyline
|
|
||||||
points="12 5 5 12 12 19"
|
|
||||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
|
||||||
></polyline>
|
|
||||||
</svg>
|
|
||||||
<div class="text-sm">Back to top</div>
|
|
||||||
</button>
|
|
|
@ -1,44 +0,0 @@
|
||||||
---
|
|
||||||
interface Component {
|
|
||||||
type: 'default' | 'info' | 'warning' | 'error'
|
|
||||||
}
|
|
||||||
|
|
||||||
const { type = 'default' } = Astro.props
|
|
||||||
|
|
||||||
let emoji = '💡'
|
|
||||||
|
|
||||||
if (type === 'info') {
|
|
||||||
emoji = 'ℹ️'
|
|
||||||
} else if (type === 'warning') {
|
|
||||||
emoji = '⚠️'
|
|
||||||
} else if (type === 'error') {
|
|
||||||
emoji = '🚨'
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class={`not-prose callout callout-${type}`}>
|
|
||||||
<span class="emoji pointer-events-none select-none">{emoji}</span>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.callout {
|
|
||||||
@apply relative my-4 flex rounded border border-orange-800 bg-orange-100 p-3 text-orange-950 dark:border-orange-200/20 dark:bg-orange-950/20 dark:text-orange-200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji {
|
|
||||||
@apply pr-3 text-xl;
|
|
||||||
}
|
|
||||||
|
|
||||||
.callout-info {
|
|
||||||
@apply border-blue-800 bg-blue-100 text-blue-950 dark:border-blue-200/20 dark:bg-blue-950/20 dark:text-blue-200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.callout-warning {
|
|
||||||
@apply border-yellow-800 bg-yellow-100 text-yellow-950 dark:border-yellow-200/20 dark:bg-yellow-950/20 dark:text-yellow-200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.callout-error {
|
|
||||||
@apply border-red-800 bg-red-100 text-red-950 dark:border-red-200/20 dark:bg-red-950/20 dark:text-red-200;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,21 +1,17 @@
|
||||||
---
|
---
|
||||||
import Container from '@components/Container.astro'
|
import Container from '@components/Container.astro'
|
||||||
import { SITE } from '@consts'
|
|
||||||
import BackToTop from '@components/BackToTop.astro'
|
|
||||||
import SocialIcons from './SocialIcons.astro'
|
import SocialIcons from './SocialIcons.astro'
|
||||||
|
import { ModeToggle } from '@components/ui/mode-toggle'
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer>
|
<footer class="py-8">
|
||||||
<Container>
|
<Container>
|
||||||
<div class="my-2 flex justify-between">
|
<div class="flex justify-between items-center">
|
||||||
<SocialIcons icon_size={'text-xl'} />
|
<div class="flex items-center space-x-4">
|
||||||
<BackToTop />
|
<ModeToggle client:load />
|
||||||
</div>
|
<p class="text-sm text-muted-foreground">© {new Date().getFullYear()} All rights reserved.</p>
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
© {new Date().getFullYear()} • {SITE.TITLE} 👀<br />
|
|
||||||
Built with Astro
|
|
||||||
</div>
|
</div>
|
||||||
|
<SocialIcons />
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -4,6 +4,8 @@ import '../styles/global.css'
|
||||||
import '@fontsource/geist-sans'
|
import '@fontsource/geist-sans'
|
||||||
import '@fontsource/geist-mono'
|
import '@fontsource/geist-mono'
|
||||||
|
|
||||||
|
import { ViewTransitions } from 'astro:transitions'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
|
@ -37,73 +39,40 @@ const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props
|
||||||
<meta property="twitter:description" content={description} />
|
<meta property="twitter:description" content={description} />
|
||||||
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
||||||
|
|
||||||
|
<ViewTransitions />
|
||||||
|
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
function init() {
|
function setDarkMode(document) {
|
||||||
onScroll()
|
const getThemePreference = () => {
|
||||||
addCopyCodeButtons()
|
if (
|
||||||
|
typeof localStorage !== 'undefined' &&
|
||||||
const backToTop = document.getElementById('back-to-top')
|
localStorage.getItem('theme')
|
||||||
backToTop?.addEventListener('click', (event) => scrollToTop(event))
|
) {
|
||||||
|
return localStorage.getItem('theme')
|
||||||
const backToPrev = document.getElementById('back-to-prev')
|
}
|
||||||
backToPrev?.addEventListener('click', () => window.history.back())
|
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? 'dark'
|
||||||
document.addEventListener('scroll', onScroll)
|
: 'theme-light'
|
||||||
}
|
|
||||||
|
|
||||||
function onScroll() {
|
|
||||||
if (window.scrollY > 0) {
|
|
||||||
document.documentElement.classList.add('scrolled')
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove('scrolled')
|
|
||||||
}
|
}
|
||||||
}
|
const isDark = getThemePreference() === 'dark'
|
||||||
|
document.documentElement.classList[isDark ? 'add' : 'remove']('dark')
|
||||||
|
|
||||||
function scrollToTop(event) {
|
if (typeof localStorage !== 'undefined') {
|
||||||
event.preventDefault()
|
const observer = new MutationObserver(() => {
|
||||||
window.scrollTo({
|
const isDark = document.documentElement.classList.contains('dark')
|
||||||
top: 0,
|
localStorage.setItem('theme', isDark ? 'dark' : 'theme-light')
|
||||||
behavior: 'smooth',
|
})
|
||||||
})
|
observer.observe(document.documentElement, {
|
||||||
}
|
attributes: true,
|
||||||
|
attributeFilter: ['class'],
|
||||||
function addCopyCodeButtons() {
|
|
||||||
let copyButtonLabel = '📋'
|
|
||||||
let codeBlocks = Array.from(document.querySelectorAll('pre'))
|
|
||||||
|
|
||||||
async function copyCode(codeBlock, copyButton) {
|
|
||||||
const codeText = codeBlock.innerText
|
|
||||||
const buttonText = copyButton.innerText
|
|
||||||
const textToCopy = codeText.replace(buttonText, '')
|
|
||||||
|
|
||||||
await navigator.clipboard.writeText(textToCopy)
|
|
||||||
copyButton.innerText = '✅'
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
copyButton.innerText = copyButtonLabel
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let codeBlock of codeBlocks) {
|
|
||||||
const wrapper = document.createElement('div')
|
|
||||||
wrapper.style.position = 'relative'
|
|
||||||
|
|
||||||
const copyButton = document.createElement('button')
|
|
||||||
copyButton.innerText = copyButtonLabel
|
|
||||||
copyButton.classList = 'copy-code'
|
|
||||||
|
|
||||||
codeBlock.setAttribute('tabindex', '0')
|
|
||||||
codeBlock.appendChild(copyButton)
|
|
||||||
|
|
||||||
codeBlock.parentNode.insertBefore(wrapper, codeBlock)
|
|
||||||
wrapper.appendChild(codeBlock)
|
|
||||||
|
|
||||||
copyButton?.addEventListener('click', async () => {
|
|
||||||
await copyCode(codeBlock, copyButton)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => init())
|
setDarkMode(document)
|
||||||
document.addEventListener('astro:after-swap', () => init())
|
|
||||||
|
document.addEventListener('astro:before-swap', (ev) => {
|
||||||
|
// Pass the incoming document to set the theme on it
|
||||||
|
setDarkMode(ev.newDocument)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,7 +15,7 @@ const { href, external, underline = true, group = false, ...rest } = Astro.props
|
||||||
href={href}
|
href={href}
|
||||||
target={external ? '_blank' : '_self'}
|
target={external ? '_blank' : '_self'}
|
||||||
class={cn(
|
class={cn(
|
||||||
'inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out',
|
'inline-block transition-colors duration-300 ease-in-out',
|
||||||
underline && 'underline underline-offset-[3px]',
|
underline && 'underline underline-offset-[3px]',
|
||||||
group && 'group',
|
group && 'group',
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const { name, avatar, bio } = member.data
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="not-prose flex size-full flex-col gap-4 overflow-hidden rounded-xl border border-foreground bg-background p-6 hover:bg-secondary sm:flex-row sm:items-center"
|
class="not-prose flex size-full flex-col gap-4 overflow-hidden rounded-xl border p-6 hover:bg-secondary sm:flex-row sm:items-center"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={avatar}
|
src={avatar}
|
||||||
|
|
|
@ -7,7 +7,7 @@ const { prevPost, nextPost } = Astro.props
|
||||||
prevPost?.slug ? (
|
prevPost?.slug ? (
|
||||||
<a
|
<a
|
||||||
href={`/blog/${prevPost?.slug}`}
|
href={`/blog/${prevPost?.slug}`}
|
||||||
class="group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pl-10 no-underline transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
class="group relative flex flex-nowrap rounded-lg border px-4 py-3 pl-10 no-underline transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -19,11 +19,11 @@ const { prevPost, nextPost } = Astro.props
|
||||||
y1="12"
|
y1="12"
|
||||||
x2="19"
|
x2="19"
|
||||||
y2="12"
|
y2="12"
|
||||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out"
|
||||||
/>
|
/>
|
||||||
<polyline
|
<polyline
|
||||||
points="12 5 5 12 12 19"
|
points="12 5 5 12 12 19"
|
||||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
class="translate-x-1 transition-transform duration-300 ease-in-out"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="flex items-center text-sm">{prevPost?.data.title}</div>
|
<div class="flex items-center text-sm">{prevPost?.data.title}</div>
|
||||||
|
@ -37,7 +37,7 @@ const { prevPost, nextPost } = Astro.props
|
||||||
nextPost?.slug ? (
|
nextPost?.slug ? (
|
||||||
<a
|
<a
|
||||||
href={`/blog/${nextPost?.slug}`}
|
href={`/blog/${nextPost?.slug}`}
|
||||||
class="group relative flex flex-grow flex-row-reverse flex-nowrap rounded-lg border border-black/15 px-4 py-4 pr-10 no-underline transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
class="group relative flex flex-grow flex-row-reverse flex-nowrap rounded-lg border px-4 py-4 pr-10 no-underline transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -49,11 +49,11 @@ const { prevPost, nextPost } = Astro.props
|
||||||
y1="12"
|
y1="12"
|
||||||
x2="19"
|
x2="19"
|
||||||
y2="12"
|
y2="12"
|
||||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out"
|
||||||
/>
|
/>
|
||||||
<polyline
|
<polyline
|
||||||
points="12 5 19 12 12 19"
|
points="12 5 19 12 12 19"
|
||||||
class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
class="-translate-x-1 transition-transform duration-300 ease-in-out"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="flex items-center text-sm">{nextPost?.data.title}</div>
|
<div class="flex items-center text-sm">{nextPost?.data.title}</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@ const { URL, icon, icon_size } = Astro.props
|
||||||
<a
|
<a
|
||||||
href={URL}
|
href={URL}
|
||||||
target={'_blank'}
|
target={'_blank'}
|
||||||
class={`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}
|
class={`inline-block ${icon_size}`}
|
||||||
>
|
>
|
||||||
<i class={`bi bi-${icon}`}></i>
|
<i class={`bi bi-${icon}`}></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
---
|
---
|
||||||
import SocialIcon from '@components/SocialIcon.astro'
|
import { Twitter, Github, Linkedin, Mail, GraduationCap, Rss } from 'lucide-react'
|
||||||
import { SITE } from '@consts'
|
import { SITE } from '@consts'
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
icon_size: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const { icon_size } = Astro.props
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class="not-prose flex flex-wrap gap-2">
|
<ul class="not-prose flex flex-wrap gap-2">
|
||||||
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x" />
|
<a href="#" class="inline-block"><Twitter /></a>
|
||||||
<SocialIcon icon_size={icon_size} URL="#" icon="github" />
|
<a href="#" class="inline-block"><Github /></a>
|
||||||
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin" />
|
<a href="#" class="inline-block"><Linkedin /></a>
|
||||||
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill" />
|
<a href="#" class="inline-block"><Mail /></a>
|
||||||
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill" />
|
<a href="#" class="inline-block"><GraduationCap /></a>
|
||||||
<SocialIcon
|
<a href={`${SITE.SITEURL}/rss.xml`} class="inline-block"><Rss /></a>
|
||||||
icon_size={icon_size}
|
|
||||||
URL={`${SITE.SITEURL}/rss.xml`}
|
|
||||||
icon="rss-fill"
|
|
||||||
/>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -27,9 +27,9 @@ function buildToc(headings: Heading[]) {
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<details open class="rounded-lg border border-black/15 dark:border-white/20">
|
<details open class="rounded-lg border">
|
||||||
<summary>Table of Contents</summary>
|
<summary>Table of Contents</summary>
|
||||||
<nav class="">
|
<nav>
|
||||||
<ul class="py-3">
|
<ul class="py-3">
|
||||||
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -40,12 +40,4 @@ function buildToc(headings: Heading[]) {
|
||||||
summary {
|
summary {
|
||||||
@apply cursor-pointer rounded-t-lg px-3 py-1.5 font-medium transition-colors;
|
@apply cursor-pointer rounded-t-lg px-3 py-1.5 font-medium transition-colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary:hover {
|
|
||||||
@apply bg-black/5 dark:bg-white/5;
|
|
||||||
}
|
|
||||||
|
|
||||||
details[open] summary {
|
|
||||||
@apply bg-black/5 dark:bg-white/5;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
57
src/components/ui/button.tsx
Normal file
57
src/components/ui/button.tsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import { Slot } from "@radix-ui/react-slot"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const buttonVariants = cva(
|
||||||
|
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default:
|
||||||
|
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||||
|
destructive:
|
||||||
|
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||||
|
outline:
|
||||||
|
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||||
|
secondary:
|
||||||
|
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||||
|
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||||
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: "h-9 px-4 py-2",
|
||||||
|
sm: "h-8 rounded-md px-3 text-xs",
|
||||||
|
lg: "h-10 rounded-md px-8",
|
||||||
|
icon: "h-9 w-9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
size: "default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export interface ButtonProps
|
||||||
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||||
|
VariantProps<typeof buttonVariants> {
|
||||||
|
asChild?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||||
|
const Comp = asChild ? Slot : "button"
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Button.displayName = "Button"
|
||||||
|
|
||||||
|
export { Button, buttonVariants }
|
203
src/components/ui/dropdown-menu.tsx
Normal file
203
src/components/ui/dropdown-menu.tsx
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
||||||
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
|
DotFilledIcon,
|
||||||
|
} from "@radix-ui/react-icons"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const DropdownMenu = DropdownMenuPrimitive.Root
|
||||||
|
|
||||||
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
||||||
|
|
||||||
|
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
||||||
|
|
||||||
|
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
||||||
|
|
||||||
|
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
||||||
|
|
||||||
|
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
||||||
|
|
||||||
|
const DropdownMenuSubTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, children, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.SubTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<ChevronRightIcon className="ml-auto h-4 w-4" />
|
||||||
|
</DropdownMenuPrimitive.SubTrigger>
|
||||||
|
))
|
||||||
|
DropdownMenuSubTrigger.displayName =
|
||||||
|
DropdownMenuPrimitive.SubTrigger.displayName
|
||||||
|
|
||||||
|
const DropdownMenuSubContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.SubContent
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuSubContent.displayName =
|
||||||
|
DropdownMenuPrimitive.SubContent.displayName
|
||||||
|
|
||||||
|
const DropdownMenuContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
||||||
|
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Portal>
|
||||||
|
<DropdownMenuPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
||||||
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</DropdownMenuPrimitive.Portal>
|
||||||
|
))
|
||||||
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const DropdownMenuItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const DropdownMenuCheckboxItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
||||||
|
>(({ className, children, checked, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.CheckboxItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
checked={checked}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<DropdownMenuPrimitive.ItemIndicator>
|
||||||
|
<CheckIcon className="h-4 w-4" />
|
||||||
|
</DropdownMenuPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
{children}
|
||||||
|
</DropdownMenuPrimitive.CheckboxItem>
|
||||||
|
))
|
||||||
|
DropdownMenuCheckboxItem.displayName =
|
||||||
|
DropdownMenuPrimitive.CheckboxItem.displayName
|
||||||
|
|
||||||
|
const DropdownMenuRadioItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.RadioItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<DropdownMenuPrimitive.ItemIndicator>
|
||||||
|
<DotFilledIcon className="h-4 w-4 fill-current" />
|
||||||
|
</DropdownMenuPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
{children}
|
||||||
|
</DropdownMenuPrimitive.RadioItem>
|
||||||
|
))
|
||||||
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
||||||
|
|
||||||
|
const DropdownMenuLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"px-2 py-1.5 text-sm font-semibold",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
||||||
|
|
||||||
|
const DropdownMenuSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DropdownMenuPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
const DropdownMenuShortcut = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
||||||
|
|
||||||
|
export {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuCheckboxItem,
|
||||||
|
DropdownMenuRadioItem,
|
||||||
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuShortcut,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuPortal,
|
||||||
|
DropdownMenuSub,
|
||||||
|
DropdownMenuSubContent,
|
||||||
|
DropdownMenuSubTrigger,
|
||||||
|
DropdownMenuRadioGroup,
|
||||||
|
}
|
52
src/components/ui/mode-toggle.tsx
Normal file
52
src/components/ui/mode-toggle.tsx
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import { Moon, Sun } from "lucide-react"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu"
|
||||||
|
|
||||||
|
export function ModeToggle() {
|
||||||
|
const [theme, setThemeState] = React.useState<
|
||||||
|
"theme-light" | "dark" | "system"
|
||||||
|
>("theme-light")
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const isDarkMode = document.documentElement.classList.contains("dark")
|
||||||
|
setThemeState(isDarkMode ? "dark" : "theme-light")
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const isDark =
|
||||||
|
theme === "dark" ||
|
||||||
|
(theme === "system" &&
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||||
|
document.documentElement.classList[isDark ? "add" : "remove"]("dark")
|
||||||
|
}, [theme])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button variant="outline" size="icon">
|
||||||
|
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
||||||
|
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
||||||
|
<span className="sr-only">Toggle theme</span>
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem onClick={() => setThemeState("theme-light")}>
|
||||||
|
Light
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => setThemeState("dark")}>
|
||||||
|
Dark
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onClick={() => setThemeState("system")}>
|
||||||
|
System
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,270 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Tutorial] Getting started with Astro-Micro-Academics'
|
|
||||||
description: 'Hit the ground running.'
|
|
||||||
date: '2024-07-26'
|
|
||||||
tags: ['guide', 'tutorial']
|
|
||||||
---
|
|
||||||
|
|
||||||
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
|
|
||||||
|
|
||||||
## Install Astro-Micro-Academics
|
|
||||||
|
|
||||||
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/jingwu2121/astro-micro-academic.git
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd astro-micro-academic
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm i
|
|
||||||
```
|
|
||||||
|
|
||||||
Run local server
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## Update the Homepage
|
|
||||||
|
|
||||||
Update your home page in `src/pages/index.astro`.
|
|
||||||
|
|
||||||
## CV & About
|
|
||||||
|
|
||||||
Update your CV and About page in `src/pages/cv.astro` and `src/pages/about.astro`.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const works = [
|
|
||||||
{
|
|
||||||
company: 'Company A',
|
|
||||||
time: '2022-Present',
|
|
||||||
job_title: 'Research Scientist',
|
|
||||||
location: 'London, UK',
|
|
||||||
description: 'Your Notes about the job',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
company: 'Company A',
|
|
||||||
time: '2022-Present',
|
|
||||||
job_title: 'Research Scientist',
|
|
||||||
location: 'London, UK',
|
|
||||||
description: 'Your Notes about the job',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const educations = [
|
|
||||||
{
|
|
||||||
school: 'University 1',
|
|
||||||
time: '2022-Present',
|
|
||||||
job_title: 'BEng in Electronic Information Engineering',
|
|
||||||
location: 'London, UK',
|
|
||||||
description: 'Your Notes about the study',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Social Links
|
|
||||||
|
|
||||||
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
|
|
||||||
|
|
||||||
## Publications metadata
|
|
||||||
|
|
||||||
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
---
|
|
||||||
title: 'Diffusion Models Beat GANs on Image Synthesis'
|
|
||||||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis.'
|
|
||||||
date: '2024-07-26'
|
|
||||||
authors: 'John B*, Jon A*, Frank C, John B, Jon A, Frank C'
|
|
||||||
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
|
|
||||||
codeURL: 'Code: '
|
|
||||||
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
|
|
||||||
dataURL: 'Data: https://github.com/markhorn-dev/astro-sphere'
|
|
||||||
img: '/rupert-cat.gif'
|
|
||||||
imgAlt: 'Paper Teaser'
|
|
||||||
pub: 'ECCV2024'
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Type | Remarks |
|
|
||||||
| :--------------------------------- | :-- | :----- | :--------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
|
||||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
|
||||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
|
||||||
| authors | Yes | string | A string seperated by comma. |
|
|
||||||
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
|
|
||||||
| img | Yes | string | Path to teaser image. |
|
|
||||||
| imgAlt | Yes | string | Description of the image. |
|
|
||||||
| pub | Yes | string | The conference or journal |
|
|
||||||
|
|
||||||
## Blog metadata
|
|
||||||
|
|
||||||
Metadata is required for each post.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
---
|
|
||||||
title: 'Blog Collection'
|
|
||||||
description: 'How to add posts to the blog.'
|
|
||||||
date: '2024-03-21'
|
|
||||||
tags: ['guide', 'tutorial']
|
|
||||||
draft: false
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Type | Remarks |
|
|
||||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
|
||||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
|
||||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
|
||||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
|
||||||
| tags | Yes | list | A list of strings |
|
|
||||||
| draft | No | boolean | If draft: true, content will not be published. |
|
|
||||||
|
|
||||||
## Customize the website metadata and set up RSS
|
|
||||||
|
|
||||||
To change the website metadata, edit `src/consts.ts`.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const SITE: Site = {
|
|
||||||
TITLE: 'Astro Micro Academics',
|
|
||||||
DESCRIPTION: 'Astro Micro Academics is for academic user.',
|
|
||||||
EMAIL: 'youremial@gmail.com',
|
|
||||||
NUM_POSTS_ON_HOMEPAGE: 2,
|
|
||||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
|
||||||
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website RSS
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Description |
|
|
||||||
| :--------------- | :-- | :--------------------------------------------------- |
|
|
||||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
|
||||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
|
||||||
| EMAIL | Yes | Displayed in contact section. |
|
|
||||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
|
||||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
|
||||||
| SITEURL | Yes | Your website URL |
|
|
||||||
|
|
||||||
### RSS Post
|
|
||||||
|
|
||||||
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Custom metadata for highlighted author in your paper
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const HIGHLIGHTAUTHOR = 'John B'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customize metadata for individual pages
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const HOME: Metadata = {
|
|
||||||
TITLE: 'Home',
|
|
||||||
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const BLOG: Metadata = {
|
|
||||||
TITLE: 'Blog',
|
|
||||||
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const RESEARCH: Metadata = {
|
|
||||||
TITLE: 'Publications',
|
|
||||||
DESCRIPTION:
|
|
||||||
'A collection of my publications with links to paper, repositories and live demos.',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CV: Metadata = {
|
|
||||||
TITLE: 'CV',
|
|
||||||
DESCRIPTION: 'your cv',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TAGS: Metadata = {
|
|
||||||
TITLE: 'TAGS',
|
|
||||||
DESCRIPTION: 'blog tag filter',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ABOUT: Metadata = {
|
|
||||||
TITLE: 'ABOUT',
|
|
||||||
DESCRIPTION: 'A self-intro',
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Description |
|
|
||||||
| :---------- | :-- | :--------------------------------------------- |
|
|
||||||
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
|
|
||||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Deploy the site
|
|
||||||
|
|
||||||
To set up RSS and Giscus, it's easier if the site is deployed and has a URL for you to use. Instantly deploy to Vercel or Netlify by clicking the buttons below.
|
|
||||||
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<a target="_blank" aria-label="Deploy with Vercel" href="https://vercel.com/new/clone?repository-url=https://github.com/trevortylerlee/astro-micro">
|
|
||||||
<img src="/deploy_vercel.svg" />
|
|
||||||
</a>
|
|
||||||
<a target="_blank" aria-label="Deploy with Netlify" href="https://app.netlify.com/start/deploy?repository=https://github.com/trevortylerlee/astro-micro">
|
|
||||||
<img src="/deploy_netlify.svg" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
To deploy manually see [Astro's docs](https://docs.astro.build/en/guides/deploy/).
|
|
||||||
|
|
||||||
To deploy to Github, see [here](https://docs.astro.build/en/guides/deploy/github/).
|
|
||||||
|
|
||||||
## Set up Giscus (from Astro Micro)
|
|
||||||
|
|
||||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// src/components/Giscus.astro
|
|
||||||
|
|
||||||
<script
|
|
||||||
is:inline
|
|
||||||
src="https://giscus.app/client.js"
|
|
||||||
data-repo="trevortylerlee/astro-micro"
|
|
||||||
data-repo-id="R_kgDOL_6l9Q"
|
|
||||||
data-category="Announcements"
|
|
||||||
data-category-id="DIC_kwDOL_6l9c4Cfk55"
|
|
||||||
data-mapping="pathname"
|
|
||||||
data-strict="0"
|
|
||||||
data-reactions-enabled="1"
|
|
||||||
data-emit-metadata="0"
|
|
||||||
data-input-position="top"
|
|
||||||
data-theme="preferred_color_scheme"
|
|
||||||
data-lang="en"
|
|
||||||
data-loading="lazy"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
async
|
|
||||||
></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// src/components/Head.astro
|
|
||||||
|
|
||||||
const setGiscusTheme = () => {
|
|
||||||
const giscus = document.querySelector('.giscus-frame')
|
|
||||||
|
|
||||||
const isDark = document.documentElement.classList.contains('dark')
|
|
||||||
|
|
||||||
if (giscus) {
|
|
||||||
const url = new URL(giscus.src)
|
|
||||||
// Change "dark" and "light" to other Giscus themes
|
|
||||||
url.searchParams.set('theme', isDark ? 'dark' : 'light')
|
|
||||||
giscus.src = url.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,105 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Everything new in Astro Micro'
|
|
||||||
description: 'Features, enhancements, and changes.'
|
|
||||||
date: '2024-05-09'
|
|
||||||
tags: ['astro-micro']
|
|
||||||
---
|
|
||||||
|
|
||||||
import Callout from '@/components/Callout.astro'
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Pagefind search 🔎
|
|
||||||
|
|
||||||
[Pagefind](https://pagefind.app) is a search library for static websites. Micro uses [Sergey Shishkin's](https://github.com/shishkin) [astro-pagefind](https://github.com/shishkin/astro-pagefind) integration. This integration simplifies development and does not require any changes to the default build script.
|
|
||||||
|
|
||||||
Press <kbd>/</kbd> or <kbd>CTRL</kbd> + <kbd>K</kbd> to open the search dialog. For Mac users, <kbd>⌘</kbd> + <kbd>K</kbd> can also be used. To dismiss the search dialog, press <kbd>Esc</kbd> or click on an area outside the component.
|
|
||||||
|
|
||||||
### Build and develop
|
|
||||||
|
|
||||||
<Callout type="error">
|
|
||||||
The site **must** be built at least once so Pagefind can index the content.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Pagefind must index the site to function
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
When developing you can continue to use `npm run dev` and Pagefind will use the index from the last available build.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Giscus comments 💬
|
|
||||||
|
|
||||||
[Giscus](https://giscus.app) leverages Github discussions to act as a comments system. To get Giscus working on your own website, see [here](/blog/01-getting-started#deploy-the-site).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Callout component 🆕
|
|
||||||
|
|
||||||
<Callout>
|
|
||||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
|
||||||
labore consequat ullamco nostrud non.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
<Callout type="info">
|
|
||||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
|
||||||
labore consequat ullamco nostrud non.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
<Callout type="warning">
|
|
||||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
|
||||||
labore consequat ullamco nostrud non.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
<Callout type="error">
|
|
||||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
|
||||||
labore consequat ullamco nostrud non.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## UI enhancements 🎨
|
|
||||||
|
|
||||||
- Elements are styled and on focus
|
|
||||||
- Increased contrast in light mode
|
|
||||||
- Active theme is indicated by theme buttons
|
|
||||||
- Separate syntax highlight themes for light and dark mode
|
|
||||||
- Code blocks have a copy button
|
|
||||||
- Add pagination to the bottom of blog posts
|
|
||||||
- Create 404 page
|
|
||||||
- Add ToC component to posts
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Other changes
|
|
||||||
|
|
||||||
- Change fonts to Geist Sans and Geist Mono
|
|
||||||
- Switch base color from "stone" to "neutral"
|
|
||||||
- Change formatted date to use "long" option for month
|
|
||||||
- Minor spacing changes throughout
|
|
||||||
- Remove "work" collection and components
|
|
||||||
- If desired, you can get the code from [Astro Nano](https://github.com/markhorn-dev/astro-nano)
|
|
||||||
- Slightly increased link decoration offset
|
|
||||||
- Slightly sped-up animations
|
|
||||||
- Reversed animation
|
|
||||||
- Ensure posts use an h1 tag for post titles
|
|
||||||
- Tweaked typography
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issues ⚠️
|
|
||||||
|
|
||||||
### Active issues
|
|
||||||
|
|
||||||
- [PostNavigation.astro is broken when deployed with Cloudflare Pages](https://github.com/trevortylerlee/astro-micro/issues/39)
|
|
||||||
|
|
||||||
### Closed issues
|
|
||||||
|
|
||||||
- Fixed by [blopker](https://github.com/blopker): [Pagefind requires a refresh to function when ViewTransitions is enabled](https://github.com/trevortylerlee/astro-micro/issues/7)
|
|
||||||
- Fixed by [blopker](https://github.com/blopker): [ToC links are obscured by Header when scrolled to](https://github.com/trevortylerlee/astro-micro/issues/4)
|
|
||||||
- Fixed by [cgranier](https://github.com/cgranier): [Pagination links advance by slug/folder](https://github.com/trevortylerlee/astro-micro/issues/26)
|
|
||||||
- Fixed by [cgranier](https://github.com/cgranier): [Hides Table of Contents when there are no headings](https://github.com/trevortylerlee/astro-micro/pull/30)
|
|
||||||
- Fixed by [arastoonet](https://github.com/arastoonet): [Fix typo in README](https://github.com/trevortylerlee/astro-micro/pull/19)
|
|
||||||
- Fixed by [luciancah](https://github.com/luciancah): [Prevent Pagefind from double-indexing results](https://github.com/trevortylerlee/astro-micro/issues/40)
|
|
|
@ -1,181 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Getting started with Astro-Micro'
|
|
||||||
description: 'Hit the ground running.'
|
|
||||||
date: '2024-03-22'
|
|
||||||
tags: ['guide', 'start']
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Install astro-micro
|
|
||||||
|
|
||||||
Clone the [Astro Micro repository](https://github.com/trevortylerlee/astro-micro.git).
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/trevortylerlee/astro-micro.git my-astro-micro
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd my-astro-micro
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm i
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customize the website metadata
|
|
||||||
|
|
||||||
To change the website metadata, edit `src/consts.ts`.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const SITE: Site = {
|
|
||||||
NAME: 'Astro Micro',
|
|
||||||
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
|
|
||||||
EMAIL: 'trevortylerlee@gmail.com',
|
|
||||||
NUM_POSTS_ON_HOMEPAGE: 3,
|
|
||||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Description |
|
|
||||||
| :--------------- | :-- | :--------------------------------------------------- |
|
|
||||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
|
||||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
|
||||||
| EMAIL | Yes | Displayed in contact section. |
|
|
||||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
|
||||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Customize metadata for individual pages
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const ABOUT: Metadata = {
|
|
||||||
TITLE: 'About',
|
|
||||||
DESCRIPTION: 'Astro Micro is a fork of Astro Nano.',
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Description |
|
|
||||||
| :---------- | :-- | :--------------------------------------------- |
|
|
||||||
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
|
|
||||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ~~Add your social media links~~ Removed in Micro Academics
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// src/consts.ts
|
|
||||||
|
|
||||||
export const SOCIALS: Socials = [
|
|
||||||
{
|
|
||||||
NAME: 'twitter-x',
|
|
||||||
HREF: 'https://twitter.com/boogerbuttcheeks',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NAME: 'github',
|
|
||||||
HREF: 'https://github.com/trevortylerlee',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
NAME: 'linkedin',
|
|
||||||
HREF: 'https://www.linkedin.com/in/trevortylerlee',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Description |
|
|
||||||
| :---- | :-- | :-------------------------------------- |
|
|
||||||
| NAME | Yes | Displayed in contact section as a link. |
|
|
||||||
| HREF | Yes | External url to social media profile. |
|
|
||||||
|
|
||||||
## Deploy the site
|
|
||||||
|
|
||||||
To set up RSS and Giscus, it's easier if the site is deployed and has a URL for you to use. Instantly deploy to Vercel or Netlify by clicking the buttons below.
|
|
||||||
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<a target="_blank" aria-label="Deploy with Vercel" href="https://vercel.com/new/clone?repository-url=https://github.com/trevortylerlee/astro-micro">
|
|
||||||
<img src="/deploy_vercel.svg" />
|
|
||||||
</a>
|
|
||||||
<a target="_blank" aria-label="Deploy with Netlify" href="https://app.netlify.com/start/deploy?repository=https://github.com/trevortylerlee/astro-micro">
|
|
||||||
<img src="/deploy_netlify.svg" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
To deploy manually see [Astro's docs](https://docs.astro.build/en/guides/deploy/).
|
|
||||||
|
|
||||||
## ~~Set up RSS~~ New config in Astro Micro Academics
|
|
||||||
|
|
||||||
Change the `site` option to the deployed site's URL.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// astro.config.mjs
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
site: 'https://astro-micro.vercel.app',
|
|
||||||
integrations: [tailwind(), sitemap(), mdx(), pagefind()],
|
|
||||||
markdown: {
|
|
||||||
shikiConfig: {
|
|
||||||
theme: 'css-variables',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
## Set up Giscus
|
|
||||||
|
|
||||||
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// src/components/Giscus.astro
|
|
||||||
|
|
||||||
<script
|
|
||||||
is:inline
|
|
||||||
src="https://giscus.app/client.js"
|
|
||||||
data-repo="trevortylerlee/astro-micro"
|
|
||||||
data-repo-id="R_kgDOL_6l9Q"
|
|
||||||
data-category="Announcements"
|
|
||||||
data-category-id="DIC_kwDOL_6l9c4Cfk55"
|
|
||||||
data-mapping="pathname"
|
|
||||||
data-strict="0"
|
|
||||||
data-reactions-enabled="1"
|
|
||||||
data-emit-metadata="0"
|
|
||||||
data-input-position="top"
|
|
||||||
data-theme="preferred_color_scheme"
|
|
||||||
data-lang="en"
|
|
||||||
data-loading="lazy"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
async
|
|
||||||
></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// src/components/Head.astro
|
|
||||||
|
|
||||||
const setGiscusTheme = () => {
|
|
||||||
const giscus = document.querySelector('.giscus-frame')
|
|
||||||
|
|
||||||
const isDark = document.documentElement.classList.contains('dark')
|
|
||||||
|
|
||||||
if (giscus) {
|
|
||||||
const url = new URL(giscus.src)
|
|
||||||
// Change "dark" and "light" to other Giscus themes
|
|
||||||
url.searchParams.set('theme', isDark ? 'dark' : 'light')
|
|
||||||
giscus.src = url.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,63 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Blog Collection'
|
|
||||||
description: 'How to add posts to the blog.'
|
|
||||||
date: '2024-03-21'
|
|
||||||
tags: ['aa']
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Working with the `blog` collection:
|
|
||||||
|
|
||||||
The `blog` collection is found in `src/content/blog`.
|
|
||||||
|
|
||||||
```
|
|
||||||
📁 /src/content/blog
|
|
||||||
└── 📁 post-1
|
|
||||||
└── 📄 index.md
|
|
||||||
└── 📁 post-2
|
|
||||||
└── 📄 index.mdx
|
|
||||||
```
|
|
||||||
|
|
||||||
In the above example, two blog posts will be generated with the folder name representing the slug.
|
|
||||||
|
|
||||||
- `https://example.com/blog/post-1`
|
|
||||||
- `https://example.com/blog/post-2`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Provide metadata
|
|
||||||
|
|
||||||
Metadata is required for each post.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
---
|
|
||||||
title: 'Blog Collection'
|
|
||||||
description: 'How to add posts to the blog.'
|
|
||||||
date: '2024-03-21'
|
|
||||||
draft: false
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Req | Type | Remarks |
|
|
||||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
|
||||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
|
||||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
|
||||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
|
||||||
| draft | No | boolean | If draft: true, content will not be published. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
All that's left to do is write the content under the metadata.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
---
|
|
||||||
title: 'Blog Collection'
|
|
||||||
description: 'How to add posts to the blog.'
|
|
||||||
date: '2024-03-21'
|
|
||||||
draft: false
|
|
||||||
---
|
|
||||||
|
|
||||||
## Working with the blog collection
|
|
||||||
<!-- content -->
|
|
||||||
```
|
|
|
@ -1,398 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Markdown syntax guide'
|
|
||||||
description: 'Get started writing content in Markdown.'
|
|
||||||
date: '2024-03-17'
|
|
||||||
---
|
|
||||||
|
|
||||||
import Callout from '@/components/Callout.astro'
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Headings
|
|
||||||
|
|
||||||
To create headings, use hash symbols (#) followed by a space. The number of hash symbols indicates the heading level.
|
|
||||||
|
|
||||||
<Callout>
|
|
||||||
Use `h2` tags instead of `h1` tags in the post. Too many `h1` tags on a single
|
|
||||||
page can impact SEO. The post title serves as the `h1`.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
```md
|
|
||||||
# Heading 1
|
|
||||||
|
|
||||||
## Heading 2
|
|
||||||
|
|
||||||
### Heading 3
|
|
||||||
|
|
||||||
#### Heading 4
|
|
||||||
|
|
||||||
##### Heading 5
|
|
||||||
|
|
||||||
###### Heading 6
|
|
||||||
```
|
|
||||||
|
|
||||||
<h1>Heading 1</h1>
|
|
||||||
<h2>Heading 2</h2>
|
|
||||||
<h3>Heading 3</h3>
|
|
||||||
<h4>Heading 4</h4>
|
|
||||||
<h5>Heading 5</h5>
|
|
||||||
<h6>Heading 6</h6>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Paragraphs
|
|
||||||
|
|
||||||
To create paragraphs, use a blank line to separate one or more lines of text.
|
|
||||||
|
|
||||||
{/* prettier-ignore */}
|
|
||||||
```md
|
|
||||||
<!-- empty line -->
|
|
||||||
I love Star Wars.
|
|
||||||
<!-- empty line -->
|
|
||||||
My favourite is Episode III – Revenge of the Sith.
|
|
||||||
<!-- empty line -->
|
|
||||||
```
|
|
||||||
|
|
||||||
I love Star Wars.
|
|
||||||
|
|
||||||
My favourite is Episode III – Revenge of the Sith.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Italic
|
|
||||||
|
|
||||||
Use one asterisk \(\*\) or underscore \(\_\) to italicize text.
|
|
||||||
|
|
||||||
{/* prettier-ignore */}
|
|
||||||
```md
|
|
||||||
I *love* Star Wars.
|
|
||||||
My _favourite_ is Episode III – Revenge of the Sith.
|
|
||||||
```
|
|
||||||
|
|
||||||
I _love_ Star Wars.
|
|
||||||
My _favourite_ is Episode III – Revenge of the Sith.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bold
|
|
||||||
|
|
||||||
Use two asterisks \(\*\) or underscores \(\_\) to bold text.
|
|
||||||
|
|
||||||
{/* prettier-ignore */}
|
|
||||||
```md
|
|
||||||
I **love** Star Wars.
|
|
||||||
My __favourite__ is Episode III – Revenge of the Sith.
|
|
||||||
```
|
|
||||||
|
|
||||||
I **love** Star Wars.
|
|
||||||
My **favourite** is Episode III – Revenge of the Sith.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Italic and Bold
|
|
||||||
|
|
||||||
Use three asterisks \(\*\) or underscores \(\_\) to both bold and italicize text.
|
|
||||||
|
|
||||||
{/* prettier-ignore */}
|
|
||||||
```md
|
|
||||||
I ***love*** Star Wars.
|
|
||||||
My ___favourite___ is Episode III – Revenge of the Sith.
|
|
||||||
```
|
|
||||||
|
|
||||||
I **_love_** Star Wars.
|
|
||||||
My **_favourite_** is Episode III – Revenge of the Sith.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Horizontal Rule
|
|
||||||
|
|
||||||
Use three hyphens \(\-\), asterisks \(\*\), or underscores \(\_\) to create a horizontal rule.
|
|
||||||
|
|
||||||
{/* prettier-ignore */}
|
|
||||||
```md
|
|
||||||
<!-- empty line -->
|
|
||||||
---
|
|
||||||
<!-- empty line -->
|
|
||||||
***
|
|
||||||
<!-- empty line -->
|
|
||||||
___
|
|
||||||
<!-- empty line -->
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
To create a link, the link text in brackets \(\[\]\) and then follow it immediately with the URL in parentheses \(\(\)\).
|
|
||||||
|
|
||||||
```md
|
|
||||||
Micro is a fork of [astro-nano](https://github.com/markhorn-dev/astro-nano).
|
|
||||||
```
|
|
||||||
|
|
||||||
Micro is a fork of [astro-nano](https://github.com/markhorn-dev/astro-nano).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ordered Lists
|
|
||||||
|
|
||||||
To create an ordered list, add line items with numbers followed by periods. Use an indent to create a nested list.
|
|
||||||
|
|
||||||
```md
|
|
||||||
1. Item 1
|
|
||||||
2. Item 2
|
|
||||||
1. Sub item 1
|
|
||||||
2. Sub item 2
|
|
||||||
3. Item 3
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Item 1
|
|
||||||
2. Item 2
|
|
||||||
1. Sub item 1
|
|
||||||
2. Sub item 2
|
|
||||||
3. Item 3
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Unordered List
|
|
||||||
|
|
||||||
To create an unordered list, add a hyphen \(\-\), an asterisk \(\*\), or a plus sign \(\+\) in front of line items. Don't mix. Use an indent to create a nested list.
|
|
||||||
|
|
||||||
```md
|
|
||||||
- Item 1
|
|
||||||
- Item 2
|
|
||||||
- Sub item 1
|
|
||||||
- Sub item 2
|
|
||||||
- Item 3
|
|
||||||
```
|
|
||||||
|
|
||||||
- Item 1
|
|
||||||
- Item 2
|
|
||||||
- Sub item 1
|
|
||||||
- Sub item 2
|
|
||||||
- Item 3
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Images
|
|
||||||
|
|
||||||
To add an image, add an exclamation mark (!), followed by alt text in brackets ([]), and the path or URL to the image asset in parentheses.
|
|
||||||
|
|
||||||
```md
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||
### Relative
|
|
||||||
|
|
||||||
Use the `` pattern relative to the same folder as the markdown file. Notice the period.
|
|
||||||
|
|
||||||
```md
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Public Image
|
|
||||||
|
|
||||||
Use the `` pattern relative to the public folder. No period.
|
|
||||||
|
|
||||||
```md
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### External Image
|
|
||||||
|
|
||||||
Use the `` pattern.
|
|
||||||
|
|
||||||
```md
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Blockquotes
|
|
||||||
|
|
||||||
To add a blockquote add the greater-than character \(\>\) before a paragraph. For multi-line blockquotes, add additional greater-than character for each line and include an empty spacer line.
|
|
||||||
|
|
||||||
```md
|
|
||||||
> So this is how liberty dies...
|
|
||||||
>
|
|
||||||
> with thunderous applause.
|
|
||||||
```
|
|
||||||
|
|
||||||
> So this is how liberty dies...
|
|
||||||
>
|
|
||||||
> with thunderous applause.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Strikethrough
|
|
||||||
|
|
||||||
Use a tilde \(\~\) symbol to strikethrough text.
|
|
||||||
|
|
||||||
```md
|
|
||||||
~I don't like sand.~ It's coarse and rough and irritating.
|
|
||||||
```
|
|
||||||
|
|
||||||
~I don't like sand.~ It's coarse and rough and irritating.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Subscript
|
|
||||||
|
|
||||||
Use the `<sub>` tag to denote subscript.
|
|
||||||
|
|
||||||
```md
|
|
||||||
H<sub>2</sub>O
|
|
||||||
```
|
|
||||||
|
|
||||||
H<sub>2</sub>O
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Superscript
|
|
||||||
|
|
||||||
Use the `<sup>` tag to denote superscript.
|
|
||||||
|
|
||||||
```md
|
|
||||||
E=mc<sup>2</sup>
|
|
||||||
```
|
|
||||||
|
|
||||||
E=mc<sup>2</sup>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Keyboard
|
|
||||||
|
|
||||||
Use the `<kbd>` tag to denote keys on the keyboard.
|
|
||||||
|
|
||||||
```md
|
|
||||||
<kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd>
|
|
||||||
```
|
|
||||||
|
|
||||||
<kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Abbreviate
|
|
||||||
|
|
||||||
Use the `<abbr>` tag to denote abbreviation.
|
|
||||||
|
|
||||||
```md
|
|
||||||
<abbr title="Graphics Interchange Format">GIF</abbr>
|
|
||||||
```
|
|
||||||
|
|
||||||
<abbr title="Graphics Interchange Format">GIF</abbr>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Highlight
|
|
||||||
|
|
||||||
Use the `<mark>` tag to denote highlighted text.
|
|
||||||
|
|
||||||
```md
|
|
||||||
Do or do not. <mark>There is no try.</mark>
|
|
||||||
```
|
|
||||||
|
|
||||||
Do or do not. <mark>There is no try.</mark>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Task Lists
|
|
||||||
|
|
||||||
Combine a list with square brackets ([]) representing a checkbox. Typing `x` inside the brackets marks the task as complete.
|
|
||||||
|
|
||||||
```md
|
|
||||||
- [x] Build a lightsaber
|
|
||||||
- [ ] Pass the Jedi Trials
|
|
||||||
- [ ] Train a padawan
|
|
||||||
```
|
|
||||||
|
|
||||||
- [x] Build a lightsaber
|
|
||||||
- [ ] Pass the Jedi Trials
|
|
||||||
- [ ] Train a padawan
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tables
|
|
||||||
|
|
||||||
Use three or more hyphens (-) for the column headers and use pipes (|) to separate each column. You can align text in the columns to the left, right, or center by adding a colon (:) to the left, right, or on both side of the hyphens.
|
|
||||||
|
|
||||||
```md
|
|
||||||
| Item | Count |
|
|
||||||
| :----- | ----: |
|
|
||||||
| X-Wing | 1 |
|
|
||||||
| Y-Wing | 2 |
|
|
||||||
| A-Wing | 3 |
|
|
||||||
```
|
|
||||||
|
|
||||||
| Item | Count |
|
|
||||||
| :----- | ----: |
|
|
||||||
| X-Wing | 1 |
|
|
||||||
| Y-Wing | 2 |
|
|
||||||
| A-Wing | 3 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Footnotes
|
|
||||||
|
|
||||||
Add a caret (^) and an identifier inside brackets \(\[\^1\]\). Identifiers can be numbers or words but can't contain spaces or tabs.
|
|
||||||
|
|
||||||
```md
|
|
||||||
Here's a footnote, [^1] and here's another one. [^2]
|
|
||||||
[^1]: This is the first footnote.
|
|
||||||
[^2]: This is the second footnote.
|
|
||||||
```
|
|
||||||
|
|
||||||
Here's a footnote, [^1] and here's another one. [^2]
|
|
||||||
[^1]: This is the first footnote.
|
|
||||||
[^2]: This is the second footnote.
|
|
||||||
|
|
||||||
See the bottom of this page to view the footnotes.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Code
|
|
||||||
|
|
||||||
To denote a word or phrase as code, enclose it in backticks (`).
|
|
||||||
|
|
||||||
```md
|
|
||||||
`package.json`
|
|
||||||
```
|
|
||||||
|
|
||||||
`package.json`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Code Blocks
|
|
||||||
|
|
||||||
Denote a code block by wrapping a section of valid code in triple backticks (`). To enable syntax highlighting, type the shorthand symbol for the language after the first three backticks. [Reference for shorthand symbols](https://shiki.style/languages).
|
|
||||||
|
|
||||||
````
|
|
||||||
```js
|
|
||||||
function hello() {
|
|
||||||
console.log("hello world");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
````
|
|
||||||
|
|
||||||
```js
|
|
||||||
function hello() {
|
|
||||||
console.log('hello world')
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Refer to [markdownguide.org](https://www.markdownguide.org/) for best practices as well as extended syntax.
|
|
||||||
|
|
||||||
---
|
|
Binary file not shown.
Before Width: | Height: | Size: 203 KiB |
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<button
|
|
||||||
onclick="alert(`You clicked the button!`)"
|
|
||||||
class="border border-black/10 p-2 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/10"
|
|
||||||
>
|
|
||||||
Relative Button
|
|
||||||
</button>
|
|
|
@ -1,71 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] MDX syntax guide'
|
|
||||||
description: 'Use interactive components in Markdown.'
|
|
||||||
date: '2024-03-16'
|
|
||||||
---
|
|
||||||
|
|
||||||
import Callout from '@/components/Callout.astro'
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
MDX is an extension of Markdown with the ability to import `.astro`,
|
|
||||||
`.jsx`, `.tsx` and other framework components you have integrated.
|
|
||||||
|
|
||||||
This guide covers the basics of MDX syntax and how to use it, as well as a few examples.
|
|
||||||
|
|
||||||
## Example 1
|
|
||||||
|
|
||||||
Importing a component from the `/components` directory.
|
|
||||||
|
|
||||||
This component accepts a Javascript date object and format it as a string.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
import DateComp from "../../../components/FormattedDate.astro";
|
|
||||||
|
|
||||||
<DateComp date={new Date()} />
|
|
||||||
```
|
|
||||||
|
|
||||||
import FormattedDate from '../../../components/FormattedDate.astro'
|
|
||||||
|
|
||||||
<FormattedDate date={new Date()} />
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Example 2
|
|
||||||
|
|
||||||
Importing a component from a relative path to your content.
|
|
||||||
|
|
||||||
This component displays an alert when the button is clicked.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
import RelativeComponent from "./component.astro";
|
|
||||||
|
|
||||||
<RelativeComponent />
|
|
||||||
```
|
|
||||||
|
|
||||||
import RelativeComponent from './component.astro'
|
|
||||||
|
|
||||||
<RelativeComponent />
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
By default Micro has zero frameworks installed. If you install a framework, components of that framework can be used in MDX files.
|
|
||||||
|
|
||||||
<Callout>
|
|
||||||
Don't forget to use [client
|
|
||||||
directives](https://docs.astro.build/en/reference/directives-reference/#client-directives)
|
|
||||||
to make framework components interactive.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
```astro
|
|
||||||
<ReactComponent client:load />
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## More Links
|
|
||||||
|
|
||||||
- [MDX Syntax Documentation](https://mdxjs.com/docs/what-is-mdx)
|
|
||||||
- [Astro Framework Integrations](https://docs.astro.build/en/guides/integrations-guide)
|
|
||||||
- [Astro Usage Documentation](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages)
|
|
||||||
- [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives)
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Year sorting example'
|
|
||||||
description: 'Nano groups posts by year.'
|
|
||||||
date: '2023-12-31'
|
|
||||||
---
|
|
||||||
|
|
||||||
This post is to demonstrate the year sorting capabilities.
|
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Draft example'
|
|
||||||
description: 'Setting draft flag to true to hide this post.'
|
|
||||||
date: '2022-12-31'
|
|
||||||
draft: false
|
|
||||||
---
|
|
||||||
|
|
||||||
This post also demonstrates the year sorting capabilities.
|
|
||||||
|
|
||||||
Try setting this file's metadata to `draft: true`.
|
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
title: '[Old] Chronological pagination example'
|
|
||||||
description: 'Pagination works regardless of folder name.'
|
|
||||||
date: '2024-03-21'
|
|
||||||
draft: false
|
|
||||||
---
|
|
||||||
|
|
||||||
This post should show up in proper chronological order even though its folder comes last in the `content/blog` directory.
|
|
||||||
|
|
||||||
The `Previous Post` and `Next Post` buttons under each blog post should also keep the proper chronological order, based on the frontmatter `date` field.
|
|
|
@ -4,7 +4,6 @@ import Header from '@components/Header.astro'
|
||||||
import Footer from '@components/Footer.astro'
|
import Footer from '@components/Footer.astro'
|
||||||
import { SITE } from '@consts'
|
import { SITE } from '@consts'
|
||||||
import '../styles/katex.css'
|
import '../styles/katex.css'
|
||||||
import { ViewTransitions } from 'astro:transitions'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: string
|
title: string
|
||||||
|
@ -18,10 +17,9 @@ const { title, description } = Astro.props
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<Head title={`${title} | ${SITE.TITLE}`} description={description} />
|
<Head title={`${title} | ${SITE.TITLE}`} description={description} />
|
||||||
<ViewTransitions />
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
class="box-border flex h-fit min-h-screen flex-col px-4 font-sans antialiased"
|
class="box-border flex h-fit min-h-screen flex-col px-4 font-sans bg-background text-foreground antialiased"
|
||||||
>
|
>
|
||||||
<Header />
|
<Header />
|
||||||
<main class="flex-grow">
|
<main class="flex-grow">
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { SITE } from '@consts'
|
||||||
<Layout title="404" description={SITE.DESCRIPTION}>
|
<Layout title="404" description={SITE.DESCRIPTION}>
|
||||||
<Container>
|
<Container>
|
||||||
<div class="mt-16 grid place-items-center gap-3">
|
<div class="mt-16 grid place-items-center gap-3">
|
||||||
<h4 class="text-2xl font-semibold text-black dark:text-white">
|
<h4 class="text-2xl font-semibold">
|
||||||
404: Page not found
|
404: Page not found
|
||||||
</h4>
|
</h4>
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Image } from 'astro:assets'
|
||||||
<Layout title="About" description="About">
|
<Layout title="About" description="About">
|
||||||
<Container>
|
<Container>
|
||||||
<div class="space-y-10">
|
<div class="space-y-10">
|
||||||
<div class="font-semibold text-black dark:text-white">About</div>
|
<div class="font-semibold">About</div>
|
||||||
<section class="not-prose flex flex-col gap-4 text-justify">
|
<section class="not-prose flex flex-col gap-4 text-justify">
|
||||||
<p class="text-justify">
|
<p class="text-justify">
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro
|
||||||
|
@ -26,7 +26,7 @@ import { Image } from 'astro:assets'
|
||||||
<div class="flex flex-col justify-center md:flex-row">
|
<div class="flex flex-col justify-center md:flex-row">
|
||||||
<div class="my-10 text-center">
|
<div class="my-10 text-center">
|
||||||
<div
|
<div
|
||||||
class="h-[250px] w-[350px] -rotate-6 overflow-hidden rounded-xl bg-neutral-300 object-cover"
|
class="h-[250px] w-[350px] -rotate-6 overflow-hidden rounded-xl object-cover"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={'/astro-nano.png'}
|
src={'/astro-nano.png'}
|
||||||
|
@ -42,7 +42,7 @@ import { Image } from 'astro:assets'
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-10 my-10 text-center">
|
<div class="mx-10 my-10 text-center">
|
||||||
<div
|
<div
|
||||||
class="mx-auto h-[250px] w-[150px] rotate-6 rounded-xl bg-neutral-300 object-cover sm:ml-auto"
|
class="mx-auto h-[250px] w-[150px] rotate-6 rounded-xl object-cover sm:ml-auto"
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={'/astro-micro.jpg'}
|
src={'/astro-micro.jpg'}
|
||||||
|
|
|
@ -62,7 +62,7 @@ const { Content, headings } = await post.render()
|
||||||
{readingTime(post.body)}
|
{readingTime(post.body)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-4xl font-semibold text-black dark:text-white">
|
<h1 class="text-4xl font-semibold">
|
||||||
{post.data.title}
|
{post.data.title}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="font-base text-sm">
|
<div class="font-base text-sm">
|
||||||
|
@ -72,7 +72,7 @@ const { Content, headings } = await post.render()
|
||||||
<div class="my-1 inline-block">
|
<div class="my-1 inline-block">
|
||||||
<a
|
<a
|
||||||
href={`/tags/${tag}`}
|
href={`/tags/${tag}`}
|
||||||
class="mx-1 rounded-full bg-orange-300 px-2 py-1 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
class="mx-1 rounded-full px-2 py-1 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
|
@ -85,7 +85,7 @@ const { Content, headings } = await post.render()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{headings.length > 0 && <TableOfContents headings={headings} />}
|
{headings.length > 0 && <TableOfContents headings={headings} />}
|
||||||
<article class="animate">
|
<article class="prose prose-neutral max-w-full dark:prose-invert prose-img:mx-auto prose-img:my-auto">
|
||||||
<Content />
|
<Content />
|
||||||
<div class="mt-24">
|
<div class="mt-24">
|
||||||
<PostNavigation prevPost={prevPost} nextPost={nextPost} />
|
<PostNavigation prevPost={prevPost} nextPost={nextPost} />
|
||||||
|
|
|
@ -31,7 +31,7 @@ const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a))
|
||||||
{
|
{
|
||||||
years.map((year) => (
|
years.map((year) => (
|
||||||
<section class="space-y-4">
|
<section class="space-y-4">
|
||||||
<div class="font-semibold text-black dark:text-white">{year}</div>
|
<div class="font-semibold">{year}</div>
|
||||||
<div>
|
<div>
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="not-prose flex flex-col gap-4">
|
||||||
{posts[year].map((post) => (
|
{posts[year].map((post) => (
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Link from '@components/Link.astro'
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content'
|
||||||
import type { CollectionEntry } from 'astro:content'
|
import type { CollectionEntry } from 'astro:content'
|
||||||
import SocialIcons from '@components/SocialIcons.astro'
|
import SocialIcons from '@components/SocialIcons.astro'
|
||||||
|
import { ModeToggle } from '@components/ui/mode-toggle'
|
||||||
|
|
||||||
const blog = (await getCollection('blog'))
|
const blog = (await getCollection('blog'))
|
||||||
.filter((post) => !post.data.draft)
|
.filter((post) => !post.data.draft)
|
||||||
|
@ -17,8 +18,9 @@ const blog = (await getCollection('blog'))
|
||||||
<Layout title="Home" description="Home">
|
<Layout title="Home" description="Home">
|
||||||
<Container>
|
<Container>
|
||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
|
<ModeToggle client:load />
|
||||||
<div class="flex flex-wrap items-center justify-between gap-y-2">
|
<div class="flex flex-wrap items-center justify-between gap-y-2">
|
||||||
<h2 class="font-semibold text-black dark:text-white">Latest posts</h2>
|
<h2 class="font-semibold">Latest posts</h2>
|
||||||
<Link href="/blog"> See all posts </Link>
|
<Link href="/blog"> See all posts </Link>
|
||||||
</div>
|
</div>
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="not-prose flex flex-col gap-4">
|
||||||
|
|
|
@ -36,9 +36,9 @@ export async function getStaticPaths() {
|
||||||
>
|
>
|
||||||
<Container>
|
<Container>
|
||||||
<div class="space-y-10">
|
<div class="space-y-10">
|
||||||
<div class="font-semibold text-black dark:text-white">
|
<div class="font-semibold">
|
||||||
Tag: <span
|
Tag: <span
|
||||||
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
class="mx-2 rounded-full px-3 py-2 transition-colors duration-300 ease-in-out"
|
||||||
>#{tag}</span
|
>#{tag}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,14 +14,14 @@ const tags = blog
|
||||||
<Layout title="Tags" description="Tags">
|
<Layout title="Tags" description="Tags">
|
||||||
<Container>
|
<Container>
|
||||||
<div class="space-y-10">
|
<div class="space-y-10">
|
||||||
<div class="font-semibold text-black dark:text-white">Tags</div>
|
<div class="font-semibold">Tags</div>
|
||||||
<ul class="flex flex-wrap">
|
<ul class="flex flex-wrap">
|
||||||
{
|
{
|
||||||
tags.map((tag) => (
|
tags.map((tag) => (
|
||||||
<li class="my-3">
|
<li class="my-3">
|
||||||
<a
|
<a
|
||||||
href={`/tags/${tag}`}
|
href={`/tags/${tag}`}
|
||||||
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
|
class="mx-2 rounded-full px-3 py-2 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -2,42 +2,6 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
article {
|
|
||||||
@apply prose prose-neutral max-w-full dark:prose-invert prose-img:mx-auto prose-img:my-auto;
|
|
||||||
@apply prose-headings:font-semibold;
|
|
||||||
@apply prose-headings:text-black prose-headings:dark:text-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer utilities {
|
|
||||||
article a {
|
|
||||||
@apply font-sans text-current underline underline-offset-[3px];
|
|
||||||
@apply decoration-black/30 dark:decoration-white/30;
|
|
||||||
@apply transition-colors duration-300 ease-in-out;
|
|
||||||
}
|
|
||||||
article a:hover {
|
|
||||||
@apply text-black dark:text-white;
|
|
||||||
@apply decoration-black/50 dark:decoration-white/50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll_bar {
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #1e293b #0f172a;
|
|
||||||
}
|
|
||||||
|
|
||||||
html #back-to-top {
|
|
||||||
@apply pointer-events-none opacity-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.scrolled #back-to-top {
|
|
||||||
@apply pointer-events-auto opacity-100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shiki config */
|
|
||||||
pre {
|
|
||||||
@apply border border-black/15 py-5 dark:border-white/20;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--astro-code-color-text: #09090b;
|
--astro-code-color-text: #09090b;
|
||||||
--astro-code-color-background: #fafafa;
|
--astro-code-color-background: #fafafa;
|
||||||
|
@ -66,19 +30,6 @@ pre {
|
||||||
--astro-code-token-link: #8d85ff;
|
--astro-code-token-link: #8d85ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy code button on codeblocks */
|
|
||||||
.copy-code {
|
|
||||||
@apply absolute right-3 top-3 grid size-9 place-content-center rounded border border-black/15 bg-neutral-100 text-center duration-300 ease-in-out dark:border-white/20 dark:bg-neutral-900;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-code:hover {
|
|
||||||
@apply bg-[#E9E9E9] transition-colors dark:bg-[#232323];
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-code:active {
|
|
||||||
@apply scale-90 transition-transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 0 0% 100%;
|
--background: 0 0% 100%;
|
||||||
|
@ -139,4 +90,18 @@ pre {
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.disable-transitions * {
|
||||||
|
@apply !transition-none;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import type { Config } from 'tailwindcss'
|
||||||
import defaultTheme from 'tailwindcss/defaultTheme'
|
import defaultTheme from 'tailwindcss/defaultTheme'
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
darkMode: ['class', 'class'],
|
darkMode: ['selector'],
|
||||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
|
Loading…
Add table
Reference in a new issue