diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b000854 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +insert_final_newline = true +tab_width = 4 +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index daa3ff6..7581c4a 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -6,74 +6,80 @@ name: Docker # documentation. on: - push: - branches: ["main"] - # Publish semver tags as releases. - tags: ["v*.*.*"] - pull_request: - branches: ["main"] + push: + branches: ["main", "refactor/shadcn"] + # Publish semver tags as releases. + tags: ["v*.*.*"] + pull_request: + branches: ["main"] env: - # Use docker.io for Docker Hub if empty - REGISTRY: ghcr.io - # github.repository as / - IMAGE_NAME: ${{ github.repository }} + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - # This is used to complete the identity challenge - # with sigstore/fulcio when running outside of PRs. - id-token: write + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write - steps: - - name: Checkout repository - uses: actions/checkout@v4 + steps: + - name: Checkout repository + uses: actions/checkout@v4 - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: all + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all - # Set up BuildKit Docker container builder to be able to build - # multi-platform images and export cache - # https://github.com/docker/setup-buildx-action - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 # v3.0.0 + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 # v3.0.0 - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - - name: Log into registry ${{ env.REGISTRY }} - if: github.event_name != 'pull_request' - uses: docker/login-action@v3 # v3.0.0 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 # v5.0.0 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 # v5.0.0 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + type=sha - # Build and push Docker image with Buildx (don't push on PR) - # https://github.com/docker/build-push-action - - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@v5 # v5.0.0 - with: - context: . - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - provenance: mode=max - sbom: true + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v5 # v5.0.0 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + provenance: mode=max + sbom: true diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..b797c17 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["inlang.vs-code-extension"] +} diff --git a/Dockerfile b/Dockerfile index a0666e5..d108d96 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +# Paraglide doesn't properly work with Bun, so it needs Node FROM imbios/bun-node:22-alpine AS base # Install dependencies into temp directory @@ -6,6 +7,7 @@ FROM base AS install RUN mkdir -p /temp/dev COPY package.json bun.lockb /temp/dev/ +COPY project.inlang /temp/dev/project.inlang RUN cd /temp/dev && bun install --frozen-lockfile FROM base AS builder @@ -13,11 +15,13 @@ FROM base AS builder COPY . /app COPY --from=install /temp/dev/node_modules /app/node_modules RUN cd /app && bun run emojis:generate -RUN cd /app && bun run build --preset node-server +RUN cd /app && bun run build -FROM oven/bun:1.1.34-alpine AS final +# Run final web server +FROM ghcr.io/static-web-server/static-web-server:2-alpine AS final -COPY --from=builder /app/.output/ /app +COPY --from=builder /app/.output/public /app/public +COPY sws.toml /etc/config.toml LABEL org.opencontainers.image.authors="Gaspard Wierzbinski (https://cpluspatch.com)" LABEL org.opencontainers.image.source="https://github.com/versia-pub/frontend" @@ -27,4 +31,5 @@ LABEL org.opencontainers.image.title="Versia-FE" LABEL org.opencontainers.image.description="Frontend for the Versia Server Project" WORKDIR /app -CMD ["bun", "run", "server/index.mjs"] \ No newline at end of file +EXPOSE 3000 +CMD ["static-web-server", "--config-file", "/etc/config.toml"] \ No newline at end of file diff --git a/README.md b/README.md index f800c96..96f57ce 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,42 @@ -

- Versia Logo -

+
+ + + + + Versia Logo + + +
-

versia-fe

-**Versia-FE** is a beautiful, fast and responsive front-end for the Versia Server project. +

+ Versia Frontend +

-## Features +
+ TypeScript logo + Vue logo + Nuxt logo + Docker logo + Bun logo + CSS3 logo + HTML5 logo + Linux logo + TailwindCSS logo +
+ + +
+ +
+ + + + Versia-FE screenshot on an iPad Pro + +
+ +# Features - [x] Timelines: public, home, local - [x] Login @@ -22,12 +52,11 @@ - [x] Note editing - [x] Alt text support everywhere - [x] Media uploads -- [x] WCAG 2.2 AAA compliance - - Testing is automated and may not catch all issues, please report any accessibility issues you find. +- [x] WCAG 2.2 AAA testing - [x] Settings - [x] Profile editing -### Browser Support +## Browser Support The following browsers are **supported** (issues will be prioritized): - **Chromium**: `110+` @@ -43,27 +72,27 @@ The following browsers will very likely work, but are not officially supported: Other browsers may work, but are not guaranteed to. -## Performance +# Performance -### JavaScript Bloat +## JavaScript -The **total** JavaScript bundle size is less than `900 kB`, but this is made even smaller by the fact that the bundle is split into multiple files, and only the necessary files are loaded on each page. +The **total** JavaScript bundle size is less than `1000 kB`, but this is made even smaller by the fact that the bundle is split into multiple files, and only the necessary files are loaded on each page. -### Benchmarks +## Benchmarks -Benchmarks are due to be conducted soon™. +Soon™. -## Installation +# Installation Versia-FE is included in the provided `docker-compose` file during [Versia Server installation](https://github.com/versia-pub/server/blob/main/docs/installation.md). To have Versia-FE and Versia Server running on the same domain, edit the Versia Server configuration to point to the Versia-FE container's address (`frontend` category inside config). -### Manual Installation +## Manual Installation Here are the steps to install Versia-FE manually: -#### Docker/Podman +### Docker/Podman ```yaml services: @@ -73,29 +102,52 @@ services: restart: unless-stopped networks: - versia-net - environment: - NUXT_PUBLIC_API_HOST: https://yourserver.com - # For Tor users, set the following environment variable in addition to the above - # NUXT_PUBLIC_ONION_API_HOST: http://youronionserver.onion ``` -Then, the frontend will be available at `http://localhost:3000` inside the container. To link it to a Versia Server, set the `NUXT_PUBLIC_API_HOST` environment variable to the server's URL. +Then, the frontend will be available at `http://localhost:3000` inside the container. -## Development +> [!TIP] +> +> By default, Versia-FE will connect to any Versia Server instance running on the same domain. +> +> You can set the `NUXT_PUBLIC_API_HOST` environment variable to point to a different Versia Server instance. -Make sure to run `bun run emojis:generate` to generate the emoji list before building or running the project. +### Manual -## License +1. Clone the repository. +```bash +git clone https://github.com/versia-pub/frontend.git +``` +2. Install dependencies. +```bash +bun install +``` +3. Build the project. +```bash +bun run build +``` +4. Serve the static files in the `.output/public` directory. +> [!WARNING] +> +> `.output/public/200.html` should be configured as a fallback for all 404 errors. + +# Development + +Run `bun run emojis:generate` to generate the emoji list before building or running the project. + +# License This project is licensed under the AGPL 3.0 - see the [LICENSE](LICENSE) file for details. -## Acknowledgments +All Versia assets (icon, logo, banners, etc) are licensed under [CC-BY-NC-SA-4.0](https://creativecommons.org/licenses/by-nc-sa/4.0). -### Projects +# Acknowledgments + +## Projects - [**Bun**](https://bun.sh): Thanks to the Bun team for creating an amazing JavaScript runtime. - [**Nuxt**](https://nuxt.com): Thanks to the Nuxt team for creating an amazing Vue framework. -### People +## People -- [**April John**](https://github.com/cutestnekoaqua): Creator and maintainer of the Versia Server ActivityPub bridge. \ No newline at end of file +- [**April John**](https://github.com/cutestnekoaqua): Creator and maintainer of the Versia Server ActivityPub bridge. diff --git a/app.vue b/app.vue index 36e1647..0a9972f 100644 --- a/app.vue +++ b/app.vue @@ -1,34 +1,46 @@ \ No newline at end of file diff --git a/app/spa-loading-template.html b/app/spa-loading-template.html new file mode 100644 index 0000000..d2fbff5 --- /dev/null +++ b/app/spa-loading-template.html @@ -0,0 +1,47 @@ +
+
+ + + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/assets/ipad-dark.webp b/assets/ipad-dark.webp new file mode 100644 index 0000000..57a451f Binary files /dev/null and b/assets/ipad-dark.webp differ diff --git a/assets/ipad-light.webp b/assets/ipad-light.webp new file mode 100644 index 0000000..b6fb5ba Binary files /dev/null and b/assets/ipad-light.webp differ diff --git a/biome.json b/biome.json index 2674238..b5b3cec 100644 --- a/biome.json +++ b/biome.json @@ -1,8 +1,7 @@ { "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "organizeImports": { - "enabled": true, - "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + "enabled": true }, "linter": { "enabled": true, @@ -11,6 +10,9 @@ "suspicious": { "noConsole": "off" }, + "performance": { + "noBarrelFile": "off" + }, "correctness": { "noNodejsModules": "off", "noUndeclaredVariables": "off", @@ -65,13 +67,20 @@ "noDuplicateElseIf": "error", "noCommonJs": "error" } - }, - "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + } }, "formatter": { "enabled": true, "indentStyle": "space", - "indentWidth": 4, - "ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"] + "indentWidth": 4 + }, + "files": { + "ignore": [ + "node_modules/**/*", + "dist/**/*", + ".output", + ".nuxt", + "paraglide" + ] } } diff --git a/bun.lockb b/bun.lockb index 1a7a99b..d4152ae 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components.json b/components.json new file mode 100644 index 0000000..2fc290f --- /dev/null +++ b/components.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "default", + "typescript": true, + "tsConfigPath": ".nuxt/tsconfig.json", + "tailwind": { + "config": "tailwind.config.ts", + "css": "styles/index.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "framework": "nuxt", + "aliases": { + "components": "~/components", + "utils": "@/lib/utils" + } +} diff --git a/components/avatars/avatar.vue b/components/avatars/avatar.vue deleted file mode 100644 index e76ef78..0000000 --- a/components/avatars/avatar.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - \ No newline at end of file diff --git a/components/buttons/button-dropdown.vue b/components/buttons/button-dropdown.vue deleted file mode 100644 index 2463143..0000000 --- a/components/buttons/button-dropdown.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/buttons/button-mobile-navbar.vue b/components/buttons/button-mobile-navbar.vue deleted file mode 100644 index 93effdd..0000000 --- a/components/buttons/button-mobile-navbar.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/components/composer/action-buttons.vue b/components/composer/action-buttons.vue deleted file mode 100644 index d02b603..0000000 --- a/components/composer/action-buttons.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - \ No newline at end of file diff --git a/components/composer/autocomplete-suggestbox.vue b/components/composer/autocomplete-suggestbox.vue deleted file mode 100644 index af58f8d..0000000 --- a/components/composer/autocomplete-suggestbox.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - \ No newline at end of file diff --git a/components/composer/button.vue b/components/composer/button.vue deleted file mode 100644 index 5b18a5d..0000000 --- a/components/composer/button.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - \ No newline at end of file diff --git a/components/composer/composer.vue b/components/composer/composer.vue index 5090665..7a4a69a 100644 --- a/components/composer/composer.vue +++ b/components/composer/composer.vue @@ -1,222 +1,299 @@ - - \ No newline at end of file diff --git a/components/inputs/text-input.vue b/components/inputs/text-input.vue deleted file mode 100644 index 4e6ddd7..0000000 --- a/components/inputs/text-input.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - \ No newline at end of file diff --git a/components/modals/composable.ts b/components/modals/composable.ts index d5682fe..ab64f5e 100644 --- a/components/modals/composable.ts +++ b/components/modals/composable.ts @@ -1,25 +1,34 @@ -import { - confirmModalService, - confirmModalWithInputService, -} from "./service.ts"; -import type { ConfirmModalOptions, ConfirmModalResult } from "./types.ts"; +export type ConfirmModalOptions = { + title?: string; + message?: string; + confirmText?: string; + cancelText?: string; + inputType?: "none" | "text" | "textarea"; + defaultValue?: string; +}; -export function useConfirmModal() { - const confirm = ( - options: ConfirmModalOptions, - ): Promise => { - return confirmModalService.confirm(options); - }; +export type ConfirmModalResult = { + confirmed: boolean; + value?: string; +}; - const confirmWithInput = ( - options: ConfirmModalOptions, - placeholder?: string, - ): Promise => { - return confirmModalWithInputService.confirm(options, placeholder); - }; +class ConfirmModalService { + private modalRef = ref<{ + open: (options: ConfirmModalOptions) => Promise; + } | null>(null); - return { - confirm, - confirmWithInput, - }; + register(modal: { + open: (options: ConfirmModalOptions) => Promise; + }) { + this.modalRef.value = modal; + } + + confirm(options: ConfirmModalOptions): Promise { + if (!this.modalRef.value) { + throw new Error("Confirmation modal not initialized"); + } + return this.modalRef.value.open(options); + } } + +export const confirmModalService = new ConfirmModalService(); diff --git a/components/modals/confirm-inline.vue b/components/modals/confirm-inline.vue new file mode 100644 index 0000000..cab014a --- /dev/null +++ b/components/modals/confirm-inline.vue @@ -0,0 +1,70 @@ + + + - - \ No newline at end of file diff --git a/components/settings/types/Enum.vue b/components/settings/types/Enum.vue deleted file mode 100644 index 7126ff4..0000000 --- a/components/settings/types/Enum.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - \ No newline at end of file diff --git a/components/settings/types/Other.vue b/components/settings/types/Other.vue deleted file mode 100644 index db1d560..0000000 --- a/components/settings/types/Other.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - \ No newline at end of file diff --git a/components/settings/types/String.vue b/components/settings/types/String.vue deleted file mode 100644 index 8903653..0000000 --- a/components/settings/types/String.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - \ No newline at end of file diff --git a/components/sidebars/account-picker.vue b/components/sidebars/account-picker.vue deleted file mode 100644 index 2401b09..0000000 --- a/components/sidebars/account-picker.vue +++ /dev/null @@ -1,100 +0,0 @@ - - - \ No newline at end of file diff --git a/components/sidebars/account-switcher.vue b/components/sidebars/account-switcher.vue new file mode 100644 index 0000000..71760af --- /dev/null +++ b/components/sidebars/account-switcher.vue @@ -0,0 +1,167 @@ + + + \ No newline at end of file diff --git a/components/sidebars/collapsible-aside.vue b/components/sidebars/collapsible-aside.vue deleted file mode 100644 index 3e2624f..0000000 --- a/components/sidebars/collapsible-aside.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - \ No newline at end of file diff --git a/components/sidebars/left-sidebar.vue b/components/sidebars/left-sidebar.vue new file mode 100644 index 0000000..433a0cc --- /dev/null +++ b/components/sidebars/left-sidebar.vue @@ -0,0 +1,212 @@ + + + \ No newline at end of file diff --git a/components/sidebars/navigation.vue b/components/sidebars/navigation.vue deleted file mode 100644 index b4abf30..0000000 --- a/components/sidebars/navigation.vue +++ /dev/null @@ -1,223 +0,0 @@ - - - \ No newline at end of file diff --git a/components/sidebars/right-sidebar.vue b/components/sidebars/right-sidebar.vue new file mode 100644 index 0000000..d349998 --- /dev/null +++ b/components/sidebars/right-sidebar.vue @@ -0,0 +1,13 @@ + + + \ No newline at end of file diff --git a/components/sidebars/settings-sidebar.vue b/components/sidebars/settings-sidebar.vue deleted file mode 100644 index 477690c..0000000 --- a/components/sidebars/settings-sidebar.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - \ No newline at end of file diff --git a/components/sidebars/sidebar.vue b/components/sidebars/sidebar.vue new file mode 100644 index 0000000..8dda9fe --- /dev/null +++ b/components/sidebars/sidebar.vue @@ -0,0 +1,55 @@ + + + diff --git a/components/sidebars/theme-switcher.vue b/components/sidebars/theme-switcher.vue new file mode 100644 index 0000000..3840cd4 --- /dev/null +++ b/components/sidebars/theme-switcher.vue @@ -0,0 +1,44 @@ + + + \ No newline at end of file diff --git a/components/skeleton/Skeleton.vue b/components/skeleton/Skeleton.vue deleted file mode 100644 index 026380e..0000000 --- a/components/skeleton/Skeleton.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/instance/Presentation.vue b/components/social-elements/instance/Presentation.vue deleted file mode 100644 index 26d951a..0000000 --- a/components/social-elements/instance/Presentation.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/attachment-dialog.vue b/components/social-elements/notes/attachment-dialog.vue deleted file mode 100644 index 9424608..0000000 --- a/components/social-elements/notes/attachment-dialog.vue +++ /dev/null @@ -1,57 +0,0 @@ -t - - \ No newline at end of file diff --git a/components/social-elements/notes/attachment.vue b/components/social-elements/notes/attachment.vue deleted file mode 100644 index 31fa60a..0000000 --- a/components/social-elements/notes/attachment.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/header.vue b/components/social-elements/notes/header.vue deleted file mode 100644 index 83f3ba1..0000000 --- a/components/social-elements/notes/header.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/interactions/button.vue b/components/social-elements/notes/interactions/button.vue deleted file mode 100644 index 63a6620..0000000 --- a/components/social-elements/notes/interactions/button.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/interactions/row.vue b/components/social-elements/notes/interactions/row.vue deleted file mode 100644 index 94f1603..0000000 --- a/components/social-elements/notes/interactions/row.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/mention.vue b/components/social-elements/notes/mention.vue deleted file mode 100644 index 514bd9f..0000000 --- a/components/social-elements/notes/mention.vue +++ /dev/null @@ -1,16 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/note-content.vue b/components/social-elements/notes/note-content.vue deleted file mode 100644 index f64ef6a..0000000 --- a/components/social-elements/notes/note-content.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/social-elements/notes/note-menu.vue b/components/social-elements/notes/note-menu.vue deleted file mode 100644 index 8bd9c92..0000000 --- a/components/social-elements/notes/note-menu.vue +++ /dev/null @@ -1,156 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/note.vue b/components/social-elements/notes/note.vue deleted file mode 100644 index 99a6314..0000000 --- a/components/social-elements/notes/note.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notes/reply-header.vue b/components/social-elements/notes/reply-header.vue deleted file mode 100644 index 8a3b0ce..0000000 --- a/components/social-elements/notes/reply-header.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/notifications/notif.vue b/components/social-elements/notifications/notif.vue deleted file mode 100644 index f48a37a..0000000 --- a/components/social-elements/notifications/notif.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/users/Account.vue b/components/social-elements/users/Account.vue deleted file mode 100644 index a0452ca..0000000 --- a/components/social-elements/users/Account.vue +++ /dev/null @@ -1,172 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/users/AccountActionsDropdown.vue b/components/social-elements/users/AccountActionsDropdown.vue deleted file mode 100644 index acc486f..0000000 --- a/components/social-elements/users/AccountActionsDropdown.vue +++ /dev/null @@ -1,164 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/users/Badge.vue b/components/social-elements/users/Badge.vue deleted file mode 100644 index b0584f3..0000000 --- a/components/social-elements/users/Badge.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/users/SmallCard.vue b/components/social-elements/users/SmallCard.vue deleted file mode 100644 index 5ee65f6..0000000 --- a/components/social-elements/users/SmallCard.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - \ No newline at end of file diff --git a/components/social-elements/users/UserCard.vue b/components/social-elements/users/UserCard.vue deleted file mode 100644 index 5024ea8..0000000 --- a/components/social-elements/users/UserCard.vue +++ /dev/null @@ -1,125 +0,0 @@ - - - \ No newline at end of file diff --git a/components/timelines/global.vue b/components/timelines/global.vue new file mode 100644 index 0000000..da3f531 --- /dev/null +++ b/components/timelines/global.vue @@ -0,0 +1,34 @@ + + + \ No newline at end of file diff --git a/components/timelines/timeline-item.vue b/components/timelines/timeline-item.vue index 8eb0544..9373171 100644 --- a/components/timelines/timeline-item.vue +++ b/components/timelines/timeline-item.vue @@ -1,13 +1,12 @@ + + diff --git a/components/ui/alert-dialog/AlertDialogAction.vue b/components/ui/alert-dialog/AlertDialogAction.vue new file mode 100644 index 0000000..718fae6 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogAction.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogCancel.vue b/components/ui/alert-dialog/AlertDialogCancel.vue new file mode 100644 index 0000000..d3be9c0 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogCancel.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogContent.vue b/components/ui/alert-dialog/AlertDialogContent.vue new file mode 100644 index 0000000..05d5ce3 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogContent.vue @@ -0,0 +1,44 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogDescription.vue b/components/ui/alert-dialog/AlertDialogDescription.vue new file mode 100644 index 0000000..a438c27 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogDescription.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogFooter.vue b/components/ui/alert-dialog/AlertDialogFooter.vue new file mode 100644 index 0000000..f8d59df --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogFooter.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogHeader.vue b/components/ui/alert-dialog/AlertDialogHeader.vue new file mode 100644 index 0000000..61d4026 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogTitle.vue b/components/ui/alert-dialog/AlertDialogTitle.vue new file mode 100644 index 0000000..2b60008 --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogTitle.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/alert-dialog/AlertDialogTrigger.vue b/components/ui/alert-dialog/AlertDialogTrigger.vue new file mode 100644 index 0000000..93287ee --- /dev/null +++ b/components/ui/alert-dialog/AlertDialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/alert-dialog/index.ts b/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..c48e47b --- /dev/null +++ b/components/ui/alert-dialog/index.ts @@ -0,0 +1,9 @@ +export { default as AlertDialog } from "./AlertDialog.vue"; +export { default as AlertDialogAction } from "./AlertDialogAction.vue"; +export { default as AlertDialogCancel } from "./AlertDialogCancel.vue"; +export { default as AlertDialogContent } from "./AlertDialogContent.vue"; +export { default as AlertDialogDescription } from "./AlertDialogDescription.vue"; +export { default as AlertDialogFooter } from "./AlertDialogFooter.vue"; +export { default as AlertDialogHeader } from "./AlertDialogHeader.vue"; +export { default as AlertDialogTitle } from "./AlertDialogTitle.vue"; +export { default as AlertDialogTrigger } from "./AlertDialogTrigger.vue"; diff --git a/components/ui/alert/Alert.vue b/components/ui/alert/Alert.vue new file mode 100644 index 0000000..2c9ee5a --- /dev/null +++ b/components/ui/alert/Alert.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/alert/AlertDescription.vue b/components/ui/alert/AlertDescription.vue new file mode 100644 index 0000000..963fce1 --- /dev/null +++ b/components/ui/alert/AlertDescription.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/alert/AlertTitle.vue b/components/ui/alert/AlertTitle.vue new file mode 100644 index 0000000..27ee82a --- /dev/null +++ b/components/ui/alert/AlertTitle.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/alert/index.ts b/components/ui/alert/index.ts new file mode 100644 index 0000000..e8b55f0 --- /dev/null +++ b/components/ui/alert/index.ts @@ -0,0 +1,25 @@ +import { type VariantProps, cva } from "class-variance-authority"; + +export { default as Alert } from "./Alert.vue"; +export { default as AlertDescription } from "./AlertDescription.vue"; +export { default as AlertTitle } from "./AlertTitle.vue"; + +export const alertVariants = cva( + "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + warning: + "border-warning/50 text-warning dark:border-warning [&>svg]:text-warning", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export type AlertVariants = VariantProps; diff --git a/components/ui/aspect-ratio/AspectRatio.vue b/components/ui/aspect-ratio/AspectRatio.vue new file mode 100644 index 0000000..f5bc40d --- /dev/null +++ b/components/ui/aspect-ratio/AspectRatio.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/aspect-ratio/index.ts b/components/ui/aspect-ratio/index.ts new file mode 100644 index 0000000..a4976a3 --- /dev/null +++ b/components/ui/aspect-ratio/index.ts @@ -0,0 +1 @@ +export { default as AspectRatio } from "./AspectRatio.vue"; diff --git a/components/ui/avatar/Avatar.vue b/components/ui/avatar/Avatar.vue new file mode 100644 index 0000000..d4af2fd --- /dev/null +++ b/components/ui/avatar/Avatar.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/avatar/AvatarFallback.vue b/components/ui/avatar/AvatarFallback.vue new file mode 100644 index 0000000..a520940 --- /dev/null +++ b/components/ui/avatar/AvatarFallback.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/avatar/AvatarImage.vue b/components/ui/avatar/AvatarImage.vue new file mode 100644 index 0000000..183321f --- /dev/null +++ b/components/ui/avatar/AvatarImage.vue @@ -0,0 +1,9 @@ + + + diff --git a/components/ui/avatar/index.ts b/components/ui/avatar/index.ts new file mode 100644 index 0000000..a36e05a --- /dev/null +++ b/components/ui/avatar/index.ts @@ -0,0 +1,24 @@ +import { type VariantProps, cva } from "class-variance-authority"; + +export { default as Avatar } from "./Avatar.vue"; +export { default as AvatarFallback } from "./AvatarFallback.vue"; +export { default as AvatarImage } from "./AvatarImage.vue"; + +export const avatarVariant = cva( + "inline-flex items-center justify-center font-normal text-foreground select-none shrink-0 bg-secondary overflow-hidden", + { + variants: { + size: { + sm: "h-10 w-10 text-xs", + base: "h-16 w-16 text-2xl", + lg: "h-32 w-32 text-5xl", + }, + shape: { + circle: "rounded-full", + square: "rounded-md", + }, + }, + }, +); + +export type AvatarVariants = VariantProps; diff --git a/components/ui/badge/Badge.vue b/components/ui/badge/Badge.vue new file mode 100644 index 0000000..7ebb774 --- /dev/null +++ b/components/ui/badge/Badge.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/badge/index.ts b/components/ui/badge/index.ts new file mode 100644 index 0000000..9360340 --- /dev/null +++ b/components/ui/badge/index.ts @@ -0,0 +1,25 @@ +import { type VariantProps, cva } from "class-variance-authority"; + +export { default as Badge } from "./Badge.vue"; + +export const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export type BadgeVariants = VariantProps; diff --git a/components/ui/breadcrumb/Breadcrumb.vue b/components/ui/breadcrumb/Breadcrumb.vue new file mode 100644 index 0000000..9271e7a --- /dev/null +++ b/components/ui/breadcrumb/Breadcrumb.vue @@ -0,0 +1,13 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbEllipsis.vue b/components/ui/breadcrumb/BreadcrumbEllipsis.vue new file mode 100644 index 0000000..eb57c2b --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbEllipsis.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbItem.vue b/components/ui/breadcrumb/BreadcrumbItem.vue new file mode 100644 index 0000000..a5e702a --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbItem.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbLink.vue b/components/ui/breadcrumb/BreadcrumbLink.vue new file mode 100644 index 0000000..a244330 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbLink.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbList.vue b/components/ui/breadcrumb/BreadcrumbList.vue new file mode 100644 index 0000000..3a312c2 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbList.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbPage.vue b/components/ui/breadcrumb/BreadcrumbPage.vue new file mode 100644 index 0000000..5e42989 --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbPage.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/breadcrumb/BreadcrumbSeparator.vue b/components/ui/breadcrumb/BreadcrumbSeparator.vue new file mode 100644 index 0000000..0e3f7fa --- /dev/null +++ b/components/ui/breadcrumb/BreadcrumbSeparator.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/breadcrumb/index.ts b/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..e51a7ed --- /dev/null +++ b/components/ui/breadcrumb/index.ts @@ -0,0 +1,7 @@ +export { default as Breadcrumb } from "./Breadcrumb.vue"; +export { default as BreadcrumbEllipsis } from "./BreadcrumbEllipsis.vue"; +export { default as BreadcrumbItem } from "./BreadcrumbItem.vue"; +export { default as BreadcrumbLink } from "./BreadcrumbLink.vue"; +export { default as BreadcrumbList } from "./BreadcrumbList.vue"; +export { default as BreadcrumbPage } from "./BreadcrumbPage.vue"; +export { default as BreadcrumbSeparator } from "./BreadcrumbSeparator.vue"; diff --git a/components/ui/button/Button.vue b/components/ui/button/Button.vue new file mode 100644 index 0000000..3c027e3 --- /dev/null +++ b/components/ui/button/Button.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/button/index.ts b/components/ui/button/index.ts new file mode 100644 index 0000000..5cc151e --- /dev/null +++ b/components/ui/button/index.ts @@ -0,0 +1,34 @@ +import { type VariantProps, cva } from "class-variance-authority"; +export { default as Button } from "./Button.vue"; + +export const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + 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 type ButtonVariants = VariantProps; diff --git a/components/ui/card/Card.vue b/components/ui/card/Card.vue new file mode 100644 index 0000000..0f2a235 --- /dev/null +++ b/components/ui/card/Card.vue @@ -0,0 +1,28 @@ + + + diff --git a/components/ui/card/CardContent.vue b/components/ui/card/CardContent.vue new file mode 100644 index 0000000..b42eeac --- /dev/null +++ b/components/ui/card/CardContent.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardDescription.vue b/components/ui/card/CardDescription.vue new file mode 100644 index 0000000..c4a4257 --- /dev/null +++ b/components/ui/card/CardDescription.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardFooter.vue b/components/ui/card/CardFooter.vue new file mode 100644 index 0000000..eb7b6cb --- /dev/null +++ b/components/ui/card/CardFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/card/CardHeader.vue b/components/ui/card/CardHeader.vue new file mode 100644 index 0000000..8779237 --- /dev/null +++ b/components/ui/card/CardHeader.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/card/CardTitle.vue b/components/ui/card/CardTitle.vue new file mode 100644 index 0000000..662f046 --- /dev/null +++ b/components/ui/card/CardTitle.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/card/index.ts b/components/ui/card/index.ts new file mode 100644 index 0000000..313887b --- /dev/null +++ b/components/ui/card/index.ts @@ -0,0 +1,6 @@ +export { default as Card } from "./Card.vue"; +export { default as CardContent } from "./CardContent.vue"; +export { default as CardDescription } from "./CardDescription.vue"; +export { default as CardFooter } from "./CardFooter.vue"; +export { default as CardHeader } from "./CardHeader.vue"; +export { default as CardTitle } from "./CardTitle.vue"; diff --git a/components/ui/carousel/Carousel.vue b/components/ui/carousel/Carousel.vue new file mode 100644 index 0000000..db9348b --- /dev/null +++ b/components/ui/carousel/Carousel.vue @@ -0,0 +1,65 @@ + + + diff --git a/components/ui/carousel/CarouselContent.vue b/components/ui/carousel/CarouselContent.vue new file mode 100644 index 0000000..d7391ac --- /dev/null +++ b/components/ui/carousel/CarouselContent.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/carousel/CarouselItem.vue b/components/ui/carousel/CarouselItem.vue new file mode 100644 index 0000000..426b71e --- /dev/null +++ b/components/ui/carousel/CarouselItem.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/carousel/CarouselNext.vue b/components/ui/carousel/CarouselNext.vue new file mode 100644 index 0000000..9abbeee --- /dev/null +++ b/components/ui/carousel/CarouselNext.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/carousel/CarouselPrevious.vue b/components/ui/carousel/CarouselPrevious.vue new file mode 100644 index 0000000..53f0b66 --- /dev/null +++ b/components/ui/carousel/CarouselPrevious.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/carousel/index.ts b/components/ui/carousel/index.ts new file mode 100644 index 0000000..3c306c2 --- /dev/null +++ b/components/ui/carousel/index.ts @@ -0,0 +1,8 @@ +export { default as Carousel } from "./Carousel.vue"; +export { default as CarouselContent } from "./CarouselContent.vue"; +export { default as CarouselItem } from "./CarouselItem.vue"; +export { default as CarouselNext } from "./CarouselNext.vue"; +export { default as CarouselPrevious } from "./CarouselPrevious.vue"; +export type { UnwrapRefCarouselApi as CarouselApi } from "./interface"; + +export { useCarousel } from "./useCarousel"; diff --git a/components/ui/carousel/interface.ts b/components/ui/carousel/interface.ts new file mode 100644 index 0000000..6510f6c --- /dev/null +++ b/components/ui/carousel/interface.ts @@ -0,0 +1,25 @@ +import type useEmblaCarousel from "embla-carousel-vue"; +import type { EmblaCarouselVueType } from "embla-carousel-vue"; +import type { HTMLAttributes, UnwrapRef } from "vue"; + +type CarouselApi = EmblaCarouselVueType[1]; +type UseCarouselParameters = Parameters; +type CarouselOptions = UseCarouselParameters[0]; +type CarouselPlugin = UseCarouselParameters[1]; + +export type UnwrapRefCarouselApi = UnwrapRef; + +export interface CarouselProps { + opts?: CarouselOptions; + plugins?: CarouselPlugin; + orientation?: "horizontal" | "vertical"; +} + +export type CarouselEmits = ( + e: "init-api", + payload: UnwrapRefCarouselApi, +) => void; + +export interface WithClassAsProps { + class?: HTMLAttributes["class"]; +} diff --git a/components/ui/carousel/useCarousel.ts b/components/ui/carousel/useCarousel.ts new file mode 100644 index 0000000..cd325e5 --- /dev/null +++ b/components/ui/carousel/useCarousel.ts @@ -0,0 +1,69 @@ +import { createInjectionState } from "@vueuse/core"; +import emblaCarouselVue from "embla-carousel-vue"; +import { onMounted, ref } from "vue"; +import type { + UnwrapRefCarouselApi as CarouselApi, + CarouselEmits, + CarouselProps, +} from "./interface"; + +const [useProvideCarousel, useInjectCarousel] = createInjectionState( + ({ opts, orientation, plugins }: CarouselProps, emits: CarouselEmits) => { + const [emblaNode, emblaApi] = emblaCarouselVue( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins, + ); + + function scrollPrev() { + emblaApi.value?.scrollPrev(); + } + function scrollNext() { + emblaApi.value?.scrollNext(); + } + + const canScrollNext = ref(false); + const canScrollPrev = ref(false); + + function onSelect(api: CarouselApi) { + canScrollNext.value = !!api?.canScrollNext(); + canScrollPrev.value = !!api?.canScrollPrev(); + } + + onMounted(() => { + if (!emblaApi.value) { + return; + } + + emblaApi.value?.on("init", onSelect); + emblaApi.value?.on("reInit", onSelect); + emblaApi.value?.on("select", onSelect); + + emits("init-api", emblaApi.value); + }); + + return { + carouselRef: emblaNode, + carouselApi: emblaApi, + canScrollPrev, + canScrollNext, + scrollPrev, + scrollNext, + orientation, + }; + }, +); + +function useCarousel() { + const carouselState = useInjectCarousel(); + + if (!carouselState) { + throw new Error("useCarousel must be used within a "); + } + + return carouselState; +} + +export { useCarousel, useProvideCarousel }; diff --git a/components/ui/checkbox/Checkbox.vue b/components/ui/checkbox/Checkbox.vue new file mode 100644 index 0000000..0b9ba46 --- /dev/null +++ b/components/ui/checkbox/Checkbox.vue @@ -0,0 +1,39 @@ + + + diff --git a/components/ui/checkbox/index.ts b/components/ui/checkbox/index.ts new file mode 100644 index 0000000..75be342 --- /dev/null +++ b/components/ui/checkbox/index.ts @@ -0,0 +1 @@ +export { default as Checkbox } from "./Checkbox.vue"; diff --git a/components/ui/collapsible/Collapsible.vue b/components/ui/collapsible/Collapsible.vue new file mode 100644 index 0000000..c39dae0 --- /dev/null +++ b/components/ui/collapsible/Collapsible.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/collapsible/CollapsibleContent.vue b/components/ui/collapsible/CollapsibleContent.vue new file mode 100644 index 0000000..42d722d --- /dev/null +++ b/components/ui/collapsible/CollapsibleContent.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/collapsible/CollapsibleTrigger.vue b/components/ui/collapsible/CollapsibleTrigger.vue new file mode 100644 index 0000000..baf5fe9 --- /dev/null +++ b/components/ui/collapsible/CollapsibleTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/collapsible/index.ts b/components/ui/collapsible/index.ts new file mode 100644 index 0000000..289bdbb --- /dev/null +++ b/components/ui/collapsible/index.ts @@ -0,0 +1,3 @@ +export { default as Collapsible } from "./Collapsible.vue"; +export { default as CollapsibleContent } from "./CollapsibleContent.vue"; +export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue"; diff --git a/components/ui/dialog/Dialog.vue b/components/ui/dialog/Dialog.vue new file mode 100644 index 0000000..ce65a77 --- /dev/null +++ b/components/ui/dialog/Dialog.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dialog/DialogClose.vue b/components/ui/dialog/DialogClose.vue new file mode 100644 index 0000000..bc3b70a --- /dev/null +++ b/components/ui/dialog/DialogClose.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/dialog/DialogContent.vue b/components/ui/dialog/DialogContent.vue new file mode 100644 index 0000000..1286073 --- /dev/null +++ b/components/ui/dialog/DialogContent.vue @@ -0,0 +1,56 @@ + + + diff --git a/components/ui/dialog/DialogDescription.vue b/components/ui/dialog/DialogDescription.vue new file mode 100644 index 0000000..f9c6516 --- /dev/null +++ b/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/dialog/DialogFooter.vue b/components/ui/dialog/DialogFooter.vue new file mode 100644 index 0000000..eba856f --- /dev/null +++ b/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dialog/DialogHeader.vue b/components/ui/dialog/DialogHeader.vue new file mode 100644 index 0000000..5a6e6f0 --- /dev/null +++ b/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/dialog/DialogScrollContent.vue b/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 0000000..24699f8 --- /dev/null +++ b/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,61 @@ + + + diff --git a/components/ui/dialog/DialogTitle.vue b/components/ui/dialog/DialogTitle.vue new file mode 100644 index 0000000..7c8d52e --- /dev/null +++ b/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,31 @@ + + + diff --git a/components/ui/dialog/DialogTrigger.vue b/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 0000000..7872f1c --- /dev/null +++ b/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/dialog/index.ts b/components/ui/dialog/index.ts new file mode 100644 index 0000000..e2b3a15 --- /dev/null +++ b/components/ui/dialog/index.ts @@ -0,0 +1,9 @@ +export { default as Dialog } from "./Dialog.vue"; +export { default as DialogClose } from "./DialogClose.vue"; +export { default as DialogContent } from "./DialogContent.vue"; +export { default as DialogDescription } from "./DialogDescription.vue"; +export { default as DialogFooter } from "./DialogFooter.vue"; +export { default as DialogHeader } from "./DialogHeader.vue"; +export { default as DialogScrollContent } from "./DialogScrollContent.vue"; +export { default as DialogTitle } from "./DialogTitle.vue"; +export { default as DialogTrigger } from "./DialogTrigger.vue"; diff --git a/components/ui/drawer/Drawer.vue b/components/ui/drawer/Drawer.vue new file mode 100644 index 0000000..4a85187 --- /dev/null +++ b/components/ui/drawer/Drawer.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/drawer/DrawerContent.vue b/components/ui/drawer/DrawerContent.vue new file mode 100644 index 0000000..bea29b9 --- /dev/null +++ b/components/ui/drawer/DrawerContent.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/drawer/DrawerDescription.vue b/components/ui/drawer/DrawerDescription.vue new file mode 100644 index 0000000..191dedd --- /dev/null +++ b/components/ui/drawer/DrawerDescription.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/drawer/DrawerFooter.vue b/components/ui/drawer/DrawerFooter.vue new file mode 100644 index 0000000..c744209 --- /dev/null +++ b/components/ui/drawer/DrawerFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/drawer/DrawerHeader.vue b/components/ui/drawer/DrawerHeader.vue new file mode 100644 index 0000000..c260400 --- /dev/null +++ b/components/ui/drawer/DrawerHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/drawer/DrawerOverlay.vue b/components/ui/drawer/DrawerOverlay.vue new file mode 100644 index 0000000..3ff11d1 --- /dev/null +++ b/components/ui/drawer/DrawerOverlay.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/drawer/DrawerTitle.vue b/components/ui/drawer/DrawerTitle.vue new file mode 100644 index 0000000..823d158 --- /dev/null +++ b/components/ui/drawer/DrawerTitle.vue @@ -0,0 +1,22 @@ + + + diff --git a/components/ui/drawer/index.ts b/components/ui/drawer/index.ts new file mode 100644 index 0000000..0677d32 --- /dev/null +++ b/components/ui/drawer/index.ts @@ -0,0 +1,8 @@ +export { default as Drawer } from "./Drawer.vue"; +export { default as DrawerContent } from "./DrawerContent.vue"; +export { default as DrawerDescription } from "./DrawerDescription.vue"; +export { default as DrawerFooter } from "./DrawerFooter.vue"; +export { default as DrawerHeader } from "./DrawerHeader.vue"; +export { default as DrawerOverlay } from "./DrawerOverlay.vue"; +export { default as DrawerTitle } from "./DrawerTitle.vue"; +export { DrawerClose, DrawerPortal, DrawerTrigger } from "vaul-vue"; diff --git a/components/ui/dropdown-menu/DropdownMenu.vue b/components/ui/dropdown-menu/DropdownMenu.vue new file mode 100644 index 0000000..031ea14 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenu.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue new file mode 100644 index 0000000..58a7df0 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue @@ -0,0 +1,42 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuContent.vue b/components/ui/dropdown-menu/DropdownMenuContent.vue new file mode 100644 index 0000000..b5a0f8b --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuContent.vue @@ -0,0 +1,40 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuGroup.vue b/components/ui/dropdown-menu/DropdownMenuGroup.vue new file mode 100644 index 0000000..b1af9b7 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuGroup.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuItem.vue b/components/ui/dropdown-menu/DropdownMenuItem.vue new file mode 100644 index 0000000..294ff09 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuItem.vue @@ -0,0 +1,34 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuLabel.vue b/components/ui/dropdown-menu/DropdownMenuLabel.vue new file mode 100644 index 0000000..4aae19f --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuLabel.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue b/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue new file mode 100644 index 0000000..bf765f4 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuRadioItem.vue b/components/ui/dropdown-menu/DropdownMenuRadioItem.vue new file mode 100644 index 0000000..38f2106 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuRadioItem.vue @@ -0,0 +1,43 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSeparator.vue b/components/ui/dropdown-menu/DropdownMenuSeparator.vue new file mode 100644 index 0000000..d34e0cd --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSeparator.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuShortcut.vue b/components/ui/dropdown-menu/DropdownMenuShortcut.vue new file mode 100644 index 0000000..774d4de --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSub.vue b/components/ui/dropdown-menu/DropdownMenuSub.vue new file mode 100644 index 0000000..ab75de7 --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSub.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSubContent.vue b/components/ui/dropdown-menu/DropdownMenuSubContent.vue new file mode 100644 index 0000000..005133c --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSubContent.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue b/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue new file mode 100644 index 0000000..f84be2b --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue @@ -0,0 +1,35 @@ + + + diff --git a/components/ui/dropdown-menu/DropdownMenuTrigger.vue b/components/ui/dropdown-menu/DropdownMenuTrigger.vue new file mode 100644 index 0000000..4eb062c --- /dev/null +++ b/components/ui/dropdown-menu/DropdownMenuTrigger.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/dropdown-menu/index.ts b/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..40938d7 --- /dev/null +++ b/components/ui/dropdown-menu/index.ts @@ -0,0 +1,16 @@ +export { default as DropdownMenu } from "./DropdownMenu.vue"; + +export { default as DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.vue"; +export { default as DropdownMenuContent } from "./DropdownMenuContent.vue"; +export { default as DropdownMenuGroup } from "./DropdownMenuGroup.vue"; +export { default as DropdownMenuItem } from "./DropdownMenuItem.vue"; +export { default as DropdownMenuLabel } from "./DropdownMenuLabel.vue"; +export { default as DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.vue"; +export { default as DropdownMenuRadioItem } from "./DropdownMenuRadioItem.vue"; +export { default as DropdownMenuSeparator } from "./DropdownMenuSeparator.vue"; +export { default as DropdownMenuShortcut } from "./DropdownMenuShortcut.vue"; +export { default as DropdownMenuSub } from "./DropdownMenuSub.vue"; +export { default as DropdownMenuSubContent } from "./DropdownMenuSubContent.vue"; +export { default as DropdownMenuSubTrigger } from "./DropdownMenuSubTrigger.vue"; +export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue"; +export { DropdownMenuPortal } from "radix-vue"; diff --git a/components/ui/form/FormControl.vue b/components/ui/form/FormControl.vue new file mode 100644 index 0000000..39ceec8 --- /dev/null +++ b/components/ui/form/FormControl.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/form/FormDescription.vue b/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..5bf2b09 --- /dev/null +++ b/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/ui/form/FormItem.vue b/components/ui/form/FormItem.vue new file mode 100644 index 0000000..75f7dd5 --- /dev/null +++ b/components/ui/form/FormItem.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/form/FormLabel.vue b/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..4da9c2c --- /dev/null +++ b/components/ui/form/FormLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/form/FormMessage.vue b/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..2377e43 --- /dev/null +++ b/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/form/index.ts b/components/ui/form/index.ts new file mode 100644 index 0000000..ff08c0b --- /dev/null +++ b/components/ui/form/index.ts @@ -0,0 +1,7 @@ +export { default as FormControl } from "./FormControl.vue"; +export { default as FormDescription } from "./FormDescription.vue"; +export { default as FormItem } from "./FormItem.vue"; +export { default as FormLabel } from "./FormLabel.vue"; +export { default as FormMessage } from "./FormMessage.vue"; +export { FORM_ITEM_INJECTION_KEY } from "./injectionKeys"; +export { Field as FormField, Form } from "vee-validate"; diff --git a/components/ui/form/injectionKeys.ts b/components/ui/form/injectionKeys.ts new file mode 100644 index 0000000..bb97756 --- /dev/null +++ b/components/ui/form/injectionKeys.ts @@ -0,0 +1,3 @@ +import type { InjectionKey } from "vue"; + +export const FORM_ITEM_INJECTION_KEY = Symbol() as InjectionKey; diff --git a/components/ui/form/useFormField.ts b/components/ui/form/useFormField.ts new file mode 100644 index 0000000..fe33234 --- /dev/null +++ b/components/ui/form/useFormField.ts @@ -0,0 +1,37 @@ +import { + FieldContextKey, + useFieldError, + useIsFieldDirty, + useIsFieldTouched, + useIsFieldValid, +} from "vee-validate"; +import { inject } from "vue"; +import { FORM_ITEM_INJECTION_KEY } from "./injectionKeys"; + +export function useFormField() { + const fieldContext = inject(FieldContextKey); + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY); + + if (!fieldContext) { + throw new Error("useFormField should be used within "); + } + + const { name } = fieldContext; + const id = fieldItemContext; + + const fieldState = { + valid: useIsFieldValid(name), + isDirty: useIsFieldDirty(name), + isTouched: useIsFieldTouched(name), + error: useFieldError(name), + }; + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + }; +} diff --git a/components/ui/hover-card/HoverCard.vue b/components/ui/hover-card/HoverCard.vue new file mode 100644 index 0000000..cebfe02 --- /dev/null +++ b/components/ui/hover-card/HoverCard.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/hover-card/HoverCardContent.vue b/components/ui/hover-card/HoverCardContent.vue new file mode 100644 index 0000000..141cf82 --- /dev/null +++ b/components/ui/hover-card/HoverCardContent.vue @@ -0,0 +1,41 @@ + + + diff --git a/components/ui/hover-card/HoverCardTrigger.vue b/components/ui/hover-card/HoverCardTrigger.vue new file mode 100644 index 0000000..e7248ae --- /dev/null +++ b/components/ui/hover-card/HoverCardTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/hover-card/index.ts b/components/ui/hover-card/index.ts new file mode 100644 index 0000000..b16bbcf --- /dev/null +++ b/components/ui/hover-card/index.ts @@ -0,0 +1,3 @@ +export { default as HoverCard } from "./HoverCard.vue"; +export { default as HoverCardContent } from "./HoverCardContent.vue"; +export { default as HoverCardTrigger } from "./HoverCardTrigger.vue"; diff --git a/components/ui/input/Input.vue b/components/ui/input/Input.vue new file mode 100644 index 0000000..f60a214 --- /dev/null +++ b/components/ui/input/Input.vue @@ -0,0 +1,23 @@ + + + diff --git a/components/ui/input/index.ts b/components/ui/input/index.ts new file mode 100644 index 0000000..110f046 --- /dev/null +++ b/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from "./Input.vue"; diff --git a/components/ui/label/Label.vue b/components/ui/label/Label.vue new file mode 100644 index 0000000..14d5840 --- /dev/null +++ b/components/ui/label/Label.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/ui/label/index.ts b/components/ui/label/index.ts new file mode 100644 index 0000000..38eaa35 --- /dev/null +++ b/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from "./Label.vue"; diff --git a/components/ui/popover/Popover.vue b/components/ui/popover/Popover.vue new file mode 100644 index 0000000..5a3f344 --- /dev/null +++ b/components/ui/popover/Popover.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/popover/PopoverContent.vue b/components/ui/popover/PopoverContent.vue new file mode 100644 index 0000000..165f002 --- /dev/null +++ b/components/ui/popover/PopoverContent.vue @@ -0,0 +1,48 @@ + + + diff --git a/components/ui/popover/PopoverTrigger.vue b/components/ui/popover/PopoverTrigger.vue new file mode 100644 index 0000000..a824de9 --- /dev/null +++ b/components/ui/popover/PopoverTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/popover/index.ts b/components/ui/popover/index.ts new file mode 100644 index 0000000..b3e258f --- /dev/null +++ b/components/ui/popover/index.ts @@ -0,0 +1,3 @@ +export { default as Popover } from "./Popover.vue"; +export { default as PopoverContent } from "./PopoverContent.vue"; +export { default as PopoverTrigger } from "./PopoverTrigger.vue"; diff --git a/components/ui/select/Select.vue b/components/ui/select/Select.vue new file mode 100644 index 0000000..dd1fc56 --- /dev/null +++ b/components/ui/select/Select.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/select/SelectContent.vue b/components/ui/select/SelectContent.vue new file mode 100644 index 0000000..8c299dc --- /dev/null +++ b/components/ui/select/SelectContent.vue @@ -0,0 +1,53 @@ + + + diff --git a/components/ui/select/SelectGroup.vue b/components/ui/select/SelectGroup.vue new file mode 100644 index 0000000..2ffe8f4 --- /dev/null +++ b/components/ui/select/SelectGroup.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/select/SelectItem.vue b/components/ui/select/SelectItem.vue new file mode 100644 index 0000000..e94456b --- /dev/null +++ b/components/ui/select/SelectItem.vue @@ -0,0 +1,46 @@ + + + diff --git a/components/ui/select/SelectItemText.vue b/components/ui/select/SelectItemText.vue new file mode 100644 index 0000000..e2719b8 --- /dev/null +++ b/components/ui/select/SelectItemText.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/select/SelectLabel.vue b/components/ui/select/SelectLabel.vue new file mode 100644 index 0000000..ab4df03 --- /dev/null +++ b/components/ui/select/SelectLabel.vue @@ -0,0 +1,15 @@ + + + diff --git a/components/ui/select/SelectScrollDownButton.vue b/components/ui/select/SelectScrollDownButton.vue new file mode 100644 index 0000000..79a0903 --- /dev/null +++ b/components/ui/select/SelectScrollDownButton.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/select/SelectScrollUpButton.vue b/components/ui/select/SelectScrollUpButton.vue new file mode 100644 index 0000000..6e10c7d --- /dev/null +++ b/components/ui/select/SelectScrollUpButton.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/select/SelectSeparator.vue b/components/ui/select/SelectSeparator.vue new file mode 100644 index 0000000..81d657d --- /dev/null +++ b/components/ui/select/SelectSeparator.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/select/SelectTrigger.vue b/components/ui/select/SelectTrigger.vue new file mode 100644 index 0000000..bb1f615 --- /dev/null +++ b/components/ui/select/SelectTrigger.vue @@ -0,0 +1,38 @@ + + + diff --git a/components/ui/select/SelectValue.vue b/components/ui/select/SelectValue.vue new file mode 100644 index 0000000..61bd93e --- /dev/null +++ b/components/ui/select/SelectValue.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/select/index.ts b/components/ui/select/index.ts new file mode 100644 index 0000000..d911c4e --- /dev/null +++ b/components/ui/select/index.ts @@ -0,0 +1,11 @@ +export { default as Select } from "./Select.vue"; +export { default as SelectContent } from "./SelectContent.vue"; +export { default as SelectGroup } from "./SelectGroup.vue"; +export { default as SelectItem } from "./SelectItem.vue"; +export { default as SelectItemText } from "./SelectItemText.vue"; +export { default as SelectLabel } from "./SelectLabel.vue"; +export { default as SelectScrollDownButton } from "./SelectScrollDownButton.vue"; +export { default as SelectScrollUpButton } from "./SelectScrollUpButton.vue"; +export { default as SelectSeparator } from "./SelectSeparator.vue"; +export { default as SelectTrigger } from "./SelectTrigger.vue"; +export { default as SelectValue } from "./SelectValue.vue"; diff --git a/components/ui/separator/Separator.vue b/components/ui/separator/Separator.vue new file mode 100644 index 0000000..1c818b8 --- /dev/null +++ b/components/ui/separator/Separator.vue @@ -0,0 +1,35 @@ + + + diff --git a/components/ui/separator/index.ts b/components/ui/separator/index.ts new file mode 100644 index 0000000..aae7f1a --- /dev/null +++ b/components/ui/separator/index.ts @@ -0,0 +1 @@ +export { default as Separator } from "./Separator.vue"; diff --git a/components/ui/sheet/Sheet.vue b/components/ui/sheet/Sheet.vue new file mode 100644 index 0000000..ce65a77 --- /dev/null +++ b/components/ui/sheet/Sheet.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/sheet/SheetClose.vue b/components/ui/sheet/SheetClose.vue new file mode 100644 index 0000000..bc3b70a --- /dev/null +++ b/components/ui/sheet/SheetClose.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/sheet/SheetContent.vue b/components/ui/sheet/SheetContent.vue new file mode 100644 index 0000000..32791bb --- /dev/null +++ b/components/ui/sheet/SheetContent.vue @@ -0,0 +1,56 @@ + + + diff --git a/components/ui/sheet/SheetDescription.vue b/components/ui/sheet/SheetDescription.vue new file mode 100644 index 0000000..c77cdf3 --- /dev/null +++ b/components/ui/sheet/SheetDescription.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/sheet/SheetFooter.vue b/components/ui/sheet/SheetFooter.vue new file mode 100644 index 0000000..a3af5f8 --- /dev/null +++ b/components/ui/sheet/SheetFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/components/ui/sheet/SheetHeader.vue b/components/ui/sheet/SheetHeader.vue new file mode 100644 index 0000000..1e6ef1f --- /dev/null +++ b/components/ui/sheet/SheetHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/ui/sheet/SheetTitle.vue b/components/ui/sheet/SheetTitle.vue new file mode 100644 index 0000000..dc7c865 --- /dev/null +++ b/components/ui/sheet/SheetTitle.vue @@ -0,0 +1,24 @@ + + + diff --git a/components/ui/sheet/SheetTrigger.vue b/components/ui/sheet/SheetTrigger.vue new file mode 100644 index 0000000..7872f1c --- /dev/null +++ b/components/ui/sheet/SheetTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/ui/sheet/index.ts b/components/ui/sheet/index.ts new file mode 100644 index 0000000..dec8c1f --- /dev/null +++ b/components/ui/sheet/index.ts @@ -0,0 +1,29 @@ +import { type VariantProps, cva } from "class-variance-authority"; + +export { default as Sheet } from "./Sheet.vue"; +export { default as SheetClose } from "./SheetClose.vue"; +export { default as SheetContent } from "./SheetContent.vue"; +export { default as SheetDescription } from "./SheetDescription.vue"; +export { default as SheetFooter } from "./SheetFooter.vue"; +export { default as SheetHeader } from "./SheetHeader.vue"; +export { default as SheetTitle } from "./SheetTitle.vue"; +export { default as SheetTrigger } from "./SheetTrigger.vue"; + +export const sheetVariants = cva( + "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + }, +); + +export type SheetVariants = VariantProps; diff --git a/components/ui/sidebar/Sidebar.vue b/components/ui/sidebar/Sidebar.vue new file mode 100644 index 0000000..d5ecc9d --- /dev/null +++ b/components/ui/sidebar/Sidebar.vue @@ -0,0 +1,97 @@ + + + diff --git a/components/ui/sidebar/SidebarContent.vue b/components/ui/sidebar/SidebarContent.vue new file mode 100644 index 0000000..5295678 --- /dev/null +++ b/components/ui/sidebar/SidebarContent.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarFooter.vue b/components/ui/sidebar/SidebarFooter.vue new file mode 100644 index 0000000..232eb58 --- /dev/null +++ b/components/ui/sidebar/SidebarFooter.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarGroup.vue b/components/ui/sidebar/SidebarGroup.vue new file mode 100644 index 0000000..2e72119 --- /dev/null +++ b/components/ui/sidebar/SidebarGroup.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupAction.vue b/components/ui/sidebar/SidebarGroupAction.vue new file mode 100644 index 0000000..01a816f --- /dev/null +++ b/components/ui/sidebar/SidebarGroupAction.vue @@ -0,0 +1,29 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupContent.vue b/components/ui/sidebar/SidebarGroupContent.vue new file mode 100644 index 0000000..07a56a2 --- /dev/null +++ b/components/ui/sidebar/SidebarGroupContent.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarGroupLabel.vue b/components/ui/sidebar/SidebarGroupLabel.vue new file mode 100644 index 0000000..18663f9 --- /dev/null +++ b/components/ui/sidebar/SidebarGroupLabel.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/sidebar/SidebarHeader.vue b/components/ui/sidebar/SidebarHeader.vue new file mode 100644 index 0000000..7f1e0ba --- /dev/null +++ b/components/ui/sidebar/SidebarHeader.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarInput.vue b/components/ui/sidebar/SidebarInput.vue new file mode 100644 index 0000000..a87c75a --- /dev/null +++ b/components/ui/sidebar/SidebarInput.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/sidebar/SidebarInset.vue b/components/ui/sidebar/SidebarInset.vue new file mode 100644 index 0000000..11da692 --- /dev/null +++ b/components/ui/sidebar/SidebarInset.vue @@ -0,0 +1,30 @@ + + + diff --git a/components/ui/sidebar/SidebarMenu.vue b/components/ui/sidebar/SidebarMenu.vue new file mode 100644 index 0000000..f097a80 --- /dev/null +++ b/components/ui/sidebar/SidebarMenu.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuAction.vue b/components/ui/sidebar/SidebarMenuAction.vue new file mode 100644 index 0000000..cd32f75 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuAction.vue @@ -0,0 +1,39 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuBadge.vue b/components/ui/sidebar/SidebarMenuBadge.vue new file mode 100644 index 0000000..10235f6 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuBadge.vue @@ -0,0 +1,25 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuButton.vue b/components/ui/sidebar/SidebarMenuButton.vue new file mode 100644 index 0000000..e2fedcb --- /dev/null +++ b/components/ui/sidebar/SidebarMenuButton.vue @@ -0,0 +1,58 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuButtonChild.vue b/components/ui/sidebar/SidebarMenuButtonChild.vue new file mode 100644 index 0000000..10413d0 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuButtonChild.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuItem.vue b/components/ui/sidebar/SidebarMenuItem.vue new file mode 100644 index 0000000..fc2d2d0 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuItem.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSkeleton.vue b/components/ui/sidebar/SidebarMenuSkeleton.vue new file mode 100644 index 0000000..37f8cf0 --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSkeleton.vue @@ -0,0 +1,33 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSub.vue b/components/ui/sidebar/SidebarMenuSub.vue new file mode 100644 index 0000000..013e6ec --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSub.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSubButton.vue b/components/ui/sidebar/SidebarMenuSubButton.vue new file mode 100644 index 0000000..635cbbc --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSubButton.vue @@ -0,0 +1,40 @@ + + + diff --git a/components/ui/sidebar/SidebarMenuSubItem.vue b/components/ui/sidebar/SidebarMenuSubItem.vue new file mode 100644 index 0000000..b04030b --- /dev/null +++ b/components/ui/sidebar/SidebarMenuSubItem.vue @@ -0,0 +1,9 @@ + + + diff --git a/components/ui/sidebar/SidebarProvider.vue b/components/ui/sidebar/SidebarProvider.vue new file mode 100644 index 0000000..67bec37 --- /dev/null +++ b/components/ui/sidebar/SidebarProvider.vue @@ -0,0 +1,94 @@ + + + diff --git a/components/ui/sidebar/SidebarRail.vue b/components/ui/sidebar/SidebarRail.vue new file mode 100644 index 0000000..617bfc5 --- /dev/null +++ b/components/ui/sidebar/SidebarRail.vue @@ -0,0 +1,32 @@ + + + diff --git a/components/ui/sidebar/SidebarSeparator.vue b/components/ui/sidebar/SidebarSeparator.vue new file mode 100644 index 0000000..c32edc2 --- /dev/null +++ b/components/ui/sidebar/SidebarSeparator.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sidebar/SidebarTrigger.vue b/components/ui/sidebar/SidebarTrigger.vue new file mode 100644 index 0000000..cf93cdf --- /dev/null +++ b/components/ui/sidebar/SidebarTrigger.vue @@ -0,0 +1,26 @@ + + + diff --git a/components/ui/sidebar/index.ts b/components/ui/sidebar/index.ts new file mode 100644 index 0000000..30fa19a --- /dev/null +++ b/components/ui/sidebar/index.ts @@ -0,0 +1,54 @@ +import { type VariantProps, cva } from "class-variance-authority"; + +export { default as Sidebar } from "./Sidebar.vue"; +export { default as SidebarContent } from "./SidebarContent.vue"; +export { default as SidebarFooter } from "./SidebarFooter.vue"; +export { default as SidebarGroup } from "./SidebarGroup.vue"; +export { default as SidebarGroupAction } from "./SidebarGroupAction.vue"; +export { default as SidebarGroupContent } from "./SidebarGroupContent.vue"; +export { default as SidebarGroupLabel } from "./SidebarGroupLabel.vue"; +export { default as SidebarHeader } from "./SidebarHeader.vue"; +export { default as SidebarInput } from "./SidebarInput.vue"; +export { default as SidebarInset } from "./SidebarInset.vue"; +export { default as SidebarMenu } from "./SidebarMenu.vue"; +export { default as SidebarMenuAction } from "./SidebarMenuAction.vue"; +export { default as SidebarMenuBadge } from "./SidebarMenuBadge.vue"; +export { default as SidebarMenuButton } from "./SidebarMenuButton.vue"; +export { default as SidebarMenuItem } from "./SidebarMenuItem.vue"; +export { default as SidebarMenuSkeleton } from "./SidebarMenuSkeleton.vue"; +export { default as SidebarMenuSub } from "./SidebarMenuSub.vue"; +export { default as SidebarMenuSubButton } from "./SidebarMenuSubButton.vue"; +export { default as SidebarMenuSubItem } from "./SidebarMenuSubItem.vue"; +export { default as SidebarProvider } from "./SidebarProvider.vue"; +export { default as SidebarRail } from "./SidebarRail.vue"; +export { default as SidebarSeparator } from "./SidebarSeparator.vue"; +export { default as SidebarTrigger } from "./SidebarTrigger.vue"; + +export { useSidebar } from "./utils"; + +export const sidebarMenuButtonVariants = cva( + "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", + { + variants: { + variant: { + default: + "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", + outline: + "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]", + }, + size: { + default: "h-8 text-sm", + sm: "h-7 text-xs", + lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export type SidebarMenuButtonVariants = VariantProps< + typeof sidebarMenuButtonVariants +>; diff --git a/components/ui/sidebar/utils.ts b/components/ui/sidebar/utils.ts new file mode 100644 index 0000000..7ca0669 --- /dev/null +++ b/components/ui/sidebar/utils.ts @@ -0,0 +1,19 @@ +import { createContext } from "radix-vue"; +import type { ComputedRef, Ref } from "vue"; + +export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; + +export const [useSidebar, provideSidebarContext] = createContext<{ + state: ComputedRef<"expanded" | "collapsed">; + open: Ref; + setOpen: (value: boolean) => void; + isMobile: Ref; + openMobile: Ref; + setOpenMobile: (value: boolean) => void; + toggleSidebar: () => void; +}>("Sidebar"); diff --git a/components/ui/skeleton/Skeleton.vue b/components/ui/skeleton/Skeleton.vue new file mode 100644 index 0000000..a439d32 --- /dev/null +++ b/components/ui/skeleton/Skeleton.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/ui/skeleton/index.ts b/components/ui/skeleton/index.ts new file mode 100644 index 0000000..72cb1d9 --- /dev/null +++ b/components/ui/skeleton/index.ts @@ -0,0 +1 @@ +export { default as Skeleton } from "./Skeleton.vue"; diff --git a/components/ui/sonner/Sonner.vue b/components/ui/sonner/Sonner.vue new file mode 100644 index 0000000..d961d9d --- /dev/null +++ b/components/ui/sonner/Sonner.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/ui/sonner/index.ts b/components/ui/sonner/index.ts new file mode 100644 index 0000000..39a59dd --- /dev/null +++ b/components/ui/sonner/index.ts @@ -0,0 +1 @@ +export { default as Toaster } from "./Sonner.vue"; diff --git a/components/ui/switch/Switch.vue b/components/ui/switch/Switch.vue new file mode 100644 index 0000000..ce5b9af --- /dev/null +++ b/components/ui/switch/Switch.vue @@ -0,0 +1,41 @@ + + + diff --git a/components/ui/switch/index.ts b/components/ui/switch/index.ts new file mode 100644 index 0000000..c986f8a --- /dev/null +++ b/components/ui/switch/index.ts @@ -0,0 +1 @@ +export { default as Switch } from "./Switch.vue"; diff --git a/components/ui/textarea/Textarea.vue b/components/ui/textarea/Textarea.vue new file mode 100644 index 0000000..13a21af --- /dev/null +++ b/components/ui/textarea/Textarea.vue @@ -0,0 +1,23 @@ + + +