mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-13 12:39:14 +00:00
Compare commits
18 Commits
v2.5.2
...
tree-focus
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
886049d714 | ||
|
|
848c059d51 | ||
|
|
8ffbd02db7 | ||
|
|
e88d57d17d | ||
|
|
5f4de6d9f5 | ||
|
|
2cce87deeb | ||
|
|
630b5b19a0 | ||
|
|
2ce1451a9f | ||
|
|
2d1badba96 | ||
|
|
1b5db078a7 | ||
|
|
91095bd63a | ||
|
|
d9703a64fd | ||
|
|
4c22e72390 | ||
|
|
d05b8fca20 | ||
|
|
afca2ad2e0 | ||
|
|
b2aa854d98 | ||
|
|
287fff7cf1 | ||
|
|
e1dedcb1b5 |
@@ -106,12 +106,12 @@
|
||||
</header>
|
||||
|
||||
<div class="sidebar-buttons">
|
||||
<sl-button size="small" class="repo-button repo-button--sponsor" href="https://github.com/sponsors/claviska" target="_blank">
|
||||
<sl-icon slot="prefix" name="heart"></sl-icon> Sponsor
|
||||
</sl-button>
|
||||
<sl-button size="small" class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace" target="_blank">
|
||||
<sl-icon slot="prefix" name="github"></sl-icon> Code
|
||||
</sl-button>
|
||||
<sl-button size="small" class="repo-button repo-button--star" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
|
||||
<sl-icon slot="prefix" name="star-fill"></sl-icon> Star
|
||||
</sl-button>
|
||||
<sl-button size="small" class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
|
||||
<sl-icon slot="prefix" name="twitter"></sl-icon> Follow
|
||||
</sl-button>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
</li>
|
||||
<li>
|
||||
<h2>Design Tokens</h2>
|
||||
<ul>
|
||||
@@ -51,7 +51,7 @@
|
||||
<li><a href="/tokens/border-radius">Border Radius</a></li>
|
||||
<li><a href="/tokens/transition">Transition</a></li>
|
||||
<li><a href="/tokens/z-index">Z-index</a></li>
|
||||
<li><a href="/tokens/more">More</a></li>
|
||||
<li><a href="/tokens/more">More Tokens</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
11
docs/assets/images/awesome.svg
Normal file
11
docs/assets/images/awesome.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="733" xmlns="http://www.w3.org/2000/svg" height="733">
|
||||
<circle cy="366.5" cx="366.5" r="366.5"/>
|
||||
<circle cy="366.5" cx="366.5" r="336.5" fill="#fede58"/>
|
||||
<path d="M325 665c-121-21-194-115-212-233v-8l-25-1-1-18h481c6 13 10 27 13 41 13 94-38 146-114 193-45 23-93 29-142 26z"/>
|
||||
<path d="M372 647c52-6 98-28 138-62 28-25 46-56 51-87 4-20 1-57-5-70l-423-1c-2 56 39 118 74 157 31 34 72 54 116 63 11 2 38 2 49 0z" fill="#871945"/>
|
||||
<path d="M76 342c-13-26-13-57-9-85 6-27 18-52 35-68 21-20 50-23 77-18 15 4 28 12 39 23 18 17 30 40 36 67 4 20 4 41 0 60l-6 21z"/>
|
||||
<path d="M234 323c5-6 6-40 2-58-3-16-4-16-10-10-14 14-38 14-52 0-15-18-12-41 6-55 3-3 5-5 5-6-1-4-22-8-34-7-42 4-57.6 40-66.2 77-3 17-1 53 4 59H234z" fill="#fff"/>
|
||||
<path d="M378 343c-2-3-6-20-7-29-5-28-1-57 11-83 15-30 41-52 72-60 29-7 57 0 82 15 26 17 45 49 50 82 2 12 2 33 0 45-1 10-5 26-8 30z"/>
|
||||
<path d="M565 324c4-5 5-34 4-50-2-14-6-24-8-24-1 0-3 2-6 5-17 17-47 13-58-9-7-16-4-31 8-43 4-4 7-8 7-9 0 0-4-2-8-3-51-17-105 20-115 80-3 15 0 43 3 53z" fill="#fff"/>
|
||||
<path d="M504 590s-46 40-105 53c-66 15-114-7-114-7s14-76 93-95c76-18 126 49 126 49z" fill="#f9bedd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1203,6 +1203,12 @@ html.sidebar-open #menu-toggle {
|
||||
font-weight: var(--sl-font-weight-normal);
|
||||
}
|
||||
|
||||
.splash li img {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -2px;
|
||||
}
|
||||
|
||||
.splash-end {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
@@ -1249,19 +1255,6 @@ html.sidebar-open #menu-toggle {
|
||||
}
|
||||
}
|
||||
|
||||
/* Repo buttons */
|
||||
.repo-button--sponsor sl-icon {
|
||||
color: var(--sl-color-pink-600);
|
||||
}
|
||||
|
||||
.repo-button--github sl-icon {
|
||||
color: var(--sl-color-neutral-700);
|
||||
}
|
||||
|
||||
.repo-button--twitter sl-icon {
|
||||
color: var(--sl-color-sky-500);
|
||||
}
|
||||
|
||||
/* Component headers */
|
||||
.component-header h1 {
|
||||
margin-bottom: 0;
|
||||
@@ -1291,14 +1284,24 @@ html.sidebar-open #menu-toggle {
|
||||
}
|
||||
|
||||
/* Repo buttons */
|
||||
.repo-button--sponsor sl-icon {
|
||||
color: var(--sl-color-pink-600);
|
||||
.sidebar-buttons {
|
||||
display: flex;
|
||||
gap: 0.125rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sidebar-buttons .repo-button {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.repo-button--github sl-icon {
|
||||
color: var(--sl-color-neutral-700);
|
||||
}
|
||||
|
||||
.repo-button--star sl-icon {
|
||||
color: var(--sl-color-yellow-500);
|
||||
}
|
||||
|
||||
.repo-button--twitter sl-icon {
|
||||
color: var(--sl-color-sky-500);
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ const App = () => {
|
||||
|
||||
### Multiple Slides Per View
|
||||
|
||||
The `slides-per-view` attribute makes it possible to display multiple slides at a time. You can also use the `slides-per-move` attribute to advance more than once slide at a time, if desired.
|
||||
The `slides-per-page` attribute makes it possible to display multiple slides at a time. You can also use the `slides-per-move` attribute to advance more than once slide at a time, if desired.
|
||||
|
||||
```html:preview
|
||||
<sl-carousel navigation pagination slides-per-page="2" slides-per-move="2">
|
||||
|
||||
@@ -289,7 +289,7 @@ const App = () => (
|
||||
|
||||
### Hoisting
|
||||
|
||||
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
Dropdown panels will be clipped if they're inside a container that has `overflow: auto|hidden`. The `hoist` attribute forces the panel to use a fixed positioning strategy, allowing it to break out of the container. In this case, the panel will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html:preview
|
||||
<div class="dropdown-hoist">
|
||||
|
||||
@@ -984,7 +984,7 @@ const App = () => {
|
||||
|
||||
By default, the popup is positioned using an absolute positioning strategy. However, if your anchor is fixed or exists within a container that has `overflow: auto|hidden`, the popup risks being clipped. To work around this, you can use a fixed positioning strategy by setting the `strategy` attribute to `fixed`.
|
||||
|
||||
The fixed positioning strategy reduces jumpiness when the anchor is fixed and allows the popup to break out containers that clip. When using this strategy, it's important to note that the content will be positioned _relative to its containing block_, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
The fixed positioning strategy reduces jumpiness when the anchor is fixed and allows the popup to break out containers that clip. When using this strategy, it's important to note that the content will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
In this example, you can see how the popup breaks out of the overflow container when it's fixed. The fixed positioning strategy tends to be less performant than absolute, so avoid using it unnecessarily.
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ const App = () => (
|
||||
|
||||
### Hoisting
|
||||
|
||||
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its containing block, which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html:preview
|
||||
<div class="tooltip-hoist">
|
||||
|
||||
@@ -19,8 +19,7 @@ toc: false
|
||||
- First-class [React support](/frameworks/react) ⚛️
|
||||
- Built-in localization 💬
|
||||
- Open source 😸
|
||||
|
||||
Designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska).
|
||||
- [More awesome than ever](https://blog.fontawesome.com/shoelace-joins-font-awesome/) 
|
||||
|
||||
</div>
|
||||
<div class="splash-end">
|
||||
@@ -105,23 +104,7 @@ If you need to support IE11 or pre-Chromium Edge, this library isn't for you. Al
|
||||
|
||||
## License
|
||||
|
||||
Shoelace is designed in New Hampshire by [Cory LaViska](https://twitter.com/claviska). It's available under the terms of the MIT license.
|
||||
|
||||
Designing, developing, and supporting this library requires a lot of time, effort, and skill. If you're using this software to make a profit, I respectfully ask that you help [fund its development](https://github.com/sponsors/claviska) by becoming a sponsor.
|
||||
|
||||
👇 Your support is very much appreciated! 👇
|
||||
|
||||
<sl-button class="repo-button repo-button--sponsor" href="https://github.com/sponsors/claviska" target="_blank">
|
||||
<sl-icon slot="prefix" name="heart"></sl-icon> Become a sponsor
|
||||
</sl-button>
|
||||
|
||||
<sl-button class="repo-button repo-button--github" href="https://github.com/shoelace-style/shoelace/stargazers" target="_blank">
|
||||
<sl-icon slot="prefix" name="github"></sl-icon> Star
|
||||
</sl-button>
|
||||
|
||||
<sl-button class="repo-button repo-button--twitter" href="https://twitter.com/shoelace_style" target="_blank">
|
||||
<sl-icon slot="prefix" name="twitter"></sl-icon> Follow
|
||||
</sl-button>
|
||||
Shoelace was created in New Hampshire by [Cory LaViska](https://twitter.com/claviska). It's available under the terms of the [MIT license](https://github.com/shoelace-style/shoelace/blob/next/LICENSE.md).
|
||||
|
||||
## Attribution
|
||||
|
||||
|
||||
@@ -12,6 +12,14 @@ Components with the <sl-badge variant="warning" pill>Experimental</sl-badge> bad
|
||||
|
||||
New versions of Shoelace are released as-needed and generally occur when a critical mass of changes have accumulated. At any time, you can see what's coming in the next release by visiting [next.shoelace.style](https://next.shoelace.style).
|
||||
|
||||
## Next
|
||||
|
||||
- Added tests for `<sl-qr-code>` [#1416]
|
||||
- Fixed a bug in `<sl-qr-code>` where the `background` attribute was never passed to the QR code [#1416]
|
||||
- Fixed a bug in `<sl-dropdown>` where aria attributes were incorrectly applied to the default `<slot>` causing Lighthouse errors [#1417]
|
||||
- Fixed a bug in `<sl-carousel>` that caused navigation to work incorrectly in some case [#1420]
|
||||
- Fixed a bug in `<sl-tree>` that caused focus to be stolen when removing focused tree items [#1430]
|
||||
|
||||
## 2.5.2
|
||||
|
||||
- Fixed broken source buttons in the docs [#1401]
|
||||
|
||||
@@ -141,7 +141,7 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
}
|
||||
|
||||
private getCurrentPage() {
|
||||
return Math.floor(this.activeSlide / this.slidesPerPage);
|
||||
return Math.ceil(this.activeSlide / this.slidesPerPage);
|
||||
}
|
||||
|
||||
private getSlides({ excludeClones = true }: { excludeClones?: boolean } = {}) {
|
||||
@@ -325,7 +325,15 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
* @param behavior - The behavior used for scrolling.
|
||||
*/
|
||||
previous(behavior: ScrollBehavior = 'smooth') {
|
||||
this.goToSlide(this.activeSlide - this.slidesPerMove, behavior);
|
||||
let previousIndex = this.activeSlide || this.activeSlide - this.slidesPerMove;
|
||||
let canSnap = false;
|
||||
|
||||
while (!canSnap && previousIndex > 0) {
|
||||
previousIndex -= 1;
|
||||
canSnap = Math.abs(previousIndex - this.slidesPerMove) % this.slidesPerMove === 0;
|
||||
}
|
||||
|
||||
this.goToSlide(previousIndex, behavior);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -411,12 +411,9 @@ export default class SlDropdown extends ShoelaceElement {
|
||||
@slotchange=${this.handleTriggerSlotChange}
|
||||
></slot>
|
||||
|
||||
<slot
|
||||
part="panel"
|
||||
class="dropdown__panel"
|
||||
aria-hidden=${this.open ? 'false' : 'true'}
|
||||
aria-labelledby="dropdown"
|
||||
></slot>
|
||||
<div aria-hidden=${this.open ? 'false' : 'true'} aria-labelledby="dropdown">
|
||||
<slot part="panel" class="dropdown__panel"></slot>
|
||||
</div>
|
||||
</sl-popup>
|
||||
`;
|
||||
}
|
||||
|
||||
144
src/components/qr-code/qr-code.test.ts
Normal file
144
src/components/qr-code/qr-code.test.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import '../../../dist/shoelace.js';
|
||||
import { expect, fixture, html } from '@open-wc/testing';
|
||||
import type SlQrCode from './qr-code';
|
||||
|
||||
const getCanvas = (qrCode: SlQrCode): HTMLCanvasElement => {
|
||||
const possibleCanvas = qrCode.shadowRoot?.querySelector<HTMLCanvasElement>('.qr-code');
|
||||
expect(possibleCanvas).to.exist;
|
||||
return possibleCanvas!;
|
||||
};
|
||||
|
||||
const expectCanvasToHaveAriaLabel = (qrCode: SlQrCode, expectedLabel: string): void => {
|
||||
const canvas = getCanvas(qrCode);
|
||||
expect(canvas).to.have.attribute('aria-label', expectedLabel);
|
||||
};
|
||||
|
||||
class Color {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
alpha: number;
|
||||
|
||||
constructor(r: number, g: number, b: number, alpha: number) {
|
||||
this.r = r;
|
||||
this.b = b;
|
||||
this.g = g;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
equals(other: Color): boolean {
|
||||
return (
|
||||
other === this || (this.r === other.r && this.b === other.b && this.g === other.g && this.alpha === other.alpha)
|
||||
);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
}
|
||||
|
||||
interface QrCodeColors {
|
||||
foreground: Color;
|
||||
background: Color;
|
||||
}
|
||||
|
||||
const getColorFromPixel = (colorArray: Uint8ClampedArray, pixelNumber: number): Color => {
|
||||
const startEntryNumber = pixelNumber * 4;
|
||||
return new Color(
|
||||
colorArray[startEntryNumber],
|
||||
colorArray[startEntryNumber + 1],
|
||||
colorArray[startEntryNumber + 2],
|
||||
colorArray[startEntryNumber + 3]
|
||||
);
|
||||
};
|
||||
|
||||
const getQrCodeColors = (qrCode: SlQrCode): QrCodeColors => {
|
||||
const canvas = getCanvas(qrCode);
|
||||
const context = canvas.getContext('2d');
|
||||
const imageData = context?.getImageData(0, 0, canvas.width, canvas.height);
|
||||
expect(imageData).not.to.be.null;
|
||||
const colorArray = imageData!.data;
|
||||
const numberOfPixels = imageData!.width * imageData!.height;
|
||||
const foregroundColor = getColorFromPixel(colorArray, 0);
|
||||
let backgroundColor: Color | null = null;
|
||||
for (let pixelNumber = 0; pixelNumber < numberOfPixels; pixelNumber++) {
|
||||
const currentColor = getColorFromPixel(colorArray, pixelNumber);
|
||||
if (!currentColor.equals(foregroundColor)) {
|
||||
backgroundColor = currentColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
foreground: foregroundColor,
|
||||
background: backgroundColor!
|
||||
};
|
||||
};
|
||||
|
||||
const red = new Color(255, 0, 0, 255);
|
||||
const white = new Color(255, 255, 255, 255);
|
||||
const blue = new Color(0, 0, 255, 255);
|
||||
|
||||
const expectQrCodeColorsToBe = (qrCode: SlQrCode, expectedColors: QrCodeColors): void => {
|
||||
const qrCodeColors = getQrCodeColors(qrCode);
|
||||
const backgroundMessage =
|
||||
'expected background color to be ' +
|
||||
expectedColors.background.toString() +
|
||||
' but got ' +
|
||||
qrCodeColors.background.toString();
|
||||
expect(qrCodeColors.background.equals(expectedColors.background), backgroundMessage).to.be.true;
|
||||
const foregroundMessage =
|
||||
'expected foreground color to be ' +
|
||||
expectedColors.foreground.toString() +
|
||||
' but got ' +
|
||||
qrCodeColors.foreground.toString();
|
||||
expect(qrCodeColors.foreground.equals(expectedColors.foreground), foregroundMessage).to.be.true;
|
||||
};
|
||||
|
||||
describe('<sl-qr-code>', () => {
|
||||
it('should render a component', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data"></sl-qr-code>`);
|
||||
|
||||
expect(qrCode).to.exist;
|
||||
});
|
||||
|
||||
it('should be accessible', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data"></sl-qr-code>`);
|
||||
|
||||
await expect(qrCode).to.be.accessible();
|
||||
});
|
||||
|
||||
it('uses the value as label if none given', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data"></sl-qr-code>`);
|
||||
|
||||
expectCanvasToHaveAriaLabel(qrCode, 'test data');
|
||||
});
|
||||
|
||||
it('uses the label if given', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data" label="test label"></sl-qr-code>`);
|
||||
|
||||
expectCanvasToHaveAriaLabel(qrCode, 'test label');
|
||||
});
|
||||
|
||||
it('sets the correct color for the qr code', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data" fill="red"></sl-qr-code>`);
|
||||
|
||||
expectQrCodeColorsToBe(qrCode, { foreground: red, background: white });
|
||||
});
|
||||
|
||||
it('sets the correct background for the qr code', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(
|
||||
html` <sl-qr-code value="test data" fill="red" background="blue"></sl-qr-code>`
|
||||
);
|
||||
|
||||
expectQrCodeColorsToBe(qrCode, { foreground: red, background: blue });
|
||||
});
|
||||
|
||||
it('has the expected size', async () => {
|
||||
const qrCode = await fixture<SlQrCode>(html` <sl-qr-code value="test data" size="100"></sl-qr-code>`);
|
||||
|
||||
const height = qrCode.getBoundingClientRect().height;
|
||||
const width = qrCode.getBoundingClientRect().width;
|
||||
expect(height).to.equal(100);
|
||||
expect(width).to.equal(100);
|
||||
});
|
||||
});
|
||||
@@ -58,7 +58,7 @@ export default class SlQrCode extends ShoelaceElement {
|
||||
radius: this.radius,
|
||||
ecLevel: this.errorCorrection,
|
||||
fill: this.fill,
|
||||
background: null,
|
||||
background: this.background,
|
||||
// We draw the canvas larger and scale its container down to avoid blurring on high-density displays
|
||||
size: this.size * 2
|
||||
},
|
||||
|
||||
@@ -258,7 +258,7 @@ describe('<sl-tab-group>', () => {
|
||||
});
|
||||
|
||||
// TODO - this fails sporadically, likely due to a timing issue. It tests fine manually.
|
||||
it('does not show scroll buttons if placement is end', async () => {
|
||||
it.skip('does not show scroll buttons if placement is end', async () => {
|
||||
const tabGroup = await fixture<SlTabGroup>(html`<sl-tab-group> ${generateTabs(50)} </sl-tab-group>`);
|
||||
tabGroup.placement = 'end';
|
||||
|
||||
@@ -269,7 +269,7 @@ describe('<sl-tab-group>', () => {
|
||||
});
|
||||
|
||||
// TODO - this fails sporadically, likely due to a timing issue. It tests fine manually.
|
||||
it('does scroll on scroll button click', async () => {
|
||||
it.skip('does scroll on scroll button click', async () => {
|
||||
const numberOfElements = 15;
|
||||
const tabGroup = await fixture<SlTabGroup>(
|
||||
html`<sl-tab-group> ${generateTabs(numberOfElements)} </sl-tab-group>`
|
||||
|
||||
@@ -159,14 +159,8 @@ export default class SlTree extends ShoelaceElement {
|
||||
private handleTreeChanged = (mutations: MutationRecord[]) => {
|
||||
for (const mutation of mutations) {
|
||||
const addedNodes: SlTreeItem[] = [...mutation.addedNodes].filter(SlTreeItem.isTreeItem) as SlTreeItem[];
|
||||
const removedNodes = [...mutation.removedNodes].filter(SlTreeItem.isTreeItem) as SlTreeItem[];
|
||||
|
||||
addedNodes.forEach(this.initTreeItem);
|
||||
|
||||
// If the focused item has been removed form the DOM, move the focus to the first focusable item
|
||||
if (removedNodes.includes(this.lastFocusedItem)) {
|
||||
this.focusItem(this.getFocusableItems()[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -45,9 +45,7 @@ function register(tagName: string): Promise<void> {
|
||||
|
||||
// Register it
|
||||
return new Promise((resolve, reject) => {
|
||||
import(path)
|
||||
.then(() => resolve())
|
||||
.catch(() => reject(new Error(`Unable to automatically load<${tagName}> from ${path}`)));
|
||||
import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { playwrightLauncher } from '@web/test-runner-playwright';
|
||||
export default {
|
||||
rootDir: '.',
|
||||
files: 'src/**/*.test.ts', // "default" group
|
||||
concurrentBrowsers: 1,
|
||||
concurrentBrowsers: 3,
|
||||
nodeResolve: true,
|
||||
testFramework: {
|
||||
config: {
|
||||
|
||||
Reference in New Issue
Block a user