Skip to content

Commit

Permalink
feat(action-menu, combobox, dropdown, input-date-picker, popover): al…
Browse files Browse the repository at this point in the history
…low logical placements for flipPlacements property. #8825 (#9490)

**Related Issue:** #8825

## Summary

- Allow logical placements in the `flipPlacements` array property.
- This allows placement options such as `leading`, `leading-start`,
`trailing`, etc. Not any `auto` options.
- Updates tests
  • Loading branch information
driskull committed Jun 6, 2024
1 parent d0fba56 commit 45aabaa
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 45 deletions.
24 changes: 12 additions & 12 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Alignment, Appearance, CollapseDirection, FlipContext, IconType, Kind,
import { RequestedItem } from "./components/accordion/interfaces";
import { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces";
import { ActionMessages } from "./components/action/assets/action/t9n";
import { EffectivePlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui";
import { FlipPlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui";
import { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n";
import { Columns } from "./components/action-group/interfaces";
import { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n";
Expand Down Expand Up @@ -100,7 +100,7 @@ export { Alignment, Appearance, CollapseDirection, FlipContext, IconType, Kind,
export { RequestedItem } from "./components/accordion/interfaces";
export { RequestedItem as RequestedItem1 } from "./components/accordion-item/interfaces";
export { ActionMessages } from "./components/action/assets/action/t9n";
export { EffectivePlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui";
export { FlipPlacement, LogicalPlacement, MenuPlacement, OverlayPositioning, ReferenceElement } from "./utils/floating-ui";
export { ActionBarMessages } from "./components/action-bar/assets/action-bar/t9n";
export { Columns } from "./components/action-group/interfaces";
export { ActionGroupMessages } from "./components/action-group/assets/action-group/t9n";
Expand Down Expand Up @@ -430,7 +430,7 @@ export namespace Components {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": EffectivePlacement[];
"flipPlacements": FlipPlacement[];
/**
* Specifies the text string for the component.
*/
Expand Down Expand Up @@ -1231,7 +1231,7 @@ export namespace Components {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": EffectivePlacement[];
"flipPlacements": FlipPlacement[];
/**
* The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any.
*/
Expand Down Expand Up @@ -1629,7 +1629,7 @@ export namespace Components {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": EffectivePlacement[];
"flipPlacements": FlipPlacement[];
/**
* Specifies the maximum number of `calcite-dropdown-item`s to display before showing a scroller. Value must be greater than `0`, and does not include `groupTitle`'s from `calcite-dropdown-group`.
*/
Expand Down Expand Up @@ -2251,7 +2251,7 @@ export namespace Components {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": EffectivePlacement[];
"flipPlacements": FlipPlacement[];
/**
* When `true`, prevents focus trapping.
*/
Expand Down Expand Up @@ -3838,7 +3838,7 @@ export namespace Components {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements": EffectivePlacement[];
"flipPlacements": FlipPlacement[];
/**
* When `true`, prevents focus trapping.
*/
Expand Down Expand Up @@ -8124,7 +8124,7 @@ declare namespace LocalJSX {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: EffectivePlacement[];
"flipPlacements"?: FlipPlacement[];
/**
* Specifies the text string for the component.
*/
Expand Down Expand Up @@ -8986,7 +8986,7 @@ declare namespace LocalJSX {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: EffectivePlacement[];
"flipPlacements"?: FlipPlacement[];
/**
* The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any.
*/
Expand Down Expand Up @@ -9427,7 +9427,7 @@ declare namespace LocalJSX {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: EffectivePlacement[];
"flipPlacements"?: FlipPlacement[];
/**
* Specifies the maximum number of `calcite-dropdown-item`s to display before showing a scroller. Value must be greater than `0`, and does not include `groupTitle`'s from `calcite-dropdown-group`.
*/
Expand Down Expand Up @@ -10065,7 +10065,7 @@ declare namespace LocalJSX {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: EffectivePlacement[];
"flipPlacements"?: FlipPlacement[];
/**
* When `true`, prevents focus trapping.
*/
Expand Down Expand Up @@ -11749,7 +11749,7 @@ declare namespace LocalJSX {
/**
* Defines the available placements that can be used when a flip occurs.
*/
"flipPlacements"?: EffectivePlacement[];
"flipPlacements"?: FlipPlacement[];
/**
* When `true`, prevents focus trapping.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { Fragment, VNode } from "@stencil/core/internal";
import { getRoundRobinIndex } from "../../utils/array";
import { focusElement, toAriaBoolean } from "../../utils/dom";
import { EffectivePlacement, LogicalPlacement, OverlayPositioning } from "../../utils/floating-ui";
import { FlipPlacement, LogicalPlacement, OverlayPositioning } from "../../utils/floating-ui";
import { guid } from "../../utils/guid";
import { isActivationKey } from "../../utils/key";
import {
Expand Down Expand Up @@ -82,7 +82,7 @@ export class ActionMenu implements LoadableComponent {
/**
* Defines the available placements that can be used when a flip occurs.
*/
@Prop() flipPlacements: EffectivePlacement[];
@Prop() flipPlacements: FlipPlacement[];

/**
* Specifies the text string for the component.
Expand Down
10 changes: 5 additions & 5 deletions packages/calcite-components/src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
connectFloatingUI,
defaultMenuPlacement,
disconnectFloatingUI,
EffectivePlacement,
filterComputedPlacements,
filterValidFlipPlacements,
FlipPlacement,
FloatingCSS,
FloatingUIComponent,
LogicalPlacement,
Expand Down Expand Up @@ -283,7 +283,7 @@ export class Combobox
/**
* Defines the available placements that can be used when a flip occurs.
*/
@Prop() flipPlacements: EffectivePlacement[];
@Prop() flipPlacements: FlipPlacement[];

/**
* Made into a prop for testing purposes only
Expand Down Expand Up @@ -523,7 +523,7 @@ export class Combobox

placement: LogicalPlacement = defaultMenuPlacement;

filteredFlipPlacements: EffectivePlacement[];
filteredFlipPlacements: FlipPlacement[];

internalValueChangeFlag = false;

Expand Down Expand Up @@ -629,7 +629,7 @@ export class Combobox
const { el, flipPlacements } = this;

this.filteredFlipPlacements = flipPlacements
? filterComputedPlacements(flipPlacements, el)
? filterValidFlipPlacements(flipPlacements, el)
: null;
};

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 @@ -16,8 +16,8 @@ import {
connectFloatingUI,
defaultMenuPlacement,
disconnectFloatingUI,
EffectivePlacement,
filterComputedPlacements,
filterValidFlipPlacements,
FlipPlacement,
FloatingCSS,
FloatingUIComponent,
MenuPlacement,
Expand Down Expand Up @@ -107,7 +107,7 @@ export class Dropdown
/**
* Defines the available placements that can be used when a flip occurs.
*/
@Prop() flipPlacements: EffectivePlacement[];
@Prop() flipPlacements: FlipPlacement[];

@Watch("flipPlacements")
flipPlacementsHandler(): void {
Expand Down Expand Up @@ -421,7 +421,7 @@ export class Dropdown

@Element() el: HTMLCalciteDropdownElement;

filteredFlipPlacements: EffectivePlacement[];
filteredFlipPlacements: FlipPlacement[];

private items: HTMLCalciteDropdownItemElement[] = [];

Expand Down Expand Up @@ -466,7 +466,7 @@ export class Dropdown
const { el, flipPlacements } = this;

this.filteredFlipPlacements = flipPlacements
? filterComputedPlacements(flipPlacements, el)
? filterValidFlipPlacements(flipPlacements, el)
: null;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ import {
connectFloatingUI,
defaultMenuPlacement,
disconnectFloatingUI,
EffectivePlacement,
filterComputedPlacements,
filterValidFlipPlacements,
FloatingCSS,
FloatingUIComponent,
FlipPlacement,
MenuPlacement,
OverlayPositioning,
reposition,
Expand Down Expand Up @@ -201,7 +201,7 @@ export class InputDatePicker
/**
* Defines the available placements that can be used when a flip occurs.
*/
@Prop() flipPlacements: EffectivePlacement[];
@Prop() flipPlacements: FlipPlacement[];

@Watch("flipPlacements")
flipPlacementsHandler(): void {
Expand Down Expand Up @@ -720,7 +720,7 @@ export class InputDatePicker

private dialogId = `date-picker-dialog--${guid()}`;

filteredFlipPlacements: EffectivePlacement[];
filteredFlipPlacements: FlipPlacement[];

private focusOnOpen = false;

Expand Down Expand Up @@ -814,7 +814,7 @@ export class InputDatePicker
const { el, flipPlacements } = this;

this.filteredFlipPlacements = flipPlacements
? filterComputedPlacements(flipPlacements, el)
? filterValidFlipPlacements(flipPlacements, el)
: null;
};

Expand Down
10 changes: 5 additions & 5 deletions packages/calcite-components/src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
connectFloatingUI,
defaultOffsetDistance,
disconnectFloatingUI,
EffectivePlacement,
filterComputedPlacements,
filterValidFlipPlacements,
FlipPlacement,
FloatingCSS,
FloatingLayout,
FloatingUIComponent,
Expand Down Expand Up @@ -121,7 +121,7 @@ export class Popover
/**
* Defines the available placements that can be used when a flip occurs.
*/
@Prop() flipPlacements: EffectivePlacement[];
@Prop() flipPlacements: FlipPlacement[];

@Watch("flipPlacements")
flipPlacementsHandler(): void {
Expand Down Expand Up @@ -253,7 +253,7 @@ export class Popover
this.updateFocusTrapElements(),
);

filteredFlipPlacements: EffectivePlacement[];
filteredFlipPlacements: FlipPlacement[];

@State() effectiveLocale = "";

Expand Down Expand Up @@ -409,7 +409,7 @@ export class Popover
const { el, flipPlacements } = this;

this.filteredFlipPlacements = flipPlacements
? filterComputedPlacements(flipPlacements, el)
? filterValidFlipPlacements(flipPlacements, el)
: null;
};

Expand Down
10 changes: 5 additions & 5 deletions packages/calcite-components/src/utils/floating-ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const {
connectFloatingUI,
defaultOffsetDistance,
disconnectFloatingUI,
effectivePlacements,
filterComputedPlacements,
flipPlacements,
filterValidFlipPlacements,
getEffectivePlacement,
placements,
positionFloatingUI,
Expand Down Expand Up @@ -197,8 +197,8 @@ it("should have correct value for defaultOffsetDistance", () => {
expect(defaultOffsetDistance).toBe(6);
});

it("should filter computed placements", () => {
expect(new Set(filterComputedPlacements([...placements], document.createElement("div")))).toEqual(
new Set(effectivePlacements),
it("should filter valid placements", () => {
expect(new Set(filterValidFlipPlacements([...placements], document.createElement("div")))).toEqual(
new Set(flipPlacements),
);
});
20 changes: 14 additions & 6 deletions packages/calcite-components/src/utils/floating-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const positionFloatingUI =
overlayPositioning: Strategy;
placement: LogicalPlacement;
flipDisabled?: boolean;
flipPlacements?: EffectivePlacement[];
flipPlacements?: FlipPlacement[];
offsetDistance?: number;
offsetSkidding?: number;
arrowEl?: SVGElement;
Expand All @@ -117,7 +117,7 @@ export const positionFloatingUI =
middleware: getMiddleware({
placement,
flipDisabled,
flipPlacements,
flipPlacements: flipPlacements?.map((placement) => getEffectivePlacement(floatingEl, placement)),
offsetDistance,
offsetSkidding,
arrowEl,
Expand Down Expand Up @@ -244,7 +244,9 @@ export const menuEffectivePlacements: EffectivePlacement[] = [
"bottom-end",
];

export const flipPlacements: EffectivePlacement[] = [
export type FlipPlacement = Exclude<LogicalPlacement, "auto" | "auto-start" | "auto-end">;

export const flipPlacements: FlipPlacement[] = [
"top",
"bottom",
"right",
Expand All @@ -257,6 +259,12 @@ export const flipPlacements: EffectivePlacement[] = [
"right-end",
"left-start",
"left-end",
"leading",
"trailing",
"leading-start",
"leading-end",
"trailing-start",
"trailing-end",
];

export type MenuPlacement = Extract<
Expand Down Expand Up @@ -374,14 +382,14 @@ function getMiddleware({
return [];
}

export function filterComputedPlacements(placements: string[], el: HTMLElement): EffectivePlacement[] {
export function filterValidFlipPlacements(placements: string[], el: HTMLElement): EffectivePlacement[] {
const filteredPlacements = placements.filter((placement: EffectivePlacement) =>
effectivePlacements.includes(placement),
flipPlacements.includes(placement),
) as EffectivePlacement[];

if (filteredPlacements.length !== placements.length) {
console.warn(
`${el.tagName}: Invalid value found in: flipPlacements. Try any of these: ${effectivePlacements
`${el.tagName}: Invalid value found in: flipPlacements. Try any of these: ${flipPlacements
.map((placement) => `"${placement}"`)
.join(", ")
.trim()}`,
Expand Down

0 comments on commit 45aabaa

Please sign in to comment.