diff --git a/.vscode/settings.json b/.vscode/settings.json index 4816602..f3175b6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,6 @@ "typescript", "typescriptreact", "vue" - ] + ], + "css.lint.unknownAtRules": "ignore" } diff --git a/app/assets/css/tailwind.css b/app/assets/css/tailwind.css index f1d8c73..6ed1557 100644 --- a/app/assets/css/tailwind.css +++ b/app/assets/css/tailwind.css @@ -1 +1,127 @@ @import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --font-sans: 'Inter Variable', sans-serif; + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --color-foreground: var(--foreground); + --color-background: var(--background); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --radius-2xl: calc(var(--radius) + 8px); + --radius-3xl: calc(var(--radius) + 12px); + --radius-4xl: calc(var(--radius) + 16px); +} + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.60 0.10 185); + --primary-foreground: oklch(0.98 0.01 181); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.705 0.015 286.067); + --chart-1: oklch(0.85 0.13 181); + --chart-2: oklch(0.78 0.13 182); + --chart-3: oklch(0.70 0.12 183); + --chart-4: oklch(0.60 0.10 185); + --chart-5: oklch(0.51 0.09 186); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.60 0.10 185); + --sidebar-primary-foreground: oklch(0.98 0.01 181); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.705 0.015 286.067); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.70 0.12 183); + --primary-foreground: oklch(0.28 0.04 193); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.552 0.016 285.938); + --chart-1: oklch(0.85 0.13 181); + --chart-2: oklch(0.78 0.13 182); + --chart-3: oklch(0.70 0.12 183); + --chart-4: oklch(0.60 0.10 185); + --chart-5: oklch(0.51 0.09 186); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.78 0.13 182); + --sidebar-primary-foreground: oklch(0.28 0.04 193); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.552 0.016 285.938); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply font-sans bg-background text-foreground; + } + html { + @apply font-sans; + } +} \ No newline at end of file diff --git a/app/assets/scss/layout/_core.scss b/app/assets/scss/layout/_core.scss deleted file mode 100644 index e040f53..0000000 --- a/app/assets/scss/layout/_core.scss +++ /dev/null @@ -1,24 +0,0 @@ -html { - height: 100%; - font-size: 14px; - line-height: 1.2; -} - -body { - font-family: Ubuntu, Arial, Helvetica, sans-serif; - color: var(--text-color); - background-color: var(--surface-ground); - margin: 0; - padding: 0; - min-height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - text-decoration: none; -} - -.layout-wrapper { - min-height: 100vh; -} diff --git a/app/assets/scss/layout/_footer.scss b/app/assets/scss/layout/_footer.scss deleted file mode 100644 index 8f96833..0000000 --- a/app/assets/scss/layout/_footer.scss +++ /dev/null @@ -1,8 +0,0 @@ -.layout-footer { - display: flex; - align-items: center; - justify-content: center; - padding: 1rem 0 1rem 0; - gap: 0.5rem; - border-top: 1px solid var(--surface-border); -} diff --git a/app/assets/scss/layout/_main.scss b/app/assets/scss/layout/_main.scss deleted file mode 100644 index 459bbdd..0000000 --- a/app/assets/scss/layout/_main.scss +++ /dev/null @@ -1,14 +0,0 @@ -.layout-main-container { - display: flex; - flex-direction: column; - min-height: 100vh; - justify-content: space-between; - padding: 6rem 2rem 0 2rem; - background-color: var(--surface-ground); - transition: margin-left var(--layout-section-transition-duration); -} - -.layout-main { - flex: 1 1 auto; - padding-bottom: 2rem; -} diff --git a/app/assets/scss/layout/_menu.scss b/app/assets/scss/layout/_menu.scss deleted file mode 100644 index a4a9642..0000000 --- a/app/assets/scss/layout/_menu.scss +++ /dev/null @@ -1,160 +0,0 @@ -@use "mixins" as *; - -.layout-sidebar { - position: fixed; - width: 20rem; - height: calc(100vh - 8rem); - z-index: 999; - overflow-y: auto; - user-select: none; - top: 6rem; - left: 2rem; - transition: - transform var(--layout-section-transition-duration), - left var(--layout-section-transition-duration); - background-color: var(--surface-overlay); - border-radius: var(--content-border-radius); - padding: 0.5rem 1.5rem; -} - -.layout-menu { - margin: 0; - padding: 0; - list-style-type: none; - - .layout-root-menuitem { - > .layout-menuitem-root-text { - font-size: 0.857rem; - text-transform: uppercase; - font-weight: 700; - color: var(--text-color); - margin: 0.75rem 0; - } - - > a { - display: none; - } - } - - a { - user-select: none; - - &.active-menuitem { - > .layout-submenu-toggler { - transform: rotate(-180deg); - } - } - } - - li.active-menuitem { - > a { - .layout-submenu-toggler { - transform: rotate(-180deg); - } - } - } - - ul { - margin: 0; - padding: 0; - list-style-type: none; - - a { - display: flex; - align-items: center; - position: relative; - outline: 0 none; - color: var(--text-color); - cursor: pointer; - padding: 0.75rem 1rem; - border-radius: var(--content-border-radius); - transition: - background-color var(--element-transition-duration), - box-shadow var(--element-transition-duration); - - .layout-menuitem-icon { - margin-right: 0.5rem; - } - - .layout-submenu-toggler { - font-size: 75%; - margin-left: auto; - transition: transform var(--element-transition-duration); - } - - &.active-route { - font-weight: 700; - color: var(--primary-color); - } - - &:hover { - background-color: var(--surface-hover); - } - - &:focus { - @include focused-inset(); - } - } - - ul { - overflow: hidden; - border-radius: var(--content-border-radius); - - li { - a { - margin-left: 1rem; - } - - li { - a { - margin-left: 2rem; - } - - li { - a { - margin-left: 2.5rem; - } - - li { - a { - margin-left: 3rem; - } - - li { - a { - margin-left: 3.5rem; - } - - li { - a { - margin-left: 4rem; - } - } - } - } - } - } - } - } - } -} - -.layout-submenu-enter-from, -.layout-submenu-leave-to { - max-height: 0; -} - -.layout-submenu-enter-to, -.layout-submenu-leave-from { - max-height: 1000px; -} - -.layout-submenu-leave-active { - overflow: hidden; - transition: max-height 0.45s cubic-bezier(0, 1, 0, 1); -} - -.layout-submenu-enter-active { - overflow: hidden; - transition: max-height 1s ease-in-out; -} diff --git a/app/assets/scss/layout/_mixins.scss b/app/assets/scss/layout/_mixins.scss deleted file mode 100644 index 6256ad9..0000000 --- a/app/assets/scss/layout/_mixins.scss +++ /dev/null @@ -1,15 +0,0 @@ -@mixin focused() { - outline-width: var(--focus-ring-width); - outline-style: var(--focus-ring-style); - outline-color: var(--focus-ring-color); - outline-offset: var(--focus-ring-offset); - box-shadow: var(--focus-ring-shadow); - transition: - box-shadow var(--transition-duration), - outline-color var(--transition-duration); -} - -@mixin focused-inset() { - outline-offset: -1px; - box-shadow: inset var(--focus-ring-shadow); -} diff --git a/app/assets/scss/layout/_preloading.scss b/app/assets/scss/layout/_preloading.scss deleted file mode 100644 index fd3c0d1..0000000 --- a/app/assets/scss/layout/_preloading.scss +++ /dev/null @@ -1,48 +0,0 @@ -.preloader { - position: fixed; - z-index: 999999; - background: #edf1f5; - width: 100%; - height: 100%; -} -.preloader-content { - border: 0 solid transparent; - border-radius: 50%; - width: 150px; - height: 150px; - position: absolute; - top: calc(50vh - 75px); - left: calc(50vw - 75px); -} - -.preloader-content:before, -.preloader-content:after { - content: ""; - border: 1em solid var(--primary-color); - border-radius: 50%; - width: inherit; - height: inherit; - position: absolute; - top: 0; - left: 0; - animation: loader 2s linear infinite; - opacity: 0; -} - -.preloader-content:before { - animation-delay: 0.5s; -} - -@keyframes loader { - 0% { - transform: scale(0); - opacity: 0; - } - 50% { - opacity: 1; - } - 100% { - transform: scale(1); - opacity: 0; - } -} diff --git a/app/assets/scss/layout/_responsive.scss b/app/assets/scss/layout/_responsive.scss deleted file mode 100644 index 6b14bcb..0000000 --- a/app/assets/scss/layout/_responsive.scss +++ /dev/null @@ -1,110 +0,0 @@ -@media screen and (min-width: 1960px) { - .layout-main, - .landing-wrapper { - width: 1504px; - margin-left: auto !important; - margin-right: auto !important; - } -} - -@media (min-width: 992px) { - .layout-wrapper { - &.layout-overlay { - .layout-main-container { - margin-left: 0; - padding-left: 2rem; - } - - .layout-sidebar { - transform: translateX(-100%); - left: 0; - top: 0; - height: 100vh; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-right: 1px solid var(--surface-border); - transition: - transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99), - left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99); - box-shadow: - 0px 3px 5px rgba(0, 0, 0, 0.02), - 0px 0px 2px rgba(0, 0, 0, 0.05), - 0px 1px 4px rgba(0, 0, 0, 0.08); - } - - &.layout-overlay-active { - .layout-sidebar { - transform: translateX(0); - } - } - } - - &.layout-static { - .layout-main-container { - margin-left: 22rem; - } - - &.layout-static-inactive { - .layout-sidebar { - transform: translateX(-100%); - left: 0; - } - - .layout-main-container { - margin-left: 0; - padding-left: 2rem; - } - } - } - - .layout-mask { - display: none; - } - } -} - -@media (max-width: 991px) { - .blocked-scroll { - overflow: hidden; - } - - .layout-wrapper { - .layout-main-container { - margin-left: 0; - padding-left: 2rem; - } - - .layout-sidebar { - transform: translateX(-100%); - left: 0; - top: 0; - height: 100vh; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - transition: - transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99), - left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99); - } - - .layout-mask { - display: none; - position: fixed; - top: 0; - left: 0; - z-index: 998; - width: 100%; - height: 100%; - background-color: var(--maskbg); - } - - &.layout-mobile-active { - .layout-sidebar { - transform: translateX(0); - } - - .layout-mask { - display: block; - } - } - } -} diff --git a/app/assets/scss/layout/_topbar.scss b/app/assets/scss/layout/_topbar.scss deleted file mode 100644 index 06cbe76..0000000 --- a/app/assets/scss/layout/_topbar.scss +++ /dev/null @@ -1,201 +0,0 @@ -@use "mixins" as *; - -.layout-topbar { - position: fixed; - height: 4rem; - z-index: 997; - left: 0; - top: 0; - width: 100%; - padding: 0 2rem; - background-color: var(--surface-card); - transition: left var(--layout-section-transition-duration); - display: flex; - align-items: center; - - .layout-topbar-logo-container { - width: 20rem; - display: flex; - align-items: center; - } - - .layout-topbar-logo { - display: inline-flex; - align-items: center; - font-size: 1.5rem; - border-radius: var(--content-border-radius); - color: var(--text-color); - font-weight: 500; - gap: 0.5rem; - - img { - width: 3rem; - } - - &:focus-visible { - @include focused(); - } - } - - .layout-topbar-action { - display: inline-flex; - justify-content: center; - align-items: center; - border-radius: 50%; - width: 2.5rem; - height: 2.5rem; - color: var(--text-color); - transition: background-color var(--element-transition-duration); - cursor: pointer; - - &:hover { - background-color: var(--surface-hover); - } - - &:focus-visible { - @include focused(); - } - - i { - font-size: 1.25rem; - } - - span { - font-size: 1rem; - display: none; - } - - &.layout-topbar-action-highlight { - background-color: var(--primary-color); - color: var(--primary-contrast-color); - } - } - - .layout-menu-button { - margin-right: 0.5rem; - } - - .layout-topbar-menu-button { - display: none; - } - - .layout-topbar-actions { - margin-left: auto; - display: flex; - gap: 1rem; - } - - .layout-topbar-menu-content { - display: flex; - gap: 1rem; - } - - .layout-config-menu { - display: flex; - gap: 1rem; - } -} - -@media (max-width: 991px) { - .layout-topbar { - padding: 0 2rem; - - .layout-topbar-logo-container { - width: auto; - } - - .layout-menu-button { - margin-left: 0; - margin-right: 0.5rem; - } - - .layout-topbar-menu-button { - display: inline-flex; - } - - .layout-topbar-menu { - position: absolute; - background-color: var(--surface-overlay); - transform-origin: top; - box-shadow: - 0px 3px 5px rgba(0, 0, 0, 0.02), - 0px 0px 2px rgba(0, 0, 0, 0.05), - 0px 1px 4px rgba(0, 0, 0, 0.08); - border-radius: var(--content-border-radius); - padding: 1rem; - right: 2rem; - top: 4rem; - min-width: 15rem; - border: 1px solid var(--surface-border); - - .layout-topbar-menu-content { - gap: 0.5rem; - } - - .layout-topbar-action { - display: flex; - width: 100%; - height: auto; - justify-content: flex-start; - border-radius: var(--content-border-radius); - padding: 0.5rem 1rem; - - i { - font-size: 1rem; - margin-right: 0.5rem; - } - - span { - font-weight: medium; - display: block; - } - } - } - - .layout-topbar-menu-content { - flex-direction: column; - } - } -} - -.config-panel { - .config-panel-label { - font-size: 0.875rem; - color: var(--text-secondary-color); - font-weight: 600; - line-height: 1; - } - - .config-panel-colors { - > div { - padding-top: 0.5rem; - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - justify-content: space-between; - - button { - border: none; - width: 1.25rem; - height: 1.25rem; - border-radius: 50%; - padding: 0; - cursor: pointer; - outline-color: transparent; - outline-width: 2px; - outline-style: solid; - outline-offset: 1px; - - &.active-color { - outline-color: var(--primary-color); - } - } - } - } - - .config-panel-settings { - display: flex; - flex-direction: column; - gap: 0.5rem; - } -} diff --git a/app/assets/scss/layout/_typography.scss b/app/assets/scss/layout/_typography.scss deleted file mode 100644 index be58cec..0000000 --- a/app/assets/scss/layout/_typography.scss +++ /dev/null @@ -1,68 +0,0 @@ -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 1.5rem 0 1rem 0; - font-family: inherit; - font-weight: 700; - line-height: 1.5; - color: var(--text-color); - - &:first-child { - margin-top: 0; - } -} - -h1 { - font-size: 2.5rem; -} - -h2 { - font-size: 2rem; -} - -h3 { - font-size: 1.75rem; -} - -h4 { - font-size: 1.5rem; -} - -h5 { - font-size: 1.25rem; -} - -h6 { - font-size: 1rem; -} - -mark { - background: #fff8e1; - padding: 0.25rem 0.4rem; - border-radius: var(--content-border-radius); - font-family: monospace; -} - -blockquote { - margin: 1rem 0; - padding: 0 2rem; - border-left: 4px solid #90a4ae; -} - -hr { - border-top: solid var(--surface-border); - border-width: 1px 0 0 0; - margin: 1rem 0; -} - -p { - margin: 0 0 1rem 0; - line-height: 1.5; - - &:last-child { - margin-bottom: 0; - } -} diff --git a/app/assets/scss/layout/_utils.scss b/app/assets/scss/layout/_utils.scss deleted file mode 100644 index c5221d3..0000000 --- a/app/assets/scss/layout/_utils.scss +++ /dev/null @@ -1,25 +0,0 @@ -/* Utils */ -.clearfix:after { - content: " "; - display: block; - clear: both; -} - -.card { - background: var(--surface-card); - padding: 2rem; - margin-bottom: 2rem; - border-radius: var(--content-border-radius); - - &:last-child { - margin-bottom: 0; - } -} - -.p-toast { - &.p-toast-top-right, - &.p-toast-top-left, - &.p-toast-top-center { - top: 100px; - } -} diff --git a/app/assets/scss/layout/layout.scss b/app/assets/scss/layout/layout.scss deleted file mode 100644 index faf39c3..0000000 --- a/app/assets/scss/layout/layout.scss +++ /dev/null @@ -1,11 +0,0 @@ -@use "./variables/_common"; -@use "./_mixins"; -@use "./_preloading"; -@use "./_core"; -@use "./_main"; -@use "./_topbar"; -@use "./_menu"; -@use "./_footer"; -@use "./_responsive"; -@use "./_utils"; -@use "./_typography"; diff --git a/app/assets/scss/layout/variables/_common.scss b/app/assets/scss/layout/variables/_common.scss deleted file mode 100644 index 5af2c5c..0000000 --- a/app/assets/scss/layout/variables/_common.scss +++ /dev/null @@ -1,26 +0,0 @@ -:root { - --primary-color: var(--p-primary-color); - --primary-contrast-color: var(--p-primary-contrast-color); - --text-color: var(--p-text-color); - --text-color-secondary: var(--p-text-muted-color); - --surface-ground: var(--p-surface-100); - --surface-border: var(--p-content-border-color); - --surface-card: var(--p-content-background); - --surface-hover: var(--p-content-hover-background); - --surface-overlay: var(--p-overlay-popover-background); - --transition-duration: var(--p-transition-duration); - --maskbg: var(--p-mask-background); - --content-border-radius: var(--p-content-border-radius); - --layout-section-transition-duration: 0.2s; - --element-transition-duration: var(--p-transition-duration); - --focus-ring-width: var(--p-focus-ring-width); - --focus-ring-style: var(--p-focus-ring-style); - --focus-ring-color: var(--p-focus-ring-color); - --focus-ring-offset: var(--p-focus-ring-offset); - --focus-ring-shadow: var(--p-focus-ring-shadow); -} - -:root[class="app-dark"] { - --p-text-color: #ffffff; - --surface-ground: var(--p-surface-950); -} diff --git a/app/assets/scss/styles.scss b/app/assets/scss/styles.scss index b434e58..ba8c14d 100644 --- a/app/assets/scss/styles.scss +++ b/app/assets/scss/styles.scss @@ -1,3 +1 @@ -@use "primeicons/primeicons.css"; -@use "~/assets/css/tailwind.css"; -@use "~/assets/scss/layout/layout.scss"; +// Nothing here. For now. diff --git a/app/components/ui/avatar/Avatar.vue b/app/components/ui/avatar/Avatar.vue new file mode 100644 index 0000000..9fb53e3 --- /dev/null +++ b/app/components/ui/avatar/Avatar.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/avatar/AvatarFallback.vue b/app/components/ui/avatar/AvatarFallback.vue new file mode 100644 index 0000000..1642b89 --- /dev/null +++ b/app/components/ui/avatar/AvatarFallback.vue @@ -0,0 +1,21 @@ + + + diff --git a/app/components/ui/avatar/AvatarImage.vue b/app/components/ui/avatar/AvatarImage.vue new file mode 100644 index 0000000..5df7505 --- /dev/null +++ b/app/components/ui/avatar/AvatarImage.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/avatar/index.ts b/app/components/ui/avatar/index.ts new file mode 100644 index 0000000..036eee9 --- /dev/null +++ b/app/components/ui/avatar/index.ts @@ -0,0 +1,3 @@ +export { default as Avatar } from "./Avatar.vue"; +export { default as AvatarFallback } from "./AvatarFallback.vue"; +export { default as AvatarImage } from "./AvatarImage.vue"; diff --git a/app/components/ui/breadcrumb/Breadcrumb.vue b/app/components/ui/breadcrumb/Breadcrumb.vue new file mode 100644 index 0000000..bbcb100 --- /dev/null +++ b/app/components/ui/breadcrumb/Breadcrumb.vue @@ -0,0 +1,13 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue b/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue new file mode 100644 index 0000000..f53b4df --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbItem.vue b/app/components/ui/breadcrumb/BreadcrumbItem.vue new file mode 100644 index 0000000..63b3d42 --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbItem.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbLink.vue b/app/components/ui/breadcrumb/BreadcrumbLink.vue new file mode 100644 index 0000000..e825394 --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbLink.vue @@ -0,0 +1,21 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbList.vue b/app/components/ui/breadcrumb/BreadcrumbList.vue new file mode 100644 index 0000000..2c47d75 --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbList.vue @@ -0,0 +1,17 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbPage.vue b/app/components/ui/breadcrumb/BreadcrumbPage.vue new file mode 100644 index 0000000..833a514 --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbPage.vue @@ -0,0 +1,20 @@ + + + diff --git a/app/components/ui/breadcrumb/BreadcrumbSeparator.vue b/app/components/ui/breadcrumb/BreadcrumbSeparator.vue new file mode 100644 index 0000000..c3e132f --- /dev/null +++ b/app/components/ui/breadcrumb/BreadcrumbSeparator.vue @@ -0,0 +1,17 @@ + + + diff --git a/app/components/ui/breadcrumb/index.ts b/app/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..e51a7ed --- /dev/null +++ b/app/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/app/components/ui/button/Button.vue b/app/components/ui/button/Button.vue new file mode 100644 index 0000000..bd3754e --- /dev/null +++ b/app/components/ui/button/Button.vue @@ -0,0 +1,24 @@ + + + diff --git a/app/components/ui/button/index.ts b/app/components/ui/button/index.ts new file mode 100644 index 0000000..b2e66e0 --- /dev/null +++ b/app/components/ui/button/index.ts @@ -0,0 +1,35 @@ +import type { VariantProps } from "class-variance-authority"; +import { 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 transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); +export type ButtonVariants = VariantProps; diff --git a/app/components/ui/collapsible/Collapsible.vue b/app/components/ui/collapsible/Collapsible.vue new file mode 100644 index 0000000..cf82a6c --- /dev/null +++ b/app/components/ui/collapsible/Collapsible.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/collapsible/CollapsibleContent.vue b/app/components/ui/collapsible/CollapsibleContent.vue new file mode 100644 index 0000000..49a402f --- /dev/null +++ b/app/components/ui/collapsible/CollapsibleContent.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/collapsible/CollapsibleTrigger.vue b/app/components/ui/collapsible/CollapsibleTrigger.vue new file mode 100644 index 0000000..b071d07 --- /dev/null +++ b/app/components/ui/collapsible/CollapsibleTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/collapsible/index.ts b/app/components/ui/collapsible/index.ts new file mode 100644 index 0000000..289bdbb --- /dev/null +++ b/app/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/app/components/ui/dropdown-menu/DropdownMenu.vue b/app/components/ui/dropdown-menu/DropdownMenu.vue new file mode 100644 index 0000000..3d5e334 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenu.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue b/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue new file mode 100644 index 0000000..ba9fc8c --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue @@ -0,0 +1,37 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuContent.vue b/app/components/ui/dropdown-menu/DropdownMenuContent.vue new file mode 100644 index 0000000..43d4847 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuContent.vue @@ -0,0 +1,37 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuGroup.vue b/app/components/ui/dropdown-menu/DropdownMenuGroup.vue new file mode 100644 index 0000000..d22b024 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuGroup.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuItem.vue b/app/components/ui/dropdown-menu/DropdownMenuItem.vue new file mode 100644 index 0000000..457c4a8 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuItem.vue @@ -0,0 +1,41 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuLabel.vue b/app/components/ui/dropdown-menu/DropdownMenuLabel.vue new file mode 100644 index 0000000..a69a7cc --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue b/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue new file mode 100644 index 0000000..32313a3 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue b/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue new file mode 100644 index 0000000..0aa597b --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue @@ -0,0 +1,38 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue b/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue new file mode 100644 index 0000000..6f3568a --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue b/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue new file mode 100644 index 0000000..3bcb2c9 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuSub.vue b/app/components/ui/dropdown-menu/DropdownMenuSub.vue new file mode 100644 index 0000000..22624e8 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuSub.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue b/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue new file mode 100644 index 0000000..bc3cf82 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue b/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue new file mode 100644 index 0000000..b878bcc --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue b/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue new file mode 100644 index 0000000..d52d0b4 --- /dev/null +++ b/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/dropdown-menu/index.ts b/app/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..9e57848 --- /dev/null +++ b/app/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 "reka-ui"; diff --git a/app/components/ui/input/Input.vue b/app/components/ui/input/Input.vue new file mode 100644 index 0000000..68f51b2 --- /dev/null +++ b/app/components/ui/input/Input.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/components/ui/input/index.ts b/app/components/ui/input/index.ts new file mode 100644 index 0000000..110f046 --- /dev/null +++ b/app/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from "./Input.vue"; diff --git a/app/components/ui/separator/Separator.vue b/app/components/ui/separator/Separator.vue new file mode 100644 index 0000000..9983e49 --- /dev/null +++ b/app/components/ui/separator/Separator.vue @@ -0,0 +1,27 @@ + + + diff --git a/app/components/ui/separator/index.ts b/app/components/ui/separator/index.ts new file mode 100644 index 0000000..aae7f1a --- /dev/null +++ b/app/components/ui/separator/index.ts @@ -0,0 +1 @@ +export { default as Separator } from "./Separator.vue"; diff --git a/app/components/ui/sheet/Sheet.vue b/app/components/ui/sheet/Sheet.vue new file mode 100644 index 0000000..ecdbffe --- /dev/null +++ b/app/components/ui/sheet/Sheet.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/sheet/SheetClose.vue b/app/components/ui/sheet/SheetClose.vue new file mode 100644 index 0000000..cc15741 --- /dev/null +++ b/app/components/ui/sheet/SheetClose.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/sheet/SheetContent.vue b/app/components/ui/sheet/SheetContent.vue new file mode 100644 index 0000000..e428f9b --- /dev/null +++ b/app/components/ui/sheet/SheetContent.vue @@ -0,0 +1,60 @@ + + + diff --git a/app/components/ui/sheet/SheetDescription.vue b/app/components/ui/sheet/SheetDescription.vue new file mode 100644 index 0000000..9a8eb2f --- /dev/null +++ b/app/components/ui/sheet/SheetDescription.vue @@ -0,0 +1,21 @@ + + + diff --git a/app/components/ui/sheet/SheetFooter.vue b/app/components/ui/sheet/SheetFooter.vue new file mode 100644 index 0000000..5c88d03 --- /dev/null +++ b/app/components/ui/sheet/SheetFooter.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/sheet/SheetHeader.vue b/app/components/ui/sheet/SheetHeader.vue new file mode 100644 index 0000000..6614d6a --- /dev/null +++ b/app/components/ui/sheet/SheetHeader.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/sheet/SheetOverlay.vue b/app/components/ui/sheet/SheetOverlay.vue new file mode 100644 index 0000000..4817197 --- /dev/null +++ b/app/components/ui/sheet/SheetOverlay.vue @@ -0,0 +1,26 @@ + + + diff --git a/app/components/ui/sheet/SheetTitle.vue b/app/components/ui/sheet/SheetTitle.vue new file mode 100644 index 0000000..d2a3344 --- /dev/null +++ b/app/components/ui/sheet/SheetTitle.vue @@ -0,0 +1,17 @@ + + + diff --git a/app/components/ui/sheet/SheetTrigger.vue b/app/components/ui/sheet/SheetTrigger.vue new file mode 100644 index 0000000..a57258e --- /dev/null +++ b/app/components/ui/sheet/SheetTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/sheet/index.ts b/app/components/ui/sheet/index.ts new file mode 100644 index 0000000..b94a071 --- /dev/null +++ b/app/components/ui/sheet/index.ts @@ -0,0 +1,8 @@ +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"; diff --git a/app/components/ui/sidebar/Sidebar.vue b/app/components/ui/sidebar/Sidebar.vue new file mode 100644 index 0000000..46ab1b7 --- /dev/null +++ b/app/components/ui/sidebar/Sidebar.vue @@ -0,0 +1,100 @@ + + + diff --git a/app/components/ui/sidebar/SidebarContent.vue b/app/components/ui/sidebar/SidebarContent.vue new file mode 100644 index 0000000..bbd5679 --- /dev/null +++ b/app/components/ui/sidebar/SidebarContent.vue @@ -0,0 +1,18 @@ + + + diff --git a/app/components/ui/sidebar/SidebarFooter.vue b/app/components/ui/sidebar/SidebarFooter.vue new file mode 100644 index 0000000..b3ea649 --- /dev/null +++ b/app/components/ui/sidebar/SidebarFooter.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarGroup.vue b/app/components/ui/sidebar/SidebarGroup.vue new file mode 100644 index 0000000..4934501 --- /dev/null +++ b/app/components/ui/sidebar/SidebarGroup.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarGroupAction.vue b/app/components/ui/sidebar/SidebarGroupAction.vue new file mode 100644 index 0000000..c1e4825 --- /dev/null +++ b/app/components/ui/sidebar/SidebarGroupAction.vue @@ -0,0 +1,31 @@ + + + diff --git a/app/components/ui/sidebar/SidebarGroupContent.vue b/app/components/ui/sidebar/SidebarGroupContent.vue new file mode 100644 index 0000000..a4ac1eb --- /dev/null +++ b/app/components/ui/sidebar/SidebarGroupContent.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarGroupLabel.vue b/app/components/ui/sidebar/SidebarGroupLabel.vue new file mode 100644 index 0000000..2c0939b --- /dev/null +++ b/app/components/ui/sidebar/SidebarGroupLabel.vue @@ -0,0 +1,30 @@ + + + diff --git a/app/components/ui/sidebar/SidebarHeader.vue b/app/components/ui/sidebar/SidebarHeader.vue new file mode 100644 index 0000000..afb6314 --- /dev/null +++ b/app/components/ui/sidebar/SidebarHeader.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarInput.vue b/app/components/ui/sidebar/SidebarInput.vue new file mode 100644 index 0000000..c494bcf --- /dev/null +++ b/app/components/ui/sidebar/SidebarInput.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/sidebar/SidebarInset.vue b/app/components/ui/sidebar/SidebarInset.vue new file mode 100644 index 0000000..48df112 --- /dev/null +++ b/app/components/ui/sidebar/SidebarInset.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenu.vue b/app/components/ui/sidebar/SidebarMenu.vue new file mode 100644 index 0000000..128ba8c --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenu.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuAction.vue b/app/components/ui/sidebar/SidebarMenuAction.vue new file mode 100644 index 0000000..6505579 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuAction.vue @@ -0,0 +1,42 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuBadge.vue b/app/components/ui/sidebar/SidebarMenuBadge.vue new file mode 100644 index 0000000..688ff90 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuBadge.vue @@ -0,0 +1,28 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuButton.vue b/app/components/ui/sidebar/SidebarMenuButton.vue new file mode 100644 index 0000000..7f89b24 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuButton.vue @@ -0,0 +1,49 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuButtonChild.vue b/app/components/ui/sidebar/SidebarMenuButtonChild.vue new file mode 100644 index 0000000..1f1d77f --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuButtonChild.vue @@ -0,0 +1,36 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuItem.vue b/app/components/ui/sidebar/SidebarMenuItem.vue new file mode 100644 index 0000000..77dc213 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuItem.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuSkeleton.vue b/app/components/ui/sidebar/SidebarMenuSkeleton.vue new file mode 100644 index 0000000..4075fd3 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuSkeleton.vue @@ -0,0 +1,31 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuSub.vue b/app/components/ui/sidebar/SidebarMenuSub.vue new file mode 100644 index 0000000..d8d450e --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuSub.vue @@ -0,0 +1,24 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuSubButton.vue b/app/components/ui/sidebar/SidebarMenuSubButton.vue new file mode 100644 index 0000000..48c689f --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuSubButton.vue @@ -0,0 +1,43 @@ + + + diff --git a/app/components/ui/sidebar/SidebarMenuSubItem.vue b/app/components/ui/sidebar/SidebarMenuSubItem.vue new file mode 100644 index 0000000..559dc60 --- /dev/null +++ b/app/components/ui/sidebar/SidebarMenuSubItem.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/sidebar/SidebarProvider.vue b/app/components/ui/sidebar/SidebarProvider.vue new file mode 100644 index 0000000..9a57a1b --- /dev/null +++ b/app/components/ui/sidebar/SidebarProvider.vue @@ -0,0 +1,92 @@ + + + diff --git a/app/components/ui/sidebar/SidebarRail.vue b/app/components/ui/sidebar/SidebarRail.vue new file mode 100644 index 0000000..5c71ca2 --- /dev/null +++ b/app/components/ui/sidebar/SidebarRail.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/components/ui/sidebar/SidebarSeparator.vue b/app/components/ui/sidebar/SidebarSeparator.vue new file mode 100644 index 0000000..03a5f34 --- /dev/null +++ b/app/components/ui/sidebar/SidebarSeparator.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/sidebar/SidebarTrigger.vue b/app/components/ui/sidebar/SidebarTrigger.vue new file mode 100644 index 0000000..c706d97 --- /dev/null +++ b/app/components/ui/sidebar/SidebarTrigger.vue @@ -0,0 +1,27 @@ + + + diff --git a/app/components/ui/sidebar/index.ts b/app/components/ui/sidebar/index.ts new file mode 100644 index 0000000..62db485 --- /dev/null +++ b/app/components/ui/sidebar/index.ts @@ -0,0 +1,60 @@ +import type { VariantProps } from "class-variance-authority"; +import type { HTMLAttributes } from "vue"; +import { cva } from "class-variance-authority"; + +export interface SidebarProps { + side?: "left" | "right"; + variant?: "sidebar" | "floating" | "inset"; + collapsible?: "offcanvas" | "icon" | "none"; + class?: HTMLAttributes["class"]; +} + +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-hidden 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; diff --git a/app/components/ui/sidebar/utils.ts b/app/components/ui/sidebar/utils.ts new file mode 100644 index 0000000..4c08290 --- /dev/null +++ b/app/components/ui/sidebar/utils.ts @@ -0,0 +1,19 @@ +import type { ComputedRef, Ref } from "vue"; +import { createContext } from "reka-ui"; + +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/app/components/ui/skeleton/Skeleton.vue b/app/components/ui/skeleton/Skeleton.vue new file mode 100644 index 0000000..15eadfc --- /dev/null +++ b/app/components/ui/skeleton/Skeleton.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/skeleton/index.ts b/app/components/ui/skeleton/index.ts new file mode 100644 index 0000000..72cb1d9 --- /dev/null +++ b/app/components/ui/skeleton/index.ts @@ -0,0 +1 @@ +export { default as Skeleton } from "./Skeleton.vue"; diff --git a/app/components/ui/tooltip/Tooltip.vue b/app/components/ui/tooltip/Tooltip.vue new file mode 100644 index 0000000..4efee8c --- /dev/null +++ b/app/components/ui/tooltip/Tooltip.vue @@ -0,0 +1,15 @@ + + + diff --git a/app/components/ui/tooltip/TooltipContent.vue b/app/components/ui/tooltip/TooltipContent.vue new file mode 100644 index 0000000..b3feaed --- /dev/null +++ b/app/components/ui/tooltip/TooltipContent.vue @@ -0,0 +1,41 @@ + + + diff --git a/app/components/ui/tooltip/TooltipProvider.vue b/app/components/ui/tooltip/TooltipProvider.vue new file mode 100644 index 0000000..7eb50dd --- /dev/null +++ b/app/components/ui/tooltip/TooltipProvider.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/components/ui/tooltip/TooltipTrigger.vue b/app/components/ui/tooltip/TooltipTrigger.vue new file mode 100644 index 0000000..e624a66 --- /dev/null +++ b/app/components/ui/tooltip/TooltipTrigger.vue @@ -0,0 +1,12 @@ + + + diff --git a/app/components/ui/tooltip/index.ts b/app/components/ui/tooltip/index.ts new file mode 100644 index 0000000..0a8a878 --- /dev/null +++ b/app/components/ui/tooltip/index.ts @@ -0,0 +1,4 @@ +export { default as Tooltip } from "./Tooltip.vue"; +export { default as TooltipContent } from "./TooltipContent.vue"; +export { default as TooltipProvider } from "./TooltipProvider.vue"; +export { default as TooltipTrigger } from "./TooltipTrigger.vue"; diff --git a/app/layouts/Default.vue b/app/layouts/Default.vue index 26b8245..a22ffae 100644 --- a/app/layouts/Default.vue +++ b/app/layouts/Default.vue @@ -1,21 +1,48 @@ - - + + diff --git a/app/layouts/default/Footer.vue b/app/layouts/default/Footer.vue deleted file mode 100644 index d480532..0000000 --- a/app/layouts/default/Footer.vue +++ /dev/null @@ -1,10 +0,0 @@ - - diff --git a/app/layouts/default/Sidebar.vue b/app/layouts/default/Sidebar.vue index 7f17150..98beae4 100644 --- a/app/layouts/default/Sidebar.vue +++ b/app/layouts/default/Sidebar.vue @@ -1,35 +1,245 @@ -