mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-19 07:29:14 +00:00
Compare commits
6 Commits
select-eve
...
kj/adaptiv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d75b47dbf1 | ||
|
|
22c9547d60 | ||
|
|
f63dfbfff0 | ||
|
|
9a7947debd | ||
|
|
d2e1653519 | ||
|
|
5b7004e72d |
@@ -249,7 +249,10 @@
|
||||
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
|
||||
</span>
|
||||
<ul>
|
||||
<li>
|
||||
<li>
|
||||
<a href="/docs/patterns/blog-news/adaptable-view/">Adaptable View</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/docs/patterns/blog-news/banners/">Banners</a>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -28,8 +28,11 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
|
||||
- Fixed a bug in JSX typings that generated the incorrect component imports [issue:1303]
|
||||
- Fixed a bug in `<wa-slider>` that prevented the thumb from receiving focus when clicking/tapping [issue:1312]
|
||||
- Fixed a bug in `<wa-scroller>` that caused the shadow to appear below relatively-positioned elements [issue:1326]
|
||||
- Fixed a bug in `<wa-details>` that caused it to expand/collapse when clicking on interactive elements in the summary [issue:1252]
|
||||
- Fixed `<wa-button>` to have `static` positioning by default and `relative` positioning only when used with `<wa-badge>` [pr:1346]
|
||||
- Fixed spacing in `<wa-input>` when both clear and password toggle icons are present [issue:1325]
|
||||
- Fixed a bug in `<wa-radio-group>` and `<wa-radio>` where changing appearances dynamically would render incorrectly [issue:1178]
|
||||
- Fixed a bug in `<wa-input>` that prevented the value from changing when assigning non-string values to `value` [issue:1323]
|
||||
|
||||
## 3.0.0-beta.4
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
import { WaHideEvent } from '../../events/hide.js';
|
||||
import { WaShowEvent } from '../../events/show.js';
|
||||
import { animate, parseDuration } from '../../internal/animate.js';
|
||||
import { getTargetElement, waitForEvent } from '../../internal/event.js';
|
||||
import { waitForEvent } from '../../internal/event.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './details.css';
|
||||
@@ -112,9 +113,27 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
private handleSummaryClick(event: MouseEvent) {
|
||||
let targetElement = getTargetElement(event);
|
||||
const eventPath = event.composedPath() as HTMLElement[];
|
||||
|
||||
if (targetElement?.closest('a, button, wa-button, input, wa-input, textarea, wa-textarea, select, wa-select')) {
|
||||
// Check if any element in the path is interactive
|
||||
const hasInteractiveElement = eventPath.some(element => {
|
||||
if (!(element instanceof HTMLElement)) return false;
|
||||
|
||||
// Check native interactive elements
|
||||
const tagName = element.tagName?.toLowerCase();
|
||||
if (['a', 'button', 'input', 'textarea', 'select'].includes(tagName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for Web Awesome form controls
|
||||
if (element instanceof WebAwesomeFormAssociatedElement) {
|
||||
return !('disabled' in element) || !element.disabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (hasInteractiveElement) {
|
||||
// Let interactive elements handle their own clicks, fixes #309
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
min=${ifDefined(this.min)}
|
||||
max=${ifDefined(this.max)}
|
||||
step=${ifDefined(this.step as number)}
|
||||
.value=${live(this.value || '')}
|
||||
.value=${live(this.value ?? '')}
|
||||
autocapitalize=${ifDefined(this.autocapitalize)}
|
||||
autocomplete=${ifDefined(this.autocomplete)}
|
||||
autocorrect=${ifDefined(this.autocorrect)}
|
||||
|
||||
@@ -18,31 +18,19 @@
|
||||
margin-inline-start: var(--wa-form-control-required-content-offset);
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
[part~='form-control-input'] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75em;
|
||||
gap: 0; /* Radios handle their own spacing */
|
||||
}
|
||||
|
||||
/* Horizontal */
|
||||
:host([orientation='horizontal']) [part~='form-control-input'] {
|
||||
flex-direction: row;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
/* Help text */
|
||||
[part~='hint'] {
|
||||
margin-block-start: 0.5em;
|
||||
}
|
||||
|
||||
/* Radios have the "button" appearance */
|
||||
:host fieldset.has-radio-buttons {
|
||||
[part~='form-control-input'] {
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +57,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'hint', 'label');
|
||||
|
||||
@state() hasRadioButtons = false;
|
||||
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
|
||||
/**
|
||||
@@ -197,11 +195,9 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
private async syncRadioElements() {
|
||||
const radios = this.getAllRadios();
|
||||
let hasRadioButtons = false;
|
||||
|
||||
// Add data attributes to support styling
|
||||
// Set positioning data attributes and properties
|
||||
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');
|
||||
@@ -213,9 +209,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
(radio as WaRadio).forceDisabled = this.disabled;
|
||||
});
|
||||
|
||||
// If at least one radio button exists, we assume it's a radio button group
|
||||
this.hasRadioButtons = hasRadioButtons;
|
||||
|
||||
await Promise.all(
|
||||
radios.map(async radio => {
|
||||
await radio.updateComplete;
|
||||
@@ -349,7 +342,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
'form-control': true,
|
||||
'form-control-radio-group': true,
|
||||
'form-control-has-label': hasLabel,
|
||||
'has-radio-buttons': this.hasRadioButtons,
|
||||
})}
|
||||
role="radiogroup"
|
||||
aria-labelledby="label"
|
||||
|
||||
@@ -31,6 +31,41 @@
|
||||
margin-block-start: 0.5em;
|
||||
}
|
||||
|
||||
/* Default spacing for default appearance radios */
|
||||
:host([appearance='default']) {
|
||||
margin-block: 0.375em; /* Half of the original 0.75em gap on each side */
|
||||
}
|
||||
|
||||
:host([appearance='default'][data-wa-radio-horizontal]) {
|
||||
margin-block: 0;
|
||||
margin-inline: 0.5em; /* Half of the original 1em gap on each side */
|
||||
}
|
||||
|
||||
/* Remove margin from first/last items to prevent extra space */
|
||||
:host([appearance='default'][data-wa-radio-first]) {
|
||||
margin-block-start: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
:host([appearance='default'][data-wa-radio-last]) {
|
||||
margin-block-end: 0;
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
/* Button appearance have no spacing, they get handled by the overlap margins below */
|
||||
:host([appearance='button']) {
|
||||
margin: 0;
|
||||
align-items: center;
|
||||
min-height: var(--wa-form-control-height);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border: var(--wa-form-control-border-width) var(--wa-form-control-border-style) var(--wa-form-control-border-color);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0 var(--wa-form-control-padding-inline);
|
||||
transition:
|
||||
background-color var(--wa-transition-fast),
|
||||
border-color var(--wa-transition-fast);
|
||||
}
|
||||
|
||||
/* Default appearance */
|
||||
:host([appearance='default']) {
|
||||
.control {
|
||||
@@ -66,6 +101,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Button appearance */
|
||||
:host([appearance='button']) {
|
||||
.control {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Checked */
|
||||
:host(:state(checked)) .control {
|
||||
color: var(--checked-icon-color);
|
||||
@@ -85,23 +127,6 @@
|
||||
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(--wa-form-control-border-width) var(--wa-form-control-border-style) var(--wa-form-control-border-color);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0 var(--wa-form-control-padding-inline);
|
||||
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;
|
||||
@@ -153,7 +178,7 @@
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Remove inner borders and handle overlap */
|
||||
/* Button overlap margins */
|
||||
:host([appearance='button'][data-wa-radio-horizontal]:not([data-wa-radio-first])) {
|
||||
margin-inline-start: calc(-1 * var(--wa-form-control-border-width));
|
||||
}
|
||||
|
||||
@@ -111,7 +111,6 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
|
||||
// We override `setValue` because we don't want to set form values from here. We want to do that in "RadioGroup" itself.
|
||||
}
|
||||
|
||||
// Update the handleClick method (around line 75)
|
||||
private handleClick = () => {
|
||||
if (!this.disabled && !this.forceDisabled) {
|
||||
this.checked = true;
|
||||
|
||||
@@ -493,6 +493,10 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
this.displayInput.focus();
|
||||
}
|
||||
|
||||
private handleComboboxClick(event: MouseEvent) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
private handleComboboxMouseDown(event: MouseEvent) {
|
||||
const path = event.composedPath();
|
||||
const isButton = path.some(el => el instanceof Element && el.tagName.toLowerCase() === 'wa-button');
|
||||
@@ -944,6 +948,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
slot="anchor"
|
||||
@keydown=${this.handleComboboxKeyDown}
|
||||
@mousedown=${this.handleComboboxMouseDown}
|
||||
@click=${this.handleComboboxClick}
|
||||
>
|
||||
<slot part="start" name="start" class="start"></slot>
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ function syncCheckboxes(changedTreeItem: WaTreeItem, initialSync = false) {
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
*
|
||||
* @cssproperty [--indent-size=var(--wa-spacing-m)] - The size of the indentation for nested items.
|
||||
* @cssproperty [--indent-size=var(--wa-space-m)] - The size of the indentation for nested items.
|
||||
* @cssproperty [--indent-guide-color=var(--wa-color-surface-border)] - The color of the indentation line.
|
||||
* @cssproperty [--indent-guide-offset=0] - The amount of vertical spacing to leave between the top and bottom of the
|
||||
* indentation line's starting position.
|
||||
|
||||
@@ -11,17 +11,3 @@ export function waitForEvent(el: HTMLElement, eventName: string) {
|
||||
el.addEventListener(eventName, done);
|
||||
});
|
||||
}
|
||||
|
||||
export function getTargetElement(event: Event) {
|
||||
if (event.target instanceof Node) {
|
||||
switch (event.target.nodeType) {
|
||||
case Node.TEXT_NODE:
|
||||
case Node.COMMENT_NODE:
|
||||
return event.target.parentNode as Element;
|
||||
case Node.ELEMENT_NODE:
|
||||
return event.target as Element;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user