Skip to content

Commit

Permalink
Merge pull request #191 from MaibornWolff/#182-fix-autocomplete-chip-…
Browse files Browse the repository at this point in the history
…input

fix(#182): fix autocomplete/chipInput
  • Loading branch information
Fuasmattn authored Jul 11, 2023
2 parents 5e0f44b + 2ee518d commit a4eb405
Show file tree
Hide file tree
Showing 11 changed files with 3,870 additions and 3,853 deletions.
10 changes: 5 additions & 5 deletions mwui-stencil/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,9 @@
"required": false
},
{
"name": "selected",
"name": "selection",
"type": "string[]",
"mutable": false,
"mutable": true,
"reflectToAttr": false,
"docs": "Currently selected options",
"docsTags": [],
Expand Down Expand Up @@ -393,7 +393,7 @@
"methods": [],
"events": [
{
"event": "valueChanged",
"event": "selectionChanged",
"detail": "string",
"bubbles": true,
"cancelable": true,
Expand Down Expand Up @@ -1793,7 +1793,7 @@
"detail": "string",
"bubbles": true,
"cancelable": true,
"composed": false,
"composed": true,
"docs": "Emits an event when value of input changes",
"docsTags": []
},
Expand All @@ -1802,7 +1802,7 @@
"detail": "string[]",
"bubbles": true,
"cancelable": true,
"composed": false,
"composed": true,
"docs": "Emits an event when its value changes",
"docsTags": []
}
Expand Down
6 changes: 3 additions & 3 deletions mwui-stencil/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export namespace Components {
/**
* Currently selected options
*/
selected: string[];
selection: string[];
/**
* HTML Input type
*/
Expand Down Expand Up @@ -1260,7 +1260,7 @@ declare namespace LocalJSX {
/**
* Emits an event when its value changes
*/
onValueChanged?: (event: MwAutocompleteCustomEvent<string>) => void;
onSelectionChanged?: (event: MwAutocompleteCustomEvent<string>) => void;
/**
* Shows how many options the user has selected as well as the allowed maximum. Only works, if `maximum` prop is defined.
*/
Expand All @@ -1280,7 +1280,7 @@ declare namespace LocalJSX {
/**
* Currently selected options
*/
selected?: string[];
selection?: string[];
/**
* HTML Input type
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ import * as MwAutocompleteStories from "./mw-autocomplete.stories.tsx";
]}
/>

## Listen to changes

Whenever the selection is updated, a `selectionChanged` event is fired. The currently selected items can be retrieved from the element, like `event.target.selection`.

```javascript
document.getElementById("my-autocomplete").addEventListener("selectionChanged", event => {
console.log(event.target.selection); // yields an array of strings
});
```

<ArgTypes of="mw-autocomplete" />

## Examples
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { newSpecPage } from "@stencil/core/testing";
import { SpecPage, newSpecPage } from "@stencil/core/testing";
import { h } from "@stencil/core";
import { MwAutocomplete } from "./mw-autocomplete";

Expand All @@ -7,7 +7,7 @@ describe("Given MwAutocomplete", () => {
name: "some-name",
label: "some-label",
required: false,
selected: [],
selection: [],
};
const setup = async ({
name,
Expand All @@ -18,8 +18,8 @@ describe("Given MwAutocomplete", () => {
inline,
required,
disabled,
selected,
}: Pick<MwAutocomplete, "name" | "label" | "placeholder" | "helperText" | "hasError" | "inline" | "required" | "disabled" | "selected"> = defaultProps) => {
selection,
}: Pick<MwAutocomplete, "name" | "label" | "placeholder" | "helperText" | "hasError" | "inline" | "required" | "disabled" | "selection"> = defaultProps): Promise<SpecPage> => {
return await newSpecPage({
components: [MwAutocomplete],
template: () => (
Expand All @@ -31,7 +31,7 @@ describe("Given MwAutocomplete", () => {
has-error={hasError}
inline={inline}
required={required}
selected={selected}
selection={selection}
disabled={disabled}
></mw-autcomplete>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ const IconTemplate = args => `
>
<mw-icon slot="icon-start" icon="search"></mw-icon>
<div slot="dropdown-menu">
<mw-menu-item title="List Item 1"></mw-menu-item>
<mw-menu-item title="List Item 2"></mw-menu-item>
<mw-menu-item title="List Item 3"></mw-menu-item>
<mw-menu-item title="List Item 4"></mw-menu-item>
<mw-menu-item text="List Item 1"></mw-menu-item>
<mw-menu-item text="List Item 2"></mw-menu-item>
<mw-menu-item text="List Item 3"></mw-menu-item>
<mw-menu-item text="List Item 4"></mw-menu-item>
</div>
</mw-autocomplete>`;
Expand Down
39 changes: 20 additions & 19 deletions mwui-stencil/src/components/mw-autocomplete/mw-autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class MwAutocomplete {
/**
* Emits an event when its value changes
*/
@Event({ bubbles: true, composed: false }) valueChanged: EventEmitter<string>;
@Event({ bubbles: true, composed: false, eventName: "selectionChanged" }) valueChanged: EventEmitter<string>;
/**
* HTML Input type
*/
Expand Down Expand Up @@ -80,16 +80,17 @@ export class MwAutocomplete {
/**
* Currently selected options
*/
@Prop({ reflect: true, mutable: false }) selected: string[] = [];
@Watch("selected")
onSelectedChange(selected: string[]): void {
@Prop({ reflect: true, mutable: true }) selection: string[] = [];
@Watch("selection")
onSelectedChange(selection: string[]): void {
if (!this.canAddToValues()) {
this.hostElement.querySelectorAll("mw-menu-item").forEach(item => {
item.setAttribute("disabled", `true`);
});
} else {
this.setItemDisabledState(selected);
this.setItemDisabledState(selection);
}
this.valueChanged.emit();
}

@State() focused = false;
Expand Down Expand Up @@ -117,7 +118,7 @@ export class MwAutocomplete {
}

private onInputChange = (event: MwChipInputCustomEvent<string> | MwTextfieldCustomEvent<string> | InputEvent): void => {
this.filterDropdownOptions(event.detail);
this.filterDropdownOptions((event.target as HTMLMwChipInputElement).value);
this.isDropdownOpen = true;
};

Expand All @@ -134,20 +135,20 @@ export class MwAutocomplete {
return;
}

this.selected = [...this.selected, value];
this.selection = [...this.selection, value];
this.removeDropdownFilter();
};

private setItemDisabledState(selected: string[]): void {
private setItemDisabledState = (selection: string[]): void => {
this.hostElement.querySelectorAll("mw-menu-item").forEach(item => {
const isDisabled = selected.includes(item.getAttribute("value"));
const isDisabled = selection.includes(item.getAttribute("value"));
item.setAttribute("disabled", `${isDisabled}`);
});
}
};

private handleChipListValueChange(event: MwChipInputCustomEvent<string[]>): void {
this.selected = event.detail;
}
private handleChipListValueChange = (event: MwChipInputCustomEvent<string[]>): void => {
this.selection = event.detail;
};

private filterDropdownOptions = (value: string | number): void => {
let hasNoSuggestions = true;
Expand All @@ -173,9 +174,9 @@ export class MwAutocomplete {
});
};

private canAddToValues(): boolean {
return !this.maximum || this.selected?.length < this.maximum;
}
private canAddToValues = (): boolean => {
return !this.maximum || this.selection?.length < this.maximum;
};

render() {
return (
Expand All @@ -198,10 +199,10 @@ export class MwAutocomplete {
disabled={this.disabled}
hasError={this.hasError}
maximum={this.maximum}
selectedChips={this.selected}
selectedChips={this.selection}
onFocus={this.onFocus}
onBlur={this.onBlur}
onChange={this.handleChipListValueChange}
onValueChanged={this.handleChipListValueChange}
onInput={this.onInputChange}
slot="anchor"
>
Expand Down Expand Up @@ -262,7 +263,7 @@ export class MwAutocomplete {
</div>
<div class="helper-text-container">
<mw-helper-text helperText={this.helperText} hasError={this.hasError} />
{this.maximum && this.optionCounter && <mw-helper-text helperText={`${this.selected.length}/${this.maximum}`} />}
{this.maximum && this.optionCounter && <mw-helper-text helperText={`${this.selection.length}/${this.maximum}`} />}
</div>
</div>
</Host>
Expand Down
8 changes: 4 additions & 4 deletions mwui-stencil/src/components/mw-autocomplete/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
| `placeholder` | `placeholder` | Placeholder to be displayed | `string` | `undefined` |
| `readOnly` | `read-only` | Whether user can't type in input field | `boolean` | `false` |
| `required` | `required` | Mark input as required | `boolean` | `false` |
| `selected` | -- | Currently selected options | `string[]` | `[]` |
| `selection` | -- | Currently selected options | `string[]` | `[]` |
| `type` | `type` | HTML Input type | `string` | `"text"` |
| `value` | `value` | input field value | `number \| string` | `undefined` |

## Events

| Event | Description | Type |
| -------------- | ------------------------------------- | --------------------- |
| `valueChanged` | Emits an event when its value changes | `CustomEvent<string>` |
| Event | Description | Type |
| ------------------ | ------------------------------------- | --------------------- |
| `selectionChanged` | Emits an event when its value changes | `CustomEvent<string>` |

## Dependencies

Expand Down
23 changes: 14 additions & 9 deletions mwui-stencil/src/components/mw-chip-input/mw-chip-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export class MwChipInput {
/**
* Emits an event when its value changes
*/
@Event({ bubbles: true, composed: false }) valueChanged: EventEmitter<string[]>;
@Event({ bubbles: true, composed: true, eventName: "valueChanged" }) valueChanged: EventEmitter<string[]>;

/**
* Emits an event when value of input changes
*/
@Event({ bubbles: true, composed: false }) inputChange: EventEmitter<string>;
@Event({ bubbles: true, composed: true }) inputChange: EventEmitter<string>;
/**
* input field name
*/
Expand Down Expand Up @@ -143,6 +143,11 @@ export class MwChipInput {
this.focused = false;
};

private onRemoveSelection = (value: string): void => {
this._selection.deselect(value);
this.onValueChange();
};

private addMultiValue = (value: string): void => {
if (value.trim()?.length === 0) {
return;
Expand All @@ -162,18 +167,18 @@ export class MwChipInput {
this.onValueChange();
};

private onValueChange(): void {
private onValueChange = (): void => {
this.selected = this._selection.selected;
this.valueChanged.emit(this.selected);
}
};

private handleInputChange(): void {
private handleInputChange = (): void => {
this.inputChange.emit(this.inputElement.value);
}
};

private canAddToValues(): boolean {
private canAddToValues = (): boolean => {
return !this.maximum || this.selected?.length < this.maximum;
}
};

render() {
const {
Expand Down Expand Up @@ -228,7 +233,7 @@ export class MwChipInput {
</span>
<div class="input-options">
{selected?.map(v => (
<mw-chip key={v} showClose={true} value={v} selected={true} toggleable={false} disabled={disabled}>
<mw-chip key={v} onMwChipClose={() => this.onRemoveSelection(v)} showClose={true} value={v} selected={true} toggleable={false} disabled={disabled}>
{v}
</mw-chip>
))}
Expand Down
Loading

0 comments on commit a4eb405

Please sign in to comment.