Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autocomplete: Add position prop #2846

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
position: absolute;
width: 100%;

&[data-popper-reference-hidden] {
pointer-events: none;
visibility: hidden;
}

.icon-check {
display: inline-flex;
margin-left: auto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('modus-autocomplete', () => {
<modus-text-input aria-autocomplete="list" aria-controls="${listId}" class="input" role="combobox" autocomplete="off" size="medium" type="search" value=""></modus-text-input>
</div>
<div class="error"></div>
<div class="options-container" style="max-height: 300px; z-index: 1; overflow-y: auto;">
<div class="options-container" part="options-container" style="max-height: 300px; z-index: 1; overflow-y: auto; position: absolute; left: 0; top: 0; margin: 0;">
<ul aria-label="options" id="${listId}" role="listbox"></ul>
</div>
<div style="display: none;">
Expand Down Expand Up @@ -57,7 +57,7 @@ describe('modus-autocomplete', () => {
<modus-text-input aria-autocomplete="list" aria-controls="${listId}" class="input" role="combobox" autocomplete="off" size="medium" type="search" value=""></modus-text-input>
</div>
<div class="error"></div>
<div class="options-container" style="max-height: 300px; z-index: 1; overflow-y: auto;">
<div class="options-container" part="options-container" style="max-height: 300px; z-index: 1; overflow-y: auto; position: absolute; left: 0; top: 0; margin: 0;">
<ul aria-label="options" id="${listId}" role="listbox"></ul>
</div>
<div style="display: none;">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { IconSearch } from '../../icons/svgs/icon-search';
import { generateElementId } from '../../utils/utils';
import { IconCheck } from '../../icons/generated-icons/IconCheck';
import { createPopper, Instance, Placement } from '@popperjs/core';

export interface ModusAutocompleteOption {
id: string;
Expand Down Expand Up @@ -74,6 +75,9 @@ export class ModusAutocomplete {
/** A promise that returns the filtered options. */
@Prop() filterOptions: (search: string) => Promise<ModusAutocompleteOption[] | string[]>;

/** (optional) The placement of the options */
@Prop() position: Placement = 'bottom-start';

/** An array to hold the selected chips. */
@State() selectedChips: ModusAutocompleteOption[] = [];

Expand All @@ -86,6 +90,8 @@ export class ModusAutocomplete {
/** Whether to show autocomplete's options when focus. */
@Prop() showOptionsOnFocus: boolean;

private popperInstance: Instance;

@Watch('options')
watchOptions() {
this.convertOptions();
Expand Down Expand Up @@ -138,6 +144,38 @@ export class ModusAutocomplete {
@State() ShowItemsOnKeyDown = false;
private listId = generateElementId() + '_list';

componentDidLoad(): void {
this.convertOptions();
if (this.multiple) {
this.initializeSelectedChips();
}
this.initializePopper();
}

disconnectedCallback(): void {
if (this.popperInstance) {
this.popperInstance.destroy();
}
}

initializePopper(): void {
const optionsContainer = this.el.shadowRoot.querySelector(`.options-container`) as HTMLElement;
const referenceElement = this.el as HTMLElement;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the chips-container as reference element? Otherwise the dropdown will be positioned based on the entire container height.


this.popperInstance = createPopper(referenceElement, optionsContainer, {
placement: 'bottom-start',
strategy: this.position === 'auto' ? 'fixed' : 'absolute',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a comment about why we use fixed strategy for auto position

Copy link
Collaborator

@prashanth-offcl prashanth-offcl Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also if I set position to auto, options container width is not restricted to the input width.
image

modifiers: [
{
name: 'offset',
options: {
offset: [0, 2],
},
},
],
});
}

componentWillLoad(): void {
this.convertOptions();
if (this.multiple) {
Expand Down Expand Up @@ -477,7 +515,7 @@ export class ModusAutocomplete {
const selectedOption = optionList.querySelector('li.selected') as HTMLElement;

if (selectedOption) {
selectedOption.scrollIntoView({ behavior: 'smooth', inline: 'nearest' });
selectedOption.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
};

Expand Down Expand Up @@ -527,6 +565,7 @@ export class ModusAutocomplete {
<div class={'error'}>{this.errorText ? <label class="sub-text error">{this.errorText}</label> : null}</div>
<div
class="options-container"
part="options-container"
style={{ maxHeight: this.dropdownMaxHeight, zIndex: this.dropdownZIndex, overflowY: 'auto' }}>
<ul id={this.listId} aria-label="options" role="listbox">
{this.displayOptions() &&
Expand Down
56 changes: 32 additions & 24 deletions stencil-workspace/src/components/modus-autocomplete/readme.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ table.density-compact {
z-index: 99;
}

.autocomplete::part(options-container) {
width: auto;
}

.editor::part(input-container) {
border: 2px solid var(--modus-input-border-active-color, #217cbb);
border-radius: unset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export class ModusTableCellEditor {
{...this.getDefaultProps('Autocomplete input')}
include-search-icon="false"
size="medium"
class="autocomplete"
options={options}
onBlur={this.handleBlur}
onKeyDown={(e) => e.stopPropagation()}
Expand All @@ -212,6 +213,7 @@ export class ModusTableCellEditor {
this.editedValue = selectedDetail;
}
}}
position="auto"
value={selectedOption}></modus-autocomplete>
</div>
);
Expand Down
Loading