@muonic/muon 0.0.2-beta.48 → 0.0.2-beta.49

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/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.0.2-beta.49](https://github.com/centrica-engineering/muon/compare/v0.0.2-beta.47...v0.0.2-beta.49) (2023-11-27)
6
+
5
7
  ### [0.0.2-beta.48](https://github.com/centrica-engineering/muon/compare/v0.0.2-beta.41...v0.0.2-beta.48) (2023-10-17)
6
8
 
7
9
 
@@ -71,14 +71,14 @@ export class Image extends MuonElement {
71
71
  get standardTemplate() {
72
72
  const isBackground = this.background;
73
73
 
74
- if (!this._ratios.includes(this.ratio)) {
75
- this.ratio = IMAGE_CONFIG_RATIO; // @TODO: add fallback `|| this._ratios[0]`
76
- }
77
-
78
74
  if (isBackground) {
79
75
  this.ratio = this.ratio?.length > 0 ? this.ratio : '16 / 9'; // without a default size background images won't show
80
76
  }
81
77
 
78
+ if (!this._ratios.includes(this.ratio)) {
79
+ this.ratio = IMAGE_CONFIG_RATIO; // @TODO: add fallback `|| this._ratios[0]`
80
+ }
81
+
82
82
  if (this.src && this.src.length > 0) {
83
83
  const imageObj = {
84
84
  src: this.src,
package/index.js CHANGED
@@ -16,7 +16,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
16
16
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
17
17
  import { cache } from 'lit/directives/cache.js';
18
18
  import { AsyncDirective } from 'lit/async-directive.js';
19
- import { ScopedElementsMixin } from '@open-wc/scoped-elements';
19
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
20
20
  import { dedupeMixin } from '@open-wc/dedupe-mixin';
21
21
  import { literal, html as staticHTML, unsafeStatic } from 'lit/static-html.js';
22
22
  import { until } from 'lit/directives/until.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muonic/muon",
3
- "version": "0.0.2-beta.48",
3
+ "version": "0.0.2-beta.49",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,53 +17,53 @@
17
17
  "author": "",
18
18
  "license": "ISC",
19
19
  "dependencies": {
20
- "@open-wc/building-rollup": "2.2.3",
21
- "@open-wc/scoped-elements": "2.2.0",
22
- "@rollup/plugin-alias": "5.0.0",
23
- "@rollup/plugin-json": "6.0.0",
24
- "@rollup/plugin-node-resolve": "15.1.0",
25
- "@rollup/plugin-replace": "5.0.2",
26
- "@rollup/plugin-virtual": "3.0.1",
27
- "@web/dev-server": "0.3.0",
28
- "@web/dev-server-rollup": "0.5.2",
29
- "@web/dev-server-storybook": "0.7.4",
20
+ "@open-wc/building-rollup": "3.0.2",
21
+ "@open-wc/scoped-elements": "3.0.2",
22
+ "@rollup/plugin-alias": "5.0.1",
23
+ "@rollup/plugin-json": "6.0.1",
24
+ "@rollup/plugin-node-resolve": "15.2.3",
25
+ "@rollup/plugin-replace": "5.0.5",
26
+ "@rollup/plugin-virtual": "3.0.2",
27
+ "@web/dev-server": "0.4.1",
28
+ "@web/dev-server-rollup": "0.6.1",
29
+ "@web/dev-server-storybook": "2.0.1",
30
30
  "@web/storybook-prebuilt": "0.1.37",
31
31
  "app-root-path": "3.1.0",
32
- "autoprefixer": "10.4.14",
32
+ "autoprefixer": "10.4.16",
33
33
  "chokidar": "3.5.3",
34
34
  "chroma-js": "2.4.2",
35
35
  "command-line-args": "5.2.1",
36
36
  "cssnano": "6.0.1",
37
37
  "deepmerge": "4.3.1",
38
38
  "element-internals-polyfill": "^1.3.8",
39
- "glob": "10.2.2",
39
+ "glob": "10.3.10",
40
40
  "glob-to-regexp": "0.4.1",
41
- "lit": "2.8.0",
41
+ "lit": "3.1.0",
42
42
  "lodash": "4.17.21",
43
43
  "path-is-inside": "1.0.2",
44
- "postcss": "8.4.27",
44
+ "postcss": "8.4.31",
45
45
  "postcss-extend-rule": "4.0.0",
46
46
  "postcss-import": "15.1.0",
47
- "postcss-preset-env": "9.1.0",
47
+ "postcss-preset-env": "9.3.0",
48
48
  "postcss-simple-vars": "7.0.1",
49
- "rollup-plugin-import-css": "3.3.1",
49
+ "rollup-plugin-import-css": "3.3.5",
50
50
  "rollup-plugin-lit-css": "4.0.1",
51
51
  "rollup-plugin-minify-html-literals": "1.2.6",
52
52
  "rollup-plugin-styles": "4.0.0",
53
- "style-dictionary": "3.8.0",
54
- "typescript": "5.0.4",
53
+ "style-dictionary": "3.9.0",
54
+ "typescript": "5.3.2",
55
55
  "web-component-analyzer": "1.1.7"
56
56
  },
57
57
  "devDependencies": {
58
- "@open-wc/testing": "3.1.8",
59
- "@web/dev-server-esbuild": "0.4.1",
60
- "@web/test-runner": "0.16.1",
61
- "@web/test-runner-browserstack": "0.6.1",
62
- "@web/test-runner-playwright": "0.10.0",
63
- "ava": "5.2.0",
64
- "c8": "7.13.0",
65
- "esmock": "2.2.1",
66
- "sinon": "15.0.4"
58
+ "@open-wc/testing": "4.0.0",
59
+ "@web/dev-server-esbuild": "1.0.1",
60
+ "@web/test-runner": "0.18.0",
61
+ "@web/test-runner-browserstack": "0.7.0",
62
+ "@web/test-runner-playwright": "0.11.0",
63
+ "ava": "5.3.1",
64
+ "c8": "8.0.1",
65
+ "esmock": "2.6.0",
66
+ "sinon": "17.0.1"
67
67
  },
68
68
  "engines": {
69
69
  "node": ">=16.13.0"
@@ -101,6 +101,8 @@ const analyze = async () => {
101
101
  return { fileName: file, text: code.toString() };
102
102
  });
103
103
 
104
+ console.log('Analyzing files: ', files.map((file) => file.fileName));
105
+
104
106
  const { results } = analyzeText(files);
105
107
 
106
108
  return results.map((result) => {
@@ -212,7 +214,7 @@ const sourceFilesAnalyzer = async () => {
212
214
  config: {
213
215
  format: 'json',
214
216
  discoverNodeModules: true,
215
- excludedDeclarationNames: ['ScopedElementsMixin']
217
+ excludedDeclarationNames: ['ScopedElementsMixin', 'ScopedElementsMixinImplementation']
216
218
  }
217
219
  }));
218
220
 
@@ -307,6 +307,8 @@ describe('form', () => {
307
307
  resetBtn.click();
308
308
 
309
309
  expect(input.value).to.equal('foo', 'no reset input value');
310
+ expect(el._resetButton.loading).to.equal(true, 'reset input loading');
311
+ expect(el._reset()).to.equal(undefined, 'no reset form value');
310
312
  });
311
313
 
312
314
  it('form cta reset with inputter', async () => {
@@ -96,3 +96,12 @@ snapshots["icon broken caches"] =
96
96
  `;
97
97
  /* end snapshot icon broken caches */
98
98
 
99
+ snapshots["icon implements icon size 48"] =
100
+ `<div
101
+ aria-hidden="true"
102
+ class="arrow-right icon"
103
+ >
104
+ </div>
105
+ `;
106
+ /* end snapshot icon implements icon size 48 */
107
+
@@ -128,10 +128,13 @@ snapshots["image implements placeholder image for background"] =
128
128
  /* end snapshot image implements placeholder image for background */
129
129
 
130
130
  snapshots["image implements placeholder image for chrome"] =
131
- `<div
132
- class="image"
133
- style="--image-ratio:16 / 9;"
134
- >
131
+ `<div class="image">
132
+ <img
133
+ alt=""
134
+ class="blur image-lazy"
135
+ loading="lazy"
136
+ src="tests/components/image/images/15.png"
137
+ >
135
138
  </div>
136
139
  `;
137
140
  /* end snapshot image implements placeholder image for chrome */
@@ -164,3 +167,45 @@ snapshots["image fallback for ratio"] =
164
167
  `;
165
168
  /* end snapshot image fallback for ratio */
166
169
 
170
+ snapshots["image implements background with empty ratio"] =
171
+ `<div class="image">
172
+ <img
173
+ alt=""
174
+ class="blur-out image-lazy"
175
+ src="tests/components/image/images/150.png"
176
+ >
177
+ </div>
178
+ `;
179
+ /* end snapshot image implements background with empty ratio */
180
+
181
+ snapshots["image implements placeholder image lazy loading"] =
182
+ `<div class="image">
183
+ <img
184
+ alt=""
185
+ class="blur image-lazy"
186
+ loading="lazy"
187
+ src="tests/components/image/images/15.png"
188
+ >
189
+ </div>
190
+ `;
191
+ /* end snapshot image implements placeholder image lazy loading */
192
+
193
+ snapshots["image implements placeholder image ratio fallback"] =
194
+ `<div class="image">
195
+ <img
196
+ alt=""
197
+ class="blur image-lazy"
198
+ src="tests/components/image/images/15.png"
199
+ >
200
+ </div>
201
+ `;
202
+ /* end snapshot image implements placeholder image ratio fallback */
203
+
204
+ snapshots["image implements background ratio fallback"] =
205
+ `<div class="image is-background">
206
+ <div class="blur-out image-holder">
207
+ </div>
208
+ </div>
209
+ `;
210
+ /* end snapshot image implements background ratio fallback */
211
+
@@ -4,8 +4,17 @@ import sinon from 'sinon';
4
4
  import { Image } from '@muonic/muon/components/image';
5
5
  import { defaultChecks } from '../../helpers';
6
6
 
7
+ const NoRatioImage = class extends Image {
8
+ constructor() {
9
+ super();
10
+ this.ratio = undefined;
11
+ }
12
+ };
13
+
7
14
  const tagName = defineCE(Image);
8
15
  const tag = unsafeStatic(tagName);
16
+ const noRatioTagName = defineCE(NoRatioImage);
17
+ const noRatioTag = unsafeStatic(noRatioTagName);
9
18
  const imageURL = 'tests/components/image/images/150.png';
10
19
  const thumbURL = 'tests/components/image/images/15.png';
11
20
 
@@ -21,6 +30,8 @@ const awaitFailed = () => {
21
30
  });
22
31
  };
23
32
 
33
+ const itSkipSafari = /WebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) ? it.skip : it;
34
+
24
35
  describe('image', () => {
25
36
 
26
37
  afterEach(() => {
@@ -106,6 +117,27 @@ describe('image', () => {
106
117
  expect(elementImage).to.not.be.null; // eslint-disable-line no-unused-expressions
107
118
  expect(img).to.be.null; // eslint-disable-line no-unused-expressions
108
119
  expect(el.type).to.equal('standard', '`type` property has default value `standard`');
120
+ expect(el.ratio).to.equal('16 / 9', '`ratio` has default token value');
121
+ expect(Array.from(holder.classList)).to.deep.equal(['image-holder', 'blur-out']);
122
+ expect(getComputedStyle(holder).backgroundImage).to.include(imageURL, 'computed style value added for background image');
123
+ expect(holder.style.getPropertyValue('--background-image')).to.include(imageURL, 'image passed as custom css variable');
124
+ });
125
+
126
+ it('implements background ratio fallback', async () => {
127
+ const el = await fixture(html`<${noRatioTag} src="${imageURL}" background></${noRatioTag}>`);
128
+
129
+ await awaitLoading(el);
130
+ await defaultChecks(el);
131
+
132
+ const shadowRoot = el.shadowRoot;
133
+ const elementImage = shadowRoot.querySelector('.image');
134
+ const img = elementImage.querySelector('img');
135
+ const holder = elementImage.querySelector('.image-holder');
136
+
137
+ expect(elementImage).to.not.be.null; // eslint-disable-line no-unused-expressions
138
+ expect(img).to.be.null; // eslint-disable-line no-unused-expressions
139
+ expect(el.type).to.equal('standard', '`type` property has default value `standard`');
140
+ expect(el.ratio).to.equal('16 / 9', '`ratio` has default token value');
109
141
  expect(Array.from(holder.classList)).to.deep.equal(['image-holder', 'blur-out']);
110
142
  expect(getComputedStyle(holder).backgroundImage).to.include(imageURL, 'computed style value added for background image');
111
143
  expect(holder.style.getPropertyValue('--background-image')).to.include(imageURL, 'image passed as custom css variable');
@@ -285,30 +317,33 @@ describe('image', () => {
285
317
  expect(consoleError.args[0]).to.deep.equal(['Image (this-is-not-an-image) failed to load']);
286
318
  });
287
319
 
288
- it('implements placeholder image for chrome', async () => {
289
- if (window.chrome === true) {
290
- const el = await fixture(html`<${tag} src="https://via.placeholder.com/35000" placeholder="${thumbURL}"></${tag}>`);
291
-
292
- await nextFrame();
293
- await defaultChecks(el);
294
-
295
- const shadowRoot = el.shadowRoot;
296
- const elementImage = shadowRoot.querySelector('.image');
297
- const img = elementImage.querySelector('img');
298
-
299
- expect(elementImage).to.not.be.null; // eslint-disable-line no-unused-expressions
300
- expect(el.type).to.equal('standard', '`type` property has default value `standard`');
301
- expect(el.ratio).to.equal('16 / 9', '`ratio` has default token value');
302
- expect(img.src).to.equal(thumbURL, 'has `src` value from el');
303
- expect(img.alt).to.equal('', 'alt has not value');
304
- expect(img.loading).to.equal('lazy', 'loading has a value');
305
- expect(Array.from(img.classList)).to.deep.equal(['image-lazy', 'blur']);
306
-
307
- if (CSS.supports('aspect-ratio', '1 / 1')) {
308
- expect(elementImage.style.getPropertyValue('--image-ratio')).to.equal('16 / 9', 'ratio passed as custom css variable');
309
- expect(getComputedStyle(elementImage).aspectRatio).to.equal('16 / 9', 'computed style value added for aspect-ratio');
310
- }
320
+ itSkipSafari('implements placeholder image for chrome', async () => {
321
+ const windowChromeInitial = window?.chrome;
322
+ window.chrome = true;
323
+
324
+ const el = await fixture(html`<${tag} src="https://via.placeholder.com/35000" placeholder="${thumbURL}"></${tag}>`);
325
+
326
+ await nextFrame();
327
+ await defaultChecks(el);
328
+
329
+ const shadowRoot = el.shadowRoot;
330
+ const elementImage = shadowRoot.querySelector('.image');
331
+ const img = elementImage.querySelector('img');
332
+
333
+ expect(elementImage).to.not.be.null; // eslint-disable-line no-unused-expressions
334
+ expect(el.type).to.equal('standard', '`type` property has default value `standard`');
335
+ expect(el.ratio).to.equal('16 / 9', '`ratio` has default token value');
336
+ expect(img.src).to.include(thumbURL, 'has `src` value from el');
337
+ expect(img.alt).to.equal('', 'alt has not value');
338
+ expect(img.loading).to.equal('lazy', 'loading has a value');
339
+ expect(Array.from(img.classList)).to.deep.equal(['image-lazy', 'blur']);
340
+
341
+ if (CSS.supports('aspect-ratio', '1 / 1')) {
342
+ expect(elementImage.style.getPropertyValue('--image-ratio')).to.equal('16 / 9', 'ratio passed as custom css variable');
343
+ expect(getComputedStyle(elementImage).aspectRatio).to.equal('16 / 9', 'computed style value added for aspect-ratio');
311
344
  }
345
+
346
+ window.chrome = windowChromeInitial;
312
347
  });
313
348
 
314
349
  });
@@ -2,7 +2,7 @@ import { expect } from '@open-wc/testing';
2
2
  import { executeServerCommand } from '@web/test-runner-commands';
3
3
 
4
4
  export const defaultChecks = async (el, options = {}) => {
5
- const { ignoredRules, ignoredTags, ignoredAccessibilityTags } = options || {};
5
+ const { ignoredRules, ignoredTags, ignoredAccessibilityTags } = options;
6
6
  const ignoredAttributes = options.ignoredAttributes || [];
7
7
  const snapshotOptions = await executeServerCommand('run-snapshots');
8
8
  if (snapshotOptions?.run === true) {
@@ -25,12 +25,39 @@ const ParentMuonComponent = class extends ScopedElementsMixin(MuonElement) {
25
25
  }
26
26
  };
27
27
 
28
+ const EmptyMuonComponent = class extends MuonElement {
29
+ };
30
+
31
+ const MultipleScopedStyles = class extends MuonElement {
32
+ get slottedStyles() {
33
+ return [
34
+ 'light-dom{color:red}',
35
+ 'light-dom{background:blue}'
36
+ ];
37
+ }
38
+ };
39
+
40
+ const BrokenScopedStyles = class extends MuonElement {
41
+ get slottedStyles() {
42
+ return [true];
43
+ }
44
+ };
45
+
28
46
  const tagName = defineCE(MuonComponent);
29
47
  const tag = unsafeStatic(tagName);
30
48
 
31
49
  const parentTagName = defineCE(ParentMuonComponent);
32
50
  const parentTag = unsafeStatic(parentTagName);
33
51
 
52
+ const emptyTagName = defineCE(EmptyMuonComponent);
53
+ const emptyTag = unsafeStatic(emptyTagName);
54
+
55
+ const multipleScopedStylesTagName = defineCE(MultipleScopedStyles);
56
+ const multipleScopedStylesTag = unsafeStatic(multipleScopedStylesTagName);
57
+
58
+ const brokenScopedStylesTagName = defineCE(BrokenScopedStyles);
59
+ const brokenScopedStylesTag = unsafeStatic(brokenScopedStylesTagName);
60
+
34
61
  describe('muon-component', () => {
35
62
  it('standard', async () => {
36
63
  const element = await fixture(html`<${tag}>foo</${tag}>`);
@@ -46,4 +73,25 @@ describe('muon-component', () => {
46
73
 
47
74
  expect(getComputedStyle(childEl).color).to.equal('rgb(255, 0, 0)', 'computed style value added for child shadow component');
48
75
  });
76
+
77
+ it('empty', async () => {
78
+ const element = await fixture(html`<${emptyTag}></${emptyTag}>`);
79
+
80
+ expect(getComputedStyle(element).color).to.equal('rgb(0, 0, 0)', 'computed style value added for empty component');
81
+ expect(element.shadowRoot.textContent).to.equal('');
82
+ });
83
+
84
+ it('multiple scoped styles', async () => {
85
+ const element = await fixture(html`<${multipleScopedStylesTag}></${multipleScopedStylesTag}>`);
86
+
87
+ expect(getComputedStyle(element).color).to.include('rgb(255, 0, 0)', 'computed style value added for component');
88
+ expect(getComputedStyle(element).background).to.include('rgb(0, 0, 255)', 'computed style value added for component');
89
+ });
90
+
91
+ it('broken scoped styles', async () => {
92
+ const element = await fixture(html`<${brokenScopedStylesTag}></${brokenScopedStylesTag}>`);
93
+
94
+ expect(getComputedStyle(element).color).to.equal('rgb(0, 0, 0)', 'computed style value added for component');
95
+ expect(element.__addLightDOM()).to.equal(undefined, 'no styles added');
96
+ });
49
97
  });
@@ -210,8 +210,11 @@ testRunner('sourceFilesAnalyzer', async (t) => {
210
210
  t.deepEqual(jsonResult.tags?.map((tag) => tag.name).sort(), components.sort());
211
211
 
212
212
  components.forEach((component) => {
213
- t.deepEqual(jsonResult.tags.filter((tag) => tag.name === component)[0].properties?.map(
214
- (property) => property.name), propertiesMap[component], component);
213
+ t.deepEqual(
214
+ jsonResult.tags
215
+ .filter((tag) => tag.name === component)[0].properties?.map(
216
+ (property) => property.name).sort(), propertiesMap[component].sort(), component
217
+ );
215
218
  });
216
219
  jsonResult.tags?.map((tag) => {
217
220
  t.true(tag.description !== undefined, `${tag.name} description is not present`);
@@ -237,8 +240,11 @@ testRunner('sourceFilesAnalyzer with prefix override', async (t) => {
237
240
  t.deepEqual(jsonResult.tags?.map((tag) => tag.name).sort(), components.sort());
238
241
 
239
242
  components.forEach((component) => {
240
- t.deepEqual(jsonResult.tags.filter((tag) => tag.name === component)[0].properties?.map(
241
- (property) => property.name), propertiesMap[component], component);
243
+ t.deepEqual(
244
+ jsonResult.tags
245
+ .filter((tag) => tag.name === component)[0].properties?.map(
246
+ (property) => property.name).sort(), propertiesMap[component].sort(), component
247
+ );
242
248
  });
243
249
  jsonResult.tags?.map((tag) => {
244
250
  t.true(tag.description !== undefined, `${tag.name} description is not present`);
@@ -293,13 +299,16 @@ testRunner('sourceFilesAnalyzer single file', async (t) => {
293
299
 
294
300
  const components = ['muon-card'];
295
301
  const propertiesMap = {
296
- 'muon-card': ['classes', 'inlineStyles', 'standardTemplate', 'image', 'alt', 'background', 'type'],
302
+ 'muon-card': ['classes', 'inlineStyles', 'standardTemplate', 'image', 'alt', 'background', 'type']
297
303
  };
298
304
  t.deepEqual(jsonResult.tags?.map((tag) => tag.name), components);
299
305
 
300
306
  components.forEach((component) => {
301
- t.deepEqual(jsonResult.tags.filter((tag) => tag.name === component)[0].properties?.map(
302
- (property) => property.name), propertiesMap[component], component);
307
+ t.deepEqual(
308
+ jsonResult.tags
309
+ .filter((tag) => tag.name === component)[0].properties?.map(
310
+ (property) => property.name).sort(), propertiesMap[component].sort(), component
311
+ );
303
312
  });
304
313
  jsonResult.tags?.map((tag) => {
305
314
  t.true(tag.description !== undefined, `${tag.name} description is not present`);