@zuzjs/ui 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +102 -6
- package/package.json +4 -2
- package/src/actions/addForm.tsx +0 -0
- package/src/actions/index.tsx +29 -0
- package/src/actions/redo.tsx +1 -0
- package/src/actions/reset.tsx +1 -0
- package/src/actions/undo.tsx +1 -0
- package/src/comps/app.tsx +34 -0
- package/src/comps/box.tsx +23 -0
- package/src/comps/button.tsx +45 -0
- package/src/comps/checkbox.tsx +74 -0
- package/src/comps/component.tsx +32 -0
- package/src/comps/contextmenu.tsx +43 -0
- package/src/comps/cover.tsx +34 -0
- package/src/comps/form.tsx +89 -0
- package/src/comps/heading.tsx +31 -0
- package/src/comps/icon.tsx +36 -0
- package/src/comps/image.tsx +26 -0
- package/src/comps/input.tsx +80 -0
- package/src/comps/placeholder.tsx +58 -0
- package/src/comps/root.tsx +32 -0
- package/src/comps/select.tsx +63 -0
- package/src/comps/spacer.tsx +20 -0
- package/src/comps/spinner.tsx +36 -0
- package/src/comps/text.tsx +27 -0
- package/src/comps/toaster.tsx +115 -0
- package/src/comps/tweet.tsx +48 -0
- package/src/context/AppContext.tsx +3 -0
- package/src/context/AppProvider.tsx +101 -0
- package/src/context/_AppProvider.tsx +116 -0
- package/src/context/combineReducers.tsx +47 -0
- package/src/context/combineState.tsx +14 -0
- package/src/context/createSlice.tsx +40 -0
- package/src/context/index.tsx +6 -0
- package/src/context/reduceReducers.tsx +6 -0
- package/src/context/store/appbase.tsx +19 -0
- package/src/context/store/theme.tsx +52 -0
- package/src/core/defaultTheme.ts +89 -0
- package/src/core/extractCurrentDesignState.tsx +0 -0
- package/src/core/index.ts +285 -0
- package/src/core/router.ts +86 -0
- package/src/core/styles.ts +361 -0
- package/src/hooks/index.tsx +8 -0
- package/src/hooks/useAppReducer.tsx +40 -0
- package/src/hooks/useChooseEffect.tsx +6 -0
- package/src/hooks/useDevice.tsx +164 -0
- package/src/hooks/useDispatch.tsx +37 -0
- package/src/hooks/useImage.tsx +58 -0
- package/src/hooks/useResizeObserver.tsx +84 -0
- package/src/hooks/useRouter.tsx +45 -0
- package/src/hooks/useSelector.tsx +9 -0
- package/src/hooks/useStore.tsx +27 -0
- package/src/hooks/useTheme.tsx +9 -0
- package/src/hooks/useToast.tsx +11 -0
- package/src/index.tsx +32 -0
- package/src/kit/Builder.tsx +18 -0
- package/src/kit/Component.tsx +32 -0
- package/src/kit/Header.tsx +21 -0
- package/src/redux/slices/app.js +26 -0
- package/src/redux/slices/form.js +46 -0
- package/src/redux/store.js +33 -0
- package/src/scss/constants.scss +4 -0
- package/src/scss/mixins.scss +3 -0
- package/src/scss/props.scss +60 -0
- package/src/scss/style.scss +106 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useReducer
|
|
6
|
+
} from 'react'
|
|
7
|
+
import PropTypes from 'prop-types'
|
|
8
|
+
import AppContext from './AppContext'
|
|
9
|
+
// import useAppReducer from '../hooks/useAppReducer'
|
|
10
|
+
import AppTheme from './store/theme'
|
|
11
|
+
let isMounted = true;
|
|
12
|
+
import appSlice from './store/appbase'
|
|
13
|
+
import combineReducers, { combineState } from './combineReducers'
|
|
14
|
+
import reduceReducers from './reduceReducers'
|
|
15
|
+
// const rootReducer = (state, action ) => ({
|
|
16
|
+
// ...state,
|
|
17
|
+
// ...action.payload
|
|
18
|
+
// })
|
|
19
|
+
|
|
20
|
+
// const rootReducer = combineReducers()
|
|
21
|
+
|
|
22
|
+
const AppProvider = ({
|
|
23
|
+
children,
|
|
24
|
+
// initialState = {},
|
|
25
|
+
reducers = {},
|
|
26
|
+
theme = {}
|
|
27
|
+
}) => {
|
|
28
|
+
|
|
29
|
+
const _dynamiceState = useMemo(() => {
|
|
30
|
+
const __ = {}
|
|
31
|
+
Object.keys(reducers).map(k => {
|
|
32
|
+
__[reducers[k].name] = [reducers[k].reducer, reducers[k].state]
|
|
33
|
+
})
|
|
34
|
+
return __
|
|
35
|
+
}, [reducers])
|
|
36
|
+
|
|
37
|
+
const _dynamiceReducers = useMemo(() => {
|
|
38
|
+
const __ = {}
|
|
39
|
+
Object.keys(reducers).map(k => {
|
|
40
|
+
__[reducers[k].name] = reduceReducers(reducers[k].reducer)
|
|
41
|
+
})
|
|
42
|
+
return __
|
|
43
|
+
}, [reducers])
|
|
44
|
+
|
|
45
|
+
const themeReducer = useCallback(() => {
|
|
46
|
+
(state, action) => ({
|
|
47
|
+
...state,
|
|
48
|
+
...action.payload
|
|
49
|
+
})
|
|
50
|
+
}, [])
|
|
51
|
+
|
|
52
|
+
// const [rootReducer, rootState] = useMemo(() => combineReducers({
|
|
53
|
+
// theme: [themeReducer, new AppTheme({ theme }).get()],
|
|
54
|
+
// [appSlice.name] : [appSlice.reducer, appSlice.state],
|
|
55
|
+
// ..._dynamiceReducers
|
|
56
|
+
// }), [reducers]);
|
|
57
|
+
|
|
58
|
+
const [_, rootState] = combineState({
|
|
59
|
+
theme: [themeReducer, new AppTheme({ theme }).get()],
|
|
60
|
+
[appSlice.name] : [appSlice.reducer, appSlice.state],
|
|
61
|
+
..._dynamiceState
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const rootReducer = combineReducers({
|
|
65
|
+
theme: reduceReducers(themeReducer),
|
|
66
|
+
[appSlice.name] : reduceReducers(appSlice.reducer),
|
|
67
|
+
..._dynamiceReducers
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
console.log(rootState)
|
|
71
|
+
|
|
72
|
+
const [state, dispatch] = useReducer(
|
|
73
|
+
rootReducer,
|
|
74
|
+
rootState
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
isMounted = true;
|
|
79
|
+
return () => {
|
|
80
|
+
isMounted = false;
|
|
81
|
+
}
|
|
82
|
+
}, [])
|
|
83
|
+
|
|
84
|
+
// const dispatch = useCallback(() => {
|
|
85
|
+
// if(isMounted){
|
|
86
|
+
// // let ags = { ...args, action: }
|
|
87
|
+
// _dispatch();
|
|
88
|
+
// // _dispatch({ action: action, payload: payload })
|
|
89
|
+
// }
|
|
90
|
+
// }, [_dispatch]);
|
|
91
|
+
|
|
92
|
+
const providedValue = useMemo(
|
|
93
|
+
() => ({
|
|
94
|
+
...rootState,
|
|
95
|
+
// defaultState,
|
|
96
|
+
dispatch
|
|
97
|
+
}),
|
|
98
|
+
[state]
|
|
99
|
+
// [defaultState, state]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return <AppContext.Provider value={providedValue}>{children}</AppContext.Provider>
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
AppProvider.defaultProps = {
|
|
106
|
+
reducers: {}
|
|
107
|
+
// initialState : {},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
AppProvider.propTypes = {
|
|
111
|
+
children: PropTypes.node.isRequired,
|
|
112
|
+
// initialState: PropTypes.instanceOf(Object)
|
|
113
|
+
reducers: PropTypes.instanceOf(Object)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default AppProvider
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const combineState = reducers => {
|
|
2
|
+
const reducerKeys = Object.keys(reducers);
|
|
3
|
+
const reducerValues = Object.values(reducers);
|
|
4
|
+
|
|
5
|
+
let globalState
|
|
6
|
+
reducerKeys.forEach((k, i) => globalState = { ...globalState, [k]: reducerValues[i][1] } )
|
|
7
|
+
|
|
8
|
+
let finalReducers = {}
|
|
9
|
+
reducerValues.forEach((v, i) => finalReducers = { ...finalReducers, [reducerKeys[i]] : v[0] });
|
|
10
|
+
|
|
11
|
+
return [
|
|
12
|
+
(state, action) => {
|
|
13
|
+
console.log('state', state)
|
|
14
|
+
console.log('action', action)
|
|
15
|
+
let hasStateChanged = false
|
|
16
|
+
const newState = {}
|
|
17
|
+
let nextStateForCurrentKey = {}
|
|
18
|
+
for(let i = 0; i < reducerKeys.length; i++){
|
|
19
|
+
const currentKey = reducerKeys[i]
|
|
20
|
+
const currentReducer = finalReducers[currentKey]
|
|
21
|
+
const prevStateForCurrentKey = state[currentKey]
|
|
22
|
+
nextStateForCurrentKey = currentReducer(
|
|
23
|
+
prevStateForCurrentKey,
|
|
24
|
+
action
|
|
25
|
+
)
|
|
26
|
+
hasStateChanged = hasStateChanged || nextStateForCurrentKey !== prevStateForCurrentKey
|
|
27
|
+
newState[currentKey] = nextStateForCurrentKey
|
|
28
|
+
}
|
|
29
|
+
return hasStateChanged ? newState : state
|
|
30
|
+
},
|
|
31
|
+
globalState
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const combineReducers = slices => {
|
|
37
|
+
return (state, action) =>
|
|
38
|
+
Object.keys(slices).reduce(
|
|
39
|
+
(acc, prop) => ({
|
|
40
|
+
...acc,
|
|
41
|
+
[prop]: slices[prop](acc[prop], action)
|
|
42
|
+
}),
|
|
43
|
+
state
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default combineReducers;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const combineState = (state) => {
|
|
2
|
+
// const reducerKeys = Object.keys(state);
|
|
3
|
+
// const stateValues = Object.values(state);
|
|
4
|
+
|
|
5
|
+
// let globalState
|
|
6
|
+
|
|
7
|
+
// reducerKeys.forEach((k, i) => globalState = { ...globalState, [k]: reducerValues[i][1] } )
|
|
8
|
+
|
|
9
|
+
// console.log(globalState)
|
|
10
|
+
|
|
11
|
+
return state;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default combineState
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React, { useReducer, useMemo } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import combineReducers from './combineReducers'
|
|
4
|
+
|
|
5
|
+
const createSlice = ({
|
|
6
|
+
name,
|
|
7
|
+
initialState,
|
|
8
|
+
reducers
|
|
9
|
+
}) => {
|
|
10
|
+
|
|
11
|
+
// const _dynamiceReducers = {}
|
|
12
|
+
// Object.keys(reducers).map(k => {
|
|
13
|
+
// _dynamiceReducers[reducers[k].name] = [reducers[k].reducer, initialState]
|
|
14
|
+
// })
|
|
15
|
+
|
|
16
|
+
// const _keys = Object.keys(reducers);
|
|
17
|
+
// const [reducer, state] = combineReducers(_dynamiceReducers);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
name,
|
|
21
|
+
reducer: reducers,
|
|
22
|
+
actions: reducers,
|
|
23
|
+
state: initialState
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
createSlice.defaultProps = {
|
|
29
|
+
name: `app`,
|
|
30
|
+
initialState: {},
|
|
31
|
+
reducers: {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
createSlice.propTypes = {
|
|
35
|
+
name: PropTypes.string.isRequired,
|
|
36
|
+
initialState: PropTypes.instanceOf(Object).isRequired,
|
|
37
|
+
reducers: PropTypes.instanceOf(Object).isRequired
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default createSlice;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import createSlice from '../createSlice'
|
|
2
|
+
|
|
3
|
+
const appSlice = createSlice({
|
|
4
|
+
name: 'app',
|
|
5
|
+
initialState: {
|
|
6
|
+
debug: true,
|
|
7
|
+
version: 1.2,
|
|
8
|
+
loading: false
|
|
9
|
+
},
|
|
10
|
+
reducers: {
|
|
11
|
+
setCVersion: (state, action) => state.version = action.payload
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const {
|
|
16
|
+
setLoading
|
|
17
|
+
} = appSlice.actions
|
|
18
|
+
|
|
19
|
+
export default appSlice;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class AppTheme {
|
|
2
|
+
|
|
3
|
+
#mode;
|
|
4
|
+
#listen;
|
|
5
|
+
#lightTheme;
|
|
6
|
+
#darkTheme;
|
|
7
|
+
|
|
8
|
+
constructor(_conf){
|
|
9
|
+
const conf = _conf || {}
|
|
10
|
+
this.#listen = "listen" in conf ? conf.listen : (mod) => { console.log(`Theme switched to ${mod}`); };
|
|
11
|
+
this.#mode = conf.mode || "auto";
|
|
12
|
+
this.#lightTheme = {
|
|
13
|
+
//CORE
|
|
14
|
+
tag: "light",
|
|
15
|
+
dark: false,
|
|
16
|
+
primary: '#edeef5',
|
|
17
|
+
secondary: '#f9f9f9',
|
|
18
|
+
textColor: '#111111',
|
|
19
|
+
...( "theme" in conf && "light" in conf.theme ? {...conf.theme.light} : {})
|
|
20
|
+
};
|
|
21
|
+
this.#darkTheme = {
|
|
22
|
+
//CORE
|
|
23
|
+
tag: "dark",
|
|
24
|
+
dark: true,
|
|
25
|
+
primary: '#21222d',
|
|
26
|
+
secondary: '#282a37',
|
|
27
|
+
textColor: '#f9f9f9',
|
|
28
|
+
...( "theme" in conf && "dark" in conf.theme ? {...conf.theme.dark} : {})
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get = () => {
|
|
33
|
+
let self = this;
|
|
34
|
+
if(self.#mode === "auto"){
|
|
35
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
|
36
|
+
self.#mode = event.matches ? "dark" : "light";
|
|
37
|
+
self.#listen(self.#mode);
|
|
38
|
+
});
|
|
39
|
+
return window.matchMedia &&
|
|
40
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches ?
|
|
41
|
+
self.#darkTheme : self.#lightTheme;
|
|
42
|
+
}else if(self.#mode === "light"){
|
|
43
|
+
return self.#lightTheme;
|
|
44
|
+
}else if(self.#mode === "dark"){
|
|
45
|
+
return self.#darkTheme;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default AppTheme
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
class AppTheme {
|
|
2
|
+
|
|
3
|
+
#mode;
|
|
4
|
+
#listen;
|
|
5
|
+
#lightTheme;
|
|
6
|
+
#darkTheme;
|
|
7
|
+
|
|
8
|
+
constructor(_conf){
|
|
9
|
+
const conf = _conf || {}
|
|
10
|
+
this.#listen = "listen" in conf ? conf.listen : (mod) => { console.log(`Theme switched to ${mod}`); };
|
|
11
|
+
this.#mode = conf.mode || "auto";
|
|
12
|
+
this.#lightTheme = {
|
|
13
|
+
//CORE
|
|
14
|
+
tag: "light",
|
|
15
|
+
dark: false,
|
|
16
|
+
color: "#3a43ac",
|
|
17
|
+
primary: '#edeef5',
|
|
18
|
+
secondary: '#e8e9f0',
|
|
19
|
+
textColor: '#111111',
|
|
20
|
+
borderColor: '#dcdce1',
|
|
21
|
+
//APP
|
|
22
|
+
app: {
|
|
23
|
+
action: 'rgba(0,0,0,0.1)',
|
|
24
|
+
actionHover: 'rgba(255,255,255,0.1)',
|
|
25
|
+
actionActive: 'rgba(0,0,0,0.8)',
|
|
26
|
+
actionDisabled: 'rgba(255,255,255,0.01)',
|
|
27
|
+
shimmerBG: '#383a48',
|
|
28
|
+
shimmerFrom: '#383a48',
|
|
29
|
+
shimmerTo: '#4a4c5b',
|
|
30
|
+
iconBG: '#4a4c5b',
|
|
31
|
+
icon: '#111111',
|
|
32
|
+
sidebarHover: 'rgba(255,255,255,0.2)',
|
|
33
|
+
sidebarActive: 'rgba(255,255,255,1)',
|
|
34
|
+
toolbar: '#d5d6dc',
|
|
35
|
+
tool: 'transparent',
|
|
36
|
+
toolActive: 'rgba(255,255,255,0.75)',
|
|
37
|
+
toolHover: 'rgba(255,255,255,0.5)',
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.#darkTheme = {
|
|
41
|
+
//CORE
|
|
42
|
+
tag: "dark",
|
|
43
|
+
dark: true,
|
|
44
|
+
color: "#3a43ac",
|
|
45
|
+
primary: '#21222d',
|
|
46
|
+
secondary: '#282a37',
|
|
47
|
+
textColor: '#f9f9f9',
|
|
48
|
+
borderColor: '#353640',
|
|
49
|
+
//APP
|
|
50
|
+
app: {
|
|
51
|
+
action: 'rgba(255,255,255,0.05)',
|
|
52
|
+
actionHover: 'rgba(255,255,255,0.1)',
|
|
53
|
+
actionActive: 'rgba(255,255,255,0.2)',
|
|
54
|
+
actionDisabled: 'rgba(255,255,255,0.01)',
|
|
55
|
+
shimmerBG: '#383a48',
|
|
56
|
+
shimmerFrom: '#383a48',
|
|
57
|
+
shimmerTo: '#4a4c5b',
|
|
58
|
+
iconBG: '#4a4c5b',
|
|
59
|
+
icon: '#ffffff',
|
|
60
|
+
toolbar: '#21222d',
|
|
61
|
+
tool: 'transparent',
|
|
62
|
+
toolHover: '#2f3144',
|
|
63
|
+
toolActive: '#2f3144',
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get = () => {
|
|
69
|
+
let self = this;
|
|
70
|
+
// if(self.#mode === "auto"){
|
|
71
|
+
// window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
|
72
|
+
// self.#mode = event.matches ? "dark" : "light";
|
|
73
|
+
// self.#listen(self.mode);
|
|
74
|
+
// });
|
|
75
|
+
// return window.matchMedia &&
|
|
76
|
+
// window.matchMedia('(prefers-color-scheme: dark)').matches ?
|
|
77
|
+
// self.#darkTheme : self.#lightTheme;
|
|
78
|
+
// }else
|
|
79
|
+
if(self.#mode === "light"){
|
|
80
|
+
return self.#lightTheme;
|
|
81
|
+
}else if(self.#mode === "dark"){
|
|
82
|
+
return self.#darkTheme;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default AppTheme
|
|
File without changes
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cloneElement,
|
|
3
|
+
isValidElement
|
|
4
|
+
} from 'react'
|
|
5
|
+
import type { ReactNode, ReactElement } from 'react'
|
|
6
|
+
import Children from 'react-children-utilities';
|
|
7
|
+
import Cookies from 'js-cookie'
|
|
8
|
+
import axios from 'axios'
|
|
9
|
+
import {
|
|
10
|
+
cssPropsDirect,
|
|
11
|
+
cssProps,
|
|
12
|
+
cssPropsVals,
|
|
13
|
+
cssPropsIgnore,
|
|
14
|
+
cssColors
|
|
15
|
+
} from './styles'
|
|
16
|
+
import { nanoid } from 'nanoid'
|
|
17
|
+
import Input from '../comps/input'
|
|
18
|
+
import Select from '../comps/select'
|
|
19
|
+
import Button from '../comps/button'
|
|
20
|
+
import { generateModalRoutes, generatePreservedRoutes, generateRegularRoutes } from './router'
|
|
21
|
+
|
|
22
|
+
const makeCSSValue = (k : any, v : any, o : any) => {
|
|
23
|
+
let ignore = cssPropsIgnore.indexOf(o) == -1;
|
|
24
|
+
if(k in cssPropsDirect && ignore == true){
|
|
25
|
+
// return cssPropsDirect[k];
|
|
26
|
+
return cssPropsDirect[k].indexOf(`__VALUE__`) > - 1 ?
|
|
27
|
+
cssPropsDirect[k].replaceAll(`__VALUE__`, `${v}${"number" == typeof v ? `px` : ``}`)
|
|
28
|
+
: cssPropsDirect[k];
|
|
29
|
+
}
|
|
30
|
+
let unit = "number" == typeof v && ignore ? `px` : ``;
|
|
31
|
+
if(cssColors.indexOf(v) > -1){
|
|
32
|
+
v = `var(--colors-${v.replaceAll(`.`, `-`)})`;
|
|
33
|
+
unit = ``;
|
|
34
|
+
}
|
|
35
|
+
else if(v in cssPropsVals){
|
|
36
|
+
v = cssPropsVals[v];
|
|
37
|
+
}
|
|
38
|
+
return `${k}:${v}${unit};`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const buildCSS = (props : any) => {
|
|
42
|
+
let css = ``;
|
|
43
|
+
Object.keys(props).map(k => {
|
|
44
|
+
css += k in cssProps ? makeCSSValue(cssProps[k], props[k], k) : '';
|
|
45
|
+
});
|
|
46
|
+
return css;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const setCSSVar = ( key : string, val : string ) => {
|
|
50
|
+
document.documentElement.style.setProperty(`--${key}`, val);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const isUrl = (u : string) => {
|
|
54
|
+
let url;
|
|
55
|
+
try{
|
|
56
|
+
url = new URL(u);
|
|
57
|
+
}catch(_){
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return url.protocol === 'http:' || url.protocol === 'https:'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const isEmail = (e : string) => {
|
|
64
|
+
let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
|
|
65
|
+
return reg.test(e);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const isIPv4 = (ipaddress : string) => {
|
|
69
|
+
return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const randstr = function(len? : number){
|
|
73
|
+
var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
74
|
+
len = len || 10;
|
|
75
|
+
for (var i = 0; i < len; i++){
|
|
76
|
+
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
77
|
+
}
|
|
78
|
+
return text;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const setCookie = (key : string, value : any, expiry? : number) => Cookies.set(key, value, { expires: expiry || 7 })
|
|
82
|
+
|
|
83
|
+
const getCookie = (key : string) => Cookies.get(key) || null;
|
|
84
|
+
|
|
85
|
+
const removeCookie = (key : string) => Cookies.remove(key)
|
|
86
|
+
|
|
87
|
+
const buildFormData = (data : object) : FormData => {
|
|
88
|
+
var formData = new FormData();
|
|
89
|
+
var _data = Cookies.get();
|
|
90
|
+
Object.keys(_data).map(k => formData.append(k, _data[k]));
|
|
91
|
+
Object.keys(data).filter(x => x != 'files').map(k => formData.append(k, data[k]));
|
|
92
|
+
if('files' in data) [data['files']].map((f: any) => formData.append('files[]', f));
|
|
93
|
+
return formData;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const grab = async (uri : string, data : object, timeout : number = 60, fd : object = null, progress? : Function, bearer : string = `__ha`) => {
|
|
97
|
+
var Bearer = getCookie(bearer) || `${randstr(8)}^${randstr(8)}`;
|
|
98
|
+
window['__grabToken'] = axios.CancelToken.source();
|
|
99
|
+
if(fd){
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
axios({
|
|
102
|
+
method: "post",
|
|
103
|
+
url: uri,
|
|
104
|
+
data: buildFormData(data),
|
|
105
|
+
timeout: 1000 * timeout,
|
|
106
|
+
cancelToken: window['__grabToken'].token,
|
|
107
|
+
headers: {
|
|
108
|
+
'Content-Type': 'multipart/form-data',
|
|
109
|
+
'Authorization': `Bearer ${Bearer}`
|
|
110
|
+
},
|
|
111
|
+
onUploadProgress: ev => {
|
|
112
|
+
//TODO: Add progress
|
|
113
|
+
// if(progress) progress(ev.)
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
.then(resp => {
|
|
117
|
+
if(resp.data && "kind" in resp.data){
|
|
118
|
+
resolve(resp.data)
|
|
119
|
+
}else{
|
|
120
|
+
reject(resp.data)
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
.catch(err => reject(err));
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
axios.post(
|
|
128
|
+
uri,
|
|
129
|
+
{
|
|
130
|
+
...Cookies.get(),
|
|
131
|
+
...data,
|
|
132
|
+
__ustmp: new Date().getTime() / 1000
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
timeout: 1000 * timeout,
|
|
136
|
+
headers: {
|
|
137
|
+
'Content-Type': 'application/json',
|
|
138
|
+
'Authorization': `Bearer ${Bearer}`
|
|
139
|
+
},
|
|
140
|
+
cancelToken: window['__grabToken'].token
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
.then(resp => {
|
|
144
|
+
if(resp.data && "kind" in resp.data){
|
|
145
|
+
resolve(resp.data)
|
|
146
|
+
}else{
|
|
147
|
+
reject(resp.data)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
.catch(err => reject(err));
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const el = (e : string) => document.querySelector(e);
|
|
155
|
+
|
|
156
|
+
const byName = (e : string) => document.querySelector(`*[name="${e}"]`);
|
|
157
|
+
|
|
158
|
+
const byId = (e : string) => document.getElementById(e);
|
|
159
|
+
|
|
160
|
+
const addProps = (children : any, prop : any) => {
|
|
161
|
+
let form = {}
|
|
162
|
+
let allowedFields = [Input, Select, Button];
|
|
163
|
+
let child = Children.deepMap(children, c => {
|
|
164
|
+
if(allowedFields.indexOf(c['type']) > -1 && c['props'] && !form[c['props'].name]){
|
|
165
|
+
form[c['props'].name] = c['props'].value || null;
|
|
166
|
+
}
|
|
167
|
+
let Clone = cloneElement(c as ReactElement<any>, prop);
|
|
168
|
+
return Clone;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
children : child,
|
|
173
|
+
fields: form
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const ucfirst = ( str : string ) => {
|
|
178
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const filterStyleProps = (props : any) => {
|
|
182
|
+
|
|
183
|
+
const pks = Object.keys(props);
|
|
184
|
+
const css = Object.keys(cssProps);
|
|
185
|
+
let filter = {}
|
|
186
|
+
css.filter(x => pks.includes(x))
|
|
187
|
+
|
|
188
|
+
// .map(k => filter[k] = props[k].toString());
|
|
189
|
+
return filter;
|
|
190
|
+
// const allowed = Object.keys(props);
|
|
191
|
+
// let allowed = Object.keys(cssProps);
|
|
192
|
+
|
|
193
|
+
// return Object.keys(props)
|
|
194
|
+
// .filter( k => allowed.includes(k))
|
|
195
|
+
// .reduce( (o, k) => {
|
|
196
|
+
// // console.log(o)
|
|
197
|
+
// console.log(k, props[k])
|
|
198
|
+
// // o[k] = props[k].toString();
|
|
199
|
+
// // return o;
|
|
200
|
+
// })
|
|
201
|
+
// return [props].filter( row => (
|
|
202
|
+
// Object.keys(row)
|
|
203
|
+
// .map(key => css.includes(key))
|
|
204
|
+
// ));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const filterHTMLProps = (props : any) => {
|
|
208
|
+
const pks = Object.keys(props);
|
|
209
|
+
const css = Object.keys(cssProps);
|
|
210
|
+
let filter = {}
|
|
211
|
+
pks.filter(x => {
|
|
212
|
+
if(x!= `for` && !css.includes(x)){
|
|
213
|
+
filter[x] = props[x]
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
return filter;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const uuid = () => nanoid()
|
|
220
|
+
|
|
221
|
+
const addScript = (src: string, callback: () => any) => {
|
|
222
|
+
var s = document.createElement('script')
|
|
223
|
+
s.setAttribute('src', src)
|
|
224
|
+
s.addEventListener('load', callback, false)
|
|
225
|
+
document.body.appendChild(s)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const shuffleArray = array => {
|
|
229
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
230
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
231
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
232
|
+
}
|
|
233
|
+
return array
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const getUriParams = () => {
|
|
237
|
+
var search = location.search.substring(1);
|
|
238
|
+
if(search=='') return JSON.parse('{}');
|
|
239
|
+
var xny = {};
|
|
240
|
+
if("URLSearchParams" in window){
|
|
241
|
+
var items = new URLSearchParams(search);
|
|
242
|
+
for(const [k, v] of items){
|
|
243
|
+
xny[k] = v || ``;
|
|
244
|
+
}
|
|
245
|
+
}else{
|
|
246
|
+
try{
|
|
247
|
+
xny = JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');
|
|
248
|
+
}catch(e){
|
|
249
|
+
xny = {};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return xny;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const rgb2hex = rgb => `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}`
|
|
256
|
+
|
|
257
|
+
export {
|
|
258
|
+
addProps,
|
|
259
|
+
addScript,
|
|
260
|
+
buildCSS,
|
|
261
|
+
buildFormData,
|
|
262
|
+
byName,
|
|
263
|
+
byId,
|
|
264
|
+
el,
|
|
265
|
+
grab,
|
|
266
|
+
isEmail,
|
|
267
|
+
isIPv4,
|
|
268
|
+
isUrl,
|
|
269
|
+
randstr,
|
|
270
|
+
setCSSVar,
|
|
271
|
+
getCookie,
|
|
272
|
+
setCookie,
|
|
273
|
+
removeCookie,
|
|
274
|
+
ucfirst,
|
|
275
|
+
filterStyleProps,
|
|
276
|
+
filterHTMLProps,
|
|
277
|
+
uuid,
|
|
278
|
+
shuffleArray,
|
|
279
|
+
getUriParams,
|
|
280
|
+
rgb2hex,
|
|
281
|
+
generateModalRoutes,
|
|
282
|
+
generatePreservedRoutes,
|
|
283
|
+
generateRegularRoutes
|
|
284
|
+
}
|
|
285
|
+
|