@plutocms/pluto 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +12 -0
- package/.github/dependabot.yml +11 -0
- package/.github/workflows/publish.yml +32 -0
- package/.prettierrc +10 -0
- package/.vscode/extensions.json +14 -0
- package/.vscode/settings.json +72 -0
- package/.vscode/vue.code-snippets +16 -0
- package/README.md +114 -0
- package/app/app.config.ts +41 -0
- package/app/app.vue +13 -0
- package/app/assets/css/tailwind.css +12 -0
- package/app/components/AdminView.vue +7 -0
- package/app/components/ColorModeButton.vue +28 -0
- package/app/components/Container.vue +20 -0
- package/app/components/Pluto/Navbar/PlutoNavbarAdmin.vue +9 -0
- package/app/components/Pluto/Navbar/PlutoNavbarAdminActions.vue +7 -0
- package/app/components/Pluto/PlutoRoot.vue +27 -0
- package/app/components/ScrollArea.vue +86 -0
- package/app/components/modal/Modal.vue +161 -0
- package/app/components/modal/ModalContent.vue +27 -0
- package/app/components/modal/ModalFooter.vue +59 -0
- package/app/components/modal/ModalHeader.vue +64 -0
- package/app/composables/object-url.ts +9 -0
- package/app/layouts/admin.vue +45 -0
- package/app/layouts/auth.vue +7 -0
- package/app/pages/admin/home.vue +21 -0
- package/app/pages/index.vue +9 -0
- package/app/plugins/autofocus.ts +5 -0
- package/bun.lock +2656 -0
- package/eslint.config.mjs +84 -0
- package/layers/sql/.env.example +5 -0
- package/layers/sql/nuxt.config.ts +26 -0
- package/nuxt.config.ts +91 -0
- package/package.json +65 -0
- package/public/img/pluto.png +0 -0
- package/tsconfig.json +9 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: bun # See documentation for possible values
|
|
9
|
+
directory: / # Location of package manifests
|
|
10
|
+
schedule:
|
|
11
|
+
interval: weekly
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
name: Publish Package
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v3
|
|
16
|
+
|
|
17
|
+
- name: Setup Bun
|
|
18
|
+
uses: oven-sh/setup-bun@v1
|
|
19
|
+
with:
|
|
20
|
+
bun-version: 'latest'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: bun install
|
|
24
|
+
|
|
25
|
+
- name: Run build
|
|
26
|
+
run: bun run build
|
|
27
|
+
|
|
28
|
+
- name: Configure NPM auth
|
|
29
|
+
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
|
|
30
|
+
|
|
31
|
+
- name: Publish to NPM
|
|
32
|
+
run: bun publish --access public
|
package/.prettierrc
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommendations": [
|
|
3
|
+
"Vue.volar",
|
|
4
|
+
"EditorConfig.EditorConfig",
|
|
5
|
+
"esbenp.prettier-vscode",
|
|
6
|
+
"dbaeumer.vscode-eslint",
|
|
7
|
+
"bradlc.vscode-tailwindcss",
|
|
8
|
+
"antfu.goto-alias",
|
|
9
|
+
"antfu.iconify",
|
|
10
|
+
"streetsidesoftware.code-spell-checker",
|
|
11
|
+
"usernamehw.errorlens"
|
|
12
|
+
],
|
|
13
|
+
"unwantedRecommendations": ["octref.vetur"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"css.lint.unknownAtRules": "ignore",
|
|
3
|
+
"less.lint.unknownAtRules": "ignore",
|
|
4
|
+
"scss.lint.unknownAtRules": "ignore",
|
|
5
|
+
"tailwindCSS.classAttributes": ["class", ".*-class(es)?", "theme", "ui"],
|
|
6
|
+
"tailwindCSS.experimental.classRegex": [
|
|
7
|
+
["Theme \\=([^;]*);?", "'([^']*)'"],
|
|
8
|
+
["Theme \\=([^;]*);?", "\"([^\"]*)\""],
|
|
9
|
+
["Theme \\=([^;]*);?", "\\`([^\\`]*)\\`"],
|
|
10
|
+
["Class \\=([^;]*);?", "'([^']*)'"],
|
|
11
|
+
["Classes \\=([^;]*);?", "'([^']*)'"],
|
|
12
|
+
["Class \\=([^;]*);?", "\"([^\"]*)\""],
|
|
13
|
+
["Classes \\=([^;]*);?", "\"([^\"]*)\""],
|
|
14
|
+
["Class \\=([^;]*);?", "\\`([^\\`]*)\\`"],
|
|
15
|
+
["Classes \\=([^;]*);?", "\\`([^\\`]*)\\`"],
|
|
16
|
+
["tw`(.*?)`", "tw\\('(.*?)'\\)", "tw\\(\\s*('(.*?)'|\"(.*?)\")\\s*\\)"],
|
|
17
|
+
["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
|
|
18
|
+
],
|
|
19
|
+
"files.associations": {
|
|
20
|
+
"*.css": "tailwindcss"
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
"editor.codeActionsOnSave": {
|
|
24
|
+
"source.fixAll": "never",
|
|
25
|
+
"source.fixAll.eslint": "explicit"
|
|
26
|
+
},
|
|
27
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
28
|
+
"editor.formatOnSave": true,
|
|
29
|
+
"editor.gotoLocation.multipleDefinitions": "goto",
|
|
30
|
+
"editor.quickSuggestions": {
|
|
31
|
+
"strings": true
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
"cSpell.words": [
|
|
35
|
+
"bunx",
|
|
36
|
+
"defu",
|
|
37
|
+
"nuxt",
|
|
38
|
+
"nuxtjs",
|
|
39
|
+
"oklch",
|
|
40
|
+
"pinia",
|
|
41
|
+
"plutocms",
|
|
42
|
+
"tailwindcss"
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
"eslint.useFlatConfig": true,
|
|
46
|
+
"eslint.validate": [
|
|
47
|
+
"javascript",
|
|
48
|
+
"javascriptreact",
|
|
49
|
+
"typescript",
|
|
50
|
+
"typescriptreact",
|
|
51
|
+
"vue",
|
|
52
|
+
"html",
|
|
53
|
+
"markdown",
|
|
54
|
+
"json",
|
|
55
|
+
"jsonc",
|
|
56
|
+
"yaml",
|
|
57
|
+
"toml",
|
|
58
|
+
"xml",
|
|
59
|
+
"gql",
|
|
60
|
+
"graphql",
|
|
61
|
+
"astro",
|
|
62
|
+
"svelte",
|
|
63
|
+
"css",
|
|
64
|
+
"less",
|
|
65
|
+
"scss",
|
|
66
|
+
"pcss",
|
|
67
|
+
"postcss",
|
|
68
|
+
"mjs"
|
|
69
|
+
],
|
|
70
|
+
|
|
71
|
+
"vue.inlayHints.missingProps": true
|
|
72
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Vue Component": {
|
|
3
|
+
"prefix": ["vue", "tem", "template", "setup"],
|
|
4
|
+
"body": [
|
|
5
|
+
"<script setup lang=\"ts\">",
|
|
6
|
+
"$1",
|
|
7
|
+
"</script>",
|
|
8
|
+
"",
|
|
9
|
+
"<template>",
|
|
10
|
+
" <div>$2</div>",
|
|
11
|
+
"</template>",
|
|
12
|
+
"",
|
|
13
|
+
],
|
|
14
|
+
"description": "Vue Component (Script first)",
|
|
15
|
+
},
|
|
16
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<img width="335" height="105" alt="image" src="https://github.com/user-attachments/assets/1cf11470-ea54-416e-a940-7221fffef1e2" />
|
|
2
|
+
|
|
3
|
+
# Pluto
|
|
4
|
+
|
|
5
|
+
> [!WARNING]
|
|
6
|
+
> 🚧 Work In Progress: Pluto is experimental. Breaking changes are expected. Not production ready yet.
|
|
7
|
+
|
|
8
|
+
Pluto is a modular, layer-driven Content Management System (CMS) built with Nuxt. A modern alternative to monolithic systems like WordPress. Extend functionality through Nuxt Layers: choose only what is needed (auth, storage, e-commerce, blog, database connectors, etc.).
|
|
9
|
+
|
|
10
|
+
## Highlights
|
|
11
|
+
|
|
12
|
+
- Nuxt + Nuxt Layers architecture
|
|
13
|
+
- Headless-first: consume via API (_with typed routes!_) or built-in composables (like `useAuth` or `useProduct`)
|
|
14
|
+
- Opt-in feature layers (Supabase, Blog, Shop, DB connectors, etc.)
|
|
15
|
+
- Core primitives: Content Types, Taxonomies, Custom Fields, Media, Permissions
|
|
16
|
+
- Deploy anywhere: Node, Edge, Serverless, Static (hybrid), Docker
|
|
17
|
+
- Developer-focused: composables, typed schemas, minimal core
|
|
18
|
+
- Dashboard is owned: fork as needed or just use it as is
|
|
19
|
+
|
|
20
|
+
## Getting Started
|
|
21
|
+
|
|
22
|
+
First, install `typescript` as a dev dependency if you haven't already. This is required for Nuxt Layers to function properly.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm i -D typescript
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then, extend your Nuxt configuration to include the Pluto layer, setting the install option to true, so Pluto's dependencies are installed automatically.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// nuxt.config.ts
|
|
32
|
+
export default defineNuxtConfig({
|
|
33
|
+
extends: [
|
|
34
|
+
['github:plutocms/pluto', { install: true }],
|
|
35
|
+
|
|
36
|
+
// Then, add any additional layers you want to use here
|
|
37
|
+
['github:plutocms/supabase', { install: true }],
|
|
38
|
+
['github:plutocms/blog', { install: true }],
|
|
39
|
+
['github:plutocms/shop', { install: true }],
|
|
40
|
+
],
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Core Concepts
|
|
45
|
+
|
|
46
|
+
- Content Types: Define structured entities (e.g. Post, Product, Page)
|
|
47
|
+
- Fields: Primitive & custom (string, rich text, media, relation, JSON, computed)
|
|
48
|
+
- Taxonomies: Hierarchical or flat classification
|
|
49
|
+
- Media: Pluggable storage (e.g. Supabase, S3, local)
|
|
50
|
+
- Auth & Identity: Provided by optional layers (e.g. Supabase)
|
|
51
|
+
- Policies: Role / capability mapping (planned)
|
|
52
|
+
|
|
53
|
+
## Layer Examples (Planned / In Progress)
|
|
54
|
+
|
|
55
|
+
| Layer | Purpose |
|
|
56
|
+
| ------------------------- | ----------------------------------------------- |
|
|
57
|
+
| core | Base CMS engine + schema registry |
|
|
58
|
+
| supabase | Auth, file storage, row-level security hooks |
|
|
59
|
+
| blog | Post model, categories, tags, markdown pipeline |
|
|
60
|
+
| shop | Product model, pricing, inventory abstraction |
|
|
61
|
+
| mysql / postgres / sqlite | Database connectors |
|
|
62
|
+
| analytics | Basic event/log capture |
|
|
63
|
+
| search | Index + query adapters (e.g. Meilisearch) |
|
|
64
|
+
|
|
65
|
+
> [!NOTE]
|
|
66
|
+
> Actual availability depends on roadmap progress.
|
|
67
|
+
|
|
68
|
+
For now, some layers are being developed (`/layers` directory) in this same repository, but will eventually be extracted into their own packages.
|
|
69
|
+
|
|
70
|
+
> [!NOTE]
|
|
71
|
+
> Optional layers may require environment variables; see ./env.example when added.
|
|
72
|
+
|
|
73
|
+
## Roadmap (Subject to Change)
|
|
74
|
+
|
|
75
|
+
Check [the roadmap here](https://github.com/ojvribeiro/pluto/issues/47).
|
|
76
|
+
|
|
77
|
+
## Contributing
|
|
78
|
+
|
|
79
|
+
- Open issues for design discussion before large PRs
|
|
80
|
+
- Keep layers isolated and opt-in
|
|
81
|
+
- Prefer typed contracts and explicit interfaces
|
|
82
|
+
- Add tests where possible (testing stack TBD)
|
|
83
|
+
|
|
84
|
+
## Philosophy
|
|
85
|
+
|
|
86
|
+
- Minimal core, everything is a layer
|
|
87
|
+
- Transparent, hackable dashboard (no locked UI bundle)
|
|
88
|
+
- Declarative schemas
|
|
89
|
+
- Runtime flexibility: choose infra, not dictated by core
|
|
90
|
+
|
|
91
|
+
## Why Not Just WordPress?
|
|
92
|
+
|
|
93
|
+
- Modern SSR + SPA hydration via Nuxt
|
|
94
|
+
- TypeScript-first developer experience
|
|
95
|
+
- Layer-based opt-in features instead of plugin global mutations
|
|
96
|
+
- Deployment portability (Edge / Serverless friendly)
|
|
97
|
+
- Headless usage is primary, not an afterthought
|
|
98
|
+
- If you're a Vue developer, you'll feel right at home.
|
|
99
|
+
|
|
100
|
+
## Security
|
|
101
|
+
|
|
102
|
+
Do not deploy to production yet. No security audit performed. Auth / ACL model incomplete.
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
TBD (likely MIT). Not final.
|
|
107
|
+
|
|
108
|
+
## Status
|
|
109
|
+
|
|
110
|
+
Experimental. Expect refactors.
|
|
111
|
+
|
|
112
|
+
## Naming Note
|
|
113
|
+
|
|
114
|
+
"Pluto" is a working name; subject to rename if conflicts arise.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export default defineAppConfig({
|
|
2
|
+
ui: {
|
|
3
|
+
button: {
|
|
4
|
+
compoundVariants: [
|
|
5
|
+
{
|
|
6
|
+
size: 'xl',
|
|
7
|
+
class: 'px-6 py-2',
|
|
8
|
+
square: false,
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
|
|
12
|
+
defaultVariants: {
|
|
13
|
+
color: 'primary',
|
|
14
|
+
variant: 'solid',
|
|
15
|
+
size: 'xl',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
formField: {
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
size: 'xl',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
input: {
|
|
26
|
+
slots: {
|
|
27
|
+
root: 'w-full',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
compoundVariants: [
|
|
31
|
+
{
|
|
32
|
+
class: 'w-full',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
size: 'xl',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
})
|
package/app/app.vue
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
@import '@nuxt/ui';
|
|
3
|
+
|
|
4
|
+
@source '../..';
|
|
5
|
+
@source '../../../../../app/**';
|
|
6
|
+
|
|
7
|
+
@theme {
|
|
8
|
+
--color-admin-content: var(--color-slate-800);
|
|
9
|
+
--color-admin-sidebar: var(--color-slate-900);
|
|
10
|
+
|
|
11
|
+
--font-outfit: 'Outfit', sans-serif;
|
|
12
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const colorMode = useColorMode()
|
|
3
|
+
|
|
4
|
+
const isDark = computed({
|
|
5
|
+
get() {
|
|
6
|
+
return colorMode.value === 'dark'
|
|
7
|
+
},
|
|
8
|
+
set() {
|
|
9
|
+
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<ClientOnly v-if="!colorMode?.forced">
|
|
16
|
+
<UButton
|
|
17
|
+
:icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
|
|
18
|
+
color="neutral"
|
|
19
|
+
variant="solid"
|
|
20
|
+
size="sm"
|
|
21
|
+
@click="isDark = !isDark"
|
|
22
|
+
/>
|
|
23
|
+
|
|
24
|
+
<template #fallback>
|
|
25
|
+
<div class="size-8" />
|
|
26
|
+
</template>
|
|
27
|
+
</ClientOnly>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassNameValue } from 'tailwind-merge'
|
|
3
|
+
import { twMerge } from 'tailwind-merge'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: ClassNameValue
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const resolvedClasses = computed(() => {
|
|
10
|
+
const defaultClasses = 'mx-auto max-w-full transition-all px-4 sm:px-6 w-350'
|
|
11
|
+
|
|
12
|
+
return twMerge([defaultClasses, props.class])
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<div :class="resolvedClasses">
|
|
18
|
+
<slot />
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup lang="ts"></script>
|
|
2
|
+
|
|
3
|
+
<template>
|
|
4
|
+
<div class="grow">
|
|
5
|
+
<UApp>
|
|
6
|
+
<NuxtRouteAnnouncer />
|
|
7
|
+
<NuxtLoadingIndicator />
|
|
8
|
+
|
|
9
|
+
<NuxtLayout>
|
|
10
|
+
<slot />
|
|
11
|
+
</NuxtLayout>
|
|
12
|
+
</UApp>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
html,
|
|
18
|
+
body {
|
|
19
|
+
height: 100%;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#__nuxt {
|
|
23
|
+
height: 100%;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
}
|
|
27
|
+
</style>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ClassNameValue } from 'tailwind-merge'
|
|
3
|
+
import { twMerge } from 'tailwind-merge'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
class?: ClassNameValue
|
|
7
|
+
trackClass?: ClassNameValue
|
|
8
|
+
thumbClass?: ClassNameValue
|
|
9
|
+
hideDelay?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
+
hideDelay: 0,
|
|
14
|
+
class: '',
|
|
15
|
+
thumbClass: '',
|
|
16
|
+
trackClass: '',
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const resolvedClasses = computed(() => {
|
|
20
|
+
const defaultClasses = `
|
|
21
|
+
h-full
|
|
22
|
+
transition-opacity
|
|
23
|
+
duration-300
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
return twMerge([defaultClasses, props.class])
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const resolvedTrackClasses = computed(() => {
|
|
30
|
+
const defaultClasses = `
|
|
31
|
+
relative
|
|
32
|
+
w-2
|
|
33
|
+
rounded-full
|
|
34
|
+
bg-transparent
|
|
35
|
+
transition-colors duration-300
|
|
36
|
+
hover:bg-black/10
|
|
37
|
+
`
|
|
38
|
+
|
|
39
|
+
return twMerge([defaultClasses, props.trackClass])
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const resolvedThumbClasses = computed(() => {
|
|
43
|
+
const defaultClasses = `
|
|
44
|
+
rounded-full
|
|
45
|
+
bg-black/40
|
|
46
|
+
hover:bg-black/40
|
|
47
|
+
active:bg-black/60
|
|
48
|
+
`
|
|
49
|
+
|
|
50
|
+
return twMerge([defaultClasses, props.thumbClass])
|
|
51
|
+
})
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<RekaScrollAreaRoot
|
|
56
|
+
:scroll-hide-delay="props.hideDelay"
|
|
57
|
+
class="h-full shrink-0 overflow-hidden transition-opacity duration-300"
|
|
58
|
+
>
|
|
59
|
+
<RekaScrollAreaViewport :class="resolvedClasses">
|
|
60
|
+
<slot />
|
|
61
|
+
</RekaScrollAreaViewport>
|
|
62
|
+
|
|
63
|
+
<Transition name="fade">
|
|
64
|
+
<RekaScrollAreaScrollbar
|
|
65
|
+
:class="resolvedTrackClasses"
|
|
66
|
+
orientation="vertical"
|
|
67
|
+
>
|
|
68
|
+
<RekaScrollAreaThumb :class="resolvedThumbClasses" />
|
|
69
|
+
</RekaScrollAreaScrollbar>
|
|
70
|
+
</Transition>
|
|
71
|
+
|
|
72
|
+
<RekaScrollAreaCorner />
|
|
73
|
+
</RekaScrollAreaRoot>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<style scoped>
|
|
77
|
+
.fade-enter-active,
|
|
78
|
+
.fade-leave-active {
|
|
79
|
+
transition: opacity 0.2s;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.fade-enter-from,
|
|
83
|
+
.fade-leave-to {
|
|
84
|
+
opacity: 0;
|
|
85
|
+
}
|
|
86
|
+
</style>
|