├── utils └── index.js ├── static ├── _redirects ├── icon.png └── user-avatar.png ├── .env.example ├── plugins ├── vuebar.js ├── vueValidate.js ├── socket.io.js ├── auth.js └── filters.js ├── middleware └── no-auth.js ├── postcss.config.js ├── .editorconfig ├── layouts └── default.vue ├── .eslintrc.js ├── .gitignore ├── README.md ├── components ├── ChatMessage.vue ├── ChatTyping.vue ├── ChatNewMessage.vue ├── UserList.vue └── Chat.vue ├── assets └── css │ ├── dragger.stylus │ └── tailwind.css ├── package.json ├── nuxt.config.js ├── pages ├── index.vue ├── login.vue └── register.vue ├── store └── index.js └── tailwind.js /utils/index.js: -------------------------------------------------------------------------------- 1 | // 2 | -------------------------------------------------------------------------------- /static/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | SOCKET_HOST_URL=http://localhost:3002 2 | API_URL=localhost:3002/api -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binbytes/nuxt-chat-app/HEAD/static/icon.png -------------------------------------------------------------------------------- /plugins/vuebar.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuebar from 'vuebar' 3 | 4 | Vue.use(Vuebar) 5 | -------------------------------------------------------------------------------- /static/user-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binbytes/nuxt-chat-app/HEAD/static/user-avatar.png -------------------------------------------------------------------------------- /plugins/vueValidate.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VeeValidate from 'vee-validate' 3 | 4 | Vue.use(VeeValidate) -------------------------------------------------------------------------------- /middleware/no-auth.js: -------------------------------------------------------------------------------- 1 | export default function ({ app, redirect }) { 2 | if (app.$auth.loggedIn) { 3 | return redirect('/') 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /plugins/socket.io.js: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client' 2 | 3 | const socket = io(process.env.SOCKET_HOST_URL) 4 | 5 | export default socket 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('tailwindcss')('./tailwind.js'), 4 | require('autoprefixer') 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /plugins/auth.js: -------------------------------------------------------------------------------- 1 | import socket from '~/plugins/socket.io.js' 2 | 3 | export default function ({ app }) { 4 | if (!app.$auth.loggedIn) { 5 | return 6 | } 7 | 8 | socket.emit('online-ping', app.$auth.user.id) 9 | } -------------------------------------------------------------------------------- /plugins/filters.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import moment from 'moment' 3 | 4 | Vue.filter('formatDate', function (value) { 5 | if (value) { 6 | return moment(String(value)).format('MM/DD/YYYY hh:mm') 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 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/default.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | env: { 5 | browser: true, 6 | node: true 7 | }, 8 | extends: 'standard', 9 | // required to lint *.vue files 10 | plugins: [ 11 | 'html' 12 | ], 13 | // add your custom rules here 14 | globals: {} 15 | }; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # env 2 | .env 3 | 4 | # dependencies 5 | node_modules 6 | 7 | # logs 8 | *.log 9 | 10 | # server build 11 | build 12 | 13 | # Nuxt build 14 | .nuxt 15 | 16 | # Nuxt generate 17 | dist 18 | 19 | # Intellij idea 20 | .idea 21 | *iml 22 | 23 | # VSCode 24 | .vscode 25 | 26 | # Generated files 27 | static/manifest*.json 28 | static/sw.js 29 | static/workbox-sw*.js 30 | 31 | # Error log 32 | yarn-error.log 33 | 34 | yarn.lock 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chat Application Frontend 2 | 3 | > An frontend of chat application built using nuxt.js 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | $ npm install # Or yarn install 10 | 11 | # copy and setup .env 12 | cp .env.example .env 13 | 14 | # serve with hot reload at localhost:3000 15 | # service worker is disabled in dev 16 | $ npm run dev 17 | 18 | # build for production and launch server 19 | $ npm run build 20 | $ npm start 21 | ``` 22 | -------------------------------------------------------------------------------- /components/ChatMessage.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /components/ChatTyping.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 20 | -------------------------------------------------------------------------------- /components/ChatNewMessage.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 27 | -------------------------------------------------------------------------------- /assets/css/dragger.stylus: -------------------------------------------------------------------------------- 1 | .vb>.vb-dragger { 2 | z-index: 5; 3 | width: 12px; 4 | right: 0; 5 | } 6 | 7 | .vb>.vb-dragger>.vb-dragger-styler { 8 | -webkit-backface-visibility: hidden; 9 | backface-visibility: hidden; 10 | -webkit-transform: rotate3d(0, 0, 0, 0); 11 | transform: rotate3d(0, 0, 0, 0); 12 | -webkit-transition: background-color 100ms ease-out, margin 100ms ease-out, height 100ms ease-out; 13 | transition: background-color 100ms ease-out, margin 100ms ease-out, height 100ms ease-out; 14 | background-color: rgba(48, 121, 244, .1); 15 | margin: 5px 5px 5px 0; 16 | border-radius: 20px; 17 | height: calc(100% - 10px); 18 | display: block; 19 | } 20 | 21 | .vb.vb-scrolling-phantom>.vb-dragger>.vb-dragger-styler { 22 | background-color: rgba(48, 121, 244, .3); 23 | } 24 | 25 | .vb>.vb-dragger:hover>.vb-dragger-styler { 26 | background-color: rgba(48, 121, 244, .5); 27 | margin: 0px; 28 | height: 100%; 29 | } 30 | 31 | .vb.vb-dragging>.vb-dragger>.vb-dragger-styler { 32 | background-color: rgba(48, 121, 244, .5); 33 | margin: 0px; 34 | height: 100%; 35 | } 36 | 37 | .vb.vb-dragging-phantom>.vb-dragger>.vb-dragger-styler { 38 | background-color: rgba(48, 121, 244, .5); 39 | } 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-chat-app", 3 | "version": "1.0.0", 4 | "description": "An web chat application built using nuxtjs", 5 | "author": "Nikunj Kanetiya ", 6 | "dependencies": { 7 | "@nuxtjs/auth": "^4.1.0", 8 | "@nuxtjs/axios": "^4.4.0", 9 | "@nuxtjs/dotenv": "^1.1.1", 10 | "@nuxtjs/pwa": "^2.0.8", 11 | "moment": "^2.19.1", 12 | "nuxt": "^1.4.0", 13 | "socket.io-client": "^2.0.3", 14 | "vee-validate": "^2.0.6", 15 | "vue-avatar-component": "^1.2.4", 16 | "vue-server-renderer": "^2.5.6", 17 | "vue-template-compiler": "^2.5.6", 18 | "vuebar": "^0.0.17" 19 | }, 20 | "scripts": { 21 | "dev": "nuxt dev", 22 | "build": "nuxt build", 23 | "start": "nuxt start", 24 | "dev-spa": "nuxt dev --spa", 25 | "build-spa": "nuxt build --spa", 26 | "start-spa": "nuxt start --spa", 27 | "generate": "nuxt generate", 28 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 29 | "precommit": "npm run lint" 30 | }, 31 | "devDependencies": { 32 | "babel-eslint": "^7.1.1", 33 | "eslint": "^3.15.0", 34 | "eslint-config-standard": "^6.2.1", 35 | "eslint-loader": "^1.6.1", 36 | "eslint-plugin-html": "^2.0.0", 37 | "eslint-plugin-promise": "^3.4.1", 38 | "eslint-plugin-standard": "^2.0.1", 39 | "stylus": "^0.54.5", 40 | "stylus-loader": "^3.0.1", 41 | "tailwindcss": "^0.1.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | 3 | module.exports = { 4 | mode: 'spa', 5 | /* 6 | ** Build 7 | */ 8 | build: { 9 | vendor: ['socket.io-client'] 10 | }, 11 | /* 12 | ** Headers 13 | ** Common headers are already provided by @nuxtjs/pwa preset 14 | */ 15 | head: { 16 | title: 'BinBytes - Chat App', 17 | link: [ 18 | { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Lato:400,700' }, 19 | { rel: 'stylesheet', href: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css' } 20 | ] 21 | }, 22 | /* 23 | ** Customize the progress-bar color 24 | */ 25 | loading: { color: '#3B8070' }, 26 | css: [ 27 | '~/assets/css/tailwind.css' 28 | ], 29 | /* 30 | ** Customize app manifest 31 | */ 32 | manifest: { 33 | theme_color: '#3B8070' 34 | }, 35 | /* 36 | ** Modules 37 | */ 38 | modules: [ 39 | [ 40 | '@nuxtjs/pwa', { workbox: false } 41 | ], 42 | '@nuxtjs/axios', 43 | '@nuxtjs/auth', 44 | '@nuxtjs/dotenv' 45 | ], 46 | /* 47 | ** Plugins 48 | */ 49 | plugins: [ 50 | '~/plugins/socket.io.js', 51 | '~/plugins/vuebar.js', 52 | '~/plugins/filters.js', 53 | '~/plugins/vueValidate.js' 54 | ], 55 | /* 56 | ** Auth settings 57 | */ 58 | auth: { 59 | resetOnError: true, 60 | rewriteRedirects: false, 61 | strategies: { 62 | local: { 63 | endpoints: { 64 | login: { url: '/auth/login', method: 'post', propertyName: 'token' }, 65 | logout: { url: '/auth/logout', method: 'post' }, 66 | user: { url: '/users/me', method: 'get', propertyName: 'user' } 67 | }, 68 | tokenRequired: true, 69 | tokenType: '', 70 | } 71 | }, 72 | plugins: [ '~/plugins/auth.js' ] 73 | }, 74 | /* 75 | ** Axios settings 76 | */ 77 | axios: { 78 | baseURL: process.env.API_URL || 'http://localhost:3002/api' 79 | }, 80 | env: { 81 | SOCKET_HOST_URL: process.env.SOCKET_HOST_URL || 'http://localhost:3002' 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /components/UserList.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 74 | -------------------------------------------------------------------------------- /components/Chat.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 74 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 75 | 76 | 110 | -------------------------------------------------------------------------------- /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 | 9 | @tailwind preflight; 10 | 11 | /** 12 | * Here you would add any of your custom component classes; stuff that you'd 13 | * want loaded *before* the utilities so that the utilities could still 14 | * override them. 15 | * 16 | * Example: 17 | * 18 | * .btn { ... } 19 | * .form-input { ... } 20 | * 21 | * Or if using a preprocessor: 22 | * 23 | * @import "components/buttons"; 24 | * @import "components/forms"; 25 | */ 26 | 27 | 28 | /** 29 | * This injects all of Tailwind's utility classes, generated based on your 30 | * config file. 31 | */ 32 | 33 | @tailwind utilities; 34 | 35 | /** 36 | * Here you would add any custom utilities you need that don't come out of the 37 | * box with Tailwind. 38 | * 39 | * Example : 40 | * 41 | * .bg-pattern-graph-paper { ... } 42 | * .skew-45 { ... } 43 | * 44 | * Or if using a preprocessor.. 45 | * 46 | * @import "utilities/backgrond-patterns"; 47 | * @import "utilities/skew-transforms"; 48 | */ 49 | 50 | .btn { 51 | @apply .font-bold .py-2 .px-4 .rounded; 52 | } 53 | 54 | .btn-blue { 55 | @apply .bg-blue .text-white; 56 | } 57 | 58 | .btn-blue:hover { 59 | @apply .bg-blue-dark; 60 | } 61 | 62 | .input-control { 63 | @apply .shadow .appearance-none .border .rounded .w-full .py-2 .px-3 .text-grey-darker; 64 | } 65 | 66 | .vb>.vb-dragger { 67 | z-index: 5; 68 | width: 12px; 69 | right: 0; 70 | } 71 | 72 | .vb>.vb-dragger>.vb-dragger-styler { 73 | -webkit-backface-visibility: hidden; 74 | backface-visibility: hidden; 75 | -webkit-transform: rotate3d(0, 0, 0, 0); 76 | transform: rotate3d(0, 0, 0, 0); 77 | -webkit-transition: background-color 100ms ease-out, margin 100ms ease-out, height 100ms ease-out; 78 | transition: background-color 100ms ease-out, margin 100ms ease-out, height 100ms ease-out; 79 | background-color: rgba(48, 121, 244, .1); 80 | margin: 5px 5px 5px 0; 81 | border-radius: 20px; 82 | height: calc(100% - 10px); 83 | display: block; 84 | } 85 | 86 | .vb.vb-scrolling-phantom>.vb-dragger>.vb-dragger-styler { 87 | background-color: rgba(48, 121, 244, .3); 88 | } 89 | 90 | .vb>.vb-dragger:hover>.vb-dragger-styler { 91 | background-color: rgba(48, 121, 244, .5); 92 | margin: 0px; 93 | height: 100%; 94 | } 95 | 96 | .vb.vb-dragging>.vb-dragger>.vb-dragger-styler { 97 | background-color: rgba(48, 121, 244, .5); 98 | margin: 0px; 99 | height: 100%; 100 | } 101 | 102 | .vb.vb-dragging-phantom>.vb-dragger>.vb-dragger-styler { 103 | background-color: rgba(48, 121, 244, .5); 104 | } 105 | -------------------------------------------------------------------------------- /pages/login.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 77 | -------------------------------------------------------------------------------- /pages/register.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 76 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import socket from '~/plugins/socket.io' 3 | 4 | export const state = () => ({ 5 | users: {}, 6 | conversations: {}, 7 | currentConversationId: null, 8 | recipientUserID: null, 9 | fetched: false 10 | }) 11 | 12 | export const getters = { 13 | currentConversation (state) { 14 | return state.currentConversationId ? state.conversations[state.currentConversationId] : null 15 | }, 16 | recipientUser (state) { 17 | return state.users ? state.users[state.recipientUserID] : null 18 | } 19 | } 20 | 21 | export const mutations = { 22 | SET_FETCHED (state) { 23 | state.fetched = true 24 | }, 25 | SET_USERS (state, users) { 26 | if (!users) return 27 | 28 | users.forEach(user => { 29 | createUser(state, user) 30 | }) 31 | }, 32 | SET_ONLINE_USERS (state, ids) { 33 | ids.forEach(id => { 34 | if (id && state.users[id]) { 35 | Vue.set(state.users[id], 'online', true) 36 | } 37 | }) 38 | }, 39 | SET_USER_OFFLINE (state, id) { 40 | Vue.set(state.users[id], 'online', false) 41 | }, 42 | SET_CONVERSATIONS (state, conversations) { 43 | if (!conversations) return 44 | 45 | conversations.forEach(conversation => { 46 | createConversation(state, conversation) 47 | }) 48 | }, 49 | ADD_CONVERSATION (state, conversation) { 50 | createConversation(state, conversation) 51 | }, 52 | SWITCH_CONVERSATION (state, id) { 53 | state.currentConversationId = id 54 | }, 55 | SET_RECIPIENT_USER_ID (state, id) { 56 | state.recipientUserID = id 57 | }, 58 | SET_MESSAGES (state, payload) { 59 | const conversation = state.conversations[payload.conversationId] 60 | 61 | Vue.set(conversation, 'messages', payload.messages) 62 | Vue.set(conversation, 'fetched', true) 63 | }, 64 | PUSH_MESSAGE (state, message) { 65 | state.conversations[message.conversationId].messages.push(message) 66 | } 67 | } 68 | 69 | export const actions = { 70 | async fetchUsers ({ state, commit }, endpoint = '/users') { 71 | const users = await this.$axios.$get(endpoint) 72 | commit('SET_USERS', users) 73 | }, 74 | 75 | async fetchConversations ({ state, commit }, endpoint = '/conversations') { 76 | const conversations = await this.$axios.$get(endpoint) 77 | commit('SET_CONVERSATIONS', conversations) 78 | }, 79 | 80 | actionAfterLoggedin ({ state, dispatch, commit }) { 81 | if (state.fetched === false) { 82 | // state.fetched = true 83 | commit('SET_FETCHED') 84 | dispatch('fetchUsers') 85 | dispatch('fetchConversations') 86 | } 87 | }, 88 | 89 | async switchConversation ({ state, commit }, recipientUserID) { 90 | let conversationId = Object.keys(state.conversations).find(id => state.conversations[id]['participants'] && state.conversations[id].participants.includes(recipientUserID)) 91 | 92 | if (conversationId) { 93 | // Fetch messages if not already fetched 94 | commit('SWITCH_CONVERSATION', conversationId) 95 | 96 | let conversation = state.conversations[conversationId] 97 | 98 | // Check if messages is fetched already 99 | if (conversation.fetched === false) { 100 | const { data } = await this.$axios.get(`conversation\\${conversationId}`) 101 | 102 | commit('SET_MESSAGES', { 103 | conversationId: conversationId, 104 | messages: data 105 | }) 106 | } 107 | } else { 108 | // create new conversation 109 | let { data } = await this.$axios.post('conversation', { 110 | recipient: recipientUserID 111 | }) 112 | 113 | commit('ADD_CONVERSATION', data) 114 | commit('SWITCH_CONVERSATION', data._id) 115 | } 116 | 117 | commit('SET_RECIPIENT_USER_ID', recipientUserID) 118 | }, 119 | 120 | pushMessage ({ commit }, message) { 121 | commit('PUSH_MESSAGE', message) 122 | }, 123 | 124 | async sendMessage ({ state, dispatch }, message, endpoint = `send-message/${state.currentConversationId}`) { 125 | const { data } = await this.$axios.post(endpoint, { 126 | body: message 127 | }) 128 | 129 | if (data) { 130 | await dispatch('pushMessage', data) 131 | socket.emit('send-message', data) 132 | } 133 | }, 134 | 135 | setOnlineUsers ({ commit }, ids) { 136 | commit('SET_ONLINE_USERS', ids) 137 | }, 138 | 139 | setOnline ({ commit }, id) { 140 | commit('SET_ONLINE_USERS', [id]) 141 | }, 142 | 143 | setOffline ({ commit }, id) { 144 | commit('SET_USER_OFFLINE', id) 145 | } 146 | } 147 | 148 | const createConversation = (state, conversation) => { 149 | conversation.messages = [] 150 | conversation.isRead = true 151 | conversation.fetched = false 152 | 153 | Vue.set(state.conversations, conversation._id, conversation) 154 | 155 | if (socket) { 156 | socket.emit('enter-conversation', conversation._id) 157 | } 158 | } 159 | 160 | const createUser = (state, user) => { 161 | user.online = false 162 | 163 | Vue.set(state.users, user.id, user) 164 | } 165 | -------------------------------------------------------------------------------- /tailwind.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Tailwind - The Utility-First CSS Framework 4 | 5 | A project by Adam Wathan (@adamwathan), Jonathan Reinink (@reinink), 6 | David Hemphill (@davidhemphill) and Steve Schoger (@steveschoger). 7 | 8 | Welcome to the Tailwind config file. This is where you can customize 9 | Tailwind specifically for your project. Don't be intimidated by the 10 | length of this file. It's really just a big JavaScript object and 11 | we've done our very best to explain each section. 12 | 13 | View the full documentation at https://tailwindcss.com. 14 | 15 | |------------------------------------------------------------------------------- 16 | | The default config 17 | |------------------------------------------------------------------------------- 18 | | 19 | | This variable contains the default Tailwind config. You don't have 20 | | to use it, but it can sometimes be helpful to have available. For 21 | | example, you may choose to merge your custom configuration 22 | | values with some of the Tailwind defaults. 23 | | 24 | */ 25 | 26 | // var defaultConfig = require('tailwindcss').defaultConfig() 27 | 28 | /* 29 | |------------------------------------------------------------------------------- 30 | | Colors https://tailwindcss.com/docs/colors 31 | |------------------------------------------------------------------------------- 32 | | 33 | | Here you can specify the colors used in your project. To get you started, 34 | | we've provided a generous palette of great looking colors that are perfect 35 | | for prototyping, but don't hesitate to change them for your project. You 36 | | own these colors, nothing will break if you change everything about them. 37 | | 38 | | We've used literal color names ("red", "blue", etc.) for the default 39 | | palette, but if you'd rather use functional names like "primary" and 40 | | "secondary", or even a numeric scale like "100" and "200", go for it. 41 | | 42 | */ 43 | 44 | var colors = { 45 | 'transparent': 'transparent', 46 | 47 | 'black': '#222b2f', 48 | 'grey-darkest': '#364349', 49 | 'grey-darker': '#596a73', 50 | 'grey-dark': '#70818a', 51 | 'grey': '#9babb4', 52 | 'grey-light': '#dae4e9', 53 | 'grey-lighter': '#f3f7f9', 54 | 'grey-lightest': '#fafcfc', 55 | 'white': '#ffffff', 56 | 57 | 'red-darkest': '#420806', 58 | 'red-darker': '#6a1b19', 59 | 'red-dark': '#cc1f1a', 60 | 'red': '#e3342f', 61 | 'red-light': '#ef5753', 62 | 'red-lighter': '#f9acaa', 63 | 'red-lightest': '#fcebea', 64 | 65 | 'orange-darkest': '#542605', 66 | 'orange-darker': '#7f4012', 67 | 'orange-dark': '#de751f', 68 | 'orange': '#f6993f', 69 | 'orange-light': '#faad63', 70 | 'orange-lighter': '#fcd9b6', 71 | 'orange-lightest': '#fff5eb', 72 | 73 | 'yellow-darkest': '#453411', 74 | 'yellow-darker': '#684f1d', 75 | 'yellow-dark': '#f2d024', 76 | 'yellow': '#ffed4a', 77 | 'yellow-light': '#fff382', 78 | 'yellow-lighter': '#fff9c2', 79 | 'yellow-lightest': '#fcfbeb', 80 | 81 | 'green-darkest': '#032d19', 82 | 'green-darker': '#0b4228', 83 | 'green-dark': '#1f9d55', 84 | 'green': '#38c172', 85 | 'green-light': '#51d88a', 86 | 'green-lighter': '#a2f5bf', 87 | 'green-lightest': '#e3fcec', 88 | 89 | 'teal-darkest': '#0d3331', 90 | 'teal-darker': '#174e4b', 91 | 'teal-dark': '#38a89d', 92 | 'teal': '#4dc0b5', 93 | 'teal-light': '#64d5ca', 94 | 'teal-lighter': '#a0f0ed', 95 | 'teal-lightest': '#e8fffe', 96 | 97 | 'blue-darkest': '#05233b', 98 | 'blue-darker': '#103d60', 99 | 'blue-dark': '#2779bd', 100 | 'blue': '#3490dc', 101 | 'blue-light': '#6cb2eb', 102 | 'blue-lighter': '#bcdefa', 103 | 'blue-lightest': '#eff8ff', 104 | 105 | 'indigo-darkest': '#191e38', 106 | 'indigo-darker': '#2f365f', 107 | 'indigo-dark': '#5661b3', 108 | 'indigo': '#6574cd', 109 | 'indigo-light': '#7886d7', 110 | 'indigo-lighter': '#b2b7ff', 111 | 'indigo-lightest': '#e6e8ff', 112 | 113 | 'purple-darkest': '#1f133f', 114 | 'purple-darker': '#352465', 115 | 'purple-dark': '#794acf', 116 | 'purple': '#9561e2', 117 | 'purple-light': '#a779e9', 118 | 'purple-lighter': '#d6bbfc', 119 | 'purple-lightest': '#f3ebff', 120 | 121 | 'pink-darkest': '#45051e', 122 | 'pink-darker': '#72173a', 123 | 'pink-dark': '#eb5286', 124 | 'pink': '#f66d9b', 125 | 'pink-light': '#fa7ea8', 126 | 'pink-lighter': '#ffbbca', 127 | 'pink-lightest': '#ffebef' 128 | } 129 | 130 | module.exports = { 131 | 132 | /* 133 | |----------------------------------------------------------------------------- 134 | | Colors https://tailwindcss.com/docs/colors 135 | |----------------------------------------------------------------------------- 136 | | 137 | | The color palette defined above is also assigned to the "colors" key of 138 | | your Tailwind config. This makes it easy to access them in your CSS 139 | | using Tailwind's config helper. For example: 140 | | 141 | | .error { color: config('colors.red') } 142 | | 143 | */ 144 | 145 | colors: colors, 146 | 147 | /* 148 | |----------------------------------------------------------------------------- 149 | | Screens https://tailwindcss.com/docs/responsive-design 150 | |----------------------------------------------------------------------------- 151 | | 152 | | Screens in Tailwind are translated to CSS media queries. They define the 153 | | responsive breakpoints for your project. By default Tailwind takes a 154 | | "mobile first" approach, where each screen size represents a minimum 155 | | viewport width. Feel free to have as few or as many screens as you 156 | | want, naming them in whatever way you'd prefer for your project. 157 | | 158 | | Tailwind also allows for more complex screen definitions, which can be 159 | | useful in certain situations. Be sure to see the full responsive 160 | | documentation for a complete list of options. 161 | | 162 | | Class name: .{screen}:{utility} 163 | | 164 | */ 165 | 166 | screens: { 167 | 'sm': '576px', 168 | 'md': '768px', 169 | 'lg': '992px', 170 | 'xl': '1200px' 171 | }, 172 | 173 | /* 174 | |----------------------------------------------------------------------------- 175 | | Fonts https://tailwindcss.com/docs/fonts 176 | |----------------------------------------------------------------------------- 177 | | 178 | | Here is where you define your project's font stack, or font families. 179 | | Keep in mind that Tailwind doesn't actually load any fonts for you. 180 | | If you're using custom fonts you'll need to import them prior to 181 | | defining them here. 182 | | 183 | | By default we provide a native font stack that works remarkably well on 184 | | any device or OS you're using, since it just uses the default fonts 185 | | provided by the platform. 186 | | 187 | | Class name: .font-{name} 188 | | 189 | */ 190 | 191 | fonts: { 192 | 'sans': [ 193 | '-apple-system', 194 | 'BlinkMacSystemFont', 195 | 'Segoe UI', 196 | 'Roboto', 197 | 'Oxygen', 198 | 'Ubuntu', 199 | 'Cantarell', 200 | 'Fira Sans', 201 | 'Droid Sans', 202 | 'Helvetica Neue' 203 | ], 204 | 'serif': [ 205 | 'Constantia', 206 | 'Lucida Bright', 207 | 'Lucidabright', 208 | 'Lucida Serif', 209 | 'Lucida', 210 | 'DejaVu Serif', 211 | 'Bitstream Vera Serif', 212 | 'Liberation Serif', 213 | 'Georgia', 214 | 'serif' 215 | ], 216 | 'mono': [ 217 | 'Menlo', 218 | 'Monaco', 219 | 'Consolas', 220 | 'Liberation Mono', 221 | 'Courier New', 222 | 'monospace' 223 | ] 224 | }, 225 | 226 | /* 227 | |----------------------------------------------------------------------------- 228 | | Text sizes https://tailwindcss.com/docs/text-sizing 229 | |----------------------------------------------------------------------------- 230 | | 231 | | Here is where you define your text sizes. Name these in whatever way 232 | | makes the most sense to you. We use size names by default, but 233 | | you're welcome to use a numeric scale or even something else 234 | | entirely. 235 | | 236 | | By default Tailwind uses the "rem" unit type for most measurements. 237 | | This allows you to set a root font size which all other sizes are 238 | | then based on. That said, you are free to use whatever units you 239 | | prefer, be it rems, ems, pixels or other. 240 | | 241 | | Class name: .text-{size} 242 | | 243 | */ 244 | 245 | textSizes: { 246 | 'xs': '.75rem', // 12px 247 | 'sm': '.875rem', // 14px 248 | 'base': '1rem', // 16px 249 | 'lg': '1.125rem', // 18px 250 | 'xl': '1.25rem', // 20px 251 | '2xl': '1.5rem', // 24px 252 | '3xl': '1.875rem', // 30px 253 | '4xl': '2.25rem', // 36px 254 | '5xl': '3rem' // 48px 255 | }, 256 | 257 | /* 258 | |----------------------------------------------------------------------------- 259 | | Font weights https://tailwindcss.com/docs/font-weight 260 | |----------------------------------------------------------------------------- 261 | | 262 | | Here is where you define your font weights. We've provided a list of 263 | | common font weight names with their respective numeric scale values 264 | | to get you started. It's unlikely that your project will require 265 | | all of these, so we recommend removing those you don't need. 266 | | 267 | | Class name: .font-{weight} 268 | | 269 | */ 270 | 271 | fontWeights: { 272 | 'hairline': 100, 273 | 'thin': 200, 274 | 'light': 300, 275 | 'normal': 400, 276 | 'medium': 500, 277 | 'semibold': 600, 278 | 'bold': 700, 279 | 'extrabold': 800, 280 | 'black': 900 281 | }, 282 | 283 | /* 284 | |----------------------------------------------------------------------------- 285 | | Leading (line height) https://tailwindcss.com/docs/line-height 286 | |----------------------------------------------------------------------------- 287 | | 288 | | Here is where you define your line height values, or as we call 289 | | them in Tailwind, leadings. 290 | | 291 | | Class name: .leading-{size} 292 | | 293 | */ 294 | 295 | leading: { 296 | 'none': 1, 297 | 'tight': 1.25, 298 | 'normal': 1.5, 299 | 'loose': 2 300 | }, 301 | 302 | /* 303 | |----------------------------------------------------------------------------- 304 | | Tracking (letter spacing) https://tailwindcss.com/docs/letter-spacing 305 | |----------------------------------------------------------------------------- 306 | | 307 | | Here is where you define your letter spacing values, or as we call 308 | | them in Tailwind, tracking. 309 | | 310 | | Class name: .tracking-{size} 311 | | 312 | */ 313 | 314 | tracking: { 315 | 'tight': '-0.05em', 316 | 'normal': '0', 317 | 'wide': '0.05em' 318 | }, 319 | 320 | /* 321 | |----------------------------------------------------------------------------- 322 | | Text colors https://tailwindcss.com/docs/text-color 323 | |----------------------------------------------------------------------------- 324 | | 325 | | Here is where you define your text colors. By default these use the 326 | | color palette we defined above, however you're welcome to set these 327 | | independently if that makes sense for your project. 328 | | 329 | | Class name: .text-{color} 330 | | 331 | */ 332 | 333 | textColors: colors, 334 | 335 | /* 336 | |----------------------------------------------------------------------------- 337 | | Background colors https://tailwindcss.com/docs/background-color 338 | |----------------------------------------------------------------------------- 339 | | 340 | | Here is where you define your background colors. By default these use 341 | | the color palette we defined above, however you're welcome to set 342 | | these independently if that makes sense for your project. 343 | | 344 | | Class name: .bg-{color} 345 | | 346 | */ 347 | 348 | backgroundColors: colors, 349 | 350 | /* 351 | |----------------------------------------------------------------------------- 352 | | Border widths https://tailwindcss.com/docs/border-width 353 | |----------------------------------------------------------------------------- 354 | | 355 | | Here is where you define your border widths. Take note that border 356 | | widths require a special "default" value set as well. This is the 357 | | width that will be used when you do not specify a border width. 358 | | 359 | | Class name: .border{-side?}{-width?} 360 | | 361 | */ 362 | 363 | borderWidths: { 364 | default: '1px', 365 | '0': '0', 366 | '2': '2px', 367 | '4': '4px', 368 | '8': '8px' 369 | }, 370 | 371 | /* 372 | |----------------------------------------------------------------------------- 373 | | Border colors https://tailwindcss.com/docs/border-color 374 | |----------------------------------------------------------------------------- 375 | | 376 | | Here is where you define your border colors. By default these use the 377 | | color palette we defined above, however you're welcome to set these 378 | | independently if that makes sense for your project. 379 | | 380 | | Take note that border colors require a special "default" value set 381 | | as well. This is the color that will be used when you do not 382 | | specify a border color. 383 | | 384 | | Class name: .border-{color} 385 | | 386 | */ 387 | 388 | borderColors: Object.assign({ default: colors['grey-light'] }, colors), 389 | 390 | /* 391 | |----------------------------------------------------------------------------- 392 | | Border radius https://tailwindcss.com/docs/border-radius 393 | |----------------------------------------------------------------------------- 394 | | 395 | | Here is where you define your border radius values. If a `default` radius 396 | | is provided, it will be made available as the non-suffixed `.rounded` 397 | | utility. 398 | | 399 | | Class name: .rounded{-radius?} 400 | | 401 | */ 402 | 403 | borderRadius: { 404 | default: '.25rem', 405 | 'sm': '.125rem', 406 | 'lg': '.5rem', 407 | 'full': '9999px', 408 | 'none': '0' 409 | }, 410 | 411 | /* 412 | |----------------------------------------------------------------------------- 413 | | Width https://tailwindcss.com/docs/width 414 | |----------------------------------------------------------------------------- 415 | | 416 | | Here is where you define your width utility sizes. These can be 417 | | percentage based, pixels, rems, or any other units. By default 418 | | we provide a sensible rem based numeric scale, a percentage 419 | | based fraction scale, plus some other common use-cases. You 420 | | can, of course, modify these values as needed. 421 | | 422 | | 423 | | It's also worth mentioning that Tailwind automatically escapes 424 | | invalid CSS class name characters, which allows you to have 425 | | awesome classes like .w-2/3. 426 | | 427 | | Class name: .w-{size} 428 | | 429 | */ 430 | 431 | width: { 432 | 'auto': 'auto', 433 | 'px': '1px', 434 | '1': '0.25rem', 435 | '2': '0.5rem', 436 | '3': '0.75rem', 437 | '4': '1rem', 438 | '6': '1.5rem', 439 | '8': '2rem', 440 | '10': '2.5rem', 441 | '12': '3rem', 442 | '16': '4rem', 443 | '24': '6rem', 444 | '32': '8rem', 445 | '48': '12rem', 446 | '64': '16rem', 447 | '1/2': '50%', 448 | '1/3': '33.33333%', 449 | '2/3': '66.66667%', 450 | '1/4': '25%', 451 | '3/4': '75%', 452 | '1/5': '20%', 453 | '2/5': '40%', 454 | '3/5': '60%', 455 | '4/5': '80%', 456 | '1/6': '16.66667%', 457 | '5/6': '83.33333%', 458 | 'full': '100%', 459 | 'screen': '100vw' 460 | }, 461 | 462 | /* 463 | |----------------------------------------------------------------------------- 464 | | Height https://tailwindcss.com/docs/height 465 | |----------------------------------------------------------------------------- 466 | | 467 | | Here is where you define your height utility sizes. These can be 468 | | percentage based, pixels, rems, or any other units. By default 469 | | we provide a sensible rem based numeric scale plus some other 470 | | common use-cases. You can, of course, modify these values as 471 | | needed. 472 | | 473 | | Class name: .h-{size} 474 | | 475 | */ 476 | 477 | height: { 478 | 'auto': 'auto', 479 | 'px': '1px', 480 | '1': '0.25rem', 481 | '2': '0.5rem', 482 | '3': '0.75rem', 483 | '4': '1rem', 484 | '6': '1.5rem', 485 | '8': '2rem', 486 | '10': '2.5rem', 487 | '12': '3rem', 488 | '16': '4rem', 489 | '24': '6rem', 490 | '32': '8rem', 491 | '48': '12rem', 492 | '64': '16rem', 493 | 'full': '100%', 494 | 'screen': '100vh' 495 | }, 496 | 497 | /* 498 | |----------------------------------------------------------------------------- 499 | | Minimum width https://tailwindcss.com/docs/min-width 500 | |----------------------------------------------------------------------------- 501 | | 502 | | Here is where you define your minimum width utility sizes. These can 503 | | be percentage based, pixels, rems, or any other units. We provide a 504 | | couple common use-cases by default. You can, of course, modify 505 | | these values as needed. 506 | | 507 | | Class name: .min-w-{size} 508 | | 509 | */ 510 | 511 | minWidth: { 512 | '0': '0', 513 | 'full': '100%' 514 | }, 515 | 516 | /* 517 | |----------------------------------------------------------------------------- 518 | | Minimum height https://tailwindcss.com/docs/min-height 519 | |----------------------------------------------------------------------------- 520 | | 521 | | Here is where you define your minimum height utility sizes. These can 522 | | be percentage based, pixels, rems, or any other units. We provide a 523 | | few common use-cases by default. You can, of course, modify these 524 | | values as needed. 525 | | 526 | | Class name: .min-h-{size} 527 | | 528 | */ 529 | 530 | minHeight: { 531 | '0': '0', 532 | 'full': '100%', 533 | 'screen': '100vh' 534 | }, 535 | 536 | /* 537 | |----------------------------------------------------------------------------- 538 | | Maximum width https://tailwindcss.com/docs/max-width 539 | |----------------------------------------------------------------------------- 540 | | 541 | | Here is where you define your maximum width utility sizes. These can 542 | | be percentage based, pixels, rems, or any other units. By default 543 | | we provide a sensible rem based scale and a "full width" size, 544 | | which is basically a reset utility. You can, of course, 545 | | modify these values as needed. 546 | | 547 | | Class name: .max-w-{size} 548 | | 549 | */ 550 | 551 | maxWidth: { 552 | 'xs': '20rem', 553 | 'sm': '30rem', 554 | 'md': '40rem', 555 | 'lg': '50rem', 556 | 'xl': '60rem', 557 | '2xl': '70rem', 558 | '3xl': '80rem', 559 | '4xl': '90rem', 560 | '5xl': '100rem', 561 | 'full': '100%' 562 | }, 563 | 564 | /* 565 | |----------------------------------------------------------------------------- 566 | | Maximum height https://tailwindcss.com/docs/max-height 567 | |----------------------------------------------------------------------------- 568 | | 569 | | Here is where you define your maximum height utility sizes. These can 570 | | be percentage based, pixels, rems, or any other units. We provide a 571 | | couple common use-cases by default. You can, of course, modify 572 | | these values as needed. 573 | | 574 | | Class name: .max-h-{size} 575 | | 576 | */ 577 | 578 | maxHeight: { 579 | 'full': '100%', 580 | 'screen': '100vh' 581 | }, 582 | 583 | /* 584 | |----------------------------------------------------------------------------- 585 | | Padding https://tailwindcss.com/docs/padding 586 | |----------------------------------------------------------------------------- 587 | | 588 | | Here is where you define your padding utility sizes. These can be 589 | | percentage based, pixels, rems, or any other units. By default we 590 | | provide a sensible rem based numeric scale plus a couple other 591 | | common use-cases like "1px". You can, of course, modify these 592 | | values as needed. 593 | | 594 | | Class name: .p{side?}-{size} 595 | | 596 | */ 597 | 598 | padding: { 599 | 'px': '1px', 600 | '0': '0', 601 | '1': '0.25rem', 602 | '2': '0.5rem', 603 | '3': '0.75rem', 604 | '4': '1rem', 605 | '6': '1.5rem', 606 | '8': '2rem' 607 | }, 608 | 609 | /* 610 | |----------------------------------------------------------------------------- 611 | | Margin https://tailwindcss.com/docs/margin 612 | |----------------------------------------------------------------------------- 613 | | 614 | | Here is where you define your margin utility sizes. These can be 615 | | percentage based, pixels, rems, or any other units. By default we 616 | | provide a sensible rem based numeric scale plus a couple other 617 | | common use-cases like "1px". You can, of course, modify these 618 | | values as needed. 619 | | 620 | | Class name: .m{side?}-{size} 621 | | 622 | */ 623 | 624 | margin: { 625 | 'px': '1px', 626 | '0': '0', 627 | '1': '0.25rem', 628 | '2': '0.5rem', 629 | '3': '0.75rem', 630 | '4': '1rem', 631 | '6': '1.5rem', 632 | '8': '2rem' 633 | }, 634 | 635 | /* 636 | |----------------------------------------------------------------------------- 637 | | Negative margin https://tailwindcss.com/docs/negative-margin 638 | |----------------------------------------------------------------------------- 639 | | 640 | | Here is where you define your negative margin utility sizes. These can 641 | | be percentage based, pixels, rems, or any other units. By default we 642 | | provide matching values to the padding scale since these utilities 643 | | generally get used together. You can, of course, modify these 644 | | values as needed. 645 | | 646 | | Class name: .-m{side?}-{size} 647 | | 648 | */ 649 | 650 | negativeMargin: { 651 | 'px': '1px', 652 | '0': '0', 653 | '1': '0.25rem', 654 | '2': '0.5rem', 655 | '3': '0.75rem', 656 | '4': '1rem', 657 | '6': '1.5rem', 658 | '8': '2rem' 659 | }, 660 | 661 | /* 662 | |----------------------------------------------------------------------------- 663 | | Shadows https://tailwindcss.com/docs/shadows 664 | |----------------------------------------------------------------------------- 665 | | 666 | | Here is where you define your shadow utilities. As you can see from 667 | | the defaults we provide, it's possible to apply multiple shadows 668 | | per utility using comma separation. 669 | | 670 | | If a `default` shadow is provided, it will be made available as the non- 671 | | suffixed `.shadow` utility. 672 | | 673 | | Class name: .shadow-{size?} 674 | | 675 | */ 676 | 677 | shadows: { 678 | default: '0 2px 4px 0 rgba(0,0,0,0.10)', 679 | 'md': '0 4px 8px 0 rgba(0,0,0,0.12), 0 2px 4px 0 rgba(0,0,0,0.08)', 680 | 'lg': '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)', 681 | 'inner': 'inset 0 2px 4px 0 rgba(0,0,0,0.06)', 682 | 'none': 'none' 683 | }, 684 | 685 | /* 686 | |----------------------------------------------------------------------------- 687 | | Z-index https://tailwindcss.com/docs/z-index 688 | |----------------------------------------------------------------------------- 689 | | 690 | | Here is where you define your z-index utility values. By default we 691 | | provide a sensible numeric scale. You can, of course, modify these 692 | | values as needed. 693 | | 694 | | Class name: .z-{index} 695 | | 696 | */ 697 | 698 | zIndex: { 699 | '0': 0, 700 | '10': 10, 701 | '20': 20, 702 | '30': 30, 703 | '40': 40, 704 | '50': 50, 705 | 'auto': 'auto' 706 | }, 707 | 708 | /* 709 | |----------------------------------------------------------------------------- 710 | | Opacity https://tailwindcss.com/docs/opacity 711 | |----------------------------------------------------------------------------- 712 | | 713 | | Here is where you define your opacity utility values. By default we 714 | | provide a sensible numeric scale. You can, of course, modify these 715 | | values as needed. 716 | | 717 | | Class name: .opacity-{name} 718 | | 719 | */ 720 | 721 | opacity: { 722 | '0': '0', 723 | '25': '.25', 724 | '50': '.5', 725 | '75': '.75', 726 | '100': '1' 727 | }, 728 | 729 | /* 730 | |----------------------------------------------------------------------------- 731 | | Packages 732 | |----------------------------------------------------------------------------- 733 | | 734 | | Here is where you can define the configuration for any Tailwind packages 735 | | you're using. These can be utility packs, component bundles, or even 736 | | complete themes. You'll want to reference each package's 737 | | documentation for a list of settings available for it. 738 | | 739 | */ 740 | 741 | packages: { 742 | } 743 | 744 | } 745 | --------------------------------------------------------------------------------