kopia lustrzana https://github.com/shoelace-style/shoelace
Merge pull request #1372 from justinfagnani/no-bind
Code size optimizations: Replace .bind() with arrow functions, add listeners in constructors.pull/1377/head
commit
c167bdd80f
|
@ -91,8 +91,6 @@ export default class SlAnimation extends ShoelaceElement {
|
|||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.createAnimation();
|
||||
this.handleAnimationCancel = this.handleAnimationCancel.bind(this);
|
||||
this.handleAnimationFinish = this.handleAnimationFinish.bind(this);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
|
@ -100,17 +98,17 @@ export default class SlAnimation extends ShoelaceElement {
|
|||
this.destroyAnimation();
|
||||
}
|
||||
|
||||
private handleAnimationFinish() {
|
||||
private handleAnimationFinish = () => {
|
||||
this.play = false;
|
||||
this.hasStarted = false;
|
||||
this.emit('sl-finish');
|
||||
}
|
||||
};
|
||||
|
||||
private handleAnimationCancel() {
|
||||
private handleAnimationCancel = () => {
|
||||
this.play = false;
|
||||
this.hasStarted = false;
|
||||
this.emit('sl-cancel');
|
||||
}
|
||||
};
|
||||
|
||||
private handleSlotChange() {
|
||||
this.destroyAnimation();
|
||||
|
|
|
@ -167,17 +167,11 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
|
|||
return '';
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleHostClick = this.handleHostClick.bind(this);
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('click', this.handleHostClick);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener('click', this.handleHostClick);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (this.isButton()) {
|
||||
this.formControlController.updateValidity();
|
||||
|
@ -204,13 +198,13 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
|
|||
}
|
||||
}
|
||||
|
||||
private handleHostClick(event: MouseEvent) {
|
||||
private handleHostClick = (event: MouseEvent) => {
|
||||
// Prevent the click event from being emitted when the button is disabled or loading
|
||||
if (this.disabled || this.loading) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleInvalid(event: Event) {
|
||||
this.formControlController.setValidity(false);
|
||||
|
|
|
@ -132,7 +132,7 @@ export default class SlCarousel extends ShoelaceElement {
|
|||
|
||||
protected firstUpdated(): void {
|
||||
this.initializeSlides();
|
||||
this.mutationObserver = new MutationObserver(this.handleSlotChange.bind(this));
|
||||
this.mutationObserver = new MutationObserver(this.handleSlotChange);
|
||||
this.mutationObserver.observe(this, { childList: true, subtree: false });
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ export default class SlCarousel extends ShoelaceElement {
|
|||
}
|
||||
}
|
||||
|
||||
private handleSlotChange(mutations: MutationRecord[]) {
|
||||
private handleSlotChange = (mutations: MutationRecord[]) => {
|
||||
const needsInitialization = mutations.some(mutation =>
|
||||
[...mutation.addedNodes, ...mutation.removedNodes].some(
|
||||
node => SlCarouselItem.isCarouselItem(node) && !(node as HTMLElement).hasAttribute('data-clone')
|
||||
|
@ -223,7 +223,7 @@ export default class SlCarousel extends ShoelaceElement {
|
|||
this.initializeSlides();
|
||||
}
|
||||
this.requestUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
@watch('loop', { waitUntilFirstUpdate: true })
|
||||
@watch('slidesPerPage', { waitUntilFirstUpdate: true })
|
||||
|
|
|
@ -20,16 +20,7 @@ export class ScrollController<T extends ScrollHost> implements ReactiveControlle
|
|||
|
||||
constructor(host: T) {
|
||||
this.host = host;
|
||||
|
||||
host.addController(this);
|
||||
|
||||
this.handleScroll = this.handleScroll.bind(this);
|
||||
this.handlePointerDown = this.handlePointerDown.bind(this);
|
||||
this.handlePointerMove = this.handlePointerMove.bind(this);
|
||||
this.handlePointerUp = this.handlePointerUp.bind(this);
|
||||
this.handlePointerUp = this.handlePointerUp.bind(this);
|
||||
this.handleTouchStart = this.handleTouchStart.bind(this);
|
||||
this.handleTouchEnd = this.handleTouchEnd.bind(this);
|
||||
}
|
||||
|
||||
async hostConnected() {
|
||||
|
@ -58,13 +49,13 @@ export class ScrollController<T extends ScrollHost> implements ReactiveControlle
|
|||
scrollContainer.removeEventListener('touchend', this.handleTouchEnd);
|
||||
}
|
||||
|
||||
handleScroll() {
|
||||
handleScroll = () => {
|
||||
if (!this.scrolling) {
|
||||
this.scrolling = true;
|
||||
this.host.requestUpdate();
|
||||
}
|
||||
this.handleScrollEnd();
|
||||
}
|
||||
};
|
||||
|
||||
@debounce(100)
|
||||
handleScrollEnd() {
|
||||
|
@ -84,7 +75,7 @@ export class ScrollController<T extends ScrollHost> implements ReactiveControlle
|
|||
}
|
||||
}
|
||||
|
||||
handlePointerDown(event: PointerEvent) {
|
||||
handlePointerDown = (event: PointerEvent) => {
|
||||
if (event.pointerType === 'touch') {
|
||||
return;
|
||||
}
|
||||
|
@ -97,9 +88,9 @@ export class ScrollController<T extends ScrollHost> implements ReactiveControlle
|
|||
|
||||
this.host.scrollContainer.addEventListener('pointermove', this.handlePointerMove);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handlePointerMove(event: PointerEvent) {
|
||||
handlePointerMove = (event: PointerEvent) => {
|
||||
const scrollContainer = this.host.scrollContainer;
|
||||
|
||||
const hasMoved = !!event.movementX || !!event.movementY;
|
||||
|
@ -111,28 +102,28 @@ export class ScrollController<T extends ScrollHost> implements ReactiveControlle
|
|||
// Ignore pointers that we are not tracking
|
||||
this.handleDrag(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handlePointerUp(event: PointerEvent) {
|
||||
handlePointerUp = (event: PointerEvent) => {
|
||||
this.pointers.delete(event.pointerId);
|
||||
this.host.scrollContainer.releasePointerCapture(event.pointerId);
|
||||
|
||||
if (this.pointers.size === 0) {
|
||||
this.handleDragEnd();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleTouchEnd(event: TouchEvent) {
|
||||
handleTouchEnd = (event: TouchEvent) => {
|
||||
for (const touch of event.changedTouches) {
|
||||
this.pointers.delete(touch.identifier);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleTouchStart(event: TouchEvent) {
|
||||
handleTouchStart = (event: TouchEvent) => {
|
||||
for (const touch of event.touches) {
|
||||
this.pointers.add(touch.identifier);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDragStart() {
|
||||
const host = this.host;
|
||||
|
|
|
@ -190,20 +190,12 @@ export default class SlColorPicker extends ShoelaceElement implements ShoelaceFo
|
|||
return this.input.validationMessage;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleFocusIn = this.handleFocusIn.bind(this);
|
||||
this.handleFocusOut = this.handleFocusOut.bind(this);
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('focusin', this.handleFocusIn);
|
||||
this.addEventListener('focusout', this.handleFocusOut);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener('focusin', this.handleFocusIn);
|
||||
this.removeEventListener('focusout', this.handleFocusOut);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.input.updateComplete.then(() => {
|
||||
this.formControlController.updateValidity();
|
||||
|
@ -222,15 +214,15 @@ export default class SlColorPicker extends ShoelaceElement implements ShoelaceFo
|
|||
});
|
||||
}
|
||||
|
||||
private handleFocusIn() {
|
||||
private handleFocusIn = () => {
|
||||
this.hasFocus = true;
|
||||
this.emit('sl-focus');
|
||||
}
|
||||
};
|
||||
|
||||
private handleFocusOut() {
|
||||
private handleFocusOut = () => {
|
||||
this.hasFocus = false;
|
||||
this.emit('sl-blur');
|
||||
}
|
||||
};
|
||||
|
||||
private handleFormatToggle() {
|
||||
const formats = ['hex', 'rgb', 'hsl', 'hsv'];
|
||||
|
|
|
@ -67,7 +67,7 @@ export default class SlDialog extends ShoelaceElement {
|
|||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'footer');
|
||||
private readonly localize = new LocalizeController(this);
|
||||
private modal: Modal;
|
||||
private modal = new Modal(this);
|
||||
private originalTrigger: HTMLElement | null;
|
||||
|
||||
@query('.dialog') dialog: HTMLElement;
|
||||
|
@ -92,12 +92,6 @@ export default class SlDialog extends ShoelaceElement {
|
|||
*/
|
||||
@property({ attribute: 'no-header', type: Boolean, reflect: true }) noHeader = false;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this);
|
||||
this.modal = new Modal(this);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.dialog.hidden = !this.open;
|
||||
|
||||
|
@ -136,12 +130,12 @@ export default class SlDialog extends ShoelaceElement {
|
|||
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
||||
}
|
||||
|
||||
private handleDocumentKeyDown(event: KeyboardEvent) {
|
||||
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
||||
if (this.open && event.key === 'Escape') {
|
||||
event.stopPropagation();
|
||||
this.requestClose('keyboard');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
|
|
|
@ -75,7 +75,7 @@ export default class SlDrawer extends ShoelaceElement {
|
|||
|
||||
private readonly hasSlotController = new HasSlotController(this, 'footer');
|
||||
private readonly localize = new LocalizeController(this);
|
||||
private modal: Modal;
|
||||
private modal = new Modal(this);
|
||||
private originalTrigger: HTMLElement | null;
|
||||
|
||||
@query('.drawer') drawer: HTMLElement;
|
||||
|
@ -109,12 +109,6 @@ export default class SlDrawer extends ShoelaceElement {
|
|||
*/
|
||||
@property({ attribute: 'no-header', type: Boolean, reflect: true }) noHeader = false;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this);
|
||||
this.modal = new Modal(this);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.drawer.hidden = !this.open;
|
||||
|
||||
|
@ -156,12 +150,12 @@ export default class SlDrawer extends ShoelaceElement {
|
|||
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
||||
}
|
||||
|
||||
private handleDocumentKeyDown(event: KeyboardEvent) {
|
||||
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
||||
if (this.open && !this.contained && event.key === 'Escape') {
|
||||
event.stopPropagation();
|
||||
this.requestClose('keyboard');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
|
|
|
@ -103,10 +103,6 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handlePanelSelect = this.handlePanelSelect.bind(this);
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||
this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this);
|
||||
this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
|
||||
|
||||
if (!this.containingElement) {
|
||||
this.containingElement = this;
|
||||
|
@ -142,7 +138,7 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
| undefined;
|
||||
}
|
||||
|
||||
handleKeyDown(event: KeyboardEvent) {
|
||||
private handleKeyDown = (event: KeyboardEvent) => {
|
||||
// Close when escape is pressed inside an open dropdown. We need to listen on the panel itself and stop propagation
|
||||
// in case any ancestors are also listening for this key.
|
||||
if (this.open && event.key === 'Escape') {
|
||||
|
@ -150,9 +146,9 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
this.hide();
|
||||
this.focusOnTrigger();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDocumentKeyDown(event: KeyboardEvent) {
|
||||
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
||||
// Close when escape or tab is pressed
|
||||
if (event.key === 'Escape' && this.open) {
|
||||
event.stopPropagation();
|
||||
|
@ -189,17 +185,17 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDocumentMouseDown(event: MouseEvent) {
|
||||
private handleDocumentMouseDown = (event: MouseEvent) => {
|
||||
// Close when clicking outside of the containing element
|
||||
const path = event.composedPath();
|
||||
if (this.containingElement && !path.includes(this.containingElement)) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handlePanelSelect(event: SlSelectEvent) {
|
||||
private handlePanelSelect = (event: SlSelectEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
|
||||
// Hide the dropdown when a menu item is selected
|
||||
|
@ -207,7 +203,7 @@ export default class SlDropdown extends ShoelaceElement {
|
|||
this.hide();
|
||||
this.focusOnTrigger();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleTriggerClick() {
|
||||
if (this.open) {
|
||||
|
|
|
@ -48,17 +48,11 @@ export default class SlMenuItem extends ShoelaceElement {
|
|||
/** Draws the menu item in a disabled state, preventing selection. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleHostClick = this.handleHostClick.bind(this);
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('click', this.handleHostClick);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener('click', this.handleHostClick);
|
||||
}
|
||||
|
||||
private handleDefaultSlotChange() {
|
||||
const textLabel = this.getTextLabel();
|
||||
|
||||
|
@ -75,13 +69,13 @@ export default class SlMenuItem extends ShoelaceElement {
|
|||
}
|
||||
}
|
||||
|
||||
private handleHostClick(event: MouseEvent) {
|
||||
private handleHostClick = (event: MouseEvent) => {
|
||||
// Prevent the click event from being emitted when the button is disabled or loading
|
||||
if (this.disabled) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@watch('checked')
|
||||
handleCheckedChange() {
|
||||
|
|
|
@ -44,7 +44,6 @@ export default class SlMutationObserver extends ShoelaceElement {
|
|||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleMutation = this.handleMutation.bind(this);
|
||||
|
||||
this.mutationObserver = new MutationObserver(this.handleMutation);
|
||||
|
||||
|
@ -57,11 +56,11 @@ export default class SlMutationObserver extends ShoelaceElement {
|
|||
this.stopObserver();
|
||||
}
|
||||
|
||||
private handleMutation(mutationList: MutationRecord[]) {
|
||||
private handleMutation = (mutationList: MutationRecord[]) => {
|
||||
this.emit('sl-mutation', {
|
||||
detail: { mutationList }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private startObserver() {
|
||||
const observeAttributes = typeof this.attr === 'string' && this.attr.length > 0;
|
||||
|
|
|
@ -45,47 +45,33 @@ export default class SlRadio extends ShoelaceElement {
|
|||
/** Disables the radio. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleBlur = this.handleBlur.bind(this);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleFocus = this.handleFocus.bind(this);
|
||||
|
||||
this.setInitialAttributes();
|
||||
this.addEventListeners();
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.removeEventListeners();
|
||||
}
|
||||
|
||||
private addEventListeners() {
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('blur', this.handleBlur);
|
||||
this.addEventListener('click', this.handleClick);
|
||||
this.addEventListener('focus', this.handleFocus);
|
||||
}
|
||||
|
||||
private removeEventListeners() {
|
||||
this.removeEventListener('blur', this.handleBlur);
|
||||
this.removeEventListener('click', this.handleClick);
|
||||
this.removeEventListener('focus', this.handleFocus);
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.setInitialAttributes();
|
||||
}
|
||||
|
||||
private handleBlur() {
|
||||
private handleBlur = () => {
|
||||
this.hasFocus = false;
|
||||
this.emit('sl-blur');
|
||||
}
|
||||
};
|
||||
|
||||
private handleClick() {
|
||||
private handleClick = () => {
|
||||
if (!this.disabled) {
|
||||
this.checked = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleFocus() {
|
||||
private handleFocus = () => {
|
||||
this.hasFocus = true;
|
||||
this.emit('sl-focus');
|
||||
}
|
||||
};
|
||||
|
||||
private setInitialAttributes() {
|
||||
this.setAttribute('role', 'radio');
|
||||
|
|
|
@ -180,9 +180,6 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
|
|||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleDocumentFocusIn = this.handleDocumentFocusIn.bind(this);
|
||||
this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this);
|
||||
this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
|
||||
|
||||
// Because this is a form control, it shouldn't be opened initially
|
||||
this.open = false;
|
||||
|
@ -211,15 +208,15 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
|
|||
this.emit('sl-blur');
|
||||
}
|
||||
|
||||
private handleDocumentFocusIn(event: KeyboardEvent) {
|
||||
private handleDocumentFocusIn = (event: KeyboardEvent) => {
|
||||
// Close when focusing out of the select
|
||||
const path = event.composedPath();
|
||||
if (this && !path.includes(this)) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleDocumentKeyDown(event: KeyboardEvent) {
|
||||
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const isClearButton = target.closest('.select__clear') !== null;
|
||||
const isIconButton = target.closest('sl-icon-button') !== null;
|
||||
|
@ -346,15 +343,15 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleDocumentMouseDown(event: MouseEvent) {
|
||||
private handleDocumentMouseDown = (event: MouseEvent) => {
|
||||
// Close when clicking outside of the select
|
||||
const path = event.composedPath();
|
||||
if (this && !path.includes(this)) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleLabelClick() {
|
||||
this.displayInput.focus();
|
||||
|
|
|
@ -70,7 +70,7 @@ export default class SlTabGroup extends ShoelaceElement {
|
|||
@property({ attribute: 'no-scroll-controls', type: Boolean }) noScrollControls = false;
|
||||
|
||||
connectedCallback() {
|
||||
const whenAllDefined = Promise.allSettled([
|
||||
const whenAllDefined = Promise.all([
|
||||
customElements.whenDefined('sl-tab'),
|
||||
customElements.whenDefined('sl-tab-panel')
|
||||
]);
|
||||
|
|
|
@ -98,23 +98,20 @@ export default class SlTooltip extends ShoelaceElement {
|
|||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
// TODO (justinfagnani): does this need to be done in firstUpdated for some
|
||||
// reason? If so, document why in a comment.
|
||||
this.addEventListener('blur', this.handleBlur, true);
|
||||
this.addEventListener('focus', this.handleFocus, true);
|
||||
this.addEventListener('click', this.handleClick);
|
||||
this.addEventListener('keydown', this.handleKeyDown);
|
||||
this.addEventListener('mouseover', this.handleMouseOver);
|
||||
this.addEventListener('mouseout', this.handleMouseOut);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleBlur = this.handleBlur.bind(this);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleFocus = this.handleFocus.bind(this);
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||
this.handleMouseOver = this.handleMouseOver.bind(this);
|
||||
this.handleMouseOut = this.handleMouseOut.bind(this);
|
||||
|
||||
this.updateComplete.then(() => {
|
||||
this.addEventListener('blur', this.handleBlur, true);
|
||||
this.addEventListener('focus', this.handleFocus, true);
|
||||
this.addEventListener('click', this.handleClick);
|
||||
this.addEventListener('keydown', this.handleKeyDown);
|
||||
this.addEventListener('mouseover', this.handleMouseOver);
|
||||
this.addEventListener('mouseout', this.handleMouseOut);
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
|
@ -127,23 +124,13 @@ export default class SlTooltip extends ShoelaceElement {
|
|||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener('blur', this.handleBlur, true);
|
||||
this.removeEventListener('focus', this.handleFocus, true);
|
||||
this.removeEventListener('click', this.handleClick);
|
||||
this.removeEventListener('keydown', this.handleKeyDown);
|
||||
this.removeEventListener('mouseover', this.handleMouseOver);
|
||||
this.removeEventListener('mouseout', this.handleMouseOut);
|
||||
}
|
||||
|
||||
private handleBlur() {
|
||||
private handleBlur = () => {
|
||||
if (this.hasTrigger('focus')) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleClick() {
|
||||
private handleClick = () => {
|
||||
if (this.hasTrigger('click')) {
|
||||
if (this.open) {
|
||||
this.hide();
|
||||
|
@ -151,37 +138,37 @@ export default class SlTooltip extends ShoelaceElement {
|
|||
this.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleFocus() {
|
||||
private handleFocus = () => {
|
||||
if (this.hasTrigger('focus')) {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleKeyDown(event: KeyboardEvent) {
|
||||
private handleKeyDown = (event: KeyboardEvent) => {
|
||||
// Pressing escape when the target element has focus should dismiss the tooltip
|
||||
if (this.open && event.key === 'Escape') {
|
||||
event.stopPropagation();
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleMouseOver() {
|
||||
private handleMouseOver = () => {
|
||||
if (this.hasTrigger('hover')) {
|
||||
const delay = parseDuration(getComputedStyle(this).getPropertyValue('--show-delay'));
|
||||
clearTimeout(this.hoverTimeout);
|
||||
this.hoverTimeout = window.setTimeout(() => this.show(), delay);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleMouseOut() {
|
||||
private handleMouseOut = () => {
|
||||
if (this.hasTrigger('hover')) {
|
||||
const delay = parseDuration(getComputedStyle(this).getPropertyValue('--hide-delay'));
|
||||
clearTimeout(this.hoverTimeout);
|
||||
this.hoverTimeout = window.setTimeout(() => this.hide(), delay);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private hasTrigger(triggerType: string) {
|
||||
const triggers = this.trigger.split(' ');
|
||||
|
|
|
@ -92,18 +92,18 @@ export default class SlTree extends ShoelaceElement {
|
|||
private mutationObserver: MutationObserver;
|
||||
private clickTarget: SlTreeItem | null = null;
|
||||
|
||||
async connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.handleTreeChanged = this.handleTreeChanged.bind(this);
|
||||
this.handleFocusIn = this.handleFocusIn.bind(this);
|
||||
this.handleFocusOut = this.handleFocusOut.bind(this);
|
||||
|
||||
this.setAttribute('role', 'tree');
|
||||
this.setAttribute('tabindex', '0');
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('focusin', this.handleFocusIn);
|
||||
this.addEventListener('focusout', this.handleFocusOut);
|
||||
this.addEventListener('sl-lazy-change', this.handleSlotChange);
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.setAttribute('role', 'tree');
|
||||
this.setAttribute('tabindex', '0');
|
||||
|
||||
await this.updateComplete;
|
||||
|
||||
|
@ -115,10 +115,6 @@ export default class SlTree extends ShoelaceElement {
|
|||
super.disconnectedCallback();
|
||||
|
||||
this.mutationObserver.disconnect();
|
||||
|
||||
this.removeEventListener('focusin', this.handleFocusIn);
|
||||
this.removeEventListener('focusout', this.handleFocusOut);
|
||||
this.removeEventListener('sl-lazy-change', this.handleSlotChange);
|
||||
}
|
||||
|
||||
// Generates a clone of the expand icon element to use for each tree item
|
||||
|
@ -160,7 +156,7 @@ export default class SlTree extends ShoelaceElement {
|
|||
});
|
||||
};
|
||||
|
||||
private handleTreeChanged(mutations: MutationRecord[]) {
|
||||
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[];
|
||||
|
@ -172,7 +168,7 @@ export default class SlTree extends ShoelaceElement {
|
|||
this.focusItem(this.getFocusableItems()[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private syncTreeItems(selectedItem: SlTreeItem) {
|
||||
const items = this.getAllTreeItems();
|
||||
|
@ -322,16 +318,16 @@ export default class SlTree extends ShoelaceElement {
|
|||
this.clickTarget = event.target as SlTreeItem;
|
||||
}
|
||||
|
||||
private handleFocusOut(event: FocusEvent) {
|
||||
private handleFocusOut = (event: FocusEvent) => {
|
||||
const relatedTarget = event.relatedTarget as HTMLElement;
|
||||
|
||||
// If the element that got the focus is not in the tree
|
||||
if (!relatedTarget || !this.contains(relatedTarget)) {
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleFocusIn(event: FocusEvent) {
|
||||
private handleFocusIn = (event: FocusEvent) => {
|
||||
const target = event.target as SlTreeItem;
|
||||
|
||||
// If the tree has been focused, move the focus to the last focused item
|
||||
|
@ -349,7 +345,7 @@ export default class SlTree extends ShoelaceElement {
|
|||
|
||||
target.tabIndex = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private handleSlotChange() {
|
||||
const items = this.getAllTreeItems();
|
||||
|
|
Ładowanie…
Reference in New Issue