From e81b5d16061657e77eca30b2ad851f9412236294 Mon Sep 17 00:00:00 2001 From: Felix Mattick Date: Fri, 21 Jan 2022 13:07:13 -0600 Subject: [PATCH] Better documentation Add files via upload Delete docs.html Delete sheets.css Add files via upload Delete docs.html Delete scr.js Delete sheets.css Add files via upload Add description list styles Misc. style changes Add documentation Create swift-dots-run.md --- .changeset/famous-timers-sparkle.md | 5 + .changeset/nice-pens-hang.md | 5 + .changeset/weak-berries-sit.md | 5 + docs/docs.html | 109 ++++++++ docs/index.html | 258 ++++-------------- docs/script.js | 88 ------ docs/scripts/docs.js | 407 ++++++++++++++++++++++++++++ docs/scripts/index.js | 14 + docs/scripts/themer.js | 73 +++++ docs/style.css | 15 +- gulpfile.js | 6 +- package.json | 4 +- src/parts/_misc.css | 9 +- src/parts/_typography.css | 14 + swift-dots-run.md | 5 + 15 files changed, 706 insertions(+), 311 deletions(-) create mode 100644 .changeset/famous-timers-sparkle.md create mode 100644 .changeset/nice-pens-hang.md create mode 100644 .changeset/weak-berries-sit.md create mode 100644 docs/docs.html delete mode 100644 docs/script.js create mode 100644 docs/scripts/docs.js create mode 100644 docs/scripts/index.js create mode 100644 docs/scripts/themer.js create mode 100644 swift-dots-run.md diff --git a/.changeset/famous-timers-sparkle.md b/.changeset/famous-timers-sparkle.md new file mode 100644 index 0000000..b5b8d38 --- /dev/null +++ b/.changeset/famous-timers-sparkle.md @@ -0,0 +1,5 @@ +--- +"water.css": minor +--- + +Add description list styles diff --git a/.changeset/nice-pens-hang.md b/.changeset/nice-pens-hang.md new file mode 100644 index 0000000..def47ed --- /dev/null +++ b/.changeset/nice-pens-hang.md @@ -0,0 +1,5 @@ +--- +"water.css": patch +--- + +Fix lack of top margin in details children diff --git a/.changeset/weak-berries-sit.md b/.changeset/weak-berries-sit.md new file mode 100644 index 0000000..908caf3 --- /dev/null +++ b/.changeset/weak-berries-sit.md @@ -0,0 +1,5 @@ +--- +"water.css": minor +--- + +Add header styles, change footer margin to last-of-type only diff --git a/docs/docs.html b/docs/docs.html new file mode 100644 index 0000000..971d859 --- /dev/null +++ b/docs/docs.html @@ -0,0 +1,109 @@ + + + + + + Element Docs | Water.css + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ +
+

Element Docs

+

+ Get started with Water.css, a drop-in collection of classless CSS styles. +

+ +

Table of contents

+ +
+ +
+ + + + +
This is a sample dialog
+
+

What is your favorite pet animal?

+ + + + + +
+
+ + + + + diff --git a/docs/index.html b/docs/index.html index d9ec359..fbc50a6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -23,8 +23,6 @@ - - @@ -37,6 +35,7 @@ + -

Water.css

+
+
+

Water.css

-

- Water.css is a drop-in collection of CSS styles to make simple websites like this just a - little bit nicer. -

-

- Now you can write your simple static site with nice semantic html, and Water.css will manage - the styling for you. -

- - + +

+ Water.css is a drop-in collection of CSS styles to make simple websites like this just a little bit nicer. +

+

+ Now you can write your simple static site with nice semantic html, and Water.css will manage the styling for you. +

+
    +
  • It's responsive
  • +
  • It's easy to theme
  • +
  • It has great browser support
  • +
  • It has a tiny size
  • +
  • It doesn't require any classes
  • +
  • It looks beautiful
  • +
  • It encourages semantic code
  • +
+

+ Go to element documentation or check out the + GitHub. +

+

Installation

+
-

Goals

- -

Is it responsive?

- Heck yeah! It doesn't include any fancy styles so it's easily mobile - responsive. Just add the famous - responsive viewport tag and + Heck yeah! It doesn't include any fancy styles so it's mobile + responsive by default. Just add the famous + responsive viewport tag and you'll be good to go!

-

In fact, try resizing this page. Everything flows super nicely as you'll see.

+

In fact, try resizing this page. Everything will flow super nicely.

Bookmarklet

@@ -194,170 +191,7 @@ -

Element demos

-

This is supposed to be a demo page so we need more elements!

- -

Form elements

-
- - - - - - - - - - - - - -
- - -
-
- - -
-
- - -
- -
- - - - - - -
- -

Code

-

- Below is some code, you can copy it with Ctrl-C. Did you know, - alert(1) can show an alert in JavaScript! -

-
// This logs a message to the console and check out the scrollbar.
console.log('Hello, world!')
- -

Other

-

Here's a horizontal rule and image because I don't know where else to put them.

- Example kitten -
- -

And here's a nicely marked up table!

- - - - - - - - - - - - - - - - - - - - - - - - - -
NameQuantityPrice
Godzilla2$299.99
Mozilla10$100,000.00
Quesadilla1$2.22
- -
- Some summary/details can't hurt! -

Lorem ipsum dolor sit blah blah.

-
- -

The dialog (form, and menu) tag

- -
- - -
- - -
This is a sample dialog
-
-

What is your favorite pet animal?

- - - - - -
-
- -

Typography

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dictum hendrerit velit, quis - ullamcorper sem congue ac. Quisque id magna rhoncus, sodales massa vel, vestibulum elit. Duis - ornare accumsan egestas. Proin maximus lacus interdum leo molestie convallis. Orci varius - natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut iaculis risus eu - felis feugiat, eu mollis neque elementum. Donec interdum, nisl id dignissim iaculis, felis dui - aliquet dui, non fermentum velit lectus ac quam. Class aptent taciti sociosqu ad litora - torquent per conubia nostra, per inceptos himenaeos. - This is strong, this is normal, this is just bold, - and this is emphasized! And heck, here's a link. -

- -
- "The HTML blockquote Element (or HTML Block Quotation Element) indicates that the enclosed - text is an extended quotation. Usually, this is rendered visually by indentation (see - Notes - for how to change it). A URL for the source of the quotation may be given using the - cite attribute, while a text representation of the source can be given using the - <cite> cite element." - -
- MDN, "The Block Quotation element" -
-
- - -
    -
  1. Ordered list item 1
  2. -
  3. Ordered list item 2
  4. -
  5. Ordered list item 3
  6. -
- -

Addresses are also styled to be awesome!

-
- john.doe@example.com
- 778-330-2389
- 666-666-6666
-
- -
- -

Heading 1

-

Heading 2

-

Heading 3

-

Heading 4

-
Heading 5
-
Heading 6
- - - + + diff --git a/docs/script.js b/docs/script.js deleted file mode 100644 index fb821c0..0000000 --- a/docs/script.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict' - -const localBase = './water.css/' - -const fileSizes = { - dark: 2.57, - light: 2.55, - auto: 3.27 -} - -const themeForm = document.getElementById('theme-form') -const stylesheet = document.getElementById('js-stylesheet') -const startupStylesheet = document.getElementById('js-startup-stylesheet') -const productHunt = document.getElementById('product-hunt') -const copyButton = document.getElementById('copy-button') -const copyButtonFeedback = document.getElementById('copy-button-feedback') -const linkSnippets = [].slice.call(document.querySelectorAll('#link-snippet-container > pre')) - -const table = { - fileName: document.getElementById('table-file-name'), - fileSize: document.getElementById('table-file-size'), - theme: document.getElementById('table-theme') -} - -const prefersColorScheme = window.matchMedia('(prefers-color-scheme: light)') - -const updateProductHunt = (theme) => { - theme = theme || (prefersColorScheme.matches ? 'light' : 'dark') - productHunt.src = `https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=${theme}&period=daily` -} - -const updateTheme = () => { - const theme = themeForm.querySelector('input[name="theme"]:checked').value - - const fileName = `${theme === 'auto' ? 'water' : theme}.min.css` - const localUrl = `${localBase}${fileName}` - - stylesheet.href = localUrl - - for (const snippet of linkSnippets) { - snippet.hidden = snippet.id.indexOf(theme) === -1 - } - - table.fileName.innerText = fileName - table.fileSize.innerText = `${fileSizes[theme].toFixed(2)} kb` - - if (theme === 'auto') { - updateProductHunt() - table.theme.innerHTML = ` - Respects user-defined theme settings using prefers-color-scheme.
- Light in browsers where the theme settings can't be detected. - ` - } else { - updateProductHunt(theme) - table.theme.innerText = `Theme is forced to ${theme}.` - } -} - -themeForm.addEventListener('change', updateTheme) - -updateProductHunt() -prefersColorScheme.addListener(() => { - if (themeForm.theme.value !== 'auto') return - updateProductHunt() -}) - -updateTheme() -startupStylesheet.parentElement.removeChild(startupStylesheet) - -copyButton.addEventListener('click', () => { - const clipboard = navigator.clipboard || window.clipboard - const theme = themeForm.querySelector('input[name="theme"]:checked').value - const snippetText = document.querySelector(`#link-snippet-${theme} code`).textContent - - clipboard.writeText(snippetText) - .then(() => { copyButtonFeedback.textContent = '✔' }) - .catch(() => { copyButtonFeedback.textContent = '❌' }) - .then(() => setTimeout(() => { copyButtonFeedback.textContent = '' }, 1000)) -}) - -document.getElementById('dialog-trigger').addEventListener('click', () => { - document.getElementById('dialog-result').innerText = '' - document.getElementById('dialog').showModal() -}) - -document.getElementById('dialog').addEventListener('close', (event) => { - document.getElementById('dialog-result').innerText = `Your answer: ${event.target.returnValue}` -}) diff --git a/docs/scripts/docs.js b/docs/scripts/docs.js new file mode 100644 index 0000000..6662770 --- /dev/null +++ b/docs/scripts/docs.js @@ -0,0 +1,407 @@ +const categories = [ + { + id: 'typography', + name: 'Typography', + description: 'HTML, being a markup language, has abundantly clear semantics for basic typography. Water.css leaves those semantics untouched.', + snippets: [ + { + id: 'copy', + name: 'Headings and copy', + code: ` +

Heading 1

+

+ This is a paragraph that could contain long-form text. Heck, here's a link. + This is important, this is normal, and this is emphasized! +

+

This is another paragraph that could contain long-form text.

+ +

Heading 2

+

You probably get the idea by now!

+ +

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+ ` + }, + { + id: 'quotes', + name: 'Quotes', + code: ` +
+ "The HTML blockquote Element (or HTML Block Quotation Element) indicates that the enclosed text is an extended quotation. Usually, this is rendered visually by indentation (see Notes for how to change it). A URL for the source of the quotation may be given using the cite attribute, while a text representation of the source can be given using the <cite> cite element." +
+ MDN, "The Block Quotation element" +
+
+ +

+ Did you know HTML supports inline quotes? I didn't, until I read that + + the <q> HTML element indicates that the enclosed text is a short inline quotation + . +

+ ` + }, + { + id: 'lists', + name: 'Lists', + code: ` + +
    +
  1. Ordered list item 1
  2. +
  3. Ordered list item 2
  4. +
  5. Ordered list item 3
  6. +
+
+
Unordered lists
+
Represents an unordered list of items, typically rendered as a bulleted list
+
Ordered lists
+
Represents an ordered list of items, typically rendered as a numbered list
+
Description lists
+
Encloses a list of groups of terms and descriptions
+
Not commonly used, but still nifty
+
+ ` + }, + { + id: 'code-etc', + name: 'Code samples, keyboard shortcuts, oh my', + code: ` +

+ Below is some code. If you select it, you can copy using Ctrl-C. + Did you know that alert(1) can show an alert in JavaScript? +

+
// This logs a message to the console and check out the scrollbar.
+console.log('Hello, world!')
+ +

HTML also has elements for variables and sample output: Hello, world!

+ ` + } + ] + }, + { + id: 'forms', + name: 'Form controls', + description: 'Water.css provides a set of styles for form controls, including text inputs, select boxes, buttons, and more.', + snippets: [ + { + id: 'text-inputs', + name: 'Text inputs', + code: ` +
+ + + + + + + + + + + +
+ ` + }, + { + id: 'buttons', + name: 'Buttons', + code: ` + +
+
+ + + + +
+ ` + }, + { + id: 'assorted-inputs', + name: 'Assorted other controls', + code: ` +
+ + + + + + +
+ Choose a Doe +
+ + +
+
+ + +
+
+ + +
+
+ + + +
+ ` + }, + { + id: 'dialogs', + name: 'Dialogs', + caniuse: 'https://caniuse.com/dialog', + code: ` +
+ + +
+ + +
This is a sample dialog
+
+

What is your favorite pet animal?

+ + + + + +
+
+ + + `, + realCode: ` +
+ + +
+ ` + } + ] + }, + { + id: 'misc', + name: 'Miscellaneous', + description: 'Styles are also provided for various other elements that don\'t strictly fit into the other categories. These include tables, dialogs, and images.', + snippets: [ + { + id: 'tables', + name: 'Tables', + code: ` + + + + + + + + + + + + + + + + + + + + + + + + + +
NameQuantityPrice
Godzilla2$299.99
Mozilla10$100,000.00
Quesadilla1$2.22
+ ` + }, + { + id: 'details', + name: 'Summary/details', + caniuse: 'https://caniuse.com/details', + code: ` +
+ Some summary/details can't hurt! +

Lorem ipsum dolor sit blah blah.

+
+ ` + }, + { + id: 'rules-etc', + name: 'Rules, images, and addresses', + code: ` +

Here's a horizontal rule and image because I don't know where else to put them.

+Example kitten +
+ +

Addresses are also styled to be awesome!

+
+ john.doe@example.com
+ 778-330-2389
+ 666-666-6666
+
+ ` + } + ] + } +] + +const tocContainer = document.getElementById('toc') +for (const category of categories) { + const li = document.createElement('li') + const a = document.createElement('a') + a.href = `#${category.id}` + a.innerText = category.name + li.appendChild(a) + + const ul = document.createElement('ul') + for (const snippet of category.snippets) { + const li = document.createElement('li') + const a = document.createElement('a') + a.href = `#${snippet.id}` + a.innerText = snippet.name + li.appendChild(a) + ul.appendChild(li) + } + + li.appendChild(ul) + tocContainer.appendChild(li) +} + +const demosContainer = document.getElementById('demos') +let first = true +for (const category of categories) { + const h2 = document.createElement('h2') + h2.id = category.id + h2.innerText = category.name + demosContainer.appendChild(h2) + + const p = document.createElement('p') + p.innerText = category.description + demosContainer.appendChild(p) + + for (const snippet of category.snippets) { + const h3 = document.createElement('h3') + h3.id = snippet.id + h3.innerText = snippet.name + demosContainer.appendChild(h3) + + if (snippet.caniuse) { + const p = document.createElement('p') + p.innerText = '⚠️ This may not be supported in all browsers. ' + const a = document.createElement('a') + a.href = snippet.caniuse + a.target = '_blank' + a.rel = 'noopener noreferrer' + a.innerText = 'See caniuse for more info.' + p.appendChild(a) + demosContainer.appendChild(p) + } + + const pre = document.createElement('pre') + const code = document.createElement('code') + code.innerText = snippet.code.trim() + code.style.position = 'relative' + + const button = document.createElement('button') + button.innerText = 'Copy' + Object.assign(button.style, { + position: 'absolute', + top: '0', + right: '0', + margin: '6px', + padding: '8px' + }) + + let timeout = null + button.addEventListener('click', () => { + navigator.clipboard.writeText(snippet.code.trim()) + button.innerText = 'Copied!' + clearTimeout(timeout) + timeout = setTimeout(() => { button.innerText = 'Copy' }, 1000) + }) + + code.appendChild(button) + + pre.appendChild(code) + demosContainer.appendChild(pre) + + const details = document.createElement('details') + details.id = `${snippet.id}-details` + details.innerHTML = snippet.realCode || snippet.code + + // Execute any scripts in the HTML. + Array.from(details.querySelectorAll('script')).forEach((oldScript) => { + const newScript = document.createElement('script') + for (const { name, value } of oldScript.attributes) { newScript.setAttribute(name, value) } + newScript.appendChild(document.createTextNode(oldScript.innerHTML)) + oldScript.parentNode.replaceChild(newScript, oldScript) + }) + + const summary = document.createElement('summary') + summary.innerText = 'Show output' + details.prepend(summary) + demosContainer.appendChild(details) + + if (first) { + details.open = true + first = false + + let firstToggle = true + details.addEventListener('toggle', () => { + if (!details.open || firstToggle) return + firstToggle = false + history.pushState({}, '', '#' + snippet.id) + }) + } else { + details.addEventListener('toggle', () => { + if (!details.open) return + history.pushState({}, '', '#' + snippet.id) + }) + } + } +} + +const hashChange = () => { + const details = document.getElementById(`${window.location.hash.slice(1)}-details`) + if (!details) return + details.open = true +} +window.addEventListener('hashchange', hashChange, false) +hashChange() + +// Dialog demo scripting. +document.getElementById('dialog-trigger').addEventListener('click', () => { + document.getElementById('dialog-result').innerText = '' + document.getElementById('dialog').showModal() +}) + +document.getElementById('dialog').addEventListener('close', (event) => { + document.getElementById('dialog-result').innerText = `Your answer: ${event.target.returnValue}` +}) diff --git a/docs/scripts/index.js b/docs/scripts/index.js new file mode 100644 index 0000000..033ec0b --- /dev/null +++ b/docs/scripts/index.js @@ -0,0 +1,14 @@ +const copyButton = document.getElementById('copy-button') +const copyButtonFeedback = document.getElementById('copy-button-feedback') +const themeForm = document.getElementById('theme-form') + +copyButton.addEventListener('click', () => { + const clipboard = navigator.clipboard || window.clipboard + const theme = themeForm.querySelector('input[name="theme"]:checked').value + const snippetText = document.querySelector(`#link-snippet-${theme} code`).textContent + + clipboard.writeText(snippetText) + .then(() => { copyButtonFeedback.textContent = '✅' }) + .catch(() => { copyButtonFeedback.textContent = '❌' }) + .then(() => setTimeout(() => { copyButtonFeedback.textContent = '' }, 1000)) +}) diff --git a/docs/scripts/themer.js b/docs/scripts/themer.js new file mode 100644 index 0000000..2db123d --- /dev/null +++ b/docs/scripts/themer.js @@ -0,0 +1,73 @@ +'use strict' + +const localBase = './water.css/' + +const fileSizes = { + dark: 2.57, + light: 2.55, + auto: 3.27 +} + +const themeForm = document.getElementById('theme-form') +const stylesheet = document.getElementById('js-stylesheet') +const startupStylesheet = document.getElementById('js-startup-stylesheet') +const productHunt = document.getElementById('product-hunt') +const linkSnippets = [...document.querySelectorAll('#link-snippet-container > pre')] + +const table = { + fileName: document.getElementById('table-file-name'), + fileSize: document.getElementById('table-file-size'), + theme: document.getElementById('table-theme') +} + +const prefersColorScheme = window.matchMedia('(prefers-color-scheme: light)') + +const updateProductHunt = (theme) => { + if (!productHunt) return + theme = theme || (prefersColorScheme.matches ? 'light' : 'dark') + productHunt.src = `https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=150490&theme=${theme}&period=daily` +} + +const updateTheme = () => { + const theme = document.querySelector('input[name="theme"]:checked').value + localStorage.setItem('theme', theme) + + const fileName = `${theme === 'auto' ? 'water' : theme}.min.css` + const localUrl = `${localBase}${fileName}` + + stylesheet.href = localUrl + + for (const snippet of linkSnippets) { + snippet.hidden = snippet.id.indexOf(theme) === -1 + } + + if (table.theme) { + table.fileName.innerText = fileName + table.fileSize.innerText = `${fileSizes[theme].toFixed(2)} kb` + + if (theme === 'auto') { + updateProductHunt() + table.theme.innerHTML = ` + Respects user-defined theme settings using prefers-color-scheme.
+ Light in browsers where the theme settings can't be detected. + ` + } else { + updateProductHunt(theme) + table.theme.innerText = `Theme is forced to ${theme}.` + } + } +} + +const storedTheme = localStorage.getItem('theme') +if (storedTheme) { + themeForm.querySelector(`input[name="theme"][value="${storedTheme}"]`).checked = true +} + +updateTheme() +themeForm.addEventListener('change', updateTheme) +startupStylesheet.parentElement.removeChild(startupStylesheet) + +prefersColorScheme.addListener(() => { + if (themeForm.theme.value !== 'auto') return + updateProductHunt() +}) diff --git a/docs/style.css b/docs/style.css index a0c3fc9..03ce95f 100755 --- a/docs/style.css +++ b/docs/style.css @@ -1,7 +1,3 @@ -html { - scroll-behavior: smooth; -} - #product-hunt { margin-top: 1rem; } @@ -63,3 +59,14 @@ body > footer { align-items: center; justify-content: space-between; } + +/* Hmmm yes great class name */ +.top-theme-form { + padding: 10px 0; + top: 0; + width: 100%; + position: sticky; + margin-top: -20px; + z-index: 999; + background: var(--background-body); +} diff --git a/gulpfile.js b/gulpfile.js index 34ee92e..06534aa 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -23,7 +23,7 @@ const postcssColorModFunction = require('postcss-color-mod-function').bind(null, }) const paths = { - docs: { src: 'docs/**', dest: 'out/docs' }, + docs: { src: 'docs/**/*', dest: 'out/docs' }, styles: { src: 'src/builds/*.css', dest: 'out', watch: 'src/**/*.css' } } @@ -93,8 +93,8 @@ const docs = () => { return ( gulp - // Exclude all HTML files but index.html - .src(paths.docs.src, { ignore: '**/!(index).html' }) + // Exclude all HTML files except for those ending with .html + .src(paths.docs.src, { ignore: '**/!(*).html' }) // * Process HTML * .pipe(htmlOnly) diff --git a/package.json b/package.json index 7704812..2edd772 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "gulp build", "dev": "gulp watch", - "lint:js": "eslint bookmarklet/original.js docs/script.js docs/index.html gulpfile.js", + "lint:js": "eslint bookmarklet/original.js docs/scripts/*.js docs/*.html gulpfile.js", "lint:css": "stylelint src/**/*.css docs/style.css", "lint": "yarn lint:js --fix && yarn lint:css --fix", "accessibility": "yarn build && node accessibility.js", @@ -77,4 +77,4 @@ "out/*.css", "LICENSE.md" ] -} +} \ No newline at end of file diff --git a/src/parts/_misc.css b/src/parts/_misc.css index 04d9a02..140004a 100644 --- a/src/parts/_misc.css +++ b/src/parts/_misc.css @@ -109,7 +109,7 @@ summary:focus { text-decoration: underline; } -details > :not(summary) { +details > :not(summary):first-child { margin-top: 0; } @@ -145,6 +145,11 @@ footer { color: var(--text-muted); } -body > footer { +body > footer:last-of-type { margin-top: 40px; } + +body > header:first-of-type { + border-bottom: 1px solid var(--border); + padding-bottom: 20px; +} diff --git a/src/parts/_typography.css b/src/parts/_typography.css index 2d275b7..11b50ff 100644 --- a/src/parts/_typography.css +++ b/src/parts/_typography.css @@ -87,3 +87,17 @@ a > code, a > strong { color: inherit; } + +dt { + font-weight: 600; + color: var(--text-bright); +} + +dd { + margin: 5px 0; + margin-left: 40px; +} + +dd + dt { + margin-top: 10px; +} diff --git a/swift-dots-run.md b/swift-dots-run.md new file mode 100644 index 0000000..6167cae --- /dev/null +++ b/swift-dots-run.md @@ -0,0 +1,5 @@ +--- +"water.css": patch +--- + +Add comprehensive element documentation