Skip to content

Commit

Permalink
feat: Add flip middleware to popover and tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
ChesneyJulian committed Jan 7, 2025
1 parent 157c2ce commit 8c92584
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
19 changes: 19 additions & 0 deletions apps/docs-app/app/components/f/components/popover.gts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export default class extends Component {
@tracked
arrow: boolean = true;

@tracked
flip: boolean = false;

@tracked
isShown?: boolean;

Expand All @@ -62,6 +65,7 @@ export default class extends Component {
<Popover
@alignment={{this.alignment}}
@arrow={{this.arrow}}
@flip={{this.flip}}
@isShown={{this.isShown}}
@offset={{this.offset}}
@side={{this.side}}
Expand Down Expand Up @@ -105,6 +109,13 @@ export default class extends Component {
@value={{this.arrow}}
@onInput={{fn this.update "arrow"}}
/>
<Args.Bool
@name="flip"
@defaultValue={{false}}
@description="Whether to flip the side the popover is on when it reaches the viewport boundary"
@value={{this.fip}}
@onInput={{fn this.update "flip"}}
/>
<Args.Bool
@name="isShown"
@defaultValue="undefined"
Expand Down Expand Up @@ -147,6 +158,7 @@ export default class extends Component {
<Popover
@alignment={{this.alignment}}
@arrow={{this.arrow}}
@flip={{this.flip}}
@isShown={{this.isShown}}
@offset={{this.offset}}
@side={{this.side}}
Expand Down Expand Up @@ -186,6 +198,13 @@ export default class extends Component {
@value={{this.arrow}}
@onInput={{fn this.update "arrow"}}
/>
<Args.Bool
@name="flip"
@defaultValue={{false}}
@description="Whether to flip the side the popover is on when it reaches the viewport boundary"
@value={{this.fip}}
@onInput={{fn this.update "flip"}}
/>
<Args.Bool
@name="isShown"
@defaultValue="undefined"
Expand Down
11 changes: 11 additions & 0 deletions apps/docs-app/app/components/f/components/tooltip.gts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export default class extends Component {
@tracked
alignment?: Alignment;

@tracked
flip?: boolean;

@tracked
offset?: number;

Expand All @@ -37,6 +40,7 @@ export default class extends Component {
<div class="p-2">
<Tooltip
@alignment={{this.alignment}}
@flip={{this.flip}}
@offset={{this.offset}}
@side={{this.side}}
@onShow={{fn this.toast.info "onShow was fired"}}
Expand Down Expand Up @@ -148,6 +152,13 @@ export default class extends Component {
@options={{array "" "start" "end"}}
@onInput={{fn this.update "alignment"}}
/>
<Args.Bool
@name="flip"
@defaultValue={{false}}
@description="Whether to flip the side the tooltip is on when it reaches the viewport boundary"
@value={{this.fip}}
@onInput={{fn this.update "flip"}}
/>
<Args.Number
@name="offset"
@description="How far to offset the tooltip from the target (in pixels)"
Expand Down
20 changes: 18 additions & 2 deletions packages/ember-core/src/components/popover.gts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { concat, hash } from '@ember/helper';
import { arrow, computePosition, offset } from '@floating-ui/dom';
import { arrow, computePosition, flip, offset } from '@floating-ui/dom';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

Expand Down Expand Up @@ -53,6 +53,7 @@ export interface PopoverSignature {
alignment?: Alignment;
arrow?: boolean;
controlElement?: HTMLElement;
flip?: boolean;
isShown?: boolean;
offset?: string | number;
side?: Direction;
Expand Down Expand Up @@ -96,6 +97,9 @@ export default class Popover extends Component<PopoverSignature> {
@tracked
_isShown = false;

@tracked
adjustedSide: Direction = 'bottom';

get hasArrow() {
return this.args.arrow ?? true;
}
Expand All @@ -120,6 +124,10 @@ export default class Popover extends Component<PopoverSignature> {
get middleware() {
const middleware = [offset(this.offset)];

if (this.args.flip) {
middleware.push(flip());
}

if (this.hasArrow) {
middleware.push(arrow({ element: this.arrow! }));
}
Expand Down Expand Up @@ -201,6 +209,14 @@ export default class Popover extends Component<PopoverSignature> {
return;
}

if (placement !== this.placement) {
this.adjustedSide = Object.keys(SIDE_TRANSLATION).find(
(side) => SIDE_TRANSLATION[side as Direction] === placement,
) as Direction;
} else {
this.adjustedSide = this.side;
}

const { x: arrowX, y: arrowY } = middlewareData.arrow!;
const staticSide: string =
ARROW_SIDE[placement.split('-')[0] as Direction]!;
Expand All @@ -226,7 +242,7 @@ export default class Popover extends Component<PopoverSignature> {
id={{this.id}}
class={{classes
(unless this.isShown "hidden")
(concat "popover bs-popover-" this.side)
(concat "popover bs-popover-" this.adjustedSide)
}}
{{onInsert this.initPopover}}
{{! @glint-expect-error Modifier types are currently not correct }}
Expand Down
2 changes: 2 additions & 0 deletions packages/ember-core/src/components/tooltip.gts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface TooltipSignature {
Args: {
alignment?: Alignment;
controlElement?: HTMLElement;
flip?: boolean;
isShown?: boolean;
offset?: string | number;
side?: Direction;
Expand Down Expand Up @@ -80,6 +81,7 @@ const Tooltip: TOC<TooltipSignature> = <template>
<Popover
class="tooltip"
@alignment={{@alignment}}
@flip={{@flip}}
@offset={{@offset}}
@side={{@side}}
@onShow={{@onShow}}
Expand Down

0 comments on commit 8c92584

Please sign in to comment.