mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-19 15:34:15 +00:00
Compare commits
133 Commits
konnorroge
...
demo-layou
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f278ce1d6d | ||
|
|
0bbf9bb275 | ||
|
|
4deb928682 | ||
|
|
4066e8c591 | ||
|
|
8eb6ee6609 | ||
|
|
620525891d | ||
|
|
384147502f | ||
|
|
730e20bd38 | ||
|
|
9b3669c428 | ||
|
|
b003273175 | ||
|
|
faae5c21fd | ||
|
|
af89149939 | ||
|
|
9b5ceb989c | ||
|
|
7862c374dc | ||
|
|
03508ec523 | ||
|
|
aadf4830c6 | ||
|
|
cd282e50ef | ||
|
|
57ddd25662 | ||
|
|
a37f2d594e | ||
|
|
6fbf921f4b | ||
|
|
c11f3d468b | ||
|
|
306eefa44b | ||
|
|
cd237d3057 | ||
|
|
c7757b8cbe | ||
|
|
b53c1d940a | ||
|
|
edd62490f8 | ||
|
|
96a381d3a3 | ||
|
|
a2a72de2cf | ||
|
|
9a51e69320 | ||
|
|
07be57847d | ||
|
|
0095ca5fe7 | ||
|
|
4b8a86f0e2 | ||
|
|
41de947779 | ||
|
|
cb1c423aea | ||
|
|
93306c99ce | ||
|
|
5f8c69064c | ||
|
|
f51a09ddf0 | ||
|
|
11337197d7 | ||
|
|
f1739309eb | ||
|
|
5007924dbd | ||
|
|
92533c0297 | ||
|
|
94558e6ea5 | ||
|
|
bab673fbdc | ||
|
|
7b20f9c87a | ||
|
|
ddbd91ad89 | ||
|
|
130844df1c | ||
|
|
d6cfa1ab24 | ||
|
|
ec613f8d32 | ||
|
|
52e2518365 | ||
|
|
9b7aad71a9 | ||
|
|
b7541d240b | ||
|
|
c67da1e818 | ||
|
|
265e523a56 | ||
|
|
bfe05d0692 | ||
|
|
651eae8cb6 | ||
|
|
8c8b3f1853 | ||
|
|
d1ed504dd8 | ||
|
|
5335c9421a | ||
|
|
1b380f3f1d | ||
|
|
d166bc0e48 | ||
|
|
595cc303e7 | ||
|
|
4260b27fd2 | ||
|
|
7c6f018c5b | ||
|
|
b892f1f86a | ||
|
|
a0e9125d61 | ||
|
|
5b741006a1 | ||
|
|
30bfabc397 | ||
|
|
4e1bea7d94 | ||
|
|
f2bb9fefee | ||
|
|
9987ce8d4f | ||
|
|
4ace1efbe0 | ||
|
|
d7920f2e75 | ||
|
|
4198cf0f15 | ||
|
|
7562905bbf | ||
|
|
4914cdb352 | ||
|
|
0c95c70192 | ||
|
|
430730f24a | ||
|
|
ab0c615e10 | ||
|
|
716ab94069 | ||
|
|
ccc6f1aa23 | ||
|
|
893f8b2740 | ||
|
|
00d5164912 | ||
|
|
fc9151e573 | ||
|
|
cf97bc3c6c | ||
|
|
eb9dbf097c | ||
|
|
5422e6431c | ||
|
|
f3a921022e | ||
|
|
be1440aee0 | ||
|
|
fe23a7ddb8 | ||
|
|
f53a643cf3 | ||
|
|
3f604fcee1 | ||
|
|
d8b6db8c5b | ||
|
|
31215dbda4 | ||
|
|
f00e8c3a65 | ||
|
|
a4f8bf94ee | ||
|
|
8ae1303188 | ||
|
|
ffc0248e4c | ||
|
|
81d3f22da6 | ||
|
|
0fa8e6f550 | ||
|
|
a67d1df89a | ||
|
|
0fe400c6f4 | ||
|
|
349aa45d2b | ||
|
|
fcf0a136f2 | ||
|
|
8acfc4c9de | ||
|
|
4f8417806c | ||
|
|
65cb3175af | ||
|
|
06135e686b | ||
|
|
340351ca4b | ||
|
|
5701bef6e9 | ||
|
|
62417ed1d1 | ||
|
|
545162eaae | ||
|
|
77a8c418ea | ||
|
|
641e92a340 | ||
|
|
3f8535e7b8 | ||
|
|
81a66df7e4 | ||
|
|
ae2480dfe2 | ||
|
|
c95b0b6c66 | ||
|
|
dee01269ad | ||
|
|
e11eb363aa | ||
|
|
0d33cabec4 | ||
|
|
b5d9b49b27 | ||
|
|
1b654c7c85 | ||
|
|
4e53ce870d | ||
|
|
932e2e7566 | ||
|
|
e76a1dc1f6 | ||
|
|
38302a7c28 | ||
|
|
71e5b10f3b | ||
|
|
3eda5510c3 | ||
|
|
32494e783c | ||
|
|
cdf38fe147 | ||
|
|
302c174055 | ||
|
|
fb044aae89 | ||
|
|
bf299d8234 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,6 +5,8 @@ package.json
|
||||
package-lock.json
|
||||
dist
|
||||
docs/assets/images/sprite.svg
|
||||
docs/public/pagefind
|
||||
node_modules
|
||||
src/react
|
||||
cdn
|
||||
.astro
|
||||
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
4
docs/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
11
docs/.vscode/launch.json
vendored
Normal file
11
docs/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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><{{ component.tagName }}> | {{ 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"><script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}"></script></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><{{ dependency }}></code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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" %}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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" %}
|
||||
@@ -1,10 +0,0 @@
|
||||
html {
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<wa-layout main-id="main-content" class="wa-theme-light">
|
||||
</wa-layout>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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 & 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>
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,138 +0,0 @@
|
||||
let count = 1;
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
})();
|
||||
@@ -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 `>` and `<`
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- fix: allow any HTML Element for templating
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
38
docs/assets/scripts/light-pen/docs/.gitignore
vendored
38
docs/assets/scripts/light-pen/docs/.gitignore
vendored
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
ruby-3.0.4
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
bridgetown: bin/bridgetown start --skip-frontend
|
||||
esbuild: pnpm run esbuild-dev
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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")
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
// console.log("Hello, Stimulus!", this.element)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
export default class SearchController extends Controller {
|
||||
show () {
|
||||
document.querySelector("bridgetown-ninja-keys").open()
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
})
|
||||
@@ -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);
|
||||
})();
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
@import "./overrides/bridgetown-ninja-keys.css";
|
||||
@import "./overrides/shoelace.css";
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
.contact__title {
|
||||
line-height: 1.3;
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ul.list li {
|
||||
line-height: 2.5;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
@@ -1,17 +0,0 @@
|
||||
@keyframes fadeInAnimation {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOutAnimation {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -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; */
|
||||
/* } */
|
||||
@@ -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 */
|
||||
@@ -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";
|
||||
@@ -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
Reference in New Issue
Block a user