@meonode/ui 0.2.16 → 0.2.18
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 +85 -10
- package/dist/core.node.d.ts +22 -15
- package/dist/core.node.d.ts.map +1 -1
- package/dist/core.node.js +58 -34
- package/dist/helper/common.helper.d.ts +15 -2
- package/dist/helper/common.helper.d.ts.map +1 -1
- package/dist/helper/common.helper.js +10 -1
- package/dist/helper/node.helper.js +3 -3
- package/dist/hoc/portal.hoc.d.ts +6 -6
- package/dist/hoc/portal.hoc.d.ts.map +1 -1
- package/dist/hoc/portal.hoc.js +7 -7
- package/dist/hook/index.d.ts +2 -0
- package/dist/hook/index.d.ts.map +1 -0
- package/dist/hook/index.js +1 -0
- package/dist/hook/usePortal.d.ts +8 -0
- package/dist/hook/usePortal.d.ts.map +1 -0
- package/dist/hook/usePortal.js +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/node.type.d.ts +14 -7
- package/dist/node.type.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,81 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.18] - 2025-09-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **feat(core)**: support function children and enhance rendering logic
|
|
13
|
+
- **feat(core)**: enhance portal with update method and NodePortal type
|
|
14
|
+
- **feat(hook)**: introduce usePortal hook for reactive portals
|
|
15
|
+
|
|
16
|
+
### Example
|
|
17
|
+
|
|
18
|
+
- **feat(portal)**: use `usePortal` hook to make the portal reactive to state changes
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Button, Div, Node, Portal, type PortalProps } from '@meonode/ui';
|
|
22
|
+
import { usePortal } from '@meonode/ui';
|
|
23
|
+
import { useState } from 'react';
|
|
24
|
+
|
|
25
|
+
const MyPortal = () => {
|
|
26
|
+
const [state, setState] = useState<number>(0);
|
|
27
|
+
const { setPortal, createComponent } = usePortal([state]);
|
|
28
|
+
|
|
29
|
+
const PortalContent = createComponent(({ portal, text }: { text: string } & PortalProps<any>) => {
|
|
30
|
+
return Div({
|
|
31
|
+
children: [
|
|
32
|
+
'This is portal content!',
|
|
33
|
+
state === 1 ? text : 'Initial text value',
|
|
34
|
+
Button(`Update Portal (${state + 1})`, {
|
|
35
|
+
onClick: () => {
|
|
36
|
+
setState((s: number) => s + 1);
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
Button('Close Portal', {
|
|
40
|
+
onClick: () => {
|
|
41
|
+
portal?.unmount();
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
}).render();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return Div({
|
|
49
|
+
children: [
|
|
50
|
+
Button('Open Portal', {
|
|
51
|
+
onClick: () => {
|
|
52
|
+
const portal = Portal<{ text: string }>(PortalContent)({ text: `Text prop still passed after update` });
|
|
53
|
+
setPortal(portal);
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
}).render();
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## [0.2.17] - 2025-09-14
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- **feat(common.helper)**: add omit and omitUndefined utility functions to create object copies without specified keys or undefined values
|
|
66
|
+
- **feat**: integrate omit and omitUndefined functions to manage finalProps for standard HTML tags and custom components
|
|
67
|
+
|
|
68
|
+
### Refactor
|
|
69
|
+
|
|
70
|
+
- **refactor**: remove unnecessary type assertions for children in core.node.ts
|
|
71
|
+
- **refactor(core.node.ts)**: streamline element creation logic
|
|
72
|
+
|
|
73
|
+
### Test
|
|
74
|
+
|
|
75
|
+
- **test**: add test case for rendering Div node using Component HOC
|
|
76
|
+
- **feat(test)**: replace Div components with Container for consistency in performance tests
|
|
77
|
+
- **test(node.test.ts)**: add test for rendering an empty prop Div node
|
|
78
|
+
|
|
79
|
+
### Removed
|
|
80
|
+
|
|
81
|
+
- **types**: removed redundant `key` prop from `FinalNodeProps` and default `key` from `NodeProps` types for cleaner type definitions
|
|
82
|
+
|
|
8
83
|
## [0.2.16] - 2025-09-13
|
|
9
84
|
|
|
10
85
|
### Added
|
|
@@ -94,20 +169,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
94
169
|
This abstracts away the need to manually use `react-dom/client`.
|
|
95
170
|
- **Before**:
|
|
96
171
|
```typescript
|
|
97
|
-
import { createRoot } from 'react-dom/client';
|
|
98
|
-
import { Div } from '@meonode/ui';
|
|
172
|
+
import { createRoot } from \'react-dom/client\';
|
|
173
|
+
import { Div } from \'@meonode/ui\';
|
|
99
174
|
|
|
100
|
-
const container = document.getElementById('root');
|
|
175
|
+
const container = document.getElementById(\'root\');
|
|
101
176
|
const root = createRoot(container);
|
|
102
|
-
root.render(Div({ children: 'Hello' }).render());
|
|
177
|
+
root.render(Div({ children: \'Hello\' }).render());
|
|
103
178
|
```
|
|
104
179
|
- **After**:
|
|
105
180
|
```typescript
|
|
106
|
-
import { Div } from '@meonode/ui';
|
|
107
|
-
import { render } from '@meonode/ui/client';
|
|
181
|
+
import { Div } from \'@meonode/ui\';
|
|
182
|
+
import { render } from \'@meonode/ui/client\';
|
|
108
183
|
|
|
109
|
-
const container = document.getElementById('root');
|
|
110
|
-
render(Div({ children: 'Hello' }), container);
|
|
184
|
+
const container = document.getElementById(\'root\');
|
|
185
|
+
render(Div({ children: \'Hello\' }), container);
|
|
111
186
|
```
|
|
112
187
|
- **constants**: add `NO_STYLE_TAGS` array and `noStyleTagsSet` for quick lookup of tags that should not receive styles
|
|
113
188
|
|
|
@@ -141,10 +216,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
141
216
|
- Improves developer experience when working with prebuilt components:
|
|
142
217
|
- Example:
|
|
143
218
|
```typescript
|
|
144
|
-
import { Div, Input } from '@meonode/ui'
|
|
219
|
+
import { Div, Input } from \'@meonode/ui\'
|
|
145
220
|
|
|
146
221
|
// Add new props
|
|
147
|
-
Div<{ field: string }>({ field: 'Hello' })
|
|
222
|
+
Div<{ field: string }>({ field: \'Hello\' })
|
|
148
223
|
|
|
149
224
|
// Override existing React props
|
|
150
225
|
Input<{ onChange: (e: { target: { value: string } }) => void }>({
|
package/dist/core.node.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React, { type
|
|
2
|
-
import type { Children, FinalNodeProps, HasRequiredProps, MergedProps, NodeElement, NodeInstance, NodeProps, PropsOf, RawNodeProps, Theme } from './node.type.js';
|
|
3
|
-
import { type Root as ReactDOMRoot } from 'react-dom/client';
|
|
1
|
+
import React, { type ReactElement, type ReactNode } from 'react';
|
|
2
|
+
import type { Children, FinalNodeProps, HasRequiredProps, MergedProps, NodeElement, NodeElementType, NodeInstance, NodePortal, NodeProps, PropsOf, RawNodeProps, Theme } from './node.type.js';
|
|
4
3
|
/**
|
|
5
4
|
* Represents a node in a React component tree with theme and styling capabilities.
|
|
6
5
|
* This class wraps React elements and handles:
|
|
@@ -10,7 +9,7 @@ import { type Root as ReactDOMRoot } from 'react-dom/client';
|
|
|
10
9
|
* - Style processing with theme variables
|
|
11
10
|
* @template E The type of React element or component this node represents
|
|
12
11
|
*/
|
|
13
|
-
export declare class BaseNode<E extends
|
|
12
|
+
export declare class BaseNode<E extends NodeElementType> implements NodeInstance<E> {
|
|
14
13
|
/** The underlying React element or component type that this node represents */
|
|
15
14
|
element: E;
|
|
16
15
|
/** Original props passed during construction, preserved for cloning/recreation */
|
|
@@ -148,6 +147,12 @@ export declare class BaseNode<E extends NodeElement> implements NodeInstance<E>
|
|
|
148
147
|
* @static
|
|
149
148
|
*/
|
|
150
149
|
static _renderProcessedNode(processedElement: NodeElement, passedTheme: Theme | undefined, passedKey?: string): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | ReactElement<any, string | React.JSXElementConstructor<any>> | null | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* Determines if a raw node is a function that should be treated as a render prop.
|
|
152
|
+
* @param rawNode
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
private _isFunctionChild;
|
|
151
156
|
/**
|
|
152
157
|
* Renders the output of a function-as-a-child, ensuring theme propagation.
|
|
153
158
|
*
|
|
@@ -241,16 +246,18 @@ export declare class BaseNode<E extends NodeElement> implements NodeInstance<E>
|
|
|
241
246
|
/**
|
|
242
247
|
* Renders the node into a React Portal.
|
|
243
248
|
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
249
|
+
* Mounts the node's rendered output into a detached DOM tree (a `div` appended to `document.body`),
|
|
250
|
+
* enabling UI elements like modals, tooltips, or notifications to appear above the main app content.
|
|
251
|
+
*
|
|
252
|
+
* Returns a `NodePortal` object with:
|
|
253
|
+
* - `render(content)`: Renders new content into the portal.
|
|
254
|
+
* - `update(next?)`: Rerenders the current node or new content.
|
|
255
|
+
* - `unmount()`: Unmounts the portal and removes the DOM element.
|
|
247
256
|
*
|
|
248
|
-
*
|
|
249
|
-
* @returns A `
|
|
250
|
-
* called in a server-side environment. The returned instance is enhanced
|
|
251
|
-
* with a custom `unmount` method that also cleans up the associated DOM element.
|
|
257
|
+
* Throws if called on the server (where `document.body` is unavailable).
|
|
258
|
+
* @returns A `NodePortal` instance for managing the portal.
|
|
252
259
|
*/
|
|
253
|
-
toPortal():
|
|
260
|
+
toPortal(): NodePortal;
|
|
254
261
|
}
|
|
255
262
|
/**
|
|
256
263
|
* Factory function to create a `BaseNode` instance.
|
|
@@ -261,7 +268,7 @@ export declare class BaseNode<E extends NodeElement> implements NodeInstance<E>
|
|
|
261
268
|
* @param additionalProps Additional props to merge into the node (optional).
|
|
262
269
|
* @returns A new `BaseNode` instance as a `NodeInstance<E>`.
|
|
263
270
|
*/
|
|
264
|
-
export declare function Node<AdditionalProps extends Record<string, any>, E extends
|
|
271
|
+
export declare function Node<AdditionalProps extends Record<string, any>, E extends NodeElementType>(element: E, props?: MergedProps<E, AdditionalProps>, additionalProps?: AdditionalProps): NodeInstance<E>;
|
|
265
272
|
/**
|
|
266
273
|
* Creates a curried node factory for a given React element or component type.
|
|
267
274
|
*
|
|
@@ -276,7 +283,7 @@ export declare function Node<AdditionalProps extends Record<string, any>, E exte
|
|
|
276
283
|
* const ButtonNode = createNode('button', { type: 'button' });
|
|
277
284
|
* const myButton = ButtonNode({ children: 'Click me', style: { color: 'red' } });
|
|
278
285
|
*/
|
|
279
|
-
export declare function createNode<AdditionalInitialProps extends Record<string, any>, E extends
|
|
286
|
+
export declare function createNode<AdditionalInitialProps extends Record<string, any>, E extends NodeElementType>(element: E, initialProps?: MergedProps<E, AdditionalInitialProps>): HasRequiredProps<PropsOf<E>> extends true ? (<AdditionalProps extends Record<string, any> = Record<string, any>>(props: MergedProps<E, AdditionalProps>) => NodeInstance<E>) & {
|
|
280
287
|
element: E;
|
|
281
288
|
} : (<AdditionalProps extends Record<string, any> = Record<string, any>>(props?: MergedProps<E, AdditionalProps>) => NodeInstance<E>) & {
|
|
282
289
|
element: E;
|
|
@@ -300,7 +307,7 @@ export declare function createNode<AdditionalInitialProps extends Record<string,
|
|
|
300
307
|
* const Text = createChildrenFirstNode('p');
|
|
301
308
|
* const myDiv = Text('Hello', { className: 'text-lg' });
|
|
302
309
|
*/
|
|
303
|
-
export declare function createChildrenFirstNode<AdditionalInitialProps extends Record<string, any>, E extends
|
|
310
|
+
export declare function createChildrenFirstNode<AdditionalInitialProps extends Record<string, any>, E extends NodeElementType>(element: E, initialProps?: Omit<NodeProps<E>, keyof AdditionalInitialProps | 'children'> & AdditionalInitialProps): HasRequiredProps<PropsOf<E>> extends true ? (<AdditionalProps extends Record<string, any> = Record<string, any>>(children: Children, props: Omit<MergedProps<E, AdditionalProps>, 'children'>) => NodeInstance<E>) & {
|
|
304
311
|
element: E;
|
|
305
312
|
} : (<AdditionalProps extends Record<string, any> = Record<string, any>>(children?: Children, props?: Omit<MergedProps<E, AdditionalProps>, 'children'>) => NodeInstance<E>) & {
|
|
306
313
|
element: E;
|
package/dist/core.node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"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"}
|
package/dist/core.node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var _excluded=["ref","key","children","nodetheme","theme","props"],_excluded2=["style"],_excluded3=["style","css"],_excluded4=["style"],_excluded5=["children","key","nativeProps"];function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],-1===b.indexOf(c)&&{}.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c={};for(var d in a)if({}.hasOwnProperty.call(a,d)){if(-1!==b.indexOf(d))continue;c[d]=a[d]}return c}function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import React,{createElement,Fragment,isValidElement}from"react";import{createStableHash,isNodeInstance,resolveDefaultStyle}from"./helper/node.helper.js";import{isForwardRef,isFragment,isMemo,isReactClassComponent,isValidElementType}from"./helper/react-is.helper.js";import{createRoot}from"react-dom/client";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,hasNoStyleTag}from"./helper/common.helper.js";import StyledRenderer from"./components/styled-renderer.client.js";import{resolveObjWithTheme}from"./helper/theme.helper.js";/**
|
|
1
|
+
"use strict";var _excluded=["ref","key","children","nodetheme","theme","props"],_excluded2=["style"],_excluded3=["style","css"],_excluded4=["style"],_excluded5=["children","key","nativeProps"];function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],-1===b.indexOf(c)&&{}.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c={};for(var d in a)if({}.hasOwnProperty.call(a,d)){if(-1!==b.indexOf(d))continue;c[d]=a[d]}return c}function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import React,{createElement,Fragment,isValidElement}from"react";import{createStableHash,isNodeInstance,resolveDefaultStyle}from"./helper/node.helper.js";import{isForwardRef,isFragment,isMemo,isReactClassComponent,isValidElementType}from"./helper/react-is.helper.js";import{createRoot}from"react-dom/client";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,hasNoStyleTag,omit,omitUndefined}from"./helper/common.helper.js";import StyledRenderer from"./components/styled-renderer.client.js";import{resolveObjWithTheme}from"./helper/theme.helper.js";/**
|
|
2
2
|
* Represents a node in a React component tree with theme and styling capabilities.
|
|
3
3
|
* This class wraps React elements and handles:
|
|
4
4
|
* - Props processing and normalization
|
|
@@ -43,7 +43,9 @@
|
|
|
43
43
|
*/_defineProperty(this,"rawProps",{}),_defineProperty(this,"isBaseNode",!0),_defineProperty(this,"_portalDOMElement",null),_defineProperty(this,"_portalReactRoot",null),_defineProperty(this,"_generateKey",function(a){var b=a.nodeIndex,c=a.element,d=a.existingKey,e=a.children;if(d)return d;var f,g=getElementTypeName(c);return f=Array.isArray(e)&&0<e.length?void 0===b?"".concat(g,"-").concat(e.length):"".concat(g,"-").concat(b,"-").concat(e.length):void 0===b?g:"".concat(g,"-").concat(b),f}),_defineProperty(this,"_normalizeChild",function(a){var c,d;// Handle null/undefined quickly
|
|
44
44
|
if(null===a||a===void 0)return a;// Primitives should be returned as-is (text nodes, numbers, booleans)
|
|
45
45
|
var e=_typeof(a);if("string"===e||"number"===e||"boolean"===e)return a;var f=(null===(c=b.rawProps)||void 0===c?void 0:c.nodetheme)||(null===(d=b.rawProps)||void 0===d?void 0:d.theme)||b.props.nodetheme||b.props.theme;// For BaseNode instances, apply current theme if child has no theme
|
|
46
|
-
if(a instanceof BaseNode){var g;return null!==(g=a.rawProps)&&void 0!==g&&g.nodetheme||void 0===f?a.render():new BaseNode(a.element,_objectSpread(_objectSpread({},a.rawProps),{},{nodetheme:f})).render()}//
|
|
46
|
+
if(a instanceof BaseNode||isNodeInstance(a)){var g;return null!==(g=a.rawProps)&&void 0!==g&&g.nodetheme||void 0===f?a.render():new BaseNode(a.element,_objectSpread(_objectSpread({},a.rawProps),{},{nodetheme:f})).render()}// Handle React.Component instances
|
|
47
|
+
if("function"==typeof a.render)// React.Component instance
|
|
48
|
+
return a.render();// Validate element type before returning
|
|
47
49
|
if(!isValidElementType(a)){var h=getComponentType(a);throw new Error("Invalid element type: ".concat(h," provided!"))}// Return valid React elements as-is
|
|
48
50
|
return a}),this.element=a,this.rawProps=c}/**
|
|
49
51
|
* Lazily processes and retrieves the final, normalized props for the node.
|
|
@@ -64,9 +66,10 @@ return a}),this.element=a,this.rawProps=c}/**
|
|
|
64
66
|
* @returns The processed `FinalNodeProps` object.
|
|
65
67
|
* @private
|
|
66
68
|
*/_processProps(){// Destructure raw props into relevant parts
|
|
67
|
-
var a=this.rawProps,b=a.ref,c=a.key,d=a.children,e=a.nodetheme,f=a.theme,g=a.props,h=void 0===g?{}:g,i=_objectWithoutProperties(a,_excluded),j=f||e,k=h,l=k.style,m=_objectWithoutProperties(k,_excluded2),n=resolveObjWithTheme(i,j),o=resolveObjWithTheme(l,j),p=n.style,q=n.css,r=_objectWithoutProperties(n,_excluded3),s=getCSSProps(r),t=getDOMProps(r),u=resolveDefaultStyle(_objectSpread(_objectSpread({},s),p)),v=this._processChildren(d,j);// Process children while maintaining theme inheritance
|
|
69
|
+
var a=this.rawProps,b=a.ref,c=a.key,d=a.children,e=a.nodetheme,f=a.theme,g=a.props,h=void 0===g?{}:g,i=_objectWithoutProperties(a,_excluded),j=f||e,k=h,l=k.style,m=_objectWithoutProperties(k,_excluded2),n=resolveObjWithTheme(i,j),o=resolveObjWithTheme(l,j),p=n.style,q=n.css,r=_objectWithoutProperties(n,_excluded3),s=getCSSProps(r),t=getDOMProps(r),u=resolveDefaultStyle(_objectSpread(_objectSpread({},s),p)),v=this._processChildren(d,j),w=omitUndefined(_objectSpread(_objectSpread({ref:b,key:c,nodetheme:j,theme:f,css:_objectSpread(_objectSpread({},u),q),style:o},t),{},{nativeProps:m,children:v}));// Process children while maintaining theme inheritance
|
|
68
70
|
// Combine processed props into final normalized form
|
|
69
|
-
|
|
71
|
+
// Special handling for standard HTML tags vs custom components
|
|
72
|
+
return"string"==typeof this.element&&(hasNoStyleTag(this.element)?w=omit(w,"css","style","theme","nodetheme"):w=omit(w,"theme","nodetheme")),w}/**
|
|
70
73
|
* Deeply clones processed children before returning them from cache so that each parent receives
|
|
71
74
|
* independent `BaseNode` instances (prevents sharing cycles and mutation bugs).
|
|
72
75
|
*
|
|
@@ -122,8 +125,7 @@ if(BaseNode._processedChildrenMapCache.has(d))return void BaseNode._processedChi
|
|
|
122
125
|
* @returns The processed children, ready for normalization and rendering.
|
|
123
126
|
* @private
|
|
124
127
|
*/_processChildren(a,b){var c=this;if(a){// Use RSC-safe caching strategy
|
|
125
|
-
var d=this._getCachedChildren(a,b);if(d)return d;var e=Array.isArray(a)?a.map(function(a,d){return c._processRawNode(a,b,d)}):this._processRawNode(a,b)
|
|
126
|
-
return BaseNode._isServer||this._setCachedChildren(a,b,e),e}}/**
|
|
128
|
+
var d=this._getCachedChildren(a,b);if(d)return d;var e;return e="function"==typeof a?a:Array.isArray(a)?a.map(function(a,d){return c._processRawNode(a,b,d)}):this._processRawNode(a,b),BaseNode._isServer||this._setCachedChildren(a,b,e),e}}/**
|
|
127
129
|
* Renders a processed `NodeElement` into a `ReactNode`, applying a theme and key if necessary.
|
|
128
130
|
*
|
|
129
131
|
* This static method centralizes the logic for converting various types of processed elements
|
|
@@ -146,6 +148,15 @@ return isReactClassComponent(a)?new BaseNode(a,d).render():isNodeInstance(a)?a.r
|
|
|
146
148
|
// 4. React.Component instance: call its render
|
|
147
149
|
// 5. Functional component: create element with key
|
|
148
150
|
// 6. Other valid ReactNode types
|
|
151
|
+
}/**
|
|
152
|
+
* Determines if a raw node is a function that should be treated as a render prop.
|
|
153
|
+
* @param rawNode
|
|
154
|
+
* @private
|
|
155
|
+
*/_isFunctionChild(a){// Basic function check
|
|
156
|
+
return!("function"!=typeof a)&&!isReactClassComponent(a)&&!isMemo(a)&&!isForwardRef(a)&&!("displayName"in a&&a.displayName&&/^[A-Z]/.test(a.displayName))&&!(a.name&&/^[A-Z]/.test(a.name))&&!(a.prototype&&"function"==typeof a.prototype.render);// Exclude React component types
|
|
157
|
+
// Check if it's a component function vs render function
|
|
158
|
+
// Component functions typically have displayName, name starting with capital, or prototype
|
|
159
|
+
// If function has prototype properties (likely a constructor), it's probably a component
|
|
149
160
|
}/**
|
|
150
161
|
* Renders the output of a function-as-a-child, ensuring theme propagation.
|
|
151
162
|
*
|
|
@@ -159,10 +170,15 @@ return isReactClassComponent(a)?new BaseNode(a,d).render():isNodeInstance(a)?a.r
|
|
|
159
170
|
* @returns The rendered `ReactNode`.
|
|
160
171
|
* @private
|
|
161
172
|
*/_functionRenderer(a){var b,c=a.render,d=a.passedTheme,e=a.processRawNode;// Invoke the render function to get the child node.
|
|
162
|
-
try{b=c()}catch(a){b=null}// Handle
|
|
163
|
-
if(b
|
|
164
|
-
if(b
|
|
165
|
-
var
|
|
173
|
+
try{b=c()}catch(a){b=null}// Handle null/undefined
|
|
174
|
+
if(null===b||b===void 0)return b;// Handle arrays of elements (common in render props)
|
|
175
|
+
if(Array.isArray(b))return b.map(function(a,b){var c=e(a,d,b);return BaseNode._renderProcessedNode(c,d,"".concat(getElementTypeName(a),"-").concat(b))});// Handle React.Component instance
|
|
176
|
+
if(b instanceof React.Component){var f=b.render(),g=e(f,d);return BaseNode._renderProcessedNode(g,d)}// Handle BaseNode instance or NodeInstance
|
|
177
|
+
if(b instanceof BaseNode||isNodeInstance(b)){var h,i=b;// If nodetheme is missing and passedTheme exists, inject it
|
|
178
|
+
return void 0===(null===(h=i.rawProps)||void 0===h?void 0:h.nodetheme)&&void 0!==d?new BaseNode(i.element,_objectSpread(_objectSpread({},i.rawProps),{},{nodetheme:d})).render():i.render()}// Handle primitives and valid React nodes (JSX, string, number, boolean)
|
|
179
|
+
if("string"==typeof b||"number"==typeof b||"boolean"==typeof b||b&&"object"===_typeof(b)&&"$$typeof"in b// React JSX element
|
|
180
|
+
)return b;// Process any other result types
|
|
181
|
+
var j=e?e(b,d):b;return j?BaseNode._renderProcessedNode(j,d):b}/**
|
|
166
182
|
* Processes a single raw node, recursively converting it into a `BaseNode` or other renderable type.
|
|
167
183
|
*
|
|
168
184
|
* This is a central method for normalizing children. It handles various types of input:
|
|
@@ -190,13 +206,8 @@ return new BaseNode(e.element,_objectSpread(_objectSpread({},f),{},{nodetheme:g,
|
|
|
190
206
|
key:h}));// Create a new BaseNode with merged props and theme
|
|
191
207
|
}// Case 2: Child is a primitive (string, number, boolean, null, undefined)
|
|
192
208
|
if("string"===d||"number"===d||"boolean"===d||null===a||void 0===a)return a;// Case 3: Child is a function that needs to be called during render (FunctionRenderer).
|
|
193
|
-
if(
|
|
194
|
-
//
|
|
195
|
-
var i=this._generateKey({nodeIndex:c,element:this._functionRenderer});// Generate key for function renderer
|
|
196
|
-
return new BaseNode(this._functionRenderer,{processRawNode:this._processRawNode.bind(this),render:a,passedTheme:b,key:i})}// Case 4: Child is a React Element (JSX element like <div> or <MyComponent>)
|
|
197
|
-
if(isValidElement(a)){var j=a.props,k=j.style,l=_objectWithoutProperties(j,_excluded4),m=_objectSpread(_objectSpread({},l),k||{}),n=m.theme||m.nodetheme||b,o=this._generateKey({nodeIndex:c,element:a.type,existingKey:a.key,children:m.children});// Combine top-level props from the element with its flattened style object properties
|
|
198
|
-
return new BaseNode(a.type,_objectSpread(_objectSpread({},m),{},{// Pass the combined props
|
|
199
|
-
nodetheme:n,key:o}))}// Case 5: Child is an ElementType (string tag, class component, Memo/ForwardRef)
|
|
209
|
+
if(this._isFunctionChild(a)){var i=this._generateKey({nodeIndex:c,element:this._functionRenderer});return new BaseNode(this._functionRenderer,{processRawNode:this._processRawNode.bind(this),render:a,passedTheme:b,key:i})}// Case 4: Child is a React Element (JSX element like <div> or <MyComponent>)
|
|
210
|
+
if(isValidElement(a)){var j=a.props,k=j.style,l=_objectWithoutProperties(j,_excluded4),m=_objectSpread(_objectSpread({},l),k||{}),n=m.theme||m.nodetheme||b,o=this._generateKey({nodeIndex:c,element:a.type,existingKey:a.key,children:m.children});return new BaseNode(a.type,_objectSpread(_objectSpread({},m),{},{nodetheme:n,key:o}))}// Case 5: Child is an ElementType (string tag, class component, Memo/ForwardRef)
|
|
200
211
|
if(isReactClassComponent(a)||"object"===d&&(isMemo(a)||isForwardRef(a))){var p,q=this._generateKey({nodeIndex:c,element:a,children:"object"===_typeof(a)&&"props"in a?null===(p=a.props)||void 0===p?void 0:p.children:void 0});// ElementTypes don't have an intrinsic key from the rawNode itself.
|
|
201
212
|
return new BaseNode(a,{nodetheme:b,// Apply parent theme
|
|
202
213
|
key:q})}// Case 6: Handle instances of React.Component
|
|
@@ -219,12 +230,15 @@ return a}/**
|
|
|
219
230
|
* @returns The rendered `ReactElement`.
|
|
220
231
|
* @throws {Error} If the node's `element` is not a valid React element type.
|
|
221
232
|
*/render(){var a=this;if(!isValidElementType(this.element)){var b=getComponentType(this.element);throw new Error("Invalid element type: ".concat(b," provided!"))}// Extract children and key
|
|
222
|
-
var c=this.props,d=c.children,e=c.key,f=c.nativeProps,g=_objectWithoutProperties(c,_excluded5),h=void 0;if(void 0
|
|
223
|
-
|
|
233
|
+
var c=this.props,d=c.children,e=c.key,f=c.nativeProps,g=_objectWithoutProperties(c,_excluded5),h=void 0;if(d!==void 0&&null!==d){if(!this._normalizedChildren||this._childrenHash!==createStableHash(d,this.props.nodetheme||this.props.theme))if(!Array.isArray(d))this._normalizedChildren=this._normalizeChild(d);else if(0<d.length){var i=d.map(function(b){return a._normalizeChild(b)});this._normalizedChildren=i.every(function(a){return null===a||void 0===a})?void 0:i}else this._normalizedChildren=void 0;h=this._normalizedChildren}// If the element is a Fragment, use React.createElement directly
|
|
234
|
+
if(this.element===Fragment||isFragment(this.element))return createElement(this.element,{key:e},h);// If the element has a `css` prop and has style tag, render using the `StyledRenderer` component
|
|
224
235
|
// This enables emotion-based style handling for the element
|
|
225
|
-
if(
|
|
226
|
-
|
|
227
|
-
}return createElement(this.element,
|
|
236
|
+
if(this.element&&!hasNoStyleTag(this.element)&&g.css){// Set displayName for easier debugging in React DevTools
|
|
237
|
+
try{var j=getElementTypeName(this.element);StyledRenderer.displayName="Styled(".concat(j,")")}catch(a){// swallow: displayName is not critical
|
|
238
|
+
}return createElement(StyledRenderer,_objectSpread(_objectSpread({element:this.element},g),{},{key:e,suppressHydrationWarning:!0},f),h)}// For other elements, create the React element directly
|
|
239
|
+
// Set displayName for easier debugging in React DevTools
|
|
240
|
+
try{this.element.displayName=getElementTypeName(this.element)}catch(a){// swallow: displayName is not critical
|
|
241
|
+
}return createElement(this.element,_objectSpread(_objectSpread({},g),{},{key:e},f),h)}/**
|
|
228
242
|
* Ensures the necessary DOM elements for portal rendering are created and attached.
|
|
229
243
|
*
|
|
230
244
|
* On the client-side, this method checks for or creates a `div` element appended
|
|
@@ -239,22 +253,32 @@ if(this._portalDOMElement&&!this._portalDOMElement.isConnected){// attempt to un
|
|
|
239
253
|
if(this._portalReactRoot){try{this._portalReactRoot.unmount()}catch(a){// swallow: unmount might fail if already removed; avoid breaking the app
|
|
240
254
|
}this._portalReactRoot=null}this._portalDOMElement=null}// Create DOM element if needed
|
|
241
255
|
// Create react root if needed
|
|
242
|
-
if(this._portalDOMElement||(this._portalDOMElement=document.createElement("div"),document.body.appendChild(this._portalDOMElement)),!this._portalReactRoot){if(!this._portalDOMElement)return!1;
|
|
256
|
+
if(this._portalDOMElement||(this._portalDOMElement=document.createElement("div"),document.body.appendChild(this._portalDOMElement)),!this._portalReactRoot){if(!this._portalDOMElement)return!1;var a=createRoot(this._portalDOMElement);this._portalReactRoot={render:a.render.bind(a),unmount:a.unmount.bind(a),update:function update(){/* will be patched later */}}}return!0}/**
|
|
243
257
|
* Renders the node into a React Portal.
|
|
244
258
|
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
259
|
+
* Mounts the node's rendered output into a detached DOM tree (a `div` appended to `document.body`),
|
|
260
|
+
* enabling UI elements like modals, tooltips, or notifications to appear above the main app content.
|
|
261
|
+
*
|
|
262
|
+
* Returns a `NodePortal` object with:
|
|
263
|
+
* - `render(content)`: Renders new content into the portal.
|
|
264
|
+
* - `update(next?)`: Rerenders the current node or new content.
|
|
265
|
+
* - `unmount()`: Unmounts the portal and removes the DOM element.
|
|
248
266
|
*
|
|
249
|
-
*
|
|
250
|
-
* @returns A `
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
try{var
|
|
267
|
+
* Throws if called on the server (where `document.body` is unavailable).
|
|
268
|
+
* @returns A `NodePortal` instance for managing the portal.
|
|
269
|
+
*/toPortal(){var a=this;if(!this._ensurePortalInfrastructure()||!this._portalReactRoot)throw new Error("toPortal() can only be called in a client-side environment where document.body is available.");// Initial render
|
|
270
|
+
(function renderCurrent(){try{var b=a.render();a._portalReactRoot.render(b)}catch(a){// swallow render errors to avoid breaking caller
|
|
271
|
+
}})();// Patch the root with an update() method and a safe unmount that also removes DOM element.
|
|
272
|
+
try{var b=this._portalReactRoot.unmount.bind(this._portalReactRoot),c=this._portalReactRoot;// Create typed handle
|
|
273
|
+
return c.update=function(b){try{if(!a._portalReactRoot)return;if(void 0===b){// Re-render current BaseNode (useful when external state changed, and you want to rerender)
|
|
274
|
+
var c=a.render();return void a._portalReactRoot.render(c)}// If next is a BaseNode or NodeInstance, render its output
|
|
275
|
+
if(b instanceof BaseNode||b&&"function"==typeof b.render){var d=b.render?b.render():b;return void a._portalReactRoot.render(d)}// Otherwise assume a ReactNode and render directly
|
|
276
|
+
a._portalReactRoot.render(b)}catch(a){// swallow
|
|
277
|
+
}},c.unmount=function(){try{b()}catch(a){// swallow
|
|
255
278
|
}// Clear references and remove DOM element
|
|
256
|
-
a._portalDOMElement
|
|
257
|
-
}
|
|
279
|
+
if(a._portalDOMElement){try{a._portalDOMElement.parentNode&&a._portalDOMElement.parentNode.removeChild(a._portalDOMElement)}catch(a){// swallow
|
|
280
|
+
}a._portalDOMElement=null}a._portalReactRoot=null},c}catch(a){// fallback: return the raw root as-is (without update/unmount patch)
|
|
281
|
+
return this._portalReactRoot}}}/**
|
|
258
282
|
* Factory function to create a `BaseNode` instance.
|
|
259
283
|
* @template AdditionalProps Additional props to merge with node props.
|
|
260
284
|
* @template E The React element or component type.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FinalNodeProps, NodeElement } from '../node.type.js';
|
|
1
|
+
import type { FinalNodeProps, NodeElement, NodeInstance } from '../node.type.js';
|
|
2
2
|
import type { ComponentProps, CSSProperties, ElementType } from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* Retrieves a deeply nested value from an object using a dot-separated string path.
|
|
@@ -26,7 +26,7 @@ export declare const getValueByPath: (obj: any, path: string) => any;
|
|
|
26
26
|
* getComponentType(React.memo(() => <div/>)) // 'memo'
|
|
27
27
|
* getComponentType(() => <div/>) // 'function'
|
|
28
28
|
*/
|
|
29
|
-
export declare const getComponentType: (component?: NodeElement) => string;
|
|
29
|
+
export declare const getComponentType: (component?: NodeInstance<NodeElement> | NodeElement) => string;
|
|
30
30
|
/**
|
|
31
31
|
* Generates a string name for an ElementType or ReactElement.
|
|
32
32
|
*
|
|
@@ -77,4 +77,17 @@ export declare function getDOMProps<E extends ElementType, T extends ComponentPr
|
|
|
77
77
|
* @returns `true` if the tag is in the no-style set, otherwise `false`.
|
|
78
78
|
*/
|
|
79
79
|
export declare function hasNoStyleTag(tag?: NodeElement): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Returns a shallow copy of the object with the specified keys omitted.
|
|
82
|
+
* @param obj The source object.
|
|
83
|
+
* @param keys The property keys to omit.
|
|
84
|
+
* @returns A new object without the omitted keys.
|
|
85
|
+
*/
|
|
86
|
+
export declare function omit<T extends object, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K>;
|
|
87
|
+
/**
|
|
88
|
+
* Removes keys from an object whose values are `undefined`.
|
|
89
|
+
* @param obj The source object.
|
|
90
|
+
* @returns A new object without keys that have `undefined` values.
|
|
91
|
+
*/
|
|
92
|
+
export declare function omitUndefined<T extends object>(obj: T): Partial<T>;
|
|
80
93
|
//# sourceMappingURL=common.helper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.helper.d.ts","sourceRoot":"","sources":["../../src/helper/common.helper.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"common.helper.d.ts","sourceRoot":"","sources":["../../src/helper/common.helper.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGvE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,iCAE1B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,iEAmC5B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAsFxD;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAA0B,CAAA;AAEjE;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAU3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAUjH;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAGxD;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAQ1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQlE"}
|
|
@@ -61,4 +61,13 @@ function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
61
61
|
* Checks if a given tag is in the set of tags that should not receive style props.
|
|
62
62
|
* @param tag The tag name to check (e.g., 'script', 'style').
|
|
63
63
|
* @returns `true` if the tag is in the no-style set, otherwise `false`.
|
|
64
|
-
*/export function hasNoStyleTag(a){return!!(a&&"string"==typeof a)&&noStyleTagsSet.has(a.toLowerCase())}
|
|
64
|
+
*/export function hasNoStyleTag(a){return!!(a&&"string"==typeof a)&&noStyleTagsSet.has(a.toLowerCase())}/**
|
|
65
|
+
* Returns a shallow copy of the object with the specified keys omitted.
|
|
66
|
+
* @param obj The source object.
|
|
67
|
+
* @param keys The property keys to omit.
|
|
68
|
+
* @returns A new object without the omitted keys.
|
|
69
|
+
*/export function omit(a){for(var b={},c=arguments.length,d=Array(1<c?c-1:0),e=1;e<c;e++)d[e-1]=arguments[e];for(var f in a)Object.prototype.hasOwnProperty.call(a,f)&&!d.includes(f)&&(b[f]=a[f]);return b}/**
|
|
70
|
+
* Removes keys from an object whose values are `undefined`.
|
|
71
|
+
* @param obj The source object.
|
|
72
|
+
* @returns A new object without keys that have `undefined` values.
|
|
73
|
+
*/export function omitUndefined(a){var b={};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&void 0!==a[c]&&(b[c]=a[c]);return b}
|
|
@@ -115,10 +115,10 @@ minWidth:0},d)};/**
|
|
|
115
115
|
* - element type (string or component name)
|
|
116
116
|
* - key (if present)
|
|
117
117
|
* - basic children shape (recursing within limits)
|
|
118
|
-
*/function nodeSignature(a){var b=Math.min,c=1<arguments.length&&void 0!==arguments[1]?arguments[1]:5,d=2<arguments.length&&void 0!==arguments[2]?arguments[2]:6,e=3<arguments.length&&void 0!==arguments[3]?arguments[3]:new WeakSet;if(null===a)return"null";if(void 0===a)return"undefined";var f=_typeof(a);if("string"===f)return"s:".concat(a);if("number"===f)return"n:".concat(a+"");if("boolean"===f)return"b:".concat(a+"");if("function"===f)return"\u0192()";if("symbol"===f)return"sym:".concat(a+"");// Arrays
|
|
118
|
+
*/function nodeSignature(a){var b=Math.min,c=1<arguments.length&&void 0!==arguments[1]?arguments[1]:5,d=2<arguments.length&&void 0!==arguments[2]?arguments[2]:6,e=3<arguments.length&&void 0!==arguments[3]?arguments[3]:new WeakSet;if(null===a)return"null";if(void 0===a)return"undefined";var f=_typeof(a);if("string"===f)return"s:".concat(a);if("number"===f)return"n:".concat(a+"");if("boolean"===f)return"b:".concat(a+"");if("function"===f)return"\u0192:(".concat(a+"",")");if("symbol"===f)return"sym:".concat(a+"");// Arrays
|
|
119
119
|
if(Array.isArray(a)){if(0>=c)return"ary[...]";for(var g=[],h=b(a.length,d),j=0;j<h;j++)g.push(nodeSignature(a[j],c-1,d,e));return a.length>d&&g.push("...len:".concat(a.length)),"ary[".concat(g.join(","),"]")}// React element-ish: detect common shapes (type + props)
|
|
120
|
-
if("object"===f&&(Object.prototype.hasOwnProperty.call(a,"type")||Object.prototype.hasOwnProperty.call(a,"props"))){var l,m,n=null!==(l=a.type)&&void 0!==l?l:a
|
|
121
|
-
try{
|
|
120
|
+
if("object"===f&&(Object.prototype.hasOwnProperty.call(a,"type")||Object.prototype.hasOwnProperty.call(a,"props"))){var l,m,n,o=null!==(l=a.type)&&void 0!==l?l:a;// Type can be string (div) or function/class. Use helper to get name.
|
|
121
|
+
try{n=getElementTypeName(o)}catch(a){try{n=o+""}catch(a){n="unknown"}}var p,q="key"in a&&void 0!==a.key&&null!==a.key?"#".concat(a.key+""):"",r="props"in a&&"object"===_typeof(a.props)?null!==(m=a.props)&&void 0!==m?m:{}:{};try{p=nodeSignature(r.children,c-1,d,e)}catch(a){p="<err>"}var s=r&&"object"===_typeof(r)&&"id"in r&&r.id?"@id:".concat(r.id+""):"",t=r&&"object"===_typeof(r)&&"className"in r&&r.className?"@class:".concat(r.className+""):"";return"el:".concat(n).concat(q).concat(s).concat(t,"{").concat(p,"}")}// Plain object
|
|
122
122
|
if("object"===f&&a&&"object"===_typeof(a)&&!("type"in a)&&!("props"in a)){if(e.has(a))return"[Circular]";if(e.add(a),0>=c)return"obj[...]";for(var u,v=Object.keys(a).sort(),w=[],x=b(v.length,d),y=0;y<x;y++){u=v[y];try{w.push("".concat(u,":").concat(nodeSignature(a[u],c-1,d,e)))}catch(a){w.push("".concat(u,":<err>"))}}return v.length>d&&w.push("...keys:".concat(v.length)),"obj{".concat(w.join(","),"}")}// Fallback
|
|
123
123
|
try{return"o:".concat(a+"")}catch(a){return"o:<unserializable>"}}/**
|
|
124
124
|
* Public: createStableHash
|
package/dist/hoc/portal.hoc.d.ts
CHANGED
|
@@ -12,8 +12,8 @@ import type { BasePortalProps, ComponentNode, NodeInstance, PortalLauncher, Port
|
|
|
12
12
|
* ```ts
|
|
13
13
|
* // Example of preferred usage with a single fixed provider:
|
|
14
14
|
* const ThemedModal = Portal(
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* ThemeProvider({ theme: 'light' }),
|
|
16
|
+
* (props) => Div({ children: props.children, style: { background: props.nodetheme?.background } })
|
|
17
17
|
* );
|
|
18
18
|
*
|
|
19
19
|
* const modalInstance = ThemedModal({ children: "Preferred content" });
|
|
@@ -31,7 +31,7 @@ export declare function Portal<P extends BasePortalProps | Record<string, any> =
|
|
|
31
31
|
* ```ts
|
|
32
32
|
* // Example of basic usage without fixed providers:
|
|
33
33
|
* const BasicModal = Portal(
|
|
34
|
-
*
|
|
34
|
+
* (props) => Div({ children: props.children, style: { padding: '20px', border: '1px solid black' } })
|
|
35
35
|
* );
|
|
36
36
|
*
|
|
37
37
|
* const basicModalInstance = BasicModal({ children: "Hello from a basic portal!" });
|
|
@@ -39,12 +39,12 @@ export declare function Portal<P extends BasePortalProps | Record<string, any> =
|
|
|
39
39
|
*
|
|
40
40
|
* // Example with dynamic providers when launching:
|
|
41
41
|
* const DynamicThemedModal = Portal(
|
|
42
|
-
*
|
|
42
|
+
* (props) => Div({ children: props.children, style: { background: props.nodetheme?.background || 'white' } })
|
|
43
43
|
* );
|
|
44
44
|
*
|
|
45
45
|
* const dynamicModalInstance = DynamicThemedModal({
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* providers: ThemeProvider({ theme: 'blue' }), // Dynamic provider
|
|
47
|
+
* children: "Content with dynamic theme"
|
|
48
48
|
* });
|
|
49
49
|
* dynamicModalInstance.unmount();
|
|
50
50
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.hoc.d.ts","sourceRoot":"","sources":["../../src/hoc/portal.hoc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"portal.hoc.d.ts","sourceRoot":"","sources":["../../src/hoc/portal.hoc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAe,YAAY,EAAyB,cAAc,EAAE,WAAW,EAAS,MAAM,mBAAmB,CAAA;AAG7J;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,eAAe,EACtF,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,EAC3B,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,aAAa,GAClD,cAAc,CAAC,CAAC,CAAC,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,eAAe,EACtF,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,aAAa,GAClD,cAAc,CAAC,CAAC,CAAC,CAAA"}
|
package/dist/hoc/portal.hoc.js
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* ```ts
|
|
12
12
|
* // Example of preferred usage with a single fixed provider:
|
|
13
13
|
* const ThemedModal = Portal(
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* ThemeProvider({ theme: 'light' }),
|
|
15
|
+
* (props) => Div({ children: props.children, style: { background: props.nodetheme?.background } })
|
|
16
16
|
* );
|
|
17
17
|
*
|
|
18
18
|
* const modalInstance = ThemedModal({ children: "Preferred content" });
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* ```ts
|
|
29
29
|
* // Example of basic usage without fixed providers:
|
|
30
30
|
* const BasicModal = Portal(
|
|
31
|
-
*
|
|
31
|
+
* (props) => Div({ children: props.children, style: { padding: '20px', border: '1px solid black' } })
|
|
32
32
|
* );
|
|
33
33
|
*
|
|
34
34
|
* const basicModalInstance = BasicModal({ children: "Hello from a basic portal!" });
|
|
@@ -36,18 +36,18 @@
|
|
|
36
36
|
*
|
|
37
37
|
* // Example with dynamic providers when launching:
|
|
38
38
|
* const DynamicThemedModal = Portal(
|
|
39
|
-
*
|
|
39
|
+
* (props) => Div({ children: props.children, style: { background: props.nodetheme?.background || 'white' } })
|
|
40
40
|
* );
|
|
41
41
|
*
|
|
42
42
|
* const dynamicModalInstance = DynamicThemedModal({
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* providers: ThemeProvider({ theme: 'blue' }), // Dynamic provider
|
|
44
|
+
* children: "Content with dynamic theme"
|
|
45
45
|
* });
|
|
46
46
|
* dynamicModalInstance.unmount();
|
|
47
47
|
* ```
|
|
48
48
|
*/// --- Implementation ---
|
|
49
49
|
export function Portal(a,b){// --- Initialization ---
|
|
50
|
-
var c,d=void 0,e=
|
|
50
|
+
var c,d=void 0,e={unmount:function unmount(){console.warn("Portal instance not yet created. Cannot unmount.")},update:function update(a){console.warn("Portal instance not yet created. Cannot update.",a)}};// --- Argument Parsing and Overload Handling ---
|
|
51
51
|
// Determines which Portal overload was called (e.g., with fixed provider or just component).
|
|
52
52
|
if("function"==typeof b&&a instanceof BaseNode)// Handles the case where a fixed provider (single) is passed.
|
|
53
53
|
d=[a],c=b;else if("function"==typeof a&&b===void 0)// Handles the case where only the component function is passed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hook/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./usePortal.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import type { NodePortal } from '../node.type.js';
|
|
3
|
+
export declare function usePortal<T extends any[]>(deps?: T): {
|
|
4
|
+
portal: NodePortal | undefined;
|
|
5
|
+
setPortal: (p: NodePortal) => NodePortal;
|
|
6
|
+
createComponent: <P>(fn: (props: P) => ReactElement<unknown, string | import("react").JSXElementConstructor<any>>) => (props: P) => ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=usePortal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePortal.d.ts","sourceRoot":"","sources":["../../src/hook/usePortal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAkC,MAAM,OAAO,CAAA;AACzE,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGpE,wBAAgB,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,IAAI,GAAE,CAAsB;;;sBAGhC,CAAC;EAwBvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}import{useCallback,useEffect,useRef}from"react";import{Node}from"../main.js";export function usePortal(){var a=0<arguments.length&&void 0!==arguments[0]?arguments[0]:[],b=useRef({}),c=useCallback(function(a){return b.current.component=a,new Proxy(a,{apply:function apply(a,c,d){var e=_slicedToArray(d,1),f=e[0];return b.current.props=f,a.call(c,f)}})},[]);return useEffect(function(){var a=b.current,c=a.portal,d=a.component,e=a.props;c&&d&&c.update(Node(d,e))},a),useEffect(function(){return function(){var a;return null===(a=b.current.portal)||void 0===a?void 0:a.unmount()}},[]),{portal:b.current.portal,setPortal:function setPortal(a){return b.current.portal=a},createComponent:c}}
|
package/dist/main.d.ts
CHANGED
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAC7E,cAAc,mBAAmB,CAAA;AACjC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA"}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAC7E,cAAc,mBAAmB,CAAA;AACjC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oBAAoB,CAAA"}
|
package/dist/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{Node,createNode,createChildrenFirstNode}from"./core.node.js";export*from"./hoc/index.js";export*from"./helper/node.helper.js";export*from"./node.type.js";export*from"./components/html.node.js";
|
|
1
|
+
export{Node,createNode,createChildrenFirstNode}from"./core.node.js";export*from"./hoc/index.js";export*from"./helper/node.helper.js";export*from"./node.type.js";export*from"./components/html.node.js";export*from"./hook/index.js";
|
package/dist/node.type.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React, { type CSSProperties, type ReactNode, type JSX, type ElementType, type ComponentType, type JSXElementConstructor, type Component, type ExoticComponent, type ReactElement } from 'react';
|
|
2
|
-
import type { Root as ReactDOMRoot } from 'react-dom/client';
|
|
3
2
|
import type { CSSInterpolation } from '@emotion/serialize';
|
|
4
3
|
import type { NO_STYLE_TAGS } from './constants/common.const.js';
|
|
5
4
|
// --- Utility Types ---
|
|
@@ -22,6 +21,7 @@ export type NonArrayReactNode = Exclude<ReactNode, ReactNode[]>;
|
|
|
22
21
|
* This includes React elements, components, promises resolving to React nodes, and NodeInstance objects.
|
|
23
22
|
*/
|
|
24
23
|
export type NodeElement = ExoticComponent<any> | NonArrayReactNode | Promise<Awaited<NonArrayReactNode>> | Component<any, any, any> | ElementType | ComponentType<any> | NodeInstance<any> | ((props?: any) => NonArrayReactNode | Promise<Awaited<NonArrayReactNode>> | Component<any, any, any> | NodeInstance<any> | ComponentNode);
|
|
24
|
+
export type NodeElementType = ElementType | ExoticComponent<any>;
|
|
25
25
|
/** A single NodeElement or an array of NodeElements */
|
|
26
26
|
export type Children = NodeElement | NodeElement[];
|
|
27
27
|
/**
|
|
@@ -37,8 +37,8 @@ export interface NodeInstance<T extends NodeElement = NodeElement> {
|
|
|
37
37
|
readonly isBaseNode: true;
|
|
38
38
|
/** Converts this node instance into a renderable React element/tree */
|
|
39
39
|
render(): ReactElement;
|
|
40
|
-
/** Creates Portal-compatible React elements for rendering outside
|
|
41
|
-
toPortal():
|
|
40
|
+
/** Creates Portal-compatible React elements for rendering outside the DOM tree */
|
|
41
|
+
toPortal(): NodePortal;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Infers the props type for a given NodeElement.
|
|
@@ -73,7 +73,6 @@ export type Theme = Partial<{
|
|
|
73
73
|
*/
|
|
74
74
|
export type FinalNodeProps = ReactAttributes & Partial<{
|
|
75
75
|
nativeProps: Omit<Omit<PropsOf<NodeElement>, 'children'>, 'style'>;
|
|
76
|
-
key: React.Key | any | null | undefined;
|
|
77
76
|
ref: any | React.Ref<unknown> | undefined;
|
|
78
77
|
style: any;
|
|
79
78
|
css: any;
|
|
@@ -111,7 +110,7 @@ export type HasNoStyleProp<E extends NodeElement> = E extends NoStyleTags ? true
|
|
|
111
110
|
* - Maintains React's key prop for reconciliation
|
|
112
111
|
* @template E - The element type these props apply to
|
|
113
112
|
*/
|
|
114
|
-
export type NodeProps<E extends NodeElement> = Omit<PropsOf<E>, keyof CSSProperties | 'children' | 'style' | 'theme' | 'props'> & ReactAttributes & (HasCSSCompatibleStyleProp<PropsOf<E>> extends true ? CSSProperties : object) & (HasNoStyleProp<E> extends true ? Partial<{
|
|
113
|
+
export type NodeProps<E extends NodeElement> = Omit<PropsOf<E>, keyof CSSProperties | 'children' | 'style' | 'theme' | 'props' | 'key'> & ReactAttributes & (HasCSSCompatibleStyleProp<PropsOf<E>> extends true ? CSSProperties : object) & (HasNoStyleProp<E> extends true ? Partial<{
|
|
115
114
|
css: CSSInterpolation;
|
|
116
115
|
}> : object) & Partial<{
|
|
117
116
|
props: Partial<Omit<PropsOf<E>, 'children'>>;
|
|
@@ -164,6 +163,14 @@ export interface BasePortalProps {
|
|
|
164
163
|
* @template T The component's own prop types
|
|
165
164
|
*/
|
|
166
165
|
export type PortalProps<T extends BasePortalProps | Record<string, any>> = T & BasePortalProps;
|
|
166
|
+
/**
|
|
167
|
+
* Interface representing a portal instance with lifecycle methods.
|
|
168
|
+
* Provides methods to unmount the portal and update its content dynamically.
|
|
169
|
+
*/
|
|
170
|
+
export interface NodePortal {
|
|
171
|
+
unmount: () => void;
|
|
172
|
+
update: (node: NodeElement) => void;
|
|
173
|
+
}
|
|
167
174
|
/**
|
|
168
175
|
* Function type for creating portal instances.
|
|
169
176
|
* Allows passing providers through props at portal creation time.
|
|
@@ -172,10 +179,10 @@ export type PortalProps<T extends BasePortalProps | Record<string, any>> = T & B
|
|
|
172
179
|
export type PortalLauncher<P extends BasePortalProps | Record<string, any>> = P extends BasePortalProps ? (props?: {
|
|
173
180
|
/** Optional provider components to wrap the portal content */
|
|
174
181
|
provider?: NodeInstance<any>;
|
|
175
|
-
}) =>
|
|
182
|
+
}) => NodePortal : (props: P & {
|
|
176
183
|
/** Optional provider components to wrap the portal content */
|
|
177
184
|
provider?: NodeInstance<any>;
|
|
178
|
-
} & Omit<PortalProps<P>, 'portal'>) =>
|
|
185
|
+
} & Omit<PortalProps<P>, 'portal'>) => NodePortal;
|
|
179
186
|
/**
|
|
180
187
|
* Merges `NodeProps<E>` with additional custom props, giving precedence to `AdditionalProps`.
|
|
181
188
|
* Useful for extending node props with extra properties, while overriding any overlapping keys.
|
package/dist/node.type.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../src/node.type.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EACZ,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,GAAG,EACR,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../src/node.type.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meonode/ui",
|
|
3
3
|
"description": "A structured approach to component composition, direct CSS-first prop styling, built-in theming, smart prop handling (including raw property pass-through), and dynamic children.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/main.js",
|
|
7
7
|
"types": "./dist/main.d.ts",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --ci",
|
|
33
33
|
"prebuild": "yarn lint && yarn test",
|
|
34
34
|
"build": "yarn prebuild && rm -rf ./dist && babel src --out-dir dist --extensions \".ts,.tsx,.js\" && tsgo --project tsconfig.build.json --diagnostics && tsc-alias",
|
|
35
|
-
"publish:pre": "./prepublish.sh && yarn version -i prerelease && yarn npm publish --tag next",
|
|
36
|
-
"publish:patch": "./prepublish.sh && yarn version -i patch && yarn npm publish --tag latest",
|
|
37
|
-
"publish:minor": "./prepublish.sh && yarn version -i minor && yarn npm publish --tag latest",
|
|
38
|
-
"publish:major": "./prepublish.sh && yarn version -i major && yarn npm publish --tag latest",
|
|
35
|
+
"publish:pre": "./prepublish.sh && yarn build && yarn version -i prerelease && yarn npm publish --tag next",
|
|
36
|
+
"publish:patch": "./prepublish.sh && yarn build && yarn version -i patch && yarn npm publish --tag latest",
|
|
37
|
+
"publish:minor": "./prepublish.sh && yarn build && yarn version -i minor && yarn npm publish --tag latest",
|
|
38
|
+
"publish:major": "./prepublish.sh && yarn build && yarn version -i major && yarn npm publish --tag latest",
|
|
39
39
|
"prepare": "husky"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|