├── .gitignore ├── 404.php ├── README.md ├── archive.php ├── assets ├── css │ ├── app.css │ ├── conditional │ │ ├── article.css │ │ ├── conditional.css │ │ └── header.css │ └── whitelist │ │ ├── buttons.css │ │ ├── forms.css │ │ ├── icons.css │ │ ├── navigation.css │ │ ├── transitions.css │ │ ├── type.css │ │ ├── whitelist.css │ │ └── wordpress.css ├── images │ └── svg │ │ ├── icon-chart.svg │ │ ├── icon-gear.svg │ │ ├── icon-growth.svg │ │ ├── icon-instagram.svg │ │ ├── icon-knowledge.svg │ │ ├── icon-mark-white.svg │ │ ├── icon-person.svg │ │ ├── icon-ribbon.svg │ │ ├── icon-search.svg │ │ ├── icon-toolbox.svg │ │ ├── icon-twitter.svg │ │ └── monitor-window.svg └── js │ ├── main.js │ └── modules │ └── menu.js ├── comments.php ├── composer.json ├── composer.lock ├── content-templates └── content-article.php ├── footer.php ├── functions.php ├── header.php ├── index.php ├── package-lock.json ├── package.json ├── page-templates └── page-sample.php ├── screenshot.png ├── search.php ├── sidebar.php ├── src ├── classes.php ├── enqueue.php ├── setup.php └── sidebars.php ├── style.css ├── tailwind.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | vendor 3 | dist 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /404.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 |
14 |

Oops! That page can't be found.

15 |

It looks like nothing was found at this location. Maybe try one of the links below or a search?

16 | 18 |
19 |
20 | 21 | 12 |
13 |

14 |
15 | 22 |
23 |
24 | p:first-of-type { 13 | @apply text-lg; 14 | } 15 | 16 | h2, 17 | h3, 18 | h4, 19 | h5, 20 | h6 { 21 | @apply font-bold; 22 | } 23 | 24 | h4, 25 | h5, 26 | h6 { 27 | text-transform: uppercase; 28 | } 29 | 30 | @screen lg { 31 | p, 32 | ul, 33 | ol { 34 | @apply mt-4 mb-8 leading-normal; 35 | } 36 | 37 | p.text-sm { 38 | @apply text-sm; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /assets/css/conditional/conditional.css: -------------------------------------------------------------------------------- 1 | @import "header"; 2 | @import "article"; -------------------------------------------------------------------------------- /assets/css/conditional/header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | @apply py-2 z-10 bg-gray-100; 3 | 4 | @screen lg { 5 | @apply py-6; 6 | } 7 | 8 | .container { 9 | @apply flex justify-between items-center; 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /assets/css/whitelist/buttons.css: -------------------------------------------------------------------------------- 1 | .button { 2 | @apply font-sans not-italic font-light rounded bg-gray-800 border-2 border-gray-800 leading-normal inline-block no-underline text-gray-200 px-6 py-4 shadow-lg text-center; 3 | transform: translateY(0); 4 | 5 | @screen lg { 6 | @apply px-12 py-4; 7 | } 8 | 9 | &:focus, 10 | &:hover { 11 | @apply text-white border-gray-800 bg-gray-800 no-underline shadow; 12 | transform: translate3d(1px, 2px, 0); 13 | cursor: pointer; 14 | } 15 | } 16 | 17 | .button-white { 18 | @extend .button; 19 | @apply bg-gray-100 text-gray-800; 20 | 21 | &:focus, 22 | &:hover { 23 | @apply bg-white text-gray-600; 24 | } 25 | } 26 | 27 | .button-primary { 28 | @extend .button; 29 | @apply bg-primary-100 text-white border-none; 30 | 31 | &:focus, 32 | &:hover { 33 | @apply border-primary-100 bg-primary-100 text-white bg-primary-200; 34 | } 35 | } 36 | 37 | .button-link { 38 | @apply font-bold font-serif not-italic; 39 | } 40 | 41 | .highlight { 42 | @apply font-bold font-sans not-italic text-primary-100; 43 | } 44 | 45 | .button-sm { 46 | @apply px-4 py-2 text-sm; 47 | } 48 | 49 | .button-lg { 50 | @apply px-12 py-4; 51 | 52 | @screen lg { 53 | @apply py-6; 54 | } 55 | } -------------------------------------------------------------------------------- /assets/css/whitelist/forms.css: -------------------------------------------------------------------------------- 1 | label { 2 | @apply text-sm font-sans uppercase font-bold; 3 | } 4 | 5 | input, 6 | textarea, 7 | select { 8 | @apply border-2 bg-gray-100 leading-normal rounded w-full py-3 px-4 mb-2 italic text-base w-full border-gray-300; 9 | @extend .transition; 10 | 11 | &[aria-invalid="true"] { 12 | @apply border-primary-100; 13 | } 14 | 15 | &:focus { 16 | @apply shadow-lg bg-gray-100 border-gray-200; 17 | transform: translate3d(-1px, -1px, 0); 18 | outline: 0; 19 | } 20 | } 21 | 22 | input, 23 | textarea { 24 | &:focus { 25 | @apply border-gray-800; 26 | } 27 | } 28 | 29 | textarea { 30 | @apply h-24; 31 | } 32 | 33 | select { 34 | @apply h-12 bg-gray-100; 35 | 36 | option { 37 | @apply bg-white; 38 | } 39 | 40 | &:focus { 41 | @apply shadow-none border-gray-300; 42 | transform: none; 43 | } 44 | } -------------------------------------------------------------------------------- /assets/css/whitelist/icons.css: -------------------------------------------------------------------------------- 1 | .svg-icon { 2 | width: 1em; 3 | height: 1em; 4 | 5 | path, 6 | polygon, 7 | rect { 8 | @apply fill-current; 9 | } 10 | 11 | circle { 12 | @apply stroke-current; 13 | stroke-width: 1; 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /assets/css/whitelist/navigation.css: -------------------------------------------------------------------------------- 1 | .nav-primary { 2 | @apply hidden; 3 | 4 | a { 5 | @apply text-gray-800 italic no-underline font-normal; 6 | 7 | &:focus, 8 | &:hover { 9 | @apply underline; 10 | } 11 | } 12 | 13 | li { 14 | @apply leading-tight; 15 | } 16 | 17 | .highlight { 18 | @apply text-primary-100 not-italic font-bold; 19 | } 20 | 21 | .button { 22 | @apply text-white; 23 | } 24 | 25 | .current-menu-item a { 26 | @apply font-bold not-italic; 27 | } 28 | 29 | @screen md { 30 | @apply block; 31 | 32 | .dark-header & { 33 | transform: none; 34 | } 35 | 36 | li { 37 | @apply mb-0; 38 | 39 | &:last-child a { 40 | @apply mr-0; 41 | } 42 | } 43 | 44 | a { 45 | @apply mx-4; 46 | } 47 | 48 | .button { 49 | @extend .button-sm; 50 | } 51 | 52 | .sub-menu { 53 | @apply hidden absolute bg-white shadow-lg; 54 | @extend .list-reset; 55 | 56 | a { 57 | @apply text-gray-200; 58 | } 59 | } 60 | 61 | .menu-item-has-children { 62 | @apply relative; 63 | 64 | &:hover { 65 | .sub-menu { 66 | @apply block; 67 | } 68 | } 69 | } 70 | } 71 | } 72 | 73 | .nav-mobile { 74 | @extend .nav-primary, .transition; 75 | @apply fixed left-0 top-0 h-full bg-white p-4 z-50 w-full overflow-scroll block z-50 text-center; 76 | transform: translate3d(-100%, 0, 0); 77 | 78 | &.active { 79 | transform: translate3d(0, 0, 0); 80 | } 81 | 82 | a { 83 | @apply block w-full text-2xl; 84 | } 85 | 86 | @screen md { 87 | @apply hidden; 88 | } 89 | 90 | .admin-bar & { 91 | top: 46px; 92 | 93 | @screen md { 94 | top: 32px; 95 | } 96 | } 97 | } 98 | 99 | 100 | @screen md { 101 | .toggle { 102 | @apply hidden; 103 | } 104 | } 105 | 106 | .footer-menu { 107 | @apply pl-0 ml-0; 108 | @extend .list-reset; 109 | 110 | a { 111 | @apply text-white not-italic; 112 | } 113 | } -------------------------------------------------------------------------------- /assets/css/whitelist/transitions.css: -------------------------------------------------------------------------------- 1 | .transition { 2 | transition: all .25s cubic-bezier(0.165, 0.84, 0.44, 1); 3 | } 4 | 5 | a, 6 | .button, 7 | .button-large, 8 | .button-lg, 9 | .button-primary, 10 | .button-bg-primary-200, 11 | .button-bg-primary-200 .icon { 12 | @extend .transition; 13 | } -------------------------------------------------------------------------------- /assets/css/whitelist/type.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 18px; 3 | } 4 | 5 | body { 6 | @apply bg-gray-100 font-serif text-base font-light leading-normal antialiased; 7 | } 8 | 9 | strong, 10 | b { 11 | @apply font-bold; 12 | } 13 | 14 | p { 15 | @apply mt-2 mb-4; 16 | } 17 | 18 | a { 19 | @apply text-primary-100 underline font-bold; 20 | 21 | &:focus, 22 | &:hover { 23 | @apply text-gray-600; 24 | } 25 | } 26 | 27 | h1, 28 | h2, 29 | h3, 30 | h4, 31 | h5, 32 | h6 { 33 | @apply mt-8 mb-4 font-sans font-light; 34 | 35 | @screen lg { 36 | @apply mt-12; 37 | } 38 | } 39 | 40 | h1, 41 | h2, 42 | h3 { 43 | @apply leading-tight; 44 | } 45 | 46 | h4, 47 | h5, 48 | h6 { 49 | @apply leading-normal; 50 | } 51 | 52 | h1 { 53 | @apply text-5xl; 54 | } 55 | 56 | h2 { 57 | @apply text-4xl; 58 | } 59 | 60 | h3 { 61 | @apply text-3xl; 62 | } 63 | 64 | h4 { 65 | @apply text-2xl; 66 | } 67 | 68 | h5 { 69 | @apply text-xl; 70 | } 71 | 72 | h6 { 73 | @apply text-xl tracking-wide; 74 | } 75 | 76 | ul, 77 | ol { 78 | @apply mt-4 mb-10 ml-2; 79 | 80 | @screen lg { 81 | @apply ml-8; 82 | } 83 | } 84 | 85 | li { 86 | @apply mb-2; 87 | 88 | .sidebar &, 89 | .article & { 90 | list-style-type: disc; 91 | } 92 | } 93 | 94 | blockquote { 95 | @apply text-center italic m-10; 96 | 97 | @screen lg { 98 | @apply m-16 text-lg; 99 | } 100 | } 101 | 102 | .list-reset { 103 | display: inline-block; 104 | list-style: none; 105 | margin: 0; 106 | padding: 0; 107 | } 108 | 109 | ::selection { 110 | @apply bg-primary-100 text-gray-200; 111 | } -------------------------------------------------------------------------------- /assets/css/whitelist/whitelist.css: -------------------------------------------------------------------------------- 1 | @import "type.css"; 2 | @import "navigation.css"; 3 | @import "buttons.css"; 4 | @import "transitions.css"; 5 | @import "icons.css"; 6 | @import "forms.css"; 7 | @import "wordpress.css"; -------------------------------------------------------------------------------- /assets/css/whitelist/wordpress.css: -------------------------------------------------------------------------------- 1 | .alignright { 2 | @apply float-right ml-4 mb-4; 3 | } 4 | 5 | .alignleft { 6 | @apply float-left mr-4 mb-4; 7 | } 8 | 9 | .aligncenter { 10 | @apply mx-auto; 11 | } 12 | 13 | img { 14 | @apply rounded; 15 | } 16 | 17 | .screen-reader-text { 18 | border: 0; 19 | clip: rect(1px, 1px, 1px, 1px); 20 | clip-path: inset(50%); 21 | height: 1px; 22 | margin: -1px; 23 | overflow: hidden; 24 | padding: 0; 25 | position: absolute; 26 | width: 1px; 27 | word-wrap: normal !important; 28 | } -------------------------------------------------------------------------------- /assets/images/svg/icon-chart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-gear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-growth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-instagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-knowledge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-mark-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/images/svg/icon-person.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-ribbon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-toolbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/icon-twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /assets/images/svg/monitor-window.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | monitor-window 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /assets/js/main.js: -------------------------------------------------------------------------------- 1 | // Build CSS 2 | import '../css/app.css' 3 | 4 | // Import JS Modules 5 | import menu_init from './modules/menu' 6 | 7 | // Load Menu Script 8 | document.addEventListener( 'DOMContentLoaded', menu_init ); -------------------------------------------------------------------------------- /assets/js/modules/menu.js: -------------------------------------------------------------------------------- 1 | export default () => { 2 | const toggles = document.querySelectorAll('.toggle') 3 | const menu = document.querySelector('.nav-mobile') 4 | 5 | if ( ! toggles || ! menu ) { 6 | return; 7 | } 8 | 9 | let active = false 10 | 11 | toggles.forEach(toggle => { 12 | toggle.addEventListener( 'click', () => { 13 | if ( active ) { 14 | open(); 15 | } else { 16 | close(); 17 | } 18 | }) 19 | }) 20 | 21 | function open() { 22 | menu.classList.remove('active') 23 | active = false 24 | } 25 | 26 | function close() { 27 | menu.classList.add('active') 28 | active = true 29 | } 30 | } -------------------------------------------------------------------------------- /comments.php: -------------------------------------------------------------------------------- 1 | 22 | 23 |
24 | 25 | 27 |

28 | ' . get_the_title() . '' 33 | ); 34 | ?> 35 |

36 | 37 | 1 && get_option( 'page_comments' ) ) : ?> 39 | 46 | 48 | 49 |
    50 | 'ol', 53 | 'short_ping' => true, 54 | ) ); ?> 55 |
56 | 57 | 1 && get_option( 'page_comments' ) ) : ?> 59 | 66 | 68 | 69 | 71 | 72 | 76 |

77 | 79 | 80 | 82 |
83 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "a7/autoload": "^2.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "c0d1ffb65b9e528acc693829affbf907", 8 | "packages": [ 9 | { 10 | "name": "a7/autoload", 11 | "version": "2.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/a7/autoload.git", 15 | "reference": "2d4a63c88150869883e43ad04e04b81125b55fd9" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/a7/autoload/zipball/2d4a63c88150869883e43ad04e04b81125b55fd9", 20 | "reference": "2d4a63c88150869883e43ad04e04b81125b55fd9", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=7.0" 25 | }, 26 | "type": "library", 27 | "autoload": { 28 | "files": [ 29 | "package.php" 30 | ] 31 | }, 32 | "notification-url": "https://packagist.org/downloads/", 33 | "license": [ 34 | "Unlicense" 35 | ], 36 | "authors": [ 37 | { 38 | "name": "A7", 39 | "email": "a7@fastmail.com", 40 | "homepage": "https://github.com/a7" 41 | } 42 | ], 43 | "description": "Automatically and recursively require_once all php files in a given directory.", 44 | "time": "2019-03-28T11:26:32+00:00" 45 | } 46 | ], 47 | "packages-dev": [], 48 | "aliases": [], 49 | "minimum-stability": "stable", 50 | "stability-flags": [], 51 | "prefer-stable": false, 52 | "prefer-lowest": false, 53 | "platform": [], 54 | "platform-dev": [] 55 | } 56 | -------------------------------------------------------------------------------- /content-templates/content-article.php: -------------------------------------------------------------------------------- 1 | 12 |
itemscope itemtype="https://schema.org/CreativeWork"> 13 |
14 |

15 | %s', 19 | esc_url( get_the_permalink() ), 20 | esc_html( get_the_title() ) 21 | ); 22 | } else { 23 | echo get_the_title(); 24 | } ?> 25 |

26 |

Published on

27 |
28 | 29 |
30 | 'rounded shadow-lg'] ); 33 | } 34 | 35 | the_content(); ?> 36 |
37 | 38 | 41 |
42 | -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | 15 | 16 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | version ); 9 | define( 'WP_Tailwind_DIR', __DIR__ ); 10 | define( 'WP_Tailwind_URL', get_template_directory_uri() ); 11 | 12 | require_once( WP_Tailwind_DIR . '/vendor/autoload.php' ); 13 | 14 | \A7\autoload( __DIR__ . '/src' ); 15 | -------------------------------------------------------------------------------- /header.php: -------------------------------------------------------------------------------- 1 | section and everything up until
6 | * 7 | * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials 8 | * 9 | * @package Freeshifter 10 | */ 11 | 12 | namespace WP_Tailwind; 13 | 14 | ?> 15 | > 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | itemscope itemtype="https://schema.org/WebPage"> 26 | 27 | '', 31 | 'theme_location' => 'primary', 32 | 'container' => 'nav', 33 | 'container_class' => 'nav-mobile', 34 | 'container_id' => 'mobile-menu', 35 | 'menu_class' => 'list-reset m-12' 36 | ] ); 37 | }?> 38 | 39 |
40 |
41 | %3$s', 48 | $tag, 49 | esc_url( home_url( '/' ) ), 50 | esc_html( get_bloginfo( 'name' ) ) 51 | ); 52 | 53 | if ( has_nav_menu( 'primary' ) ) { 54 | wp_nav_menu([ 55 | 'theme_location' => 'primary', 56 | 'container' => 'nav', 57 | 'container_class' => 'nav-primary ml-auto', 58 | 'menu_class' => 'list-reset m-0 md:flex md:justify-end md:items-center' 59 | ]); 60 | } ?> 61 | 64 |
65 |
66 | 67 |
-------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 12 |
13 |
14 | 21 |
22 | 24 | 27 | 29 |
30 | 1%", 45 | "last 2 versions", 46 | "not ie <= 11" 47 | ], 48 | "engines": { 49 | "node": ">=10.5.0", 50 | "npm": ">=6.4.1" 51 | }, 52 | "author": "", 53 | "license": "ISC" 54 | } 55 | -------------------------------------------------------------------------------- /page-templates/page-sample.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |
13 |
14 | Search Results for: %s', 18 | esc_html( get_search_query() ) 19 | ); 20 | 21 | echo '
'; 22 | while ( have_posts() ) { 23 | the_post(); ?> 24 | ', 44 | get_the_excerpt() 45 | ); ?> 46 | 47 | 48 |
49 | '; 52 | 53 | the_posts_navigation(); 54 | 55 | else : 56 | 57 | printf( 'Sorry, no results for %s', 58 | esc_html( get_search_query() ) 59 | ); 60 | 61 | endif; ?> 62 |
63 |
64 | 65 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /src/classes.php: -------------------------------------------------------------------------------- 1 | __( 'Primary Menu', 'wp-tailwind' ), 25 | 'footer' => __( 'Footer Menu', 'wp-tailwind' ), 26 | ] ); 27 | 28 | // Switch default core markup for search form, comment form, and comments to output valid HTML5. 29 | add_theme_support( 'html5', [ 30 | 'search-form', 31 | 'comment-form', 32 | 'comment-list', 33 | 'gallery', 34 | 'caption', 35 | ] ); 36 | 37 | } ); -------------------------------------------------------------------------------- /src/sidebars.php: -------------------------------------------------------------------------------- 1 | esc_html( 'Sidebar' ), 12 | 'id' => 'sidebar', 13 | 'description' => '', 14 | 'before_widget' => '
', 15 | 'after_widget' => '
', 16 | 'before_title' => '

', 17 | 'after_title' => '

', 18 | ] ); 19 | 20 | } ); -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme Name: WP Tailwind 3 | * Theme URI: https://github.com/freeshifter/wp-tailwind 4 | * Author: Freeshifter LLC 5 | * Author URI: https://www.freeshifter.com 6 | * Version: 1.0.0 7 | * License: GNU General Public License v2 or later 8 | * License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 | * Text Domain: wp-tailwind 10 | */ 11 | -------------------------------------------------------------------------------- /tailwind.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | prefix: '', 3 | important: false, 4 | separator: ':', 5 | theme: { 6 | screens: { 7 | sm: '640px', 8 | md: '768px', 9 | lg: '1024px', 10 | xl: '1280px', 11 | retina: { 12 | 'min-resolution': '192dpi' 13 | } 14 | }, 15 | colors: { 16 | transparent: 'transparent', 17 | 18 | black: '#000', 19 | white: '#fff', 20 | 21 | gray: { 22 | 100: '#f7fafc', 23 | 200: '#edf2f7', 24 | 300: '#e2e8f0', 25 | 400: '#cbd5e0', 26 | 500: '#a0aec0', 27 | 600: '#718096', 28 | 700: '#4a5568', 29 | 800: '#2d3748', 30 | 900: '#1a202c', 31 | }, 32 | primary: { 33 | 100: '#DB3A34', 34 | 200: '#CC3630' 35 | } 36 | }, 37 | spacing: { 38 | px: '1px', 39 | '0': '0', 40 | '1': '0.25rem', 41 | '2': '0.5rem', 42 | '3': '0.75rem', 43 | '4': '1rem', 44 | '5': '1.25rem', 45 | '6': '1.5rem', 46 | '8': '2rem', 47 | '10': '2.5rem', 48 | '12': '3rem', 49 | '16': '4rem', 50 | '20': '5rem', 51 | '24': '6rem', 52 | '32': '8rem', 53 | '40': '10rem', 54 | '48': '12rem', 55 | '56': '14rem', 56 | '64': '16rem', 57 | }, 58 | backgroundColor: theme => theme('colors'), 59 | backgroundPosition: { 60 | bottom: 'bottom', 61 | center: 'center', 62 | left: 'left', 63 | 'left-bottom': 'left bottom', 64 | 'left-top': 'left top', 65 | right: 'right', 66 | 'right-bottom': 'right bottom', 67 | 'right-top': 'right top', 68 | top: 'top', 69 | }, 70 | backgroundSize: { 71 | auto: 'auto', 72 | cover: 'cover', 73 | contain: 'contain', 74 | }, 75 | borderColor: theme => ({ 76 | ...theme('colors'), 77 | default: theme('colors.gray.300', 'currentColor'), 78 | }), 79 | borderRadius: { 80 | none: '0', 81 | sm: '0.125rem', 82 | default: '0.25rem', 83 | lg: '0.5rem', 84 | full: '9999px', 85 | }, 86 | borderWidth: { 87 | default: '1px', 88 | '0': '0', 89 | '2': '2px', 90 | '4': '4px', 91 | '8': '8px', 92 | }, 93 | boxShadow: { 94 | default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', 95 | md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', 96 | lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', 97 | xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', 98 | '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', 99 | inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', 100 | outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', 101 | none: 'none', 102 | }, 103 | container: {}, 104 | cursor: { 105 | auto: 'auto', 106 | default: 'default', 107 | pointer: 'pointer', 108 | wait: 'wait', 109 | text: 'text', 110 | move: 'move', 111 | 'not-allowed': 'not-allowed', 112 | }, 113 | fill: { 114 | current: 'currentColor', 115 | }, 116 | flex: { 117 | '1': '1 1 0%', 118 | auto: '1 1 auto', 119 | initial: '0 1 auto', 120 | none: 'none', 121 | }, 122 | flexGrow: { 123 | '0': '0', 124 | default: '1', 125 | }, 126 | flexShrink: { 127 | '0': '0', 128 | default: '1', 129 | }, 130 | fontFamily: { 131 | sans: [ 132 | '-apple-system', 133 | 'BlinkMacSystemFont', 134 | '"Segoe UI"', 135 | 'Roboto', 136 | '"Helvetica Neue"', 137 | 'Arial', 138 | '"Noto Sans"', 139 | 'sans-serif', 140 | '"Apple Color Emoji"', 141 | '"Segoe UI Emoji"', 142 | '"Segoe UI Symbol"', 143 | '"Noto Color Emoji"', 144 | ], 145 | serif: [ 146 | 'Georgia', 147 | 'Cambria', 148 | '"Times New Roman"', 149 | 'Times', 150 | 'serif', 151 | ], 152 | mono: [ 153 | 'Menlo', 154 | 'Monaco', 155 | 'Consolas', 156 | '"Liberation Mono"', 157 | '"Courier New"', 158 | 'monospace', 159 | ], 160 | }, 161 | fontSize: { 162 | xs: '0.75rem', 163 | sm: '0.875rem', 164 | base: '1rem', 165 | lg: '1.125rem', 166 | xl: '1.25rem', 167 | '2xl': '1.5rem', 168 | '3xl': '1.875rem', 169 | '4xl': '2.25rem', 170 | '5xl': '3rem', 171 | '6xl': '4rem', 172 | }, 173 | fontWeight: { 174 | hairline: '100', 175 | thin: '200', 176 | light: '300', 177 | normal: '400', 178 | medium: '500', 179 | semibold: '600', 180 | bold: '700', 181 | extrabold: '800', 182 | black: '900', 183 | }, 184 | height: theme => ({ 185 | auto: 'auto', 186 | ...theme('spacing'), 187 | full: '100%', 188 | screen: '100vh', 189 | }), 190 | inset: { 191 | '0': '0', 192 | auto: 'auto', 193 | }, 194 | letterSpacing: { 195 | tighter: '-0.05em', 196 | tight: '-0.025em', 197 | normal: '0', 198 | wide: '0.025em', 199 | wider: '0.05em', 200 | widest: '0.1em', 201 | }, 202 | lineHeight: { 203 | none: '1', 204 | tight: '1.25', 205 | snug: '1.375', 206 | normal: '1.5', 207 | relaxed: '1.625', 208 | loose: '2', 209 | }, 210 | listStyleType: { 211 | none: 'none', 212 | disc: 'disc', 213 | decimal: 'decimal', 214 | }, 215 | margin: (theme, { negative }) => ({ 216 | auto: 'auto', 217 | ...theme('spacing'), 218 | ...negative(theme('spacing')), 219 | }), 220 | maxHeight: { 221 | full: '100%', 222 | screen: '100vh', 223 | }, 224 | maxWidth: { 225 | xs: '20rem', 226 | sm: '24rem', 227 | md: '28rem', 228 | lg: '32rem', 229 | xl: '36rem', 230 | '2xl': '42rem', 231 | '3xl': '48rem', 232 | '4xl': '56rem', 233 | '5xl': '64rem', 234 | '6xl': '72rem', 235 | full: '100%', 236 | }, 237 | minHeight: { 238 | '0': '0', 239 | full: '100%', 240 | screen: '100vh', 241 | }, 242 | minWidth: { 243 | '0': '0', 244 | full: '100%', 245 | }, 246 | objectPosition: { 247 | bottom: 'bottom', 248 | center: 'center', 249 | left: 'left', 250 | 'left-bottom': 'left bottom', 251 | 'left-top': 'left top', 252 | right: 'right', 253 | 'right-bottom': 'right bottom', 254 | 'right-top': 'right top', 255 | top: 'top', 256 | }, 257 | opacity: { 258 | '0': '0', 259 | '25': '0.25', 260 | '50': '0.5', 261 | '75': '0.75', 262 | '100': '1', 263 | }, 264 | order: { 265 | first: '-9999', 266 | last: '9999', 267 | none: '0', 268 | '1': '1', 269 | '2': '2', 270 | '3': '3', 271 | '4': '4', 272 | '5': '5', 273 | '6': '6', 274 | '7': '7', 275 | '8': '8', 276 | '9': '9', 277 | '10': '10', 278 | '11': '11', 279 | '12': '12', 280 | }, 281 | padding: theme => theme('spacing'), 282 | stroke: { 283 | current: 'currentColor', 284 | }, 285 | textColor: theme => theme('colors'), 286 | width: theme => ({ 287 | auto: 'auto', 288 | ...theme('spacing'), 289 | '1/2': '50%', 290 | '1/3': '33.33333%', 291 | '2/3': '66.66667%', 292 | '1/4': '25%', 293 | '2/4': '50%', 294 | '3/4': '75%', 295 | '1/5': '20%', 296 | '2/5': '40%', 297 | '3/5': '60%', 298 | '4/5': '80%', 299 | '1/6': '16.66667%', 300 | '2/6': '33.33333%', 301 | '3/6': '50%', 302 | '4/6': '66.66667%', 303 | '5/6': '83.33333%', 304 | '1/12': '8.33333%', 305 | '2/12': '16.66667%', 306 | '3/12': '25%', 307 | '4/12': '33.33333%', 308 | '5/12': '41.66667%', 309 | '6/12': '50%', 310 | '7/12': '58.33333%', 311 | '8/12': '66.66667%', 312 | '9/12': '75%', 313 | '10/12': '83.33333%', 314 | '11/12': '91.66667%', 315 | full: '100%', 316 | screen: '100vw', 317 | }), 318 | zIndex: { 319 | auto: 'auto', 320 | '0': '0', 321 | '10': '10', 322 | '20': '20', 323 | '30': '30', 324 | '40': '40', 325 | '50': '50', 326 | }, 327 | }, 328 | variants: { 329 | alignContent: ['responsive'], 330 | alignItems: ['responsive'], 331 | alignSelf: ['responsive'], 332 | appearance: ['responsive'], 333 | backgroundAttachment: ['responsive'], 334 | backgroundColor: ['responsive', 'hover', 'focus'], 335 | backgroundPosition: ['responsive'], 336 | backgroundRepeat: ['responsive'], 337 | backgroundSize: ['responsive'], 338 | borderCollapse: ['responsive'], 339 | borderColor: ['responsive', 'hover', 'focus'], 340 | borderRadius: ['responsive'], 341 | borderStyle: ['responsive'], 342 | borderWidth: ['responsive'], 343 | boxShadow: ['responsive', 'hover', 'focus'], 344 | cursor: ['responsive'], 345 | display: ['responsive'], 346 | fill: ['responsive'], 347 | flex: ['responsive'], 348 | flexDirection: ['responsive'], 349 | flexGrow: ['responsive'], 350 | flexShrink: ['responsive'], 351 | flexWrap: ['responsive'], 352 | float: ['responsive'], 353 | fontFamily: ['responsive'], 354 | fontSize: ['responsive'], 355 | fontSmoothing: ['responsive'], 356 | fontStyle: ['responsive'], 357 | fontWeight: ['responsive', 'hover', 'focus'], 358 | height: ['responsive'], 359 | inset: ['responsive'], 360 | justifyContent: ['responsive'], 361 | letterSpacing: ['responsive'], 362 | lineHeight: ['responsive'], 363 | listStylePosition: ['responsive'], 364 | listStyleType: ['responsive'], 365 | margin: ['responsive'], 366 | maxHeight: ['responsive'], 367 | maxWidth: ['responsive'], 368 | minHeight: ['responsive'], 369 | minWidth: ['responsive'], 370 | objectFit: ['responsive'], 371 | objectPosition: ['responsive'], 372 | opacity: ['responsive'], 373 | order: ['responsive'], 374 | outline: ['responsive', 'focus'], 375 | overflow: ['responsive'], 376 | padding: ['responsive'], 377 | pointerEvents: ['responsive'], 378 | position: ['responsive'], 379 | resize: ['responsive'], 380 | stroke: ['responsive'], 381 | tableLayout: ['responsive'], 382 | textAlign: ['responsive'], 383 | textColor: ['responsive', 'hover', 'focus'], 384 | textDecoration: ['responsive', 'hover', 'focus'], 385 | textTransform: ['responsive'], 386 | userSelect: ['responsive'], 387 | verticalAlign: ['responsive'], 388 | visibility: ['responsive'], 389 | whitespace: ['responsive'], 390 | width: ['responsive'], 391 | wordBreak: ['responsive'], 392 | zIndex: ['responsive'], 393 | }, 394 | corePlugins: {}, 395 | plugins: [], 396 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | const ImageminPlugin = require('imagemin-webpack-plugin').default; 5 | const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); 6 | const PurgeCSS = require('@fullhuman/postcss-purgecss'); 7 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 8 | const isProduction = 'production' === process.env.NODE_ENV; 9 | 10 | // Set the build prefix. 11 | let prefix = isProduction ? '.min' : ''; 12 | 13 | // Set the PostCSS Plugins. 14 | const post_css_plugins = [ 15 | require('postcss-import'), 16 | require('tailwindcss')('./tailwind.js'), 17 | require('postcss-nested'), 18 | require('postcss-custom-properties'), 19 | require('autoprefixer') 20 | ] 21 | 22 | // Add PurgeCSS for production builds. 23 | if ( isProduction ) { 24 | post_css_plugins.push(require('cssnano')); 25 | post_css_plugins.push( 26 | PurgeCSS({ 27 | content: [ 28 | './*.php', 29 | './src/**/*.php', 30 | './page-templates/*.php', 31 | './assets/images/**/*.svg', 32 | './assets/scss/whitelist/*.css', 33 | './../../mu-plugins/app/src/components/**/*.php', 34 | ], 35 | css: [ 36 | './node_modules/tailwindcss/dist/base.css' 37 | ], 38 | // Use Extractor configuration from Tailwind Docs 39 | // https://tailwindcss.com/docs/controlling-file-size#setting-up-purge-css-manually 40 | defaultExtractor: content => { 41 | // Capture as liberally as possible, including things like `h-(screen-1.5)` 42 | const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [] 43 | 44 | // Capture classes within other delimiters like .block(class="w-1/2") in Pug 45 | const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [] 46 | 47 | return broadMatches.concat(innerMatches) 48 | }, 49 | whitelistPatterns: getCSSWhitelistPatterns() 50 | }) 51 | ) 52 | } 53 | 54 | const config = { 55 | entry: './assets/js/main.js', 56 | optimization: { 57 | minimizer: [ 58 | new UglifyJsPlugin({ 59 | cache: true, 60 | parallel: true, 61 | sourceMap: true 62 | }) 63 | ] 64 | }, 65 | output: { 66 | filename: `[name]${prefix}.js`, 67 | path: path.resolve(__dirname, 'dist') 68 | }, 69 | mode: process.env.NODE_ENV, 70 | module: { 71 | rules: [ 72 | { 73 | test: /\.js$/, 74 | loader: 'babel-loader', 75 | options: { 76 | presets: [ 77 | [ 78 | "@babel/preset-env" 79 | ] 80 | ] 81 | } 82 | }, 83 | { 84 | test: /\.css$/, 85 | use: [ 86 | MiniCssExtractPlugin.loader, 87 | { 88 | loader: 'css-loader', 89 | options: { 90 | importLoaders: 1, 91 | sourceMap: ! isProduction 92 | } 93 | }, 94 | { 95 | loader: 'postcss-loader', 96 | options: { 97 | ident: 'postcss', 98 | sourceMap: isProduction || 'inline', 99 | plugins: post_css_plugins, 100 | }, 101 | } 102 | ], 103 | } 104 | ] 105 | }, 106 | resolve: { 107 | alias: { 108 | '@' : path.resolve('assets'), 109 | '@images': path.resolve('../images') 110 | } 111 | }, 112 | plugins: [ 113 | new MiniCssExtractPlugin({ 114 | filename: `[name]${prefix}.css`, 115 | }), 116 | new CopyWebpackPlugin({ 117 | patterns: [{ 118 | from: './assets/images/', 119 | to: 'images', 120 | globOptions: { 121 | ignore: [ 122 | '**/.DS_Store' 123 | ] 124 | } 125 | }] 126 | }), 127 | new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i }) 128 | ] 129 | } 130 | 131 | // Fire up a local server if requested 132 | if (process.env.SERVER) { 133 | config.plugins.push( 134 | new BrowserSyncPlugin( 135 | { 136 | proxy: 'https://example.dev', 137 | files: [ 138 | '**/*.php', 139 | '**/*.scss' 140 | ], 141 | port: 3000, 142 | notify: false, 143 | } 144 | ) 145 | ) 146 | } 147 | 148 | /** 149 | * List of RegExp patterns for PurgeCSS 150 | * @returns {RegExp[]} 151 | */ 152 | function getCSSWhitelistPatterns() { 153 | return [ 154 | /^home(-.*)?$/, 155 | /^blog(-.*)?$/, 156 | /^archive(-.*)?$/, 157 | /^date(-.*)?$/, 158 | /^error404(-.*)?$/, 159 | /^admin-bar(-.*)?$/, 160 | /^search(-.*)?$/, 161 | /^nav(-.*)?$/, 162 | /^wp(-.*)?$/, 163 | /^screen(-.*)?$/, 164 | /^navigation(-.*)?$/, 165 | /^(.*)-template(-.*)?$/, 166 | /^(.*)?-?single(-.*)?$/, 167 | /^postid-(.*)?$/, 168 | /^post-(.*)?$/, 169 | /^attachmentid-(.*)?$/, 170 | /^attachment(-.*)?$/, 171 | /^page(-.*)?$/, 172 | /^(post-type-)?archive(-.*)?$/, 173 | /^author(-.*)?$/, 174 | /^category(-.*)?$/, 175 | /^tag(-.*)?$/, 176 | /^menu(-.*)?$/, 177 | /^tags(-.*)?$/, 178 | /^tax-(.*)?$/, 179 | /^term-(.*)?$/, 180 | /^date-(.*)?$/, 181 | /^(.*)?-?paged(-.*)?$/, 182 | /^depth(-.*)?$/, 183 | /^children(-.*)?$/, 184 | ]; 185 | } 186 | 187 | module.exports = config 188 | --------------------------------------------------------------------------------