Compare commits

..

69 Commits

Author SHA1 Message Date
Lea Verou
b001f144c8 Update library.ts 2025-05-09 13:27:45 -04:00
Lea Verou
8a7a7dc3b0 Update icon.md 2025-05-09 13:20:27 -04:00
Lea Verou
eefa57f61a Docs 2025-05-09 12:59:24 -04:00
Lea Verou
c69cabf413 Make registerIconLibrary() return the created instance 2025-05-09 12:49:13 -04:00
Lea Verou
7de111341e Update tests 2025-05-09 12:48:57 -04:00
Lea Verou
5558a0f2cd If no system() is defined, route through WA immediately 2025-05-09 12:48:47 -04:00
Lea Verou
de4221365a Drop spriteSheet option, add getMarkup option instead 2025-05-09 12:47:39 -04:00
Lea Verou
b85e6bcdf3 Aliases and external mappings 2025-05-08 15:16:16 -04:00
Lea Verou
ad539a00f2 Finish rewrite 2025-05-08 15:16:16 -04:00
Lea Verou
1559b08a63 Move FA kit-specific stuff to the FA icon library 2025-05-08 15:16:16 -04:00
Lea Verou
400db9a608 Revamp icon libraries
- Make `custom` an icon library too and remove `fromLibrary` distinction: now everything comes from a library
- `IconLibrary` class to handle functionality
- Move caching, fetching, and DOM construction to the icon library
- Rename `resolver` to `getUrl`, `fetched` to `inlined` and `addFetched()` to `inline()`
- Eliminate different handling between sprite sheets and other icons (e.g. mutation caching, template construction)
2025-05-08 15:16:16 -04:00
Lea Verou
1f280b3b9f Basic functionality with the new API 2025-05-08 15:16:16 -04:00
Lea Verou
e9f2104f15 Use system: prefix for system icons 2025-05-08 15:16:04 -04:00
Lea Verou
ad53a0aa56 Merge branch 'next' into icon-fetched 2025-05-07 16:11:26 -04:00
Cory LaViska
d94589d113 fix radio button validation (#912) 2025-05-07 18:46:24 +00:00
Cory LaViska
3508bf6339 Cloak improvement (#911)
* simplify cloak selector so it's 100% opt-in

* prevent the discovery event from bubbling

* update changelog

* whitespaec
2025-05-07 18:17:26 +00:00
Cory LaViska
61e65ffcb9 Improve native radio alignment (#904)
* show initial checks (feels less broken now)

* improve native radio dot alignment

* Update src/styles/native/radio.css

Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>

* Update src/styles/native/radio.css

Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>

* Update src/styles/native/radio.css

Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>

---------

Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>
2025-05-07 16:43:11 +00:00
Lea Verou
d79d753f4c Remove unused import 2025-05-02 17:36:08 -04:00
Lea Verou
6306955c74 Changes
- Signature
- `getKey` from URL
- Fix bugs with `deepEntries()` / `flatten()`
2025-05-02 17:32:44 -04:00
Lea Verou
cff9d56b3f Merge branch 'icon-fetched' of https://github.com/shoelace-style/webawesome into icon-fetched 2025-05-02 16:03:31 -04:00
Lea Verou
9fde4a820e Incorporate suggested edits
Co-Authored-By: Cory LaViska <55639+claviska@users.noreply.github.com>
2025-05-02 16:03:30 -04:00
Lea Verou
34c0b562fe Address feedback 2025-05-02 16:02:45 -04:00
Lea Verou
f499a932f9 Update docs/docs/resources/contributing.md
Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2025-05-02 14:35:37 -04:00
Lea Verou
85cca22d71 Update docs/docs/components/icon.md
Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2025-05-02 12:59:43 -04:00
Lea Verou
c261f25c65 Kill library="system" with 🔥 2025-05-02 11:36:56 -04:00
Lea Verou
ac1d412a8f Merge default and system libraries, fixes #901
- Pre-fetched icons for all libraries via the `fetched` property
- `addFetched()` to add more prefetched icons to an existing library (needed for extensibility story)
- Update docs
- Update changelog
- Separate unregistered and register library types
2025-05-02 11:36:56 -04:00
Lindsay M
aed28adbe4 Update to FA 6.7.2 and add all Duotone styles (#906)
* Update to FA 6.7.2 and add all Duotone styles

* Add changelog
2025-05-02 10:30:51 -04:00
Cory LaViska
15b8bde81b fix matter form control label + focus bug (#897) 2025-05-01 16:20:03 -04:00
Cory LaViska
9ee3fb5d28 Remove old code util; fix color scheme shortcut; fix initial examples (#905)
* fix color scheme shortcut

* remove old unused examples script and styles

* don't open the first example's code _sometimes_
2025-05-01 20:17:27 +00:00
Cory LaViska
47aa376c08 fix width example (#899) 2025-05-01 16:15:21 -04:00
Cory LaViska
69ba974a50 fix select + icon + clear spacing (#903)
* fix select + icon + clear spacing

* update styles

* revert
2025-05-01 18:56:02 +00:00
Lea Verou
8dfb411e5e Add typography metadata to themes 2025-04-30 09:42:27 -04:00
Lea Verou
a35a8fd2ad Theme typography.css fixes
- Add `:where([class^='wa-theme-'], [class*=' wa-theme-'])` to default `typography.css` since we declare mappings that need to be inherited by other themes.
- Remove declarations that redeclare defaults
- Ensure consistent order
- [Awesome] Switch code font to ui-monospace
2025-04-30 09:42:27 -04:00
Cory LaViska
2503005bbd fix radio group margin (#898) 2025-04-29 19:58:08 +00:00
Cory LaViska
78027170ea fix feature request advice (#895) 2025-04-29 14:41:01 -04:00
Konnor Rogers
a20aa48992 fix select (#892)
* fix select

* prettier
2025-04-29 12:33:03 -04:00
Lindsay M
ac8accd664 Fix color contrast in Premium theme, closes #880 (#890)
* Fix `--wa-color-brand-fill-loud` in Premium theme

* jk. *Actually* fix contrast in Premium theme.
2025-04-29 09:52:04 -04:00
Lea Verou
c571573063 [Skeleton] Remove base part, rel #207 (#885) 2025-04-28 17:04:06 -04:00
Lea Verou
e813440315 [Image-comparer] Several fixes + rename to comparer (#883)
Co-authored-by: Cory LaViska <cory@abeautifulsite.net>
2025-04-28 16:58:24 -04:00
Lea Verou
cfc3f181a3 Fix broken demo, improve passthrough CSS (#879)
Fixes several issues for components using the `display: contents` technique:
- Introduce `--display` CSS property to make it possible to override internal display value of base part.
- Ensure `display: contents` is always applied with `!important` to avoid rendering glitches like the one here
- Ensure non-inherited custom properties are also inherited
- Ensure the `hidden` attribute still works.
2025-04-23 11:52:23 -04:00
Konnor Rogers
7545f04c46 remove all references to /docs/installation (#872) 2025-04-21 17:01:09 -04:00
Lea Verou
38bd6528fe Only apply wa-button-group-vertical class when <wa-radio-group> is a radio button group, fixes #870 2025-04-15 18:07:57 -04:00
Lea Verou
2202ea9642 CSS custom properties to set certain component attributes (#447) 2025-04-15 17:56:38 -04:00
Konnor Rogers
58fbcede51 update patterns to isPro (#869) 2025-04-14 14:59:27 -04:00
Lea Verou
971200cc88 Move domChange() to separate module (#868) 2025-04-14 12:52:00 -04:00
Konnor Rogers
b75d3b615c fix login media query and leaking variables with Turbo (#867)
* fix media queries to use wa-desktop-only

* fix errors in remix.js when changing pages

* prettier
2025-04-14 11:11:08 -04:00
Kelsey Jackson
9d1c47449e Kj/first pattern launch (#861)
* dividing up e-commerce patterns

* started invoice table

* building out the filter

* Initial Commit

* switching machines

* switching machines

* started split image pattern:

* commiting to merge in next

* commiting to switch machines

* upated the product detail patterns

* updated product list patterns

* updated some patterns

* filter work

* added utilities to order history

* added utilities to order-summary

* updated width of container

* switching machines

* switching machines

* fixing conflicts

* editing descriptions

* updated descriptions

* adding some polish

* more filter work

* updated prouct preview

* Revisions to "Product Features"

* "Category Filters" revisions + `wa-placeholder` utility

* cleaned up product list

* tweaked product overview

* tweaked order history

* tweak category preview

* "Checkout Form" revisions

* Re-add `navigation` to "Product Features" carousel

* cleaned up shopping cart

* tweaked order summary

* Add missing file extension

* Fix typo in file name

* Revert checkout form changes in attempt to improve diff

* Reimplement checkout form revisions

* cleaned up checkout form

* Add "What's a Pattern?" and "Using Patterns" to index

* Update category descriptions and headings

* Add docs layout for patterns with stylesheet

* tweaked customer review

* Add checkout form example

* a little more polish

* more tweaks

* switching branches to merge

* created e-commerce index

* unlisted links

* updtated content

* updated content for category preview

* updated order history

* committing to bring branches up to next

* inital commit

* Reorganize app patterns into separate pages

* switching machines

* Add link style utilities

* Refactor product list patterns

* more polish

* Refactor product overview patterns

* switching machines

* Refactor shopping cart patterns

* committing to pull down changes

* updated product preview

* updated image

* updated incentives

* Clean up utility usage and code formatting for category previews

* started updating with style utilities

* Clean up utilities and formatting, replace placeholder text in order history

* updated incentive images

* updated reviews

* added review variant

* more polish

* some heavy duty updates

* removed store navigation

* switching machines
:

* Clean up utility usage and code formatting for order summaries

* Clean up utility usage and code formatting for product previews

* big switchover

* removed old file

* working on sidebar

* updated sidebar

* created info category

* splitting up the old blog page

* a little cleanup and adding detail

* got three done

* updated social share

* Quick formatting adjustment

* initial paywalls

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

* some newsletter signups

* added login patterns

* reworked feeds'

* a few more

* added a few more

* add more app patterns

* 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

* switching machines

* catching up with next

* added permissions pattern

* switching machines

* added post articles

* having local browset issues

* a few more app patterns

* took out info patterns

* spiffed up the action panels

* gave the action panels a once over

* added content to data display

* updated a few patterns

* clean up a few e-commerce patterns

* added time componen to reviews

---------

Co-authored-by: lindsaym-fa <dev@lindsaym.design>
Co-authored-by: Lea Verou <lea@verou.me>
Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>
2025-04-14 11:10:54 -04:00
Lea Verou
003fd28cb0 Mark code-demo and viewport-demo as pro 2025-04-10 10:57:06 -05:00
Lea Verou
2f300d8930 [Popup] Use viewport as default boundary for flip too (#865) 2025-04-10 10:52:15 -05:00
Lea Verou
f13deb87bb Drop hoist from public API, use Popover API where supported (#351)
* First stab at using the Popover API for PE

* fix popup

* First stab at using the Popover API for PE

* fix popup

* Prettier

* Fix TS error

* Remove workaround

* Default to `strategy = fixed` if Popover API is not supported

* Clear out default UA styles for popovers

* Kill `hoist` with fire 🔥

* Refactor

* Update `@floating-ui/dom`

* Fix flipping and shofting

* Fix autosize

* Use `defaultBoundary` for `flip` too

That way we get the previous behavior for it.

* Remove `strategy`, just use `SUPPORTS_POPOVER` check where relevant

* Remove uses of `strategy`

* Use viewport as the default boundary for shifting and autosizing and add `boundary=scroll` to override

---------

Co-authored-by: konnorrogers <konnor5456@gmail.com>
2025-04-09 16:47:40 -05:00
Konnor Rogers
deb9fd70b3 fix pass through copying (#860)
* fix pass through copying

* prettier
2025-04-04 13:46:41 -04:00
Lea Verou
ff3b3d6558 Remove current class from existing sidebar link before adding it to new one 2025-04-02 14:16:03 -04:00
Lea Verou
6b3edb8a56 Tiny fix in saving mixin 2025-04-02 14:16:03 -04:00
Lea Verou
6162b8b115 Move v-content directive to separate file 2025-04-02 11:51:12 -04:00
Lea Verou
cff752b600 Move CRUD logic from palette app to Vue mixin 2025-04-02 11:51:12 -04:00
Lea Verou
7892a94b9b Rewrite and generalize CRUD logic for customizable entities (palettes, themes) (#854)
* Generalize CRUD logic to more easily support themes (and other types of entities)
* Decouple data structures managing saved entities (palettes, themes), sidebar update logic, and palette app (and soon themer) by using events
* Simplify logic (a lot of it carried complexity back from the time we did not use uids and/or was overly general)
* `PersistedArray` class to encapsulate arrays persisted in localStorage
* Remove unused `palette.equals()` function
2025-04-01 16:26:25 -04:00
Lea Verou
40a58ff35f Do not rely on {% raw %}, fixes #851 2025-03-31 17:53:33 -04:00
Lea Verou
0f2950c4cc Import CRUD parts from #828 2025-03-31 17:53:33 -04:00
Cory LaViska
b334884f57 remove unused custom properties (#853) 2025-03-31 17:08:50 +00:00
Cory LaViska
734417d66b fix version 2025-03-28 13:40:28 -04:00
Lea Verou
2cfd651d2f Prevent theme icons from getting focus when tabbing
Looks like `tabindex="-1"` didn't work, need to file a separate issue for that
2025-03-28 13:27:08 -04:00
Lea Verou
3e2d1b98be Changelog fixes
- Moved fixes to bug fixes section
- Linked `allDefined()` and `.wa-cloak` to their docs
- Grouped related bugfixes together
- Moved docs bugfixes to the end (since they are of least interest to users)
2025-03-28 13:27:08 -04:00
Lea Verou
40f332f37c Expand docs on allDefined() 2025-03-28 13:27:08 -04:00
Lea Verou
bfda64f690 Fix wa-cloak docs 2025-03-28 13:27:08 -04:00
Konnor Rogers
883d6df2ef fix z-index issues on sticky-disabled elements. (#848) 2025-03-28 12:26:30 -04:00
Lea Verou
b4240fd321 Move /docs/installation to /docs/, fix parent URL logic, closes #585 (#846)
* Fix: Parent URL should be undefined if parent is falsy

* Document `docs.11tydata.js` better

* Move `docs/installation.md` to `docs/`, fixes #585

* Just in case
2025-03-28 12:12:42 -04:00
Cory LaViska
8755a834f6 3.0.0-alpha.12 2025-03-28 11:07:44 -04:00
Cory LaViska
8d905296b8 update changelog 2025-03-28 11:07:42 -04:00
Cory LaViska
8eba1e5003 Various bug fixes (#839)
* add default icon spacing in tab; fixes #779

* fix radio button pill styles; fixes #759

* remove redundant styles

* fixes #840

* fix focus ring in Safari; fixes #745

* improve details styles; fixes #685

* update examples

* Revert "improve details styles; fixes #685"

This reverts commit 8151872d22.

* revert

* revert

* fix dropdown alignment in button group; closes #374

* fix progress animation in Safari; closes #356

* fix native checkbox indeterminate icon; closes #386

* add comment

* stop running SSR tests locally

* update test

* add FA kit code for codepen 🤞🏻

* remove wa-cloak after components load

* fix whitespace

* update display labels when changed; fixes #702

* fix radio labels (ALPHA-211)

* revert example

* add option as a dep of select

* remove outdated section
2025-03-28 10:57:01 -04:00
187 changed files with 7735 additions and 4525 deletions

View File

@@ -36,10 +36,16 @@ 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

@@ -0,0 +1,9 @@
import { inlined } from '../../dist/components/icon/library.wa.js';
let { classic } = inlined;
let { solid, regular } = classic;
export default [
...Object.entries(solid).map(([name, svg]) => ({ name, family: 'solid', variant: 'solid', svg })),
...Object.entries(regular).map(([name, svg]) => ({ name, family: 'regular', variant: 'regular', svg })),
];

View File

@@ -4,7 +4,6 @@
{% include 'head.njk' %}
<meta name="theme-color" content="#f36944">
<script type="module" src="/assets/scripts/code-examples.js"></script>
<script type="module" src="/assets/scripts/scroll.js"></script>
<script type="module" src="/assets/scripts/turbo.js"></script>
@@ -20,7 +19,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="">
<wa-page view="desktop" disable-navigation-toggle="" mobile-breakpoint="1140">
<header slot="header" class="wa-split">
{# Logo #}
<div id="docs-branding">
@@ -33,13 +32,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="only-desktop">{{ package.version }}</small>
<wa-badge variant="warning" appearance="filled" class="only-desktop">Alpha</wa-badge>
<small id="version-number" class="wa-desktop-only">{{ package.version }}</small>
<wa-badge variant="warning" appearance="filled" class="wa-desktop-only">Alpha</wa-badge>
</div>
<div id="docs-toolbar" class="wa-cluster wa-gap-xs">
{# Desktop selectors #}
<div class="only-desktop wa-cluster wa-gap-xs">
<div class="wa-desktop-only wa-cluster wa-gap-xs">
{% include "preset-theme-selector.njk" %}
{% include "color-scheme-selector.njk" %}
</div>
@@ -48,7 +47,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="only-desktop">/</kbd>
<kbd slot="suffix" class="wa-desktop-only">/</kbd>
</wa-button>
{# Login #}

View File

@@ -1,7 +1,7 @@
{# Getting started #}
<h2>Getting Started</h2>
<ul>
<li><a href="/docs/installation">Installation</a></li>
<li><a href="/docs/">Installation</a></li>
<li><a href="/docs/usage">Usage</a></li>
<li><a href="/docs/customizing">Customizing</a></li>
<li><a href="/docs/form-controls">Form Controls</a></li>

View File

@@ -0,0 +1,8 @@
<svg width="96" height="57" viewBox="0 0 96 57" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 1H84C90.0751 1 95 5.92487 95 12V45C95 51.0751 90.0751 56 84 56H12C5.92487 56 1 51.0751 1 45V12C1 5.92487 5.92487 1 12 1Z" fill="white" stroke="#E4E5E9" stroke-width="2"/>
<rect x="7" y="39" width="50" height="11" rx="4" fill="#4895FD"/>
<rect x="7" y="8" width="41" height="5" fill="#616D8A"/>
<rect x="7" y="19.75" width="76" height="3" fill="#D9D9D9"/>
<rect x="7" y="25" width="76" height="3" fill="#D9D9D9"/>
<rect x="7" y="32" width="76" height="3" fill="#D9D9D9"/>
</svg>

After

Width:  |  Height:  |  Size: 587 B

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,10 @@
<svg width="120" height="87" viewBox="0 0 240 178" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="39" width="67" height="63" rx="12" fill="#D9D9D9"/>
<rect y="115" width="67" height="63" rx="12" fill="#D9D9D9"/>
<rect width="67" height="19" rx="6" fill="#D9D9D9"/>
<rect x="87" y="39" width="67" height="63" rx="12" fill="#D9D9D9"/>
<rect x="174" y="39" width="67" height="63" rx="12" fill="#D9D9D9"/>
<rect x="174" y="7" width="67" height="4.75" rx="2.375" fill="#D9D9D9"/>
<rect x="87" y="115" width="67" height="63" rx="12" fill="#D9D9D9"/>
<rect x="174" y="115" width="67" height="63" rx="12" fill="#D9D9D9"/>
</svg>

After

Width:  |  Height:  |  Size: 631 B

View File

@@ -21,8 +21,8 @@
</div>
</div>
<div class="row row-2">
<wa-input value="Input" size="small"></wa-input>
<wa-button size="small" variant="brand">Go</wa-button>
<wa-input value="Input" size="small" inert></wa-input>
<wa-button size="small" variant="brand" inert>Go</wa-button>
</div>
</div>
</template>

View File

@@ -255,7 +255,7 @@
{# Importing #}
<h2>Importing</h2>
<p>
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.
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.
</p>
<wa-tab-group label="How would you like to import this component?">

View File

@@ -30,12 +30,21 @@
{% include 'breadcrumbs.njk' %}
<h1 v-if="saved" class="title">
{% raw %}{{ saved.title }}{% endraw %}
<wa-icon-button name="pencil" label="Rename palette" @click="rename"></wa-icon-button>
<wa-icon-button class="delete" name="trash" label="Delete palette" @click="deleteSaved"></wa-icon-button>
<h1 class="title">
<span v-content="title">{{ title }}</span>
<template v-if="saved || tweaked">
<wa-icon-button name="pencil" label="Rename palette" @click="rename"></wa-icon-button>
<wa-icon-button v-if="saved" class="delete" name="trash" label="Delete palette" @click="deleteSaved"></wa-icon-button>
<wa-button @click="save()" :disabled="!unsavedChanges"
:variant="unsavedChanges ? 'success' : 'neutral'" size="small" :appearance="unsavedChanges ? 'accent' : 'outlined'">
<span slot="prefix" class="icon-modifier">
<wa-icon name="sidebar" variant="regular"></wa-icon>
<wa-icon name="circle-plus" class="modifier" style="color: light-dark(var(--wa-color-green-70), var(--wa-color-green-60));"></wa-icon>
</span>
<span v-content="unsavedChanges ? 'Save' : 'Saved'">Save</span>
</wa-button>
</template>
</h1>
<h1 v-if="!saved" class="title">{{ title }}</h1>
<div class="block-info">
<code class="class">.wa-palette-{{ paletteId }}</code>
@@ -59,7 +68,7 @@
<wa-icon name="sliders-simple" slot="icon" variant="regular"></wa-icon>
This palette has been tweaked.
<div class="wa-cluster wa-gap-xs">
<wa-tag v-for="tweakHumanReadable, param in tweaksHumanReadable" removable @wa-remove="reset(param)">{% raw %}{{ tweakHumanReadable }}{% endraw %}</wa-tag>
<wa-tag v-for="tweakHumanReadable, param in tweaksHumanReadable" removable @wa-remove="reset(param)" v-content="tweakHumanReadable"></wa-tag>
</div>
<wa-button @click="reset()" appearance="outlined" variant="danger">
@@ -68,13 +77,6 @@
</span>
Reset
</wa-button>
<wa-button v-if="!saved" @click="save" variant="success">
<span slot="prefix" class="icon-modifier">
<wa-icon name="sidebar" variant="regular"></wa-icon>
<wa-icon name="circle-plus" class="modifier" style="color: light-dark(var(--wa-color-green-70), var(--wa-color-green-60));"></wa-icon>
</span>
Save
</wa-button>
</wa-callout>
<table class="colors main wa-palette-{{ paletteId }}">
@@ -124,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 }}" hoist>
<wa-tooltip for="gray-undertone-{{ h }}">
{{ h | capitalize }}
</wa-tooltip>
{%- endif -%}
@@ -139,7 +141,7 @@
@input="tweaking.grayChroma = true" @change="tweaking.grayChroma = false">
<div slot="label">
Gray colorfulness
<wa-icon-button @click="grayChroma = originalGrayChroma" class="clear-button" name="circle-xmark" library="system" variant="regular" label="Reset"></wa-icon-button>
<wa-icon-button @click="grayChroma = originalGrayChroma" class="clear-button" name="system:circle-xmark" variant="regular" label="Reset"></wa-icon-button>
</div>
</wa-slider>
<div class="label-min">Neutral</div>
@@ -158,7 +160,7 @@
@change="tweaking.hue = tweaking.{{ hue }} = false">
<div slot="label">
Tweak {{ hue }} hue
<wa-icon-button @click="hueShifts.{{ hue }} = 0" class="clear-button" name="circle-xmark" library="system" variant="regular" label="Reset"></wa-icon-button>
<wa-icon-button @click="hueShifts.{{ hue }} = 0" class="clear-button" name="system:circle-xmark" variant="regular" label="Reset"></wa-icon-button>
</div>
</wa-slider>
<div class="label-min">More {{hueBefore}}</div>
@@ -202,7 +204,7 @@ style="--min: {{ chromaScaleBounds[0] }}; --max: {{ chromaScaleBounds[1] }};">
@change="tweaking.chroma = false">
<div slot="label">
Overall colorfulness
<wa-icon-button @click="chromaScale = 1" class="clear-button" name="circle-xmark" library="system" variant="regular" label="Reset"></wa-icon-button>
<wa-icon-button @click="chromaScale = 1" class="clear-button" name="system:circle-xmark" variant="regular" label="Reset"></wa-icon-button>
</div>
</wa-slider>
<div class="label-min">More muted</div>

View File

@@ -0,0 +1,5 @@
{% extends '../_layouts/block.njk' %}
{% block head %}
<link href="/docs/patterns/patterns.css" rel="stylesheet">
{% endblock %}

View File

@@ -25,8 +25,8 @@ wa_data.palettes = {
{% endfor %}
};
</script>
<link href="{{ page.url }}../remix.css" rel="stylesheet">
<script src="{{ page.url }}../remix.js" type="module"></script>
<link href="/docs/themes/remix.css" rel="stylesheet">
<script src="/docs/themes/remix.js" type="module"></script>
{% endblock %}
{% block header %}

View File

@@ -102,12 +102,7 @@ const templates = {
export function codeExamplesPlugin(eleventyConfig, options = {}) {
const defaultOptions = {
container: 'body',
defaultOpen: (code, { outputPathIndex }) => {
return (
outputPathIndex === 1 && // is first
code.textContent.length < 500
); // is short
},
defaultOpen: () => false,
};
options = { ...defaultOptions, ...options };

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" hoist></wa-copy-button>`;
<wa-copy-button from="${codeId}" class="copy-button"></wa-copy-button>`;
});
return doc.toString();

View File

@@ -1,59 +0,0 @@
document.addEventListener('click', event => {
const toggle = event.target?.closest('.code-example-toggle');
const pen = event.target?.closest('.code-example-pen');
// Toggle source
if (toggle) {
const codeExample = toggle.closest('.code-example');
const isOpen = !codeExample.classList.contains('open');
toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
codeExample.classList.toggle('open', isOpen);
}
// Edit in CodePen
if (pen) {
const codeExample = pen.closest('.code-example');
const code = codeExample.querySelector('code');
const cdnUrl = document.documentElement.dataset.cdnUrl;
const html =
`<script data-fa-kit-code="b10bfbde90" type="module" src="${cdnUrl}webawesome.loader.js"></script>\n` +
`<link rel="stylesheet" href="${cdnUrl}styles/themes/default.css">\n` +
`<link rel="stylesheet" href="${cdnUrl}styles/webawesome.css">\n` +
`<link rel="stylesheet" href="${cdnUrl}styles/utilities.css">\n\n` +
`${code.textContent}`;
const css = 'html > body {\n padding: 2rem !important;\n}';
const js = '';
const form = document.createElement('form');
form.action = 'https://codepen.io/pen/define';
form.method = 'POST';
form.target = '_blank';
const data = {
title: '',
description: '',
tags: ['webawesome'],
editors: '1000',
head: '<meta name="viewport" content="width=device-width">',
html_classes: '',
css_external: '',
js_external: '',
js_module: true,
js_pre_processor: 'none',
html,
css,
js,
};
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'data';
input.value = JSON.stringify(data);
form.append(input);
document.documentElement.append(form);
form.submit();
form.remove();
}
});

167
docs/assets/scripts/my.js Normal file
View File

@@ -0,0 +1,167 @@
const my = (globalThis.my = new EventTarget());
export default my;
class PersistedArray extends Array {
constructor(key) {
super();
this.key = key;
if (this.key) {
this.fromLocalStorage();
}
// Items were updated in another tab
addEventListener('storage', event => {
if (event.key === this.key || !event.key) {
this.fromLocalStorage();
}
});
}
/**
* Update data from local storage
*/
fromLocalStorage() {
// First, empty the array
this.splice(0, this.length);
// Then, fill it with the data from local storage
let saved = localStorage[this.key] ? JSON.parse(localStorage[this.key]) : null;
if (saved) {
this.push(...saved);
}
}
/**
* Write data to local storage
*/
toLocalStorage() {
if (this.length > 0) {
localStorage[this.key] = JSON.stringify(this);
} else {
delete localStorage[this.key];
}
}
}
class SavedEntities extends EventTarget {
constructor({ key, type, url }) {
super();
this.key = key;
this.type = type;
this.url = url ?? type + 's';
this.saved = new PersistedArray(key);
let all = this;
this.entityPrototype = {
type: this.type,
baseUrl: this.baseUrl,
get url() {
return all.getURL(this);
},
get parentUrl() {
return all.getParentURL(this);
},
delete() {
all.delete(this);
},
};
}
getUid() {
if (this.saved.length === 0) {
return 1;
}
let uids = new Set(this.saved.map(p => p.uid));
// Find first available number
for (let i = 1; i <= this.saved.length + 1; i++) {
if (!uids.has(i)) {
return i;
}
}
}
get baseUrl() {
return `/docs/${this.url}/`;
}
getURL(entity) {
return this.getParentURL(entity) + entity.search;
}
getParentURL(entity) {
return this.baseUrl + entity.id + '/';
}
getObject(entity) {
let ret = Object.create(this.entityPrototype, Object.getOwnPropertyDescriptors(entity));
// debugger;
return ret;
}
/**
* Save an entity, either by updating its existing entry or creating a new one
* @param {object} entity
*/
save(entity) {
if (!entity.uid) {
// First time saving
entity.uid = this.getUid();
}
let savedPalettes = this.saved;
let existingIndex = entity.uid ? this.saved.findIndex(p => p.uid === entity.uid) : -1;
let newIndex = existingIndex > -1 ? existingIndex : savedPalettes.length;
this.saved.splice(newIndex, 1, entity);
this.saved.toLocalStorage();
this.dispatchEvent(new CustomEvent('save', { detail: this.getObject(entity) }));
return entity;
}
delete(entity) {
let count = this.saved.length;
if (count === 0 || !entity?.uid) {
// No stored entities or this entity has not been saved
return;
}
// TODO improve UX of this
if (!confirm(`Are you sure you want to delete ${this.type}${entity.title}”?`)) {
return;
}
for (let index; (index = this.saved.findIndex(p => p.uid === entity.uid)) > -1; ) {
this.saved.splice(index, 1);
}
if (this.saved.length === count) {
// Nothing was removed
return;
}
this.saved.toLocalStorage();
this.dispatchEvent(new CustomEvent('delete', { detail: this.getObject(entity) }));
}
dispatchEvent(event) {
super.dispatchEvent(event);
my.dispatchEvent(event);
}
}
my.palettes = new SavedEntities({
key: 'savedPalettes',
type: 'palette',
});

View File

@@ -1,254 +1,119 @@
const sidebar = (globalThis.sidebar = {});
import my from '/assets/scripts/my.js';
sidebar.palettes = {
render() {
if (this.saved.length === 0) {
return;
}
const sidebar = {
addChild(a, parentA) {
let parentLi = parentA.closest('li');
let ul = parentLi.querySelector(':scope > ul');
ul ??= parentLi.appendChild(document.createElement('ul'));
let li = document.createElement('li');
li.append(a);
ul.appendChild(li);
for (let palette of this.saved) {
sidebar.palette.render(palette);
}
sidebar.updateCurrent();
},
updateSaved() {
this.saved = localStorage.savedPalettes ? JSON.parse(localStorage.savedPalettes) : [];
},
save(saved = this.saved) {
this.saved = saved ?? [];
if (saved.length > 0) {
localStorage.savedPalettes = JSON.stringify(saved);
} else {
delete localStorage.savedPalettes;
}
},
};
sidebar.palettes.updateSaved();
addEventListener('storage', event => sidebar.palettes.updateSaved());
sidebar.palette = {
getUid() {
let savedPalettes = sidebar.palettes.saved;
let uids = new Set(savedPalettes.map(p => p.uid));
if (savedPalettes.length === 0) {
return 1;
}
// Find first available number
for (let i = 1; i <= savedPalettes.length + 1; i++) {
if (!uids.has(i)) {
return i;
// If we are on the same page, update the current link
let url = location.href.replace(/#.+$/, '');
if (url.startsWith(a.href)) {
// Remove existing current
for (let current of document.querySelectorAll('#sidebar a.current')) {
current.classList.remove('current');
}
}
},
equals(p1, p2) {
if (!p1 || !p2) {
return false;
a.classList.add('current');
}
return p1.id === p2.id && p1.uid === p2.uid;
return a;
},
delete(palette) {
let savedPalettes = sidebar.palettes.saved;
let count = savedPalettes.length;
if (count === 0) {
removeLink(a) {
if (!a || !a.isConnected) {
// Link doesn't exist or is already removed
return;
}
// TODO improve UX of this
if (!confirm(`Are you sure you want to delete palette “${palette.title}”?`)) {
return;
let li = a?.closest('li');
let ul = li?.closest('ul');
let parentA = ul?.closest('li')?.querySelector(':scope > a');
li?.remove();
if (ul?.children.length === 0) {
ul.remove();
}
savedPalettes = savedPalettes.filter(p => !sidebar.palette.equals(palette, p));
if (savedPalettes.length === count) {
// Nothing was removed
return;
}
// Update UI
let pathname = `/docs/palettes/${palette.id}/`;
let url = pathname + palette.search;
let uls = new Set();
for (let a of document.querySelectorAll(`#sidebar a[href="${url}"]`)) {
let li = a.closest('li');
let ul = li.closest('ul');
uls.add(ul);
li.remove();
}
// Remove empty lists
for (let ul of uls) {
if (!ul.children.length) {
ul.remove();
}
}
sidebar.updateCurrent();
sidebar.palettes.save(savedPalettes);
if (sidebar.palette.equals(globalThis.paletteApp?.saved, palette)) {
paletteApp.postDelete();
if (a.classList.contains('current')) {
// If the deleted palette was the current one, the current one is now the parent
parentA.classList.add('current');
}
},
getSaved(palette, savedPalettes = sidebar.palettes.saved) {
return savedPalettes.find(p => sidebar.palette.equals(p, palette));
findEntity(entity) {
return document.querySelector(`#sidebar a[href^="${entity.baseUrl}"][data-uid="${entity.uid}"]`);
},
render(palette) {
// Find existing <a>
let { title, id, search, uid } = palette;
renderEntity(entity) {
let { url, parentUrl } = entity;
for (let a of document.querySelectorAll(`#sidebar a[href^="/docs/palettes/${id}/"][data-uid="${uid}"]`)) {
// Palette already in sidebar, just update it
a.textContent = palette.title;
a.href = `/docs/palettes/${id}/${search}`;
return;
}
let pathname = `/docs/palettes/${id}/`;
let url = pathname + search;
let parentA = document.querySelector(`a[href="${pathname}"]`);
// Find parent
let parentA = document.querySelector(`#sidebar a[href="${parentUrl}"]`);
let parentLi = parentA?.closest('li');
let a;
if (parentLi) {
a = Object.assign(document.createElement('a'), { href: url, textContent: title });
a.dataset.uid = uid;
let badges = [...parentLi.querySelectorAll('wa-badge')].map(badge => badge.cloneNode(true));
let ul = parentLi.querySelector('ul') ?? parentLi.appendChild(document.createElement('ul'));
let li = document.createElement('li');
let deleteButton = Object.assign(document.createElement('wa-icon-button'), {
name: 'trash',
label: 'Delete',
className: 'delete',
});
deleteButton.addEventListener('click', () => {
let palette = { id, uid, title: a.textContent, search: a.search };
sidebar.palette.delete(palette);
});
li.append(a, ' ', ...badges, deleteButton);
ul.appendChild(li);
}
},
save(palette, saved) {
let savedPalettes = sidebar.palettes.saved;
let existing = this.getSaved(saved ?? palette, savedPalettes);
let oldValues;
if (existing) {
// Rename
oldValues = { ...existing };
Object.assign(existing, palette);
} else {
savedPalettes.push(palette);
if (!parentLi) {
throw new Error(`Cannot find parent url ${parentUrl}`);
}
this.render(palette, oldValues);
sidebar.updateCurrent();
// Find existing
let a = this.findEntity(entity);
let alreadyExisted = !!a;
sidebar.palettes.save(savedPalettes);
},
};
a ??= document.createElement('a');
sidebar.updateCurrent = function () {
// Find the sidebar link with the longest shared prefix with the current URL
let pathParts = location.pathname.split('/').filter(Boolean);
let prefixes = [];
a.textContent = entity.title;
a.href = url;
if (pathParts.length === 1) {
// If at /docs/ we just use that, otherwise we want at least two parts (/docs/xxx/)
prefixes.push('/' + pathParts[0] + '/');
} else {
for (let i = 2; i <= pathParts.length; i++) {
prefixes.push('/' + pathParts.slice(0, i).join('/') + '/');
}
}
if (!alreadyExisted) {
a.dataset.uid = entity.uid;
// Last prefix includes the search too (if any)
if (location.search) {
let params = new URLSearchParams(location.search);
params.sort();
prefixes.push(prefixes.at(-1) + location.search);
}
a = sidebar.addChild(a, parentA);
// We want to start from the longest prefix
prefixes.reverse();
let candidates;
let matchingPrefix;
// This is mainly to port Pro badges
let badges = Array.from(parentLi.querySelectorAll('wa-badge'), badge => badge.cloneNode(true));
let append = [...badges];
for (let prefix of prefixes) {
candidates = document.querySelectorAll(`#sidebar a[href^="${prefix}"]`);
if (candidates.length > 0) {
matchingPrefix = prefix;
break;
}
}
if (!matchingPrefix) {
// Abort mission
return;
}
if (matchingPrefix === pathParts.at(-1)) {
// Full path matches, check search
if (location.search) {
candidates = [...candidates];
let searchParams = new URLSearchParams(location.search);
if (searchParams.has('uid')) {
// Only consider candidates with the same uid
candidates = candidates.filter(a => {
let params = new URLSearchParams(a.search);
return params.get('uid') === searchParams.get('uid');
});
} else {
// Sort candidates based on how many params they have in common, in descending order
candidates = candidates.sort((a, b) => {
return countSharedSearchParams(searchParams, b.search) - countSharedSearchParams(searchParams, a.search);
if (entity.delete) {
let deleteButton = Object.assign(document.createElement('wa-icon-button'), {
name: 'trash',
label: 'Delete',
className: 'delete',
});
deleteButton.addEventListener('click', () => entity.delete());
append.push(deleteButton);
}
if (append.length > 0) {
a.closest('li').append(' ', ...append);
}
}
}
},
if (candidates.length > 0) {
for (let current of document.querySelectorAll('#sidebar a.current')) {
current.classList.remove('current');
render() {
for (let type in my) {
let controller = my[type];
if (!controller.saved) {
continue;
}
for (let entity of controller.saved) {
let object = controller.getObject(entity);
this.renderEntity(object);
}
}
candidates[0].classList.add('current');
}
},
};
sidebar.render = function () {
this.palettes.render();
};
globalThis.sidebar = sidebar;
// Update sidebar when my saved stuff changes
my.addEventListener('delete', e => sidebar.removeLink(sidebar.findEntity(e.detail)));
my.addEventListener('save', e => sidebar.renderEntity(e.detail));
sidebar.render();
window.addEventListener('turbo:render', () => sidebar.render());
function countSharedSearchParams(searchParams, search) {
if (!search || search === '?') {
return 0;
}
let params = new URLSearchParams(search);
return [...searchParams.keys()].filter(k => params.get(k) === searchParams.get(k)).length;
}

View File

@@ -1,34 +1,5 @@
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;
}
}
import { domChange } from './util/dom-change.js';
export { domChange };
export function nextFrame() {
return new Promise(resolve => requestAnimationFrame(resolve));
@@ -135,6 +106,6 @@ document.addEventListener('keydown', event => {
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
) {
event.preventDefault();
colorScheme.set(theming.colorScheme.resolvedValue === 'dark' ? 'light' : 'dark');
colorScheme.set(colorScheme.get() === 'dark' ? 'light' : 'dark');
}
});

View File

@@ -13,56 +13,42 @@ export default class Permalink extends URLSearchParams {
return Object.fromEntries(this.entries());
}
#mappings = new WeakMap();
mapObject(obj, mapping = {}) {
this.#mappings.set(obj, mapping);
}
readFrom(obj) {
let mapping = this.#mappings.get(obj) ?? {};
let { keyFrom = IDENTITY, valueFrom = IDENTITY } = mapping;
for (let key in obj) {
let value = obj[key];
let mappedValue = valueFrom(value);
let mappedKey = keyFrom(key);
this.set(mappedKey, mappedValue);
}
}
writeTo(obj) {
let mapping = this.#mappings.get(obj) ?? {};
let { keyTo = IDENTITY, valueTo = IDENTITY, canExtend = false } = mapping;
for (let [key, value] of this) {
let mappedKey = keyTo(key);
let mappedValue = valueTo(value);
if (canExtend || mappedKey in obj) {
obj[mappedKey] = mappedValue;
}
}
}
set(key, value, defaultValue) {
let oldValue = this.get(key);
if (equals(value, defaultValue) || equals(value, '')) {
value = null;
}
if (!value || value == defaultValue) {
value ??= null; // undefined -> null
let oldValue = Array.isArray(value) ? this.getAll(key) : this.get(key);
let changed = !equals(value, oldValue);
if (!changed) {
// Nothing to do here
return;
}
if (Array.isArray(value)) {
super.delete(key);
value = value.slice();
if (oldValue) {
this.changed = true;
for (let v of value) {
if (v || v === 0) {
if (typeof v === 'object') {
super.append(key, JSON.stringify(v));
} else {
super.append(key, v);
}
}
}
} else if (value === null) {
super.delete(key);
} else {
super.set(key, value);
if (String(value) !== String(oldValue)) {
this.changed = true;
}
}
this.sort();
this.changed ||= changed;
}
/**
@@ -79,3 +65,40 @@ export default class Permalink extends URLSearchParams {
}
}
}
function equals(value, oldValue) {
if (Array.isArray(value) || Array.isArray(oldValue)) {
value = toArray(value);
oldValue = toArray(oldValue);
if (value.length !== oldValue.length) {
return false;
}
return value.every((v, i) => equals(v, oldValue[i]));
}
// (value ?? oldValue ?? true) returns true if they're both empty (null or undefined)
[value, oldValue] = [value, oldValue].map(v => (!v && v !== false && v !== 0 ? null : v));
return value === oldValue || String(value) === String(oldValue);
}
/**
* Convert a value to an array. `undefined` and `null` values are converted to an empty array.
* @param {*} value - The value to convert.
* @returns {any[]} The converted array.
*/
function toArray(value) {
value ??= [];
if (Array.isArray(value)) {
return value;
}
// Don't convert "foo" into ["f", "o", "o"]
if (typeof value !== 'string' && typeof value[Symbol.iterator] === 'function') {
return Array.from(value);
}
return [value];
}

View File

@@ -0,0 +1,37 @@
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

@@ -0,0 +1,22 @@
// Like v-text, but doesn't complain if the element has content,
// making it possible to use in a PE fashion, with the contents being the fallback
export default function content(el, { value, arg }) {
if (!el.dataset.fallback) {
// Store the original content as a fallback the first time
el.dataset.fallback = el.textContent;
}
if (value === '') {
value = el.dataset.fallback;
} else {
if (arg === 'number') {
value = Number(value).toLocaleString(undefined, { maximumSignificantDigits: 2 });
}
}
if (arg === 'html') {
el.innerHTML = value;
} else {
el.textContent = value;
}
}

View File

@@ -0,0 +1,110 @@
import my from '/assets/scripts/my.js';
import Permalink from '/assets/scripts/tweak/permalink.js';
export default {
data() {
return {
uid: undefined,
saved: null,
unsavedChanges: false,
permalink: new Permalink(),
};
},
created() {
if (this.permalink.has('uid')) {
this.uid = Number(this.permalink.get('uid'));
this.saved = this.controller.saved.find(p => p.uid === this.uid);
}
this.controller.addEventListener('delete', ({ detail: entity }) => {
if (entity.uid === this.saved?.uid) {
this.postDelete();
}
});
},
mounted() {
this.$nextTick().then(() => {
if (!location.search || this.saved) {
this.unsavedChanges = false;
}
});
},
computed: {
controller() {
return my[this.collection];
},
title() {
if (this.saved) {
return this.saved.title;
} else if (this.unsavedChanges) {
return this.defaultTitle;
} else {
return this.originalTitle;
}
},
},
watch: {
saved: {
deep: true,
handler() {
this.unsavedChanges = !this.saved;
},
},
},
methods: {
async save({ title } = {}) {
let uid = this.uid;
this.saved ??= { uid: this.uid };
this.saved.id = this.id;
if (title) {
// Renaming
this.saved.title = title;
} else {
this.saved.title ??= this.defaultTitle;
}
this.saved.search = location.search;
this.saved = this.controller.save(this.saved);
if (uid !== this.saved.uid) {
// UID changed (most likely from saving a new entity)
this.uid = this.saved.uid;
this.permalink.set('uid', this.uid);
this.permalink.updateLocation();
await this.$nextTick();
this.save(); // Save again to update the search param to include the UID
}
this.unsavedChanges = false;
},
rename() {
let newTitle = prompt('Title:', this.saved?.title ?? this.defaultTitle);
if (newTitle && newTitle !== this.saved?.title) {
this.save({ title: newTitle });
}
},
// Cannot name this delete() because Vue complains
deleteSaved() {
this.controller.delete(this.saved);
},
postDelete() {
this.saved = null;
this.permalink.delete('uid');
this.uid = undefined;
this.permalink.updateLocation();
},
},
};

View File

@@ -1,87 +0,0 @@
.code-example {
border: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
border-radius: var(--wa-border-radius-l);
color: var(--wa-color-text-normal);
margin-block-end: var(--wa-flow-spacing);
}
.code-example-preview {
padding: 2rem;
border-bottom: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
> :first-child {
margin-block-start: 0;
}
> :last-child {
margin-block-end: 0;
}
}
.code-example-source {
border-bottom: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
}
.code-example:not(.open) .code-example-source {
display: none;
}
.code-example.open .code-example-toggle wa-icon {
rotate: 180deg;
}
.code-example-source pre {
position: relative;
border-radius: 0;
margin: 0;
white-space: normal;
}
.code-example-source:not(:has(+ .code-example-buttons)) {
border-bottom: none;
pre {
border-bottom-right-radius: var(--wa-border-radius-l);
border-bottom-left-radius: var(--wa-border-radius-l);
}
}
.code-example-buttons {
display: flex;
align-items: stretch;
button {
all: unset;
flex: 1 0 auto;
font-size: 0.875rem;
color: var(--wa-color-text-quiet);
border-left: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
text-align: center;
padding: 0.5rem;
cursor: pointer;
&:first-of-type {
border-left: none;
border-bottom-left-radius: var(--wa-border-radius-l);
}
&:last-of-type {
border-bottom-right-radius: var(--wa-border-radius-l);
}
&:focus-visible {
outline: var(--wa-focus-ring);
}
}
.code-example-pen {
flex: 0 0 100px;
white-space: nowrap;
}
wa-icon {
width: 1em;
height: 1em;
vertical-align: -2px;
}
}

View File

@@ -1,4 +1,3 @@
@import 'code-examples.css';
@import 'code-highlighter.css';
@import 'copy-code.css';
@import 'outline.css';
@@ -608,13 +607,6 @@ 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 hoist>
<wa-dropdown>
<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" hoist>
<wa-dropdown placement="bottom-end">
<wa-button slot="trigger" variant="brand" caret>
<span class="wa-visually-hidden">More options</span>
</wa-button>

View File

@@ -3,6 +3,7 @@ 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

@@ -1,14 +1,16 @@
---
title: Image Comparer
description: Compare visual differences between similar photos with a sliding panel.
title: Comparer
description: Compare visual differences between similar content with a sliding panel.
tags: [imagery, niche]
icon: image-comparer
icon: comparer
---
For best results, use images that share the same dimensions. The slider can be controlled by dragging or pressing the left and right arrow keys. (Tip: press shift + arrows to move the slider in larger intervals, or home + end to jump to the beginning or end.)
This is especially useful for comparing images, but can be used for comparing any type of content (for an example of using it to compare entire UIs, check out our [theme pages](/docs/themes/default/)).
For best results, use content that shares the same dimensions.
The slider can be controlled by dragging or pressing the left and right arrow keys. (Tip: press shift + arrows to move the slider in larger intervals, or home + end to jump to the beginning or end.)
```html {.example}
<wa-image-comparer>
<wa-comparer>
<img
slot="before"
src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&sat=-100&bri=-5"
@@ -19,7 +21,7 @@ For best results, use images that share the same dimensions. The slider can be c
src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80"
alt="Color version of kittens in a basket looking around."
/>
</wa-image-comparer>
</wa-comparer>
```
## Examples
@@ -29,7 +31,7 @@ For best results, use images that share the same dimensions. The slider can be c
Use the `position` attribute to set the initial position of the slider. This is a percentage from `0` to `100`.
```html {.example}
<wa-image-comparer position="25">
<wa-comparer position="25">
<img
slot="before"
src="https://images.unsplash.com/photo-1520903074185-8eca362b3dce?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1200&q=80"
@@ -40,5 +42,5 @@ Use the `position` attribute to set the initial position of the slider. This is
src="https://images.unsplash.com/photo-1520640023173-50a135e35804?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80"
alt="A person sitting on a yellow curb tying shoelaces on a boot."
/>
</wa-image-comparer>
</wa-comparer>
```

View File

@@ -88,10 +88,10 @@ You can add the special `data-dialog="close"` attribute to a button inside the d
### Custom Width
Just use the CSS `width` property to set the dialog's width.
Just use the `--width` custom property to set the dialog's width.
```html {.example}
<wa-dialog label="Dialog" with-header with-footer class="dialog-width" style="width: 50vw;">
<wa-dialog label="Dialog" with-header with-footer class="dialog-width" style="--width: 50vw;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<wa-button slot="footer" variant="brand" data-dialog="close">Close</wa-button>
</wa-dialog>

View File

@@ -180,38 +180,3 @@ 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,11 +17,94 @@ 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/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.
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`, `duotone`, and `sharp-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>
<wa-icon family="brands" name="font-awesome"></wa-icon>
<wa-icon family="brands" name="web-awesome"></wa-icon>
<wa-icon family="classic" variant="light" name="sparkles"></wa-icon>
<wa-icon family="sharp" variant="solid" name="fire"></wa-icon>
<wa-icon family="duotone" variant="regular" name="cake-slice"></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
@@ -103,7 +186,8 @@ Custom icons can be loaded individually with the `src` attribute. Only SVGs on a
You can register additional icons to use with the `<wa-icon>` component through icon libraries. Icon files can exist locally or on a CORS-enabled endpoint (e.g. a CDN). There is no limit to how many icon libraries you can register and there is no cost associated with registering them, as individual icons are only requested when they're used.
Web Awesome ships with two built-in icon libraries, `default` and `system`. The [default icon library](#customizing-the-default-library) is provided courtesy of [Font Awesome](https://fontawesome.com/). The [system icon library](#customizing-the-system-library) contains only a small subset of icons that are used internally by Web Awesome components.
Web Awesome ships with one built-in icon library: `default`.
The [default icon library](#customizing-the-default-library) is provided courtesy of [Font Awesome](https://fontawesome.com/).
To register an additional icon library, use the `registerIconLibrary()` function that's exported from `dist/webawesome.js`. At a minimum, you must provide a name and a resolver function. The resolver function translates an icon name to a URL where the corresponding SVG file exists. Refer to the examples below to better understand how it works.
@@ -115,8 +199,9 @@ Here's an example that registers an icon library located in the `/assets/icons`
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('my-icons', {
resolver: (name, family, variant) => `/assets/icons/${name}.svg`,
registerIconLibrary({
name: 'my-icons',
getUrl: (name, family, variant) => `/assets/icons/${name}.svg`,
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
@@ -131,6 +216,289 @@ To display an icon, set the `library` and `name` attributes of an `<wa-icon>` el
If an icon is used before registration occurs, it will be empty initially but shown when registered.
### Customizing the Default Icon Library
The default icon library contains over 2,000 icons courtesy of [Font Awesome](https://fontawesome.com/).
These are the icons that display when you use `<wa-icon>` without the `library` attribute.
If you prefer to have these icons resolve to a different icon library, simply register it using the `default` name:
For example, this will change the default icon library to use [Bootstrap Icons](https://icons.getbootstrap.com/) loaded from the jsDelivr CDN.
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('default', {
name: 'default',
getUrl: (name, family) => {
const suffix = family === 'filled' ? '-fill' : '';
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
}
});
</script>
```
You can also register an existing library as the default:
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
let myIcons = registerIconLibrary({
name: 'my-icons',
getUrl: (name, family, variant) => `/assets/icons/${name}.svg`,
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
// Alias of my-icons to default
registerIconLibrary('default', myIcons);
</script>
```
This allows you to have multiple libraries that co-exist, only one of which is the default.
### Customizing system icons
Web Awesome components use a number of icons internally.
For example, the checkmark icon in `<wa-checkbox>` or the chevron used in `<wa-details>`.
These icons have a `system:` prefix in their name, e.g. `system:check` or `system:chevron-down`.
To specify how these map to your icon library, you can define a `system()` function that maps Web Awesomes system icons to your librarys icons.
The `system()` function receives the icon name, family and variant as arguments and returns an object with the new `name`, `family`, and `variant`.
For example, here is how to define system icon mappings for the Bootstrap Icons library:
```js
import { registerIconLibrary } from '/dist/webawesome.js';
let system = {
filled: ['circle', 'pause', 'play', 'star', 'user'],
nameMap: {
'check': 'check-lg',
'circle': 'circle',
'circle-xmark': 'x-circle',
'eye-dropper': 'eyedropper',
'eye': 'eye',
'eye-slash': 'eye-slash',
'grip-vertical': 'grip-vertical',
'indeterminate': 'dash-lg',
'minus': 'dash-lg',
'pause': 'pause',
'play': 'play',
'user': 'person',
'xmark': 'x-lg',
}
};
registerIconLibrary({
name: 'bootstrap-icons',
system(name, family) {
return {
// Transform names where different
name: system.nameMap[name] || name,
// Default to non-filled as many of system's "solid" icons are not filled in Bootstrap Icons
family: system.filled.includes(name) ? 'filled' : ''
};
},
getUrl: (name, family) => {
const suffix = family === 'filled' ? '-fill' : '';
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
}
});
```
You can also specify a `library` key to resolve a system icon through a different library, e.g. WAs default icon library.
For example, the code above will try to resolve any system icons through your library and only fall back to WA's default library if they fail to load.
This maximizes the odds that icons from your library are used, but can also be unpredictable.
To resolve any system icon you have not vetted via the Web Awesome default library, you can use the `library` key:
```js
let system = {
filled: ['circle', 'pause', 'play', 'star', 'user'],
nameMap: {
'chevron-down': 'chevron-down',
'chevron-left': 'chevron-left',
'chevron-right': 'chevron-right',
'check': 'check-lg',
'circle': 'circle',
'eye-dropper': 'eyedropper',
'grip-vertical': 'grip-vertical',
'indeterminate': 'dash-lg',
'pause': 'pause',
'play': 'play',
'circle-xmark': 'x-circle',
'grip-vertical': 'grip-vertical',
'eye-slash': 'eye-slash',
'eye': 'eye',
'user': 'person',
'xmark': 'x-lg',
}
};
registerIconLibrary({
name: 'bootstrap-icons',
system(name, family) {
if (!system.nameMap[name]) {
// If the icon is not known, use the default library
return { library: 'wa', name, family, variant };
}
return {
name: system.nameMap[name],
family: system.filled.includes(name) ? 'filled' : ''
};
},
getUrl: (name, family) => {
const suffix = family === 'filled' ? '-fill' : '';
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
}
});
```
#### Index of All System Icons { #system-icons-index }
These are all system icons used currently by Web Awesome components (`system:` prefix omitted for readability):
| Name | Variant | Icon |
| --- | --- | --- |
{%- for icon in systemIcons %}
| `{{ icon.name }}` | `{{ icon.variant }}` | <wa-icon library="wa" name="system:{{ icon.name }}" family="classic" variant="{{ icon.variant }}"></wa-icon> |
{%- endfor %}
### Inlined icons { #inlined }
Inlined icons are SVG icons that are loaded directly from code rather than from HTTP requests, making them load faster in your application.
Inlining critical icons improves performance by eliminating HTTP requests, reducing load times, and ensuring they are immediately available.
As an example, all of [Web Awesomes default system icons](#system-icons-index) are inlined, and we strongly advise you inline the corresponding icons in your custom icon libraries as well.
#### How to Use Inlined Icons
The `inlined` property allows you to provide icon SVG markup directly in your code.
This creates a mapping of `(name, family, variant)` to SVG markup.
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary({
name: 'default',
getUrl: name => `/path/to/custom/icons/${name}.svg`,
inlined: {
check: '<svg xmlns="http://www.w3.org/2000/svg">...</svg>',
}
});
</script>
```
The structure of the `inlined` property is as follows:
- For simple libraries (no families or variants): `{ name: svg }`
- For libraries with families (no variants): `{ family: { name: svg } }`
- For complex libraries (with both family and variant): `{ family: { variant: { name: svg } } }`
#### Adding More Inlined Icons
To add additional icons to an existing library, use the `inline()` method:
```js
import { getIconLibrary } from '/dist/webawesome.js';
let defaultLibrary = getIconLibrary('default');
defaultLibrary.inline({
classic: { // family
regular: { // variant
'circle-info': '<svg xmlns="http://www.w3.org/2000/svg">...</svg>',
'triangle-exclamation': '<svg xmlns="http://www.w3.org/2000/svg">...</svg>'
// ...
}
}
});
```
#### Best Practice
When using custom icon libraries with Web Awesome components, always inline system icons to ensure optimal performance.
### Customize icon markup, for SVG sprites and more
By default, icon markup is produced by fetching the URL returned by the `getUrl()` function.
You can provide a `getMarkup()` function to customize this.
A common use case for that is SVG sprites, often used to improve performance by avoiding multiple trips for each SVG.
The browser will load the sprite sheet once and then you reference the particular SVG within the sprite sheet using its id:
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary({
name: 'sprite',
getUrl: name => `/assets/images/sprite.svg#${name}`,
getMarkup: url => `<svg fill="currentColor"><use href="${url}"></use></svg>`
});
</script>
```
As always, make sure to benchmark these changes. When using HTTP/2, it may in fact be more bandwidth-friendly to use multiple small requests instead of 1 large sprite sheet.
:::warning
When using sprite sheets, the `wa-load` and `wa-error` events will not fire.
For security reasons, browsers may apply the same-origin policy on `<use>` elements located in the `<wa-icon>` shadow DOM and may refuse to load a cross-origin URL. There is currently no defined way to set a cross-origin policy for `<use>` elements. For this reason, sprite sheets should only be used if you're self-hosting them.
:::
### Fallbacks
By default, if an icon fails to load, WA will retry using the WA default icon library, and if that also fails, a blank icon will be displayed.
You can provide a `fallback()` function to customize this behavior.
Some examples for common use cases follow.
If you never want icons outside your library to display:
```js
registerIconLibrary({
name: 'my-icons',
getUrl: (name, family, variant) => `/assets/icons/${name}.svg`,
fallback: (name, family, variant) => {
// Don't show anything if an icon is not found
return null;
}
});
```
If you want to display a certain designated "missing icon" icon:
```js
registerIconLibrary({
name: 'my-icons',
getUrl: (name, family, variant) => `/assets/icons/${name}.svg`,
inlined: {
// Make sure the missing icon never fails by inlining it:
'missing-icon': '<svg xmlns="http://www.w3.org/2000/svg">...</svg>'
}
fallback: (name, family, variant) => {
return {name: 'missing-icon'};
}
});
```
If you want to retry with the default family and variant:
```js
registerIconLibrary({
name: 'my-icons',
getUrl: (name, family, variant) => `/assets/icons/${name}.svg`,
fallback: (name, family, variant) => {
if (family !== 'classic' || variant !== 'solid') {
return { name, family: 'classic', variant: 'solid' };
}
}
});
```
## Icon Library Examples { #icon-libraries }
The following examples demonstrate how to register a number of popular, open source icon libraries via CDN. Feel free to adapt the code as you see fit to use your own origin or naming conventions.
### Bootstrap Icons
@@ -143,8 +511,42 @@ Icons in this library are licensed under the [MIT License](https://github.com/tw
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('default', {
resolver: (name, family) => {
let system = {
filled: ['circle', 'pause', 'play', 'star', 'user'],
nameMap: {
'chevron-down': 'chevron-down',
'chevron-left': 'chevron-left',
'chevron-right': 'chevron-right',
'check': 'check-lg',
'circle': 'circle',
'eye-dropper': 'eyedropper',
'grip-vertical': 'grip-vertical',
'indeterminate': 'dash-lg',
'pause': 'pause',
'play': 'play',
'circle-xmark': 'x-circle',
'grip-vertical': 'grip-vertical',
'eye-slash': 'eye-slash',
'eye': 'eye',
'user': 'person',
'xmark': 'x-lg',
}
};
registerIconLibrary({
name: 'default',
system(name, family) {
if (!system.nameMap[name]) {
// If the icon is not known, use the default library
return { library: 'wa', name: name, family, variant };
}
return {
name: system.nameMap[name],
family: system.filled.includes(name) ? 'filled' : ''
};
},
getUrl: (name, family) => {
const suffix = family === 'filled' ? '-fill' : '';
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
}
@@ -162,8 +564,9 @@ Icons in this library are licensed under the [Creative Commons 4.0 License](http
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('boxicons', {
resolver: name => {
registerIconLibrary({
name: 'boxicons',
getUrl: name => {
let folder = 'regular';
if (name.substring(0, 4) === 'bxs-') folder = 'solid';
if (name.substring(0, 4) === 'bxl-') folder = 'logos';
@@ -216,8 +619,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('lucide', {
resolver: name => `https://cdn.jsdelivr.net/npm/lucide-static@0.16.29/icons/${name}.svg`
registerIconLibrary({
name: 'lucide',
getUrl: name => `https://cdn.jsdelivr.net/npm/lucide-static@0.16.29/icons/${name}.svg`
});
</script>
```
@@ -232,8 +636,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/ta
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('heroicons', {
resolver: name => `https://cdn.jsdelivr.net/npm/heroicons@2.0.1/24/outline/${name}.svg`
registerIconLibrary({
name: 'heroicons',
getUrl: name => `https://cdn.jsdelivr.net/npm/heroicons@2.0.1/24/outline/${name}.svg`
});
</script>
@@ -257,8 +662,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('iconoir', {
resolver: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`
registerIconLibrary({
name: 'iconoir',
getUrl: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`
});
</script>
@@ -282,8 +688,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/io
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('ionicons', {
resolver: name => `https://cdn.jsdelivr.net/npm/ionicons@5.1.2/dist/ionicons/svg/${name}.svg`,
registerIconLibrary({
name: 'ionicons',
getUrl: name => `https://cdn.jsdelivr.net/npm/ionicons@5.1.2/dist/ionicons/svg/${name}.svg`,
mutator: svg => {
svg.setAttribute('fill', 'currentColor');
svg.setAttribute('stroke', 'currentColor');
@@ -327,8 +734,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/mi
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('jam', {
resolver: name => `https://cdn.jsdelivr.net/npm/jam-icons@2.0.0/svg/${name}.svg`,
registerIconLibrary({
name: 'jam',
getUrl: name => `https://cdn.jsdelivr.net/npm/jam-icons@2.0.0/svg/${name}.svg`,
mutator: svg => svg.setAttribute('fill', 'currentColor')
});
</script>
@@ -360,8 +768,9 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('material', {
resolver: name => {
registerIconLibrary({
name: 'material',
getUrl: name => {
const match = name.match(/^(.*?)(_(round|sharp))?$/);
return `https://cdn.jsdelivr.net/npm/@material-icons/svg@1.0.5/svg/${match[1]}/${match[3] || 'outline'}.svg`;
},
@@ -403,8 +812,9 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('remixicon', {
resolver: name => {
registerIconLibrary({
name: 'remixicon',
getUrl: name => {
const match = name.match(/^(.*?)\/(.*?)?$/);
match[1] = match[1].charAt(0).toUpperCase() + match[1].slice(1);
return `https://cdn.jsdelivr.net/npm/remixicon@2.5.0/icons/${match[1]}/${match[2]}.svg`;
@@ -440,8 +850,9 @@ Icons in this library are licensed under the [MIT License](https://github.com/ta
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('tabler', {
resolver: name => `https://cdn.jsdelivr.net/npm/@tabler/icons@1.68.0/icons/${name}.svg`,
registerIconLibrary({
name: 'tabler',
getUrl: name => `https://cdn.jsdelivr.net/npm/@tabler/icons@1.68.0/icons/${name}.svg`,
mutator: svg => {
svg.style.fill = 'none';
svg.setAttribute('stroke', 'currentColor');
@@ -476,8 +887,9 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('unicons', {
resolver: name => {
registerIconLibrary({
name: 'unicons',
getUrl: name => {
const match = name.match(/^(.*?)(-s)?$/);
return `https://cdn.jsdelivr.net/npm/@iconscout/unicons@3.0.3/svg/${match[2] === '-s' ? 'solid' : 'line'}/${
match[1]
@@ -504,61 +916,6 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
</div>
```
### Customizing the Default Library
The default icon library contains over 2,000 icons courtesy of [Font Awesome](https://fontawesome.com/). These are the icons that display when you use `<wa-icon>` without the `library` attribute. If you prefer to have these icons resolve elsewhere or to a different icon library, register an icon library using the `default` name and a custom resolver.
For example, this will change the default icon library to use [Bootstrap Icons](https://icons.getbootstrap.com/) loaded from the jsDelivr CDN.
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('default', {
resolver: (name, family) => {
const suffix = family === 'filled' ? '-fill' : '';
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
}
});
</script>
```
#### Customize the default library to use SVG sprites
To improve performance you can use a SVG sprites to avoid multiple trips for each SVG. The browser will load the sprite sheet once and then you reference the particular SVG within the sprite sheet using hash selector.
As always, make sure to benchmark these changes. When using HTTP/2, it may in fact be more bandwidth-friendly to use multiple small requests instead of 1 large sprite sheet.
:::warning
When using sprite sheets, the `wa-load` and `wa-error` events will not fire.
For security reasons, browsers may apply the same-origin policy on `<use>` elements located in the `<wa-icon>` shadow DOM and may refuse to load a cross-origin URL. There is currently no defined way to set a cross-origin policy for `<use>` elements. For this reason, sprite sheets should only be used if you're self-hosting them.
:::
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('sprite', {
resolver: name => `/assets/images/sprite.svg#${name}`,
mutator: svg => svg.setAttribute('fill', 'currentColor'),
spriteSheet: true
});
</script>
```
### Customizing the System Library
The system library contains only the icons used internally by Web Awesome components. Unlike the default icon library, the system library does not rely on physical assets. Instead, its icons are hard-coded as data URIs into the resolver to ensure their availability.
If you want to change the icons Web Awesome uses internally, you can register an icon library using the `system` name and a custom resolver. If you choose to do this, it's your responsibility to provide all of the icons that are required by components. You can reference `src/components/library.system.ts` for a complete list of system icons used by Web Awesome.
```html
<script type="module">
import { registerIconLibrary } from '/dist/webawesome.js';
registerIconLibrary('system', {
resolver: name => `/path/to/custom/icons/${name}.svg`
});
</script>
```

View File

@@ -885,4 +885,4 @@ If you dont want to use [native styles](/docs/native/), you can include this
```html
<link rel="stylesheet" href="{% cdnUrl 'styles/components/page.css' %}" />
```
```

View File

@@ -468,75 +468,20 @@ 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. 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.
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.
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>
<wa-popup placement="top" flip active boundary="scroll">
<span slot="anchor"></span>
<div class="box"></div>
</wa-popup>
@@ -592,7 +537,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>
<wa-popup placement="top" flip flip-fallback-placements="right bottom" flip-fallback-strategy="initial" active boundary="scroll">
<span slot="anchor"></span>
<div class="box"></div>
</wa-popup>
@@ -626,14 +571,18 @@ 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 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`.
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.
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>
<wa-popup placement="top" shift shift-padding="10" active boundary="scroll">
<span slot="anchor"></span>
<div class="box"></div>
</wa-popup>
@@ -676,7 +625,11 @@ 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 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.
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.
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.
@@ -685,7 +638,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>
<wa-popup placement="top" auto-size="both" auto-size-padding="10" active boundary="scroll">
<span slot="anchor"></span>
<div class="box"></div>
</wa-popup>

View File

@@ -425,11 +425,3 @@ 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

@@ -129,7 +129,7 @@ Set a matching width and height to make a circle, square, or rounded avatar skel
<style>
.skeleton-avatars wa-skeleton {
display: inline-block;
display: inline-flex;
width: 3rem;
height: 3rem;
margin-right: 0.5rem;

View File

@@ -152,25 +152,3 @@ 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,6 +3,7 @@ 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/installation/#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/#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

@@ -5,8 +5,11 @@ import { sort } from '../_utils/filters.js';
export default {
eleventyComputed: {
// Default parent. Can be overridden by explicitly setting parent in the data.
// parent can refer to either an ancestor page in the URL or another page in the same directory
/**
* Default parent slug. Can be overridden by explicitly setting parent in the data.
* It can be either the URL slug of a page in the same directory or a parent directory.
* @returns {string | undefined}
*/
parent(data) {
let { parent, page } = data;
@@ -17,16 +20,28 @@ export default {
return page.url.split('/').filter(Boolean).at(-2);
},
/**
* URL of parent page
* @returns {string | undefined}
*/
parentUrl(data) {
let { parent, page } = data;
return getParentUrl(page.url, parent);
},
/**
* Collection item of parent page
* @returns {object | undefined} Parent page item
*/
parentItem(data) {
let { parentUrl } = data;
return data.collections.all.find(item => item.url === parentUrl);
},
/**
* Child pages of current page
* @returns {object[]} Array of child pages
*/
children(data) {
let { collections, page, parentOf } = data;
@@ -48,7 +63,17 @@ export default {
},
};
/**
* Resolve a parent slug against a page URL
* @param {string} url - The URL of the page
* @param {string} parent - The slug of the parent page
* @returns {string} The resolved URL of the parent page
*/
function getParentUrl(url, parent) {
if (!parent) {
return undefined;
}
let parts = url.split('/').filter(Boolean);
let ancestorIndex = parts.findLastIndex(part => part === parent);
let retParts = parts.slice();
@@ -64,15 +89,18 @@ function getParentUrl(url, parent) {
let ret = retParts.join('/');
if (url.startsWith('/')) {
// If the current page starts with a slash, make sure the parent does too
// This is pretty much always the case with 11ty page URLs
ret = '/' + ret;
}
if (!retParts.at(-1).includes('.') && !ret.endsWith('/')) {
if (!retParts.at(-1)?.includes('.') && !ret.endsWith('/')) {
// If no extension, make sure to end with a slash
ret += '/';
}
if (ret === '/docs/') {
// We don't want anyone's parent to be "Installation"!
ret = '/';
}

View File

@@ -1412,7 +1412,8 @@ hasOutline: false
import { registerIconLibrary } from '/dist/webawesome.js';
// Ensure regular icons are always available for the knobs
registerIconLibrary('fa-classic-regular', {
registerIconLibrary({
name: 'fa-classic-regular',
resolver: name => `https://ka-f.fontawesome.com/releases/v6.5.1/svgs/regular/${name}.svg`
});
@@ -1453,36 +1454,47 @@ hasOutline: false
break;
case 'premium':
iconFamily.value = 'custom';
registerIconLibrary('default', {
registerIconLibrary({
name: 'default',
resolver: name => `/assets/icons/chunk/${name}.svg`,
mutator: svg => {[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));}
});
registerIconLibrary('system', {
registerIconLibrary({
name: 'system',
resolver: name => `/assets/icons/chunk/${name}.svg`,
mutator: svg => {[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));}
});
break;
case 'playful':
iconFamily.value = 'custom';
registerIconLibrary('default', {
registerIconLibrary({
name: 'default',
resolver: name => `/assets/icons/jelly/${name}.svg`,
mutator: svg => {[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));}
});
registerIconLibrary('system', {
registerIconLibrary({
name: 'system',
name: 'system',
name: 'system',
resolver: name => `/assets/icons/jelly/${name}.svg`,
mutator: svg => {[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));}
});
break;
case 'brutalist':
caregisterIconLibrary({
registerIconLibrary({
registerIconLibrary({
name: 'default',
iconFamily.value = 'custom';
registerIconLibrary('default', {
registerIconLibrary({
name: 'default',
resolver: name => `/assets/icons/utility/${name}.svg`,
mutator: svg => {
[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));
[...svg.querySelectorAll('[stroke="black"]')].map(el => el.setAttribute('stroke', 'currentColor'));
}
});
registerIconLibrary('system', {
registerIconLibrary({
name: 'system',
resolver: name => `/assets/icons/utility/${name}.svg`,
mutator: svg => {
[...svg.querySelectorAll('[fill="black"]')].map(el => el.setAttribute('fill', 'currentColor'));
@@ -1497,10 +1509,12 @@ hasOutline: false
break;
case 'classic':
iconFamily.value = 'custom';
registerIconLibrary('default', {
registerIconLibrary({
name: 'default',
resolver: name => `/assets/icons/bootstrap/${name}.svg`,
});
registerIconLibrary('system', {
registerIconLibrary({
name: 'system',
resolver: name => `/assets/icons/bootstrap/${name}.svg`,
});
break;
@@ -1531,7 +1545,8 @@ hasOutline: false
iconLibrary = 'sharp-solid';
}
// Ensures sharp-solid variations are available for ratings, etc.
registerIconLibrary('always-solid', {
registerIconLibrary({
name: 'always-solid',
resolver: name => `https://ka-f.fontawesome.com/releases/v6.5.1/svgs/sharp-solid/${name}.svg`
});
solidifyRatingStars();
@@ -1557,15 +1572,18 @@ hasOutline: false
iconLibrary = 'solid';
}
// Ensures solid variations are available for radios, ratings, etc.
registerIconLibrary('always-solid', {
registerIconLibrary({
name: 'always-solid',
resolver: name => `https://ka-f.fontawesome.com/releases/v6.5.1/svgs/solid/${name}.svg`
});
solidifyRatingStars();
}
registerIconLibrary('default', {
registerIconLibrary({
name: 'default',
resolver: name => `https://ka-f.fontawesome.com/releases/v6.5.1/svgs/${iconLibrary}/${name}.svg`
});
registerIconLibrary('system', {
registerIconLibrary({
name: 'system',
resolver: name => `https://ka-f.fontawesome.com/releases/v6.5.1/svgs/${iconLibrary}/${name}.svg`
});
};

View File

@@ -32,7 +32,7 @@ To get everything included in Web Awesome, add the following code to the `<head>
This snippet includes three parts:
1. **The default theme**, a stylesheet that gives a cohesive look to Web Awesome components with both light and dark modes
2. **Web Awesome styles**, an optional stylesheet that [styles native HTML elements](/docs/native) and includes [utility classes](/docs/utilities) you can use in your project
2. **Web Awesome styles**, an optional stylesheet that [styles native HTML elements](/docs/native) and includes [utility classes](/docs/utilities) you can use in your project
3. **The autoloader**, a lightweight script watches the DOM for unregistered Web Awesome elements and lazy loads them for you — even if they're added dynamically
Now you can [start using Web Awesome!](/docs/usage)
@@ -58,7 +58,7 @@ Font Awesome users can set their kit code to unlock Font Awesome Pro icons. You
## Advanced Setup
The autoloader is the easiest way to use Web Awesome, but different projects (or your own preferences!) may require different installation methods.
The autoloader is the easiest way to use Web Awesome, but different projects (or your own preferences!) may require different installation methods.
### Installing via npm
@@ -122,4 +122,4 @@ Most of the magic behind assets is handled internally by Web Awesome, but if you
// Get the path to an asset, e.g. /path/to/assets/file.ext
const assetPath = getBasePath('file.ext');
</script>
```
```

View File

@@ -10,7 +10,7 @@ override:tags: []
{% markdown %}
## Installation
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 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 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

@@ -11,8 +11,8 @@ file: styles/native/radio.css
```html {.example}
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="a" value="1" checked> Option 1</label>
<label><input type="radio" name="a" value="2"> Option 2</label>
</div>
```
@@ -24,9 +24,9 @@ To set the initial value and checked state, use the `checked` attribute on the c
```html {.example}
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
<label><input type="radio" name="b" value="1" checked> Option 1</label>
<label><input type="radio" name="b" value="2"> Option 2</label>
<label><input type="radio" name="b" value="3"> Option 3</label>
</div>
```
@@ -36,9 +36,9 @@ Use the `disabled` attribute to disable a radio.
```html {.example}
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2" disabled> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<label><input type="radio" name="c" value="1" checked> Option 1</label>
<label><input type="radio" name="c" value="2" disabled> Option 2</label>
<label><input type="radio" name="c" value="3"> Option 3</label>
</div>
```
@@ -49,26 +49,26 @@ Use the [size utilities](/docs/utilities/size) to change the radios' size.
```html {.example}
<fieldset class="wa-size-s wa-cluster">
<legend>Small</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<label><input type="radio" name="d" value="1" checked> Option 1</label>
<label><input type="radio" name="d" value="2"> Option 2</label>
<label><input type="radio" name="d" value="3"> Option 3</label>
</fieldset>
<br />
<fieldset class="wa-size-m wa-cluster">
<legend>Medium</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<label><input type="radio" name="e" value="1" checked> Option 1</label>
<label><input type="radio" name="e" value="2"> Option 2</label>
<label><input type="radio" name="e" value="3"> Option 3</label>
</fieldset>
<br />
<fieldset class="wa-size-l wa-cluster">
<legend>Large</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<label><input type="radio" name="f" value="1" checked> Option 1</label>
<label><input type="radio" name="f" value="2"> Option 2</label>
<label><input type="radio" name="f" value="3"> Option 3</label>
</fieldset>
```
@@ -78,16 +78,16 @@ You can wrap native radios in a flex container to give them a horizontal or vert
```html {.example}
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
<label><input type="radio" name="g" value="1" checked> Option 1</label>
<label><input type="radio" name="g" value="2"> Option 2</label>
<label><input type="radio" name="g" value="3"> Option 3</label>
</div>
```
```html {.example}
<div class="wa-stack">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
<label><input type="radio" name="h" value="1" checked> Option 1</label>
<label><input type="radio" name="h" value="2"> Option 2</label>
<label><input type="radio" name="h" value="3"> Option 3</label>
</div>
```

View File

@@ -6,6 +6,8 @@ import { cssImport, cssLiteral, cssRule } from '../../assets/scripts/tweak/code.
import { maxGrayChroma, moreHue, selectors, urls } from '../../assets/scripts/tweak/data.js';
import { subtractAngles } from '../../assets/scripts/tweak/util.js';
import Prism from '/assets/scripts/prism.js';
import content from '/assets/scripts/vue/directives/content.js';
import savedMixin from '/assets/scripts/vue/mixins/saved.js';
await Promise.all(['wa-slider'].map(tag => customElements.whenDefined(tag)));
@@ -38,24 +40,25 @@ for (let palette in allPalettes) {
const percentFormatter = value => value.toLocaleString(undefined, { style: 'percent' });
let paletteAppSpec = {
mixins: [savedMixin],
data() {
let appRoot = document.querySelector('#palette-app');
let paletteId = appRoot.dataset.paletteId;
let palette = allPalettes[paletteId];
let id = appRoot.dataset.paletteId;
let palette = allPalettes[id];
return {
uid: undefined,
paletteId,
paletteTitle: palette.title,
id,
originalTitle: palette.title,
originalColors: palette.colors,
permalink: new Permalink(),
hueRanges,
hueShifts: Object.fromEntries(hues.map(hue => [hue, 0])),
chromaScale: 1,
grayChroma: undefined,
grayColor: undefined,
tweaking: {},
saved: null,
type: 'palette',
collection: 'palettes',
};
},
@@ -63,20 +66,16 @@ let paletteAppSpec = {
// Non-reactive variables to expose
Object.assign(this, { moreHue });
// Read URL params and apply them. This facilitates permalinks.
this.permalink.mapObject(this.hueShifts, {
keyTo: key => key.replace(/-shift$/, ''),
keyFrom: key => key + '-shift',
valueFrom: value => (!value ? '' : Number(value)),
valueTo: value => (!value ? 0 : Number(value)),
});
this.grayChroma = this.originalGrayChroma;
this.grayColor = this.originalGrayColor;
if (location.search) {
// Update from URL
this.permalink.writeTo(this.hueShifts);
// Read URL params and apply them. This facilitates permalinks.
for (let hue in this.hueShifts) {
if (this.permalink.has(hue + '-shift')) {
this.hueShifts[hue] = Number(this.permalink.get(hue + '-shift'));
}
}
for (let param of ['chroma-scale', 'gray-color', 'gray-chroma']) {
if (this.permalink.has(param)) {
@@ -91,12 +90,6 @@ let paletteAppSpec = {
this[prop] = value;
}
}
if (this.permalink.has('uid')) {
this.uid = Number(this.permalink.get('uid'));
}
this.saved = sidebar.palette.getSaved(this.getPalette());
}
},
@@ -107,6 +100,11 @@ let paletteAppSpec = {
},
computed: {
/** Default palette title for saving */
defaultTitle() {
return this.originalTitle + ' (tweaked)';
},
tweaks() {
return {
hueShifts: this.hueShifts,
@@ -123,7 +121,7 @@ let paletteAppSpec = {
code() {
let ret = {};
for (let language of ['html', 'css']) {
let code = getPaletteCode(this.paletteId, this.colors, this.tweaked, { language, cdnUrl });
let code = getPaletteCode(this.id, this.colors, this.tweaked, { language, cdnUrl });
ret[language] = {
raw: code,
highlighted: Prism.highlight(code, Prism.languages[language], language),
@@ -284,7 +282,9 @@ let paletteAppSpec = {
hueShifts: {
deep: true,
handler() {
this.permalink.readFrom(this.hueShifts);
for (let hue in this.hueShifts) {
this.permalink.set(hue + '-shift', this.hueShifts[hue], 0);
}
},
},
@@ -308,69 +308,12 @@ let paletteAppSpec = {
// Update page URL
this.permalink.updateLocation();
if (this.saved) {
this.save({ silent: true });
}
this.unsavedChanges = true;
},
},
},
methods: {
getPalette() {
return { id: this.paletteId, uid: this.uid, search: location.search };
},
save({ silent } = {}) {
let title = silent
? (this.saved?.title ?? this.paletteTitle)
: prompt('Palette title:', `${this.paletteTitle} (tweaked)`);
if (!title) {
return;
}
let uid = this.uid;
if (!uid) {
// First time saving
this.uid = uid = sidebar.palette.getUid();
this.permalink.set('uid', uid);
this.permalink.updateLocation();
}
let palette = { ...this.getPalette(), uid, title };
sidebar.palette.save(palette, this.saved);
this.saved = palette;
},
rename() {
if (!this.saved) {
return;
}
let newTitle = prompt('New title:', this.saved.title);
if (!newTitle) {
return;
}
this.saved.title = newTitle;
sidebar.palette.save(this.saved);
},
deleteSaved() {
sidebar.palette.delete(this.saved);
},
postDelete() {
this.saved = null;
this.permalink.delete('uid');
this.uid = undefined;
this.permalink.updateLocation();
},
/**
* Remove a specific tweak or all tweaks
* @param {string} [param] - The tweak to remove. If not provided, all tweaks are removed.
@@ -399,28 +342,7 @@ let paletteAppSpec = {
},
directives: {
// Like v-text, but doesn't complain if the element has content,
// making it possible to use in a PE fashion, with the contents being the fallback
content(el, { value, arg }) {
if (!el.dataset.fallback) {
// Store the original content as a fallback the first time
el.dataset.fallback = el.textContent;
}
if (value === '') {
value = el.dataset.fallback;
} else {
if (arg === 'number') {
value = Number(value).toLocaleString(undefined, { maximumSignificantDigits: 2 });
}
}
if (arg === 'html') {
el.innerHTML = value;
} else {
el.textContent = value;
}
},
content,
},
compilerOptions: {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
---
title: Action Panel
description: 'Help users complete tasks efficiently with quick access to key actions.'
icon: action-panel
isPro: true
---
## Simple
```html {.example}
<wa-card style="max-width: 60ch; margin: auto">
<div class="wa-stack wa-align-items-start">
<h3 class="wa-heading-m">New Dashboard</h3>
<p>Arrange your data into a single view to monitor trends and track performance.</p>
<wa-button variant="brand" size="small">Build Dashboard</wa-button>
</div>
</wa-card>
```
## With Flanked Button
```html {.example}
<wa-card style="max-width: 60ch; margin: auto">
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-m">Query with SQL Runner</h3>
<p>Access your database to run ad hoc queries.</p>
</div>
<wa-button variant="brand" size="small">New Query</wa-button>
</div>
</wa-card>
```
## With Switch
```html {.example}
<wa-card style="max-width: 70ch; margin: auto">
<div class="wa-stack">
<div class="wa-flank:end">
<h3 id="auto-renew-label" class="wa-heading-m">Auto-renew</h3>
<wa-switch size="large" aria-labelledby="auto-renew-label"></wa-switch>
</div>
<p class="wa-body-s">Automatically renew your subscription using your preferred payment method. We'll send you a reminder 30 days before we draft your account.</p>
</div>
</wa-card>
```
## Avatar and Quick actions
```html {.example}
<wa-card style="margin: 0 auto; max-width: 45ch;">
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1532202802379-df93d543bac3?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile-image"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Super Dog</span>
<div class="wa-caption-m wa-cluster wa-gap-xs">
<span>Online</span>
<wa-icon name="circle" style="color: var(--wa-color-green); font-size: 10px;"></wa-icon>
</div>
</div>
<div class="wa-cluster" style="font-size: var(--wa-font-size-l);">
<wa-icon-button name="microphone" label="audio-input"></wa-icon-button>
<wa-icon-button name="headphones" label="audio-output"></wa-icon-button>
<wa-icon-button name="gear" label="settings"></wa-icon-button>
</div>
</div>
</div>
</wa-card>
```

View File

@@ -0,0 +1,336 @@
---
title: Activity Log
description: 'Track and organize recent user actions or events.'
---
## Simple
```html {.example}
<div class="wa-stack" style="max-width: 60ch; margin: auto">
<article class="wa-flank:end wa-align-items-baseline" style="--flank-size: 10ch">
<div class="wa-grid">
<div class="wa-cluster">
<wa-icon name="french-fries" fixed-width></wa-icon>
<span>Fast food</span>
</div>
<wa-relative-time sync></wa-relative-time>
</div>
<wa-tag variant="danger">- $5.00</wa-tag>
</article>
<wa-divider></wa-divider>
<article class="wa-flank:end wa-align-items-baseline" style="--flank-size: 10ch">
<div class="wa-grid">
<div class="wa-cluster">
<wa-icon name="piggy-bank" fixed-width></wa-icon>
<span>Refund</span>
</div>
<wa-relative-time date="2025-03-26T09:00:00-04:00"></wa-relative-time>
</div>
<wa-tag variant="success">+ $48.99</wa-tag>
</article>
<wa-divider></wa-divider>
<article class="wa-flank:end wa-align-items-baseline" style="--flank-size: 10ch">
<div class="wa-grid">
<div class="wa-cluster">
<wa-icon name="carrot" fixed-width></wa-icon>
<span>Groceries</span>
</div>
<wa-relative-time date="2025-03-24T09:00:00-04:00"></wa-relative-time>
</div>
<wa-tag variant="danger">- $115.37</wa-tag>
</article>
<wa-divider></wa-divider>
<article class="wa-flank:end wa-align-items-baseline" style="--flank-size: 10ch">
<div class="wa-grid">
<div class="wa-cluster">
<wa-icon name="shirt" fixed-width></wa-icon>
<span>Clothing</span>
</div>
<wa-relative-time date="2025-03-15T09:00:00-04:00"></wa-relative-time>
</div>
<wa-tag variant="danger">- $220.99</wa-tag>
</article>
</div>
```
## Timeline with Icons
```html {.example}
<div class="wa-stack wa-gap-3xs" style="max-width: 60ch; margin: auto">
<article class="wa-flank" style="flex-wrap: nowrap">
<wa-avatar style="--size: 2rem">
<wa-icon slot="icon" name="acorn"></wa-icon>
</wa-avatar>
<div class="wa-flank:end wa-gap-xs">
<span>Buried by <strong>squirrel</strong></span>
<wa-format-date date="2025-04-01" month="short" day="numeric"></wa-format-date>
</div>
</article>
<wa-divider vertical style="height: 1em; margin-left: 1rem"></wa-divider>
<article class="wa-flank" style="flex-wrap: nowrap">
<wa-avatar style="--size: 2rem">
<wa-icon slot="icon" name="seedling"></wa-icon>
</wa-avatar>
<div class="wa-flank:end wa-gap-xs">
<span>Germinated in <strong>nutrient-rich soil</strong></span>
<wa-format-date date="2025-05-29" month="short" day="numeric"></wa-format-date>
</div>
</article>
<wa-divider vertical style="height: 1em; margin-left: 1rem"></wa-divider>
<article class="wa-flank" style="flex-wrap: nowrap">
<wa-avatar style="--size: 2rem">
<wa-icon slot="icon" name="tree-deciduous"></wa-icon>
</wa-avatar>
<div class="wa-flank:end wa-gap-xs">
<span>Matured by <strong>water</strong> and <strong>sunlight</strong></span>
<wa-format-date date="2025-09-15" month="short" day="numeric"></wa-format-date>
</div>
</article>
<wa-divider vertical style="height: 1em; margin-left: 1rem"></wa-divider>
<article class="wa-flank" style="flex-wrap: nowrap">
<wa-avatar style="--size: 2rem">
<wa-icon slot="icon" name="crate-apple"></wa-icon>
</wa-avatar>
<div class="wa-flank:end wa-gap-xs">
<span>Fruit harvested by <strong>you</strong></span>
<wa-format-date date="2025-10-18" month="short" day="numeric"></wa-format-date>
</div>
</article>
</div>
```
## With Expandable Details
```html {.example}
<wa-card style="max-width: 70ch; margin: auto">
<h3 class="wa-heading-m">Monthly Activity</h3>
<div class="wa-stack">
<wa-details>
<span class="wa-heading-m" slot="summary">
February
</span>
<div class="wa-stack">
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" name="envelope" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Email blasts</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">Nick Burkhart</a><span>sent to</span><a href="#">likely customers</a>
</div>
</div>
<wa-format-date date="2025-02-28" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" name="phone" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Spoke with the Pope</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">Artur Fleck</a><span>for 1 hour</span>
</div>
</div>
<wa-format-date date="2025-02-23" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
</div>
</wa-details>
<wa-details>
<span class="wa-heading-m" slot="summary">
March
</span>
<div class="wa-stack">
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" name="video" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Zoom Call with Northeast office</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">Axel Foley</a><span>for 47 minutes</span>
</div>
</div>
<wa-format-date date="2025-03-15" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" name="calendar" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Scheduled birthday party</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">John Blaze</a><span>in</span><a href="#">Social Events</a>
</div>
</div>
<wa-format-date date="2025-03-03" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
</div>
</wa-details>
<wa-details>
<span class="wa-heading-m" slot="summary">
April
</span>
<div class="wa-stack">
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" family="brands" name="intercom" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Got new lead</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">Jack Carter</a><span>on Intercom switchboard</span>
</div>
</div>
<wa-format-date date="2025-04-18" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank">
<wa-icon style="font-size: var(--wa-font-size-l)" name="list-check" fixed-width></wa-icon>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Completed Todo</span>
<div class="wa-cluster wa-gap-2xs">
<a href="#">Huey Freeman</a><span>marked complete on</span><a href="#">Daily Tasks</a>
</div>
</div>
<wa-format-date date="2025-04-02" month="short" day="numeric" class="wa-caption-m"></wa-format-date>
</div>
</article>
</div>
</wa-details>
</div>
</wa-card>
```
## Card Separated
```html {.example}
<div class="wa-stack" style="max-width: 45ch; margin: 0 auto;">
<div class="wa-stack">
<wa-card>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1559188286-a173792c8340?q=80&w=2906&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-stack wa-gap-0">
<div class="wa-split">
<span class="wa-heading-s">Isaiah Hamilton</span>
<wa-relative-time class="wa-caption-s" date="2025-01-15T09:17:00-04:00"></wa-relative-time>
</div>
<p>Who's on first?</p>
<a href="#" class="wa-cluster wa-gap-2xs">
<wa-icon name="reply" family="sharp" variant="regular"></wa-icon>
<span>Reply</span>
</a>
</div>
</div>
</wa-card>
<div class="wa-flank wa-gap-xl">
<wa-divider vertical style="height: auto; align-self: stretch"></wa-divider>
<ul class="wa-stack">
<li class="wa-stack wa-gap-2xs">
<wa-card>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1645288059073-af3e9eb62a29?q=80&w=2936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-stack wa-gap-0">
<div class="wa-split">
<span class="wa-heading-s">Melvin Hurst</span>
<wa-relative-time class="wa-caption-s" date="2025-02-15T09:17:00-04:00"></wa-relative-time>
</div>
<p>What's on second?</p>
<a href="#" class="wa-cluster wa-gap-2xs">
<wa-icon name="reply" family="sharp" variant="regular"></wa-icon>
<span>Reply</span>
</a>
</div>
</div>
</wa-card>
</li>
<li class="wa-stack wa-gap-2xs">
<wa-card>
<div class="wa-flank wa-align-items-start">
<wa-avatar image="https://images.unsplash.com/photo-1674044494331-8db2ecf18d46?q=80&w=3019&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-stack wa-gap-xs">
<div class="wa-split">
<span class="wa-heading-s">Vanessa Wright</span>
</div>
<wa-textarea size="small" aria-label="Add Your Comment"></wa-textarea>
</div>
</div>
</wa-card>
</li>
</ul>
</div>
</div>
</div>
```
## Divider Separated
```html {.example}
<wa-card with-header style="max-width: 54ch; margin: 0 auto;">
<div slot="header" class="wa-split">
<div>
<span>Notifications</span>
<wa-badge appearance="filled" variant="success" pill>2</wa-badge>
</div>
<wa-icon name="close"></wa-icon>
</div>
<div class="wa-stack">
<article>
<div class="wa-flank wa-align-items-start">
<wa-avatar image="https://images.unsplash.com/photo-1614807547811-4174d3582092?q=80&w=2932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split">
<span><strong>Happy</strong> commented in <a href="#">Reporting Dashboard</a></span>
<wa-icon name="circle" style="color: var(--wa-color-green);"></wa-icon>
</div>
<div class="wa-split">
<span class="wa-caption-m">Friday 3:12PM</span>
<wa-relative-time class="wa-caption-m" date="2025-02-15T09:17:00-04:00"></wa-relative-time>
</div>
<wa-callout variant="neutral">
Really love this approach. I think this is the best solution for the sync issue.
</wa-callout>
</div>
</div>
<wa-divider></wa-divider>
</article>
<article>
<div class="wa-flank wa-align-items-start">
<wa-avatar image="https://images.unsplash.com/photo-1613428800237-c86372070fab?q=80&w=3017&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split">
<span><strong>Charlotte</strong> followed you</span>
<wa-icon name="circle" style="color: var(--wa-color-green);"></wa-icon>
</div>
<div class="wa-split">
<span class="wa-caption-m">Friday 3:04PM</span>
<wa-relative-time class="wa-caption-m" date="2025-02-15T09:17:00-04:00"></wa-relative-time>
</div>
</div>
</div>
<wa-divider></wa-divider>
</article>
<article>
<div class="wa-flank wa-align-items-start">
<wa-avatar image="https://images.unsplash.com/photo-1645288059073-af3e9eb62a29?q=80&w=2936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Profile image"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split">
<span><strong>Tavitian</strong> invited you to <a href="#">Homepage Redesign</a></span>
</div>
<div class="wa-split">
<span class="wa-caption-m">Friday 2:22PM</span>
<wa-relative-time class="wa-caption-m" date="2025-02-15T09:17:00-04:00"></wa-relative-time>
</div>
<div class="wa-cluster wa-gap-xs">
<wa-button appearance="outlined" size="small">Decline</wa-button>
<wa-button variant="brand" size="small">Accept</wa-button>
</div>
</div>
</div>
<wa-divider></wa-divider>
</article>
</div>
</wa-card>
```

View File

@@ -0,0 +1,3 @@
{
"tags": ["app"]
}

View File

@@ -0,0 +1,165 @@
---
title: Comments
description: 'Enable users to engage in discussions, provide feedback, or record their thoughts.'
isPro: true
---
## Card with Header & Footer
```html {.example}
<form style="max-width: 60ch; margin: auto">
<wa-card>
<div slot="header" id="comment-area-label">
<span class="wa-heading-s">Leave a Comment</span>
</div>
<wa-textarea aria-labelledby="comment-area-label"></wa-textarea>
<div slot="footer" class="wa-cluster" style="justify-content: flex-end">
<wa-button appearance="filled" size="small">
<wa-icon slot="prefix" name="paperclip" variant="solid"></wa-icon>
Attach a file
</wa-button>
<wa-button variant="brand" size="small">Comment</wa-button>
</div>
</wa-card>
</form>
```
## Card with Thread
```html {.example}
<wa-card style="max-width: 60ch; margin: auto">
<div class="wa-stack">
<h3 class="wa-heading-m">Comments</h3>
<wa-textarea aria-label="Comment"></wa-textarea>
<wa-button variant="brand">Add Comment</wa-button>
<wa-divider></wa-divider>
<ul class="wa-stack">
<li class="wa-stack wa-gap-2xs">
<div class="wa-flank">
<wa-avatar initials="RF" label="User avatar"></wa-avatar>
<div class="wa-cluster">
<strong>Robert Fox</strong>
<span class="wa-caption-m">commented <wa-relative-time date="2025-03-31T09:17:00-04:00"></wa-relative-time></span>
</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis mollis nunc, vel tempor sem faucibus nec. Suspendisse potenti. Pellentesque lobortis pulvinar nulla non tempor. Interdum et malesuada fames ac ante ipsum primis in faucibus.</p>
</li>
<div class="wa-flank wa-gap-xl">
<wa-divider vertical style="height: auto; align-self: stretch"></wa-divider>
<ul class="wa-stack">
<li class="wa-stack wa-gap-2xs">
<div class="wa-flank">
<wa-avatar initials="VF" label="User avatar"></wa-avatar>
<div class="wa-cluster">
<strong>Virginia Woolf</strong>
<span class="wa-caption-m">commented <wa-relative-time date="2025-03-31T12:32:00-04:00"></wa-relative-time></span>
</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis mollis nunc, vel tempor sem faucibus nec.</p>
</li>
<li class="wa-stack wa-gap-2xs">
<div class="wa-flank">
<wa-avatar initials="CV" label="User avatar"></wa-avatar>
<div class="wa-cluster">
<strong>Clarissa Vaughan</strong>
<span class="wa-caption-m">commented <wa-relative-time></wa-relative-time></span>
</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis mollis nunc, vel tempor sem faucibus nec.</p>
</li>
<li class="wa-cluster">
<wa-icon name="reply"></wa-icon>
<a href="">Leave a reply</a>
</li>
</ul>
</div>
</ul>
</div>
</wa-card>
```
## With Avatar & Additional Actions
```html {.example}
<div class="wa-align-items-start wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="User avatar"></wa-avatar>
<div class="wa-stack wa-gap-s">
<wa-textarea placeholder="Add to the conversation..." aria-label="Add comment"></wa-textarea>
<div class="wa-split">
<div class="wa-cluster wa-gap-s">
<wa-icon-button name="paperclip" label="Attach File" id="attach-button"></wa-icon-button>
<wa-tooltip for="attach-button">Attach File</wa-tooltip>
<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>
</div>
</div>
</div>
```
## Rich Card with Multiple Actions
```html {.example}
<wa-card with-header with-footer style="max-width: 60ch; margin: auto">
<div slot="header">
<h3 class="wa-heading-s">I watched...</h3>
</div>
<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"
/>
</div>
<span class="wa-heading-l">Heretic</span>
</div>
<wa-divider></wa-divider>
<dl class="wa-split">
<dt>Date</dt>
<dd>
<wa-format-date date="2025-03-13T00:00:00.000-04:00" weekday="long" month="long" day="numeric" year="numeric" class="wa-caption-m"></wa-format-date>
</dd>
</dl>
<wa-divider></wa-divider>
<div class="wa-split">
<wa-rating label="Rating"></wa-rating>
<wa-checkbox>Loved it!</wa-checkbox>
</div>
<wa-divider></wa-divider>
<wa-textarea placeholder="Add review..." aria-label="Add review"></wa-textarea>
</div>
<div slot="footer" class="wa-grid">
<wa-button appearance="outlined">Cancel</wa-button>
<wa-button variant="brand">Save</wa-button>
</div>
</wa-card>
```
## With Preview Pane
```html{.example}
<div style="max-width: 60ch; margin: 0 auto;">
<wa-card class="wa-border-radius-square" with-footer>
<h3 class="wa-heading-m">Add a comment</h3>
<wa-tab-group>
<wa-tab panel="write">Write</wa-tab>
<wa-tab panel="preview">Preview</wa-tab>
<wa-tab-panel name="write">
<div class="wa-stack">
<div class="wa-cluster wa-gap-xs" style="justify-content: flex-end;">
<wa-icon-button name="link" label="add link"></wa-icon-button>
<wa-icon-button name="at" label="mention collaborator"></wa-icon-button>
<wa-icon-button name="hashtag" label="change heading"></wa-icon-button>
</div>
<wa-textarea aria-label="Add a comment"></wa-textarea>
</div>
</wa-tab-panel>
<wa-tab-panel name="preview">Your content will render here.</wa-tab-panel>
</wa-tab-group>
<div slot="footer" class="wa-cluster" style="justify-content: flex-end;">
<wa-button appearance="outlined" size="small">Post</wa-button>
</div>
</wa-card>
</div>
```

View File

@@ -0,0 +1,174 @@
---
title: Data Display
description: 'Convey insights, metrics, and aggregate data at a glance.'
isPro: true
---
## Simple
```html {.example}
<wa-card>
<div class="wa-grid wa-gap-3xl" style="--min-column-size: 24ch;">
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster wa-gap-xs">
<wa-icon name="sack-dollar"></wa-icon>
<span>Incomes</span>
</div>
<div class="wa-cluster wa-gap-xs" style="color: var(--wa-color-green);">
<wa-icon name="arrow-trend-up"></wa-icon>
<wa-format-number class="wa-heading-s" type="percent" value=".475"></wa-format-number>
</div>
</div>
<wa-format-number class="wa-heading-xl" type="currency" currency="USD" value="175000000" lang="en-US"></wa-format-number>
</div>
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster wa-gap-xs">
<wa-icon name="credit-card"></wa-icon>
<span>Expenses</span>
</div>
<div class="wa-cluster wa-gap-xs" style="color: var(--wa-color-red);">
<wa-icon name="arrow-trend-down"></wa-icon>
<wa-format-number class="wa-heading-s" type="percent" value=".27"></wa-format-number>
</div>
</div>
<wa-format-number class="wa-heading-xl" class="wa-heading-xl" type="currency" currency="USD" value="289472" lang="en-US"></wa-format-number>
</div>
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster wa-gap-xs">
<wa-icon name="seedling"></wa-icon>
<span>Investments</span>
</div>
<div class="wa-cluster wa-gap-xs" style="color: var(--wa-color-green);">
<wa-icon name="arrow-trend-up"></wa-icon>
<wa-format-number class="wa-heading-s" type="percent" value=".14"></wa-format-number>
</div>
</div>
<wa-format-number class="wa-heading-xl" class="wa-heading-xl" type="currency" currency="USD" value="569213" lang="en-US"></wa-format-number>
</div>
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster wa-gap-xs">
<wa-icon name="landmark"></wa-icon>
<span>Mortgages & Loans</span>
</div>
</div>
<wa-format-number class="wa-heading-xl" class="wa-heading-xl" type="currency" currency="USD" value="23904" lang="en-US"></wa-format-number>
</div>
</div>
</wa-card>
```
## Cards with Avatars
```html {.example}
<div class="wa-grid" style="--min-column-size: 30ch">
<wa-card>
<div class="wa-flank wa-align-items-start">
<wa-avatar shape="rounded">
<wa-icon slot="icon" name="user-group"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<h3 class="wa-caption-m">Total Subscribers</h3>
<div class="wa-cluster wa-gap-xs">
<span class="wa-heading-l">81,779</span>
<wa-badge variant="success" appearance="filled outlined" pill>
<wa-icon fixed-width name="arrow-up" label="Up"></wa-icon>
212
</wa-badge>
</div>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank wa-align-items-start">
<wa-avatar shape="rounded">
<wa-icon slot="icon" name="envelope-open"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<h3 class="wa-caption-m">Open Rate</h3>
<div class="wa-cluster wa-gap-xs">
<span class="wa-heading-l">61.58%</span>
<wa-badge variant="success" appearance="filled outlined" pill>
<wa-icon fixed-width name="arrow-up" label="Up"></wa-icon>
4.5%
</wa-badge>
</div>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank wa-align-items-start">
<wa-avatar shape="rounded">
<wa-icon slot="icon" name="arrow-pointer"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<h3 class="wa-caption-m">Click Rate</h3>
<div class="wa-cluster wa-gap-xs">
<span class="wa-heading-l">25.74%</span>
<wa-badge variant="danger" appearance="filled outlined" pill>
<wa-icon fixed-width name="arrow-down" label="Down"></wa-icon>
2.1%
</wa-badge>
</div>
</div>
</div>
</wa-card>
</div>
```
## Condensed Card
```html {.example}
<wa-card style="max-width: 50ch; margin: auto">
<div slot="header" class="wa-split">
<h3 class="wa-heading-m"><span style="color: var(--wa-color-text-quiet)">query</span> getUser</h3>
<wa-icon-button id="go-to-query-button" name="chevron-right" label="Go to Query"></wa-icon-button>
<wa-tooltip for="go-to-query-button">Go to Query</wa-tooltip>
</div>
<div class="wa-stack wa-gap-xl">
<div class="wa-split wa-align-items-stretch">
<article class="wa-stack wa-align-items-start wa-gap-xs">
<h4 class="wa-caption-l">Cache Hit Rate</h4>
<div class="wa-cluster wa-heading-2xl">
<wa-progress-ring value="12.3" style="--size: 1em; --track-width: 0.125em"></wa-progress-ring>
<span>12.3%</span>
</div>
<wa-badge appearance="filled outlined" variant="danger"><wa-icon name="arrow-down"></wa-icon> down from 19.6%</wa-badge>
</article>
<article class="wa-stack wa-gap-xs wa-align-items-end">
<h4 class="wa-caption-l">Max CHR</h4>
<span class="wa-heading-2xl">72.6%</span>
<wa-badge appearance="filled outlined" variant="success"><wa-icon name="sparkles"></wa-icon> CHR Impact +5.4%</wa-badge>
</article>
</div>
<wa-divider></wa-divider>
<article class="wa-stack wa-gap-xl">
<div class="wa-stack wa-gap-xs">
<h4 class="wa-caption-l">Cacheable Bandwidth</h4>
<div class="wa-split">
<span class="wa-heading-2xl">90.5 GB</span>
<span class="wa-caption-xl">69.9%</span>
</div>
<wa-progress-bar value="30.1" label="Cached and non-cacheable bandwidth"></wa-progress-bar>
</div>
<dl class="wa-stack wa-caption-m">
<div class="wa-cluster">
<dt>Cached</dt>
<dd>12.8 GB (9.8%)</dd>
</div>
<div class="wa-cluster">
<dt>Non-Cacheable</dt>
<dd>26.3 GB (20.3%)</dd>
</div>
<div class="wa-cluster">
<dt>Total</dt>
<dd>129.6 GB</dd>
</div>
</dl>
</article>
</div>
</wa-card>
```

View File

@@ -0,0 +1,253 @@
---
title: Description List
description: 'Help users digest detailed information in a structured, easy-to-scan format.'
isPro: true
---
## Left Aligned
```html {.example}
<div class="wa-stack">
<h3 class="wa-heading-m">Applicant Info</h3>
<p class="wa-caption-m">Details about the applicant and attachments.</p>
<wa-divider></wa-divider>
<dl class="wa-stack wa-gap-2xl">
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Full name</dt>
<dd>Bucky Barnes</dd>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Application for</dt>
<dd>Machine Learning Engineer</dd>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Email address</dt>
<dd>winter_soldier@example.com</dd>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Salary expectation</dt>
<dd>$240,000</dd>
</div>
<div class="wa-flank wa-align-items-start" style="--flank-size: 20ch;">
<dt>About</dt>
<dd>After being lost in action and brainwashed into becoming Hydra's ruthless assassin, my journey is one of redemption, healing, and reclaiming my true self. Though burdened with the weight of the past, I remain a fierce warrior, loyal to those I love, and I'm always striving to atone for those dark days as the Winter Soldier.
</dd>
</div>
<div class="wa-flank wa-align-items-start" style="--flank-size: 20ch;">
<dt>Attachments</dt>
<dd>
<wa-card>
<div class="wa-stack">
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_resume.pdf</span>
<span>2.4mb</span>
</span>
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_cover_letter.pdf</span>
<span>2.4mb</span>
</span>
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
</div>
</div>
</div>
</wa-card>
</dd>
</div>
</dl>
</div>
```
## Two Column
```html{.example}
<div class="wa-stack">
<h2 class="wa-heading-m">Applicant Info</h2>
<p class="wa-caption-m">Details about the applicant and attachments.</p>
<wa-divider></wa-divider>
<dl class="wa-grid wa-gap-2xl" style="--min-column-size: 40ch;">
<div class="wa-stack wa-gap-xs">
<dt>Full name</dt>
<dd>Bucky Barnes</dd>
</div>
<div class="wa-stack wa-gap-xs">
<dt>Application for</dt>
<dd>Machine Learning Engineer</dd>
</div>
<div class="wa-stack wa-gap-xs">
<dt>Email address</dt>
<dd>winter_soldier@example.com</dd>
</div>
<div class="wa-stack wa-gap-xs">
<dt>Salary expectation</dt>
<dd>$240,000</dd>
</div>
<div class="wa-stack wa-gap-xs wa-span-grid">
<dt>About</dt>
<dd>After being lost in action and brainwashed into becoming Hydra's ruthless assassin, my journey is one of redemption, healing, and reclaiming my true self. Though burdened with the weight of the past, I remain a fierce warrior, loyal to those I love, and I'm always striving to atone for those dark days as the Winter Soldier.
</dd>
</div>
<div class="wa-stack wa-gap-xs wa-span-grid">
<dt>Attachments</dt>
<dd>
<wa-card>
<div>
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_resume.pdf</span>
<span>2.4mb</span>
</span>
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_cover_letter.pdf</span>
<span>2.4mb</span>
</span>
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
</div>
</div>
</div>
</wa-card>
</dd>
</div>
</dl>
</div>
```
## Left Aligned with Actions
```html {.example}
<div class="wa-stack">
<h3 class="wa-heading-m">Applicant Info</h3>
<p class="wa-caption-m">Details about the applicant and attachments.</p>
<wa-divider></wa-divider>
<dl class="wa-stack wa-gap-2xl">
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Full name</dt>
<div class="wa-flank:end">
<dd>Bucky Barnes</dd>
<wa-button appearance="plain" variant="brand" size="small">Edit</wa-button>
</div>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Application for</dt>
<div class="wa-flank:end">
<dd>Machine Learning Engineer</dd>
<wa-button appearance="plain" variant="brand" size="small">Edit</wa-button>
</div>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Email address</dt>
<div class="wa-flank:end">
<dd>winter_soldier@example.com</dd>
<wa-button appearance="plain" variant="brand" size="small">Edit</wa-button>
</div>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Salary expectation</dt>
<div class="wa-flank:end">
<dd>$240,000</dd>
<wa-button appearance="plain" variant="brand" size="small">Edit</wa-button>
</div>
</div>
<div class="wa-flank wa-align-items-start" style="--flank-size: 20ch;">
<dt>About</dt>
<div class="wa-flank:end">
<dd>After being lost in action and brainwashed into becoming Hydra's ruthless assassin, my journey is one of redemption, healing, and reclaiming my true self. Though burdened with the weight of the past, I remain a fierce warrior, loyal to those I love, and I'm always striving to atone for those dark days as the Winter Soldier.</dd>
<wa-button appearance="plain" variant="brand" size="small">Edit</wa-button>
</div>
</div>
<div class="wa-flank" style="--flank-size: 20ch;">
<dt>Attachments</dt>
<dd>
<wa-card>
<div class="wa-stack">
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_resume.pdf</span>
<span>2.4mb</span>
</span>
<div class="wa-cluster wa-gap-2xs">
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
<wa-divider vertical style="height: 1em"></wa-divider>
<wa-button appearance="plain" variant="danger" size="small">Delete</wa-button>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank">
<wa-icon name="paperclip"></wa-icon>
<div class="wa-split">
<span class="wa-caption-m wa-cluster">
<span>bb_cover_letter.pdf</span>
<span>2.4mb</span>
</span>
<div class="wa-cluster wa-gap-2xs">
<wa-button appearance="plain" variant="brand" size="small">Download</wa-button>
<wa-divider vertical style="height: 1em"></wa-divider>
<wa-button appearance="plain" variant="danger" size="small">Delete</wa-button>
</div>
</div>
</div>
</div>
</wa-card>
</dd>
</div>
</dl>
</div>
```
## Condensed
```html{.example}
<wa-card appearance="filled" style="max-width: 45ch; margin: auto">
<div class="wa-stack">
<div class="wa-split wa-align-items-start">
<dl class="wa-stack wa-gap-2xs">
<dt class="wa-heading-s">Amount</dt>
<dd class="wa-heading-l">$5,610.00</dd>
</dl>
<wa-badge appearance="filled outlined" variant="success">Paid</wa-badge>
</div>
<wa-divider></wa-divider>
<dl class="wa-stack">
<div class="wa-flank wa-align-items-stretch">
<dt><wa-icon name="user" label="Name" fixed-width></wa-icon></dt>
<dd>Sam Wilson</dd>
</div>
<div class="wa-flank wa-align-items-stretch">
<dt><wa-icon name="calendar-days" label="Date" fixed-width></wa-icon></dt>
<dd><wa-format-date date="2025-03-15"></wa-format-date></dd>
</div>
<div class="wa-flank wa-align-items-stretch">
<dt><wa-icon family="brands" name="cc-visa" label="Credit Card" fixed-width></wa-icon></dt>
<dd>Paid with Visa 1234</dd>
</div>
</dl>
</div>
<div slot="footer">
<a href="" class="wa-cluster wa-gap-2xs">
<span>Download Receipt</span>
<wa-icon name="arrow-right"></wa-icon>
</a>
</div>
</wa-card>
```

View File

@@ -0,0 +1,207 @@
---
title: Empty State
description: 'Guide users with helpful prompts and visuals when no content is available.'
isPro: true
---
## Simple
```html {.example}
<div class="wa-stack wa-align-items-center">
<wa-icon name="backpack" class="wa-caption-l" style="font-size: var(--wa-font-size-3xl)"></wa-icon>
<span class="wa-heading-m">No Kits</span>
<p class="wa-caption-l">Manage all of your project's icons in a kit.</p>
<wa-button>
<wa-icon slot="prefix" name="plus"></wa-icon>
Add Kit
</wa-button>
</div>
```
## With Interactive Placeholder
```html {.example}
<a href="" class="wa-stack wa-align-items-center wa-placeholder wa-link-plain" style="max-width: 60ch; margin: auto">
<wa-icon name="ufo-beam" class="wa-caption-l" family="sharp" style="font-size: var(--wa-font-size-3xl)"></wa-icon>
<p class="wa-heading-m">No Custom Icons</p>
<p style="text-align: center">Add your own icon or logo to get started.</p>
</a>
```
## With Templates
```html {.example}
<wa-card with-header with-footer style="max-width: 70ch; margin: auto">
<div slot="header" class="wa-stack wa-gap-xs">
<h2 class="wa-heading-m">Projects</h2>
</div>
<div class="wa-stack wa-gap-xl">
<p class="wa-caption-m">You havent created a project yet. Get started by selecting a template or start with a blank canvas.</p>
<div class="wa-grid wa-gap-xl" style="--min-column-size: 30ch;">
<a href="" class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-yellow-90);color: var(--wa-color-yellow-40);">
<wa-icon slot="icon" name="note-sticky"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Quick Note <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
Jot down any idea. Will it make sense later? Who knows.
</p>
</div>
</a>
<a href="" class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-red-90);color: var(--wa-color-red-40);">
<wa-icon slot="icon" name="list-check"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Checklist <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
The ultimate tool for looking busy.
</p>
</div>
</a>
<a href=""class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-purple-90);color: var(--wa-color-purple-40);">
<wa-icon slot="icon" name="table-cells"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Spreadsheet <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
Endless rows and columns of tiny, soul-crushing numbers.
</p>
</div>
</a>
<a href="" class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-orange-90);color: var(--wa-color-orange-40);">
<wa-icon slot="icon" name="presentation-screen"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Slideshow <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
Dramatic transitions make everything seem more official.
</p>
</div>
</a>
<a href="" class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-green-90);color: var(--wa-color-green-40);">
<wa-icon slot="icon" name="pen-field"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Form <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
Collect the deepest personal details and darkest secrets.
</p>
</div>
</a>
<a href="" class="wa-flank wa-align-items-start wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-blue-90);color: var(--wa-color-blue-40);">
<wa-icon slot="icon" name="image"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-align-items-center wa-cluster wa-gap-xs wa-heading-s">
Create a Photo Album <wa-icon name="arrow-right"></wa-icon>
</span>
<p class="wa-caption-m">
Curate your best memories or most basic food pictures.
</p>
</div>
</a>
</div>
</div>
<div slot="footer">
<a href="" class="wa-cluster wa-gap-xs">
<span>Or start with a blank canvas</span>
<wa-icon name="arrow-right"></wa-icon>
</a>
</div>
</wa-card>
```
## Add people
```html {.example}
<wa-card style="max-width: 60ch; margin: 0 auto;">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-m">Add team members</h3>
<p>This project is awful lonely. Invite some team members to liven up the joint.</p>
<div class="wa-flank:end wa-gap-xs">
<wa-input></wa-input><wa-button>Invite</wa-button>
</div>
<div class="wa-stack">
<em class="wa-caption-l">Team members previously added to projects</em>
<wa-divider></wa-divider>
<section>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1614807547811-4174d3582092?q=80&w=2932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Earl Upton</span>
<span class="wa-caption-m">DevOps</span>
</div>
<wa-button appearance="plain">
<wa-icon name="user-plus" slot="prefix"></wa-icon>
Invite
</wa-button>
</div>
</div>
<wa-divider></wa-divider>
</section>
<section>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1613428800237-c86372070fab?q=80&w=3017&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" lable="profile image"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Steamboat Willie</span>
<span class="wa-caption-m">Captain</span>
</div>
<wa-button appearance="plain">
<wa-icon name="user-plus" slot="prefix"></wa-icon>
Invite
</wa-button>
</div>
</div>
<wa-divider></wa-divider>
</section>
<section>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1678582967399-bf558533f5eb?q=80&w=3029&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Melissa Eckers</span>
<span class="wa-caption-m">Cloud Engineer</span>
</div>
<wa-button appearance="plain">
<wa-icon name="user-plus" slot="prefix"></wa-icon>
Invite
</wa-button>
</div>
</div>
<wa-divider></wa-divider>
</section><section>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1559188286-a173792c8340?q=80&w=2906&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-s">Devin Shears</span>
<span class="wa-caption-m">UX Writer</span>
</div>
<wa-button appearance="plain">
<wa-icon name="user-plus" slot="prefix"></wa-icon>
Invite
</wa-button>
</div>
</div>
<wa-divider></wa-divider>
</section>
</div>
</div>
</wa-card>
```

View File

@@ -0,0 +1,119 @@
---
title: FAQ
description: 'Empower users to learn more with a structured list of questions and answers.'
isPro: true
---
## With Flanked Heading & Description
```html {.example}
<div class="wa-flank wa-align-items-start wa-gap-2xl" style="--flank-size: 35ch">
<div>
<h2>Frequently Asked Questions</h2>
<p>Cant find an answer? Reach out to your local <a href="">Operator</a>, or contact <a href="">the Oracle</a>, and enjoy a cookie. &#127850;</p>
</div>
<dl class="wa-stack wa-gap-2xl">
<div class="wa-stack wa-gap-xs">
<dt>Is Zion actually real, or just another Matrix?</dt>
<dd>Ah, the question that keeps redpills up at night. Sure, we escaped the first Matrix, but whos to say Zion isnt just another layer of the simulation?</dd>
</div>
<div class="wa-stack wa-gap-xs">
<dt>Why do the Agents always wear suits?</dt>
<dd>Because nothing says "unstoppable digital enforcer" like a generic business professional aesthetic. Also, intimidation. You ever try fighting someone in sunglasses and a tie? Its terrifying.</dd>
</div>
<div class="wa-stack wa-gap-xs">
<dt>Can I go back into the Matrix once Im out?</dt>
<dd>Technically, yes—via hacking in. Emotionally? That depends on how well you handle the knowledge that nothing around you is real.</dd>
</div>
</dl>
</div>
```
## With Expandable Answers
```html {.example}
<div class="wa-stack">
<h2>Frequently Asked Questions</h2>
<wa-details appearance="plain">
<h3 slot="summary" class="wa-heading-m" style="margin: 0">Is Zion actually real, or just another Matrix?</h3>
Ah, the question that keeps redpills up at night. Sure, we escaped the first Matrix, but whos to say Zion isnt just another layer of the simulation?
</wa-details>
<wa-divider></wa-divider>
<wa-details appearance="plain">
<h3 slot="summary" class="wa-heading-m" style="margin: 0">Why do the Agents always wear suits?</h3>
Because nothing says "unstoppable digital enforcer" like a generic business professional aesthetic. Also, intimidation. You ever try fighting someone in sunglasses and a tie? Its terrifying.
</wa-details>
<wa-divider></wa-divider>
<wa-details appearance="plain">
<h3 slot="summary" class="wa-heading-m" style="margin: 0">Can I go back into the Matrix once Im out?</h3>
Technically, yes—via hacking in. Emotionally? That depends on how well you handle the knowledge that nothing around you is real.
</wa-details>
</div>
```
## Two Column
```html {.example}
<div class="wa-stack wa-gap-2xl">
<h2>Frequently Asked Questions</h2>
<dl class="wa-stack wa-gap-2xl">
<div class="wa-grid wa-gap-xs">
<dt class="wa-heading-m">Is Zion actually real, or just another Matrix?</dt>
<dd>Ah, the question that keeps redpills up at night. Sure, we escaped the first Matrix, but whos to say Zion isnt just another layer of the simulation?</dd>
</div>
<wa-divider></wa-divider>
<div class="wa-grid wa-gap-xs">
<dt class="wa-heading-m">Why do the Agents always wear suits?</dt>
<dd>Because nothing says "unstoppable digital enforcer" like a generic business professional aesthetic. Also, intimidation. You ever try fighting someone in sunglasses and a tie? Its terrifying.</dd>
</div>
<wa-divider></wa-divider>
<div class="wa-grid wa-gap-xs">
<dt class="wa-heading-m">Can I go back into the Matrix once Im out?</dt>
<dd>Technically, yes—via hacking in. Emotionally? That depends on how well you handle the knowledge that nothing around you is real.</dd>
</div>
</dl>
</div>
```
## Multiple Columns
```html{.example}
<div>
<h2>Frequently Asked Questions</h2>
<dl class="wa-grid wa-gap-m" style="--min-column-size: 30ch;">
<div class="wa-stack wa-gap-xs">
<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>
</div>
<div class="wa-stack wa-gap-xs">
<dt class="wa-heading-m">Do you offer a free trial?</dt>
<dd>
<p>We offer a free trial to first-time subscribers. You can find more about the trial here.</p>
<p>We also have the following opportunities to learn for free:</p>
<ul>
<li>The online bootcamp is a free, two-week curriculum to get you started with web development.</li>
<li>You can create a free account to gain access to five full courses for free.</li>
</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

@@ -0,0 +1,525 @@
---
title: Grid List
description: 'Improve browsing and selection by organizing data in a structured grid layout.'
isPro: true
---
## Cards with Footer Actions
```html {.example}
<div class="wa-grid" style="--min-column-size: 30ch;">
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<div class="wa-cluster wa-gap-xs">
<h3 class="wa-heading-s">Barklia Woofington</h3 class="wa-heading-s">
<wa-badge pill>Admin</wa-badge>
</div>
<span class="wa-caption-m">Canine Executive Officer</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1593270379182-fe1b1f6d67e5?q=80&w=2175&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of black and white Border Collie"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<div class="wa-cluster wa-gap-xs">
<h3 class="wa-heading-s">Maggie Pawsworth</h3 class="wa-heading-s">
<wa-badge pill>Admin</wa-badge>
</div>
<span class="wa-caption-m">Canine Fetch Officer</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1514479425649-0981aca9fe41?q=80&w=3474&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of black collie mix"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Rex Tailwag</h3 class="wa-heading-s">
<span class="wa-caption-m">Head of Security</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1610968755695-d7fcb5fd4b92?q=80&w=2848&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of black and tan German Shepherd"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Luna Sniffington</h3 class="wa-heading-s">
<span class="wa-caption-m">Hound Relations</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1526440847959-4e38e7f00b04?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of black and tan Yorkshire Terrier"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Charlie Drooler</h3 class="wa-heading-s">
<span class="wa-caption-m">Head of Sales</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1554692844-6627ca340264?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of tan and white corgi"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Daisy Zoomley</h3 class="wa-heading-s">
<span class="wa-caption-m">IT Support</span>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1544378062-0b74cc8b4713?q=80&w=3648&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="Avatar of gray Weimaraner"></wa-avatar>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
</div>
```
## Cards with Footer Actions & Large Image
```html {.example}
<div class="wa-grid" style="--min-column-size: 29ch;">
<wa-card with-footer>
<div class="wa-stack wa-align-items-center wa-gap-xs">
<div class="wa-frame wa-border-radius-circle">
<img src="https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?q=80&w=2680&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<h2 class="wa-heading-m">Scott Summers</h2>
<p class="wa-caption-l">DevOps</p>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-stack wa-align-items-center wa-gap-xs">
<div class="wa-frame wa-border-radius-circle">
<img src="https://images.unsplash.com/photo-1559188286-a173792c8340?q=80&w=2906&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<h2 class="wa-heading-m">Kaitlin Moore</h2>
<p class="wa-caption-l">Systems Engineer</p>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-stack wa-align-items-center wa-gap-xs">
<div class="wa-frame wa-border-radius-circle">
<img src="https://images.unsplash.com/photo-1613428800237-c86372070fab?q=80&w=3017&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<h2 class="wa-heading-m">Nessa Riley</h2>
<p class="wa-caption-l">Cloud Engineer</p>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-stack wa-align-items-center wa-gap-xs">
<div class="wa-frame wa-border-radius-circle">
<img src="https://images.unsplash.com/photo-1645288059073-af3e9eb62a29?q=80&w=2936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<h2 class="wa-heading-m">Veronica Staley</h2>
<p class="wa-caption-l">Machine Learning Engineer</p>
</div>
<div slot="footer" class="wa-grid wa-gap-xs" style="--min-column-size: 10ch;">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="at"></wa-icon>
Email
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="phone"></wa-icon>
Phone
</wa-button>
</div>
</wa-card>
</div>
```
## with Images
```html {.example}
<div class="wa-grid">
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?q=80&w=2680&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Jeff Hanks</span>
<span>Product Designer</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1674044494331-8db2ecf18d46?q=80&w=3019&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Allen Bryant</span>
<span>Staff Engineer</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1645288059073-af3e9eb62a29?q=80&w=2936&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Mariah Greene</span>
<span>DevOps</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1613428800237-c86372070fab?q=80&w=3017&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Beverly Winslow</span>
<span>Design Systems Lead</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1614807547811-4174d3582092?q=80&w=2932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Eric Masterson</span>
<span>Copy Writer</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
<article class="wa-stack">
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1559188286-a173792c8340?q=80&w=2906&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
<div class="wa-stack wa-gap-3xs">
<span>Stephen Coffee</span>
<span>Visual Designer</span>
</div>
<div class="wa-cluster wa-gap-3xs">
<wa-icon-button name="bluesky" family="brands" label="link to Blusky profile"></wa-icon-button>
<wa-icon-button name="dribbble" family="brands" label="link to Dribbble profile"></wa-icon-button>
</div>
</article>
</div>
```
## Linked Cards with Options Menu
```html{.example}
<div class="wa-grid" style="--min-column-size: 25ch">
<wa-card>
<div class="wa-flank:end">
<a href="" class="wa-flank wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-yellow-80); --text-color: var(--wa-color-yellow-40)">
<wa-icon slot="icon" name="pancakes"></wa-icon>
</wa-avatar>
<div class="wa-gap-2xs wa-stack">
<span class="wa-heading-s">Breakfast</span>
<span class="wa-caption-m">28 Items</span>
</div>
</a>
<wa-dropdown>
<wa-icon-button id="more-actions-1" slot="trigger" name="ellipsis-vertical" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="more-actions-1">More actions</wa-tooltip>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<a href="" class="wa-flank wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-orange-80); --text-color: var(--wa-color-orange-40)">
<wa-icon slot="icon" name="burger-cheese"></wa-icon>
</wa-avatar>
<div class="wa-gap-2xs wa-stack">
<span class="wa-heading-s">Lunch + Dinner</span>
<span class="wa-caption-m">40 Items</span>
</div>
</a>
<wa-dropdown>
<wa-icon-button id="more-actions-2" slot="trigger" name="ellipsis-vertical" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="more-actions-2">More actions</wa-tooltip>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<a href="" class="wa-flank wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-indigo-80); --text-color: var(--wa-color-indigo-40)">
<wa-icon slot="icon" name="martini-glass-citrus"></wa-icon>
</wa-avatar>
<div class="wa-gap-2xs wa-stack">
<span class="wa-heading-s">Beverages</span>
<span class="wa-caption-m">19 Items</span>
</div>
</a>
<wa-dropdown>
<wa-icon-button id="more-actions-3" slot="trigger" name="ellipsis-vertical" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="more-actions-3">More actions</wa-tooltip>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<a href="" class="wa-flank wa-link-plain">
<wa-avatar shape="rounded" style="--background-color: var(--wa-color-pink-80); --text-color: var(--wa-color-pink-40)">
<wa-icon slot="icon" name="cake-slice"></wa-icon>
</wa-avatar>
<div class="wa-gap-2xs wa-stack">
<span class="wa-heading-s">Dessert</span>
<span class="wa-caption-m">11 Items</span>
</div>
</a>
<wa-dropdown>
<wa-icon-button id="more-actions-4" slot="trigger" name="ellipsis-vertical" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="more-actions-4">More actions</wa-tooltip>
</div>
</wa-card>
</div>
```
## Kanban
```html {.example}
<div>
<h2>Project #487</h2>
<div class="wa-grid wa-gap-2xl">
<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">
<div class="wa-cluster wa-gap-2xs">
<span class="wa-heading-s">Unit Testing</span>
<wa-dropdown>
<wa-icon-button id="task-action-4" slot="trigger" name="ellipsis" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="task-action-4">More actions</wa-tooltip>
</div>
<div class="wa-cluster wa-gap-2xs">
<wa-badge appearance="outlined" pill>DevOps</wa-badge> <wa-badge variant="neutral" appearance="outlined" pill>Priority: Low</wa-badge>
</div>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1559188286-a173792c8340?q=80&w=2906&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
label="profile image"></wa-avatar>
</div>
</wa-card>
<wa-button appearance="plain">
<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">
<div class="wa-cluster wa-gap-2xs">
<span class="wa-heading-s">UX Audit</span>
<wa-dropdown>
<wa-icon-button id="task-action-2" slot="trigger" name="ellipsis" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="task-action-2">More actions</wa-tooltip>
</div>
<div class="wa-cluster wa-gap-2xs">
<wa-badge appearance="outlined" pill>Design</wa-badge> <wa-badge variant="warning" appearance="outlined" pill>Priority: Medium</wa-badge>
</div>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1613428800237-c86372070fab?q=80&w=3017&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
label="profile image"></wa-avatar>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<div class="wa-stack wa-gap-2xs">
<div class="wa-cluster wa-gap-2xs">
<span class="wa-heading-s">Visual Testing</span>
<wa-dropdown>
<wa-icon-button id="task-action-3" slot="trigger" name="ellipsis" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="task-action-3">More actions</wa-tooltip>
</div>
<div class="wa-cluster wa-gap-2xs">
<wa-badge appearance="outlined" pill>Design</wa-badge> <wa-badge variant="danger" appearance="outlined" pill>Priority: High</wa-badge>
</div>
</div>
<wa-avatar image="https://images.unsplash.com/photo-1614807547811-4174d3582092?q=80&w=2932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" label="profile image"></wa-avatar>
</div>
</wa-card>
<wa-button appearance="plain">
<wa-icon name="plus"></wa-icon>
Add Task
</wa-button>
</div>
<div class="wa-stack">
<div class="wa-cluster wa-gap-s"><span>Ready for Review</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">
<div class="wa-cluster wa-gap-2xs">
<span class="wa-heading-s">Deploy Bug Fixes</span>
<wa-dropdown>
<wa-icon-button id="task-action-1" slot="trigger" name="ellipsis" label="More actions"></wa-icon-button>
<wa-menu>
<wa-menu-item>Copy link</wa-menu-item>
<wa-menu-item>Rename</wa-menu-item>
<wa-menu-item>Move to trash</wa-menu-item>
</wa-menu>
</wa-dropdown>
<wa-tooltip for="task-action-1">More actions</wa-tooltip>
</div>
<div class="wa-cluster wa-gap-2xs">
<wa-badge appearance="outlined" pill>Development</wa-badge> <wa-badge variant="warning" appearance="outlined" pill>Priority: Medium</wa-badge>
</div>
</div>
<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

@@ -0,0 +1,9 @@
---
title: App
description: Pre-built action panels, data displays, and more ready to drop into your web app.
parent: patterns
layout: overview
override:tags: []
listChildren: true
isPro: false
---

View File

@@ -0,0 +1,266 @@
---
title: Leaderboard
description: 'Engage and motivate users by highlighting top performers, scores, and achievements.'
isPro: true
---
## Simple
```html {.example}
<div class="wa-stack">
<h3>Daily Crossword</h3>
<div class="wa-grid">
<wa-callout variant="warning" appearance="filled">
<wa-icon slot="icon" name="timer"></wa-icon>
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-l">11h 54m 52s</span>
<span class="wa-caption-m">until play ends</span>
</div>
</wa-callout>
<wa-callout variant="neutral" appearance="filled">
<wa-icon slot="icon" name="user-group"></wa-icon>
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-l">304</span>
<span class="wa-caption-m">players on this leaderboard</span>
</div>
</wa-callout>
</div>
<wa-card>
<div class="wa-stack">
<ol class="wa-stack">
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="1" fixed-width></wa-icon>
<wa-avatar>
<wa-icon slot="icon" name="hat-wizard"></wa-icon>
</wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>wordwiz</span>
<small class="wa-caption-l">00:01:41</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="2" fixed-width></wa-icon>
<wa-avatar initials="A"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>acrossNdown</span>
<small class="wa-caption-l">00:01:58</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="3" fixed-width></wa-icon>
<wa-avatar initials="X"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>XwordChamp</span>
<small class="wa-caption-l">00:02:14</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="4" fixed-width></wa-icon>
<wa-avatar>
<wa-icon slot="icon" name="chess-knight"></wa-icon>
</wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>puzzlepoet</span>
<small class="wa-caption-l">00:02:16</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="5" fixed-width></wa-icon>
<wa-avatar initials="R"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>RiddleMeThis</span>
<small class="wa-caption-l">00:02:34</small>
</div>
</li>
</ol>
</div>
<div slot="footer">
<a href="" class="wa-cluster wa-gap-xs wa-caption-m">
<span>View all standings</span>
<wa-icon name="arrow-right"></wa-icon>
</a>
</div>
</wa-card>
</div>
```
## Two Column
```html {.example}
<div class="wa-stack">
<h3>Collective Activity for Yesterday</h3>
<div class="wa-grid">
<wa-callout variant="neutral" appearance="filled">
<wa-icon slot="icon" name="book"></wa-icon>
<div class="wa-stack wa-gap-0">
<h4 class="wa-heading-xs">Items Studied</h4>
<div class="wa-heading-2xl">482,813</div>
</div>
</wa-callout>
<wa-callout variant="brand" appearance="filled">
<wa-icon slot="icon" name="diploma"></wa-icon>
<div class="wa-stack wa-gap-0">
<h4 class="wa-heading-xs">Items Mastered</h4>
<div class="wa-heading-2xl">67,106</div>
</div>
</wa-callout>
<wa-callout variant="success" appearance="filled">
<wa-icon slot="icon" name="wand-sparkles"></wa-icon>
<div class="wa-stack wa-gap-0">
<h4 class="wa-heading-xs">Items Created</h4>
<div class="wa-heading-2xl">2,080</div>
</div>
</wa-callout>
</div>
<div class="wa-grid">
<wa-card>
<div slot="header" class="wa-flank wa-gap-xl">
<wa-icon name="graduation-cap" class="wa-heading-xl"></wa-icon>
<span class="wa-gap-2xs wa-stack">
<h4>Study Leaders</h4>
<span class="wa-caption-m">Items mastered in the last 7 days</span>
</span>
</div>
<div class="wa-stack">
<ol class="wa-stack">
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="1" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1620428268482-cf1851a36764?q=80&w=3418&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>mitsuwo</span>
<small class="wa-caption-l">2,753</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="2" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1639628735078-ed2f038a193e?q=80&w=3348&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>knowledgeninja</span>
<small class="wa-caption-l">2,298</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="3" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1638803040283-7a5ffd48dad5?q=80&w=2592&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>NxtLvl</span>
<small class="wa-caption-l">2,008</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="4" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1630549316063-7ae02749d2cc?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>brainiac</span>
<small class="wa-caption-l">1,954</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="5" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1582845512747-e42001c95638?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>eduexplorer</span>
<small class="wa-caption-l">1,897</small>
</div>
</li>
</ol>
</div>
</wa-card>
<wa-card>
<div slot="header" class="wa-flank wa-gap-xl">
<wa-icon name="hat-wizard" class="wa-heading-xl"></wa-icon>
<span class="wa-gap-2xs wa-stack">
<h4>Creation Leaders</h4>
<span class="wa-caption-m">Items created in the last 7 days</span>
</span>
</div>
<div class="wa-stack">
<ol class="wa-stack">
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="1" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1630549316063-7ae02749d2cc?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>brainiac</span>
<small class="wa-caption-l">134</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="2" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1546776230-bb86256870ce?q=80&w=3368&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>LessonLegend</span>
<small class="wa-caption-l">115</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="3" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1620428268482-cf1851a36764?q=80&w=3418&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>mitsuwo</span>
<small class="wa-caption-l">98</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="4" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1586374579358-9d19d632b6df?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>wiswiz</span>
<small class="wa-caption-l">79</small>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank">
<div class="wa-cluster">
<wa-icon name="5" fixed-width></wa-icon>
<wa-avatar image="https://images.unsplash.com/photo-1639628735078-ed2f038a193e?q=80&w=3348&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" shape="rounded"></wa-avatar>
</div>
<div class="wa-split wa-gap-xs">
<span>knowledgeninja</span>
<small class="wa-caption-l">77</small>
</div>
</li>
</ol>
</div>
</wa-card>
</div>
</div>
```

View File

@@ -0,0 +1,52 @@
---
title: Pagination
description: 'Improve navigation and performance by breaking long lists or content into manageable pages.'
isPro: true
---
## Simple
```html {.example}
<div class="wa-stack">
<div class="wa-placeholder"></div>
<wa-divider></wa-divider>
<div class="wa-split">
<span class="wa-caption-l">Showing 1 to 10 of 50 Results</span>
<div class="wa-cluster wa-gap-xs">
<wa-button appearance="outlined">
<wa-icon slot="prefix" name="chevron-left"></wa-icon>
Prev
</wa-button>
<wa-button appearance="outlined">
<wa-icon slot="suffix" name="chevron-right"></wa-icon>
Next
</wa-button>
</div>
</div>
</div>
```
## With Button Group
```html {.example}
<div class="wa-stack">
<div class="wa-placeholder"></div>
<wa-divider></wa-divider>
<div class="wa-split">
<span class="wa-caption-l">Showing 1 to 10 of 50 Results</span>
<wa-button-group orientation="horizontal">
<wa-button appearance="outlined">
<wa-icon name="chevron-left"></wa-icon>
</wa-button>
<wa-button appearance="accent" variant="brand">1</wa-button>
<wa-button appearance="outlined">2</wa-button>
<wa-button appearance="outlined">3</wa-button>
<wa-button appearance="outlined" disabled>...</wa-button>
<wa-button appearance="outlined">10</wa-button>
<wa-button appearance="outlined">
<wa-icon name="chevron-right"></wa-icon>
</wa-button>
</wa-button-group>
</div>
</div>
```

View File

@@ -0,0 +1,229 @@
---
title: Permissions
description: 'Permission patterns provide or restrict access to users.'
isPro: true
---
## With Form Inputs
```html{.example}
<wa-card with-header style="max-width: 72ch; margin: 0 auto;">
<div slot="header" class="wa-split">
<h2 class="wa-heading-m">Invite Team Members</h2>
<wa-icon name="close"></wa-icon>
</div>
<div class="wa-stack wa-gap-2xl">
<div class="wa-align-items-end wa-flank:end wa-gap-2xs">
<wa-input label="Email" placeholder="contact@example.com"></wa-input>
<wa-button variant="success">Send Invite</wa-button>
</div>
<div class="wa-stack">
<span class="wa-heading-s">Project Members</span>
<div class="wa-stack wa-gap-xl">
<div class="wa-flank">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1580489944761-15a19d654956?q=80&w=1961&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-xs">Jessica Jones</span>
<span class="wa-caption-m" style="word-break: break-word">jessica.jones@example.com</span>
</div>
<wa-select value="owner">
<wa-option value="owner">Owner</wa-option>
<wa-option value="admin">Admin</wa-option>
<wa-option value="can-edit">Can Edit</wa-option>
<wa-option value="view-only">View Only</wa-option>
</wa-select>
</div>
</div>
<div class="wa-flank">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1566492031773-4f4e44671857?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-xs">Foggy Nelson</span>
<span class="wa-caption-m" style="word-break: break-word">foggy.nelson@example.com</span>
</div>
<wa-select value="admin">
<wa-option value="owner">Owner</wa-option>
<wa-option value="admin">Admin</wa-option>
<wa-option value="can-edit">Can Edit</wa-option>
<wa-option value="view-only">View Only</wa-option>
</wa-select>
</div>
</div>
<div class="wa-flank">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1494790108377-be9c29b29330?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-xs">Karen Page</span>
<span class="wa-caption-m" style="word-break: break-word">karen.page@example.com</span>
</div>
<wa-select value="can-edit">
<wa-option value="owner">Owner</wa-option>
<wa-option value="admin">Admin</wa-option>
<wa-option value="can-edit">Can Edit</wa-option>
<wa-option value="view-only">View Only</wa-option>
</wa-select>
</div>
</div>
<div class="wa-flank">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1599566150163-29194dcaad36?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-0">
<span class="wa-heading-xs">Matt Murdock</span>
<span class="wa-caption-m" style="word-break: break-word">matt.murdock@example.com</span>
</div>
<wa-select value="view-only">
<wa-option value="owner">Owner</wa-option>
<wa-option value="admin">Admin</wa-option>
<wa-option value="can-edit">Can Edit</wa-option>
<wa-option value="view-only">View Only</wa-option>
</wa-select>
</div>
</div>
</div>
</div>
<div class="wa-align-items-end wa-flank:end wa-gap-2xs">
<wa-input label="Share Link" value="https://sharelink3435re.com" disabled></wa-input>
<wa-button variant="brand" appearance="filled outlined">
<wa-icon slot="prefix" name="link" variant="solid"></wa-icon>
Copy Link
</wa-button>
</div>
</div>
</wa-card>
```
## Link Settings
```html {.example}
<wa-card style="max-width: 45ch; margin: 0 auto;">
<div class="wa-stack">
<h2 class="wa-heading-m">Manage Link</h2>
<wa-input label="Expiration Date" type="date"></wa-input>
<wa-radio-group
label="Share Limit"
orientation="horizontal"
name="share-limit"
value="0"
>
<wa-radio-button value="0">None</wa-radio-button>
<wa-radio-button value="5">5</wa-radio-button>
<wa-radio-button value="10">10</wa-radio-button>
<wa-radio-button value="50">50</wa-radio-button>
<wa-radio-button value="100">100</wa-radio-button>
</wa-radio-group>
<wa-divider></wa-divider>
<wa-switch hint="Members are removed after logging out." checked>Temporary Access</wa-switch>
<div class="wa-cluster wa-gap-xs" style="justify-content: flex-end">
<wa-button size="small" appearance="outlined" pill>Cancel</wa-button>
<wa-button size="small" variant="brand" pill>Generate</wa-button>
</div>
</div>
</wa-card>
```
## Role Settings
```html {.example}
<div style="max-width: 78ch; margin: 0 auto;">
<h2>Settings</h2>
<p>Update settings for this server.</p>
<wa-tab-group>
<wa-tab panel="general">
<div class="wa-cluster">
<wa-icon name="user"></wa-icon>
<span>User Permissions</span>
</div>
</wa-tab>
<wa-tab-panel name="general">
<wa-card>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1741289308283-feba56f857cc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTl8fGJlYXJkfGVufDB8MnwwfHx8Mg%3D%3D" alt="image avatar"></wa-avatar>
<div class="wa-split">
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-s">Kris Kringle</span>
<span class="wa-caption-m">Admin</span>
</div>
<wa-button appearance="plain">
<wa-icon slot="prefix" name="edit"></wa-icon>
Edit Profile
</wa-button>
</div>
</div>
</wa-card>
<table>
<thead>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1579824894326-77ec5aaf8703?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NDJ8fHJlaW5kZWVyfGVufDB8MnwwfHx8Mg%3D%3D"></wa-avatar>
<span class="wa-caption-m">Dasher</span>
</div>
</td>
<td>
<wa-select value="moderator">
<wa-option value="moderator">Moderator</wa-option>
<wa-option value="contributor">Contributor</wa-option>
<wa-option value="reader">Reader</wa-option>
</wa-select>
</td>
</tr>
<tr>
<td>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1691065686144-916ff29d1b4f?q=80&w=2666&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<span class="wa-caption-m">Dancer</span>
</div>
</td>
<td>
<wa-select value="moderator">
<wa-option value="moderator">Moderator</wa-option>
<wa-option value="contributor">Contributor</wa-option>
<wa-option value="reader">Reader</wa-option>
</wa-select>
</td>
</tr>
<tr>
<td>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1616742618872-9e8a890d90b2?q=80&w=2712&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<span class="wa-caption-m">Prancer</span>
</div>
</td>
<td>
<wa-select value="contributor">
<wa-option value="moderator">Moderator</wa-option>
<wa-option value="contributor">Contributor</wa-option>
<wa-option value="reader">Reader</wa-option>
</wa-select>
</td>
</tr>
<tr>
<td>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1728290403857-1b7909db2baa?q=80&w=2680&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<span class="wa-caption-m">Vixen</span>
</div>
</td>
<td>
<wa-select value="reader">
<wa-option value="moderator">Moderator</wa-option>
<wa-option value="contributor">Contributor</wa-option>
<wa-option value="reader">Reader</wa-option>
</wa-select>
</td>
</tr>
</tbody>
</table>
</wa-tab-panel>
</wa-tab-group>
</div>
```

View File

@@ -0,0 +1,168 @@
---
title: Pricing
description: 'Help users make informed purchasing decisions with clear, structured pricing.'
isPro: true
---
## Three Tiers
```html{.example}
<div class="wa-grid">
<wa-card>
<div class="wa-stack">
<div class="wa-cluster wa-heading-l">
<wa-icon name="apple-core"></wa-icon>
<h3>Lite</h3>
</div>
<span class="wa-flank wa-align-items-baseline wa-gap-2xs">
<span class="wa-heading-2xl">$60</span>
<span class="wa-caption-l">per year</span>
</span>
<p class="wa-caption-l">An online-only plan for web-based projects.</p>
<wa-button variant="brand" appearance="outlined">Get Lite</wa-button>
</div>
<div slot="footer" class="wa-stack">
<h4 class="wa-heading-s">What You Get</h4>
<div class="wa-stack">
<div class="wa-flank">
<wa-icon name="user" fixed-width></wa-icon>
<span class="wa-caption-m">1 user</span>
</div>
<div class="wa-flank">
<wa-icon name="suitcase" fixed-width></wa-icon>
<span class="wa-caption-m">2 custom kits</span>
</div>
<div class="wa-flank">
<wa-icon name="chart-simple" fixed-width></wa-icon>
<span class="wa-caption-m">Up to 100k pageviews</span>
</div>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster wa-heading-l">
<wa-icon name="apple-whole"></wa-icon>
<h3>Pro</h3>
</div>
<wa-badge>Most Popular</wa-badge>
</div>
<span class="wa-flank wa-align-items-baseline wa-gap-2xs">
<span class="wa-heading-2xl">$120</span>
<span class="wa-caption-l">per year</span>
</span>
<p class="wa-caption-l">A great all-around plan for online or desktop use.</p>
<wa-button variant="brand">Get Pro</wa-button>
</div>
<div slot="footer" class="wa-stack">
<h4 class="wa-heading-s">What You Get</h4>
<div class="wa-stack">
<div class="wa-flank">
<wa-icon name="user" fixed-width></wa-icon>
<span class="wa-caption-m">5 users</span>
</div>
<div class="wa-flank">
<wa-icon name="suitcase" fixed-width></wa-icon>
<span class="wa-caption-m">20 custom kits</span>
</div>
<div class="wa-flank">
<wa-icon name="chart-simple" fixed-width></wa-icon>
<span class="wa-caption-m">Up to 1M pageviews</span>
</div>
<div class="wa-flank">
<wa-icon name="arrow-down-to-line" fixed-width></wa-icon>
<span class="wa-caption-m">Kit downloads</span>
</div>
<div class="wa-flank">
<wa-icon name="cloud-plus" fixed-width></wa-icon>
<span class="wa-caption-m">Cloud hosting</span>
</div>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<div class="wa-cluster wa-heading-l">
<wa-icon name="crate-apple"></wa-icon>
<h3>Max</h3>
</div>
<span class="wa-flank wa-align-items-baseline wa-gap-2xs">
<span class="wa-heading-2xl">$600</span>
<span class="wa-caption-l">per year</span>
</span>
<p class="wa-caption-l">Our biggest plan with more of everything.</p>
<wa-button variant="brand" appearance="outlined">Get Max</wa-button>
</div>
<div slot="footer" class="wa-stack">
<h4 class="wa-heading-s">What You Get</h4>
<div class="wa-stack">
<div class="wa-flank">
<wa-icon name="user" fixed-width></wa-icon>
<span class="wa-caption-m">50 users</span>
</div>
<div class="wa-flank">
<wa-icon name="suitcase" fixed-width></wa-icon>
<span class="wa-caption-m">Unlimited custom kits</span>
</div>
<div class="wa-flank">
<wa-icon name="chart-simple" fixed-width></wa-icon>
<span class="wa-caption-m">Up to 10M pageviews</span>
</div>
<div class="wa-flank">
<wa-icon name="arrow-down-to-line" fixed-width></wa-icon>
<span class="wa-caption-m">Kit downloads</span>
</div>
<div class="wa-flank">
<wa-icon name="cloud-plus" fixed-width></wa-icon>
<span class="wa-caption-m">Cloud hosting</span>
</div>
</div>
</div>
</wa-card>
</div>
```
## Single Tier
```html {.example}
<wa-card>
<div class="wa-grid">
<div class="wa-stack">
<h3 class="wa-heading-l">Lifetime Membership</h3>
<p>Learn at your own pace with expert-led content, exclusive resources, and a community of like-minded learners.</p>
<wa-divider></wa-divider>
<h4 class="wa-heading-s">Membership Includes:</h4>
<div class="wa-grid">
<div class="wa-flank wa-gap-xs">
<wa-icon name="check"></wa-icon>
<span class="wa-caption-m">Private forum access</span>
</div>
<div class="wa-flank wa-gap-xs">
<wa-icon name="check"></wa-icon>
<span class="wa-caption-m">Priority admission to events</span>
</div>
<div class="wa-flank wa-gap-xs">
<wa-icon name="check"></wa-icon>
<span class="wa-caption-m">Yearly skill assessment</span>
</div>
<div class="wa-flank wa-gap-xs">
<wa-icon name="check"></wa-icon>
<span class="wa-caption-m">Members-only swag</span>
</div>
</div>
</div>
<wa-callout variant="neutral" appearance="filled">
<div class="wa-stack wa-align-items-center" style="justify-content: center">
<h4 class="wa-heading-s">Pay Once, Own it Forever</h4>
<div class="wa-cluster wa-align-items-baseline wa-gap-2xs">
<span class="wa-heading-3xl">$459</span>
<span>USD</span>
</div>
<wa-button variant="brand" style="width: 100%">Get Access</wa-button>
<small class="wa-caption-m">30-day money back guarantee</small>
</div>
</wa-callout>
</div>
</wa-card>
```

View File

@@ -1,6 +1,8 @@
---
title: Blog
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
@@ -366,4 +368,4 @@ TODO Page Description
}
</style>
```
```

View File

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

View File

@@ -1,13 +0,0 @@
---
title: Category Filter
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## With inline actions and expandable sidebar filters
```html{.example}
```

View File

@@ -1,12 +0,0 @@
---
title: Category Preview
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## Three Column (WIP)
```

View File

@@ -1,14 +0,0 @@
---
title: Order History
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## Invoice panels
```html{.example}
```

View File

@@ -1,13 +0,0 @@
---
title: Product List
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## With split image
```html{.example}
```

View File

@@ -1,129 +0,0 @@
---
title: Product Detail
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## With color and size selector
```html{.example}
<div class="with-inline-price">
<wa-card with-header>
<div class="card-header" slot="header">
<span class="card-title">Graphic Tank</span>
<wa-icon-button name="close" label="close-modal"></wa-icon-button>
</div>
<div class="card-body">
<img style="border-radius: var(--border-radius)" src="/assets/images/patterns/gervyn-louis-IS03ajI00Fc-unsplash.jpg" />
<form class="detail">
<span class="price">$32</span>
<span class="rating"><wa-rating></wa-rating><a style="margin-left: .5rem; " href="*">36 Reviews</a></span>
<wa-radio-group style="margin-bottom: 1rem;" label="Select an option" name="a" value="1">
<wa-radio-button value="Black">Black</wa-radio-button>
<wa-radio-button value="White">White</wa-radio-button>
<wa-radio-button value="Gray">Gray</wa-radio-button>
</wa-radio-group>
<wa-select label="Sizes" placeholder="select size">
<wa-option value="option-1">Option 1</wa-option>
<wa-option value="option-2">Option 2</wa-option>
<wa-option value="option-3">Option 3</wa-option>
</wa-select>
<wa-button size="medium" style="width: 100%; margin-top: auto;">Medium</wa-button>
</form>
</div>
</wa-card>
</div>
<style>
.with-inline-price {
wa-card {
width: 100%;
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
.card-title {
font-size: large;
font-weight: 600;
}
}
.card-body {
display: grid;
grid-template-columns: 35% 1fr;
gap: 1rem;
.detail {
display: flex;
flex-direction: column;
.price {
font-size: xx-large;
font-weight: 600;
}
.rating {
margin-bottom: 1rem;
}
}
}
}
}
</style>
```
## with large selector
```html{.example}
<wa-card class="large-selector">
<div class="card-body">
<div style="grid-column: 1/6">
<img style="border-radius: var(--border-radius); height: 100%; object-fit: cover;" src="/assets/images/patterns/gervyn-louis-IS03ajI00Fc-unsplash.jpg" />
</div>
<div style="grid-column: 6/-1" class="info">
<h2>Basic Tank</h2>
<wa-icon-button name="close" label="close-modal"></wa-icon-button>
<section>
<p style="font-size: x-large;font-weight: 600;">$32</p>
<div style="display: flex; align-items: flex-start">
<p>3.9</p>
<wa-rating></wa-rating>
<a href="*" style="margin-left: auto;">See all 512 Reviews</a>
</div>
</section>
<section>
<form>
<wa-radio-group label="Color" hint="Choose the most appropriate option." name="a" value="black" style="margin-bottom: 1rem;">
<wa-radio value="black">Black</wa-radio>
<wa-radio value="gray">Gray</wa-radio>
</wa-radio-group>
<wa-radio-group label="Size" hint="Select an option that makes you proud." name="a" value="medium" style="margin-bottom: 1rem;">
<wa-radio-button value="small">S</wa-radio-button>
<wa-radio-button value="medium">M</wa-radio-button>
<wa-radio-button value="large">L</wa-radio-button>
<wa-radio-button value="extra-large">XL</wa-radio-button>
</wa-radio-group>
<wa-button size="medium" style="width: 100%; margin-top: auto;margin-bottom: 1rem;">Medium</wa-button>
<a href="*" style="display: inline-block;width: 100%;text-align: center;">View full details</a>
</form>
</section>
</div>
</div>
</wa-card>
<style>
.large-selector .card-body {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
.info {
position: relative;
wa-icon-button {
position: absolute;
top: 0;
right: 0;
}
}
}
</style>
```

View File

@@ -1,166 +0,0 @@
---
title: Product Lists
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## With Product Grid
```html{.example}
<div class="with-product-grid">
<div class="grid-item">
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div class="grid-item-name">Shirt</div>
<wa-rating label="Rating" readonly value="3"></wa-rating>
<a class="grid-item-reviews" href="#">38 Reviews</a>
<div class="grid-item-price">$170</div>
</div>
<div class="grid-item">
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div class="grid-item-name">Shirt</div>
<wa-rating label="Rating" readonly value="3"></wa-rating>
<a class="grid-item-reviews" href="#">38 Reviews</a>
<div class="grid-item-price">$170</div>
</div>
<div class="grid-item">
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div class="grid-item-name">Shirt</div>
<wa-rating label="Rating" readonly value="3"></wa-rating>
<a class="grid-item-reviews" href="#">38 Reviews</a>
<div class="grid-item-price">$170</div>
</div>
<div class="grid-item">
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div class="grid-item-name">Shirt</div>
<wa-rating label="Rating" readonly value="3"></wa-rating>
<a class="grid-item-reviews" href="#">38 Reviews</a>
<div class="grid-item-price">$170</div>
</div>
</div>
<style>
.with-product-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
border: var(--wa-panel-border-width) var(--wa-border-style) var(--wa-color-neutral-border-quiet);
.grid-item {
padding: 1.5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.grid-item:nth-of-type(odd) {
border-right: var(--wa-panel-border-width) var(--wa-border-style) var(--wa-color-neutral-border-quiet);
}
.grid-item:not(:nth-last-child(-n + 2)) {
border-bottom: var(--wa-panel-border-width) var(--wa-border-style) var(--wa-color-neutral-border-quiet);
}
.grid-item-image {
width: 100%;
object-fit: cover;
}
.grid-item-name {
margin-top: 1rem;
font-weight: var(--wa-font-weight-bold);
}
.grid-item wa-rating {
--symbol-size: var(--wa-font-size-m);
margin-top: .5rem;
}
.grid-item-reviews {
--wa-link-decoration-default: none;
--wa-color-text-link: var(--wa-color-gray-50);
font-size: var(--wa-font-size-m);
}
.grid-item-price {
font-size: var(--wa-font-size-2xl);
font-weight: var(--wa-font-weight-bold);
}
}
</style>
```
## Card with full details
```html{.example}
<div class="card-with-details">
<wa-card with-footer>
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div slot="footer" class="card-footer details">
<span class="detail-name">Basic Tee 8-pack</span>
<p class="detail-description">Get the full lineup of our Basic Tees. Have a fresh shirt all week, and an extra for laundry day.</p>
<span class="detail-color">8 colors</span>
<span class="detail-price">$256</span>
</div>
</wa-card>
<wa-card with-footer>
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div slot="footer" class="card-footer details">
<span class="detail-name">Basic Tee 8-pack</span>
<p class="detail-description">Get the full lineup of our Basic Tees. Have a fresh shirt all week, and an extra for laundry day.</p>
<span class="detail-color">8 colors</span>
<span class="detail-price">$256</span>
</div>
</wa-card>
<wa-card with-footer>
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div slot="footer" class="card-footer details">
<span class="detail-name">Basic Tee 8-pack</span>
<p class="detail-description">Get the full lineup of our Basic Tees. Have a fresh shirt all week, and an extra for laundry day.</p>
<span class="detail-color">8 colors</span>
<span class="detail-price">$256</span>
</div>
</wa-card>
<wa-card with-footer>
<img class="grid-item-image" src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
<div slot="footer" class="card-footer details">
<span class="detail-name">Basic Tee 8-pack</span>
<p class="detail-description">Get the full lineup of our Basic Tees. Have a fresh shirt all week, and an extra for laundry day.</p>
<span class="detail-color">8 colors</span>
<span class="detail-price">$256</span>
</div>
</wa-card>
</div>
<style>
.card-with-details {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
.card-with-details wa-card::part(body) {
padding: 0;
}
.card-with-details .card-footer {
display: flex;
flex-direction: column;
}
.details {
.detail-description {
color: var(--wa-color-gray-50);
}
.detail-name {
font-size: var(--wa-font-size-l);
font-weight: var(--wa-font-weight-action);
}
.detail-color {
color: var(--wa-color-gray-50);
font-style: italic;
}
.detail-price {
font-size: var(--wa-font-size-xl);
font-weight: var(--wa-font-weight-action);
}
}
</style>
```
## With color swatches (WIP)
```html{.example}
```

View File

@@ -1,465 +0,0 @@
---
title: Product Reviews
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## With images grid
```html{.example}
<div class="with-image-grid">
<wa-breadcrumb>
<wa-breadcrumb-item>Clothing</wa-breadcrumb-item>
<wa-breadcrumb-item>Men's</wa-breadcrumb-item>
<wa-breadcrumb-item>Shirts &amp; Tops</wa-breadcrumb-item>
</wa-breadcrumb>
<div class="image-grid">
<img src="/assets/images/patterns/gervyn-louis-IS03ajI00Fc-unsplash.jpg" />
<img src="/assets/images/patterns/gervyn-louis-KXvd7y7AU6Q-unsplash.jpg" />
<img src="/assets/images/patterns/gervyn-louis-semwwyXFQho-unsplash.jpg" />
<img src="/assets/images/patterns/mad-rabbit-tattoo-7N4FMowSGek-unsplash.jpg" />
</div>
<div>
<h2>Tank top</h2>
<p>The Basic Tee 6-Pack allows you to fully express your vibrant personality with three grayscale options. Feeling adventurous? Put on a heather gray tee. Want to be a trendsetter? Try our exclusive colorway: "Black". Need to add an extra pop of color to your outfit? Our white tee has you covered.</p>
<h3>Highlights</h3>
<ul>
<li>Hand cut and sewn locally</li>
</ul>
<h3>Highlights</h3>
<p>The 6-Pack includes two black, two white, and two heather gray Basic Tees. Sign up for our subscription service and be the first to get new, exciting colors, like our upcoming "Charcoal Gray" limited release.</p>
<span>$192</span>
<div>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
<a href="#">117 Reviews</a>
</div>
<wa-radio-group label="Select an option" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1">Option 1</wa-radio-button>
<wa-radio-button value="2">Option 2</wa-radio-button>
<wa-radio-button value="3">Option 3</wa-radio-button>
</wa-radio-group>
<wa-radio-group label="Select an option" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1">Option 1</wa-radio-button>
<wa-radio-button value="2">Option 2</wa-radio-button>
<wa-radio-button value="3">Option 3</wa-radio-button>
</wa-radio-group>
<wa-button>Add to Cart</wa-button>
</div>
</div>
<style>
.with-image-grid {
wa-breadcrumb::part(base) {
margin-bottom: 1rem;
}
.image-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
}
.image-grid img:nth-of-type(1) {
grid-column: 1/-1;
}
.image-grid img:nth-of-type(2) {
grid-column: 1/7;
}
.image-grid img:nth-of-type(3) {
grid-column: 7/-1;
}
.image-grid img:nth-of-type(4) {
grid-column: 1/-1;
}
}
</style>
```
## With Tiered Images
```html{.example}
<div class="with-tiered-images">
<wa-breadcrumb>
<wa-breadcrumb-item>Clothing</wa-breadcrumb-item>
<wa-breadcrumb-item>Men's</wa-breadcrumb-item>
<wa-breadcrumb-item>Shirts &amp; Tops</wa-breadcrumb-item>
</wa-breadcrumb>
<div>
<div class="heading">
<h2>Basic Tee</h2>
<span style="font-size: var(--wa-font-size-2xl)">$35</span>
</div>
<div class="rating">
<span>3.9</span>
<wa-rating label="Rating" precision="0.5" value="3.9"></wa-rating>
<a href="#">117 Reviews</a>
</div>
<div class="tiered-images">
<img src="/assets/images/patterns/gervyn-louis-IS03ajI00Fc-unsplash.jpg" />
<img src="/assets/images/patterns/gervyn-louis-KXvd7y7AU6Q-unsplash.jpg" />
<img src="/assets/images/patterns/gervyn-louis-semwwyXFQho-unsplash.jpg" />
</div>
</div>
<wa-radio-group label="Select an option" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1">Option 1</wa-radio-button>
<wa-radio-button value="2">Option 2</wa-radio-button>
<wa-radio-button value="3">Option 3</wa-radio-button>
</wa-radio-group>
<wa-radio-group label="Select an option" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1">Option 1</wa-radio-button>
<wa-radio-button value="2">Option 2</wa-radio-button>
<wa-radio-button value="3">Option 3</wa-radio-button>
</wa-radio-group>
<wa-button>Add to Cart</wa-button>
<h3>Description</h3>
<p>The Basic tee is an honest new take on a classic. The tee uses super soft, pre-shrunk cotton for true comfort and a dependable fit. They are hand cut and sewn locally, with a special dye technique that gives each tee it's own look.</p>
<p>Looking to stock your closet? The Basic tee also comes in a 3-pack or 5-pack at a bundle discount.</p>
<hr />
<h3>Highlights</h3>
<ul>
<li>Hand cut and sewn locally</li>
</ul>
<div>
<wa-card>
<wa-icon family="solid" name="earth-americas"></wa-icon>
<h3>International delivery</h3>
<p>Get your order in 2 years</p>
</wa-card>
<wa-card>
<wa-icon family="solid" name="earth-americas"></wa-icon>
<h3>International delivery</h3>
<p>Get your order in 2 years</p>
</wa-card>
</div>
</div>
<style>
.with-tiered-images {
wa-breadcrumb::part(base) {
margin-bottom: 1rem;
}
.heading {
display: flex;
justify-content: space-between;
align-items: center;
}
.rating {
display: flex;
span {
display: inline-block;
margin-right: 1rem;
}
wa-rating {
margin-right: 1rem;
}
}
.tiered-images {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
}
.tiered-images img:nth-of-type(1) {
grid-column: 1/-1;
}
.tiered-images img:nth-of-type(2) {
grid-column: 1/7;
}
.tiered-images img:nth-of-type(3) {
grid-column: 7/-1;
}
</style>
```
## with images and expandable details
```html {.example}
<wa-carousel class="carousel-thumbnails" navigation loop>
<wa-carousel-item>
<img
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
src="/assets/examples/carousel/pullover-1.jpg"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
src="/assets/examples/carousel/pullover-2.jpg"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
src="/assets/examples/carousel/pullover-3.jpg"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
src="/assets/examples/carousel/pullover-4.jpg"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
src="/assets/examples/carousel/pullover-5.jpg"
/>
</wa-carousel-item>
</wa-carousel>
<div class="thumbnails">
<div class="thumbnails__scroller">
<img alt="Thumbnail by 1" class="thumbnails__image active" src="/assets/examples/carousel/pullover-1.jpg" />
<img alt="Thumbnail by 2" class="thumbnails__image" src="/assets/examples/carousel/pullover-2.jpg" />
<img alt="Thumbnail by 3" class="thumbnails__image" src="/assets/examples/carousel/pullover-3.jpg" />
<img alt="Thumbnail by 4" class="thumbnails__image" src="/assets/examples/carousel/pullover-4.jpg" />
<img alt="Thumbnail by 5" class="thumbnails__image" src="/assets/examples/carousel/pullover-5.jpg" />
</div>
</div>
<div>
<h3 style="--wa-space-xl: 0;">Pullover Sweater</h3>
<span class="price-big">$140</span>
<wa-rating class="sweater-rating" label="Rating" precision="0.5" value="2.5"></wa-rating>
<p>The Zip Tote Basket is the perfect midpoint between shopping tote and comfy backpack. With convertible straps, you can hand carry, should sling, or backpack this convenient and spacious bag. The zip top and durable canvas construction keeps your goods protected for all-day use.</p>
<wa-radio-group label="Select Color" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1"></wa-radio-button>
<wa-radio-button value="2"></wa-radio-button>
<wa-radio-button value="3"></wa-radio-button>
</wa-radio-group>
<div>
<wa-button>Add to cart</wa-button>
<wa-icon-button name="gear" label="Settings"></wa-icon-button>
</div>
<div class="details-group-example">
<wa-details summary="First" open>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</wa-details>
<wa-details summary="Second">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</wa-details>
<wa-details summary="Third">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</wa-details>
</div>
</div>
<style>
.carousel-thumbnails {
--slide-aspect-ratio: 3 / 2;
}
wa-radio-button #shadow-root div .button--medium {
padding: var(--wa-space-xs) var(--wa-space-xs);
}
.color-circle {
--background: #000;
background: var(--background);
width: 50px;
height: 100%;
}
.sweater-rating {
margin-bottom: 1rem;
}
.price-big {
display: block;
font-size: 32px;
}
.thumbnails {
display: flex;
justify-content: center;
margin-bottom: 1rem;
}
.thumbnails__scroller {
display: flex;
gap: var(--wa-space-s);
overflow-x: auto;
scrollbar-width: none;
scroll-behavior: smooth;
scroll-padding: var(--wa-space-s);
}
.thumbnails__scroller::-webkit-scrollbar {
display: none;
}
.thumbnails__image {
width: 64px;
height: 64px;
object-fit: cover;
opacity: 0.3;
will-change: opacity;
transition: 250ms opacity;
cursor: pointer;
}
.thumbnails__image.active {
opacity: 1;
}
.details-group-example wa-details:not(:last-of-type) {
margin-bottom: var(--wa-space-2xs);
}
</style>
<script>
{
const carousel = document.querySelector('.carousel-thumbnails');
const scroller = document.querySelector('.thumbnails__scroller');
const thumbnails = document.querySelectorAll('.thumbnails__image');
scroller.addEventListener('click', e => {
const target = e.target;
if (target.matches('.thumbnails__image')) {
const index = [...thumbnails].indexOf(target);
carousel.goToSlide(index);
}
});
carousel.addEventListener('wa-slide-change', e => {
const slideIndex = e.detail.index;
[...thumbnails].forEach((thumb, i) => {
thumb.classList.toggle('active', i === slideIndex);
if (i === slideIndex) {
thumb.scrollIntoView({
block: 'nearest'
});
}
});
});
}
const container = document.querySelector('.details-group-example');
// Close all other details when one is shown
container.addEventListener('wa-show', event => {
if (event.target.localName === 'wa-details') {
[...container.querySelectorAll('wa-details')].map(details => (details.open = event.target === details));
}
});
</script>
```
## Split with image
```html {.example}
<div class="split-with-image">
<div class="div-1">
<wa-breadcrumb>
<wa-breadcrumb-item>Clothing</wa-breadcrumb-item>
<wa-breadcrumb-item>Men's</wa-breadcrumb-item>
<wa-breadcrumb-item>Shirts &amp; Tops</wa-breadcrumb-item>
</wa-breadcrumb>
<h2>Everyday Ruck Snack</h2>
<span>
<span>$220</span> |
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
<span>1624 reviews</span>
</span>
<p>Don't compromise on snack-carrying capacity with this lightweight and spacious bag. The drawstring top keeps all your favorite chips, crisps, fries, biscuits, crackers, and cookies secure.</p>
<span><wa-icon family="solid" name="check"></wa-icon> In stock and ready to ship</span>
</div>
<div class="div-2">
<img src="/assets/images/patterns/gervyn-louis-IS03ajI00Fc-unsplash.jpg" />
</div>
<div class="div-3">
<wa-radio-group label="Select an option" hint="Select an option that makes you proud." name="a" value="1">
<wa-radio-button value="1">Option 1</wa-radio-button>
<wa-radio-button value="2">Option 2</wa-radio-button>
<wa-radio-button value="3">Option 3</wa-radio-button>
</wa-radio-group>
</div>
</div>
<style>
.split-with-image {
display: grid;
/* grid-template-columns: repeat(2, 1fr); */
/* height: 1000px; */
/* gap: 1rem; */
.div-1 {
}
.div-2 {
/* background-color: black;
grid-column-start: 2;
grid-row: span 2 / span 2; */
}
.div-3 {
}
}
</style>
```
## With tabs
```html{.example}
<div>
<wa-rating class="sweater-rating" label="Rating" precision="0.5" value="2.5"></wa-rating>
<h2>Application UI Icon Pack</h2>
<img alt="Sample of 30 icons with friendly and fun details in outline, filled, and brand color styles." src="https://tailwindui.com/img/ecommerce-images/product-page-05-product-01.jpg" class="aqk aql">
<p>The Application UI Icon Pack comes with over 200 icons in 3 styles: outline, filled, and branded. This playful icon pack is tailored for complex application user interfaces with a friendly and legible look.</p>
<wa-button variant="brand">Brand</wa-button>
<wa-button variant="success">Success</wa-button>
<hr />
<h3>Highlights</h3>
<ul>
<li>200+ SVG icons in 3 unique styles</li>
<li>Compatible with Figma, Sketch, and Adobe XD</li>
<li>Drawn on 24 x 24 pixel grid</li>
</ul>
<hr />
<h3>License</h3>
<p>For personal and professional use. You cannot resell or redistribute these icons in their original or modified state. <a href="#">Read full license</a></p>
<hr />
<h3>Share</h3>
<wa-icon family="brands" name="facebook"></wa-icon>
<wa-icon family="brands" name="instagram"></wa-icon>
<wa-icon family="brands" name="x-twitter"></wa-icon>
<wa-tab-group>
<wa-tab panel="general">General</wa-tab>
<wa-tab panel="custom">Custom</wa-tab>
<wa-tab panel="advanced">Advanced</wa-tab>
<wa-tab panel="disabled" disabled>Disabled</wa-tab>
<wa-tab-panel name="general">
<div></div>
<div>
<h3>Hector Gibbons</h3>
<p>July 12, 2021</p>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
<p>Blown away by how polished this icon pack is. Everything looks so consistent and each SVG is optimized out of the box so I can use it directly with confidence. It would take me several hours to create a single icon this good, so it's a steal at this price.</p>
</div>
</wa-tab-panel>
<wa-tab-panel name="custom">This is the custom tab panel.</wa-tab-panel>
<wa-tab-panel name="advanced">This is the advanced tab panel.</wa-tab-panel>
<wa-tab-panel name="disabled">This is a disabled tab panel.</wa-tab-panel>
</wa-tab-group>
</div>
```

View File

@@ -1,10 +0,0 @@
---
title: Shopping Cart
description: TODO
parent: ecommerce
tags: e-commerce
---
TODO Page Description
## Examples

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
---
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
```html{.example}
<h1>New Arrivals</h1>
<div class="wa-flank wa-align-items-start" style="--flank-size: 200px;">
<form class="wa-stack">
<wa-checkbox checked>All Products</wa-checkbox>
<wa-checkbox>Sale</wa-checkbox>
<wa-checkbox>Travel</wa-checkbox>
<wa-checkbox>Organization</wa-checkbox>
<wa-checkbox>Accessories</wa-checkbox>
<wa-details summary="Color" open>
<div class="wa-stack">
<wa-checkbox>White</wa-checkbox>
<wa-checkbox>Beige</wa-checkbox>
<wa-checkbox>Blue</wa-checkbox>
<wa-checkbox>Brown</wa-checkbox>
<wa-checkbox>Green</wa-checkbox>
</div>
</wa-details>
<wa-details summary="Category">
<div class="wa-stack">
<wa-checkbox>Outdoor</wa-checkbox>
<wa-checkbox>Indoor</wa-checkbox>
<wa-checkbox>All Weather</wa-checkbox>
</div>
</wa-details>
<wa-details summary="Size">
<div class="wa-stack">
<wa-checkbox>Small</wa-checkbox>
<wa-checkbox>Medium</wa-checkbox>
<wa-checkbox>Large</wa-checkbox>
<wa-checkbox>XL</wa-checkbox>
<wa-checkbox>XXL</wa-checkbox>
</div>
</wa-details>
</form>
<div class="wa-placeholder"></div>
</div>
</div>
```
## Sidebar with Dropdowns
```html{.example}
<h1>New Arrivals</h1>
<div class="wa-flank wa-align-items-start">
<div class="wa-stack">
<wa-select label="Product Type" placeholder="Products" value="all-products">
<wa-option value="all-products">All Products</wa-option>
<wa-option value="sale">Sale</wa-option>
<wa-option value="travel">Travel</wa-option>
<wa-option value="organization">Organization</wa-option>
<wa-option value="accessories">Accessories</wa-option>
</wa-select>
<wa-divider></wa-divider>
<wa-select label="Color" placeholder="Color" value="black" multiple>
<wa-option value="black">Black</wa-option>
<wa-option value="white">White</wa-option>
<wa-option value="gray">Gray</wa-option>
</wa-select>
<wa-select label="Category" placeholder="Category" value="outdoor" multiple>
<wa-option value="outdoor">Outdoor</wa-option>
<wa-option value="indoor">Indoor</wa-option>
<wa-option value="all-weather">All Weather</wa-option>
</wa-select>
<wa-select label="Size" placeholder="Size" value="xl xxl" multiple>
<wa-option value="s">Small</wa-option>
<wa-option value="m">Medium</wa-option>
<wa-option value="l">Large</wa-option>
<wa-option value="xl">XL</wa-option>
<wa-option value="xxl">XXL</wa-option>
</wa-select>
</div>
<div class="wa-placeholder"></div>
</div>
```

View File

@@ -0,0 +1,163 @@
---
title: Category Preview
description: 'Help shoppers discover your product offerings with showcases of product categories.'
icon: preview
isPro: true
---
## Split with Image Grid
```html {.example}
<div class="wa-flank wa-align-items-start" style="--flank-size: 20rem;">
<div class="wa-stack wa-gap-2xl">
<h2 class="wa-heading-xl">Casual Collection</h2>
<p class="wa-body-s">Look good &mdash; without looking like you're trying too hard. Our casual collection includes laid back styles that work in <em>almost</em> any situation.</p>
<wa-button>View the Collection</wa-button>
</div>
<div class="wa-stack">
<div class="wa-frame:landscape wa-border-radius-s">
<img
src="https://images.unsplash.com/photo-1544441893-675973e31985?q=80&w=2340&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="An analog watch, cotton pants, crew neck tee, and pair of tennis shoes (Photograph by Mnz)"
/>
</div>
<div class="wa-grid">
<div class="wa-frame:landscape wa-border-radius-s">
<img
src="https://images.unsplash.com/photo-1548768041-2fceab4c0b85?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Stack of three folded solid color tees (Photograph by Mnz)"
/>
</div>
<div class="wa-frame:landscape wa-border-radius-s">
<img
src="https://images.unsplash.com/photo-1544441892-794166f1e3be?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Pair of bright white tennis shoes(Photograph by Mnz)"
/>
</div>
</div>
</div>
</div>
```
## Columns with Tall Images
```html {.example}
<div class="wa-stack">
<h2 class="wa-heading-xl">Shop by Category</h2>
<div class="wa-grid">
<a href="" class="wa-stack wa-link-plain">
<div class="wa-frame:portrait wa-border-radius-s">
<img
src="https://uploads.webawesome.com/organization.jpg"
alt="Inside of a closet filled with clothes on wooden hangers and integrated shelving with shoes"
/>
</div>
<span class="wa-caption-xl">Organization</span>
</a>
<a href="" class="wa-stack wa-link-plain">
<div class="wa-frame:portrait wa-border-radius-s">
<img
src="https://uploads.webawesome.com/bags.jpg"
alt="Young person hugging a small floral patterned book bag between their arms"
/>
</div>
<span class="wa-caption-xl">Bags</span>
</a>
<a href="" class="wa-stack wa-link-plain">
<div class="wa-frame:portrait wa-border-radius-s">
<img
src="https://uploads.webawesome.com/outdoor-2.jpg"
alt="Person in a mountain clearing wearing a waterproof hooded windbreaker in black and orange"
/>
</div>
<span class="wa-caption-xl">Outdoor</span>
</a>
</div>
</div>
```
## Columns with Cards
```html {.example}
<div class="wa-stack">
<div class="wa-split">
<h2 class="wa-heading-xl">Shop by Category</h2>
<a href="" class="wa-cluster">
<span>Browse All Categories</span>
<wa-icon name="arrow-right"></wa-icon>
</a>
</div>
<div class="wa-grid">
<a href="" class="wa-link-plain">
<wa-card style="height: 100%">
<img
slot="image"
src="https://img.fortawesome.com/cfa83f3c/outdoor-3x.jpg"
alt="Two hikers wearing long canvas pants, weatherproof jackets, and backpacks"
/>
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-m">Outdoor</span>
<p class="wa-caption-m">Durable canvas gear for all conditions.</p>
</div>
</wa-card>
</a>
<a href="" class="wa-link-plain">
<wa-card style="height: 100%">
<img
slot="image"
src="https://img.fortawesome.com/cfa83f3c/home.jpg"
alt="Woman sitting on a couch in a bright home, wearing a thick knit sweater"
/>
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-m">Home</span>
<p class="wa-caption-m">Cozy up on the couch and relax in soft cotton.</p>
</div>
</wa-card>
</a>
<a href="" class="wa-link-plain">
<wa-card style="height: 100%">
<img
slot="image"
src="https://img.fortawesome.com/cfa83f3c/fitness.jpg"
alt="Athlete training in fitted active wear tee and shorts"
/>
<div class="wa-stack wa-gap-xs">
<span class="wa-heading-m">Active</span>
<p class="wa-caption-m">Get fit in style with breathable poly blends.</p>
</div>
</wa-card>
</a>
</div>
</div>
```
## Square Image Grid
```html {.example}
<div class="wa-stack wa-gap-2xl">
<div class="wa-stack wa-gap-xs wa-align-items-center">
<h2 class="wa-heading-xl">New Arrivals</h2>
<p class="wa-caption-l">Explore brand new furniture to accentuate your home aesthetic &mdash; just for you.</p>
</div>
<div class="wa-grid">
<div class="wa-stack">
<div class="wa-frame wa-border-radius-m">
<img
src="https://uploads.webawesome.com/indoor-furniture.jpg"
alt="Sunny room with a mid-century modern couch, accent chair, and elegant lamp"
/>
</div>
<wa-button appearance="outlined">View Indoor Furniture</wa-button>
</div>
<div class="wa-stack">
<div class="wa-frame wa-border-radius-m">
<img
src="https://uploads.webawesome.com/outdoor-furniture.jpg"
alt="Covered patio with rustic wooden cabinets, writing desk, and stool"
/>
</div>
<wa-button appearance="outlined">View Outdoor Furniture</wa-button>
</div>
</div>
</div>
```

View File

@@ -0,0 +1,245 @@
---
title: Checkout Form
description: 'Let shoppers checkout with ease with streamlined forms to capture shipping and payment info.'
isPro: true
---
## Full Form with Order Summary Card
```html {.example}
<div class="wa-grid wa-gap-3xl">
<div class="wa-stack">
<h4>Contact</h4>
<wa-input type="email" label="Email Address"></wa-input>
<wa-divider></wa-divider>
<h4>Shipping</h4>
<wa-select label="Country" value="us">
<wa-option value="ca">Canada</wa-option>
<wa-option value="mx">Mexico</wa-option>
<wa-option value="us">United States</wa-option>
</wa-select>
<div class="wa-grid">
<wa-input label="First Name"></wa-input>
<wa-input label="Last Name"></wa-input>
</div>
<wa-input label="Company"></wa-input>
<wa-input label="Address"></wa-input>
<div class="wa-grid" style="--min-column-size: 10ch;">
<wa-input label="City"></wa-input>
<wa-input label="State"></wa-input>
<wa-input label="Postal Code"></wa-input>
</div>
<wa-input label="Phone"></wa-input>
<wa-divider></wa-divider>
<wa-radio-group label="Shipping Method" name="shipping-method" value="standard" orientation="horizontal">
<wa-radio value="standard" hint="7-10 business days">Standard</wa-radio>
<wa-radio value="express" hint="2-5 business days">Express</wa-radio>
</wa-radio-group>
<wa-divider></wa-divider>
<h4>Payment</h4>
<wa-radio-group label="Payment Method" name="payment-method" value="credit" orientation="horizontal">
<wa-radio value="credit">Credit Card</wa-radio>
<wa-radio value="paypal">Paypal</wa-radio>
</wa-radio-group>
<wa-input label="Card Number"></wa-input>
<wa-input label="Name on Card"></wa-input>
<div class="wa-grid">
<wa-input label="Expiration Date" placeholder="MM/YY"></wa-input>
<wa-input label="CVC"></wa-input>
</div>
</div>
<div class="wa-stack">
<h4>Order Summary</h4>
<wa-card>
<div class="wa-stack">
<div class="wa-flank wa-align-items-start" style="--flank-size: 7rem">
<div class="wa-frame wa-border-radius-s">
<img src="https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDM1MzB8&ixlib=rb-4.0.3&q=80&w=1080" alt="">
</div>
<div class="wa-stack wa-gap-xs">
<div class="wa-split">
<span class="wa-heading-s">Dolce Runners</span>
<wa-icon-button name="trash" label="Remove from cart"></wa-icon-button>
</div>
<span class="wa-caption-m">Cream/Seafoam</span>
<span class="wa-caption-m">12.5</span>
<div class="wa-split">
<span>$135.00</span>
<wa-select value="1" size="small" style="max-width: 8ch">
<wa-option value="1">1</wa-option>
<wa-option value="2">2</wa-option>
<wa-option value="3">3</wa-option>
</wa-select>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-align-items-start" style="--flank-size: 7rem">
<div class="wa-frame wa-border-radius-s">
<img src="https://images.unsplash.com/photo-1514989940723-e8e51635b782?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDM1Njh8&ixlib=rb-4.0.3&q=80&w=1080" alt="">
</div>
<div class="wa-stack wa-gap-xs">
<div class="wa-split">
<span class="wa-heading-s">Dunk High</span>
<wa-icon-button name="trash" label="Remove from cart"></wa-icon-button>
</div>
<span class="wa-caption-m">Sand/Amber/Black</span>
<span class="wa-caption-m">12.5</span>
<div class="wa-split">
<span>$180.00</span>
<wa-select value="1" size="small" style="max-width: 8ch">
<wa-option value="1">1</wa-option>
<wa-option value="2">2</wa-option>
<wa-option value="3">3</wa-option>
</wa-select>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-align-items-start" style="--flank-size: 7rem">
<div class="wa-frame wa-border-radius-s">
<img src="https://images.unsplash.com/photo-1606107557195-0e29a4b5b4aa?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDM2MTF8&ixlib=rb-4.0.3&q=80&w=1080" alt="">
</div>
<div class="wa-stack wa-gap-xs">
<div class="wa-split">
<span class="wa-heading-s">NB Runner</span>
<wa-icon-button name="trash" label="Remove from cart"></wa-icon-button>
</div>
<span class="wa-caption-m">Forrest Green</span>
<span class="wa-caption-m">12.5</span>
<div class="wa-split">
<span>$48.99</span>
<wa-select value="1" size="small" style="max-width: 8ch">
<wa-option value="1">1</wa-option>
<wa-option value="2">2</wa-option>
<wa-option value="3">3</wa-option>
</wa-select>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-stack">
<div class="wa-split wa-caption-m">
<span>Subtotal</span>
<span>$363.99</span>
</div>
<div class="wa-split wa-caption-m">
<span>Shipping</span>
<span>FREE</span>
</div>
<div class="wa-split wa-heading-m">
<span>Total</span>
<span>$363.99</span>
</div>
</div>
<wa-divider></wa-divider>
<wa-button variant="brand">Confirm Order</wa-button>
</div>
</wa-card>
</div>
</div>
```
## Short Form with Order Summary
```html {.example}
<div class="wa-grid wa-gap-3xl">
<div class="wa-stack wa-gap-xl">
<h2>Payment</h2>
<wa-input type="email" label="Email" placeholder="ex. tanderson@metacortex.com">
<wa-icon slot="prefix" name="envelope"></wa-icon>
</wa-input>
<wa-input label="Card Number" placeholder="1234 1234 1234 1234">
<wa-icon slot="prefix" name="credit-card"></wa-icon>
</wa-input>
<div class="wa-grid" style="--min-column-size: 12ch">
<wa-input label="Expiration" placeholder="MM/YY">
<wa-icon slot="prefix" name="calendar"></wa-icon>
</wa-input>
<wa-input label="CVC" placeholder="CVC">
<wa-icon slot="prefix" name="lock"></wa-icon>
</wa-input>
</div>
<wa-input label="Cardholder Name" placeholder="Thomas Anderson">
<wa-icon slot="prefix" name="user"></wa-icon>
</wa-input>
<div class="wa-grid" style="--min-column-size: 12ch">
<wa-select label="Country" value="us">
<wa-icon slot="prefix" name="globe"></wa-icon>
<wa-option value="ca">Canada</wa-option>
<wa-option value="us">United States</wa-option>
<wa-option value="mx">Mexico</wa-option>
</wa-select>
<wa-input label="ZIP" placeholder="12345">
<wa-icon slot="prefix" name="location-dot"></wa-icon>
</wa-input>
</div>
<wa-switch checked>Sign me up for more offers from this store</wa-switch>
<wa-button variant="brand">Pay Now</wa-button>
</div>
<div class="wa-stack wa-gap-xl">
<h2>Order Summary</h2>
<div class="wa-split">
<div class="wa-cluster">
<div class="wa-frame wa-border-radius-m" style="max-width: 4rem">
<img src="https://images.unsplash.com/photo-1618677366787-9727aacca7ea?q=80&w=3255&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Glasses with black wire frames and dark tinted, circular lenses (Photograph by Colin Lloyd)">
</div>
<strong>Morpheus</strong>
</div>
<div class="wa-cluster">
<wa-input type="number" value="1" style="max-width: 5rem"></wa-input>
<span>$120.00</span>
</div>
</div>
<div class="wa-split">
<div class="wa-cluster">
<div class="wa-frame wa-border-radius-m" style="max-width: 4rem">
<img src="https://images.unsplash.com/photo-1511499767150-a48a237f0083?q=80&w=3558&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Glasses with rose gold wire frames and green tinted, circular lenses (Photograph by Charles Deluvio)">
</div>
<div class="wa-stack wa-gap-3xs">
<strong>Seraph</strong>
<em class="wa-caption-m">Tinted</em>
</div>
</div>
<div class="wa-cluster">
<wa-input type="number" value="1" style="max-width: 5rem"></wa-input>
<span>$180.00</span>
</div>
</div>
<div class="wa-split">
<div class="wa-cluster">
<div class="wa-frame wa-border-radius-m" style="max-width: 4rem">
<img src="https://images.unsplash.com/photo-1547104442-a40f335740cb?q=80&w=3348&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Glasses with tortoise shell half frames and large, rounded lenses (Photograph by Sincerely Media)">
</div>
<div class="wa-stack wa-gap-3xs">
<strong>Keymaker</strong>
<em class="wa-caption-m">Glossy</em>
</div>
</div>
<div class="wa-cluster">
<wa-input type="number" value="1" style="max-width: 5rem"></wa-input>
<span>$50.00</span>
</div>
</div>
<div class="wa-flank:end">
<wa-input placeholder="Discount code or gift card"></wa-input>
<wa-button appearance="filled">Apply</wa-button>
</div>
<div class="wa-stack wa-gap-s">
<div class="wa-split">
<span>Subtotal</span>
<strong>$530.00</strong>
</div>
<div class="wa-split">
<span>Shipping</span>
<span>$8.00</span>
</div>
<div class="wa-split">
<strong>Total</strong>
<strong>$538.00</strong>
</div>
</div>
</div>
</div>
```

View File

@@ -0,0 +1,3 @@
{
"tags": ["ecommerce"]
}

View File

@@ -0,0 +1,124 @@
---
title: Incentives
description: 'Encourage shoppers to buy your products with value propositions, discounts, and promotions.'
isPro: true
---
## 3 Column
```html{.example}
<div class="wa-gap-3xl wa-stack" style="max-width: 960px; margin: 0 auto;">
<div class="wa-align-items-center wa-grid">
<div>
<span class="wa-heading-xl">Unlock your Superpower</span>
<p class="wa-caption-l">Web development is like a superpower—you can turn your ideas into actual products online, and learning it from home means you dont need a fancy degree or expensive tuition to start building your future.</p>
</div>
<div class="wa-frame wa-border-radius-l">
<img src="https://images.unsplash.com/photo-1551981878-4c70c3e64135?q=80&w=2960&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
</div>
<div class="wa-grid">
<div class="wa-stack wa-gap-xs">
<wa-icon name="briefcase" variant="light" style="font-size: 32px;"></wa-icon>
<span class="wa-heading-s">Career Opportunities</span>
<p class="wa-caption-m">Mastering web development can lead to high-paying jobs, freelancing gigs, or even launching your own business or app.</p>
</div>
<div class="wa-stack wa-gap-xs">
<wa-icon name="laptop-code" variant="light" style="font-size: 32px;"></wa-icon>
<span class="wa-heading-s">Flexibility of Online Learning</span>
<p class="wa-caption-m">Perfect for people balancing school, work, or other responsibilities—no need to attend in-person classes</p>
</div>
<div class="wa-stack wa-gap-xs">
<wa-icon name="palette" variant="light" style="font-size: 32px;"></wa-icon>
<span class="wa-heading-s">Creative & Practical Skillset</span>
<p class="wa-caption-m">You can build real, functional things like personal portfolios, blogs, or web apps—and immediately see your progress.</p>
</div>
</div>
</div>
```
## 2 Column with Cards
```html{.example}
<div class="wa-grid" style="--min-column-size: 24ch;">
<wa-card>
<div class="wa-flank">
<div>
<wa-icon name="hands" style="font-size: 2.5rem;"></wa-icon>
</div>
<div class="wa-gap-s wa-stack">
<span class="wa-heading-m">Hands-on training</span>
<p class="wa-caption-l">Upskill effectively with AI-powered coding exercises, practice tests, and quizzes.</p>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank">
<div>
<wa-icon name="medal" style="font-size: 2.5rem;"></wa-icon>
</div>
<div class="wa-gap-s wa-stack">
<span class="wa-heading-m">Certification prep</span>
<p class="wa-caption-l">Prep for industry-recognized certifications by solving real-world challenges and earn badges along the way</p>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank">
<div>
<wa-icon name="chart-line" style="font-size: 2.5rem;"></wa-icon>
</div>
<div class="wa-gap-s wa-stack">
<div class="wa-split wa-gap-2xs">
<span class="wa-heading-m">Insights and analytics</span>
<wa-badge appearance="filled outlined" variant="warning">Pro Plan</wa-badge>
</div>
<p class="wa-caption-l">Fast-track goals with advanced insights plus a dedicated customer success team to help drive effective learning.</p>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank">
<div>
<wa-icon name="puzzle-piece" style="font-size: 2.5rem;"></wa-icon>
</div>
<div class="wa-gap-s wa-stack">
<div class="wa-split wa-gap-2xs">
<span class="wa-heading-m">Customizable content</span>
<wa-badge appearance="filled outlined" variant="warning">Pro Plan</wa-badge>
</div>
<p class="wa-caption-l">Create tailored learning paths for team and organization goals and even host your own content and resources.</p>
</div>
</div>
</wa-card>
</div>
```
## 4 Column
```html{.example}
<div>
<div class="wa-grid" style="--min-column-size: 16ch;">
<div class="wa-stack wa-gap-xs">
<wa-icon family="duotone" name="magnifying-glass" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<span class="wa-heading-s">In-Demand Skills</span>
<p class="wa-caption-m">Learn skills that lead to well-paying jobs, freelance work, or remote opportunities.</p>
</div>
<div class="wa-stack wa-gap-xs">
<wa-icon family="duotone" name="chalkboard-user" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<span class="wa-heading-s">Learn Anytime, Anywhere</span>
<p class="wa-caption-m">Flexible learning fits into any schedule—perfect for students, parents, or full-time workers.</p>
</div>
<div class="wa-stack wa-gap-xs">
<wa-icon family="duotone" name="people-arrows" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<span class="wa-heading-s">Build and Launch Your Own Projects</span>
<p class="wa-caption-m">Youre not just learning theory—youre creating real, functional websites and apps.</p>
</div>
<div class="wa-stack wa-gap-xs">
<wa-icon family="duotone" name="code" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<span class="wa-heading-s">Low-Cost Entry</span>
<p class="wa-caption-m">You dont need a tech degree or expensive tools to get started</p>
</div>
</div>
</div>
```

View File

@@ -0,0 +1,8 @@
---
title: Ecommerce
description: Pre-built product overviews, shopping carts, and more to help you build high-converting storefronts.
parent: patterns
layout: overview
override:tags: []
isPro: false
---

View File

@@ -0,0 +1,251 @@
---
title: Order History
description: 'Empower your customers to view past purchases and track upcoming orders with comprehensive order histories.'
isPro: true
---
## List
```html {.example}
<div class="wa-stack wa-gap-2xl">
<h2>Order History</h2>
<p class="wa-caption-m">Check the status of recent orders, manage returns, and download invoices.</p>
<dl class="wa-split">
<span class="wa-stack wa-gap-0">
<dt>Order number</dt>
<dd>WU88191111</dd>
</span>
<span class="wa-stack wa-gap-0">
<dt>Date placed</dt>
<dd>January 22, 2021</dd>
</span>
<span class="wa-stack wa-gap-0">
<dt>Total amount</dt>
<dd>$590.00</dd>
</span>
<span class="wa-cluster">
<wa-button variant="neutral" appearance="outlined">View Order</wa-button>
<wa-button variant="neutral" appearance="outlined">View Invoice</wa-button>
</span>
</dl>
<wa-divider></wa-divider>
<div class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-s" style="aspect-ratio: 3 / 2">
<img
src="https://img.fortawesome.com/cfa83f3c/light-fixtures.jpg"
alt=""
/>
</div>
<div class="wa-stack">
<div class="wa-split">
<span><strong>Dome Light Fixtures</strong></span>
<span><strong>$215.00</strong></span>
</div>
<p class="wa-caption-m">Illuminate your space with elegance and style with stunning Dome Light Fixtures. The shape of these lights complements both modern and traditional interiors.</p>
<div class="wa-split">
<wa-badge appearance="filled" variant="success">Delivered</wa-badge>
<div class="wa-cluster">
<wa-button size="small" appearance="plain" variant="neutral">View Product</wa-button>
<wa-button size="small" appearance="accent" variant="brand">Buy Again</wa-button>
</div>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-s" style="aspect-ratio: 3 / 2">
<img
src="https://img.fortawesome.com/cfa83f3c/modern-chair.jpg"
alt=""
/>
</div>
<div class="wa-stack">
<div class="wa-split">
<span><strong>Reading Chair</strong></span>
<span><strong>$115.00</strong></span>
</div>
<p class="wa-caption-m">Add a pop of color and a touch of elegance to any room with our Reading Chair featuring vibrant yellow fabric upholstery.</p>
<div class="wa-split">
<wa-badge appearance="filled" variant="brand">Out for delivery</wa-badge>
<div class="wa-cluster">
<wa-button size="small" appearance="plain" variant="neutral">View Product</wa-button>
<wa-button size="small" appearance="accent" variant="brand">Buy Again</wa-button>
</div>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-s" style="aspect-ratio: 3 / 2">
<img
src="https://img.fortawesome.com/cfa83f3c/sofa.jpg"
alt=""
/>
</div>
<div class="wa-stack">
<div class="wa-split">
<span><strong>Custom Sofa</strong></span>
<span><strong>$260.00</strong></span>
</div>
<p class="wa-caption-m">Experience luxury and comfort like never before with our Custom Sofa, designed to elevate any living space. This sofa features exquisite velvet upholstery for an air of sophistication.</p>
<div class="wa-split">
<wa-badge appearance="filled" variant="neutral">Preparing to ship</wa-badge>
<div class="wa-cluster">
<wa-button size="small" appearance="plain" variant="neutral">View Product</wa-button>
<wa-button size="small" appearance="accent" variant="brand">Buy Again</wa-button>
</div>
</div>
</div>
</div>
</div>
```
## Invoice Table
```html {.example}
<div class="wa-stack wa-gap-2xl">
<wa-callout appearance="filled" variant="neutral">
<div class="wa-flank:end wa-align-items-center">
<dl class="wa-grid">
<div class="wa-stack wa-gap-0">
<dt>Date Placed</dt>
<dd>
<wa-format-date date="2021-01-22" month="long" day="numeric" year="numeric"></wa-format-date>
</dd>
</div>
<div class="wa-stack wa-gap-0">
<dt>Order Number</dt>
<dd>WU88191111</dd>
</div>
<div class="wa-stack wa-gap-0">
<dt>Total Amount</dt>
<dd>$590.00</dd>
</div>
</dl>
<wa-button>View Invoice</wa-button>
</div>
</wa-callout>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Status</th>
<th>Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="wa-cluster wa-align-items-start">
<div class="wa-frame:landscape wa-border-radius-s" style="max-width: 8rem">
<img
src="https://img.fortawesome.com/cfa83f3c/light-fixtures.jpg"
alt=""
/>
</div>
<span>Dome Light Fixtures</span>
</div>
</td>
<td>$215.00</td>
<td>Delivered Jan 25, 2021</td>
<td><a href="">View</a></td>
</tr>
<tr>
<td>
<div class="wa-cluster wa-align-items-start">
<div class="wa-frame:landscape wa-border-radius-s" style="max-width: 8rem">
<img
src="https://img.fortawesome.com/cfa83f3c/modern-chair.jpg"
alt=""
/>
</div>
<span>Reading Chair</span>
</div>
</td>
<td>$115.00</td>
<td>Delivered Jan 25, 2021</td>
<td><a href="">View</a></td>
</tr>
<tr>
<td>
<div class="wa-cluster wa-align-items-start">
<div class="wa-frame:landscape wa-border-radius-s" style="max-width: 8rem">
<img
src="https://img.fortawesome.com/cfa83f3c/sofa.jpg"
alt=""
/>
</div>
<span>Custom Sofa</span>
</div>
</td>
<td>$260.00</td>
<td>Delivered Jan 25, 2021</td>
<td><a href="">View</a></td>
</tr>
</tbody>
</table>
</div>
```
## Card separated
```html{.example}
<div class="wa-stack" style="max-width: 60ch; margin: 0 auto;">
<wa-card>
<div class="wa-flank:end">
<div class="wa-stack">
<div class="wa-cluster wa-gap-xs">
<wa-avatar shape="rounded" label="Avatar with an image icon">
<wa-icon slot="icon"family="brands" name="amazon"></wa-icon>
</wa-avatar>
<span class="wa-heading-s">Amazon</span>
</div>
<div class="wa-stack wa-gap-xs">
<span>Expected Tomorrow</span>
<wa-progress-bar value="75" label="delivery progress" style="height: 0.5rem;"></wa-progress-bar>
</div>
</div>
<div class="wa-frame wa-border-radius-m" style="max-width: 6rem;">
<img src="https://images.unsplash.com/photo-1589810635657-232948472d98?q=80&w=2680&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<div class="wa-stack">
<div class="wa-cluster wa-gap-xs">
<wa-avatar shape="rounded" label="Avatar with an image icon">
<wa-icon slot="icon" family="sharp" variant="light" name="shirt"></wa-icon>
</wa-avatar>
<span class="wa-heading-s">T-shirt Depot</span>
</div>
<div class="wa-stack wa-gap-xs">
<span>Out for Delivery</span>
<wa-progress-bar value="95" label="delivery progress" style="height: 0.5rem;"></wa-progress-bar>
</div>
</div>
<div class="wa-frame wa-border-radius-m" style="max-width: 6rem;">
<img src="https://images.unsplash.com/photo-1576566588028-4147f3842f27?q=80&w=2400&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end">
<div class="wa-stack">
<div class="wa-cluster wa-gap-xs">
<wa-avatar shape="rounded" label="Avatar with an image icon">
<wa-icon slot="icon" variant="duotone" name="gamepad-modern"></wa-icon>
</wa-avatar>
<span class="wa-heading-s">Game Theory</span>
</div>
<div class="wa-stack wa-gap-xs">
<span>Shipping Soon</span>
<wa-progress-bar value="15" label="delivery progress" style="height: 0.5rem;"></wa-progress-bar>
</div>
</div>
<div class="wa-frame wa-border-radius-m" style="max-width: 6rem;">
<img src="https://images.unsplash.com/photo-1627421383054-488d9c9828f5?q=80&w=2960&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
</div>
</div>
</wa-card>
</div>
```

View File

@@ -0,0 +1,295 @@
---
title: Order Summary
description: 'Give shoppers confidence in their purchases with summaries of everything included in their order.'
isPro: true
---
## Simple
```html {.example}
<div class="wa-stack wa-gap-xl">
<wa-callout variant="success">
<em>Payment Successful</em>
<wa-icon slot="icon" name="circle-check"></wa-icon>
</wa-callout>
<wa-card>
<div class="wa-stack wa-gap-xl">
<h2>Thank you for ordering from us!</h2>
<p class="wa-caption-l">We're processing your order now. A confirmation email will be sent to you momentarily!</p>
<dl class="wa-cluster">
<dt>Order #</dt>
<dd>49548790-24545</dd>
</dl>
<wa-divider></wa-divider>
<div class="wa-flank:end wa-align-items-start wa-gap-xl" style="--flank-size: 14em">
<div class="wa-stack wa-gap-xl">
<ul class="wa-stack wa-gap-xl">
<li class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/vase-1.jpg"
alt=""
/>
</div>
<div class="wa-split">
<span class="wa-heading-s">Spotted Flower Pot</span>
<span>$75.00</span>
</div>
</li>
<wa-divider></wa-divider>
<li class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/decorative-vase.jpg"
alt=""
/>
</div>
<div class="wa-split">
<span class="wa-heading-s">Decorative Vase</span>
<span>$51.00</span>
</div>
</li>
</ul>
<wa-divider></wa-divider>
<dl class="wa-stack wap-gap-2xs wa-caption-l">
<div class="wa-split">
<dt>Subtotal</dt>
<dd>$126.00</dd>
</div>
<div class="wa-split">
<dt>Shipping</dt>
<dd>$8.00</dd>
</div>
<div class="wa-split">
<dt>Taxes</dt>
<dd>$6.40</dd>
</div>
<div class="wa-split">
<dt>Total</dt>
<dd>$140.40</dd>
</div>
</dl>
</div>
<wa-callout variant="neutral" appearance="filled">
<dl class="wa-stack" style="margin: 0">
<dt>Shipping Address</dt>
<dd>
<address class="wa-stack wa-gap-2xs">
<span>Donna Noble</span>
<span>56 Front Street</span>
<span>Las Cruces, NM 56929</span>
</address>
</dd>
<dt>Payment Information</dt>
<dd class="wa-flank wa-gap-s">
<wa-icon label="Visa" class="wa-body-xl" family="brands" name="cc-visa" style="color: #224DBA;"></wa-icon>
<span>Ending with 9065</span>
</dd>
</dl>
</wa-callout>
</div>
</div>
</wa-card>
<wa-button size="large" variant="brand" appearance="plain">
<wa-icon slot="suffix" name="arrow-right" variant="solid"></wa-icon>
Continue Shopping
</wa-button>
</div>
```
## With Details
```html {.example}
<div class="wa-stack">
<h2>Order Details</h2>
<div class="wa-split">
<div class="wa-cluster">
<span>Order placed <wa-format-date date="2025-02-26T09:00:00-04:00" month="long" day="numeric" year="numeric"></wa-format-date></span>
<wa-divider vertical style="height: 2em"></wa-divider>
<span>Order # 45646456-4656-4542</span>
</div>
<wa-button size="small" appearance="outlined" pill>View Invoice</wa-button>
</div>
<wa-card>
<div class="wa-split wa-align-items-start">
<div class="wa-stack">
<h3 class="wa-heading-s">Shipping Address</h3>
<address class="wa-stack wa-gap-xs wa-caption-m">
<span>Johnny Blaze</span>
<span>200 Park Avenue</span>
<span>Manhattan, NY 45789-3412</span>
<span>United States</span>
</address>
<wa-button size="small" appearance="outlined" pill>Change</wa-button>
</div>
<div class="wa-stack">
<h3 class="wa-heading-s">Payment Method</h3>
<div class="wa-flank wa-gap-s">
<wa-icon class="wa-body-xl" family="brands" name="cc-visa" style="color: #224DBA;"></wa-icon>
<span class="wa-caption-m">Visa ending in 9542</span>
</div>
</div>
<div class="wa-stack">
<h3 class="wa-heading-s">Order Summary</h3>
<dl class="wa-stack wa-gap-xs wa-caption-m">
<div class="wa-split">
<dt>Item(s) Subtotal</dt>
<dd>$39.00</dd>
</div>
<div class="wa-split">
<dt>Shipping & Handling</dt>
<dd>$0.00</dd>
</div>
<div class="wa-split">
<dt>Pre-tax Total</dt>
<dd>$39.00</dd>
</div>
<div class="wa-split">
<dt>Tax</dt>
<dd>$39.00</dd>
</div>
<wa-divider></wa-divider>
<div class="wa-split wa-body-m">
<dt>Grand Total</dt>
<dd>$39.00</dd>
</div>
</dl>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank:end wa-align-items-start" style="--flank-size: 12rem">
<div class="wa-stack">
<h3 class="wa-heading-s">Arriving Saturday</h3>
<div class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/sparkling-water.jpg"
alt=""
/>
</div>
<div class="wa-stack">
<a href="" class="wa-caption-m">Mineragua Sparkling Water 12 Count</a>
<span class="wa-caption-s">Sold by: <a href="">Mineragua</a></span>
<div class="wa-cluster">
<span class="wa-heading-s">$39.00</span>
<wa-button appearance="outlined" size="small" pill>
<wa-icon slot="prefix" name="rotate" variant="solid"></wa-icon>
Buy Again
</wa-button>
</div>
</div>
</div>
</div>
<div class="wa-stack wa-gap-xs">
<wa-button size="small" variant="brand" pill>Track Package</wa-button>
<wa-button size="small" appearance="outlined" variant="neutral" pill>Cancel Item(s)</wa-button>
<wa-button size="small" appearance="outlined" variant="neutral" pill>Ask Question</wa-button>
<wa-button size="small" appearance="outlined" variant="neutral" pill>Write Review</wa-button>
</div>
</div>
</wa-card>
</div>
```
## With Status & Description
```html {.example}
<div class="wa-stack wa-gap-xl">
<div class="wa-split">
<div class="wa-cluster">
<h2>Order #7093</h2>
<a href="">View Invoice</a>
</div>
<p class="wa-caption-m">Order placed <wa-format-date date="2025-06-12T09:00:00-04:00" month="long" day="numeric" year="numeric"></wa-format-date></p>
</div>
<wa-card>
<div class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/vase-1.jpg"
alt=""
/>
</div>
<div class="wa-stack wa-align-items-start wa-gap-s">
<div class="wa-split wa-gap-s">
<h3 class="wa-heading-m">Spotted Flower Pot</h3>
<span>$75.00</span>
</div>
<p class="wa-caption-m">Wood fired, salt glaze</p>
<wa-tag variant="success" appearance="filled" size="small">Delivered</wa-tag>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/decorative-vase.jpg"
alt=""
/>
</div>
<div class="wa-stack wa-align-items-start wa-gap-s">
<div class="wa-split wa-gap-s">
<h3 class="wa-heading-m">Decorative Vase</h3>
<span>$51.00</span>
</div>
<p class="wa-caption-m">High quality Japanese Kutani-yaki ceramic-ware</p>
<wa-tag variant="neutral" appearance="filled" size="small">Shipping Soon</wa-tag>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-flank wa-align-items-start">
<div class="wa-frame wa-border-radius-s">
<img
src="https://uploads.webawesome.com/cuong-duyen-ceramic.jpg"
alt=""
/>
</div>
<div class="wa-stack wa-align-items-start wa-gap-s">
<div class="wa-split wa-gap-s">
<h3 class="wa-heading-m">Cuong Duyen Ceramic</h3>
<span>$48.00</span>
</div>
<p class="wa-caption-m">Koishiwara-yaki style with crystalline glaze</p>
<wa-tag variant="brand" appearance="filled" size="small">Out for Delivery</wa-tag>
</div>
</div>
</wa-card>
<wa-divider></wa-divider>
<wa-callout variant="neutral" appearance="filled">
<div class="wa-grid">
<div class="wa-stack">
<h3 class="wa-heading-s">Shipping Address</h3>
<address class="wa-stack wa-gap-xs wa-caption-m">
<span>Donna Noble</span>
<span>56 Front Street</span>
<span>Las Cruces, NM 56929</span>
</address>
</div>
<div class="wa-stack">
<h3 class="wa-heading-s">Order Summary</h3>
<dl class="wa-stack wa-gap-xs wa-caption-m">
<div class="wa-split">
<dt>Item(s) Subtotal</dt>
<dd>$174.00</dd>
</div>
<div class="wa-split">
<dt>Shipping & Handling</dt>
<dd>$0.00</dd>
</div>
<div class="wa-split">
<dt>Tax</dt>
<dd>$17.40</dd>
</div>
<wa-divider></wa-divider>
<div class="wa-split wa-body-m">
<dt>Total</dt>
<dd>$191.40</dd>
</div>
</dl>
</div>
</div>
</wa-callout>
</div>
```

View File

@@ -0,0 +1,183 @@
---
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
```html {.example}
<div class="wa-grid wa-gap-2xl">
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1633933329864-5d4c4423ad54?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Bunch of fresh basil leaves with purple veins (Photograph by Svitlana)"
/>
</div>
<strong>Basil</strong>
<wa-rating label="Rating" size="small" readonly value="5"></wa-rating>
<span class="wa-caption-m">41 Reviews</span>
<strong>$8.59</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1662892194342-f95c33cc16e3?q=80&w=3000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Bunch of cut chamomile blooms (Photograph by Rootnot Creations)"
/>
</div>
<strong>Chamomile</strong>
<wa-rating label="Rating" size="small" readonly value="3"></wa-rating>
<span class="wa-caption-m">17 Reviews</span>
<strong>$10.29</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1636396279461-f875646332d9?q=80&w=3360&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Canvas bundle of cut lavender blooms (Photograph by volant)"
/>
</div>
<strong>Lavender</strong>
<wa-rating label="Rating" size="small" readonly value="4"></wa-rating>
<span class="wa-caption-m">29 Reviews</span>
<strong>$9.99</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1501085934018-450c8e615dbc?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Blooming marjoram plant (Photograph by Monika Grabkowska)"
/>
</div>
<strong>Marjoram</strong>
<wa-rating label="Rating" size="small" readonly value="4"></wa-rating>
<span class="wa-caption-m">11 Reviews</span>
<strong>$8.59</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1688633767797-455f59c98272?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Group of mature oregano plants (Photograph Nikolett Emmert)"
/>
</div>
<strong>Oregano</strong>
<wa-rating label="Rating" size="small" readonly value="5"></wa-rating>
<span class="wa-caption-m">38 Reviews</span>
<strong>$8.59</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1603109731710-dba41b1096a7?q=80&w=2259&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Cluster of peppermint plants (Photograph by Josefin)"
/>
</div>
<strong>Peppermint</strong>
<wa-rating label="Rating" size="small" readonly value="5"></wa-rating>
<span class="wa-caption-m">26 Reviews</span>
<strong>$9.99</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1726994803809-0e065bd4b25b?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Mature rosemary stems (Photograph by 360floralflaves)"
/>
</div>
<strong>Rosemary</strong>
<wa-rating label="Rating" size="small" readonly value="4"></wa-rating>
<span class="wa-caption-m">34 Reviews</span>
<strong>$8.59</strong>
</a>
<a class="wa-stack wa-align-items-center wa-gap-xs wa-link-plain" href="">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1659834742696-44573974981b?q=80&w=3542&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Group of sage plants (Photograph by Susie Burleson)"
/>
</div>
<strong>Sage</strong>
<wa-rating label="Rating" size="small" readonly value="5"></wa-rating>
<span class="wa-caption-m">24 Reviews</span>
<strong>$9.29</strong>
</a>
</div>
```
## Even Card Grid with Details
```html {.example}
<div class="wa-grid" style="--min-column-size: 50ch">
<div class="wa-grid">
<a href="" class="wa-link-plain">
<wa-card>
<img slot="image"
src="https://images.unsplash.com/photo-1622445272461-c6580cab8755?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Man in a relaxed fit, white, crew neck t-shirt (Photography by Mediamodifier)"
/>
<div class="wa-stack">
<div class="wa-flank:end wa-align-items-start wa-heading-m">
<span>Plain Classic Tee</span>
<span>$24</span>
</div>
<p class="wa-caption-m">Keep it casual or dress it up. Soft, 100% cotton with a crew neckline, perfect for any occasion.</p>
<em class="wa-caption-m">8 colors</em>
</div>
</wa-card>
</a>
<a href="" class="wa-link-plain">
<wa-card>
<img slot="image"
src="https://images.unsplash.com/photo-1554568218-0f1715e72254?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Woman in a light heather t-shirt printed with sharp black ink (Photograph by Christian Bolt)"
/>
<div class="wa-stack">
<div class="wa-flank:end wa-align-items-start wa-heading-m">
<span>One-color Graphic Tee</span>
<span>$32</span>
</div>
<p class="wa-caption-m">Your own spin on our classic tee. Hand screen printed for the ultimate accuracy and quality.</p>
<em class="wa-caption-m">6 colors</em>
</div>
</wa-card>
</a>
</div>
<div class="wa-grid">
<a href="" class="wa-link-plain">
<wa-card>
<img slot="image"
src="https://images.unsplash.com/photo-1567098260939-5d9cee055592?q=80&w=2832&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Man in a black t-shirt printed with many-colored gradients (Photograph by Marcel)"
/>
<div class="wa-stack">
<div class="wa-flank:end wa-align-items-start wa-heading-m">
<span>Multi-color Graphic Tee</span>
<span>$36</span>
</div>
<p class="wa-caption-m">Make a statement. Screen printed with vibrant, quality inks to last wash after wash.</p>
<em class="wa-caption-m">4 colors</em>
</div>
</wa-card>
</a>
<a href="" class="wa-link-plain">
<wa-card>
<img slot="image"
src="https://images.unsplash.com/photo-1709185727063-c3caae752a64?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Woman in a black t-shirt with a bright white logo printed on the pocket (Photograph by SASI)"
/>
<div class="wa-stack">
<div class="wa-flank:end wa-align-items-start wa-heading-m">
<span>Pocket Graphic Tee</span>
<span>$29</span>
</div>
<p class="wa-caption-m">Go classic with a bit of your own flair. Screen printed, eye-catching detail on the pocket.</p>
<em class="wa-caption-m">6 colors</em>
</div>
</wa-card>
</a>
</div>
</div>
```

View File

@@ -0,0 +1,430 @@
---
title: Product Overview
description: 'Showcase your products with overviews including images, ratings, features, options, and more.'
isPro: true
---
## Split with Image
```html {.example}
<div class="wa-grid wa-gap-2xl">
<div class="wa-stack wa-gap-2xl">
<h2>San Ignacio Pache</h2>
<p>A smooth, balanced Arabica varietal, grown and roasted on the Guerrero family's farm. Rich caramel and malt flavors blend with bright citrus for a complex brew suitable for drip, pour over, espresso, or however you take your coffee.</p>
<div class="wa-stack">
<wa-select label="Bag Size" value="12oz">
<wa-option value="12oz">12 oz &ndash; $19.95</wa-option>
<wa-option value="3lb">3 lb &ndash; $72.00</wa-option>
<wa-option value="5lb">5 lb &ndash; $99.75</wa-option>
</wa-select>
<wa-select label="Bean Type" value="whole">
<wa-option value="whole">Whole</wa-option>
<wa-option value="drip">Drip Grind</wa-option>
<wa-option value="espresso">Espresso Grind</wa-option>
</wa-select>
</div>
<div class="wa-stack">
<div class="wa-flank">
<wa-input type="number" aria-label="Quantity" value="1" min="1" style="max-width: 8ch"></wa-input>
<wa-button variant="brand">
<wa-icon slot="prefix" name="basket-shopping"></wa-icon>
Add to Basket
</wa-button>
</div>
<div class="wa-flank wa-caption-m">
<wa-icon name="truck"></wa-icon>
<span>Free shipping on orders over $60</span>
</div>
</div>
<dl class="wa-grid">
<div class="wa-flank">
<wa-avatar>
<wa-icon slot="icon" name="coffee-bean"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-0">
<dt>Roast</dt>
<dd>Medium</dd>
</div>
</div>
<div class="wa-flank">
<wa-avatar>
<wa-icon slot="icon" name="earth-americas"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-0">
<dt>Origin</dt>
<dd>San Ignacio, Peru</dd>
</div>
</div>
<div class="wa-flank">
<wa-avatar>
<wa-icon slot="icon" name="sun-haze"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-0">
<dt>Process</dt>
<dd>Washed</dd>
</div>
</div>
<div class="wa-flank">
<wa-avatar>
<wa-icon slot="icon" name="mug-hot"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-0">
<dt>Tasting Notes</dt>
<dd>Caramel, malt, orange</dd>
</div>
</div>
</dl>
</div>
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1600396538702-d234dbb79139?q=80&w=3833&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Whole roasted coffee beans (Photograph by Jocelyn Morales)"
/>
</div>
</div>
```
## With Image Grid
```html {.example}
<div class="wa-stack wa-gap-2xl">
<wa-breadcrumb>
<wa-breadcrumb-item>Clothing</wa-breadcrumb-item>
<wa-breadcrumb-item>Women's</wa-breadcrumb-item>
<wa-breadcrumb-item>Shirts &amp; Tops</wa-breadcrumb-item>
</wa-breadcrumb>
<div class="wa-grid wa-gap-xs" style="--min-column-size: 10ch">
<div class="wa-frame" style="height: 100%; width: 100%">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1614792568992-ded1c487c1dd?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Patrick Perkins)"
/>
</div>
<div class="wa-grid wa-gap-xs">
<div class="wa-frame" style="aspect-ratio: 3 / 2">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1614725078749-29c421fd0e51?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Patrick Perkins)"
/>
</div>
<div class="wa-frame" style="aspect-ratio: 3 / 2">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1614725808713-e6bbe418fc5d?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Patrick Perkins)"
/>
</div>
</div>
<div class="wa-frame" style="height: 100%; width: 100%">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1614725078379-9d1330a08c95?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Patrick Perkins)"
/>
</div>
</div>
<div class="wa-grid wa-gap-xl" style="--min-column-size: 30ch">
<h2 class="wa-heading-l">Cropped Fitted Tank Top</h2>
<span class="wa-body-xl">$59</span>
</div>
<div class="wa-grid wa-gap-xl" style="--min-column-size: 30ch">
<div class="wa-stack wa-gap-xl">
<div class="wa-cluster">
<wa-rating label="Rating" readonly value="3.5"></wa-rating>
<a href="">117 Reviews</a>
</div>
<p>Made with a breathable, stretchy fabric blend for unparalleled comfort and flattering style. Pairs perfectly with your favorite high-waisted jeans for lazy summer weekends or lively nights out.</p>
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-xs">Good to Know</h3>
<p class="wa-body-xs">95% cotton, 5% elastane. Our tops are pre-shrunk to ensure a consistent fit with no surprises. Machine wash cold. Tumble dry low.</p>
</div>
</div>
<div class="wa-stack">
<wa-radio-group label="Color" name="color" value="black" orientation="horizontal">
<wa-radio-button id="radio-black" value="black">
<wa-icon name="square" label="Black" style="color: black;"></wa-icon>
<wa-tooltip for="radio-black">Black</wa-tooltip>
</wa-radio-button>
<wa-radio-button id="radio-gray" value="gray">
<wa-icon name="square" label="Gray" style="color: gray;"></wa-icon>
<wa-tooltip for="radio-gray">Gray</wa-tooltip>
</wa-radio-button>
<wa-radio-button id="radio-indigo" value="indigo">
<wa-icon name="square" label="Indigo" style="color: indigo;"></wa-icon>
<wa-tooltip for="radio-indigo">Indigo</wa-tooltip>
</wa-radio-button>
<wa-radio-button id="radio-olive" value="olive">
<wa-icon name="square" label="Olive" style="color: olive;"></wa-icon>
<wa-tooltip for="radio-olive">Olive</wa-tooltip>
</wa-radio-button>
</wa-radio-group>
<wa-radio-group label="Size" name="size" value="s" orientation="horizontal">
<wa-radio-button value="xs">XS</wa-radio-button>
<wa-radio-button value="s">S</wa-radio-button>
<wa-radio-button value="m">M</wa-radio-button>
<wa-radio-button value="l">L</wa-radio-button>
<wa-radio-button value="xl">XL</wa-radio-button>
</wa-radio-group>
<wa-button variant="brand">
<wa-icon slot="prefix" name="cart-plus" variant="solid"></wa-icon>
Add to Cart
</wa-button>
</div>
</div>
</div>
```
## With Tiered Images
```html {.example}
<div class="wa-stack wa-gap-2xl">
<wa-breadcrumb>
<wa-breadcrumb-item>Clothing</wa-breadcrumb-item>
<wa-breadcrumb-item>Men's</wa-breadcrumb-item>
<wa-breadcrumb-item>Shirts &amp; Tops</wa-breadcrumb-item>
</wa-breadcrumb>
<div class="wa-grid wa-gap-2xl" style="--min-column-size: 35ch">
<div class="wa-stack wa-gap-xs">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1630643583573-c68623718072?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Gervyn Louis)"
/>
<div class="wa-grid wa-gap-xs" style="--min-column-size: 0ch">
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1571666274590-f8cc87006500?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Gervyn Louis)"
/>
<img class="wa-border-radius-s"
src="https://images.unsplash.com/photo-1630643591760-a6ed60ef499f?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Gervyn Louis)"
/>
</div>
</div>
<div class="wa-stack">
<div class="wa-split">
<h2 class="wa-heading-l">Graphic Cutoff Tee</h2>
<span class="wa-body-xl">$65</span>
</div>
<div class="wa-split">
<div class="wa-cluster">
<wa-rating label="Rating" readonly value="4.2"></wa-rating>
<span>4.2</span>
</div>
<a href="#">144 Reviews</a>
</div>
<wa-radio-group label="Color" name="color" value="black" orientation="horizontal">
<wa-radio-button value="black">
<wa-icon slot="prefix" name="shirt" style="color: black;"></wa-icon>
Vintage Black
</wa-radio-button>
<wa-radio-button value="gray">
<wa-icon slot="prefix" name="shirt" style="color: gray;"></wa-icon>
Faded Gray
</wa-radio-button>
</wa-radio-group>
<wa-radio-group label="Size" name="size" value="s" orientation="horizontal">
<wa-radio-button value="xs">XS</wa-radio-button>
<wa-radio-button value="s">S</wa-radio-button>
<wa-radio-button value="m">M</wa-radio-button>
<wa-radio-button value="l">L</wa-radio-button>
<wa-radio-button value="xl">XL</wa-radio-button>
</wa-radio-group>
<wa-button variant="brand">
<wa-icon slot="prefix" name="bag-shopping" variant="solid"></wa-icon>
Add to Bag
</wa-button>
<wa-divider></wa-divider>
<h3 class="wa-heading-s">Description</h3>
<p>Stay cool, <em>slay</em> cool. Train hard and recover in style with this ultra-breathable cutoff tee. Made from 100% organic, quick-drying cotton to keep the air flowing whether you're lifting, sprinting, or crushing HIIT sessions.</p>
<wa-divider></wa-divider>
<h3 class="wa-heading-s">Highlights</h3>
<div class="wa-grid">
<wa-card class="wa-span-grid">
<div class="wa-stack">
<wa-icon name="hand-holding-heart"></wa-icon>
<h4 class="wa-heading-s">People and Planet First</h4>
<p class="wa-caption-m">Ethical production, fair wages, and sustainable materials empower every part of our supply chain.</p>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<wa-icon name="earth-americas"></wa-icon>
<h4 class="wa-heading-s">International Shipping</h4>
<p class="wa-caption-m">Wherever you are, your order will meet you there.</p>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<wa-icon name="arrow-right-arrow-left"></wa-icon>
<h4 class="wa-heading-s">90-day Returns</h4>
<p class="wa-caption-m">Not happy? Return your item and get a full refund.</p>
</div>
</wa-card>
</div>
</div>
</div>
</div>
```
## With Carousel and Collapsible Details
```html {.example}
<div class="wa-stack wa-gap-2xl">
<wa-carousel pagination navigation loop style="--aspect-ratio: 3 / 2;">
<wa-carousel-item>
<img
src="https://images.unsplash.com/photo-1601379327928-bedfaf9da2d0?q=80&w=3456&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Four folded and stacked knit sweaters in three colors (Photograph by Tijana Drndarski)"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
src="https://images.unsplash.com/photo-1519804270019-39e929a7afb5?q=80&w=3774&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Knit sweater in sand color full view, showing waffle knit pattern, relaxed fit, and crew neckline (Photograph by Jonathan Zerger)"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
src="https://images.unsplash.com/photo-1519805614447-6f49142e6697?q=80&w=3633&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Knit sweater in sand color shoulder detail, showing relaxed fit on broader shoulders (Photograph by Jonathan Zerger)"
/>
</wa-carousel-item>
<wa-carousel-item>
<img
src="https://images.unsplash.com/photo-1522230130022-498e355165c5?q=80&w=3774&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Knit sweater in sand color sleeve detail, showing loose fit around the arms (Photograph by Jonathan Zerger)"
/>
</wa-carousel-item>
</wa-carousel>
<div class="wa-grid wa-gap-2xl" style="--min-column-size: 30ch;">
<div class="wa-stack">
<div class="wa-split">
<h3>Pullover Sweater</h3>
<span class="wa-body-xl">$140</span>
</div>
<wa-rating label="Rating" precision="0.5" value="4.5" readonly></wa-rating>
<p>Wrap yourself in warmth and effortless style with this wool knit Pullover Sweater. Designed for unparalleled comfort. The relaxed fit and classic crew neckline make it a versatile staple for layering or wearing solo.</p>
<wa-radio-group label="Color" name="color" value="sand" orientation="horizontal">
<wa-radio-button value="sand">
<wa-icon slot="prefix" name="circle" style="color: burlywood;"></wa-icon>
Sand
</wa-radio-button>
<wa-radio-button value="shale">
<wa-icon slot="prefix" name="circle" style="color: silver;"></wa-icon>
Shale
</wa-radio-button>
<wa-radio-button value="slate">
<wa-icon slot="prefix" name="circle" style="color: dimgray;"></wa-icon>
Slate
</wa-radio-button>
</wa-radio-group>
<wa-radio-group label="Size" name="size" value="s" orientation="horizontal">
<wa-radio-button value="xs">XS</wa-radio-button>
<wa-radio-button value="s">S</wa-radio-button>
<wa-radio-button value="m">M</wa-radio-button>
<wa-radio-button value="l">L</wa-radio-button>
<wa-radio-button value="xl">XL</wa-radio-button>
</wa-radio-group>
<wa-button variant="brand">Add to Cart</wa-button>
</div>
<div class="wa-stack">
<wa-details summary="Size and Fit" open>
<ul class="wa-body-s">
<li>True to size with a relaxed fit</li>
<li>Fits all shoulder shapes, broad to narrow</li>
<li>No pinching in the arms or irritating seams</li>
<li>Ribbed cuffs and hem</li>
</ul>
</wa-details>
<wa-details summary="Materials and Care">
<ul class="wa-body-s">
<li>Durable Merino and Yak wool blend</li>
<li>Machine wash cold on delicate cycle</li>
<li>Lay flat to dry</li>
<li>Made with <wa-icon name="heart" label="love"></wa-icon> in Bentonville, USA</li>
</ul>
</wa-details>
<wa-details summary="Shipping">
<ul class="wa-body-s">
<li>Flat $9 shipping free for orders under $200.</li>
<li>Free shipping on orders over $200, anywhere in the world.</li>
</ul>
</wa-details>
</div>
</div>
</div>
```
## With Tabs
```html {.example}
<div class="wa-flank:end wa-align-items-start wa-gap-2xl" style="--flank-size: 30ch">
<div class="wa-stack">
<img class="wa-border-radius-l"
src="https://img.fortawesome.com/cfa83f3c/icon-grid-wallpaper.png"
alt="Sample of 48 line-style icons"
/>
<wa-tab-group>
<wa-tab panel="license">License</wa-tab>
<wa-tab panel="faq">FAQ</wa-tab>
<wa-tab-panel name="license">
<p class="wa-body-s">Your purchase includes a perpetual Font Awesome Pro License to use Classic Light icons on unlimited projects. <a href="">Read the full license terms.</a></p>
</wa-tab-panel>
<wa-tab-panel name="faq">
<dl class="wa-stack wa-body-s">
<dt>Do I need to renew my subscription to receive fixes?</dt>
<dd>We split up Font Awesome releases into regular updates and bug-fix updates. With a Font Awesome Pro plan that has a perpetual license, you'll always be entitled to bug-fix updates for your last version, even after your subscription has expired.</dd>
<dt>Can I use Font Awesome Pro in themes, plug-ins, or open source projects?</dt>
<dd>For themes and open source projects, right now it's best to just use Font Awesome Free. We are working a better solution, so feel free to get in touch if you have thoughts.</dd>
<dt>Do you offer enterprise licenses for Font Awesome Pro?</dt>
<dd>We don't currently offer Enterprise-level licenses, but we may do so in the future. Get in touch if interested.</dd>
</dl>
</wa-tab-panel>
</wa-tab-group>
</div>
<div class="wa-stack wa-gap-l">
<wa-badge appearance="filled">Sale</wa-badge>
<h2>Icon Pack: Classic Light</h2>
<p class="wa-body-l">Easy, readable icons with a lighter touch.</p>
<div class="wa-cluster wa-gap-xs wa-body-l">
<s>$60</s>
<strong>$49</strong>
</div>
<wa-button variant="brand" size="large">
<wa-icon slot="prefix" name="arrow-down-to-line" variant="solid"></wa-icon>
Get Icons
</wa-button>
<wa-divider></wa-divider>
<h3 class="wa-heading-m">What's in the Pack</h3>
<ul class="wa-stack wa-gap-xs">
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>3,323 icons</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>Pre-bundled Font Awesome kit</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>Ligature-based desktop font files</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>Individual SVGs + SVG sprites</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>Web fonts + SVG framework</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>SCSS/LESS CSS preprocessor files</span>
</li>
<li class="wa-flank">
<wa-icon name="badge-check"></wa-icon>
<span>Perpetual Pro license</span>
</li>
</ul>
</div>
</div>
```

View File

@@ -0,0 +1,161 @@
---
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
```html {.example}
<wa-card with-header>
<div class="wa-split" slot="header">
<h3 class="wa-heading-l">Stan Smith® Camo Tongue Tee</h3>
<wa-icon-button name="close" label="Close Preview"></wa-icon-button>
</div>
<div class="wa-grid wa-gap-xl">
<div class="wa-frame wa-border-radius-l" style="aspect-ratio: auto">
<img
src="https://images.unsplash.com/photo-1660997351262-6c31d8a35b6c?q=80&w=2000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Stan Smith graphic crew-neck tee in honeydew color"
/>
</div>
<div class="wa-split:column wa-align-items-stretch wa-gap-xl">
<div class="wa-stack wa-gap-xl">
<div class="wa-cluster">
<span class="wa-heading-2xl">$32</span>
<wa-divider vertical style="height: 2em"></wa-divider>
<wa-rating label="Rating" value="3.75" readonly></wa-rating>
<a href="" class="wa-caption-m">36 Reviews</a>
</div>
<p>An ode to the “Sneaker that go with everything” …even this tee.</p>
<wa-divider></wa-divider>
<div class="wa-stack wa-gap-s">
<h4 class="wa-heading-s">Categories</h4>
<div class="wa-cluster wa-gap-2xs">
<a href=""><wa-tag appearance="outlined" size="small" pill>Men's</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Sneakers</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Tees</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Lifestyle</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Fashion</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Casual</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Stan Smith</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Tennis</wa-tag></a>
<a href=""><wa-tag appearance="outlined" size="small" pill>Sports</wa-tag></a>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-stack wa-gap-s">
<wa-select label="Color" value="honeydew">
<wa-option value="hotpink">
<wa-icon slot="prefix" name="circle" style="color: hotpink;"></wa-icon>
Hot Pink
</wa-option>
<wa-option value="honeydew">
<wa-icon slot="prefix" name="circle" style="color: honeydew;"></wa-icon>
Honeydew
</wa-option>
<wa-option value="coral">
<wa-icon slot="prefix" name="circle" style="color: lightcoral;"></wa-icon>
Coral
</wa-option>
<wa-option value="wheat">
<wa-icon slot="prefix" name="circle" style="color: wheat;"></wa-icon>
Wheat
</wa-option>
<wa-option value="lilac">
<wa-icon slot="prefix" name="circle" style="color: #C8A2C8;"></wa-icon>
Lilac
</wa-option>
<wa-option value="burnt-orange">
<wa-icon slot="prefix" name="circle" style="color: #FF5733"></wa-icon>
Burnt Orange
</wa-option>
</wa-select>
<wa-select label="Size" value="large">
<wa-option value="small">Small</wa-option>
<wa-option value="medium">Medium</wa-option>
<wa-option value="large">Large</wa-option>
<wa-option value="xl">XL</wa-option>
<wa-option value="xxl">XXL</wa-option>
</wa-select>
</div>
</div>
<wa-button variant="brand">
Add to Cart
<wa-icon slot="suffix" name="cart-shopping" variant="solid"></wa-icon>
</wa-button>
</div>
</div>
</wa-card>
```
## With Description & Details
```html{.example}
<wa-card>
<div class="wa-split" slot="header">
<h3 class="wa-heading-l">Champion® Crossbody Bag</h3>
<wa-icon-button name="close" label="Close Preview"></wa-icon-button>
</div>
<div class="wa-grid wa-gap-xl">
<div class="wa-frame wa-border-radius-l" style="aspect-ratio: auto">
<img
src="https://images.unsplash.com/photo-1643467358005-899641cab7b5?q=80&w=2487&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Black weatherproof crossbody bag with two large zipper pockets"
/>
</div>
<div class="wa-split:column wa-align-items-stretch wa-gap-xl">
<div class="wa-stack wa-gap-xl">
<div class="wa-split wa-align-items-start">
<span class="wa-heading-2xl">$40</span>
<wa-icon-button id="favorite" label="Favorite" name="heart" variant="regular"></wa-icon-button>
<wa-tooltip for="favorite">Add to Favorites</wa-tooltip>
</div>
<div class="wa-split">
<div class="wa-cluster wa-gap-xs">
<span>3.9</span>
<wa-rating value="3.9" readonly></wa-rating>
</div>
<a href="">See 512 Reviews</a>
</div>
<wa-divider></wa-divider>
<wa-callout size="small">
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
You purchased this item on <wa-format-date date="2023-02-20T09:00:00-04:00" month="long" day="numeric" year="numeric"></wa-format-date>
</wa-callout>
<div class="wa-gap-xs wa-stack">
<h4 class="wa-heading-m">About</h4>
<p class="wa-body-s">The Champion® Crossbody Bag is crafted for the trendsetter. Its sleek silhouette, paired with a tonal branded adjustable sling strap, ensures you look effortlessly cool no matter where you go.</p>
</div>
<wa-divider></wa-divider>
<div class="wa-gap-xs wa-stack">
<h4 class="wa-heading-m">Details</h4>
<dl class="wa-grid" style="--min-column-size: 15ch">
<div class="wa-gap-2xs wa-stack">
<dt class="wa-body-s">Care Instructions</dt>
<dd class="wa-caption-m">Hand Wash Only</dd>
</div>
<div class="wa-gap-2xs wa-stack">
<dt class="wa-body-s">Origin</dt>
<dd class="wa-caption-m">Imported</dd>
</div>
<div class="wa-gap-2xs wa-stack">
<dt class="wa-body-s">Country of Origin</dt>
<dd class="wa-caption-m">China</dd>
</div>
</dl>
</div>
</div>
<div class="wa-flank:end wa-align-items-end">
<wa-button variant="brand" size="medium">
<wa-icon slot="suffix" name="cart-shopping" variant="solid"></wa-icon>Add to Cart
</wa-button>
<wa-button appearance="outlined" size="medium">
<wa-icon slot="suffix" name="arrow-right" variant="solid"></wa-icon>View Full Details
</wa-button>
</div>
</div>
</div>
</wa-card>
```

View File

@@ -0,0 +1,212 @@
---
title: Product Reviews
description: 'Help shoppers make informed decisions with ratings, reviews, and testimonials from your customers.'
isPro: true
---
## Multi column
```html{.example}
<div style="max-width: 960px; margin: 0 auto;">
<span class="wa-heading-m">Recent Reviews</span>
<wa-divider></wa-divider>
<div class="wa-flank wa-gap-s" style="--flank-size: 20%">
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Viktor Vaughn</span>
<wa-relative-time date="2020-07-15T09:17:00-04:00" class="wa-caption-m"></wa-relative-time>
</div>
<div class="wa-flank">
<wa-rating label="Rating" readonly value="5"></wa-rating>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Solid treadmill for home workouts!</span>
<p>Best treadmill I've ever owned! It has a sleek design, and the features are top-notch. I use it daily for my cardio workouts, and the motor is powerful enough to keep up with my running. Its easy to adjust the speed and incline, and the display is clear and simple to read. Worth every penny!</p>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-gap-s" style="--flank-size: 20%">
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Ben Grimm</span>
<wa-relative-time date="2020-07-15T09:17:00-04:00" class="wa-caption-m"></wa-relative-time>
</div>
<div class="wa-flank">
<wa-rating label="Rating" readonly value="4"></wa-rating>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Good value, a few minor flaws</span>
<p>Decent treadmill for the price, but I feel like the belt could be a little wider for comfort. The cushioning is good, but sometimes I experience a slight wobble when running at high speeds. For casual walking, it's fine, but Im not sure its built for intense runners.</p>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-gap-s" style="--flank-size: 20%">
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Johnny Storm</span>
<wa-relative-time date="2020-07-15T09:17:00-04:00" class="wa-caption-m"></wa-relative-time>
</div>
<div class="wa-flank">
<wa-rating label="Rating" readonly value="4"></wa-rating>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Decent, but could use upgrades</span>
<p>This treadmill has been a great addition to my home gym. It's sturdy, easy to use, and I like that it tracks my steps and heart rate. The only downside is that it's a bit bulky, so I had to rearrange my space to make room for it. Overall, I'm happy with the performance and would recommend it.</p>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-gap-s" style="--flank-size: 20%">
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Sue Storm</span>
<wa-relative-time date="2020-07-15T09:17:00-04:00" class="wa-caption-m"></wa-relative-time>
</div>
<div class="wa-flank">
<wa-rating label="Rating" readonly value="4"></wa-rating>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Perfect for small spaces</span>
<p>I absolutely love my new treadmill! Its perfect for my daily workouts. The setup was quick, and its so quiet that I can use it while watching TV without any interruptions. The different incline levels really help mix up my routine, and the built-in programs keep things interesting. Highly recommend for anyone looking to stay fit at home!</p>
</div>
</div>
</div>
</div>
```
## With Ratings Distribution
```html {.example}
<div style="max-width: 960px; margin: 0 auto;">
<div class="wa-align-items-start wa-flank wa-gap-2xl">
<div class="wa-gap-s wa-stack">
<span class="wa-heading-m">Customer Reviews</span>
<div class="wa-stack wa-gap-xs"><wa-rating label="Rating" precision="0.5" value="4.6" size="small"></wa-rating> <span class="wa-caption-m">Based on 1624 reviews</span></div>
<div class="wa-stack">
<span class="wa-cluster wa-gap-2xs">
<span>5</span>
<wa-icon name="star" style="font-size: 12px;"></wa-icon>
<wa-progress-bar value="63" label="Upload progress" style="height: 6px; width: 50%"></wa-progress-bar>
<wa-format-number type="percent" value=".63"></wa-format-number>
</span>
<span class="wa-cluster wa-gap-2xs">
<span>4</span>
<wa-icon name="star" style="font-size: 12px;"></wa-icon>
<wa-progress-bar value="17" label="Upload progress" style="height: 6px; width: 50%"></wa-progress-bar>
<wa-format-number type="percent" value=".17"></wa-format-number>
</span>
<span class="wa-cluster wa-gap-2xs">
<span>3</span>
<wa-icon name="star" style="font-size: 12px;"></wa-icon>
<wa-progress-bar value="15" label="Upload progress" style="height: 6px; width: 50%"></wa-progress-bar>
<wa-format-number type="percent" value=".15"></wa-format-number>
</span>
<span class="wa-cluster wa-gap-2xs">
<span>2</span>
<wa-icon name="star" style="font-size: 12px;"></wa-icon>
<wa-progress-bar value="3" label="Upload progress" style="height: 6px; width: 50%"></wa-progress-bar>
<wa-format-number type="percent" value=".03"></wa-format-number>
</span>
<span class="wa-cluster wa-gap-2xs">
<span>1</span>
<wa-icon name="star" style="font-size: 12px;"></wa-icon>
<wa-progress-bar value="2" label="Upload progress" style="height: 6px; width: 50%"></wa-progress-bar>
<wa-format-number type="percent" value=".02"></wa-format-number>
</span>
</div>
</div>
<div>
<div>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1494790108377-be9c29b29330?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Michelle Jasper</span>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
</div>
</div>
<p>I bought this grow light for my herbs and succulents, and wow—what a difference. After just a week, my basil perked up, and new leaves started popping up. Super easy to set up and doesnt get too hot. Highly recommend for anyone growing indoors!</p>
</div>
<wa-divider></wa-divider>
<div>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1599566150163-29194dcaad36?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Doug Michaels</span>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
</div>
</div>
<p>This light really helps my plants grow during the winter months. The brightness is strong, and I love the adjustable height. The only downside is the timer—it resets if you unplug it. Otherwise, great value for the price!</p>
</div>
<wa-divider></wa-divider>
<div>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1580489944761-15a19d654956?q=80&w=2561&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Stephanie Hurst</span>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
</div>
</div>
<p>I dont get much natural light in my apartment, so this grow light has been a game-changer. Im using it for my small tomato plants and some lettuce, and theyre growing faster than expected. Plus, the light isnt too harsh on the eyes</p>
</div>
<wa-divider></wa-divider>
<div>
<div class="wa-flank">
<wa-avatar image="https://images.unsplash.com/photo-1566492031773-4f4e44671857?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<div class="wa-stack wa-gap-2xs">
<span class="wa-heading-s">Miles Rogers</span>
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
</div>
</div>
<p>Ive tried a few grow lights, and this one is my favorite. It stays cool, uses less power, and my peace lilies and spider plants are growing beautifully. I just wish it came in more color options for the stand, but performance-wise, its excellent.</p>
</div>
</div>
</div>
</div>
```
## Two Column
```html{.example}
<div class="wa-stack" style="max-width: 960px; margin: 0 auto;">
<div class="wa-flank wa-align-items-center">
<div class="wa-stack wa-align-items-center wa-gap-xs">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1607746882042-944635dfe10e?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<p>Ripley</p>
<div>
<wa-icon-button name="thumbs-up" label="I don't like this review"></wa-icon-button>
<wa-icon-button name="thumbs-down" label="I like this review"></wa-icon-button>
</div>
</div>
<div>
<wa-rating label="Rating" precision="0.5" value="5" readonly></wa-rating>
<p>I recently purchased the Modern Sofa Couch, and I couldn't be happier with my decision! The process from ordering to delivery was smooth and hassle-free</p>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-align-items-center">
<div class="wa-stack wa-align-items-center wa-gap-xs">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?q=80&w=2574&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<p>Kane</p>
<div>
<wa-icon-button name="thumbs-up" label="I don't like this review"></wa-icon-button>
<wa-icon-button name="thumbs-down" label="I like this review"></wa-icon-button>
</div>
</div>
<div>
<wa-rating label="Rating" precision="0.5" value="3.4" readonly></wa-rating>
<p>The cushions are soft yet supportive, and the sectional layout gives plenty of space to stretch out. Its perfect for movie nights or just lounging with a good book.</p>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank wa-align-items-center">
<div class="wa-stack wa-align-items-center wa-gap-xs">
<wa-avatar label="User avatar" image="https://images.unsplash.com/photo-1728577740843-5f29c7586afe?q=80&w=2680&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"></wa-avatar>
<p>Parker</p>
<div>
<wa-icon-button name="thumbs-up" label="I don't like this review"></wa-icon-button>
<wa-icon-button name="thumbs-down" label="I like this review"></wa-icon-button>
</div>
</div>
<div>
<wa-rating label="Rating" precision="0.5" value="3.8" readonly></wa-rating>
<p>The leather is high quality, but its a little firmer than I thought. That said, after sitting on it for a while, it does soften up and feels more comfortable. Its perfect if youre looking for a more structured seating experience.</p>
</div>
</div>
<wa-divider></wa-divider>
</div>
```

View File

@@ -0,0 +1,278 @@
---
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
```html {.example}
<div class="wa-stack wa-gap-2xl">
<h2>Shopping Cart</h2>
<div class="wa-grid wa-align-items-start wa-gap-2xl">
<div class="wa-stack wa-gap-xl">
<article class="wa-flank wa-gap-xl" style="--flank-size: 8rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1523381294911-8d3cead13475?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDIzNDd8&ixlib=rb-4.0.3&q=80&w=1080"
alt=""
/>
</div>
<div class="wa-flank:end wa-align-items-baseline">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Classic Tee</h3>
<span class="wa-caption-m">Sage Green</span>
<span class="wa-caption-m">Large</span>
<span>$20.00</span>
</div>
<wa-icon-button name="xmark" label="Remove" id="remove-1"></wa-icon-button>
<wa-tooltip for="remove-1">Remove</wa-tooltip>
</div>
</article>
<article class="wa-flank wa-gap-xl" style="--flank-size: 8rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1564859227552-81fde4a1df0b?q=80&w=2671&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
<div class="wa-flank:end wa-align-items-baseline">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">RVCA Graphic</h3>
<span class="wa-caption-m">White</span>
<span class="wa-caption-m">Large</span>
<span>$25.00</span>
</div>
<wa-icon-button name="xmark" label="Remove" id="remove-2"></wa-icon-button>
<wa-tooltip for="remove-2">Remove</wa-tooltip>
</div>
</article>
<article class="wa-flank wa-gap-xl" style="--flank-size: 8rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1503341733017-1901578f9f1e?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
<div class="wa-flank:end wa-align-items-baseline">
<div class="wa-stack wa-gap-xs">
<h3 class="wa-heading-s">Stay Wild Graphic</h3>
<span class="wa-caption-m">Black</span>
<span class="wa-caption-m">Large</span>
<span>$18.00</span>
</div>
<wa-icon-button name="xmark" label="Remove" id="remove-3"></wa-icon-button>
<wa-tooltip for="remove-3">Remove</wa-tooltip>
</div>
</article>
</div>
<wa-card>
<div slot="header">
<h3 class="wa-heading-m">Order Summary</h3>
</div>
<div class="wa-stack">
<div class="wa-split">
<span class="wa-caption-l">Subtotal</span>
<strong>$63.00</strong>
</div>
<wa-divider></wa-divider>
<div class="wa-split">
<span class="wa-caption-l">Shipping</span>
<strong>$5.00</strong>
</div>
<wa-divider></wa-divider>
<div class="wa-split">
<span class="wa-caption-l">Tax</span>
<strong>$5.50</strong>
</div>
<wa-divider></wa-divider>
<div class="wa-split wa-body-l">
<span>Total</span>
<strong>$73.50</strong>
</div>
<wa-button variant="brand">Checkout</wa-button>
</div>
</wa-card>
</div>
</div>
</div>
```
## Single Column
```html {.example}
<div class="wa-stack wa-gap-2xl" style="max-width: 60ch; margin: auto">
<h2>Your Cart</h2>
<wa-divider></wa-divider>
<article class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-m" style="aspect-ratio: 3 / 2">
<img
src="https://images.unsplash.com/photo-1594787317357-dcda50fd1d78?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDI4MDd8&ixlib=rb-4.0.3&q=80&w=1080"
alt=""
/>
</div>
<div class="wa-split:column wa-align-items-stretch wa-gap-xs">
<div class="wa-stack wa-gap-xs">
<span class="wa-split wa-gap-xs">
<h3 class="wa-heading-m">Convertible</h3>
<span>$32.00</span>
</span>
<wa-tag size="small" variant="neutral" appearance="filled" pill style="width: fit-content">Cherry Red</wa-tag>
</div>
<div class="wa-split">
<wa-badge appearance="filled" variant="success">In Stock</wa-badge>
<wa-button appearance="plain" size="small" variant="danger">
<wa-icon slot="suffix" name="trash"></wa-icon>
Remove
</wa-button>
</div>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-m" style="aspect-ratio: 3 / 2">
<img
src="https://images.unsplash.com/photo-1597670250484-0e9aff7f8804?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDI4NTB8&ixlib=rb-4.0.3&q=80&w=1080"
alt=""
/>
</div>
<div class="wa-split:column wa-align-items-stretch wa-gap-xs">
<div class="wa-stack wa-gap-xs">
<span class="wa-split wa-gap-xs">
<h3 class="wa-heading-m">Racers (3 Pack)</h3>
<span>$80.00</span>
</span>
<wa-tag size="small" variant="neutral" appearance="filled" pill style="width: fit-content">Assorted Colors</wa-tag>
</div>
<div class="wa-split">
<wa-badge appearance="filled" variant="success">In Stock</wa-badge>
<wa-button appearance="plain" size="small" variant="danger">
<wa-icon slot="suffix" name="trash"></wa-icon>
Remove
</wa-button>
</div>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank" style="--flank-size: 12rem">
<div class="wa-frame wa-border-radius-m" style="aspect-ratio: 3 / 2">
<img
src="https://images.unsplash.com/photo-1594787826350-19386fdb2363?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDI4ODV8&ixlib=rb-4.0.3&q=80&w=1080"
alt=""
/>
</div>
<div class="wa-split:column wa-align-items-stretch wa-gap-xs">
<div class="wa-stack wa-gap-xs">
<span class="wa-split wa-gap-xs">
<h3 class="wa-heading-m">Volkswagen T2</h3>
<span>$60.00</span>
</span>
<wa-tag size="small" variant="neutral" appearance="filled" pill style="width: fit-content">Red/White</wa-tag>
</div>
<div class="wa-split">
<wa-badge appearance="filled" variant="warning">Low Stock</wa-badge>
<wa-button appearance="plain" size="small" variant="danger">
<wa-icon slot="suffix" name="trash"></wa-icon>
Remove
</wa-button>
</div>
</div>
</article>
<wa-divider></wa-divider>
<div class="wa-stack">
<div class="wa-split">
<h3 class="wa-heading-m">Subtotal</h3>
<span class="wa-body-l">$172.00</span>
</div>
<span class="wa-caption-m">Shipping and taxes calculated at checkout</span>
<wa-button size="large" variant="brand">Checkout</wa-button>
<div class="cluster">
<span class="wa-caption-m">Not quite ready?</span>
<wa-button appearance="plain" size="small" variant="brand">
Continue Shopping
<wa-icon name="arrow-right"></wa-icon>
</wa-button>
</div>
</div>
</div>
```
## Drawer
```html {.example viewport}
<wa-drawer label="Shopping Cart" with-header with-footer open>
<div class="wa-stack">
<article class="wa-flank" style="--flank-size: 6rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1704677982224-89cd6d039fa6?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDEwOTJ8&ixlib=rb-4.0.3&q=80&w=1080"
alt=""
/>
</div>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split wa-gap-2xs">
<strong>AJ1 Low</strong>
<strong>$170.00</strong>
</div>
<span class="wa-caption-m">Multi-color</span>
<div class="wa-split wa-gap-2xs">
<span class="wa-body-s">Qty: 1</span>
<wa-button appearance="plain" size="small">Remove</wa-button>
</div>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank" style="--flank-size: 6rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1672908615254-71a0b373eaba?q=80&w=3560&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by Hamed darzi)"
/>
</div>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split wa-gap-2xs">
<strong>The Trails</strong>
<strong>$35.00</strong>
</div>
<span class="wa-caption-m">Twilight Blue</span>
<div class="wa-split wa-gap-2xs">
<span class="wa-body-s">Qty: 1</span>
<wa-button appearance="plain" size="small">Remove</wa-button>
</div>
</div>
</article>
<wa-divider></wa-divider>
<article class="wa-flank" style="--flank-size: 6rem">
<div class="wa-frame wa-border-radius-m">
<img
src="https://images.unsplash.com/photo-1693443687750-611ad77f3aba?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="(Photograph by tian dayong)"
/>
</div>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split wa-gap-2xs">
<strong>Outcast 2-pack</strong>
<strong>$27.00</strong>
</div>
<span class="wa-caption-m">Black / White</span>
<div class="wa-split wa-gap-2xs">
<span class="wa-body-s">Qty: 1</span>
<wa-button appearance="plain" size="small">Remove</wa-button>
</div>
</div>
</article>
</div>
<div slot="footer" class="wa-stack" style="width: 100%">
<div class="wa-split">
<strong>Subtotal</strong>
<strong>$232.00</strong>
</div>
<span class="wa-caption-m">Shipping and taxes calculated at checkout.</span>
<wa-button variant="brand">Checkout</wa-button>
<wa-button appearance="plain" size="small" variant="brand">
Continue Shopping
<wa-icon name="arrow-right"></wa-icon>
</wa-button>
</div>
</wa-drawer>
```

View File

@@ -0,0 +1,85 @@
---
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
```html{.example}
<wa-dropdown>
<wa-button slot="trigger" caret>Shop</wa-button>
<wa-menu class="mm-grid">
<div>
<wa-menu-label>Shop by Department</wa-menu-label>
<wa-menu-item value="apple">Mens</wa-menu-item>
<wa-menu-item value="banana">Womens</wa-menu-item>
<wa-menu-item value="orange">Kids</wa-menu-item>
<wa-menu-item value="orange">
Infants
<wa-menu slot="submenu">
<wa-menu-item value="uppercase">Newborns</wa-menu-item>
<wa-menu-item value="lowercase">6 Months</wa-menu-item>
<wa-menu-item value="capitalize">12 Months</wa-menu-item>
</wa-menu>
</wa-menu-item>
<wa-menu-item value="orange">Big & Tall</wa-menu-item>
</div>
<div>
<wa-menu-label>Shop by Category</wa-menu-label>
<wa-menu-item value="apple">Shirts</wa-menu-item>
<wa-menu-item value="banana">Pants</wa-menu-item>
<wa-menu-item value="orange">Shoes</wa-menu-item>
</div>
<div>
<wa-menu-label>Just Arrived</wa-menu-label>
<wa-menu-item>
<a href="#">
<img style="width: 100%; max-width: 200px;" src="https://images.unsplash.com/photo-1523381294911-8d3cead13475?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w1OTAyOTl8MHwxfGFsbHx8fHx8fHx8fDE3MTg2NDIzNDd8&ixlib=rb-4.0.3&q=80&w=1080" />
</a>
</wa-menu-item>
</div>
<wa-menu-item style="grid-column: 1/-1;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="margin:0;">footer with something cool in it</p>
<wa-button variant="brand" size="small">Signup now</wa-button>
</div>
</wa-menu-item>
</wa-menu>
</wa-dropdown>
<style>
.mm-grid {
display: grid;
grid-template-columns: repeat(3, auto);
gap: 1rem;
.card-overview small {
color: var(--wa-color-text-quiet);
}
.card-overview [slot='footer'] {
display: flex;
justify-content: space-between;
align-items: center;
}
}
</style>
```

View File

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

View File

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

View File

@@ -1,6 +1,28 @@
---
title: Patterns
description: Patterns are reusable solutions to common design problems.
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">
{% markdown %}
## What's a Pattern?
A pattern is a code snippet composed of components, style utilities, and native HTML that you can copy and paste into any project that uses Web Awesome.
It's a chunk of a user interface, rather than a single component, that allows you to implement UI solutions without designing something from scratch.
Patterns are designed according to proven usability practices so they're responsive, accessible, and cohesive out-of-the-box. Importantly, patterns don't handle business logic or functionality like form submissions, data processing, encryption, etc. It's up to you to implement the logic you need for your project.
Patterns are written as standard HTML, so you can use them just as you would any ol' HTML and customize them to fit your specific needs.
## Using Patterns
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.
{% endmarkdown %}
</div>

View File

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

View File

@@ -1,6 +1,8 @@
---
title: News
description: TODO
unlisted: true
isPro: true
---
TODO Page Description
@@ -156,4 +158,4 @@ TODO Page Description
}
}
</style>
```
```

View File

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

View File

@@ -0,0 +1,7 @@
.anchor-heading:has(+ wa-code-demo, + template + wa-code-demo) {
font-size: var(--wa-font-size-l);
}
wa-code-demo:has(+ .anchor-heading) {
margin-block-end: var(--wa-space-3xl);
}

View File

@@ -1,6 +1,7 @@
{
"layout": "block.njk",
"layout": "patterns.njk",
"tags": ["patterns"],
"wide": true,
"noAlpha": true
"noAlpha": true,
"isPro": true
}

View File

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

View File

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

View File

@@ -14,35 +14,54 @@ During the alpha period, things might break! We take breaking changes very serio
## Next
- Fixed the search dialog's styles so it doesn't jump around as you search
- Removed close watcher logic to backdrop hide animation bugs in `<wa-dialog>` and `<wa-drawer>`; this logic is already handled and we'll revisit `CloseWatcher` when browser support is better and behaviors are consistent
- Fixed a bug that caused dropdowns inside button groups to show with a vertical misalignment
- Revert `<wa-dialog>` structure and CSS to fix clipped content in dialogs (WA-A #123) and light dismiss in iOS Safari (WA-A #201)
- Fixed a bug in `<wa-progress>` that prevented Safari from animation progress changes
- Fixed the missing indeterminate icon in native checkbox styles
- Fixed a bug where changing a `<wa-option>` label wouldn't update the display label in `<wa-select>`
- Fixed a bug in `<wa-radio>` where elements would stack instead of display inline
- All icon libraries can now declare **pre-fetched** icons and skip the HTTP request.
When these icons are used, the pre-fetched version is automatically used, with no additional opt-in.
- 🚨 BREAKING: No more `system` library, just use `default`.
The improvement above allowed us to fold Web Awesomes own `system` icon library into the `default` library
so the performance benefits can be automatic and shared across all uses of the `default` library,
rather then requiring a conscious decision to use a different library.
This also makes WA components play better with different icon libraries and different default families and variants.
- Fixed a bug that caused an undesired margin below radio groups
- 🚨 BREAKING: Renamed `<image-comparer>` to `<wa-comparer>` and improved compatibility for non-image content
- Added support for Duotone Thin, Light, and Regular styles and the Sharp Duotone family of styles to `<wa-icon>`
- Fixed a bug that caused `<wa-radio-group>` to have an undesired margin below it
- Fixed a bug in `<wa-select>` that caused incorrect spacing of icons
- Fixed a bug in the Matter theme that prevented clicks on form control labels to not focus the control
- Fixed a bug in `<wa-radio-group>` that prevented radio buttons from validating
- Improved native radio alignment
- Improved the `.wa-cloak` utility class so all FOUCE-related solutions are 100% opt-in
## 3.0.0-alpha.12
### Enhancements
- Added `appearance` to [`<wa-details>`](/docs/components/details) and [`<wa-card>`](/docs/components/card) and support for the [appearance utilities](/docs/utilities/appearance/) in the [`<details>` native styles](/docs/native/details).
- Added an `orange` scale to all color palettes
- Added the `.wa-cloak` utility to prevent FOUCE
- Added the `allDefined()` utility for awaiting component registration
- Added default spacing to icons slotted into `<wa-tab>`
- Fixed `wa-pill` class for text fields
- Added the [`.wa-cloak` utility](/docs/utilities/fouce) to prevent FOUCE
- Added the [`allDefined()` utility](/docs/usage/#all-defined) for awaiting component registration
### Bugfixes
### Bug fixes
- Specifying inherited CSS properties on `<wa-tooltip>` now works as expected ([thanks Dennis!](https://github.com/shoelace-style/webawesome-alpha/discussions/203))
- Fixed a bug in `<wa-select>` that made it hard to use with VueJS, Svelte, and many other frameworks
- Fixed the `wa-pill` class for text fields
- Fixed `pill` style for `<wa-input>` elements
- Fixed a bug in `<wa-color-picker>` that prevented light dismiss from working when clicking immediately above the color picker dropdown
- Fixed a bug in `<wa-select multiple>` that sometimes resulted in empty `<div>` elements being output
- Fixed a bug in `<wa-radio-button>` that prevented the pill effect from applying properly
- Fixed a bug where changing a `<wa-option>` label wouldn't update the display label in `<wa-select>`
- Added default spacing to icons slotted into `<wa-tab>`
- Lots of fixes around pill-shaped elements:
- Fixed the `wa-pill` class for text fields
- Fixed `pill` style for `<wa-input>` and `<wa-radio-button>` elements
- Fixed a bug in `<wa-radio-button>` that prevented active buttons from receiving the correct styles
- Fixed a bug in `<wa-button>` that prevented the focus ring from showing in Safari
- Fixed alignment of `<wa-dropdown>` inside button groups
- Removed close watcher logic to backdrop hide animation bugs in `<wa-dialog>` and `<wa-drawer>`; this logic is already handled and we'll revisit `CloseWatcher` when browser support is better and behaviors are consistent
- Revert `<wa-dialog>` structure and CSS to fix clipped content in dialogs (WA-A #123) and light dismiss in iOS Safari (WA-A #201)
- Fixed a bug in `<wa-color-picker>` that prevented light dismiss from working when clicking immediately above the color picker dropdown
- Fixed a bug in `<wa-progress>` that prevented Safari from animation progress changes
- Fixed the missing indeterminate icon in [native checkbox styles](/docs/native/checkbox)
- Fixed a bug in `<wa-radio>` where elements would stack instead of display inline
- Docs fixes:
- Fixed the search dialog's styles so it doesn't jump around as you search
- Theme cards now have icons
## 3.0.0-alpha.11

View File

@@ -31,7 +31,7 @@ The [issue tracker](https://github.com/shoelace-style/webawesome-alpha/issues) i
- Please **do not** use the issue tracker for feature requests. Use [the discussion forum](https://github.com/shoelace-style/webawesome-alpha/discussions/categories/ideas) instead.
- Please **do not** derail, hijack, or troll issues. Keep the discussion on topic and be respectful of others.
- Please **do not** post comments with "+1" or "👍". Use [reactions](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) instead.
- Please **do** use the issue tracker for feature requests, bug reports, and pull requests.
- Please **do** use the issue tracker for bug reports and pull requests.
Issues that do not follow these guidelines are subject to closure. There simply aren't enough resources for the author and contributors to troubleshoot personal support requests.
@@ -352,13 +352,11 @@ Form controls should support submission and validation through the following con
### System Icons
Avoid inlining SVG icons inside of templates. If a component requires an icon, make sure `<wa-icon>` is a dependency of the component and use the [system library](/components/icon#customizing-the-system-library):
Avoid inlining SVG icons inside of templates.
If a component requires an icon, make sure `<wa-icon>` is a dependency of the component.
```html
<wa-icon library="system" name="..." variant="..."></wa-icon>
```
This will render the icons instantly whereas the default library will fetch them from a remote source. If an icon isn't available in the system library, you will need to add it to `library.system.ts`. Using the system library ensures that all icons load instantly and are customizable by users who wish to provide a custom resolver for the system library.
If it is not one of the [pre-fetched icons](/components/icon#fetched) in the `default` library,
you should add it. This will render the icons instantly rather than fetching them from a remote source.
### Writing tests

View File

@@ -0,0 +1,71 @@
---
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

@@ -5,4 +5,6 @@ isPro: true
tags: pro
palette: rudimentary
brand: green
fonts:
body: Inter
---

View File

@@ -4,4 +4,6 @@ description: Punchy and vibrant, the rockstar of themes.
order: 0.2
palette: bright
brand: blue
fonts:
body: Quicksand
---

View File

@@ -5,4 +5,8 @@ isPro: true
tags: pro
palette: default
brand: blue
fonts:
body: Space Grotesk
heading: IBM Plex Sans Condensed
code: Space Mono
---

View File

@@ -3,4 +3,5 @@ title: Classic
description: Timeless elegance that never goes out of style.
order: 0.1
palette: classic
brand: blue
---

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