From a71c9fc3156ae202af48c2342ce627e0d4f8f7c6 Mon Sep 17 00:00:00 2001 From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com> Date: Thu, 19 Dec 2024 00:29:51 -0500 Subject: [PATCH] feat(root): add shadow root support (#52) --- .github/FUNDING.yml | 2 +- .github/workflows/ci.yml | 2 +- app/build/ssg.ts | 3 + app/examples/shadow-root/styles.css | 31 + app/mod.css | 29 +- app/mod.html | 229 +++++-- app/mod.ts | 2 + app/sections/preset-build.html | 17 +- app/sections/preview-website.html | 21 +- app/sections/supported-browsers.html | 13 +- styles/@code-editor/mod.html | 29 +- styles/@discrete-scrollbars/mod.css | 6 +- styles/@form-validation/mod.css | 6 +- styles/@form-validation/mod.html | 13 +- styles/@istanbul-coverage/mod.css | 2 +- styles/@istanbul-coverage/mod.html | 47 +- styles/@layouts/mod.css | 22 +- styles/@layouts/mod.html | 3 +- styles/@layouts/simple.html | 19 +- styles/@root/mod.css | 22 +- styles/@syntax-highlighting/mod.css | 6 +- styles/@syntax-highlighting/mod.html | 35 +- styles/@utilities/classes.html | 357 +++++++--- styles/@utilities/colors.html | 150 +++-- styles/@utilities/flashes.html | 5 +- styles/@utilities/mod.css | 823 +++++++++++++++++------ styles/@utilities/mod.html | 6 +- styles/abbreviations/abbr.html | 12 +- styles/abbreviations/mod.css | 6 +- styles/anchors/a.html | 4 +- styles/annotations/ins.html | 2 +- styles/annotations/mark.html | 2 +- styles/annotations/mod.css | 6 +- styles/annotations/rp.html | 2 +- styles/annotations/rt.html | 2 +- styles/annotations/ruby.html | 2 +- styles/annotations/sub.html | 2 +- styles/annotations/sup.html | 2 +- styles/bars/meter.html | 5 +- styles/bars/mod.css | 6 +- styles/collapsibles/details.html | 2 - styles/collapsibles/summary.html | 2 +- styles/computing/kbd.html | 2 +- styles/computing/mod.css | 4 +- styles/flow/blockquote.html | 10 +- styles/flow/figcaption.html | 2 +- styles/flow/figure.html | 2 +- styles/flow/mod.css | 8 +- styles/flow/p.html | 6 +- styles/flow/pre.html | 12 +- styles/forms/button.html | 12 +- styles/forms/form.html | 4 +- styles/forms/input.html | 6 +- styles/forms/label.html | 18 +- styles/forms/legend.html | 2 +- styles/forms/mod+utilities.css | 2 +- styles/forms/mod.css | 50 +- styles/forms/select.html | 6 +- styles/forms/textarea.html | 9 +- styles/headings/h1.html | 13 +- styles/headings/mod.css | 8 +- styles/lists/dd.html | 2 +- styles/lists/dl.html | 7 +- styles/lists/dt.html | 2 +- styles/lists/li.html | 2 +- styles/lists/ol.html | 2 +- styles/lists/ul.html | 2 +- styles/media/iframe.html | 2 +- styles/media/img.html | 2 +- styles/media/video.html | 2 +- styles/modals/dialog.html | 13 +- styles/modals/mod.css | 2 +- styles/navigation/menu.html | 14 +- styles/navigation/mod.css | 43 +- styles/navigation/nav.html | 16 +- styles/sectioning/article.html | 3 +- styles/sectioning/body.html | 1 - styles/sectioning/html.html | 1 - styles/sectioning/mod.css | 8 +- styles/sectioning/section.html | 9 +- styles/styling/b.html | 2 +- styles/styling/cite.html | 2 +- styles/styling/dfn.html | 2 +- styles/styling/em.html | 2 +- styles/styling/i.html | 2 +- styles/styling/mod.css | 2 +- styles/styling/s.html | 2 +- styles/styling/small.html | 2 +- styles/styling/strong.html | 2 +- styles/styling/u.html | 2 +- styles/tables/caption.html | 2 +- styles/tables/mod.css | 4 +- styles/tables/table.html | 46 +- styles/tables/td.html | 2 +- styles/tables/th.html | 2 +- styles/tables/tr.html | 2 +- styles/unstyled/components/slot.html | 2 +- styles/unstyled/components/template.html | 2 +- styles/unstyled/computing/data.html | 2 +- styles/unstyled/computing/time.html | 2 +- styles/unstyled/document/base.html | 2 +- styles/unstyled/document/head.html | 2 +- styles/unstyled/document/link.html | 2 +- styles/unstyled/document/meta.html | 2 +- styles/unstyled/document/style.html | 2 +- styles/unstyled/document/title.html | 2 +- styles/unstyled/forms/datalist.html | 2 +- styles/unstyled/forms/optgroup.html | 2 +- styles/unstyled/forms/option.html | 2 +- styles/unstyled/generic/div.html | 2 +- styles/unstyled/generic/span.html | 2 +- styles/unstyled/media/area.html | 2 +- styles/unstyled/media/audio.html | 2 +- styles/unstyled/media/embed.html | 2 +- styles/unstyled/media/map.html | 2 +- styles/unstyled/media/math.html | 2 +- styles/unstyled/media/object.html | 2 +- styles/unstyled/media/picture.html | 2 +- styles/unstyled/media/portal.html | 2 +- styles/unstyled/media/source.html | 2 +- styles/unstyled/media/svg.html | 2 +- styles/unstyled/media/track.html | 2 +- styles/unstyled/scripting/canvas.html | 2 +- styles/unstyled/scripting/noscript.html | 2 +- styles/unstyled/scripting/script.html | 2 +- styles/unstyled/sectioning/address.html | 2 +- styles/unstyled/sectioning/search.html | 2 +- styles/unstyled/tables/tbody.html | 2 +- styles/unstyled/tables/tfoot.html | 2 +- styles/unstyled/tables/thead.html | 2 +- styles/unstyled/text/bdi.html | 2 +- styles/unstyled/text/bdo.html | 2 +- styles/unstyled/text/br.html | 2 +- styles/unstyled/text/wbr.html | 2 +- 134 files changed, 1709 insertions(+), 711 deletions(-) create mode 100644 app/examples/shadow-root/styles.css diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 6252e0d..55196dc 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: lowlighter \ No newline at end of file +github: lowlighter diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed86397..0e7ec08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,4 +28,4 @@ jobs: - name: Run npm publish run: | deno task build - deno run --allow-all jsr:@libs/bundle/ts/cli/publish deno.jsonc --loglevel debug --npm.registry 'https://registry.npmjs.org' --npm.token '${{ secrets.NPM_TOKEN }}' --npm.access public \ No newline at end of file + deno run --allow-all jsr:@libs/bundle/ts/cli/publish deno.jsonc --loglevel debug --npm.registry 'https://registry.npmjs.org' --npm.token '${{ secrets.NPM_TOKEN }}' --npm.access public diff --git a/app/build/ssg.ts b/app/build/ssg.ts index 8238bc7..c171b44 100644 --- a/app/build/ssg.ts +++ b/app/build/ssg.ts @@ -23,6 +23,9 @@ export async function ssg() { console.log("Created .pages/mod.svg") await copy(new URL("app/mod.css", root), new URL(".pages/mod.css", root)) console.log("Created .pages/mod.css") + // Copy examples + await copy(fromFileUrl(new URL("app/examples", root)), new URL(".pages/examples", root)) + console.log(`Created .pages/examples`) // Generate CSS const dist = fromFileUrl(new URL("dist", root)).replaceAll("\\", "/") await ensureDir(new URL(".pages/v/main", root)) diff --git a/app/examples/shadow-root/styles.css b/app/examples/shadow-root/styles.css new file mode 100644 index 0000000..bf954b7 --- /dev/null +++ b/app/examples/shadow-root/styles.css @@ -0,0 +1,31 @@ +.example-shadow-root-content { + display: flex; + justify-content: space-around; +} + +section { + margin-bottom: 0; +} + +img { + max-width: 100px; + flex-shrink: 1; + box-shadow: var(--shadow); + margin: 1rem; +} + +aside { + margin: 0; + flex-grow: 1; + border-left: none; +} + +aside b { + color: var(--default); +} + +audio { + margin-top: 0.25rem; + border-radius: var(--bd-radius); + width: 100%; +} diff --git a/app/mod.css b/app/mod.css index 49f9717..2b5b1b3 100644 --- a/app/mod.css +++ b/app/mod.css @@ -82,7 +82,7 @@ details summary a { } .matcha-build .variables input[name$="opacity"] { - margin-left: .25rem; + margin-left: 0.25rem; width: 3rem; text-align: center; } @@ -106,7 +106,7 @@ details summary a { } .matcha-build .styling label small { - opacity: .75; + opacity: 0.75; } .matcha-build .styling > div { @@ -170,13 +170,13 @@ details summary a { font-size: 85%; font-weight: normal; list-style: circle; - margin: 0 .5rem; + margin: 0 0.5rem; } .css-compatibility-table.details :is(td, th) > :nth-child(1) { border-bottom: 1px solid var(--bg-contrast); - padding-bottom: .5rem; - margin-bottom: .5rem; + padding-bottom: 0.5rem; + margin-bottom: 0.5rem; } .css-compatibility-table.details :is(td, th) > :nth-child(n+2) { @@ -281,7 +281,7 @@ details summary a { justify-content: end; margin-bottom: 0; border-bottom: none; - margin: .5rem 0 .25rem; + margin: 0.5rem 0 0.25rem; } .example-tabs > li { @@ -366,12 +366,12 @@ details summary a { width: 1.5em; } -.example input:is([type="datetime-local"],[type="date"],[type="month"],[type="week"],[type="time"]) { +.example input:is([type="datetime-local"], [type="date"], [type="month"], [type="week"], [type="time"]) { max-width: 100px; } @media (min-width: 640px) { - .example input:is([type="datetime-local"],[type="date"],[type="month"],[type="week"],[type="time"]) { + .example input:is([type="datetime-local"], [type="date"], [type="month"], [type="week"], [type="time"]) { max-width: none; } } @@ -380,6 +380,11 @@ details summary a { z-index: 200; } +.example .example-shadow-root { + border: 2px dotted var(--bg-contrast); + border-radius: var(--bd-radius); +} + /* Layout structure */ .layout-structure, .layout-structure ul { padding-left: 1rem; @@ -405,7 +410,7 @@ details summary a { left: 0; width: 100%; height: 100%; - background-color: rgba(100, 0, 0, .2); + background-color: rgba(100, 0, 0, 0.2); backdrop-filter: brightness(50%) blur(5px); } @@ -418,15 +423,15 @@ details summary a { } .easter-egg.glitch.blue, .easter-egg.glitch.red { - opacity: .1; + opacity: 0.1; animation: 1s glitch infinite; } @keyframes glitch { - 1%{ + 1% { transform: rotateX(10deg) skewX(90deg); } - 2%{ + 2% { transform: rotateX(0deg) skewX(0deg); } } diff --git a/app/mod.html b/app/mod.html index 910bbb0..19f04af 100644 --- a/app/mod.html +++ b/app/mod.html @@ -3,7 +3,10 @@ matcha.css | Drop-in semantic styling library in pure CSS - + @@ -20,25 +23,72 @@

matcha.css

@@ -59,15 +109,34 @@

matcha.css

matcha.css is a pure CSS library designed to style HTML elements similarly to a default browser stylesheet, eliminating the need for users to manually patch their documents.

- Ideal for fast prototyping, static HTML pages, Markdown-generated documents, and developers seeking to streamline their workflow without delving into CSS intricacies and want to make use of the full range of available HTML elements. + Ideal for fast prototyping, static HTML pages, Markdown-generated documents, and developers seeking to streamline their workflow without delving into CSS intricacies and want to make use + of the full range of available HTML elements.

🍵 Fun Fact: This very page is styled using matcha.css! @@ -78,20 +147,19 @@

Why choose matcha.css?

Agnostic
- Works seamlessly with any document and covers a broader range of HTML elements compared to similar libraries. - It remains unobtrusive by leveraging CSS pseudo-elements and offers extensive browser support. + Works seamlessly with any document and covers a broader range of HTML elements compared to similar libraries. It remains unobtrusive by leveraging CSS pseudo-elements and offers + extensive browser support.
Reversible
- Simply include its <link rel="stylesheet"> to get started, - and remove it whenever necessary without the need for document refactoring or cleanup. + Simply include its <link rel="stylesheet"> to get started, and remove it whenever necessary without the need for document + refactoring or cleanup.
Semantic
Adapts styling based on elements hierarchy, providing intuitive behaviors such as - implicit submenus when nesting <menu> elements, - required field indicator (*) when a <label> is paired with <input required>, - etc. + implicit submenus when nesting <menu> elements, required field indicator (*) when a <label> is paired with <input required>, etc.
Customizable
@@ -99,35 +167,39 @@

Why choose matcha.css?

Open-source
- Released under the MIT License, - freely available at github.com/lowlighter/matcha. + Released under the MIT License, freely available at github.com/lowlighter/matcha.

Usage

- To utilize matcha.css, just include the following line in the <head> section of your document. - It's that simple! + To utilize matcha.css, just include the following line in the <head> section of your document. It's that simple!

<link rel="stylesheet" href="https://matcha.mizu.sh/matcha.css">

- Assets are hosted on Vercel but matcha.css is also available on npm + Assets are hosted on Vercel but matcha.css is also available on npm and CDN services that distributes npm packages such as JSdelivr.

- All published versions are available in the /v/ directory. - By default, the main branch is served. + All published versions are available in the /v/ directory. By default, the main branch is served.

À la carte

- Each subdirectory available in github.com/lowlighter/matcha/styles is also served directly from this website. - For example, if you only wish to include the @syntax-highlighting styles rather than using the default build or a custom one, you could use: + Each subdirectory available in github.com/lowlighter/matcha/styles is also served directly from this + website. For example, if you only wish to include the @syntax-highlighting styles rather than using the default build or a custom one, you could use:

<link rel="stylesheet" href="https://matcha.mizu.sh/styles/@syntax-highlighting/mod.css">

- However note that unless you provide your own CSS variables, you will most likely need to include the @root package as it contains all matcha.css variables definition. + However note that unless you provide your own CSS variables, you will most likely need to include the @root package as it contains + all matcha.css variables definition.

@@ -270,6 +342,39 @@

Code editor

Istanbul coverage reports

+
+

Shadow roots

+

+ matcha.css defines also defines its CSS variables using the :host pseudo-class, which + makes it compatible with shadow DOMs. +

+
+

+ *The following element is contained within a shadow DOM.
+ It is isolated from the rest of the document so you may import matcha.css again and use other custom styles + without conflicts. +

+
+ +
+
+

Unstyled

@@ -350,19 +455,35 @@

Scripting

- \ No newline at end of file + diff --git a/app/mod.ts b/app/mod.ts index 1dc82ed..25f71fe 100644 --- a/app/mod.ts +++ b/app/mod.ts @@ -39,6 +39,8 @@ switch (Deno.args[0]) { return api_minify(request) case new URLPattern("/api/preview", url.origin).test(url.href.replace(url.search, "")): return api_preview(request) + case new URLPattern("/examples/shadow-root/styles.css", url.origin).test(url.href.replace(url.search, "")): + return new Response(await Deno.readFile(new URL("examples/shadow-root/styles.css", import.meta.url)), { headers: { "Content-Type": "text/css" } }) case new URLPattern("/highlight.js", url.origin).test(url.href.replace(url.search, "")): return fetch(highlight) case new URLPattern("/v/*", url.origin).test(url.href.replace(url.search, "")): diff --git a/app/sections/preset-build.html b/app/sections/preset-build.html index 46457a3..4773e74 100644 --- a/app/sections/preset-build.html +++ b/app/sections/preset-build.html @@ -1,11 +1,11 @@

Preset builds

- matcha.css provides preset builds for added convenience. - If you need a specific set of features, you can also use the custom builder. + matcha.css provides preset builds for added convenience. If you need a specific set of features, you can also use the custom builder.

-
\ No newline at end of file +
diff --git a/app/sections/preview-website.html b/app/sections/preview-website.html index c6c1e40..7cc5251 100644 --- a/app/sections/preview-website.html +++ b/app/sections/preview-website.html @@ -10,9 +10,8 @@

🕵️ Preview a Website