Compare commits

..

133 Commits

Author SHA1 Message Date
Dave Gandy
f278ce1d6d evening up line breaks 2024-03-12 12:12:08 -05:00
lindsaym-fa
0bbf9bb275 hide astro dev toolbar for layouts 2024-03-12 13:09:15 -04:00
lindsaym-fa
4deb928682 add configurable drawer background color 2024-03-12 13:04:49 -04:00
lindsaym-fa
4066e8c591 Merge remote-tracking branch 'origin/konnorrogers/layout-with-astro' into demo-layout 2024-03-12 12:33:25 -04:00
konnorrogers
8eb6ee6609 fix grid for navigation 2024-03-12 12:19:51 -04:00
lindsaym-fa
620525891d add nav toggle to advanced layout 2024-03-12 11:41:56 -04:00
konnorrogers
384147502f rename to pagE 2024-03-12 10:36:55 -04:00
lindsaym-fa
730e20bd38 remove extraneous classes 2024-03-12 10:03:32 -04:00
konnorrogers
9b3669c428 Merge branch 'next' of https://github.com/shoelace-style/webawesome into konnorrogers/layout-with-astro 2024-02-28 15:08:03 -05:00
konnorrogers
b003273175 remove vercel.json 2024-02-27 16:09:35 -05:00
konnorrogers
faae5c21fd remove sandbox-settings 2024-02-27 15:51:44 -05:00
konnorrogers
af89149939 maybe now? 2024-02-27 15:40:40 -05:00
konnorrogers
9b5ceb989c add sandbox-settings 2024-02-27 15:31:35 -05:00
konnorrogers
7862c374dc add sandbox-settings 2024-02-27 15:28:43 -05:00
konnorrogers
03508ec523 add sandbox-settings 2024-02-27 15:21:00 -05:00
konnorrogers
aadf4830c6 add vercel.json 2024-02-27 14:36:40 -05:00
konnorrogers
cd282e50ef add vercel.json 2024-02-27 14:30:35 -05:00
konnorrogers
57ddd25662 add vercel.json 2024-02-27 14:23:25 -05:00
konnorrogers
a37f2d594e add vercel.json 2024-02-27 14:18:25 -05:00
konnorrogers
6fbf921f4b add vercel.json 2024-02-27 14:14:39 -05:00
konnorrogers
c11f3d468b prettier 2024-02-27 13:41:55 -05:00
konnorrogers
306eefa44b rename layout to page 2024-02-27 13:39:55 -05:00
konnorrogers
cd237d3057 light-pen 3 2024-02-26 16:24:34 -05:00
konnorrogers
c7757b8cbe working on astro layout 2024-02-22 14:33:49 -05:00
Cory LaViska
b53c1d940a backport 1880 2024-02-21 13:33:00 -05:00
Cory LaViska
edd62490f8 backport 1839 2024-02-20 15:01:35 -05:00
Cory LaViska
96a381d3a3 backport 1879 2024-02-20 14:18:48 -05:00
Cory LaViska
a2a72de2cf backport 1788 2024-02-20 14:13:23 -05:00
Cory LaViska
9a51e69320 backport 1878 2024-02-20 14:00:49 -05:00
Cory LaViska
07be57847d backport 1874 2024-02-20 13:48:57 -05:00
Cory LaViska
0095ca5fe7 backport 1877 2024-02-20 12:53:38 -05:00
konnorrogers
4b8a86f0e2 continued work on layouts 2024-02-13 18:40:37 -05:00
konnorrogers
41de947779 working on playgrounds 2024-02-09 16:32:45 -05:00
Cory LaViska
cb1c423aea backport 1862 2024-02-09 10:05:14 -05:00
Cory LaViska
93306c99ce backport 1800, 1860 2024-02-09 09:58:13 -05:00
Cory LaViska
5f8c69064c backport 1852 2024-02-09 09:46:46 -05:00
Cory LaViska
f51a09ddf0 backport 1840 2024-02-08 12:46:08 -05:00
konnorrogers
11337197d7 first layout converted to sportawesome 2024-02-07 13:41:12 -05:00
konnorrogers
f1739309eb fix buildS 2024-02-07 12:46:46 -05:00
konnorrogers
5007924dbd working on layouts 2024-02-06 16:24:25 -05:00
Konnor Rogers
92533c0297 Convert to Starlight (#22)
* first pass at starlight

* converting to starlight

* working on converting to starlight

* working on data

* watch custom-elements.json

* turn on pagefind

* add component meta data

* fix renderings / overrides.

* fix mdx logo

* continue starlight work

* building site

* get global styles + reloads working

* themer fixes

* adding additional headings

* working on dynamic content

* have TableOfContents.astro push to TOC

* working on code stuff

* remove code preview

* deploy

* add patch package

* patch in build

* patch in build

* remove {% raw %} calls

* convert to starlight...complete

* prettier

* update lockfile

* merge main

* fix index.mdx

* prettier'

* fix small things

* docs updates

* add dark mode shortcut

* prettier

* prettier

* prettier

* remove pagefind from public

* add twitteR

* prettier

* fix tests

* prettier
2024-02-05 11:02:14 -05:00
Cory LaViska
94558e6ea5 Merge pull request #19 from shoelace-style/backport-menu-item-loading
backport `<sl-menu-item loading>`
2024-01-31 16:13:59 -05:00
lindsaym-fa
bab673fbdc optional class for alternating table row colors 2024-01-31 15:27:39 -05:00
lindsaym-fa
7b20f9c87a deprecate global toggle-size properties 2024-01-30 16:06:09 -05:00
lindsaym-fa
ddbd91ad89 update radio with custom properties, svg circle 2024-01-30 15:45:27 -05:00
lindsaym-fa
130844df1c add custom properties to carousel 2024-01-25 14:08:31 -05:00
lindsaym-fa
d6cfa1ab24 add custom properties to tag 2024-01-24 16:40:25 -05:00
Cory LaViska
ec613f8d32 backport 1797 2024-01-24 13:31:42 -05:00
Cory LaViska
52e2518365 backport 1818 2024-01-24 13:24:29 -05:00
Cory LaViska
9b7aad71a9 backport 1831 2024-01-24 13:23:41 -05:00
Cory LaViska
b7541d240b backport 1828 2024-01-24 13:21:27 -05:00
Cory LaViska
c67da1e818 backport 1826 2024-01-24 13:20:36 -05:00
Cory LaViska
265e523a56 backport 1822 2024-01-24 13:16:38 -05:00
Cory LaViska
bfe05d0692 backport 1821 2024-01-24 12:25:13 -05:00
Cory LaViska
651eae8cb6 backport 1820 2024-01-24 12:21:41 -05:00
lindsaym-fa
8c8b3f1853 add custom properties to badge 2024-01-23 11:27:01 -05:00
lindsaym-fa
d1ed504dd8 update custom properties on checkbox doc 2024-01-18 08:46:51 -06:00
lindsaym-fa
5335c9421a add depth to checkbox 2024-01-17 16:44:34 -06:00
lindsaym-fa
1b380f3f1d document custom properties for checkbox 2024-01-17 09:33:11 -06:00
lindsaym-fa
d166bc0e48 add custom properties to checkbox 2024-01-17 09:08:26 -06:00
lindsaym-fa
595cc303e7 add custom property for progress bar shadows 2024-01-16 14:08:11 -06:00
lindsaym-fa
4260b27fd2 tweak spacing for playful theme 2024-01-16 13:55:59 -06:00
lindsaym-fa
7c6f018c5b rename border tokens with s/m/l convention 2024-01-16 13:50:30 -06:00
lindsaym-fa
b892f1f86a re-integrate borders into main theme stylesheets 2024-01-16 13:42:32 -06:00
lindsaym-fa
a0e9125d61 add custom properties to details component 2024-01-16 13:13:32 -06:00
lindsaym-fa
5b741006a1 tweak playful theme font weights 2024-01-16 12:57:12 -06:00
lindsaym-fa
30bfabc397 add link decoration tokens; undo dark mode borders 2024-01-16 10:02:49 -06:00
lindsaym-fa
4e1bea7d94 update fonts, remove font imports from themes 2024-01-15 09:18:34 -06:00
lindsaym-fa
f2bb9fefee dark theme adjustments 2024-01-08 23:19:14 -05:00
lindsaym-fa
9987ce8d4f simplify themer logic 2024-01-08 22:49:48 -05:00
lindsaym-fa
4ace1efbe0 minor themer tweaks 2024-01-08 18:06:02 -05:00
Konnor Rogers
d7920f2e75 Add logo uploader (#18)
* fix tabbable, add logo uploader

* Add icon chooser and project name to themer

* Add icon chooser and project name to themer

* make theme swapping less jarring

* add depth to themer

* update font families / font weights on theme change

* fix prettier

* update themer to reset values on theme change

* remove custom-elements.mjs

* prettier

* update comments in isVisible

* add PR #

* prettier

* update changelog

* prettier

* update changelog

* fix themer

* ensure target exists

* update icon search

* prettier

* fix select test

* prettier

* fix sprite svg

* remove custom-elements.mjs

* Add small validation to themer

* prettier

* fix conflicts

* prettier

* remove cem-manifest.mjs

---------

Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2024-01-08 16:43:57 -05:00
Kelsey Jackson
4198cf0f15 Merge pull request #24 from shoelace-style/theming-ui/dark-mode-for-all-themes
add the ability to toggle light and dark mode for themes
2024-01-08 14:03:16 -06:00
Kelsey Jackson
7562905bbf made updates 2024-01-05 15:20:33 -06:00
Kelsey Jackson
4914cdb352 Merge pull request #23 from shoelace-style/theming-ui/add-curated-font-list
add list of curated fonts
2024-01-04 18:08:21 -06:00
Kelsey Jackson
0c95c70192 updated spacing issue 2024-01-03 11:30:16 -06:00
Kelsey Jackson
430730f24a Merge branch 'next' into theming-ui/add-curated-font-list 2024-01-03 11:01:05 -06:00
Kelsey Jackson
ab0c615e10 updated text 2024-01-03 10:46:53 -06:00
Kelsey Jackson
716ab94069 Merge branch 'next' into theming-ui/dark-mode-for-all-themes 2024-01-03 10:26:08 -06:00
lindsaym-fa
ccc6f1aa23 adjust applied code background color 2023-12-13 17:44:25 -05:00
lindsaym-fa
893f8b2740 fix sandbox icons 2023-12-13 17:10:08 -05:00
lindsaym-fa
00d5164912 touch up icons 2023-12-13 17:02:24 -05:00
Cory LaViska
fc9151e573 backport 1787 2023-12-13 12:04:53 -05:00
Kelsey Jackson
cf97bc3c6c add the ability to toggle light and dark mode for themes 2023-12-12 10:58:29 -06:00
Cory LaViska
eb9dbf097c prettier 2023-12-11 16:53:11 -05:00
konnorrogers
5422e6431c fix copying cdn build to _site after its been built 2023-12-11 16:25:24 -05:00
Cory LaViska
f3a921022e Merge branch 'icon' into next 2023-12-11 16:02:12 -05:00
Cory LaViska
be1440aee0 update settings 2023-12-11 16:01:44 -05:00
Kelsey Jackson
fe23a7ddb8 add list of curated fonts 2023-12-11 11:51:53 -06:00
lindsaym-fa
f53a643cf3 improve typescale 2023-12-08 17:53:33 -05:00
Konnor Rogers
3f604fcee1 prettier (#20) 2023-12-08 15:09:34 -05:00
lindsaym-fa
d8b6db8c5b darken background in themer sample UI 2023-12-08 14:19:54 -05:00
lindsaym-fa
31215dbda4 define font size at root in applied styles 2023-12-08 14:18:24 -05:00
Cory LaViska
f00e8c3a65 prettier ci output 2023-12-07 16:30:37 -05:00
Cory LaViska
a4f8bf94ee fix 2023-12-07 16:26:44 -05:00
Cory LaViska
8ae1303188 sigh 2023-12-07 16:26:07 -05:00
Cory LaViska
ffc0248e4c fix build 2023-12-07 15:59:53 -05:00
konnorrogers
81d3f22da6 fix dev server output for errors / logging 2023-12-07 15:18:56 -05:00
Cory LaViska
0fa8e6f550 update build 2023-12-07 14:58:12 -05:00
Cory LaViska
a67d1df89a fix error 2023-12-07 14:57:53 -05:00
Cory LaViska
0fe400c6f4 Merge branch 'next' into icon 2023-12-07 10:09:54 -05:00
Cory LaViska
349aa45d2b backport 2023-12-06 17:18:12 -05:00
Cory LaViska
fcf0a136f2 backport 1771 2023-12-06 16:26:15 -05:00
Cory LaViska
8acfc4c9de backport 1767 2023-12-06 16:19:01 -05:00
Cory LaViska
4f8417806c backport 1764 2023-12-06 12:02:20 -05:00
Cory LaViska
65cb3175af update soooo many icons 2023-12-05 17:37:06 -05:00
Cory LaViska
06135e686b fic code bg color 2023-12-05 13:55:31 -05:00
lindsaym-fa
340351ca4b improve variance between depth levels 2023-12-01 12:12:49 -05:00
Cory LaViska
5701bef6e9 backport 1749 2023-12-01 10:29:37 -05:00
Cory LaViska
62417ed1d1 backport PR 1752 2023-12-01 10:15:20 -05:00
Cory LaViska
545162eaae data-web-awesome instead of data-webawesome 2023-11-28 14:19:08 -05:00
lindsaym-fa
77a8c418ea add Font Awesome theme 2023-11-22 14:55:37 -05:00
lindsaym-fa
641e92a340 improve shadow calculations 2023-11-22 14:35:17 -05:00
lindsaym-fa
3f8535e7b8 remove border color change for alerts 2023-11-22 14:33:41 -05:00
konnorrogers
81a66df7e4 add exportConditions for tests 2023-11-21 11:07:46 -05:00
Lindsay M
ae2480dfe2 Theme revisions (#12)
* remove square, stretch, and squish spacing tokens

* remove units from base tokens

* rename corner tokens with t-shirt size scale

* rename 'font-size' tokens to 'size'

* rename 'neutral' primitives to 'base'

* remove black and white tokens

* improve 'form-controls' tokens

* reintroduce granular focus ring tokens

* fix themer styles

* tweak shadow styles

* improve naming and scope of foundational colors

* overhaul color naming and add new themes

* more classic sl component styles

* make 'chic' theme dark by default

* adjust table row colors

* remove deprecated properties from 'classic' theme

* remove mistakenly committed stylesheets

* revert adjustment to space properties

* delete web-types.json

* revert "rename 'font-size' tokens to 'size'"
2023-11-15 11:43:40 -05:00
Cory LaViska
c95b0b6c66 backport PR 1722 2023-11-14 13:15:57 -05:00
Konnor Rogers
dee01269ad Konnorrogers/backport 1711 and 1714 (#11)
* backport #1711 & #1714

* remove custom-elements.mjs

* prettier
2023-11-14 12:22:18 -05:00
Cory LaViska
e11eb363aa Merge branch 'next' of https://github.com/shoelace-style/webawesome into next 2023-11-13 15:57:49 -05:00
Cory LaViska
0d33cabec4 add back two-way binding info 2023-11-13 15:57:47 -05:00
Konnor Rogers
b5d9b49b27 backport #1707 & #1708 (#10)
* backport #1707 & #1708

* prettier

* fix prettier log level

* fix test

* backport #1707 & #1708
2023-11-08 15:20:06 -05:00
Lindsay M
1b654c7c85 Support theme customizations for depth and borders
* Move custom properties related to shadows and borders to separate stylesheets
* Change base values and themer calculations related to shadows and borders to be unitless
* Add low-level custom properties for alert, button, card, input, select, switch, and textarea
* Add generic guidance for authoring custom properties to the Contributing docs
2023-11-03 13:46:00 -04:00
Cory LaViska
4e53ce870d backport PR 1702 2023-11-03 10:27:03 -04:00
Cory LaViska
932e2e7566 update jet brains plugin and stop writing to package.json 2023-11-02 08:53:17 -04:00
Konnor Rogers
e76a1dc1f6 fix no translation error (#8)
* fix no translation error

* prettier
2023-11-01 16:49:24 -04:00
Cory LaViska
38302a7c28 fix bad port 2023-10-25 13:38:21 -04:00
Cory LaViska
71e5b10f3b backport PR 1684 2023-10-25 13:07:59 -04:00
Cory LaViska
3eda5510c3 fix tests 2023-10-23 12:33:14 -04:00
Cory LaViska
32494e783c backport PR 1605 2023-10-23 12:03:18 -04:00
Cory LaViska
cdf38fe147 remove ts-check 2023-10-23 11:35:32 -04:00
Cory LaViska
302c174055 backport PR 1671 2023-10-23 10:48:37 -04:00
Cory LaViska
fb044aae89 backport PR 1670 2023-10-23 10:19:34 -04:00
Cory LaViska
bf299d8234 backport PR 1670 2023-10-20 09:04:15 -04:00
2516 changed files with 23628 additions and 75737 deletions

2
.gitignore vendored
View File

@@ -5,6 +5,8 @@ package.json
package-lock.json
dist
docs/assets/images/sprite.svg
docs/public/pagefind
node_modules
src/react
cdn
.astro

View File

@@ -2,7 +2,7 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"debug.enableStatusBarColor": false
}

View File

@@ -47,6 +47,7 @@
"dropdowns",
"easings",
"endraw",
"endregion",
"enterkeyhint",
"eqeqeq",
"erroneou",
@@ -102,6 +103,7 @@
"monospace",
"mousedown",
"mousemove",
"mouseout",
"mouseup",
"multiselectable",
"nextjs",
@@ -113,6 +115,7 @@
"Numberish",
"oklab",
"oklch",
"onscrollend",
"outdir",
"ParamagicDev",
"peta",
@@ -170,10 +173,13 @@
"valpha",
"valuenow",
"valuetext",
"viewports",
"Vuejs",
"WCAG",
"webawesome",
"WEBP",
"Webpacker"
"Webpacker",
"xmark"
],
"ignorePaths": [
"package.json",

View File

@@ -1,6 +1,7 @@
import * as path from 'path';
import { customElementJetBrainsPlugin } from 'custom-element-jet-brains-integration';
import { customElementVsCodePlugin } from 'custom-element-vs-code-integration';
import { customElementVuejsPlugin } from 'custom-element-vuejs-integration';
import { parse } from 'comment-parser';
import { pascalCase } from 'pascal-case';
import commandLineArgs from 'command-line-args';
@@ -38,6 +39,7 @@ export default {
customElementsManifest.package = { name, description, version, author, homepage, license };
}
},
// Infer tag names because we no longer use @customElement decorators.
{
name: 'wa-infer-tag-names',
@@ -66,6 +68,7 @@ export default {
}
}
},
// Parse custom jsDoc tags
{
name: 'wa-custom-tags',
@@ -137,6 +140,7 @@ export default {
}
}
},
{
name: 'wa-react-event-names',
analyzePhase({ ts, node, moduleDoc }) {
@@ -155,6 +159,7 @@ export default {
}
}
},
{
name: 'wa-translate-module-paths',
packageLinkPhase({ customElementsManifest }) {
@@ -191,6 +196,7 @@ export default {
});
}
},
// Generate custom VS Code data
customElementVsCodePlugin({
outdir,
@@ -202,15 +208,23 @@ export default {
}
]
}),
customElementJetBrainsPlugin({
outdir: './dist',
excludeCss: true,
packageJson: false,
referencesTemplate: (_, tag) => {
return {
name: 'Documentation',
url: `https://shoelace.style/components/${tag.replace('wa-', '')}`
};
}
}),
customElementVuejsPlugin({
outdir: './dist/types/vue',
fileName: 'index.d.ts',
componentTypePath: (_, tag) => `../../components/${tag.replace('wa-', '')}/${tag.replace('wa-', '')}.component.js`
})
]
};

4
docs/.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
docs/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View File

@@ -1,349 +0,0 @@
{% extends "default.njk" %}
{# Find the component based on the `tag` front matter #}
{% set component = getComponent('wa-' + page.fileSlug) %}
{% block content %}
{# Determine the badge variant #}
{% if component.status == 'stable' %}
{% set badgeVariant = 'brand' %}
{% elseif component.status == 'experimental' %}
{% set badgeVariant = 'warning' %}
{% elseif component.status == 'planned' %}
{% set badgeVariant = 'neutral' %}
{% elseif component.status == 'deprecated' %}
{% set badgeVariant = 'danger' %}
{% else %}
{% set badgeVariant = 'neutral' %}
{% endif %}
{# Header #}
<header class="component-header">
<h1>{{ component.name | classNameToComponentName }}</h1>
<div class="component-header__tag">
<code>&lt;{{ component.tagName }}&gt; | {{ component.name }}</code>
</div>
<div class="component-header__info">
<wa-badge variant="neutral" pill>
Since {{component.since or '?' }}
</wa-badge>
<wa-badge variant="{{ badgeVariant }}" pill style="text-transform: capitalize;">
{{ component.status }}
</wa-badge>
</div>
</header>
<p class="component-summary">
{% if component.summary %}
{{ component.summary | markdownInline | safe }}
{% endif %}
</p>
{# Markdown content #}
{{ content | safe }}
{# Importing #}
<h2>Importing</h2>
<p>
If you're using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use
any of the following snippets to <a href="/getting-started/installation#cherry-picking">cherry pick</a> this component.
</p>
<wa-tab-group>
<wa-tab slot="nav" panel="script">Script</wa-tab>
<wa-tab slot="nav" panel="import">Import</wa-tab>
<wa-tab slot="nav" panel="bundler">Bundler</wa-tab>
<wa-tab slot="nav" panel="react">React</wa-tab>
<wa-tab-panel name="script">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a script tag:
</p>
<pre><code class="language-html">&lt;script type=&quot;module&quot; src=&quot;https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}&quot;&gt;&lt;/script&gt;</code></pre>
</wa-tab-panel>
<wa-tab-panel name="import">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a JavaScript import:
</p>
<pre><code class="language-js">import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}';</code></pre>
</wa-tab-panel>
<wa-tab-panel name="bundler">
<p>
To import this component using <a href="{{ rootUrl('/getting-started/installation#bundling') }}">a bundler</a>:
</p>
<pre><code class="language-js">import '@shoelace-style/shoelace/{{ meta.npmdir }}/{{ component.path }}';</code></pre>
</wa-tab-panel>
<wa-tab-panel name="react">
<p>
To import this component as a <a href="/frameworks/react">React component</a>:
</p>
<pre><code class="language-js">import {{ component.name }} from '@shoelace-style/shoelace/{{ meta.npmdir }}/react/{{ component.tagNameWithoutPrefix }}';</code></pre>
</wa-tab-panel>
</wa-tab-group>
{# Slots #}
{% if component.slots.length %}
<h2>Slots</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for slot in component.slots %}
<tr>
<td class="nowrap">
{% if slot.name %}
<code>{{ slot.name }}</code>
{% else %}
(default)
{% endif %}
</td>
<td>{{ slot.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#slots') }}">using slots</a>.</em></p>
{% endif %}
{# Properties #}
{% if component.properties.length %}
<h2>Properties</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-reflects">Reflects</th>
<th class="table-type">Type</th>
<th class="table-default">Default</th>
</tr>
</thead>
<tbody>
{% for prop in component.properties %}
<tr>
<td>
<code class="nowrap">{{ prop.name }}</code>
{% if prop.attribute | length > 0 %}
{% if prop.attribute != prop.name %}
<br>
<wa-tooltip content="This attribute is different from its property">
<small>
<code class="nowrap">
{{ prop.attribute }}
</code>
</small>
</wa-tooltip>
{% endif %}
{% endif %}
</td>
<td>
{{ prop.description | markdownInline | safe }}
</td>
<td style="text-align: center;">
{% if prop.reflects %}
<wa-icon label="yes" name="check-lg"></wa-icon>
{% endif %}
</td>
<td>
{% if prop.type.text %}
<code>{{ prop.type.text | markdownInline | safe }}</code>
{% else %}
-
{% endif %}
</td>
<td>
{% if prop.default %}
<code>{{ prop.default | markdownInline | safe }}</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<td class="nowrap"><code>updateComplete</code></td>
<td>
A read-only promise that resolves when the component has
<a href="/getting-started/usage?#component-rendering-and-updating">finished updating</a>.
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#attributes-and-properties') }}">attributes and properties</a>.</em></p>
{% endif %}
{# Events #}
{% if component.events.length %}
<h2>Events</h2>
<table>
<thead>
<tr>
<th class="table-name" data-flavor="html">Name</th>
<th class="table-name" data-flavor="react">React Event</th>
<th class="table-description">Description</th>
<th class="table-event-detail">Event Detail</th>
</tr>
</thead>
<tbody>
{% for event in component.events %}
<tr>
<td data-flavor="html"><code class="nowrap">{{ event.name }}</code></td>
<td data-flavor="react"><code class="nowrap">{{ event.reactName }}</code></td>
<td>{{ event.description | markdownInline | safe }}</td>
<td>
{% if event.type.text %}
<code>{{ event.type.text }}</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#events') }}">events</a>.</em></p>
{% endif %}
{# Methods #}
{% if component.methods.length %}
<h2>Methods</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-arguments">Arguments</th>
</tr>
</thead>
<tbody>
{% for method in component.methods %}
<tr>
<td class="nowrap"><code>{{ method.name }}()</code></td>
<td>{{ method.description | markdownInline | safe }}</td>
<td>
{% if method.parameters.length %}
<code>
{% for param in method.parameters %}
{{ param.name }}: {{ param.type.text }}{% if not loop.last %},{% endif %}
{% endfor %}
</code>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#methods') }}">methods</a>.</em></p>
{% endif %}
{# Custom Properties #}
{% if component.cssProperties.length %}
<h2>Custom Properties</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
<th class="table-default">Default</th>
</tr>
</thead>
<tbody>
{% for cssProperty in component.cssProperties %}
<tr>
<td class="nowrap"><code>{{ cssProperty.name }}</code></td>
<td>{{ cssProperty.description | markdownInline | safe }}</td>
<td>{{ cssProperty.default }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/usage#custom-properties') }}">customizing CSS custom properties</a>.</em></p>
{% endif %}
{# CSS Parts #}
{% if component.cssParts.length %}
<h2>Parts</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for cssPart in component.cssParts %}
<tr>
<td class="nowrap"><code>{{ cssPart.name }}</code></td>
<td>{{ cssPart.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/customizing/#css-parts') }}">customizing CSS parts</a>.</em></p>
{% endif %}
{# Animations #}
{% if component.animations.length %}
<h2>Animations</h2>
<table>
<thead>
<tr>
<th class="table-name">Name</th>
<th class="table-description">Description</th>
</tr>
</thead>
<tbody>
{% for animation in component.animations %}
<tr>
<td class="nowrap"><code>{{ animation.name }}</code></td>
<td>{{ animation.description | markdownInline | safe }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><em>Learn more about <a href="{{ rootUrl('/getting-started/customizing#animations') }}">customizing animations</a>.</em></p>
{% endif %}
{# Dependencies #}
{% if component.dependencies.length %}
<h2>Dependencies</h2>
<p>This component automatically imports the following dependencies.</p>
<ul>
{% for dependency in component.dependencies %}
<li><code>&lt;{{ dependency }}&gt;</code></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

View File

@@ -1,129 +0,0 @@
<!DOCTYPE html>
<html
lang="en"
data-layout="{{ layout }}"
data-wa-version="{{ meta.version }}"
>
<head>
{# Metadata #}
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ meta.description }}" />
<title>{{ meta.title }}</title>
{# Opt out of Turbo caching #}
<meta name="turbo-cache-control">
{# Stylesheets #}
<link rel="stylesheet" href="{{ assetUrl('styles/docs.css') }}" />
<link rel="stylesheet" href="{{ assetUrl('styles/code-previews.css') }}" />
<link rel="stylesheet" href="{{ assetUrl('styles/search.css') }}" />
{# Favicons #}
<link rel="icon" href="{{ assetUrl('images/favicon.svg') }}" type="image/x-icon" />
{# Twitter Cards #}
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="shoelace_style" />
<meta name="twitter:image" content="{{ assetUrl(meta.image, true) }}" />
{# OpenGraph #}
<meta property="og:url" content="{{ rootUrl(page.url, true) }}" />
<meta property="og:title" content="{{ meta.title }}" />
<meta property="og:description" content="{{ meta.description }}" />
<meta property="og:image" content="{{ assetUrl(meta.image, true) }}" />
{# Web Awesome #}
<link rel="stylesheet" href="/dist/themes/applied.css" />
<link rel="stylesheet" href="/dist/themes/forms.css" />
<link id="theme-stylesheet" rel="stylesheet" href="/dist/themes/default.css" />
<script type="module" src="/dist/autoloader.js"></script>
{# Set the initial theme and menu states here to prevent flashing #}
<script>
(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = localStorage.getItem('theme') || 'auto';
document.documentElement.classList.toggle('wa-theme-default-dark', theme === 'dark' || (theme === 'auto' && prefersDark));
})();
</script>
{# Web Fonts #}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500;1,600&family=Noto+Sans+Mono&display=swap" rel="stylesheet">
{# Turbo + Scroll positioning #}
<script src="{{ assetUrl('scripts/turbo.js') }}" type="module"></script>
<script src="{{ assetUrl('scripts/docs.js') }}" defer></script>
<script src="{{ assetUrl('scripts/code-previews.js') }}" defer></script>
<script src="{{ assetUrl('scripts/lunr.js') }}" defer></script>
<script src="{{ assetUrl('scripts/search.js') }}" defer></script>
</head>
<body>
<a id="skip-to-main" class="wa-visually-hidden" href="#main-content" data-smooth-link="false">
Skip to main content
</a>
{# Menu toggle #}
<button id="menu-toggle" type="button" aria-label="Menu">
<svg width="148" height="148" viewBox="0 0 148 148" xmlns="http://www.w3.org/2000/svg">
<g stroke="currentColor" stroke-width="18" fill="none" fill-rule="evenodd" stroke-linecap="round">
<path d="M9.5 125.5h129M9.5 74.5h129M9.5 23.5h129"></path>
</g>
</svg>
</button>
<aside id="sidebar" data-preserve-scroll>
<header>
<a href="/">
{% include 'logo.njk' %}
</a>
<div class="sidebar-version">
{{ meta.version }}
</div>
</header>
<div class="sidebar-buttons">
<wa-button size="small" class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace" target="_blank">
<wa-icon slot="prefix" name="github"></wa-icon> Code
</wa-button>
<wa-button size="small" class="repo-button repo-button--star" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
<wa-icon slot="prefix" name="star-fill"></wa-icon> Star
</wa-button>
<wa-button size="small" class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
<wa-icon slot="prefix" name="twitter"></wa-icon> Follow
</wa-button>
</div>
<button class="search-box" type="button" title="Press / to search" aria-label="Search" data-plugin="search">
<wa-icon name="search"></wa-icon>
<span>Search</span>
</button>
<nav>
{% include 'sidebar.njk' %}
</nav>
</aside>
{# Content #}
<main>
<a id="main-content"></a>
<article id="content" class="content{% if toc %} content--with-toc{% endif %}">
{% if toc %}
<div class="content__toc">
<ul>
<li class="top"><a href="#">{{ meta.title }}</a></li>
</ul>
</div>
{% endif %}
<div class="content__body">
{% block content %}
{{ content | safe }}
{% endblock %}
</div>
</article>
</main>
</body>
</html>

View File

@@ -1,105 +0,0 @@
<!DOCTYPE html>
<html
lang="en"
data-layout="{{ layout }}"
data-shoelace-version="{{ meta.version }}"
>
<head>
<!--
JSPM Generator Import Map
Edit URL: https://generator.jspm.io/#jcs9DoMwDIbhDF16kW4kpFO7cYkeIASTGBmDEvNz+zaduhSJwdInvY9vF6Wub/ViQSHoVMQQqZzoITfW6qeuDWFr/JTgMJLjsLgA2ficT6jBrS77hLOcwPtIilCau37o+rdMhwm84FpIgr68/28LZ9dDFWWkQ7NF4G/coK38NM4TA0vVQY8MRdfa2g8tjhfiKAE
-->
<script type="importmap">
{
"imports": {
"highlight.js/lib/core": "https://ga.jspm.io/npm:highlight.js@11.9.0/es/core.js",
"highlight.js/lib/languages/css": "https://ga.jspm.io/npm:highlight.js@11.9.0/es/languages/css.js",
"highlight.js/lib/languages/javascript": "https://ga.jspm.io/npm:highlight.js@11.9.0/es/languages/javascript.js",
"highlight.js/lib/languages/xml": "https://ga.jspm.io/npm:highlight.js@11.9.0/es/languages/xml.js",
"lit": "https://ga.jspm.io/npm:lit@2.8.0/index.js",
"lit/directives/ref.js": "https://ga.jspm.io/npm:lit@2.8.0/directives/ref.js",
"lit/directives/unsafe-html.js": "https://ga.jspm.io/npm:lit@2.8.0/directives/unsafe-html.js",
"lit/directives/when.js": "https://ga.jspm.io/npm:lit@2.8.0/directives/when.js",
"web-component-define": "https://ga.jspm.io/npm:web-component-define@2.0.11/src/index.js"
},
"scopes": {
"https://ga.jspm.io/": {
"@lit/reactive-element": "https://ga.jspm.io/npm:@lit/reactive-element@1.6.3/reactive-element.js",
"@open-wc/dedupe-mixin": "https://ga.jspm.io/npm:@open-wc/dedupe-mixin@1.4.0/index.js",
"lit-element/lit-element.js": "https://ga.jspm.io/npm:lit-element@3.3.3/lit-element.js",
"lit-html": "https://ga.jspm.io/npm:lit-html@2.8.0/lit-html.js",
"lit-html/": "https://ga.jspm.io/npm:lit-html@2.8.0/"
}
}
}
</script>
<script async src="https://ga.jspm.io/npm:es-module-shims@1.8.0/dist/es-module-shims.js" crossorigin="anonymous"></script>
{# Metadata #}
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ meta.description }}" />
<title>{{ meta.title }}</title>
{# Opt out of Turbo caching #}
<meta name="turbo-cache-control" content="no-cache">
<meta name="turbo-cache-control" content="no-preview">
{# Favicons #}
<link rel="icon" href="{{ assetUrl('images/favicon.svg') }}" type="image/x-icon" />
{# Twitter Cards #}
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="shoelace_style" />
<meta name="twitter:image" content="{{ assetUrl(meta.image, true) }}" />
{# OpenGraph #}
<meta property="og:url" content="{{ rootUrl(page.url, true) }}" />
<meta property="og:title" content="{{ meta.title }}" />
<meta property="og:description" content="{{ meta.description }}" />
<meta property="og:image" content="{{ assetUrl(meta.image, true) }}" />
{# WebAwesome #}
<link rel="stylesheet" href="/dist/themes/default.css" />
<link rel="stylesheet" href="/dist/themes/applied.css" />
<script type="module" src="/dist/webawesome.js"></script>
{# Set the initial theme and menu states here to prevent flashing #}
<script>
(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = localStorage.getItem('theme') || 'auto';
document.documentElement.classList.toggle('wa-theme-dark', theme === 'dark' || (theme === 'auto' && prefersDark));
if (window.Turbo) {
window.Turbo.session.drive = false
}
})();
</script>
<style>
*, *:before, *:after {
box-sizing: border-box;
}
html, body {
height: 100%;
min-height: 100%;
}
body {
margin: 0;
}
[hidden] {
display: none !important;
}
</style>
</head>
<body>
{% block content %}
{{ content | safe }}
{% endblock %}
</body>
</html>

View File

@@ -1,72 +0,0 @@
html {
min-height: 100%;
height: auto;
}
body {
padding: 0;
height: auto;
}
.grid {
font-size: 1.35rem;
text-align: center;
display: grid;
place-content: center;
padding: 1rem;
}
header {
background-color: var(--wa-color-blue-90);
}
aside {
min-width: 250px;
max-width: 250px;
height: 100%;
}
main {
background-color: var(--wa-color-green-90);
height: 100%;
}
footer {
background-color: var(--wa-color-blue-80);
}
.banner {
background-color: var(--wa-color-yellow-90);
}
.header {
background-color: var(--wa-color-blue-90);
}
.banner, .header {
min-width: 100%;
height: 100%;
}
[slot=header] {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
}
[slot=aside] {
background-color: var(--wa-color-yellow-90);
}
[slot=menu] {
background-color: var(--wa-color-red-80);
}
[slot=main-header] {
background-color: var(--wa-color-red-90);
padding: 1rem;
}
[slot=main-footer] {
background-color: var(--wa-color-red-70);
}

View File

@@ -1,22 +0,0 @@
<wa-layout main-id="main-content" class="wa-theme-light">
<header slot="banner" class="grid banner">
Banner
</header>
<header slot="header" class="grid header">Header</header>
<aside class="grid" slot="menu">Menu</aside>
<header class="grid" slot="main-header">Inline header</header>
<main class="grid" id="main-content">
<div style="width: 20ch; margin: 0 auto; background-color: white;">Main</div>
</main>
<footer class="grid" slot="main-footer">Inline footer</footer>
<aside class="grid" slot="aside">Aside</aside>
<footer class="grid" slot="footer">Footer</footer>
</wa-layout>
{% include "layout-widget.njk" %}

View File

@@ -1,217 +0,0 @@
html {
min-height: 100%;
height: auto;
}
body {
padding: 0;
height: auto;
}
main {
min-height: 100%;
padding: 1rem 2rem;
}
/* Layout */
wa-layout {
background-color: var(--wa-color-neutral-95);
color: var(--wa-color-neutral-20);
}
wa-card :is(p, h3) {
margin: 0;
}
wa-layout::part(header) {
/** Because headers are sticky, this keeps text from leaking through. */
background-color: var(--wa-color-white);
}
wa-layout::part(drawer__panel) {
height: 100%;
}
wa-layout[view="mobile"] {
background-color: var(--wa-color-white);
--menu-width: 0px;
}
wa-layout[view="mobile"]::part(header) {
padding: 0.25rem;
border-bottom: 1px solid var(--wa-color-neutral-70);
}
wa-layout[view="mobile"]::part(navigation) {
display: none;
}
wa-layout[view="desktop"]::part(main) {
padding-top: 1rem;
}
wa-layout[view="desktop"] {
--menu-width: 250px;
}
wa-layout[view="desktop"]::part(navigation) {
padding-top: 1.9rem;
}
wa-layout[view="desktop"] > [slot="header"] {
display: none;
}
wa-layout[view="desktop"]::part(header) {
display: none;
}
wa-layout[view="desktop"] main {
background-color: var(--wa-color-white);
box-shadow: 0px 0px 3px 1px rgba(0,0,0,0.05);
border: 1px solid var(--wa-color-neutral-80);
border-top-left-radius: 8px;
}
/* Navigation / Lists */
/* Highlights */
.highlight {
font-size: 0.85em;
padding: 0.4em 0.6em;
border-radius: 6px;
display: inline-block;
}
.highlight--success {
background-color: var(--wa-color-success-fill-muted);
color: var(--wa-color-success-text-on-muted);
}
.highlight--danger {
background-color: var(--wa-color-red-90);
color: var(--wa-color-red-30);
}
/* Text */
.text--light {
color: var(--wa-color-neutral-40);
}
/* Cards */
.wa-card--muted::part(base) {
--border-color: transparent;
background-color: transparent;
display: grid;
height: 100%;
box-shadow: none;
}
.wa-card--muted::part(body) {
display: grid;
align-content: flex-end;
gap: var(--padding);
}
/* Buttons */
.wa-button--card {
--border-radius: 8px;
--padding: 1rem 0px;
}
.wa-button--card.wa-button--muted {
--background-color: var(--wa-color-neutral-95);
}
.wa-button--card::part(base) {
height: 100%;
border-radius: var(--border-radius);
padding: var(--padding);
}
.wa-button--card::part(label) {
width: 100%;
}
.wa-button--muted {
--text-color: var(--wa-color-neutral-30);
--text-color-active: var(--wa-color-neutral-30);
--background-color: transparent;
--background-color-active: var(--wa-color-neutral-90);
--border-color: transparent;
--border-color-active: var(--wa-color-neutral-80);
}
.wa-button--muted::part(base) {
background-color: var(--background-color);
color: var(--text-color);
border-color: var(--border-color);
}
.wa-button--muted:is(:focus-within)::part(base) {
background-color: var(--background-color);
color: var(--text-color-active);
border-color: var(--border-color-active);
}
.wa-button--muted:is(:hover)::part(base) {
background-color: var(--background-color-active);
color: var(--text-color-active);
border-color: var(--border-color-active);
}
.wa-button--logo::part(base) {
font-size: 1.5rem;
color: var(--wa-color-neutral-30);
}
.wa-button--square::part(base) {
border-radius: 0px;
}
.wa-button--stretch {
width: 100%;
}
.wa-button--stretch::part(label) {
flex: 1 1 auto;
}
.wa-button--nav-footer {
--border-color: var(--wa-color-neutral-70);
--wa-spacing-large: 8px;
}
wa-layout[view="desktop"] .wa-button--nav-footer::part(base) {
--border-color: transparent;
border-top-color: var(--wa-color-neutral-70);
}
/* Tables */
table {
max-width: 100%;
border: none;
border-collapse: collapse;
color: inherit;
}
table tr {
border-bottom: 1px solid var(--wa-color-neutral-70);
}
table th {
font-weight: var(--wa-font-weight-semibold);
text-align: left;
padding: 0.75rem 1rem;
}
table td {
line-height: var(--wa-line-height-normal);
padding: 1rem;
}
* > table {
max-width: 100%;
overflow-x: auto;
}

View File

@@ -1,438 +0,0 @@
<wa-layout main-id="main-content" class="wa-theme-light">
<header slot="header">
<wa-icon-button name="list" style="font-size: 1.5rem" data-toggle-nav></wa-icon>
</header>
<wa-button href="#" variant="text" style="padding: 0 0.4rem" class="wa-button--logo wa-button--stretch wa-button--muted" size="large" slot="navigation-header">
<wa-icon name="music-note" slot="prefix" style="font-size: 2rem;"></wa-icon>
Musicify
</wa-button>
<nav style="padding: 1rem;" slot="navigation">
<wa-nav-group style="height: 100%;">
<wa-nav-item href="#">
<wa-icon name="search" slot="prefix"></wa-icon>
Search
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="bell" slot="prefix"></wa-icon>
Notifications
</wa-nav-item>
<wa-divider></wa-divider>
<wa-nav-item href="#" current="page">
<wa-icon name="house-door" slot="prefix"></wa-icon>
Home
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="music-note-list" slot="prefix"></wa-icon>
Playlists
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="file-earmark-music" slot="prefix"></wa-icon>
Tracks
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="gear" slot="prefix"></wa-icon>
Settings
</wa-nav-item>
<wa-nav-item href="#" style="margin-top: auto;">
<wa-icon name="question-circle" slot="prefix"></wa-icon>
Help
</wa-nav-item>
</wa-nav-group>
</nav>
<!-- Hacky override to make padding 8px -->
<wa-button slot="navigation-footer" outline class="wa-button--square wa-button--stretch wa-button--muted wa-button--nav-footer" size="large" href="#">
<div style="display: grid; align-items: center; max-width: 100%; gap: 8px; grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);">
<wa-avatar shape="rounded" style="--size: 36px;"></wa-avatar>
<div style="text-overflow: ellipsis; max-width: 100%; overflow: hidden; text-align: start; font-size: 1rem;">Really really really long name</div>
<wa-icon name="chevron-right"></wa-icon>
</div>
</wa-button>
<main id="main-content" class="main">
<h1 style="margin: 0.5rem 0 2rem 0;">Good Evening, Konnor Rogers</h1>
<section>
<div style="display: flex; justify-content: space-between; flex-wrap: wrap; align-items: flex-end; gap: 8px;">
<h2 style="">Overview</h2>
<wa-select value="monthly">
<wa-option value="daily">Daily</wa-option>
<wa-option value="weekly">Weekly</wa-option>
<wa-option value="monthly">Monthly</wa-option>
<wa-option value="yearly">Yearly</wa-option>
</wa-select>
</div>
<wa-divider></wa-divider>
<div style="margin-top: 1rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); grid-auto-rows: 1fr; gap: var(--wa-spacing-large); text-align: center;">
<wa-card class="wa-card--muted" style="--padding: 8px;">
<h3 slot="header">Total listening time</h3>
<p>
<strong><wa-format-number value="35000"></wa-format-number></strong> minutes
</p>
<p>
<mark class="highlight highlight--success">
+16%
</mark>
<small class="text--light">from last month</small>
</p>
</wa-card>
<wa-card class="wa-card--muted" style="--padding: 8px;">
<h3 slot="header">Total songs played</h3>
<p>
<strong><wa-format-number value="302"></wa-format-number></strong> songs
</p>
<p>
<mark class="highlight highlight--danger">
-0.3%
</mark>
<small class="text--light">from last month</small>
</p>
</wa-card>
<wa-card class="wa-card--muted" style="--padding: 8px;">
<h3 slot="header">Average listening session</h3>
<p>
<strong><wa-format-number value="36"></wa-format-number></strong> minutes
</p>
<p>
<mark class="highlight highlight--success">
+11.4%
</mark>
<small class="text--light">from last month</small>
</p>
</wa-card>
<wa-card class="wa-card--muted" style="--padding: 8px;">
<h3 slot="header">Average track listening time</h3>
<p>
<strong><wa-format-number value="2"></wa-format-number></strong> minutes,
<strong><wa-format-number value="42"></wa-format-number></strong> seconds
</p>
<p>
<mark class="highlight highlight--success">
-6.2%
</mark>
<small class="text--light">from last month</small>
</p>
</wa-card>
</div>
</section>
<section style="margin-top: 3rem;">
<h2>Recent playlists</h2>
<div style="margin-top: 1rem; --card-width: clamp(200px, 100%, 350px); display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--card-width), 1fr)); gap: 16px;">
<wa-button variant="neutral" class="wa-button--card wa-button--muted" href="#">
<div style="display: flex; gap: 1rem;">
<img src="https://via.placeholder.com/100x100" height="100" width="100" style="align-self: center; border-radius: 8px; display: inline-block; max-width: 100%; flex: 0 1 auto;">
<article style="display: grid; align-content: center; color: var(--wa-color-neutral-700); grid-template-columns: minmax(0, 1fr); max-width: 100%; overflow: hidden; width: 100%;">
<h2 style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
Punk Rock Anthems
</h2>
<p style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
For when you just wanna rock out, have a good time, and feel angsty.
</p>
<wa-icon name="chevron-right" style="justify-self: flex-end;"></wa-icon>
</article>
</div>
</wa-button>
<wa-button variant="neutral" class="wa-button--card wa-button--muted" href="#">
<div style="display: flex; gap: 1rem;">
<img src="https://via.placeholder.com/100x100" height="100" width="100" style="align-self: center; border-radius: 8px; display: inline-block; max-width: 100%;">
<article style="display: grid; align-content: center; color: var(--wa-color-neutral-700); grid-template-columns: minmax(0, 1fr); max-width: 100%; overflow: hidden; width: 100%;">
<h2 style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
Random
</h2>
<p style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
Throw it on shuffle, and embrace the chaos.
</p>
<wa-icon name="chevron-right" style="justify-self: flex-end;"></wa-icon>
</article>
</div>
</wa-button>
<wa-button variant="neutral" class="wa-button--card wa-button--muted" href="#">
<div style="display: flex; gap: 1rem;">
<img src="https://via.placeholder.com/100x100" height="100" width="100" style="align-self: center; border-radius: 8px; display: inline-block;">
<article style="display: grid; align-content: center; color: var(--wa-color-neutral-700); grid-template-columns: minmax(0, 1fr); max-width: 100%; overflow: hidden; width: 100%;">
<h2 style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
Classics
</h2>
<p style="max-width: 100%; text-overflow: ellipsis; overflow: hidden;">
Timeless songs that you love to relive.
</p>
<wa-icon name="chevron-right" style="justify-self: flex-end;"></wa-icon>
</article>
</div>
</wa-button>
</div>
</section>
<section style="margin-top: 3rem;">
<h2>Recent tracks</h2>
<div style="margin-top: 1rem; max-width: 100%; overflow: auto;">
<table style="width: 100%; min-width: 500px; border-spacing: 2px;">
<thead>
<tr>
<th>
Release Date
</th>
<th>
Name
</th>
<th>
Album
</th>
<th>
Artist
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
<tr>
<td>
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
</td>
<td>
No Strangers to Love
</td>
<td>
You Know the Rules
</td>
<td>
Rick Barry
</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
</wa-layout>

View File

@@ -1,11 +0,0 @@
<wa-layout main-id="main-content" class="wa-theme-light">
<header class="grid" slot="header">Header</header>
<aside class="grid" slot="menu">Menu</aside>
<main class="grid" id="main-content">
Main
</main>
<aside class="grid" slot="aside">Aside</aside>
<footer class="grid" slot="footer">Footer</footer>
</wa-layout>
{% include "layout-widget.njk" %}

View File

@@ -1,10 +0,0 @@
html {
min-height: 100%;
height: auto;
}
body {
padding: 0;
height: auto;
}

View File

@@ -1,2 +0,0 @@
<wa-layout main-id="main-content" class="wa-theme-light">
</wa-layout>

View File

@@ -1,181 +0,0 @@
html {
min-height: 100%;
height: auto;
}
body {
padding: 0;
height: auto;
--wa-color-brand-fill-vivid: var(--wa-color-blue-20);
margin: 0 auto;
}
/** https://andy-bell.co.uk/my-favourite-3-lines-of-css/ */
.flow > * + * {
margin-block-start: var(--wa-flow-spacing);
}
img {
display: inline-block;
max-width: 100%;
height: auto;
}
.navigation--desktop::part(nav-items) {
gap: 2rem;
}
.navigation--top::part(nav-items) {
flex-direction: row;
}
.navigation--top wa-nav-item {
font-size: 1.4rem;
font-weight: bold;
}
.navigation--top wa-nav-item::part(content) {
text-align: center;
justify-content: center;
}
.navigation--top wa-nav-item {
--text-color: var(--wa-color-brand-text-on-vivid);
--text-color-hover: var(--wa-color-text-normal);
--background-color: transparent;
--background-color-hover: var(--wa-color-neutral-fill-muted-alt);
}
.header {
display: flex;
border-bottom: 1px solid var(--wa-color-brand-fill-vivid);
background-color: var(--wa-color-white);
}
.header > * {
padding-top: var(--wa-space-base);
padding-bottom: var(--wa-space-base);
}
.header__navigation {
display: flex;
clip-path: polygon(2rem 0,100% 0,100% 100%,0 100%);
padding-inline-start: 2.5rem;
padding-inline-end: var(--wa-space-base);
background-color: var(--wa-color-brand-fill-vivid);
width: 100%;
}
.header > .logo {
padding-inline-start: var(--wa-space-base);
/** Responsive font size for the top header to make it flow nicer */
font-size: clamp(1rem, 4vw, 1.4rem);
}
a.logo {
flex-shrink: 0;
font-size: 1.4rem;
font-weight: bold;
color: var(--wa-color-text-normal);
text-decoration: none;
margin: auto;
}
a.logo:is(:hover, :focus) {
text-decoration: underline;
}
.logo__accent {
color: var(--wa-color-yellow-70);
}
.navigation--desktop {
display: flex;
align-items: center;
width: 100%;
}
.navigation--desktop wa-nav-item[current="page"] {
text-decoration: underline;
text-underline-offset: 8px;
text-decoration-thickness: 4px;
text-decoration-color: var(--wa-color-red-50);
}
.navigation--extra {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
margin-inline-start: auto;
}
wa-layout[view="desktop"] [data-toggle-nav],
wa-layout[view="desktop"]::part(navigation) {
display: none;
}
wa-layout[view="mobile"] .navigation--desktop {
display: none;
}
.layout-banner {
padding: var(--wa-space-base);
text-align: center;
background-color: var(--wa-color-yellow-80);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(clamp(175px, 100%, 400px), 1fr));
gap: var(--wa-space-base);
grid-template-rows: 1fr;
align-items: start;
max-width: 100%;
}
.stats-grid table {
border-collapse: separate;
border-spacing: 0;
border-radius: 8px;
border: 1px solid var(--wa-color-surface-outline);
}
.table-scroll {
max-width: 100%;
overflow-x: auto;
}
.stats-grid table * {
font-variant-numeric: tabular-nums;
}
.stats-grid table th {
font-weight: bold;
text-align: center;
}
.stats-grid table td:nth-child(2) {
text-align: end;
}
.navigation--top.navigation--social::part(nav-items) {
justify-content: flex-end;
}
.navigation--social {
flex-grow: 1;
}
.navigation--top .social-link {
display: none;
}
@media screen and (min-width: 415px) {
.navigation--top .social-link {
display: flex;
}
}

View File

@@ -1,292 +0,0 @@
<wa-layout main-id="main-content" class="wa-theme-light" mobile-breakpoint="925" disable-sticky="banner">
<header class="layout-banner" slot="banner">
Reminder! Get your insurance paperwork in by Oct 12!
</header>
<header class="header" slot="header">
<a href="#" class="logo">
<span>Sport</span> <span class="logo__accent">Awesome</span>
</a>
<div class="header__navigation">
<wa-nav-group class="navigation navigation--top navigation--desktop">
<wa-nav-item href="#" current="page">Home</wa-nav-item>
<wa-nav-item href="#">Schedule</wa-nav-item>
<wa-nav-item href="#">Roster</wa-nav-item>
<wa-nav-item href="#">Stats</wa-nav-item>
<wa-nav-item href="#">Videos</wa-nav-item>
</wa-nav-group>
<wa-nav-group class="navigation navigation--top navigation--social">
<wa-nav-item class="social-link" href="#"><wa-icon name="instagram"></wa-icon></wa-nav-item>
<wa-nav-item class="social-link" href="#"><wa-icon name="facebook"></wa-icon></wa-nav-item>
<wa-nav-item data-toggle-nav href="#"><wa-icon name="list"></wa-icon></wa-nav-item>
</wa-nav-group>
</div>
</header>
<a href="#" class="logo" slot="navigation-header">
Sport <span class="logo__accent">Awesome</span>
</a>
<wa-nav-group slot="navigation">
<wa-nav-item href="#" current="page">
<wa-icon name="house-door" slot="prefix"></wa-icon>
Home
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="calendar" slot="prefix"></wa-icon>
Schedule
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="people" slot="prefix"></wa-icon>
Roster
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="graph-up-arrow" slot="prefix"></wa-icon>
Stats
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="camera-video" slot="prefix"></wa-icon>
Videos
</wa-nav-item>
<wa-divider></wa-divider>
<wa-nav-group>
<wa-nav-item href="#">
<wa-icon name="instagram" slot="prefix"></wa-icon>
Instagram
</wa-nav-item>
<wa-nav-item href="#">
<wa-icon name="facebook" slot="prefix"></wa-icon>
Facebook
</wa-nav-item>
</wa-nav-group>
</wa-nav-group>
<main id="main-content" class="flow" style="padding: var(--wa-space-base);">
<div style="display: flex; flex-wrap: wrap; gap: 16px;">
<img src="https://via.placeholder.com/1600x900" height="512" width="300" style="aspect-ratio: 16/9; min-width: 75%; flex-grow: 1;">
<aside style="display: flex; flex-direction: column; border-radius: var(--wa-corners-1x); flex-grow: 1; flex-shrink: 1;">
<header style="font-size: 1.4rem; font-weight: bold; color: var(--wa-color-brand-text-on-vivid); background-color: var(--wa-color-brand-fill-vivid); padding: var(--wa-space-base); text-align: center; border-top-left-radius: inherit; border-top-right-radius: inherit;">
Upcoming
</header>
<div style="color: var(--wa-color-brand-text-on-vivid); background-color: var(--wa-color-red-40); padding: 0.5rem; text-align: center; font-weight: bold;">
Tryouts!
</div>
<div style="background-color: var(--wa-color-neutral-90); padding: var(--wa-space-base); border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; text-align: center;">
<span style="font-weight: bold; font-size: 1.2rem;">Barclay's Center</span>
<br>
<time>Sat, Jul 3rd • 11:30am</time>
</div>
</aside>
</div>
<section>
<h1>Welcome to Sport <span class="logo__accent">Awesome</span></h1>
<p>
Dolor quam voluptate nostrum neque eius. Quo nemo corporis repellat quia sunt molestiae! Dolorem labore laudantium nobis numquam reprehenderit? Voluptatibus odio animi nemo maiores accusamus eaque Assumenda perferendis omnis quae.
Adipisicing beatae lorem nisi aliquid similique Voluptas doloremque pariatur tempore omnis maiores explicabo. Provident iste vel explicabo corporis quaerat! Necessitatibus minus quas iusto ducimus consequatur illo Cum eos adipisci ut!
</p>
</section>
<section>
<h2 style="text-align: center; font-weight: bold; font-size: 1.5em;">Stats</h2>
<div class="stats-grid">
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Serve
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Attempts</td>
<td>2936</td>
</tr>
<tr>
<td>Serve %</td>
<td>93.6%</td>
</tr>
<tr>
<td>Aces</td>
<td>268</td>
</tr>
<tr>
<td>Errors</td>
<td>189</td>
</tr>
</tbody>
</table>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Serve Receive
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Attempts</td>
<td>2428</td>
</tr>
<tr>
<td>Pass Rating</td>
<td>1.72</td>
</tr>
<tr>
<td>Pass Error %</td>
<td>13.3%</td>
</tr>
<tr>
<td>3-pass %</td>
<td>28.5%</td>
</tr>
</tbody>
</table>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Attack
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Attempts</td>
<td>3624</td>
</tr>
<tr>
<td>Kills</td>
<td>1431</td>
</tr>
<tr>
<td>Errors</td>
<td>268</td>
</tr>
<tr>
<td>Hitting Efficiency</td>
<td>0.254</td>
</tr>
<tr>
<td>Kill %</td>
<td>39.5%</td>
</tr>
</tbody>
</table>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Dig
</th>
</tr>
<tbody>
<tr>
<td>Attempts</td>
<td>3124</td>
</tr>
<tr>
<td>Digs</td>
<td>2235</td>
</tr>
<tr>
<td>Errors</td>
<td>889</td>
</tr>
<tr>
<td>Dig %</td>
<td>71.5%</td>
</tr>
</tbody>
</table>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Block
</th>
</tr>
<tbody>
<tr>
<td>Blocks</td>
<td>348</td>
</tr>
<tr>
<td>Errors</td>
<td>414</td>
</tr>
<tr>
<td>Block %</td>
<td>31.6%</td>
</tr>
<tr>
<td>Error %</td>
<td>24.6%</td>
</tr>
</tbody>
</table>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th colspan="2">
Set
</th>
</tr>
<tbody>
<tr>
<td>Assists</td>
<td>1364</td>
</tr>
<tr>
<td>Errors</td>
<td>81</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
<footer slot="main-footer" style="background-color: var(--wa-color-brand-fill-vivid); color: var(--wa-color-text-inverse); padding: var(--wa-space-base); text-align: center;">
© 2023 - Sport Awesome
</footer>
</wa-layout>

View File

@@ -1,31 +0,0 @@
<script type="module" src="/assets/scripts/light-pen/exports/index.js">
</script>
<light-pen style="height: 100%; padding: 8px;" resize-position="30" sandbox-settings="
allow-downloads
allow-forms
allow-modals
allow-orientation-lock
allow-pointer-lock
allow-popups
allow-presentation
allow-same-origin
allow-scripts
">
<script type="text/plain" slot="html">
{% include html_file %}
</script>
<script type="text/plain" slot="css">
@import "/dist/themes/default.css";
@import "/dist/themes/applied.css";
{% include css_file %}
</script>
<script type="text/plain" slot="js">
import { setBasePath } from "/dist/utilities/base-path.js";
setBasePath("/dist");
import("/dist/autoloader.js");
</script>
</light-pen>

View File

@@ -1,84 +0,0 @@
<ul>
<li>
<h2>Experimental</h2>
<ul>
<li><a href="/experimental/themer">Themer</a></li>
<li><a href="/experimental/style-guide">Style Guide</a></li>
<li><a href="/experimental/form-validation">Form Validation Styles</a></li>
<li style="margin-top: .5rem;"><wa-switch id="theme-toggle">Dark mode</wa-switch></li>
<script type="module">
// Temporary dark toggle
const toggle = document.getElementById('theme-toggle');
toggle.checked = document.documentElement.classList.contains('wa-theme-default-dark');
toggle.addEventListener('wa-change', () => {
document.documentElement.classList.toggle('wa-theme-default-dark');
localStorage.setItem('theme', toggle.checked ? 'dark' : 'light');
});
</script>
</ul>
</li>
<li>
<h2>Getting Started</h2>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/getting-started/installation">Installation</a></li>
<li><a href="/getting-started/usage">Usage</a></li>
<li><a href="/getting-started/themes">Themes</a></li>
<li><a href="/getting-started/customizing">Customizing</a></li>
<li><a href="/getting-started/form-controls">Form Controls</a></li>
<li><a href="/getting-started/localization">Localization</a></li>
</ul>
</li>
<li>
<h2>Frameworks</h2>
<ul>
<li><a href="/frameworks/react">React</a></li>
<li><a href="/frameworks/vue">Vue</a></li>
<li><a href="/frameworks/angular">Angular</a></li>
</ul>
</li>
<li>
<h2>Resources</h2>
<ul>
<li><a href="/resources/community">Community</a></li>
<li><a href="https://github.com/shoelace-style/shoelace/discussions">Help &amp; Support</a></li>
<li><a href="/resources/accessibility">Accessibility</a></li>
<li><a href="/resources/contributing">Contributing</a></li>
<li><a href="/resources/changelog">Changelog</a></li>
</ul>
</li>
<li>
<h2>Components</h2>
<ul>
{% for component in meta.components %}
<li>
<a href="/components/{{ component.tagName | removeWaPrefix }}">
{{ component.name | classNameToComponentName }}
</a>
</li>
{% endfor %}
</ul>
</li>
<li>
<h2>Design Tokens</h2>
<ul>
<li><a href="/tokens/typography">Typography</a></li>
<li><a href="/tokens/color">Color</a></li>
<li><a href="/tokens/spacing">Spacing</a></li>
<li><a href="/tokens/borders">Borders</a></li>
<li><a href="/tokens/shadows">Shadows</a></li>
<li><a href="/tokens/transition">Transition</a></li>
<li><a href="/tokens/z-index">Z-index</a></li>
<li><a href="/tokens/more">More Tokens</a></li>
</ul>
</li>
<li>
<h2>Tutorials</h2>
<ul>
<li><a href="/tutorials/integrating-with-laravel">Integrating with Laravel</a></li>
<li><a href="/tutorials/integrating-with-nextjs">Integrating with NextJS</a></li>
<li><a href="/tutorials/integrating-with-rails">Integrating with Rails</a></li>
</ul>
</li>
</ul>

View File

@@ -1,35 +0,0 @@
function normalizePathname(pathname) {
// Remove /index.html
if (pathname.endsWith('/index.html')) {
pathname = pathname.replace(/\/index\.html/, '');
}
// Remove trailing slashes
return pathname.replace(/\/$/, '');
}
/**
* Adds a class name to links that are currently active.
*/
module.exports = function (doc, options) {
options = {
className: 'active-link', // the class to add to active links
pathname: undefined, // the current pathname to compare
within: 'body', // element containing the target links
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('a').forEach(link => {
if (normalizePathname(options.pathname) === normalizePathname(link.pathname)) {
link.classList.add(options.className);
}
});
return doc;
};

View File

@@ -1,64 +0,0 @@
const { createSlug } = require('./strings.cjs');
/**
* Turns headings into clickable, deep linkable anchors. The provided doc should be a document object provided by JSDOM.
* The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
options = {
levels: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], // the headings to convert
className: 'anchor-heading', // the class name to add
within: 'body', // the element containing the target headings
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(heading => {
const hasAnchor = heading.querySelector('a');
const anchor = doc.createElement('a');
let id = heading.textContent ?? '';
let suffix = 0;
// Skip heading levels we don't care about
if (!options.levels?.includes(heading.tagName.toLowerCase())) {
return;
}
// Convert dots to underscores
id = id.replace(/\./g, '_');
// Turn it into a slug
id = createSlug(id);
// Make sure it starts with a letter
if (!/^[a-z]/i.test(id)) {
id = `id_${id}`;
}
// Make sure the id is unique
const originalId = id;
while (doc.getElementById(id) !== null) {
id = `${originalId}-${++suffix}`;
}
if (hasAnchor || !id) return;
heading.setAttribute('id', id);
anchor.setAttribute('href', `#${encodeURIComponent(id)}`);
anchor.setAttribute('aria-label', `Direct link to "${heading.textContent}"`);
if (options.className) {
heading.classList.add(options.className);
}
// Append the anchor
heading.append(anchor);
});
return doc;
};

View File

@@ -1,138 +0,0 @@
let count = 1;
function escapeHtml(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
/**
* Turns code fields with the :preview suffix into interactive code previews.
*/
module.exports = function (doc, options) {
options = {
within: 'body', // the element containing the code fields to convert
...options
};
const within = doc.querySelector(options.within);
if (!within) {
return doc;
}
within.querySelectorAll('[class*=":preview"]').forEach(code => {
const pre = code.closest('pre');
if (!pre) {
return;
}
const adjacentPre = pre.nextElementSibling?.tagName.toLowerCase() === 'pre' ? pre.nextElementSibling : null;
const reactCode = adjacentPre?.querySelector('code[class$="react"]');
const sourceGroupId = `code-preview-source-group-${count}`;
const isExpanded = code.getAttribute('class').includes(':expanded');
const noCodePen = code.getAttribute('class').includes(':no-codepen');
count++;
const htmlButton = `
<button type="button"
title="Show HTML code"
class="code-preview__button code-preview__button--html"
>
HTML
</button>
`;
const reactButton = `
<button type="button" title="Show React code" class="code-preview__button code-preview__button--react">
React
</button>
`;
const codePenButton = `
<button type="button" class="code-preview__button code-preview__button--codepen" title="Edit on CodePen">
<svg
width="138"
height="26"
viewBox="0 0 138 26"
fill="none"
stroke="currentColor"
stroke-width="2.3"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M80 6h-9v14h9 M114 6h-9 v14h9 M111 13h-6 M77 13h-6 M122 20V6l11 14V6 M22 16.7L33 24l11-7.3V9.3L33 2L22 9.3V16.7z M44 16.7L33 9.3l-11 7.4 M22 9.3l11 7.3 l11-7.3 M33 2v7.3 M33 16.7V24 M88 14h6c2.2 0 4-1.8 4-4s-1.8-4-4-4h-6v14 M15 8c-1.3-1.3-3-2-5-2c-4 0-7 3-7 7s3 7 7 7 c2 0 3.7-0.8 5-2 M64 13c0 4-3 7-7 7h-5V6h5C61 6 64 9 64 13z" />
</svg>
</button>
`;
const codePreview = `
<div class="code-preview ${isExpanded ? 'code-preview--expanded' : ''}">
<div class="code-preview__preview">
${code.textContent}
<div class="code-preview__resizer">
<wa-icon name="grip-vertical"></wa-icon>
</div>
</div>
<div class="code-preview__source-group" id="${sourceGroupId}">
<div class="code-preview__source code-preview__source--html" ${reactCode ? 'data-flavor="html"' : ''}>
<pre><code class="language-html">${escapeHtml(code.textContent)}</code></pre>
</div>
${
reactCode
? `
<div class="code-preview__source code-preview__source--react" data-flavor="react">
<pre><code class="language-jsx">${escapeHtml(reactCode.textContent)}</code></pre>
</div>
`
: ''
}
</div>
<div class="code-preview__buttons">
<button
type="button"
class="code-preview__button code-preview__toggle"
aria-expanded="${isExpanded ? 'true' : 'false'}"
aria-controls="${sourceGroupId}"
>
Source
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
${reactCode ? ` ${htmlButton} ${reactButton} ` : ''}
${noCodePen ? '' : codePenButton}
</div>
</div>
`;
pre.insertAdjacentHTML('afterend', codePreview);
pre.remove();
if (adjacentPre) {
adjacentPre.remove();
}
});
// Wrap code preview scripts in anonymous functions so they don't run in the global scope
doc.querySelectorAll('.code-preview__preview script').forEach(script => {
if (script.type === 'module') {
// Modules are already scoped
script.textContent = script.innerHTML;
} else {
// Wrap non-modules in an anonymous function so they don't run in the global scope
script.textContent = `(() => { ${script.innerHTML} })();`;
}
});
return doc;
};

View File

@@ -1,23 +0,0 @@
let codeBlockId = 0;
/**
* Adds copy code buttons to code fields. The provided doc should be a document object provided by JSDOM. The same
* document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc) {
doc.querySelectorAll('pre > code').forEach(code => {
const pre = code.closest('pre');
const button = doc.createElement('wa-copy-button');
if (!code.id) {
code.id = `code-block-${++codeBlockId}`;
}
button.classList.add('copy-code-button');
button.setAttribute('from', code.id);
pre.append(button);
});
return doc;
};

View File

@@ -1,41 +0,0 @@
const { isExternalLink } = require('./strings.cjs');
/**
* Transforms external links to make them safer and optionally add a target. The provided doc should be a document
* object provided by JSDOM. The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
options = {
className: 'external-link', // the class name to add to links
noopener: true, // sets rel="noopener"
noreferrer: true, // sets rel="noreferrer"
ignore: () => false, // callback function to filter links that should be ignored
within: 'body', // element that contains the target links
target: '', // sets the target attribute
...options
};
const within = doc.querySelector(options.within);
if (within) {
within.querySelectorAll('a').forEach(link => {
if (isExternalLink(link) && !options.ignore(link)) {
link.classList.add(options.className);
const rel = [];
if (options.noopener) rel.push('noopener');
if (options.noreferrer) rel.push('noreferrer');
if (rel.length) {
link.setAttribute('rel', rel.join(' '));
}
if (options.target) {
link.setAttribute('target', options.target);
}
}
});
}
return doc;
};

View File

@@ -1,63 +0,0 @@
const Prism = require('prismjs');
const PrismLoader = require('prismjs/components/index.js');
PrismLoader('diff');
PrismLoader.silent = true;
/** Highlights a code string. */
function highlight(code, language) {
const alias = language.replace(/^diff-/, '');
const isDiff = /^diff-/i.test(language);
// Auto-load the target language
if (!Prism.languages[alias]) {
PrismLoader(alias);
if (!Prism.languages[alias]) {
throw new Error(`Unsupported language for code highlighting: "${language}"`);
}
}
// Register diff-* languages to use the diff grammar
if (isDiff) {
Prism.languages[language] = Prism.languages.diff;
}
return Prism.highlight(code, Prism.languages[language], language);
}
/**
* Highlights all code fields that have a language parameter. If the language has a colon in its name, the first chunk
* will be the language used and additional chunks will be applied as classes to the `<pre>`. For example, a code field
* tagged with "html:preview" will be rendered as `<pre class="language-html preview">`.
*
* The provided doc should be a document object provided by JSDOM. The same document will be returned with the
* appropriate DOM manipulations.
*/
module.exports = function (doc) {
doc.querySelectorAll('pre > code[class]').forEach(code => {
// Look for class="language-*" and split colons into separate classes
code.classList.forEach(className => {
if (className.startsWith('language-')) {
//
// We use certain suffixes to indicate code previews, expanded states, etc. The class might look something like
// this:
//
// class="language-html:preview:expanded"
//
// The language will always come first, so we need to drop the "language-" prefix and everything after the first
// color to get the highlighter language.
//
const language = className.replace(/^language-/, '').split(':')[0];
try {
code.innerHTML = highlight(code.textContent ?? '', language);
} catch (err) {
// Language not found, skip it
}
}
});
});
return doc;
};

View File

@@ -1,75 +0,0 @@
const MarkdownIt = require('markdown-it');
const markdownItContainer = require('markdown-it-container');
const markdownItIns = require('markdown-it-ins');
const markdownItKbd = require('markdown-it-kbd');
const markdownItMark = require('markdown-it-mark');
const markdownItReplaceIt = require('markdown-it-replace-it');
const markdown = MarkdownIt({
html: true,
xhtmlOut: false,
breaks: false,
langPrefix: 'language-',
linkify: false,
typographer: false
});
// Third-party plugins
markdown.use(markdownItContainer);
markdown.use(markdownItIns);
markdown.use(markdownItKbd);
markdown.use(markdownItMark);
markdown.use(markdownItReplaceIt);
// Callouts
['tip', 'warning', 'danger'].forEach(type => {
const variant = type === 'tip' ? 'brand' : type;
let icon = 'info-circle';
if (type === 'warning') icon = 'exclamation-circle';
if (type === 'danger') icon = 'exclamation-triangle';
markdown.use(markdownItContainer, type, {
render: function (tokens, idx) {
if (tokens[idx].nesting === 1) {
return `
<wa-alert class="callout" variant="${variant}" open>
<wa-icon slot="icon" name="${icon}"></wa-icon>
`;
}
return '</wa-alert>\n';
}
});
});
// Asides
markdown.use(markdownItContainer, 'aside', {
render: function (tokens, idx) {
if (tokens[idx].nesting === 1) {
return `<aside>`;
}
return '</aside>\n';
}
});
// Details
markdown.use(markdownItContainer, 'details', {
validate: params => params.trim().match(/^details\s+(.*)$/),
render: (tokens, idx) => {
const m = tokens[idx].info.trim().match(/^details\s+(.*)$/);
if (tokens[idx].nesting === 1) {
return `<details>\n<summary><span>${markdown.utils.escapeHtml(m[1])}</span></summary>\n`;
}
return '</details>\n';
}
});
// Replace [#1234] with a link to GitHub issues
markdownItReplaceIt.replacements.push({
name: 'github-issues',
re: /\[#([0-9]+)\]/gs,
sub: '<a href="https://github.com/shoelace-style/shoelace/issues/$1">#$1</a>',
html: true,
default: true
});
module.exports = markdown;

View File

@@ -1,26 +0,0 @@
const { format } = require('prettier');
/** Formats markup using prettier. */
module.exports = function (content, options) {
options = {
arrowParens: 'avoid',
bracketSpacing: true,
htmlWhitespaceSensitivity: 'css',
insertPragma: false,
bracketSameLine: false,
jsxSingleQuote: false,
parser: 'html',
printWidth: 120,
proseWrap: 'preserve',
quoteProps: 'as-needed',
requirePragma: false,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
useTabs: false,
...options
};
return format(content, options);
};

View File

@@ -1,24 +0,0 @@
/**
* @typedef {object} Replacement
* @property {string | RegExp} pattern
* @property {string} replacement
*/
/**
* @typedef {Array<Replacement>} Replacements
*/
/**
* @param {Document} content
* @param {Replacements} replacements
*/
module.exports = function (content, replacements) {
/** This seems trivial, but by assigning to a string first, THEN using innerHTML after iterating over every replacement, we reduce the calculations of JSDOM. At the time of writing benchmarks show a reduction from 9seconds to 3 seconds by doing so. */
let html = content.body.innerHTML;
replacements.forEach(replacement => {
html = html.replaceAll(replacement.pattern, replacement.replacement);
});
content.body.innerHTML = html;
};

View File

@@ -1,26 +0,0 @@
/**
* Turns tables into scrollable tables
* The same document will be returned with the appropriate DOM manipulations.
*/
module.exports = function (doc, options) {
// We don't want to run this on layouts.
if (doc.querySelector("[data-layout='layout-example.njk']")) {
return;
}
const tables = [...doc.querySelectorAll('table')];
options = {
className: 'table-scroll', // the class name to add to the table's container
...options
};
tables.forEach(table => {
const div = doc.createElement('div');
div.classList.add(options.className);
table.insertAdjacentElement('beforebegin', div);
div.append(table);
});
return doc;
};

View File

@@ -1,16 +0,0 @@
const slugify = require('slugify');
/** Creates a slug from an arbitrary string of text. */
module.exports.createSlug = function (text) {
return slugify(String(text), {
remove: /[^\w|\s]/g,
lower: true
});
};
/** Determines whether or not a link is external. */
module.exports.isExternalLink = function (link) {
// We use the "internal" hostname when initializing JSDOM so we know that those are local links
if (!link.hostname || link.hostname === 'internal') return false;
return true;
};

View File

@@ -1,42 +0,0 @@
/**
* Generates an in-page table of contents based on headings.
*/
module.exports = function (doc, options) {
options = {
levels: ['h2'], // headings to include (they must have an id)
container: 'nav', // the container to append links to
listItem: true, // if true, links will be wrapped in <li>
within: 'body', // the element containing the headings to summarize
...options
};
const container = doc.querySelector(options.container);
const within = doc.querySelector(options.within);
const headingSelector = options.levels.map(h => `${h}[id]`).join(', ');
if (!container || !within) {
return doc;
}
within.querySelectorAll(headingSelector).forEach(heading => {
const listItem = doc.createElement('li');
const link = doc.createElement('a');
const level = heading.tagName.slice(1);
link.href = `#${heading.id}`;
link.textContent = heading.textContent;
if (options.listItem) {
// List item + link
listItem.setAttribute('data-level', level);
listItem.append(link);
container.append(listItem);
} else {
// Link only
link.setAttribute('data-level', level);
container.append(link);
}
});
return doc;
};

View File

@@ -1,23 +0,0 @@
const smartquotes = require('smartquotes');
smartquotes.replacements.push([/---/g, '\u2014']); // em dash
smartquotes.replacements.push([/--/g, '\u2013']); // en dash
smartquotes.replacements.push([/\.\.\./g, '\u2026']); // ellipsis
smartquotes.replacements.push([/\(c\)/gi, '\u00A9']); // copyright
smartquotes.replacements.push([/\(r\)/gi, '\u00AE']); // registered trademark
smartquotes.replacements.push([/\?!/g, '\u2048']); // ?!
smartquotes.replacements.push([/!!/g, '\u203C']); // !!
smartquotes.replacements.push([/\?\?/g, '\u2047']); // ??
smartquotes.replacements.push([/([0-9]\s?)-(\s?[0-9])/g, '$1\u2013$2']); // number ranges use en dash
/**
* Improves typography by adding smart quotes and similar corrections within the specified element(s).
*
* The provided doc should be a document object provided by JSDOM. The same document will be returned with the
* appropriate DOM manipulations.
*/
module.exports = function (doc, selector = 'body') {
const elements = [...doc.querySelectorAll(selector)];
elements.forEach(el => smartquotes.element(el));
return doc;
};

View File

@@ -1,210 +0,0 @@
//
// Sidebar
//
// When the sidebar is hidden, we apply the inert attribute to prevent focus from reaching it. Due to the many states
// the sidebar can have (e.g. static, hidden, expanded), we test for visibility by checking to see if it's placed
// offscreen or not. Then, on resize/transition we make sure to update the attribute accordingly.
//
(() => {
function getSidebar() {
return document.getElementById('sidebar');
}
function isSidebarOpen() {
return document.documentElement.classList.contains('sidebar-open');
}
function isSidebarVisible() {
return getSidebar()?.getBoundingClientRect().x >= 0;
}
function toggleSidebar(force) {
const isOpen = typeof force === 'boolean' ? force : !isSidebarOpen();
return document.documentElement.classList.toggle('sidebar-open', isOpen);
}
function updateInert() {
const sidebar = getSidebar();
if (sidebar) {
sidebar.inert = !isSidebarVisible();
}
}
// Toggle the menu
document.addEventListener('click', event => {
const menuToggle = event.target.closest('#menu-toggle');
if (!menuToggle) return;
toggleSidebar();
});
// Update the sidebar's inert state when the window resizes and when the sidebar transitions
window.addEventListener('resize', () => toggleSidebar(false));
document.addEventListener('transitionend', event => {
const sidebar = event.target.closest('#sidebar');
if (!sidebar) return;
updateInert();
});
// Close when a menu item is selected on mobile
document.addEventListener('click', event => {
const sidebar = event.target.closest('#sidebar');
const link = event.target.closest('a');
if (!sidebar || !link) return;
if (isSidebarOpen()) {
toggleSidebar();
}
});
// Close when open and escape is pressed
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && isSidebarOpen()) {
event.stopImmediatePropagation();
toggleSidebar();
}
});
// Close when clicking outside of the sidebar
document.addEventListener('mousedown', event => {
if (isSidebarOpen() & !event.target?.closest('#sidebar, #menu-toggle')) {
event.stopImmediatePropagation();
toggleSidebar();
}
});
updateInert();
})();
//
// Open details when printing
//
(() => {
const detailsOpenOnPrint = new Set();
window.addEventListener('beforeprint', () => {
detailsOpenOnPrint.clear();
document.querySelectorAll('details').forEach(details => {
if (details.open) {
detailsOpenOnPrint.add(details);
}
details.open = true;
});
});
window.addEventListener('afterprint', () => {
document.querySelectorAll('details').forEach(details => {
details.open = detailsOpenOnPrint.has(details);
});
detailsOpenOnPrint.clear();
});
})();
//
// Smooth links
//
(() => {
document.addEventListener('click', event => {
const link = event.target.closest('a');
const id = (link?.hash ?? '').substr(1);
const isFragment = link?.hasAttribute('href') && link?.getAttribute('href').startsWith('#');
if (!link || !isFragment || link.getAttribute('data-smooth-link') === 'false') {
return;
}
// Scroll to the top
if (link.hash === '') {
event.preventDefault();
window.scroll({ top: 0, behavior: 'smooth' });
history.pushState(undefined, undefined, location.pathname);
}
// Scroll to an id
if (id) {
const target = document.getElementById(id);
if (target) {
event.preventDefault();
window.scroll({ top: target.offsetTop, behavior: 'smooth' });
history.pushState(undefined, undefined, `#${id}`);
}
}
});
})();
//
// Table of Contents scrollspy
//
(() => {
// This will be stale if its not a function.
const getLinks = () => [...document.querySelectorAll('.content__toc a')];
const linkTargets = new WeakMap();
const visibleTargets = new WeakSet();
const observer = new IntersectionObserver(handleIntersect, { rootMargin: '0px 0px' });
let debounce;
function handleIntersect(entries) {
entries.forEach(entry => {
// Remember which targets are visible
if (entry.isIntersecting) {
visibleTargets.add(entry.target);
} else {
visibleTargets.delete(entry.target);
}
});
updateActiveLinks();
}
function updateActiveLinks() {
const links = getLinks();
// Find the first visible target and activate the respective link
links.find(link => {
const target = linkTargets.get(link);
if (target && visibleTargets.has(target)) {
links.forEach(el => el.classList.toggle('active', el === link));
return true;
}
return false;
});
}
// Observe link targets
function observeLinks() {
getLinks().forEach(link => {
const hash = link.hash.slice(1);
const target = hash ? document.querySelector(`.content__body #${hash}`) : null;
if (target) {
linkTargets.set(link, target);
observer.observe(target);
}
});
}
observeLinks();
document.addEventListener('turbo:load', updateActiveLinks);
document.addEventListener('turbo:load', observeLinks);
})();
//
// Show custom versions in the sidebar
//
(() => {
function updateVersion() {
const el = document.querySelector('.sidebar-version');
if (!el) return;
if (location.hostname === 'next.shoelace.style') el.textContent = 'Next';
if (location.hostname === 'localhost') el.textContent = 'Development';
}
updateVersion();
document.addEventListener('turbo:load', updateVersion);
})();

View File

@@ -1,11 +0,0 @@
## 1.1.0
- A number of fixes including allowing `<template>` elements to be slotted into `<light-pen>` and `<light-preview>`
## 1.0.2
- fix: issues with `&gt;` and `&lt;`
## 1.0.1
- fix: allow any HTML Element for templating

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Konnor Rogers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,96 +0,0 @@
# Light(weight) Code(pen)
## Demo
<https://konnorrogers.github.io/light-pen>
## Purpose
A small lightweight editor using `<pre><code></code></pre>` and a `<textarea>`
Inspired by Chris Ferdinandi
## Install
```
npm install light-pen
```
## Getting started
```js
// Auto-register <light-pen>
import "light-pen"
// Registry yourself
import LightPen "light-pen/exports/light-pen.js"
LightPen.define() // Registers `<light-pen>`
// Register under another name
import LightPen "light-pen/exports/light-pen.js"
LightPen.define("other-name")
```
## Usage
```html
<light-pen></light-pen>
```
That's it!
### Slotting in HTML / CSS / JS
```html
<light-pen>
<script type="text/plain" slot="html">
<div style="color: red;">
<div>Hi there friends</div>
</div>
<p>
Sup dude
</p>
</script>
<script type="text/plain" slot="css">
p {
color: green;
}
</script>
<script type="text/plain" slot="js">
console.log("Hi")
</script>
</light-pen>
```
### Changing the title
```html
<light-pen>
<div slot="title">My Awesome Editor</div>
</light-pen>
```
### Opening languages by default
`<light-pen>` Takes a string of comma separated languages to open on initial render.
```
<light-pen open-languages="html,css,js">
</light-pen>
```
More to come for more docs coming on how to change things!
## Roadmap
- [ ] - Implement an extendable `LightPenBase` which includes a pluggable syntax highlighter and theme.
- [ ] - Implement `<textarea>` rendering hooks to add CodeMirror for more robuste setups.
- [ ] - Add vertical resizing of `<textarea>`
- [ ] - More documentation around customization.
- [ ] - Add a console logger
>>>>>>> 7b592c8f5f05ed82d439d7950450eec06dc3ab66

View File

@@ -1,44 +0,0 @@
// @ts-check
// import { expandTypesPlugin } from './expand-types.js'
const globs = ['exports/**/*.{d.ts,js}', 'internal/**/*.{d.ts,js}', 'types/**/*.d.ts']
export default {
/** Globs to analyze */
globs,
/** Globs to exclude */
exclude: ['node_modules', 'docs'],
/** Directory to output CEM to */
outdir: '.',
/** Run in dev mode, provides extra logging */
dev: process.argv.includes("--verbose"),
/** Run in watch mode, runs on file changes */
watch: process.argv.includes("--watch"),
/** Include third party custom elements manifests */
dependencies: true,
/** Output CEM path to `package.json`, defaults to true */
packagejson: true,
/** Enable special handling for litelement */
litelement: true,
/** Enable special handling for catalyst */
catalyst: false,
/** Enable special handling for fast */
fast: false,
/** Enable special handling for stencil */
stencil: false,
// overrideModuleCreation: ({ts, globs}) => {
// const program = ts.createProgram(globs, {target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.ESNext, allowJs: true, checkJs: true});
//
// // If we dont do this, everything blows up.
// program.getTypeChecker()
//
// return program.getSourceFiles().filter(sf => globs.find(glob => {
// return sf.fileName.includes(glob)
// }))
// },
// /** Provide custom plugins */
// plugins: [
// /** You can now pass the typeChecker to your plugins */
// expandTypesPlugin({ globs })
// ],
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +0,0 @@
# Bridgetown
output
.bridgetown-cache
.bridgetown-metadata
.bridgetown-webpack
# Dependency folders
node_modules
bower_components
vendor
# Caches
.sass-cache
.npm
.node_repl_history
# Ignore bundler config.
/.bundle
# Ignore Byebug command history file.
.byebug_history
# dotenv environment variables file
.env
# Mac files
.DS_Store
# Yarn
yarn-error.log
yarn-debug.log*
.pnp/
.pnp.js
# Yarn Integrity file
.yarn-integrity
src/bridgetown
src/meta.json

View File

@@ -1 +0,0 @@
ruby-3.0.4

View File

@@ -1,49 +0,0 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
####
# Welcome to your project's Gemfile, used by Rubygems & Bundler.
#
# To install a plugin, run:
#
# bundle add new-plugin-name -g bridgetown_plugins
#
# This will ensure the plugin is added to the correct Bundler group.
#
# When you run Bridgetown commands, we recommend using a binstub like so:
#
# bin/bridgetown start (or console, etc.)
#
# This will help ensure the proper Bridgetown version is running.
####
# If you need to upgrade/switch Bridgetown versions, change the line below
# and then run `bundle update bridgetown`
gem "bridgetown", "~> 1.3"
# Uncomment to add file-based dynamic routing to your project:
# gem "bridgetown-routes", "~> 1.3"
# Uncomment to use the Inspectors API to manipulate the output
# of your HTML or XML resources:
gem "nokogiri", "~> 1.13"
# Puma is a Rack-compatible server used by Bridgetown
# (you can optionally limit this to the "development" group)
gem "puma", "~> 5.6"
gem "bridgetown-quick-search", "~> 2.0"
# gem "asset_mapper", "~> 1.0"
gem "asset_mapper", "~> 1.0"
# gem "rack-cors", "~> 2.0"
gem "rack-cors", "~> 2.0"
gem "custom_elements_manifest_parser", "~> 0.2.4"
gem "ruby-lsp", "~> 0.11.1", :group => :development, require: false
gem "yard", "~> 0.9.34", :group => :development
gem "solargraph", "~> 0.49.0", :group => :development
gem "debug", "~> 1.8", :group => :development

View File

@@ -1,241 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
activemodel (7.0.8)
activesupport (= 7.0.8)
activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
amazing_print (1.5.0)
asset_mapper (1.0.1)
dry-configurable (~> 1.0)
dry-files (~> 1.0)
dry-initializer (~> 3.0)
dry-types (~> 1.5)
rake (>= 10)
zeitwerk (~> 2.5)
ast (2.4.2)
backport (1.2.0)
base64 (0.1.1)
benchmark (0.2.1)
bridgetown (1.3.1)
bridgetown-builder (= 1.3.1)
bridgetown-core (= 1.3.1)
bridgetown-paginate (= 1.3.1)
bridgetown-builder (1.3.1)
bridgetown-core (= 1.3.1)
bridgetown-core (1.3.1)
activemodel (>= 6.0, < 8.0)
activesupport (>= 6.0, < 8.0)
addressable (~> 2.4)
amazing_print (~> 1.2)
colorator (~> 1.0)
erubi (~> 1.9)
faraday (~> 2.0)
faraday-follow_redirects (~> 0.3)
hash_with_dot_access (~> 1.2)
i18n (~> 1.0)
kramdown (~> 2.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 5.0)
listen (~> 3.0)
rake (>= 13.0)
roda (~> 3.46)
rouge (~> 3.0)
serbea (~> 1.0)
thor (~> 1.1)
tilt (~> 2.0)
zeitwerk (~> 2.5)
bridgetown-paginate (1.3.1)
bridgetown-core (= 1.3.1)
bridgetown-quick-search (2.0.0)
bridgetown (>= 1.2.0.beta2, < 2.0)
colorator (1.1.0)
concurrent-ruby (1.2.2)
custom_elements_manifest_parser (0.2.4)
dry-struct (~> 1.0)
dry-types (~> 1.0)
dry-validation (~> 1.0)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
diff-lcs (1.5.0)
dry-configurable (1.1.0)
dry-core (~> 1.0, < 2)
zeitwerk (~> 2.6)
dry-core (1.0.1)
concurrent-ruby (~> 1.0)
zeitwerk (~> 2.6)
dry-files (1.0.1)
dry-inflector (1.0.0)
dry-initializer (3.1.1)
dry-logic (1.5.0)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0, < 2)
zeitwerk (~> 2.6)
dry-schema (1.13.3)
concurrent-ruby (~> 1.0)
dry-configurable (~> 1.0, >= 1.0.1)
dry-core (~> 1.0, < 2)
dry-initializer (~> 3.0)
dry-logic (>= 1.4, < 2)
dry-types (>= 1.7, < 2)
zeitwerk (~> 2.6)
dry-struct (1.6.0)
dry-core (~> 1.0, < 2)
dry-types (>= 1.7, < 2)
ice_nine (~> 0.11)
zeitwerk (~> 2.6)
dry-types (1.7.1)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0)
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
dry-validation (1.10.0)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0, < 2)
dry-initializer (~> 3.0)
dry-schema (>= 1.12, < 2)
zeitwerk (~> 2.6)
e2mmap (0.1.0)
erubi (1.12.0)
faraday (2.7.11)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-follow_redirects (0.3.0)
faraday (>= 1, < 3)
faraday-net_http (3.0.2)
ffi (1.15.5)
hash_with_dot_access (1.2.0)
activesupport (>= 5.0.0, < 8.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
io-console (0.6.0)
irb (1.8.1)
rdoc
reline (>= 0.3.8)
jaro_winkler (1.5.6)
json (2.6.3)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
language_server-protocol (3.17.0.3)
liquid (5.4.0)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
minitest (5.20.0)
nio4r (2.5.8)
nokogiri (1.13.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.9-x86_64-linux)
racc (~> 1.4)
parallel (1.23.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
psych (5.1.0)
stringio
public_suffix (5.0.3)
puma (5.6.5)
nio4r (~> 2.0)
racc (1.6.0)
rack (3.0.8)
rack-cors (2.0.1)
rack (>= 2.0.0)
rainbow (3.1.1)
rake (13.0.6)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rbs (2.8.4)
rdoc (6.5.0)
psych (>= 4.0.0)
regexp_parser (2.8.1)
reline (0.3.9)
io-console (~> 0.5)
reverse_markdown (2.1.1)
nokogiri
rexml (3.2.6)
roda (3.72.0)
rack
rouge (3.30.0)
rubocop (1.56.4)
base64 (~> 0.1.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
ruby-lsp (0.11.1)
language_server-protocol (~> 3.17.0)
sorbet-runtime (>= 0.5.5685)
yarp (>= 0.12, < 0.13)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
serbea (1.0.1)
activesupport (>= 6.0)
erubi (>= 1.10)
tilt (~> 2.0)
solargraph (0.49.0)
backport (~> 1.2)
benchmark
bundler (~> 2.0)
diff-lcs (~> 1.4)
e2mmap
jaro_winkler (~> 1.5)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.1)
parser (~> 3.0)
rbs (~> 2.0)
reverse_markdown (~> 2.0)
rubocop (~> 1.38)
thor (~> 1.0)
tilt (~> 2.0)
yard (~> 0.9, >= 0.9.24)
sorbet-runtime (0.5.11064)
stringio (3.0.8)
thor (1.2.2)
tilt (2.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
yard (0.9.34)
yarp (0.12.0)
zeitwerk (2.6.12)
PLATFORMS
arm64-darwin-21
arm64-darwin-22
x86_64-linux
DEPENDENCIES
asset_mapper (~> 1.0)
bridgetown (~> 1.3)
bridgetown-quick-search (~> 2.0)
custom_elements_manifest_parser (~> 0.2.4)
debug (~> 1.8)
nokogiri (~> 1.13)
puma (~> 5.6)
rack-cors (~> 2.0)
ruby-lsp (~> 0.11.1)
solargraph (~> 0.49.0)
yard (~> 0.9.34)
BUNDLED WITH
2.3.5

View File

@@ -1,2 +0,0 @@
bridgetown: bin/bridgetown start --skip-frontend
esbuild: pnpm run esbuild-dev

View File

@@ -1,70 +0,0 @@
# Bridgetown Website README
Welcome to your new Bridgetown website! You can update this README file to provide additional context and setup information for yourself or other contributors.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Install](#install)
- [Development](#development)
- [Commands](#commands)
- [Deployment](#deployment)
- [Contributing](#contributing)
## Prerequisites
- [GCC](https://gcc.gnu.org/install/)
- [Make](https://www.gnu.org/software/make/)
- [Ruby](https://www.ruby-lang.org/en/downloads/)
- `>= 2.7`
- [Bridgetown Gem](https://rubygems.org/gems/bridgetown)
- `gem install bridgetown -N`
- [Node](https://nodejs.org)
- `>= 12`
- [Yarn](https://yarnpkg.com)
## Install
```sh
cd bridgetown-site-folder
bundle install && yarn install
```
> Learn more: [Bridgetown Getting Started Documentation](https://www.bridgetownrb.com/docs/).
## Development
To start your site in development mode, run `bin/bridgetown start` and navigate to [localhost:4000](https://localhost:4000/)!
Use a [theme](https://github.com/topics/bridgetown-theme) or add some [plugins](https://www.bridgetownrb.com/plugins/) to get started quickly.
### Commands
```sh
# running locally
bin/bridgetown start
# build & deploy to production
bin/bridgetown deploy
# load the site up within a Ruby console (IRB)
bin/bridgetown console
```
> Learn more: [Bridgetown CLI Documentation](https://www.bridgetownrb.com/docs/command-line-usage)
## Deployment
You can deploy Bridgetown sites on hosts like Render or Vercel as well as traditional web servers by simply building and copying the output folder to your HTML root.
> Read the [Bridgetown Deployment Documentation](https://www.bridgetownrb.com/docs/deployment) for more information.
## Contributing
If repo is on GitHub:
1. Fork it
2. Clone the fork using `git clone` to your local development machine.
3. Create your feature branch (`git checkout -b my-new-feature`)
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Push to the branch (`git push origin my-new-feature`)
6. Create a new Pull Request

View File

@@ -1,49 +0,0 @@
require "bridgetown"
Bridgetown.load_tasks
# Run rake without specifying any command to execute a deploy build by default.
task default: :deploy
#
# Standard set of tasks, which you can customize if you wish:
#
desc "Build the Bridgetown site for deployment"
task :deploy => [:clean, "frontend:build"] do
Bridgetown::Commands::Build.start
end
desc "Build the site in a test environment"
task :test do
ENV["BRIDGETOWN_ENV"] = "test"
Bridgetown::Commands::Build.start
end
desc "Runs the clean command"
task :clean do
Bridgetown::Commands::Clean.start
end
namespace :frontend do
desc "Build the frontend with esbuild for deployment"
task :build do
sh "yarn run esbuild"
end
desc "Watch the frontend with esbuild during development"
task :dev do
sh "yarn run esbuild-dev"
rescue Interrupt
end
end
#
# Add your own Rake tasks here! You can use `environment` as a prerequisite
# in order to write automations or other commands requiring a loaded site.
#
# task :my_task => :environment do
# puts site.root_dir
# automation do
# say_status :rake, "I'm a Rake tast =) #{site.config.url}"
# end
# end

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'bridgetown' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("bridgetown-core", "bridgetown")

View File

@@ -1,27 +0,0 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'bridgetown' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("bridgetown-core", "bridgetown")

View File

@@ -1,48 +0,0 @@
baseurl: "" # OPTIONAL: the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site, e.g. https://example.com
destination: output
development:
url: "localhost:4000"
# production:
# url: "https://konnorrogers.github.io"
# base_path: "/light-pen"
template_engine: erb
permalink: pretty
collections:
documentation:
output: true
defaults:
- scope:
path: "images"
values:
image: true
- scope:
path: "_documentation"
values:
layout: doc
permalink: /:categories/:slug
category_order: 0
doc_order: 0
- scope:
path: "_documentation/guides"
values:
category: guides
category_order: 10
- scope:
path: "_documentation/components"
values:
category: components
category_order: 20
- scope:
path: "_documentation/references"
values:
category: references
category_order: 30

View File

@@ -1,16 +0,0 @@
# This file is used by Rack-based servers during the Bridgetown boot process.
require "bridgetown-core/rack/boot"
Bridgetown::Rack.boot
require "rack/cors"
use Rack::Cors do
allow do
origins '*'
resource '/*', headers: :any, methods: :get
end
end
run RodaApp.freeze.app # see server/roda_app.rb

View File

@@ -1,310 +0,0 @@
// This file is created and managed by Bridgetown.
// Instead of editing this file, add your overrides to `esbuild.config.js`
//
// To update this file to the latest version provided by Bridgetown,
// run `bridgetown esbuild update`. Any changes to this file will be overwritten
// when an update is applied hence we strongly recommend adding overrides to
// `esbuild.config.js` instead of editing this file.
//
// Shipped with Bridgetown v1.1.0
const path = require("path")
const fsLib = require("fs")
const fs = fsLib.promises
const { pathToFileURL, fileURLToPath } = require("url")
const glob = require("glob")
const postcss = require("postcss")
const postCssImport = require("postcss-import")
const readCache = require("read-cache")
// Detect if an NPM package is available
const moduleAvailable = name => {
try {
require.resolve(name)
return true
} catch (e) { }
return false
}
// Generate a Source Map URL (used by the Sass plugin)
const generateSourceMappingURL = sourceMap => {
const data = Buffer.from(JSON.stringify(sourceMap), "utf-8").toString("base64")
return `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${data} */`
}
// Import Sass if available
let sass
if (moduleAvailable("sass")) {
sass = require("sass")
}
// Glob plugin derived from:
// https://github.com/thomaschaaf/esbuild-plugin-import-glob
// https://github.com/xiaohui-zhangxh/jsbundling-rails/commit/b15025dcc20f664b2b0eb238915991afdbc7cb58
const importGlobPlugin = () => ({
name: "import-glob",
setup: (build) => {
build.onResolve({ filter: /\*/ }, async (args) => {
if (args.resolveDir === "") {
return; // Ignore unresolvable paths
}
const adjustedPath = args.path.replace(/^bridgetownComponents\//, "../../src/_components/")
return {
path: adjustedPath,
namespace: "import-glob",
pluginData: {
path: adjustedPath,
resolveDir: args.resolveDir,
},
}
})
build.onLoad({ filter: /.*/, namespace: "import-glob" }, async (args) => {
const files = glob.sync(args.pluginData.path, {
cwd: args.pluginData.resolveDir,
}).sort()
const importerCode = `
${files
.map((module, index) => `import * as module${index} from '${module}'`)
.join(';')}
const modules = {${files
.map((module, index) => `
"${module.replace("../../src/_components/", "")}": module${index},`)
.join("")}
};
export default modules;
`
return { contents: importerCode, resolveDir: args.pluginData.resolveDir }
})
},
})
// Plugin for PostCSS
const postCssPlugin = (options, configuration) => ({
name: "postcss",
async setup(build) {
// Process .css files with PostCSS
build.onLoad({ filter: (configuration.filter || /\.css$/) }, async (args) => {
const additionalFilePaths = []
const css = await fs.readFile(args.path, "utf8")
// Configure import plugin so PostCSS can properly resolve `@import`ed CSS files
const importPlugin = postCssImport({
filter: itemPath => !itemPath.startsWith("/"), // ensure it doesn't try to import source-relative paths
load: async filename => {
let contents = await readCache(filename, "utf-8")
const filedir = path.dirname(filename)
// We'll want to track any imports later when in watch mode:
additionalFilePaths.push(filename)
// We need to transform `url(...)` in imported CSS so the filepaths are properly
// relative to the entrypoint. Seems icky to have to hack this! C'est la vie...
contents = contents.replace(/url\(['"]?\.\/(.*?)['"]?\)/g, (_match, p1) => {
const relpath = path.relative(args.path, path.resolve(filedir, p1)).replace(/^\.\.\//, "")
return `url("${relpath}")`
})
return contents
}
})
// Process the file through PostCSS
const result = await postcss([importPlugin, ...options.plugins]).process(css, {
map: true,
...options.options,
from: args.path,
});
return {
contents: result.css,
loader: "css",
watchFiles: [args.path, ...additionalFilePaths],
}
})
},
})
// Plugin for Sass
const sassPlugin = (options) => ({
name: "sass",
async setup(build) {
// Process .scss and .sass files with Sass
build.onLoad({ filter: /\.(sass|scss)$/ }, async (args) => {
if (!sass) {
console.error("error: Sass is not installed. Try running `yarn add sass` and then building again.")
return
}
const modulesFolder = pathToFileURL("node_modules/")
const localOptions = {
importers: [{
// An importer that redirects relative URLs starting with "~" to
// `node_modules`.
findFileUrl(url) {
if (!url.startsWith('~')) return null
return new URL(url.substring(1), modulesFolder)
}
}],
sourceMap: true,
...options
}
const result = sass.compile(args.path, localOptions)
const watchPaths = result.loadedUrls
.filter((x) => x.protocol === "file:" && !x.pathname.startsWith(modulesFolder.pathname))
.map((x) => x.pathname)
let cssOutput = result.css.toString()
if (result.sourceMap) {
const basedir = process.cwd()
const sourceMap = result.sourceMap
const promises = sourceMap.sources.map(async source => {
const sourceFile = await fs.readFile(fileURLToPath(source), "utf8")
return sourceFile
})
sourceMap.sourcesContent = await Promise.all(promises)
sourceMap.sources = sourceMap.sources.map(source => {
return path.relative(basedir, fileURLToPath(source))
})
cssOutput += '\n' + generateSourceMappingURL(sourceMap)
}
return {
contents: cssOutput,
loader: "css",
watchFiles: [args.path, ...watchPaths],
}
})
},
})
// Set up defaults and generate frontend bundling manifest file
const bridgetownPreset = (outputFolder) => ({
name: "bridgetownPreset",
async setup(build) {
// Ensure any imports anywhere starting with `/` are left verbatim
// so they can be used in-browser for actual `src` repo files
build.onResolve({ filter: /^\// }, args => {
return { path: args.path, external: true }
})
build.onStart(() => {
console.log("esbuild: frontend bundling started...")
})
// Generate the final output manifest
build.onEnd(async (result) => {
if (!result.metafile) {
console.warn("esbuild: build process error, cannot write manifest")
return
}
await fs.writeFile(path.join(outputFolder, 'meta.json'), JSON.stringify(result.metafile), { encoding: "utf8" })
const manifest = {}
const entrypoints = []
// We don't need `frontend/` cluttering up everything
// const stripPrefix = (str) => str.replace(/^frontend\//, "")
// For calculating the file size of bundle output
const fileSize = (path) => {
const { size } = fsLib.statSync(path)
const i = Math.floor(Math.log(size) / Math.log(1024))
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ['B', 'KB', 'MB', 'GB', 'TB'][i]
}
// Let's loop through all the various outputs
// for (const key in result.metafile.outputs) {
// const value = result.metafile.outputs[key]
// const inputs = Object.keys(value.inputs)
// const pathShortener = new RegExp(`^${outputFolder}\\/_bridgetown\\/static\\/`, "g")
// const outputPath = key.replace(pathShortener, "")
// if (value.entryPoint) {
// // We have an entrypoint!
// manifest[stripPrefix(value.entryPoint)] = outputPath
// entrypoints.push([outputPath, fileSize(key)])
// } else if (key.match(/index(\.js)?\.[^-.]*\.css/) && inputs.find(item => item.match(/\.(s?css|sass)$/))) {
// // Special treatment for index.css
// manifest[stripPrefix(inputs.find(item => item.match(/\.(s?css|sass)$/)))] = outputPath
// entrypoints.push([outputPath, fileSize(key)])
// } else if (inputs.length > 0) {
// // Naive implementation, we'll just grab the first input and hope it's accurate
// manifest[stripPrefix(inputs[0])] = outputPath
// }
// }
// const manifestFolder = path.join(process.cwd(), ".bridgetown-cache", "frontend-bundling")
// await fs.mkdir(manifestFolder, { recursive: true })
// await fs.writeFile(path.join(manifestFolder, "manifest.json"), JSON.stringify(manifest))
console.log("esbuild: frontend bundling complete!")
console.log("esbuild: entrypoints processed:")
entrypoints.forEach(entrypoint => {
const [entrypointName, entrypointSize] = entrypoint
console.log(` - ${entrypointName}: ${entrypointSize}`)
})
})
}
})
// Load the PostCSS config from postcss.config.js or whatever else is a supported location/format
const postcssrc = require("postcss-load-config")
const postCssConfig = postcssrc.sync()
module.exports = async (outputFolder, esbuildOptions) => {
esbuildOptions.plugins = esbuildOptions.plugins || []
// Add the PostCSS & glob plugins to the top of the plugin stack
esbuildOptions.plugins.unshift(postCssPlugin(postCssConfig, esbuildOptions.postCssPluginConfig || {}))
if (esbuildOptions.postCssPluginConfig) delete esbuildOptions.postCssPluginConfig
esbuildOptions.plugins.unshift(importGlobPlugin())
// Add the Sass plugin
esbuildOptions.plugins.push(sassPlugin(esbuildOptions.sassOptions || {}))
// Add the Bridgetown preset
esbuildOptions.plugins.push(bridgetownPreset(outputFolder))
// esbuild, take it away!
const esbuild = require("esbuild")
const watch = process.argv.includes("--watch")
const config = {
bundle: true,
loader: {
".jpg": "file",
".png": "file",
".gif": "file",
".svg": "file",
".woff": "file",
".woff2": "file",
".ttf": "file",
".eot": "file",
},
resolveExtensions: [".tsx", ".ts", ".jsx", ".js", ".css", ".scss", ".sass", ".json", ".js.rb"],
nodePaths: ["frontend/javascript", "frontend/styles"],
minify: process.argv.includes("--minify"),
sourcemap: true,
target: "es2016",
entryPoints: ["frontend/javascript/index.js"],
entryNames: "[dir]/[name].[hash]",
outdir: path.join(process.cwd(), `${outputFolder}/bridgetown/static`),
publicPath: "/bridgetown/static",
metafile: true,
...esbuildOptions,
}
if (watch) {
const context = await esbuild.context(config).catch(() => process.exit(1))
await context.watch().catch(() => process.exit(1))
} else {
await esbuild.build(config).catch(() => process.exit(1))
}
}

View File

@@ -1,20 +0,0 @@
Bridgetown.configure do |config|
config.url = ENV.fetch("URL", "https://konnorrogers.github.io")
config.base_path = ENV.fetch("BASE_PATH", "/light-pen")
config.base_url = config.url + config.base_path
init :"bridgetown-quick-search"
# init :ssr
# init :"bridgetown-routes"
# only :server do
# roda do |app|
# app.plugin :default_headers,
# 'Content-Type'=>'text/html',
# 'Strict-Transport-Security'=>'max-age=16070400;',
# 'X-Content-Type-Options'=>'nosniff',
# 'X-Frame-Options'=>'deny',
# 'X-XSS-Protection'=>'1; mode=block',
# 'Access-Control-Allow-Origin'=>'*'
# end
# end
end

View File

@@ -1,27 +0,0 @@
# Puma is a fast, concurrent web server for Ruby & Rack
#
# Learn more at: https://puma.io
#
port ENV.fetch("BRIDGETOWN_PORT") { 4000 }
# You can adjust the number of workers (separate processes) and threads
# (per process) based on your production system
#
if ENV["BRIDGETOWN_ENV"] == "production"
workers ENV.fetch("BRIDGETOWN_CONCURRENCY") { 4 }
end
max_threads_count = ENV.fetch("BRIDGETOWN_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("BRIDGETOWN_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
# Preload the application for maximum performance
#
preload_app!
# Use the Bridgetown logger format
#
require "bridgetown-core/rack/logger"
log_formatter do |msg|
Bridgetown::Rack::Logger.message_with_prefix msg
end

View File

@@ -1,57 +0,0 @@
// @ts-check
const { spawn } = require("child_process");
// const glob = require("glob")
const build = require("./config/esbuild.defaults.js")
const AssetMapper = require("asset-mapper-esbuild").default
// Update this if you need to configure a destination folder other than `output`
const outputFolder = "src"
// You can customize this as you wish, perhaps to add new esbuild plugins.
//
// ```
const path = require("path")
const esbuildCopy = require('esbuild-plugin-copy').default
// const esbuildOptions = {
// }
// ```
//
// You can also support custom base_path deployments via changing `publicPath`.
//
// ```
// const esbuildOptions = { publicPath: "/my_subfolder/_bridgetown/static" }
// ```
const watch = process.argv.includes("--watch")
const esbuildOptions = {
target: "es2020",
entryPoints: {
"javascript/index": "frontend/javascript/index.js",
"javascript/defer": "frontend/javascript/defer.js",
"light-pen/exports/light-pen": "../exports/light-pen.js",
"light-pen/exports/light-preview": "../exports/light-preview.js",
},
define: {
"process.env.BASE_PATH": `"${process.env.BASE_PATH}"`
},
publicPath: path.join(process.env.BASE_PATH, "bridgetown", "static"),
outdir: path.join(process.cwd(), outputFolder, "bridgetown", "static"),
splitting: true,
format: "esm",
plugins: [
esbuildCopy({
assets: {
from: [path.resolve(__dirname, 'node_modules/@shoelace-style/shoelace/dist/assets/icons/**/*.svg')],
to: [path.resolve(__dirname, 'src/shoelace-assets/assets/icons')],
},
verbose: false
}),
AssetMapper({
manifestFile: path.join(process.cwd(), ".bridgetown-cache", "asset-mapper-manifest.json"),
// outputRoot: path.join(process.cwd(), process.env.BASE_PATH)
}),
]
}
build(outputFolder, esbuildOptions)

View File

@@ -1,21 +0,0 @@
// @ts-check
import { Controller } from "@hotwired/stimulus"
export default class ClipboardController extends Controller {
connect () {
this.element.addEventListener("clipboard-copy", this.showSuccess)
}
showSuccess = () => {
this.element.classList.add("clipboard--success")
this.element.classList.remove("clipboard--idle")
if (this.timeout) {
clearTimeout(this.timeout)
}
this.timeout = setTimeout(() => {
this.element.classList.remove("clipboard--success")
this.element.classList.add("clipboard--idle")
}, 2_000)
}
}

View File

@@ -1,6 +0,0 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
// console.log("Hello, Stimulus!", this.element)
}
}

View File

@@ -1,72 +0,0 @@
import { Controller } from "@hotwired/stimulus"
export default class ScrollSpyController extends Controller {
connect () {
this.observer = new IntersectionObserver(this.handleIntersect, { rootMargin: '0px 0px' });
this.linkMap = new WeakMap();
this.visibleSet = new WeakSet();
this.observeLinks()
this.updateActiveLinks()
this.selector = ["1","2","3","4","5","6"].map((str) => "h" + str + "[id]").join(",")
document.querySelectorAll(this.selector).forEach((header) => {
this.observer.observe(header);
});
document.addEventListener("turbo:load", this.observeLinks)
document.addEventListener("turbo:load", this.updateActiveLinks)
this.observeLinks()
this.updateActiveLinks()
}
disconnect () {
this.observer.disconnect()
}
get links () {
return [...document.querySelectorAll('#table-of-contents li a')];
}
handleIntersect = (entries) => {
entries.forEach(entry => {
// Remember which targets are visible
if (entry.isIntersecting) {
this.visibleSet.add(entry.target);
} else {
this.visibleSet.delete(entry.target);
}
});
this.updateActiveLinks();
}
updateActiveLinks = () => {
const links = this.links;
// Find the first visible target and activate the respective link
links.find(link => {
const target = this.linkMap.get(link);
if (target && this.visibleSet.has(target)) {
links.forEach(el => el.parentElement.classList.toggle('is-active', el === link));
return true;
}
return false;
});
}
observeLinks = () => {
this.links.forEach(link => {
const hash = link.hash.slice(1);
const target = hash ? document.querySelector(`main #${hash}`) : null;
if (target) {
this.linkMap.set(link, target);
this.observer.observe(target);
}
});
}
}

View File

@@ -1,6 +0,0 @@
import { Controller } from "@hotwired/stimulus"
export default class SearchController extends Controller {
show () {
document.querySelector("bridgetown-ninja-keys").open()
}
}

View File

@@ -1,39 +0,0 @@
import { Controller } from "@hotwired/stimulus"
export default class SideNavController extends Controller {
async open() {
document.addEventListener("sl-hide", this.reset)
this.drawer.removeAttribute("hidden")
this.scrollTop = window.scrollY;
document.body.classList.add('fixed-body');
// Scroll the wrapper, rather than setting an offset
// via `top` or `transform`.
document.body.scroll(0, this.scrollTop);
await this.drawer.show()
}
reset = () => {
window.scrollTo(0, this.scrollTop);
document.body.classList.remove('fixed-body');
}
async close () {
document.removeEventListener("sl-hide", this.reset)
this.reset()
await this.drawer.hide()
}
async toggle() {
if (this.drawer.open) {
await this.open()
} else {
await this.close()
}
}
get drawer() {
return document.querySelector("#side-nav-drawer")
}
}

View File

@@ -1,58 +0,0 @@
import { Controller } from "@hotwired/stimulus"
export default class ThemeSwitcher extends Controller {
constructor (...args) {
super(...args)
this.handleSelect = (e) => {
window.applyTheme(e.detail.item.value)
}
this.handleShortcut = (event) => {
if (
event.key === '\\' &&
!event.composedPath().some(el => {
return (
['input', 'textarea'].includes(el?.tagName?.toLowerCase()) ||
el.hasAttribute?.("contenteditable") ||
el.getAttribute?.("role") === "textbox"
)
})
) {
event.preventDefault();
window.applyTheme(window.themeIsDark() ? 'light' : 'dark');
}
}
this.setLight = () => {
window.applyTheme("light")
}
this.setDark = () => {
window.applyTheme("dark")
}
// Set the initial theme and sync the UI
window.applyTheme(window.getTheme());
}
connect () {
this.element.addEventListener("sl-select", this.handleSelect)
document.addEventListener("keydown", this.handleShortcut)
// Update the theme when the preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this.setDark);
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', this.setLight);
// Set the initial theme and sync the UI
window.applyTheme(window.getTheme());
}
disconnect () {
this.element.removeEventListener("sl-select", this.handleSelect)
document.removeEventListener("keydown", this.handleShortcut)
}
}

View File

@@ -1,87 +0,0 @@
import "../styles/defer.css"
import { BridgetownNinjaKeys } from "@konnorr/bridgetown-quick-search/ninja-keys.js"
;(window.requestIdleCallback || window.setTimeout)(async () => {
// const { BridgetownNinjaKeys } = await import("@konnorr/bridgetown-quick-search/ninja-keys.js")
/** @type {import("konnors-ninja-keys").INinjaAction[]} */
const staticData = [
{
id: "theme-light",
icon: "<sl-icon name='sun'></sl-icon>",
title: "Light Mode",
section: "Theme",
keywords: "theme",
handler () {
window.applyTheme("light");
return {keepOpen: true}
}
},
{
id: "theme-dark",
icon: "<sl-icon name='moon'></sl-icon>",
title: "Dark Mode",
section: "Theme",
keywords: "theme",
handler () {
window.applyTheme("dark");
return {keepOpen: true}
}
},
{
id: "theme-system",
icon: "<sl-icon name='display'></sl-icon>",
title: "System",
section: "Theme",
keywords: "theme",
handler () {
window.applyTheme("system");
return {keepOpen: true}
}
},
]
;(class extends BridgetownNinjaKeys {
constructor (...args) {
super(...args)
this.staticData = staticData
}
createData() {
this.results = this.showResultsForQuery(this._search || "*").reverse()
this.results.forEach((result) => {
result.icon = `<sl-icon name="link-45deg"></sl-icon>`
})
return [
...this.staticData,
...this.results,
]
}
open () {
this.scrollTop = window.scrollY;
document.body.classList.add('fixed-body');
// Scroll the wrapper, rather than setting an offset
// via `top` or `transform`.
document.body.scroll(0, this.scrollTop);
this.nonModals.forEach((el) => {
el.setAttribute("inert", "")
})
super.open()
}
close () {
document.body.classList.remove('fixed-body');
window.scrollTo(0, this.scrollTop);
super.close()
this.nonModals.forEach((el) => el.removeAttribute("inert"))
}
get nonModals () {
return [...document.body.children].filter((el) => el.localName !== "bridgetown-ninja-keys")
}
}).define("bridgetown-ninja-keys")
})

View File

@@ -1,61 +0,0 @@
import "../styles/index.css"
import { Application } from "@hotwired/stimulus"
// Shoelace
import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js";
import LazyLoader from "./src/lazy-loader.js"
import * as Turbo from "@hotwired/turbo"
window.Turbo = Turbo
import "./src/layout.js"
//
LazyLoader()
//
setBasePath(process.env.BASE_PATH + "/shoelace-assets")
// Import all JavaScript & CSS files from src/_components
import components from "bridgetownComponents/**/*.{js,jsx,js.rb,css}"
window.Stimulus = Application.start()
import controllers from "./controllers/**/*.{js,js.rb}"
Object.entries(controllers).forEach(([filename, controller]) => {
if (filename.includes("_controller.") || filename.includes("-controller.")) {
const identifier = filename.replace("./controllers/", "")
.replace(/[_-]controller..*$/, "")
.replace("_", "-")
.replace("/", "--")
Stimulus.register(identifier, controller.default)
}
})
;(() => {
if (!window.scrollPositions) {
window.scrollPositions = {};
}
function preserveScroll() {
document.querySelectorAll('[data-preserve-scroll').forEach(element => {
scrollPositions[element.id] = element.scrollTop;
});
}
function restoreScroll(event) {
if (event.detail && event.detail.newBody) {
event.detail.newBody.querySelectorAll('[data-preserve-scroll]').forEach(element => {
element.scrollTop = scrollPositions[element.id];
});
}
document.querySelectorAll('[data-preserve-scroll').forEach(element => {
element.scrollTop = scrollPositions[element.id];
});
}
window.addEventListener('turbo:before-cache', preserveScroll);
window.addEventListener('turbo:before-render', restoreScroll);
window.addEventListener('turbo:render', restoreScroll);
})();

View File

@@ -1,10 +0,0 @@
class ExternalIcon extends HTMLElement {
connectedCallback () {
this.attachShadow({ mode: "open" })
this.shadowRoot.innerHTML = `<sl-icon name="box-arrow-up-right"></sl-icon><sl-visually-hidden>Opens in new window</sl-visually-hidden>`
}
}
if (!window.customElements.get("external-icon")) {
window.customElements.define("external-icon", ExternalIcon)
}

View File

@@ -1,211 +0,0 @@
import {LitElement, html, css} from "lit"
class KrLayout extends LitElement {
static styles = css`
:host {
display: block;
box-sizing: border-box;
min-height: var(--height);
--height: 100vh;
--height: 100dvh;
--menu-width: auto;
--main-width: 1fr;
--aside-width: auto;
/** This is a best guess. We'll attempt to calculate this with a resize observer. **/
--header-height: 68.33px;
}
:host([variant="documentation"]) {
--menu-width: 250px;
--main-width: 105ch;
--aside-width: auto;
}
:host([variant="documentation"])::part(body) {
justify-content: center;
}
*, *:after, *:before {
box-sizing: border-box;;
}
[part~="base"] {
display: grid;
/** Header, Main, Footer **/
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
min-height: var(--height);
}
[part~="header"] {
max-width: 100%;
position: sticky;
background: white;
z-index: 2;
}
:is(.header, .aside, .menu, .footer) ::slotted(*) {
height: 100%;
}
:is(.aside, .menu) ::slotted(*) {
min-width: 100%;
width: 100%;
max-width: 100%;
}
[part~="header"] {
top: 0px;
}
[part~="body"] {
display: grid;
/** Menu, Main, Aside **/
grid-template-columns: minmax(0, var(--menu-width)) minmax(0, var(--main-width)) minmax(0, var(--aside-width));
grid-template-rows: minmax(0, 1fr);
}
[part~="aside"],
[part~="menu"] {
display: grid;
grid-template-columns: minmax(0, 1fr);
max-height: calc(var(--height) - var(--header-height));
overflow: auto;
position: sticky;
top: var(--header-height);
overscroll-behavior: contain;
}
[part~="main"] {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr);
/* main-header, main, main-footer */
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
}
[part~="footer"] {}
sl-visually-hidden:not(:focus-within) {
position: absolute !important;
width: 1px !important;
height: 1px !important;
clip: rect(0 0 0 0) !important;
clip-path: inset(50%) !important;
border: none !important;
overflow: hidden !important;
white-space: nowrap !important;
padding: 0 !important;
}
.skip-links {
position: absolute;
top: 0;
left: 0;
height: calc(var(--header-height, 48px) - 2px);
width: 100vw;
z-index: 4;
background-color: inherit;
display: grid;
grid-template-columns: minmax(0, 1fr);
place-items: center;
text-align: center;
}
`
static properties = {
main_id: { attribute: "main-id", reflect: true }
}
constructor () {
super()
this.main_id = "main"
}
createResizeObserver (slot) {
return new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.contentBoxSize) {
const contentBoxSize = entry.borderBoxSize[0];
this.style.setProperty(`--${slot}-height`, `${contentBoxSize.blockSize}px`)
}
}
})
}
connectedCallback () {
super.connectedCallback?.()
this.headerResizeObserver = this.createResizeObserver("header");
this.footerResizeObserver = this.createResizeObserver("footer");
setTimeout(() => {
this.header = this.shadowRoot.querySelector("[part~='header']")
this.headerResizeObserver.observe(this.header)
// this.footer = this.shadowRoot.querySelector("[part~='main-footer']")
// this.footerResizeObserver.observe(this.footer)
})
}
disconnectedCallback () {
super.disconnectedCallback?.()
this.headerResizeObserver.unobserve(this.header)
// this.footerResizeObserver.unobserve(this.footer)
}
render () {
return html`
<sl-visually-hidden class="skip-links" part="skip-links">
<slot name="skip-links">
<a href=${`#${this.main_id}`} part="skip-link">
${this.skipToMain || "Skip to main"}
</a>
</slot>
</sl-visually-hidden>
<div class="base" part="base">
<div class="header" part="header">
<slot name="header"></slot>
</div>
<div class="body" part="body">
<div class="menu" part="menu">
<slot name="menu"></slot>
</div>
<div class="main" part="main">
<div class="main-header" part="main-header">
<slot name="main-header"></slot>
</div>
<div class="main-content" part="main-content"><slot></slot></div>
<div class="main-footer" part="main-footer">
<slot name="main-footer"></slot>
</div>
</div>
<div class="aside" part="aside">
<slot name="aside"></slot>
</div>
</div>
<div class="footer" part="footer">
<slot name="footer"></slot>
</div>
</div>
<div part="dialog" class="dialog">
<slot name="dialog"></slot>
</div>
`
}
}
if (!window.customElements.get("kr-layout")) {
window.customElements.define("kr-layout", KrLayout)
}

View File

@@ -1,101 +0,0 @@
import LazyLoader from "web-component-lazy-loader";
export default function lazyLoader() {
return new LazyLoader({
components: {
"light-pen": {
register () {
import("light-pen/exports/light-pen-register.js")
}
},
"light-preview": {
register () {
import("light-pen/exports/light-preview-register.js")
}
},
"clipboard-copy": {
register() {
import("@github/clipboard-copy-element");
},
},
"external-icon": {
register() {
import("./external-icon.js");
},
},
// Shoelace
"sl-alert": {
register() {
import("@shoelace-style/shoelace/dist/components/alert/alert.js");
},
},
// "sl-breadcrumb": {
// register () { import("@shoelace-style/shoelace/dist/components/breadcrumb/breadcrumb.js"); }
// },
// "sl-breadcrumb-item": {
// register () { import("@shoelace-style/shoelace/dist/components/breadcrumb-item/breadcrumb-item.js"); }
// },
"sl-button": {
register() {
import("@shoelace-style/shoelace/dist/components/button/button.js");
},
},
"sl-divider": {
register() {
import("@shoelace-style/shoelace/dist/components/divider/divider.js");
},
},
"sl-drawer": {
register() {
import("@shoelace-style/shoelace/dist/components/drawer/drawer.js");
},
},
"sl-dropdown": {
register() {
import(
"@shoelace-style/shoelace/dist/components/dropdown/dropdown.js"
);
},
},
"sl-icon": {
register() {
import("@shoelace-style/shoelace/dist/components/icon/icon.js");
},
},
"sl-icon-button": {
register() {
import(
"@shoelace-style/shoelace/dist/components/icon-button/icon-button.js"
);
},
},
"sl-menu": {
register() {
import("@shoelace-style/shoelace/dist/components/menu/menu.js");
},
},
"sl-menu-item": {
register() {
import(
"@shoelace-style/shoelace/dist/components/menu-item/menu-item.js"
);
},
},
"sl-menu-label": {
register() {
import(
"@shoelace-style/shoelace/dist/components/menu-label/menu-label.js"
);
},
},
"sl-visually-hidden": {
register() {
import(
"@shoelace-style/shoelace/dist/components/visually-hidden/visually-hidden.js"
);
},
},
},
}).start();
}

View File

@@ -1,24 +0,0 @@
@import "./components/_alert.css";
@import "./components/_aspect_ratio.css";
@import "./components/_blog.css";
@import "./components/_button.css";
@import "./components/_call_to_action.css";
@import "./components/_clipboard.css";
@import "./components/_contact.css";
@import "./components/_footer.css";
@import "./components/_header.css";
@import "./components/_hero.css";
@import "./components/_input.css";
@import "./components/_layout.css";
@import "./components/_list.css";
@import "./components/_link.css";
@import "./components/_logo.css";
@import "./components/_main_list.css";
@import "./components/_pagination.css";
@import "./components/_side_nav.css";
@import "./components/_syntax_block.css";
@import "./components/_table_of_contents.css";
@import "./components/_text.css";
@import "./components/_theme_switcher.css";
@import "./components/_top_nav.css";
@import "./components/_tables.css";

View File

@@ -1,42 +0,0 @@
/** For for prose sections, blogging concerns, Markdown, etc. */
/** Pretty syntax blocks */
pre.highlight {
padding: 0.85rem 1rem;
margin: 0;
overflow-x: auto;
}
code
.highlighter-rouge,
.highlight {
border-radius: 8px;
font-size: 0.85rem;
line-height: 1.4;
font-family: var(--sl-font-mono);
}
code,
.highlight,
.highlighter-rouge {
position: relative;
}
/* Inline code blocks */
code,
code.highlight,
code.highlighter-rouge {
/** Layout */
display: inline-block;
font-size: 0.85em;
padding: 0.1em 0.4em;
margin: 4px 0;
border-radius: 6px;
white-space: break-spaces;
vertical-align: middle;
/* Decoration */
background-color: var(--code-background-color);
color: var(--code-color);
}

View File

@@ -1,195 +0,0 @@
html {
box-sizing: border-box;
height: 100%;
}
*, *:before, *:after {
box-sizing: border-box;
}
body {
max-width: 100%;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeSpeed;
scrollbar-gutter: stable;
font-family: var(--sl-font-sans);
background-color: var(--body-color);
color: var(--text-color);
display: grid;
grid-template-rows: minmax(0, 1fr);
min-height: 100%;
margin: 0;
padding: 0;
}
[hidden] {
display: none !important;
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%;
}
input, button, textarea, select {
font: inherit;
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
}
body {
font-family: var(--sl-font-sans);
min-height: 100%;
}
button {
appearance: none;
border: none;
background: none;
}
button:hover {
cursor: pointer;
}
h1,h2,h3,h4,h5,h6 {
scroll-margin-top: calc(80px + 2em);
margin: 0;
padding: 0;
margin-top: var(--sl-spacing-large);
margin-bottom: var(--sl-spacing-small);
}
main p {
font-size: 1rem;
}
h1 {
font-size: 1.25rem;
margin: 0;
margin-top: 1rem;
margin-bottom: 1rem;
}
h2 {
font-size: 1.15rem;
}
h3, h4 {
font-size: 1.1rem;
}
h5, h6 {
font-size: 1.05rem;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
padding: 0;
font-size: 1rem;
}
p, li {
line-height: 1.5;
}
li {
font-size: 1rem;
}
ul {
line-height: 1.8;
list-style: disc outside;
}
ul ul {
list-style: circle outside;
}
ul ul ul {
list-style: square outside;
}
ul ul ul ul {
list-style: disc outside;
}
[tabindex="-1"] {
outline: transparent;
}
a,
kr-layout::part(skip-link) {
word-wrap: anywhere;
/* outline: transparent; */
/* Unable to distinguish identifier, this makes links obvious */
text-decoration-line: underline;
text-decoration-style: solid;
text-decoration-color: var(--link-color);
text-underline-offset: 0.25em;
color: var(--link-color);
border-radius: 2px;
display: inline;
padding: 0.25em;
margin: -0.25em;
line-height: 1.2;
transition: all 0.2s;
}
kr-layout::part(skip-link):is(:hover),
a:is(:hover) {
color: var(--link-color-focus);
}
kr-layout::part(skip-link):is(:focus-visible),
a:is(:focus-visible) {
box-shadow: 0px 0px 3px 3px var(--sl-color-primary-600);
outline: transparent;
/* for when Safari supports border-radius */
/* outline: 3px solid var(--sl-color-primary-600); */
/* outline-offset: 4px; */
}
@supports not selector(:focus-visible) {
kr-layout::part(skip-link):is(:focus),
a:is(:focus) {
box-shadow: 0px 0px 3px 3px var(--sl-color-primary-600);
outline: transparent;
/* for when Safari supports border-radius */
/* outline: 3px solid var(--sl-color-primary-600); */
/* outline-offset: 4px; */
}
}
code > span {
line-height: var(--sl-line-height-dense);
}
kbd {
font-family: var(--sl-font-mono);
font-size: 87.5%;
background-color: var(--sl-color-neutral-50);
border-radius: 4px;
border: solid 1px var(--sl-color-neutral-200);
box-shadow: inset 0 1px 0 var(--sl-color-neutral-0);
padding: 2px 5px;
line-height: 1;
}
a external-icon {
padding-top: 0.25em;
font-size: 0.75em;
margin-inline-start: -0.15em;
}
blockquote {
border-inline-start: 4px solid var(--divider-color);
margin-inline-start: 0.5rem;
padding: 0.75rem;
background-color: var(--sl-color-neutral-50);
}

View File

@@ -1,2 +0,0 @@
@import "./overrides/bridgetown-ninja-keys.css";
@import "./overrides/shoelace.css";

View File

@@ -1,13 +0,0 @@
sl-alert {
margin: 1rem 0;
}
sl-alert p {
margin: 0;
padding: 0;
}
sl-alert::part(base) {
box-shadow: 3px 3px 6px 1px var(--sl-color-neutral-100);
}

View File

@@ -1,22 +0,0 @@
[style*="--aspect-ratio"] > :first-child {
width: 100%;
}
[style*="--aspect-ratio"] > img {
height: auto;
}
[style*="--aspect-ratio"] {
position: relative;
}
[style*="--aspect-ratio"]::before {
content: "";
display: block;
padding-bottom: calc(100% / (var(--aspect-ratio)));
}
[style*="--aspect-ratio"] > :first-child {
position: absolute;
top: 0;
left: 0;
height: 100%;
}

View File

@@ -1,31 +0,0 @@
.blog-link:focus {
box-shadow: none;
}
.blog-link:focus .blog-link__card::part(base) {
box-shadow: 0px 0px 4px 1px var(--sl-color-primary-700);
}
.blog-link__card::part(base) {
transform: translateY(0px);
transition: transform 0.5s ease-in-out;
}
.blog-link:is(:focus, :hover) .blog-link__card::part(base) {
transform: translateY(-3px);
}
.blog-link,
.blog-link:focus {
color: var(--sl-color-neutral-700);
}
.blog-link:is(:hover) {
color: var(--sl-color-primary-900);
}
.blog-link:is(:hover) .blog-link__card::part(base) {
border: 1px solid var(--sl-color-primary-700);
background-color: var(--sl-color-primary-50);
}

View File

@@ -1,52 +0,0 @@
/** Button */
.button {
padding: 0.4em 0.6em;
display: block;
position: relative;
width: auto;
cursor: pointer;
display: inline-flex;
align-items: stretch;
justify-content: center;
border-style: solid;
border-width: var(--sl-input-border-width);
font-family: var(--sl-input-font-family);
font-weight: var(--sl-font-weight-semibold);
user-select: none;
white-space: nowrap;
transition: var(--sl-transition-x-fast) background-color, var(--sl-transition-x-fast) color,
var(--sl-transition-x-fast) border, var(--sl-transition-x-fast) box-shadow;
background-color: var(--sl-color-neutral-0);
border-color: var(--sl-color-neutral-300);
color: var(--sl-color-neutral-700);
font-size: var(--sl-button-font-size-medium);
border-radius: var(--sl-input-border-radius-medium);
}
.button::-moz-focus-inner {
border: 0;
}
.button:focus {
outline: transparent;
}
.button:focus-visible {
outline: var(--sl-focus-ring);
outline-offset: var(--sl-focus-ring-offset);
}
.button:hover {
background-color: var(--sl-color-primary-50);
border-color: var(--sl-color-primary-300);
color: var(--sl-color-primary-700);
}
.button:active {
background-color: var(--sl-color-primary-100);
border-color: var(--sl-color-primary-400);
color: var(--sl-color-primary-700);
}

View File

@@ -1,24 +0,0 @@
.call-to-action__items {
margin-top: 1.75rem;
margin-bottom: 3rem;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.5rem;
padding: 0;
}
.reason__grid {
display: grid;
gap: 1rem;
}
.reason__grid > * {
height: 100%;
}
@media screen and (min-width: 1024px) {
.reason__grid {
grid-template-columns: repeat(3, 1fr);
}
}

View File

@@ -1,33 +0,0 @@
/** Clipboard **/
.clipboard.clipboard--success:is(:hover, :focus, :active),
.clipboard.clipboard--success {
background-color: var(--sl-color-success-100);
border-color: var(--sl-color-success-600);
color: var(--sl-color-success-800);
}
.clipboard {
align-items: center;
}
.clipboard sl-icon {
font-size: 1rem;
}
.clipboard__icon--success, .clipboard__icon--idle {
transition: transform .2s ease-in-out;
}
.clipboard .clipboard__icon--idle,
.clipboard.clipboard--success .clipboard__icon--success {
transform: scale(1);
}
.clipboard.clipboard--success .clipboard__icon--idle,
.clipboard.clipboard--idle .clipboard__icon--success {
height: 0;
width: 0;
visibility: hidden;
transform: scale(0);
}

View File

@@ -1,6 +0,0 @@
.contact__title {
line-height: 1.3;
font-size: 1.25rem;
margin-bottom: 0;
}

View File

@@ -1,7 +0,0 @@
.footer {
width: 100%;
margin-top: auto;
padding: var(--sl-spacing-large) var(--sl-spacing-2x-small);
text-align: center;
background-color: var(--sl-color-neutral-50);
}

View File

@@ -1,11 +0,0 @@
.nav-header {
display: grid;
grid-template-columns: minmax(0, 1fr);
padding: 0.5rem;
padding-inline-end: 1.5rem;
font-size: 1.05em;
justify-items: space-between;
border-bottom: 1px solid var(--sl-color-neutral-200);
background-color: var(--body-color);
min-height: var(--header-height);
}

View File

@@ -1,30 +0,0 @@
.hero {
margin: 0 auto;
padding: 16px;
max-width: 600px;
}
.hero--mobile {
display: flex;
margin-top: 1rem;
margin-bottom: 1rem;
}
.hero--mobile a {
display: flex;
justify-content: center;
margin: 0 auto;
width: auto;
flex: 0 0 auto;
}
.hero--mobile .logo__text{
font-size: 2.5rem;
}
.hero__caption {
font-size: 0.85em;
margin-top: 6px;
border-inline-start: 4px solid var(--divider-color);
padding-inline-start: 8px;
}

View File

@@ -1,28 +0,0 @@
.input {
font-size: var(--input-font-size);
font-family: inherit;
padding: var(--input-padding);
background-color: var(--input-bg-color);
border: var(--input-border-width) var(--input-border-style) var(--input-border-color);
border-radius: var(--input-border-radius);
height: var(--sl-spacing-2x-large);
color: var(--sl-color-neutral-700);
}
.input {
transition: 150ms box-shadow ease-in-out;
}
.input:focus,
.input:hover {
border-color: var(--sl-color-primary-500);
}
.input:focus {
box-shadow: 0 0 0 var(--input-focus-ring-width)
hsla(198.6 88.7% 48.4% / 0.4);
/* for users who may have shadows and other colors turned off */
outline: var(--input-focus-ring-width) solid transparent;
}

View File

@@ -1,103 +0,0 @@
:is(.index, .doc, .page, .post) kr-layout {
background-color: var(--sl-color-neutral-50);
}
/* .documentation-content {} */
body:is(.index, .doc, .page, .post) kr-layout::part(main-content) {
background: var(--body-color);
}
kr-layout > [slot='aside'] {
display: none;
}
/* Janky hack for iOS mobile */
.fixed-body {
position: fixed;
height: var(--viewport-height, 100%);
width: 100%;
/* Allow the main content to be scrolled,
so we can adjust the scroll position with JS. */
overflow: auto;
}
body:is(.default, .home) kr-layout {
--menu-width: 0px;
--main-width: 1fr;
--aside-width: 0px;
}
kr-layout {
--menu-width: auto;
--main-width: 105ch;
--aside-width: auto;
}
kr-layout,
kr-layout::part(skip-links) {
background-color: var(--body-color);
}
kr-layout::part(body) {
max-width: 100%;
justify-content: center;
margin: 0 auto;
}
kr-layout::part(main) {
background-color: var(--body-color);
}
main {
max-width: 100%;
padding: 0 var(--main-padding-x) 2rem;
width: 100%;
margin: 0 auto;
background-color: var(--body-color);
color: var(--text-color);
}
:is(.default, .home) main {
max-width: var(--main-width);
}
:is(.default, .home) .footer {
width: 100vw;
}
:is(.doc, .index, .page, .post) main {
background-color: var(--body-color);
}
@media screen and (min-width: 1360px) {
kr-layout > [slot='aside'] {
display: block;
}
}
@media screen and (min-width: 1024px) {
body:is(.index, .doc, .page, .post) kr-layout::part(main),
body:is(.index, .doc, .page, .post) kr-layout::part(menu),
body:is(.index, .doc, .page, .post) kr-layout::part(aside) {
padding-top: 2rem;
}
.documentation-content {
border-radius: 32px;
}
body:is(.index, .doc, .page, .post) kr-layout::part(main) {
background-color: transparent;
margin-inline-end: 16px;
margin-inline-start: 16px;
}
body:is(.index, .doc, .page, .post) kr-layout::part(main-content) {
box-shadow: 0 0 5px 0 rgb(0 0 0 / 10%);
background: var(--body-color);
border-radius: 32px;
}
}

View File

@@ -1,47 +0,0 @@
.logo__link {
display: flex;
flex: 1 0 auto;
width: auto;
align-items: center;
}
.logo__link:is(:focus, :hover) {
text-decoration-line: underline;
text-decoration-style: solid;
text-decoration-color: var(--link-color);
color: var(--link-color-focus);
}
.logo__link:is(:focus, :hover) * {
color: var(--link-color-focus);
}
.blog-link__header,
.contact__link,
.main-list__link,
.side-nav__link,
.nav-link {
font-weight: bold;
color: var(--sl-color-neutral-800);
text-decoration-line: underline;
text-decoration-style: solid;
text-decoration-color: var(--sl-color-primary-500);
text-underline-offset: 0.3em;
}
.link__flex {
display: inline-flex;
gap: 0.25em;
align-items: center;
cursor: pointer;
max-width: max-content;
}
.link--small {
font-size: 0.85em;
}
.link--large {
font-size: 1em;
}

View File

@@ -1,3 +0,0 @@
ul.list li {
line-height: 2.5;
}

View File

@@ -1,21 +0,0 @@
.main-list {
padding: 0;
list-style: none;
display: grid;
gap: 8px;
}
.main-list__item {
padding: 8px;
max-width: 100%;
line-height: 1.3;
font-size: 1.25rem;
text-align: center;
}
@media screen and (min-width: 400px) {
.main-list {
grid-auto-flow: column;
}
}

View File

@@ -1,44 +0,0 @@
/** Pagination */
sl-button:is(.previous-page, .next-page) {
transition: transform 0.15s;
}
sl-button:is(.previous-page, .next-page)::part(label) {
max-width: calc(100% - 24px);
width: 100%;
overflow: hidden;
}
sl-button:is(.next-page)::part(base) {
justify-content: start;
justify-content: flex-start;
}
sl-button:is(.previous-page)::part(base) {
justify-content: end;
justify-content: flex-end;
}
sl-button:is(.next-page, .previous-page):is(:hover, :focus) {
box-shadow: var(--sl-color-neutral-50) 0px 12px 13px;
transform: translateY(-2px);
}
.pagination-footer {
padding-top: 2rem;
margin-top: auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
justify-content: space-between;
gap: 1rem;
}
pagination-title {
display: block;
max-width: 100%;
overflow: hidden;
font-size: 1.15rem;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@@ -1,95 +0,0 @@
.side-nav ul {
list-style-type: " ";
}
.side-nav__menu {
margin: 0;
padding-inline-start: 0;
min-width: 250px;
max-width: 100%;
}
ul.side-nav__menu li::marker {
content: ""
}
.side-nav__item {
padding: 8px;
max-width: 100%;
line-height: 1.3;
font-size: 1rem;
font-weight: normal;
}
.side-nav__link {
font-weight: normal;
text-decoration: none;
color: var(--sl-color-neutral-700);
}
.side-nav__link:is(:hover, :focus) {
color: var(--link-color);
text-decoration: underline;
}
.side-nav--desktop {
display: none;
flex-direction: column;
align-items: flex-end;
max-width: 275px;
max-height: 100%;
padding-bottom: 1rem;
overflow: auto;
}
.side-nav__menu {
list-style: none;
padding: 0;
padding-top: 1rem;
}
.side-nav__drawer__header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--sl-color-neutral-200);
padding-bottom: 1rem;
}
.side-nav__item.is-active {
font-weight: normal;
border-inline-start: 4px solid var(--sl-color-primary-600);
background-color: var(--sl-color-primary-100);
}
.side-nav__item.is-active,
.side-nav__item.is-active a {
color: var(--sl-color-primary-700);
}
.side-nav__category-header {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.side-nav__category-menu:not(:first-child) {
margin-top: 1.25rem;
}
@media screen and (min-width: 1024px) {
.side-nav--desktop {
display: flex;
}
.side-nav__category-menu {
padding-inline-start: 40px;
}
.side-nav__category-menu:first-of-type {
padding-top: 0;
}
.side-nav__drawer {
display: none;
}
}

View File

@@ -1,38 +0,0 @@
.syntax-block {
position: relative;
margin-block-end: 1rem;
margin-block-start: 1rem;
}
.syntax-block {
border: 1px solid var(--divider-color);
border-radius: var(--sl-border-radius-large);
}
.syntax-block pre {
margin: 0;
}
.syntax-block__actions {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 8px;
}
.syntax-block .highlight {
border-top-right-radius: 0px;
border-top-left-radius: 0px;
}
.syntax-block__badge {
font-size: 0.85em;
color: var(--sl-color-neutral-700);
}
:is(.language-bash, .language-shell, .language-zsh, .language-sh).highlighter-rouge pre.highlight::before {
content: "$";
user-select: none;
padding-inline-end: 0.45em;
color: gray;
}

View File

@@ -1,39 +0,0 @@
.table-of-contents {
margin-inline-start: 1rem;
min-width: 275px;
max-width: 275px;
}
.table-of-contents * {
max-width: 100%;
}
.table-of-contents__header {
margin: 0;
padding: 0;
padding-top: 1rem;
font-weight: normal;
color: var(--sl-color-neutral-800);
font-size: 1.05rem;
}
.table-of-contents__list {
padding: 0;
margin: 0;
margin-top: 1rem;
list-style: none;
}
.table-of-contents__list a {
text-decoration: none;
}
.table-of-contents__list li {
border-inline-start: 4px solid var(--sl-color-neutral-400);
padding-inline-start: 1rem;
}
.table-of-contents__list li {
padding: 0.5rem;
}

View File

@@ -1,33 +0,0 @@
.table-container {
max-width: 100%;
overflow-x: auto;
}
table {
border-collapse: collapse;
min-width: 100%;
height: auto;
}
th {
text-align: start;
font-weight: 500;
font-size: 1.1em;
}
th,
td {
padding: 1rem;
}
tr {
border-bottom: 1px solid var(--divider-color);
}
tbody > tr:nth-of-type(2n) {
background-color: rgba(0,0,0,0.02);
}
tbody > tr code {
border: 1px solid rgba(0,0,0,0.2);
}

View File

@@ -1,21 +0,0 @@
.logo__text {
color: var(--text-color-primary);
font-size: var(--sl-font-size-x-large);
padding-bottom: var(--sl-spacing-x-small);
margin-bottom: calc(var(--sl-spacing-x-small) - (var(--sl-spacing-x-small) * 2));
margin-inline-start: var(--sl-spacing-2x-small);
}
.site-title,
.slogan {
text-align: center;
}
.slogan {
max-width: max(75%, 600px);
margin: 0 auto;
}
.site-title {
margin-top: 0;
}

View File

@@ -1,26 +0,0 @@
/* Themes */
.theme-item {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
}
[data-controller~='theme-switcher'],
[data-controller~='theme-switcher']:not(:defined) {
height: 0;
width: 0;
opacity: 0;
visibility: hidden;
}
[data-controller~='theme-switcher']:defined {
height: unset;
width: unset;
visibility: visible;
opacity: 1;
animation: fadeInAnimation ease 500ms;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}

View File

@@ -1,106 +0,0 @@
.top-nav {
display: flex;
max-width: var(--top-nav-max-width);
justify-content: center;
margin: 0 auto;
background-color: var(--body-color);
width: 100%;
}
.top-nav__search,
.top-nav__go-home,
.top-nav__categories {
display: flex;
align-items: center;
}
.top-nav__go-home {
min-width: 100px;
}
.top-nav__hamburger__button {
font-size: 1.75em;
}
.top-nav__hamburger__button::part(base),
.top-nav__search__button::part(base) {
color: var(--sl-color-gray-600);
font-size: var(--sl-font-size-x-large);
}
.top-nav__hamburger__button::part(base):is(:hover, :focus),
.top-nav__search__button::part(base):is(:hover, :focus) {
color: var(--link-color-focus);
}
.top-nav__hamburger__button::part(base):focus,
.top-nav__search__button::part(base):focus {
border-color: var(--link-color-focus);
box-shadow: 0 0 6px var(--link-color-focus);
}
.top-nav__search {
margin: 0;
margin-inline-start: auto;
}
.top-nav__github sl-icon {
font-size: 2rem;
}
.top-nav__github {
height: auto;
}
.top-nav__links {
display: flex;
align-items: center;
justify-content: flex-end;
flex: 0 1 auto;
}
.top-nav__categories {
display: none;
font-family: var(--sl-font-sans);
font-weight: bold;
min-width: fit-content;
gap: 1rem;
}
.top-nav__categories > * {
margin: 0;
}
.top-nav__github {
padding-top: var(--sl-spacing-2x-small);
margin-inline-start: var(--sl-spacing-medium);
margin-inline-end: 2px;
}
.top-nav__go-home,
.top-nav__command-palette-button {
display: none;
}
@media screen and (min-width: 1024px) {
/* .hero--mobile, */
.top-nav__hamburger__button,
.top-nav__search__button {
display: none;
}
.top-nav__go-home,
.top-nav__command-palette-button {
display: flex;
}
.top-nav__search {
margin: 0 auto 0 auto;
order: unset;
}
.top-nav__categories {
display: flex;
}
}

View File

@@ -1,10 +0,0 @@
/*
* Anything that can be deferred and not cause layout shift.
* IE: colors, fonts, syntax highlighting, etc.
*/
@import "@shoelace-style/shoelace/dist/themes/light.css";
@import "@shoelace-style/shoelace/dist/themes/dark.css";
@import "./tokens/_colors.css";
@import "./defer/_syntax.css";
@import "./defer/_fonts.css";

View File

@@ -1,17 +0,0 @@
@keyframes fadeInAnimation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeOutAnimation {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

View File

@@ -1,10 +0,0 @@
/** Nothing here...yet */
/* @font-face { */
/* font-family: 'VT323'; */
/* src: */
/* url('/assets/fonts/VT323.ttf') format('truetype'); */
/* font-display: swap; */
/* font-weight: 400; */
/* font-style: normal; */
/* font-stretch: 100; */
/* } */

View File

@@ -1,67 +0,0 @@
/** Syntax highlighting only */
.highlight { color: black; background-color: #f8f8f8; font-family: var(--sl-font-mono); }
.highlight * { font-family: var(--sl-font-mono); }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #000000; font-weight: bold } /* Keyword */
.highlight .o { color: #000000; font-weight: bold } /* Operator */
.highlight .ch { color: #999988; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.highlight .cpf { color: #999988; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #dd1144 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nl { color: #990000; font-weight: bold } /* Name.Label */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #009999 } /* Literal.Number.Bin */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #dd1144 } /* Literal.String.Backtick */
.highlight .sc { color: #dd1144 } /* Literal.String.Char */
.highlight .sd { color: #dd1144 } /* Literal.String.Doc */
.highlight .s2 { color: #dd1144 } /* Literal.String.Double */
.highlight .se { color: #dd1144 } /* Literal.String.Escape */
.highlight .sh { color: #dd1144 } /* Literal.String.Heredoc */
.highlight .si { color: #dd1144 } /* Literal.String.Interpol */
.highlight .sx { color: #dd1144 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #dd1144 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View File

@@ -1,9 +0,0 @@
/* Tokens */
@import "./tokens/_layout.css";
@import "./tokens/_typography.css";
@import "./_normalize.css";
@import "./_components.css";
@import "./_content.css";
@import "./_layout.css";
@import "./_overrides.css";

View File

@@ -1,30 +0,0 @@
bridgetown-ninja-keys {
/* This is a hacky media query. We do this so that we can guess for mobile devices we should
be full height / width so we don't need to deal with dialog scrolling bullshit. */
--ninja-top: 0px;
--ninja-width: clamp(200px, 100vw, 100ch);
--ninja-accent-color: var(--sl-color-primary-600);
z-index: 9999;
}
bridgetown-ninja-keys::part(modal-content) {
height: 100%;
--ninja-actions-height: 100%;
border-radius: 0px;
}
@media screen and (min-width: 768px) {
bridgetown-ninja-keys::part(modal-content) {
height: unset;
--ninja-top: 10vh;
--ninja-actions-height: 60vh;
--ninja-width: clamp(200px, 90vw, 100ch);
border-radius: 8px;
}
}
bridgetown-ninja-keys.dark {
--ninja-modal-background: rgba(35, 35, 35, 1);
--ninja-text-color: gray;
}

Some files were not shown because too many files have changed in this diff Show More