Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4d5761a
sollution for input number
BF150 Mar 16, 2026
a53e3ac
feat: enhance input components with event logging and stop propagatio…
deleonio Mar 17, 2026
abdaae4
number focus
BF150 Mar 17, 2026
5f7a8aa
combobox fortschritt
BF150 Mar 17, 2026
847ed76
Merge remote-tracking branch 'origin/develop' into feature/8838-blur-…
BF150 Mar 18, 2026
d783ae8
removed debugging
BF150 Mar 19, 2026
0c41f38
single select events
BF150 Mar 19, 2026
0e2fe56
Merge branch 'develop' into feature/8838-blur-in-complex-inputs
BF150 Mar 19, 2026
d7e4e0b
Update all snapshots
BF150 Mar 19, 2026
ff65c01
linting
BF150 Mar 19, 2026
fe663f7
verhält sich jetzt anders als ein normales input
BF150 Mar 20, 2026
3065077
Merge branch 'develop' into feature/8838-blur-in-complex-inputs
BF150 Mar 20, 2026
59d8673
übersehen
BF150 Mar 20, 2026
ede87d5
Merge branch 'develop' into feature/8838-blur-in-complex-inputs
BF150 Mar 20, 2026
5ce1ce4
Merge branch 'develop' into feature/8838-blur-in-complex-inputs
BF150 Mar 26, 2026
d9c4574
....
BF150 Mar 26, 2026
5ab4d09
Update all snapshots
BF150 Mar 26, 2026
da141be
Merge remote-tracking branch 'origin/develop' into feature/8838-blur-…
BF150 Mar 30, 2026
872edcc
not needed
BF150 Mar 30, 2026
cd8a946
Update all snapshots
BF150 Mar 30, 2026
be5252e
Merge branch 'develop' into feature/8838-blur-in-complex-inputs
BF150 Apr 8, 2026
a7ff365
Update all snapshots
BF150 Apr 8, 2026
73bf9a2
focusout statt blur , feuert nur wenn die gesamte toolbar verlassen wird
BF150 Apr 9, 2026
fc1963e
logs entfernt
BF150 Apr 10, 2026
632544f
noch ein log entfernt
BF150 Apr 10, 2026
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 @@ -34,9 +34,17 @@ exports["Component hydration snapshots/renders kol-card with renderToString(0)"]

exports["Component hydration snapshots/renders kol-card with streamToString(0)"] = "<kol-card _label=\"Test kol-card\" s-mode=\"default\" class=\"sc-kol-card-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><kol-card-wc class=\"sc-kol-card-default hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card</strong><div class=\"kol-card__content\"><slot class=\"sc-kol-card-default\"></slot></div></div></kol-card-wc></template>Test content</kol-card>";

exports["Component hydration snapshots/renders kol-combobox with renderToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down kol-custom-suggestions-toggle sc-kol-combobox-default\" role=\"presentation\"></i></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";
exports["Component hydration snapshots/renders kol-card-wc with renderToString(0)"] = "<kol-card-wc _label=\"Test kol-card-wc\" class=\"hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card-wc</strong><div class=\"kol-card__content\">Test content</div></div></kol-card-wc>";

exports["Component hydration snapshots/renders kol-combobox with streamToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down kol-custom-suggestions-toggle sc-kol-combobox-default\" role=\"presentation\"></i></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";
exports["Component hydration snapshots/renders kol-card-wc with streamToString(0)"] = "<kol-card-wc _label=\"Test kol-card-wc\" class=\"hydrated\"><div aria-labelledby=\"nonce\" class=\"kol-card\" role=\"group\"><strong class=\"kol-headline kol-headline--strong kol-card__header kol-headline--single\" id=\"[id]\">Test kol-card-wc</strong><div class=\"kol-card__content\">Test content</div></div></kol-card-wc>";

exports["Component hydration snapshots/renders kol-click-button with renderToString(0)"] = "<kol-click-button _label=\"Test kol-click-button\" class=\"sc-kol-click-button-h hydrated\"><template shadowrootmode=\"open\"><button class=\"kol-click-button sc-kol-click-button\"><span class=\"kol-click-button__label sc-kol-click-button\">Test kol-click-button</span></button></template></kol-click-button>";

exports["Component hydration snapshots/renders kol-click-button with streamToString(0)"] = "<kol-click-button _label=\"Test kol-click-button\" class=\"sc-kol-click-button-h hydrated\"><template shadowrootmode=\"open\"><button class=\"kol-click-button sc-kol-click-button\"><span class=\"kol-click-button__label sc-kol-click-button\">Test kol-click-button</span></button></template></kol-click-button>";

exports["Component hydration snapshots/renders kol-combobox with renderToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <button type=\"button\" tabindex=\"-1\" class=\"kol-combobox-toggle sc-kol-combobox-default\"><i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down sc-kol-combobox-default\" role=\"presentation\"></i></button></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";

exports["Component hydration snapshots/renders kol-combobox with streamToString(0)"] = "<kol-combobox _label=\"Test kol-combobox\" _suggestions=\"Test value\" s-mode=\"default\" class=\"sc-kol-combobox-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div class=\"kol-form-field kol-combobox sc-kol-combobox-default\"><label class=\"kol-form-field__label sc-kol-combobox-default\" id=\"[id]\" htmlfor=\"[id]\"><span class=\"kol-span kol-form-field__label-text sc-kol-combobox-default\"><span class=\"kol-span__container sc-kol-combobox-default\"><span class=\"kol-span__label sc-kol-combobox-default\">Test kol-combobox</span><span aria-hidden=\"true\" class=\"kol-span__label sc-kol-combobox-default\" hidden><slot name=\"expert\" class=\"sc-kol-combobox-default\"></slot></span></span></span></label><div class=\"kol-form-field__input sc-kol-combobox-default\"><div class=\"kol-input-container sc-kol-combobox-default\"><div class=\"kol-input-container__container sc-kol-combobox-default\"><div class=\"kol-combobox__group sc-kol-combobox-default\"><input class=\"kol-input kol-combobox__input sc-kol-combobox-default\" type=\"text\" title=\"\" autocapitalize=\"off\" autocorrect=\"off\" id=\"[id]\" role=\"combobox\" aria-autocomplete=\"both\" aria-controls=\"[id]\" aria-expanded=\"false\" aria-labelledby=\"[id]\" value=\"\"> <button type=\"button\" tabindex=\"-1\" class=\"kol-combobox-toggle sc-kol-combobox-default\"><i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-down sc-kol-combobox-default\" role=\"presentation\"></i></button></div><ul role=\"listbox\" class=\"kol-custom-suggestions-options-group sc-kol-combobox-default\" hidden></ul></div></div></div></div></template>Test content</kol-combobox>";

exports["Component hydration snapshots/renders kol-details with renderToString(0)"] = "<kol-details _label=\"Test kol-details\" s-mode=\"default\" class=\"sc-kol-details-default-h hydrated\" style=\"visibility: hidden;\"><template shadowrootmode=\"open\"><style>/* CSS normalized */</style><div id=\"[id]\" class=\"collapsible kol-details sc-kol-details-default\"><strong class=\"kol-headline kol-headline--strong collapsible__heading kol-details__heading kol-headline--single sc-kol-details-default\"><kol-button-wc class=\"collapsible__heading-button kol-details__heading-button sc-kol-details-default hydrated\" slot=\"expert\"><button aria-controls=\"[id]\" aria-expanded=\"false\" class=\"kol-button kol-button--normal kol-button--standalone\" type=\"button\"><span class=\"kol-span kol-button__text\"><span class=\"kol-span__container\"><i aria-hidden=\"true\" class=\"kol-icon kol-icon__icon kolicon-chevron-right kol-span__icon kol-span__icon--left\" role=\"presentation\"></i><span class=\"kol-span__label\">Test kol-details</span><span aria-hidden=\"true\" class=\"kol-span__label\" hidden></span></span></span></button></kol-button-wc></strong><div class=\"collapsible__wrapper kol-details__wrapper sc-kol-details-default\"><div class=\"collapsible__wrapper-animation kol-details__wrapper-animation sc-kol-details-default\"><div aria-hidden=\"true\" class=\"collapsible__content kol-details__content indented-text sc-kol-details-default\" id=\"[id]\"><slot class=\"sc-kol-details-default\"></slot></div></div></div></div></template>Test content</kol-details>";

Expand Down
16 changes: 16 additions & 0 deletions packages/components/src/components/button/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ export class KolButtonWc implements ButtonAPI, FocusableElement {
}
};

private readonly onFocus = (event: FocusEvent) => {
this.state?._on?.onFocus?.(event);
if (this.host) {
dispatchDomEvent(this.host, KolEvent.focus);
}
};

private readonly onBlur = (event: FocusEvent) => {
this.state?._on?.onBlur?.(event);
if (this.host) {
dispatchDomEvent(this.host, KolEvent.blur);
}
};

public render(): JSX.Element {
const hasExpertSlot = showExpertSlot(this.state._label);
const ariaDescription = this.state._ariaDescription?.trim();
Expand Down Expand Up @@ -165,6 +179,8 @@ export class KolButtonWc implements ButtonAPI, FocusableElement {
name={this.state._name}
onClick={this.onClick}
onMouseDown={this.onMouseDown}
onFocus={this.onFocus}
onBlur={this.onBlur}
role={this.state._role}
tabIndex={this.state._tabIndex}
type={this.state._type}
Expand Down
72 changes: 42 additions & 30 deletions packages/components/src/components/combobox/shadow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
private refSuggestions: HTMLLIElement[] = [];
private _focusedOptionIndex: number = -1;
private readonly translateDeleteSelection = translate('kol-delete-selection');
private clearButtonFocused = false;

/**
* Returns the current value.
Expand Down Expand Up @@ -114,6 +115,7 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
option,
);
this.controller.setFormAssociatedValue(option);
this._filteredSuggestions = [...this.state._suggestions];
this.state._value = option;
this.refInput?.focus();
}
Expand Down Expand Up @@ -161,7 +163,7 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
} else {
this._filteredSuggestions = Array.isArray(this.state._suggestions)
? this.state._suggestions.filter((option: W3CInputValue) => {
return (option as string).toLowerCase().includes(query.toLowerCase());
return (option as string).toLowerCase().includes(query.trim().toLowerCase());
})
: this._filteredSuggestions;

Expand Down Expand Up @@ -253,14 +255,6 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
name: this.state._name,
required: this.state._required,
...this.controller.onFacade,
onFocus: (event) => {
this.controller.onFacade.onFocus(event);
this.inputHasFocus = true;
},
onBlur: (event) => {
this.controller.onFacade.onBlur(event);
this.inputHasFocus = false;
},
onChange: this.onChange.bind(this),
onInput: this.onInput.bind(this),
placeholder: this.state._placeholder,
Expand Down Expand Up @@ -288,17 +282,25 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
onClick: () => {
this.clearSelection();
},
onFocus: () => {
this.clearButtonFocused = true;
},
onBlur: () => {
this.clearButtonFocused = false;
},
}}
/>
)}
<IconFC
icons="kolicon-chevron-down"
label=""
class={clsx('kol-custom-suggestions-toggle', {
'kol-custom-suggestions-toggle--disabled': isDisabled,
})}
<button
type="button"
tabIndex={-1}
class="kol-combobox-toggle"
onClick={this.toggleListbox.bind(this)}
/>
disabled={this._disabled}
hidden={isDisabled}
>
<IconFC icons="kolicon-chevron-down" label="" />
</button>
</div>
{
<CustomSuggestionsOptionsGroupFc
Expand Down Expand Up @@ -388,7 +390,9 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
case ' ':
case 'Enter':
case 'NumpadEnter': {
if (this._isOpen) {
if (this.clearButtonFocused) {
this.clearSelection();
} else if (this._isOpen) {
if (this.selectFocusedOption()) {
this._isOpen = false;
}
Expand All @@ -398,6 +402,12 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
event.preventDefault();
break;
}
case 'Space': {
if (this.clearButtonFocused) {
this.clearSelection();
}
break;
}
case 'Home': {
this.blockSuggestionMouseOver = true;
handleEvent(undefined, () => {
Expand Down Expand Up @@ -673,25 +683,27 @@ export class KolCombobox implements ComboboxAPI, FocusableElement {
this.blockSuggestionMouseOver = false;
}

@Listen('focusout')
public handleFocusOut(event: FocusEvent) {
@Listen('focusin')
public handleFocusIn(event: FocusEvent) {
setTimeout(() => {
if (!this.host?.contains(document.activeElement)) {
this.onBlur(event);
if (this.host?.contains(document.activeElement) && !this.inputHasFocus) {
this.controller.onFacade.onFocus(event);
this.inputHasFocus = true;
}
});
}
@Listen('blur')
public handleWindowBlur(event: FocusEvent) {
this.onBlur(event);
}

private onBlur(event: FocusEvent): void {
if (this._isOpen) {
if (event instanceof FocusEvent && event.view === window) {
this._isOpen = false;
@Listen('focusout')
public handleFocusOut(event: FocusEvent) {
setTimeout(() => {
if (this.inputHasFocus && !this.host?.contains(document.activeElement)) {
this.controller.onFacade.onBlur(event);
this.inputHasFocus = false;
if (this._isOpen) {
this._isOpen = false;
}
}
}
});
}

private onChange(event: Event): void {
Expand Down
12 changes: 4 additions & 8 deletions packages/components/src/components/combobox/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@
&__delete {
@include kol-button-styles('kol-button');
}
}

.kol-custom-suggestions-toggle {
&:not(&--disabled) {
cursor: pointer;
}

&--disabled {
opacity: 0.5;
&-toggle {
min-height: 0;
flex: 0;
align-self: stretch;
}
}
}
Loading
Loading