mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-14 21:19:13 +00:00
Compare commits
154 Commits
base
...
kj/first-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a0f7751f4 | ||
|
|
b7ed832554 | ||
|
|
aa6a875d01 | ||
|
|
48412f9672 | ||
|
|
cb1f9c8b48 | ||
|
|
2e072fac3b | ||
|
|
bdd4c3ec9a | ||
|
|
3b30f9f39e | ||
|
|
1999b65591 | ||
|
|
444e0d3e46 | ||
|
|
5aeedceb2d | ||
|
|
1e1cd2406e | ||
|
|
e72f2c1847 | ||
|
|
910c6cb3fb | ||
|
|
55edcd2470 | ||
|
|
952a44b5eb | ||
|
|
2ca8422bc8 | ||
|
|
beb88fac56 | ||
|
|
a588194b95 | ||
|
|
a1ba80fe8d | ||
|
|
a3edcaf27d | ||
|
|
595c40c0fa | ||
|
|
7e2f32a965 | ||
|
|
7b3bd8e027 | ||
|
|
5711819e9c | ||
|
|
760c09781d | ||
|
|
5b59bee2ff | ||
|
|
ec1ffcefdc | ||
|
|
d828dd3600 | ||
|
|
0984cde1c5 | ||
|
|
5edad481f0 | ||
|
|
aab221dcb1 | ||
|
|
bbe6b4c6b3 | ||
|
|
6ee5c27b9d | ||
|
|
c3af1174ca | ||
|
|
db5b967390 | ||
|
|
8e3ffc4abe | ||
|
|
b5523c33b7 | ||
|
|
f031cab138 | ||
|
|
67c46a21dd | ||
|
|
c310ee1072 | ||
|
|
8fff50d3d8 | ||
|
|
944f9002c7 | ||
|
|
eba2a75ffb | ||
|
|
c3de5a8915 | ||
|
|
c18aa23d76 | ||
|
|
54e14a20c0 | ||
|
|
97b8e96a6e | ||
|
|
55a362b741 | ||
|
|
d9cafdafb7 | ||
|
|
81bf6865ec | ||
|
|
873eb47d18 | ||
|
|
a564d3061f | ||
|
|
ef865396f2 | ||
|
|
903085257d | ||
|
|
27237441a1 | ||
|
|
b0291653f8 | ||
|
|
3962c50844 | ||
|
|
314801c368 | ||
|
|
dc30ed8503 | ||
|
|
e12be798b8 | ||
|
|
7f29f1b4ea | ||
|
|
3563d6a2dd | ||
|
|
007d93077f | ||
|
|
80b78aeb16 | ||
|
|
8bc8ea85a5 | ||
|
|
61a6cd9fb9 | ||
|
|
7fb3fd5982 | ||
|
|
dc580b3351 | ||
|
|
74719d4c06 | ||
|
|
47a7cdedd0 | ||
|
|
d906940726 | ||
|
|
a782470c6a | ||
|
|
de175ed4a1 | ||
|
|
3612f8fdfa | ||
|
|
bc76df4b31 | ||
|
|
9ad7f4a6be | ||
|
|
a7457630aa | ||
|
|
e19928123f | ||
|
|
e644862f58 | ||
|
|
76529c628e | ||
|
|
62ded7b15a | ||
|
|
65af9980f1 | ||
|
|
db592194fd | ||
|
|
0f9ea14033 | ||
|
|
057b76a10a | ||
|
|
b466ba9d0f | ||
|
|
9c979931da | ||
|
|
898311590a | ||
|
|
5f4510f355 | ||
|
|
b8eeb3db23 | ||
|
|
8574270340 | ||
|
|
aa042a0a6e | ||
|
|
fe81a41a6b | ||
|
|
f3628ad2d8 | ||
|
|
169337077d | ||
|
|
406d9a9708 | ||
|
|
faaf75c0a2 | ||
|
|
13b67db869 | ||
|
|
b7fdda4b03 | ||
|
|
d60e675702 | ||
|
|
414a318f0b | ||
|
|
ff8ed89645 | ||
|
|
e027ab1291 | ||
|
|
d8f97b15b4 | ||
|
|
a8ed6f2c19 | ||
|
|
c7f5dc69ad | ||
|
|
42381722c5 | ||
|
|
b2f9ec573f | ||
|
|
b85e59b8ca | ||
|
|
8bd69694ce | ||
|
|
7672923479 | ||
|
|
c94006c6aa | ||
|
|
91ce2f2271 | ||
|
|
9c609e44de | ||
|
|
28a8e4250a | ||
|
|
656a38cd3d | ||
|
|
9b90e56b45 | ||
|
|
0c84a2ff37 | ||
|
|
511cca7931 | ||
|
|
2069d223f0 | ||
|
|
37d2455965 | ||
|
|
85b05fc655 | ||
|
|
52328d9805 | ||
|
|
2c89c5f510 | ||
|
|
5ac9e8cff1 | ||
|
|
e238e35b3b | ||
|
|
c6d8d37871 | ||
|
|
4dddb183fd | ||
|
|
d49ed53e9a | ||
|
|
99e2ffc17b | ||
|
|
97c79c29b9 | ||
|
|
7da9f53e27 | ||
|
|
a9cc02193f | ||
|
|
9ad1c8f060 | ||
|
|
e0eaea2024 | ||
|
|
a8b7b6a93f | ||
|
|
581e47043a | ||
|
|
9ffe0cfe3c | ||
|
|
45df4a924f | ||
|
|
43eed9d15e | ||
|
|
a0ff411463 | ||
|
|
04cd027c7e | ||
|
|
a68a157ebc | ||
|
|
b2a24a3b52 | ||
|
|
cbb456ffda | ||
|
|
e0038c3125 | ||
|
|
3e5d3120b1 | ||
|
|
020f4cbaed | ||
|
|
9106bb88cf | ||
|
|
a822ab98c8 | ||
|
|
026777c085 | ||
|
|
6d87b9b24a | ||
|
|
d5affa01e9 |
@@ -36,16 +36,10 @@ const globalData = {
|
||||
},
|
||||
};
|
||||
|
||||
const passThroughExtensions = ['js', 'css', 'png', 'svg', 'jpg', 'mp4'];
|
||||
const passThrough = [...passThroughExtensions.map(ext => 'docs/**/*.' + ext)];
|
||||
|
||||
export default function (eleventyConfig) {
|
||||
/**
|
||||
* If you plan to add or remove any of these extensions, make sure to let either Konnor or Cory know as these passthrough extensions
|
||||
* will also need to be updated in the Web Awesome App.
|
||||
*/
|
||||
const passThroughExtensions = ['js', 'css', 'png', 'svg', 'jpg', 'mp4'];
|
||||
|
||||
const baseDir = process.env.BASE_DIR || 'docs';
|
||||
const passThrough = [...passThroughExtensions.map(ext => path.join(baseDir, '**/*.' + ext))];
|
||||
|
||||
/**
|
||||
* This is the guard we use for now to make sure our final built files dont need a 2nd pass by the server. This keeps us able to still deploy the bare HTML files on Vercel until the app is ready.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</head>
|
||||
<body class="layout-{{ layout | stripExtension }}{{ ' page-wide' if wide }}">
|
||||
<!-- use view="desktop" as default to reduce layout jank on desktop site. -->
|
||||
<wa-page view="desktop" disable-navigation-toggle="" mobile-breakpoint="1140">
|
||||
<wa-page view="desktop" disable-navigation-toggle="">
|
||||
<header slot="header" class="wa-split">
|
||||
{# Logo #}
|
||||
<div id="docs-branding">
|
||||
@@ -33,13 +33,13 @@
|
||||
<span class="wa-desktop-only">{% include "logo.njk" %}</span>
|
||||
<span class="wa-mobile-only">{% include "logo-simple.njk" %}</span>
|
||||
</a>
|
||||
<small id="version-number" class="wa-desktop-only">{{ package.version }}</small>
|
||||
<wa-badge variant="warning" appearance="filled" class="wa-desktop-only">Alpha</wa-badge>
|
||||
<small id="version-number" class="only-desktop">{{ package.version }}</small>
|
||||
<wa-badge variant="warning" appearance="filled" class="only-desktop">Alpha</wa-badge>
|
||||
</div>
|
||||
|
||||
<div id="docs-toolbar" class="wa-cluster wa-gap-xs">
|
||||
{# Desktop selectors #}
|
||||
<div class="wa-desktop-only wa-cluster wa-gap-xs">
|
||||
<div class="only-desktop wa-cluster wa-gap-xs">
|
||||
{% include "preset-theme-selector.njk" %}
|
||||
{% include "color-scheme-selector.njk" %}
|
||||
</div>
|
||||
@@ -48,7 +48,7 @@
|
||||
<wa-button id="search-trigger" appearance="outlined" size="small" data-search>
|
||||
<wa-icon slot="prefix" name="magnifying-glass"></wa-icon>
|
||||
Search
|
||||
<kbd slot="suffix" class="wa-desktop-only">/</kbd>
|
||||
<kbd slot="suffix" class="only-desktop">/</kbd>
|
||||
</wa-button>
|
||||
|
||||
{# Login #}
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
{# Importing #}
|
||||
<h2>Importing</h2>
|
||||
<p>
|
||||
The <a href="/docs/#quick-start-autoloading-via-cdn">autoloader</a> is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
|
||||
The <a href="/docs/installation/#quick-start-autoloading-via-cdn">autoloader</a> is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
|
||||
</p>
|
||||
|
||||
<wa-tab-group label="How would you like to import this component?">
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
{% for h in hues -%}
|
||||
{%- if h !== 'gray' -%}
|
||||
<wa-radio-button id="gray-undertone-{{ h }}" value="{{ h }}" label="{{ h | capitalize }}" style="--color: var(--wa-color-{{ h }})"></wa-radio-button>
|
||||
<wa-tooltip for="gray-undertone-{{ h }}">
|
||||
<wa-tooltip for="gray-undertone-{{ h }}" hoist>
|
||||
{{ h | capitalize }}
|
||||
</wa-tooltip>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -25,8 +25,8 @@ wa_data.palettes = {
|
||||
{% endfor %}
|
||||
};
|
||||
</script>
|
||||
<link href="/docs/themes/remix.css" rel="stylesheet">
|
||||
<script src="/docs/themes/remix.js" type="module"></script>
|
||||
<link href="{{ page.url }}../remix.css" rel="stylesheet">
|
||||
<script src="{{ page.url }}../remix.js" type="module"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function copyCodePlugin(eleventyConfig, options = {}) {
|
||||
|
||||
// Add a copy button
|
||||
pre.innerHTML += `<wa-icon-button href="#${preId}" class="block-link-icon" name="link"></wa-icon-button>
|
||||
<wa-copy-button from="${codeId}" class="copy-button"></wa-copy-button>`;
|
||||
<wa-copy-button from="${codeId}" class="copy-button" hoist></wa-copy-button>`;
|
||||
});
|
||||
|
||||
return doc.toString();
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
import { domChange } from './util/dom-change.js';
|
||||
export { domChange };
|
||||
let initialPageLoadComplete = document.readyState === 'complete';
|
||||
|
||||
if (!initialPageLoadComplete) {
|
||||
window.addEventListener('load', () => {
|
||||
initialPageLoadComplete = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Helper for view transitions
|
||||
export function domChange(fn, { behavior = 'smooth', ignoreInitialLoad = true } = {}) {
|
||||
const canUseViewTransitions =
|
||||
document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
// Skip transitions on initial page load
|
||||
if (!initialPageLoadComplete && ignoreInitialLoad) {
|
||||
fn(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (canUseViewTransitions && behavior === 'smooth') {
|
||||
const transition = document.startViewTransition(() => {
|
||||
fn(true);
|
||||
// Wait a brief delay before finishing the transition to prevent jumpiness
|
||||
return new Promise(resolve => setTimeout(resolve, 200));
|
||||
});
|
||||
return transition;
|
||||
} else {
|
||||
fn(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function nextFrame() {
|
||||
return new Promise(resolve => requestAnimationFrame(resolve));
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
let initialPageLoadComplete = document.readyState === 'complete';
|
||||
|
||||
if (!initialPageLoadComplete) {
|
||||
window.addEventListener('load', () => {
|
||||
initialPageLoadComplete = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for performing a DOM change using a view transition, wherever supported and reduced motion is not desired.
|
||||
* @param {function} fn - Function to perform the DOM change. If async, must resolve when the change is complete.
|
||||
* @param {object} [options] - Options for the transition
|
||||
* @param {'smooth' | 'instant'} [options.behavior] - Transition behavior. Defaults to 'smooth'. 'instant' will skip the transition.
|
||||
* @param {boolean} [options.ignoreInitialLoad] - If true, will skip the transition on initial page load. Defaults to true.
|
||||
*/
|
||||
export function domChange(fn, { behavior = 'smooth', ignoreInitialLoad = true } = {}) {
|
||||
const canUseViewTransitions =
|
||||
document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
// Skip transitions on initial page load
|
||||
if (!initialPageLoadComplete && ignoreInitialLoad) {
|
||||
fn(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (canUseViewTransitions && behavior === 'smooth') {
|
||||
const transition = document.startViewTransition(() => {
|
||||
fn(true);
|
||||
// Wait a brief delay before finishing the transition to prevent jumpiness
|
||||
return new Promise(resolve => setTimeout(resolve, 200));
|
||||
});
|
||||
return transition;
|
||||
} else {
|
||||
fn(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -608,6 +608,13 @@ table.colors {
|
||||
margin-block-end: var(--wa-flow-spacing);
|
||||
}
|
||||
|
||||
/** mobile */
|
||||
@media screen and (max-width: 768px) {
|
||||
wa-page .only-desktop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/** desktop */
|
||||
@media screen and not (max-width: 768px) {
|
||||
/* Navigation sidebar */
|
||||
|
||||
@@ -167,7 +167,7 @@ Other elements can also be placed inside button groups:
|
||||
<wa-button-group label="Example Button Group">
|
||||
<wa-button>Button</wa-button>
|
||||
<button>Native Button</button>
|
||||
<wa-dropdown>
|
||||
<wa-dropdown hoist>
|
||||
<wa-button slot="trigger" caret>Dropdown</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
@@ -185,7 +185,7 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/do
|
||||
```html {.example}
|
||||
<wa-button-group label="Example Button Group">
|
||||
<wa-button variant="brand">Save</wa-button>
|
||||
<wa-dropdown placement="bottom-end">
|
||||
<wa-dropdown placement="bottom-end" hoist>
|
||||
<wa-button slot="trigger" variant="brand" caret>
|
||||
<span class="wa-visually-hidden">More options</span>
|
||||
</wa-button>
|
||||
|
||||
@@ -3,7 +3,6 @@ title: Code Demo
|
||||
description: Code demos can be used to render code examples as inline live demos.
|
||||
tags: component
|
||||
noAlpha: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
|
||||
@@ -180,3 +180,38 @@ To create a submenu, nest an `<wa-menu slot="submenu">` element in a [menu item]
|
||||
:::warning
|
||||
As a UX best practice, avoid using more than one level of submenu when possible.
|
||||
:::
|
||||
|
||||
### Hoisting
|
||||
|
||||
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html {.example}
|
||||
<div class="dropdown-hoist">
|
||||
<wa-dropdown>
|
||||
<wa-button slot="trigger" caret>No Hoist</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
<wa-menu-item>Item 2</wa-menu-item>
|
||||
<wa-menu-item>Item 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
</wa-dropdown>
|
||||
|
||||
<wa-dropdown hoist>
|
||||
<wa-button slot="trigger" caret>Hoist</wa-button>
|
||||
<wa-menu>
|
||||
<wa-menu-item>Item 1</wa-menu-item>
|
||||
<wa-menu-item>Item 2</wa-menu-item>
|
||||
<wa-menu-item>Item 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
</wa-dropdown>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dropdown-hoist {
|
||||
position: relative;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -17,93 +17,13 @@ Not sure which icon to use? [Find the perfect icon over at Font Awesome!](https:
|
||||
|
||||
The default icon library is Font Awesome Free, which comes with two icon families: `classic` and `brands`. Use the `family` attribute to set the icon family.
|
||||
|
||||
Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regular`, and `solid`. Font Awesome Pro users can [provide their kit code](/docs/#using-font-awesome-kit-codes) to unlock additional families, including `sharp` and `duotone`. For these icon families, use the `variant` attribute to set the variant.
|
||||
Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regular`, and `solid`. Font Awesome Pro users can [provide their kit code](/docs/installation/#using-font-awesome-kit-codes) to unlock additional families, including `sharp` and `duotone`. For these icon families, use the `variant` attribute to set the variant.
|
||||
|
||||
```html {.example}
|
||||
<wa-icon family="brands" name="font-awesome"></wa-icon>
|
||||
<wa-icon family="brands" name="web-awesome"></wa-icon>
|
||||
```
|
||||
|
||||
### Setting defaults via CSS
|
||||
|
||||
You can use certain CSS custom properties to set icon defaults, not just on the icon itself, but any ancestor.
|
||||
This can be useful when you want certain parameters to vary based on context, e.g. icons inside callouts or all icons for a given theme.
|
||||
|
||||
:::warning
|
||||
These CSS properties are intended to set **defaults**, and thus only make a difference when the corresponding attributes are not set.
|
||||
In future versions of Web Awesome, we may change this behavior to allow CSS properties to override attributes if `!important` is used.
|
||||
:::
|
||||
|
||||
For example, here is how you can use CSS custom properties to set a default icon for each type of callout:
|
||||
|
||||
```html {.example}
|
||||
<wa-callout>
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
This is a normal callout.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="danger">
|
||||
<wa-icon slot="icon" name="dumpster-fire" variant="solid"></wa-icon>
|
||||
This is a callout with an explicit icon, which overrides these defaults.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="warning">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Here be dragons.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="danger">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Here be more dragons.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="success">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Success!
|
||||
</wa-callout>
|
||||
|
||||
<style>
|
||||
wa-callout {
|
||||
--wa-icon-variant: regular;
|
||||
--wa-icon-name: info-circle;
|
||||
|
||||
&[variant="warning"] {
|
||||
--wa-icon-name: triangle-exclamation;
|
||||
}
|
||||
|
||||
&[variant="danger"] {
|
||||
--wa-icon-name: circle-exclamation;
|
||||
}
|
||||
|
||||
&[variant="success"] {
|
||||
--wa-icon-name: circle-check;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
You can even set icons dynamically, as a response to user interaction or media queries.
|
||||
For example, here's how we can change the icon on hover:
|
||||
|
||||
```html {.example}
|
||||
<wa-button class="github" href="https://github.com/webawesome/webawesome"><wa-icon slot="prefix" fixed-width></wa-icon> GitHub Repo</wa-button>
|
||||
<style>
|
||||
.github {
|
||||
--wa-icon-name: github;
|
||||
--wa-icon-family: brands;
|
||||
|
||||
&:hover {
|
||||
--wa-icon-name: arrow-up-right-from-square;
|
||||
--wa-icon-family: classic;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
Icons inherit their color from the current text color. Thus, you can set the `color` property on the `<wa-icon>` element or an ancestor to change the color.
|
||||
@@ -641,4 +561,4 @@ If you want to change the icons Web Awesome uses internally, you can register an
|
||||
resolver: name => `/path/to/custom/icons/${name}.svg`
|
||||
});
|
||||
</script>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -468,20 +468,75 @@ Use the `sync` attribute to make the popup the same width or height as the ancho
|
||||
</script>
|
||||
```
|
||||
|
||||
### Positioning Strategy
|
||||
|
||||
By default, the popup is positioned using an absolute positioning strategy. However, if your anchor is fixed or exists within a container that has `overflow: auto|hidden`, the popup risks being clipped. To work around this, you can use a fixed positioning strategy by setting the `strategy` attribute to `fixed`.
|
||||
|
||||
The fixed positioning strategy reduces jumpiness when the anchor is fixed and allows the popup to break out containers that clip. When using this strategy, it's important to note that the content will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
In this example, you can see how the popup breaks out of the overflow container when it's fixed. The fixed positioning strategy tends to be less performant than absolute, so avoid using it unnecessarily.
|
||||
|
||||
Toggle the switch and scroll the container to see the difference.
|
||||
|
||||
```html {.example}
|
||||
<div class="popup-strategy">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" strategy="fixed" active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
</div>
|
||||
|
||||
<wa-switch checked>Fixed</wa-switch>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.popup-strategy .overflow {
|
||||
position: relative;
|
||||
height: 300px;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.popup-strategy span[slot='anchor'] {
|
||||
display: inline-block;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border: dashed 2px var(--wa-color-neutral-fill-loud);
|
||||
margin: 150px 50px;
|
||||
}
|
||||
|
||||
.popup-strategy .box {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background: var(--wa-color-brand-fill-loud);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
.popup-strategy wa-switch {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const container = document.querySelector('.popup-strategy');
|
||||
const popup = container.querySelector('wa-popup');
|
||||
const fixed = container.querySelector('wa-switch');
|
||||
|
||||
fixed.addEventListener('change', () => (popup.strategy = fixed.checked ? 'fixed' : 'absolute'));
|
||||
</script>
|
||||
```
|
||||
|
||||
### Flip
|
||||
|
||||
When the popup doesn't have enough room in its preferred placement, it can automatically flip to keep it in view and visually connected to its anchor.
|
||||
To enable this, use the `flip` attribute. By default, the popup will flip to the opposite placement, but you can configure preferred fallback placements using `flip-fallback-placement` and `flip-fallback-strategy`. Additional options are available to control the flip behavior's boundary and padding.
|
||||
|
||||
By default, flip takes effect when the popup would overflow the viewport.
|
||||
You can use `boundary="scroll"` to make the popup resize when it overflows its nearest scrollable container instead.
|
||||
When the popup doesn't have enough room in its preferred placement, it can automatically flip to keep it in view. To enable this, use the `flip` attribute. By default, the popup will flip to the opposite placement, but you can configure preferred fallback placements using `flip-fallback-placement` and `flip-fallback-strategy`. Additional options are available to control the flip behavior's boundary and padding.
|
||||
|
||||
Scroll the container to see how the popup flips to prevent clipping.
|
||||
|
||||
```html {.example}
|
||||
<div class="popup-flip">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" flip active boundary="scroll">
|
||||
<wa-popup placement="top" flip active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
@@ -537,7 +592,7 @@ Scroll the container to see how the popup changes it's fallback placement to pre
|
||||
```html {.example}
|
||||
<div class="popup-flip-fallbacks">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" flip flip-fallback-placements="right bottom" flip-fallback-strategy="initial" active boundary="scroll">
|
||||
<wa-popup placement="top" flip flip-fallback-placements="right bottom" flip-fallback-strategy="initial" active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
@@ -571,18 +626,14 @@ Scroll the container to see how the popup changes it's fallback placement to pre
|
||||
|
||||
### Shift
|
||||
|
||||
When a popup is longer than its anchor, it risks overflowing.
|
||||
In this case, use the `shift` attribute to shift the popup along its axis and back into view. You can customize the shift behavior using `shiftBoundary` and `shift-padding`.
|
||||
|
||||
By default, auto-size takes effect when the popup would overflow the viewport.
|
||||
You can use `boundary="scroll"` to make the popup resize when it overflows its nearest scrollable container instead.
|
||||
When a popup is longer than its anchor, it risks being clipped by an overflowing container. In this case, use the `shift` attribute to shift the popup along its axis and back into view. You can customize the shift behavior using `shiftBoundary` and `shift-padding`.
|
||||
|
||||
Toggle the switch to see the difference.
|
||||
|
||||
```html {.example}
|
||||
<div class="popup-shift">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" shift shift-padding="10" active boundary="scroll">
|
||||
<wa-popup placement="top" shift shift-padding="10" active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
@@ -625,11 +676,7 @@ Toggle the switch to see the difference.
|
||||
|
||||
### Auto-size
|
||||
|
||||
Use the `auto-size` attribute to tell the popup to resize when necessary to prevent it from overflowing.
|
||||
Possible values are `horizontal`, `vertical`, and `both`. You can use `autoSizeBoundary` and `auto-size-padding` to customize the behavior of this option. Auto-size works well with `flip`, but if you're using `auto-size-padding` make sure `flip-padding` is the same value.
|
||||
|
||||
By default, auto-size takes effect when the popup would overflow the viewport.
|
||||
You can use `boundary="scroll"` to make the popup resize when it overflows its nearest scrollable container instead.
|
||||
Use the `auto-size` attribute to tell the popup to resize when necessary to prevent it from getting clipped. Possible values are `horizontal`, `vertical`, and `both`. You can use `autoSizeBoundary` and `auto-size-padding` to customize the behavior of this option. Auto-size works well with `flip`, but if you're using `auto-size-padding` make sure `flip-padding` is the same value.
|
||||
|
||||
When using `auto-size`, one or both of `--auto-size-available-width` and `--auto-size-available-height` will be applied to the host element. These values determine the available space the popover has before clipping will occur. Since they cascade, you can use them to set a max-width/height on your popup's content and easily control its overflow.
|
||||
|
||||
@@ -638,7 +685,7 @@ Scroll the container to see the popup resize as its available space changes.
|
||||
```html {.example}
|
||||
<div class="popup-auto-size">
|
||||
<div class="overflow">
|
||||
<wa-popup placement="top" auto-size="both" auto-size-padding="10" active boundary="scroll">
|
||||
<wa-popup placement="top" auto-size="both" auto-size-padding="10" active>
|
||||
<span slot="anchor"></span>
|
||||
<div class="box"></div>
|
||||
</wa-popup>
|
||||
|
||||
@@ -425,3 +425,11 @@ This can be hard to conceptualize, so heres a fairly large example showing how l
|
||||
</script>
|
||||
```
|
||||
|
||||
<script type="module">
|
||||
//
|
||||
// TODO - remove once we switch to the Popover API
|
||||
//
|
||||
customElements.whenDefined('wa-select').then(() => {
|
||||
document.querySelectorAll('wa-code-demo [slot="preview"] wa-select').forEach(select => select.hoist = true);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -152,3 +152,25 @@ Use the `--max-width` custom property to change the width the tooltip can grow t
|
||||
<wa-button id="wrapping-tooltip">Hover me</wa-button>
|
||||
```
|
||||
|
||||
### Hoisting
|
||||
|
||||
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html {.example}
|
||||
<div class="tooltip-hoist">
|
||||
<wa-tooltip for="no-hoist">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="no-hoist">No Hoist</wa-button>
|
||||
|
||||
<wa-tooltip for="hoist" hoist>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="hoist">Hoist</wa-button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tooltip-hoist {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -3,7 +3,6 @@ title: Viewport Demo
|
||||
description: Viewport demos can be used to display an iframe as a resizable, zoomable preview.
|
||||
tags: component
|
||||
noAlpha: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
|
||||
@@ -10,7 +10,7 @@ You can customize the look and feel of Web Awesome at a high level with themes.
|
||||
|
||||
Web Awesome uses [themes](/docs/themes) to apply a cohesive look and feel across the entire library. Themes are built with a collection of predefined CSS custom properties, which we call [design tokens](/docs/tokens), and there are many premade themes you can choose from.
|
||||
|
||||
To use a theme, simply add a link to the theme's stylesheet to the `<head>` of your page. For example, you can replace the link to `default.css` in the [installation code](/docs/#quick-start-autoloading-via-cdn) with this snippet to use the *Awesome* theme:
|
||||
To use a theme, simply add a link to the theme's stylesheet to the `<head>` of your page. For example, you can replace the link to `default.css` in the [installation code](/docs/installation/#quick-start-autoloading-via-cdn) with this snippet to use the *Awesome* theme:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/themes/awesome.css' %}" />
|
||||
@@ -197,7 +197,7 @@ For example, we can give all outlined callouts a thick left border, regardless o
|
||||
|
||||
<style>
|
||||
wa-callout:is(
|
||||
[appearance~="outlined"],
|
||||
[appearance~="outlined"],
|
||||
.wa-outlined
|
||||
) {
|
||||
border-left-width: var(--wa-panel-border-radius);
|
||||
|
||||
@@ -10,7 +10,7 @@ override:tags: []
|
||||
{% markdown %}
|
||||
## Installation
|
||||
|
||||
Layout components are included in Web Awesome's [autoloader](/docs/#quick-start-autoloading-via-cdn). You can also import them individually via [cherry picking](/docs/#cherry-picking).
|
||||
Layout components are included in Web Awesome's [autoloader](/docs/installation/#quick-start-autoloading-via-cdn). You can also import them individually via [cherry picking](/docs/installation/#cherry-picking).
|
||||
|
||||
Layout utilities are bundled with all [style utilities](/docs/utilities). You can import all Web Awesome page styles (including [native styles](/docs/native/)) by including the following stylesheet in your project:
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Action Panel
|
||||
description: 'Help users complete tasks efficiently with quick access to key actions.'
|
||||
icon: action-panel
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Activity Log
|
||||
description: 'Track and organize recent user actions or events.'
|
||||
|
||||
---
|
||||
|
||||
## Simple
|
||||
@@ -261,7 +260,7 @@ description: 'Track and organize recent user actions or events.'
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Comments
|
||||
description: 'Enable users to engage in discussions, provide feedback, or record their thoughts.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Card with Header & Footer
|
||||
@@ -92,7 +91,7 @@ isPro: true
|
||||
<wa-icon-button name="face-smile" label="Add Sticker" id="sticker-button"></wa-icon-button>
|
||||
<wa-tooltip for="sticker-button">Add Sticker</wa-tooltip>
|
||||
</div>
|
||||
<wa-button variant="brand">Comment</wa-button>
|
||||
<wa-button variant="brand">Comment</wa-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,9 +107,9 @@ isPro: true
|
||||
<div class="wa-stack">
|
||||
<div class="wa-flank" style="--flank-size: 3rem">
|
||||
<div class="wa-frame:portrait wa-border-radius-s">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1607675742178-f616ae75044b?q=80&w=3435&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
|
||||
alt="the cover image for the film"
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1607675742178-f616ae75044b?q=80&w=3435&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
|
||||
alt="the cover image for the film"
|
||||
/>
|
||||
</div>
|
||||
<span class="wa-heading-l">Heretic</span>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
---
|
||||
title: Data Display
|
||||
description: 'Convey insights, metrics, and aggregate data at a glance.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
|
||||
## Simple
|
||||
## Simple
|
||||
```html {.example}
|
||||
<wa-card>
|
||||
<div class="wa-grid wa-gap-3xl" style="--min-column-size: 24ch;">
|
||||
@@ -171,4 +170,4 @@ isPro: true
|
||||
</article>
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Description List
|
||||
description: 'Help users digest detailed information in a structured, easy-to-scan format.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Left Aligned
|
||||
@@ -250,4 +249,4 @@ isPro: true
|
||||
</a>
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Empty State
|
||||
description: 'Guide users with helpful prompts and visuals when no content is available.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple
|
||||
@@ -126,7 +125,7 @@ isPro: true
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
## Add people
|
||||
## Add people
|
||||
```html {.example}
|
||||
<wa-card style="max-width: 60ch; margin: 0 auto;">
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
@@ -147,7 +146,7 @@ isPro: true
|
||||
<span class="wa-caption-m">DevOps</span>
|
||||
</div>
|
||||
<wa-button appearance="plain">
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
Invite
|
||||
</wa-button>
|
||||
</div>
|
||||
@@ -163,7 +162,7 @@ isPro: true
|
||||
<span class="wa-caption-m">Captain</span>
|
||||
</div>
|
||||
<wa-button appearance="plain">
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
Invite
|
||||
</wa-button>
|
||||
</div>
|
||||
@@ -179,7 +178,7 @@ isPro: true
|
||||
<span class="wa-caption-m">Cloud Engineer</span>
|
||||
</div>
|
||||
<wa-button appearance="plain">
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
Invite
|
||||
</wa-button>
|
||||
</div>
|
||||
@@ -194,7 +193,7 @@ isPro: true
|
||||
<span class="wa-caption-m">UX Writer</span>
|
||||
</div>
|
||||
<wa-button appearance="plain">
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
<wa-icon name="user-plus" slot="prefix"></wa-icon>
|
||||
Invite
|
||||
</wa-button>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: FAQ
|
||||
description: 'Empower users to learn more with a structured list of questions and answers.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## With Flanked Heading & Description
|
||||
@@ -87,7 +86,7 @@ isPro: true
|
||||
<dt class="wa-heading-m">How often do you update your courses?</dt>
|
||||
<dd>A course is updated once there is a fundamental shift in the language or library’s underlying API. You can check our <a href="#">workshop</a> list to see if a new version of a given course is on the schedule. You may also write to us as <a href="#">support@frontendmasters.com</a> with suggestions for updates.</dd>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
<dt class="wa-heading-m">Do you offer certificates of completion?</dt>
|
||||
<dd>You can download certificates of completion from the <a href="#">Completed Courses</a> list in your Learning Library. Click the diploma icon next to the course to download the certificate in light or dark mode. A link to your Public Profile is included on each certificate if you’ve created one. Public Profiles showcase your learning journey and are a fantastic way to share progress with friends, co-workers, or employers. Public Profiles are available to members with an active Frontend Masters subscription who have watched ten or more hours of content. Visit the <a href="#">Public Profile</a> section in My Account to get started.</dd>
|
||||
@@ -104,16 +103,16 @@ isPro: true
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
<dt class="wa-heading-m">Do you have discounts for students?</dt>
|
||||
<dd>We are part of the <a href="#">GitHub Student Developer Pack</a>, allowing students six months of free access to the entire platform.</dd>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
<dt class="wa-heading-m">How do I cancel my plan?</dt>
|
||||
<dd>You can cancel your Frontend Masters subscription by visiting the <a href="#">Subscription tab</a> in your My Account area.</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Grid List
|
||||
description: 'Improve browsing and selection by organizing data in a structured grid layout.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Cards with Footer Actions
|
||||
@@ -398,8 +397,8 @@ isPro: true
|
||||
<div class="wa-stack">
|
||||
<div class="wa-cluster wa-gap-s"><span>Draft</span> <wa-badge appearance="filled outlined" variant="neutral">1</wa-badge></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<wa-card>
|
||||
<div class="wa-flank:end">
|
||||
<div class="wa-stack wa-gap-2xs">
|
||||
@@ -427,12 +426,12 @@ isPro: true
|
||||
<wa-icon name="plus"></wa-icon>
|
||||
Add Task
|
||||
</wa-button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wa-stack">
|
||||
<div class="wa-cluster wa-gap-s"><span>In Progress</span> <wa-badge appearance="filled outlined" variant="neutral">2</wa-badge></div>
|
||||
|
||||
|
||||
<wa-card>
|
||||
<div class="wa-flank:end">
|
||||
<div class="wa-stack wa-gap-2xs">
|
||||
@@ -482,7 +481,7 @@ isPro: true
|
||||
<wa-icon name="plus"></wa-icon>
|
||||
Add Task
|
||||
</wa-button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wa-stack">
|
||||
@@ -509,17 +508,18 @@ isPro: true
|
||||
<wa-avatar initials="KK" label="Avatar with initials: KK"></wa-avatar>
|
||||
</div>
|
||||
</wa-card>
|
||||
|
||||
|
||||
|
||||
|
||||
<wa-button appearance="plain">
|
||||
<wa-icon name="plus"></wa-icon>
|
||||
Add Task
|
||||
</wa-button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
@@ -5,5 +5,4 @@ parent: patterns
|
||||
layout: overview
|
||||
override:tags: []
|
||||
listChildren: true
|
||||
isPro: false
|
||||
---
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Leaderboard
|
||||
description: 'Engage and motivate users by highlighting top performers, scores, and achievements.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Pagination
|
||||
description: 'Improve navigation and performance by breaking long lists or content into manageable pages.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Permissions
|
||||
description: 'Permission patterns provide or restrict access to users.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## With Form Inputs
|
||||
@@ -119,7 +118,7 @@ isPro: true
|
||||
<wa-button size="small" variant="brand" pill>Generate</wa-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</wa-card>
|
||||
```
|
||||
|
||||
@@ -171,7 +170,7 @@ isPro: true
|
||||
<wa-option value="moderator">Moderator</wa-option>
|
||||
<wa-option value="contributor">Contributor</wa-option>
|
||||
<wa-option value="reader">Reader</wa-option>
|
||||
</wa-select>
|
||||
</wa-select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -223,7 +222,7 @@ isPro: true
|
||||
</tbody>
|
||||
</table>
|
||||
</wa-tab-panel>
|
||||
|
||||
|
||||
</wa-tab-group>
|
||||
</div>
|
||||
```
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Pricing
|
||||
description: 'Help users make informed purchasing decisions with clear, structured pricing.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Three Tiers
|
||||
@@ -165,4 +164,4 @@ isPro: true
|
||||
</wa-callout>
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Blog
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
@@ -368,4 +367,4 @@ TODO Page Description
|
||||
}
|
||||
|
||||
</style>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Business
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Category Filter
|
||||
description: 'Helps the user find the right products with filters to refine search results by specific attributes.'
|
||||
icon: checkbox
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Sidebar with Checkboxes & Expandable Filters
|
||||
@@ -81,4 +80,4 @@ isPro: true
|
||||
</div>
|
||||
<div class="wa-placeholder"></div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Category Preview
|
||||
description: 'Help shoppers discover your product offerings with showcases of product categories.'
|
||||
icon: preview
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Split with Image Grid
|
||||
@@ -160,4 +159,4 @@ isPro: true
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Checkout Form
|
||||
description: 'Let shoppers checkout with ease with streamlined forms to capture shipping and payment info.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
|
||||
@@ -242,4 +241,4 @@ isPro: true
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Incentives
|
||||
description: 'Encourage shoppers to buy your products with value propositions, discounts, and promotions.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## 3 Column
|
||||
@@ -121,4 +120,4 @@ isPro: true
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -4,5 +4,4 @@ description: Pre-built product overviews, shopping carts, and more to help you b
|
||||
parent: patterns
|
||||
layout: overview
|
||||
override:tags: []
|
||||
isPro: false
|
||||
---
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Order History
|
||||
description: 'Empower your customers to view past purchases and track upcoming orders with comprehensive order histories.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## List
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Order Summary
|
||||
description: 'Give shoppers confidence in their purchases with summaries of everything included in their order.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple
|
||||
@@ -292,4 +291,4 @@ isPro: true
|
||||
</div>
|
||||
</wa-callout>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Product Lists
|
||||
description: 'Let shoppers browse and compare products with detailed lists of the products in your store.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Simple Grid with Ratings
|
||||
@@ -180,4 +179,4 @@ isPro: true
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Product Overview
|
||||
description: 'Showcase your products with overviews including images, ratings, features, options, and more.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Split with Image
|
||||
@@ -427,4 +426,4 @@ isPro: true
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Product Preview
|
||||
description: 'Give shoppers a quick look at your products as they browse with modal previews.'
|
||||
icon: preview
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## With Product Options
|
||||
@@ -158,4 +157,4 @@ isPro: true
|
||||
</div>
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Product Reviews
|
||||
description: 'Help shoppers make informed decisions with ratings, reviews, and testimonials from your customers.'
|
||||
isPro: true
|
||||
---
|
||||
## Multi column
|
||||
|
||||
@@ -209,4 +208,4 @@ isPro: true
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
</div>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Shopping Cart
|
||||
description: 'Give shoppers an overview of selected items with shopping carts that let them edit items and proceed to checkout.'
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Two Columns with Summary Card
|
||||
@@ -275,4 +274,4 @@ isPro: true
|
||||
</wa-button>
|
||||
</div>
|
||||
</wa-drawer>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Store Navigation
|
||||
description: 'Help shoppers explore categories and find products with all of the links they need to navigate your store.'
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
## Popup Menu
|
||||
@@ -82,4 +81,4 @@ isPro: true
|
||||
|
||||
|
||||
</style>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Business
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Entertainment
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -3,7 +3,6 @@ title: Patterns
|
||||
description: Patterns are reusable UI solutions to common design problems, ready to copy and paste into any project.
|
||||
layout: overview
|
||||
override:tags: []
|
||||
isPro: false
|
||||
---
|
||||
|
||||
<div class="max-line-length">
|
||||
@@ -22,7 +21,7 @@ Patterns are written as standard HTML, so you can use them just as you would any
|
||||
|
||||
To use a pattern in your project, refer to each pattern's docs for a copyable code snippet. Paste the snippet wherever you'd like the pattern to appear in your project.
|
||||
|
||||
Because patterns use a combination of Web Awesome features, they work best when you have [native styles](/docs/native), [style utilities](/docs/utilities), and a [theme](/docs/themes) installed in addition to Web Awesome [components](/docs/components). Refer to the [Installation page](/docs/) to set up all of these features in your project.
|
||||
Because patterns use a combination of Web Awesome features, they work best when you have [native styles](/docs/native), [style utilities](/docs/utilities), and a [theme](/docs/themes) installed in addition to Web Awesome [components](/docs/components). Refer to the [Installation page](/docs/installation) to set up all of these features in your project.
|
||||
|
||||
{% endmarkdown %}
|
||||
</div>
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Membership
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: News
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
@@ -158,4 +157,4 @@ TODO Page Description
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Non-profit
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
"layout": "patterns.njk",
|
||||
"tags": ["patterns"],
|
||||
"wide": true,
|
||||
"noAlpha": true,
|
||||
"isPro": true
|
||||
"noAlpha": true
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Portfolio
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
title: Product Landing
|
||||
description: TODO
|
||||
unlisted: true
|
||||
isPro: true
|
||||
---
|
||||
|
||||
TODO Page Description
|
||||
|
||||
## Examples
|
||||
## Examples
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
title: CSS Properties Benchmark
|
||||
unlisted: true
|
||||
wide: true
|
||||
---
|
||||
|
||||
{% set icons = {
|
||||
check: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>',
|
||||
'chevron-down': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>',
|
||||
'chevron-left': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/></svg>',
|
||||
'chevron-right': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>',
|
||||
circle: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/></svg>',
|
||||
'eye-dropper': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M341.6 29.2L240.1 130.8l-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4L482.8 170.4c39-39 39-102.2 0-141.1s-102.2-39-141.1 0zM55.4 323.3c-15 15-23.4 35.4-23.4 56.6v42.4L5.4 462.2c-8.5 12.7-6.8 29.6 4 40.4s27.7 12.5 40.4 4L89.7 480h42.4c21.2 0 41.6-8.4 56.6-23.4L309.4 335.9l-45.3-45.3L143.4 411.3c-3 3-7.1 4.7-11.3 4.7H96V379.9c0-4.2 1.7-8.3 4.7-11.3L221.4 247.9l-45.3-45.3L55.4 323.3z"/></svg>',
|
||||
'grip-vertical': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M40 352l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zm192 0l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 320c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 192l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 160c-22.1 0-40-17.9-40-40L0 72C0 49.9 17.9 32 40 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40z"/></svg>',
|
||||
indeterminate: '<svg part="indeterminate-icon" class="icon" viewBox="0 0 16 16"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"><g stroke="currentColor" stroke-width="2"><g transform="translate(2.285714, 6.857143)"><path d="M10.2857143,1.14285714 L1.14285714,1.14285714"></path></g></g></g></svg>',
|
||||
minus: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg>',
|
||||
pause: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z"/></svg>',
|
||||
play: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg>',
|
||||
star: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><path d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg>',
|
||||
user: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg>',
|
||||
xmark: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>'
|
||||
} %}
|
||||
|
||||
<style>
|
||||
.icon-tests {
|
||||
font-size: .5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
wa-icon {
|
||||
transition: 1s font-size;
|
||||
&:hover {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{% set repetitions = 200 %}
|
||||
|
||||
<h2>Setting everything via attributes</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}" variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting variant & family via CSS</h2>
|
||||
|
||||
<div class="icon-tests" style="--wa-icon-variant: regular; --wa-icon-family: classic">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting name via CSS</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
<span style="--wa-icon-name: {{ icon }}">
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
17
docs/docs/themes/remix.js
vendored
17
docs/docs/themes/remix.js
vendored
@@ -30,8 +30,8 @@ function init() {
|
||||
|
||||
codeSnippets = document.querySelector('#usage ~ wa-tab-group.import-stylesheet-code:first-of-type');
|
||||
codeSnippets = {
|
||||
html: codeSnippets?.querySelector('code.language-html'),
|
||||
css: codeSnippets?.querySelector('code.language-css'),
|
||||
html: codeSnippets.querySelector('code.language-html'),
|
||||
css: codeSnippets.querySelector('code.language-css'),
|
||||
};
|
||||
|
||||
data = {
|
||||
@@ -73,10 +73,11 @@ function init() {
|
||||
|
||||
Promise.all(Object.values(selects).map(select => select.updateComplete)).then(() => render());
|
||||
|
||||
globalThis.remixApp = { selects, codeSnippets, data, computed, render };
|
||||
return { selects, codeSnippets, data, computed, render };
|
||||
}
|
||||
|
||||
init();
|
||||
globalThis.remixApp = init();
|
||||
|
||||
// Async load CSS for other themes *before* current theme stylesheet
|
||||
let themeStylesheet = document.querySelector('#theme-stylesheet');
|
||||
|
||||
@@ -150,14 +151,12 @@ function render(changedAspect) {
|
||||
// Update code snippets
|
||||
for (let language in codeSnippets) {
|
||||
let codeSnippet = codeSnippets[language];
|
||||
if (!codeSnippet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let code = getThemeCode(data.baseTheme, data.params, { language, cdnUrl });
|
||||
codeSnippet.textContent = code;
|
||||
Prism.highlightElement(codeSnippet);
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('turbo:render', init);
|
||||
addEventListener('turbo:render', event => {
|
||||
remixApp = init();
|
||||
});
|
||||
|
||||
@@ -27,7 +27,6 @@ See your theme's focus ring in action by navigating this form example with your
|
||||
<style>
|
||||
form > * + * {
|
||||
display: block;
|
||||
--display: block;
|
||||
width: fit-content;
|
||||
margin-block-start: var(--wa-space-m);
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ layout: page
|
||||
</wa-callout>
|
||||
</div>
|
||||
<div>
|
||||
<wa-button href="/docs/" appearance="outlined" class="tile">
|
||||
<wa-button href="/docs/installation" appearance="outlined" class="tile">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-block-end: 1rem;">
|
||||
<div class="icon-heading" style="margin-block-end: 0;">
|
||||
<wa-icon name="pen-ruler" fixed-width></wa-icon>
|
||||
|
||||
27
package-lock.json
generated
27
package-lock.json
generated
@@ -10,13 +10,12 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@floating-ui/dom": "^1.6.12",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0",
|
||||
"style-observer": "^0.0.7"
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
@@ -1633,20 +1632,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.6.13",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
|
||||
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
|
||||
"license": "MIT",
|
||||
"version": "1.6.12",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
|
||||
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.6.0",
|
||||
"@floating-ui/utils": "^0.2.9"
|
||||
"@floating-ui/utils": "^0.2.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||
"license": "MIT"
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
|
||||
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
|
||||
},
|
||||
"node_modules/@github/catalyst": {
|
||||
"version": "1.6.0",
|
||||
@@ -13088,12 +13085,6 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/style-observer": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/style-observer/-/style-observer-0.0.7.tgz",
|
||||
"integrity": "sha512-t75H3CRy+vd5q3yqyrf/De4tkz33hPQTiCcfh0NTesI5G7kJnZ227LEYTwqjKTtaFOCJvqZcYFHpJlF8bsk3bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
|
||||
@@ -68,13 +68,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@floating-ui/dom": "^1.6.12",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0",
|
||||
"style-observer": "^0.0.7"
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
:host {
|
||||
color: var(--wa-color-text-link);
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
:host(:last-of-type) {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font: inherit;
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
@@ -8,10 +16,6 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:host(:last-of-type) {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
font: inherit;
|
||||
|
||||
@@ -17,6 +17,7 @@ import styles from './breadcrumb-item.css';
|
||||
* @slot separator - The separator to use for the breadcrumb item. This will only change the separator for this item. If
|
||||
* you want to change it for all items in the group, set the separator on `<wa-breadcrumb>` instead.
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
* @csspart label - The breadcrumb item's label.
|
||||
* @csspart prefix - The container that wraps the prefix.
|
||||
* @csspart suffix - The container that wraps the suffix.
|
||||
@@ -71,45 +72,47 @@ export default class WaBreadcrumbItem extends WebAwesomeElement {
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<span part="prefix" class="prefix">
|
||||
<slot name="prefix"></slot>
|
||||
</span>
|
||||
<div part="base" class="breadcrumb-item">
|
||||
<span part="prefix" class="prefix">
|
||||
<slot name="prefix"></slot>
|
||||
</span>
|
||||
|
||||
${this.renderType === 'link'
|
||||
? html`
|
||||
<a
|
||||
part="label"
|
||||
class="label label--link"
|
||||
href="${this.href!}"
|
||||
target="${ifDefined(this.target ? this.target : undefined)}"
|
||||
rel=${ifDefined(this.target ? this.rel : undefined)}
|
||||
>
|
||||
<slot></slot>
|
||||
</a>
|
||||
`
|
||||
: ''}
|
||||
${this.renderType === 'button'
|
||||
? html`
|
||||
<button part="label" type="button" class="label label--button">
|
||||
<slot @slotchange=${this.handleSlotChange}></slot>
|
||||
</button>
|
||||
`
|
||||
: ''}
|
||||
${this.renderType === 'dropdown'
|
||||
? html`
|
||||
<div part="label" class="label label--dropdown">
|
||||
<slot @slotchange=${this.handleSlotChange}></slot>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
${this.renderType === 'link'
|
||||
? html`
|
||||
<a
|
||||
part="label"
|
||||
class="label label--link"
|
||||
href="${this.href!}"
|
||||
target="${ifDefined(this.target ? this.target : undefined)}"
|
||||
rel=${ifDefined(this.target ? this.rel : undefined)}
|
||||
>
|
||||
<slot></slot>
|
||||
</a>
|
||||
`
|
||||
: ''}
|
||||
${this.renderType === 'button'
|
||||
? html`
|
||||
<button part="label" type="button" class="label label--button">
|
||||
<slot @slotchange=${this.handleSlotChange}></slot>
|
||||
</button>
|
||||
`
|
||||
: ''}
|
||||
${this.renderType === 'dropdown'
|
||||
? html`
|
||||
<div part="label" class="label label--dropdown">
|
||||
<slot @slotchange=${this.handleSlotChange}></slot>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
|
||||
<span part="suffix" class="suffix">
|
||||
<slot name="suffix"></slot>
|
||||
</span>
|
||||
<span part="suffix" class="suffix">
|
||||
<slot name="suffix"></slot>
|
||||
</span>
|
||||
|
||||
<span part="separator" class="separator" aria-hidden="true">
|
||||
<slot name="separator"></slot>
|
||||
</span>
|
||||
<span part="separator" class="separator" aria-hidden="true">
|
||||
<slot name="separator"></slot>
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
:host {
|
||||
--display: inline-flex;
|
||||
|
||||
display: contents;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:where([part~='base']) {
|
||||
all: inherit;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
/*
|
||||
* Label
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,6 @@ import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/button.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
@@ -40,7 +39,6 @@ import styles from './button.css';
|
||||
* @csspart caret - The button's caret icon, a `<wa-icon>` element.
|
||||
* @csspart spinner - The spinner that shows when the button is in the loading state.
|
||||
*
|
||||
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
|
||||
* @cssproperty --background-color - The button's background color when the button is not being interacted with.
|
||||
* @cssproperty --background-color-active - The button's background color when active.
|
||||
* @cssproperty --background-color-hover - The button's background color on hover.
|
||||
@@ -53,7 +51,7 @@ import styles from './button.css';
|
||||
*/
|
||||
@customElement('wa-button')
|
||||
export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static rectProxy = 'button';
|
||||
|
||||
static get validators() {
|
||||
|
||||
@@ -210,6 +210,12 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
/** Disables the color picker. */
|
||||
@property({ type: Boolean }) disabled = false;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/** Shows the opacity slider. Enabling this will cause the formatted value to be HEXA, RGBA, or HSLA. */
|
||||
@property({ type: Boolean }) opacity = false;
|
||||
|
||||
@@ -1091,6 +1097,7 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
aria-disabled=${this.disabled ? 'true' : 'false'}
|
||||
.containingElement=${this}
|
||||
?disabled=${this.disabled}
|
||||
?hoist=${this.hoist}
|
||||
@wa-after-show=${this.handleAfterShow}
|
||||
@wa-after-hide=${this.handleAfterHide}
|
||||
>
|
||||
|
||||
@@ -97,6 +97,13 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
/** The preferred placement of the tooltip. */
|
||||
@property({ attribute: 'tooltip-placement' }) tooltipPlacement: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the tooltip from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|hidden|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all,
|
||||
* scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
private async handleCopy() {
|
||||
if (this.disabled || this.isCopying) {
|
||||
return;
|
||||
@@ -213,6 +220,7 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
for="copy-button"
|
||||
placement=${this.tooltipPlacement}
|
||||
?disabled=${this.disabled}
|
||||
?hoist=${this.hoist}
|
||||
exportparts="
|
||||
base:tooltip__base,
|
||||
base__popup:tooltip__base__popup,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
:host {
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
--display: block;
|
||||
|
||||
display: contents !important;
|
||||
}
|
||||
|
||||
details {
|
||||
all: inherit;
|
||||
display: block;
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import { getTargetElement, waitForEvent } from '../../internal/event.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import nativeStyles from '../../styles/native/details.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
@@ -44,11 +43,10 @@ import styles from './details.css';
|
||||
* @cssproperty --spacing - The amount of space around and between the details' content. Expects a single value.
|
||||
* @cssproperty [--show-duration=200ms] - The show duration to use when applying built-in animation classes.
|
||||
* @cssproperty [--hide-duration=200ms] - The hide duration to use when applying built-in animation classes.
|
||||
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
|
||||
*/
|
||||
@customElement('wa-details')
|
||||
export default class WaDetails extends WebAwesomeElement {
|
||||
static shadowStyle = [passthroughStyles, appearanceStyles, nativeStyles, styles];
|
||||
static shadowStyle = [appearanceStyles, nativeStyles, styles];
|
||||
|
||||
private detailsObserver: MutationObserver;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@@ -95,6 +95,12 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
/** The distance in pixels from which to offset the panel along its trigger. */
|
||||
@property({ type: Number }) skidding = 0;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the panel from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/**
|
||||
* Syncs the popup width or height to that of the trigger element.
|
||||
*/
|
||||
@@ -409,6 +415,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
placement=${this.placement}
|
||||
distance=${this.distance}
|
||||
skidding=${this.skidding}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
auto-size="vertical"
|
||||
|
||||
@@ -48,21 +48,21 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
@state() private svg: SVGElement | HTMLTemplateResult | null = null;
|
||||
|
||||
/** The name of the icon to draw. Available names depend on the icon library being used. */
|
||||
@property({ cssProperty: '--wa-icon-name' }) name?: string;
|
||||
@property({ reflect: true }) name?: string;
|
||||
|
||||
/**
|
||||
* The family of icons to choose from. For Font Awesome Free (default), valid options include `classic` and `brands`.
|
||||
* For Font Awesome Pro subscribers, valid options include, `classic`, `sharp`, `duotone`, and `brands`. Custom icon
|
||||
* libraries may or may not use this property.
|
||||
*/
|
||||
@property({ cssProperty: '--wa-icon-family' }) family: string;
|
||||
@property({ reflect: true }) family: string;
|
||||
|
||||
/**
|
||||
* The name of the icon's variant. For Font Awesome, valid options include `thin`, `light`, `regular`, and `solid` for
|
||||
* the `classic` and `sharp` families. Some variants require a Font Awesome Pro subscription. Custom icon libraries
|
||||
* may or may not use this property.
|
||||
*/
|
||||
@property({ cssProperty: '--wa-icon-variant' }) variant: string;
|
||||
@property({ reflect: true }) variant: string;
|
||||
|
||||
/** Draws the icon in a fixed-width both. */
|
||||
@property({ attribute: 'fixed-width', type: Boolean, reflect: true }) fixedWidth: false;
|
||||
@@ -80,16 +80,14 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
@property() label = '';
|
||||
|
||||
/** The name of a registered custom icon library. */
|
||||
@property({ cssProperty: '--wa-icon-library', default: 'default' }) library = 'default';
|
||||
@property({ reflect: true }) library = 'default';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
watchIcon(this);
|
||||
}
|
||||
|
||||
firstUpdated(changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties);
|
||||
firstUpdated() {
|
||||
this.initialRender = true;
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image-comparer {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -23,6 +23,7 @@ import styles from './image-comparer.css';
|
||||
*
|
||||
* @event change - Emitted when the position changes.
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
* @csspart before - The container that wraps the before image.
|
||||
* @csspart after - The container that wraps the after image.
|
||||
* @csspart divider - The divider that separates the images.
|
||||
@@ -39,18 +40,19 @@ export default class WaImageComparer extends WebAwesomeElement {
|
||||
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.image-comparer') base: HTMLElement;
|
||||
@query('.handle') handle: HTMLElement;
|
||||
|
||||
/** The position of the divider as a percentage. */
|
||||
@property({ type: Number, reflect: true }) position = 50;
|
||||
|
||||
private handleDrag(event: PointerEvent) {
|
||||
const { width } = this.getBoundingClientRect();
|
||||
const { width } = this.base.getBoundingClientRect();
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
drag(this, {
|
||||
drag(this.base, {
|
||||
onMove: x => {
|
||||
this.position = parseFloat(clamp((x / width) * 100, 0, 100).toFixed(2));
|
||||
if (isRtl) this.position = 100 - this.position;
|
||||
@@ -96,45 +98,46 @@ export default class WaImageComparer extends WebAwesomeElement {
|
||||
const isRtl = this.hasUpdated ? this.localize.dir() === 'rtl' : this.dir === 'rtl';
|
||||
|
||||
return html`
|
||||
<div class="image">
|
||||
<div part="before" class="before">
|
||||
<slot name="before"></slot>
|
||||
<div part="base" id="image-comparer" class="image-comparer" @keydown=${this.handleKeyDown}>
|
||||
<div class="image">
|
||||
<div part="before" class="before">
|
||||
<slot name="before"></slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
part="after"
|
||||
class="after"
|
||||
style=${styleMap({
|
||||
clipPath: isRtl ? `inset(0 0 0 ${100 - this.position}%)` : `inset(0 ${100 - this.position}% 0 0)`,
|
||||
})}
|
||||
>
|
||||
<slot name="after"></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
part="after"
|
||||
class="after"
|
||||
part="divider"
|
||||
class="divider"
|
||||
style=${styleMap({
|
||||
clipPath: isRtl ? `inset(0 0 0 ${100 - this.position}%)` : `inset(0 ${100 - this.position}% 0 0)`,
|
||||
left: isRtl ? `${100 - this.position}%` : `${this.position}%`,
|
||||
})}
|
||||
@mousedown=${this.handleDrag}
|
||||
@touchstart=${this.handleDrag}
|
||||
>
|
||||
<slot name="after"></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
part="divider"
|
||||
class="divider"
|
||||
style=${styleMap({
|
||||
left: isRtl ? `${100 - this.position}%` : `${this.position}%`,
|
||||
})}
|
||||
@keydown=${this.handleKeyDown}
|
||||
@mousedown=${this.handleDrag}
|
||||
@touchstart=${this.handleDrag}
|
||||
>
|
||||
<div
|
||||
part="handle"
|
||||
class="handle"
|
||||
role="scrollbar"
|
||||
aria-valuenow=${this.position}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
aria-controls="image-comparer"
|
||||
tabindex="0"
|
||||
>
|
||||
<slot name="handle">
|
||||
<wa-icon library="system" name="grip-vertical" variant="solid"></wa-icon>
|
||||
</slot>
|
||||
<div
|
||||
part="handle"
|
||||
class="handle"
|
||||
role="scrollbar"
|
||||
aria-valuenow=${this.position}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
aria-controls="image-comparer"
|
||||
tabindex="0"
|
||||
>
|
||||
<slot name="handle">
|
||||
<wa-icon library="system" name="grip-vertical" variant="solid"></wa-icon>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -275,6 +275,7 @@ export class SubmenuController implements ReactiveController {
|
||||
flip
|
||||
flip-fallback-strategy="best-fit"
|
||||
skidding="${this.skidding}"
|
||||
strategy="fixed"
|
||||
auto-size="vertical"
|
||||
auto-size-padding="10"
|
||||
>
|
||||
|
||||
@@ -19,19 +19,6 @@
|
||||
isolation: isolate;
|
||||
max-width: var(--auto-size-available-width, none);
|
||||
max-height: var(--auto-size-available-height, none);
|
||||
|
||||
/* Clear UA styles for [popover] */
|
||||
:where(&) {
|
||||
inset: unset;
|
||||
padding: unset;
|
||||
margin: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
color: unset;
|
||||
background: unset;
|
||||
border: unset;
|
||||
overflow: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.popup--fixed {
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
import {
|
||||
arrow,
|
||||
autoUpdate,
|
||||
computePosition,
|
||||
flip,
|
||||
getOverflowAncestors,
|
||||
offset,
|
||||
platform,
|
||||
shift,
|
||||
size,
|
||||
} from '@floating-ui/dom';
|
||||
import { arrow, autoUpdate, computePosition, flip, offset, platform, shift, size } from '@floating-ui/dom';
|
||||
import { offsetParent } from 'composed-offset-position';
|
||||
import type { PropertyValues } from 'lit';
|
||||
import { html } from 'lit';
|
||||
@@ -33,8 +23,6 @@ function isVirtualElement(e: unknown): e is VirtualElement {
|
||||
);
|
||||
}
|
||||
|
||||
const SUPPORTS_POPOVER = globalThis?.HTMLElement?.prototype.hasOwnProperty('popover');
|
||||
|
||||
/**
|
||||
* @summary Popup is a utility that lets you declaratively anchor "popup" containers to another element.
|
||||
* @documentation https://backers.webawesome.com/docs/components/popup
|
||||
@@ -109,8 +97,11 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
| 'left-start'
|
||||
| 'left-end' = 'top';
|
||||
|
||||
/** Which bounding box to use for flipping, shifting, and auto-sizing? */
|
||||
@property() boundary: 'viewport' | 'scroll' = 'viewport';
|
||||
/**
|
||||
* Determines how the popup is positioned. The `absolute` strategy works well in most cases, but if overflow is
|
||||
* clipped, using a `fixed` position strategy can often workaround it.
|
||||
*/
|
||||
@property({ reflect: true }) strategy: 'absolute' | 'fixed' = 'absolute';
|
||||
|
||||
/** The distance in pixels from which to offset the panel away from its anchor. */
|
||||
@property({ type: Number }) distance = 0;
|
||||
@@ -290,8 +281,6 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
return;
|
||||
}
|
||||
|
||||
this.popup.showPopover?.();
|
||||
|
||||
this.cleanup = autoUpdate(this.anchorEl, this.popup, () => {
|
||||
this.reposition();
|
||||
});
|
||||
@@ -299,8 +288,6 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
|
||||
private async stop(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.popup.hidePopover?.();
|
||||
|
||||
if (this.cleanup) {
|
||||
this.cleanup();
|
||||
this.cleanup = undefined;
|
||||
@@ -347,21 +334,11 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
this.popup.style.height = '';
|
||||
}
|
||||
|
||||
let defaultBoundary;
|
||||
|
||||
if (SUPPORTS_POPOVER && !isVirtualElement(this.anchor) && this.boundary === 'scroll') {
|
||||
// When using the Popover API, the floating element is no longer in the same DOM context
|
||||
// as the overflow ancestors so Floating-UI can't find them.
|
||||
// For flip, `elementContext: 'reference'` gets it to use the anchor element instead,
|
||||
// but the option is not available for shift() or size(), so we basically need to implement it ourselves.
|
||||
defaultBoundary = getOverflowAncestors(this.anchorEl as Element).filter(el => el instanceof Element);
|
||||
}
|
||||
|
||||
// Then we flip
|
||||
if (this.flip) {
|
||||
middleware.push(
|
||||
flip({
|
||||
boundary: this.flipBoundary || defaultBoundary,
|
||||
boundary: this.flipBoundary,
|
||||
// @ts-expect-error - We're converting a string attribute to an array here
|
||||
fallbackPlacements: this.flipFallbackPlacements,
|
||||
fallbackStrategy: this.flipFallbackStrategy === 'best-fit' ? 'bestFit' : 'initialPlacement',
|
||||
@@ -374,7 +351,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
if (this.shift) {
|
||||
middleware.push(
|
||||
shift({
|
||||
boundary: this.shiftBoundary || defaultBoundary,
|
||||
boundary: this.shiftBoundary,
|
||||
padding: this.shiftPadding,
|
||||
}),
|
||||
);
|
||||
@@ -384,7 +361,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
if (this.autoSize) {
|
||||
middleware.push(
|
||||
size({
|
||||
boundary: this.autoSizeBoundary || defaultBoundary,
|
||||
boundary: this.autoSizeBoundary,
|
||||
padding: this.autoSizePadding,
|
||||
apply: ({ availableWidth, availableHeight }) => {
|
||||
if (this.autoSize === 'vertical' || this.autoSize === 'both') {
|
||||
@@ -422,14 +399,15 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
//
|
||||
// More info: https://github.com/shoelace-style/shoelace/issues/1135
|
||||
//
|
||||
const getOffsetParent = SUPPORTS_POPOVER
|
||||
? (element: Element) => platform.getOffsetParent(element, offsetParent)
|
||||
: platform.getOffsetParent;
|
||||
const getOffsetParent =
|
||||
this.strategy === 'absolute'
|
||||
? (element: Element) => platform.getOffsetParent(element, offsetParent)
|
||||
: platform.getOffsetParent;
|
||||
|
||||
computePosition(this.anchorEl, this.popup, {
|
||||
placement: this.placement,
|
||||
middleware,
|
||||
strategy: SUPPORTS_POPOVER ? 'absolute' : 'fixed',
|
||||
strategy: this.strategy,
|
||||
platform: {
|
||||
...platform,
|
||||
getOffsetParent,
|
||||
@@ -585,12 +563,11 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
></span>
|
||||
|
||||
<div
|
||||
popover="manual"
|
||||
part="popup"
|
||||
class=${classMap({
|
||||
popup: true,
|
||||
'popup--active': this.active,
|
||||
'popup--fixed': !SUPPORTS_POPOVER,
|
||||
'popup--fixed': this.strategy === 'fixed',
|
||||
'popup--has-arrow': this.arrow,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
:host {
|
||||
--indicator-color: var(--wa-color-brand-fill-loud);
|
||||
--display: flex;
|
||||
|
||||
display: contents;
|
||||
height: 1.25rem;
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
@@ -9,6 +9,8 @@
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
all: inherit;
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { customElement, property } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { clamp } from '../../internal/math.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import styles from './progress-bar.css';
|
||||
|
||||
@@ -21,11 +20,10 @@ import styles from './progress-bar.css';
|
||||
* @csspart label - The progress bar's label.
|
||||
*
|
||||
* @cssproperty --indicator-color - The color of the indicator.
|
||||
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
|
||||
*/
|
||||
@customElement('wa-progress-bar')
|
||||
export default class WaProgressBar extends WebAwesomeElement {
|
||||
static shadowStyle = [passthroughStyles, styles];
|
||||
static shadowStyle = styles;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
/** The current progress as a percentage, 0 to 100. */
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
:host {
|
||||
--display: inline-flex;
|
||||
display: contents;
|
||||
}
|
||||
|
||||
:where([part~='base']) {
|
||||
all: inherit;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.prefix,
|
||||
|
||||
@@ -6,7 +6,6 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/button.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
@@ -46,11 +45,10 @@ import styles from './radio-button.css';
|
||||
* @csspart prefix - The container that wraps the prefix.
|
||||
* @csspart label - The container that wraps the radio button's label.
|
||||
* @csspart suffix - The container that wraps the suffix.
|
||||
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
|
||||
*/
|
||||
@customElement('wa-radio-button')
|
||||
export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static rectProxy = 'input';
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
||||
|
||||
@@ -356,7 +356,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
part="form-control-input"
|
||||
class=${classMap({
|
||||
'wa-button-group': this.hasRadioButtons,
|
||||
'wa-button-group-vertical': this.hasRadioButtons && this.orientation === 'vertical',
|
||||
'wa-button-group-vertical': this.orientation === 'vertical',
|
||||
})}
|
||||
@slotchange=${this.syncRadioElements}
|
||||
></slot>
|
||||
|
||||
@@ -229,6 +229,12 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
*/
|
||||
@property({ type: Boolean, reflect: true }) open = false;
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the listbox from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
/** The select's visual appearance. */
|
||||
@property({ reflect: true }) appearance: 'filled' | 'outlined' = 'outlined';
|
||||
|
||||
@@ -885,6 +891,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
'placeholder-visible': isPlaceholderVisible,
|
||||
})}
|
||||
placement=${this.placement}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
sync="width"
|
||||
|
||||
@@ -92,6 +92,13 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
*/
|
||||
@property() trigger = 'hover focus';
|
||||
|
||||
/**
|
||||
* Enable this option to prevent the tooltip from being clipped when the component is placed inside a container with
|
||||
* `overflow: auto|hidden|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all,
|
||||
* scenarios.
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
@property() for: string | null = null;
|
||||
|
||||
@state() anchor: null | Element = null;
|
||||
@@ -283,7 +290,7 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.anchor = newAnchor;
|
||||
}
|
||||
|
||||
@watch(['distance', 'placement', 'skidding'])
|
||||
@watch(['distance', 'hoist', 'placement', 'skidding'])
|
||||
async handleOptionsChange() {
|
||||
if (this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
@@ -333,6 +340,7 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
placement=${this.placement}
|
||||
distance=${this.distance}
|
||||
skidding=${this.skidding}
|
||||
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
||||
flip
|
||||
shift
|
||||
arrow
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import type { CSSResult, CSSResultGroup, PropertyDeclaration, PropertyValues } from 'lit';
|
||||
import { LitElement, defaultConverter, isServer, unsafeCSS } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { ElementStyleObserver } from 'style-observer';
|
||||
import componentStyles from '../styles/shadow/component.css';
|
||||
import { getComputedStyle } from './computedStyle.js';
|
||||
|
||||
// Augment Lit's module
|
||||
declare module 'lit' {
|
||||
@@ -13,11 +11,6 @@ declare module 'lit' {
|
||||
*/
|
||||
default?: any;
|
||||
initial?: any;
|
||||
|
||||
/**
|
||||
* Indicates whether the property should reflect to a CSS custom property.
|
||||
*/
|
||||
cssProperty?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,99 +72,6 @@ export default class WebAwesomeElement extends LitElement {
|
||||
|
||||
internals: ElementInternals;
|
||||
|
||||
/** Metadata about CSS-settable props on this element */
|
||||
private cssProps: Record<PropertyKey, { setVia?: 'css' | 'attribute' | 'js'; updating?: boolean }> = {};
|
||||
private computedStyle: CSSStyleDeclaration | null = null;
|
||||
private styleObserver: ElementStyleObserver | null = null;
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
// Set the initial computed styles
|
||||
const Self = this.constructor as typeof WebAwesomeElement;
|
||||
let cssProps = Object.keys(Self.cssProps);
|
||||
|
||||
if (cssProps.length > 0) {
|
||||
let properties: string[] = [];
|
||||
|
||||
if (Object.keys(this.cssProps).length === 0) {
|
||||
// First time connected, initialize
|
||||
this.cssProps = Object.fromEntries(
|
||||
cssProps.map(property => {
|
||||
let setVia = this.getSetVia(property);
|
||||
return [property, { setVia }];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
for (let property in this.cssProps) {
|
||||
let setVia = this.cssProps[property].setVia;
|
||||
if (!setVia || setVia === 'css') {
|
||||
// No attribute set, observe CSS property
|
||||
properties.push(property);
|
||||
}
|
||||
}
|
||||
|
||||
this.handleCSSPropertyChange(properties);
|
||||
|
||||
this.styleObserver ??= new ElementStyleObserver(this, (records: object[]) => {
|
||||
let cssProperties = new Set(records.map((record: { property: string }) => record.property));
|
||||
|
||||
// Map CSS properties to prop names
|
||||
let properties = cssProps.filter(property => {
|
||||
let cssProperty = Self.cssProps[property].cssProperty as string;
|
||||
return cssProperties.has(cssProperty);
|
||||
});
|
||||
|
||||
this.handleCSSPropertyChange(properties);
|
||||
});
|
||||
this.styleObserver.unobserve();
|
||||
this.styleObserver.observe(properties.map(property => Self.cssProps[property].cssProperty as string));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to CSS property changes for CSS properties reflecting props
|
||||
* @param [properties] - Prop names. Defaults to all CSS-reflected props.
|
||||
* @void
|
||||
*/
|
||||
handleCSSPropertyChange(properties?: PropertyKey | PropertyKey[]) {
|
||||
const Self = this.constructor as typeof WebAwesomeElement;
|
||||
|
||||
properties ??= Object.keys(Self.cssProps);
|
||||
properties = Array.isArray(properties) ? properties : [properties];
|
||||
|
||||
if (properties.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.computedStyle ??= getComputedStyle(this);
|
||||
|
||||
for (let property of properties) {
|
||||
let propOptions = Self.cssProps[property];
|
||||
let cssProperty = propOptions?.cssProperty;
|
||||
let meta = this.cssProps[property];
|
||||
|
||||
if (!cssProperty || (meta.setVia && meta.setVia !== 'css')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = this.computedStyle?.getPropertyValue(cssProperty);
|
||||
// if (property === 'variant' && !value) debugger;
|
||||
|
||||
if (value) {
|
||||
meta.setVia = 'css';
|
||||
meta.updating = true;
|
||||
// @ts-ignore
|
||||
this[property] = value.trim();
|
||||
|
||||
this.updateComplete.then(() => {
|
||||
meta.updating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
|
||||
if (!this.#hasRecordedInitialProperties) {
|
||||
(this.constructor as typeof WebAwesomeElement).elementProperties.forEach(
|
||||
@@ -215,50 +115,6 @@ export default class WebAwesomeElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get how a prop was set
|
||||
* @param property - The property to check
|
||||
*/
|
||||
private getSetVia(property: PropertyKey): 'css' | 'js' | 'attribute' | undefined {
|
||||
let Self = this.constructor as typeof WebAwesomeElement;
|
||||
let setVia;
|
||||
let propOptions = Self.cssProps[property];
|
||||
let attribute = typeof propOptions.attribute === 'string' ? propOptions.attribute : (property as string);
|
||||
|
||||
if (propOptions.attribute !== false && this.hasAttribute(attribute)) {
|
||||
setVia = 'attribute';
|
||||
} else {
|
||||
// @ts-ignore
|
||||
let value = this[property as PropertyKey];
|
||||
if (value !== undefined && value !== propOptions.default) {
|
||||
setVia = 'js';
|
||||
}
|
||||
}
|
||||
|
||||
return setVia as 'attribute' | 'js' | 'css' | undefined;
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
let Self = this.constructor as typeof WebAwesomeElement;
|
||||
let cssProps = Object.keys(Self.cssProps);
|
||||
|
||||
if (cssProps.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let [property] of changedProperties) {
|
||||
let meta = this.cssProps[property];
|
||||
|
||||
if (meta && typeof property === 'string' && !(meta.setVia === 'css' && meta.updating)) {
|
||||
// A prop is being set via JS or an attribute that was previously set via CSS
|
||||
// and it's not because we're in the middle of an update
|
||||
meta.setVia = this.getSetVia(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected update(changedProperties: PropertyValues<this>): void {
|
||||
try {
|
||||
super.update(changedProperties);
|
||||
@@ -374,11 +230,6 @@ export default class WebAwesomeElement extends LitElement {
|
||||
*/
|
||||
static rectProxy: undefined | string;
|
||||
|
||||
/**
|
||||
* Props that can be set via CSS custom properties
|
||||
*/
|
||||
static cssProps: Record<PropertyKey, PropertyDeclaration> = {};
|
||||
|
||||
static createProperty(name: PropertyKey, options?: PropertyDeclaration): void {
|
||||
if (options) {
|
||||
if (options.initial !== undefined && options.default === undefined) {
|
||||
@@ -405,18 +256,8 @@ export default class WebAwesomeElement extends LitElement {
|
||||
|
||||
super.createProperty(name, options);
|
||||
|
||||
// Wrap the default accessor with logic to return the default value if the value is null
|
||||
if (options) {
|
||||
if (options.cssProperty) {
|
||||
// Add to the set of CSS-settable props
|
||||
if (this.cssProps === WebAwesomeElement.cssProps) {
|
||||
// Each class needs its own, otherwise they'd share the same object
|
||||
this.cssProps = {};
|
||||
}
|
||||
|
||||
this.cssProps[name] = options;
|
||||
}
|
||||
|
||||
// Wrap the default accessor with logic to return the default value if the value is null
|
||||
if (options.default !== undefined) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(this.prototype, name as string);
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Styles for elements that need to use display: contents on the host to enable styling with regular CSS properties (see #207, #259).
|
||||
* To use, make sure that the element that needs to inherit properties set on the host has a part of base or a class of .styling-host.
|
||||
*/
|
||||
@property --display {
|
||||
syntax: '*';
|
||||
inherits: false;
|
||||
}
|
||||
|
||||
:host {
|
||||
display: contents !important;
|
||||
}
|
||||
|
||||
:where([part~='base'], .styling-host) {
|
||||
all: inherit;
|
||||
|
||||
/* Add any non-inherited custom properties here, as all: inherit won't cover them */
|
||||
--display: inherit;
|
||||
|
||||
display: var(--display, inline);
|
||||
}
|
||||
|
||||
:host([hidden]) {
|
||||
display: none !important;
|
||||
}
|
||||
Reference in New Issue
Block a user