From 660e4fd701923bd6ad7e8d1280bbe24949572388 Mon Sep 17 00:00:00 2001 From: David Haz Date: Tue, 8 Jul 2025 23:34:52 +0300 Subject: [PATCH] documentation structure --- eslint.config.ts | 1 + index.html | 33 +- package-lock.json | 162 ++++- package.json | 6 +- src/assets/logos/vue-bits-logo-small-dark.svg | 4 +- src/assets/logos/vuebits-gh-black.svg | 18 +- src/components/code/CliInstallation.vue | 144 ++++ src/components/code/CodeExample.vue | 110 +++ src/components/code/Dependencies.vue | 18 + src/components/common/ContributionSection.vue | 47 ++ src/components/common/Customize.vue | 6 + src/components/common/PreviewSlider.vue | 118 ++++ src/components/common/PreviewSwitch.vue | 115 ++++ src/components/common/PropTable.vue | 131 ++++ src/components/common/RefreshButton.vue | 39 ++ src/components/common/TabbedLayout.vue | 166 +++++ .../landing/DisplayHeader/DisplayHeader.css | 4 +- .../landing/FeatureCards/FeatureCards.css | 14 +- src/components/landing/Footer/Footer.css | 2 +- src/components/landing/Hero/Hero.vue | 2 +- .../landing/StartBuilding/StartBuilding.css | 10 +- src/components/layouts/CategoryLayout.vue | 53 +- src/components/navs/Header.vue | 231 +++++++ src/components/navs/Sidebar.vue | 334 +++++++++ src/composables/useForceRerender.ts | 18 + src/constants/Categories.ts | 31 + src/constants/Components.ts | 22 + .../code/Animations/fadeContentCode.ts | 27 + src/constants/code/Backgrounds/dotGridCode.ts | 39 ++ .../code/TextAnimations/splitTextCode.ts | 33 + src/content/Backgrounds/DotGrid/DotGrid.vue | 4 +- src/content/Backgrounds/Squares/Squares.vue | 2 +- .../TextAnimations/SplitText/SplitText.vue | 5 + src/css/base.css | 15 +- src/css/category.css | 479 +++++++++++++ src/css/landing.css | 4 +- src/css/main.css | 2 + src/css/sidebar.css | 643 ++++++++++++++++++ src/demo/Animations/FadeContentDemo.vue | 117 ++++ src/demo/Backgrounds/DotGridDemo.vue | 153 +++++ src/demo/TextAnimations/SplitTextDemo.vue | 88 +++ src/main.ts | 21 + src/pages/CategoryPage.vue | 66 +- src/types/code.ts | 7 + src/utils/utils.ts | 18 +- vite.config.ts | 5 +- 46 files changed, 3488 insertions(+), 79 deletions(-) create mode 100644 src/components/code/CliInstallation.vue create mode 100644 src/components/code/CodeExample.vue create mode 100644 src/components/code/Dependencies.vue create mode 100644 src/components/common/ContributionSection.vue create mode 100644 src/components/common/Customize.vue create mode 100644 src/components/common/PreviewSlider.vue create mode 100644 src/components/common/PreviewSwitch.vue create mode 100644 src/components/common/PropTable.vue create mode 100644 src/components/common/RefreshButton.vue create mode 100644 src/components/common/TabbedLayout.vue create mode 100644 src/components/navs/Header.vue create mode 100644 src/components/navs/Sidebar.vue create mode 100644 src/composables/useForceRerender.ts create mode 100644 src/constants/code/Animations/fadeContentCode.ts create mode 100644 src/constants/code/Backgrounds/dotGridCode.ts create mode 100644 src/constants/code/TextAnimations/splitTextCode.ts create mode 100644 src/css/category.css create mode 100644 src/css/sidebar.css create mode 100644 src/demo/Animations/FadeContentDemo.vue create mode 100644 src/demo/Backgrounds/DotGridDemo.vue create mode 100644 src/demo/TextAnimations/SplitTextDemo.vue create mode 100644 src/types/code.ts diff --git a/eslint.config.ts b/eslint.config.ts index e73d45e..140c745 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -23,6 +23,7 @@ export default defineConfigWithVueTs( files: ['**/*.vue'], rules: { 'vue/multi-word-component-names': 'off', + 'vue/no-reserved-component-names': 'off', }, }, ) diff --git a/index.html b/index.html index 73181a1..9e2887c 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,24 @@ - - - - - Vue Bits - - -
- - - + + + + + + + + + + + + Vue Bits + + + +
+ + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f6a56bb..8faa6ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,15 @@ "name": "vue-bits", "version": "0.0.0", "dependencies": { + "@primeuix/themes": "^1.2.1", + "@wdns/vue-code-block": "^2.3.5", "gsap": "^3.13.0", "ogl": "^1.0.11", "primeicons": "^7.0.0", + "primevue": "^4.3.6", "vue": "^3.5.17", - "vue-router": "^4.5.1" + "vue-router": "^4.5.1", + "vue-sonner": "^2.0.1" }, "devDependencies": { "@tailwindcss/vite": "^4.1.11", @@ -1307,6 +1311,74 @@ "dev": true, "license": "MIT" }, + "node_modules/@primeuix/styled": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.7.0.tgz", + "integrity": "sha512-xUqMdQb75izeDkNWFK1QlU15aUl5LIU97Fq68IXOhrqqLsKEBnj5ftntFZrENQW70jAHwALdWP4EOGi/poc9Tg==", + "license": "MIT", + "dependencies": { + "@primeuix/utils": "^0.6.0" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/styles": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@primeuix/styles/-/styles-1.2.1.tgz", + "integrity": "sha512-Tri7pPgZgxrVmhJG8ijZZFolQ6vu27xnkGoAB9EFY8YlaKTM5iqkWzEcqdxy2KmgFWMXi+BrPHwO0RdQ6JCT+g==", + "license": "MIT", + "dependencies": { + "@primeuix/styled": "^0.7.0" + } + }, + "node_modules/@primeuix/themes": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@primeuix/themes/-/themes-1.2.1.tgz", + "integrity": "sha512-DVCFDncvag47tpag3TdufDTuvUbfKnkgzmlxAQkwuMS0IlPA3wChrf9VlL2wETg/ZpJm/tHobkJBnB9FmkiqnA==", + "license": "MIT", + "dependencies": { + "@primeuix/styled": "^0.7.0" + } + }, + "node_modules/@primeuix/utils": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.6.0.tgz", + "integrity": "sha512-ULpB87ImNAiX36OMtyDeRceWB7N/mVlh6gGLqp/lx8UMKZlLIQH/UAFND86hYXHwNpXeNKcWfMGreb0Oc0hcZA==", + "license": "MIT", + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primevue/core": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.3.6.tgz", + "integrity": "sha512-ZuP0gqpEbIkpz9Em/O4Du+fRj0qyOl2YYuxhlELAtRg8+YkMsSJDd2ai2GM623sYRWOIwMr5rWevZGB1WqukzQ==", + "license": "MIT", + "dependencies": { + "@primeuix/styled": "^0.7.0", + "@primeuix/utils": "^0.6.0" + }, + "engines": { + "node": ">=12.11.0" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@primevue/icons": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.3.6.tgz", + "integrity": "sha512-QVFmfikMpo4/DObMSbB5kS8MH1OoQrx8N9prEZaMvfFzD3hixxK24l2VrcS5x5/0NnP3szwZwTCmEAutCygX6A==", + "license": "MIT", + "dependencies": { + "@primeuix/utils": "^0.6.0", + "@primevue/core": "4.3.6" + }, + "engines": { + "node": ">=12.11.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.19", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", @@ -2591,6 +2663,28 @@ } } }, + "node_modules/@wdns/vue-code-block": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@wdns/vue-code-block/-/vue-code-block-2.3.5.tgz", + "integrity": "sha512-09TguXcFZEA/9Fyx4c/3Jp4XUK82OKiT1TwH8cBeGg6Nj1E1R16nuABq1yJSvq/GZCxXtOJWw9i3TdxV4MctOw==", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/webdevnerdstuff" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/WebDevNerdStuff" + } + ], + "license": "MIT", + "dependencies": { + "highlight.js": "^11.8.0", + "prismjs": "^1.29.0", + "ua-parser-js": "^1.0.38", + "vue": "^3.4.31" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -3681,6 +3775,15 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", @@ -4838,6 +4941,31 @@ "integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==", "license": "MIT" }, + "node_modules/primevue": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.3.6.tgz", + "integrity": "sha512-Wwg2dH6pBmOdkj9L/OnrCQf9AKPHfY5CcfnDyWeh0tNlR+XjYKGl8qvMdJOvGO9jjg6UdsX5MSaU8vDDsSG+sg==", + "license": "MIT", + "dependencies": { + "@primeuix/styled": "^0.7.0", + "@primeuix/styles": "^1.2.0", + "@primeuix/utils": "^0.6.0", + "@primevue/core": "4.3.6", + "@primevue/icons": "4.3.6" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5309,6 +5437,32 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/ua-parser-js": { + "version": "1.0.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz", + "integrity": "sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -5671,6 +5825,12 @@ "vue": "^3.2.0" } }, + "node_modules/vue-sonner": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vue-sonner/-/vue-sonner-2.0.1.tgz", + "integrity": "sha512-sn4vjCRzRcnMaxaLa9aNSyZQi6S+gshiea5Lc3eqpkj0ES9LH8ljg+WJCkxefr28V4PZ9xkUXBIWpxGfQxstIg==", + "license": "MIT" + }, "node_modules/vue-tsc": { "version": "2.2.12", "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", diff --git a/package.json b/package.json index e6a12cf..7a228cb 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,15 @@ "lint": "eslint . --fix" }, "dependencies": { + "@primeuix/themes": "^1.2.1", + "@wdns/vue-code-block": "^2.3.5", "gsap": "^3.13.0", "ogl": "^1.0.11", "primeicons": "^7.0.0", + "primevue": "^4.3.6", "vue": "^3.5.17", - "vue-router": "^4.5.1" + "vue-router": "^4.5.1", + "vue-sonner": "^2.0.1" }, "devDependencies": { "@tailwindcss/vite": "^4.1.11", diff --git a/src/assets/logos/vue-bits-logo-small-dark.svg b/src/assets/logos/vue-bits-logo-small-dark.svg index 2f9ca97..7ae370b 100644 --- a/src/assets/logos/vue-bits-logo-small-dark.svg +++ b/src/assets/logos/vue-bits-logo-small-dark.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/assets/logos/vuebits-gh-black.svg b/src/assets/logos/vuebits-gh-black.svg index 7306df5..e86e09f 100644 --- a/src/assets/logos/vuebits-gh-black.svg +++ b/src/assets/logos/vuebits-gh-black.svg @@ -1,11 +1,11 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/components/code/CliInstallation.vue b/src/components/code/CliInstallation.vue new file mode 100644 index 0000000..d578d98 --- /dev/null +++ b/src/components/code/CliInstallation.vue @@ -0,0 +1,144 @@ + + + + + \ No newline at end of file diff --git a/src/components/code/CodeExample.vue b/src/components/code/CodeExample.vue new file mode 100644 index 0000000..ad6c040 --- /dev/null +++ b/src/components/code/CodeExample.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/src/components/code/Dependencies.vue b/src/components/code/Dependencies.vue new file mode 100644 index 0000000..b27fb66 --- /dev/null +++ b/src/components/code/Dependencies.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/common/ContributionSection.vue b/src/components/common/ContributionSection.vue new file mode 100644 index 0000000..0473fc2 --- /dev/null +++ b/src/components/common/ContributionSection.vue @@ -0,0 +1,47 @@ + + + \ No newline at end of file diff --git a/src/components/common/Customize.vue b/src/components/common/Customize.vue new file mode 100644 index 0000000..89d709d --- /dev/null +++ b/src/components/common/Customize.vue @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/src/components/common/PreviewSlider.vue b/src/components/common/PreviewSlider.vue new file mode 100644 index 0000000..c5a020b --- /dev/null +++ b/src/components/common/PreviewSlider.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/common/PreviewSwitch.vue b/src/components/common/PreviewSwitch.vue new file mode 100644 index 0000000..2bdf305 --- /dev/null +++ b/src/components/common/PreviewSwitch.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/src/components/common/PropTable.vue b/src/components/common/PropTable.vue new file mode 100644 index 0000000..51e2848 --- /dev/null +++ b/src/components/common/PropTable.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/src/components/common/RefreshButton.vue b/src/components/common/RefreshButton.vue new file mode 100644 index 0000000..bcadb79 --- /dev/null +++ b/src/components/common/RefreshButton.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/src/components/common/TabbedLayout.vue b/src/components/common/TabbedLayout.vue new file mode 100644 index 0000000..d481b4d --- /dev/null +++ b/src/components/common/TabbedLayout.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/src/components/landing/DisplayHeader/DisplayHeader.css b/src/components/landing/DisplayHeader/DisplayHeader.css index 648c46b..701035a 100644 --- a/src/components/landing/DisplayHeader/DisplayHeader.css +++ b/src/components/landing/DisplayHeader/DisplayHeader.css @@ -11,7 +11,7 @@ padding: 0 4em; height: 160px; margin: 0 auto; - background: linear-gradient(to bottom, #0e0e0e, transparent); + background: linear-gradient(to bottom, #0b0b0b, transparent); } .header-container { @@ -125,7 +125,7 @@ } .cta-button span { - background-color: #0e0e0e; + background-color: #0b0b0b; margin-left: 1em; margin-right: calc(1em - 8px); padding-top: .1em; diff --git a/src/components/landing/FeatureCards/FeatureCards.css b/src/components/landing/FeatureCards/FeatureCards.css index 32722f2..38accce 100644 --- a/src/components/landing/FeatureCards/FeatureCards.css +++ b/src/components/landing/FeatureCards/FeatureCards.css @@ -175,7 +175,7 @@ .feature-card { user-select: none; - background: #0e0e0e; + background: #0b0b0b; border: 1px solid rgba(148, 184, 154, 0.2); border-radius: 16px; padding: 2rem; @@ -357,7 +357,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to top, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to top, #0b0b0b 0%, transparent 100%); border-radius: 0 0 8px 8px; pointer-events: none; z-index: 2; @@ -370,7 +370,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to bottom, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to bottom, #0b0b0b 0%, transparent 100%); border-radius: 8px 8px 0 0; pointer-events: none; z-index: 2; @@ -410,7 +410,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to top, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to top, #0b0b0b 0%, transparent 100%); border-radius: 0 0 8px 8px; pointer-events: none; z-index: 2; @@ -423,7 +423,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to bottom, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to bottom, #0b0b0b 0%, transparent 100%); border-radius: 8px 8px 0 0; pointer-events: none; z-index: 2; @@ -462,7 +462,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to top, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to top, #0b0b0b 0%, transparent 100%); border-radius: 0 0 8px 8px; pointer-events: none; z-index: 2; @@ -475,7 +475,7 @@ left: 0; right: 0; height: 20%; - background: linear-gradient(to bottom, #0e0e0e 0%, transparent 100%); + background: linear-gradient(to bottom, #0b0b0b 0%, transparent 100%); border-radius: 8px 8px 0 0; pointer-events: none; z-index: 2; diff --git a/src/components/landing/Footer/Footer.css b/src/components/landing/Footer/Footer.css index e078525..aa49be4 100644 --- a/src/components/landing/Footer/Footer.css +++ b/src/components/landing/Footer/Footer.css @@ -3,7 +3,7 @@ margin-top: 8rem; padding: 2.4rem; border-top: 1px solid rgba(149, 184, 148, 0.1); - background: linear-gradient(to bottom, transparent, #0e0e0e); + background: linear-gradient(to bottom, transparent, #0b0b0b); z-index: 220; } diff --git a/src/components/landing/Hero/Hero.vue b/src/components/landing/Hero/Hero.vue index fc32eeb..3b4e0cc 100644 --- a/src/components/landing/Hero/Hero.vue +++ b/src/components/landing/Hero/Hero.vue @@ -16,7 +16,7 @@ Browse Components
- +
diff --git a/src/components/landing/StartBuilding/StartBuilding.css b/src/components/landing/StartBuilding/StartBuilding.css index 4ce1d65..8b442b5 100644 --- a/src/components/landing/StartBuilding/StartBuilding.css +++ b/src/components/landing/StartBuilding/StartBuilding.css @@ -57,7 +57,7 @@ } .start-building-title { - color: #0e0e0e; + color: #0b0b0b; font-size: 2.6rem; font-weight: 600; margin: 0; @@ -65,7 +65,7 @@ } .start-building-subtitle { - color: #0e0e0e; + color: #0b0b0b; font-size: 1.2rem; font-weight: 500; margin: -1rem 0 0 0; @@ -76,8 +76,8 @@ .start-building-button { background: transparent; - color: #0e0e0e; - border: 2px solid #0e0e0e; + color: #0b0b0b; + border: 2px solid #0b0b0b; padding: .6rem 1.6rem; font-size: 1.1rem; font-weight: 600; @@ -87,7 +87,7 @@ } .start-building-button:hover { - background: #0e0e0e; + background: #0b0b0b; color: #27FF64; } diff --git a/src/components/layouts/CategoryLayout.vue b/src/components/layouts/CategoryLayout.vue index 7faf18b..a1d0138 100644 --- a/src/components/layouts/CategoryLayout.vue +++ b/src/components/layouts/CategoryLayout.vue @@ -1,34 +1,35 @@ - - +import Header from '../navs/Header.vue'; +import Sidebar from '../navs/Sidebar.vue'; + \ No newline at end of file diff --git a/src/components/navs/Header.vue b/src/components/navs/Header.vue new file mode 100644 index 0000000..8509155 --- /dev/null +++ b/src/components/navs/Header.vue @@ -0,0 +1,231 @@ + + + \ No newline at end of file diff --git a/src/components/navs/Sidebar.vue b/src/components/navs/Sidebar.vue new file mode 100644 index 0000000..6b7abfe --- /dev/null +++ b/src/components/navs/Sidebar.vue @@ -0,0 +1,334 @@ + + + \ No newline at end of file diff --git a/src/composables/useForceRerender.ts b/src/composables/useForceRerender.ts new file mode 100644 index 0000000..fba5ae4 --- /dev/null +++ b/src/composables/useForceRerender.ts @@ -0,0 +1,18 @@ +import { ref } from 'vue' + +/** + * Composable for force re-rendering components + * Useful for demo components that need to restart animations or reset state + */ +export function useForceRerender() { + const rerenderKey = ref(0) + + const forceRerender = () => { + rerenderKey.value++ + } + + return { + rerenderKey, + forceRerender + } +} diff --git a/src/constants/Categories.ts b/src/constants/Categories.ts index e69de29..0d400dd 100644 --- a/src/constants/Categories.ts +++ b/src/constants/Categories.ts @@ -0,0 +1,31 @@ +// Highlighted sidebar items +export const NEW = []; +export const UPDATED = []; + +// Used for main sidebar navigation +export const CATEGORIES = [ + { + name: 'Text Animations', + subcategories: [ + 'Split Text', + ] + }, + { + name: 'Animations', + subcategories: [ + 'Fade Content', + ] + }, + { + name: 'Components', + subcategories: [ + + ], + }, + { + name: 'Backgrounds', + subcategories: [ + 'Dot Grid', + ], + } +]; \ No newline at end of file diff --git a/src/constants/Components.ts b/src/constants/Components.ts index e69de29..e1794ce 100644 --- a/src/constants/Components.ts +++ b/src/constants/Components.ts @@ -0,0 +1,22 @@ +const animations = { + 'fade-content': () => import("../demo/Animations/FadeContentDemo.vue"), +}; + +const textAnimations = { + 'split-text': () => import("../demo/TextAnimations/SplitTextDemo.vue"), +}; + +const components = { + +}; + +const backgrounds = { + 'dot-grid': () => import("../demo/Backgrounds/DotGridDemo.vue"), +}; + +export const componentMap = { + ...animations, + ...textAnimations, + ...components, + ...backgrounds, +}; diff --git a/src/constants/code/Animations/fadeContentCode.ts b/src/constants/code/Animations/fadeContentCode.ts new file mode 100644 index 0000000..3cca1d8 --- /dev/null +++ b/src/constants/code/Animations/fadeContentCode.ts @@ -0,0 +1,27 @@ +import code from '@content/Animations/FadeContent/FadeContent.vue?raw' +import type { CodeObject } from '../../../types/code' + +export const fadeContent: CodeObject = { + cli: `npx jsrepo add https://vuebits.dev/Animations/FadeContent`, + usage: ` + +`, + code +} diff --git a/src/constants/code/Backgrounds/dotGridCode.ts b/src/constants/code/Backgrounds/dotGridCode.ts new file mode 100644 index 0000000..ad90c38 --- /dev/null +++ b/src/constants/code/Backgrounds/dotGridCode.ts @@ -0,0 +1,39 @@ +import code from '@content/Backgrounds/DotGrid/DotGrid.vue?raw' +import type { CodeObject } from '../../../types/code' + +export const dotGrid: CodeObject = { + cli: `npx jsrepo add https://vuebits.dev/Backgrounds/DotGrid`, + installation: `npm install gsap`, + usage: ` + + + +`, + code +} diff --git a/src/constants/code/TextAnimations/splitTextCode.ts b/src/constants/code/TextAnimations/splitTextCode.ts new file mode 100644 index 0000000..427d0d4 --- /dev/null +++ b/src/constants/code/TextAnimations/splitTextCode.ts @@ -0,0 +1,33 @@ +// Fun fact: this is the first component ever made for Vue Bits! +import code from '@content/TextAnimations/SplitText/SplitText.vue?raw' +import type { CodeObject } from '../../../types/code' + +export const splitText: CodeObject = { + cli: `npx jsrepo add https://vuebits.dev/TextAnimations/SplitText`, + installation: `npm install gsap`, + usage: ` + +`, + code +} \ No newline at end of file diff --git a/src/content/Backgrounds/DotGrid/DotGrid.vue b/src/content/Backgrounds/DotGrid/DotGrid.vue index 3e6512d..4591dfa 100644 --- a/src/content/Backgrounds/DotGrid/DotGrid.vue +++ b/src/content/Backgrounds/DotGrid/DotGrid.vue @@ -51,8 +51,8 @@ export interface DotGridProps { const props = withDefaults(defineProps(), { dotSize: 16, gap: 32, - baseColor: '#5227FF', - activeColor: '#5227FF', + baseColor: '#27FF64', + activeColor: '#27FF64', proximity: 150, speedTrigger: 100, shockRadius: 250, diff --git a/src/content/Backgrounds/Squares/Squares.vue b/src/content/Backgrounds/Squares/Squares.vue index 6280463..8b8bb29 100644 --- a/src/content/Backgrounds/Squares/Squares.vue +++ b/src/content/Backgrounds/Squares/Squares.vue @@ -84,7 +84,7 @@ const drawGrid = () => { Math.sqrt(canvas.width ** 2 + canvas.height ** 2) / 2 ) gradient.addColorStop(0, "rgba(0, 0, 0, 0)") - gradient.addColorStop(1, "#0e0e0e") + gradient.addColorStop(1, "#0b0b0b") ctx.fillStyle = gradient ctx.fillRect(0, 0, canvas.width, canvas.height) diff --git a/src/content/TextAnimations/SplitText/SplitText.vue b/src/content/TextAnimations/SplitText/SplitText.vue index 8f2f389..be2bde2 100644 --- a/src/content/TextAnimations/SplitText/SplitText.vue +++ b/src/content/TextAnimations/SplitText/SplitText.vue @@ -47,6 +47,10 @@ const props = withDefaults(defineProps(), { textAlign: 'center' }) +const emit = defineEmits<{ + 'animation-complete': [] +}>() + const textRef = ref(null) const animationCompletedRef = ref(false) const scrollTriggerRef = ref(null) @@ -130,6 +134,7 @@ const initializeAnimation = async () => { immediateRender: true, }) props.onLetterAnimationComplete?.() + emit('animation-complete') }, }) diff --git a/src/css/base.css b/src/css/base.css index eaf4da4..17a1520 100644 --- a/src/css/base.css +++ b/src/css/base.css @@ -8,10 +8,23 @@ } body { - background-color: #0e0e0e; + background-color: #0b0b0b; + font-family: 'Figtree', sans-serif !important; + font-size: 16px; color: #fff; min-height: 100vh; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; +} + +.app-container { + min-height: 100vh; + display: flex; + padding: 0 2em; +} + +.back-to-top { + background: #0b0b0b !important; + border: 1px solid #142216; } \ No newline at end of file diff --git a/src/css/category.css b/src/css/category.css new file mode 100644 index 0000000..2f1d9d3 --- /dev/null +++ b/src/css/category.css @@ -0,0 +1,479 @@ +.category-wrapper { + position: relative; + width: 100%; + max-width: 1440px; + margin: 0 auto; +} + +.main-nav { + background: linear-gradient(to bottom, #0b0b0b, transparent); + width: 100%; + position: fixed; + padding: 0 2em; + height: 85px; + background: #0b0b0b; + left: 0; +} + +.main-nav .nav-items { + position: relative; + height: 85px; + padding: 0; + max-width: 1440px; + margin: 0 auto; +} + +.main-nav .nav-items::before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + width: 100%; + height: 1px; + background: linear-gradient(to right, transparent, #1e3726, transparent); +} + +.main-nav .nav-items::after { + pointer-events: none; + content: ''; + position: fixed; + left: 0; + top: 70px; + z-index: -1; + width: 100%; + height: 50px; + background: linear-gradient(to bottom, #0b0b0b, transparent); +} + +.main-nav .nav-items .logo { + position: relative; +} + +.main-nav .nav-items .logo img { + height: 26px; +} + +.category-name { + color: white; + font-weight: 900; + letter-spacing: -1px; + font-size: 18px; +} + +.category-page { + width: calc(100% - 200px); + position: absolute; + right: 0; + padding: 8em 0 6em 1em; + min-height: 100vh; +} + +.category-page .main-category { + text-transform: uppercase; + opacity: 0.5; + letter-spacing: -0.5px; + font-size: 1rem; + font-weight: 300; + margin: 0; +} + +.category-page .sub-category { + margin-bottom: 0.5em; + line-height: 1em; + font-size: 4.5rem; + color: #fff; + font-weight: 900; +} + +.demo-container { + min-height: 500px; + position: relative; + width: 100%; + background: #0b0b0b; + border: 1px solid #142216; + padding: 1em; + margin-top: 1.4rem; + border-radius: 20px; + display: flex; + align-items: center; + justify-content: center; +} + +div:has(> .props-table) { + border: 1px solid #142216; + border-radius: 20px; +} + +.split-text-demo, +.blur-text-demo { + font-size: 6rem; + font-weight: bolder; +} + +.scrambled-text-demo { + max-width: 600px; + font-size: 1rem; + font-weight: bolder; + color: #27FF64; +} + +.star-border-demo .inner-content { + padding: 1em 3em; + background-color: #0b0b0b !important; + border: 1px solid #142216 !important +} + +.custom-bounceCards { + position: relative; + top: 2em; +} + +.custom-folder { + margin-top: 4em; +} + +.rotating-text-demo-container { + white-space: pre; + font-size: clamp(2rem, 6vw, 6rem); + display: flex; + justify-content: center; + align-items: center; +} + +.rotating-text-demo-container .rotating-text-demo { + display: inline-block; + color: #0b0b0b; + background-color: #27FF64; + padding: 0 0.4em; + border-radius: 15px; + transition: width 0.3s ease; +} + +.ballpit-demo { + position: relative; +} + +.tilted-card-demo-text { + font-family: "Figtree", sans-serif; + font-weight: 900; + text-transform: capitalize; + box-shadow: 0 5px 30px #0b0b0b59; + border-radius: 15px; + color: #fff; + background: rgba(0, 0, 0, 0.4); + padding: 0.5rem 1em; + letter-spacing: -0.5px; + margin: 2em; +} + +.shapeblur-demo { + position: relative; + mix-blend-mode: difference; + z-index: 2; +} + +.decrypted-text { + font-size: 2rem; + display: inline-block; + font-weight: 400; + color: #fff; + cursor: pointer; +} + +.variable-proximity-demo { + max-width: 20ch; + line-height: 100%; + font-size: 4rem !important; + cursor: pointer; + text-align: center; +} + +.shiny-text-demo { + font-weight: 300; +} + +.shiny-button { + cursor: pointer; + border: 1px solid #353535; + background-color: #111; + padding: 0.4em 1.2em; + border-radius: 50px; + transition: 0.3s ease; +} + +.shiny-button:hover { + background-color: #222; +} + +.demo-title { + font-weight: 900; + font-size: 1.6rem; + margin-top: 1rem; + margin-bottom: .4rem; + color: #fff; +} + +.demo-title span { + font-size: 0.8rem; + color: #a1a1aa; + font-weight: 500; +} + +.demo-title::first-letter { + text-transform: uppercase; +} + +.demo-title-contribute { + margin: 0; + font-size: 1.4rem; + font-weight: 900; +} + +.demo-title-contribute { + letter-spacing: -0.5px; + font-weight: 600; + margin-bottom: 1em; + text-align: center; + font-size: 1.65rem; + color: #A7EF9E; +} + +.contribute-buttons { + display: flex; + gap: 0.5rem; + justify-content: center; + align-items: center; + flex-direction: row; +} + +.contribute-button { + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.75rem; + background: #333333; + border-radius: 10px; + border: 1px solid #142216; + color: #fff; + height: 2.5rem; + padding: 0 1rem; + text-decoration: none; + transition: background-color 0.3s ease; +} + +.contribute-button:hover { + background: #142216; +} + +.contribute-separator { + margin: 0 0.5rem; + font-size: 16px; + color: #a1a1aa; +} + +.contribute-container { + background: #0b0b0b; + border: 1px solid #142216; + border-radius: 20px; + padding: 46px; + margin-top: 1.4rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.contribute-button { + background-color: #0b0b0b !important; + border: 1px solid #142216; + transition: 0.5s ease; +} + +.contribute-button span { + color: #a1a1aa; +} + +.contribute-button:hover { + background-color: #142216 !important; +} + +.demo-details { + font-size: 1.6rem; + margin: 0 0 1em; + display: flex; + gap: 0.3em; +} + +.demo-details span { + background-color: #111; + border: 1px solid #142216; + white-space: nowrap; + color: #A7EF9E; + border-radius: 10px; + font-size: 0.8rem; + padding: 0.5em 1em; + transition: 0.3s ease; + user-select: none; +} + +.demo-extra-info { + margin: 1em 0; + display: flex; + align-items: center; + gap: 0.5em; + color: #a1a1aa; +} + +.jsrepo-info a { + text-decoration: underline; +} + +.cli-divider { + position: relative; + margin: 2em auto 2em; + width: 100%; + height: 1px; + background: linear-gradient(to right, transparent, #142216, transparent); +} + +.cli-divider::before { + content: "Or"; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + background-color: #0b0b0b; + padding: 0 1em; + color: #a1a1aa; +} + +.coming-soon a { + color: #27FF64; + text-decoration: underline; +} + +@media only screen and (max-width: 767px) { + .main-nav { + padding: 0 1em; + } + + .category-wrapper { + position: static; + } + + .category-page { + width: 100%; + padding: 6em 1em 0; + } + + .category-page .main-category { + font-size: 1rem; + } + + .category-page .sub-category { + font-size: 3rem; + } + + .split-text-demo, + .blur-text-demo { + font-size: 2rem; + font-weight: bolder; + } + + .decrypted-text { + font-size: 1rem; + } + + .variable-proximity-demo { + font-size: 1.6rem !important; + } + + .contribute-buttons { + flex-direction: column; + gap: 1rem; + } + + .contribute-button { + width: 90%; + } + + .contribute-separator { + display: none; + } + + .demo-title-contribute { + font-size: 1rem; + } +} + +.custom-gradient-class { + padding: 1em 2em; + text-align: center; +} + +.count-up-text { + font-size: 4rem; + font-weight: bold; +} + +.custom-spotlight-card { + user-select: none; + background-color: #333333 !important; + border: 1px solid #142216 !important; + width: 350px; + height: 300px; +} + +/* Contribution Section Responsive Styles */ +.contribute-buttons { + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + flex-wrap: wrap; +} + +.contribute-button { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem 1.5rem; + text-decoration: none; + border-radius: 8px; + transition: all 0.3s ease; + white-space: nowrap; + min-width: 0; + flex: 1; + justify-content: center; +} + +.contribute-button i { + font-size: 1rem; + flex-shrink: 0; +} + +.contribute-button span { + font-weight: 500; +} + +.contribute-separator { + font-weight: 500; + white-space: nowrap; +} + +@media (max-width: 768px) { + .contribute-buttons { + flex-direction: column; + width: 100%; + } + + .contribute-button { + width: 100%; + flex: none; + } + + .contribute-separator { + order: 2; + } +} \ No newline at end of file diff --git a/src/css/landing.css b/src/css/landing.css index f38ea74..374a904 100644 --- a/src/css/landing.css +++ b/src/css/landing.css @@ -11,7 +11,7 @@ left: 0; width: 300px; height: 100vh; - background: linear-gradient(to right, #0e0e0e, transparent); + background: linear-gradient(to right, #0b0b0b, transparent); z-index: 2; pointer-events: none; } @@ -23,7 +23,7 @@ right: 0; width: 300px; height: 100vh; - background: linear-gradient(to left, #0e0e0e, transparent); + background: linear-gradient(to left, #0b0b0b, transparent); z-index: 2; pointer-events: none; } diff --git a/src/css/main.css b/src/css/main.css index 3e7cf8d..b603084 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -1,3 +1,5 @@ @import './base.css'; +@import './sidebar.css'; +@import './category.css'; @import './landing.css'; diff --git a/src/css/sidebar.css b/src/css/sidebar.css new file mode 100644 index 0000000..4523fd9 --- /dev/null +++ b/src/css/sidebar.css @@ -0,0 +1,643 @@ +.sidebar, +.sidebar-mobile { + background-color: #0b0b0b !important; +} + +.sidebar::before { + content: ''; + position: fixed; + bottom: 0; + left: 0; + width: 100%; + height: 200px; + pointer-events: none; + background: linear-gradient(to top, #0b0b0b, transparent); + z-index: 4; + transition: opacity 0.3s ease; +} + +.sidebar.sidebar-no-fade::before { + opacity: 0; +} + +.sidebar { + padding: 4.75rem 0 6em 0 !important; + position: fixed; + top: 57px; + height: 100vh; + width: 0; + padding: 1.25rem; + overflow-y: auto; + display: none; +} + +@media (min-width: 768px) { + .sidebar { + display: block; + width: 200px; + } +} + +.sidebar-content { + position: relative; +} + +.sidebar::-webkit-scrollbar { + width: 10px; +} + +.sidebar::-webkit-scrollbar-track { + display: none; +} + +.sidebar::-webkit-scrollbar-thumb { + background: #0b0b0b; + border-radius: 50px; +} + +.sidebar::-webkit-scrollbar-thumb:hover { + background: #142216; +} + +.sidebar-logo { + padding: 2em calc(1em + 2px) !important; + border-bottom: none; + width: 100%; +} + +.sidebar-logo img { + position: relative; + height: 30px; +} + +.sidebar-item { + position: relative; + font-size: 0.9rem; + color: #a1a1aa; + padding: 0.25em 0; + display: flex; + align-items: center; + transition: color 0.3s ease; + text-decoration: none !important; +} + +.sidebar-item:hover { + color: #fff; +} + +.active-sidebar-item { + width: fit-content; + padding: 0.25em 0.25em 0.25em 0; + color: #fff; + position: relative; + transition: color 0.3s ease; +} + +.active-sidebar-item::before { + content: ''; + position: absolute; + left: -1.15rem; + top: 50%; + transform: translateY(-50%); + width: 2px; + height: 16px; + background-color: #fff; + border-radius: 1px; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.active-sidebar-item:hover { + text-decoration: none; +} + +.sidebar-item .new-tag, +.sidebar-item .updated-tag { + margin-left: 0.6em; + font-size: 10px; + border-radius: 6px; + font-weight: 500; + padding: 0.2em 0.4em; + opacity: 1; + text-decoration: none !important; +} + +.sidebar-item .new-tag { + color: #fff; + border: 1px solid #5227ff; + background-color: rgba(82, 39, 255, 0.3); +} + +.sidebar-item .updated-tag { + color: #fff; + border: 1px solid #ffffff77; + background-color: #ffffff26; +} + +.github-button { + border: 1px solid transparent; + transition: 0.3s ease; +} + +.github-button img { + transition: filter 0.3s ease; +} + +.github-button:hover { + border-color: #ffffff1c; + background-color: #0b0b0b !important; + color: #fff; +} + +.github-button:hover img { + filter: invert(100%); +} + +.cta-button-docs { + font-weight: 500; + font-size: 12px; + padding: 0 0 0 1rem; + height: 40px; + background: linear-gradient(135deg, + rgb(30, 160, 63), + rgba(24, 47, 255, 0.6)); + background-size: 200% 200%; + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + border: 1px solid rgba(255, 255, 255, 0.07); + color: #fff; + border: none; + border-radius: 50px; + cursor: pointer; + + display: flex; + align-items: center; + white-space: nowrap; + justify-content: space-between; + transition: .3s ease; +} + +.cta-button-docs span { + background-color: #0b0b0b; + margin-left: 1em; + margin-right: calc(1em - 6px); + padding-top: .1em; + height: 30px; + border-radius: 50px; + width: 75px; + font-weight: 600; + font-size: 12px; + + display: flex; + align-items: center; + justify-content: center; +} + +.cta-button-docs span img { + margin-right: 4px; + width: 12px; + height: 12px; + transition: .3s ease; +} + +/* Active and Hover Line Indicators */ +.active-line { + position: absolute; + left: 0; + width: 2px; + height: 16px; + background-color: #fff; + border-radius: 1px; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + pointer-events: none; + z-index: 2; +} + +.hover-line { + position: absolute; + left: 0; + width: 2px; + height: 16px; + background-color: #ffffff66; + border-radius: 1px; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + pointer-events: none; + z-index: 1; +} + +/* Categories Structure */ +.categories-list { + display: flex; + flex-direction: column; +} + +.category { + margin-bottom: 1rem; +} + +.category-name { + margin-bottom: 0.5rem; + font-weight: 900; + letter-spacing: -1px; + color: #fff; + font-size: 1rem; +} + +.category-items { + display: flex; + flex-direction: column; + gap: 0.125rem; + padding-left: 1rem; + border-left: 2px solid #ffffff33; + position: relative; +} + +.mobile-logo { + height: 30px; +} + +.mobile-buttons { + display: flex; + gap: 0.5rem; +} + +.icon-button { + border-radius: 10px; + border: 1px solid #ffffff1c; + background: #0b0b0b; + color: #fff; + padding: 0.5rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: 0.3s ease; +} + +.icon-button:hover { + border-color: #ffffff33; + background-color: #0a0a0a; +} + +/* Header Component Styles */ +.main-nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + background-color: #0b0b0b; +} + +.nav-items { + display: flex; + align-items: center; + justify-content: space-between; + height: 80px; + padding: 0 1rem; +} + +.logo img { + height: 26px; +} + +.mobile-menu-button { + display: flex; + align-items: center; + justify-content: center; + padding: 0.5rem; + background: #0b0b0b; + border: 1px solid #ffffff1c; + border-radius: 8px; + color: #fff; + cursor: pointer; + transition: all 0.3s ease; +} + +.mobile-menu-button:hover { + border-color: #ffffff33; + background-color: #0a0a0a; +} + +@media (min-width: 768px) { + .mobile-menu-button { + display: none; + } +} + +.desktop-nav { + display: none; + align-items: center; + gap: 0.5rem; +} + +@media (min-width: 768px) { + .desktop-nav { + display: flex; + } +} + +.search-button { + display: flex; + align-items: center; + gap: 0.25rem; + height: 40px; + padding: 0 0.5rem 0 0.75rem; + border-radius: 50px; + background: #0b0b0b; + border: 1px solid #142216; + font-weight: 600; + cursor: text; + user-select: none; + transition: transform 0.3s ease; + font-size: 12px; +} + +.search-button:hover { + transform: scale(0.98); +} + +.search-icon { + color: #142216; + font-size: 16px; +} + +.search-text { + color: #a6a6a6; + margin-right: 2rem; +} + +.search-kbd { + display: flex; + align-items: center; + gap: 0.25rem; + font-size: 10px; + padding: 0 0.5rem; + border-radius: 50px; + background: #1a1a1a; + color: #a6a6a6; + border: 1px solid #333; +} + +.cta-button-docs { + font-weight: 500; + font-size: 12px; + padding: 0 0 0 1rem; + height: 40px; + background: linear-gradient(135deg, + rgb(30, 160, 63), + rgba(24, 47, 255, 0.6)); + background-size: 200% 200%; + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + border: 1px solid rgba(255, 255, 255, 0.07); + color: #fff; + border-radius: 50px; + cursor: pointer; + display: flex; + align-items: center; + white-space: nowrap; + justify-content: space-between; + transition: 0.3s ease; +} + +.cta-button-docs:hover { + transform: scale(0.98); +} + +.star-count { + background-color: #0b0b0b; + margin-left: 1em; + margin-right: calc(1em - 6px); + padding-top: 0.1em; + height: 30px; + border-radius: 50px; + width: 75px; + font-weight: 600; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; +} + +.star-count img { + margin-right: 4px; + width: 12px; + height: 12px; + transition: 0.3s ease; +} + +/* Mobile Drawer Styles */ +.drawer-overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.5); + z-index: 1500; + display: flex; + justify-content: center; + align-items: flex-start; + padding-top: 0; +} + +.drawer-content { + width: 100%; + height: 100%; + background-color: #0b0b0b; + overflow-y: auto; +} + +.drawer-header { + display: flex; + position: relative; + align-items: center; + justify-content: space-between; + height: 85px; + padding: 0 2rem; + margin-bottom: 1.5rem; +} + +.drawer-header::before { + content: ''; + position: absolute; + right: 0; + bottom: 0; + width: 100%; + height: 1px; + background: linear-gradient(to right, transparent, #1e3726, transparent); +} + +.drawer-logo { + height: 26px; +} + +.close-button { + display: flex; + align-items: center; + justify-content: center; + padding: 0.5rem; + background: #0b0b0b; + border: 1px solid #ffffff1c; + border-radius: 8px; + color: #fff; + cursor: pointer; + font-size: 16px; + transition: all 0.3s ease; +} + +.close-button:hover { + border-color: #ffffff33; + background-color: #0a0a0a; +} + +.drawer-body { + padding: 0 1rem; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.drawer-section { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.section-title { + font-weight: bold; + color: #fff; + margin-bottom: 0.5rem; +} + +.drawer-link { + color: #a1a1aa; + text-decoration: none; + padding: 0.25rem 0; + display: flex; + align-items: center; + gap: 0.25rem; + transition: color 0.3s ease; +} + +.drawer-link:hover { + color: #fff; +} + +.arrow-icon { + transform: rotate(-45deg); + font-size: 14px; +} + +.drawer-separator { + height: 1px; + background-color: #ffffff1c; + margin: 1rem 0; +} + +/* Drawer Navigation Styles */ +.drawer-navigation { + margin-bottom: 2rem; +} + +.drawer-navigation .categories-container { + display: flex; + flex-direction: column; + gap: 1.25rem; +} + +.drawer-navigation .category { + margin-bottom: 1rem; +} + +.drawer-navigation .category-name { + margin-bottom: 0.5rem; + font-weight: 900; + letter-spacing: -1px; + color: #fff; + font-size: 1rem; +} + +.drawer-navigation .category-items { + display: flex; + flex-direction: column; + gap: 0.125rem; + padding-left: 1rem; + border-left: 2px solid #ffffff33; + position: relative; +} + +.drawer-navigation .sidebar-item { + position: relative; + font-size: 0.9rem; + color: #a1a1aa; + padding: 0.25em 0; + display: flex; + align-items: center; + transition: color 0.3s ease; + text-decoration: none !important; +} + +.drawer-navigation .sidebar-item:hover { + color: #fff; +} + +.drawer-navigation .active-sidebar-item { + width: fit-content; + padding: 0.25em 0.25em 0.25em 0; + color: #fff; + position: relative; + transition: color 0.3s ease; +} + +.drawer-navigation .active-sidebar-item::before { + content: ''; + position: absolute; + left: -1.15rem; + top: 50%; + transform: translateY(-50%); + width: 2px; + height: 16px; + background-color: #fff; + border-radius: 1px; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.drawer-navigation .active-sidebar-item:hover { + text-decoration: none; +} + +.drawer-navigation .sidebar-item .new-tag, +.drawer-navigation .sidebar-item .updated-tag { + margin-left: 0.6em; + font-size: 10px; + border-radius: 6px; + font-weight: 500; + padding: 0.2em 0.4em; + opacity: 1; + text-decoration: none !important; +} + +.drawer-navigation .sidebar-item .new-tag { + color: #fff; + border: 1px solid #5227ff; + background-color: rgba(82, 39, 255, 0.3); +} + +.drawer-navigation .sidebar-item .updated-tag { + color: #fff; + border: 1px solid #ffffff77; + background-color: #ffffff26; +} + +@media (min-width: 768px) { + .drawer-overlay { + display: none; + } +} + +@media only screen and (max-width: 767px) { + .drawer-header { + padding: 0 1em; + } +} \ No newline at end of file diff --git a/src/demo/Animations/FadeContentDemo.vue b/src/demo/Animations/FadeContentDemo.vue new file mode 100644 index 0000000..175443f --- /dev/null +++ b/src/demo/Animations/FadeContentDemo.vue @@ -0,0 +1,117 @@ + + + + + \ No newline at end of file diff --git a/src/demo/Backgrounds/DotGridDemo.vue b/src/demo/Backgrounds/DotGridDemo.vue new file mode 100644 index 0000000..f146184 --- /dev/null +++ b/src/demo/Backgrounds/DotGridDemo.vue @@ -0,0 +1,153 @@ + + + + + \ No newline at end of file diff --git a/src/demo/TextAnimations/SplitTextDemo.vue b/src/demo/TextAnimations/SplitTextDemo.vue new file mode 100644 index 0000000..5366320 --- /dev/null +++ b/src/demo/TextAnimations/SplitTextDemo.vue @@ -0,0 +1,88 @@ + + + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 9819c49..713d259 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,32 @@ +/* eslint-disable vue/multi-word-component-names */ +/* eslint-disable vue/no-reserved-component-names */ + import './css/main.css' +import 'primeicons/primeicons.css' import { createApp } from 'vue' import App from './App.vue' import router from './router' +// PrimeVue imports +import PrimeVue from 'primevue/config' +import Aura from '@primeuix/themes/aura' +import Button from 'primevue/button' +import Toast from 'primevue/toast' +import ToastService from 'primevue/toastservice' + const app = createApp(App) app.use(router) +app.use(PrimeVue, { + theme: { + preset: Aura + } +}) +app.use(ToastService) + +// Global components +app.component('Button', Button) +app.component('Toast', Toast) app.mount('#app') diff --git a/src/pages/CategoryPage.vue b/src/pages/CategoryPage.vue index d8fe378..5a6f2bf 100644 --- a/src/pages/CategoryPage.vue +++ b/src/pages/CategoryPage.vue @@ -1,11 +1,69 @@ diff --git a/src/types/code.ts b/src/types/code.ts new file mode 100644 index 0000000..e55aef9 --- /dev/null +++ b/src/types/code.ts @@ -0,0 +1,7 @@ +export interface CodeObject { + cli?: string + utility?: string + code?: string + usage?: string + installation?: string +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 740eca8..8cfd2b7 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -6,11 +6,11 @@ export const getStarsCount = async (repo: string = 'DavidHDev/vue-bits'): Promise => { try { const response = await fetch(`https://api.github.com/repos/${repo}`) - + if (!response.ok) { throw new Error(`GitHub API error: ${response.status}`) } - + const data = await response.json() return data.stargazers_count || 0 } catch (error) { @@ -18,3 +18,17 @@ export const getStarsCount = async (repo: string = 'DavidHDev/vue-bits'): Promis throw error } } + +/** + * Decodes a label from kebab-case to title case + * @param label - The label to decode (e.g., "split-text") + * @returns The decoded label (e.g., "Split Text") + */ +export const decodeLabel = (label: string): string => { + if (!label) return '' + + return label + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' ') +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index d3a4ad4..3131a1b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,6 +5,8 @@ import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import tailwindcss from '@tailwindcss/vite' +import path from 'path' + export default defineConfig({ plugins: [ vue(), @@ -13,7 +15,8 @@ export default defineConfig({ ], resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) + '@': fileURLToPath(new URL('./src', import.meta.url)), + '@content': path.resolve(__dirname, 'src/content'), }, }, })