├── .prettierrc ├── favicon.ico ├── assets ├── logo.png ├── README.md └── css │ ├── tailwind.css │ └── theme.css ├── static ├── favicon.ico ├── apple-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── ms-icon-70x70.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── android-icon-144x144.png ├── android-icon-192x192.png ├── apple-icon-precomposed.png ├── browserconfig.xml └── README.md ├── layouts ├── default.vue ├── README.md └── theme.vue ├── plugins ├── vue-lazyload.js ├── theme4nuxt.js └── README.md ├── pages ├── index.vue ├── howto.vue ├── store.vue ├── blog │ ├── _path │ │ └── index.vue │ └── index.vue ├── about.vue └── README.md ├── .editorconfig ├── middleware └── README.md ├── store ├── README.md └── index.js ├── components ├── core │ ├── heading │ │ └── index.vue │ ├── services │ │ └── index.vue │ ├── skills │ │ └── index.vue │ ├── prices │ │ └── index.vue │ ├── tiles │ │ └── index.vue │ └── cards │ │ └── index.vue ├── theme │ ├── ComponentWrapper.vue │ ├── index.js │ └── nav │ │ └── index.vue └── posts │ └── index.vue ├── .eslintrc.js ├── .snyk ├── postcss.config.js ├── nuxt.config.js ├── .gitignore ├── package.json ├── themes ├── theme5.js ├── theme8.js ├── index.js ├── theme3.js ├── theme7.js ├── theme4.js ├── theme6.js ├── theme1.js └── theme2.js └── README.md /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/favicon.ico -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/assets/logo.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /static/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon.png -------------------------------------------------------------------------------- /static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/favicon-96x96.png -------------------------------------------------------------------------------- /static/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/ms-icon-70x70.png -------------------------------------------------------------------------------- /static/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-57x57.png -------------------------------------------------------------------------------- /static/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-60x60.png -------------------------------------------------------------------------------- /static/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-72x72.png -------------------------------------------------------------------------------- /static/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-76x76.png -------------------------------------------------------------------------------- /static/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/ms-icon-144x144.png -------------------------------------------------------------------------------- /static/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/ms-icon-150x150.png -------------------------------------------------------------------------------- /static/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/ms-icon-310x310.png -------------------------------------------------------------------------------- /static/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-36x36.png -------------------------------------------------------------------------------- /static/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-48x48.png -------------------------------------------------------------------------------- /static/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-72x72.png -------------------------------------------------------------------------------- /static/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-96x96.png -------------------------------------------------------------------------------- /static/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-114x114.png -------------------------------------------------------------------------------- /static/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-120x120.png -------------------------------------------------------------------------------- /static/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-144x144.png -------------------------------------------------------------------------------- /static/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-152x152.png -------------------------------------------------------------------------------- /static/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-180x180.png -------------------------------------------------------------------------------- /static/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-144x144.png -------------------------------------------------------------------------------- /static/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/android-icon-192x192.png -------------------------------------------------------------------------------- /static/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swina/theme4nuxt/HEAD/static/apple-icon-precomposed.png -------------------------------------------------------------------------------- /plugins/vue-lazyload.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueLazyload from 'vue-lazyload'; 3 | 4 | Vue.use(VueLazyload); -------------------------------------------------------------------------------- /plugins/theme4nuxt.js: -------------------------------------------------------------------------------- 1 | import theme from '~/themes/theme1.js' 2 | 3 | export default ({ app }, inject) => { 4 | inject('theme4nuxt', () => theme) 5 | } 6 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Application Layouts. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). 8 | -------------------------------------------------------------------------------- /static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /pages/howto.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your application middleware. 6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages. 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /pages/store.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /components/core/heading/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /components/theme/ComponentWrapper.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 13 | 'plugin:vue/essential', 14 | ], 15 | // required to lint *.vue files 16 | plugins: [ 17 | 'vue' 18 | ], 19 | // add your custom rules here 20 | rules: {} 21 | } -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.25.0 3 | ignore: {} 4 | # patches apply the minimum changes required to fix a vulnerability 5 | patch: 6 | SNYK-JS-LODASH-567746: 7 | - nuxt > @nuxt/telemetry > inquirer > lodash: 8 | patched: '2023-04-11T06:52:18.401Z' 9 | - nuxt > @nuxt/builder > @nuxt/webpack > hard-source-webpack-plugin > lodash: 10 | patched: '2023-04-11T06:52:18.401Z' 11 | - nuxt > @nuxt/builder > @nuxt/webpack > optimize-css-assets-webpack-plugin > last-call-webpack-plugin > lodash: 12 | patched: '2023-04-11T06:52:18.401Z' 13 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const join = require('path').join 2 | const tailwindJS = join(__dirname, 'tailwind.js') 3 | 4 | module.exports = { 5 | plugins: [ 6 | require('tailwindcss')(tailwindJS), 7 | require('autoprefixer') 8 | ] 9 | } 10 | /* 11 | const tailwindcss = require('tailwindcss') 12 | const purgecss = require('@fullhuman/postcss-purgecss') 13 | const cssnano = require('cssnano') 14 | const autoprefixer = require('autoprefixer') 15 | 16 | module.exports = { 17 | plugins: [ 18 | tailwindcss('./tailwind.js'), 19 | cssnano({ 20 | preset: 'default', 21 | }), 22 | purgecss({ 23 | content: ['./layouts/**///*.vue','./themes/**/*.js'] 24 | //}), 25 | //autoprefixer 26 | //] 27 | //} 28 | -------------------------------------------------------------------------------- /pages/blog/_path/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | -------------------------------------------------------------------------------- /pages/blog/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /components/theme/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import upperFirst from 'lodash/upperFirst' 3 | import camelCase from 'lodash/camelCase' 4 | 5 | const requireComponent = require.context( 6 | '@/components/theme', true, /\.vue$/ 7 | ) 8 | 9 | requireComponent.keys().forEach(fileName => { 10 | const componentConfig = requireComponent(fileName) 11 | let componentName = 'v-' 12 | componentName += camelCase(fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')) 13 | //if ( componentName.indexOf('-mood') < 0 ){ 14 | // componentName = componentName.replace('Index','') 15 | //} else { 16 | // componentName = componentName.replace('Index','') 17 | //} 18 | componentName = componentName.replace('Index','') 19 | console.log ( componentName ) 20 | Vue.component(componentName, componentConfig.default || componentConfig) 21 | }) 22 | -------------------------------------------------------------------------------- /components/core/services/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 30 | -------------------------------------------------------------------------------- /components/core/skills/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 47 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | import pkg from './package' 2 | 3 | export default { 4 | mode: 'universal', 5 | head: { 6 | title: pkg.name, 7 | meta: [ 8 | { charset: 'utf-8' }, 9 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 10 | { hid: 'description', name: 'description', content: pkg.description } 11 | ], 12 | link: [ 13 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, 14 | { rel: 'stylesheet' , href: 'https://fonts.googleapis.com/icon?family=Material+Icons' } 15 | ] 16 | }, 17 | 18 | loading: { color: '#000' }, 19 | 20 | icon: [ 21 | '~/assets/logo.png' 22 | ], 23 | 24 | css: [ 25 | '~/assets/css/tailwind.css', 26 | '~/assets/css/theme.css' 27 | ], 28 | 29 | 30 | plugins: [ 31 | { src: '~/plugins/theme4nuxt.js' , ssr: true }, 32 | { src: '~/components/theme' , ssr: false }, 33 | { src: '~/plugins/vue-lazyload', ssr: false } 34 | ], 35 | 36 | modules: [ 37 | '@nuxtjs/axios', 38 | '@nuxtjs/pwa', 39 | '@nuxtjs/markdownit' 40 | ], 41 | build: { 42 | extend(config, ctx) { 43 | // Run ESLint on save 44 | if (ctx.isDev && ctx.isClient) { 45 | config.module.rules.push({ 46 | //enforce: 'pre', 47 | test: /\.(js|vue)$/, 48 | loader: 'eslint-loader', 49 | exclude: /(node_modules)/ 50 | }) 51 | } 52 | 53 | } 54 | }, 55 | 56 | } 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | -------------------------------------------------------------------------------- /components/core/prices/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "theme4nuxt-demo", 3 | "version": "1.0.0", 4 | "description": "A tailwind theming solution for Nuxt.js", 5 | "author": "A. Nardone", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "build:css": "postcss ./assets/css/tailwind.css -o ./static/tailwind.css", 11 | "start": "nuxt start", 12 | "generate": "nuxt generate", 13 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 14 | "precommit": "npm run lint", 15 | "prepare": "npm run snyk-protect", 16 | "snyk-protect": "snyk-protect" 17 | }, 18 | "dependencies": { 19 | "@nuxtjs/axios": "^5.13.6", 20 | "@nuxtjs/markdownit": "^1.2.4", 21 | "@nuxtjs/pwa": "^3.3.5", 22 | "cross-env": "^5.2.0", 23 | "nuxt": "^2.16.3", 24 | "vue-lazyload": "^1.2.6", 25 | "@snyk/protect": "latest" 26 | }, 27 | "devDependencies": { 28 | "@fullhuman/postcss-purgecss": "^1.1.0", 29 | "@nuxtjs/eslint-config": "^0.0.1", 30 | "autoprefixer": "^10.4.14", 31 | "babel-eslint": "^10.0.1", 32 | "cssnano": "^6.0.0", 33 | "eslint": "^5.15.1", 34 | "eslint-config-prettier": "^4.1.0", 35 | "eslint-config-standard": ">=12.0.0", 36 | "eslint-loader": "^2.1.2", 37 | "eslint-plugin-import": ">=2.16.0", 38 | "eslint-plugin-jest": ">=22.3.0", 39 | "eslint-plugin-node": ">=8.0.1", 40 | "eslint-plugin-nuxt": ">=0.4.2", 41 | "eslint-plugin-prettier": "^3.0.1", 42 | "eslint-plugin-promise": ">=4.0.1", 43 | "eslint-plugin-standard": ">=4.0.0", 44 | "eslint-plugin-vue": "^5.2.2", 45 | "glob-all": "^3.3.1", 46 | "nodemon": "^2.0.22", 47 | "nuxt-purgecss": "^0.2.1", 48 | "prettier": "^1.16.4", 49 | "purgecss-webpack-plugin": "^1.4.0", 50 | "tailwindcss": "^3.3.1", 51 | "serialize-javascript": ">=3.1.0" 52 | }, 53 | "snyk": true 54 | } 55 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import grid from '~/themes' 2 | 3 | export const state = () => ({ 4 | theme : grid, 5 | theme_file: 'index.js', 6 | themes : null, 7 | currentTheme : 0, //{ name: 'Corporate Business' , file: 'index.js' }, 8 | initData : {} 9 | }) 10 | 11 | export const mutations = { 12 | init_data ( state , data ){ 13 | state.initData = data 14 | }, 15 | theme ( state , data ){ 16 | state.theme = data 17 | }, 18 | theme_file ( state , data ){ 19 | state.theme_file = data 20 | }, 21 | themes (state,data) { 22 | state.themes = data 23 | }, 24 | currentTheme(state,index){ 25 | state.currentTheme = index 26 | } 27 | } 28 | 29 | export const actions = { 30 | async nuxtServerInit({commit}, context ){ 31 | let init = context.app.$theme4nuxt().initData 32 | 33 | let api 34 | let data = {} 35 | for ( var n=0 ; n < init.length ; n++ ){ 36 | if ( init[n].type === 'api' ) { 37 | let qry = await context.app.$axios.get(init[n].api); 38 | !qry.data.data ? data[init[n].name] = qry.data : data[init[n].name] = qry.data.data 39 | } 40 | if ( init[n].type === 'array' ){ 41 | data[init[n].name] = init[n].value 42 | } 43 | } 44 | let themes = [] 45 | for ( var t=1 ; t < 9 ; t++ ){ 46 | let mytheme = await import('~/themes/theme' + t + '.js') 47 | themes.push(mytheme.default) 48 | } 49 | commit ('init_data', data ) 50 | commit('themes',themes) 51 | }, 52 | 53 | SetTheme({commit},theme){ 54 | commit('theme',theme) 55 | }, 56 | SetCurrentTheme({commit},theme){ 57 | commit('currentTheme',theme) 58 | }, 59 | SetThemeFile({commit},file){ 60 | commit('theme_file',file) 61 | }, 62 | } 63 | 64 | export const getters = { 65 | 'init' : state => state.initData, 66 | 'theme' : state => state.theme, 67 | } 68 | 69 | export const strict = false -------------------------------------------------------------------------------- /assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This injects Tailwind's base styles, which is a combination of 3 | * Normalize.css and some additional base styles. 4 | * 5 | * You can see the styles here: 6 | * https://github.com/tailwindcss/tailwindcss/blob/master/css/preflight.css 7 | * 8 | * If using `postcss-import`, use this import instead: 9 | * 10 | * @import "tailwindcss/preflight"; 11 | */ 12 | @tailwind preflight; 13 | 14 | /** 15 | * This injects any component classes registered by plugins. 16 | * 17 | * If using `postcss-import`, use this import instead: 18 | * 19 | * @import "tailwindcss/components"; 20 | */ 21 | @tailwind components; 22 | 23 | .btn { 24 | @apply py-2 px-4 rounded; 25 | } 26 | 27 | button { 28 | @apply outline-none; 29 | } 30 | 31 | a , a:focus , a:link , a:visited , button:focus , button:active { 32 | @apply outline-none; 33 | } 34 | 35 | pre { 36 | @apply bg-grey-light; 37 | @apply rounded ; @apply p-4 ; @apply leading-loose ; @apply font-mono ; @apply text-xs; @apply w-full; @apply overflow-y-auto; 38 | } 39 | 40 | .object-cover { 41 | background-size: cover!important; 42 | } 43 | 44 | /** 45 | * Here you would add any of your custom component classes; stuff that you'd 46 | * want loaded *before* the utilities so that the utilities could still 47 | * override them. 48 | * 49 | * Example: 50 | * 51 | * .btn { ... } 52 | * .form-input { ... } 53 | * 54 | * Or if using a preprocessor or `postcss-import`: 55 | * 56 | * @import "components/buttons"; 57 | * @import "components/forms"; 58 | */ 59 | 60 | /** 61 | * This injects all of Tailwind's utility classes, generated based on your 62 | * config file. 63 | * 64 | * If using `postcss-import`, use this import instead: 65 | * 66 | * @import "tailwindcss/utilities"; 67 | */ 68 | @tailwind utilities; 69 | 70 | /** 71 | * Here you would add any custom utilities you need that don't come out of the 72 | * box with Tailwind. 73 | * 74 | * Example : 75 | * 76 | * .bg-pattern-graph-paper { ... } 77 | * .skew-45 { ... } 78 | * 79 | * Or if using a preprocessor or `postcss-import`: 80 | * 81 | * @import "utilities/background-patterns"; 82 | * @import "utilities/skew-transforms"; 83 | */ 84 | -------------------------------------------------------------------------------- /components/posts/index.vue: -------------------------------------------------------------------------------- 1 | 25 | 82 | -------------------------------------------------------------------------------- /components/core/tiles/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 53 | -------------------------------------------------------------------------------- /components/theme/nav/index.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 105 | -------------------------------------------------------------------------------- /themes/theme5.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Zig-Zag Blog', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen font-serif', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : '/posts?$sort[createdAt]=-1&$limit=4' }, 9 | { type: 'api' , name: 'services' , api : '/sections?type=services' }, 10 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 11 | } 12 | ], 13 | 14 | navigation : [{ 15 | css : "items-start w-full z-50 pt-16 px-4 pb-4 bg-black rounded-br rounded-bl rounded-bl-lg", 16 | button : "mt-5 mr-5 bg-blue-dark shadow text-white p-2 border-grey-light border-2", 17 | line : "hover:text-black hover:bg-white text-right justify-start text-grey-dark" , 18 | link : 'text-grey-dark hover:text-red px-4 no-underline', 19 | left : false, 20 | transition : 'slideright', 21 | orientation: 'horizontal' , 22 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'}] 23 | }], 24 | template: { 25 | main : { 26 | css : "w-full", 27 | 28 | }, 29 | areas: { 30 | order : ['header','content','footer'], 31 | header : { 32 | root: 'w-full flex flex-wrap mb-12', 33 | blocks : [ 34 | { 35 | css: 'w-full h-12 flex items-center pl-4 text-grey mobile' , 36 | elements : [ 37 | { type: 'menu' , navigation: 0, homepage: false} 38 | ] 39 | }, 40 | { 41 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-24 col z-10' , 42 | elements : [ 43 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false} 44 | ] 45 | }, 46 | { 47 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-24 col justify-end text-right pr-4 col-nav' , 48 | elements : [ 49 | { type: 'nav' , navigation: 0 , homepage: false} 50 | ] 51 | }, 52 | 53 | ] 54 | }, 55 | content : { 56 | root: 'w-full flex flex-wrap', 57 | blocks : [ 58 | { 59 | css: 'w-full', 60 | elements: [ 61 | { type: 'css' , content: 'bg-header-5 h-screen clipped-zig-zag -mt-24 z-back' , homepage: false } 62 | ] 63 | }, 64 | { 65 | css: 'w-full bg-blue-lighter m-4 rounded-lg', 66 | elements: [ 67 | { type: 'component' , component: 'core/services' , options: {data: 'services'} , title: 'Features' , homepage: true }, 68 | ] 69 | }, 70 | { 71 | css: 'w-full', 72 | elements : [ 73 | 74 | { type: 'html' , content: '

Blog

' , homepage:true }, 75 | { type: 'component' , component: 'posts' , options: { data: 'info' } , homepage: true , nuxt: true }, 76 | 77 | { type: 'html' , content: '

News

' , homepage: true }, 78 | { type: 'component' , component: 'posts' , options: { data: 'info' } , homepage: true } 79 | ], 80 | } 81 | ] 82 | }, 83 | footer : { 84 | root : 'w-full', 85 | blocks : [ 86 | { 87 | css: 'h-16 items-center flex justify-center col-span-4 bg-teal-lighter text-center text-white' , 88 | elements : [ 89 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 90 | ] 91 | } 92 | ] 93 | } 94 | }, 95 | } 96 | 97 | } 98 | 99 | export default layout -------------------------------------------------------------------------------- /components/core/cards/index.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | -------------------------------------------------------------------------------- /pages/about.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | -------------------------------------------------------------------------------- /themes/theme8.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Classic Blog', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , //'/posts?$sort[createdAt]=-1&$limit=4' }, 9 | { type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , // '/posts?$sort[createdAt]=-1&$limit=4' }, 10 | { type: 'api' , name: 'services' , api : 'http://localhost:3030/sections?type=services' }, 11 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 12 | } 13 | ], 14 | 15 | navigation : [{ 16 | css : "items-start font-serif w-full pt-16 px-4 pb-20 bg-white shadow-lg h-screen", 17 | button : "m-1 bg-white p-2 border-black border-2 rounded-full", 18 | line : "hover:text-black hover:bg-white text-grey" , 19 | link : 'font-serif text-black hover:text-grey-dark hover:text-bold py-10 px-4 no-underline', 20 | left : false, 21 | transition: 'slideright', 22 | orientation: 'horizontal' , 23 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'} ] 24 | }], 25 | template: { 26 | main : { 27 | css : "w-full flex flex-wrap font-serif", 28 | 29 | }, 30 | areas: { 31 | order : ['header','aside' , 'content', 'footer'], 32 | header : { 33 | root: 'w-full flex flex-wrap', 34 | blocks : [ 35 | 36 | { 37 | css: 'w-full h-24 justify-center flex items-center col bg-white font-serif' , 38 | elements : [ 39 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 40 | ], 41 | homepage: false 42 | }, 43 | { 44 | css: 'w-full h-24 justify-center flex items-center col bg-white font-serif border-b mb-4 mobile' , 45 | elements : [ 46 | { type: 'menu' , navigation: 0, homepage: false} 47 | ] 48 | }, 49 | 50 | 51 | { 52 | css: 'w-full h-64 bg-header-9 mx-8', 53 | elements: [ 54 | { type: 'html' , content: ''} 55 | ], 56 | homepage: true 57 | } 58 | ] 59 | }, 60 | content : { 61 | root: 'w-full md:w-3/4 lg:w-3/4 shadow-lg flex flex-wrap', 62 | blocks : [ 63 | { 64 | css: 'w-full flex items-start', 65 | elements: [ 66 | { type: 'html' , content: '

Hello this is my Classic Blog Theme

Helping you to create your theme

Learn how to create a theme for Nuxt with a single configuration file.

' }, 67 | ], 68 | homepage: true 69 | }, 70 | { 71 | css: 'w-full flex items-start', 72 | elements: [ 73 | { type: 'html' , content: '' , nuxt: true }, 74 | ], 75 | homepage: false 76 | }, 77 | { 78 | css: 'w-1/2 flex items-center justify-center', 79 | elements: [ 80 | { type: 'component' , component: 'core/skills' , options: { data: 'skills' , color:'bg-red' } }, 81 | ], 82 | homepage: true 83 | }, 84 | 85 | 86 | ] 87 | }, 88 | aside : { 89 | root: 'w-full md:w-1/4 lg:w-1/4 flex-row items-start', 90 | blocks : [ 91 | { 92 | css: 'w-full pt-8 px-8', 93 | elements: [ 94 | { type: 'html' , content: '

Helping you to create your theme

Learn how to create a theme for Nuxt with a single configuration file.

' }, 95 | ], 96 | homepage: false 97 | }, 98 | 99 | { 100 | css: 'w-full flex pt-8 px-8 leading-loose', 101 | elements: [ 102 | { type: 'html' , content: '

Tipography

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
' }, 103 | ], 104 | homepage: false 105 | }, 106 | { 107 | css: 'w-full flex pt-8 px-8', 108 | elements: [ 109 | { type: 'html' , content: '

Bullet list

\ 110 |

Ordered list

  1. List 1
  2. List 2
  3. List 3
' }, 111 | ], 112 | homepage: false 113 | }, 114 | ] 115 | }, 116 | footer : { 117 | root : 'w-full', 118 | blocks : [ 119 | { 120 | css: 'h-16 items-center flex justify-center col-span-4 text-center text-grey-dark text-sm border-t' , 121 | elements : [ 122 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , } 123 | ], 124 | homepage: false 125 | } 126 | ] 127 | } 128 | }, 129 | } 130 | 131 | } 132 | 133 | export default layout -------------------------------------------------------------------------------- /themes/index.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Corporate Business', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | license : 'MIT' , 6 | root : 'w-full flex flex-wrap min-h-screen', 7 | homepage : '/', 8 | initData : [ 9 | //{ type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , 10 | //{ type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , 11 | { type: 'array' , name: 'services' , value : [ 12 | {"type":"services", 13 | "title":"CSS Only", 14 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework", 15 | "path":"css-only", 16 | "_id":"0tSvdJebN4cKmKa6", 17 | "icon":"style"}, 18 | {"type":"services", 19 | "title":"Custom Design", 20 | "abstract":"Create your custom theme without any opinionated framework", 21 | "icon":"chrome_reader_mode", 22 | "path":"theme-builder", 23 | "_id":"MSOXCaCn4AfNz57w"}, 24 | {"type":"services", 25 | "title":"Integration", 26 | "abstract":"Feel free to use your own components, API and data", 27 | "path":"api-data", 28 | "_id":"ueN9BbEdxvKoZWNi" 29 | ,"icon":"compare_arrows"} 30 | ] }, 31 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 32 | } 33 | ], 34 | 35 | 36 | navigation : [{ 37 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen", 38 | button : "m-1 bg-white p-2 border-black border-2 rounded-full", 39 | line : "hover:text-black hover:bg-white text-grey-lightest" , 40 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline', 41 | left : false, 42 | transition: 'slideright', 43 | orientation : 'horizontal' , 44 | items : [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'}] 45 | }], 46 | template: { 47 | main : { 48 | css : "w-full", 49 | }, 50 | areas: { 51 | order : ['header','content','footer'], 52 | header : { 53 | root: 'w-full flex flex-wrap', 54 | blocks : [ 55 | { 56 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 57 | elements: [ 58 | { type: 'html' , content: 'theme4nuxt@moodgiver.com' } 59 | ], 60 | homepage: false 61 | }, 62 | { 63 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 64 | elements: [ 65 | { type: 'html' , content: '+1 123 456 7890' } 66 | ], 67 | homepage: false 68 | }, 69 | { 70 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' , 71 | elements : [ 72 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 73 | ], 74 | homepage: false 75 | }, 76 | { 77 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 78 | elements : [ 79 | { type: 'menu' , navigation: 0, homepage: false} 80 | ] 81 | }, 82 | 83 | 84 | { 85 | css: 'w-full bg-green-light flex h-128 items-center p-8 -mt-24 bg-header-8', 86 | 87 | elements: [ 88 | { type: 'html' , content: '

Theme4Nuxt

A solution to prototype or create themes for Nuxt using tailwind.css framework

' , action: '/howto'} 89 | ], 90 | homepage: true 91 | } 92 | 93 | ] 94 | }, 95 | content : { 96 | root: 'w-full flex flex-wrap', 97 | blocks : [ 98 | { 99 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6', 100 | elements: [ 101 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } }, 102 | ], 103 | homepage: true 104 | }, 105 | 106 | { 107 | css: 'w-1/2 flex items-center gradient-blue-green h-64 text-white py-12 px-8 justify-center', 108 | elements: [ 109 | { type: 'html' , content: '

Helping you to create your theme

Learn how to create a theme for Nuxt with a single configuration file.

' , homepage: true }, 110 | ], 111 | homepage: true 112 | }, 113 | 114 | { 115 | css: 'w-1/2 flex items-center gradient-blue-green h-64 text-grey-dark py-12 justify-center', 116 | elements: [ 117 | { type: 'html' , content: '' , homepage: true }, 118 | ], 119 | homepage: true 120 | }, 121 | 122 | { 123 | css: 'w-full flex flex-wrap mt-4', 124 | elements : [ 125 | { type: 'component' , name: 'v-coreCards' , component: 'core/cards' , options: { contest: 'info' } , data: [] , homepage: true , nuxt: true } 126 | ] 127 | }, 128 | 129 | 130 | ] 131 | }, 132 | footer : { 133 | root : 'w-full', 134 | blocks : [ 135 | { 136 | css: 'h-16 items-center flex justify-center col-span-4 bg-black text-center text-white' , 137 | elements : [ 138 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 139 | ] 140 | } 141 | ] 142 | } 143 | }, 144 | }, 145 | extra: { 146 | html : '
Corporate Business Theme 0.2.0
' 147 | } 148 | 149 | } 150 | 151 | export default layout -------------------------------------------------------------------------------- /themes/theme3.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'SOHO Business', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' }, 9 | { type: 'api' , name: 'services' , api : '/sections?type=services' }, 10 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 11 | } 12 | ], 13 | 14 | navigation : [{ 15 | css : "items-start w-full z-50 pt-16 pl-8 pb-20 bg-red clipped-tag-down rounded-bl-lg", 16 | button : "m-4 bg-red text-white p-4 border-red-light border-2 rounded-full", 17 | line : "hover:text-black hover:bg-red-light text-white border-b border-red-light" , 18 | link : 'text-grey hover:text-black px-4 no-underline', 19 | left : false, 20 | transition : 'slidedown', 21 | orientation: 'horizontal' , 22 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'}] 23 | }], 24 | template: { 25 | main : { 26 | css : "w-full bg-black", 27 | 28 | }, 29 | areas: { 30 | order : ['header','content','footer'], 31 | header : { 32 | root: 'w-full flex flex-wrap', 33 | blocks : [ 34 | 35 | { 36 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-24 flex col z-30 bg-white border-b border-red items-center justify-center' , 37 | elements : [ 38 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 39 | ] 40 | }, 41 | { 42 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-24 col z-30 bg-white justify-end items-center flex text-right pr-24 col-nav border-b border-red mobile' , 43 | elements : [ 44 | { type: 'menu' , navigation: 0, homepage: false} 45 | ] 46 | }, 47 | 48 | 49 | ] 50 | }, 51 | content : { 52 | root: 'w-full flex flex-wrap', 53 | blocks : [ 54 | { 55 | css: 'w-full', 56 | elements: [ 57 | { type: 'css' , content: 'bg-header-4 h-screen z-back -mt-24' , homepage: true } 58 | ], 59 | homepage: true 60 | }, 61 | { 62 | css: 'w-full bg-black text-grey-dark pb-24', 63 | elements: [ 64 | { type: 'component' , component: 'core/services' , options: { data: 'services' } , homepage: true }, 65 | ], 66 | homepage: true 67 | }, 68 | { 69 | css : 'w-full -mt-12 lg:-mt-24', 70 | elements : [ 71 | { type: 'html' , content : '' 72 | } 73 | ], 74 | homepage: true 75 | }, 76 | { 77 | css: 'w-full pt-12 -mt-1 bg-white', 78 | elements : [ 79 | { type: 'html' , content: '

Blog

' , homepage: true }, 80 | 81 | { type: 'component' , component: 'posts' , options: { data: 'info' } , homepage: true }, 82 | 83 | { type: 'html' , content: '

News

' , homepage: true }, 84 | { type: 'component' , component: 'posts' , options: { data: 'info' } , homepage: true , nuxt: true} 85 | ], 86 | }, 87 | 88 | ] 89 | }, 90 | footer : { 91 | root : 'w-full', 92 | blocks : [ 93 | { 94 | css: 'h-16 items-center flex justify-center col-span-4 bg-red text-center text-white' , 95 | elements : [ 96 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 97 | ] 98 | } 99 | ] 100 | } 101 | }, 102 | } 103 | /* 104 | template: { 105 | main : { 106 | css : "w-full grid columns-4 rows-5", 107 | 108 | }, 109 | grid : [ 110 | 'h-16 bg-red col' , 111 | 'h-16 col col-span-3 justify-end text-right pr-4 bg-red' , 112 | 'z-back h-screen bg-header-1 -mt-16 col-span-4' , 113 | 'col-span-4 sm:px-8 px-8 bg-black' , 114 | 'row-span-2 p-4 bg-black w-full' , 115 | 'row-span-2 bg-black col-span-2' , 116 | 'row-span-2 px-4 bg-black text-white' , 117 | 'h-16 items-center border-t-4 border-red flex justify-center col-span-4 bg-grey-darkest text-center text-grey' 118 | ], 119 | blocks : [ 120 | [{ type: 'html' , content: '

Theme4Nuxt

' }], 121 | [{ type: 'nav' , navigation: 0 }], 122 | [{ type: 'html' , content: ''}], 123 | [{ type: 'component' , name: 'v-coreServices' , title: '' , css: 'bg-red-light shadow icon-rounded rounded text-white px-8 sm:px-16 -mt-16' , data : 'services' , api: 'services' } ], 124 | [{ type: 'html' , content: '' } ], 125 | [{ type: 'component' , name: 'v-coreTiles' , data: 'posts' , nuxt: true }], 126 | [{ type: 'component' , name: 'v-coreSkills' , data: 'skills' }], 127 | [{ type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' }] 128 | ] 129 | }, 130 | extra :{ 131 | 132 | } 133 | */ 134 | } 135 | 136 | export default layout -------------------------------------------------------------------------------- /themes/theme7.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Corporate Business', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | license : 'MIT' , 6 | root : 'w-full flex flex-wrap min-h-screen', 7 | homepage : '/', 8 | initData : [ 9 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , 10 | { type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , 11 | { type: 'array' , name: 'services' , value : [ 12 | {"type":"services", 13 | "title":"CSS Only", 14 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework", 15 | "path":"css-only", 16 | "_id":"0tSvdJebN4cKmKa6", 17 | "icon":"style"}, 18 | {"type":"services", 19 | "title":"Custom Design", 20 | "abstract":"Create your custom theme without any opinionated framework", 21 | "icon":"chrome_reader_mode", 22 | "path":"theme-builder", 23 | "_id":"MSOXCaCn4AfNz57w"}, 24 | {"type":"services", 25 | "title":"Integration", 26 | "abstract":"Feel free to use your own components, API and data", 27 | "path":"api-data", 28 | "_id":"ueN9BbEdxvKoZWNi" 29 | ,"icon":"compare_arrows"} 30 | ] }, 31 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 32 | } 33 | ], 34 | 35 | 36 | navigation : [{ 37 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen", 38 | button : "m-1 bg-white p-2 border-black border-2 rounded-full", 39 | line : "hover:text-black hover:bg-white text-grey-lightest" , 40 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline', 41 | left : false, 42 | transition: 'slideright', 43 | orientation : 'horizontal' , 44 | items : [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'} ] 45 | }], 46 | template: { 47 | main : { 48 | css : "w-full", 49 | }, 50 | areas: { 51 | order : ['header','content','footer'], 52 | header : { 53 | root: 'w-full flex flex-wrap', 54 | blocks : [ 55 | { 56 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 57 | elements: [ 58 | { type: 'html' , content: 'theme4nuxt@moodgiver.com' } 59 | ], 60 | homepage: false 61 | }, 62 | { 63 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 64 | elements: [ 65 | { type: 'html' , content: '+1 123 456 7890' } 66 | ], 67 | homepage: false 68 | }, 69 | { 70 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' , 71 | elements : [ 72 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 73 | ], 74 | homepage: false 75 | }, 76 | { 77 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 78 | elements : [ 79 | { type: 'menu' , navigation: 0, homepage: false} 80 | ] 81 | }, 82 | 83 | 84 | { 85 | css: 'w-full bg-green-light flex h-128 items-center p-8 -mt-24 bg-header-8', 86 | 87 | elements: [ 88 | { type: 'html' , content: '

Theme4Nuxt

A solution to prototype or create themes for Nuxt using tailwind.css framework

' , action: '/howto'} 89 | ], 90 | homepage: true 91 | } 92 | 93 | ] 94 | }, 95 | content : { 96 | root: 'w-full flex flex-wrap', 97 | blocks : [ 98 | { 99 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6', 100 | elements: [ 101 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' , box: 'bg-white rounded py-8 px-4 h-full shadow-lg' } }, 102 | ], 103 | homepage: true 104 | }, 105 | 106 | { 107 | css: 'w-1/2 flex items-center gradient-blue-green h-64 text-white py-12 px-8 justify-center', 108 | elements: [ 109 | { type: 'html' , content: '

Helping you to create your theme

Learn how to create a theme for Nuxt with a single configuration file.

' , homepage: true }, 110 | ], 111 | homepage: true 112 | }, 113 | 114 | { 115 | css: 'w-1/2 flex items-center gradient-blue-green h-64 text-grey-dark py-12 justify-center', 116 | elements: [ 117 | { type: 'html' , content: '' , homepage: true }, 118 | ], 119 | homepage: true 120 | }, 121 | { 122 | css: 'w-full shadow my-8', 123 | elements: [ 124 | { type: 'component' , component: 'core/prices' , 125 | options: { 126 | data : 'prices' , 127 | style : "px-8 scale-1", 128 | title : '

Pricing

' , 129 | css : 'rounded-t border h-64 bg-white hover:shadow-lg text-center text-grey-darkest p-4 pb-8', 130 | action : 'bg-white border-l border-r border-b rounded-b flex items-center justify-center', 131 | button : 'm-4 py-2 px-4 bg-green-light hover:bg-green text-white rounded', 132 | } 133 | }, 134 | ], 135 | homepage: true 136 | }, 137 | { 138 | css: 'w-full flex flex-wrap mt-4', 139 | elements : [ 140 | { type: 'component' , name: 'v-coreCards' , component: 'core/cards' , options: { contest: 'info' } , data: [] , homepage: true , nuxt: true } 141 | ] 142 | }, 143 | 144 | 145 | ] 146 | }, 147 | footer : { 148 | root : 'w-full', 149 | blocks : [ 150 | { 151 | css: 'h-16 items-center flex justify-center col-span-4 bg-black text-center text-white' , 152 | elements : [ 153 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 154 | ] 155 | } 156 | ] 157 | } 158 | }, 159 | }, 160 | extra: { 161 | html : '
Corporate Business Theme 0.2.0
' 162 | } 163 | 164 | } 165 | 166 | export default layout -------------------------------------------------------------------------------- /assets/css/theme.css: -------------------------------------------------------------------------------- 1 | .bg-header-0 { 2 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/smoke-png-541.png') no-repeat; 3 | background-size: cover; 4 | } 5 | 6 | .bg-header-1 { 7 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg1.jpg') no-repeat; 8 | background-size: cover; 9 | } 10 | 11 | .bg-header-2 { 12 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-3.jpg') no-repeat; 13 | background-size: cover; 14 | } 15 | 16 | .bg-header-3 { 17 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-5.jpg') no-repeat center center; 18 | background-size: cover; 19 | } 20 | 21 | .bg-header-4 { 22 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-4.jpg') no-repeat center center; 23 | background-size: cover; 24 | } 25 | 26 | 27 | .bg-header-5 { 28 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-6.jpg') no-repeat center center; 29 | background-size: cover; 30 | } 31 | 32 | .bg-theme-3 { 33 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/small/theme4nuxt-theme-3.jpg') no-repeat center center; 34 | background-size: cover; 35 | } 36 | 37 | .bg-header-7 { 38 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-7.jpg') no-repeat center center; 39 | background-size: cover; 40 | } 41 | 42 | .bg-header-8 { 43 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-8.jpg') no-repeat center center; 44 | background-size: cover; 45 | } 46 | 47 | .bg-header-9 { 48 | background: url('https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-9.jpg') no-repeat center center; 49 | background-size: cover; 50 | } 51 | 52 | .h-80 { 53 | height:20rem; 54 | } 55 | .h-96 { 56 | height:24rem; 57 | } 58 | 59 | .h-128 { 60 | height:32rem; 61 | } 62 | 63 | .clipped-menu { 64 | -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 18% 100%, 0 81%); 65 | clip-path: polygon(0 0, 100% 0, 100% 100%, 18% 100%, 0 81%); 66 | 67 | } 68 | 69 | 70 | .clipped-menu-right { 71 | -webkit-clip-path: polygon(0 0, 100% 0, 100% 81%, 81% 100%, 0 100%); 72 | clip-path: polygon(0 0, 100% 0, 100% 81%, 81% 100%, 0 100%); 73 | } 74 | 75 | .clipped-right-point { 76 | -webkit-clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%); 77 | clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%); 78 | } 79 | 80 | .clipped-left-point { 81 | -webkit-clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 25% 100%, 0% 50%); 82 | clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 25% 100%, 0% 50%); 83 | } 84 | 85 | .clipped-tag-down { 86 | -webkit-clip-path: polygon(50% 0%, 100% 0, 100% 100%, 51% 84%, 0 100%, 0 0); 87 | clip-path: polygon(50% 0%, 100% 0, 100% 100%, 51% 84%, 0 100%, 0 0); 88 | } 89 | 90 | .clipped-circle-left { 91 | -webkit-clip-path: circle(92.6% at 26% 0); 92 | clip-path: circle(92.6% at 26% 0); 93 | } 94 | 95 | .clipped-zig-zag { 96 | -webkit-clip-path: polygon(35% 33%, 70% 12%, 100% 32%, 100% 93%, 66% 75%, 38% 93%, 0 68%, 0 13%); 97 | clip-path: polygon(35% 33%, 70% 12%, 100% 32%, 100% 93%, 66% 75%, 38% 93%, 0 68%, 0 13%); 98 | } 99 | 100 | .clipped-angle-right { 101 | clip-path: polygon(0 0, 100% 0, 100% 94%, 0% 100%); 102 | } 103 | 104 | .clipped-angle-right-lg { 105 | clip-path: polygon(0 0, 100% 0, 100% 64%, 0% 100%); 106 | } 107 | 108 | .clipped-angle-left { 109 | clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 94%); 110 | } 111 | 112 | .clipped-angle-left-lg { 113 | clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 64%); 114 | } 115 | 116 | .clipped-angle-up-right { 117 | clip-path: polygon(0 36%, 100% 0, 100% 100%, 0 100%); 118 | } 119 | .clipped-arrow-left { 120 | -webkit-clip-path: polygon(14% 0, 100% 0, 100% 100%, 14% 99%, 0 50%); 121 | clip-path: polygon(14% 0, 100% 0, 100% 100%, 14% 99%, 0 50%); 122 | } 123 | 124 | .clipped-arrow-down { 125 | -webkit-clip-path: polygon(17% 0, 83% 0, 83% 59%, 100% 60%, 50% 100%, 0% 60%, 17% 60%); 126 | clip-path: polygon(17% 0, 83% 0, 83% 59%, 100% 60%, 50% 100%, 0% 60%, 17% 60%); 127 | } 128 | 129 | .clipped-next { 130 | -webkit-clip-path: polygon(0 40%, 0 0, 100% 0, 100% 100%, 70% 100%, 0 100%, 0 60%, 3% 50%); 131 | clip-path: polygon(0 40%, 0 0, 100% 0, 100% 100%, 70% 100%, 0 100%, 0 60%, 3% 50%); 132 | } 133 | .clipped-half-down { 134 | -webkit-clip-path: polygon(40% 0%, 40% 20%, 100% 20%, 100% 80%, 40% 80%, 40% 100%, 0% 50%); 135 | clip-path: polygon(40% 0%, 40% 20%, 100% 20%, 100% 80%, 40% 80%, 40% 100%, 0% 50%); 136 | 137 | transition: all 750ms ease-in-out 138 | 139 | } 140 | .slide-enter-active { 141 | transition: transform .8s ease-in-out; 142 | } 143 | 144 | .slide-leave-active { 145 | transition: transform .8s ease-in-out; 146 | } 147 | 148 | .slide-enter-to, .slide-leave { 149 | /*max-height: 100%;*/ 150 | overflow: hidden; 151 | opacity:1; 152 | } 153 | 154 | .slide-enter, .slide-leave-to { 155 | overflow: hidden; 156 | /*max-height: 0;*/ 157 | opacity:0; 158 | } 159 | 160 | /*---------------------------*/ 161 | 162 | .slideleft-enter-active { 163 | transition: transform .8s ease-in-out; 164 | } 165 | 166 | .slideleft-leave-active { 167 | transition: transform .8s ease-in-out; 168 | } 169 | 170 | .slideleft-enter-to, .slideleft-leave { 171 | transform: translate(0%, 0); 172 | overflow: hidden; 173 | } 174 | 175 | .slideleft-enter, .slideleft-leave-to { 176 | transform: translate(-100%, 0); 177 | margin-right: 0; 178 | } 179 | 180 | /*----------------------------*/ 181 | 182 | /*---------------------------*/ 183 | 184 | .slideright-enter-active { 185 | transition: transform .8s ease-in-out; 186 | } 187 | 188 | .slideright-leave-active { 189 | transition: transform .8s ease-in-out; 190 | } 191 | 192 | .slideright-enter-to, .slideright-leave { 193 | transform: translate(0%, 0); 194 | overflow: hidden; 195 | } 196 | 197 | .slideright-enter, .slideright-leave-to { 198 | transform: translate(100%, 0); 199 | margin-right: 0; 200 | } 201 | 202 | /*----------------------------*/ 203 | 204 | .flip { 205 | transition: transform .5s ease-in-out; 206 | transform: rotateY(0deg); 207 | } 208 | 209 | .flip > div { 210 | transform: rotateY(180deg); 211 | width:100%; 212 | height:100%; 213 | opacity:0; 214 | } 215 | 216 | .flip:hover { 217 | transition: transform .8s ease-in-out; 218 | transform: rotateY(180deg); 219 | opacity:1 220 | } 221 | 222 | .flip:hover > div { 223 | transition: transform .8s ease-in-out; 224 | transform: rotateY(180deg); 225 | opacity:1 226 | } 227 | 228 | .slidedown > div { 229 | transition: transform .8s ease-in-out; 230 | transform: translate(0,-100%); 231 | opacity:0; 232 | } 233 | 234 | .slidedown:hover > div { 235 | transition: transform .8s ease-in-out; 236 | transform: translate(0,0); 237 | min-width:100%; 238 | opacity:1; 239 | } 240 | 241 | .scale-1 { 242 | transition: transform .2s ease-in-out; 243 | transform: scale(1,1); 244 | z-index:1; 245 | } 246 | 247 | .scale-1:hover { 248 | transition: transform .2s ease-in-out; 249 | transform: scale(1.2,1.2); 250 | z-index:10; 251 | } 252 | 253 | .submenu > div { 254 | opacity:0; 255 | } 256 | 257 | .submenu:hover > div { 258 | opacity:1; 259 | } 260 | 261 | /*---------------------------*/ 262 | 263 | .slidedown-enter-active { 264 | transition: transform .8s ease-in-out; 265 | } 266 | 267 | .slidedown-leave-active { 268 | transition: transform .8s ease-in-out; 269 | } 270 | 271 | .slidedown-enter-to, .slidedown-leave { 272 | transform: translate(0, 0); 273 | overflow: hidden; 274 | } 275 | 276 | .slidedown-enter, .slidedown-leave-to { 277 | transform: translate(0, -100%); 278 | margin-right: 0; 279 | } 280 | 281 | /*----------------------------*/ 282 | 283 | /*---------------------------*/ 284 | .w-translate-center { 285 | margin:0 auto; 286 | position:absolute; 287 | transform: translate(-50%,0); 288 | } 289 | 290 | @media screen and (max-width: 576px){ 291 | .w-translate-center { 292 | transform: translate(0,0); 293 | } 294 | } 295 | .slidedowncenter-enter-active { 296 | transition: transform .8s ease-in-out; 297 | } 298 | 299 | .slidedowncenter-leave-active { 300 | transition: transform .8s ease-in-out; 301 | } 302 | 303 | .slidedowncenter-enter-to, .slidedowncenter-leave { 304 | transform: translate(-50%, 0); 305 | overflow: hidden; 306 | } 307 | 308 | .slidedowncenter-enter, .slidedowncenter-leave-to { 309 | transform: translate(-50%,-100%); 310 | overflow:hidden; 311 | } 312 | 313 | /*----------------------------*/ 314 | 315 | 316 | .rotate-enter-active { 317 | transition: transform .8s ease-in-out; 318 | } 319 | .rotate-leave-active { 320 | transition: transform 0.8s ease-in-out; 321 | } 322 | 323 | .rotate-enter-to, .rotate-leave { 324 | transform:rotate(360deg); 325 | } 326 | 327 | .rotate-enter , .rotate-leave-to { 328 | max-width:0px; 329 | max-height:0px; 330 | transform:rotate(0deg); 331 | } 332 | 333 | .gradient-blue { 334 | background-color: #667eea; 335 | background-image: linear-gradient(to bottom, #00c6fb, #005bea) 336 | } 337 | 338 | 339 | .gradient-blue-dark { 340 | background-color: #455ab9; 341 | background-image: linear-gradient(to bottom, #455ab9, #012e77) 342 | } 343 | 344 | .gradient-blue-green { 345 | background-color: #179489; 346 | background-image: linear-gradient(to bottom, #179489, #005d81) 347 | } 348 | 349 | .gradient-green { 350 | background-color: #66ea9d; 351 | background-image: linear-gradient(to bottom, #66ea9d, #20b40c) 352 | } 353 | 354 | @media screen and (max-width: 640px){ 355 | .mobile { 356 | display:none; 357 | } 358 | } 359 | 360 | .h-full-calc-1-4 { 361 | min-height: calc(100vh*.25); 362 | } 363 | 364 | .h-full-calc-1-2 { 365 | min-height: calc(100vh*.50); 366 | } 367 | -------------------------------------------------------------------------------- /themes/theme4.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Angle e-commerce', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , //'/posts?$sort[createdAt]=-1&$limit=4' }, 9 | { type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , // '/posts?$sort[createdAt]=-1&$limit=4' }, 10 | { type: 'api' , name: 'services' , api : 'http://localhost:3030/sections?type=services' }, 11 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 12 | } 13 | ], 14 | 15 | navigation : [{ 16 | css : "items-start w-full pt-16 px-2 pb-20 bg-green-light clipped-angle-left", 17 | button : "m-4 bg-white p-4 border-black border-2 rounded-full", 18 | line : "hover:text-black hover:bg-green-lighter text-grey-lightest" , 19 | link : 'text-white hover:text-white hover:bg-black rounded hover:text-bold py-2 px-4 no-underline', 20 | left : false, 21 | transition: 'slidedown', 22 | orientation: 'horizontal' , 23 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'}] 24 | }], 25 | template: { 26 | main : { 27 | css : "w-full", 28 | 29 | }, 30 | areas: { 31 | order : ['header','content','footer'], 32 | header : { 33 | root: 'w-full flex flex-wrap', 34 | blocks : [ 35 | 36 | 37 | 38 | { 39 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-24 flex items-center col bg-green-light' , 40 | elements : [ 41 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 42 | ], 43 | homepage: false 44 | }, 45 | { 46 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-green-light mobile' , 47 | elements : [ 48 | { type: 'menu' , navigation: 0, homepage: false} 49 | ] 50 | }, 51 | 52 | 53 | { 54 | css: 'w-full bg-green-light h-32 clipped-angle-left-lg', 55 | 56 | elements: [ 57 | { type: 'html' , content: ''} 58 | ] 59 | } 60 | ] 61 | }, 62 | content : { 63 | root: 'w-full flex flex-wrap', 64 | blocks : [ 65 | 66 | { 67 | css: 'w-full flex flex-wrap justify-center', 68 | elements : [ 69 | { type: 'component' , component: 'core/cards' , options: { contest: 'products' }, homepage: true , nuxt: true } 70 | ] 71 | }, 72 | 73 | 74 | { 75 | css: 'w-full bg-green-light h-32 clipped-angle-up-right', 76 | 77 | elements: [ 78 | { type: 'html' , content: ''} 79 | ] 80 | }, 81 | 82 | 83 | { 84 | css: 'w-full flex items-center justify-center h-48 pt-8 -mt-2 bg-green-light', 85 | elements: [ 86 | { type: 'html' , content: '

Do you need a theme solution for Nuxt?

Theme4Nuxt

' , homepage: true } 87 | ], 88 | homepage: true 89 | }, 90 | { 91 | css: 'w-full bg-green-light text-grey-light shadow', 92 | elements: [ 93 | { type: 'component' , component: 'core/services' , options : { data: 'services' , single: 'h-full py-8 shadow-lg px-4 bg-blue-dark rounded'} , title: 'Features' , homepage: true }, 94 | ], 95 | homepage: true 96 | }, 97 | /*{ 98 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 99 | elements : [ 100 | { type: 'html' , content: '

Blog

' , homepage: true }, 101 | //{ type: 'component' , name: 'v-posts' , data: 'info' , homepage: true }, 102 | ] 103 | }, 104 | { 105 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 106 | elements : [ 107 | 108 | 109 | { type: 'html' , content: '

News

' , homepage: true }, 110 | //{ type: 'component' , name: 'v-posts' , data: 'info' , homepage: true } 111 | ], 112 | }, 113 | */ 114 | 115 | ] 116 | }, 117 | footer : { 118 | root : 'w-full', 119 | blocks : [ 120 | { 121 | css: 'h-16 items-center flex justify-center col-span-4 bg-green-light text-center text-white' , 122 | elements : [ 123 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 124 | ] 125 | } 126 | ] 127 | } 128 | }, 129 | } 130 | /* 131 | template: { 132 | main : { 133 | css : "w-full grid columns-4 rows-5", 134 | 135 | }, 136 | grid : [ 137 | 'h-16 bg-red' , 138 | 'h-16 bg-red col col-span-2 flex items-center justify-center' , 139 | 'h-16 bg-red col', 140 | 'col-span-4' , 141 | 'row-span-2 col-span-4 p-12' , 142 | 'row-span-2 p-12 col-span-2' , 143 | 'row-span-2 p-12 col-span-2' , 144 | 'h-16 items-center flex justify-center col-span-4 bg-grey-light' 145 | ], 146 | blocks : [ 147 | [{ type: 'html' , content: '

Theme4Nuxt

' ,homepage: false }], 148 | [{ type: 'menu' , navigation: 0, homepage: false}], 149 | [{ type: 'nav' , navigation: 0, homepage: false}], 150 | [{ type: 'html' , content: '
\ 151 |
\ 152 |

Need a theme for Nuxt?\ 153 |

Discover how to create themes for Nuxt

\ 154 |

A creative way to design your theme for Nuxt.

\ 155 |

It\' easy, fast and replicable.

\ 156 | \ 157 | \ 158 |
' , action: '/howto' , homepage: true }], 159 | [ 160 | { type: 'component' , name: 'v-coreServices' , title: '' , css: 'bg-red-light shadow icon-rounded rounded text-white px-8 -mt-16' , data : 'services' , api: 'services' , homepage: true } 161 | ] , 162 | [ 163 | { type: 'component' , name: 'v-posts' , data: 'info' , homepage: true , nuxt: true } , 164 | { type: 'component' , name: 'v-coreSkills' , data: 'skills' ,homepage: true} 165 | ], 166 | [ 167 | { type: 'component' , name: 'v-coreTiles' , data: 'posts' , homepage: true } 168 | ], 169 | [ 170 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' } 171 | ] 172 | ], 173 | nuxt: 'mt-4' 174 | }, 175 | 176 | extra: { 177 | html: '
\ 178 |
\ 179 |
\ 180 |
', 181 | action: '/howto' 182 | } 183 | */ 184 | } 185 | 186 | export default layout -------------------------------------------------------------------------------- /themes/theme6.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Tiles Landing Page', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , //'/posts?$sort[createdAt]=-1&$limit=4' }, 9 | { type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , // '/posts?$sort[createdAt]=-1&$limit=4' }, 10 | { type: 'api' , name: 'services' , api : 'http://localhost:3030/sections?type=services' }, 11 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 12 | } 13 | ], 14 | 15 | navigation : [{ 16 | css : "items-start w-full pt-16 pl-8 pb-20 bg-grey-dark clipped-angle-right", 17 | button : "m-4 bg-white p-4 border-black border-2 rounded-full", 18 | line : "hover:text-grey hover:bg-black text-grey-lightest" , 19 | link : 'text-white hover:text-white hover:bg-black rounded hover:text-bold py-2 px-4 no-underline', 20 | left : false, 21 | transition: 'slidedown', 22 | orientation: 'horizontal' , 23 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'} ] 24 | }], 25 | template: { 26 | main : { 27 | css : "w-full bg-black", 28 | 29 | }, 30 | areas: { 31 | order : ['header','content' ], 32 | header : { 33 | root: 'w-full flex flex-wrap', 34 | blocks : [ 35 | 36 | 37 | 38 | { 39 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 flex items-center col bg-black z-10' , 40 | elements : [ 41 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 42 | ], 43 | homepage: false 44 | }, 45 | { 46 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 flip col z-30 justify-left items-center flex bg-grey-darkest z-10 mobile' , 47 | elements: [ 48 | { type: 'html' , content: '

Home

' , action: '/'} 49 | ], 50 | homepage: false 51 | }, 52 | { 53 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 flip flex items-center col bg-black z-10 mobile' , 54 | elements: [ 55 | { type: 'html' , content: '

Blog

' , action: '/blog'} 56 | ], 57 | homepage: false 58 | }, 59 | { 60 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-header-3 z-10' , 61 | elements: [ 62 | { type: 'html' , content: ''} 63 | ], 64 | homepage: false 65 | }, 66 | 67 | ] 68 | }, 69 | content : { 70 | root: 'w-full flex flex-wrap', 71 | blocks : [ 72 | { 73 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-2 flex items-center bg-header-1 mobile' , 74 | elements: [ 75 | { type: 'css' , content: 'bg-header-1'} 76 | ], 77 | homepage: true 78 | }, 79 | { 80 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-full-calc-1-2 py-8 px-4 bg-header-2 z-10 mobile' , 81 | elements: [ 82 | { type: 'html' , content: '

Do you need a theme solution for Nuxt?

Theme4Nuxt

' , action: '/howto' } 83 | ], 84 | homepage: true 85 | }, 86 | { 87 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 flip flex items-center col bg-grey-darkest mobile' , 88 | elements: [ 89 | { type: 'html' , content: '

About

' , action: '/about'} 90 | ], 91 | homepage: false 92 | }, 93 | { 94 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 col z-30 justify-left items-center flex bg-header-5' , 95 | elements: [ 96 | { type: 'html' , content: ''} 97 | ], 98 | homepage: false 99 | }, 100 | { 101 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 slidedown text-center flex items-center col bg-grey-darkest mobile' , 102 | elements: [ 103 | { type: 'html' , content: '

How to

' , action: '/howto'} 104 | ], 105 | homepage: false 106 | }, 107 | { 108 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-full-calc-1-4 slidedown text-center flex items-center col bg-black mobile' , 109 | elements: [ 110 | { type: 'html' , content: '

Store

' , action: '/store'} 111 | ], 112 | homepage: false 113 | }, 114 | { 115 | css: 'w-full flex flex-wrap bg-white' , 116 | elements: [ 117 | { type: 'html' , content: '' , nuxt: true} 118 | ], 119 | homepage: false 120 | }, 121 | ] 122 | }, 123 | 124 | }, 125 | } 126 | /* 127 | template: { 128 | main : { 129 | css : "w-full grid columns-4 rows-5", 130 | 131 | }, 132 | grid : [ 133 | 'h-16 bg-red' , 134 | 'h-16 bg-red col col-span-2 flex items-center justify-center' , 135 | 'h-16 bg-red col', 136 | 'col-span-4' , 137 | 'row-span-2 col-span-4 p-12' , 138 | 'row-span-2 p-12 col-span-2' , 139 | 'row-span-2 p-12 col-span-2' , 140 | 'h-16 items-center flex justify-center col-span-4 bg-grey-light' 141 | ], 142 | blocks : [ 143 | [{ type: 'html' , content: '

Theme4Nuxt

' ,homepage: false }], 144 | [{ type: 'menu' , navigation: 0, homepage: false}], 145 | [{ type: 'nav' , navigation: 0, homepage: false}], 146 | [{ type: 'html' , content: '
\ 147 |
\ 148 |

Need a theme for Nuxt?\ 149 |

Discover how to create themes for Nuxt

\ 150 |

A creative way to design your theme for Nuxt.

\ 151 |

It\' easy, fast and replicable.

\ 152 | \ 153 | \ 154 |
' , action: '/howto' , homepage: true }], 155 | [ 156 | { type: 'component' , name: 'v-coreServices' , title: '' , css: 'bg-red-light shadow icon-rounded rounded text-white px-8 -mt-16' , data : 'services' , api: 'services' , homepage: true } 157 | ] , 158 | [ 159 | { type: 'component' , name: 'v-posts' , data: 'info' , homepage: true , nuxt: true } , 160 | { type: 'component' , name: 'v-coreSkills' , data: 'skills' ,homepage: true} 161 | ], 162 | [ 163 | { type: 'component' , name: 'v-coreTiles' , data: 'posts' , homepage: true } 164 | ], 165 | [ 166 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' } 167 | ] 168 | ], 169 | nuxt: 'mt-4' 170 | }, 171 | 172 | extra: { 173 | html: '
\ 174 |
\ 175 |
\ 176 |
', 177 | action: '/howto' 178 | } 179 | */ 180 | } 181 | 182 | export default layout -------------------------------------------------------------------------------- /layouts/theme.vue: -------------------------------------------------------------------------------- 1 | 208 | 284 | -------------------------------------------------------------------------------- /themes/theme1.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'Marine Theme', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { 9 | type : 'array' , 10 | 11 | name: 'prices', 12 | value: [ 13 | { 14 | title : '

Developer

', 15 | price : '

Free

', 16 | summary : '
Includes
', 17 | list : ['5 Projects','1 Member account', '1 Database' , '1 GB Hosting' ], 18 | button : 'Start' 19 | }, 20 | { 21 | title : '

Pro

', 22 | price : '

$ 9/mo.

', 23 | summary : '
Includes
', 24 | list : ['50 Projects','3 Member accounts', '10 Database' , '10 GB Hosting' ], 25 | button : 'Start' 26 | }, 27 | { 28 | title : '

Business

', 29 | price : '

$ 15/mo.

', 30 | summary : '
Includes
', 31 | list : ['5 Projects','1 Member account', '1 Database' , '1 GB Hosting' ], 32 | button : 'Start' 33 | }, 34 | { 35 | title : '

Agency

', 36 | price : '

$ 29/mo.

', 37 | summary : '
Includes
', 38 | list : ['50 Projects','3 Member accounts', '10 Database' , '10 GB Hosting' ], 39 | button : 'Start' 40 | }, 41 | ] 42 | } , 43 | { type: 'array' , name: 'services' , value : [ 44 | {"type":"services", 45 | "title":"CSS Only", 46 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework", 47 | "path":"css-only", 48 | "_id":"0tSvdJebN4cKmKa6", 49 | "icon":"style"}, 50 | {"type":"services", 51 | "title":"Custom Design", 52 | "abstract":"Create your custom theme without any opinionated framework", 53 | "icon":"chrome_reader_mode", 54 | "path":"theme-builder", 55 | "_id":"MSOXCaCn4AfNz57w"}, 56 | {"type":"services", 57 | "title":"Integration", 58 | "abstract":"Feel free to use your own components, API and data", 59 | "path":"api-data", 60 | "_id":"ueN9BbEdxvKoZWNi" 61 | ,"icon":"compare_arrows"} 62 | ] }, 63 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 64 | } 65 | ], 66 | 67 | navigation : [{ 68 | css : "items-start w-full pt-16 px-4 pb-20 bg-indigo rounded-bl-lg", 69 | button : "m-4 bg-white p-4 border-black border-2 rounded-full", 70 | line : "hover:text-black hover:bg-orange text-grey-lightest" , 71 | link : 'text-white hover:text-white hover:bg-indigo rounded hover:text-bold py-2 px-4 no-underline', 72 | left : false, 73 | bottom : false, 74 | transition : 'slidedown', 75 | orientation : 'horizontal' , 76 | items : [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'Store' , path: '/store' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'} ] 77 | }], 78 | template: { 79 | main : { 80 | css : "w-full", 81 | 82 | }, 83 | areas: { 84 | order : ['header','content','footer'], 85 | header : { 86 | root: 'w-full flex flex-wrap', 87 | blocks : [ 88 | 89 | { 90 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-24 flex items-center col bg-blue' , 91 | elements : [ 92 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 93 | ], 94 | homepage: false 95 | }, 96 | { 97 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-24 z-30 justify-left items-center flex pr-12 bg-blue mobile' , 98 | elements : [ 99 | { type: 'menu' , navigation: 0, homepage: false} 100 | ] 101 | }, 102 | { 103 | css: 'w-full flex items-center justify-center h-64 bg-blue', 104 | elements: [ 105 | { type: 'html' , content: '

Do you need a free theme solution for Nuxt?

Theme4Nuxt

' , action: '/howto' } 106 | ], 107 | homepage: true 108 | }, 109 | 110 | { 111 | css: 'w-full bg-white', 112 | 113 | elements: [ 114 | { type: 'html' , content: '\ 125 | \ 127 | \ 129 | \ 130 | \ 132 | image/svg+xml\ 133 | \ 135 | \ 136 | \ 137 | \ 138 | \ 139 | \ 142 | \ 146 | \ 147 | \ 149 | \ 150 | '} 151 | ] 152 | } 153 | ] 154 | }, 155 | content : { 156 | root: 'w-full flex flex-wrap', 157 | blocks : [ 158 | 159 | { 160 | css: 'w-full flex flex-wrap mt-4', 161 | elements : [ 162 | { type: 'component' , name: 'v-coreCards' , component: 'core/cards' , options: { contest: 'info' } , data: [] , homepage: true , nuxt: true } 163 | ] 164 | }, 165 | 166 | { 167 | css: 'w-full bg-blue-light text-blue-lighter shadow my-8', 168 | elements: [ 169 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } }, 170 | ], 171 | homepage: true 172 | }, 173 | { 174 | css: 'w-full shadow my-8', 175 | elements: [ 176 | { type: 'component' , component: 'core/prices' , 177 | options: { 178 | data : 'prices' , 179 | style : "px-8 scale-1", 180 | title : '

Pricing Table Component Demo

' , 181 | css : 'rounded-t border h-64 bg-white hover:shadow-lg text-center text-grey-darkest p-4 pb-8', 182 | action : 'bg-white border-l border-r border-b rounded-b flex items-center justify-center', 183 | button : 'btn bg-green-light hover:bg-green text-white rounded m-2', 184 | } 185 | }, 186 | ], 187 | homepage: true 188 | }, 189 | /* 190 | { 191 | css: "w-full h-64", 192 | elements: [ 193 | { type: 'component' , component: 'core/heading' , options: { css: 'object-cover h-64' , bg: 'https://storage.googleapis.com/ghostfood-539ae.appspot.com/theme4nuxt/bg-3.jpg'}} 194 | ] 195 | }, 196 | { 197 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 198 | elements : [ 199 | { type: 'html' , content: '

Blog

' , homepage: true }, 200 | { type: 'component' , component: 'posts' , options: { data: 'info' } } 201 | ], 202 | homepage: true 203 | }, 204 | 205 | { 206 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 207 | elements : [ 208 | 209 | 210 | { type: 'html' , content: '

News

' , homepage: true }, 211 | { type: 'component' , component: 'posts' , options: { data: 'info' } } 212 | ], 213 | homepage: true 214 | }, 215 | */ 216 | 217 | ] 218 | }, 219 | footer : { 220 | root : 'w-full', 221 | blocks : [ 222 | { 223 | css: 'h-16 items-center flex justify-center col-span-4 bg-blue-light text-center text-white' , 224 | elements : [ 225 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 226 | ] 227 | } 228 | ] 229 | } 230 | }, 231 | } 232 | /* 233 | template: { 234 | main : { 235 | css : "w-full grid columns-4 rows-5", 236 | 237 | }, 238 | grid : [ 239 | 'h-16 bg-red' , 240 | 'h-16 bg-red col col-span-2 flex items-center justify-center' , 241 | 'h-16 bg-red col', 242 | 'col-span-4' , 243 | 'row-span-2 col-span-4 p-12' , 244 | 'row-span-2 p-12 col-span-2' , 245 | 'row-span-2 p-12 col-span-2' , 246 | 'h-16 items-center flex justify-center col-span-4 bg-grey-light' 247 | ], 248 | blocks : [ 249 | [{ type: 'html' , content: '

Theme4Nuxt

' ,homepage: false }], 250 | [{ type: 'menu' , navigation: 0, homepage: false}], 251 | [{ type: 'nav' , navigation: 0, homepage: false}], 252 | [{ type: 'html' , content: '
\ 253 |
\ 254 |

Need a theme for Nuxt?\ 255 |

Discover how to create themes for Nuxt

\ 256 |

A creative way to design your theme for Nuxt.

\ 257 |

It\' easy, fast and replicable.

\ 258 | \ 259 | \ 260 |
' , action: '/howto' , homepage: true }], 261 | [ 262 | { type: 'component' , name: 'v-coreServices' , title: '' , css: 'bg-red-light shadow icon-rounded rounded text-white px-8 -mt-16' , data : 'services' , api: 'services' , homepage: true } 263 | ] , 264 | [ 265 | { type: 'component' , name: 'v-posts' , data: 'info' , homepage: true , nuxt: true } , 266 | { type: 'component' , name: 'v-coreSkills' , data: 'skills' ,homepage: true} 267 | ], 268 | [ 269 | { type: 'component' , name: 'v-coreTiles' , data: 'posts' , homepage: true } 270 | ], 271 | [ 272 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' } 273 | ] 274 | ], 275 | nuxt: 'mt-4' 276 | }, 277 | 278 | extra: { 279 | html: '
\ 280 |
\ 281 |
\ 282 |
', 283 | action: '/howto' 284 | } 285 | */ 286 | } 287 | 288 | export default layout -------------------------------------------------------------------------------- /pages/README.md: -------------------------------------------------------------------------------- 1 | # theme4nuxt 2 | 3 | 4 | Theme4Nuxt is a basic theming solution for Nuxtjs. I decided to develop it in order to have an easy way to prototype layouts/themes for Nuxt using a configuration file. 5 | 6 | Based only on `tailwind.css` framework is developed to give the possibility to create your custom design without any opinionated framework. 7 | 8 | # Features 9 | 10 | - custom design based on CSS only 11 | - fast theme/layout prototype 12 | - create html semantic elements (header,section,aside,footer) 13 | - easy full responsive design implementation 14 | - easy integration with existing 15 | - components 16 | - api 17 | - markdown pages 18 | - easy theme switching 19 | - homepage design 20 | - extra basic components included (used in this demo) 21 | - responsive navigation 22 | - progress bars 23 | - cards 24 | - features/services info box 25 | - call for action 26 | 27 | 28 | # How it works 29 | 30 | **Requirements** : tailwind.css 31 | 32 | 33 | Theme4Nuxt is based on the following: 34 | - a **theme** js file (./themes/index.js) 35 | - a **single vue** file to deploy the theme to be used as layout template (./layout/theme.vue) 36 | - a Vue **component wrapper** in order to integrate any component dynamically (./components/theme/ComponentWrapper.vue) 37 | - a Vue **navigation component** in order to create a navigation system (./components/theme/nav/index.vue) 38 | - a **theme4nuxt** plugin in order to preload data server side (./plugins/theme4nuxt.js) 39 | 40 | 41 | 42 | ## Theme file 43 | 44 | Create a `themes` folder in your project root. 45 | 46 | Create an `index.js` in the themes folder 47 | 48 | #### Structure of the theme 49 | 50 | Each theme configuration file has the following structure: 51 | 52 | 53 | - theme general info (name, author, version, license) 54 | - a **root** property with css classes. This is the main container of your theme 55 | - a **homepage** property with the path for the homepage 56 | - a **initData** array of objects representing the initial data to load at startup. Data can be **API** or **Array** 57 | - a **navigation** array of objects. You can define different navigations and then use in your templates. 58 | - a **template** the main object of your theme. 59 | 60 | 61 | ``` 62 | const theme = { 63 | name : 'Corporate Business', 64 | author : 'A. Nardone', 65 | version : '0.2.0', 66 | license : 'MIT' 67 | root : 'w-full flex flex-wrap min-h-screen', 68 | homepage : '/', 69 | ... 70 | } 71 | 72 | export default theme 73 | ``` 74 | ### initData Section ### 75 | The **initData** is where you can define which data has to be preloaded. 76 | 77 | They can be **API** or **arrays** of data, depends on your rendering functions/components. 78 | 79 | *The current theme is using some WordPress API to simulate the preloading feature* 80 | 81 | ``` 82 | initData : [ 83 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , 84 | { type: 'array' , name: 'services' , value : [ 85 | {"type":"services", 86 | "title":"CSS Only", 87 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework", 88 | "path":"css-only", 89 | "_id":"0tSvdJebN4cKmKa6", 90 | "icon":"style"}, 91 | {"type":"services", 92 | "title":"Custom Design", 93 | "abstract":"Create your custom theme without any opinionated framework", 94 | "icon":"chrome_reader_mode", 95 | "path":"theme-builder", 96 | "_id":"MSOXCaCn4AfNz57w"}, 97 | {"type":"services", 98 | "title":"Integration", 99 | "abstract":"Feel free to use your own components, API and data", 100 | "path":"api-data", 101 | "_id":"ueN9BbEdxvKoZWNi" 102 | ,"icon":"compare_arrows"} 103 | ] }, 104 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 105 | } 106 | ], 107 | ``` 108 | 109 | In case of API **axios** library will be used to fetch data (asyncronously) server side. 110 | 111 | **Data preloading is implemented using `nuxtServerInit` directly from the store.** 112 | 113 | file: ./store/index.js 114 | 115 | ``` 116 | ... 117 | async nuxtServerInit({commit}, context ){ 118 | //read theme configuration using $theme4nuxt() injected by ./plugins/index.js 119 | let init = context.app.$theme4nuxt().initData 120 | let data = {} 121 | //iterate thru all initial data to be loaded 122 | for ( var n=0 ; n < init.length ; n++ ){ 123 | if ( init[n].type === 'api' ) { 124 | let qry = await context.app.$axios.get(init[n].api); 125 | data[init[n].name] = qry.data 126 | } 127 | if ( init[n].type === 'array' ){ 128 | data[init[n].name] = init[n].value 129 | } 130 | } 131 | //save data to store 132 | commit ('init_data', data ) 133 | if ( !context.app.store.state.theme ){ 134 | commit ('theme',context.app.$theme4nuxt() ) 135 | } 136 | }, 137 | ... 138 | ``` 139 | 140 | **Preload theme and injext function to read initData configuration** 141 | 142 | file: ./plugins/index.js 143 | 144 | ``` 145 | import theme from '~/themes' 146 | 147 | export default ({ app }, inject) => { 148 | inject('theme4nuxt', () => theme) 149 | } 150 | ``` 151 | # The Theme # 152 | 153 | We analyze the current theme that has been used for this website. 154 | 155 | ### navigation Section ### 156 | 157 | The navigation section is required if you want to use the built-in navigation system as showed in the demo. This component create a responsive main navigation icon that open a menu with the options defined. 158 | 159 | The navigation section is also used in the template in order to render a normal navigation menu. 160 | In this version child menus are not supported. If you need this option you can use your component or navigation system. 161 | 162 | ``` 163 | ... 164 | navigation : [{ 165 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen", 166 | button : "m-1 bg-white p-2 border-black border-2 rounded-full", 167 | line : "hover:text-black hover:bg-white text-grey-lightest" , 168 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline', 169 | left : false, 170 | transition: 'slideright', 171 | orientation: 'horizontal' , 172 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } ] 173 | }], 174 | ... 175 | ``` 176 | 177 | ### template Section ### 178 | 179 | The **template** section is the core of the theming system and has 2 main objects 180 | - **main** 181 | - **areas** 182 | 183 | 184 | 185 | 186 | The ***main*** object 187 | 188 | The main object is where is defined the class of the main container and will generate a semantic **<main>** html element. 189 | ``` 190 | ... 191 | template: { 192 | main : { 193 | css : "w-full", 194 | 195 | }, 196 | ... 197 | ``` 198 | 199 | 200 | 201 | The **areas** object 202 | 203 | With the areas object you define all the elements of your template. 204 | 205 | First you can define the order of the area to be rendered as semantic html blocks. Available areas are: 206 | - header 207 | - aside 208 | - content (will be rendered as section) 209 | - footer 210 | 211 | **order is important in order to render elements correctly** 212 | 213 | 214 | ``` 215 | ... 216 | template: { 217 | ... 218 | areas: { 219 | order : ['header','content','footer'], 220 | ... 221 | ``` 222 | 223 | Our example will create a **header**, a **section** area and a **footer**. 224 | 225 | 226 | ### Creating the header ### 227 | 228 | ``` 229 | ... 230 | template: { 231 | ... 232 | areas: { 233 | areas: { 234 | order : ['header','content','footer'], 235 | header : { 236 | root: 'w-full flex flex-wrap', 237 | blocks : [ 238 | { 239 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 240 | elements: [ 241 | { type: 'html' , content: '\ 242 | theme4nuxt@moodgiver.com\ 243 | '} 244 | ] 245 | }, 246 | { 247 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 248 | elements: [ 249 | { type: 'html' , content: '\ 250 | +1 123 456 7890\ 251 | '} 252 | ] 253 | }, 254 | { 255 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' , 256 | elements : [ 257 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 258 | ], 259 | homepage: false 260 | }, 261 | { 262 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 263 | elements : [ 264 | { type: 'menu' , navigation: 0, homepage: false} 265 | ] 266 | }, 267 | { 268 | css: 'w-full bg-green-light h-128 -mt-24 bg-header-8', 269 | elements: [ 270 | { type: 'html' , content: ''} 271 | ], 272 | homepage: true 273 | } 274 | 275 | ] 276 | }, 277 | ... 278 | ``` 279 | In order to create a semantic html **<header>** element we create a header object. Following structure will be used for each defined area. 280 | 281 | For each section (header, aside, content, footer) we have : 282 | 283 | - **root** element container (css) 284 | - **blocks** array of objects 285 | 286 | In our theme we wanted to create: 287 | - a top bar with email and phone ref, 288 | - a header with a logo/title centered, 289 | - a centered menu right to the title 290 | - an image as heading 291 | 292 | 293 | 294 | The top bar block. 295 | ``` 296 | ... 297 | 298 | header : { 299 | root: 'w-full flex flex-wrap', 300 | blocks : [ 301 | { 302 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 303 | elements: [ 304 | { type: 'html' , content: '\ 305 | theme4nuxt@moodgiver.com\ 306 | '} 307 | ], 308 | homepage: false 309 | }, 310 | { 311 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 312 | elements: [ 313 | { type: 'html' , content: '\ 314 | +1 123 456 7890\ 315 | '} 316 | ], 317 | homepage: false 318 | }, 319 | ... 320 | } 321 | } 322 | ``` 323 | 324 | For each block we have to define 325 | 326 | - **css** : tailwind css classes for the block 327 | - **elements** : array of elements we want to render 328 | - **homepage** : set to true in order to display only in the homepage 329 | 330 | **elements** is an array of object that will be rendered following the order in which they are created. 331 | 332 | ### elements types ## 333 | Each element has the following properties to be set 334 | 335 | - **type** 336 | 337 | the system manage the following types of elements: 338 | - **html** 339 | - **component** 340 | - **menu** 341 | - **css** 342 | 343 | 344 | ### The *html* element ### 345 | 346 | So far for our title we create a css full-width element with other css properties (height, color, items alignment, etc. etc.) as a container. 347 | 348 | Then we created a **html** element type. 349 | 350 | For the **html** element type we must provide the content thru the **content** value. In this case we will assign directly HTML code to inject and render. In this way you can assign css to your html content and it will be rendered correctly. 351 | 352 | ### The *menu* element ### 353 | 354 | In order to render our menu we create a new row (block object) with his proper css. 355 | 356 | In order to render the right menu we have to assign which item in the navigation array we will use. Assign the navigation value representing the posisition in the navigation array (in our case we have only one navigation menu so we assign a value of 0). 357 | 358 | ``` 359 | ... 360 | 361 | header : { 362 | root: 'w-full flex flex-wrap', 363 | blocks : [ 364 | ... 365 | { 366 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 367 | elements : [ 368 | { type: 'menu' , navigation: 0, homepage: false} 369 | ], 370 | homepage: false 371 | }, 372 | ... 373 | } 374 | ... 375 | ``` 376 | ### Creating the content ### 377 | 378 | In order to create the content, that will be rendered as a semantic HTML **<section>** we follow the same structure. 379 | 380 | We will analyze only how to integrate a component in the theme. 381 | 382 | **Component theme integration** 383 | 384 | ``` 385 | ... 386 | 387 | content : { 388 | 389 | root: 'w-full flex flex-wrap', 390 | blocks : [ 391 | { 392 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6', 393 | elements: [ 394 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } }, 395 | ], 396 | homepage: true 397 | }, 398 | ... 399 | ] 400 | } 401 | ... 402 | ``` 403 | 404 | To load a custom component we have to define as element the following data: 405 | - **type** : "component", 406 | - **component** : the path of our component (if you are using a vue component with a different name from index.vue you need to define ex. /mycomponent/mycomponent.vue will load the mycomponent.vue in the folder mycomponent of the components folder) 407 | - **options** : an object of options that you need to pass to your components (props) 408 | 409 | 410 | Theme4Nuxt loads components dynamically using a component wrapper. 411 | 412 | Theme4Nuxt component wrapper (components/theme/ComponentWrapper.vue) 413 | 414 | ```html 415 | 420 | 421 | 434 | ``` 435 | 436 | 437 | 438 | 439 | ## Nuxt configuration 440 | 441 | In order to work properly you need to update your nuxt.config.js with the following 442 | 443 | file: ./nuxt.config.js 444 | 445 | ```js 446 | css: [ 447 | '~/assets/css/tailwind.css' //if you set a nuxt project with tailwind framework you should have this 448 | ], 449 | 450 | plugins: [ 451 | '~/plugins/index.js', 452 | '~/components/theme' //load all theme required components 453 | ], 454 | 455 | modules: [ 456 | '@nuxtjs/axios', 457 | '@nuxtjs/pwa', 458 | '@nuxtjs/markdownit' //used to integrate markdown files 459 | ], 460 | ... 461 | 462 | ``` 463 | 464 | 465 | ## Build Setup 466 | 467 | ``` bash 468 | # install dependencies 469 | $ npm install 470 | 471 | # serve with hot reload at localhost:3000 472 | $ npm run dev 473 | 474 | # build for production and launch server 475 | $ npm run build 476 | $ npm start 477 | 478 | # generate static project 479 | $ npm run generate 480 | ``` 481 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # theme4nuxt 2 | 3 | 4 | Theme4Nuxt is a basic theming solution for Nuxtjs. I decided to develop it in order to have an easy way to prototype layouts/themes for Nuxt using a configuration file. 5 | 6 | Based only on `tailwind.css` framework is developed to give the possibility to create your custom design without any opinionated framework. 7 | 8 | # Demo 9 | 10 | (A simple demo)[https://theme4nuxt.firebaseapp.com/] 11 | 12 | 13 | # Features 14 | 15 | - custom design based on CSS only 16 | - fast theme/layout prototype 17 | - create html semantic elements (header,section,aside,footer) 18 | - easy full responsive design implementation 19 | - easy integration with existing 20 | - components 21 | - api 22 | - markdown pages 23 | - easy theme switching 24 | - homepage design 25 | - extra basic components included (used in this demo) 26 | - responsive navigation 27 | - progress bars 28 | - cards 29 | - features/services info box 30 | - call for action 31 | 32 | 33 | # How it works 34 | 35 | **Requirements** : tailwind.css 36 | 37 | 38 | Theme4Nuxt is based on the following: 39 | - a **theme** js file (./themes/index.js) 40 | - a **single vue** file to deploy the theme to be used as layout template (./layout/theme.vue) 41 | - a Vue **component wrapper** in order to integrate any component dynamically (./components/theme/ComponentWrapper.vue) 42 | - a Vue **navigation component** in order to create a navigation system (./components/theme/nav/index.vue) 43 | - a **theme4nuxt** plugin in order to preload data server side (./plugins/theme4nuxt.js) 44 | 45 | 46 | 47 | ## Theme file 48 | 49 | Create a `themes` folder in your project root. 50 | 51 | Create an `index.js` in the themes folder 52 | 53 | #### Structure of the theme 54 | 55 | Each theme configuration file has the following structure: 56 | 57 | 58 | - theme general info (name, author, version, license) 59 | - a **root** property with css classes. This is the main container of your theme 60 | - a **homepage** property with the path for the homepage 61 | - a **initData** array of objects representing the initial data to load at startup. Data can be **API** or **Array** 62 | - a **navigation** array of objects. You can define different navigations and then use in your templates. 63 | - a **template** the main object of your theme. 64 | 65 | 66 | ``` 67 | const theme = { 68 | name : 'Corporate Business', 69 | author : 'A. Nardone', 70 | version : '0.2.0', 71 | license : 'MIT' 72 | root : 'w-full flex flex-wrap min-h-screen', 73 | homepage : '/', 74 | ... 75 | } 76 | 77 | export default theme 78 | ``` 79 | ### initData Section ### 80 | The **initData** is where you can define which data has to be preloaded. 81 | 82 | They can be **API** or **arrays** of data, depends on your rendering functions/components. 83 | 84 | *The current theme is using some WordPress API to simulate the preloading feature* 85 | 86 | ``` 87 | initData : [ 88 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , 89 | { type: 'array' , name: 'services' , value : [ 90 | {"type":"services", 91 | "title":"CSS Only", 92 | "abstract":"Theme4Nuxt is developed using only CSS with the Tailwind framework", 93 | "path":"css-only", 94 | "_id":"0tSvdJebN4cKmKa6", 95 | "icon":"style"}, 96 | {"type":"services", 97 | "title":"Custom Design", 98 | "abstract":"Create your custom theme without any opinionated framework", 99 | "icon":"chrome_reader_mode", 100 | "path":"theme-builder", 101 | "_id":"MSOXCaCn4AfNz57w"}, 102 | {"type":"services", 103 | "title":"Integration", 104 | "abstract":"Feel free to use your own components, API and data", 105 | "path":"api-data", 106 | "_id":"ueN9BbEdxvKoZWNi" 107 | ,"icon":"compare_arrows"} 108 | ] }, 109 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 110 | } 111 | ], 112 | ``` 113 | 114 | In case of API **axios** library will be used to fetch data (asyncronously) server side. 115 | 116 | **Data preloading is implemented using `nuxtServerInit` directly from the store.** 117 | 118 | file: ./store/index.js 119 | 120 | ``` 121 | ... 122 | async nuxtServerInit({commit}, context ){ 123 | //read theme configuration using $theme4nuxt() injected by ./plugins/index.js 124 | let init = context.app.$theme4nuxt().initData 125 | let data = {} 126 | //iterate thru all initial data to be loaded 127 | for ( var n=0 ; n < init.length ; n++ ){ 128 | if ( init[n].type === 'api' ) { 129 | let qry = await context.app.$axios.get(init[n].api); 130 | data[init[n].name] = qry.data 131 | } 132 | if ( init[n].type === 'array' ){ 133 | data[init[n].name] = init[n].value 134 | } 135 | } 136 | //save data to store 137 | commit ('init_data', data ) 138 | if ( !context.app.store.state.theme ){ 139 | commit ('theme',context.app.$theme4nuxt() ) 140 | } 141 | }, 142 | ... 143 | ``` 144 | 145 | **Preload theme and injext function to read initData configuration** 146 | 147 | file: ./plugins/index.js 148 | 149 | ``` 150 | import theme from '~/themes' 151 | 152 | export default ({ app }, inject) => { 153 | inject('theme4nuxt', () => theme) 154 | } 155 | ``` 156 | # The Theme # 157 | 158 | We analyze the current theme that has been used for this website. 159 | 160 | ### navigation Section ### 161 | 162 | The navigation section is required if you want to use the built-in navigation system as showed in the demo. This component create a responsive main navigation icon that open a menu with the options defined. 163 | 164 | The navigation section is also used in the template in order to render a normal navigation menu. 165 | In this version child menus are not supported. If you need this option you can use your component or navigation system. 166 | 167 | ``` 168 | ... 169 | navigation : [{ 170 | css : "items-start w-full pt-16 px-4 pb-20 bg-black opacity-75 h-screen", 171 | button : "m-1 bg-white p-2 border-black border-2 rounded-full", 172 | line : "hover:text-black hover:bg-white text-grey-lightest" , 173 | link : 'text-white hover:text-black hover:bg-white hover:text-bold py-10 px-4 no-underline', 174 | left : false, 175 | transition: 'slideright', 176 | orientation: 'horizontal' , 177 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } ] 178 | }], 179 | ... 180 | ``` 181 | 182 | ### template Section ### 183 | 184 | The **template** section is the core of the theming system and has 2 main objects 185 | - **main** 186 | - **areas** 187 | 188 | 189 | 190 | 191 | The ***main*** object 192 | 193 | The main object is where is defined the class of the main container and will generate a semantic **<main>** html element. 194 | ``` 195 | ... 196 | template: { 197 | main : { 198 | css : "w-full", 199 | 200 | }, 201 | ... 202 | ``` 203 | 204 | 205 | 206 | The **areas** object 207 | 208 | With the areas object you define all the elements of your template. 209 | 210 | First you can define the order of the area to be rendered as semantic html blocks. Available areas are: 211 | - header 212 | - aside 213 | - content (will be rendered as section) 214 | - footer 215 | 216 | **order is important in order to render elements correctly** 217 | 218 | 219 | ``` 220 | ... 221 | template: { 222 | ... 223 | areas: { 224 | order : ['header','content','footer'], 225 | ... 226 | ``` 227 | 228 | Our example will create a **header**, a **section** area and a **footer**. 229 | 230 | 231 | ### Creating the header ### 232 | 233 | ``` 234 | ... 235 | template: { 236 | ... 237 | areas: { 238 | areas: { 239 | order : ['header','content','footer'], 240 | header : { 241 | root: 'w-full flex flex-wrap', 242 | blocks : [ 243 | { 244 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 245 | elements: [ 246 | { type: 'html' , content: '\ 247 | theme4nuxt@moodgiver.com\ 248 | '} 249 | ] 250 | }, 251 | { 252 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 253 | elements: [ 254 | { type: 'html' , content: '\ 255 | +1 123 456 7890\ 256 | '} 257 | ] 258 | }, 259 | { 260 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 h-24 opacity-75 justify-end flex items-center col bg-black' , 261 | elements : [ 262 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 263 | ], 264 | homepage: false 265 | }, 266 | { 267 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 268 | elements : [ 269 | { type: 'menu' , navigation: 0, homepage: false} 270 | ] 271 | }, 272 | { 273 | css: 'w-full bg-green-light h-128 -mt-24 bg-header-8', 274 | elements: [ 275 | { type: 'html' , content: ''} 276 | ], 277 | homepage: true 278 | } 279 | 280 | ] 281 | }, 282 | ... 283 | ``` 284 | In order to create a semantic html **<header>** element we create a header object. Following structure will be used for each defined area. 285 | 286 | For each section (header, aside, content, footer) we have : 287 | 288 | - **root** element container (css) 289 | - **blocks** array of objects 290 | 291 | In our theme we wanted to create: 292 | - a top bar with email and phone ref, 293 | - a header with a logo/title centered, 294 | - a centered menu right to the title 295 | - an image as heading 296 | 297 | 298 | 299 | The top bar block. 300 | ``` 301 | ... 302 | 303 | header : { 304 | root: 'w-full flex flex-wrap', 305 | blocks : [ 306 | { 307 | css: 'w-1/2 flex items-center h-12 bg-black text-grey text-xs pl-4 mobile', 308 | elements: [ 309 | { type: 'html' , content: '\ 310 | theme4nuxt@moodgiver.com\ 311 | '} 312 | ], 313 | homepage: false 314 | }, 315 | { 316 | css: 'w-1/2 flex items-center justify-end h-12 bg-black text-grey text-xs pr-16 mobile', 317 | elements: [ 318 | { type: 'html' , content: '\ 319 | +1 123 456 7890\ 320 | '} 321 | ], 322 | homepage: false 323 | }, 324 | ... 325 | } 326 | } 327 | ``` 328 | 329 | For each block we have to define 330 | 331 | - **css** : tailwind css classes for the block 332 | - **elements** : array of elements we want to render 333 | - **homepage** : set to true in order to display only in the homepage 334 | 335 | **elements** is an array of object that will be rendered following the order in which they are created. 336 | 337 | ### elements types ## 338 | Each element has the following properties to be set 339 | 340 | - **type** 341 | 342 | the system manage the following types of elements: 343 | - **html** 344 | - **component** 345 | - **menu** 346 | - **css** 347 | 348 | 349 | ### The *html* element ### 350 | 351 | So far for our title we create a css full-width element with other css properties (height, color, items alignment, etc. etc.) as a container. 352 | 353 | Then we created a **html** element type. 354 | 355 | For the **html** element type we must provide the content thru the **content** value. In this case we will assign directly HTML code to inject and render. In this way you can assign css to your html content and it will be rendered correctly. 356 | 357 | ### The *menu* element ### 358 | 359 | In order to render our menu we create a new row (block object) with his proper css. 360 | 361 | In order to render the right menu we have to assign which item in the navigation array we will use. Assign the navigation value representing the posisition in the navigation array (in our case we have only one navigation menu so we assign a value of 0). 362 | 363 | ``` 364 | ... 365 | 366 | header : { 367 | root: 'w-full flex flex-wrap', 368 | blocks : [ 369 | ... 370 | { 371 | css: 'w-full md:w-1/2 lg:w-1/2 xl:w-1/2 border-l opacity-75 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-black mobile' , 372 | elements : [ 373 | { type: 'menu' , navigation: 0, homepage: false} 374 | ], 375 | homepage: false 376 | }, 377 | ... 378 | } 379 | ... 380 | ``` 381 | ### Creating the content ### 382 | 383 | In order to create the content, that will be rendered as a semantic HTML **<section>** we follow the same structure. 384 | 385 | We will analyze only how to integrate a component in the theme. 386 | 387 | **Component theme integration** 388 | 389 | ``` 390 | ... 391 | 392 | content : { 393 | 394 | root: 'w-full flex flex-wrap', 395 | blocks : [ 396 | { 397 | css: 'w-full bg-transparent text-grey mx-4 -mt-20 py-6', 398 | elements: [ 399 | { type: 'component' , component: 'core/services' , options: { data: 'services' , title: 'Features' } }, 400 | ], 401 | homepage: true 402 | }, 403 | ... 404 | ] 405 | } 406 | ... 407 | ``` 408 | 409 | To load a custom component we have to define as element the following data: 410 | - **type** : "component", 411 | - **component** : the path of our component (if you are using a vue component with a different name from index.vue you need to define ex. /mycomponent/mycomponent.vue will load the mycomponent.vue in the folder mycomponent of the components folder) 412 | - **options** : an object of options that you need to pass to your components (props) 413 | 414 | 415 | Theme4Nuxt loads components dynamically using a component wrapper. 416 | 417 | Theme4Nuxt component wrapper (components/theme/ComponentWrapper.vue) 418 | ``` 419 | 424 | 425 | 438 | ``` 439 | 440 | 441 | 442 | 443 | ## Nuxt configuration 444 | 445 | In order to work properly you need to update your nuxt.config.js with the following 446 | 447 | file: ./nuxt.config.js 448 | 449 | ``` 450 | /* 451 | ** Load tailwind.css 452 | */ 453 | css: [ 454 | '~/assets/css/tailwind.css' //if you set a nuxt project with tailwind framework you should have this 455 | ], 456 | 457 | /* 458 | ** Plugins to load before mounting the App 459 | */ 460 | plugins: [ 461 | '~/plugins/index.js', 462 | '~/components/theme' //load all theme required components 463 | ], 464 | 465 | /* 466 | ** Nuxt.js modules 467 | */ 468 | modules: [ 469 | //axios, pwa and markdown support 470 | '@nuxtjs/axios', 471 | '@nuxtjs/pwa', 472 | '@nuxtjs/markdownit' //used to integrate markdown files 473 | ], 474 | ... 475 | 476 | ``` 477 | 478 | 479 | ## Build Setup 480 | 481 | ``` bash 482 | # install dependencies 483 | $ npm install 484 | 485 | # serve with hot reload at localhost:3000 486 | $ npm run dev 487 | 488 | # build for production and launch server 489 | $ npm run build 490 | $ npm start 491 | 492 | # generate static project 493 | $ npm run generate 494 | ``` 495 | -------------------------------------------------------------------------------- /themes/theme2.js: -------------------------------------------------------------------------------- 1 | const layout = { 2 | name : 'e-commerce Waves', 3 | author : 'A. Nardone', 4 | version : '0.2.0', 5 | root : 'w-full flex flex-wrap min-h-screen', 6 | homepage : '/', 7 | initData : [ 8 | { type: 'api' , name: 'posts' , api : 'https://www.techcrunch.com/wp-json/wp/v2/posts' } , //'/posts?$sort[createdAt]=-1&$limit=4' }, 9 | { type: 'api' , name: 'info' , api : 'https://www.gianlucagiacalone.it/wp-json/wp/v2/posts' } , // '/posts?$sort[createdAt]=-1&$limit=4' }, 10 | { type: 'api' , name: 'services' , api : 'http://localhost:3030/sections?type=services' }, 11 | { type: 'array' , name: 'skills' , value : [{name:'CREATIVITY' , value: "90%"} , { name: 'ORGANIZATION' , value: "85%"} , { name: 'TEAM WORK' , value: "75%"} , { name: 'COMMUNICATION' , value: "70%"}] 12 | } 13 | ], 14 | 15 | navigation : [{ 16 | css : "items-start w-full pt-16 px-2 pb-20 bg-purple-dark clipped-angle-right", 17 | button : "m-4 bg-white p-4 border-black border-2 rounded-full", 18 | line : "hover:text-black hover:bg-purple-light text-grey-lightest" , 19 | link : 'text-white hover:text-white hover:bg-indigo rounded hover:text-bold py-2 px-4 no-underline', 20 | left : false, 21 | transition: 'slidedown', 22 | orientation: 'horizontal' , 23 | items: [ { name : 'Home' , path: '/' } , { name: 'Blog' , path: '/blog' } , { name: 'About' , path: '/about' } , { name: 'How to' , path: '/howto' } , { name: 'GitHub', path: 'https://github.com/swina/theme4nuxt'} ] 24 | }], 25 | template: { 26 | main : { 27 | css : "w-full", 28 | 29 | }, 30 | areas: { 31 | order : ['header','content','footer'], 32 | header : { 33 | root: 'w-full flex flex-wrap', 34 | blocks : [ 35 | 36 | 37 | 38 | { 39 | css: 'w-full md:w-1/4 lg:w-1/4 xl:w-1/4 h-24 flex items-center col bg-purple-dark' , 40 | elements : [ 41 | { type: 'html' , content: '

Theme4Nuxt

' , homepage: false } 42 | ], 43 | homepage: false 44 | }, 45 | { 46 | css: 'w-full md:w-3/4 lg:w-3/4 xl:w-3/4 h-24 col z-30 justify-left items-center flex text-right pr-12 col-nav bg-purple-dark mobile' , 47 | elements : [ 48 | { type: 'menu' , navigation: 0, homepage: false} 49 | ] 50 | }, 51 | 52 | 53 | { 54 | css: 'w-full bg-white', 55 | 56 | elements: [ 57 | { type: 'html' , content: '\ 68 | \ 70 | \ 72 | \ 73 | \ 75 | image/svg+xml\ 76 | \ 78 | \ 79 | \ 80 | \ 81 | \ 82 | \ 86 | \ 90 | \ 91 | \ 92 | '} 93 | ] 94 | } 95 | ] 96 | }, 97 | content : { 98 | root: 'w-full flex flex-wrap', 99 | blocks : [ 100 | { 101 | 102 | css: 'w-full flex flex-wrap justify-center', 103 | elements : [ 104 | { type: 'html' , content: '' , nuxt: true , homepage: false } 105 | ] 106 | }, 107 | 108 | { 109 | css: 'w-full flex flex-wrap justify-center', 110 | elements : [ 111 | { type: 'component' , component: 'core/cards' , options: { contest: 'products' } , homepage: true } 112 | ], 113 | }, 114 | 115 | { 116 | css: 'w-full bg-white -mb-8', 117 | 118 | elements: [ 119 | { type: 'html' , content: '\ 134 | \ 136 | \ 155 | \ 157 | \ 158 | \ 160 | image/svg+xml\ 161 | \ 163 | \ 164 | \ 165 | \ 166 | \ 167 | \ 173 | \ 179 | \ 180 | \ 181 | '} 182 | ] 183 | }, 184 | { 185 | css: 'w-full flex items-center justify-center h-48 pt-8 -mt-2 bg-purple-dark', 186 | elements: [ 187 | { type: 'html' , content: '

Do you need a theme solution for Nuxt?

Theme4Nuxt

' , homepage: true } 188 | ], 189 | homepage: true 190 | }, 191 | 192 | /*{ 193 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 194 | elements : [ 195 | { type: 'html' , content: '

Blog

' , homepage: true }, 196 | //{ type: 'component' , name: 'v-posts' , data: 'info' , homepage: true }, 197 | ] 198 | }, 199 | { 200 | css: 'w-full md:w-full lg:w-1/2 xl:w-1/2', 201 | elements : [ 202 | 203 | 204 | { type: 'html' , content: '

News

' , homepage: true }, 205 | //{ type: 'component' , name: 'v-posts' , data: 'info' , homepage: true } 206 | ], 207 | }, 208 | */ 209 | 210 | ] 211 | }, 212 | footer : { 213 | root : 'w-full', 214 | blocks : [ 215 | { 216 | css: 'h-16 items-center flex justify-center w-full bg-purple-dark text-center text-white' , 217 | elements : [ 218 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' , homepage: false} 219 | ] 220 | } 221 | ] 222 | } 223 | }, 224 | } 225 | /* 226 | template: { 227 | main : { 228 | css : "w-full grid columns-4 rows-5", 229 | 230 | }, 231 | grid : [ 232 | 'h-16 bg-red' , 233 | 'h-16 bg-red col col-span-2 flex items-center justify-center' , 234 | 'h-16 bg-red col', 235 | 'col-span-4' , 236 | 'row-span-2 col-span-4 p-12' , 237 | 'row-span-2 p-12 col-span-2' , 238 | 'row-span-2 p-12 col-span-2' , 239 | 'h-16 items-center flex justify-center col-span-4 bg-grey-light' 240 | ], 241 | blocks : [ 242 | [{ type: 'html' , content: '

Theme4Nuxt

' ,homepage: false }], 243 | [{ type: 'menu' , navigation: 0, homepage: false}], 244 | [{ type: 'nav' , navigation: 0, homepage: false}], 245 | [{ type: 'html' , content: '
\ 246 |
\ 247 |

Need a theme for Nuxt?\ 248 |

Discover how to create themes for Nuxt

\ 249 |

A creative way to design your theme for Nuxt.

\ 250 |

It\' easy, fast and replicable.

\ 251 | \ 252 | \ 253 |
' , action: '/howto' , homepage: true }], 254 | [ 255 | { type: 'component' , name: 'v-coreServices' , title: '' , css: 'bg-red-light shadow icon-rounded rounded text-white px-8 -mt-16' , data : 'services' , api: 'services' , homepage: true } 256 | ] , 257 | [ 258 | { type: 'component' , name: 'v-posts' , data: 'info' , homepage: true , nuxt: true } , 259 | { type: 'component' , name: 'v-coreSkills' , data: 'skills' ,homepage: true} 260 | ], 261 | [ 262 | { type: 'component' , name: 'v-coreTiles' , data: 'posts' , homepage: true } 263 | ], 264 | [ 265 | { type: 'html' , content: 'Theme4Nuxt - a theme solution for Nuxtjs - Author: Antonio Nardone - License MIT' } 266 | ] 267 | ], 268 | nuxt: 'mt-4' 269 | }, 270 | 271 | extra: { 272 | html: '
\ 273 |
\ 274 |
\ 275 |
', 276 | action: '/howto' 277 | } 278 | */ 279 | } 280 | 281 | export default layout --------------------------------------------------------------------------------