@zuzjs/ui 0.3.1 → 0.3.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/dist/index.js +232 -92
- package/dist/styles.css +2 -2
- package/jest.config.js +7 -0
- package/package.json +1 -1
- package/rollup.config.js +68 -0
- package/src/comps/box.tsx +1 -0
- package/src/comps/button.tsx +1 -0
- package/src/comps/contextmenu.tsx +38 -19
- package/src/comps/input.tsx +141 -6
- package/src/comps/mediaplayer.tsx +12 -0
- package/src/comps/toaster.tsx +11 -5
- package/src/context/store/theme.tsx +2 -2
- package/src/core/index.ts +79 -5
- package/src/core/styles.ts +12 -1
- package/src/hooks/index.tsx +2 -1
- package/src/hooks/useContextMenu.tsx +86 -51
- package/src/hooks/useDevice.tsx +27 -23
- package/src/hooks/useMediaPlayer.tsx +27 -0
- package/src/hooks/useNavigator.tsx +6 -0
- package/src/hooks/useRender.tsx +29 -0
- package/src/index.tsx +1 -3
- package/src/scss/style.scss +2 -2
- package/tsconfig.json +21 -0
- package/tsconfig.lib.json +9 -0
- package/tsconfig.spec.json +21 -0
- package/src/core/defaultTheme.ts +0 -90
- package/src/redux/slices/app.js +0 -26
- package/src/redux/slices/form.js +0 -46
- package/src/redux/store.js +0 -33
package/dist/index.js
CHANGED
|
@@ -7,7 +7,6 @@ import axios from 'axios';
|
|
|
7
7
|
import { nanoid } from 'nanoid';
|
|
8
8
|
import { ClassNames } from '@emotion/react';
|
|
9
9
|
import ReactDOM from 'react-dom/client';
|
|
10
|
-
export { Link } from 'react-router-dom';
|
|
11
10
|
import styled from '@emotion/styled';
|
|
12
11
|
|
|
13
12
|
const AppContext = createContext({});
|
|
@@ -50,7 +49,12 @@ function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
|
50
49
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
51
50
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
52
51
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
53
|
-
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
55
|
+
var e = new Error(message);
|
|
56
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
|
+
};
|
|
54
58
|
|
|
55
59
|
var _AppTheme_mode, _AppTheme_listen, _AppTheme_lightTheme, _AppTheme_darkTheme;
|
|
56
60
|
class AppTheme {
|
|
@@ -62,11 +66,11 @@ class AppTheme {
|
|
|
62
66
|
this.get = () => {
|
|
63
67
|
let self = this;
|
|
64
68
|
if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "auto") {
|
|
65
|
-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
|
69
|
+
typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
|
66
70
|
__classPrivateFieldSet(self, _AppTheme_mode, event.matches ? "dark" : "light", "f");
|
|
67
71
|
__classPrivateFieldGet(self, _AppTheme_listen, "f").call(self, __classPrivateFieldGet(self, _AppTheme_mode, "f"));
|
|
68
72
|
});
|
|
69
|
-
return window.matchMedia &&
|
|
73
|
+
return typeof window !== 'undefined' && window.matchMedia &&
|
|
70
74
|
window.matchMedia('(prefers-color-scheme: dark)').matches ?
|
|
71
75
|
__classPrivateFieldGet(self, _AppTheme_darkTheme, "f") : __classPrivateFieldGet(self, _AppTheme_lightTheme, "f");
|
|
72
76
|
}
|
|
@@ -155,7 +159,7 @@ const AppProvider = ({ children, initialState = {}, theme = {}, lang = {} }) =>
|
|
|
155
159
|
// }
|
|
156
160
|
// }, [_dispatch]);
|
|
157
161
|
const providedValue = useMemo(() => (Object.assign(Object.assign({}, state), { dispatch })), [state]);
|
|
158
|
-
return jsx(AppContext.Provider,
|
|
162
|
+
return jsx(AppContext.Provider, { value: providedValue, children: children });
|
|
159
163
|
};
|
|
160
164
|
AppProvider.defaultProps = {
|
|
161
165
|
theme: {},
|
|
@@ -198,6 +202,10 @@ const cssProps = {
|
|
|
198
202
|
"ac": "align-content",
|
|
199
203
|
"alignContent": "align-content",
|
|
200
204
|
"aic": "aic",
|
|
205
|
+
"ais": "ais",
|
|
206
|
+
"aie": "aie",
|
|
207
|
+
"nous": "nous",
|
|
208
|
+
"nope": "nope",
|
|
201
209
|
"ai": "align-items",
|
|
202
210
|
"alignItems": "align-items",
|
|
203
211
|
"ass": "ass",
|
|
@@ -454,6 +462,7 @@ const cssProps = {
|
|
|
454
462
|
"wordBreak": "word-break",
|
|
455
463
|
"wordSpacing": "word-spacing",
|
|
456
464
|
"wrap": "wrap",
|
|
465
|
+
"textWrap": "textWrap",
|
|
457
466
|
"wordWrap": "word-wrap",
|
|
458
467
|
"writingMode": "writing-mode",
|
|
459
468
|
"zIndex": "z-index",
|
|
@@ -490,6 +499,8 @@ const cssPropsDirect = {
|
|
|
490
499
|
'flex': 'display: flex;',
|
|
491
500
|
'fwrap': 'flex-wrap: wrap;',
|
|
492
501
|
'aic': 'align-items: center;',
|
|
502
|
+
'ais': 'align-items: flex-start;',
|
|
503
|
+
'aie': 'align-items: flex-end;',
|
|
493
504
|
'ass': 'align-self: flex-start;',
|
|
494
505
|
'asc': 'align-self: center;',
|
|
495
506
|
'ase': 'align-self: flex-end;',
|
|
@@ -502,13 +513,17 @@ const cssPropsDirect = {
|
|
|
502
513
|
'block': 'display: block;',
|
|
503
514
|
'bold': "font-weight: bold;",
|
|
504
515
|
'wrap': "word-wrap: break-word;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 99%;",
|
|
516
|
+
'textWrap': "word-wrap: break-word;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 99%;",
|
|
505
517
|
'pointer': "cursor: pointer;",
|
|
506
518
|
'fb': 'font-family: var(--primary-font-bold);',
|
|
507
519
|
'ph': 'padding-left: __VALUE__;padding-right: __VALUE__;',
|
|
508
520
|
'pv': 'padding-bottom: __VALUE__;padding-top: __VALUE__;',
|
|
509
521
|
'mv': 'margin-bottom: __VALUE__;margin-top: __VALUE__;',
|
|
510
522
|
'mh': 'margin-left: __VALUE__;margin-right: __VALUE__;',
|
|
511
|
-
'anim': 'transition:all __VALUE__s linear 0s;'
|
|
523
|
+
'anim': 'transition:all __VALUE__s linear 0s;',
|
|
524
|
+
'nous': 'user-select: none;',
|
|
525
|
+
'nope': 'pointer-events: none;',
|
|
526
|
+
'tdn': 'text-decoration: none;',
|
|
512
527
|
};
|
|
513
528
|
const cssPropsIgnore = [
|
|
514
529
|
'weight', `opacity`
|
|
@@ -581,27 +596,44 @@ const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
|
|
|
581
596
|
return {};
|
|
582
597
|
};
|
|
583
598
|
|
|
599
|
+
typeof window !== "undefined" && !!document.documentElement.currentStyle;
|
|
584
600
|
const Input = forwardRef((props, ref) => {
|
|
585
|
-
const { as, accept, multiple, onChange, onKeyUp, onClick, readOnly, type, tag, placeholder, name, form, touched, onSubmit, value, defaultValue, fref, autoComplete } = props;
|
|
601
|
+
const { as, accept, multiple, onChange, onKeyUp, onClick, onBlur, onFocus, readOnly, type, tag, placeholder, name, form, touched, onSubmit, value, defaultValue, fref, autoComplete, elastic, minRows, maxRows } = props;
|
|
586
602
|
const dispatch = useDispatch(STORE_FORM_KEY);
|
|
587
603
|
const { forms } = useStore(state => state[STORE_FORM_KEY], false);
|
|
588
604
|
let Tag = tag || 'input';
|
|
589
605
|
const El = Tag;
|
|
590
606
|
const _ref = fref || useRef();
|
|
591
607
|
const _defaultCSS = `width: 100%;border-radius: var(--radius-base);padding-left: 4px;padding-right: 4px;border-style: solid;border-width: 1px;border-color: var(--colors-gray-200);`;
|
|
608
|
+
props.value !== undefined;
|
|
609
|
+
useRef();
|
|
610
|
+
useEffect(() => { }, []);
|
|
592
611
|
return (jsx(ClassNames, { children: ({ css, cx }) => jsx(El, Object.assign({}, cleanProps(props), { type: type || `text`, placeholder: placeholder || undefined, autoComplete: autoComplete || undefined, name: name || nanoid(), multiple: type == 'file' ? multiple : undefined, accept: accept || `*`, className: `${as ? `${as} ` : ``}f ${cx(css `${_defaultCSS}${buildCSS(props)}&:hover {${buildCSS(props.hover || {})}} &:focus {${buildCSS(props.focus || {})}}`)}`, ref: _ref, value: value || undefined, defaultValue: defaultValue || ``, onKeyUp: (e) => {
|
|
593
612
|
let k = e['keyCode'] || ['which'];
|
|
594
|
-
if (El != 'textarea' && k == 13
|
|
613
|
+
if (form && onSubmit && El != 'textarea' && k == 13) {
|
|
595
614
|
onSubmit(forms[form]);
|
|
596
615
|
}
|
|
616
|
+
else {
|
|
617
|
+
if (onKeyUp)
|
|
618
|
+
onKeyUp(e);
|
|
619
|
+
}
|
|
597
620
|
}, onChange: e => {
|
|
598
621
|
let val = type == 'file' ?
|
|
599
622
|
e.currentTarget.files
|
|
600
623
|
: e.currentTarget.value;
|
|
601
|
-
|
|
624
|
+
if (form)
|
|
625
|
+
dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val == "" ? null : val, forms)));
|
|
626
|
+
// if(El == `textarea` && elastic) handleElastic()
|
|
602
627
|
onChange && onChange(val == "" ? null : val);
|
|
603
628
|
}, onClick: onClick ? onClick : () => { }, readOnly: readOnly || false, onBlur: e => {
|
|
604
|
-
|
|
629
|
+
if (onBlur)
|
|
630
|
+
onBlur(e);
|
|
631
|
+
}, onFocus: e => {
|
|
632
|
+
if (touched == false)
|
|
633
|
+
dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms));
|
|
634
|
+
if (onFocus)
|
|
635
|
+
onFocus(e);
|
|
636
|
+
} })) }));
|
|
605
637
|
});
|
|
606
638
|
|
|
607
639
|
const Select = forwardRef((props, ref) => {
|
|
@@ -614,12 +646,12 @@ const Select = forwardRef((props, ref) => {
|
|
|
614
646
|
var _a;
|
|
615
647
|
dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, defaultValue && defaultValue != null && defaultValue != "" && defaultValue != undefined ? defaultValue : ((_a = options[0]) === null || _a === void 0 ? void 0 : _a.value) || '-1', forms)));
|
|
616
648
|
}, []);
|
|
617
|
-
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("select",
|
|
649
|
+
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("select", { onChange: e => {
|
|
618
650
|
let val = e.currentTarget.value;
|
|
619
651
|
dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val, forms)));
|
|
620
652
|
onChange && onChange(val);
|
|
621
653
|
}, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)), onBlur: e => {
|
|
622
|
-
}, name: name || nanoid(), className: `${as ? as : ``} ${cx(css `${_defaultCSS}${buildCSS(props)}&:hover {${buildCSS(props.hover || {})}}`)}`, ref: _ref
|
|
654
|
+
}, name: name || nanoid(), className: `${as ? as : ``} ${cx(css `${_defaultCSS}${buildCSS(props)}&:hover {${buildCSS(props.hover || {})}}`)}`, ref: _ref, children: options === null || options === void 0 ? void 0 : options.map(o => jsx("option", { value: o.value, children: o.label }, `select-${name}-option-${o.value}`)) }) }));
|
|
623
655
|
});
|
|
624
656
|
|
|
625
657
|
const useTheme = (mod = 'auto') => {
|
|
@@ -756,6 +788,7 @@ const EMPTY_BREAKPOINT = {
|
|
|
756
788
|
minWidth: undefined,
|
|
757
789
|
maxWidth: undefined,
|
|
758
790
|
};
|
|
791
|
+
const isBrowser = typeof window !== 'undefined';
|
|
759
792
|
const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
|
|
760
793
|
const buildQueries = (breakpoints) => {
|
|
761
794
|
const sorted = Object.keys(breakpoints).sort((a, b) => breakpoints[b] - breakpoints[a]);
|
|
@@ -796,7 +829,7 @@ const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
|
|
|
796
829
|
*/
|
|
797
830
|
if (typeof window !== 'undefined' &&
|
|
798
831
|
!(defaultBreakpoint && hydrateInitial)) {
|
|
799
|
-
const mediaQuery = window.matchMedia(query);
|
|
832
|
+
const mediaQuery = window === null || window === void 0 ? void 0 : window.matchMedia(query);
|
|
800
833
|
if (mediaQuery.matches) {
|
|
801
834
|
return breakpoint;
|
|
802
835
|
}
|
|
@@ -816,32 +849,34 @@ const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
|
|
|
816
849
|
}, []);
|
|
817
850
|
/** On changes to mediaQueries, subscribe to changes using window.matchMedia */
|
|
818
851
|
useChooseEffect(() => {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
list.addEventListener('change', handleChange);
|
|
829
|
-
}
|
|
830
|
-
else {
|
|
831
|
-
list.addListener(handleChange);
|
|
832
|
-
}
|
|
833
|
-
/** Map the unsubscribers array to a list of unsubscriber methods */
|
|
834
|
-
return () => {
|
|
852
|
+
if (isBrowser) {
|
|
853
|
+
const unsubscribers = mediaQueries.map((_a) => {
|
|
854
|
+
var { query } = _a, breakpoint = __rest(_a, ["query"]);
|
|
855
|
+
const list = window.matchMedia(query);
|
|
856
|
+
updateBreakpoint(list, breakpoint);
|
|
857
|
+
const handleChange = (event) => {
|
|
858
|
+
updateBreakpoint(event, breakpoint);
|
|
859
|
+
};
|
|
860
|
+
const supportsNewEventListeners = 'addEventListener' in list && 'removeEventListener' in list;
|
|
835
861
|
if (supportsNewEventListeners) {
|
|
836
|
-
list.
|
|
862
|
+
list.addEventListener('change', handleChange);
|
|
837
863
|
}
|
|
838
864
|
else {
|
|
839
|
-
list.
|
|
865
|
+
list.addListener(handleChange);
|
|
840
866
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
867
|
+
/** Map the unsubscribers array to a list of unsubscriber methods */
|
|
868
|
+
return () => {
|
|
869
|
+
if (supportsNewEventListeners) {
|
|
870
|
+
list.removeEventListener('change', handleChange);
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
list.removeListener(handleChange);
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
});
|
|
877
|
+
/** Return a function that when called, will call all unsubscribers */
|
|
878
|
+
return () => unsubscribers.forEach((unsubscriber) => unsubscriber());
|
|
879
|
+
}
|
|
845
880
|
}, [mediaQueries, updateBreakpoint]);
|
|
846
881
|
/** Print a nice debug value for React Devtools */
|
|
847
882
|
useDebugValue(currentBreakpoint, (c) => typeof c.breakpoint === 'string'
|
|
@@ -869,12 +904,15 @@ class Toaster {
|
|
|
869
904
|
__classPrivateFieldSet(this, _Toaster_defaultTimeLeft, 4, "f");
|
|
870
905
|
const rootID = (config === null || config === void 0 ? void 0 : config.root) || `toast-container`;
|
|
871
906
|
__classPrivateFieldSet(this, _Toaster_root, rootID, "f");
|
|
872
|
-
|
|
907
|
+
this.addRoot();
|
|
908
|
+
}
|
|
909
|
+
addRoot() {
|
|
910
|
+
if (window.document.querySelector(`#${__classPrivateFieldGet(this, _Toaster_root, "f")}`))
|
|
873
911
|
return;
|
|
874
912
|
var root = window.document.createElement('div');
|
|
875
|
-
root.id =
|
|
913
|
+
root.id = __classPrivateFieldGet(this, _Toaster_root, "f");
|
|
876
914
|
window.document.body.appendChild(root);
|
|
877
|
-
__classPrivateFieldSet(this, _Toaster_container, window.document.querySelector(`#${
|
|
915
|
+
__classPrivateFieldSet(this, _Toaster_container, window.document.querySelector(`#${__classPrivateFieldGet(this, _Toaster_root, "f")}`), "f");
|
|
878
916
|
}
|
|
879
917
|
dismiss(ID) {
|
|
880
918
|
let self = this;
|
|
@@ -894,6 +932,7 @@ class Toaster {
|
|
|
894
932
|
}
|
|
895
933
|
toast(config) {
|
|
896
934
|
var self = this;
|
|
935
|
+
self.addRoot();
|
|
897
936
|
var ID = 'toast-' + nanoid(), toast = window.document.createElement('div'); window.document.createElement('div');
|
|
898
937
|
toast.id = ID;
|
|
899
938
|
toast.style.backgroundColor = `#111`;
|
|
@@ -951,71 +990,115 @@ const useLang = (mod = 'en') => {
|
|
|
951
990
|
const Box = forwardRef((props, ref) => {
|
|
952
991
|
const _noClick = () => { };
|
|
953
992
|
// console.log(props)
|
|
954
|
-
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("div", Object.assign({}, cleanProps(props), { title: props.title || undefined, id: props.id || undefined, onClick: props.onClick || _noClick, className: `${props.as ? `${props.as} ` : ``}${cx(css `${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: props.bref || ref
|
|
993
|
+
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("div", Object.assign({}, cleanProps(props), { title: props.title || undefined, id: props.id || undefined, onDoubleClick: props.onDoubleClick || undefined, onClick: props.onClick || _noClick, className: `${props.as ? `${props.as} ` : ``}${cx(css `${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: props.bref || ref, children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : props.children })) }));
|
|
955
994
|
});
|
|
956
995
|
|
|
957
|
-
const
|
|
958
|
-
const ID = `context-${contextID}`;
|
|
959
|
-
useState(false);
|
|
960
|
-
const [root, setRoot] = useState(null);
|
|
996
|
+
const Menu = ({ ID, hide, e, items, width }) => {
|
|
961
997
|
const nodeRef = useRef(null);
|
|
962
|
-
const
|
|
963
|
-
|
|
998
|
+
const [p, setP] = useState(getMousePosition(e));
|
|
999
|
+
const [visible, setVisible] = useState(false);
|
|
1000
|
+
const checkBoundaries = (x, y) => {
|
|
964
1001
|
if (nodeRef.current) {
|
|
965
1002
|
const { innerWidth, innerHeight } = window;
|
|
966
1003
|
const { offsetWidth, offsetHeight } = nodeRef.current;
|
|
967
1004
|
if (x + offsetWidth > innerWidth)
|
|
968
|
-
x -= x + offsetWidth - innerWidth;
|
|
1005
|
+
x -= offsetWidth; //x + offsetWidth - innerWidth;
|
|
969
1006
|
if (y + offsetHeight > innerHeight)
|
|
970
|
-
y -=
|
|
1007
|
+
y -= offsetHeight;
|
|
971
1008
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1009
|
+
setP({ x, y });
|
|
1010
|
+
setVisible(true);
|
|
1011
|
+
};
|
|
1012
|
+
useEffect(() => {
|
|
1013
|
+
checkBoundaries(p.x, p.y);
|
|
1014
|
+
}, [e]);
|
|
1015
|
+
return (jsx(Box, { bref: nodeRef, flex: true, dir: `cols`, fixed: true, top: p.y, left: p.x, w: width || 220, opacity: visible ? 1 : 0, as: `zuz-contextmenu ${ID}`, children: items.map((m, i) => m.id == `line` ? jsx(Box, { as: `line` }, `line-${i}-${m.id}`) : jsx("button", { onClick: ev => {
|
|
1016
|
+
if (m.onClick) {
|
|
1017
|
+
m.onClick(ev, m);
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
console.log(`No onClick eventFound`);
|
|
1021
|
+
}
|
|
1022
|
+
hide();
|
|
1023
|
+
}, children: m.label }, `cm-${i}-${m.id}`)) }));
|
|
1024
|
+
};
|
|
1025
|
+
const useContextMenu = (contextID, contextWidth, contextToken = `____uchides`) => {
|
|
1026
|
+
const ID = `contextmenu-${contextID}`;
|
|
1027
|
+
useState(false);
|
|
1028
|
+
const [root, setRoot] = useState(null);
|
|
1029
|
+
const el = (e) => window.document.createElement(e);
|
|
1030
|
+
const createRoot = () => {
|
|
1031
|
+
if (!window.document.querySelector(`#${ID}`)) {
|
|
1032
|
+
let div = el(`div`);
|
|
1033
|
+
div.id = ID;
|
|
1034
|
+
window.document.body.appendChild(div);
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
const hideAll = () => {
|
|
1038
|
+
if (window[contextToken]) {
|
|
1039
|
+
window[contextToken].map((h) => h['ID'] != ID && h['fnc']());
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
const _hide = () => {
|
|
975
1043
|
try {
|
|
976
1044
|
root === null || root === void 0 ? void 0 : root.unmount();
|
|
1045
|
+
document.querySelector(`#${ID}`).parentNode.removeChild(document.querySelector(`#${ID}`));
|
|
977
1046
|
setRoot(null);
|
|
978
1047
|
}
|
|
979
1048
|
catch (e) { }
|
|
980
1049
|
};
|
|
981
|
-
const
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
return (jsx(Box, Object.assign({ bref: nodeRef, flex: true, dir: `cols`, fixed: true, top: y, left: x, as: `zuz-contextmenu ${ID}` }, { children: items && items.map((m, i) => m.id == `line` ? jsx(Box, { as: `line` }, `line-${i}-${m.id}`) : jsx("button", Object.assign({ onClick: ev => {
|
|
985
|
-
if (m.onClick) {
|
|
986
|
-
m.onClick(ev, m);
|
|
987
|
-
}
|
|
988
|
-
else {
|
|
989
|
-
console.log(`No onClick eventFound`);
|
|
990
|
-
}
|
|
991
|
-
hide();
|
|
992
|
-
} }, { children: m.label }), `cm-${i}-${m.id}`)) })));
|
|
1050
|
+
const hide = () => {
|
|
1051
|
+
_hide();
|
|
1052
|
+
hideAll();
|
|
993
1053
|
};
|
|
994
1054
|
const show = (e, items) => {
|
|
995
1055
|
e.preventDefault();
|
|
996
1056
|
e.stopPropagation();
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
div.id = ID;
|
|
1000
|
-
window.document.body.appendChild(div);
|
|
1001
|
-
}
|
|
1002
|
-
root.render(Menu(e, items));
|
|
1057
|
+
hideAll();
|
|
1058
|
+
root.render(jsx(Menu, { e: e, width: contextWidth || 220, items: items, ID: ID, hide: hide }));
|
|
1003
1059
|
};
|
|
1004
1060
|
useEffect(() => {
|
|
1005
|
-
|
|
1006
|
-
let div = el(`div`);
|
|
1007
|
-
div.id = ID;
|
|
1008
|
-
window.document.body.appendChild(div);
|
|
1009
|
-
}
|
|
1061
|
+
createRoot();
|
|
1010
1062
|
if (!root)
|
|
1011
1063
|
setRoot(ReactDOM.createRoot(document.getElementById(ID)));
|
|
1012
1064
|
}, [root]);
|
|
1065
|
+
useEffect(() => {
|
|
1066
|
+
if (contextToken in window == false) {
|
|
1067
|
+
window[contextToken] = [];
|
|
1068
|
+
}
|
|
1069
|
+
if (window[contextToken].findIndex(x => x.ID == ID) == -1) {
|
|
1070
|
+
window[contextToken].push({ ID: ID, fnc: _hide });
|
|
1071
|
+
if (window[contextToken].length > document.querySelectorAll('div[id^="contextmenu-"]').length) {
|
|
1072
|
+
window[contextToken].shift();
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
}, []);
|
|
1013
1076
|
return {
|
|
1014
1077
|
show,
|
|
1015
|
-
hide
|
|
1078
|
+
hide,
|
|
1079
|
+
hideAll
|
|
1016
1080
|
};
|
|
1017
1081
|
};
|
|
1018
1082
|
|
|
1083
|
+
const useRender = (isMounted, delay) => {
|
|
1084
|
+
const [canRender, setCanRender] = useState(false);
|
|
1085
|
+
// console.log(
|
|
1086
|
+
// `isMounted:`, isMounted,
|
|
1087
|
+
// `canRender:`, canRender,
|
|
1088
|
+
// )
|
|
1089
|
+
useEffect(() => {
|
|
1090
|
+
let outID;
|
|
1091
|
+
if (isMounted && !canRender) {
|
|
1092
|
+
setCanRender(true);
|
|
1093
|
+
}
|
|
1094
|
+
else if (isMounted && canRender) {
|
|
1095
|
+
outID = setTimeout(() => setCanRender(false), delay * 1000);
|
|
1096
|
+
}
|
|
1097
|
+
return () => clearTimeout(outID);
|
|
1098
|
+
}, [isMounted, delay]);
|
|
1099
|
+
return canRender;
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1019
1102
|
const Button = forwardRef((props, ref) => {
|
|
1020
1103
|
const { forms } = useStore(state => state[STORE_FORM_KEY], false);
|
|
1021
1104
|
if (props.html) {
|
|
@@ -1025,14 +1108,14 @@ const Button = forwardRef((props, ref) => {
|
|
|
1025
1108
|
return (jsx("button", Object.assign({}, cleanProps(props), { title: "title" in props ? props.title : undefined, type: props.type, className: `button${props.as ? ` ${props.as}` : ``} ${cx(css `
|
|
1026
1109
|
padding: 5px 10px;
|
|
1027
1110
|
border-radius: 2px;
|
|
1028
|
-
${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: ref, onClick: e => {
|
|
1111
|
+
${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: ref, onDoubleClick: props.onDoubleClick || undefined, onClick: e => {
|
|
1029
1112
|
if (props.form && props.type && props.type == 'submit') {
|
|
1030
1113
|
props.onSubmit(forms[props.form]);
|
|
1031
1114
|
}
|
|
1032
1115
|
else {
|
|
1033
1116
|
props.onClick ? props.onClick(e) : () => console.warn('onClick Missing');
|
|
1034
1117
|
}
|
|
1035
|
-
}, disabled: props.disabled || false
|
|
1118
|
+
}, disabled: props.disabled || false, children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : props.children })));
|
|
1036
1119
|
} }));
|
|
1037
1120
|
});
|
|
1038
1121
|
|
|
@@ -1134,7 +1217,7 @@ const cleanProps = (props) => {
|
|
|
1134
1217
|
delete _props[k];
|
|
1135
1218
|
}
|
|
1136
1219
|
});
|
|
1137
|
-
let _extras = [`as`, `hover`, `bref`];
|
|
1220
|
+
let _extras = [`as`, `hover`, `bref`, `tag`];
|
|
1138
1221
|
_extras.map(x => x in _props && delete _props[x]);
|
|
1139
1222
|
return _props;
|
|
1140
1223
|
};
|
|
@@ -1186,7 +1269,7 @@ const buildFormData = (data) => {
|
|
|
1186
1269
|
[data['files']].map((f) => formData.append('files[]', f));
|
|
1187
1270
|
return formData;
|
|
1188
1271
|
};
|
|
1189
|
-
const
|
|
1272
|
+
const withRest = async (uri, data, timeout = 60, fd = null, progress, bearer = `__ha`) => {
|
|
1190
1273
|
var Bearer = getCookie(bearer) || `${randstr(8)}^${randstr(8)}`;
|
|
1191
1274
|
window['__grabToken'] = axios.CancelToken.source();
|
|
1192
1275
|
if (fd) {
|
|
@@ -1291,7 +1374,7 @@ const filterHTMLProps = (props) => {
|
|
|
1291
1374
|
});
|
|
1292
1375
|
return filter;
|
|
1293
1376
|
};
|
|
1294
|
-
const uuid = () => nanoid();
|
|
1377
|
+
const uuid = (len = 21) => nanoid(len);
|
|
1295
1378
|
const addScript = (src, callback) => {
|
|
1296
1379
|
var s = document.createElement('script');
|
|
1297
1380
|
s.setAttribute('src', src);
|
|
@@ -1374,13 +1457,75 @@ const getMousePosition = e => {
|
|
|
1374
1457
|
pos.y = 0;
|
|
1375
1458
|
return pos;
|
|
1376
1459
|
};
|
|
1460
|
+
const copyToClipboard = (str, callback) => {
|
|
1461
|
+
const el = document.createElement('textarea');
|
|
1462
|
+
let storeContentEditable = el.contentEditable;
|
|
1463
|
+
let storeReadOnly = el.readOnly;
|
|
1464
|
+
el.value = str;
|
|
1465
|
+
el.contentEditable = `true`;
|
|
1466
|
+
el.readOnly = false;
|
|
1467
|
+
el.setAttribute('readonly', `false`);
|
|
1468
|
+
el.setAttribute('contenteditable', `true`);
|
|
1469
|
+
el.style.position = 'absolute';
|
|
1470
|
+
el.style.left = '-999999999px';
|
|
1471
|
+
document.body.appendChild(el);
|
|
1472
|
+
const selected = document.getSelection().rangeCount > 0
|
|
1473
|
+
? document.getSelection().getRangeAt(0)
|
|
1474
|
+
: false;
|
|
1475
|
+
el.select();
|
|
1476
|
+
el.setSelectionRange(0, 999999);
|
|
1477
|
+
document.execCommand('copy');
|
|
1478
|
+
document.body.removeChild(el);
|
|
1479
|
+
if (selected) {
|
|
1480
|
+
document.getSelection().removeAllRanges();
|
|
1481
|
+
document.getSelection().addRange(selected);
|
|
1482
|
+
}
|
|
1483
|
+
el.contentEditable = storeContentEditable;
|
|
1484
|
+
el.readOnly = storeReadOnly;
|
|
1485
|
+
if (callback)
|
|
1486
|
+
callback();
|
|
1487
|
+
};
|
|
1488
|
+
/**
|
|
1489
|
+
* Format bytes as human-readable text.
|
|
1490
|
+
*
|
|
1491
|
+
* @param bytes Number of bytes.
|
|
1492
|
+
* @param si True to use metric (SI) units, aka powers of 1000. False to use
|
|
1493
|
+
* binary (IEC), aka powers of 1024.
|
|
1494
|
+
* @param dp Number of decimal places to display.
|
|
1495
|
+
*
|
|
1496
|
+
* @return Formatted string.
|
|
1497
|
+
*/
|
|
1498
|
+
const formatSize = (bytes, si = false, dp = 1) => {
|
|
1499
|
+
const thresh = si ? 1000 : 1024;
|
|
1500
|
+
if (Math.abs(bytes) < thresh) {
|
|
1501
|
+
return bytes + ' B';
|
|
1502
|
+
}
|
|
1503
|
+
const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
1504
|
+
let u = -1;
|
|
1505
|
+
const r = 10 ** dp;
|
|
1506
|
+
do {
|
|
1507
|
+
bytes /= thresh;
|
|
1508
|
+
++u;
|
|
1509
|
+
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
|
1510
|
+
return bytes.toFixed(dp) + ' ' + units[u];
|
|
1511
|
+
};
|
|
1512
|
+
const slugify = (...args) => {
|
|
1513
|
+
const value = args.join(' ');
|
|
1514
|
+
return value
|
|
1515
|
+
.normalize('NFD') // split an accented letter in the base letter and the acent
|
|
1516
|
+
.replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
|
|
1517
|
+
.toLowerCase()
|
|
1518
|
+
.trim()
|
|
1519
|
+
.replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
|
|
1520
|
+
.replace(/\s+/g, '-'); // separator
|
|
1521
|
+
};
|
|
1377
1522
|
|
|
1378
1523
|
const AppMain = forwardRef((props, ref) => {
|
|
1379
1524
|
// const { dispatch } = useStore()
|
|
1380
1525
|
// if("theme" in props && !theme){
|
|
1381
1526
|
// dispatch(setTheme(props.theme));
|
|
1382
1527
|
// }
|
|
1383
|
-
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("main",
|
|
1528
|
+
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("main", { className: `${props.as ? props.as : `zuz-app`} ${cx(css `${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, children: props.children }) }));
|
|
1384
1529
|
});
|
|
1385
1530
|
const App = forwardRef((props, ref) => {
|
|
1386
1531
|
return (jsx(AppProvider, { children: jsx(AppMain, {}) }));
|
|
@@ -1432,7 +1577,7 @@ function Checkbox(props) {
|
|
|
1432
1577
|
}
|
|
1433
1578
|
|
|
1434
1579
|
const Spinner = (props) => {
|
|
1435
|
-
return (jsxs(Box,
|
|
1580
|
+
return (jsxs(Box, { rel: true, w: props.size, h: props.size, zIndex: `1`, useSelect: `none`, children: [jsx(Box, { abs: true, as: `spinner rotating`, animationDirection: `reverse`, animationDuration: typeof props.s1 == `string` ? props.s1 : `${props.s1}s`, w: props.size, r: props.radius, h: props.size, bg: props.color, opacity: 0.2 }), jsx(Box, { abs: true, as: `spinner rotating`, animationDuration: typeof props.s2 == `string` ? props.s2 : `${props.s2}s`, w: props.size, r: props.radius, h: props.size, bg: props.color, opacity: 0.5 })] }));
|
|
1436
1581
|
};
|
|
1437
1582
|
Spinner.defaultProps = {
|
|
1438
1583
|
size: 30,
|
|
@@ -1453,11 +1598,11 @@ const Heading = forwardRef((props, ref) => {
|
|
|
1453
1598
|
const { children, as, h } = props;
|
|
1454
1599
|
let Tag = `h${h || 1}`;
|
|
1455
1600
|
const HeadingTag = Tag;
|
|
1456
|
-
return (jsx(ClassNames, { children: ({ css, cx }) => jsx(HeadingTag,
|
|
1601
|
+
return (jsx(ClassNames, { children: ({ css, cx }) => jsx(HeadingTag, { className: `${as ? `${as} ` : ``}${cx(css `${buildCSS(props)}`)}`, ref: ref, children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : children }) }));
|
|
1457
1602
|
});
|
|
1458
1603
|
|
|
1459
1604
|
const Cover = (props) => {
|
|
1460
|
-
return (jsx(Box,
|
|
1605
|
+
return (jsx(Box, { abs: true, fill: true, bgFilter: props.backdrop ? `saturate(${props.backdrop.saturate}%) blur(${props.backdrop.blur}px)` : undefined, zIndex: `2`, bg: props.bg, children: jsxs(Box, { abs: true, abc: true, aic: true, jcc: true, flex: true, dir: `cols`, gap: 20, children: [jsx(Spinner, {}, `cover-spinner`), props.label && jsx(Heading, { size: 16, as: `f`, opacity: 0.7, children: props.label }, `cover-label`)] }, `cover-shadow`) }, `cover-cloud`));
|
|
1461
1606
|
};
|
|
1462
1607
|
Cover.defaultProps = {
|
|
1463
1608
|
bg: `rgba(0,0,0,0.5)`,
|
|
@@ -1514,7 +1659,7 @@ Form.propTypes = {
|
|
|
1514
1659
|
|
|
1515
1660
|
const Icon = forwardRef((props, ref) => {
|
|
1516
1661
|
const { as, path, size, color, hover } = props;
|
|
1517
|
-
return (jsx(Box,
|
|
1662
|
+
return (jsx(Box, { hover: hover || {}, flex: true, bref: ref, as: `icon-${as}`, ai: `c`, jc: `c`, size: size || 24, color: color || `#111111`, children: path && Array(path).fill(undefined).map((p, i) => jsx("span", { className: `path${i + 1}` }, `ico-${as}-${i}`)) }));
|
|
1518
1663
|
});
|
|
1519
1664
|
|
|
1520
1665
|
const Image$1 = forwardRef((props, ref) => {
|
|
@@ -1652,7 +1797,7 @@ class Masonry extends Component$1 {
|
|
|
1652
1797
|
classNameOutput = 'my-masonry-grid';
|
|
1653
1798
|
}
|
|
1654
1799
|
}
|
|
1655
|
-
return (jsx("div", Object.assign({}, rest, { className: classNameOutput
|
|
1800
|
+
return (jsx("div", Object.assign({}, rest, { className: classNameOutput, children: this.renderColumns() })));
|
|
1656
1801
|
}
|
|
1657
1802
|
}
|
|
1658
1803
|
|
|
@@ -1679,7 +1824,7 @@ const Spacer = ({ w, h }) => {
|
|
|
1679
1824
|
|
|
1680
1825
|
const Text = forwardRef((props, ref) => {
|
|
1681
1826
|
const { children, as } = props;
|
|
1682
|
-
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("p",
|
|
1827
|
+
return (jsx(ClassNames, { children: ({ css, cx }) => jsx("p", { className: `${as ? `${as} ` : ``}${cx(css `${buildCSS(props)}`)}`, ref: ref, children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : children }) }));
|
|
1683
1828
|
});
|
|
1684
1829
|
|
|
1685
1830
|
const Tweet = (props) => {
|
|
@@ -1714,11 +1859,6 @@ const Tweet = (props) => {
|
|
|
1714
1859
|
return (jsx(Box, { as: `tweet`, weight: 1, bref: _tweet }));
|
|
1715
1860
|
};
|
|
1716
1861
|
|
|
1717
|
-
const ContextMenu = forwardRef((props, ref) => {
|
|
1718
|
-
const { as, size, color, hover, pos, items } = props;
|
|
1719
|
-
return (jsx(Box, Object.assign({ hover: hover || {}, flex: true, dir: `cols`, fixed: true, top: (pos === null || pos === void 0 ? void 0 : pos.y) || 0, left: (pos === null || pos === void 0 ? void 0 : pos.x) || 0, bref: ref, as: `contextmenu-${as}`, size: size || 24, color: color || `#111111` }, { children: items && items.map((m, i) => jsx(Button, Object.assign({ onClick: m.on ? m.on : () => { } }, { children: m.label }), `cm-${i}-${m.id}`)) })));
|
|
1720
|
-
});
|
|
1721
|
-
|
|
1722
1862
|
const buildElement = (el) => {
|
|
1723
1863
|
switch (el.is) {
|
|
1724
1864
|
case "Box":
|
|
@@ -1736,4 +1876,4 @@ const Header = forwardRef((props, ref) => {
|
|
|
1736
1876
|
return (jsx(Fragment, { children: buildComponent(data) }));
|
|
1737
1877
|
});
|
|
1738
1878
|
|
|
1739
|
-
export { App, Component as Block, Box, Button, Checkbox,
|
|
1879
|
+
export { App, Component as Block, Box, Button, Checkbox, Cover, Form, Header, Heading, Icon, Image$1 as Image, Input, Masonry, Placeholder, AppProvider as Provider, Select, Spacer, Spinner, Text, Toaster, Tweet, addProps, addScript, buildCSS, buildFormData, byId, byName, camelCase, cleanProps, copyToClipboard, createSlice, el, filterHTMLProps, filterStyleProps, formatSize, generateModalRoutes, generatePreservedRoutes, generateRegularRoutes, getCookie, getHostname, getMousePosition, getUriParams, imgPromiseFactory, isEmail, isIPv4, isUrl, parseFilename, randstr, removeCookie, rgb2hex, setCSSVar, setCookie, shuffleArray, slugify, ucfirst, useContextMenu, useDevice, useDispatch, useImage, useLang, useRender, useResizeObserver, useStore, useTheme, useToast, uuid, withRest };
|
package/dist/styles.css
CHANGED
|
@@ -458,7 +458,7 @@ button {
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
.zuz-contextmenu {
|
|
461
|
-
|
|
461
|
+
width: 220px;
|
|
462
462
|
border-radius: 5px;
|
|
463
463
|
padding: 4px;
|
|
464
464
|
background: rgba(34, 34, 34, 0.5);
|
|
@@ -476,7 +476,7 @@ button {
|
|
|
476
476
|
border-radius: 4px;
|
|
477
477
|
}
|
|
478
478
|
.zuz-contextmenu button:hover {
|
|
479
|
-
background: #
|
|
479
|
+
background: #5183ff;
|
|
480
480
|
}
|
|
481
481
|
.zuz-contextmenu .line {
|
|
482
482
|
height: 1px;
|
package/jest.config.js
ADDED