Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 79efea5

Browse files
committed
feat(dropdowns): added fixed strategy option
1 parent 1d15549 commit 79efea5

File tree

28 files changed

+543
-13
lines changed

28 files changed

+543
-13
lines changed

.changeset/warm-glasses-sink.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ebay/ebayui-core": minor
3+
---
4+
5+
feat(dropdowns): added fixed strategy option

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"@commitlint/cli": "^19",
101101
"@commitlint/config-conventional": "^19",
102102
"@ebay/browserslist-config": "^2.10.0",
103-
"@ebay/skin": "~19.1.0",
103+
"@ebay/skin": "~19.1.1",
104104
"@marko/compiler": "^5.39.12",
105105
"@marko/prettyprint": "^3.0.1",
106106
"@marko/testing-library": "^6",
@@ -145,7 +145,7 @@
145145
"vitest": "^3.0.7"
146146
},
147147
"peerDependencies": {
148-
"@ebay/skin": "~19.0.0",
148+
"@ebay/skin": "~19.1.1",
149149
"marko": "^4.27.0 || ^5.31.12"
150150
},
151151
"publishConfig": {

src/common/dropdown/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99

1010
interface DropdownUtilOptions {
1111
reverse?: boolean;
12+
strategy?: "absolute" | "fixed";
1213
offset?: number;
1314
}
1415

@@ -39,7 +40,9 @@ export class DropdownUtil {
3940
update() {
4041
computePosition(this.host, this.overlay, {
4142
placement: this.options.reverse ? "bottom-end" : "bottom-start",
42-
middleware: [offset(this.options.offset ?? 4), flip(), shift()],
43+
strategy: this.options.strategy ?? "fixed",
44+
middleware: [offset(this.options.offset ?? 4), flip({
45+
}), shift()],
4346
}).then(({ x, y }) => {
4447
Object.assign(this.overlay.style, {
4548
left: `${x}px`,

src/components/ebay-combobox/combobox.stories.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,16 @@ export default {
9090
description:
9191
"If true, the option will always be shown even if it does not match the filter",
9292
},
93-
93+
strategy: {
94+
control: { type: "select" },
95+
options: ["absolute", "fixed"],
96+
table: {
97+
defaultValue: {
98+
summary: "absolute",
99+
},
100+
},
101+
description: "Swap between fixed and absolute positioning strategy. Use fixed when dropdown is in contained in an overflow and needs to be visible as you scroll the screen.",
102+
},
94103
onCollapse: {
95104
action: "on-collapse",
96105
table: {

src/components/ebay-combobox/component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface ComboboxInput extends Omit<Marko.HTML.Input, `on${string}`> {
2828
autocomplete?: "list" | "none";
2929
"list-selection"?: "manual" | "automatic";
3030
"floating-label"?: AttrString;
31+
strategy?: "fixed" | "absolute";
3132
button?: Marko.Input<"button"> &
3233
Marko.AttrTag<{
3334
htmlAttributes?: Record<string, unknown>;
@@ -319,6 +320,9 @@ export default class Combobox extends Marko.Component<Input, State> {
319320
this.dropdownUtil = new DropdownUtil(
320321
this.input.dropdownElement?.() ?? this.getEl("combobox"),
321322
this.getEl("listbox"),
323+
{
324+
strategy: this.input.strategy,
325+
}
322326
);
323327
if (this.isExpanded()) {
324328
this.dropdownUtil.show();

src/components/ebay-combobox/index.marko

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ $ const {
88
style,
99
borderless,
1010
autocomplete,
11+
strategy,
1112
option: options = [],
1213
dropdownElement,
1314
floatingLabel,
@@ -92,7 +93,7 @@ $ var id = inputId || component.getElId("input");
9293
</if>
9394
</span>
9495
<if(component._hasVisibleOptions())>
95-
<div key="listbox" role="listbox" class="combobox__listbox">
96+
<div key="listbox" role="listbox" class=["combobox__listbox", strategy === "fixed" && "combobox__listbox--fixed"]>
9697
<for|option| of=component._getVisibleOptions()>
9798
$ const { text, value, class: optionClass, ...htmlOption } = option;
9899
$ var isSelected = (

src/components/ebay-combobox/test/__snapshots__/test.server.js.snap

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,88 @@ exports[`combobox > renders with default actionable button 1`] = `
458458
</DocumentFragment>"
459459
`;
460460

461+
exports[`combobox > renders with fixed strategy 1`] = `
462+
"<DocumentFragment>
463+
<span
464+
class="combobox"
465+
>
466+
<span
467+
class="combobox__control"
468+
>
469+
<input
470+
aria-autocomplete="list"
471+
aria-expanded="false"
472+
aria-haspopup="listbox"
473+
autocomplete="off"
474+
id="s0-input"
475+
name="example1text"
476+
role="combobox"
477+
type="text"
478+
/>
479+
</span>
480+
<div
481+
class="combobox__listbox combobox__listbox--fixed"
482+
role="listbox"
483+
>
484+
<div
485+
class="combobox__option"
486+
role="option"
487+
tabindex="-1"
488+
>
489+
<span>
490+
August Campaign
491+
</span>
492+
</div>
493+
<div
494+
class="combobox__option"
495+
role="option"
496+
tabindex="-1"
497+
>
498+
<span>
499+
4th of July Sale (paused)
500+
</span>
501+
</div>
502+
<div
503+
class="combobox__option"
504+
role="option"
505+
tabindex="-1"
506+
>
507+
<span>
508+
Basic Offer
509+
</span>
510+
</div>
511+
<div
512+
class="combobox__option"
513+
role="option"
514+
tabindex="-1"
515+
>
516+
<span>
517+
Basic Offer 2
518+
</span>
519+
</div>
520+
<div
521+
class="combobox__option"
522+
role="option"
523+
tabindex="-1"
524+
>
525+
<span>
526+
Basic Offer 3
527+
</span>
528+
</div>
529+
<div
530+
class="combobox__option"
531+
role="option"
532+
tabindex="-1"
533+
>
534+
<span>
535+
Basic Offer 4
536+
</span>
537+
</div>
538+
</div>
539+
</span>
540+
</DocumentFragment>"
541+
`;
542+
461543
exports[`combobox > renders with floating label 1`] = `
462544
"<DocumentFragment>
463545
<span

src/components/ebay-combobox/test/test.server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ describe("combobox", () => {
1818
await htmlSnap(Isolated, { option: [] });
1919
});
2020

21+
it("renders with fixed strategy", async () => {
22+
await htmlSnap(Isolated, { strategy: "fixed" });
23+
});
24+
2125
it("renders with second item selected", async () => {
2226
await htmlSnap(Isolated, { value: Isolated.args.option[2].text });
2327
});

src/components/ebay-fake-menu-button/component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ interface FakeMenuButtonInput extends Omit<Marko.HTML.Span, `on${string}`> {
2525
"text-align"?: "center";
2626
type?: FakeMenuInput["type"];
2727
reverse?: boolean;
28+
strategy?: "absolute" | "fixed";
2829
"fix-width"?: boolean;
2930
item?: Marko.AttrTag<FakeMenuItem>;
3031
"collapse-on-select"?: boolean;
@@ -138,6 +139,7 @@ class FakeMenuButton extends Marko.Component<Input> {
138139
this.getEl("content"),
139140
{
140141
reverse: this.input.reverse,
142+
strategy: this.input.strategy,
141143
},
142144
);
143145
}

0 commit comments

Comments
 (0)