├── env.d.ts
├── src
├── components
│ ├── consts.ts
│ ├── index.ts
│ ├── utils
│ │ ├── SlotExtr.vue
│ │ └── FixedRoute.vue
│ ├── Content3.vue
│ ├── GlTemplate.vue
│ └── GoldenLayout.vue
├── sfc.d.ts
├── main.ts
├── views
│ ├── AboutView.vue
│ └── HomeView.vue
├── assets
│ ├── logo.svg
│ ├── main.css
│ └── base.css
├── router
│ └── index.ts
├── ts
│ └── predefined-layouts.ts
└── App.vue
├── public
└── favicon.ico
├── .vscode
└── extensions.json
├── .prettierrc.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── index.html
├── .eslintrc.cjs
├── .gitignore
├── vite.config.ts
├── LICENSE
├── package.json
└── README.md
/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/components/consts.ts:
--------------------------------------------------------------------------------
1 | export const layoutKey = Symbol("layout");
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eddow/v3-gl-ext/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/components/index.ts:
--------------------------------------------------------------------------------
1 | import GoldenLayout from "./GoldenLayout.vue";
2 |
3 | export { GoldenLayout };
--------------------------------------------------------------------------------
/src/sfc.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue'
3 | export default Vue
4 | }
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
3 | }
4 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/prettierrc",
3 | "semi": false,
4 | "tabWidth": 4,
5 | "singleQuote": true,
6 | "printWidth": 100,
7 | "trailingComma": "none"
8 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | {
5 | "path": "./tsconfig.node.json"
6 | },
7 | {
8 | "path": "./tsconfig.app.json"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import './assets/main.css'
2 |
3 | import { createApp } from 'vue'
4 | import App from './App.vue'
5 | import router from './router'
6 |
7 | const app = createApp(App)
8 |
9 | app.use(router)
10 |
11 | app.mount('#app')
12 |
--------------------------------------------------------------------------------
/src/views/AboutView.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is an about page
4 |
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/utils/SlotExtr.vue:
--------------------------------------------------------------------------------
1 |
2 | Slots extraction
3 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.dom.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4 | "exclude": ["src/**/__tests__/*"],
5 | "compilerOptions": {
6 | "composite": true,
7 | "baseUrl": ".",
8 | "paths": {
9 | "@/*": ["./src/*"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/node18/tsconfig.json",
3 | "include": [
4 | "vite.config.*",
5 | "vitest.config.*",
6 | "cypress.config.*",
7 | "nightwatch.conf.*",
8 | "playwright.config.*"
9 | ],
10 | "compilerOptions": {
11 | "composite": true,
12 | "module": "ESNext",
13 | "types": ["node"]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | require('@rushstack/eslint-patch/modern-module-resolution')
3 |
4 | module.exports = {
5 | root: true,
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended',
9 | '@vue/eslint-config-typescript',
10 | '@vue/eslint-config-prettier/skip-formatting'
11 | ],
12 | parserOptions: {
13 | ecmaVersion: 'latest'
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
--------------------------------------------------------------------------------
/src/components/utils/FixedRoute.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app {
4 | max-width: 1280px;
5 | margin: 0 auto;
6 | padding: 2rem;
7 |
8 | font-weight: normal;
9 | }
10 |
11 | a,
12 | .green {
13 | text-decoration: none;
14 | color: hsla(160, 100%, 37%, 1);
15 | transition: 0.4s;
16 | }
17 |
18 | @media (hover: hover) {
19 | a:hover {
20 | background-color: hsla(160, 100%, 37%, 0.2);
21 | }
22 | }
23 |
24 | @media (min-width: 1024px) {
25 | body {
26 | display: flex;
27 | place-items: center;
28 | }
29 |
30 | #app {
31 | grid-template-columns: 1fr 1fr;
32 | padding: 0 2rem;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/views/HomeView.vue:
--------------------------------------------------------------------------------
1 |
2 | Welcome aboard!
3 |
4 |
5 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHistory } from 'vue-router'
2 | import HomeView from '../views/HomeView.vue'
3 |
4 | const router = createRouter({
5 | history: createWebHistory(import.meta.env.BASE_URL),
6 | routes: [
7 | {
8 | path: '/',
9 | name: 'other',
10 | component: HomeView
11 | },
12 | {
13 | path: '/home',
14 | name: 'home',
15 | component: HomeView,
16 | meta: {
17 | title: 'Home'
18 | }
19 | },
20 | {
21 | path: '/about',
22 | name: 'about',
23 | // route level code-splitting
24 | // this generates a separate chunk (About.[hash].js) for this route
25 | // which is lazy-loaded when the route is visited.
26 | component: () => import('../views/AboutView.vue')
27 | }
28 | ]
29 | })
30 |
31 | export default router
32 |
--------------------------------------------------------------------------------
/src/components/Content3.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | 2
5 | 3
6 | 4
7 | 5
8 | 6
9 | 7
10 | 8
11 | 9
12 | 0
13 | 1
14 | 2
15 | 3
16 | 4
17 | 5
18 | 6
19 | 7
20 | 8
21 | 9
22 | 0
23 | 1
24 | 2
25 | 3
26 | 4
27 | 5
28 | 6
29 | 7
30 | 8
31 | 9
32 | 0
33 | 1
34 | 2
35 | 3
36 | 4
37 | 5
38 | 6
39 | 7
40 | 8
41 | 9
42 | 0
43 | 1
44 | 2
45 | 3
46 | 4
47 | 5
48 | 6
49 | 7
50 | 8
51 | 9
52 | 0
53 |
54 |
55 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'node:url'
2 | import { resolve } from 'path';
3 | import { defineConfig } from 'vite'
4 | import vue from '@vitejs/plugin-vue'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [
9 | vue(),
10 | ],
11 | build: {
12 | cssCodeSplit: true,
13 | lib: {
14 | // Could also be a dictionary or array of multiple entry points
15 | entry: "src/components/main.ts",
16 | name: 'myLibraryVueTs',
17 | formats: ["es", "cjs", "umd"],
18 | fileName: format => `my-library-vue-ts.${format}.js`
19 | },
20 | rollupOptions: {
21 | // make sure to externalize deps that should not be bundled
22 | // into your library
23 | input: {
24 | main: resolve(__dirname, "src/components/main.ts")
25 | },
26 | external: ['vue', 'golden-layout']
27 | },
28 | },
29 | resolve: {
30 | alias: {
31 | '@': fileURLToPath(new URL('./src', import.meta.url))
32 | }
33 | }
34 | })
35 |
--------------------------------------------------------------------------------
/src/ts/predefined-layouts.ts:
--------------------------------------------------------------------------------
1 | import {
2 | ComponentItemConfig,
3 | ItemType,
4 | LayoutConfig,
5 | } from "golden-layout";
6 |
7 | const miniRowConfig: LayoutConfig = {
8 | root: {
9 | type: ItemType.column,
10 | content: [{
11 | type: "component",
12 | title: "Init",
13 | header: { show: "top" },
14 | componentType: "Content1",
15 | width: 10,
16 | componentState: { abc: 'Yhea' },
17 | } as ComponentItemConfig, {
18 | type: ItemType.row,
19 | content: [{
20 | type: "component",
21 | title: "Title 1st",
22 | header: { show: "top" },
23 | isClosable: false,
24 | componentType: "Content1",
25 | width: 10,
26 | componentState: { abc: 123 },
27 | } as ComponentItemConfig, {
28 | type: "component",
29 | title: "I'm wide",
30 | header: { show: "top", popout: false },
31 | componentType: "Content2"
32 | } as ComponentItemConfig
33 | ]}]
34 | }
35 | };
36 |
37 | export const prefinedLayouts = {
38 | miniRow: miniRowConfig,
39 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 emedware
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v3-gl-ext",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "run-p type-check build-only",
8 | "preview": "vite preview",
9 | "build-only": "vite build",
10 | "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
11 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
12 | "format": "prettier --write src/"
13 | },
14 | "dependencies": {
15 | "golden-layout": "^2.6.0",
16 | "vue": "^3.3.4",
17 | "vue-router": "^4.2.2"
18 | },
19 | "devDependencies": {
20 | "@rushstack/eslint-patch": "^1.2.0",
21 | "@tsconfig/node18": "^2.0.1",
22 | "@types/node": "^18.16.17",
23 | "@vitejs/plugin-vue": "^4.2.3",
24 | "@vue/eslint-config-prettier": "^7.1.0",
25 | "@vue/eslint-config-typescript": "^11.0.3",
26 | "@vue/tsconfig": "^0.4.0",
27 | "eslint": "^8.39.0",
28 | "eslint-plugin-vue": "^9.11.0",
29 | "npm-run-all": "^4.1.5",
30 | "prettier": "^2.8.8",
31 | "typescript": "~5.0.4",
32 | "vite": "^4.3.9",
33 | "vue-tsc": "^1.6.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # v3-gl-ext
2 |
3 | Vue3 golden layout and extensions - successor of [vue-golden-layout](https://github.com/emedware/vue-golden-layout)
4 |
5 | ## Project Setup
6 |
7 | ```sh
8 | npm install
9 | ```
10 |
11 | ### Compile and Hot-Reload for Development
12 |
13 | ```sh
14 | npm run dev
15 | ```
16 |
17 | ### Type-Check, Compile and Minify for Production
18 |
19 | ```sh
20 | npm run build
21 | ```
22 |
23 | ## Usage
24 |
25 | ```html
26 |
27 |
28 |
29 | ...
30 |
31 |
32 |
33 |
45 | ```
46 |
47 | ### Properties
48 |
49 | If `router` is true, every route change will either open a new tab or select the good one if already opened. Also, the url changes with tab change.
50 |
51 | ## TODOs
52 |
53 | - [ ] Config watching through property
54 | - [ ] Route sub-components
55 | - [ ] Route whole config (adds in the column/row instead of the stack)
--------------------------------------------------------------------------------
/src/components/GlTemplate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
55 |
--------------------------------------------------------------------------------
/src/assets/base.css:
--------------------------------------------------------------------------------
1 | /* color palette from */
2 | :root {
3 | --vt-c-white: #ffffff;
4 | --vt-c-white-soft: #f8f8f8;
5 | --vt-c-white-mute: #f2f2f2;
6 |
7 | --vt-c-black: #181818;
8 | --vt-c-black-soft: #222222;
9 | --vt-c-black-mute: #282828;
10 |
11 | --vt-c-indigo: #2c3e50;
12 |
13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17 |
18 | --vt-c-text-light-1: var(--vt-c-indigo);
19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20 | --vt-c-text-dark-1: var(--vt-c-white);
21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22 | }
23 |
24 | /* semantic color variables for this project */
25 | :root {
26 | --color-background: var(--vt-c-white);
27 | --color-background-soft: var(--vt-c-white-soft);
28 | --color-background-mute: var(--vt-c-white-mute);
29 |
30 | --color-border: var(--vt-c-divider-light-2);
31 | --color-border-hover: var(--vt-c-divider-light-1);
32 |
33 | --color-heading: var(--vt-c-text-light-1);
34 | --color-text: var(--vt-c-text-light-1);
35 |
36 | --section-gap: 160px;
37 | }
38 |
39 | @media (prefers-color-scheme: dark) {
40 | :root {
41 | --color-background: var(--vt-c-black);
42 | --color-background-soft: var(--vt-c-black-soft);
43 | --color-background-mute: var(--vt-c-black-mute);
44 |
45 | --color-border: var(--vt-c-divider-dark-2);
46 | --color-border-hover: var(--vt-c-divider-dark-1);
47 |
48 | --color-heading: var(--vt-c-text-dark-1);
49 | --color-text: var(--vt-c-text-dark-2);
50 | }
51 | }
52 |
53 | *,
54 | *::before,
55 | *::after {
56 | box-sizing: border-box;
57 | margin: 0;
58 | font-weight: normal;
59 | }
60 |
61 | body {
62 | min-height: 100vh;
63 | color: var(--color-text);
64 | background: var(--color-background);
65 | transition: color 0.5s, background-color 0.5s;
66 | line-height: 1.6;
67 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
68 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
69 | font-size: 15px;
70 | text-rendering: optimizeLegibility;
71 | -webkit-font-smoothing: antialiased;
72 | -moz-osx-font-smoothing: grayscale;
73 | }
74 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
Golden Layout Demo
15 |
16 |
17 |
20 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
37 |
38 | {{abc || 111}}
39 |
40 |
41 |
42 | 111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
94 |
95 |
157 | ./components
--------------------------------------------------------------------------------
/src/components/GoldenLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
345 |
--------------------------------------------------------------------------------