mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Merge branch 'kj/layout-patterns' of github.com:shoelace-style/webawesome into kj/layout-patterns
This commit is contained in:
@@ -15,16 +15,19 @@
|
||||
"autoloading",
|
||||
"autoplay",
|
||||
"bezier",
|
||||
"Blockquotes",
|
||||
"boxicons",
|
||||
"CACHEABLE",
|
||||
"callout",
|
||||
"callouts",
|
||||
"canvastext",
|
||||
"chatbubble",
|
||||
"checkmark",
|
||||
"Clippy",
|
||||
"codebases",
|
||||
"codepen",
|
||||
"colocated",
|
||||
"colorjs",
|
||||
"colour",
|
||||
"combobox",
|
||||
"Commonmark",
|
||||
@@ -131,6 +134,7 @@
|
||||
"petabit",
|
||||
"Preact",
|
||||
"preconnect",
|
||||
"prerendered",
|
||||
"prismjs",
|
||||
"progressbar",
|
||||
"radiogroup",
|
||||
|
||||
@@ -48,8 +48,6 @@
|
||||
{% endif %}
|
||||
|
||||
<link rel="stylesheet" href="/dist/styles/webawesome.css" />
|
||||
<link id="color-stylesheet" rel="stylesheet" href="/dist/styles/utilities.css" />
|
||||
<link rel="stylesheet" href="/dist/styles/forms.css" />
|
||||
|
||||
{# Used by Web Awesome App to inject other assets into the head. #}
|
||||
{% server "head" %}
|
||||
|
||||
@@ -145,7 +145,6 @@
|
||||
<a href="/docs/components/radio-group/">Radio Group</a>
|
||||
<ul>
|
||||
<li><a href="/docs/components/radio/">Radio</a></li>
|
||||
<li><a href="/docs/components/radio-button/">Radio Button</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/docs/components/rating/">Rating</a></li>
|
||||
@@ -178,35 +177,6 @@
|
||||
</ul>
|
||||
</wa-details>
|
||||
|
||||
<!-- Native styles -->
|
||||
<wa-details appearance="outlined">
|
||||
<h2 slot="summary">
|
||||
<a href="/docs/native/" title="Overview">
|
||||
Native Styles
|
||||
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
|
||||
</a>
|
||||
</h2>
|
||||
<ul>
|
||||
<li><a href="/docs/native/button/">Button</a></li>
|
||||
<li><a href="/docs/native/callout/">Callout</a></li>
|
||||
<li><a href="/docs/native/checkbox/">Checkbox</a></li>
|
||||
<li><a href="/docs/native/content/">Content</a></li>
|
||||
<li><a href="/docs/native/details/">Details</a></li>
|
||||
<li><a href="/docs/native/dialog/">Dialog</a></li>
|
||||
<li><a href="/docs/native/input/">Input</a></li>
|
||||
<li><a href="/docs/native/lists/">Lists</a></li>
|
||||
<li>
|
||||
<a href="/docs/native/progress/">Progress Bar</a>
|
||||
<wa-icon name="flask" aria-hidden="true"></wa-icon>
|
||||
</li>
|
||||
<li><a href="/docs/native/radio/">Radio</a></li>
|
||||
<li><a href="/docs/native/select/">Select</a></li>
|
||||
<li><a href="/docs/native/slider/">Slider</a></li>
|
||||
<li><a href="/docs/native/table/">Table</a></li>
|
||||
<li><a href="/docs/native/textarea/">Textarea</a></li>
|
||||
</ul>
|
||||
</wa-details>
|
||||
|
||||
<!-- Style utilities -->
|
||||
<wa-details appearance="outlined">
|
||||
<h2 slot="summary">
|
||||
@@ -216,14 +186,10 @@
|
||||
</a>
|
||||
</h2>
|
||||
<ul>
|
||||
<li><a href="/docs/utilities/appearance/">Appearance</a></li>
|
||||
<li><a href="/docs/utilities/native/">Native Styles</a></li>
|
||||
<li><a href="/docs/utilities/color/">Color</a></li>
|
||||
<li><a href="/docs/utilities/fouce/">Reduce FOUCE</a></li>
|
||||
<li><a href="/docs/utilities/fouce/">Reducing FOUCE</a></li>
|
||||
<li><a href="/docs/utilities/rounding/">Rounding</a></li>
|
||||
<li>
|
||||
<a href="/docs/utilities/size/">Size</a>
|
||||
<wa-icon name="flask" aria-hidden="true"></wa-icon>
|
||||
</li>
|
||||
<li><a href="/docs/utilities/text/">Text</a></li>
|
||||
<li><a href="/docs/utilities/visually-hidden/">Visually Hidden</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
{% endif -%}
|
||||
|
||||
{%- if status %}
|
||||
{%- if status == "wip" %}
|
||||
<wa-badge variant="danger">
|
||||
<wa-icon name="pickaxe"></wa-icon>
|
||||
Work In Progress
|
||||
</wa-badge>
|
||||
{%- elif status == "experimental" %}
|
||||
{%- if status == "experimental" %}
|
||||
<wa-badge variant="warning">
|
||||
<wa-icon name="flask"></wa-icon>
|
||||
Experimental
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<th></th>
|
||||
<th><code><wa-button></code></th>
|
||||
<th><code><button></code></th>
|
||||
<th><code>.wa-button</code></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -17,306 +16,168 @@
|
||||
<td>
|
||||
<button>Button</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>accent</code> + <code>outlined</code></th>
|
||||
<td>
|
||||
<div class="wa-button">Button</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="accent outlined">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="accent outlined">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="accent outlined">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="accent outlined">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="accent outlined">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-accent wa-outlined">Brand</button>
|
||||
<button class="wa-neutral wa-accent wa-outlined">Neutral</button>
|
||||
<button class="wa-success wa-accent wa-outlined">Success</button>
|
||||
<button class="wa-warning wa-accent wa-outlined">Warning</button>
|
||||
<button class="wa-danger wa-accent wa-outlined">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-brand</code></th>
|
||||
<th><code>accent</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-brand">Brand</wa-button>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="accent">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="accent">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="accent">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="accent">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="accent">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-brand">Brand</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-brand">Brand</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-accent">Brand</button>
|
||||
<button class="wa-neutral wa-accent">Neutral</button>
|
||||
<button class="wa-success wa-accent">Success</button>
|
||||
<button class="wa-warning wa-accent">Warning</button>
|
||||
<button class="wa-danger wa-accent">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-neutral</code></th>
|
||||
<th><code>filled</code> + <code>outlined</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-neutral">Neutral</wa-button>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="filled outlined">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="filled outlined">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="filled outlined">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="filled outlined">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="filled outlined">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-neutral">Neutral</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-neutral">Neutral</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-filled wa-outlined">Brand</button>
|
||||
<button class="wa-neutral wa-filled wa-outlined">Neutral</button>
|
||||
<button class="wa-success wa-filled wa-outlined">Success</button>
|
||||
<button class="wa-warning wa-filled wa-outlined">Warning</button>
|
||||
<button class="wa-danger wa-filled wa-outlined">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-success</code></th>
|
||||
<th><code>filled</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-success">Success</wa-button>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="filled">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="filled">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="filled">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="filled">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="filled">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-success">Success</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-success">Success</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-filled">Brand</button>
|
||||
<button class="wa-neutral wa-filled">Neutral</button>
|
||||
<button class="wa-success wa-filled">Success</button>
|
||||
<button class="wa-warning wa-filled">Warning</button>
|
||||
<button class="wa-danger wa-filled">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-warning</code></th>
|
||||
<th><code>outlined</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-warning">Warning</wa-button>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="outlined">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="outlined">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="outlined">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="outlined">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="outlined">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-warning">Warning</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-warning">Warning</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-outlined">Brand</button>
|
||||
<button class="wa-neutral wa-outlined">Neutral</button>
|
||||
<button class="wa-success wa-outlined">Success</button>
|
||||
<button class="wa-warning wa-outlined">Warning</button>
|
||||
<button class="wa-danger wa-outlined">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-danger</code></th>
|
||||
<th><code>plain</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-danger">Danger</wa-button>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<wa-button variant="brand" appearance="plain">Brand</wa-button>
|
||||
<wa-button variant="neutral" appearance="plain">Neutral</wa-button>
|
||||
<wa-button variant="success" appearance="plain">Success</wa-button>
|
||||
<wa-button variant="warning" appearance="plain">Warning</wa-button>
|
||||
<wa-button variant="danger" appearance="plain">Danger</wa-button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-danger">Danger</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-danger">Danger</div>
|
||||
<div class="wa-cluster wa-gap-2xs">
|
||||
<button class="wa-brand wa-plain">Brand</button>
|
||||
<button class="wa-neutral wa-plain">Neutral</button>
|
||||
<button class="wa-success wa-plain">Success</button>
|
||||
<button class="wa-warning wa-plain">Warning</button>
|
||||
<button class="wa-danger wa-plain">Danger</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-accent</code></th>
|
||||
<th><code>small</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-accent">Accent</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-accent">Accent</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-accent">Accent</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-filled</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-filled">Filled</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-filled">Filled</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-filled">Filled</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-outlined</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-outlined">Outlined</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-outlined">Outlined</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-outlined">Outlined</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-plain</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-plain">Plain</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-plain">Plain</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-plain">Plain</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-s</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-size-s">Small</wa-button>
|
||||
<wa-button size="small">Small</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-size-s">Small</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-size-s">Small</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-m</code></th>
|
||||
<th><code>medium</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-size-m">Medium</wa-button>
|
||||
<wa-button size="medium">Medium</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-size-m">Medium</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-size-m">Medium</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-l</code></th>
|
||||
<th><code>large</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-size-l">Large</wa-button>
|
||||
<wa-button size="large">Large</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-size-l">Large</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-size-l">Large</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-pill</code></th>
|
||||
<th><code>pill</code></th>
|
||||
<td>
|
||||
<wa-button class="wa-pill">Pill</wa-button>
|
||||
<wa-button pill>Pill</wa-button>
|
||||
</td>
|
||||
<td>
|
||||
<button class="wa-pill">Pill</button>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-button wa-pill">Pill</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3>Callout</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
<table>
|
||||
<thead>
|
||||
<th></th>
|
||||
<th><code><wa-callout></code></th>
|
||||
<th><code>.wa-callout</code></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="test-failure"><em>default</em></th>
|
||||
<td>
|
||||
<wa-callout>Callout</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout">Callout</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-brand</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-brand">Brand</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-brand">Brand</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-neutral</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-neutral">Neutral</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-neutral">Neutral</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-success</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-success">Success</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-success">Success</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-warning</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-warning">Warning</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-warning">Warning</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-danger</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-danger">Danger</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-danger">Danger</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-accent</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-accent">Accent</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-accent">Accent</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-filled</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-filled">Filled</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-filled">Filled</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-outlined</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-outlined">Outlined</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-outlined">Outlined</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-plain</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-plain">Plain</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-plain">Plain</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-s</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-size-s">Small</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-size-s">Small</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-m</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-size-m">Medium</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-size-m">Medium</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-l</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-size-l">Large</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-size-l">Large</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-pill</code></th>
|
||||
<td>
|
||||
<wa-callout class="wa-pill">Pill</wa-callout>
|
||||
</td>
|
||||
<td>
|
||||
<div class="wa-callout wa-pill">Pill</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -425,7 +286,7 @@
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3 class="test-failure">Input</h3>
|
||||
<h3>Input</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
<table>
|
||||
@@ -472,36 +333,36 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-filled</code></th>
|
||||
<th><code>filled</code></th>
|
||||
<td>
|
||||
<wa-input label="Input (filled)" placeholder="Placeholder" class="wa-filled"></wa-input>
|
||||
<wa-input label="Input (filled)" placeholder="Placeholder" appearance="filled"></wa-input>
|
||||
</td>
|
||||
<td>
|
||||
<label>Input (filled) <input type="text" placeholder="Placeholder" class="wa-filled"></input></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-s</code></th>
|
||||
<th><code>small</code></th>
|
||||
<td>
|
||||
<wa-input label="Input (small)" placeholder="Placeholder" class="wa-size-s"></wa-input>
|
||||
<wa-input label="Input (small)" placeholder="Placeholder" size="small"></wa-input>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-s">Input (small) <input type="text" placeholder="Placeholder"></input></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-m</code></th>
|
||||
<th><code>medium</code></th>
|
||||
<td>
|
||||
<wa-input label="Input (medium)" placeholder="Placeholder" class="wa-size-m"></wa-input>
|
||||
<wa-input label="Input (medium)" placeholder="Placeholder" size="medium"></wa-input>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-m">Input (medium) <input type="text" placeholder="Placeholder"></input></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-l</code></th>
|
||||
<th><code>large</code></th>
|
||||
<td>
|
||||
<wa-input label="Input (large)" placeholder="Placeholder" class="wa-size-l"></wa-input>
|
||||
<wa-input label="Input (large)" placeholder="Placeholder" size="large"></wa-input>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-l">Input (large) <input type="text" placeholder="Placeholder"></input></label>
|
||||
@@ -597,9 +458,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-filled</code></th>
|
||||
<th><code>filled</code></th>
|
||||
<td>
|
||||
<wa-select label="Select (filled)" value="1" class="wa-filled">
|
||||
<wa-select label="Select (filled)" value="1" appearance="filled">
|
||||
<wa-option value="1">Option</wa-option>
|
||||
</wa-select>
|
||||
</td>
|
||||
@@ -612,9 +473,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-s</code></th>
|
||||
<th><code>small</code></th>
|
||||
<td>
|
||||
<wa-select label="Select (small)" value="1" class="wa-size-s">
|
||||
<wa-select label="Select (small)" value="1" size="small">
|
||||
<wa-option value="1">Option</wa-option>
|
||||
</wa-select>
|
||||
</td>
|
||||
@@ -627,9 +488,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-m</code></th>
|
||||
<th><code>medium</code></th>
|
||||
<td>
|
||||
<wa-select label="Select (medium)" value="1" class="wa-size-m">
|
||||
<wa-select label="Select (medium)" value="1" size="medium">
|
||||
<wa-option value="1">Option</wa-option>
|
||||
</wa-select>
|
||||
</td>
|
||||
@@ -642,9 +503,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-l</code></th>
|
||||
<th><code>large</code></th>
|
||||
<td>
|
||||
<wa-select label="Select (large)" value="1" class="wa-size-l">
|
||||
<wa-select label="Select (large)" value="1" size="large">
|
||||
<wa-option value="1">Option</wa-option>
|
||||
</wa-select>
|
||||
</td>
|
||||
@@ -661,7 +522,7 @@
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3 class="test-failure">Slider</h3>
|
||||
<h3>Slider</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
<table>
|
||||
@@ -685,7 +546,7 @@
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3 class="test-failure">Textarea</h3>
|
||||
<h3>Textarea</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
<table>
|
||||
@@ -705,36 +566,36 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-filled</code></th>
|
||||
<th><code>filled</code></th>
|
||||
<td>
|
||||
<wa-textarea label="Textarea (filled)" placeholder="Placeholder" class="wa-filled" rows="2"></wa-textarea>
|
||||
<wa-textarea label="Textarea (filled)" placeholder="Placeholder" appearance="filled" rows="2"></wa-textarea>
|
||||
</td>
|
||||
<td>
|
||||
<label>Textarea (filled) <textarea placeholder="Placeholder" class="wa-filled" rows="2"></textarea></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-s</code></th>
|
||||
<th><code>small</code></th>
|
||||
<td>
|
||||
<wa-textarea label="Textarea (small)" placeholder="Placeholder" class="wa-size-s" rows="2"></wa-textarea>
|
||||
<wa-textarea label="Textarea (small)" placeholder="Placeholder" size="small" rows="2"></wa-textarea>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-s">Textarea (small) <textarea placeholder="Placeholder" rows="2"></textarea></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-m</code></th>
|
||||
<th><code>medium</code></th>
|
||||
<td>
|
||||
<wa-textarea label="Textarea (medium)" placeholder="Placeholder" class="wa-size-m" rows="2"></wa-textarea>
|
||||
<wa-textarea label="Textarea (medium)" placeholder="Placeholder" size="medium" rows="2"></wa-textarea>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-m">Textarea (medium) <textarea placeholder="Placeholder" rows="2"></textarea></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>.wa-size-l</code></th>
|
||||
<th><code>large</code></th>
|
||||
<td>
|
||||
<wa-textarea label="Textarea (large)" placeholder="Placeholder" class="wa-size-l" rows="2"></wa-textarea>
|
||||
<wa-textarea label="Textarea (large)" placeholder="Placeholder" size="large" rows="2"></wa-textarea>
|
||||
</td>
|
||||
<td>
|
||||
<label class="wa-size-l">Textarea (large) <textarea placeholder="Placeholder" rows="2"></textarea></label>
|
||||
|
||||
@@ -160,60 +160,6 @@
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3>Card</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
<table>
|
||||
<thead>
|
||||
<th></th>
|
||||
<th><code>size=""</code></th>
|
||||
<th><code>.wa-size-[s|m|l]</code></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><code>small</code>/<code>s</code></th>
|
||||
<td>
|
||||
<wa-card size="small">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
<td>
|
||||
<wa-card class="wa-size-s">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>medium</code>/<code>m</code></th>
|
||||
<td>
|
||||
<wa-card size="medium">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
<td>
|
||||
<wa-card class="wa-size-m">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code>large</code>/<code>l</code></th>
|
||||
<td>
|
||||
<wa-card size="large">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
<td>
|
||||
<wa-card class="wa-size-l">
|
||||
Card
|
||||
</wa-card>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<h3>Checkbox</h3>
|
||||
|
||||
<div class="table-scroll">
|
||||
@@ -534,14 +480,14 @@
|
||||
<th><code>small</code>/<code>s</code></th>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button size="small" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button size="small" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" size="small" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" size="small" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button class="wa-size-s" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button class="wa-size-s" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" class="wa-size-s" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" class="wa-size-s" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -549,14 +495,14 @@
|
||||
<th><code>medium</code>/<code>m</code></th>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button size="medium" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button size="medium" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" size="medium" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" size="medium" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button class="wa-size-m" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button class="wa-size-m" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" class="wa-size-m" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" class="wa-size-m" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -564,14 +510,14 @@
|
||||
<th><code>large</code>/<code>l</code></th>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button size="large" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button size="large" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" size="large" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" size="large" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
<td>
|
||||
<wa-radio-group orientation="horizontal">
|
||||
<wa-radio-button class="wa-size-l" value="1">Radio</wa-radio-button>
|
||||
<wa-radio-button class="wa-size-l" value="2">Button</wa-radio-button>
|
||||
<wa-radio appearance="button" class="wa-size-l" value="1">Radio</wa-radio>
|
||||
<wa-radio appearance="button" class="wa-size-l" value="2">Button</wa-radio>
|
||||
</wa-radio-group>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -599,8 +545,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" size="small">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
@@ -611,8 +557,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" class="wa-size-s">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
@@ -626,8 +572,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" size="medium">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
@@ -638,8 +584,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" class="wa-size-m">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
@@ -653,8 +599,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" size="large">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
@@ -665,8 +611,8 @@
|
||||
<wa-radio value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-radio-group orientation="horizontal" label="Radio Button Group" hint="Hint" class="wa-size-l">
|
||||
<wa-radio-button value="1">Radio 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Radio 2</wa-radio-button>
|
||||
<wa-radio appearance="button" value="1">Radio 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Radio 2</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
{% extends '../_layouts/block.njk' %}
|
||||
{% set component = components[page.fileSlug] %}
|
||||
|
||||
{# Component header #}
|
||||
{% block notes %}
|
||||
{% if native %}
|
||||
<wa-callout variant="success">
|
||||
<wa-icon slot="icon" name="lightbulb" variant="regular"></wa-icon>
|
||||
Just want the styles?
|
||||
Check out the <a href="/docs/native/{{ native }}/">{{ ('/docs/native/' + native + '/') | getTitleFromUrl }} native styles</a>!
|
||||
</wa-callout>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{# Component API #}
|
||||
{% block afterContent %}
|
||||
{# Slots #}
|
||||
|
||||
@@ -40,24 +40,6 @@ export const themeConfig = {
|
||||
return this.base;
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
library: {
|
||||
cssProperty: '--wa-icon-library',
|
||||
default: 'default',
|
||||
},
|
||||
family: {
|
||||
cssProperty: '--wa-icon-family',
|
||||
default(baseTheme) {
|
||||
return baseTheme?.icon?.family ?? 'classic';
|
||||
},
|
||||
},
|
||||
style: {
|
||||
cssProperty: '--wa-icon-variant',
|
||||
default(baseTheme) {
|
||||
return baseTheme?.icon?.style ?? 'solid';
|
||||
},
|
||||
},
|
||||
},
|
||||
rounding: {
|
||||
cssProperty: '--wa-border-radius-scale',
|
||||
default(baseTheme) {
|
||||
|
||||
@@ -4,14 +4,7 @@ const lunr = res[0].default;
|
||||
const searchData = await res[1].json();
|
||||
const searchIndex = lunr.Index.load(searchData.searchIndex);
|
||||
const map = searchData.map;
|
||||
const searchDebounce = 100;
|
||||
const icons = {
|
||||
component: 'puzzle-piece',
|
||||
document: 'file',
|
||||
home: 'house',
|
||||
native: 'code',
|
||||
theme: 'palette',
|
||||
};
|
||||
const searchDebounce = 200;
|
||||
let searchTimeout;
|
||||
|
||||
// We're using Turbo, so references to these elements aren't guaranteed to remain intact
|
||||
@@ -26,8 +19,12 @@ function getElements() {
|
||||
// Show the search dialog when slash (or CMD+K) is pressed and focus is not inside a form element
|
||||
document.addEventListener('keydown', event => {
|
||||
if (
|
||||
(event.key === '/' || (event.key === 'k' && (event.metaKey || event.ctrlKey))) &&
|
||||
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
|
||||
(event.key === 'k' && (event.metaKey || event.ctrlKey)) ||
|
||||
(event.key === '/' &&
|
||||
!event.composedPath().some(el => {
|
||||
const tag = el?.tagName?.toLowerCase();
|
||||
return tag === 'textarea' || (tag === 'input' && !['checkbox', 'radio'].includes(el.type));
|
||||
}))
|
||||
) {
|
||||
event.preventDefault();
|
||||
show();
|
||||
@@ -48,7 +45,7 @@ function show() {
|
||||
input.addEventListener('input', handleInput);
|
||||
results.addEventListener('click', handleSelection);
|
||||
dialog.addEventListener('keydown', handleKeyDown);
|
||||
dialog.addEventListener('wa-hide', hide, { once: true });
|
||||
dialog.addEventListener('wa-hide', handleClose);
|
||||
dialog.open = true;
|
||||
}
|
||||
|
||||
@@ -58,9 +55,17 @@ function hide() {
|
||||
input.removeEventListener('input', handleInput);
|
||||
results.removeEventListener('click', handleSelection);
|
||||
dialog.removeEventListener('keydown', handleKeyDown);
|
||||
dialog.removeEventListener('wa-hide', handleClose);
|
||||
dialog.open = false;
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
const { input } = getElements();
|
||||
|
||||
input.value = '';
|
||||
updateResults();
|
||||
}
|
||||
|
||||
function handleInput() {
|
||||
const { input } = getElements();
|
||||
|
||||
@@ -68,14 +73,6 @@ function handleInput() {
|
||||
searchTimeout = setTimeout(() => updateResults(input.value), searchDebounce);
|
||||
}
|
||||
|
||||
function handleClear() {
|
||||
const { input } = getElements();
|
||||
|
||||
input.value = '';
|
||||
input.focus();
|
||||
updateResults();
|
||||
}
|
||||
|
||||
function handleKeyDown(event) {
|
||||
const { input, results } = getElements();
|
||||
|
||||
@@ -129,7 +126,12 @@ function handleSelection(event) {
|
||||
if (link) {
|
||||
event.preventDefault();
|
||||
hide();
|
||||
location.href = link.href;
|
||||
|
||||
if (window.Turbo) {
|
||||
Turbo.visit(link.href);
|
||||
} else {
|
||||
location.href = link.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,11 +141,40 @@ async function updateResults(query = '') {
|
||||
|
||||
try {
|
||||
const hasQuery = query.length > 0;
|
||||
const searchTokens = query
|
||||
.split(' ')
|
||||
.map((term, index, arr) => `${term}${index === arr.length - 1 ? `* ${term}~1` : '~1'}`)
|
||||
.join(' ');
|
||||
const matches = hasQuery ? searchIndex.search(`${query} ${searchTokens}`) : [];
|
||||
let matches = [];
|
||||
|
||||
if (hasQuery) {
|
||||
// Track seen refs to avoid duplicates
|
||||
const seenRefs = new Set();
|
||||
|
||||
// Start with a standard search to get the best "exact match" result
|
||||
searchIndex.search(`${query}`).forEach(match => {
|
||||
matches.push(match);
|
||||
seenRefs.add(match.ref);
|
||||
});
|
||||
|
||||
// Add wildcard matches if not already included
|
||||
searchIndex.search(`${query}*`).forEach(match => {
|
||||
if (!seenRefs.has(match.ref)) {
|
||||
matches.push(match);
|
||||
seenRefs.add(match.ref);
|
||||
}
|
||||
});
|
||||
|
||||
// Add fuzzy search matches last
|
||||
const fuzzyTokens = query
|
||||
.split(' ')
|
||||
.map(term => `${term}~1`)
|
||||
.join(' ');
|
||||
|
||||
searchIndex.search(fuzzyTokens).forEach(match => {
|
||||
if (!seenRefs.has(match.ref)) {
|
||||
matches.push(match);
|
||||
seenRefs.add(match.ref);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const hasResults = hasQuery && matches.length > 0;
|
||||
|
||||
dialog.classList.toggle('has-results', hasQuery && hasResults);
|
||||
@@ -159,17 +190,17 @@ async function updateResults(query = '') {
|
||||
const displayTitle = page.title ?? '';
|
||||
const displayDescription = page.description ?? '';
|
||||
const displayUrl = page.url.replace(/^\//, '');
|
||||
let icon = icons.document;
|
||||
let icon = 'file-text';
|
||||
|
||||
li.classList.add('site-search-result');
|
||||
li.setAttribute('role', 'option');
|
||||
li.setAttribute('id', `search-result-item-${match.ref}`);
|
||||
li.setAttribute('data-selected', index === 0 ? 'true' : 'false');
|
||||
|
||||
if (page.url === '/') icon = icons.home;
|
||||
if (page.url.startsWith('/docs/native')) icon = icons.native;
|
||||
if (page.url.startsWith('/docs/components')) icon = icons.component;
|
||||
if (page.url.startsWith('/docs/theme') || page.url.startsWith('/docs/restyle')) icon = icons.theme;
|
||||
if (page.url === '/') icon = 'home';
|
||||
if (page.url.startsWith('/docs/utilities/native')) icon = 'code';
|
||||
if (page.url.startsWith('/docs/components')) icon = 'puzzle-piece';
|
||||
if (page.url.startsWith('/docs/theme') || page.url.startsWith('/docs/restyle')) icon = 'palette';
|
||||
|
||||
a.href = page.url;
|
||||
a.innerHTML = `
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
export function capitalize(str) {
|
||||
str += '';
|
||||
return str[0].toUpperCase() + str.slice(1);
|
||||
return str[0]?.toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,7 @@ export function slugify(str) {
|
||||
* @returns {string} The camel case string.
|
||||
*/
|
||||
export function camelCase(str) {
|
||||
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
||||
return str.replace(/-([a-z])/g, (_, letter) => letter?.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,5 +38,5 @@ export function camelCase(str) {
|
||||
* @returns {string} The kebab case string.
|
||||
*/
|
||||
export function kebabCase(str) {
|
||||
return str.replace(/([A-Z])/g, '-$1').toLowerCase();
|
||||
return str.replace(/([A-Z])/g, '-$1')?.toLowerCase();
|
||||
}
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
padding: 2rem 3.25rem 2rem 2rem;
|
||||
min-width: 20rem;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
> :first-child {
|
||||
> :first-child:not(dialog) {
|
||||
margin-block-start: 0;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
> :last-child:not(dialog) {
|
||||
margin-block-end: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +93,18 @@ wa-page > header {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2:not(:first-child),
|
||||
wa-details:not(:first-child) {
|
||||
h2:not(:first-child) {
|
||||
margin-block-start: var(--wa-space-xs);
|
||||
}
|
||||
|
||||
wa-details {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
--spacing: var(--wa-space-xs);
|
||||
|
||||
&::part(base) {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -302,6 +305,13 @@ h1.title {
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
/* Show URLs for printed links */
|
||||
a:not(.anchor-heading)[href]::after {
|
||||
content: ' (' attr(href) ')';
|
||||
}
|
||||
}
|
||||
|
||||
/* Callouts */
|
||||
.callout {
|
||||
display: flex;
|
||||
@@ -416,146 +426,6 @@ wa-card .page-name {
|
||||
margin-block-start: var(--wa-space-2xl);
|
||||
}
|
||||
|
||||
/* Interactive cards */
|
||||
wa-card[role='button'][tabindex='0'],
|
||||
button,
|
||||
a[href],
|
||||
wa-option,
|
||||
wa-radio,
|
||||
wa-checkbox {
|
||||
/* Disabled state */
|
||||
&:is(:disabled, [disabled], [aria-disabled='true']) {
|
||||
&:is(wa-card, :has(> wa-card)) {
|
||||
opacity: 60%;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(:not(:disabled, [disabled], [aria-disabled='true'])) {
|
||||
&:has(> wa-card) {
|
||||
/* Parents only (not interactive <wa-card>) */
|
||||
margin: calc(var(--wa-border-width-m) + 1px);
|
||||
padding: 0;
|
||||
|
||||
/* Hover state */
|
||||
&:hover,
|
||||
&:state(hover),
|
||||
&:state(current) {
|
||||
/* Do not change the parent background as a hover effect (we style the card instead) */
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
&::part(control),
|
||||
&:is(wa-option)::part(checked-icon) {
|
||||
--background-color-checked: var(--wa-color-brand-fill-loud);
|
||||
--checked-icon-scale: 0.5;
|
||||
--offset: var(--wa-space-2xs);
|
||||
|
||||
position: absolute;
|
||||
inset: calc(var(--offset) + var(--wa-border-width-m));
|
||||
inset-block-end: auto;
|
||||
inset-inline-start: auto;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
background: var(--wa-color-brand-fill-loud);
|
||||
color: var(--wa-color-brand-on-loud);
|
||||
}
|
||||
|
||||
&::part(checked-icon) {
|
||||
color: var(--wa-color-brand-on-loud);
|
||||
}
|
||||
|
||||
&:is(wa-option)::part(checked-icon) {
|
||||
inset-block-start: calc(var(--wa-space-smaller) - 0.5em);
|
||||
inset-inline-end: calc(var(--wa-space-smaller) - 0.5em);
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
line-height: 1em;
|
||||
padding: 0.4em;
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
text-align: center;
|
||||
font-size: var(--wa-font-size-xs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hover state */
|
||||
&:hover,
|
||||
&:state(hover),
|
||||
&:state(current) {
|
||||
&:is(wa-card),
|
||||
> wa-card {
|
||||
--border-color: var(--wa-color-brand-border-loud);
|
||||
border-color: var(--border-color);
|
||||
box-shadow: 0 0 0 var(--wa-border-width-s) var(--border-color);
|
||||
}
|
||||
}
|
||||
|
||||
&:is(wa-card, :has(> wa-card)) {
|
||||
/* Interactive card parent */
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
/* Unselected state */
|
||||
&:where(:not(:state(checked), :state(selected), [aria-checked='true'], [aria-selected='true'])) {
|
||||
&::part(checked-icon),
|
||||
&::part(control) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:is(wa-card),
|
||||
> wa-card {
|
||||
/* The card itself */
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Selected cards */
|
||||
:state(selected),
|
||||
:state(checked),
|
||||
[aria-checked='true'],
|
||||
[aria-selected='true'] {
|
||||
&:is(wa-card, :has(> wa-card)) {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:is(wa-card),
|
||||
> wa-card {
|
||||
--border-color: var(--wa-color-brand-border-loud);
|
||||
box-shadow: 0 0 0 var(--wa-border-width-m) var(--border-color);
|
||||
|
||||
&::part(body) {
|
||||
background: var(--wa-color-brand-fill-quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wa-select:has(> wa-option > wa-card) {
|
||||
&::part(listbox) {
|
||||
--column-width: 1fr;
|
||||
--columns: 1;
|
||||
--gap: var(--wa-space-smaller);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(var(--column-width), 1fr));
|
||||
width: calc(var(--columns) * var(--column-width) + (var(--columns) - 1) * var(--gap) + 2 * var(--wa-space));
|
||||
max-width: var(--auto-size-available-width, 90vw);
|
||||
gap: var(--gap);
|
||||
padding: var(--wa-space-smaller) var(--wa-space);
|
||||
}
|
||||
|
||||
> wa-option > wa-card {
|
||||
--spacing: var(--wa-space-s);
|
||||
}
|
||||
}
|
||||
|
||||
wa-radio:has(> wa-card) {
|
||||
grid-template-columns: 1fr;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Swatches */
|
||||
.swatch {
|
||||
position: relative;
|
||||
|
||||
@@ -71,7 +71,8 @@ html.wa-theme-tailspin .preview-container {
|
||||
.hero {
|
||||
--hero-background-color: var(--wa-color-surface-default);
|
||||
--hero-lines-color: color-mix(in oklab, var(--wa-color-neutral-fill-normal), transparent 30%);
|
||||
background: linear-gradient(to top, var(--wa-color-surface-lowered), transparent 40%),
|
||||
background:
|
||||
linear-gradient(to top, var(--wa-color-surface-lowered), transparent 40%),
|
||||
radial-gradient(circle at 10% 70%, color-mix(in oklab, var(--wa-color-red-50) 16%, transparent), transparent 30%),
|
||||
radial-gradient(
|
||||
circle at 40% 50%,
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
.swatch-select {
|
||||
padding: 2px;
|
||||
|
||||
wa-radio-button {
|
||||
wa-radio {
|
||||
--swatch-border-color: color-mix(in oklab, canvastext, transparent 80%);
|
||||
|
||||
&::part(base) {
|
||||
@@ -93,7 +93,7 @@
|
||||
--border-radius: var(--wa-border-radius-circle);
|
||||
}
|
||||
|
||||
wa-radio-button:is([checked], :state(checked)) {
|
||||
wa-radio:is([checked], :state(checked)) {
|
||||
--swatch-border-color: var(--wa-color-surface-default);
|
||||
&::part(base) {
|
||||
box-shadow:
|
||||
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
let value = this.computed[key];
|
||||
|
||||
if (key === 'library') {
|
||||
titles[key] = iconLibraries[value].title;
|
||||
titles[key] = iconLibraries[value]?.title;
|
||||
}
|
||||
|
||||
titles[key] ??= capitalize(value);
|
||||
@@ -113,6 +113,7 @@ export default {
|
||||
if (vary.length > 0) {
|
||||
for (let param of vary) {
|
||||
let allValues = library[param];
|
||||
if (!allValues) return;
|
||||
let random = (allValues.random ??= []);
|
||||
|
||||
while (random.length < TOTAL_ICONS) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import InfoTip from './info-tip.js';
|
||||
const template = `
|
||||
<wa-radio-group :label class="swatch-select" :class="'swatch-shape-' + shape" orientation="horizontal" :value @input="handleInput">
|
||||
<info-tip v-for="value in values">
|
||||
<wa-radio-button :value :label="getLabel(value)" :style="{'--color': getColor(value)}"></wa-radio-button>
|
||||
<wa-radio appearance="button" :value :label="getLabel(value)" :style="{'--color': getColor(value)}"></wa-radio>
|
||||
<template #content>
|
||||
{{ getLabel(value) }}
|
||||
</template>
|
||||
|
||||
@@ -55,7 +55,7 @@ it is rarely a good idea to mix sizes within the same button group.
|
||||
Set the `orientation` attribute to `vertical` to make a vertical button group.
|
||||
|
||||
```html {.example}
|
||||
<wa-button-group orientation="vertical" label="Options" style="max-width: 80px;">
|
||||
<wa-button-group orientation="vertical" label="Options" style="max-width: 120px;">
|
||||
<wa-button>
|
||||
<wa-icon slot="prefix" name="plus"></wa-icon>
|
||||
New
|
||||
@@ -157,16 +157,13 @@ Pill buttons are supported through the button's `pill` attribute.
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
### Dropdowns and Native Buttons in Button Groups
|
||||
### Dropdowns in Button Groups
|
||||
|
||||
Other elements can also be placed inside button groups:
|
||||
- Native buttons as long as their [native styles](/docs/native/button) are included
|
||||
- Dropdowns as long as the trigger is either a `<wa-button>`, or a `<button>` with [native styles](/docs/native/button) included.
|
||||
Dropdowns can be placed into button groups.
|
||||
|
||||
```html {.example}
|
||||
<wa-button-group label="Example Button Group">
|
||||
<wa-button>Button</wa-button>
|
||||
<button>Native Button</button>
|
||||
<wa-dropdown>
|
||||
<wa-button slot="trigger" caret>Dropdown</wa-button>
|
||||
<wa-menu>
|
||||
@@ -175,6 +172,7 @@ Other elements can also be placed inside button groups:
|
||||
<wa-menu-item>Item 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
</wa-dropdown>
|
||||
<wa-button>Button</wa-button>
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
|
||||
@@ -110,15 +110,15 @@ Use the `appearance` attribute to change the callout's visual appearance (the de
|
||||
Use the `size` attribute to change a callout's size.
|
||||
|
||||
```html {.example}
|
||||
<wa-callout variant="brand" appearance="outlined accent" size="large">
|
||||
<wa-icon slot="icon" name="circle-info" variant="solid"></wa-icon>
|
||||
<wa-callout size="large">
|
||||
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
|
||||
This is meant to be very emphasized.
|
||||
</wa-callout>
|
||||
<wa-callout>
|
||||
<wa-callout size="medium">
|
||||
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
|
||||
Normal-sized callout.
|
||||
</wa-callout>
|
||||
<wa-callout variant="plain" appearance="plain" size="small">
|
||||
<wa-callout size="small">
|
||||
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
|
||||
Just a small tip!
|
||||
</wa-callout>
|
||||
|
||||
@@ -127,41 +127,6 @@ If using SSR, you need to also use the `with-media` attribute to add a media sec
|
||||
</style>
|
||||
```
|
||||
|
||||
### Sizing
|
||||
|
||||
Use the `size` attribute to change a card's size.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-stack">
|
||||
<wa-card size="small">
|
||||
This is a small card.
|
||||
|
||||
<footer slot="footer" class="wa-split">
|
||||
<wa-button variant="brand" pill>More Info</wa-button>
|
||||
<wa-rating></wa-rating>
|
||||
</footer>
|
||||
</wa-card>
|
||||
|
||||
<wa-card size="medium">
|
||||
This is a medium card (default).
|
||||
|
||||
<footer slot="footer" class="wa-split">
|
||||
<wa-button variant="brand" pill>More Info</wa-button>
|
||||
<wa-rating></wa-rating>
|
||||
</footer>
|
||||
</wa-card>
|
||||
|
||||
<wa-card size="large">
|
||||
This is a large card.
|
||||
|
||||
<footer slot="footer" class="wa-split">
|
||||
<wa-button variant="brand" pill>More Info</wa-button>
|
||||
<wa-rating></wa-rating>
|
||||
</footer>
|
||||
</wa-card>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the `appearance` attribute to change the card's visual appearance.
|
||||
|
||||
@@ -27,86 +27,6 @@ Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regu
|
||||
<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
|
||||
|
||||
Icons inherit their color from the current text color. Thus, you can set the `color` property on the `<wa-icon>` element or an ancestor to change the color.
|
||||
@@ -222,17 +142,33 @@ This will register the [Bootstrap Icons](https://icons.getbootstrap.com/) librar
|
||||
|
||||
Icons in this library are licensed under the [MIT License](https://github.com/twbs/icons/blob/main/LICENSE).
|
||||
|
||||
```html
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('default', {
|
||||
registerIconLibrary('bootstrap', {
|
||||
resolver: (name, family) => {
|
||||
const suffix = family === 'filled' ? '-fill' : '';
|
||||
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div style="font-size: 24px;">
|
||||
<wa-icon library="bootstrap" name="backpack"></wa-icon>
|
||||
<wa-icon library="bootstrap" name="cup-hot"></wa-icon>
|
||||
<wa-icon library="bootstrap" name="envelope-heart"></wa-icon>
|
||||
<wa-icon library="bootstrap" name="inboxes"></wa-icon>
|
||||
<wa-icon library="bootstrap" name="lamp"></wa-icon>
|
||||
<wa-icon library="bootstrap" name="piggy-bank"></wa-icon>
|
||||
<br />
|
||||
<wa-icon library="bootstrap" family="filled" name="backpack"></wa-icon>
|
||||
<wa-icon library="bootstrap" family="filled" name="cup-hot"></wa-icon>
|
||||
<wa-icon library="bootstrap" family="filled" name="envelope-heart"></wa-icon>
|
||||
<wa-icon library="bootstrap" family="filled" name="inboxes"></wa-icon>
|
||||
<wa-icon library="bootstrap" family="filled" name="lamp"></wa-icon>
|
||||
<wa-icon library="bootstrap" family="filled" name="piggy-bank"></wa-icon>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Boxicons
|
||||
@@ -287,6 +223,18 @@ This will register the [Lucide](https://lucide.dev/) icon library using the jsDe
|
||||
Icons in this library are licensed under the [MIT License](https://github.com/lucide-icons/lucide/blob/master/LICENSE).
|
||||
|
||||
```html {.example}
|
||||
<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`,
|
||||
mutator: svg => svg.querySelectorAll('path').forEach(path => {
|
||||
path.setAttribute('fill', 'none');
|
||||
path.setAttribute('stroke', 'currentColor');
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<div style="font-size: 24px;">
|
||||
<wa-icon library="lucide" name="feather"></wa-icon>
|
||||
<wa-icon library="lucide" name="pie-chart"></wa-icon>
|
||||
@@ -295,14 +243,6 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
|
||||
<wa-icon library="lucide" name="printer"></wa-icon>
|
||||
<wa-icon library="lucide" name="shopping-cart"></wa-icon>
|
||||
</div>
|
||||
|
||||
<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`
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### Heroicons
|
||||
@@ -316,7 +256,11 @@ Icons in this library are licensed under the [MIT License](https://github.com/ta
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('heroicons', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/heroicons@2.0.1/24/outline/${name}.svg`
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/heroicons@2.0.1/24/outline/${name}.svg`,
|
||||
mutator: svg => svg.querySelectorAll('path').forEach(path => {
|
||||
path.setAttribute('fill', 'none');
|
||||
path.setAttribute('stroke', 'currentColor');
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -341,7 +285,11 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('iconoir', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`
|
||||
resolver: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`,
|
||||
mutator: svg => svg.querySelectorAll('path').forEach(path => {
|
||||
path.setAttribute('fill', 'none');
|
||||
path.setAttribute('stroke', 'currentColor');
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ body {
|
||||
```
|
||||
|
||||
:::info
|
||||
If you use [native styles](/docs/native/), this is already taken care of.
|
||||
If you use [native styles](/docs/utilities/native/), this is already taken care of.
|
||||
:::
|
||||
|
||||
## Examples
|
||||
@@ -164,7 +164,7 @@ wa-page[view='desktop'] [data-toggle-nav] {
|
||||
```
|
||||
|
||||
:::info
|
||||
If you use [native styles](/docs/native/), this is already taken care for you, and the `data-toggle-nav` button is already hidden on wider screens.
|
||||
If you use [native styles](/docs/utilities/native/), this is already taken care for you, and the `data-toggle-nav` button is already hidden on wider screens.
|
||||
:::
|
||||
|
||||
#### Custom Widths
|
||||
@@ -205,13 +205,7 @@ You can override the default spacing for each slot with your own CSS. In this ex
|
||||
|
||||
## Utility classes
|
||||
|
||||
[Native styles](/docs/native/) define a few useful defaults for `<wa-page>`, as well as two utility classes you can use for common responsive design tasks:
|
||||
[Native styles](/docs/utilities/native/) define a few useful defaults for `<wa-page>`, as well as two utility classes you can use for common responsive design tasks:
|
||||
|
||||
- `.wa-mobile-only` hides an element on the desktop view
|
||||
- `.wa-desktop-only` hides an element on the mobile view
|
||||
|
||||
If you don’t want to use [native styles](/docs/native/), you can include this stylesheet in your project to use these:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/components/page.css' %}" />
|
||||
```
|
||||
@@ -1,151 +0,0 @@
|
||||
---
|
||||
title: Radio Button
|
||||
description: Radios buttons allow the user to select a single option from a group using a button-like control.
|
||||
tags: forms
|
||||
parent: radio-group
|
||||
icon: radio-group
|
||||
---
|
||||
|
||||
Radio buttons are designed to be used with [radio groups](/docs/components/radio-group). When a radio button has focus, the arrow keys can be used to change the selected option just like standard radio controls.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" 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>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Checked States
|
||||
|
||||
To set the initial value and checked state, use the `value` attribute on the containing radio group.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" 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>
|
||||
```
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a radio button.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2" disabled>Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a radio button's size.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group size="small" label="Select an option" orientation="horizontal" 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>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="medium" label="Select an option" orientation="horizontal" 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>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="large" label="Select an option" orientation="horizontal" 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>
|
||||
```
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Use the `pill` attribute to give radio buttons rounded edges.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group size="small" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="medium" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="large" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
### Prefix and Suffix Icons
|
||||
|
||||
Use the `prefix` and `suffix` slots to add icons.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">
|
||||
<wa-icon slot="prefix" name="archive" variant="solid"></wa-icon>
|
||||
Option 1
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="2">
|
||||
<wa-icon slot="suffix" name="bag-shopping" variant="solid"></wa-icon>
|
||||
Option 2
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="3">
|
||||
<wa-icon slot="prefix" name="gift" variant="solid"></wa-icon>
|
||||
<wa-icon slot="suffix" name="shopping-cart" variant="solid"></wa-icon>
|
||||
Option 3
|
||||
</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
### Buttons with Icons
|
||||
|
||||
You can omit button labels and use icons instead. Make sure to set a `label` attribute on each icon so screen readers will announce each option correctly.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="neutral">
|
||||
<wa-radio-button value="angry">
|
||||
<wa-icon name="face-angry" variant="solid" label="Angry"></wa-icon>
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="sad">
|
||||
<wa-icon name="face-frown" variant="solid" label="Sad"></wa-icon>
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="neutral">
|
||||
<wa-icon name="face-meh" variant="solid" label="Neutral"></wa-icon>
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="happy">
|
||||
<wa-icon name="face-smile" variant="solid" label="Happy"></wa-icon>
|
||||
</wa-radio-button>
|
||||
|
||||
<wa-radio-button value="laughing">
|
||||
<wa-icon name="face-laugh" variant="solid" label="Laughing"></wa-icon>
|
||||
</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Radio Group
|
||||
description: Radio groups are used to group multiple radios or radio buttons so they function as a single form control.
|
||||
description: Radio groups are used to group multiple radios so they function as a single form control.
|
||||
tags: [inputs, forms]
|
||||
icon: radio-group
|
||||
---
|
||||
@@ -29,7 +29,7 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
|
||||
|
||||
### Radio Buttons
|
||||
|
||||
[Radio buttons](/docs/components/radio-button) offer an alternate way to display radio controls. In this case, an internal [button group](/docs/components/button-group) is used to group the buttons into a single, cohesive control.
|
||||
Set the `appearance` attribute to `button` on all radios to render a radio button group.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group
|
||||
@@ -39,9 +39,9 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
|
||||
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 appearance="button" value="1">Option 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Option 2</wa-radio>
|
||||
<wa-radio appearance="button" value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
|
||||
<br>
|
||||
@@ -54,9 +54,9 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
|
||||
value="1"
|
||||
style="max-width: 300px;"
|
||||
>
|
||||
<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 appearance="button" value="1">Option 1</wa-radio>
|
||||
<wa-radio appearance="button" value="2">Option 2</wa-radio>
|
||||
<wa-radio appearance="button" value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
@@ -92,7 +92,7 @@ The default orientation for radio items is `vertical`. Set the `orientation` to
|
||||
|
||||
### Sizing Options
|
||||
|
||||
The size of [Radios](/docs/components/radio) and [Radio Buttons](/docs/components/radio-button) will be determined by the Radio Group's `size` attribute.
|
||||
The size of [Radios](/docs/components/radio) will be determined by the Radio Group's `size` attribute.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" size="medium" value="medium" onchange="this.size = this.value">
|
||||
|
||||
@@ -7,11 +7,7 @@ native: input
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<form action="about:blank" target="_blank">
|
||||
<wa-textarea label="Type something', will ya" name="a"></wa-textarea>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
<wa-textarea label="Type something', will ya"></wa-textarea>
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
@@ -133,7 +133,7 @@ Most (but not all) components expose parts. You can find them in each component'
|
||||
|
||||
## Native Elements
|
||||
|
||||
If you're using [native styles](/docs/native), any custom styles added for a component should also target the corresponding native element. In general, the same styles you declare for components will work just the same to style their native counterparts.
|
||||
If you're using [native styles](/docs/utilities/native), any custom styles added for a component should also target the corresponding native element. In general, the same styles you declare for components will work just the same to style their native counterparts.
|
||||
|
||||
For example, we can give `<input type="checkbox">` the same custom styles as `<wa-checkbox>` by using the custom properties required to style the component:
|
||||
```html {.example}
|
||||
@@ -196,10 +196,7 @@ For example, we can give all outlined callouts a thick left border, regardless o
|
||||
</wa-callout>
|
||||
|
||||
<style>
|
||||
wa-callout:is(
|
||||
[appearance~="outlined"],
|
||||
.wa-outlined
|
||||
) {
|
||||
wa-callout:is([appearance~="outlined"]) {
|
||||
border-left-width: var(--wa-panel-border-radius);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -524,10 +524,10 @@ hasOutline: false
|
||||
</div>
|
||||
<div>
|
||||
<wa-radio-group label="Need a logo?" name="project-logo-selector" value="shapes">
|
||||
<wa-radio-button value="shapes"><wa-icon name="shapes"></wa-icon></wa-radio-button>
|
||||
<wa-radio-button value="meteor"><wa-icon name="meteor"></wa-icon></wa-radio-button>
|
||||
<wa-radio-button value="cat-space"><wa-icon name="cat-space"></wa-icon></wa-radio-button>
|
||||
<wa-radio-button value="puzzle-piece"><wa-icon name="puzzle-piece"></wa-icon></wa-radio-button>
|
||||
<wa-radio appearance="button" value="shapes"><wa-icon name="shapes"></wa-icon></wa-radio>
|
||||
<wa-radio appearance="button" value="meteor"><wa-icon name="meteor"></wa-icon></wa-radio>
|
||||
<wa-radio appearance="button" value="cat-space"><wa-icon name="cat-space"></wa-icon></wa-radio>
|
||||
<wa-radio appearance="button" value="puzzle-piece"><wa-icon name="puzzle-piece"></wa-icon></wa-radio>
|
||||
<wa-button value="[choose]" appearance="plain" id="icon-chooser-trigger" class="logo-chooser">
|
||||
<wa-tooltip for="icon-chooser-trigger" distance="-3" hoist>Browse Icons</wa-tooltip>
|
||||
<wa-icon name="ellipsis" library="fa-classic-regular"></wa-icon>
|
||||
@@ -684,12 +684,12 @@ hasOutline: false
|
||||
|
||||
<div id="color-mode-selector">
|
||||
<wa-radio-group class="hidden-label" label="Color mode" name="color-mode" value="light">
|
||||
<wa-radio-button value="light">
|
||||
<wa-radio appearance="button" value="light">
|
||||
<wa-icon name="sun" library="fa-classic-regular"></wa-icon>
|
||||
</wa-radio-button>
|
||||
<wa-radio-button value="dark">
|
||||
</wa-radio>
|
||||
<wa-radio appearance="button" value="dark">
|
||||
<wa-icon name="moon" library="fa-classic-regular"></wa-icon>
|
||||
</wa-radio-button>
|
||||
</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
|
||||
@@ -2239,10 +2239,10 @@ hasOutline: false
|
||||
<div>
|
||||
<div style="margin: var(--wa-space-3xl) 0">
|
||||
<wa-radio-group label="Choose a finish" name="finish" value="Matte" class="product-finish">
|
||||
<wa-radio-button value="Matte">Matte</wa-radio-button>
|
||||
<wa-radio-button value="Glossy">Glossy</wa-radio-button>
|
||||
<wa-radio-button value="Pebbled" disabled>Pebbled</wa-radio-button>
|
||||
<wa-radio-button value="Holo">Holo</wa-radio-button>
|
||||
<wa-radio appearance="button" value="Matte">Matte</wa-radio>
|
||||
<wa-radio appearance="button" value="Glossy">Glossy</wa-radio>
|
||||
<wa-radio appearance="button" value="Pebbled" disabled>Pebbled</wa-radio>
|
||||
<wa-radio appearance="button" value="Holo">Holo</wa-radio>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
<div style="display: flex; align-items: end; gap: 1rem;">
|
||||
|
||||
@@ -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/utilities/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)
|
||||
|
||||
@@ -12,7 +12,7 @@ override:tags: []
|
||||
|
||||
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:
|
||||
Layout utilities are bundled with all [style utilities](/docs/utilities). You can import all Web Awesome page styles (including [native styles](/docs/utilities/native/)) by including the following stylesheet in your project:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/webawesome.css' %}" />
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
---
|
||||
title: Button
|
||||
description: 'Button styles apply your Web Awesome theme to native HTML buttons. Buttons are activated by users to perform actions, such as submitting a form.'
|
||||
tags: forms
|
||||
component: button
|
||||
icon: button
|
||||
snippets:
|
||||
'<button>': https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
|
||||
'.wa-button': false
|
||||
file: styles/native/button.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<button>Button</button>
|
||||
<input type="button" value="Input (button)">
|
||||
<input type="reset" value="Input (reset)">
|
||||
<input type="submit" value="Input (submit)">
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Use the [variant utility classes](../utilities/color.md) to set the button's semantic variant.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-neutral">Neutral</button>
|
||||
<button class="wa-brand">Brand</button>
|
||||
<button class="wa-success">Success</button>
|
||||
<button class="wa-warning">Warning</button>
|
||||
<button class="wa-danger">Danger</button>
|
||||
```
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the [appearance utility classes](/docs/utilities/appearance) to change the button's visual appearance:
|
||||
|
||||
```html {.example}
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-neutral">A + O</button>
|
||||
<button class="wa-accent wa-neutral">Accent</button>
|
||||
<button class="wa-outlined wa-neutral">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-neutral">F + O</button>
|
||||
<button class="wa-filled wa-neutral">Filled</button>
|
||||
<button class="wa-plain wa-neutral">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-brand">A + O</button>
|
||||
<button class="wa-accent wa-brand">Accent</button>
|
||||
<button class="wa-outlined wa-brand">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-brand">F + O</button>
|
||||
<button class="wa-filled wa-brand">Filled</button>
|
||||
<button class="wa-plain wa-brand">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-success">A + O</button>
|
||||
<button class="wa-accent wa-success">Accent</button>
|
||||
<button class="wa-outlined wa-success">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-success">F + O</button>
|
||||
<button class="wa-filled wa-success">Filled</button>
|
||||
<button class="wa-plain wa-success">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-warning">A + O</button>
|
||||
<button class="wa-accent wa-warning">Accent</button>
|
||||
<button class="wa-outlined wa-warning">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-warning">F + O</button>
|
||||
<button class="wa-filled wa-warning">Filled</button>
|
||||
<button class="wa-plain wa-warning">Plain</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="wa-accent wa-outlined wa-danger">A + O</button>
|
||||
<button class="wa-accent wa-danger">Accent</button>
|
||||
<button class="wa-outlined wa-danger">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-danger">F + O</button>
|
||||
<button class="wa-filled wa-danger">Filled</button>
|
||||
<button class="wa-plain wa-danger">Plain</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the [size utility classes](../utilities/size.md) to change a button's size.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-size-s">Small</button>
|
||||
<button class="wa-size-m">Medium</button>
|
||||
<button class="wa-size-l">Large</button>
|
||||
```
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Use the `wa-pill` class to give buttons rounded edges.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-size-s wa-pill">Small</button>
|
||||
<button class="wa-size-m wa-pill">Medium</button>
|
||||
<button class="wa-size-l wa-pill">Large</button>
|
||||
```
|
||||
|
||||
### Link Buttons
|
||||
|
||||
It's often helpful to have a link that looks like a button.
|
||||
This is possible by adding a `wa-button` class to your link.
|
||||
|
||||
```html {.example}
|
||||
<a href="https://example.com/" class="wa-button">Link</a>
|
||||
<a href="https://example.com/" target="_blank" class="wa-button">New Window</a>
|
||||
<a href="/assets/images/logo.svg" download="shoelace.svg" class="wa-button">Download</a>
|
||||
```
|
||||
|
||||
### Setting a Custom Width
|
||||
|
||||
As expected, buttons can be given a custom width by setting the `width` CSS property. This is useful for making buttons span the full width of their container on smaller screens.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-size-s" style="width: 100%; margin-bottom: 1rem;">Small</button>
|
||||
<button class="wa-size-m" style="width: 100%; margin-bottom: 1rem;">Medium</button>
|
||||
<button class="wa-size-l" style="width: 100%;">Large</button>
|
||||
```
|
||||
<!--
|
||||
|
||||
### Loading
|
||||
|
||||
Use the `loading` attribute to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-brand" loading>Brand</button>
|
||||
<button class="wa-success" loading>Success</button>
|
||||
<button class="wa-neutral" loading>Neutral</button>
|
||||
<button class="wa-warning" loading>Warning</button>
|
||||
<button class="wa-danger" loading>Danger</button>
|
||||
```
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a button.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-brand" disabled>Brand</button>
|
||||
<button class="wa-success" disabled>Success</button>
|
||||
<button class="wa-neutral" disabled>Neutral</button>
|
||||
<button class="wa-warning" disabled>Warning</button>
|
||||
``` -->
|
||||
@@ -1,117 +0,0 @@
|
||||
---
|
||||
title: Callout
|
||||
description: Callouts are used to display important messages inline.
|
||||
component: callout
|
||||
icon: callout
|
||||
snippets: '.wa-callout'
|
||||
file: styles/native/callout.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<article class="wa-callout">
|
||||
This is a callout style, applied to a standard article element.
|
||||
</article>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Use the [variant utility classes](../utilities/color.md) to set the callout's color variant.
|
||||
|
||||
```html {.example}
|
||||
<article class="wa-callout wa-brand">
|
||||
<strong>This is super informative</strong><br />
|
||||
You can tell by how pretty the callout is.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-success">
|
||||
<strong>Your changes have been saved</strong><br />
|
||||
You can safely exit the app now.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-neutral">
|
||||
<strong>Your settings have been updated</strong><br />
|
||||
Settings will take effect on next login.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-warning">
|
||||
<strong>Your session has ended</strong><br />
|
||||
Please login again to continue.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-danger">
|
||||
<strong>Your account has been deleted</strong><br />
|
||||
We're very sorry to see you go!
|
||||
</article>
|
||||
```
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the [appearance utility classes](/docs/utilities/appearance) to change the callout's visual appearance (the default is `outlined filled`).
|
||||
|
||||
```html {.example}
|
||||
<article class="wa-callout wa-brand wa-outlined wa-accent">
|
||||
This <strong>accent</strong> callout is also <strong>outlined</strong>
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-brand wa-accent">
|
||||
This <strong>accent</strong> callout draws attention without an outline
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-brand wa-outlined wa-filled">
|
||||
This callout is both <strong>filled</strong> and <strong>outlined</strong>
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-brand wa-filled">
|
||||
This callout is only <strong>filled</strong>
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-brand wa-outlined">
|
||||
Here's an <strong>outlined</strong> callout
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-brand wa-plain">
|
||||
No bells and whistles on this <strong>plain</strong> callout
|
||||
</article>
|
||||
```
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the [size utility classes](../utilities/size.md) to change a callout's size.
|
||||
|
||||
```html {.example}
|
||||
<article class="wa-callout wa-brand wa-outlined wa-accent wa-size-l">
|
||||
This is meant to be very emphasized.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout">
|
||||
Normal-sized callout.
|
||||
</article>
|
||||
|
||||
<br />
|
||||
|
||||
<article class="wa-callout wa-plain wa-plain wa-size-s">
|
||||
Just a small tip!
|
||||
</article>
|
||||
```
|
||||
@@ -1,90 +0,0 @@
|
||||
---
|
||||
title: Checkbox
|
||||
description: Checkboxes allow the user to toggle an option on or off.
|
||||
tags: forms
|
||||
component: checkbox
|
||||
icon: checkbox
|
||||
elements:
|
||||
"<input type=checkbox>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox
|
||||
file: styles/native/checkbox.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox"> Checkbox</label>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Checked
|
||||
|
||||
Use the `checked` attribute to activate the checkbox.
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox" checked> Checked</label>
|
||||
```
|
||||
|
||||
<!--
|
||||
### Indeterminate
|
||||
|
||||
Use the `indeterminate` JS property to make the checkbox indeterminate.
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox" class="indeterminate"> Indeterminate</label>
|
||||
<script>
|
||||
document.querySelector(".indeterminate").indeterminate = true;
|
||||
</script>
|
||||
```
|
||||
-->
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable the checkbox.
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox" disabled> Disabled</label>
|
||||
```
|
||||
|
||||
<!--
|
||||
### Sizes
|
||||
|
||||
Use the [size utilities](/docs/utilities/size) to change a checkbox's size.
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox" class="wa-size-s"> Small</label>
|
||||
<br />
|
||||
<label><input type="checkbox" class="wa-size-m"> Medium</label>
|
||||
<br />
|
||||
<label><input type="checkbox" class="wa-size-l"> Large</label>
|
||||
```
|
||||
-->
|
||||
|
||||
### Custom Validity
|
||||
|
||||
Use the `setCustomValidity()` method to set a custom validation message. This will prevent the form from submitting and make the browser display the error message you provide. To clear the error, call this function with an empty string.
|
||||
|
||||
```html {.example}
|
||||
<form class="custom-validity">
|
||||
<label><input type="checkbox"> Check me</label>
|
||||
<br />
|
||||
<button type="submit" variant="brand" style="margin-top: 1rem;">Submit</button>
|
||||
</form>
|
||||
<script>
|
||||
const form = document.querySelector('.custom-validity');
|
||||
const checkbox = form.querySelector('input[type=checkbox]');
|
||||
const errorMessage = `Don't forget to check me!`;
|
||||
|
||||
// Set initial validity
|
||||
checkbox.setCustomValidity(errorMessage);
|
||||
|
||||
// Update validity on change
|
||||
checkbox.addEventListener('change', () => {
|
||||
checkbox.setCustomValidity(checkbox.checked ? '' : errorMessage);
|
||||
});
|
||||
|
||||
// Handle submit
|
||||
form.addEventListener('submit', event => {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
title: Content
|
||||
description: 'Content styles apply your Web Awesome theme to HTML text content, code, and images.'
|
||||
tags: content
|
||||
layout: element
|
||||
icon: skeleton
|
||||
elements:
|
||||
"<h1>-<h6>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements
|
||||
"<blockquote>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote
|
||||
"<strong>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong
|
||||
"<em>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em
|
||||
"<u>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u
|
||||
"<del>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del
|
||||
"<ins>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins
|
||||
"<s>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s
|
||||
"<small>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small
|
||||
"<sub>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub
|
||||
"<sup>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup
|
||||
"<abbr>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr
|
||||
"<kbd>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd
|
||||
"<mark>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark
|
||||
"<a>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
|
||||
"<code>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code
|
||||
"<img>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
|
||||
file: styles/native/content.css
|
||||
---
|
||||
|
||||
|
||||
## Typography
|
||||
|
||||
Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Amet mauris commodo quis imperdiet. Bibendum ut tristique et egestas quis ipsum suspendisse. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat.
|
||||
|
||||
Cras pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci. Scelerisque eleifend donec pretium vulputate sapien nec. Donec et odio pellentesque diam volutpat commodo sed egestas egestas. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque.
|
||||
|
||||
> What is a Web year now, about three months? And when people can browse around, discover new things, and download them fast, when we all have agents - then Web years could slip by before human beings can notice.
|
||||
>
|
||||
> — Tim Berners-Lee
|
||||
|
||||
## Inline Text
|
||||
|
||||
```html
|
||||
Feugiat nisl pretium fusce id. Ipsum dolor sit amet consectetur adipiscing elit. Eget nunc lobortis mattis aliquam faucibus purus. Metus dictum at tempor commodo ullamcorper a lacus vestibulum. Urna condimentum mattis pellentesque id nibh tortor id.
|
||||
```
|
||||
|
||||
<div class="two-columns">
|
||||
<p><strong>Bold</strong></p>
|
||||
<p><em>Italics</em></p>
|
||||
<p><u>Underline</u></p>
|
||||
<p><del>Deleted</del></p>
|
||||
<p><ins>Inserted</ins></p>
|
||||
<p><s>Strike-through</s></p>
|
||||
<p><small>Small</small></p>
|
||||
<p><span>Text <sub>Sub</sub></span></p>
|
||||
<p><span>Text <sup>Sup</sup></span></p>
|
||||
<p><abbr title="Abbreviation">Abbr.</abbr></p>
|
||||
<p><kbd>Keyboard</kbd></p>
|
||||
<p><mark>Highlighted</mark></p>
|
||||
<p><a href="#">Link text</a></p>
|
||||
<p><code>Inline code</code></p>
|
||||
</div>
|
||||
|
||||
## Headings
|
||||
|
||||
### Heading 3
|
||||
|
||||
Feugiat nisl pretium fusce id. Ipsum dolor sit amet consectetur adipiscing elit. Eget nunc lobortis mattis aliquam faucibus purus. Metus dictum at tempor commodo ullamcorper a lacus vestibulum. Urna condimentum mattis pellentesque id nibh tortor id.
|
||||
|
||||
#### Heading 4
|
||||
|
||||
Gravida arcu ac tortor dignissim convallis aenean. Pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Ipsum nunc aliquet bibendum enim facilisis gravida neque. Donec adipiscing tristique risus nec feugiat in.
|
||||
|
||||
##### Heading 5
|
||||
|
||||
Enim diam vulputate ut pharetra sit. Enim facilisis gravida neque convallis a cras. Enim neque volutpat ac tincidunt vitae semper. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend donec pretium.
|
||||
|
||||
###### Heading 6
|
||||
|
||||
Tincidunt ornare massa eget egestas purus viverra accumsan in nisl. Facilisis mauris sit amet massa vitae. Nunc faucibus a pellentesque sit amet porttitor. Adipiscing tristique risus nec feugiat in fermentum.
|
||||
|
||||
|
||||
## Code Blocks
|
||||
|
||||
```
|
||||
// do a thing
|
||||
export function thing() {
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
## Images
|
||||
|
||||

|
||||
@@ -1,82 +0,0 @@
|
||||
---
|
||||
title: Details
|
||||
description: 'Details styles apply your Web Awesome theme to the HTML `<details>` element. Details show a brief summary and expand to show additional content.'
|
||||
tags: apps
|
||||
layout: element
|
||||
component: details
|
||||
icon: details
|
||||
elements:
|
||||
"<details>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details
|
||||
file: styles/native/details.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<details>
|
||||
<summary>Tincidunt nunc pulvinar</summary>
|
||||
<p>Ut lectus arcu bibendum at varius. Convallis a cras semper auctor neque vitae. Odio pellentesque diam volutpat commodo sed egestas. Amet dictum sit amet justo donec enim diam vulputate ut.</p>
|
||||
</details>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the [appearance utility classes](/docs/utilities/appearance) to change the element's visual appearance:
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-stack">
|
||||
<details>
|
||||
<summary>Outlined (default)</summary>
|
||||
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.
|
||||
</details>
|
||||
<details class="wa-filled">
|
||||
<summary>Filled</summary>
|
||||
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.
|
||||
</details>
|
||||
<details class="wa-filled wa-outlined">
|
||||
<summary>Filled + Outlined</summary>
|
||||
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.
|
||||
</details>
|
||||
<details class="wa-plain">
|
||||
<summary>Plain</summary>
|
||||
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.
|
||||
</details>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Right-to-Left Languages
|
||||
|
||||
The details styling automatically adapts to right-to-left languages:
|
||||
|
||||
```html {.example}
|
||||
<details lang="ar" dir="rtl">
|
||||
<summary>تبديلني</summary>
|
||||
استخدام طريقة لوريم إيبسوم لأنها تعطي توزيعاَ طبيعياَ -إلى حد ما- للأحرف عوضاً عن
|
||||
</details>
|
||||
```
|
||||
|
||||
## Accordions
|
||||
|
||||
In [modern browsers](https://caniuse.com/mdn-html_elements_details_name),
|
||||
grouping `<details>` elements via the `name` attribute provides accordion-style functionality:
|
||||
|
||||
```html {.example}
|
||||
<details name="details-accordion">
|
||||
<summary>Enim diam</summary>
|
||||
<p>Nunc faucibus a pellentesque sit amet porttitor. Adipiscing tristique risus nec feugiat in fermentum. Leo duis ut diam quam nulla porttitor massa id. Mauris nunc congue nisi vitae.</p>
|
||||
</details>
|
||||
|
||||
<details name="details-accordion">
|
||||
<summary>Arcu non odio</summary>
|
||||
<p>Sed libero enim sed faucibus turpis in eu mi bibendum. Nunc mi ipsum faucibus vitae aliquet nec. Ultricies tristique nulla aliquet enim tortor. Tellus at urna condimentum mattis pellentesque.</p>
|
||||
</details>
|
||||
|
||||
<details name="details-accordion">
|
||||
<summary>Ut porttitor</summary>
|
||||
<p>Eu facilisis sed odio morbi quis commodo odio aenean sed. Sit amet purus gravida quis blandit turpis cursus. Eu consequat ac felis donec et odio pellentesque diam volutpat.</p>
|
||||
</details>
|
||||
```
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
title: Dialog
|
||||
description: 'Dialog styles apply your Web Awesome theme to the HTML `<dialog>` element. Dialogs, also called "modals", appear above the page and interrupt a user''s focus.'
|
||||
tags: apps
|
||||
icon: dialog
|
||||
elements:
|
||||
"<dialog>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
|
||||
component: dialog
|
||||
file: styles/native/dialog.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<dialog id="dialog-overview">
|
||||
<header>
|
||||
<h2>Dialog</h2>
|
||||
<button data-dialog="close" class="wa-plain">✖️</button>
|
||||
</header>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
||||
<footer>
|
||||
<button class="wa-brand" data-dialog="close">Close</button>
|
||||
</footer>
|
||||
</dialog>
|
||||
|
||||
<button>Open Dialog</button>
|
||||
|
||||
<script>
|
||||
const dialog = document.querySelector('#dialog-overview');
|
||||
const openButton = dialog.nextElementSibling;
|
||||
|
||||
openButton.addEventListener('click', () => dialog.showModal());
|
||||
dialog.addEventListener('click', event => {
|
||||
if (event.target.closest('[data-dialog="close"]')) {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
title: Native Styles
|
||||
description: Native styles apply your theme to native HTML elements so they match the look and feel of Web Awesome components.
|
||||
See the [installation instructions](#installation) to use native styles in your project.
|
||||
layout: overview
|
||||
categories: ['forms', 'apps', 'content']
|
||||
override:tags: []
|
||||
---
|
||||
|
||||
{% markdown %}
|
||||
Web Awesome works _with_ the platform, rather than trying to reinvent it.
|
||||
If all you need is styles, you don’t need to use new `<wa-*>` elements!
|
||||
We also provide styles that make native HTML elements look good so you can continue using what you know and gradually adopt Web Awesome as you see fit.
|
||||
|
||||
## Installation
|
||||
|
||||
To use all Web Awesome page styles (including [utilities](/docs/utilities/)), include the following stylesheet in your project:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/webawesome.css' %}" />
|
||||
```
|
||||
|
||||
Or, to _only_ include styles for native elements:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/native.css' %}" />
|
||||
```
|
||||
|
||||
## Opting Out of Native Styles
|
||||
|
||||
So you've decided to use Native Styles and now you need to style an element or a part of a page completely differently, what to do?
|
||||
You can create an opt-out with the power of [CSS Cascade Layers](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_layers)!
|
||||
|
||||
Instead of including Native Styles with a `<link>` element, you can include it like this:
|
||||
|
||||
```html
|
||||
<style>
|
||||
@import url('{% cdnUrl 'styles/webawesome.css' %}') layer(wa);
|
||||
|
||||
@layer wa {
|
||||
.wa-off,
|
||||
.wa-off-deep,
|
||||
.wa-off-deep * {
|
||||
all: revert-layer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
Then you can opt-out of Native Styles styling by using a `wa-off` class on individual elements or `wa-off-deep` for entire subtrees:
|
||||
|
||||
```html
|
||||
<p>
|
||||
<button>I’m Awesome</button>
|
||||
<button class="wa-off">I’m not</button>
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p>Lorem Ipsum dolor sit amet</p>
|
||||
<button>I’m also awesome</button>
|
||||
</blockquote>
|
||||
<blockquote class="wa-off">
|
||||
<p>Lorem Ipsum dolor sit amet</p>
|
||||
<button >I’m also not</button>
|
||||
</blockquote>
|
||||
<blockquote class="wa-off-deep">
|
||||
<p>Lorem Ipsum dolor sit amet</p>
|
||||
<button>I’m also not</button>
|
||||
</blockquote>
|
||||
```
|
||||
|
||||
You could even design opt-outs for specific elements!
|
||||
E.g. to opt-out of `<details>` styling:
|
||||
|
||||
```css
|
||||
@layer wa {
|
||||
details.wa-details-off,
|
||||
.wa-details-off details,{
|
||||
all: revert-layer;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you find yourself opting out of entire element types too much, you could consider only including the parts of Native Styles you need instead of the whole thing.
|
||||
You can find instructions for how to do that on the individual Native Styles pages.
|
||||
{% endmarkdown %}
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: Input
|
||||
description: Inputs collect data from the user.
|
||||
tags: forms
|
||||
icon: input
|
||||
component: input
|
||||
elements:
|
||||
"<input>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
|
||||
file: styles/native/input.css
|
||||
---
|
||||
|
||||
## Text Fields
|
||||
|
||||
```html {.example}
|
||||
<label>Input (text) <input type="text" placeholder="placeholder"></label>
|
||||
<wa-input label="WA Input (text)" type="text" placeholder="placeholder"></wa-input>
|
||||
|
||||
<label>Input (number) <input type="number"></label>
|
||||
<wa-input label="WA Input (number)" type="number"></wa-input>
|
||||
|
||||
<label>Input (password) <input type="password" required></label>
|
||||
<wa-input label="WA Input (password)" type="password" required></wa-input>
|
||||
|
||||
<label>Input (email) <input type="email"></label>
|
||||
<wa-input label="WA Input (email)" type="email"></wa-input>
|
||||
|
||||
<label>Input (search) <input type="search"></label>
|
||||
<wa-input label="WA Input (search)" type="search"></wa-input>
|
||||
|
||||
<label>Input (tel) <input type="tel"></label>
|
||||
<wa-input label="WA Input (tel)" type="tel"></wa-input>
|
||||
|
||||
<label>Input (url) <input type="url"></label>
|
||||
<wa-input label="WA Input (url)" type="url"></wa-input>
|
||||
```
|
||||
|
||||
## Pill shaped text fields
|
||||
|
||||
Add the `wa-pill` class to an `<input>` to make it pill-shaped.
|
||||
|
||||
```html {.example}
|
||||
<label>Input <input type="text" placeholder="placeholder" class="wa-pill"></label>
|
||||
```
|
||||
|
||||
## Color Picker
|
||||
|
||||
Basic:
|
||||
|
||||
```html {.example}
|
||||
<label>Input (color) <input type="color" value="#ff0066"></label>
|
||||
<wa-color-picker label="WA Color Picker" value="#ff0066"></wa-color-picker>
|
||||
```
|
||||
|
||||
With swatches:
|
||||
|
||||
```html {.example}
|
||||
<label>Input (color) <input type="color" value="#ff0066" list="swatches"></label>
|
||||
<datalist id="swatches">
|
||||
<option value="#0070ef">Web Awesome Blue</option>
|
||||
<option>#f5a623</option>
|
||||
<option>#f8e71c</option>
|
||||
<option>#8b572a</option>
|
||||
<option>#7ed321</option>
|
||||
<option>#417505</option>
|
||||
<option>#bd10e0</option>
|
||||
<option>#9013fe</option>
|
||||
</datalist>
|
||||
|
||||
<wa-color-picker label="WA Color Picker" value="#ff0066"
|
||||
swatches="#0070ef; #f5a623; #f8e71c; #8b572a; #7ed321; #417505; #bd10e0; #9013fe;"></wa-color-picker>
|
||||
```
|
||||
|
||||
## Time and Date Pickers
|
||||
|
||||
```html {.example}
|
||||
<label>Input (datetime-local) <input type="datetime-local"></label>
|
||||
<wa-input label="WA Input (datetime-local)" type="datetime-local"></wa-input>
|
||||
|
||||
<label>Input (date) <input type="date"></label>
|
||||
<wa-input label="WA Input (date)" type="date"></wa-input>
|
||||
|
||||
<label>Input (time) <input type="time"></label>
|
||||
<wa-input label="WA Input (time)" type="time"></wa-input>
|
||||
```
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Lists
|
||||
description: 'List styles apply your Web Awesome theme to HTML lists, such as bulleted, numbered, or description lists.'
|
||||
tags: content
|
||||
layout: element
|
||||
elements:
|
||||
"<ul>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul
|
||||
"<ol>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol
|
||||
"<dl>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
|
||||
file: styles/native/lists.css
|
||||
---
|
||||
|
||||
## Unordered Lists
|
||||
|
||||
- List item 1
|
||||
- List item 2
|
||||
- List item 3
|
||||
- Subitem a
|
||||
- Subitem b
|
||||
|
||||
## Ordered Lists
|
||||
|
||||
1. List item 1
|
||||
2. List item 2
|
||||
3. List item 3
|
||||
- Subitem a
|
||||
- Subitem b
|
||||
|
||||
## Definition Lists
|
||||
|
||||
<dl>
|
||||
<dt>Definition 1</dt>
|
||||
<dd>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.</dd>
|
||||
<dt>Definition 2</dt>
|
||||
<dd>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</dd>
|
||||
<dt>Definition 3</dt>
|
||||
<dd>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</dd>
|
||||
</dl>
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"layout": "element.njk",
|
||||
"tags": ["native"]
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: Progress Bar
|
||||
description: Progress bars are used to show the status of an ongoing operation.
|
||||
tags: apps
|
||||
icon: progress-bar
|
||||
status: experimental
|
||||
component: progress-bar
|
||||
elements:
|
||||
"<progress>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress
|
||||
file: styles/native/progress.css
|
||||
---
|
||||
|
||||
|
||||
```html {.example}
|
||||
<progress value="40" max="100"></progress>
|
||||
```
|
||||
|
||||
Indeterminate:
|
||||
|
||||
|
||||
```html {.example}
|
||||
<progress></progress>
|
||||
```
|
||||
|
||||
### Custom Height
|
||||
|
||||
Use the `height` CSS property to set the progress bar's height.
|
||||
|
||||
```html {.example}
|
||||
<progress value="50" style="height: 6px;"></progress>
|
||||
```
|
||||
@@ -1,93 +0,0 @@
|
||||
---
|
||||
title: Radio
|
||||
description: Radios allow the user to select a single option from a group.
|
||||
tags: forms
|
||||
icon: radio-group
|
||||
component: radio
|
||||
elements:
|
||||
"<input type=radio>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
|
||||
file: styles/native/radio.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<label><input type="radio" name="a" value="1" checked> Option 1</label>
|
||||
<label><input type="radio" name="a" value="2"> Option 2</label>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Initial Value
|
||||
|
||||
To set the initial value and checked state, use the `checked` attribute on the corresponding radio.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<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>
|
||||
```
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a radio.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<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>
|
||||
```
|
||||
|
||||
### Sizes
|
||||
|
||||
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="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="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="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>
|
||||
```
|
||||
|
||||
### Orientation
|
||||
|
||||
You can wrap native radios in a flex container to give them a horizontal or vertical orientation with even spacing. The convenience [`wa-cluster`](/docs/utilities/cluster) and [`wa-stack`](/docs/utilities/stack) utilities make this easy.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<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="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>
|
||||
```
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
title: Select
|
||||
description: Selects allow you to choose items from a menu of predefined options.
|
||||
tags: forms
|
||||
icon: select
|
||||
component: select
|
||||
elements:
|
||||
"<select>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select
|
||||
file: styles/native/select.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<label>Select
|
||||
<select id="select">
|
||||
<option value="option-1">Option 1</option>
|
||||
<option value="option-2">Option 2</option>
|
||||
<option value="option-3">Option 3</option>
|
||||
</select>
|
||||
</label>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the [appearance utilities](/docs/utilities/appearance/) to change the select's visual appearance.
|
||||
|
||||
```html {.example}
|
||||
<label>Select
|
||||
<select id="select" class="wa-filled">
|
||||
<option value="option-1">Option 1</option>
|
||||
<option value="option-2">Option 2</option>
|
||||
<option value="option-3">Option 3</option>
|
||||
</select>
|
||||
</label>
|
||||
```
|
||||
|
||||
### Grouping options
|
||||
|
||||
In [modern browsers](https://caniuse.com/mdn-html_elements_select_hr_in_select), you can use the `<hr>` element as a divider:
|
||||
|
||||
```html {.example}
|
||||
<select>
|
||||
<small>Section 1</small>
|
||||
<option value="option-1">Option 1</option>
|
||||
<option value="option-2">Option 2</option>
|
||||
<option value="option-3">Option 3</option>
|
||||
<hr />
|
||||
<small>Section 2</small>
|
||||
<option value="option-4">Option 4</option>
|
||||
<option value="option-5">Option 5</option>
|
||||
<option value="option-6">Option 6</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
To provide labels, you can use the `<optgroup>` element (with or without dividers):
|
||||
|
||||
```html {.example}
|
||||
<select>
|
||||
<optgroup label="Section 1">
|
||||
<option value="option-1">Option 1</option>
|
||||
<option value="option-2">Option 2</option>
|
||||
<option value="option-3">Option 3</option>
|
||||
</optgroup>
|
||||
<optgroup label="Section 2">
|
||||
<option value="option-4">Option 4</option>
|
||||
<option value="option-5">Option 5</option>
|
||||
<hr />
|
||||
<option value="option-6">Option 6</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
```
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
title: Slider
|
||||
description: Sliders allow the user to select a single value within a given range using a slider.
|
||||
tags: forms
|
||||
layout: element
|
||||
icon: slider
|
||||
component: slider
|
||||
elements:
|
||||
"<input type=range>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
|
||||
file: styles/native/slider.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<label>Select a value: <input type="range"></label>
|
||||
```
|
||||
|
||||
### Min, Max, and Step
|
||||
|
||||
Use the `min` and `max` attributes to set the range's minimum and maximum values, respectively. The `step` attribute determines the value's interval when increasing and decreasing.
|
||||
|
||||
```html {.example}
|
||||
<input type="range" min="0" max="10" step="1">
|
||||
```
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a slider.
|
||||
|
||||
```html {.example}
|
||||
<input type="range" disabled>
|
||||
```
|
||||
|
||||
<!--
|
||||
### Custom Track Colors
|
||||
|
||||
You can customize the active and inactive portions of the track using the `--track-color-active` and `--track-color-inactive` custom properties.
|
||||
|
||||
```html {.example}
|
||||
<input type="range"
|
||||
style="
|
||||
--track-color-active: var(--wa-color-brand-fill-loud);
|
||||
--track-color-inactive: var(--wa-color-brand-fill-normal);
|
||||
"
|
||||
>
|
||||
```
|
||||
|
||||
### Right-to-Left languages
|
||||
|
||||
The styles adapt to right-to-left (RTL) languages as you would expect.
|
||||
|
||||
```html {.example}
|
||||
<input type="range" dir=rtl>
|
||||
```
|
||||
-->
|
||||
@@ -1,136 +0,0 @@
|
||||
---
|
||||
title: Table
|
||||
description: 'Table styles apply your Web Awesome theme to the HTML table content. Tables structure data in rows and columns, making it easy to look up information in a complex data set.'
|
||||
tags: content
|
||||
elements:
|
||||
"<table>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
|
||||
file: styles/native/tables.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<table>
|
||||
<caption>I'm just a table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
<th>Column 3</th>
|
||||
<th>Column 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
## Alternating Rows
|
||||
|
||||
You can use the `wa-zebra-rows` class to add alternating row colors to your table:
|
||||
|
||||
```html {.example}
|
||||
<table class="wa-zebra-rows">
|
||||
<caption>I'm just a table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
<th>Column 3</th>
|
||||
<th>Column 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
## Variants
|
||||
|
||||
You can use [color utility classes](/docs/utilities/colors) to apply different colors to your table:
|
||||
|
||||
```html {.example}
|
||||
<table class="wa-zebra-rows wa-brand">
|
||||
<caption>I'm just a table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
<th>Column 3</th>
|
||||
<th>Column 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Textarea
|
||||
description: Textareas collect data from the user and allow multiple lines of text.
|
||||
tags: forms
|
||||
icon: textarea
|
||||
component: textarea
|
||||
elements:
|
||||
"<textarea>": https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea
|
||||
file: styles/native/input.css
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<label>Textarea <textarea></textarea></label>
|
||||
```
|
||||
|
||||
### Placeholders
|
||||
|
||||
Use the `placeholder` attribute to add a placeholder.
|
||||
|
||||
```html {.example}
|
||||
<textarea placeholder="Type something"></textarea>
|
||||
```
|
||||
|
||||
### Appearance
|
||||
|
||||
Use the [appearence utilities](/docs/utilities/appearance/) to change the textarea's visual appearance.
|
||||
|
||||
```html {.example}
|
||||
<textarea placeholder="Type something" class="wa-filled"></textarea>
|
||||
```
|
||||
|
||||
### Expand with Content
|
||||
|
||||
You can use `field-sizing: content` in [browsers that support it](https://caniuse.com/mdn-css_properties_field-sizing) to make the textarea grow as the user types:
|
||||
|
||||
```html {.example}
|
||||
<textarea placeholder="Type something" style="field-sizing: content"></textarea>
|
||||
```
|
||||
@@ -23,7 +23,8 @@ wa-dropdown > .color.swatch {
|
||||
--track-color-inactive: transparent;
|
||||
--track-color-active: transparent;
|
||||
--thumb-color: var(--color-tweaked, var(--color));
|
||||
--thumb-shadow: 0 0 0 var(--thumb-gap) var(--wa-color-surface-default),
|
||||
--thumb-shadow:
|
||||
0 0 0 var(--thumb-gap) var(--wa-color-surface-default),
|
||||
var(--wa-shadow-offset-x-m) var(--wa-shadow-offset-y-m) var(--wa-shadow-blur-m)
|
||||
calc(var(--wa-shadow-offset-x-m) * -1 + var(--thumb-gap)) var(--wa-color-shadow);
|
||||
|
||||
|
||||
@@ -115,11 +115,11 @@ isPro: true
|
||||
<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 appearance="button" value="0">None</wa-radio>
|
||||
<wa-radio appearance="button" value="5">5</wa-radio>
|
||||
<wa-radio appearance="button" value="10">10</wa-radio>
|
||||
<wa-radio appearance="button" value="50">50</wa-radio>
|
||||
<wa-radio appearance="button" value="100">100</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-divider></wa-divider>
|
||||
<wa-switch hint="Members are removed after logging out." checked>Temporary Access</wa-switch>
|
||||
|
||||
@@ -153,29 +153,29 @@ isPro: true
|
||||
</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-radio appearance="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-radio>
|
||||
<wa-radio appearance="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-radio>
|
||||
<wa-radio appearance="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-radio>
|
||||
<wa-radio appearance="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>
|
||||
</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 appearance="button" value="xs">XS</wa-radio>
|
||||
<wa-radio appearance="button" value="s">S</wa-radio>
|
||||
<wa-radio appearance="button" value="m">M</wa-radio>
|
||||
<wa-radio appearance="button" value="l">L</wa-radio>
|
||||
<wa-radio appearance="button" value="xl">XL</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-button variant="brand">
|
||||
<wa-icon slot="prefix" name="cart-plus" variant="solid"></wa-icon>
|
||||
@@ -228,21 +228,21 @@ isPro: true
|
||||
<a href="#">144 Reviews</a>
|
||||
</div>
|
||||
<wa-radio-group label="Color" name="color" value="black" orientation="horizontal">
|
||||
<wa-radio-button value="black">
|
||||
<wa-radio appearance="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-radio>
|
||||
<wa-radio appearance="button" value="gray">
|
||||
<wa-icon slot="prefix" name="shirt" style="color: gray;"></wa-icon>
|
||||
Faded Gray
|
||||
</wa-radio-button>
|
||||
</wa-radio>
|
||||
</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 appearance="button" value="xs">XS</wa-radio>
|
||||
<wa-radio appearance="button" value="s">S</wa-radio>
|
||||
<wa-radio appearance="button" value="m">M</wa-radio>
|
||||
<wa-radio appearance="button" value="l">L</wa-radio>
|
||||
<wa-radio appearance="button" value="xl">XL</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-button variant="brand">
|
||||
<wa-icon slot="prefix" name="bag-shopping" variant="solid"></wa-icon>
|
||||
@@ -329,25 +329,25 @@ isPro: true
|
||||
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-radio appearance="button" value="sand">
|
||||
<wa-icon slot="prefix" name="circle" style="color: burlywood;"></wa-icon>
|
||||
Sand
|
||||
</wa-radio-button>
|
||||
<wa-radio-button value="shale">
|
||||
</wa-radio>
|
||||
<wa-radio appearance="button" value="shale">
|
||||
<wa-icon slot="prefix" name="circle" style="color: silver;"></wa-icon>
|
||||
Shale
|
||||
</wa-radio-button>
|
||||
<wa-radio-button value="slate">
|
||||
</wa-radio>
|
||||
<wa-radio appearance="button" value="slate">
|
||||
<wa-icon slot="prefix" name="circle" style="color: dimgray;"></wa-icon>
|
||||
Slate
|
||||
</wa-radio-button>
|
||||
</wa-radio>
|
||||
</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 appearance="button" value="xs">XS</wa-radio>
|
||||
<wa-radio appearance="button" value="s">S</wa-radio>
|
||||
<wa-radio appearance="button" value="m">M</wa-radio>
|
||||
<wa-radio appearance="button" value="l">L</wa-radio>
|
||||
<wa-radio appearance="button" value="xl">XL</wa-radio>
|
||||
</wa-radio-group>
|
||||
<wa-button variant="brand">Add to Cart</wa-button>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ Patterns are written as standard HTML, so you can use them just as you would any
|
||||
|
||||
To use a pattern in your project, refer to each pattern's docs for a copyable code snippet. Paste the snippet wherever you'd like the pattern to appear in your project.
|
||||
|
||||
Because patterns use a combination of Web Awesome features, they work best when you have [native styles](/docs/native), [style utilities](/docs/utilities), and a [theme](/docs/themes) installed in addition to Web Awesome [components](/docs/components). Refer to the [Installation page](/docs/) to set up all of these features in your project.
|
||||
Because patterns use a combination of Web Awesome features, they work best when you have [native styles](/docs/utilities/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>
|
||||
|
||||
@@ -14,6 +14,10 @@ During the alpha period, things might break! We take breaking changes very serio
|
||||
|
||||
## Next
|
||||
|
||||
- 🚨 BREAKING: Greatly simplified how native styles work and removed redundant utilities
|
||||
- Removed `.wa-button`, `.wa-callout` classes
|
||||
- Removed `themes/native/*.css` files; use `native.css` to opt into native styles
|
||||
- Clarified which utilities classes can be applied to which native elements
|
||||
- 🚨 BREAKING: Removed the extra dash in the `<wa-carousel>` CSS part name `pagination-item--active` => `pagination-item-active`
|
||||
- 🚨 BREAKING: Renamed the `classic` theme to `shoelace`
|
||||
- 🚨 BREAKING: Renamed `pulse` attribute in `<wa-badge>` to `attention="pulse"` and added `attention="bounce"` [issue:#940]
|
||||
@@ -26,9 +30,14 @@ During the alpha period, things might break! We take breaking changes very serio
|
||||
- `<wa-select clearable>` => `<wa-select with-clear>`
|
||||
- `<wa-tab-group no-scroll-controls>` => `<wa-tab-group without-scroll-controls>`
|
||||
- `<wa-tag removable>` => `<wa-tag with-remove>`
|
||||
- 🚨 BREAKING: removed the `size` attribute from `<wa-card>`; please set the size of child elements on the children directly
|
||||
- Added a `min-block-size` to `<wa-divider orientation="vertical">` to ensure the divider is visible regardless of container height [issue:675]
|
||||
- Fixed a bug in `<wa-radio-group>` that caused radios to uncheck when assigning a numeric value [issue:924]
|
||||
- Fixed `<wa-button-group>` so dividers properly show between buttons
|
||||
- Fixed the tooltip position in `<wa-slider>` when using RTL
|
||||
- Fixed a bug in `<wa-details>` and native `<details>` styles that made the summary hard to click [issue:684]
|
||||
- Improved CSS utilities and Native Styles to use [CSS layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) for easier end user customization (no more specificity conflicts — your CSS wins!)
|
||||
- Improved native `<button>` styles to properly space icons
|
||||
- Removed the experimental `<wa-code-demo>` component
|
||||
|
||||
## 3.0.0-alpha.13
|
||||
@@ -53,7 +62,7 @@ During the alpha period, things might break! We take breaking changes very serio
|
||||
|
||||
### 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 `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/utilities/native/details).
|
||||
- Added an `orange` scale to all color palettes
|
||||
- Added the [`.wa-cloak` utility](/docs/utilities/fouce) to prevent FOUCE
|
||||
- Added the [`allDefined()` utility](/docs/usage/#all-defined) for awaiting component registration
|
||||
@@ -78,7 +87,7 @@ During the alpha period, things might break! We take breaking changes very serio
|
||||
- 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 the missing indeterminate icon in [native checkbox styles](/docs/utilities/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
|
||||
@@ -224,13 +233,13 @@ You can find them in the first column of each color palette.
|
||||
### Native styles
|
||||
|
||||
- Added native styles for
|
||||
[buttons](/docs/native/button),
|
||||
[input fields](/docs/native/input),
|
||||
[dialogs](/docs/native/dialog),
|
||||
[details](/docs/native/details),
|
||||
[tables](/docs/native/table),
|
||||
[lists](/docs/native/lists),
|
||||
and most [content elements](/docs/native/content).
|
||||
[buttons](/docs/utilities/native/button),
|
||||
[input fields](/docs/utilities/native/input),
|
||||
[dialogs](/docs/utilities/native/dialog),
|
||||
[details](/docs/utilities/native/details),
|
||||
[tables](/docs/utilities/native/table),
|
||||
[lists](/docs/utilities/native/lists),
|
||||
and most [content elements](/docs/utilities/native/content).
|
||||
|
||||
### Style utilities
|
||||
|
||||
|
||||
@@ -355,13 +355,7 @@ TL;DR – a component is a dependency if and only if it's rendered inside anothe
|
||||
|
||||
Many Web Awesome components use other Web Awesome components internally. For example, `<wa-button>` uses both `<wa-icon>` and `<wa-spinner>` for its caret icon and loading state, respectively. Since these components appear in the button's shadow root, they are considered dependencies of Button. Since dependencies are automatically loaded, users only need to import the button and everything will work as expected.
|
||||
|
||||
Contrast this to `<wa-select>` and `<wa-option>`. At first, one might assume that Option is a dependency of Select. After all, you can't really use Select without slotting in at least one Option. However, Option _is not_ a dependency of Select! The reason is because no Option is rendered in the Select's shadow root. Since the options are provided by the user, it's up to them to import both components independently.
|
||||
|
||||
People often suggest that Web Awesome should auto-load Select + Option, Menu + Menu Item, Breadcrumb + Breadcrumb Item, etc. Although some components are designed to work together, they're technically not dependencies so eagerly loading them may not be desirable. What if someone wants to roll their own component with a superset of features? They wouldn't be able to if Web Awesome automatically imported it!
|
||||
|
||||
Similarly, in the case of `<wa-radio-group>` there was originally only `<wa-radio>`, but now you can use either `<wa-radio>` or `<wa-radio-button>` as child elements. Which component(s) should be auto-loaded dependencies in this case? Had Radio been a dependency of Radio Group, users that only wanted Radio Buttons would be forced to register both with no way to opt out and no way to provide their own customized version.
|
||||
|
||||
For non-dependencies, _the user_ should decide what gets registered, even if it comes with a minor inconvenience.
|
||||
The rule of thumb for dependencies is: if a component is rendered _inside_ a host element's shadow root OR if the component is required to be slotted in by the user (e.g. `<wa-radio-group>` + `<wa-radio>`), it's a dependency.
|
||||
|
||||
### Form Controls
|
||||
|
||||
|
||||
@@ -27,40 +27,18 @@ wide: true
|
||||
--width: var(--wa-border-width-m);
|
||||
--spacing: var(--wa-space-3xl);
|
||||
}
|
||||
.test-failure::before {
|
||||
content: '\f071';
|
||||
color: red;
|
||||
font-family: 'Font Awesome 6 Duotone', 'Font Awesome 6 Free';
|
||||
font-size: 1em;
|
||||
font-weight: 900;
|
||||
margin-inline-end: 0.5rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
With so many ways to build with and use Web Awesome components, visual tests help ensure consistency and prevent broken styles from leaking into production.
|
||||
|
||||
These tests can come in handy when creating or customizing your own theme. Look through each test case to make sure that custom styles in your theme cover all of the attributes, utilities, and built-in styles Web Awesome offers.
|
||||
|
||||
Known test failures that affect the entire library, regardless of theme, are indicated by <wa-icon name="triangle-exclamation" family="duotone" style="color: red;" label="alert icon"></wa-icon> and will be addressed in a future release.
|
||||
|
||||
<wa-tab-group>
|
||||
<wa-tab panel="appearance">Appearance</wa-tab>
|
||||
<wa-tab panel="alignment">Alignment</wa-tab>
|
||||
<wa-tab panel="native">Native</wa-tab>
|
||||
<wa-tab panel="color">Color</wa-tab>
|
||||
<wa-tab panel="harmony">Harmony</wa-tab>
|
||||
<wa-tab panel="native">Native Styles</wa-tab>
|
||||
<wa-tab panel="size">Size</wa-tab>
|
||||
|
||||
<wa-tab-panel name="appearance">
|
||||
|
||||
## Appearance
|
||||
|
||||
Appearance tests ensure that both the `appearance` attribute and `.wa-[appearance]` classes have identical results for components that support them. Developers should be able to use both of these interchangeably on components to get the intended look and feel.
|
||||
|
||||
{% include 'visual-tests/appearance.njk' %}
|
||||
|
||||
</wa-tab-panel>
|
||||
<wa-tab panel="alignment">Alignment</wa-tab>
|
||||
<wa-tab panel="harmony">Harmony</wa-tab>
|
||||
|
||||
<wa-tab-panel name="alignment">
|
||||
|
||||
@@ -94,9 +72,9 @@ Harmony tests show how related components look together. These can help validate
|
||||
|
||||
<wa-tab-panel name="native">
|
||||
|
||||
## Native Styles
|
||||
## Native
|
||||
|
||||
Native styles tests ensure that supported native elements and component utilities look the same as their Web Awesome component counterparts. Native elements and component utilities may also support the same [appearance](/docs/utilities/appearance/), [color](/docs/utilities/color/), and [size](/docs/utilities/size/) utilities as components.
|
||||
Native style tests ensure that supported native elements and utilities look the same as their Web Awesome component counterparts. Native elements may also support the same appearance, color, and size utilities as components.
|
||||
|
||||
{% include 'visual-tests/native.njk' %}
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
title: CSS Properties Benchmark
|
||||
unlisted: true
|
||||
wide: true
|
||||
---
|
||||
|
||||
{% set icons = {
|
||||
check: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>',
|
||||
'chevron-down': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>',
|
||||
'chevron-left': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/></svg>',
|
||||
'chevron-right': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>',
|
||||
circle: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/></svg>',
|
||||
'eye-dropper': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M341.6 29.2L240.1 130.8l-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4L482.8 170.4c39-39 39-102.2 0-141.1s-102.2-39-141.1 0zM55.4 323.3c-15 15-23.4 35.4-23.4 56.6v42.4L5.4 462.2c-8.5 12.7-6.8 29.6 4 40.4s27.7 12.5 40.4 4L89.7 480h42.4c21.2 0 41.6-8.4 56.6-23.4L309.4 335.9l-45.3-45.3L143.4 411.3c-3 3-7.1 4.7-11.3 4.7H96V379.9c0-4.2 1.7-8.3 4.7-11.3L221.4 247.9l-45.3-45.3L55.4 323.3z"/></svg>',
|
||||
'grip-vertical': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M40 352l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zm192 0l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 320c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 192l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 160c-22.1 0-40-17.9-40-40L0 72C0 49.9 17.9 32 40 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40z"/></svg>',
|
||||
indeterminate: '<svg part="indeterminate-icon" class="icon" viewBox="0 0 16 16"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"><g stroke="currentColor" stroke-width="2"><g transform="translate(2.285714, 6.857143)"><path d="M10.2857143,1.14285714 L1.14285714,1.14285714"></path></g></g></g></svg>',
|
||||
minus: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg>',
|
||||
pause: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z"/></svg>',
|
||||
play: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg>',
|
||||
star: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><path d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg>',
|
||||
user: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg>',
|
||||
xmark: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>'
|
||||
} %}
|
||||
|
||||
<style>
|
||||
.icon-tests {
|
||||
font-size: .5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
wa-icon {
|
||||
transition: 1s font-size;
|
||||
&:hover {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{% set repetitions = 200 %}
|
||||
|
||||
<h2>Setting everything via attributes</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}" variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting variant & family via CSS</h2>
|
||||
|
||||
<div class="icon-tests" style="--wa-icon-variant: regular; --wa-icon-family: classic">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting name via CSS</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
<span style="--wa-icon-name: {{ icon }}">
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
2
docs/docs/themes/matter.md
vendored
2
docs/docs/themes/matter.md
vendored
@@ -74,7 +74,7 @@ If you want it to start from the position the button was clicked, you can use th
|
||||
document.addEventListener("mousedown", evt => {
|
||||
let target = evt.target;
|
||||
|
||||
if (!target.matches?.('wa-button, button, .wa-button')) {
|
||||
if (!target.matches?.('wa-button, button')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
---
|
||||
title: Appearance Variants
|
||||
description: Appearance utilities apply a collection of properties to achieve certain effects, like making elements accented, outlined, filled, or plain.
|
||||
snippets:
|
||||
- .wa-accent
|
||||
- .wa-outlined
|
||||
- .wa-filled
|
||||
- .wa-plain
|
||||
file: styles/utilities/appearance.css
|
||||
---
|
||||
|
||||
Some Web Awesome components, like `<wa-button>`, allow you to change their overall style by using an `appearance` attribute:
|
||||
|
||||
{% for component in componentsBy.attribute.appearance %}
|
||||
- <a href="../{{ component.url }}"><code><{{ component.tagName }}></code></a>
|
||||
{%- endfor %}
|
||||
|
||||
You can create the same effect on any element by using the appearance utility classes:
|
||||
|
||||
- `.wa-accent`
|
||||
- `.wa-outlined`
|
||||
- `.wa-filled`
|
||||
- `.wa-plain`
|
||||
|
||||
Using these classes is a two-way handshake:
|
||||
they do not directly apply styles, but define custom properties that you can use in styles that should respond to these utilities:
|
||||
- `--background-color`
|
||||
- `--background-color-hover`
|
||||
- `--background-color-active`
|
||||
- `--border-color`
|
||||
- `--border-color-hover`
|
||||
- `--text-color`
|
||||
- `--text-color-hover`
|
||||
|
||||
Then you can use (some of) these properties in any class that should respond to these.
|
||||
|
||||
For example, assume we wanted to make a custom `.badge` class with appearance variants.
|
||||
This is all we need to do:
|
||||
|
||||
```html { .example }
|
||||
<small class="badge wa-accent">Accent</small>
|
||||
<small class="badge wa-outlined">Outlined</small>
|
||||
<small class="badge wa-filled">Filled</small>
|
||||
<small class="badge wa-plain">Plain</small>
|
||||
|
||||
<style>
|
||||
.badge {
|
||||
background-color: var(--background-color);
|
||||
border: 1px solid var(--border-color);
|
||||
color: var(--text-color);
|
||||
padding: var(--wa-space-2xs) var(--wa-space-xs);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## With Color Variants
|
||||
|
||||
These properties also work well with the [color variants](/docs/utilities/color/) utility classes:
|
||||
|
||||
```html { .example }
|
||||
<div class="wa-stack">
|
||||
<div class="wa-brand">
|
||||
<small class="badge wa-accent">Accent</small>
|
||||
<small class="badge wa-outlined">Outlined</small>
|
||||
<small class="badge wa-filled">Filled</small>
|
||||
<small class="badge wa-plain">Plain</small>
|
||||
</div>
|
||||
<div class="wa-danger">
|
||||
<small class="badge wa-accent">Accent</small>
|
||||
<small class="badge wa-outlined">Outlined</small>
|
||||
<small class="badge wa-filled">Filled</small>
|
||||
<small class="badge wa-plain">Plain</small>
|
||||
</div>
|
||||
<div class="wa-warning">
|
||||
<small class="badge wa-accent">Accent</small>
|
||||
<small class="badge wa-outlined">Outlined</small>
|
||||
<small class="badge wa-filled">Filled</small>
|
||||
<small class="badge wa-plain">Plain</small>
|
||||
</div>
|
||||
<div class="wa-success">
|
||||
<small class="badge wa-accent">Accent</small>
|
||||
<small class="badge wa-outlined">Outlined</small>
|
||||
<small class="badge wa-filled">Filled</small>
|
||||
<small class="badge wa-plain">Plain</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.badge {
|
||||
background-color: var(--background-color);
|
||||
border: 1px solid var(--border-color);
|
||||
color: var(--text-color);
|
||||
padding: var(--wa-space-2xs) var(--wa-space-xs);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
title: Color Variants
|
||||
description: Color utilities allow you to apply the brand, neutral, success, warning, and danger colors from your theme to any element.
|
||||
icon: tokens/color
|
||||
snippets:
|
||||
- .wa-brand
|
||||
- .wa-neutral
|
||||
- .wa-success
|
||||
- .wa-warning
|
||||
- .wa-danger
|
||||
file: styles/utilities/variants.css
|
||||
---
|
||||
|
||||
@@ -30,7 +24,7 @@ You can create the same effect on any element by using the color variant utility
|
||||
Using these classes is a two-way handshake:
|
||||
they do not directly apply styles, but define generic color tokens modeled after our [Semantic Colors](/docs/tokens/color/#semantic-colors) but *without* the group identifier (`neutral`, `brand`, `success`, `warning`, `danger`), defaulting to `neutral`.
|
||||
This means that styles can be written to respond to variants by using e.g. `--wa-color-fill-loud` instead of e.g. `--wa-color-brand-fill-loud`,
|
||||
and all of our [native styles](/docs/native/) do so (where it made sense).
|
||||
and all of our [native styles](/docs/utilities/native/) do so (where it made sense).
|
||||
|
||||
For example, assume we wanted to make a custom `.callout` class with color variants.
|
||||
This is all we need to do:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Reduce FOUCE
|
||||
title: Reducing FOUCE
|
||||
description: Utility to improve the loading experience by hiding non-prerendered custom elements until they are registered.
|
||||
file: styles/utilities/fouce.css
|
||||
icon: spinner
|
||||
|
||||
@@ -10,7 +10,7 @@ override:tags: []
|
||||
{% markdown %}
|
||||
## Installation
|
||||
|
||||
To use all Web Awesome page styles (including [native styles](/docs/native/)), include the following stylesheet in your project:
|
||||
To use all Web Awesome page styles (including [native styles](/docs/utilities/native/)), include the following stylesheet in your project:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/webawesome.css' %}" />
|
||||
|
||||
456
docs/docs/utilities/native.md
Normal file
456
docs/docs/utilities/native.md
Normal file
@@ -0,0 +1,456 @@
|
||||
---
|
||||
title: Native Styles
|
||||
description: Native styles apply your theme to native HTML elements so they match the look and feel of Web Awesome components.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# Web Awesome Native Styles
|
||||
|
||||
Web Awesome provides optional Native Styles that make native HTML elements look good so you can continue using what you know and gradually adopt Web Awesome as you see fit.
|
||||
|
||||
## Installation
|
||||
|
||||
To use all Web Awesome page styles (including [utilities](/docs/utilities/)), include the following stylesheet in your project:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/webawesome.css' %}" />
|
||||
```
|
||||
|
||||
Or, to _only_ include styles for native elements:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="{% cdnUrl 'styles/native.css' %}" />
|
||||
```
|
||||
|
||||
## Elements
|
||||
|
||||
### Headings
|
||||
|
||||
Semantic heading elements with proper hierarchy and styling.
|
||||
|
||||
```html {.example}
|
||||
<h1>Heading 1</h1>
|
||||
<h2>Heading 2</h2>
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h6>Heading 6</h6>
|
||||
```
|
||||
|
||||
### Paragraphs
|
||||
|
||||
Standard paragraph text with optimal spacing and readability.
|
||||
|
||||
```html {.example}
|
||||
<p>Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Amet mauris commodo quis imperdiet. Bibendum ut tristique et egestas quis ipsum suspendisse. Sit amet nulla facilisi morbi tempus iaculis urna id volutpat.</p>
|
||||
|
||||
<p>Cras pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci. Scelerisque eleifend donec pretium vulputate sapien nec. Donec et odio pellentesque diam volutpat commodo sed egestas egestas. Mauris rhoncus aenean vel elit scelerisque mauris pellentesque.</p>
|
||||
```
|
||||
|
||||
### Blockquotes
|
||||
|
||||
Styled quotations that stand out from regular text.
|
||||
|
||||
```html {.example}
|
||||
<blockquote>
|
||||
What is a Web year now, about three months? And when people can browse around, discover new things, and download them fast, when we all have agents - then Web years could slip by before human beings can notice.<br><br>
|
||||
— Tim Berners-Lee
|
||||
</blockquote>
|
||||
```
|
||||
|
||||
### Lists
|
||||
|
||||
Organized content in bulleted or numbered format with proper nesting support.
|
||||
|
||||
```html {.example}
|
||||
<ul>
|
||||
<li>List item 1</li>
|
||||
<li>List item 2
|
||||
<ul>
|
||||
<li>Subitem a</li>
|
||||
<li>Subitem b</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>List item 3</li>
|
||||
</ul>
|
||||
|
||||
<ol>
|
||||
<li>List item 1</li>
|
||||
<li>List item 2
|
||||
<ul>
|
||||
<li>Subitem a</li>
|
||||
<li>Subitem b</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>List item 3</li>
|
||||
</ol>
|
||||
```
|
||||
|
||||
### Definition Lists
|
||||
|
||||
Term and definition pairs for glossaries and descriptions.
|
||||
|
||||
```html {.example}
|
||||
<dl>
|
||||
<dt>Definition 1</dt>
|
||||
<dd>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.</dd>
|
||||
<dt>Definition 2</dt>
|
||||
<dd>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</dd>
|
||||
<dt>Definition 3</dt>
|
||||
<dd>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</dd>
|
||||
</dl>
|
||||
```
|
||||
|
||||
### Details
|
||||
|
||||
Collapsible content sections with expand/collapse functionality.
|
||||
|
||||
```html {.example}
|
||||
<details>
|
||||
<summary>Tincidunt nunc pulvinar</summary>
|
||||
<p>Ut lectus arcu bibendum at varius. Convallis a cras semper auctor neque vitae. Odio pellentesque diam volutpat commodo sed egestas. Amet dictum sit amet justo donec enim diam vulputate ut.</p>
|
||||
</details>
|
||||
```
|
||||
|
||||
### Dialog
|
||||
|
||||
Modal dialog windows for alerts, confirmations, and overlays.
|
||||
|
||||
```html {.example}
|
||||
<dialog id="dialog-example">
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
||||
<button type="button">Close</button>
|
||||
</dialog>
|
||||
|
||||
<button>Open Dialog</button>
|
||||
|
||||
<script>
|
||||
const dialog = document.querySelector('#dialog-example');
|
||||
const openButton = dialog.nextElementSibling;
|
||||
const closeButton = dialog.querySelector('button');
|
||||
|
||||
openButton.addEventListener('click', () => dialog.showModal());
|
||||
closeButton.addEventListener('click', () => dialog.close());
|
||||
</script>
|
||||
```
|
||||
|
||||
### Inline Text
|
||||
|
||||
Various text formatting elements for emphasis and semantic meaning.
|
||||
|
||||
```html {.example}
|
||||
<div class="two-columns">
|
||||
<p><strong>Bold</strong></p>
|
||||
<p><em>Italics</em></p>
|
||||
<p><u>Underline</u></p>
|
||||
<p><del>Deleted</del></p>
|
||||
<p><ins>Inserted</ins></p>
|
||||
<p><s>Strike-through</s></p>
|
||||
<p><small>Small</small></p>
|
||||
<p><span>Text <sub>Sub</sub></span></p>
|
||||
<p><span>Text <sup>Sup</sup></span></p>
|
||||
<p><abbr title="Abbreviation">Abbr.</abbr></p>
|
||||
<p><kbd>Keyboard</kbd></p>
|
||||
<p><mark>Highlighted</mark></p>
|
||||
<p><a href="#">Link text</a></p>
|
||||
<p><code>Inline code</code></p>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Code Blocks
|
||||
|
||||
Formatted code snippets with proper syntax styling.
|
||||
|
||||
```
|
||||
// do a thing
|
||||
export function thing() {
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### Images
|
||||
|
||||
Responsive images with proper scaling and styling.
|
||||
|
||||

|
||||
|
||||
### Progress Bars
|
||||
|
||||
Visual indicators for task completion and loading states.
|
||||
|
||||
```html {.example}
|
||||
<progress value="40" max="100"></progress>
|
||||
<br>
|
||||
<progress></progress>
|
||||
```
|
||||
|
||||
### Tables
|
||||
|
||||
Structured data presentation with clean styling and optional zebra striping.
|
||||
|
||||
```html {.example}
|
||||
<table>
|
||||
<caption>I'm just a table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
<th>Column 3</th>
|
||||
<th>Column 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
You can use the `wa-zebra-rows` class to add alternating row colors to your table:
|
||||
|
||||
```html {.example}
|
||||
<table class="wa-zebra-rows">
|
||||
<caption>I'm just a table</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1</th>
|
||||
<th>Column 2</th>
|
||||
<th>Column 3</th>
|
||||
<th>Column 4</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
<td>Cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
## Form Controls
|
||||
|
||||
### Buttons
|
||||
|
||||
Use the [variant utility classes](../utilities/color.md) to set the button's semantic variant.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-neutral"><wa-icon name="home"></wa-icon> Neutral</button>
|
||||
<button class="wa-brand">Brand</button>
|
||||
<button class="wa-success">Success</button>
|
||||
<button class="wa-warning">Warning</button>
|
||||
<button class="wa-danger">Danger</button>
|
||||
```
|
||||
|
||||
Use the [appearance utility classes](/docs/utilities/appearance) to change the button's visual appearance:
|
||||
|
||||
```html {.example}
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-neutral">A + O</button>
|
||||
<button class="wa-accent wa-neutral">Accent</button>
|
||||
<button class="wa-outlined wa-neutral">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-neutral">F + O</button>
|
||||
<button class="wa-filled wa-neutral">Filled</button>
|
||||
<button class="wa-plain wa-neutral">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-brand">A + O</button>
|
||||
<button class="wa-accent wa-brand">Accent</button>
|
||||
<button class="wa-outlined wa-brand">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-brand">F + O</button>
|
||||
<button class="wa-filled wa-brand">Filled</button>
|
||||
<button class="wa-plain wa-brand">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-success">A + O</button>
|
||||
<button class="wa-accent wa-success">Accent</button>
|
||||
<button class="wa-outlined wa-success">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-success">F + O</button>
|
||||
<button class="wa-filled wa-success">Filled</button>
|
||||
<button class="wa-plain wa-success">Plain</button>
|
||||
</div>
|
||||
<div style="margin-block-end: 1rem;">
|
||||
<button class="wa-accent wa-outlined wa-warning">A + O</button>
|
||||
<button class="wa-accent wa-warning">Accent</button>
|
||||
<button class="wa-outlined wa-warning">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-warning">F + O</button>
|
||||
<button class="wa-filled wa-warning">Filled</button>
|
||||
<button class="wa-plain wa-warning">Plain</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="wa-accent wa-outlined wa-danger">A + O</button>
|
||||
<button class="wa-accent wa-danger">Accent</button>
|
||||
<button class="wa-outlined wa-danger">Outlined</button>
|
||||
<button class="wa-filled wa-outlined wa-danger">F + O</button>
|
||||
<button class="wa-filled wa-danger">Filled</button>
|
||||
<button class="wa-plain wa-danger">Plain</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
Use the [size utility classes](../utilities/size.md) to change a button's size.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-size-s">Small</button>
|
||||
<button class="wa-size-m">Medium</button>
|
||||
<button class="wa-size-l">Large</button>
|
||||
```
|
||||
|
||||
Use the `wa-pill` class to give buttons rounded edges.
|
||||
|
||||
```html {.example}
|
||||
<button class="wa-size-s wa-pill">Small</button>
|
||||
<button class="wa-size-m wa-pill">Medium</button>
|
||||
<button class="wa-size-l wa-pill">Large</button>
|
||||
```
|
||||
|
||||
### Checkboxes
|
||||
|
||||
Multi-select form controls with checked, indeterminate, and disabled states.
|
||||
|
||||
```html {.example}
|
||||
<label><input type="checkbox" checked> Checked</label><br>
|
||||
<label><input type="checkbox" class="indeterminate"> Indeterminate</label><br>
|
||||
<label><input type="checkbox" disabled> Disabled</label>
|
||||
|
||||
<script>
|
||||
document.querySelector(".indeterminate").indeterminate = true;
|
||||
</script>
|
||||
```
|
||||
|
||||
### Radios
|
||||
|
||||
Single-select form controls for mutually exclusive choices.
|
||||
|
||||
You can wrap native radios in a flex container to give them a horizontal or vertical orientation with even spacing. The convenience [`wa-cluster`](/docs/utilities/cluster) and [`wa-stack`](/docs/utilities/stack) utilities make this easy.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<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>
|
||||
|
||||
<div class="wa-stack" style="margin-block-start: var(--wa-space-2xl);">
|
||||
<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>
|
||||
```
|
||||
|
||||
### Selects
|
||||
|
||||
Dropdown menus for choosing from a list of options.
|
||||
|
||||
```html {.example}
|
||||
<label>Select
|
||||
<select id="select">
|
||||
<option value="option-1">Option 1</option>
|
||||
<option value="option-2">Option 2</option>
|
||||
<option value="option-3">Option 3</option>
|
||||
</select>
|
||||
</label>
|
||||
```
|
||||
|
||||
### Sliders
|
||||
|
||||
Range inputs for selecting numeric values within a specified range.
|
||||
|
||||
```html {.example}
|
||||
<label>Select a value: <input type="range"></label>
|
||||
```
|
||||
|
||||
### Text Fields
|
||||
|
||||
Various input types for collecting user text and data.
|
||||
|
||||
```html {.example}
|
||||
<label>Text <input type="text" placeholder="placeholder"></label>
|
||||
|
||||
<label>Number <input type="number"></label>
|
||||
|
||||
<label>Password <input type="password" required></label>
|
||||
|
||||
<label>Email <input type="email"></label>
|
||||
|
||||
<label>Search <input type="search"></label>
|
||||
|
||||
<label>Telephone <input type="tel"></label>
|
||||
|
||||
<label>URL <input type="url"></label>
|
||||
```
|
||||
|
||||
Add the `wa-pill` class to an `<input>` to make it pill-shaped.
|
||||
|
||||
```html {.example}
|
||||
<label>Input <input type="text" placeholder="placeholder" class="wa-pill"></label>
|
||||
```
|
||||
|
||||
### Color Pickers
|
||||
|
||||
Visual color selection interface with hex value input.
|
||||
|
||||
```html {.example}
|
||||
<label>Input (color) <input type="color" value="#ff0066"></label>
|
||||
```
|
||||
|
||||
### Date & Time Pickers
|
||||
|
||||
Specialized inputs for selecting dates, times, and datetime values.
|
||||
|
||||
```html {.example}
|
||||
<label>Input (datetime-local) <input type="datetime-local"></label>
|
||||
|
||||
<label>Input (date) <input type="date"></label>
|
||||
|
||||
<label>Input (time) <input type="time"></label>
|
||||
```
|
||||
|
||||
### Textareas
|
||||
|
||||
Multi-line text input fields for longer content.
|
||||
|
||||
```html {.example}
|
||||
<label>Textarea <textarea placeholder="Type something"></textarea></label>
|
||||
```
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Rounding Utilities
|
||||
description: Border radius utilities set an element's border radius property.
|
||||
tags: ["utilities"]
|
||||
status: wip
|
||||
---
|
||||
|
||||
<style>
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
---
|
||||
title: Size
|
||||
description: Size utilities give elements one of three preset sizes (small, medium, or large).
|
||||
icon: tokens/space
|
||||
status: experimental
|
||||
snippets:
|
||||
- .wa-size-s
|
||||
- .wa-size-m
|
||||
- .wa-size-l
|
||||
---
|
||||
|
||||
Some Web Awesome components, like `<wa-button>`, allow you to change their size to one of three presets: `small`, `medium`, and `large` by using a `size` attribute:
|
||||
|
||||
{% for component in componentsBy.attribute.size %}
|
||||
- <a href="../{{ component.url }}"><code><{{ component.tagName }}></code></a>
|
||||
{%- endfor %}
|
||||
|
||||
You can create the same effect on any element by using the size utility classes:
|
||||
|
||||
- `.wa-size-s`
|
||||
- `.wa-size-m` _(default)_
|
||||
- `.wa-size-l`
|
||||
|
||||
Using these classes does two things:
|
||||
- It sets `font-size` to one of the [size tokens](/docs/tokens/typography/#font-size).
|
||||
You can use CSS `em` units to reference that size in other properties.
|
||||
- It calculates `--wa-form-control-height` based on the applied size, supporting consistent heights for elements like inputs and buttons.
|
||||
- It aliases a bunch of other properties that CSS can use:
|
||||
|
||||
| Custom Property | Small | Medium | Large |
|
||||
| --------------- | ----- | ------ | ----- |
|
||||
| `--wa-size` | `--wa-font-size-s` | `--wa-font-size-m` | `--wa-font-size-l` |
|
||||
| `--wa-size-smaller` | `--wa-font-size-xs` | `--wa-font-size-s` | `--wa-font-size-m` |
|
||||
| `--wa-space` | `--wa-space-s` | `--wa-space-m` | `--wa-space-l` |
|
||||
| `--wa-space-smaller` | `--wa-space-xs` | `--wa-space-s` | `--wa-space-m` |
|
||||
|
||||
For example, assume we wanted to make a custom `.tag` class with size variants.
|
||||
|
||||
```html { .example }
|
||||
<span class="tag wa-size-s">Small</span>
|
||||
<span class="tag">Default</span>
|
||||
<span class="tag wa-size-m">Medium</span>
|
||||
<span class="tag wa-size-l">Large</span>
|
||||
|
||||
<style>
|
||||
.tag {
|
||||
display: inline-block;
|
||||
padding: var(--wa-space-smaller) var(--wa-space);
|
||||
border-radius: var(--wa-border-radius-m); /* usually fixed across sizes */
|
||||
background-color: var(--wa-color-fill-quiet);
|
||||
border: 1px solid var(--wa-color-border-quiet);
|
||||
color: var(--wa-color-on-quiet);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Advanced: Customizing Sizes
|
||||
|
||||
But what if you are creating a style that should **generally** be smaller (e.g. a badge) or larger (e.g. a pull quote)?
|
||||
For example, suppose we wanted to define a custom `.tag2` class just like `.tag` in the previous section,
|
||||
but with a different set of sizes.
|
||||
|
||||
This is possible, though a bit more involved.
|
||||
The first thing you need to do is define these 8 properties in your CSS for your "breakpoints":
|
||||
|
||||
| Custom property | Default value |
|
||||
| --------------- | ------------- |
|
||||
| `--size-xs` | `var(--wa-font-size-xs)` |
|
||||
| `--size-s` | `var(--wa-font-size-s)` |
|
||||
| `--size-m` | `var(--wa-font-size-m)` |
|
||||
| `--size-l` | `var(--wa-font-size-l)` |
|
||||
| `--space-xs` | `var(--wa-space-xs)` |
|
||||
| `--space-s` | `var(--wa-space-s)` |
|
||||
| `--space-m` | `var(--wa-space-m)` |
|
||||
| `--space-l` | `var(--wa-space-l)` |
|
||||
|
||||
|
||||
It would look like this:
|
||||
|
||||
```css
|
||||
.tag2 {
|
||||
--size-xs: var(--wa-font-size-2xs);
|
||||
--size-s: var(--wa-font-size-xs);
|
||||
--size-m: var(--wa-font-size-s);
|
||||
--size-l: var(--wa-font-size-m);
|
||||
|
||||
--space-xs: var(--wa-space-2xs);
|
||||
--space-s: var(--wa-space-xs);
|
||||
--space-m: var(--wa-space-s);
|
||||
--space-l: var(--wa-space-m);
|
||||
}
|
||||
```
|
||||
|
||||
That by itself is sufficient to give you sizes when the utility classes are used, though no default size:
|
||||
|
||||
```html { .example }
|
||||
<span class="tag2 wa-size-s">Small</span>
|
||||
<span class="tag2">Default</span>
|
||||
<span class="tag2 wa-size-m">Medium</span>
|
||||
<span class="tag2 wa-size-l">Large</span>
|
||||
|
||||
<style>
|
||||
.tag2 {
|
||||
--size-xs: var(--wa-font-size-2xs);
|
||||
--size-s: var(--wa-font-size-xs);
|
||||
--size-m: var(--wa-font-size-s);
|
||||
--size-l: var(--wa-font-size-m);
|
||||
|
||||
--space-xs: var(--wa-space-2xs);
|
||||
--space-s: var(--wa-space-xs);
|
||||
--space-m: var(--wa-space-s);
|
||||
--space-l: var(--wa-space-m);
|
||||
|
||||
display: inline-block;
|
||||
font-size: var(--wa-size); /* needed for the default size */
|
||||
padding: var(--wa-space-smaller) var(--wa-space);
|
||||
border-radius: var(--wa-border-radius-s); /* usually fixed across sizes */
|
||||
background-color: var(--wa-color-fill-quiet);
|
||||
border: 1px solid var(--wa-color-border-quiet);
|
||||
color: var(--wa-color-on-quiet);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
Supporting a default size as well requires a little bit more plumbing:
|
||||
|
||||
```html { .example }
|
||||
<div>
|
||||
<span class="tag3 wa-size-s">Small</span>
|
||||
<span class="tag3">Default</span>
|
||||
<span class="tag3 wa-size-m">Medium</span>
|
||||
<span class="tag3 wa-size-l">Large</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tag3 {
|
||||
--size-xs: var(--wa-font-size-2xs);
|
||||
--size-s: var(--wa-font-size-xs);
|
||||
--size-m: var(--wa-font-size-s);
|
||||
--size-l: var(--wa-font-size-m);
|
||||
|
||||
--space-xs: var(--wa-space-2xs);
|
||||
--space-s: var(--wa-space-xs);
|
||||
--space-m: var(--wa-space-s);
|
||||
--space-l: var(--wa-space-m);
|
||||
|
||||
/* Default size assignments with 0 specificity */
|
||||
:where(&) {
|
||||
--wa-size: var(--size-m);
|
||||
--wa-size-smaller: var(--size-s);
|
||||
--wa-space: var(--space-m);
|
||||
--wa-space-smaller: var(--space-s);
|
||||
}
|
||||
|
||||
display: inline-block;
|
||||
font-size: var(--wa-size); /* needed for the default size */
|
||||
padding: var(--wa-space-smaller) var(--wa-space);
|
||||
border-radius: var(--wa-border-radius-s); /* usually fixed across sizes */
|
||||
background-color: var(--wa-color-fill-quiet);
|
||||
border: 1px solid var(--wa-color-border-quiet);
|
||||
color: var(--wa-color-on-quiet);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
2
docs/src/env.d.ts
vendored
2
docs/src/env.d.ts
vendored
@@ -1,2 +0,0 @@
|
||||
/// <reference types="astro/client" />
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
1609
package-lock.json
generated
1609
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@
|
||||
"create": "plop --plopfile scripts/plop/plopfile.js",
|
||||
"test": "CSR_ONLY=\"true\" web-test-runner --group default",
|
||||
"test:component": "CSR_ONLY=\"true\" web-test-runner -- --watch --group",
|
||||
"test:contrast": "cd src/styles/color && node contrast.test.js",
|
||||
"test:contrast": "node scripts/color-palette-contrast-test.js",
|
||||
"test:watch": "web-test-runner --watch --group default",
|
||||
"prettier": "prettier --check --log-level=warn .",
|
||||
"prettier:fix": "prettier --write --log-level=warn .",
|
||||
@@ -71,8 +71,7 @@
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0",
|
||||
"style-observer": "^0.0.7"
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
@@ -117,6 +116,7 @@
|
||||
"marked": "^11.1.0",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"npm-check-updates": "^17.1.11",
|
||||
"nunjucks": "^3.2.4",
|
||||
"ora": "^8.1.1",
|
||||
"pascal-case": "^3.1.2",
|
||||
"playwright": "^1.49.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Get a list of all CSS files in repo
|
||||
import chalk from 'chalk';
|
||||
import Color from 'colorjs.io';
|
||||
import palettes from './palettes.js';
|
||||
import palettes from '../src/styles/color/scripts/palettes.js';
|
||||
|
||||
let targetContrasts = {
|
||||
40: 3,
|
||||
@@ -23,8 +23,8 @@ describe('<wa-badge>', () => {
|
||||
|
||||
it('should default to square styling, with the brand color', async () => {
|
||||
const el = await fixture<WaBadge>(html` <wa-badge>Badge</wa-badge> `);
|
||||
expect(el.getAttribute('variant')).to.eq(null);
|
||||
expect(el.variant).to.eq('inherit');
|
||||
expect(el.getAttribute('variant')).to.eq('brand');
|
||||
expect(el.variant).to.eq('brand');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -24,13 +24,7 @@ export default class WaBadge extends WebAwesomeElement {
|
||||
static shadowStyle = [variantStyles, appearanceStyles, styles];
|
||||
|
||||
/** The badge's theme variant. Defaults to `brand` if not within another element with a variant. */
|
||||
@property({ reflect: true, initial: 'brand' }) variant:
|
||||
| 'brand'
|
||||
| 'neutral'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| 'danger'
|
||||
| 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) variant: 'brand' | 'neutral' | 'success' | 'warning' | 'danger' = 'brand';
|
||||
|
||||
/** The badge's visual appearance. */
|
||||
@property({ reflect: true }) appearance: 'accent' | 'filled' | 'outlined' = 'accent';
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
:host {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
flex-wrap: wrap;
|
||||
gap: 1px;
|
||||
|
||||
> :hover,
|
||||
&::slotted(:hover) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Focus and checked are always on top */
|
||||
> :focus,
|
||||
&::slotted(:focus),
|
||||
> [aria-checked='true'],
|
||||
&::slotted([aria-checked='true']),
|
||||
> [checked],
|
||||
&::slotted([checked]) {
|
||||
z-index: 2 !important;
|
||||
}
|
||||
}
|
||||
|
||||
:host([orientation='vertical']) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Button groups with at least one outlined button will not have a gap and instead have borders overlap */
|
||||
.button-group.has-outlined {
|
||||
gap: 0;
|
||||
|
||||
&:not([aria-orientation='vertical']):not(.button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-inline-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
|
||||
&:is([aria-orientation='vertical'], .button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-block-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,9 @@ import { html } from 'lit';
|
||||
import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import buttonGroupStyles from '../../styles/utilities/button-group.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
import type WaButton from '../button/button.js';
|
||||
import type WaRadioButton from '../radio-button/radio-button.js';
|
||||
import styles from './button-group.css';
|
||||
|
||||
/**
|
||||
@@ -22,7 +20,7 @@ import styles from './button-group.css';
|
||||
*/
|
||||
@customElement('wa-button-group')
|
||||
export default class WaButtonGroup extends WebAwesomeElement {
|
||||
static shadowStyle = [sizeStyles, variantStyles, buttonGroupStyles, styles];
|
||||
static shadowStyle = [sizeStyles, variantStyles, styles];
|
||||
|
||||
@query('slot') defaultSlot: HTMLSlotElement;
|
||||
|
||||
@@ -39,16 +37,10 @@ export default class WaButtonGroup extends WebAwesomeElement {
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
||||
/** The component's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** The button group's theme variant. Defaults to `neutral` if not within another element with a variant. */
|
||||
@property({ reflect: true, initial: 'neutral' }) variant:
|
||||
| 'neutral'
|
||||
| 'brand'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| 'danger'
|
||||
| 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' = 'neutral';
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
@@ -93,6 +85,7 @@ export default class WaButtonGroup extends WebAwesomeElement {
|
||||
|
||||
if (button) {
|
||||
if ((button as WaButton).appearance === 'outlined') this.hasOutlined = true;
|
||||
button.setAttribute('size', this.size);
|
||||
button.classList.add('wa-button-group__button');
|
||||
button.classList.toggle('wa-button-group__horizontal', this.orientation === 'horizontal');
|
||||
button.classList.toggle('wa-button-group__vertical', this.orientation === 'vertical');
|
||||
@@ -126,7 +119,7 @@ function findButton(el: HTMLElement) {
|
||||
const selector = 'wa-button, wa-radio-button';
|
||||
|
||||
// The button could be the target element or a child of it (e.g. a dropdown or tooltip anchor)
|
||||
return (el.closest(selector) ?? el.querySelector(selector)) as WaButton | WaRadioButton;
|
||||
return (el.closest(selector) ?? el.querySelector(selector)) as WaButton;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -1,7 +1,97 @@
|
||||
:host {
|
||||
--display: inline-flex;
|
||||
@layer wa-component {
|
||||
:host {
|
||||
--background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
|
||||
--background-color-hover: color-mix(in oklab, var(--background-color), var(--wa-color-mix-hover));
|
||||
--background-color-active: color-mix(in oklab, var(--background-color), var(--wa-color-mix-active));
|
||||
|
||||
position: relative;
|
||||
--border-color: transparent;
|
||||
--border-color-hover: var(--border-color);
|
||||
--border-color-active: var(--border-color);
|
||||
--border-width: max(1px, var(--wa-form-control-border-width));
|
||||
|
||||
--box-shadow: initial;
|
||||
|
||||
--text-color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
|
||||
--text-color-hover: var(--text-color);
|
||||
--text-color-active: var(--text-color);
|
||||
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--border-width);
|
||||
box-shadow: var(--box-shadow);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
transition-property: background, border, box-shadow, color;
|
||||
transition-duration: var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
cursor: pointer;
|
||||
padding: 0 var(--wa-space, var(--wa-space-m));
|
||||
font-family: inherit;
|
||||
font-size: var(--wa-size, var(--wa-font-size-m));
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
line-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
|
||||
height: var(--wa-form-control-height);
|
||||
width: 100%;
|
||||
|
||||
display: inline-flex;
|
||||
background-color: var(--background-color);
|
||||
border-color: var(--border-color, var(--background-color));
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Interactive states */
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
background-color: var(--background-color-hover, var(--background-color));
|
||||
border-color: var(--border-color-hover, var(--border-color, var(--background-color-hover)));
|
||||
color: var(--text-color-hover, var(--text-color));
|
||||
}
|
||||
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
background-color: var(--background-color-active, var(--background-color));
|
||||
border-color: var(--border-color-active, var(--border-color, var(--background-color-active)));
|
||||
color: var(--text-color-active, var(--text-color));
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
.button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled state */
|
||||
.button.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* When disabled, prevent mouse events from bubbling up from children */
|
||||
.button.disabled * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Keep it last so Safari doesn't stop parsing this block */
|
||||
.button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Pill modifier */
|
||||
:host([pill]) .button {
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -38,7 +128,7 @@ wa-icon[part~='caret'] {
|
||||
height: 0.875em;
|
||||
}
|
||||
|
||||
.wa-button:has(&) .suffix {
|
||||
.button:has(&) .suffix {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +164,6 @@ wa-icon[part~='caret'] {
|
||||
/*
|
||||
* Badges
|
||||
*/
|
||||
|
||||
button ::slotted(wa-badge) {
|
||||
border-color: var(--wa-color-surface-default);
|
||||
position: absolute;
|
||||
@@ -97,6 +186,67 @@ slot[name='prefix']::slotted(*) {
|
||||
}
|
||||
|
||||
slot[name='suffix']::slotted(*),
|
||||
.wa-button:not(.visually-hidden-label) [part~='caret'] {
|
||||
.button:not(.visually-hidden-label) [part~='caret'] {
|
||||
margin-inline-start: var(--wa-space);
|
||||
}
|
||||
|
||||
/*
|
||||
* Button group border radius modifications
|
||||
*/
|
||||
|
||||
/* Remove border radius from all grouped buttons by default */
|
||||
:host(.wa-button-group__button) .button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Horizontal orientation */
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-last) .button {
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Vertical orientation */
|
||||
:host(.wa-button-group__vertical) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical) .button {
|
||||
width: 100%;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-last) .button {
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Handle pill modifier for button groups */
|
||||
:host([pill]) .wa-button-group__horizontal.wa-button-group__button-first {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill]) .wa-button-group__horizontal.wa-button-group__button-last {
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill]) .wa-button-group__vertical.wa-button-group__button-first {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill]) .wa-button-group__vertical.wa-button-group__button-last {
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
@@ -44,100 +44,6 @@ describe('<wa-button>', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an attribute is removed', () => {
|
||||
it("should return to 'inherit' when attribute removed with no initial attribute", async () => {
|
||||
const el = await fixture<WaButton>(html`<wa-button>Button label</wa-button>`);
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
|
||||
el.removeAttribute('variant');
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
});
|
||||
|
||||
it("should return to 'inherit' when attribute removed with an initial attribute", async () => {
|
||||
const el = await fixture<WaButton>(html`<wa-button variant="primary">Button label</wa-button>`);
|
||||
|
||||
expect(el.variant).to.equal('primary');
|
||||
expect(el.getAttribute('variant')).to.equal('primary');
|
||||
|
||||
el.removeAttribute('variant');
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a property is set to null', () => {
|
||||
it("should return to 'default' when property set to null with no initial attribute", async () => {
|
||||
const el = await fixture<WaButton>(html`<wa-button>Button label</wa-button>`);
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
|
||||
// @ts-expect-error Its a test. Stop.
|
||||
el.variant = null;
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
});
|
||||
|
||||
it("should return to 'default' when property set to null with an initial attribute", async () => {
|
||||
const el = await fixture<WaButton>(html`<wa-button variant="primary">Button label</wa-button>`);
|
||||
|
||||
expect(el.variant).to.equal('primary');
|
||||
expect(el.getAttribute('variant')).to.equal('primary');
|
||||
|
||||
// @ts-expect-error Its a test. Stop.
|
||||
el.variant = null;
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.getAttribute('variant')).to.equal(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when provided no parameters', () => {
|
||||
it('passes accessibility test', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
|
||||
await expect(el).to.be.accessible();
|
||||
});
|
||||
|
||||
it('default values are set correctly', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
|
||||
|
||||
expect(el.title).to.equal('');
|
||||
expect(el.variant).to.equal('inherit');
|
||||
expect(el.appearance).to.equal('accent');
|
||||
expect(el.size).to.equal('inherit');
|
||||
expect(el.disabled).to.equal(false);
|
||||
expect(el.caret).to.equal(false);
|
||||
expect(el.loading).to.equal(false);
|
||||
expect(el.pill).to.equal(false);
|
||||
});
|
||||
|
||||
it('should render as a <button>', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
|
||||
expect(el.shadowRoot!.querySelector('button')).to.exist;
|
||||
expect(el.shadowRoot!.querySelector('a')).not.to.exist;
|
||||
});
|
||||
|
||||
it('should not have a spinner present', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
|
||||
expect(el.shadowRoot!.querySelector('wa-spinner')).not.to.exist;
|
||||
});
|
||||
|
||||
it('should not have a caret present', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button>Button Label</wa-button> `);
|
||||
expect(el.shadowRoot?.querySelector('[part~="caret"]')).not.to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when disabled', () => {
|
||||
it('passes accessibility test', async () => {
|
||||
const el = await fixture<WaButton>(html` <wa-button disabled>Button Label</wa-button> `);
|
||||
|
||||
@@ -7,8 +7,6 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/button.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
@@ -48,14 +46,14 @@ import styles from './button.css';
|
||||
* @cssproperty --border-color - The color of the button's border when the button is not being interacted with.
|
||||
* @cssproperty --border-color-active - The color of the button's border when active.
|
||||
* @cssproperty --border-color-hover - The color of the button's border on hover.
|
||||
* @cssproperty --box-shadow - The shadow effects around the edges of the button.
|
||||
* @cssproperty --text-color - The color of the button's label when the button is not being interacted with.
|
||||
* @cssproperty --text-color-active - The color of the button's label when active.
|
||||
* @cssproperty --text-color-hover - The color of the button's label on hover.
|
||||
*/
|
||||
@customElement('wa-button')
|
||||
export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static rectProxy = 'button';
|
||||
static shadowStyle = [styles, variantStyles, sizeStyles, appearanceStyles];
|
||||
|
||||
static get validators() {
|
||||
return [...super.validators, MirrorValidator()];
|
||||
@@ -65,21 +63,20 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.wa-button') button: HTMLButtonElement | HTMLLinkElement;
|
||||
@query('.button') button: HTMLButtonElement | HTMLLinkElement;
|
||||
|
||||
@state() invalid = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
/** The button's theme variant. Defaults to `neutral` if not within another element with a variant. */
|
||||
@property({ reflect: true, initial: 'neutral' })
|
||||
variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true })
|
||||
variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' = 'neutral';
|
||||
|
||||
/** The button's visual appearance. */
|
||||
@property({ reflect: true, default: 'accent' })
|
||||
appearance: 'accent' | 'filled' | 'outlined' | 'plain' = 'accent';
|
||||
@property({ reflect: true }) appearance: 'accent' | 'filled' | 'outlined' | 'plain' = 'accent';
|
||||
|
||||
/** The button's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** Draws the button with a caret. Used to indicate that the button triggers a dropdown menu or similar behavior. */
|
||||
@property({ type: Boolean, reflect: true }) caret = false;
|
||||
@@ -103,16 +100,16 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
* The name of the button, submitted as a name/value pair with form data, but only when this button is the submitter.
|
||||
* This attribute is ignored when `href` is present.
|
||||
*/
|
||||
@property({ reflect: true }) name: string | null = null;
|
||||
@property({ reflect: true }) name: string;
|
||||
|
||||
/**
|
||||
* The value of the button, submitted as a pair with the button's name as part of the form data, but only when this
|
||||
* button is the submitter. This attribute is ignored when `href` is present.
|
||||
*/
|
||||
@property({ reflect: true }) value: string | null = null;
|
||||
@property({ reflect: true }) value: string;
|
||||
|
||||
/** When set, the underlying button will be rendered as an `<a>` with this `href` instead of a `<button>`. */
|
||||
@property({ reflect: true }) href = null;
|
||||
@property({ reflect: true }) href: string;
|
||||
|
||||
/** Tells the browser where to open the link. Only used when `href` is present. */
|
||||
@property() target: '_blank' | '_parent' | '_self' | '_top';
|
||||
@@ -230,7 +227,6 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
part="base"
|
||||
class=${classMap({
|
||||
button: true,
|
||||
'wa-button': true,
|
||||
caret: this.caret,
|
||||
disabled: this.disabled,
|
||||
loading: this.loading,
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
:host {
|
||||
--icon-color: currentColor;
|
||||
--icon-color: var(--text-color);
|
||||
--icon-size: var(--wa-font-size-l);
|
||||
--spacing: var(--wa-space-m);
|
||||
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: stretch;
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
background-color: var(--background-color, var(--wa-color-fill-quiet));
|
||||
border-color: var(--border-color, transparent);
|
||||
border-style: var(--wa-panel-border-style);
|
||||
border-width: var(--wa-panel-border-width);
|
||||
color: var(--wa-color-text-normal);
|
||||
gap: var(--spacing);
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
:host([appearance~='accent']) {
|
||||
color: var(--text-color, var(--wa-color-text-normal));
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
@@ -11,10 +26,6 @@
|
||||
align-items: center;
|
||||
color: var(--icon-color);
|
||||
font-size: var(--icon-size);
|
||||
|
||||
::slotted(*) {
|
||||
margin-inline-end: var(--spacing);
|
||||
}
|
||||
}
|
||||
|
||||
[part~='message'] {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import nativeStyles from '../../styles/native/callout.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
@@ -25,16 +24,10 @@ import styles from './callout.css';
|
||||
*/
|
||||
@customElement('wa-callout')
|
||||
export default class WaCallout extends WebAwesomeElement {
|
||||
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, styles];
|
||||
|
||||
/** The callout's theme variant. Defaults to `brand` if not within another element with a variant. */
|
||||
@property({ reflect: true, initial: 'brand' }) variant:
|
||||
| 'brand'
|
||||
| 'neutral'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| 'danger'
|
||||
| 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) variant: 'brand' | 'neutral' | 'success' | 'warning' | 'danger' | 'brand' = 'brand';
|
||||
|
||||
/** The callout's visual appearance. */
|
||||
@property({ reflect: true }) appearance:
|
||||
@@ -46,7 +39,7 @@ export default class WaCallout extends WebAwesomeElement {
|
||||
| 'outlined accent' = 'outlined filled';
|
||||
|
||||
/** The callout's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
render() {
|
||||
return html`
|
||||
|
||||
@@ -22,12 +22,11 @@
|
||||
color: var(--wa-color-text-normal);
|
||||
}
|
||||
|
||||
:host(:is([appearance~='accent'], .wa-accent)) {
|
||||
:host(:is([appearance~='accent'])) {
|
||||
color: var(--text-color, var(--wa-color-text-normal));
|
||||
}
|
||||
|
||||
:host([appearance~='filled']),
|
||||
:host(.wa-filled) {
|
||||
:host([appearance~='filled']) {
|
||||
--inner-border-color: oklab(from var(--outlined-border-color) l a b / 65%);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,6 @@ export default class WaCard extends WebAwesomeElement {
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'footer', 'header', 'media');
|
||||
|
||||
/** The component's size. Will be inherited by any descendants with a `size` attribute. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
|
||||
/** The card's visual appearance. */
|
||||
@property({ reflect: true })
|
||||
appearance: 'accent' | 'filled' | 'outlined' | 'plain' = 'outlined';
|
||||
|
||||
@@ -1,9 +1,77 @@
|
||||
[part~='base'] {
|
||||
:host {
|
||||
--background-color: var(--wa-form-control-background-color);
|
||||
--background-color-checked: var(--wa-form-control-activated-color);
|
||||
--border-color: var(--wa-form-control-border-color);
|
||||
--border-color-checked: var(--wa-form-control-activated-color);
|
||||
--border-radius: min(
|
||||
calc(var(--toggle-size) * 0.375),
|
||||
var(--wa-border-radius-s)
|
||||
); /* min prevents entirely circular checkbox */
|
||||
--border-style: var(--wa-border-style);
|
||||
--border-width: var(--wa-form-control-border-width);
|
||||
--box-shadow: none;
|
||||
--checked-icon-color: var(--wa-color-brand-on-loud);
|
||||
--toggle-size: 1lh;
|
||||
|
||||
color: var(--wa-form-control-value-color);
|
||||
display: inline-flex;
|
||||
font-family: inherit;
|
||||
font-weight: var(--wa-form-control-value-font-weight);
|
||||
line-height: var(--wa-form-control-value-line-height);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:host [part~='control'] {
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--toggle-size);
|
||||
height: var(--toggle-size);
|
||||
border-color: var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
border-style: var(--border-style);
|
||||
border-width: var(--border-width);
|
||||
background-color: var(--background-color);
|
||||
box-shadow: var(--box-shadow);
|
||||
transition:
|
||||
background var(--wa-transition-normal),
|
||||
border-color var(--wa-transition-fast),
|
||||
box-shadow var(--wa-transition-fast),
|
||||
color var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
|
||||
margin-inline-end: var(--wa-space-xs);
|
||||
}
|
||||
|
||||
:host [part~='base'] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
color: var(--wa-form-control-value-color);
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Checked */
|
||||
[part~='base'] [part~="control"]:has(:checked, :indeterminate) /* scoping this rule to :host breaks in Firefox */ {
|
||||
color: var(--checked-icon-color);
|
||||
border-color: var(--border-color-checked);
|
||||
background-color: var(--background-color-checked);
|
||||
}
|
||||
|
||||
/* Focus */
|
||||
[part~='base'] [part~="control"]:has(> input:focus-visible:not(:disabled)) /* scoping this rule to :host breaks in Firefox */ {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
:host [part~='base']:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
@@ -8,8 +8,7 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { RequiredValidator } from '../../internal/validators/required-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/checkbox.css';
|
||||
import formControlStyles from '../../styles/shadow/form-control.css';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import '../icon/icon.js';
|
||||
import styles from './checkbox.css';
|
||||
@@ -56,7 +55,7 @@ import styles from './checkbox.css';
|
||||
*/
|
||||
@customElement('wa-checkbox')
|
||||
export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [formControlStyles, sizeStyles, nativeStyles, styles];
|
||||
static shadowStyle = [formControlStyles, sizeStyles, styles];
|
||||
|
||||
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };
|
||||
|
||||
@@ -98,7 +97,7 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
|
||||
/** The checkbox's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** Disables the checkbox. */
|
||||
@property({ type: Boolean }) disabled = false;
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
.grid {
|
||||
position: relative;
|
||||
height: var(--grid-height);
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
|
||||
linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
|
||||
border-top-left-radius: calc(var(--border-radius) - var(--border-width));
|
||||
border-top-right-radius: calc(var(--border-radius) - var(--border-width));
|
||||
@@ -250,7 +251,8 @@
|
||||
}
|
||||
|
||||
.transparent-bg {
|
||||
background-image: linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
|
||||
background-image:
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%);
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('<wa-color-picker>', () => {
|
||||
expect(inputHandler).to.have.been.calledTwice;
|
||||
});
|
||||
|
||||
it('should emit change and input when the hue slider is moved', async () => {
|
||||
it.skip('should emit change and input when the hue slider is moved', async () => {
|
||||
const el = await fixture<WaColorPicker>(html` <wa-color-picker></wa-color-picker> `);
|
||||
const trigger = el.shadowRoot!.querySelector<HTMLButtonElement>('[part~="trigger"]')!;
|
||||
const slider = el.shadowRoot!.querySelector<HTMLElement>('[part~="hue-slider"]')!;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { RequiredValidator } from '../../internal/validators/required-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import formControlStyles from '../../styles/shadow/form-control.css';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import visuallyHidden from '../../styles/utilities/visually-hidden.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
@@ -199,7 +199,7 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
@property() format: 'hex' | 'rgb' | 'hsl' | 'hsv' = 'hex';
|
||||
|
||||
/** Determines the size of the color picker's trigger */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** Removes the button that lets users toggle between format. */
|
||||
@property({ attribute: 'without-format-toggle', type: Boolean }) withoutFormatToggle = false;
|
||||
@@ -520,32 +520,41 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
|
||||
private parseColor(colorString: string) {
|
||||
if (!colorString || colorString.trim() === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const color = new TinyColor(colorString);
|
||||
if (!color.isValid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const hslColor = color.toHsl();
|
||||
const rgb = color.toRgb();
|
||||
const hsvColor = color.toHsv();
|
||||
|
||||
// Checks for null RGB values
|
||||
if (!rgb || rgb.r == null || rgb.g == null || rgb.b == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Adjust saturation and lightness from 0-1 to 0-100
|
||||
const hsl = {
|
||||
h: hslColor.h,
|
||||
s: hslColor.s * 100,
|
||||
l: hslColor.l * 100,
|
||||
a: hslColor.a,
|
||||
h: hslColor.h || 0,
|
||||
s: (hslColor.s || 0) * 100,
|
||||
l: (hslColor.l || 0) * 100,
|
||||
a: hslColor.a || 0,
|
||||
};
|
||||
|
||||
const rgb = color.toRgb();
|
||||
|
||||
const hex = color.toHexString();
|
||||
const hexa = color.toHex8String();
|
||||
|
||||
const hsvColor = color.toHsv();
|
||||
// Adjust saturation and value from 0-1 to 0-100
|
||||
const hsv = {
|
||||
h: hsvColor.h,
|
||||
s: hsvColor.s * 100,
|
||||
v: hsvColor.v * 100,
|
||||
a: hsvColor.a,
|
||||
h: hsvColor.h || 0,
|
||||
s: (hsvColor.s || 0) * 100,
|
||||
v: (hsvColor.v || 0) * 100,
|
||||
a: hsvColor.a || 0,
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -589,9 +598,9 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
r: rgb.r,
|
||||
g: rgb.g,
|
||||
b: rgb.b,
|
||||
a: rgb.a,
|
||||
a: rgb.a || 0,
|
||||
string: this.setLetterCase(
|
||||
`rgba(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)}, ${rgb.a.toFixed(2).toString()})`,
|
||||
`rgba(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)}, ${(rgb.a || 0).toFixed(2).toString()})`,
|
||||
),
|
||||
},
|
||||
hex: this.setLetterCase(hex),
|
||||
@@ -991,7 +1000,7 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
value=${this.isEmpty ? '' : this.inputValue}
|
||||
.value=${this.isEmpty ? '' : this.inputValue}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
aria-label=${this.localize.term('currentValue')}
|
||||
|
||||
@@ -1,23 +1,85 @@
|
||||
:host {
|
||||
--icon-color: var(--wa-color-text-quiet);
|
||||
--spacing: var(--wa-space-m);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
--display: block;
|
||||
--outlined-border-color: var(--wa-color-surface-border);
|
||||
|
||||
display: block;
|
||||
}
|
||||
|
||||
:host([appearance='plain']) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(var(--spacing) + var(--wa-focus-ring-offset));
|
||||
}
|
||||
}
|
||||
|
||||
details {
|
||||
display: block;
|
||||
overflow-anchor: none;
|
||||
border: var(--wa-panel-border-width) var(--border-color) var(--wa-panel-border-style);
|
||||
background-color: var(--background-color, var(--wa-color-surface-default));
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
color: var(--text-color, inherit);
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
background: none;
|
||||
border: solid var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
|
||||
summary {
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host([disabled]) details {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: not-allowed;
|
||||
:host summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
padding: var(--spacing); /* Add padding here */
|
||||
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
summary:focus-visible {
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(var(--spacing) + var(--wa-focus-ring-offset));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +112,8 @@ details {
|
||||
.content {
|
||||
display: block;
|
||||
padding-block-start: var(--spacing);
|
||||
padding-inline: var(--spacing); /* Add horizontal padding */
|
||||
padding-block-end: var(--spacing); /* Add bottom padding */
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
|
||||
@@ -8,8 +8,6 @@ import { animate, parseDuration } from '../../internal/animate.js';
|
||||
import { getTargetElement, waitForEvent } from '../../internal/event.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import nativeStyles from '../../styles/native/details.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
@@ -48,7 +46,7 @@ import styles from './details.css';
|
||||
*/
|
||||
@customElement('wa-details')
|
||||
export default class WaDetails extends WebAwesomeElement {
|
||||
static shadowStyle = [passthroughStyles, appearanceStyles, nativeStyles, styles];
|
||||
static shadowStyle = [appearanceStyles, styles];
|
||||
|
||||
private detailsObserver: MutationObserver;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@@ -40,6 +40,19 @@
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
/* Sizes */
|
||||
:host([size='small']) ::slotted(wa-menu) {
|
||||
font-size: var(--wa-font-size-s);
|
||||
}
|
||||
|
||||
:host([size='medium']) ::slotted(wa-menu) {
|
||||
font-size: var(--wa-font-size-m);
|
||||
}
|
||||
|
||||
:host([size='large']) ::slotted(wa-menu) {
|
||||
font-size: var(--wa-font-size-l);
|
||||
}
|
||||
|
||||
/* When users slot a menu, make sure it conforms to the popup's auto-size */
|
||||
::slotted(wa-menu) {
|
||||
max-width: var(--auto-size-available-width) !important;
|
||||
|
||||
@@ -43,26 +43,24 @@ interface IconSource {
|
||||
export default class WaIcon extends WebAwesomeElement {
|
||||
static shadowStyle = styles;
|
||||
|
||||
private initialRender = false;
|
||||
|
||||
@state() private svg: SVGElement | HTMLTemplateResult | null = null;
|
||||
|
||||
/** The name of the icon to draw. Available names depend on the icon library being used. */
|
||||
@property({ cssProperty: '--wa-icon-name' }) name?: string;
|
||||
@property() name?: string;
|
||||
|
||||
/**
|
||||
* The family of icons to choose from. For Font Awesome Free (default), valid options include `classic` and `brands`.
|
||||
* For Font Awesome Pro subscribers, valid options include, `classic`, `sharp`, `duotone`, and `brands`. Custom icon
|
||||
* libraries may or may not use this property.
|
||||
*/
|
||||
@property({ cssProperty: '--wa-icon-family' }) family: string;
|
||||
@property() family: string;
|
||||
|
||||
/**
|
||||
* The name of the icon's variant. For Font Awesome, valid options include `thin`, `light`, `regular`, and `solid` for
|
||||
* the `classic` and `sharp` families. Some variants require a Font Awesome Pro subscription. Custom icon libraries
|
||||
* may or may not use this property.
|
||||
*/
|
||||
@property({ cssProperty: '--wa-icon-variant' }) variant: string;
|
||||
@property() variant: string;
|
||||
|
||||
/** Draws the icon in a fixed-width both. */
|
||||
@property({ attribute: 'fixed-width', type: Boolean, reflect: true }) fixedWidth: false;
|
||||
@@ -80,7 +78,7 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
@property() label = '';
|
||||
|
||||
/** The name of a registered custom icon library. */
|
||||
@property({ cssProperty: '--wa-icon-library', default: 'default' }) library = 'default';
|
||||
@property() library = 'default';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
@@ -90,7 +88,6 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
|
||||
firstUpdated(changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this.initialRender = true;
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
@@ -200,11 +197,6 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
iconCache.set(url, iconResolver);
|
||||
}
|
||||
|
||||
// If we haven't rendered yet, exit early. This avoids unnecessary work due to watching multiple props.
|
||||
if (!this.initialRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
const svg = await iconResolver;
|
||||
|
||||
if (svg === RETRYABLE_ERROR) {
|
||||
@@ -237,7 +229,7 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
// Sometimes (like with SSR -> hydration) mutators dont get applied due to race conditions. This ensures mutators get re-applied.
|
||||
// Sometimes (like with SSR -> hydration) mutators don't get applied due to race conditions. This ensures mutators get re-applied.
|
||||
const library = getIconLibrary(this.library);
|
||||
|
||||
const svg = this.shadowRoot?.querySelector('svg');
|
||||
@@ -251,7 +243,6 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
return this.svg;
|
||||
}
|
||||
|
||||
// @TODO: 16x16 is generally a safe bet. Perhaps be user setable?? `size="16x16"`, size="20x16". We just want to avoid "blowouts" with SSR.
|
||||
return html`<svg part="svg" fill="currentColor" width="16" height="16"></svg>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ function dataUri(svg: string) {
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
||||
}
|
||||
|
||||
export const iconsByVariant: { [key: string]: { [key: string]: string } } = {
|
||||
export const icons: { [key: string]: { [key: string]: string } } = {
|
||||
//
|
||||
// Solid variant
|
||||
//
|
||||
solid: {
|
||||
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>`,
|
||||
'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 0s12.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>`,
|
||||
@@ -21,7 +24,11 @@ export const iconsByVariant: { [key: string]: { [key: string]: string } } = {
|
||||
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>`,
|
||||
},
|
||||
//
|
||||
// Regular variant
|
||||
//
|
||||
regular: {
|
||||
'circle-question': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm169.8-90.7c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg>`,
|
||||
'circle-xmark': `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z"/></svg>`,
|
||||
copy: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z"/></svg>`,
|
||||
eye: `<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><path d="M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z"/></svg>`,
|
||||
@@ -29,11 +36,6 @@ export const iconsByVariant: { [key: string]: { [key: string]: string } } = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Union of all icons, across variants
|
||||
*/
|
||||
export const icons: { [key: string]: string } = Object.assign({}, ...Object.values(iconsByVariant));
|
||||
|
||||
//
|
||||
// System icons are a separate library to ensure they're always available, regardless of how the default icon library is
|
||||
// configured or if its icons resolve properly. All Web Awesome components must use the system library instead of the
|
||||
@@ -42,14 +44,10 @@ export const icons: { [key: string]: string } = Object.assign({}, ...Object.valu
|
||||
const systemLibrary: IconLibrary = {
|
||||
name: 'system',
|
||||
resolver: (name: string, _family = 'classic', variant = 'solid') => {
|
||||
// family is ignored for now
|
||||
// Default to `regular` for unknown variants
|
||||
variant = variant in iconsByVariant ? variant : 'regular';
|
||||
let collection = icons[variant];
|
||||
|
||||
let icons = iconsByVariant[variant];
|
||||
|
||||
// Fall back to other variants if icon is not found in the variant requested
|
||||
let svg = icons[name] ?? iconsByVariant.regular[name] ?? iconsByVariant.solid[name];
|
||||
// Fall back to a question mark if the icon is missing
|
||||
let svg = collection[name] ?? icons.regular[name] ?? icons.regular['circle-question'];
|
||||
|
||||
if (svg) {
|
||||
return dataUri(svg);
|
||||
|
||||
@@ -1,21 +1,74 @@
|
||||
:host {
|
||||
--border-width: var(--wa-form-control-border-width);
|
||||
--box-shadow: initial;
|
||||
--outlined-background-color: var(--wa-form-control-background-color);
|
||||
--outlined-border-color: var(--wa-form-control-border-color);
|
||||
--outlined-text-color: var(--wa-form-control-value-color);
|
||||
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.wa-text-field {
|
||||
.text-field {
|
||||
flex: auto;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: start;
|
||||
position: relative;
|
||||
|
||||
border-color: inherit;
|
||||
border-style: inherit;
|
||||
border-radius: inherit;
|
||||
transition: inherit;
|
||||
|
||||
height: var(--wa-form-control-height);
|
||||
padding-block: 0;
|
||||
border-color: var(--border-color, var(--wa-form-control-border-color));
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
border-style: var(--wa-form-control-border-style);
|
||||
border-width: var(--border-width);
|
||||
cursor: text;
|
||||
color: var(--wa-form-control-value-color);
|
||||
font-size: var(--wa-size);
|
||||
font-family: inherit;
|
||||
font-weight: var(--wa-form-control-value-font-weight);
|
||||
line-height: var(--wa-form-control-value-line-height);
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
transition:
|
||||
background-color var(--wa-transition-normal),
|
||||
border var(--wa-transition-normal),
|
||||
outline var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
background-color: var(--background-color, var(--wa-form-control-background-color));
|
||||
box-shadow: var(--box-shadow);
|
||||
padding: var(--wa-space-smaller) var(--wa-space);
|
||||
|
||||
&:focus-within {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Style disabled inputs */
|
||||
&:has(:disabled) {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
:host([pill]) .text-field {
|
||||
border-radius: var(--wa-border-radius-pill) !important;
|
||||
}
|
||||
|
||||
.text-field input,
|
||||
.text-field textarea {
|
||||
/*
|
||||
Fixes an alignment issue with placeholders.
|
||||
https://github.com/shoelace-style/webawesome/issues/342
|
||||
*/
|
||||
height: 100%;
|
||||
|
||||
padding: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
cursor: inherit;
|
||||
-webkit-appearance: none;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
input {
|
||||
@@ -29,17 +82,51 @@ input {
|
||||
height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
|
||||
padding-block: 0;
|
||||
color: inherit;
|
||||
|
||||
&:autofill {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
caret-color: var(--wa-form-control-value-color);
|
||||
}
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: var(--wa-form-control-placeholder-color);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
&::-webkit-search-decoration,
|
||||
&::-webkit-search-cancel-button,
|
||||
&::-webkit-search-results-button,
|
||||
&::-webkit-search-results-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
input::-webkit-search-decoration,
|
||||
input::-webkit-search-cancel-button,
|
||||
input::-webkit-search-results-button,
|
||||
input::-webkit-search-results-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
textarea {
|
||||
&:autofill {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
caret-color: var(--wa-form-control-value-color);
|
||||
}
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
&::placeholder {
|
||||
color: var(--wa-form-control-placeholder-color);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.prefix,
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('<wa-input>', () => {
|
||||
const el = await fixture<WaInput>(html` <wa-input></wa-input> `);
|
||||
|
||||
expect(el.type).to.equal('text');
|
||||
expect(el.size).to.equal('inherit');
|
||||
expect(el.size).to.equal('medium');
|
||||
expect(el.name).to.equal(null);
|
||||
expect(el.value).to.equal(null);
|
||||
expect(el.defaultValue).to.equal(null);
|
||||
|
||||
@@ -8,8 +8,7 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/input.css';
|
||||
import formControlStyles from '../../styles/shadow/form-control.css';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
@@ -58,7 +57,7 @@ import styles from './input.css';
|
||||
*/
|
||||
@customElement('wa-input')
|
||||
export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [sizeStyles, appearanceStyles, formControlStyles, nativeStyles, styles];
|
||||
static shadowStyle = [sizeStyles, appearanceStyles, formControlStyles, styles];
|
||||
|
||||
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };
|
||||
|
||||
@@ -115,7 +114,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
@property({ attribute: 'value', reflect: true }) defaultValue: string | null = this.getAttribute('value') || null;
|
||||
|
||||
/** The input's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** The input's visual appearance. */
|
||||
@property({ reflect: true }) appearance: 'filled' | 'outlined' = 'outlined';
|
||||
@@ -400,7 +399,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
<slot name="label">${this.label}</slot>
|
||||
</label>
|
||||
|
||||
<div part="input" class="wa-text-field">
|
||||
<div part="input" class="text-field">
|
||||
<slot name="prefix" part="prefix" class="prefix"></slot>
|
||||
|
||||
<input
|
||||
|
||||
@@ -28,7 +28,7 @@ export default class WaMenu extends WebAwesomeElement {
|
||||
static shadowStyle = [sizeStyles, styles];
|
||||
|
||||
/** The component's size. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
@query('slot') defaultSlot: HTMLSlotElement;
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
import type { PropertyValues } from 'lit';
|
||||
import { html, isServer } from 'lit';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { live } from 'lit/directives/live.js';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import { toLength, toPx } from '../../internal/css-values.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import visuallyHidden from '../../styles/utilities/visually-hidden.css';
|
||||
import styles from './page.css';
|
||||
import mobileStyles from './page.mobile.styles.js';
|
||||
|
||||
import '../button/button.js';
|
||||
import '../drawer/drawer.js';
|
||||
import '../icon/icon.js';
|
||||
|
||||
import type { PropertyValues } from 'lit';
|
||||
import type WaDrawer from '../drawer/drawer.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './page.css';
|
||||
import mobileStyles from './page.mobile.styles.js';
|
||||
|
||||
if (typeof ResizeObserver === 'undefined') {
|
||||
globalThis.ResizeObserver = class {
|
||||
@@ -28,6 +25,58 @@ if (typeof ResizeObserver === 'undefined') {
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// TODO - the toPx and toLength functions aren't used anywhere else, and they're not named or documented well enough to
|
||||
// abstract into a utility as-is.
|
||||
//
|
||||
|
||||
/** Converts a non-pixel value to a pixel value. */
|
||||
function toPx(value: string | number, element: HTMLElement | SVGElement = document.documentElement): number {
|
||||
if (!Number.isNaN(Number(value))) {
|
||||
return Number(value);
|
||||
}
|
||||
|
||||
// If CSS.registerProperty isn't supported, try to parse as-is
|
||||
if (!window.CSS || !CSS.registerProperty) {
|
||||
if (typeof value === 'string' && value.endsWith('px')) {
|
||||
return parseFloat(value);
|
||||
}
|
||||
return Number(value) || 0;
|
||||
}
|
||||
|
||||
const resolver = '--wa-length-resolver';
|
||||
|
||||
// Register the property if not already done
|
||||
if (!CSS.registerProperty.toString().includes(resolver)) {
|
||||
try {
|
||||
CSS.registerProperty({
|
||||
name: resolver,
|
||||
syntax: '<length>',
|
||||
inherits: false,
|
||||
initialValue: '0px',
|
||||
});
|
||||
} catch (e) {
|
||||
// Property might already be registered
|
||||
}
|
||||
}
|
||||
|
||||
const previousValue = element.style.getPropertyValue(resolver);
|
||||
element.style.setProperty(resolver, value as string);
|
||||
const computedValue = getComputedStyle(element)?.getPropertyValue(resolver);
|
||||
element.style.setProperty(resolver, previousValue);
|
||||
|
||||
if (computedValue?.endsWith('px')) {
|
||||
return parseFloat(computedValue);
|
||||
}
|
||||
|
||||
return Number(computedValue) || 0;
|
||||
}
|
||||
|
||||
/** Converts a number or string to a CSS px value. Not used anywhere else, so consolidated here for the time being. */
|
||||
function toLength(px: number | string): string {
|
||||
return Number.isNaN(Number(px)) ? (px as string) : `${px}px`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Pages offer an easy way to scaffold entire page layouts using minimal markup.
|
||||
* @documentation https://backers.webawesome.com/docs/components/page
|
||||
@@ -373,3 +422,34 @@ declare global {
|
||||
'wa-page': WaPage;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Append a supporting light DOM styles for <wa-page>
|
||||
//
|
||||
const stylesheet = new CSSStyleSheet();
|
||||
|
||||
stylesheet.replaceSync(`
|
||||
:is(html, body):has(wa-page) {
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Because headers are sticky, this is needed to make sure page fragment anchors scroll down past the headers / subheaders and are visible.
|
||||
IE: \`<a href="#id-for-h2">\` anchors.
|
||||
*/
|
||||
wa-page :is(*, *:after, *:before) {
|
||||
scroll-margin-top: var(--scroll-margin-top);
|
||||
}
|
||||
|
||||
wa-page[view='desktop'] [data-toggle-nav] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
wa-page[view='mobile'] .wa-desktop-only, wa-page[view='desktop'] .wa-mobile-only {
|
||||
display: none !important;
|
||||
}
|
||||
`);
|
||||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];
|
||||
|
||||
@@ -109,7 +109,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
| 'left-start'
|
||||
| 'left-end' = 'top';
|
||||
|
||||
/** Which bounding box to use for flipping, shifting, and auto-sizing? */
|
||||
/** The bounding box to use for flipping, shifting, and auto-sizing. */
|
||||
@property() boundary: 'viewport' | 'scroll' = 'viewport';
|
||||
|
||||
/** The distance in pixels from which to offset the panel away from its anchor. */
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
:host {
|
||||
--indicator-color: var(--wa-color-brand-fill-loud);
|
||||
--display: flex;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 1.25rem;
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
color: var(--wa-color-brand-on-loud);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
width: var(--percentage);
|
||||
display: flex;
|
||||
|
||||
@@ -4,7 +4,6 @@ import { customElement, property } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { clamp } from '../../internal/math.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import styles from './progress-bar.css';
|
||||
|
||||
@@ -25,7 +24,7 @@ import styles from './progress-bar.css';
|
||||
*/
|
||||
@customElement('wa-progress-bar')
|
||||
export default class WaProgressBar extends WebAwesomeElement {
|
||||
static shadowStyle = [passthroughStyles, styles];
|
||||
static shadowStyle = styles;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
/** The current progress as a percentage, 0 to 100. */
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
:host {
|
||||
--display: inline-flex;
|
||||
}
|
||||
|
||||
.prefix,
|
||||
.suffix,
|
||||
.label {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* We use a hidden input so constraint validation errors work, since they don't appear to show when used with buttons.
|
||||
We can't actually hide it, though, otherwise the messages will be suppressed by the browser. */
|
||||
.hidden-input {
|
||||
all: unset;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
outline: dotted 1px red;
|
||||
opacity: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checked buttons
|
||||
*/
|
||||
:host([checked]) {
|
||||
--indicator-color: var(--wa-form-control-activated-color);
|
||||
--indicator-width: var(--wa-border-width-s);
|
||||
|
||||
box-shadow: inset 0 0 0 var(--indicator-width) var(--indicator-color);
|
||||
|
||||
& button {
|
||||
--border-color: var(--indicator-color);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Active buttons
|
||||
*/
|
||||
button:active {
|
||||
--text-color-active: var(--wa-form-control-activated-color);
|
||||
--border-color-active: var(--wa-form-control-activated-color);
|
||||
}
|
||||
|
||||
/* Horizontal radio pill buttons */
|
||||
:host([data-wa-radio-horizontal][data-wa-radio-first]:not([data-wa-radio-last])) .wa-pill {
|
||||
border-start-end-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
:host([data-wa-radio-horizontal][data-wa-radio-inner]) .wa-pill {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([data-wa-radio-horizontal][data-wa-radio-last]:not([data-wa-radio-first])) .wa-pill {
|
||||
border-start-start-radius: 0;
|
||||
border-end-start-radius: 0;
|
||||
}
|
||||
|
||||
/* Vertical radio pill buttons */
|
||||
:host([data-wa-radio-vertical][data-wa-radio-first]:not([data-wa-radio-last])) .wa-pill {
|
||||
border-end-start-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
:host([data-wa-radio-vertical][data-wa-radio-inner]) .wa-pill {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([data-wa-radio-vertical][data-wa-radio-last]:not([data-wa-radio-first])) .wa-pill {
|
||||
border-start-start-radius: 0;
|
||||
border-start-end-radius: 0;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { html } from 'lit';
|
||||
import { fixtures } from '../../internal/test/fixture.js';
|
||||
import type WaRadioGroup from '../radio-group/radio-group.js';
|
||||
import type WaRadioButton from './radio-button.js';
|
||||
|
||||
describe('<wa-radio-button>', () => {
|
||||
for (const fixture of fixtures) {
|
||||
describe(`with "${fixture.type}" rendering`, () => {
|
||||
it('should not get checked when disabled', async () => {
|
||||
const radioGroup = await fixture<WaRadioGroup>(html`
|
||||
<wa-radio-group value="1">
|
||||
<wa-radio-button id="radio-1" value="1"></wa-radio-button>
|
||||
<wa-radio-button id="radio-2" value="2" disabled></wa-radio-button>
|
||||
</wa-radio-group>
|
||||
`);
|
||||
const radio1 = radioGroup.querySelector<WaRadioButton>('#radio-1')!;
|
||||
const radio2 = radioGroup.querySelector<WaRadioButton>('#radio-2')!;
|
||||
|
||||
radio2.click();
|
||||
await Promise.all([radio1.updateComplete, radio2.updateComplete]);
|
||||
|
||||
expect(radio1.checked).to.be.true;
|
||||
expect(radio2.checked).to.be.false;
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,160 +0,0 @@
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { html } from 'lit/static-html.js';
|
||||
import { HasSlotController } from '../../internal/slot.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import nativeStyles from '../../styles/native/button.css';
|
||||
import passthroughStyles from '../../styles/shadow/passthrough.css';
|
||||
import appearanceStyles from '../../styles/utilities/appearance.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
import styles from './radio-button.css';
|
||||
|
||||
/**
|
||||
* @summary Radios buttons allow the user to select a single option from a group using a button-like control.
|
||||
* @documentation https://backers.webawesome.com/docs/components/radio-button
|
||||
* @status stable
|
||||
* @since 2.0
|
||||
*
|
||||
* @slot - The radio button's label.
|
||||
* @slot prefix - A presentational prefix icon or similar element.
|
||||
* @slot suffix - A presentational suffix icon or similar element.
|
||||
*
|
||||
* @event blur - Emitted when the button loses focus.
|
||||
* @event focus - Emitted when the button gains focus.
|
||||
*
|
||||
* @cssproperty --indicator-color - The color of the checked button indicator.
|
||||
* @cssproperty --indicator-width - The width of the checked button indicator.
|
||||
*
|
||||
* @csspart base - The internal `<button>` element.
|
||||
* @csspart checked - The internal button element when the radio button is checked.
|
||||
* @csspart prefix - The container that wraps the prefix.
|
||||
* @csspart label - The container that wraps the radio button's label.
|
||||
* @csspart suffix - The container that wraps the suffix.
|
||||
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
|
||||
*/
|
||||
@customElement('wa-radio-button')
|
||||
export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
|
||||
static rectProxy = 'input';
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
||||
|
||||
@query('button') input: HTMLButtonElement;
|
||||
@query('.hidden-input') hiddenInput: HTMLInputElement;
|
||||
|
||||
/**
|
||||
* @internal The radio button's checked state. This is exposed as an "internal" attribute so we can reflect it, making
|
||||
* it easier to style in button groups.
|
||||
*/
|
||||
@property({ type: Boolean, reflect: true }) checked = false;
|
||||
|
||||
/** The radio's value. When selected, the radio group will receive this value. */
|
||||
@property({ reflect: true }) value: string;
|
||||
|
||||
/** Disables the radio button. */
|
||||
@property({ type: Boolean }) disabled = false;
|
||||
|
||||
/**
|
||||
* The radio button's size. When used inside a radio group, the size will be determined by the radio group's size so
|
||||
* this attribute can typically be omitted.
|
||||
*/
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
|
||||
/** Draws a pill-style radio button with rounded edges. */
|
||||
@property({ type: Boolean, reflect: true }) pill = false;
|
||||
|
||||
/**
|
||||
* The string pointing to a form's id.
|
||||
*/
|
||||
@property({ reflect: true }) form: string | null = null;
|
||||
|
||||
/**
|
||||
* Used for SSR. if true, will show slotted prefix on initial render.
|
||||
*/
|
||||
@property({ type: Boolean, attribute: 'with-prefix' }) withPrefix = false;
|
||||
|
||||
/**
|
||||
* Used for SSR. if true, will show slotted suffix on initial render.
|
||||
*/
|
||||
@property({ type: Boolean, attribute: 'with-suffix' }) withSuffix = false;
|
||||
|
||||
/**
|
||||
* Used for SSR. if true, will show slotted suffix on initial render. (should this be withDefault, since its the default slot??)
|
||||
*/
|
||||
@property({ type: Boolean, attribute: 'with-label' }) withLabel = false;
|
||||
|
||||
// Needed for Form Validation. Without it we get a console error.
|
||||
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.setAttribute('role', 'presentation');
|
||||
}
|
||||
|
||||
private handleClick(e: MouseEvent) {
|
||||
if (this.disabled) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
this.checked = true;
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/** Sets focus on the radio button. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.input.focus(options);
|
||||
}
|
||||
|
||||
/** Removes focus from the radio button. */
|
||||
blur() {
|
||||
this.input.blur();
|
||||
}
|
||||
|
||||
render() {
|
||||
const hasLabel = this.hasUpdated ? this.hasSlotController.test('[default]') : this.withLabel;
|
||||
const hasPrefix = this.hasUpdated ? this.hasSlotController.test('prefix') : this.withPrefix;
|
||||
const hasSuffix = this.hasUpdated ? this.hasSlotController.test('suffix') : this.withSuffix;
|
||||
|
||||
return html`
|
||||
<button
|
||||
part="base${this.checked ? ' checked' : ''}"
|
||||
role="radio"
|
||||
aria-checked="${this.checked}"
|
||||
class=${classMap({
|
||||
'wa-neutral': !this.checked,
|
||||
'wa-brand': this.checked,
|
||||
disabled: this.disabled,
|
||||
'wa-outlined': true,
|
||||
'wa-filled': this.checked,
|
||||
'wa-pill': this.pill,
|
||||
'has-label': hasLabel,
|
||||
'has-prefix': hasPrefix,
|
||||
'has-suffix': hasSuffix,
|
||||
})}
|
||||
aria-disabled=${this.disabled}
|
||||
type="button"
|
||||
value=${ifDefined(this.value)}
|
||||
@click=${this.handleClick}
|
||||
>
|
||||
<slot name="prefix" part="prefix" class="prefix"></slot>
|
||||
<slot part="label" class="label"></slot>
|
||||
<slot name="suffix" part="suffix" class="suffix"></slot>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'wa-radio-button': WaRadioButton;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
margin-inline-start: var(--wa-form-control-required-content-offset);
|
||||
}
|
||||
|
||||
.wa-button-group {
|
||||
.button-group {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -35,13 +35,14 @@
|
||||
gap: var(--wa-space-m);
|
||||
}
|
||||
|
||||
/* When radio buttons are slotted */
|
||||
:host([orientation]) .form-control-has-radio-buttons [part~='form-control-input'] {
|
||||
gap: 0;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
/* Help text */
|
||||
[part~='hint'] {
|
||||
margin-block-start: var(--wa-space-xs);
|
||||
}
|
||||
|
||||
/* Radios have the "button" appearance */
|
||||
:host fieldset.has-radio-buttons {
|
||||
[part~='form-control-input'] {
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,61 +249,6 @@ describe('<wa-radio-group>', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a size is applied', () => {
|
||||
it('should apply the same size to all radios', async () => {
|
||||
const radioGroup = await fixture<WaRadioGroup>(html`
|
||||
<wa-radio-group size="large">
|
||||
<wa-radio id="radio-1" value="1"></wa-radio>
|
||||
<wa-radio id="radio-2" value="2"></wa-radio>
|
||||
</wa-radio-group>
|
||||
`);
|
||||
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio');
|
||||
|
||||
expect(radio1.size).to.equal('inherit');
|
||||
expect(radio1.getComputed('size')).to.equal('large');
|
||||
expect(radio2.size).to.equal('inherit');
|
||||
expect(radio2.getComputed('size')).to.equal('large');
|
||||
});
|
||||
|
||||
it('should apply the same size to all radio buttons', async () => {
|
||||
const radioGroup = await fixture<WaRadioGroup>(html`
|
||||
<wa-radio-group size="large">
|
||||
<wa-radio-button id="radio-1" value="1"></wa-radio-button>
|
||||
<wa-radio-button id="radio-2" value="2"></wa-radio-button>
|
||||
</wa-radio-group>
|
||||
`);
|
||||
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio-button');
|
||||
|
||||
expect(radio1.size).to.equal('inherit');
|
||||
expect(radio1.getComputed('size')).to.equal('large');
|
||||
expect(radio2.size).to.equal('inherit');
|
||||
expect(radio2.getComputed('size')).to.equal('large');
|
||||
});
|
||||
|
||||
it('should update the computed size of all radio buttons when size changes', async () => {
|
||||
const radioGroup = await fixture<WaRadioGroup>(html`
|
||||
<wa-radio-group size="small">
|
||||
<wa-radio-button id="radio-1" value="1"></wa-radio-button>
|
||||
<wa-radio-button id="radio-2" value="2"></wa-radio-button>
|
||||
</wa-radio-group>
|
||||
`);
|
||||
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio-button');
|
||||
|
||||
expect(radio1.size).to.equal('inherit');
|
||||
expect(radio1.getComputed('size')).to.equal('small');
|
||||
expect(radio2.size).to.equal('inherit');
|
||||
expect(radio2.getComputed('size')).to.equal('small');
|
||||
|
||||
radioGroup.size = 'large';
|
||||
await radioGroup.updateComplete;
|
||||
|
||||
expect(radio1.size).to.equal('inherit');
|
||||
expect(radio1.getComputed('size')).to.equal('large');
|
||||
expect(radio2.size).to.equal('inherit');
|
||||
expect(radio2.getComputed('size')).to.equal('large');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when handling focus', () => {
|
||||
const doAction = async (instance: WaRadioGroup, type: string) => {
|
||||
if (type === 'focus') {
|
||||
|
||||
@@ -6,25 +6,21 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { RequiredValidator } from '../../internal/validators/required-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import formControlStyles from '../../styles/shadow/form-control.css';
|
||||
import buttonGroupStyles from '../../styles/utilities/button-group.css';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import '../radio-button/radio-button.js';
|
||||
import type WaRadioButton from '../radio-button/radio-button.js';
|
||||
import '../radio/radio.js';
|
||||
import type WaRadio from '../radio/radio.js';
|
||||
import styles from './radio-group.css';
|
||||
|
||||
/**
|
||||
* @summary Radio groups are used to group multiple [radios](/docs/components/radio) or [radio buttons](/docs/components/radio-button) so they function as a single form control.
|
||||
* @summary Radio groups are used to group multiple [radios](/docs/components/radio) so they function as a single form control.
|
||||
* @documentation https://backers.webawesome.com/docs/components/radio-group
|
||||
* @status stable
|
||||
* @since 2.0
|
||||
*
|
||||
* @dependency wa-radio
|
||||
* @dependency wa-radio-button
|
||||
*
|
||||
* @slot - The default slot where `<wa-radio>` or `<wa-radio-button>` elements are placed.
|
||||
* @slot - The default slot where `<wa-radio>` elements are placed.
|
||||
* @slot label - The radio group's label. Required for proper accessibility. Alternatively, you can use the `label`
|
||||
* attribute.
|
||||
* @slot hint - Text that describes how to use the radio group. Alternatively, you can use the `hint` attribute.
|
||||
@@ -41,7 +37,7 @@ import styles from './radio-group.css';
|
||||
*/
|
||||
@customElement('wa-radio-group')
|
||||
export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
static shadowStyle = [sizeStyles, buttonGroupStyles, formControlStyles, styles];
|
||||
static shadowStyle = [sizeStyles, formControlStyles, styles];
|
||||
|
||||
static get validators() {
|
||||
const validators = isServer
|
||||
@@ -61,9 +57,9 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'hint', 'label');
|
||||
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
@state() hasRadioButtons = false;
|
||||
|
||||
@state() private hasRadioButtons = false;
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
|
||||
/**
|
||||
* The radio group's label. Required for proper accessibility. If you need to display HTML, use the `label` slot
|
||||
@@ -102,7 +98,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
@property({ attribute: 'value', reflect: true }) defaultValue: string | null = this.getAttribute('value') || null;
|
||||
|
||||
/** The radio group's size. This size will be applied to all child radios and radio buttons, except when explicitly overridden. */
|
||||
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
|
||||
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
||||
|
||||
/** Ensures a child radio is checked before allowing the containing form to submit. */
|
||||
@property({ type: Boolean, reflect: true }) required = false;
|
||||
@@ -132,8 +128,29 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We use the first available radio as the validationTarget similar to native HTML that shows the validation popup on
|
||||
* the first radio element.
|
||||
*/
|
||||
get validationTarget() {
|
||||
if (isServer) return undefined;
|
||||
|
||||
const radio = this.querySelector<WaRadio>(':is(wa-radio):not([disabled])');
|
||||
if (!radio) return undefined;
|
||||
|
||||
return radio;
|
||||
}
|
||||
|
||||
formResetCallback(...args: Parameters<WebAwesomeFormAssociatedElement['formResetCallback']>) {
|
||||
this.value = this.defaultValue;
|
||||
|
||||
super.formResetCallback(...args);
|
||||
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
private handleRadioClick = (e: Event) => {
|
||||
const clickedRadio = (e.target as HTMLElement).closest<WaRadio | WaRadioButton>('wa-radio, wa-radio-button');
|
||||
const clickedRadio = (e.target as HTMLElement).closest<WaRadio>('wa-radio');
|
||||
|
||||
if (!clickedRadio || clickedRadio.disabled) {
|
||||
return;
|
||||
@@ -144,17 +161,13 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
clickedRadio.checked = true;
|
||||
|
||||
const radios = this.getAllRadios();
|
||||
const hasRadioButtons = radios.some(radio => radio.tagName.toLowerCase() === 'wa-radio-button');
|
||||
for (const radio of radios) {
|
||||
if (clickedRadio === radio) {
|
||||
continue;
|
||||
}
|
||||
|
||||
radio.checked = false;
|
||||
|
||||
if (!hasRadioButtons) {
|
||||
radio.setAttribute('tabindex', '-1');
|
||||
}
|
||||
radio.setAttribute('tabindex', '-1');
|
||||
}
|
||||
|
||||
if (this.value !== oldValue) {
|
||||
@@ -164,7 +177,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
};
|
||||
|
||||
private getAllRadios() {
|
||||
return [...this.querySelectorAll<WaRadio | WaRadioButton>('wa-radio, wa-radio-button')];
|
||||
return [...this.querySelectorAll<WaRadio>('wa-radio')];
|
||||
}
|
||||
|
||||
private handleLabelClick() {
|
||||
@@ -173,12 +186,12 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
private async syncRadioElements() {
|
||||
const radios = this.getAllRadios();
|
||||
|
||||
// Detect the presence of radio buttons
|
||||
this.hasRadioButtons = radios.some(radio => radio.localName === 'wa-radio-button');
|
||||
let hasRadioButtons = false;
|
||||
|
||||
// Add data attributes to support styling
|
||||
radios.forEach((radio, index) => {
|
||||
if (radio.appearance === 'button') hasRadioButtons = true;
|
||||
radio.setAttribute('size', this.size);
|
||||
radio.toggleAttribute('data-wa-radio-horizontal', this.orientation !== 'vertical');
|
||||
radio.toggleAttribute('data-wa-radio-vertical', this.orientation === 'vertical');
|
||||
radio.toggleAttribute('data-wa-radio-first', index === 0);
|
||||
@@ -186,8 +199,10 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
radio.toggleAttribute('data-wa-radio-last', index === radios.length - 1);
|
||||
});
|
||||
|
||||
// If at least one radio button exists, we assume it's a radio button group
|
||||
this.hasRadioButtons = hasRadioButtons;
|
||||
|
||||
await Promise.all(
|
||||
// Sync the checked state and size
|
||||
radios.map(async radio => {
|
||||
await radio.updateComplete;
|
||||
|
||||
@@ -200,43 +215,8 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
);
|
||||
|
||||
if (radios.length > 0 && !radios.some(radio => radio.checked)) {
|
||||
if (this.hasRadioButtons) {
|
||||
const buttonRadio = radios[0].shadowRoot?.querySelector('button');
|
||||
|
||||
if (buttonRadio) {
|
||||
buttonRadio.setAttribute('tabindex', '0');
|
||||
}
|
||||
} else {
|
||||
radios[0].setAttribute('tabindex', '0');
|
||||
}
|
||||
radios[0].setAttribute('tabindex', '0');
|
||||
}
|
||||
|
||||
if (this.hasRadioButtons) {
|
||||
const buttonGroup = this.shadowRoot?.querySelector('wa-button-group');
|
||||
|
||||
if (buttonGroup) {
|
||||
buttonGroup.disableRole = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We use the first available radio as the validationTarget similar to native HTML that shows the validation popup on
|
||||
* the first radio element.
|
||||
*/
|
||||
get validationTarget() {
|
||||
if (isServer) return undefined;
|
||||
|
||||
const radio = this.querySelector<WaRadio | WaRadioButton>(':is(wa-radio, wa-radio-button):not([disabled])');
|
||||
if (!radio) return undefined;
|
||||
|
||||
// If it's a radio button, return the internal button element
|
||||
if (radio.localName === 'wa-radio-button') {
|
||||
return radio.input || radio;
|
||||
}
|
||||
|
||||
// Otherwise return the radio itself
|
||||
return radio;
|
||||
}
|
||||
|
||||
@watch('value')
|
||||
@@ -244,19 +224,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
@watch('size', { waitUntilFirstUpdate: true })
|
||||
handleSizeChange() {
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
formResetCallback(...args: Parameters<WebAwesomeFormAssociatedElement['formResetCallback']>) {
|
||||
this.value = this.defaultValue;
|
||||
|
||||
super.formResetCallback(...args);
|
||||
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
private handleKeyDown(event: KeyboardEvent) {
|
||||
if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(event.key)) {
|
||||
return;
|
||||
@@ -340,7 +307,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
'form-control': true,
|
||||
'form-control-radio-group': true,
|
||||
'form-control-has-label': hasLabel,
|
||||
'form-control-has-radio-buttons': this.hasRadioButtons,
|
||||
'has-radio-buttons': this.hasRadioButtons,
|
||||
})}
|
||||
role="radiogroup"
|
||||
aria-labelledby="label"
|
||||
@@ -358,14 +325,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
<slot name="label">${this.label}</slot>
|
||||
</label>
|
||||
|
||||
<slot
|
||||
part="form-control-input"
|
||||
class=${classMap({
|
||||
'wa-button-group': this.hasRadioButtons,
|
||||
'wa-button-group-vertical': this.hasRadioButtons && this.orientation === 'vertical',
|
||||
})}
|
||||
@slotchange=${this.syncRadioElements}
|
||||
></slot>
|
||||
<slot part="form-control-input" @slotchange=${this.syncRadioElements}></slot>
|
||||
|
||||
<slot
|
||||
name="hint"
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
:host {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
--background-color: var(--wa-form-control-background-color);
|
||||
--background-color-checked: var(--background-color);
|
||||
--border-color: var(--wa-form-control-border-color);
|
||||
--border-color-checked: var(--wa-form-control-activated-color);
|
||||
--border-style: var(--wa-border-style);
|
||||
--border-width: var(--wa-form-control-border-width);
|
||||
--box-shadow: none;
|
||||
--checked-icon-color: var(--wa-form-control-activated-color);
|
||||
--checked-icon-scale: 0.75;
|
||||
--toggle-size: round(1lh, 1px);
|
||||
|
||||
color: var(--wa-form-control-value-color);
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: top;
|
||||
vertical-align: middle;
|
||||
font-family: inherit;
|
||||
font-weight: var(--wa-form-control-value-font-weight);
|
||||
line-height: var(--wa-form-control-value-line-height);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:host(:focus-visible) {
|
||||
:host(:focus) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.checked-icon {
|
||||
display: flex;
|
||||
fill: currentColor;
|
||||
width: var(--toggle-size);
|
||||
height: var(--toggle-size);
|
||||
scale: var(--checked-icon-scale);
|
||||
}
|
||||
|
||||
/* When the control isn't checked, hide the circle for Windows High Contrast mode a11y */
|
||||
:host(:not(:state(checked))) svg circle {
|
||||
opacity: 0;
|
||||
@@ -28,6 +36,146 @@
|
||||
}
|
||||
|
||||
[part~='hint'] {
|
||||
grid-column: 2;
|
||||
margin-block-start: var(--wa-space-3xs);
|
||||
}
|
||||
|
||||
/* Default appearance */
|
||||
:host([appearance='default']) {
|
||||
.control {
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--toggle-size);
|
||||
height: var(--toggle-size);
|
||||
border-color: var(--border-color);
|
||||
border-radius: 50%;
|
||||
border-style: var(--border-style);
|
||||
border-width: var(--border-width);
|
||||
background-color: var(--background-color);
|
||||
box-shadow: var(--box-shadow);
|
||||
color: transparent;
|
||||
transition:
|
||||
background var(--wa-transition-normal),
|
||||
border-color var(--wa-transition-fast),
|
||||
box-shadow var(--wa-transition-fast),
|
||||
color var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
|
||||
margin-inline-end: var(--wa-space-xs);
|
||||
}
|
||||
|
||||
.checked-icon {
|
||||
display: flex;
|
||||
fill: currentColor;
|
||||
width: var(--toggle-size);
|
||||
height: var(--toggle-size);
|
||||
scale: var(--checked-icon-scale);
|
||||
}
|
||||
}
|
||||
|
||||
/* Checked */
|
||||
:host(:state(checked)) .control {
|
||||
color: var(--checked-icon-color);
|
||||
border-color: var(--border-color-checked);
|
||||
background-color: var(--background-color-checked);
|
||||
}
|
||||
|
||||
/* Focus */
|
||||
:host(:focus-visible) .control {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
:host([disabled]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Button appearance */
|
||||
:host([appearance='button']) {
|
||||
align-items: center;
|
||||
min-height: var(--wa-form-control-height);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border: var(--border-width) var(--border-style) var(--wa-form-control-border-color);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0 var(--wa-space);
|
||||
transition:
|
||||
background-color var(--wa-transition-fast),
|
||||
border-color var(--wa-transition-fast);
|
||||
|
||||
.control {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Horizontal grouping - remove inner border radius */
|
||||
:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-inner]) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-first]) {
|
||||
border-start-end-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-last]) {
|
||||
border-start-start-radius: 0;
|
||||
border-end-start-radius: 0;
|
||||
}
|
||||
|
||||
/* Vertical grouping - remove inner border radius */
|
||||
:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-inner]) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-first]) {
|
||||
border-end-start-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-last]) {
|
||||
border-start-start-radius: 0;
|
||||
border-start-end-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='button']:hover:not([disabled], :state(checked))) {
|
||||
background-color: color-mix(in srgb, var(--wa-color-surface-default) 95%, var(--wa-color-mix-hover));
|
||||
}
|
||||
|
||||
:host([appearance='button']:focus-visible) {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
:host([appearance='button']:state(checked)) {
|
||||
border-color: var(--border-color-checked);
|
||||
background-color: var(--wa-color-brand-fill-quiet);
|
||||
}
|
||||
|
||||
:host([appearance='button']:state(checked):focus-visible) {
|
||||
outline: var(--wa-focus-ring-style) var(--wa-focus-ring-width) var(--wa-color-brand-border-loud);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Remove inner borders and handle overlap */
|
||||
:host([appearance='button'][data-wa-radio-horizontal]:not([data-wa-radio-first])) {
|
||||
margin-inline-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
|
||||
:host([appearance='button'][data-wa-radio-vertical]:not([data-wa-radio-first])) {
|
||||
margin-block-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
|
||||
/* Ensure interactive states are visible above adjacent buttons */
|
||||
:host([appearance='button']:hover),
|
||||
:host([appearance='button']:state(checked)) {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:host([appearance='button']:focus-visible) {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user