@justeattakeaway/pie-webc-core 15.0.0 → 15.0.1

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/dist/index.js CHANGED
@@ -1,45 +1,49 @@
1
- import { customElement as a } from "lit/decorators.js";
2
- const d = (t, e, s) => function(r, i) {
3
- const o = `#${i}`;
4
- Object.defineProperty(r, i, {
1
+ import { customElement as d } from "lit/decorators.js";
2
+ const b = (t, e, s) => function(i, r) {
3
+ const o = `#${r}`;
4
+ Object.defineProperty(i, r, {
5
5
  get() {
6
6
  return this[o];
7
7
  },
8
8
  set(c) {
9
9
  e.includes(c) ? this[o] = c : (console.error(
10
- `<${t}> Invalid value "${c}" provided for property "${i}".`,
10
+ `<${t}> Invalid value "${c}" provided for property "${r}".`,
11
11
  `Must be one of: ${e.join(" | ")}.`,
12
12
  `Falling back to default value: "${s}"`
13
13
  ), this[o] = s);
14
14
  },
15
15
  configurable: !0
16
16
  });
17
- }, l = (t) => function(s, n) {
18
- const r = `#${n}`;
17
+ }, l = (t) => t == null || typeof t == "string" && t.trim() === "", f = (t) => function(s, n) {
18
+ const i = `#${n}`, r = `#${n}HasBeenSet`, o = `#${n}HasWarned`;
19
19
  Object.defineProperty(s, n, {
20
20
  get() {
21
- return this[r];
21
+ return this[i];
22
22
  },
23
- set(i) {
24
- (i == null || typeof i == "string" && i.trim() === "") && console.error(`<${t}> Missing required attribute "${n}"`), this[r] = i;
23
+ set(u) {
24
+ this[r] = !0, l(u) && console.error(`<${t}> Missing required attribute "${n}"`), this[i] = u;
25
25
  },
26
26
  configurable: !0
27
27
  });
28
+ const c = s, a = c.connectedCallback;
29
+ c.connectedCallback = function() {
30
+ a == null || a.call(this), !this[r] && !this[o] && (this[o] = !0, console.error(`<${t}> Missing required attribute "${n}"`));
31
+ };
28
32
  };
29
- function h(t) {
33
+ function m(t) {
30
34
  return (e) => {
31
35
  try {
32
- a(t)(e);
36
+ d(t)(e);
33
37
  } catch (s) {
34
- const n = customElements.get(t), r = n == null ? void 0 : n.v;
35
- e.v !== r && console.warn(
36
- `PIE Web Component: "${t}" was already registered with version: ${r ?? "No version data found. Icon components do not contain version data. If the component is not an icon, please report the missing version data."}.`,
38
+ const n = customElements.get(t), i = n == null ? void 0 : n.v;
39
+ e.v !== i && console.warn(
40
+ `PIE Web Component: "${t}" was already registered with version: ${i ?? "No version data found. Icon components do not contain version data. If the component is not an icon, please report the missing version data."}.`,
37
41
  s
38
42
  );
39
43
  }
40
44
  };
41
45
  }
42
- function b(t) {
46
+ function v(t) {
43
47
  return new CustomEvent(t.type, {
44
48
  detail: {
45
49
  sourceEvent: t
@@ -48,7 +52,7 @@ function b(t) {
48
52
  cancelable: t.cancelable
49
53
  });
50
54
  }
51
- function p(t, e, s) {
55
+ function g(t, e, s) {
52
56
  e.startsWith("pie-") || console.warn("A custom event name should start with `pie-`");
53
57
  const n = new CustomEvent(e, {
54
58
  bubbles: !0,
@@ -57,7 +61,7 @@ function p(t, e, s) {
57
61
  });
58
62
  t.dispatchEvent(n);
59
63
  }
60
- const m = (t) => {
64
+ const p = (t) => {
61
65
  class e extends t {
62
66
  constructor() {
63
67
  super(...arguments), this._isRTL = !1, this.observer = null;
@@ -89,20 +93,20 @@ const m = (t) => {
89
93
  }
90
94
  }
91
95
  return e;
92
- }, f = (t) => {
96
+ }, $ = (t) => {
93
97
  const s = class s extends t {
94
98
  get form() {
95
99
  return this._internals.form;
96
100
  }
97
101
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
- constructor(...r) {
99
- super(...r), this._internals = this.attachInternals();
102
+ constructor(...i) {
103
+ super(...i), this._internals = this.attachInternals();
100
104
  }
101
105
  };
102
106
  s.formAssociated = !0;
103
107
  let e = s;
104
108
  return e;
105
- }, v = (t) => {
109
+ }, w = (t) => {
106
110
  const s = class s extends t {
107
111
  };
108
112
  s.shadowRootOptions = {
@@ -117,12 +121,12 @@ const m = (t) => {
117
121
  return e;
118
122
  };
119
123
  export {
120
- v as DelegatesFocusMixin,
121
- f as FormControlMixin,
122
- m as RtlMixin,
123
- p as dispatchCustomEvent,
124
- l as requiredProperty,
125
- h as safeCustomElement,
126
- d as validPropertyValues,
127
- b as wrapNativeEvent
124
+ w as DelegatesFocusMixin,
125
+ $ as FormControlMixin,
126
+ p as RtlMixin,
127
+ g as dispatchCustomEvent,
128
+ f as requiredProperty,
129
+ m as safeCustomElement,
130
+ b as validPropertyValues,
131
+ v as wrapNativeEvent
128
132
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-webc-core",
3
- "version": "15.0.0",
3
+ "version": "15.0.1",
4
4
  "description": "PIE design system base classes, mixins and utilities for web components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,21 +1,46 @@
1
+ const isMissing = <T>(value: T): boolean => value === undefined || value === null || (typeof value === 'string' && value.trim() === '');
2
+
1
3
  /**
2
4
  * A decorator for marking a property as required.
3
5
  * If the property's value is `undefined`, `null` or empty string, an error is logged.
6
+ *
7
+ * This also checks on `connectedCallback` so a missing required property is still reported
8
+ * even when the corresponding attribute is never set at all (in which case the property
9
+ * setter below is never invoked).
4
10
  * @returns {Function} - The decorator function.
5
11
  */
6
12
  export const requiredProperty = <T>(componentName: string) => function validateRequiredProperty (target: object, propertyKey: string): void {
7
13
  const privatePropertyKey = `#${propertyKey}`;
14
+ const hasBeenSetKey = `#${propertyKey}HasBeenSet`;
15
+ const hasWarnedKey = `#${propertyKey}HasWarned`;
8
16
 
9
17
  Object.defineProperty(target, propertyKey, {
10
18
  get (): T {
11
19
  return this[privatePropertyKey];
12
20
  },
13
21
  set (value: T): void {
14
- if (value === undefined || value === null || (typeof value === 'string' && value.trim() === '')) {
22
+ this[hasBeenSetKey] = true;
23
+
24
+ if (isMissing(value)) {
15
25
  console.error(`<${componentName}> Missing required attribute "${propertyKey}"`);
16
26
  }
17
27
  this[privatePropertyKey] = value;
18
28
  },
19
29
  configurable: true,
20
30
  });
31
+
32
+ const elementProto = target as { connectedCallback?: (this: Record<string, unknown>) => void };
33
+ const originalConnectedCallback = elementProto.connectedCallback;
34
+
35
+ elementProto.connectedCallback = function connectedCallback (this: Record<string, unknown>): void {
36
+ originalConnectedCallback?.call(this);
37
+
38
+ // Guard with a dedicated "has warned" flag (rather than reusing hasBeenSetKey) so an
39
+ // element that reconnects repeatedly while still missing the prop (e.g. a virtualised
40
+ // list recycling DOM nodes) only logs once, instead of on every reconnect.
41
+ if (!this[hasBeenSetKey] && !this[hasWarnedKey]) {
42
+ this[hasWarnedKey] = true;
43
+ console.error(`<${componentName}> Missing required attribute "${propertyKey}"`);
44
+ }
45
+ };
21
46
  };