Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<tedi-card
class="tedi-select__dropdown"
spacing="none"
[style.width.px]="dropdownWidth()"
[style.width]="!!dropdownWidth() ? dropdownWidth() + 'px' : 'auto'"
>
<tedi-card-content>
<ul
Expand Down
19 changes: 16 additions & 3 deletions community/components/form/select/multiselect.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ export class MultiselectComponent
* @default true
*/
clearable = input<boolean>(true);
/**
* Optional element reference to calculate dropdown width from.
* If provided but null, dropdown will use auto width.
* If not provided, defaults to the host element width.
* @default undefined
*/
dropdownWidthRef = input<ElementRef | null>();
feedbackText = input<ComponentInputs<FeedbackTextComponent>>();

readonly specialOptionControls = specialOptionControls;
Expand All @@ -146,7 +153,7 @@ export class MultiselectComponent
triggerRef = viewChild(CdkOverlayOrigin, { read: ElementRef });
hostRef = inject(ElementRef);
options = contentChildren(SelectOptionComponent);
dropdownWidth = signal(0);
dropdownWidth = signal<number | null>(0);
disabled = signal(false);

optionGroups = computed(() => {
Expand Down Expand Up @@ -220,8 +227,14 @@ export class MultiselectComponent
}

private setDropdownWidth(): void {
const computedWidth =
this.hostRef?.nativeElement?.getBoundingClientRect()?.width ?? 0;
const widthRef = this.dropdownWidthRef();
if (widthRef === null) {
this.dropdownWidth.set(null);
return;
}

const element = widthRef?.nativeElement ?? this.hostRef?.nativeElement;
const computedWidth = element?.getBoundingClientRect()?.width ?? 0;
this.dropdownWidth.set(computedWidth);
}

Expand Down
59 changes: 59 additions & 0 deletions community/components/form/select/multiselect.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,62 @@ export const multiselectNoOptions: Story = {
},
}),
};

export const multiselectAutoWidthDropdown: Story = {
render: (args) => ({
template: `
<tedi-multiselect
[inputId]="inputId"
[placeholder]="placeholder"
[label]="label"
[feedbackText]="feedbackText"
[required]="required"
[state]="state"
[size]="size"
[multiRow]="multiRow"
[clearableTags]="clearableTags"
[selectAll]="selectAll"
[selectableGroups]="selectableGroups"
[clearable]="clearable"
[dropdownWidthRef]="null"
[disabled]="disabled"
>
<tedi-select-option value="option1" label="Option 1" />
<tedi-select-option value="option2" label="Option 2" />
<tedi-select-option value="option3" label="Option 3" />
<tedi-select-option value="option4" label="Option 4" />
<tedi-select-option value="option5" label="Option 5" />
</tedi-multiselect>
`,
props: {
...args,
},
}),
};

export const multiselectCustomWidthDropdown: Story = {
render: (args) => ({
template: `
<div #customWidthElement style="width: 400px; border: 1px solid black; padding: 8px; margin-bottom: 16px;">
This div sets the dropdown width to 400px
</div>
<tedi-multiselect
[inputId]="inputId"
[placeholder]="placeholder"
[label]="label"
[feedbackText]="feedbackText"
[dropdownWidthRef]="getElementRef(customWidthElement)"
>
<tedi-select-option value="option1" label="Option 1" />
<tedi-select-option value="option2" label="Option 2" />
<tedi-select-option value="option3" label="Option 3" />
<tedi-select-option value="option4" label="Option 4" />
<tedi-select-option value="option5" label="Option 5" />
</tedi-multiselect>
`,
props: {
...args,
getElementRef: (element: HTMLElement) => ({ nativeElement: element }),
},
}),
};
3 changes: 1 addition & 2 deletions community/components/form/select/select.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,13 @@
<tedi-card
class="tedi-select__dropdown"
spacing="none"
[style.width.px]="dropdownWidth()"
[style.width]="!!dropdownWidth() ? dropdownWidth() + 'px' : 'auto'"
>
<tedi-card-content>
<ul
[id]="listboxId"
class="tedi-select__options"
cdkListbox
cdkListboxUseActiveDescendant
[cdkListboxValue]="selectedOptions()"
(cdkListboxValueChange)="handleValueChange($event)"
>
Expand Down
4 changes: 2 additions & 2 deletions community/components/form/select/select.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@

&__dropdown {
box-shadow: 0px 1px 5px 0px var(--alpha-20);
max-height: 300px;
overflow-y: auto;

@include mixins.responsive-styles(margin-top, form-field-outer-spacing);
@include mixins.responsive-styles(margin-bottom, form-field-outer-spacing);
Expand All @@ -60,6 +58,8 @@
&__options {
margin: 0;
padding: 0;
max-height: 300px;
overflow-y: auto;

&:focus .cdk-option-active {
background: var(--dropdown-item-hover-background);
Expand Down
19 changes: 16 additions & 3 deletions community/components/form/select/select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ export class SelectComponent
* @default false
*/
clearable = input<boolean>(true);
/**
* Optional element reference to calculate dropdown width from.
* If provided but null, dropdown will use auto width.
* If not provided, defaults to the host element width.
* @default undefined
*/
dropdownWidthRef = input<ElementRef | null>();
feedbackText = input<ComponentInputs<FeedbackTextComponent>>();

isOpen = signal(false);
Expand All @@ -115,7 +122,7 @@ export class SelectComponent
triggerRef = viewChild(CdkOverlayOrigin, { read: ElementRef });
hostRef = inject(ElementRef);
options = contentChildren(SelectOptionComponent);
dropdownWidth = signal(0);
dropdownWidth = signal<number | null>(null);
disabled = signal(false);

optionGroups = computed(() => {
Expand Down Expand Up @@ -186,8 +193,14 @@ export class SelectComponent
});

private setDropdownWidth(): void {
const computedWidth =
this.hostRef?.nativeElement?.getBoundingClientRect()?.width ?? 0;
const widthRef = this.dropdownWidthRef();
if (widthRef === null) {
this.dropdownWidth.set(null);
return;
}

const element = widthRef?.nativeElement ?? this.hostRef?.nativeElement;
const computedWidth = element?.getBoundingClientRect()?.width ?? 0;
this.dropdownWidth.set(computedWidth);
}

Expand Down
60 changes: 60 additions & 0 deletions community/components/form/select/select.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,63 @@ export const singleSelectGroupedOptions: Story = {
},
}),
};

export const dropdownWidthAuto: Story = {
render: (args) => ({
template: `
<tedi-select
[inputId]="inputId"
[placeholder]="placeholder"
[label]="label"
[feedbackText]="feedbackText"
[required]="required"
[disabled]="disabled"
[state]="state"
[size]="size"
[clearable]="clearable"
[dropdownWidthRef]="null"
>
<tedi-select-option value="option1" label="Option 1" group="Group 1"/>
<tedi-select-option value="option2" label="Option 2" group="Group 1"/>
<tedi-select-option value="option3" label="Option 3" group="Group 1"/>
<tedi-select-option value="option4" label="Option 4" group="Group 2"/>
<tedi-select-option value="option5" label="Option 5" group="Group 2"/>
</tedi-select>
`,
props: {
...args,
},
}),
};

export const dropdownWidthCustomElement: Story = {
render: (args) => ({
template: `
<div #customWidthElement style="width: 400px; border: 1px solid black; padding: 8px; margin-bottom: 16px;">
This div sets the dropdown width to 400px
</div>
<tedi-select
[inputId]="inputId"
[placeholder]="placeholder"
[label]="label"
[feedbackText]="feedbackText"
[required]="required"
[disabled]="disabled"
[state]="state"
[size]="size"
[clearable]="clearable"
[dropdownWidthRef]="getElementRef(customWidthElement)"
>
<tedi-select-option value="option1" label="Option 1" group="Group 1"/>
<tedi-select-option value="option2" label="Option 2" group="Group 1"/>
<tedi-select-option value="option3" label="Option 3" group="Group 1"/>
<tedi-select-option value="option4" label="Option 4" group="Group 2"/>
<tedi-select-option value="option5" label="Option 5" group="Group 2"/>
</tedi-select>
`,
props: {
...args,
getElementRef: (element: HTMLElement) => ({ nativeElement: element }),
},
}),
};
Loading