@vitus-labs/core 1.2.2 → 1.2.3-alpha.3

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/lib/index.js CHANGED
@@ -1,276 +1,432 @@
1
- export { get, merge, omit, pick, set, throttle } from 'lodash-es';
2
- export { default as memoize } from 'moize';
3
- import { ThemeProvider, styled, css } from 'styled-components';
4
- import React, { createContext, useMemo, isValidElement, createElement, cloneElement } from 'react';
5
- import { isFragment, isValidElementType } from 'react-is';
1
+ import { ThemeProvider, css, styled } from "styled-components";
2
+ import { cloneElement, createContext, createElement, isValidElement, useMemo } from "react";
3
+ import { Fragment, jsx } from "react/jsx-runtime";
4
+ import { isFragment, isMemo, isValidElementType } from "react-is";
6
5
 
7
- class Configuration {
8
- css;
9
- styled;
10
- ExternalProvider;
11
- component = 'div';
12
- textComponent = 'span';
13
- constructor(props) {
14
- this.css = props.css;
15
- this.styled = props.styled;
16
- this.ExternalProvider = props.provider;
17
- this.component = props.component;
18
- this.textComponent = props.textComponent;
19
- }
20
- init = (props) => {
21
- if (props.css) {
22
- this.css = props.css;
23
- }
24
- if (props.styled) {
25
- this.styled = props.styled;
26
- }
27
- if (props.provider) {
28
- this.ExternalProvider = props.provider;
29
- }
30
- if (props.component) {
31
- this.component = props.component;
32
- }
33
- if (props.textComponent) {
34
- this.textComponent = props.textComponent;
35
- }
36
- };
37
- }
38
- const defaultParams = {
39
- css,
40
- styled,
41
- provider: ThemeProvider,
42
- component: 'div',
43
- textComponent: 'span',
6
+ //#region src/compose.ts
7
+ /**
8
+ * Right-to-left function composition.
9
+ * `compose(f, g, h)(x)` === `f(g(h(x)))`.
10
+ *
11
+ * Used throughout the system to build HOC chains —
12
+ * `compose(attrsHoc, userHoc1, userHoc2)(Component)`.
13
+ */
14
+ const compose = (...fns) => (p) => fns.reduceRight((acc, cur) => cur(acc), p);
15
+
16
+ //#endregion
17
+ //#region src/config.ts
18
+ var Configuration = class {
19
+ css;
20
+ styled;
21
+ ExternalProvider;
22
+ component = "div";
23
+ textComponent = "span";
24
+ constructor(props) {
25
+ this.css = props.css;
26
+ this.styled = props.styled;
27
+ this.ExternalProvider = props.provider;
28
+ this.component = props.component;
29
+ this.textComponent = props.textComponent;
30
+ }
31
+ init = (props) => {
32
+ if (props.css) this.css = props.css;
33
+ if (props.styled) this.styled = props.styled;
34
+ if (props.provider) this.ExternalProvider = props.provider;
35
+ if (props.component) this.component = props.component;
36
+ if (props.textComponent) this.textComponent = props.textComponent;
37
+ };
44
38
  };
45
- const config = new Configuration(defaultParams);
39
+ const config = new Configuration({
40
+ css,
41
+ styled,
42
+ provider: ThemeProvider,
43
+ component: "div",
44
+ textComponent: "span"
45
+ });
46
46
  const { init } = config;
47
47
 
48
+ //#endregion
49
+ //#region src/isEmpty.ts
48
50
  const isEmpty = (param) => {
49
- if (!param || param === null)
50
- return true;
51
- if (typeof param !== 'object') {
52
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
53
- return true;
54
- }
55
- if (Array.isArray(param) && param.length === 0) {
56
- return true;
57
- }
58
- if (Object.entries(param).length === 0 && param.constructor === Object) {
59
- return true;
60
- }
61
- return false;
51
+ if (!param) return true;
52
+ if (typeof param !== "object") return true;
53
+ if (Array.isArray(param)) return param.length === 0;
54
+ return Object.keys(param).length === 0;
62
55
  };
63
56
 
57
+ //#endregion
58
+ //#region src/context.tsx
59
+ /**
60
+ * Internal React context shared across all @vitus-labs packages.
61
+ * Carries the theme object plus any extra provider props.
62
+ */
64
63
  const context = createContext({});
65
64
  const VitusLabsProvider = context.Provider;
65
+ /**
66
+ * Dual-layer provider that feeds both the internal VitusLabs context
67
+ * and an optional external styling provider (e.g. styled-components'
68
+ * ThemeProvider). When no theme is supplied, renders children directly.
69
+ */
66
70
  const Provider = ({ theme, children, ...props }) => {
67
- const ExternalProvider = useMemo(() => config.ExternalProvider, []);
68
- const context = useMemo(() => ({ theme, ...props }), [theme, props]);
69
- // eslint-disable-next-line react/jsx-no-useless-fragment
70
- if (isEmpty(theme) || !theme)
71
- return React.createElement(React.Fragment, null, children);
72
- if (ExternalProvider) {
73
- return (React.createElement(VitusLabsProvider, { value: context },
74
- React.createElement(ExternalProvider, { theme: theme }, children)));
75
- }
76
- return React.createElement(VitusLabsProvider, { value: context }, children);
71
+ const ExternalProvider = useMemo(() => config.ExternalProvider, []);
72
+ const context = useMemo(() => ({
73
+ theme,
74
+ ...props
75
+ }), [
76
+ theme,
77
+ ...Object.values(props),
78
+ props
79
+ ]);
80
+ if (isEmpty(theme) || !theme) return /* @__PURE__ */ jsx(Fragment, { children });
81
+ if (ExternalProvider) return /* @__PURE__ */ jsx(VitusLabsProvider, {
82
+ value: context,
83
+ children: /* @__PURE__ */ jsx(ExternalProvider, {
84
+ theme,
85
+ children
86
+ })
87
+ });
88
+ return /* @__PURE__ */ jsx(VitusLabsProvider, {
89
+ value: context,
90
+ children
91
+ });
77
92
  };
78
93
 
79
- const compose = (...fns) => (p) =>
80
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
81
- fns.reduceRight((acc, cur) => cur(acc), p);
82
-
83
- const render = (content, attachProps) => {
84
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
85
- if (!content)
86
- return null;
87
- const isValidEl = isValidElement(content);
88
- const render = (child) => attachProps ? createElement(child, attachProps) : createElement(child);
89
- if (typeof content === 'string' && isValidEl) {
90
- return render(content);
91
- }
92
- if (['number', 'boolean', 'bigint', 'string'].includes(typeof content)) {
93
- return content;
94
- }
95
- if (Array.isArray(content) || isFragment(content)) {
96
- return content;
97
- }
98
- if (isValidElementType(content)) {
99
- return render(content);
100
- }
101
- if (isValidEl) {
102
- if (isEmpty(attachProps)) {
103
- return content;
104
- }
105
- return cloneElement(content, attachProps);
106
- }
107
- return content;
94
+ //#endregion
95
+ //#region src/hoistNonReactStatics.ts
96
+ const REACT_STATICS = {
97
+ childContextTypes: true,
98
+ contextType: true,
99
+ contextTypes: true,
100
+ defaultProps: true,
101
+ displayName: true,
102
+ getDefaultProps: true,
103
+ getDerivedStateFromError: true,
104
+ getDerivedStateFromProps: true,
105
+ mixins: true,
106
+ propTypes: true,
107
+ type: true
108
+ };
109
+ const KNOWN_STATICS = {
110
+ name: true,
111
+ length: true,
112
+ prototype: true,
113
+ caller: true,
114
+ callee: true,
115
+ arguments: true,
116
+ arity: true
117
+ };
118
+ const FORWARD_REF_STATICS = {
119
+ $$typeof: true,
120
+ render: true,
121
+ defaultProps: true,
122
+ displayName: true,
123
+ propTypes: true
124
+ };
125
+ const MEMO_STATICS = {
126
+ $$typeof: true,
127
+ compare: true,
128
+ defaultProps: true,
129
+ displayName: true,
130
+ propTypes: true,
131
+ type: true
132
+ };
133
+ const TYPE_STATICS = {};
134
+ TYPE_STATICS[Symbol.for("react.forward_ref")] = FORWARD_REF_STATICS;
135
+ TYPE_STATICS[Symbol.for("react.memo")] = MEMO_STATICS;
136
+ const getStatics = (component) => {
137
+ if (isMemo(component)) return MEMO_STATICS;
138
+ return TYPE_STATICS[component.$$typeof] || REACT_STATICS;
139
+ };
140
+ const hoistNonReactStatics = (target, source, excludeList) => {
141
+ if (typeof source === "string") return target;
142
+ const proto = Object.getPrototypeOf(source);
143
+ if (proto && proto !== Object.prototype) hoistNonReactStatics(target, proto, excludeList);
144
+ const keys = [...Object.getOwnPropertyNames(source), ...Object.getOwnPropertySymbols(source)];
145
+ const targetStatics = getStatics(target);
146
+ const sourceStatics = getStatics(source);
147
+ for (const key of keys) {
148
+ const k = key;
149
+ if (KNOWN_STATICS[k] || excludeList?.[k] || sourceStatics[k] || targetStatics[k]) continue;
150
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
151
+ if (descriptor) try {
152
+ Object.defineProperty(target, key, descriptor);
153
+ } catch {}
154
+ }
155
+ return target;
108
156
  };
109
157
 
158
+ //#endregion
159
+ //#region src/html/htmlTags.ts
110
160
  const HTML_TAGS = [
111
- 'a',
112
- 'abbr',
113
- // 'acronym',
114
- 'address',
115
- // 'applet',
116
- 'area',
117
- 'article',
118
- 'aside',
119
- 'audio',
120
- 'b',
121
- // 'base',
122
- // 'basefont',
123
- 'bdi',
124
- 'bdo',
125
- 'big',
126
- 'blockquote',
127
- 'body',
128
- 'br',
129
- 'button',
130
- 'canvas',
131
- 'caption',
132
- // 'center',
133
- 'cite',
134
- 'code',
135
- 'col',
136
- 'colgroup',
137
- 'data',
138
- 'datalist',
139
- 'dd',
140
- 'del',
141
- 'details',
142
- 'dfn',
143
- 'dialog',
144
- // 'dir',
145
- 'div',
146
- 'dl',
147
- 'dt',
148
- 'em',
149
- 'embed',
150
- 'fieldset',
151
- 'figcaption',
152
- 'figure',
153
- // 'font',
154
- 'footer',
155
- 'form',
156
- // 'frame',
157
- // 'frameset',
158
- 'h1',
159
- 'h2',
160
- 'h3',
161
- 'h4',
162
- 'h5',
163
- 'h6',
164
- // 'head',
165
- 'header',
166
- 'hr',
167
- 'html',
168
- 'i',
169
- 'iframe',
170
- 'img',
171
- 'input',
172
- 'ins',
173
- 'kbd',
174
- 'label',
175
- 'legend',
176
- 'li',
177
- // 'link',
178
- 'main',
179
- 'map',
180
- 'mark',
181
- // 'meta',
182
- 'meter',
183
- 'nav',
184
- // 'noframes',
185
- // 'noscript',
186
- 'object',
187
- 'ol',
188
- 'optgroup',
189
- 'option',
190
- 'output',
191
- 'p',
192
- // 'param',
193
- 'picture',
194
- 'pre',
195
- 'progress',
196
- 'q',
197
- 'rp',
198
- 'rt',
199
- 'ruby',
200
- 's',
201
- 'samp',
202
- // 'script',
203
- 'section',
204
- 'select',
205
- 'small',
206
- 'source',
207
- 'span',
208
- // 'strike',
209
- 'strong',
210
- // 'style',
211
- 'sub',
212
- 'summary',
213
- 'sup',
214
- 'svg',
215
- 'table',
216
- 'tbody',
217
- 'td',
218
- 'template',
219
- 'textarea',
220
- 'tfoot',
221
- 'th',
222
- 'thead',
223
- 'time',
224
- // 'title',
225
- 'tr',
226
- 'track',
227
- // 'tt',
228
- 'u',
229
- 'ul',
230
- 'var',
231
- 'video',
232
- 'wbr',
161
+ "a",
162
+ "abbr",
163
+ "address",
164
+ "area",
165
+ "article",
166
+ "aside",
167
+ "audio",
168
+ "b",
169
+ "bdi",
170
+ "bdo",
171
+ "big",
172
+ "blockquote",
173
+ "body",
174
+ "br",
175
+ "button",
176
+ "canvas",
177
+ "caption",
178
+ "cite",
179
+ "code",
180
+ "col",
181
+ "colgroup",
182
+ "data",
183
+ "datalist",
184
+ "dd",
185
+ "del",
186
+ "details",
187
+ "dfn",
188
+ "dialog",
189
+ "div",
190
+ "dl",
191
+ "dt",
192
+ "em",
193
+ "embed",
194
+ "fieldset",
195
+ "figcaption",
196
+ "figure",
197
+ "footer",
198
+ "form",
199
+ "h1",
200
+ "h2",
201
+ "h3",
202
+ "h4",
203
+ "h5",
204
+ "h6",
205
+ "header",
206
+ "hr",
207
+ "html",
208
+ "i",
209
+ "iframe",
210
+ "img",
211
+ "input",
212
+ "ins",
213
+ "kbd",
214
+ "label",
215
+ "legend",
216
+ "li",
217
+ "main",
218
+ "map",
219
+ "mark",
220
+ "meter",
221
+ "nav",
222
+ "object",
223
+ "ol",
224
+ "optgroup",
225
+ "option",
226
+ "output",
227
+ "p",
228
+ "picture",
229
+ "pre",
230
+ "progress",
231
+ "q",
232
+ "rp",
233
+ "rt",
234
+ "ruby",
235
+ "s",
236
+ "samp",
237
+ "section",
238
+ "select",
239
+ "small",
240
+ "source",
241
+ "span",
242
+ "strong",
243
+ "sub",
244
+ "summary",
245
+ "sup",
246
+ "svg",
247
+ "table",
248
+ "tbody",
249
+ "td",
250
+ "template",
251
+ "textarea",
252
+ "tfoot",
253
+ "th",
254
+ "thead",
255
+ "time",
256
+ "tr",
257
+ "track",
258
+ "u",
259
+ "ul",
260
+ "var",
261
+ "video",
262
+ "wbr"
233
263
  ];
234
264
  const HTML_TEXT_TAGS = [
235
- 'abbr',
236
- 'b',
237
- 'bdi',
238
- 'bdo',
239
- 'big',
240
- 'blockquote',
241
- 'cite',
242
- 'code',
243
- 'dl',
244
- 'dt',
245
- 'em',
246
- 'figcaption',
247
- 'h1',
248
- 'h2',
249
- 'h3',
250
- 'h4',
251
- 'h5',
252
- 'h6',
253
- 'i',
254
- 'ins',
255
- 'kbd',
256
- 'label',
257
- 'legend',
258
- 'li',
259
- 'p',
260
- 'pre',
261
- 'q',
262
- 'rp',
263
- 'rt',
264
- 's',
265
- 'small',
266
- 'span',
267
- 'strong',
268
- 'sub',
269
- 'summary',
270
- 'sup',
271
- 'time',
272
- 'u',
265
+ "abbr",
266
+ "b",
267
+ "bdi",
268
+ "bdo",
269
+ "big",
270
+ "blockquote",
271
+ "cite",
272
+ "code",
273
+ "del",
274
+ "div",
275
+ "dl",
276
+ "dt",
277
+ "em",
278
+ "figcaption",
279
+ "h1",
280
+ "h2",
281
+ "h3",
282
+ "h4",
283
+ "h5",
284
+ "h6",
285
+ "i",
286
+ "ins",
287
+ "kbd",
288
+ "label",
289
+ "legend",
290
+ "li",
291
+ "p",
292
+ "pre",
293
+ "q",
294
+ "rp",
295
+ "rt",
296
+ "s",
297
+ "small",
298
+ "span",
299
+ "strong",
300
+ "sub",
301
+ "summary",
302
+ "sup",
303
+ "time",
304
+ "u"
273
305
  ];
274
306
 
275
- export { HTML_TAGS, HTML_TEXT_TAGS, Provider, compose, config, context, init, isEmpty, render };
276
- //# sourceMappingURL=index.js.map
307
+ //#endregion
308
+ //#region src/render.ts
309
+ const render = (content, attachProps) => {
310
+ if (!content) return null;
311
+ const render = (child) => attachProps ? createElement(child, attachProps) : createElement(child);
312
+ if ([
313
+ "number",
314
+ "boolean",
315
+ "bigint",
316
+ "string"
317
+ ].includes(typeof content)) return content;
318
+ if (Array.isArray(content) || isFragment(content)) return content;
319
+ if (isValidElementType(content)) return render(content);
320
+ if (isValidElement(content)) {
321
+ if (isEmpty(attachProps)) return content;
322
+ return cloneElement(content, attachProps);
323
+ }
324
+ return content;
325
+ };
326
+
327
+ //#endregion
328
+ //#region src/utils.ts
329
+ const omit = (obj, keys) => {
330
+ if (obj == null) return {};
331
+ if (!keys || keys.length === 0) return { ...obj };
332
+ const result = {};
333
+ const keysSet = new Set(keys);
334
+ for (const key in obj) if (Object.hasOwn(obj, key) && !keysSet.has(key)) result[key] = obj[key];
335
+ return result;
336
+ };
337
+ const pick = (obj, keys) => {
338
+ if (obj == null) return {};
339
+ if (!keys || keys.length === 0) return { ...obj };
340
+ const result = {};
341
+ for (const key of keys) {
342
+ const k = key;
343
+ if (Object.hasOwn(obj, k)) result[k] = obj[k];
344
+ }
345
+ return result;
346
+ };
347
+ const PATH_RE = /[^.[\]]+/g;
348
+ /** Split a dot/bracket path string into individual key tokens. */
349
+ const parsePath = (path) => {
350
+ if (Array.isArray(path)) return path;
351
+ return path.match(PATH_RE) ?? [];
352
+ };
353
+ const get = (obj, path, defaultValue) => {
354
+ const keys = parsePath(path);
355
+ let result = obj;
356
+ for (const key of keys) {
357
+ if (result == null) return defaultValue;
358
+ result = result[key];
359
+ }
360
+ return result === void 0 ? defaultValue : result;
361
+ };
362
+ const UNSAFE_KEYS = new Set([
363
+ "__proto__",
364
+ "prototype",
365
+ "constructor"
366
+ ]);
367
+ const set = (obj, path, value) => {
368
+ const keys = parsePath(path);
369
+ if (keys.some((k) => UNSAFE_KEYS.has(k))) return obj;
370
+ let current = obj;
371
+ for (let i = 0; i < keys.length - 1; i++) {
372
+ const key = keys[i];
373
+ const nextKey = keys[i + 1];
374
+ if (current[key] == null) current[key] = /^\d+$/.test(nextKey) ? [] : {};
375
+ current = current[key];
376
+ }
377
+ const lastKey = keys[keys.length - 1];
378
+ if (lastKey != null) current[lastKey] = value;
379
+ return obj;
380
+ };
381
+ const throttle = (fn, wait = 0) => {
382
+ let lastCallTime;
383
+ let timeoutId;
384
+ let lastArgs;
385
+ const throttled = (...args) => {
386
+ const now = Date.now();
387
+ if (lastCallTime === void 0 || now - lastCallTime >= wait) {
388
+ lastCallTime = now;
389
+ fn(...args);
390
+ } else {
391
+ lastArgs = args;
392
+ if (timeoutId === void 0) {
393
+ const remaining = wait - (now - lastCallTime);
394
+ timeoutId = setTimeout(() => {
395
+ lastCallTime = Date.now();
396
+ timeoutId = void 0;
397
+ if (lastArgs) {
398
+ fn(...lastArgs);
399
+ lastArgs = void 0;
400
+ }
401
+ }, remaining);
402
+ }
403
+ }
404
+ };
405
+ throttled.cancel = () => {
406
+ if (timeoutId !== void 0) {
407
+ clearTimeout(timeoutId);
408
+ timeoutId = void 0;
409
+ }
410
+ lastArgs = void 0;
411
+ lastCallTime = void 0;
412
+ };
413
+ return throttled;
414
+ };
415
+ const isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
416
+ const merge = (target, ...sources) => {
417
+ for (const source of sources) {
418
+ if (source == null) continue;
419
+ for (const key of Object.keys(source)) {
420
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
421
+ const targetVal = target[key];
422
+ const sourceVal = source[key];
423
+ if (isPlainObject(targetVal) && isPlainObject(sourceVal)) target[key] = merge({ ...targetVal }, sourceVal);
424
+ else target[key] = sourceVal;
425
+ }
426
+ }
427
+ return target;
428
+ };
429
+
430
+ //#endregion
431
+ export { HTML_TAGS, HTML_TEXT_TAGS, Provider, compose, config, context, get, hoistNonReactStatics, init, isEmpty, merge, omit, pick, render, set, throttle };
432
+ //# sourceMappingURL=index.js.map