Skip to content

Commit

Permalink
fix(floating-ui): improve floating element performance (#8409)
Browse files Browse the repository at this point in the history
**Related Issue:** #7979 #8214 #8386 #8419 #5697

## Summary

- reverts #8001
  - Keeps doc updates 
- reverts partially #8230
- Keeps drag classes that are setting `overflow:hidden` when a drag is
occurring.
- Keeps roundByDPR floating-ui fix.
https://floating-ui.com/docs/misc#subpixel-and-accelerated-positioning
- Hides overflow for `calcite-sortable--chosen` class
- Only sets `top` and `left` on floating element once positioned. **This
fixes native drag and drop issue**
  • Loading branch information
driskull authored Dec 13, 2023
1 parent 509c9f1 commit 4d8cfb8
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@mixin sortable-helper-classes() {
.calcite-sortable--chosen,
.calcite-sortable--ghost,
.calcite-sortable--drag {
overflow: hidden;
Expand Down
10 changes: 10 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6260,6 +6260,8 @@ declare global {
};
interface HTMLCalciteListElementEventMap {
"calciteListChange": void;
"calciteListDragEnd": ListDragDetail;
"calciteListDragStart": ListDragDetail;
"calciteListFilter": void;
"calciteListOrderChange": ListDragDetail;
"calciteInternalListDefaultSlotChange": void;
Expand Down Expand Up @@ -9984,6 +9986,14 @@ declare namespace LocalJSX {
* Emits when any of the list item selections have changed.
*/
"onCalciteListChange"?: (event: CalciteListCustomEvent<void>) => void;
/**
* Emits when the component's dragging has ended.
*/
"onCalciteListDragEnd"?: (event: CalciteListCustomEvent<ListDragDetail>) => void;
/**
* Emits when the component's dragging has started.
*/
"onCalciteListDragStart"?: (event: CalciteListCustomEvent<ListDragDetail>) => void;
/**
* Emits when the component's filter has changed.
*/
Expand Down
10 changes: 5 additions & 5 deletions packages/calcite-components/src/components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ export class Dropdown

@Watch("open")
openHandler(): void {
if (!this.disabled) {
onToggleOpenCloseComponent(this);
onToggleOpenCloseComponent(this);

if (this.disabled) {
this.open = false;
return;
}

this.open = false;
this.reposition(true);
}

/**
Expand Down Expand Up @@ -549,7 +551,6 @@ export class Dropdown
};

onBeforeOpen(): void {
this.reposition(true);
this.calciteDropdownBeforeOpen.emit();
}

Expand All @@ -563,7 +564,6 @@ export class Dropdown

onClose(): void {
this.calciteDropdownClose.emit();
this.reposition(true);
}

setReferenceEl = (el: HTMLDivElement): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ export class InputDatePicker
this.open = false;
return;
}

this.reposition(true);
}

/**
Expand Down Expand Up @@ -766,7 +768,6 @@ export class InputDatePicker
}

onBeforeOpen(): void {
this.reposition(true);
this.calciteInputDatePickerBeforeOpen.emit();
}

Expand All @@ -792,7 +793,6 @@ export class InputDatePicker
this.restoreInputFocus();
this.focusOnOpen = false;
this.datePickerEl.reset();
this.reposition(true);
}

setStartInput = (el: HTMLCalciteInputElement): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,15 @@ export class InputTimePicker
@Prop({ reflect: true, mutable: true }) open = false;

@Watch("open")
openHandler(open: boolean): void {
openHandler(): void {
onToggleOpenCloseComponent(this);

if (this.disabled || this.readOnly) {
this.open = false;
return;
}

if (open) {
this.reposition(true);
}
this.reposition(true);
}

/** When `true`, interaction is prevented and the component is displayed with lower opacity. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export class Popover
@Watch("open")
openHandler(): void {
onToggleOpenCloseComponent(this);

this.reposition(true);
this.setExpandedAttr();
}

Expand Down Expand Up @@ -499,7 +499,6 @@ export class Popover
};

onBeforeOpen(): void {
this.reposition(true);
this.calcitePopoverBeforeOpen.emit();
}

Expand All @@ -515,7 +514,6 @@ export class Popover
onClose(): void {
this.calcitePopoverClose.emit();
deactivateFocusTrap(this);
this.reposition(true);
}

storeArrowEl = (el: SVGElement): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class Tooltip implements FloatingUIComponent, OpenCloseComponent {
@Watch("open")
openHandler(): void {
onToggleOpenCloseComponent(this);
this.reposition(true);
}

/**
Expand Down Expand Up @@ -249,7 +250,6 @@ export class Tooltip implements FloatingUIComponent, OpenCloseComponent {
// --------------------------------------------------------------------------

onBeforeOpen(): void {
this.reposition(true);
this.calciteTooltipBeforeOpen.emit();
}

Expand All @@ -263,7 +263,6 @@ export class Tooltip implements FloatingUIComponent, OpenCloseComponent {

onClose(): void {
this.calciteTooltipClose.emit();
this.reposition(true);
}

private setTransitionEl = (el): void => {
Expand Down
2 changes: 1 addition & 1 deletion packages/calcite-components/src/tests/commonTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ export function floatingUIOwner(
await scrollTo(scrollablePageSizeInPx, scrollablePageSizeInPx);
await page.waitForChanges();

expect(await getTransform()).not.toBe(initialClosedTransform);
expect(await getTransform()).toBe(initialClosedTransform);

await scrollTo(0, 0);
await page.waitForChanges();
Expand Down
16 changes: 13 additions & 3 deletions packages/calcite-components/src/utils/floating-ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,34 @@ describe("repositioning", () => {
expect(floatingEl.style.left).toBe("0");
}

it("repositions immediately by default", async () => {
it("repositions only for open components", async () => {
await reposition(fakeFloatingUiComponent, positionOptions);
assertPreOpenPositioning(floatingEl);

fakeFloatingUiComponent.open = true;

await reposition(fakeFloatingUiComponent, positionOptions);
assertOpenPositioning(floatingEl);
});

it("repositions immediately by default", async () => {
fakeFloatingUiComponent.open = true;

reposition(fakeFloatingUiComponent, positionOptions);

assertPreOpenPositioning(floatingEl);

await waitForAnimationFrame();
assertOpenPositioning(floatingEl);
});

it("can reposition after a delay", async () => {
assertPreOpenPositioning(floatingEl);

fakeFloatingUiComponent.open = true;

reposition(fakeFloatingUiComponent, positionOptions, true);

assertPreOpenPositioning(floatingEl);

await new Promise<void>((resolve) => setTimeout(resolve, repositionDebounceTimeout));
assertOpenPositioning(floatingEl);
});
Expand Down
10 changes: 6 additions & 4 deletions packages/calcite-components/src/utils/floating-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ export const positionFloatingUI =
pointerEvents,
position,
transform: open ? `translate(${roundByDPR(x)}px,${roundByDPR(y)}px)` : "",
left: open ? "0" : "",
top: open ? "0" : "",
top: 0,
left: 0,
});
};

Expand Down Expand Up @@ -427,6 +427,10 @@ export async function reposition(
options: Parameters<typeof positionFloatingUI>[1],
delayed = false
): Promise<void> {
if (!component.open) {
return;
}

const positionFunction = delayed ? getDebouncedReposition(component) : positionFloatingUI;

return positionFunction(component, options);
Expand Down Expand Up @@ -489,8 +493,6 @@ export function connectFloatingUI(

// initial positioning based on https://floating-ui.com/docs/computePosition#initial-layout
position: component.overlayPositioning,
top: "0",
left: "0",
});

const runAutoUpdate = Build.isBrowser
Expand Down

0 comments on commit 4d8cfb8

Please sign in to comment.