├── .gitignore ├── .husky └── pre-commit ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── prettier.config.js ├── public ├── .well-known │ └── brave-rewards-verification.txt ├── favicon.ico └── favicon.svg ├── src ├── App.vue ├── assets │ ├── logo.png │ └── prism.css ├── components │ ├── AppFooter.vue │ ├── BaseInput.vue │ ├── CodeContainer.vue │ ├── RangeInput.vue │ ├── ShadowForm.vue │ ├── ShadowModal.vue │ └── icons │ │ ├── Chevron.vue │ │ ├── Clipboard.vue │ │ ├── GitHub.vue │ │ └── TwoBeards.vue ├── getShadowStyles.js ├── index.css ├── main.js └── uuid.js ├── tailwind.config.js └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | 24 | .vercel -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # box-shadows 2 | 3 | Box shadows are fun. This is a web app to help you create awesome box shadows. Head over to https://box-shadow.dev to give it a whirl. 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Box Shadows 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "box-shadows", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview", 8 | "prepare": "husky install", 9 | "format": "prettier --write --ignore-unknown ." 10 | }, 11 | "dependencies": { 12 | "@headlessui/vue": "^1.2.0", 13 | "klona": "^2.0.0", 14 | "vue": "^3.0.5" 15 | }, 16 | "devDependencies": { 17 | "@tailwindcss/forms": "^0.5.0", 18 | "@vitejs/plugin-vue": "^3.0.0", 19 | "@vue/compiler-sfc": "^3.0.5", 20 | "autoprefixer": "^10.4.4", 21 | "husky": "^8.0.0", 22 | "lint-staged": "^13.0.3", 23 | "postcss": "^8.4.12", 24 | "prettier": "2.7.1", 25 | "prismjs": "^1.23.0", 26 | "tailwindcss": "^3.0.24", 27 | "vite": "^3.1.4" 28 | }, 29 | "lint-staged": { 30 | "**/*": "prettier --write --ignore-unknown", 31 | "*.{js,css,md}": "prettier --write" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'es5', 3 | tabWidth: 4, 4 | semi: false, 5 | singleQuote: true, 6 | } 7 | -------------------------------------------------------------------------------- /public/.well-known/brave-rewards-verification.txt: -------------------------------------------------------------------------------- 1 | This is a Brave Rewards publisher verification file. 2 | 3 | Domain: box-shadow.dev 4 | Token: 7cc919ba6aaee9e3079fdffef236a77cd48006d51354a197dcb1c8038b6a3af2 5 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/two-beards/box-shadows/469f29cca85a1a02d376789981d2f0aaaa5e0933/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 179 | 180 | 209 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/two-beards/box-shadows/469f29cca85a1a02d376789981d2f0aaaa5e0933/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/prism.css: -------------------------------------------------------------------------------- 1 | /** 2 | * prism.js theme 3 | */ 4 | 5 | :root { 6 | --inline-code-bg: #f5f3ff; 7 | --inline-code-color: #6d28d9; 8 | --code-border: #cbd5e1; 9 | --code-fg: #6e7f91; 10 | --code-comment: #a8b3bd; 11 | --code-blue: #2563eb; 12 | --code-cyan: #06b6d4; 13 | --code-purple: #7c3aed; 14 | --code-green: #10b981; 15 | --code-red: #ef4444; 16 | --code-yellow: #f59e0b; 17 | --tab-size: 4; 18 | } 19 | 20 | /* purgecss start ignore */ 21 | 22 | code[class*='language-'], 23 | pre.prismjs { 24 | color: var(--code-fg); 25 | background: none; 26 | border-radius: 0; 27 | padding: 0; 28 | font-size: 1rem; 29 | text-align: left; 30 | white-space: pre; 31 | word-spacing: normal; 32 | word-break: normal; 33 | word-wrap: normal; 34 | line-height: 1.5; 35 | 36 | -moz-tab-size: var(--tab-size); 37 | -o-tab-size: var(--tab-size); 38 | tab-size: var(--tab-size); 39 | 40 | -webkit-hyphens: none; 41 | -moz-hyphens: none; 42 | -ms-hyphens: none; 43 | hyphens: none; 44 | } 45 | 46 | /* Code blocks */ 47 | pre.prismjs { 48 | background: transparent; 49 | border-top: 1px solid var(--code-border); 50 | border-bottom: 1px solid var(--code-border); 51 | margin: 1rem -1rem 2rem; 52 | overflow: auto; 53 | padding: 1rem; 54 | width: 100vw; 55 | } 56 | 57 | @media all and (min-width: 640px) { 58 | pre.prismjs { 59 | border-radius: 0.25rem; 60 | border: 1px solid var(--code-border); 61 | margin-left: 0; 62 | margin-right: 0; 63 | width: auto; 64 | } 65 | } 66 | 67 | .token.comment, 68 | .token.block-comment, 69 | .token.prolog, 70 | .token.doctype, 71 | .token.cdata { 72 | color: var(--code-comment); 73 | } 74 | 75 | .token.punctuation { 76 | color: var(--code-fg); 77 | } 78 | 79 | .token.tag, 80 | .token.namespace, 81 | .token.boolean, 82 | .token.deleted, 83 | .token.number, 84 | .token.interpolation-punctuation { 85 | color: var(--code-red); 86 | } 87 | 88 | .token.function-name, 89 | .token.function, 90 | .token.attr-name, 91 | .token.property, 92 | .language-html .token.attr-value, 93 | .token.url { 94 | color: var(--code-blue); 95 | } 96 | 97 | .language-html .token.property, 98 | .language-html .token.attr-name, 99 | .language-html .token.namespace, 100 | .token.class-name, 101 | .token.constant, 102 | .token.variable, 103 | .token.symbol { 104 | color: var(--code-yellow); 105 | } 106 | 107 | .token.selector, 108 | .token.important, 109 | .token.atrule, 110 | .token.keyword, 111 | .token.builtin { 112 | color: var(--code-purple); 113 | } 114 | 115 | .token.operator, 116 | .token.entity { 117 | color: var(--code-cyan); 118 | } 119 | 120 | .token.string, 121 | .token.char, 122 | .token.attr-value, 123 | .token.regex, 124 | .token.inserted { 125 | color: var(--code-green); 126 | } 127 | 128 | .token.important, 129 | .token.bold { 130 | font-weight: bold; 131 | } 132 | 133 | .token.italic { 134 | font-style: italic; 135 | } 136 | 137 | .token.entity { 138 | cursor: help; 139 | } 140 | 141 | /* purgecss end ignore */ 142 | -------------------------------------------------------------------------------- /src/components/AppFooter.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | -------------------------------------------------------------------------------- /src/components/BaseInput.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 37 | 38 | 50 | -------------------------------------------------------------------------------- /src/components/CodeContainer.vue: -------------------------------------------------------------------------------- 1 | 22 | 82 | -------------------------------------------------------------------------------- /src/components/RangeInput.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 65 | 66 | 173 | -------------------------------------------------------------------------------- /src/components/ShadowForm.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | 131 | -------------------------------------------------------------------------------- /src/components/ShadowModal.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 77 | -------------------------------------------------------------------------------- /src/components/icons/Chevron.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /src/components/icons/Clipboard.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/components/icons/GitHub.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /src/components/icons/TwoBeards.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 55 | 56 | 66 | -------------------------------------------------------------------------------- /src/getShadowStyles.js: -------------------------------------------------------------------------------- 1 | export default function (shadows) { 2 | const styles = shadows 3 | .filter((s) => s.active) 4 | .map((s) => { 5 | let prefix = s.inset ? 'inset ' : '' 6 | return `${prefix}${s.offsetX}px ${s.offsetY}px ${s.blur}px ${s.spread}px ${s.color}` 7 | }) 8 | .join(',') 9 | .trim() 10 | 11 | return `box-shadow: ${styles};` 12 | } 13 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import './index.css' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /src/uuid.js: -------------------------------------------------------------------------------- 1 | // @lukeed/uuid 2 | // for some reason, rollup was complaining about trying to import "crypto" from Node, 3 | // even though it's also in browsers. 4 | 5 | let SIZE = 4096, 6 | HEX = [], 7 | IDX = 0, 8 | BUFFER 9 | 10 | for (; IDX < 256; IDX++) { 11 | HEX[IDX] = (IDX + 256).toString(16).substring(1) 12 | } 13 | 14 | export default function () { 15 | if (!BUFFER || IDX + 16 > SIZE) { 16 | BUFFER = crypto.getRandomValues(new Uint8Array(SIZE)) 17 | IDX = 0 18 | } 19 | 20 | var i = 0, 21 | tmp, 22 | out = '' 23 | for (; i < 16; i++) { 24 | tmp = BUFFER[i + IDX] 25 | if (i == 6) out += HEX[(tmp & 15) | 64] 26 | else if (i == 8) out += HEX[(tmp & 63) | 128] 27 | else out += HEX[tmp] 28 | 29 | if (i & 1 && i > 1 && i < 11) out += '-' 30 | } 31 | 32 | IDX++ 33 | return out 34 | } 35 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], 3 | darkMode: false, 4 | theme: { 5 | extend: {}, 6 | }, 7 | variants: { 8 | extend: {}, 9 | }, 10 | plugins: [require('@tailwindcss/forms')], 11 | } 12 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | }) 8 | --------------------------------------------------------------------------------