├── .npmignore ├── .gitignore ├── demo.gif ├── readme.md ├── prettier.config.js ├── package.json └── source └── index.js /.npmignore: -------------------------------------------------------------------------------- 1 | /demo.gif 2 | /.git 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /node_modules 3 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/assertchris/use-tailwind-preset/HEAD/demo.gif -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Use Tailwind Preset 2 | 3 | ![Using the helper](./demo.gif) 4 | 5 | This helper installs [the tailwind preset](https://github.com/laravel-frontend-presets/tailwindcss), and then cleans up after itself. 6 | 7 | ``` 8 | npx use-tailwind-preset 9 | ``` 10 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "printWidth": 120, 3 | "tabWidth": 4, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": false, 7 | "quoteProps": "preserve", 8 | "jsxSingleQuote": false, 9 | "trailingComma": "all", 10 | "bracketSpacing": true, 11 | "jsxBracketSameLine": false, 12 | "arrowParens": "avoid", 13 | "proseWrap": "never", 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "use-tailwind-preset", 3 | "version": "2.0.1", 4 | "description": "Quickly use Tailwind in new Laravel projects", 5 | "main": "build/index.js", 6 | "bin": "build/index.js", 7 | "author": "Christopher Pitt ", 8 | "license": "MIT", 9 | "scripts": { 10 | "build": "babel source --out-dir=build", 11 | "prepare": "npm run build" 12 | }, 13 | "files": [ 14 | "build" 15 | ], 16 | "dependencies": { 17 | "ink": "^2.6.0", 18 | "ink-select-input": "^3.1.2", 19 | "react": "^16.12.0" 20 | }, 21 | "devDependencies": { 22 | "@babel/cli": "^7.7.5", 23 | "@babel/core": "^7.7.5", 24 | "@babel/plugin-proposal-class-properties": "^7.7.4", 25 | "@babel/preset-env": "^7.7.5", 26 | "@babel/preset-react": "^7.7.4", 27 | "@types/react": "^16.9.15" 28 | }, 29 | "babel": { 30 | "plugins": [ 31 | "@babel/plugin-proposal-class-properties" 32 | ], 33 | "presets": [ 34 | "@babel/preset-react", 35 | [ 36 | "@babel/preset-env", 37 | { 38 | "targets": { 39 | "esmodules": true 40 | } 41 | } 42 | ] 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /source/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { exec } from "child_process" 4 | import React, { Component } from "react" 5 | import { render, Box, Color } from "ink" 6 | import SelectInput from "ink-select-input" 7 | 8 | const run = async command => 9 | new Promise(function(resolve, reject) { 10 | exec(command, function(err, stdout, stderr) { 11 | if (err) { 12 | return reject(err) 13 | } 14 | 15 | resolve(stderr, stdout) 16 | }) 17 | }) 18 | 19 | const commands = { 20 | "npm": { 21 | "install": async () => run("npm install"), 22 | "build": async () => run("npm run dev"), 23 | }, 24 | "preset": { 25 | "install": async () => run("composer require laravel-frontend-presets/tailwindcss --dev -n"), 26 | "use": async (withAuth = false) => run(`php artisan preset ${withAuth ? "tailwindcss-auth" : "tailwindcss"}`), 27 | "remove": async () => run("composer remove laravel-frontend-presets/tailwindcss --dev -n"), 28 | }, 29 | } 30 | 31 | const messages = { 32 | "npm": { 33 | "install": "Installing the NPM dependencies...", 34 | "build": "Building the static assets...", 35 | }, 36 | "preset": { 37 | "install": "Installing the Tailwind preset...", 38 | "use": "Using the Tailwind preset...", 39 | "remove": "Removing the Tailwind preset...", 40 | }, 41 | "done": "All done! Get building.", 42 | "docs": "You can find the docs at https://tailwindcss.com", 43 | } 44 | 45 | class Wizard extends Component { 46 | state = { 47 | step: "auth-question", 48 | status: undefined, 49 | withAuth: false, 50 | } 51 | 52 | async componentDidUpdate() { 53 | const { step, withAuth } = this.state 54 | 55 | if (step == "preset.install") { 56 | await commands.preset.install() 57 | this.setState({ step: "preset.use", status: messages.preset.use }) 58 | } 59 | 60 | if (step == "preset.use") { 61 | await commands.preset.use(withAuth) 62 | this.setState({ step: "npm.install", status: messages.npm.install }) 63 | } 64 | 65 | if (step == "npm.install") { 66 | await commands.npm.install() 67 | this.setState({ step: "npm.build", status: messages.npm.build }) 68 | } 69 | 70 | if (step == "npm.build") { 71 | await commands.npm.build() 72 | this.setState({ step: "preset.remove", status: messages.preset.remove }) 73 | } 74 | 75 | if (step == "preset.remove") { 76 | await commands.preset.remove() 77 | this.setState({ step: "done", status: undefined }) 78 | } 79 | } 80 | 81 | handleAuthAnswer = item => { 82 | this.setState({ withAuth: item.value, step: "preset.install", status: messages.preset.install }) 83 | } 84 | 85 | render() { 86 | const { step, withAuth } = this.state 87 | 88 | if (step == "done") { 89 | return this.renderDone() 90 | } 91 | 92 | if (step == "auth-question") { 93 | return this.renderAuthQuestion() 94 | } 95 | 96 | return this.renderInstall() 97 | } 98 | 99 | renderDone = () => { 100 | return ( 101 | 102 | 103 | {messages.done} 104 | 105 | 106 | {messages.docs} 107 | 108 | 109 | ) 110 | } 111 | 112 | renderAuthQuestion = () => { 113 | const items = [ 114 | { 115 | label: "Yes", 116 | value: true, 117 | }, 118 | { 119 | label: "No", 120 | value: false, 121 | }, 122 | ] 123 | 124 | return ( 125 | 126 | 127 | Include auth files? 128 | 129 | 130 | 131 | 132 | 133 | ) 134 | } 135 | 136 | renderInstall() { 137 | const { withAuth, status } = this.state 138 | 139 | return ( 140 | 141 | 142 | Generate auth files:{" "} 143 | {withAuth ? yes : no} 144 | 145 | 146 | {status} 147 | 148 | 149 | ) 150 | } 151 | } 152 | 153 | render() 154 | --------------------------------------------------------------------------------