anu-verzum 1.15.0 → 1.17.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
@@ -440,7 +440,7 @@ Supports both <i>HTML</i> and <i>inline-SVG</i> element creation, "stateful" (or
440
440
 
441
441
  <h3 id="function-components">Function components</h3>
442
442
 
443
- - Function components are functions which can receive <code>props</code> and must always return either an <i>HTML element</i>, an <i>inline-SVG element</i>, a <i>Component</i> or <code>NULL</code>.
443
+ - Function components are functions which can receive <code>props</code> and must always return either an <i>HTML element</i>, an <i>inline-SVG element</i>, a <i>Component</i>, a <i>string</i>, a <i>number</i>, a <i>boolean</i>, or <code>NULL</code>.
444
444
  - Both class-based and function component names must start with a capital letter, inline-SVG-s and HTML element names are lower-case!
445
445
 
446
446
  ```typescript
@@ -8,7 +8,7 @@ export declare abstract class Component<P extends Record<string, any> = Props, S
8
8
  static isAnuComponent?: boolean;
9
9
  constructor(props: P, context?: Record<string, any>);
10
10
  setState(partialState?: Partial<S> | ((prevState: S, prevProps: P) => S)): void;
11
- abstract render(): AnuElement | AnuElement[] | string | number | null | undefined;
11
+ abstract render(): AnuElement | AnuElement[] | string | number | boolean | null | undefined;
12
12
  componentDidMount(): void;
13
13
  componentDidUpdate(_prevProps: P, _prevState: S): void;
14
14
  componentWillUnmount(): void;
@@ -26,7 +26,7 @@ const updateDomProperties = (dom, prevProps, nextProps, isSvgElement = false) =>
26
26
  }
27
27
  return name.startsWith('on');
28
28
  };
29
- const isAttribute = name => !isEvent(name) && name !== 'children' && name !== 'style' && name !== 'ref' && name !== 'key';
29
+ const isAttribute = name => !isEvent(name) && name !== 'children' && name !== 'style';
30
30
  const isNew = (prev, next) => key => prev[key] !== next[key];
31
31
  const isGone = (prev, next) => key => !(key in next);
32
32
  Object.keys(prevProps).filter(isEvent).filter(key => !(key in nextProps) || isNew(prevProps, nextProps)(key)).forEach(name => {
@@ -4,19 +4,19 @@ export type AnuNode = AnuChild | AnuNode[];
4
4
  export type AnuCSSProperties = Partial<Record<keyof CSSStyleDeclaration, string | number>>;
5
5
  export type Props = {
6
6
  children?: AnuNode;
7
- ref?: Ref<any>;
8
- key?: string | number;
9
7
  style?: AnuCSSProperties;
10
8
  [key: string]: any;
11
9
  };
12
10
  export type Ref<T> = {
13
11
  current: T | null;
14
12
  };
15
- export type FunctionComponent<P extends Props = Props> = (props: P) => AnuElement<any, any> | AnuElement<any>[] | null;
13
+ export type FunctionComponent<P extends Props = Props> = (props: P) => AnuElement<any, any> | AnuElement<any, any>[] | string | number | boolean | null | undefined;
16
14
  export type ComponentConstructor<P extends Props = Props> = new (props: P, context?: Record<string, any>) => any;
17
15
  export type ElementType = string | FunctionComponent | ComponentConstructor;
18
16
  export type AnuElement<P = Props, T extends ElementType = ElementType> = {
19
17
  type: T;
20
18
  props: P;
19
+ key: string | null;
20
+ ref: Ref<any> | null;
21
21
  };
22
22
  export declare const createElement: (type: ElementType, config: Props | null, ...args: any[]) => AnuElement;
@@ -9,10 +9,16 @@ const createTextElement = value => ({
9
9
  type: TEXT_ELEMENT,
10
10
  props: {
11
11
  nodeValue: String(value)
12
- }
12
+ },
13
+ key: null,
14
+ ref: null
13
15
  });
14
16
  const createElement = (type, config, ...args) => {
17
+ const key = config != null && config.key != null ? String(config.key) : null;
18
+ const ref = config != null && config.ref != null ? config.ref : null;
15
19
  const props = Object.assign({}, config);
20
+ delete props.key;
21
+ delete props.ref;
16
22
  if (args.length > 0) {
17
23
  const rawChildren = [].concat(...args);
18
24
  props.children = rawChildren.filter(c => c !== null && c !== false).map(c => typeof c === 'function' ? createElement(c, {
@@ -23,7 +29,9 @@ const createElement = (type, config, ...args) => {
23
29
  }
24
30
  return {
25
31
  type,
26
- props
32
+ props,
33
+ key,
34
+ ref
27
35
  };
28
36
  };
29
37
  exports.createElement = createElement;
@@ -174,7 +174,7 @@ const reconcileChildrenArray = (wipFiber, newChildElements) => {
174
174
  let oldFiber = wipFiber.alternate ? wipFiber.alternate.child : undefined;
175
175
  let oldIndex = 0;
176
176
  while (oldFiber) {
177
- const mapKey = oldFiber.props.key ?? oldIndex;
177
+ const mapKey = oldFiber.key ?? oldIndex;
178
178
  oldFiberMap.set(mapKey, oldFiber);
179
179
  oldFiber = oldFiber.sibling;
180
180
  oldIndex++;
@@ -182,7 +182,7 @@ const reconcileChildrenArray = (wipFiber, newChildElements) => {
182
182
  let prevFiber;
183
183
  for (let i = 0; i < elements.length; i++) {
184
184
  const element = elements[i];
185
- const mapKey = element.props.key ?? i;
185
+ const mapKey = element.key ?? i;
186
186
  const matchedOldFiber = oldFiberMap.get(mapKey);
187
187
  const sameType = matchedOldFiber !== undefined && element.type === matchedOldFiber.type;
188
188
  let newFiber;
@@ -190,6 +190,8 @@ const reconcileChildrenArray = (wipFiber, newChildElements) => {
190
190
  newFiber = {
191
191
  type: matchedOldFiber.type,
192
192
  tag: matchedOldFiber.tag,
193
+ key: matchedOldFiber.key,
194
+ ref: element.ref,
193
195
  stateNode: matchedOldFiber.stateNode,
194
196
  props: element.props,
195
197
  parent: wipFiber,
@@ -211,6 +213,8 @@ const reconcileChildrenArray = (wipFiber, newChildElements) => {
211
213
  newFiber = {
212
214
  type: element.type,
213
215
  tag: getTag(element),
216
+ key: element.key,
217
+ ref: element.ref,
214
218
  props: element.props,
215
219
  parent: wipFiber,
216
220
  effectTag: PLACEMENT
@@ -265,6 +269,8 @@ const cloneChildFibers = parentFiber => {
265
269
  const newChild = {
266
270
  type: oldChild.type,
267
271
  tag: oldChild.tag,
272
+ key: oldChild.key,
273
+ ref: oldChild.ref,
268
274
  stateNode: oldChild.stateNode,
269
275
  props: oldChild.props,
270
276
  partialState: oldChild.partialState,
@@ -337,8 +343,8 @@ const commitWork = effect => {
337
343
  } else {
338
344
  domParent.appendChild(effect.stateNode);
339
345
  }
340
- if (effect.props.ref) {
341
- effect.props.ref.current = effect.stateNode;
346
+ if (effect.ref) {
347
+ effect.ref.current = effect.stateNode;
342
348
  }
343
349
  } else if (effect.tag === CLASS_COMPONENT) {
344
350
  if (effect.stateNode.componentDidMount) {
@@ -358,8 +364,8 @@ const commitWork = effect => {
358
364
  domParent.appendChild(effect.stateNode);
359
365
  }
360
366
  (0, _domUtils.updateDomProperties)(effect.stateNode, effect.alternate.props, effect.props, _domUtils.SVG_ELEMENT_LIST.indexOf(effect.type) > -1);
361
- if (effect.props.ref) {
362
- effect.props.ref.current = effect.stateNode;
367
+ if (effect.ref) {
368
+ effect.ref.current = effect.stateNode;
363
369
  }
364
370
  } else if (effect.tag === CLASS_COMPONENT) {
365
371
  if (effect.stateNode.componentDidUpdate) {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import Utils from './misc/utils';
2
2
  import ServerAPI from './server-api/server-api';
3
- import { createElement, AnuElement, Props } from './core/elements';
3
+ import { createElement, AnuElement, Props, Ref } from './core/elements';
4
4
  import { createRef, render } from './core/reconciler';
5
5
  import store from './store/store';
6
6
  import { createContext } from './core/components/Context';
@@ -146,10 +146,14 @@ export { store, ServerAPI, Utils, Connector, Feature, History, Intl };
146
146
  export type { AbbreviateNumberOptions } from './core/components/Intl';
147
147
  declare global {
148
148
  namespace JSX {
149
+ interface IntrinsicAttributes {
150
+ key?: string | number | null;
151
+ ref?: Ref<any> | null;
152
+ }
149
153
  interface Element extends AnuElement<any, any> {
150
154
  }
151
155
  interface ElementClass {
152
- render(): AnuElement | AnuElement[] | string | number | null | undefined;
156
+ render(): AnuElement | AnuElement[] | string | number | boolean | null | undefined;
153
157
  }
154
158
  interface ElementAttributesProperty {
155
159
  props: Record<string, unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anu-verzum",
3
- "version": "1.15.0",
3
+ "version": "1.17.0",
4
4
  "description": "A \"React-like\" UI library that supports JSX syntax, Redux-like state management, array-rendering, i18n, routing and many more.",
5
5
  "keywords": [
6
6
  "anu-verzum",