Skip to content

Commit

Permalink
Merge pull request #2282 from apuliasoft/feat/kup-input-panel-autofoc…
Browse files Browse the repository at this point in the history
…us-in-error
  • Loading branch information
lucafoscili authored Dec 9, 2024
2 parents 8bb1235 + d0201b6 commit fd09c3d
Showing 1 changed file with 46 additions and 30 deletions.
76 changes: 46 additions & 30 deletions packages/ketchup/src/components/kup-input-panel/kup-input-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2038,36 +2038,55 @@ export class KupInputPanel {
);
}

#setFocusOnFirstInput() {
const form = this.#formRef;
const firstCellContent =
form?.querySelector<HTMLElement>('.f-cell__content');
if (!form || !firstCellContent) return;

const firstInput = this.#findFirstInput(firstCellContent);
if (firstInput) {
setTimeout(() => firstInput.focus(), 300);
#setFocusOnInputElement() {
if (!this.#formRef) return;

const MS_TO_FOCUS = 300;

// set focus on first input error
const fCellContents = Array.from(
this.#formRef.querySelectorAll<HTMLElement>('.f-cell__content')
);
for (const fCellContent of fCellContents) {
const inputError = this.#findFirstInput(fCellContent, true);
if (inputError) {
setTimeout(() => inputError.focus(), MS_TO_FOCUS);
return;
}
}

// set focus on first input of the first cellContent
if (!this.autoFocus || fCellContents.length === 0) return;
const input = this.#findFirstInput(fCellContents[0]);
if (input) {
setTimeout(() => input.focus(), MS_TO_FOCUS);
}
}

#findFirstInput(
element: HTMLElement | ShadowRoot
): HTMLInputElement | null {
const directInput = element.querySelector<HTMLInputElement>('input');
if (directInput) return directInput;

const shadowElements =
element instanceof HTMLElement
? element.querySelectorAll<HTMLElement>('*')
: [];
for (const elem of Array.from(shadowElements)) {
if (elem.shadowRoot) {
const shadowInput = elem.shadowRoot.querySelector('input');
if (shadowInput) return shadowInput;
}
element: HTMLElement,
withError: boolean = false
): HTMLInputElement {
if (!element || !(element instanceof HTMLElement)) return;

const INPUT_SELECTOR = '.mdc-text-field__input';
const ERROR_SELECTOR = '.mdc-text-field--error';
const selector = withError
? `${ERROR_SELECTOR} ${INPUT_SELECTOR}`
: INPUT_SELECTOR;

const input = element.querySelector<HTMLInputElement>(selector);
if (input) return input;

// find inner shadow inputs
const shadowRootElements = Array.from(
element.querySelectorAll<HTMLElement>('*')
).filter((innerElemnent) => innerElemnent.shadowRoot);
for (const element of shadowRootElements) {
const shadowInput =
element.shadowRoot.querySelector<HTMLInputElement>(selector);
if (shadowInput) return shadowInput;
}

return null;
}

#setAutoSkip(inputId: string, event: InputEvent): void {
Expand All @@ -2085,7 +2104,7 @@ export class KupInputPanel {
}

const inputElements = Array.from(
this.#formRef.querySelectorAll<HTMLElement>('.f-text-field')
this.#formRef?.querySelectorAll<HTMLElement>('.f-text-field')
).reduce<{ id: string; HTMLInputElement: HTMLInputElement }[]>(
(result, divElement) => {
const inputElement = divElement.querySelector('input');
Expand Down Expand Up @@ -2135,18 +2154,15 @@ export class KupInputPanel {
componentDidLoad() {
this.#didLoadInteractables();
this.kupReady.emit({ comp: this, id: this.rootElement.id });
this.#setFocusOnInputElement();
this.#kupManager.debug.logLoad(this, true);
if (this.#formRef && this.autoFocus) {
this.#setFocusOnFirstInput();
}
}

componentWillRender() {
this.#kupManager.debug.logRender(this, false);
}

componentDidRender() {
// autoFocus
if (this.#formRef) {
const fs: NodeListOf<HTMLElement> =
this.#formRef.querySelectorAll('.f-text-field');
Expand Down

0 comments on commit fd09c3d

Please sign in to comment.