Compare commits

..

154 Commits

Author SHA1 Message Date
Kelsey Jackson
3a0f7751f4 added time componen to reviews 2025-04-09 15:19:13 -05:00
Kelsey Jackson
b7ed832554 clean up a few e-commerce patterns 2025-04-09 11:02:24 -05:00
Kelsey Jackson
aa6a875d01 updated a few patterns 2025-04-08 10:58:13 -05:00
Kelsey Jackson
48412f9672 added content to data display 2025-04-07 09:49:16 -05:00
Kelsey Jackson
cb1f9c8b48 gave the action panels a once over 2025-04-07 09:07:16 -05:00
Kelsey Jackson
2e072fac3b spiffed up the action panels 2025-04-07 09:00:45 -05:00
Kelsey Jackson
bdd4c3ec9a took out info patterns 2025-04-04 12:22:28 -05:00
Kelsey Jackson
3b30f9f39e Merge pull request #859 from shoelace-style/kj/patterns-home-stretch
Kj/patterns home stretch
2025-04-04 12:17:39 -05:00
Kelsey Jackson
1999b65591 a few more app patterns 2025-04-04 12:16:21 -05:00
Kelsey Jackson
444e0d3e46 having local browset issues 2025-04-04 11:10:40 -05:00
Kelsey Jackson
5aeedceb2d added post articles 2025-04-03 21:53:50 -05:00
Kelsey Jackson
1e1cd2406e switching machines 2025-04-03 19:14:19 -05:00
Kelsey Jackson
e72f2c1847 added permissions pattern 2025-04-03 09:47:12 -05:00
Kelsey Jackson
910c6cb3fb Merge branch 'pattern-main' into kj/patterns-home-stretch 2025-04-02 17:24:17 -05:00
Kelsey Jackson
55edcd2470 Merge branch 'next' into pattern-main 2025-04-02 17:23:49 -05:00
Kelsey Jackson
952a44b5eb catching up with next 2025-04-02 17:23:06 -05:00
Kelsey Jackson
2ca8422bc8 switching machines 2025-04-02 16:05:09 -05:00
Kelsey Jackson
beb88fac56 fixed conflicts 2025-04-01 13:00:16 -05:00
Lindsay M
a588194b95 App pattern tweaks (#827)
* Fix `patterns.css` reference

* Tweaks to action panel patterns

* Tweaks to comments patterns

* Progress on data display patterns

* Progress on empty state patterns

* Use email-related data from recent update in `pattern-main` (altered slightly)

* Tweaks to data display patterns

* Tweaks to empty state patterns

* Tweaks to FAQ patterns

* Tweaks to feed patterns

* Tweaks to grid patterns

* Tweaks to pagination patterns

* Tweaks to pricing patterns

* Tweaks to description list patterns

* Tweaks to leaderboard patterns

* Add and update names and descriptions

* Ensure comments fields have labels

* Tweak recent additions
2025-04-01 13:45:26 -04:00
Kelsey Jackson
a1ba80fe8d add more app patterns 2025-04-01 00:36:12 -05:00
Kelsey Jackson
a3edcaf27d added a few more 2025-03-30 23:54:39 -05:00
Kelsey Jackson
595c40c0fa Merge pull request #820 from shoelace-style/kj/info-patterns
got three done
2025-03-28 04:18:46 -05:00
Kelsey Jackson
7e2f32a965 a few more 2025-03-28 04:17:12 -05:00
Kelsey Jackson
7b3bd8e027 fixed conflicts 2025-03-28 01:58:11 -05:00
Kelsey Jackson
5711819e9c Merge pull request #847 from shoelace-style/kj/pattern-additions
reworked feeds'
2025-03-28 01:55:02 -05:00
Kelsey Jackson
760c09781d reworked feeds' 2025-03-28 01:52:57 -05:00
Kelsey Jackson
5b59bee2ff added login patterns 2025-03-27 22:50:00 -05:00
Kelsey Jackson
ec1ffcefdc some newsletter signups 2025-03-27 15:35:18 -05:00
Lea Verou
d828dd3600 Use overviews in pattern subcategories (#826)
* Do not error if no pages

* Automatically set parents and tags for patterns

* Update overview.njk

* [WIP] Use overview pages for pattern listings

* Remove explicit parents

---------

Co-authored-by: lindsaym-fa <dev@lindsaym.design>
2025-03-26 15:22:48 -04:00
lindsaym-fa
0984cde1c5 Merge branch 'next' into pattern-main 2025-03-26 15:14:42 -04:00
Kelsey Jackson
5edad481f0 Merge branch 'kj/info-patterns' of github.com:shoelace-style/webawesome into kj/info-patterns 2025-03-26 13:49:29 -05:00
Kelsey Jackson
aab221dcb1 initial paywalls 2025-03-26 13:49:23 -05:00
lindsaym-fa
bbe6b4c6b3 Quick formatting adjustment 2025-03-24 16:45:19 -04:00
Kelsey Jackson
6ee5c27b9d updated social share 2025-03-24 14:24:26 -05:00
Lea Verou
c3af1174ca Merge branch 'next' into pattern-main 2025-03-21 17:43:21 -04:00
Kelsey Jackson
db5b967390 Merge pull request #822 from shoelace-style/kj/pattern-polish
a little cleanup and adding detail
2025-03-21 10:45:55 -05:00
Kelsey Jackson
8e3ffc4abe got three done 2025-03-20 17:16:22 -05:00
Kelsey Jackson
b5523c33b7 a little cleanup and adding detail 2025-03-19 17:17:02 -05:00
Kelsey Jackson
f031cab138 splitting up the old blog page 2025-03-19 12:09:42 -05:00
Kelsey Jackson
67c46a21dd created info category 2025-03-18 18:56:23 -05:00
Kelsey Jackson
c310ee1072 Merge pull request #804 from shoelace-style/kj/pattern-sidebar
Kj/pattern sidebar
2025-03-18 13:40:39 -05:00
Kelsey Jackson
8fff50d3d8 updated sidebar 2025-03-18 13:28:41 -05:00
Kelsey Jackson
944f9002c7 working on sidebar 2025-03-18 09:38:39 -05:00
Kelsey Jackson
eba2a75ffb Merge pull request #775 from shoelace-style/kj/app-pattern
App Patterns
2025-03-14 16:04:09 -05:00
Kelsey Jackson
c3de5a8915 removed old file 2025-03-14 16:02:39 -05:00
Kelsey Jackson
c18aa23d76 merging pattern-maiin 2025-03-14 16:00:32 -05:00
Kelsey Jackson
54e14a20c0 Merge pull request #703 from shoelace-style/kj/e-commerce-patterns
Kj/e commerce patterns
2025-03-14 15:57:58 -05:00
Kelsey Jackson
97b8e96a6e Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-03-14 15:56:08 -05:00
Kelsey Jackson
55a362b741 Merge branch 'pattern-main' into kj/app-pattern 2025-03-14 15:55:45 -05:00
Kelsey Jackson
d9cafdafb7 Merge branch 'next' into pattern-main 2025-03-14 15:55:15 -05:00
Kelsey Jackson
81bf6865ec big switchover 2025-03-14 06:10:40 -05:00
lindsaym-fa
873eb47d18 Clean up utility usage and code formatting for product previews 2025-03-11 17:20:07 -04:00
lindsaym-fa
a564d3061f Clean up utility usage and code formatting for order summaries 2025-03-11 14:22:04 -04:00
Kelsey Jackson
ef865396f2 switching machines
:
2025-03-11 09:26:58 -05:00
Kelsey Jackson
903085257d removed store navigation 2025-03-07 11:12:39 -06:00
Kelsey Jackson
27237441a1 some heavy duty updates 2025-03-07 10:59:24 -06:00
Kelsey Jackson
b0291653f8 more polish 2025-03-06 22:43:13 -06:00
Kelsey Jackson
3962c50844 added review variant 2025-03-06 12:59:44 -06:00
Kelsey Jackson
314801c368 updated reviews 2025-03-05 16:40:36 -06:00
Kelsey Jackson
dc30ed8503 updated incentive images 2025-03-05 16:37:49 -06:00
lindsaym-fa
e12be798b8 Clean up utilities and formatting, replace placeholder text in order history 2025-03-04 14:30:00 -05:00
Kelsey Jackson
7f29f1b4ea started updating with style utilities 2025-03-04 13:09:41 -06:00
lindsaym-fa
3563d6a2dd Clean up utility usage and code formatting for category previews 2025-03-04 12:14:48 -05:00
Kelsey Jackson
007d93077f updated incentives 2025-03-04 11:04:31 -06:00
Kelsey Jackson
80b78aeb16 Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-03-04 10:14:31 -06:00
Kelsey Jackson
8bc8ea85a5 Merge branch 'next' into pattern-main 2025-03-04 10:14:14 -06:00
Kelsey Jackson
61a6cd9fb9 updated image 2025-03-03 14:46:54 -06:00
Kelsey Jackson
7fb3fd5982 updated product preview 2025-03-03 14:22:45 -06:00
Kelsey Jackson
dc580b3351 committing to pull down changes 2025-03-03 10:38:10 -06:00
lindsaym-fa
74719d4c06 Refactor shopping cart patterns 2025-02-28 15:46:06 -05:00
Kelsey Jackson
47a7cdedd0 switching machines 2025-02-28 09:37:05 -06:00
lindsaym-fa
d906940726 Refactor product overview patterns 2025-02-27 17:04:10 -05:00
Kelsey Jackson
a782470c6a more polish 2025-02-27 11:47:56 -06:00
lindsaym-fa
de175ed4a1 Refactor product list patterns 2025-02-26 11:39:41 -05:00
lindsaym-fa
3612f8fdfa Add link style utilities 2025-02-26 11:39:11 -05:00
Kelsey Jackson
bc76df4b31 switching machines 2025-02-26 07:31:36 -06:00
lindsaym-fa
9ad7f4a6be Reorganize app patterns into separate pages 2025-02-25 12:02:29 -05:00
Kelsey Jackson
a7457630aa inital commit 2025-02-24 16:45:27 -06:00
Kelsey Jackson
e19928123f Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-02-24 11:05:08 -06:00
Kelsey Jackson
e644862f58 Merge branch 'next' into pattern-main 2025-02-24 11:04:45 -06:00
Kelsey Jackson
76529c628e committing to bring branches up to next 2025-02-24 11:04:07 -06:00
Kelsey Jackson
62ded7b15a updated order history 2025-02-21 15:27:43 -06:00
Kelsey Jackson
65af9980f1 updated content for category preview 2025-02-21 10:08:33 -06:00
Kelsey Jackson
db592194fd updtated content 2025-02-21 09:45:19 -06:00
Kelsey Jackson
0f9ea14033 unlisted links 2025-02-19 11:12:05 -06:00
Kelsey Jackson
057b76a10a created e-commerce index 2025-02-19 10:09:42 -06:00
Kelsey Jackson
b466ba9d0f Merge pull request #748 from shoelace-style/lm/ecommerce-patterns-revisions
Suggested Revisions to E-commerce Patterns
2025-02-18 13:34:45 -06:00
Kelsey Jackson
9c979931da fixed conflicts 2025-02-18 13:33:46 -06:00
Kelsey Jackson
898311590a switching branches to merge 2025-02-18 13:31:53 -06:00
Kelsey Jackson
5f4510f355 more tweaks 2025-02-18 09:56:49 -06:00
Kelsey Jackson
b8eeb3db23 a little more polish 2025-02-14 07:42:36 -06:00
lindsaym-fa
8574270340 Add checkout form example 2025-02-13 23:06:50 -05:00
lindsaym-fa
aa042a0a6e Merge branch 'kj/e-commerce-patterns' into lm/ecommerce-patterns-revisions 2025-02-13 21:53:47 -05:00
Kelsey Jackson
fe81a41a6b Merge branch 'kj/e-commerce-patterns' of github.com:shoelace-style/webawesome into kj/e-commerce-patterns 2025-02-13 15:09:27 -06:00
Kelsey Jackson
f3628ad2d8 tweaked customer review 2025-02-13 15:08:30 -06:00
lindsaym-fa
169337077d Add docs layout for patterns with stylesheet 2025-02-13 15:49:09 -05:00
lindsaym-fa
406d9a9708 Update category descriptions and headings 2025-02-13 15:47:21 -05:00
lindsaym-fa
faaf75c0a2 Add "What's a Pattern?" and "Using Patterns" to index 2025-02-13 13:22:46 -05:00
Kelsey Jackson
13b67db869 Merge branch 'kj/e-commerce-patterns' of github.com:shoelace-style/webawesome into kj/e-commerce-patterns 2025-02-13 10:35:40 -06:00
Kelsey Jackson
b7fdda4b03 cleaned up checkout form 2025-02-13 10:35:31 -06:00
lindsaym-fa
d60e675702 Reimplement checkout form revisions 2025-02-13 10:23:46 -05:00
lindsaym-fa
414a318f0b Revert checkout form changes in attempt to improve diff 2025-02-13 10:00:45 -05:00
lindsaym-fa
ff8ed89645 Merge branch 'kj/e-commerce-patterns' into lm/ecommerce-patterns-revisions 2025-02-13 09:55:45 -05:00
lindsaym-fa
e027ab1291 Fix typo in file name 2025-02-13 09:52:56 -05:00
lindsaym-fa
d8f97b15b4 Add missing file extension 2025-02-13 09:52:00 -05:00
Kelsey Jackson
a8ed6f2c19 tweaked order summary 2025-02-12 16:14:21 -06:00
Kelsey Jackson
c7f5dc69ad cleaned up shopping cart 2025-02-12 15:07:03 -06:00
lindsaym-fa
42381722c5 Re-add navigation to "Product Features" carousel 2025-02-12 15:10:42 -05:00
lindsaym-fa
b2f9ec573f Merge branch 'kj/e-commerce-patterns' into lm/ecommerce-patterns-revisions 2025-02-12 15:05:33 -05:00
lindsaym-fa
b85e59b8ca "Checkout Form" revisions 2025-02-12 15:01:29 -05:00
Kelsey Jackson
8bd69694ce tweak category preview 2025-02-12 13:28:00 -06:00
Kelsey Jackson
7672923479 tweaked order history 2025-02-12 12:05:43 -06:00
Kelsey Jackson
c94006c6aa tweaked product overview 2025-02-12 11:21:17 -06:00
Kelsey Jackson
91ce2f2271 cleaned up product list 2025-02-12 10:08:51 -06:00
lindsaym-fa
9c609e44de "Category Filters" revisions + wa-placeholder utility 2025-02-11 17:06:40 -05:00
lindsaym-fa
28a8e4250a Revisions to "Product Features" 2025-02-11 17:05:38 -05:00
Kelsey Jackson
656a38cd3d updated prouct preview 2025-02-11 11:58:52 -06:00
Kelsey Jackson
9b90e56b45 more filter work 2025-02-11 10:57:29 -06:00
Kelsey Jackson
0c84a2ff37 Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-02-11 09:11:36 -06:00
Kelsey Jackson
511cca7931 Merge branch 'next' into pattern-main 2025-02-11 09:10:58 -06:00
Kelsey Jackson
2069d223f0 adding some polish 2025-02-11 09:10:18 -06:00
Kelsey Jackson
37d2455965 updated descriptions 2025-02-10 14:37:00 -06:00
Kelsey Jackson
85b05fc655 editing descriptions 2025-02-07 15:50:15 -06:00
Kelsey Jackson
52328d9805 fixing conflicts 2025-02-07 14:24:40 -06:00
Kelsey Jackson
2c89c5f510 switching machines 2025-02-07 11:42:00 -06:00
Kelsey Jackson
5ac9e8cff1 Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-02-05 12:16:50 -06:00
Kelsey Jackson
e238e35b3b Merge branch 'next' into pattern-main 2025-02-05 12:16:22 -06:00
Kelsey Jackson
c6d8d37871 switching machines 2025-01-31 09:43:40 -06:00
Kelsey Jackson
4dddb183fd updated width of container 2025-01-29 13:39:51 -06:00
Kelsey Jackson
d49ed53e9a added utilities to order-summary 2025-01-29 13:33:48 -06:00
Kelsey Jackson
99e2ffc17b added utilities to order history 2025-01-29 13:06:14 -06:00
Kelsey Jackson
97c79c29b9 Merge branch 'kj/e-commerce-patterns' of github.com:shoelace-style/webawesome into kj/e-commerce-patterns 2025-01-29 12:32:10 -06:00
Kelsey Jackson
7da9f53e27 filter work 2025-01-28 15:04:03 -06:00
Kelsey Jackson
a9cc02193f updated some patterns 2025-01-27 13:30:18 -06:00
Kelsey Jackson
9ad1c8f060 updated product list patterns 2025-01-27 13:17:09 -06:00
Kelsey Jackson
e0eaea2024 upated the product detail patterns 2025-01-27 11:20:40 -06:00
Kelsey Jackson
a8b7b6a93f Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-01-23 08:56:50 -06:00
Kelsey Jackson
581e47043a Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-01-22 18:50:38 -06:00
Kelsey Jackson
9ffe0cfe3c Merge branch 'next' into pattern-main 2025-01-22 18:50:11 -06:00
Kelsey Jackson
45df4a924f commiting to switch machines 2025-01-22 14:08:14 -06:00
Kelsey Jackson
43eed9d15e Merge branch 'next' into kj/e-commerce-patterns 2025-01-22 12:30:32 -06:00
Kelsey Jackson
a0ff411463 commiting to merge in next 2025-01-22 12:27:47 -06:00
Kelsey Jackson
04cd027c7e started split image pattern: 2025-01-17 14:44:14 -06:00
Kelsey Jackson
a68a157ebc switching machines 2025-01-15 16:41:13 -06:00
Kelsey Jackson
b2a24a3b52 Merge branch 'pattern-main' into kj/e-commerce-patterns 2025-01-09 11:31:46 -06:00
Kelsey Jackson
cbb456ffda switching machines 2025-01-09 11:29:32 -06:00
Kelsey Jackson
e0038c3125 Initial Commit 2025-01-09 10:59:33 -06:00
Kelsey Jackson
3e5d3120b1 Merge branch 'next' into kj/e-commerce-patterns 2025-01-08 16:19:29 -06:00
Kelsey Jackson
020f4cbaed building out the filter 2025-01-07 11:26:29 -06:00
Kelsey Jackson
9106bb88cf fixed merge conflicts 2025-01-06 10:34:51 -06:00
Kelsey Jackson
a822ab98c8 Merge branch 'next' into kj/e-commerce-patterns 2025-01-02 11:57:42 -06:00
Kelsey Jackson
026777c085 started invoice table 2024-12-18 09:53:15 -06:00
Kelsey Jackson
6d87b9b24a Merge branch 'next' into kj/e-commerce-patterns 2024-12-17 12:23:27 -06:00
Kelsey Jackson
d5affa01e9 dividing up e-commerce patterns 2024-12-11 15:06:01 -06:00
86 changed files with 434 additions and 695 deletions

View File

@@ -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.
*/

View File

@@ -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 #}

View File

@@ -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?">

View File

@@ -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 -%}

View File

@@ -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 %}

View File

@@ -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();

View File

@@ -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));

View File

@@ -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;
}
}

View File

@@ -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 */

View File

@@ -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>

View File

@@ -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}

View File

@@ -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>
```

View File

@@ -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>
```
```

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
```

View File

@@ -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}

View File

@@ -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);

View File

@@ -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:

View File

@@ -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

View File

@@ -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>
```

View File

@@ -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>

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>

View File

@@ -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 librarys 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 youve 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>
```
```

View File

@@ -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>
```

View File

@@ -5,5 +5,4 @@ parent: patterns
layout: overview
override:tags: []
listChildren: true
isPro: false
---

View File

@@ -1,7 +1,6 @@
---
title: Leaderboard
description: 'Engage and motivate users by highlighting top performers, scores, and achievements.'
isPro: true
---
## Simple

View File

@@ -1,7 +1,6 @@
---
title: Pagination
description: 'Improve navigation and performance by breaking long lists or content into manageable pages.'
isPro: true
---
## Simple

View File

@@ -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>
```

View File

@@ -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>
```
```

View File

@@ -2,7 +2,6 @@
title: Blog
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
@@ -368,4 +367,4 @@ TODO Page Description
}
</style>
```
```

View File

@@ -2,9 +2,8 @@
title: Business
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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
---

View File

@@ -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

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -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>
```
```

View File

@@ -2,9 +2,8 @@
title: Business
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -2,9 +2,8 @@
title: Entertainment
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -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>

View File

@@ -2,9 +2,8 @@
title: Membership
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -2,7 +2,6 @@
title: News
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
@@ -158,4 +157,4 @@ TODO Page Description
}
}
</style>
```
```

View File

@@ -2,9 +2,8 @@
title: Non-profit
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -2,6 +2,5 @@
"layout": "patterns.njk",
"tags": ["patterns"],
"wide": true,
"noAlpha": true,
"isPro": true
"noAlpha": true
}

View File

@@ -2,9 +2,8 @@
title: Portfolio
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -2,9 +2,8 @@
title: Product Landing
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
## Examples
## Examples

View File

@@ -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>

View File

@@ -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();
});

View File

@@ -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);
}

View File

@@ -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
View File

@@ -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",

View File

@@ -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",

View File

@@ -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;

View File

@@ -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>
`;
}
}

View File

@@ -1,9 +1,13 @@
:host {
--display: inline-flex;
display: contents;
position: relative;
}
:where([part~='base']) {
all: inherit;
display: inline-flex;
}
/*
* Label
*/

View File

@@ -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() {

View File

@@ -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}
>

View File

@@ -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,

View File

@@ -1,10 +1,13 @@
:host {
--show-duration: 200ms;
--hide-duration: 200ms;
--display: block;
display: contents !important;
}
details {
all: inherit;
display: block;
overflow-anchor: none;
}

View File

@@ -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);

View File

@@ -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"

View File

@@ -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();
}

View File

@@ -6,6 +6,9 @@
display: inline-block;
position: relative;
}
.image-comparer {
max-width: 100%;
max-height: 100%;
overflow: hidden;

View File

@@ -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>
`;

View File

@@ -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"
>

View File

@@ -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 {

View File

@@ -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,
})}
>

View File

@@ -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;
}

View File

@@ -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. */

View File

@@ -1,5 +1,10 @@
:host {
--display: inline-flex;
display: contents;
}
:where([part~='base']) {
all: inherit;
display: inline-flex;
}
.prefix,

View File

@@ -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');

View File

@@ -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>

View File

@@ -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"

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}