Skip to content

Commit

Permalink
style(esl-popup): modify config definition and param keys
Browse files Browse the repository at this point in the history
  • Loading branch information
dshovchko committed Dec 13, 2024
1 parent 4c99720 commit aa46292
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/modules/esl-popup/core/esl-popup-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface ESLPopupActionParams extends ESLToggleableActionParams {
export type ProxiedParams = Required<ESLPopupActionParams>;

/** List of ESLPopupActionParams keys */
export const KEYSOF_POPUP_ACTION_PARAMS: string[] = [
export const KEYSOF_POPUP_ACTION_PARAMS: (keyof ESLPopupActionParams)[] = [
'position',
'positionOrigin',
'behavior',
Expand Down
62 changes: 26 additions & 36 deletions src/modules/esl-popup/core/esl-popup.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {range} from '../../esl-utils/misc/array';
import {ExportNs} from '../../esl-utils/environment/export-ns';
import {bind, memoize, ready, attr, boolAttr, jsonAttr, listen, decorate, prop} from '../../esl-utils/decorators';
import {bind, memoize, ready, attr, boolAttr, jsonAttr, listen, decorate} from '../../esl-utils/decorators';
import {ESLTraversingQuery} from '../../esl-traversing-query/core';
import {afterNextRender, rafDecorator} from '../../esl-utils/async/raf';
import {ESLToggleable} from '../../esl-toggleable/core';
import {isElement, isRelativeNode, isRTL, Rect, getListScrollParents, getViewportRect} from '../../esl-utils/dom';
import {parseBoolean, parseNumber, toBooleanAttribute} from '../../esl-utils/misc/format';
import {copyDefinedKeys} from '../../esl-utils/misc/object';
import {ESLIntersectionTarget, ESLIntersectionEvent} from '../../esl-event-listener/core/targets/intersection.target';
import {calcPopupPosition, isOnHorizontalAxis} from './esl-popup-position';
import {ESLPopupPlaceholder} from './esl-popup-placeholder';
Expand All @@ -19,26 +18,6 @@ import type {ESLPopupActionParams, ProxiedParams} from './esl-popup-types';
const INTERSECTION_LIMIT_FOR_ADJACENT_AXIS = 0.7;
const DEFAULT_OFFSET_ARROW = 50;

function buildConfig(params: ESLPopupActionParams, popup: ESLPopup): ProxiedParams {
return new Proxy<ProxiedParams>(params as ProxiedParams, {
get<T extends keyof ESLPopupActionParams>(target: ESLPopupActionParams, p: T | symbol): ESLPopupActionParams[T] {
return Reflect.get(target, p) ?? Reflect.get(popup, p);
},
set: (): boolean => false,
deleteProperty: (): boolean => false,
has<T extends keyof ESLPopupActionParams>(target: ESLPopupActionParams, p: T | symbol): boolean {
return Reflect.has(target, p) || Reflect.has(popup, p);
},
ownKeys(target: ESLPopupActionParams): (string | symbol)[] {
const paramKeys = Reflect.ownKeys(target);
const popupKeys = popup.PARAM_KEYS
.filter((key: string) => !paramKeys.includes(key) && Reflect.has(popup, key as keyof ESLPopup));
return [...paramKeys, ...popupKeys];
},
getOwnPropertyDescriptor: (): PropertyDescriptor | undefined => ({enumerable: true, configurable: true})
});
}

@ExportNs('Popup')
export class ESLPopup extends ESLToggleable {
public static override is = 'esl-popup';
Expand All @@ -49,8 +28,7 @@ export class ESLPopup extends ESLToggleable {
intersectionMargin: '0px'
};

/** List of popup params keys */
@prop(KEYSOF_POPUP_ACTION_PARAMS) public PARAM_KEYS: string[];
public static PARAM_KEYS: string[] = KEYSOF_POPUP_ACTION_PARAMS as string[];

/** Classname of popups arrow element */
@attr({defaultValue: 'esl-popup-arrow'}) public arrowClass: string;
Expand Down Expand Up @@ -103,14 +81,31 @@ export class ESLPopup extends ESLToggleable {
public override a11y: ESLA11yType;

public $placeholder: ESLPopupPlaceholder | null;
public config: ProxiedParams;

/** Store params and create proxied config */
protected set params(value: ESLPopupActionParams) {
this._params = copyDefinedKeys(value);
this.config = buildConfig(this._params, this);
@memoize()
public get config(): ProxiedParams {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const $popup = this;
return new Proxy<ProxiedParams>({} as ProxiedParams, {
get<T extends keyof ESLPopupActionParams>(target: ESLPopupActionParams, p: T | symbol): ESLPopupActionParams[T] {
return Reflect.get($popup._params, p) ?? Reflect.get($popup, p);
},
set: (): boolean => false,
deleteProperty: (): boolean => false,
has<T extends keyof ESLPopupActionParams>(target: ESLPopupActionParams, p: T | symbol): boolean {
return Reflect.has($popup._params, p) || Reflect.has($popup, p);
},
ownKeys(target: ESLPopupActionParams): (string | symbol)[] {
const paramKeys = Reflect.ownKeys($popup._params);
const popupKeys = ($popup.constructor as typeof ESLPopup).PARAM_KEYS
.filter((key: string) => !paramKeys.includes(key) && Reflect.has($popup, key as keyof ESLPopup));
return [...paramKeys, ...popupKeys];
},
getOwnPropertyDescriptor: (): PropertyDescriptor | undefined => ({enumerable: true, configurable: true})
});
}
protected _params: ESLPopupActionParams;

protected _params: ESLPopupActionParams = {};
protected _intersectionRatio: IntersectionRatioRect = {};
protected _updateLoopID: number;

Expand All @@ -133,11 +128,6 @@ export class ESLPopup extends ESLToggleable {
return Rect.from(this.$container).shift(window.scrollX, window.scrollY);
}

public constructor() {
super();
this.params = {};
}

@ready
protected override connectedCallback(): void {
super.connectedCallback();
Expand Down Expand Up @@ -200,7 +190,7 @@ export class ESLPopup extends ESLToggleable {
}

super.onShow(params);
this.params = params;
this._params = params;

this.style.visibility = 'hidden'; // eliminates the blinking of the popup at the previous position

Expand Down
28 changes: 21 additions & 7 deletions src/modules/esl-popup/test/esl-popup.config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ describe('ESLPopup: proxy logic of config', () => {
}
TestPopup2.register();

const defaultAttributes: ESLPopupActionParams = {
const defaultAction: ESLPopupActionParams = {
action: 'show'
};

const defaultAttrs: ESLPopupActionParams = {
position: 'top',
positionOrigin: 'outer',
behavior: 'fit',
Expand All @@ -43,20 +47,20 @@ describe('ESLPopup: proxy logic of config', () => {
test('should return default attributes if the showing parameters and default parameters are missing', () => {
$popup = new TestPopup1();
$popup.show({});
expect({...$popup.config}).toEqual(defaultAttributes);
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultAction});
});

test('should return merging default parameters and default attributes if the showing parameters are missing', () => {
$popup.show({});
expect({...$popup.config}).toEqual({...defaultAttributes, ...defaultParams});
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultParams, ...defaultAction});
});

test('should return merging showing parameters, default parameters, and default attributes', () => {
const params: ESLPopupActionParams = {
extraClass: 'test-class'
};
$popup.show(params);
expect({...$popup.config}).toEqual({...defaultAttributes, ...defaultParams, ...params});
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultParams, ...params, ...defaultAction});
});

test('should have value from default params in the case also prop defined via attributes', () => {
Expand Down Expand Up @@ -90,7 +94,7 @@ describe('ESLPopup: proxy logic of config', () => {
const entries = Object.entries($popup.config);
expect(entries).toEqual(expect.arrayContaining([
...Object.entries(defaultParams),
...Object.entries(defaultAttributes)
...Object.entries(defaultAttrs)
]));
});

Expand All @@ -102,9 +106,19 @@ describe('ESLPopup: proxy logic of config', () => {
extraStyle: 'color: red'
};
$popup.show(params1);
expect({...$popup.config}).toEqual({...defaultAttributes, ...defaultParams, ...params1});
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultParams, ...params1, ...defaultAction});
$popup.hide();
$popup.show(params2);
expect({...$popup.config}).toEqual({...defaultAttributes, ...defaultParams, ...params2});
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultParams, ...params2, ...defaultAction});
});

test('should be updated after attribure changing', () => {
const params: ESLPopupActionParams = {
extraClass: 'test-class'
};
$popup.show(params);
expect({...$popup.config}).toEqual({...defaultAttrs, ...defaultParams, ...params, ...defaultAction});
$popup.container = '::prev';
expect({...$popup.config}).toEqual({...defaultAttrs, container: '::prev', ...defaultParams, ...params, ...defaultAction});
});
});
9 changes: 4 additions & 5 deletions src/modules/esl-share/core/esl-share-popup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ExportNs} from '../../esl-utils/environment/export-ns';
import {ESLPopup, KEYSOF_POPUP_ACTION_PARAMS} from '../../esl-popup/core';
import {bind, listen, memoize, prop} from '../../esl-utils/decorators';
import {bind, listen, memoize} from '../../esl-utils/decorators';
import {ESLShareButton} from './esl-share-button';
import {ESLShareConfig} from './esl-share-config';

Expand All @@ -24,7 +24,7 @@ export interface ESLSharePopupActionParams extends ESLPopupActionParams {
disableArrow?: boolean;
}
/** List of ESLSharePopupActionParams keys */
export const KEYSOF_SHAREPOPUP_ACTION_PARAMS: string[] = [
export const KEYSOF_SHAREPOPUP_ACTION_PARAMS: (keyof ESLSharePopupActionParams)[] = [
...KEYSOF_POPUP_ACTION_PARAMS,
'list',
'dir',
Expand Down Expand Up @@ -52,6 +52,8 @@ export class ESLSharePopup extends ESLPopup {
hideDelay: 300
};

public static override PARAM_KEYS: string[] = KEYSOF_SHAREPOPUP_ACTION_PARAMS as string[];

/** List of attributes to forward from the activator to the {@link ESLSharePopup} */
public static forwardedAttrs = ['share-title', 'share-url'];

Expand All @@ -67,9 +69,6 @@ export class ESLSharePopup extends ESLPopup {
return ESLSharePopup.create();
}

/** List of share popup params keys */
@prop(KEYSOF_SHAREPOPUP_ACTION_PARAMS) public override PARAM_KEYS: string[];

/** Hashstring with a list of buttons already rendered in the popup */
protected _list: string = '';

Expand Down
9 changes: 4 additions & 5 deletions src/modules/esl-tooltip/core/esl-tooltip.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ExportNs} from '../../esl-utils/environment/export-ns';
import {ESLPopup, KEYSOF_POPUP_ACTION_PARAMS} from '../../esl-popup/core';
import {memoize, prop} from '../../esl-utils/decorators';
import {memoize} from '../../esl-utils/decorators';

import type {ESLPopupActionParams} from '../../esl-popup/core';

Expand All @@ -17,7 +17,7 @@ export interface ESLTooltipActionParams extends ESLPopupActionParams {
disableArrow?: boolean;
}
/** List of ESLTooltipActionParams keys */
export const KEYSOF_TOOLTIP_ACTION_PARAMS: string[] = [
export const KEYSOF_TOOLTIP_ACTION_PARAMS: (keyof ESLTooltipActionParams)[] = [
...KEYSOF_POPUP_ACTION_PARAMS,
'text',
'html',
Expand All @@ -36,6 +36,8 @@ export class ESLTooltip extends ESLPopup {
hideDelay: 300
};

public static override PARAM_KEYS: string[] = KEYSOF_TOOLTIP_ACTION_PARAMS as string[];

/** Shared instanse of Tooltip */
@memoize()
public static get sharedInstance(): ESLTooltip {
Expand All @@ -57,9 +59,6 @@ export class ESLTooltip extends ESLPopup {
this.sharedInstance.hide(params);
}

/** List of tooltip params keys */
@prop(KEYSOF_TOOLTIP_ACTION_PARAMS) public override PARAM_KEYS: string[];

public override connectedCallback(): void {
super.connectedCallback();
this.classList.add(ESLPopup.is);
Expand Down

0 comments on commit aa46292

Please sign in to comment.