Skip to content

Commit 9301a21

Browse files
authored
feat(floating-panel): set trigger id (#28)
1 parent 04b41b8 commit 9301a21

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Allow trigger id to be set in the Floating panel element
12+
913
## [0.2.0] - 2024-01-14
1014

1115
### Added

packages/core/src/elements/floating_panel/index.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export default class FloatingPanelElement extends ImpulseElement {
2929
*/
3030
@property({ type: Boolean }) active = false;
3131

32+
/**
33+
* If the trigger lives outside the floating panel, you can set the trigger element's id.
34+
*/
35+
@property() triggerId: string;
36+
3237
/**
3338
* One of 'absolute' or 'fixed'.
3439
* https://floating-ui.com/docs/computeposition#strategy
@@ -61,7 +66,7 @@ export default class FloatingPanelElement extends ImpulseElement {
6166
*/
6267
@property() sync?: 'width' | 'height' | 'both';
6368

64-
@target() trigger: HTMLElement;
69+
@target() trigger?: HTMLElement;
6570
@target() panel: HTMLElement;
6671

6772
private cleanup?: ReturnType<typeof autoUpdate>;
@@ -82,12 +87,21 @@ export default class FloatingPanelElement extends ImpulseElement {
8287
}
8388
}
8489

90+
/**
91+
* We want to restart the placement logic when the trigger id changes.
92+
*/
93+
async triggerIdChanged() {
94+
await this.stop();
95+
this.start();
96+
}
97+
8598
start() {
99+
if (!this.triggerElement) return;
86100
this.panel.style.position = this.strategy;
87101
this.panel.style.top = '0px';
88102
this.panel.style.left = '0px';
89103

90-
this.cleanup = autoUpdate(this.trigger, this.panel, this.position.bind(this));
104+
this.cleanup = autoUpdate(this.triggerElement, this.panel, this.position.bind(this));
91105
}
92106

93107
async stop(): Promise<void> {
@@ -104,7 +118,7 @@ export default class FloatingPanelElement extends ImpulseElement {
104118
}
105119

106120
async position() {
107-
if (!this.active) return;
121+
if (!this.active || !this.triggerElement) return;
108122

109123
const middleware: Middleware[] = [offset(presence(this.offsetOptions))];
110124

@@ -132,7 +146,7 @@ export default class FloatingPanelElement extends ImpulseElement {
132146
? (element: Element) => platform.getOffsetParent(element, offsetParent)
133147
: platform.getOffsetParent;
134148

135-
const { x, y, strategy, placement } = await computePosition(this.trigger, this.panel, {
149+
const { x, y, strategy, placement } = await computePosition(this.triggerElement, this.panel, {
136150
placement: this.placement,
137151
middleware,
138152
strategy: this.strategy,
@@ -151,6 +165,10 @@ export default class FloatingPanelElement extends ImpulseElement {
151165
this.setAttribute('data-current-placement', placement);
152166
this.emit('changed');
153167
}
168+
169+
private get triggerElement() {
170+
return document.getElementById(this.triggerId) || this.trigger;
171+
}
154172
}
155173

156174
declare global {

packages/playground/index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@
127127
</div>
128128
</twc-tabs>
129129
</div>
130+
131+
<div class="mt-8">
132+
<h2>Floating panel with trigger id</h2>
133+
<div class="mt-2">
134+
<button type="button" id="trigger-id-1">Button 1</button>
135+
<button type="button" id="trigger-id-2">Button 2</button>
136+
137+
<twc-floating-panel trigger-id="trigger-id-1" active placement="bottom">
138+
<div data-target="twc-floating-panel.panel" class="bg-white rounded shadow p-4 border">
139+
Floating contents!
140+
</div>
141+
</twc-floating-panel>
142+
</div>
143+
</div>
130144
<script type="module" src="/src/index.ts"></script>
131145
</body>
132146
</html>

0 commit comments

Comments
 (0)