Skip to content
Closed
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
12 changes: 12 additions & 0 deletions src/Deloser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,18 @@ export class DeloserAPI implements Types.DeloserAPI {
return deloser;
}

applyAttribute(
element: HTMLElement,
existingDeloser: Types.Deloser | undefined,
newProps: Types.DeloserProps
): Types.Deloser {
if (existingDeloser) {
existingDeloser.setProps(newProps);
return existingDeloser;
}
return this.createDeloser(element, newProps);
}

getActions(element: HTMLElement): Types.DeloserElementActions | undefined {
for (
let e: HTMLElement | null = element;
Expand Down
13 changes: 13 additions & 0 deletions src/Groupper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,19 @@ export class GroupperAPI implements Types.GroupperAPI {
return newGroupper;
}

applyAttribute(
element: HTMLElement,
existingGroupper: Types.Groupper | undefined,
newProps: Types.GroupperProps,
sys: Types.SysProps | undefined
): Types.Groupper {
if (existingGroupper) {
existingGroupper.setProps(newProps);
return existingGroupper;
}
return this.createGroupper(element, newProps, sys);
}

forgetCurrentGrouppers(): void {
this._current = {};
}
Expand Down
155 changes: 53 additions & 102 deletions src/Instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,16 @@ export function updateTabsterByAttribute(

switch (key) {
case "deloser":
if (tabsterOnElement.deloser) {
tabsterOnElement.deloser.setProps(
if (tabster.deloser) {
tabsterOnElement.deloser = tabster.deloser.applyAttribute(
element,
tabsterOnElement.deloser,
newTabsterProps.deloser as Types.DeloserProps
);
} else {
if (tabster.deloser) {
tabsterOnElement.deloser =
tabster.deloser.createDeloser(
element,
newTabsterProps.deloser as Types.DeloserProps
);
} else if (__DEV__) {
console.error(
"Deloser API used before initialization, please call `getDeloser()`"
);
}
} else if (__DEV__) {
console.error(
"Deloser API used before initialization, please call `getDeloser()`"
);
}
break;

Expand All @@ -159,113 +153,70 @@ export function updateTabsterByAttribute(
break;

case "modalizer":
{
let newModalizerProps: Types.ModalizerProps | undefined;
const modalizerAPI = tabster.modalizer;

if (tabsterOnElement.modalizer) {
const props =
newTabsterProps.modalizer as Types.ModalizerProps;
const newModalizerId = props.id;
if (
newModalizerId &&
oldTabsterProps?.modalizer?.id !== newModalizerId
) {
// Modalizer id is changed, given the modalizers have complex logic and could be
// composite, it is easier to recreate the Modalizer instance than to implement
// the id update.
tabsterOnElement.modalizer.dispose();
newModalizerProps = props;
} else {
tabsterOnElement.modalizer.setProps(props);
}
} else {
if (modalizerAPI) {
newModalizerProps = newTabsterProps.modalizer;
} else if (__DEV__) {
console.error(
"Modalizer API used before initialization, please call `getModalizer()`"
);
}
}

if (modalizerAPI && newModalizerProps) {
tabsterOnElement.modalizer =
modalizerAPI.createModalizer(
element,
newModalizerProps,
sys
);
}
if (tabster.modalizer) {
tabsterOnElement.modalizer =
tabster.modalizer.applyAttribute(
element,
tabsterOnElement.modalizer,
newTabsterProps.modalizer as Types.ModalizerProps,
oldTabsterProps?.modalizer,
sys
);
} else if (__DEV__) {
console.error(
"Modalizer API used before initialization, please call `getModalizer()`"
);
}

break;

case "restorer":
if (tabsterOnElement.restorer) {
tabsterOnElement.restorer.setProps(
newTabsterProps.restorer as Types.RestorerProps
);
} else {
if (tabster.restorer) {
if (newTabsterProps.restorer) {
tabsterOnElement.restorer =
tabster.restorer.createRestorer(
element,
newTabsterProps.restorer
);
}
} else if (__DEV__) {
console.error(
"Restorer API used before initialization, please call `getRestorer()`"
);
if (tabster.restorer) {
if (newTabsterProps.restorer) {
tabsterOnElement.restorer =
tabster.restorer.applyAttribute(
element,
tabsterOnElement.restorer,
newTabsterProps.restorer
);
}
} else if (__DEV__) {
console.error(
"Restorer API used before initialization, please call `getRestorer()`"
);
}

break;

case "focusable":
tabsterOnElement.focusable = newTabsterProps.focusable;
break;

case "groupper":
if (tabsterOnElement.groupper) {
tabsterOnElement.groupper.setProps(
newTabsterProps.groupper as Types.GroupperProps
if (tabster.groupper) {
tabsterOnElement.groupper = tabster.groupper.applyAttribute(
element,
tabsterOnElement.groupper,
newTabsterProps.groupper as Types.GroupperProps,
sys
);
} else if (__DEV__) {
console.error(
"Groupper API used before initialization, please call `getGroupper()`"
);
} else {
if (tabster.groupper) {
tabsterOnElement.groupper =
tabster.groupper.createGroupper(
element,
newTabsterProps.groupper as Types.GroupperProps,
sys
);
} else if (__DEV__) {
console.error(
"Groupper API used before initialization, please call `getGroupper()`"
);
}
}
break;

case "mover":
if (tabsterOnElement.mover) {
tabsterOnElement.mover.setProps(
newTabsterProps.mover as Types.MoverProps
if (tabster.mover) {
tabsterOnElement.mover = tabster.mover.applyAttribute(
element,
tabsterOnElement.mover,
newTabsterProps.mover as Types.MoverProps,
sys
);
} else if (__DEV__) {
console.error(
"Mover API used before initialization, please call `getMover()`"
);
} else {
if (tabster.mover) {
tabsterOnElement.mover = tabster.mover.createMover(
element,
newTabsterProps.mover as Types.MoverProps,
sys
);
} else if (__DEV__) {
console.error(
"Mover API used before initialization, please call `getMover()`"
);
}
}
break;

Expand Down
22 changes: 22 additions & 0 deletions src/Modalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,28 @@ export class ModalizerAPI implements Types.ModalizerAPI {
return modalizer;
}

applyAttribute(
element: HTMLElement,
existingModalizer: Types.Modalizer | undefined,
newProps: Types.ModalizerProps,
oldProps: Types.ModalizerProps | undefined,
sys: Types.SysProps | undefined
): Types.Modalizer {
if (existingModalizer) {
const newId = newProps.id;
if (newId && oldProps?.id !== newId) {
// Modalizer id is changed, given the modalizers have complex logic and could be
// composite, it is easier to recreate the Modalizer instance than to implement
// the id update.
existingModalizer.dispose();
return this.createModalizer(element, newProps, sys);
}
existingModalizer.setProps(newProps);
return existingModalizer;
}
return this.createModalizer(element, newProps, sys);
}

private _onModalizerDispose = (modalizer: Modalizer) => {
const id = modalizer.id;
const userId = modalizer.userId;
Expand Down
13 changes: 13 additions & 0 deletions src/Mover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,19 @@ export class MoverAPI implements Types.MoverAPI {
return newMover;
}

applyAttribute(
element: HTMLElement,
existingMover: Types.Mover | undefined,
newProps: Types.MoverProps,
sys: Types.SysProps | undefined
): Types.Mover {
if (existingMover) {
existingMover.setProps(newProps);
return existingMover;
}
return this.createMover(element, newProps, sys);
}

private _onMoverDispose = (mover: Mover) => {
delete this._movers[mover.id];
};
Expand Down
12 changes: 12 additions & 0 deletions src/Restorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,16 @@ export class RestorerAPI implements RestorerAPIType {

return restorer;
}

applyAttribute(
element: HTMLElement,
existingRestorer: RestorerInterface | undefined,
newProps: RestorerProps
): RestorerInterface {
if (existingRestorer) {
existingRestorer.setProps(newProps);
return existingRestorer;
}
return this.createRestorer(element, newProps);
}
}
34 changes: 34 additions & 0 deletions src/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,12 @@ export type DeloserConstructor = (
interface DeloserInterfaceInternal {
/** @internal */
createDeloser(element: HTMLElement, props: DeloserProps): Deloser;
/** @internal */
applyAttribute(
element: HTMLElement,
existing: Deloser | undefined,
newProps: DeloserProps
): Deloser;
}

export interface DeloserAPI extends DeloserInterfaceInternal, Disposable {
Expand Down Expand Up @@ -862,6 +868,13 @@ interface MoverAPIInternal {
props: MoverProps,
sys: SysProps | undefined
): Mover;
/** @internal */
applyAttribute(
element: HTMLElement,
existing: Mover | undefined,
newProps: MoverProps,
sys: SysProps | undefined
): Mover;
}

import { type MoverKeys as _MoverKeys } from "./Consts.js";
Expand Down Expand Up @@ -923,6 +936,13 @@ export interface GroupperAPIInternal {
event: KeyboardEvent,
fromModalizer?: boolean
): void;
/** @internal */
applyAttribute(
element: HTMLElement,
existing: Groupper | undefined,
newProps: GroupperProps,
sys: SysProps | undefined
): Groupper;
}

import { type GroupperMoveFocusActions as _GroupperMoveFocusActions } from "./Consts.js";
Expand Down Expand Up @@ -1090,6 +1110,14 @@ interface ModalizerAPIInternal extends TabsterPartWithAcceptElement {
props: ModalizerProps,
sys: SysProps | undefined
): Modalizer;
/** @internal */
applyAttribute(
element: HTMLElement,
existing: Modalizer | undefined,
newProps: ModalizerProps,
oldProps: ModalizerProps | undefined,
sys: SysProps | undefined
): Modalizer;
/**
* Sets active modalizers.
* When active, everything outside of the modalizers with the specific user
Expand Down Expand Up @@ -1134,6 +1162,12 @@ export interface ModalizerAPI extends ModalizerAPIInternal, Disposable {
interface RestorerAPIInternal {
/** @internal */
createRestorer(element: HTMLElement, props: RestorerProps): Restorer;
/** @internal */
applyAttribute(
element: HTMLElement,
existing: Restorer | undefined,
newProps: RestorerProps
): Restorer;
}

export interface RestorerAPI extends RestorerAPIInternal, Disposable {}
Expand Down
Loading