@htmlplus/element 2.6.0 → 2.8.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/README.md CHANGED
@@ -142,6 +142,11 @@ In the `index.html` file.
142
142
 
143
143
  </details>
144
144
 
145
+ <details>
146
+ <summary>Consumer</summary>
147
+ TODO
148
+ </details>
149
+
145
150
  <details>
146
151
  <summary>Direction</summary>
147
152
 
@@ -468,6 +473,11 @@ Parameters:
468
473
  The configuration for property decorator.
469
474
  <br />
470
475
  <br />
476
+ - `attribute` (Optional)
477
+ <br />
478
+ Specifies the name of the attribute related to the property.
479
+ <br />
480
+ <br />
471
481
  - `reflect` (Optional)
472
482
  <br />
473
483
  Whether property value is reflected back to the associated attribute. default is `false`.
@@ -475,7 +485,7 @@ Parameters:
475
485
  <br />
476
486
  - `type` (Optional)
477
487
  <br />
478
- Do not set the value to this property. This value is automatically set during transforming.
488
+ Specifies the property `type` and supports [data types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures). If this value is not set, it will be set automatically during transforming.
479
489
  <br />
480
490
  <br />
481
491
 
@@ -503,6 +513,11 @@ In the `index.html` file.
503
513
 
504
514
  </details>
505
515
 
516
+ <details>
517
+ <summary>Provider</summary>
518
+ TODO
519
+ </details>
520
+
506
521
  <details>
507
522
  <summary>Query</summary>
508
523
 
@@ -758,6 +773,13 @@ TODO
758
773
 
759
774
  </details>
760
775
 
776
+ <details>
777
+ <summary>dispatch</summary>
778
+
779
+ TODO
780
+
781
+ </details>
782
+
761
783
  <details>
762
784
  <summary>host</summary>
763
785
 
@@ -835,15 +857,6 @@ TODO
835
857
 
836
858
  </details>
837
859
 
838
- <details>
839
- <summary>styles</summary>
840
-
841
- Converts a JavaScript object containing CSS styles to a CSS string.
842
-
843
- TODO
844
-
845
- </details>
846
-
847
860
  <details>
848
861
  <summary>toUnit</summary>
849
862
 
@@ -882,13 +895,6 @@ TODO
882
895
 
883
896
  </details>
884
897
 
885
- <details>
886
- <summary>connectCallback</summary>
887
-
888
- TODO
889
-
890
- </details>
891
-
892
898
  <details>
893
899
  <summary>connectedCallback</summary>
894
900
 
@@ -13,7 +13,12 @@ export function Element() {
13
13
  const tag = getTag(constructor);
14
14
  if (customElements.get(tag))
15
15
  return;
16
- class Plus extends HTMLElement {
16
+ customElements.define(tag, proxy(constructor));
17
+ };
18
+ }
19
+ const proxy = (constructor) => {
20
+ var _a;
21
+ return _a = class Plus extends HTMLElement {
17
22
  constructor() {
18
23
  super();
19
24
  this.attachShadow({
@@ -29,12 +34,15 @@ export function Element() {
29
34
  adoptedCallback() {
30
35
  call(this[CONSTANTS.API_INSTANCE], CONSTANTS.LIFECYCLE_ADOPTED);
31
36
  }
32
- attributeChangedCallback(attribute, prev, next) {
37
+ attributeChangedCallback(key, prev, next) {
38
+ var _a;
33
39
  // ensures the integrity of readonly properties to prevent potential errors.
34
40
  try {
35
- this[camelCase(attribute)] = next;
41
+ const attribute = (_a = constructor[CONSTANTS.MAPPER]) === null || _a === void 0 ? void 0 : _a[key];
42
+ const property = attribute || camelCase(key);
43
+ this[property] = next;
36
44
  }
37
- catch (_a) { }
45
+ catch (_b) { }
38
46
  }
39
47
  connectedCallback() {
40
48
  const instance = this[CONSTANTS.API_INSTANCE];
@@ -54,11 +62,10 @@ export function Element() {
54
62
  disconnectedCallback() {
55
63
  call(this[CONSTANTS.API_INSTANCE], CONSTANTS.LIFECYCLE_DISCONNECTED);
56
64
  }
57
- }
65
+ },
58
66
  // TODO
59
- Plus.formAssociated = constructor['formAssociated'];
67
+ _a.formAssociated = constructor['formAssociated'],
60
68
  // TODO
61
- Plus.observedAttributes = constructor['observedAttributes'];
62
- customElements.define(tag, Plus);
63
- };
64
- }
69
+ _a.observedAttributes = constructor['observedAttributes'],
70
+ _a;
71
+ };
@@ -3,14 +3,20 @@ import { HTMLPlusElement } from '../../types';
3
3
  * The configuration for property decorator.
4
4
  */
5
5
  export interface PropertyOptions {
6
+ /**
7
+ * Specifies the name of the attribute related to the property.
8
+ */
9
+ attribute?: string;
6
10
  /**
7
11
  * Whether property value is reflected back to the associated attribute. default is `false`.
8
12
  */
9
13
  reflect?: boolean;
10
14
  /**
11
- * Do not set the value to this property. This value is automatically set during transforming.
15
+ * Specifies the property `type` and supports
16
+ * [data types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures).
17
+ * If this value is not set, it will be set automatically during transforming.
12
18
  */
13
- type?: number;
19
+ type?: any;
14
20
  }
15
21
  /**
16
22
  * Creates a reactive property, reflecting a corresponding attribute value,
@@ -7,11 +7,22 @@ import { appendToMethod, defineProperty, host, request, toProperty, updateAttrib
7
7
  */
8
8
  export function Property(options) {
9
9
  return function (target, key, descriptor) {
10
- var _a;
10
+ var _a, _b, _c;
11
+ // Creates a unique symbol for the lock flag.
12
+ const locked = Symbol();
11
13
  // Converts property name to string.
12
14
  const name = String(key);
15
+ // Calculates attribute.
16
+ const attribute = (options === null || options === void 0 ? void 0 : options.attribute) || kebabCase(name);
13
17
  // Registers an attribute that is intricately linked to the property.
14
- ((_a = target.constructor)['observedAttributes'] || (_a['observedAttributes'] = [])).push(kebabCase(name));
18
+ ((_a = target.constructor)['observedAttributes'] || (_a['observedAttributes'] = [])).push(attribute);
19
+ // TODO
20
+ if (attribute) {
21
+ // TODO
22
+ (_b = target.constructor)[_c = CONSTANTS.MAPPER] || (_b[_c] = {});
23
+ // TODO
24
+ target.constructor[CONSTANTS.MAPPER][attribute] = name;
25
+ }
15
26
  // TODO: This feature is an experimental
16
27
  // When the property is a getter function.
17
28
  if (descriptor) {
@@ -22,15 +33,15 @@ export function Property(options) {
22
33
  // Defines a new getter function.
23
34
  descriptor.get = function () {
24
35
  const value = getter === null || getter === void 0 ? void 0 : getter.apply(this);
25
- this[CONSTANTS.API_LOCKED] = true;
26
- updateAttribute(this, name, value);
27
- this[CONSTANTS.API_LOCKED] = false;
36
+ this[locked] = true;
37
+ updateAttribute(this, attribute, value);
38
+ this[locked] = false;
28
39
  return value;
29
40
  };
30
41
  // TODO: Check the lifecycle
31
42
  appendToMethod(target, CONSTANTS.LIFECYCLE_UPDATED, function () {
32
43
  // Calls the getter function to update the related attribute.
33
- this[name];
44
+ this[key];
34
45
  });
35
46
  }
36
47
  }
@@ -53,9 +64,9 @@ export function Property(options) {
53
64
  return;
54
65
  if (!(options === null || options === void 0 ? void 0 : options.reflect))
55
66
  return;
56
- this[CONSTANTS.API_LOCKED] = true;
57
- updateAttribute(this, name, next);
58
- this[CONSTANTS.API_LOCKED] = false;
67
+ this[locked] = true;
68
+ updateAttribute(this, attribute, next);
69
+ this[locked] = false;
59
70
  });
60
71
  }
61
72
  // Attaches the getter and setter functions to the current property of the target class.
@@ -71,7 +82,7 @@ export function Property(options) {
71
82
  const set = descriptor
72
83
  ? undefined
73
84
  : (input) => {
74
- if (this[CONSTANTS.API_LOCKED]) {
85
+ if (this[locked]) {
75
86
  return;
76
87
  }
77
88
  this[key] = toProperty(input, options === null || options === void 0 ? void 0 : options.type);
@@ -1 +1 @@
1
- export declare const toProperty: (input: any, type: number | undefined) => any;
1
+ export declare const toProperty: (input: any, type?: any) => any;
@@ -4,7 +4,7 @@ export const toProperty = (input, type) => {
4
4
  if (type === undefined)
5
5
  return input;
6
6
  const string = `${input}`;
7
- if (CONSTANTS.TYPE_BOOLEAN & type) {
7
+ if (CONSTANTS.TYPE_BOOLEAN & type || type === Boolean) {
8
8
  if (string === '')
9
9
  return true;
10
10
  if (string === 'true')
@@ -12,23 +12,23 @@ export const toProperty = (input, type) => {
12
12
  if (string === 'false')
13
13
  return false;
14
14
  }
15
- if (CONSTANTS.TYPE_NUMBER & type) {
15
+ if (CONSTANTS.TYPE_NUMBER & type || type === Number) {
16
16
  if (string != '' && !isNaN(input)) {
17
17
  return parseFloat(input);
18
18
  }
19
19
  }
20
- if (CONSTANTS.TYPE_NULL & type) {
20
+ if (CONSTANTS.TYPE_NULL & type || type === null) {
21
21
  if (string === 'null') {
22
22
  return null;
23
23
  }
24
24
  }
25
- if (CONSTANTS.TYPE_DATE & type) {
25
+ if (CONSTANTS.TYPE_DATE & type || type === Date) {
26
26
  const value = new Date(input);
27
27
  if (value.toString() != 'Invalid Date') {
28
28
  return value;
29
29
  }
30
30
  }
31
- if (CONSTANTS.TYPE_ARRAY & type) {
31
+ if (CONSTANTS.TYPE_ARRAY & type || type === Array) {
32
32
  try {
33
33
  const value = JSON.parse(input);
34
34
  if (typeOf(value) == 'array') {
@@ -37,7 +37,7 @@ export const toProperty = (input, type) => {
37
37
  }
38
38
  catch (_a) { }
39
39
  }
40
- if (CONSTANTS.TYPE_OBJECT & type) {
40
+ if (CONSTANTS.TYPE_OBJECT & type || type === Object) {
41
41
  try {
42
42
  const value = JSON.parse(input);
43
43
  if (typeOf(value) == 'object') {
@@ -46,7 +46,7 @@ export const toProperty = (input, type) => {
46
46
  }
47
47
  catch (_b) { }
48
48
  }
49
- if (CONSTANTS.TYPE_UNDEFINED & type) {
49
+ if (CONSTANTS.TYPE_UNDEFINED & type || type === undefined) {
50
50
  if (string === 'undefined') {
51
51
  return undefined;
52
52
  }
@@ -1,8 +1,8 @@
1
1
  export declare const PACKAGE_NAME = "@htmlplus/element";
2
+ export declare const MAPPER: unique symbol;
2
3
  export declare const API_CONNECTED: unique symbol;
3
4
  export declare const API_HOST: unique symbol;
4
5
  export declare const API_INSTANCE: unique symbol;
5
- export declare const API_LOCKED: unique symbol;
6
6
  export declare const API_REQUEST: unique symbol;
7
7
  export declare const API_RENDER_COMPLETED: unique symbol;
8
8
  export declare const API_STACKS: unique symbol;
@@ -1,9 +1,10 @@
1
1
  export const PACKAGE_NAME = '@htmlplus/element';
2
+ // TODO
3
+ export const MAPPER = Symbol();
2
4
  // APIs
3
5
  export const API_CONNECTED = Symbol();
4
6
  export const API_HOST = Symbol();
5
7
  export const API_INSTANCE = Symbol();
6
- export const API_LOCKED = Symbol();
7
8
  export const API_REQUEST = Symbol();
8
9
  export const API_RENDER_COMPLETED = Symbol();
9
10
  export const API_STACKS = Symbol();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htmlplus/element",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "author": "Masood Abdolian <m.abdolian@gmail.com>",
@@ -2,7 +2,7 @@ import template from '@babel/template';
2
2
  import t from '@babel/types';
3
3
  import { camelCase, kebabCase, pascalCase } from 'change-case';
4
4
  import * as CONSTANTS from '../../constants/index.js';
5
- import { addDependency, getType, print, visitor } from '../utils/index.js';
5
+ import { addDependency, extractAttribute, getType, print, visitor } from '../utils/index.js';
6
6
  export const CUSTOM_ELEMENT_OPTIONS = {
7
7
  prefix: undefined,
8
8
  typings: true
@@ -185,6 +185,16 @@ export const customElement = (options) => {
185
185
  const { expression } = path.node;
186
186
  if (((_a = expression.callee) === null || _a === void 0 ? void 0 : _a.name) != CONSTANTS.DECORATOR_PROPERTY)
187
187
  return;
188
+ if (!expression.arguments.length) {
189
+ expression.arguments.push(t.objectExpression([]));
190
+ }
191
+ const [argument] = expression.arguments;
192
+ const filtered = argument.properties.filter((property) => {
193
+ return property.key.name != CONSTANTS.DECORATOR_PROPERTY_TYPE;
194
+ });
195
+ if (argument.properties.length != filtered.length)
196
+ return;
197
+ argument.properties = filtered;
188
198
  let type = 0;
189
199
  const extract = (input) => {
190
200
  var _a;
@@ -266,13 +276,6 @@ export const customElement = (options) => {
266
276
  }
267
277
  };
268
278
  extract(getType(context.directoryPath, ast, (_b = path.parentPath.node.typeAnnotation) === null || _b === void 0 ? void 0 : _b.typeAnnotation));
269
- if (!expression.arguments.length) {
270
- expression.arguments.push(t.objectExpression([]));
271
- }
272
- const [argument] = expression.arguments;
273
- argument.properties = argument.properties.filter((property) => {
274
- return property.key.name != CONSTANTS.DECORATOR_PROPERTY_TYPE;
275
- });
276
279
  argument.properties.push(t.objectProperty(t.identifier(CONSTANTS.DECORATOR_PROPERTY_TYPE), t.numericLiteral(type)));
277
280
  }
278
281
  });
@@ -280,10 +283,12 @@ export const customElement = (options) => {
280
283
  if (options.typings) {
281
284
  visitor(ast, {
282
285
  Program(path) {
283
- const attributes = context.classProperties.map((property) => {
284
- const key = property.key;
286
+ const attributes = context
287
+ .classProperties.filter((property) => !t.isClassMethod(property))
288
+ .map((property) => {
289
+ const key = extractAttribute(property) || kebabCase(property.key['name']);
285
290
  const typeAnnotation = property.typeAnnotation;
286
- return Object.assign(t.tSPropertySignature(t.stringLiteral(kebabCase(key.name)), typeAnnotation), {
291
+ return Object.assign(t.tSPropertySignature(t.stringLiteral(kebabCase(key)), typeAnnotation), {
287
292
  optional: property.optional,
288
293
  leadingComments: t.cloneNode(property, true).leadingComments
289
294
  });
@@ -310,8 +315,13 @@ export const customElement = (options) => {
310
315
  });
311
316
  const properties = context.classProperties.map((property) => {
312
317
  const key = property.key;
313
- const typeAnnotation = property.typeAnnotation;
314
- return Object.assign(t.tSPropertySignature(t.identifier(key.name), typeAnnotation), {
318
+ // TODO
319
+ const readonly = property.readonly || !!property['returnType'];
320
+ // TODO
321
+ const typeAnnotation = (property.typeAnnotation ||
322
+ property['returnType']);
323
+ return Object.assign(t.tsPropertySignature(t.identifier(key.name), typeAnnotation), {
324
+ readonly,
315
325
  optional: property.optional,
316
326
  leadingComments: t.cloneNode(property, true).leadingComments
317
327
  });
@@ -3,7 +3,7 @@ import fs from 'fs-extra';
3
3
  import { glob } from 'glob';
4
4
  import path from 'path';
5
5
  import * as CONSTANTS from '../../constants/index.js';
6
- import { extractFromComment, getInitializer, getTypeReference, print } from '../utils/index.js';
6
+ import { extractAttribute, extractFromComment, getInitializer, getTypeReference, print } from '../utils/index.js';
7
7
  export const DOCUMENT_OPTIONS = {
8
8
  destination: path.join('dist', 'document.json')
9
9
  };
@@ -117,7 +117,7 @@ export const document = (options) => {
117
117
  });
118
118
  const properties = context.classProperties.map((property) => {
119
119
  var _a, _b, _c;
120
- const attribute = kebabCase(property.key['name']);
120
+ const attribute = extractAttribute(property) || kebabCase(property.key['name']);
121
121
  // TODO
122
122
  const initializer = getInitializer(property.value);
123
123
  const name = property.key['name'];
@@ -1,7 +1,7 @@
1
1
  import { kebabCase } from 'change-case';
2
2
  import fs from 'fs-extra';
3
3
  import path from 'path';
4
- import { extractFromComment, getType, print } from '../utils/index.js';
4
+ import { extractAttribute, extractFromComment, getType, print } from '../utils/index.js';
5
5
  export const VISUAL_STUDIO_CODE_OPTIONS = {
6
6
  destination: path.join('dist', 'visual-studio-code.json')
7
7
  };
@@ -31,7 +31,7 @@ export const visualStudioCode = (options) => {
31
31
  }, extractFromComment(context.class, ['description']));
32
32
  for (const property of context.classProperties || []) {
33
33
  const attribute = Object.assign({
34
- name: kebabCase(property.key['name']),
34
+ name: extractAttribute(property) || kebabCase(property.key['name']),
35
35
  values: []
36
36
  }, extractFromComment(property, ['description']));
37
37
  const type = print(getType(context.directoryPath, context.fileAST, (_c = property.typeAnnotation) === null || _c === void 0 ? void 0 : _c['typeAnnotation']));
@@ -1,7 +1,7 @@
1
1
  import { kebabCase } from 'change-case';
2
2
  import fs from 'fs-extra';
3
3
  import path from 'path';
4
- import { extractFromComment, getInitializer, getType, print } from '../utils/index.js';
4
+ import { extractAttribute, extractFromComment, getInitializer, getType, print } from '../utils/index.js';
5
5
  export const WEB_TYPES_OPTIONS = {
6
6
  destination: path.join('dist', 'web-types.json'),
7
7
  packageName: '',
@@ -35,7 +35,7 @@ export const webTypes = (options) => {
35
35
  const attributes = (_a = context.classProperties) === null || _a === void 0 ? void 0 : _a.map((property) => {
36
36
  var _a;
37
37
  return Object.assign({
38
- name: kebabCase(property.key['name']),
38
+ name: extractAttribute(property) || kebabCase(property.key['name']),
39
39
  value: {
40
40
  // kind: TODO
41
41
  type: print(getType(context.directoryPath, context.fileAST, (_a = property.typeAnnotation) === null || _a === void 0 ? void 0 : _a['typeAnnotation']))
@@ -0,0 +1,2 @@
1
+ import t from '@babel/types';
2
+ export declare const extractAttribute: (property: t.ClassProperty) => string | undefined;
@@ -0,0 +1,10 @@
1
+ import * as CONSTANTS from '../../constants/index.js';
2
+ export const extractAttribute = (property) => {
3
+ try {
4
+ return property.decorators
5
+ .find((decorator) => decorator.expression.callee.name == CONSTANTS.DECORATOR_PROPERTY)
6
+ .expression.arguments[0].properties.find((property) => property.key.name == 'attribute').value
7
+ .value;
8
+ }
9
+ catch (_a) { }
10
+ };
@@ -1,4 +1,5 @@
1
1
  export * from './addDependency.js';
2
+ export * from './extractAttribute.js';
2
3
  export * from './extractFromComment.js';
3
4
  export * from './getInitializer.js';
4
5
  export * from './getType.js';
@@ -1,4 +1,5 @@
1
1
  export * from './addDependency.js';
2
+ export * from './extractAttribute.js';
2
3
  export * from './extractFromComment.js';
3
4
  export * from './getInitializer.js';
4
5
  export * from './getType.js';