@justeattakeaway/pie-webc-core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/CHANGELOG.md +12 -0
- package/package.json +3 -1
- package/src/index.ts +0 -1
- package/src/mixins/rtl/rtlMixin.ts +18 -6
- package/tsconfig.json +1 -1
- package/src/test-helpers/components/index.ts +0 -1
- package/src/test-helpers/components/web-component-test-wrapper/WebComponentTestWrapper.ts +0 -78
- package/src/test-helpers/components/web-component-test-wrapper/webComponentTestWrapper.scss +0 -20
- package/src/test-helpers/defs.ts +0 -15
- package/src/test-helpers/get-all-prop-combos.ts +0 -83
- package/src/test-helpers/index.ts +0 -4
- package/src/test-helpers/rendering.ts +0 -10
package/.eslintignore
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [Changed] - Add js/ts linting and fix errors ([#653](https://github.com/justeattakeaway/pie/pull/653)) by [@jamieomaguire](https://github.com/jamieomaguire)
|
|
8
|
+
|
|
9
|
+
## 0.6.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [Changed] - Improve TS typings in RTL mixin and provde extendable prop interface for components ([#623](https://github.com/justeattakeaway/pie/pull/623)) by [@jamieomaguire](https://github.com/jamieomaguire)
|
|
14
|
+
|
|
3
15
|
## 0.5.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-webc-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "PIE design system base classes, mixins and utilities for web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"author": "JustEatTakeaway - Design System Web Team",
|
|
8
8
|
"license": "Apache-2.0",
|
|
9
9
|
"scripts": {
|
|
10
|
+
"lint:scripts": "run -T eslint .",
|
|
11
|
+
"lint:scripts:fix": "run -T eslint . --fix",
|
|
10
12
|
"test": "run -T vitest run"
|
|
11
13
|
},
|
|
12
14
|
"volta": {
|
package/src/index.ts
CHANGED
|
@@ -2,18 +2,30 @@
|
|
|
2
2
|
import { LitElement } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators/property.js';
|
|
4
4
|
|
|
5
|
+
// According to TS, "A mixin class must have a constructor with a single rest parameter of type 'any[]'."
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
7
|
type Constructor<T> = new (...args: any[]) => T;
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
type htmlDirAttribute = 'ltr' | 'rtl' | 'auto';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Any component property interface that implements RTL should extend this interface. See the ModalProps interface for an example of this.
|
|
13
|
+
*/
|
|
14
|
+
export interface RTLComponentProps {
|
|
15
|
+
dir: htmlDirAttribute
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// This is just used by the dynamically constructed class below and does not need to be imported or referenced anywhere else
|
|
19
|
+
declare class _RTLInterface {
|
|
20
|
+
dir: htmlDirAttribute;
|
|
9
21
|
isRTL: boolean;
|
|
10
22
|
}
|
|
11
23
|
|
|
12
24
|
export const RtlMixin =
|
|
13
25
|
<T extends Constructor<LitElement>>(superClass: T) => {
|
|
14
|
-
class RTLElement extends superClass {
|
|
15
|
-
@property({ type: String })
|
|
16
|
-
dir = '';
|
|
26
|
+
class RTLElement extends superClass implements _RTLInterface {
|
|
27
|
+
@property({ type: String, reflect: true })
|
|
28
|
+
dir : htmlDirAttribute = 'ltr';
|
|
17
29
|
|
|
18
30
|
/**
|
|
19
31
|
* Returns true if the element is in Right to Left mode.
|
|
@@ -37,5 +49,5 @@ export const RtlMixin =
|
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
51
|
|
|
40
|
-
return RTLElement as Constructor<
|
|
52
|
+
return RTLElement as Constructor<_RTLInterface> & T;
|
|
41
53
|
};
|
package/tsconfig.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './web-component-test-wrapper/WebComponentTestWrapper';
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { LitElement, html, unsafeCSS } from 'lit';
|
|
2
|
-
import { property } from 'lit/decorators.js';
|
|
3
|
-
import styles from './webComponentTestWrapper.scss?inline';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This is a Web Component used for visual testing purposes.
|
|
7
|
-
* It allows us to wrap a component we'd like to test in a container
|
|
8
|
-
* that displays the component's props as a label.
|
|
9
|
-
*
|
|
10
|
-
* Alternatively, this component supports a page mode. In this mode,
|
|
11
|
-
* the test component is not wrapped and labelled, however you can add
|
|
12
|
-
* any amount of HTML to the page to help with testing. This useful for components
|
|
13
|
-
* such as Modal and Dialog components where we need to test the component in the context of
|
|
14
|
-
* the page markup.
|
|
15
|
-
*
|
|
16
|
-
* Components can be tested without this, but it's useful if your tests
|
|
17
|
-
* require additional markup when testing a component.
|
|
18
|
-
*/
|
|
19
|
-
export class WebComponentTestWrapper extends LitElement {
|
|
20
|
-
static styles = unsafeCSS(styles);
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The prop key and values to display above the component.
|
|
24
|
-
* This should be a single string representing a comma separated list of prop key/value pairs.
|
|
25
|
-
* Such as: 'size: small, isFullWidth: true'
|
|
26
|
-
*/
|
|
27
|
-
@property({ type: String })
|
|
28
|
-
propKeyValues = '';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Use in combination with the `pageMarkup` named slot to render the component alongside additional HTML
|
|
32
|
-
* to test the component in the context of the page.
|
|
33
|
-
*/
|
|
34
|
-
@property({ type: Boolean })
|
|
35
|
-
pageMode = false;
|
|
36
|
-
|
|
37
|
-
// Renders a string such as 'size: small, isFullWidth: true'
|
|
38
|
-
// as HTML such as:
|
|
39
|
-
// <p class="c-webComponentTestWrapper-label"><b>size</b>: <code>small</code></p>
|
|
40
|
-
// <p class="c-webComponentTestWrapper-label"><b>isFullWidth</b>: <code>true</code></p>
|
|
41
|
-
_renderPropKeyValues () {
|
|
42
|
-
return this.propKeyValues.split(',').map((propKeyValueString) => {
|
|
43
|
-
const [key, value] = propKeyValueString.split(':');
|
|
44
|
-
|
|
45
|
-
return html`<p class="c-webComponentTestWrapper-label"><b>${key}</b>: <code>${value}</code></p>`;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
render () {
|
|
50
|
-
if (this.pageMode) {
|
|
51
|
-
return html`
|
|
52
|
-
<div>
|
|
53
|
-
<slot name="component"></slot>
|
|
54
|
-
<slot name="pageMarkup"></slot>
|
|
55
|
-
</div>`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return html`
|
|
59
|
-
<div class="c-webComponentTestWrapper">
|
|
60
|
-
${this._renderPropKeyValues()}
|
|
61
|
-
<div class="c-webComponentTestWrapper-slot">
|
|
62
|
-
<slot name="component"></slot>
|
|
63
|
-
</div>
|
|
64
|
-
</div>`;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const componentSelector = 'web-component-test-wrapper';
|
|
69
|
-
|
|
70
|
-
if (!customElements.get(componentSelector)) {
|
|
71
|
-
customElements.define(componentSelector, WebComponentTestWrapper);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
declare global {
|
|
75
|
-
interface HTMLElementTagNameMap {
|
|
76
|
-
[componentSelector]: WebComponentTestWrapper;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
.c-webComponentTestWrapper {
|
|
2
|
-
padding-block: var(--dt-spacing-c);
|
|
3
|
-
padding-inline: var(--dt-spacing-e);
|
|
4
|
-
font-family: var(--dt-font-interactive-m-family);
|
|
5
|
-
font-size: calc(var(--dt-font-size-20) * 1px);
|
|
6
|
-
border: 1px solid var(--dt-color-background-dark);
|
|
7
|
-
display: grid;
|
|
8
|
-
grid-template-columns: 1fr 1fr;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.c-webComponentTestWrapper-label {
|
|
12
|
-
margin-block: var(--dt-spacing-c);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.c-webComponentTestWrapper-slot {
|
|
16
|
-
padding: var(--dt-spacing-c);
|
|
17
|
-
border: 1px dashed var(--dt-color-background-dark);
|
|
18
|
-
grid-column: 1 / 3;
|
|
19
|
-
margin-block-start: var(--dt-spacing-c);
|
|
20
|
-
}
|
package/src/test-helpers/defs.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
export type PropObject = {
|
|
3
|
-
[key: string]: any;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
export type WebComponentPropValues = {
|
|
7
|
-
[key: string]: any;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type WebComponentTestInput = {
|
|
11
|
-
propValues: WebComponentPropValues;
|
|
12
|
-
renderedString: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type WebComponentRenderFn = (propVals: WebComponentPropValues) => string;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { PropObject, WebComponentPropValues } from './defs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate all possible combinations of properties for a given object.
|
|
5
|
-
*
|
|
6
|
-
* @param {PropObject} obj - The object containing properties for which combinations are to be generated.
|
|
7
|
-
* Each property value can any data type.
|
|
8
|
-
*
|
|
9
|
-
* @returns {WebComponentPropValues[]} An array of objects, where each object is a unique combination of web component property values.
|
|
10
|
-
*/
|
|
11
|
-
export const getAllPropCombinations = (obj: PropObject): WebComponentPropValues[] => {
|
|
12
|
-
const propertyKeys = Object.keys(obj);
|
|
13
|
-
const combinationsOfPropValues: WebComponentPropValues[] = [];
|
|
14
|
-
|
|
15
|
-
// This function generates combinations of properties from a given object.
|
|
16
|
-
// It does this by recursively concatenating each property value to an 'accumulatedPropertyValues' array,
|
|
17
|
-
// and adding the resulting combination to a 'WebComponentPropValues' array when it reaches the end of the keys.
|
|
18
|
-
function generatePropCombinations (accumulatedPropertyValues: any[], i: number): void {
|
|
19
|
-
// When 'i' equals the length of 'keys', we've reached the end of the keys.
|
|
20
|
-
// This means we've formed a complete combination.
|
|
21
|
-
if (i === propertyKeys.length) {
|
|
22
|
-
// Create an empty object to hold the current WebComponentPropValues.
|
|
23
|
-
const combo: WebComponentPropValues = {};
|
|
24
|
-
// Loop over the 'accumulatedPropertyValues' array, which contains the property values for this combination.
|
|
25
|
-
for (let j = 0; j < accumulatedPropertyValues.length; j++) {
|
|
26
|
-
// Assign each value to the corresponding key in the 'combo' object.
|
|
27
|
-
combo[propertyKeys[j]] = accumulatedPropertyValues[j];
|
|
28
|
-
}
|
|
29
|
-
// Add this combination to the 'combinationsOfPropValues' array.
|
|
30
|
-
combinationsOfPropValues.push(combo);
|
|
31
|
-
// End the recursion for this branch.
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Get the current key and its values from the input object.
|
|
36
|
-
const propertyKey = propertyKeys[i];
|
|
37
|
-
const propertyValues = obj[propertyKey];
|
|
38
|
-
|
|
39
|
-
if (typeof propertyValues === 'boolean') {
|
|
40
|
-
// If the values for this key are a boolean, we generate two combinations:
|
|
41
|
-
// one with the value 'true', and one with the value 'false'.
|
|
42
|
-
generatePropCombinations([...accumulatedPropertyValues, true], i + 1);
|
|
43
|
-
generatePropCombinations([...accumulatedPropertyValues, false], i + 1);
|
|
44
|
-
} else if (Array.isArray(propertyValues)) {
|
|
45
|
-
// If the values for this key are an array, we generate a combination for each value in the array.
|
|
46
|
-
for (let j = 0; j < propertyValues.length; j++) {
|
|
47
|
-
generatePropCombinations([...accumulatedPropertyValues, propertyValues[j]], i + 1);
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
// If the values for this key are neither a boolean nor an array,
|
|
51
|
-
// we simply generate a single combination with the value as is.
|
|
52
|
-
generatePropCombinations([...accumulatedPropertyValues, propertyValues], i + 1);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
generatePropCombinations([], 0);
|
|
57
|
-
|
|
58
|
-
return combinationsOfPropValues;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Splits an array of component prop combinations by a particular property value.
|
|
63
|
-
*
|
|
64
|
-
* @param {WebComponentPropValues[]} propValueCombinations - The array of combinations to split.
|
|
65
|
-
* @param {string} property - The property to split by.
|
|
66
|
-
*
|
|
67
|
-
* @returns {Record<string, WebComponentPropValues[]>} An object mapping each unique property value to the combinations that have it.
|
|
68
|
-
*/
|
|
69
|
-
export const splitCombinationsByPropertyValue = (propValueCombinations: WebComponentPropValues[], property: string): Record<string, WebComponentPropValues[]> => propValueCombinations
|
|
70
|
-
.reduce((splitCombinations: Record<string, WebComponentPropValues[]>, combination: WebComponentPropValues) => {
|
|
71
|
-
const propertyValue = combination[property];
|
|
72
|
-
const propertyValueKey = String(propertyValue);
|
|
73
|
-
|
|
74
|
-
if (!(propertyValueKey in splitCombinations)) {
|
|
75
|
-
splitCombinations[propertyValueKey] = [];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Add the current combination to the array for its property value
|
|
79
|
-
splitCombinations[propertyValueKey].push(combination);
|
|
80
|
-
|
|
81
|
-
return splitCombinations;
|
|
82
|
-
}, {});
|
|
83
|
-
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { WebComponentPropValues, WebComponentTestInput, WebComponentRenderFn } from './defs';
|
|
2
|
-
|
|
3
|
-
export function createTestWebComponent (propVals: WebComponentPropValues, componentRenderFn: WebComponentRenderFn): WebComponentTestInput {
|
|
4
|
-
const testComponent: WebComponentTestInput = {
|
|
5
|
-
propValues: propVals,
|
|
6
|
-
renderedString: componentRenderFn(propVals),
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
return testComponent;
|
|
10
|
-
}
|