Skip to content

Commit 8556f01

Browse files
committed
Add triggerHtmlTag to resolve glint issue, fix triggerElement type in calculate Position
1 parent 278d43d commit 8556f01

4 files changed

Lines changed: 69 additions & 56 deletions

File tree

docs/app/components/snippets/custom-position-1.gts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type {
77

88
export default class extends Component {
99
calculatePosition(
10-
trigger: Element,
10+
trigger: HTMLElement,
1111
content: HTMLElement,
1212
_destination: HTMLElement,
1313
{ horizontalPosition, verticalPosition }: CalculatePositionOptions,

ember-basic-dropdown/src/components/basic-dropdown.gts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,37 @@ export type { Dropdown, DropdownActions, TRootEventType };
3535
const UNINITIALIZED = {};
3636
const IGNORED_STYLES = ['top', 'left', 'right', 'width', 'height'];
3737

38-
export interface BasicDropdownDefaultBlock {
38+
export interface BasicDropdownDefaultBlock<
39+
TriggerHtmlTag extends keyof HTMLElementTagNameMap = 'div',
40+
> {
3941
uniqueId: string;
4042
disabled: boolean;
4143
isOpen: boolean;
4244
actions: DropdownActions;
43-
Trigger: ComponentLike<BasicDropdownTriggerSignature>;
45+
Trigger: ComponentLike<
46+
Omit<BasicDropdownTriggerSignature<TriggerHtmlTag>, 'Args'> & {
47+
Args: Omit<
48+
BasicDropdownTriggerSignature<TriggerHtmlTag>['Args'],
49+
'htmlTag'
50+
>;
51+
}
52+
>;
4453
Content: ComponentLike<BasicDropdownContentSignature>;
4554
}
4655

47-
export interface BasicDropdownSignature {
56+
export interface BasicDropdownSignature<
57+
TriggerHtmlTag extends keyof HTMLElementTagNameMap = 'div',
58+
> {
4859
Element: HTMLElement;
49-
Args: BasicDropdownArgs;
60+
Args: BasicDropdownArgs<TriggerHtmlTag>;
5061
Blocks: {
51-
default: [BasicDropdownDefaultBlock];
62+
default: [BasicDropdownDefaultBlock<TriggerHtmlTag>];
5263
};
5364
}
5465

55-
export interface BasicDropdownArgs {
66+
export interface BasicDropdownArgs<
67+
TriggerHtmlTag extends keyof HTMLElementTagNameMap = 'div',
68+
> {
5669
initiallyOpened?: boolean;
5770
renderInPlace?: boolean;
5871
verticalPosition?: VerticalPosition;
@@ -64,16 +77,21 @@ export interface BasicDropdownArgs {
6477
rootEventType?: TRootEventType;
6578
preventScroll?: boolean;
6679
matchTriggerWidth?: boolean;
80+
triggerHtmlTag?: TriggerHtmlTag;
6781
onInit?: (dropdown: Dropdown) => void;
6882
registerAPI?: (dropdown: Dropdown | null) => void;
6983
onOpen?: (dropdown: Dropdown, e?: Event) => boolean | void;
7084
onClose?: (dropdown: Dropdown, e?: Event) => boolean | void;
71-
triggerComponent?: ComponentLike<BasicDropdownTriggerSignature> | undefined;
85+
triggerComponent?:
86+
| ComponentLike<BasicDropdownTriggerSignature<TriggerHtmlTag>>
87+
| undefined;
7288
contentComponent?: ComponentLike<BasicDropdownContentSignature> | undefined;
7389
calculatePosition?: CalculatePosition;
7490
}
7591

76-
export default class BasicDropdown extends Component<BasicDropdownSignature> {
92+
export default class BasicDropdown<
93+
TriggerHtmlTag extends keyof HTMLElementTagNameMap = 'div',
94+
> extends Component<BasicDropdownSignature<TriggerHtmlTag>> {
7795
@tracked hPosition: HorizontalPosition | null = null;
7896
@tracked vPosition: VerticalPosition | null = null;
7997
@tracked top: string | undefined;
@@ -171,7 +189,7 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
171189
}
172190

173191
// Lifecycle hooks
174-
constructor(owner: Owner, args: BasicDropdownArgs) {
192+
constructor(owner: Owner, args: BasicDropdownArgs<TriggerHtmlTag>) {
175193
super(owner, args);
176194
if (this.args.onInit) {
177195
this.args.onInit(this.publicAPI);
@@ -306,7 +324,6 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
306324
previousVerticalPosition,
307325
renderInPlace,
308326
matchTriggerWidth,
309-
dropdown: this,
310327
},
311328
);
312329
return this.applyReposition(triggerElement, dropdownElement, positionData);
@@ -491,10 +508,14 @@ export default class BasicDropdown extends Component<BasicDropdownSignature> {
491508
);
492509
}
493510

494-
get triggerComponent(): ComponentLike<BasicDropdownTriggerSignature> {
511+
get triggerComponent(): ComponentLike<
512+
BasicDropdownTriggerSignature<TriggerHtmlTag>
513+
> {
495514
return (
496515
this.args.triggerComponent ||
497-
(BasicDropdownTrigger as ComponentLike<BasicDropdownTriggerSignature>)
516+
(BasicDropdownTrigger as ComponentLike<
517+
BasicDropdownTriggerSignature<TriggerHtmlTag>
518+
>)
498519
);
499520
}
500521

ember-basic-dropdown/src/utils/calculate-position.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type BasicDropdown from '../components/basic-dropdown.gts';
21
import type { VerticalPosition, HorizontalPosition } from '../types.ts';
32

43
// To avoid breaking the current types export we need this
@@ -11,7 +10,6 @@ export interface CalculatePositionOptions {
1110
previousHorizontalPosition?: HorizontalPosition | undefined;
1211
previousVerticalPosition?: VerticalPosition | undefined;
1312
renderInPlace: boolean;
14-
dropdown: BasicDropdown;
1513
}
1614

1715
export type CalculatePositionResultStyle = {
@@ -30,24 +28,24 @@ export type CalculatePositionResult = {
3028
};
3129

3230
export type CalculatePosition = (
33-
trigger: Element,
31+
trigger: HTMLElement,
3432
content: HTMLElement,
3533
destination: HTMLElement,
3634
options: CalculatePositionOptions,
3735
) => CalculatePositionResult;
3836

39-
export const calculateWormholedPosition: CalculatePosition = (
40-
trigger,
41-
content,
42-
destination,
37+
export function calculateWormholedPosition(
38+
trigger: HTMLElement,
39+
content: HTMLElement,
40+
destination: HTMLElement,
4341
{
4442
horizontalPosition,
4543
verticalPosition,
4644
matchTriggerWidth,
4745
previousHorizontalPosition,
4846
previousVerticalPosition,
49-
},
50-
) => {
47+
}: CalculatePositionOptions,
48+
): CalculatePositionResult {
5149
// Collect information about all the involved DOM elements
5250
const scroll = { left: window.pageXOffset, top: window.pageYOffset };
5351
let { left: triggerLeft, top: triggerTop } = trigger.getBoundingClientRect();
@@ -202,14 +200,14 @@ export const calculateWormholedPosition: CalculatePosition = (
202200
}
203201

204202
return { horizontalPosition, verticalPosition, style };
205-
};
203+
}
206204

207-
export const calculateInPlacePosition: CalculatePosition = (
208-
trigger,
209-
content,
210-
_destination,
211-
{ horizontalPosition, verticalPosition },
212-
) => {
205+
export function calculateInPlacePosition(
206+
trigger: HTMLElement,
207+
content: HTMLElement,
208+
_destination: HTMLElement,
209+
{ horizontalPosition, verticalPosition }: CalculatePositionOptions,
210+
): CalculatePositionResult {
213211
let dropdownRect;
214212
const positionData: CalculatePositionResult = {
215213
horizontalPosition: 'left',
@@ -243,7 +241,7 @@ export const calculateInPlacePosition: CalculatePosition = (
243241
positionData.verticalPosition = 'below';
244242
}
245243
return positionData;
246-
};
244+
}
247245

248246
export function getScrollParent(element: Element) {
249247
let style = window.getComputedStyle(element);
@@ -268,17 +266,18 @@ export function getScrollParent(element: Element) {
268266

269267
return document.body;
270268
}
271-
const calculatePosition: CalculatePosition = (
272-
trigger,
273-
content,
274-
destination,
275-
options,
276-
) => {
269+
270+
function calculatePosition(
271+
trigger: HTMLElement,
272+
content: HTMLElement,
273+
destination: HTMLElement,
274+
options: CalculatePositionOptions,
275+
): CalculatePositionResult {
277276
if (options.renderInPlace) {
278277
return calculateInPlacePosition(trigger, content, destination, options);
279278
} else {
280279
return calculateWormholedPosition(trigger, content, destination, options);
281280
}
282-
};
281+
}
283282

284283
export default calculatePosition;

test-app/tests/integration/components/basic-dropdown-test.gts

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,13 +1057,8 @@ module('Integration | Component | basic-dropdown', function (hooks) {
10571057
const self = this;
10581058

10591059
assert.expect(4);
1060-
this.calculatePosition = function (
1061-
_triggerElement,
1062-
_dropdownElement,
1063-
_destinationElement,
1064-
{ dropdown },
1065-
) {
1066-
assert.ok(dropdown, 'dropdown should be passed to the component');
1060+
this.calculatePosition = function () {
1061+
assert.ok('dropdown should be passed to the component');
10671062
return {
10681063
horizontalPosition: 'right',
10691064
verticalPosition: 'above',
@@ -1118,9 +1113,9 @@ module('Integration | Component | basic-dropdown', function (hooks) {
11181113
_triggerElement,
11191114
_dropdownElement,
11201115
_destinationElement,
1121-
{ dropdown, renderInPlace },
1116+
{ renderInPlace },
11221117
) {
1123-
assert.ok(dropdown, 'dropdown should be passed to the component');
1118+
assert.ok(renderInPlace, 'dropdown should be passed to the component');
11241119
if (renderInPlace) {
11251120
return {
11261121
horizontalPosition: 'right',
@@ -1327,27 +1322,25 @@ module('Integration | Component | basic-dropdown', function (hooks) {
13271322

13281323
await render(
13291324
<template>
1330-
<BasicDropdown as |parent|>
1331-
<parent.Trigger class="parent" @htmlTag="button">Trigger of the first
1325+
<BasicDropdown @triggerHtmlTag="button" as |parent|>
1326+
<parent.Trigger class="parent" type="button">Trigger of the first
13321327
dropdown</parent.Trigger>
13331328
<parent.Content @overlay={{true}}>
1334-
<BasicDropdown as |child|>
1329+
<BasicDropdown @triggerHtmlTag="button" as |child|>
13351330
<p class="body-parent">
13361331
<br />First level of the dropdpwn<br />
13371332
</p>
1338-
<child.Trigger class="child" @htmlTag="button">Trigger of the
1339-
second dropdown</child.Trigger>
1333+
<child.Trigger class="child" type="button">Trigger of the second
1334+
dropdown</child.Trigger>
13401335
<child.Content @overlay={{true}}>
13411336
<p class="body-child">
13421337
<br />Second level of the second<br />
1343-
<BasicDropdown as |grandchild|>
1338+
<BasicDropdown @triggerHtmlTag="button" as |grandchild|>
13441339
<p>
13451340
<br />Second level of the dropdpwn<br />
13461341
</p>
1347-
<grandchild.Trigger
1348-
class="grandchild"
1349-
@htmlTag="button"
1350-
>Trigger of the Third dropdown</grandchild.Trigger>
1342+
<grandchild.Trigger class="grandchild" type="button">Trigger
1343+
of the Third dropdown</grandchild.Trigger>
13511344
<grandchild.Content @overlay={{true}}>
13521345
<p class="body-grandchild">
13531346
<br />Third level of the third<br />

0 commit comments

Comments
 (0)