diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..24eb271 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f85b914 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vector-drawable-nextjs.iml b/.idea/vector-drawable-nextjs.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/vector-drawable-nextjs.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0fef3c8..06ad7b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -233,6 +233,23 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.14.0.tgz", "integrity": "sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==" }, + "@tanem/svg-injector": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-8.2.1.tgz", + "integrity": "sha512-F8KbsSQnxLHRqoenP2MmB3IWKYANGqDtpyBIQZ6/tnkW7JYgZFG8PxM+QVrfiNbe62C+1b+HfGzb4xJjdu3NYQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "content-type": "^1.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", @@ -1172,6 +1189,11 @@ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -1778,6 +1800,11 @@ "safe-buffer": "^5.1.1" } }, + "exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -3769,6 +3796,20 @@ "scheduler": "^0.20.1" } }, + "react-from-dom": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/react-from-dom/-/react-from-dom-0.5.1.tgz", + "integrity": "sha512-ki6OGVgSjDCF0Gt4SMl2cUNBA9ZB8g59bwv9ZiSEXQ37Cw9ZGY0s7EgfPFQYDvaiVx22jto7/dYgQeS+Qw1Mfw==" + }, + "react-inlinesvg": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-2.2.2.tgz", + "integrity": "sha512-5uXTB0yL9LiRLbN5FhTnL1IK9mLg93kspY2HnKUftzoJDEqZrlscuZxzXStbMBZpNyO359U7QDspM3AqUYUrog==", + "requires": { + "exenv": "^1.2.2", + "react-from-dom": "^0.5.1" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -3779,6 +3820,16 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-svg": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/react-svg/-/react-svg-11.2.1.tgz", + "integrity": "sha512-melHPgs52FQ0h9A6Q8I6jtBj12wQLF8ZhHrTd3pUbyTOXkkxn7DmGiNyyc0zh66pKuXaXrYMgOXl/N3ToOYs7A==", + "requires": { + "@babel/runtime": "^7.12.5", + "@tanem/svg-injector": "^8.2.0", + "prop-types": "^15.7.2" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -4986,6 +5037,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "vector-drawable-svg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vector-drawable-svg/-/vector-drawable-svg-1.0.2.tgz", + "integrity": "sha512-HSyzExG9JPRPwcC3pHQI9Hq/RokYAKMxevGDrxynmF01vFsMqIcZ2HrbJhvofx3f5527PDjMkYvElze7X3polg==", + "requires": { + "xml-formatter": "^2.4.0", + "xmldom": "^0.4.0" + } + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -5335,6 +5395,24 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "xml-formatter": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.4.0.tgz", + "integrity": "sha512-xTQ2IfbkCQKn0DGN5SD5KUgTgVohWiolyOXTLUHKJczIuSeGonN0BPduB9VQR5HOEuT1KOHQsOHSmTpU76zpUA==", + "requires": { + "xml-parser-xo": "^3.1.1" + } + }, + "xml-parser-xo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.1.1.tgz", + "integrity": "sha512-gq1nDlJxjKQpPPZUhLbJ52pghtlB4Rz6LAQULm3SF6xzOYVnUloBglNhJR9vtZB3vIxMN/R3nZTf3qmun+6GCg==" + }, + "xmldom": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.4.0.tgz", + "integrity": "sha512-2E93k08T30Ugs+34HBSTQLVtpi6mCddaY8uO+pMNk1pqSjV5vElzn4mmh6KLxN3hki8rNcHSYzILoh3TEWORvA==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 3a945fd..d58c1fc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "dependencies": { "next": "10.0.5", "react": "17.0.1", - "react-dom": "17.0.1" + "react-dom": "17.0.1", + "react-inlinesvg": "^2.2.2", + "react-svg": "^11.2.1", + "vector-drawable-svg": "^1.0.2" } } diff --git a/pages/_document.js b/pages/_document.js new file mode 100644 index 0000000..d52767e --- /dev/null +++ b/pages/_document.js @@ -0,0 +1,37 @@ +import Document, {Html, Head, Main, NextScript} from 'next/document' + +export default class MyDocument extends Document { + render() { + return ( + + + + + + + + + + VectorDrawable to SVG + + + + + + + + + + + + +
+
+
+ + + + ) + } +} diff --git a/pages/api/hello.js b/pages/api/hello.js deleted file mode 100644 index 5b77ec0..0000000 --- a/pages/api/hello.js +++ /dev/null @@ -1,6 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction - -export default (req, res) => { - res.statusCode = 200 - res.json({ name: 'John Doe' }) -} diff --git a/pages/index.js b/pages/index.js index 43956d9..6957bd9 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,65 +1,169 @@ -import Head from 'next/head' -import styles from '../styles/Home.module.css' +import {ReactSVG} from "react-svg"; +import {useState} from "react"; +import {transform} from 'vector-drawable-svg'; +import SVG from 'react-inlinesvg'; + + +const STATE_NONE = -1 +const STATE_DRAG_LEAVE = 0 +const STATE_DRAGGING = 1 +const STATE_DROP = 2 + + +function downloadBlob(filename, text) { + const element = document.createElement('a'); + element.setAttribute('href', 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(text)); + element.setAttribute('download', filename); + element.style.display = 'none'; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); +} + +function isValidFileType(type) { + if (type === 'text/xml') return true; + return type === 'application/xml'; +} + +function transformXmlOrNull(value, options) { + if (!value) { + return null; + } + try { + return transform(value, options) + } catch (e) { + console.warn(e) + } +} + +function dropzoneClassOfState(state) { + if (state === STATE_DRAG_LEAVE) return ''; + if (state === STATE_DRAGGING) return 'vd-highlight'; + if (state === STATE_DROP) return 'vd-active'; +} + +async function readFileContent(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result) + reader.readAsText(file); + }); +} export default function Home() { - return ( -
- - Create Next App - - -
-

- Welcome to Next.js! -

+ const [dragState, setDragState] = useState(STATE_NONE) + const [isEnabled, setEnabled] = useState(false); + const [vectorDrawableFile, setVectorDrawableFile] = useState() + const [transformedSvg, setTransformedSvg] = useState() -

- Get started by editing{' '} - pages/index.js -

+ function handleFileUpload() { + setEnabled(!isEnabled) + } -
- -

Documentation →

-

Find in-depth information about Next.js features and API.

-
+ function dragEnter(e) { + e.stopPropagation(); + e.preventDefault(); + setDragState(STATE_DRAGGING) + } - -

Learn →

-

Learn about Next.js in an interactive course with quizzes!

-
+ function dragLeave(e) { + e.stopPropagation(); + e.preventDefault(); + setDragState(STATE_DRAG_LEAVE) + } - -

Examples →

-

Discover and deploy boilerplate example Next.js projects.

-
+ async function fileDrop(e) { + e.preventDefault(); + e.stopPropagation(); + const files = e.dataTransfer.files; - -

Deploy →

-

- Instantly deploy your Next.js site to a public URL with Vercel. -

-
+ if (files.length > 0) { + const file = files[0] + if (isValidFileType(file.type)) { + const xmlContent = await readFileContent(file); + const svgContent = transformXmlOrNull(xmlContent); + if (!svgContent) { + return; + } + + setTransformedSvg(svgContent); + setVectorDrawableFile(file); + setDragState(STATE_DROP); + return; + } + } + + setDragState(STATE_NONE); + } + + function dragOver(e) { + e.preventDefault(); + e.stopPropagation(); + e.dataTransfer.dropEffect = 'copy'; + } + + function clearUpload() { + setDragState(STATE_NONE) + setVectorDrawableFile(null); + setTransformedSvg(null); + } + + function downloadCurrentSvg() { + if (!transformedSvg) { + return; + } + + let filename = 'output.svg'; + if (vectorDrawableFile) { + filename = vectorDrawableFile.name.split('.').slice(0, -1).join('.') + "svg"; + } + + downloadBlob(filename, transformedSvg); + } + + return ( +
+
+

VectorDrawable to SVG

+

Drop your valid a vector drawable file here.

+
+
+ +
+
+
+ +
+
+ +
+ +
+

{vectorDrawableFile?.name}

+
+
+
+ + + + +
-
- - -
- ) + ) } diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..8515625 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..4628905 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..f27db47 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..b3930d0 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/public/close.svg b/public/close.svg new file mode 100644 index 0000000..e496433 --- /dev/null +++ b/public/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/download-circular-button.svg b/public/download-circular-button.svg new file mode 100644 index 0000000..1cdc900 --- /dev/null +++ b/public/download-circular-button.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..d4b57fc Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..64be7ff Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 4965832..a4f8ab2 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/github.svg b/public/github.svg new file mode 100644 index 0000000..4280c00 --- /dev/null +++ b/public/github.svg @@ -0,0 +1 @@ + diff --git a/public/mstile-144x144.png b/public/mstile-144x144.png new file mode 100644 index 0000000..e4a2079 Binary files /dev/null and b/public/mstile-144x144.png differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png new file mode 100644 index 0000000..90296c7 Binary files /dev/null and b/public/mstile-150x150.png differ diff --git a/public/mstile-310x150.png b/public/mstile-310x150.png new file mode 100644 index 0000000..5a7d562 Binary files /dev/null and b/public/mstile-310x150.png differ diff --git a/public/mstile-310x310.png b/public/mstile-310x310.png new file mode 100644 index 0000000..8920354 Binary files /dev/null and b/public/mstile-310x310.png differ diff --git a/public/mstile-70x70.png b/public/mstile-70x70.png new file mode 100644 index 0000000..1911ce5 Binary files /dev/null and b/public/mstile-70x70.png differ diff --git a/public/plus.svg b/public/plus.svg new file mode 100644 index 0000000..be7bb64 --- /dev/null +++ b/public/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..b20abb7 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/public/thumbnail-cover.png b/public/thumbnail-cover.png new file mode 100644 index 0000000..f9f31bb Binary files /dev/null and b/public/thumbnail-cover.png differ diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index fbf0e25..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/styles/Home.module.css b/styles/Home.module.css index 42e7e60..e69de29 100644 --- a/styles/Home.module.css +++ b/styles/Home.module.css @@ -1,122 +0,0 @@ -.container { - min-height: 100vh; - padding: 0 0.5rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.main { - padding: 5rem 0; - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.footer { - width: 100%; - height: 100px; - border-top: 1px solid #eaeaea; - display: flex; - justify-content: center; - align-items: center; -} - -.footer img { - margin-left: 0.5rem; -} - -.footer a { - display: flex; - justify-content: center; - align-items: center; -} - -.title a { - color: #0070f3; - text-decoration: none; -} - -.title a:hover, -.title a:focus, -.title a:active { - text-decoration: underline; -} - -.title { - margin: 0; - line-height: 1.15; - font-size: 4rem; -} - -.title, -.description { - text-align: center; -} - -.description { - line-height: 1.5; - font-size: 1.5rem; -} - -.code { - background: #fafafa; - border-radius: 5px; - padding: 0.75rem; - font-size: 1.1rem; - font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, - Bitstream Vera Sans Mono, Courier New, monospace; -} - -.grid { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - max-width: 800px; - margin-top: 3rem; -} - -.card { - margin: 1rem; - flex-basis: 45%; - padding: 1.5rem; - text-align: left; - color: inherit; - text-decoration: none; - border: 1px solid #eaeaea; - border-radius: 10px; - transition: color 0.15s ease, border-color 0.15s ease; -} - -.card:hover, -.card:focus, -.card:active { - color: #0070f3; - border-color: #0070f3; -} - -.card h3 { - margin: 0 0 1rem 0; - font-size: 1.5rem; -} - -.card p { - margin: 0; - font-size: 1.25rem; - line-height: 1.5; -} - -.logo { - height: 1em; -} - -@media (max-width: 600px) { - .grid { - width: 100%; - flex-direction: column; - } -} diff --git a/styles/globals.css b/styles/globals.css index e5e2dcc..dd3c762 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,16 +1,235 @@ +:root { + --vd-color-surface: #1F1F1F; + --vd-color-on-surface: rgba(255, 255, 255, 0.03); + --vd-color-stroke: rgba(255, 255, 255, .23); + --vd-color-text: rgba(255, 255, 255, 0.69); + --vd-color-primary: #269BFF; + --vd-color-light-primary: #37a3ff; + --vd-color-dark-primary: #1a7fd6; + --vd-color-secondary-text: rgba(255, 255, 255, 0.33); + --vd-size-corner-radius: 24px; +} + html, body { - padding: 0; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + padding: 0; + margin: 0; + font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + background-color: var(--vd-color-surface); + color: var(--vd-color-text); } a { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; +} + +p { + margin: 0; } * { - box-sizing: border-box; + box-sizing: border-box; +} + +.container { + max-width: 720px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: center; +} + +.vd-form-center { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; +} + + +.vd-title { + padding: 0; + margin: 0; + font-size: 3em; + text-align: center; +} + +.vd-subtitle { + padding: 0; + margin: 10px 0; + color: var(--vd-color-secondary-text); + text-align: center; + font-size: 1.2em; +} + +.vd-head { + margin-top: 60px; +} + +.vd-dropzone { + cursor: pointer; + margin-top: 24px; + min-width: 400px; + min-height: 400px; + background-color: var(--vd-color-on-surface); + border-radius: var(--vd-size-corner-radius); + border: 2px dashed var(--vd-color-stroke); + position: relative; + display: flex; + overflow: hidden; +} + +.vd-dropzone.vd-highlight { + border: 2px dashed var(--vd-color-primary); +} + +.vd-dropzone.vd-active { + border: 2px dashed var(--vd-color-primary); +} + +.vd-dropzone.vd-active .vd-image-container { + display: flex; +} + +.vd-dropzone.vd-active .vd-placeholder { + display: none; +} + +.vd-dropzone .vd-image-container { + flex-grow: 1; + display: none; + flex-direction: column; + position: relative; +} + +.text-button-icon { + position: absolute; + top: 0; + right: 0; + margin-right: 14px; + margin-top: 12px; + padding: 10px; + width: 38px; + height: 38px; + border-radius: 50%; + transition: 0.2s ease-in-out; +} + +.text-button-icon:hover { + background: rgba(255, 255, 255, 0.05); +} +.text-button-icon:active { + background: rgba(255, 255, 255, 0.1); +} + + +.vd-dropzone .vd-image-container .vd-filename { + background: rgba(0, 0, 0, .1); + text-align: center; + padding: 8px 14px; +} + +.vd-dropzone .vd-image-container .vd-filename p { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 400px; +} + +.vd-dropzone .vd-image-container .vd-image { + flex-grow: 1; + display: flex; + text-align: center; + align-items: center; + justify-content: center; +} + + +.vd-dropzone .vd-image-container .vd-image img { + max-width: 300px; + max-height: 300px; +} + + +.vd-placeholder { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; +} + +.vd-download { + margin-top: 28px; +} + +button { + font-family: inherit; + color: inherit; + background: var(--vd-color-primary); + font-size: 1.2em; + border: none; + min-width: 400px; + border-radius: calc(var(--vd-size-corner-radius) / 1.5); + padding: 14px 0; + outline: none; + transition: .23s ease; + display: flex; + align-items: center; + justify-content: center; + + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome, Edge, Opera and Firefox */ +} + +button:not(:disabled) { + cursor: pointer; +} + + + +button svg { + width: 1.2em; + height: 1.2em; + fill: var(--vd-color-text); + margin-right: 8px; + margin-top: 4px; +} + +button:disabled svg { + fill: rgba(255, 255,255, 0.17); +} + +button:disabled { + background: #1C1C1C; + color: rgba(255, 255,255, 0.17); +} + +button:not(:disabled):hover { + background: var(--vd-color-light-primary); +} + +button:not(:disabled):active { + background: var(--vd-color-dark-primary); +} + +.vd-placeholder svg { + max-width: 48px; + max-height: 48px; + fill: var(--vd-color-secondary-text); +} + +.vd-footer { + margin-top: 20px; +} + +.vd-github svg { + width: 2em; + height: 2em; }