@zuzjs/ui 0.3.2 → 0.3.4
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 +0 -0
- package/dist/hooks.js +89 -0
- package/dist/styles.css +37 -62
- package/dist/ui.js +665 -0
- package/jest.config.js +0 -0
- package/package.json +16 -18
- package/rollup.config.js +30 -47
- package/src/comps/box.tsx +24 -28
- package/src/comps/button.tsx +23 -47
- package/src/comps/crumb.tsx +9 -0
- package/src/comps/form.tsx +57 -88
- package/src/comps/heading.tsx +25 -31
- package/src/comps/icon.tsx +24 -36
- package/src/comps/input.tsx +24 -224
- package/src/comps/select.tsx +23 -63
- package/src/comps/spinner.tsx +23 -35
- package/src/comps/stylesheet.tsx +5 -0
- package/src/context/AppContext.tsx +2 -2
- package/src/context/AppProvider.tsx +68 -105
- package/src/context/createSlice.tsx +15 -39
- package/src/context/index.tsx +4 -5
- package/src/core/css.ts +1 -0
- package/src/core/index.tsx +241 -0
- package/src/core/styles.ts +378 -371
- package/src/hooks/index.tsx +2 -10
- package/src/hooks/useDispatch.tsx +36 -36
- package/src/hooks/useStore.tsx +24 -26
- package/src/hooks.tsx +8 -0
- package/src/scss/mixins.scss +2 -2
- package/src/scss/props.scss +91 -69
- package/src/scss/{style.scss → styles.scss} +102 -132
- package/src/ui.tsx +13 -0
- package/tsconfig.json +0 -0
- package/tsconfig.lib.json +0 -0
- package/tsconfig.spec.json +0 -0
- package/dist/index.js +0 -1868
- package/src/actions/addForm.tsx +0 -0
- package/src/actions/index.tsx +0 -29
- package/src/actions/redo.tsx +0 -1
- package/src/actions/reset.tsx +0 -1
- package/src/actions/undo.tsx +0 -1
- package/src/comps/app.tsx +0 -34
- package/src/comps/checkbox.tsx +0 -74
- package/src/comps/component.tsx +0 -32
- package/src/comps/contextmenu.tsx +0 -60
- package/src/comps/cover.tsx +0 -34
- package/src/comps/image.tsx +0 -34
- package/src/comps/masonry.tsx +0 -192
- package/src/comps/mediaplayer.tsx +0 -12
- package/src/comps/placeholder.tsx +0 -58
- package/src/comps/root.tsx +0 -32
- package/src/comps/spacer.tsx +0 -20
- package/src/comps/text.tsx +0 -27
- package/src/comps/toaster.tsx +0 -117
- package/src/comps/tweet.tsx +0 -48
- package/src/context/_AppProvider.tsx +0 -116
- package/src/context/combineReducers.tsx +0 -47
- package/src/context/combineState.tsx +0 -14
- package/src/context/reduceReducers.tsx +0 -6
- package/src/context/store/appbase.tsx +0 -19
- package/src/context/store/lang.tsx +0 -26
- package/src/context/store/theme.tsx +0 -54
- package/src/core/defaultTheme.ts +0 -90
- package/src/core/extractCurrentDesignState.tsx +0 -0
- package/src/core/index.ts +0 -431
- package/src/core/router.ts +0 -86
- package/src/hooks/useAppReducer.tsx +0 -40
- package/src/hooks/useChooseEffect.tsx +0 -6
- package/src/hooks/useContextMenu.tsx +0 -123
- package/src/hooks/useDevice.tsx +0 -164
- package/src/hooks/useImage.tsx +0 -84
- package/src/hooks/useLang.tsx +0 -9
- package/src/hooks/useMediaPlayer.tsx +0 -27
- package/src/hooks/useNavigator.tsx +0 -6
- package/src/hooks/useRender.tsx +0 -29
- package/src/hooks/useResizeObserver.tsx +0 -84
- package/src/hooks/useRouter.tsx +0 -45
- package/src/hooks/useSelector.tsx +0 -9
- package/src/hooks/useTheme.tsx +0 -9
- package/src/hooks/useToast.tsx +0 -11
- package/src/index.tsx +0 -35
- package/src/kit/Builder.tsx +0 -18
- package/src/kit/Component.tsx +0 -32
- package/src/kit/Header.tsx +0 -21
- package/src/redux/slices/app.js +0 -26
- package/src/redux/slices/form.js +0 -46
- package/src/redux/store.js +0 -33
- package/src/scss/constants.scss +0 -4
package/src/core/index.ts
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
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 cleanProps = (props : any) => {
|
|
42
|
-
let _props = { ...props }
|
|
43
|
-
Object.keys(_props).map(k => {
|
|
44
|
-
if(k in cssProps){
|
|
45
|
-
delete _props[k]
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
let _extras = [`as`,`hover`,`bref`,`tag`]
|
|
49
|
-
_extras.map(x => x in _props && delete _props[x])
|
|
50
|
-
return _props
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const buildCSS = (props : any) => {
|
|
54
|
-
let css = ``;
|
|
55
|
-
Object.keys(props).map(k => {
|
|
56
|
-
css += k in cssProps ? makeCSSValue(cssProps[k], props[k], k) : '';
|
|
57
|
-
});
|
|
58
|
-
return css;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const setCSSVar = ( key : string, val : string ) => {
|
|
62
|
-
document.documentElement.style.setProperty(`--${key}`, val);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const isUrl = (u : string) => {
|
|
66
|
-
let url;
|
|
67
|
-
try{
|
|
68
|
-
url = new URL(u);
|
|
69
|
-
}catch(_){
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
return url.protocol === 'http:' || url.protocol === 'https:'
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const isEmail = (e : string) => {
|
|
76
|
-
let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
|
|
77
|
-
return reg.test(e);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const isIPv4 = (ipaddress : string) => {
|
|
81
|
-
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);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const randstr = function(len? : number){
|
|
85
|
-
var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
86
|
-
len = len || 10;
|
|
87
|
-
for (var i = 0; i < len; i++){
|
|
88
|
-
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
89
|
-
}
|
|
90
|
-
return text;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const setCookie = (key : string, value : any, expiry? : number, host? : string) => Cookies.set(key, value, { expires: expiry || 7, domain: host || window.location.host })
|
|
94
|
-
|
|
95
|
-
const getCookie = (key : string) => Cookies.get(key) || null;
|
|
96
|
-
|
|
97
|
-
const removeCookie = (key : string) => Cookies.remove(key)
|
|
98
|
-
|
|
99
|
-
const buildFormData = (data : object) : FormData => {
|
|
100
|
-
var formData = new FormData();
|
|
101
|
-
var _data = Cookies.get();
|
|
102
|
-
Object.keys(_data).map(k => formData.append(k, _data[k]));
|
|
103
|
-
Object.keys(data).filter(x => x != 'files').map(k => formData.append(k, data[k]));
|
|
104
|
-
if('files' in data) [data['files']].map((f: any) => formData.append('files[]', f));
|
|
105
|
-
return formData;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const grab = async (uri : string, data : object, timeout : number = 60, fd : object = null, progress? : Function, bearer : string = `__ha`) => {
|
|
109
|
-
var Bearer = getCookie(bearer) || `${randstr(8)}^${randstr(8)}`;
|
|
110
|
-
window['__grabToken'] = axios.CancelToken.source();
|
|
111
|
-
if(fd){
|
|
112
|
-
return new Promise((resolve, reject) => {
|
|
113
|
-
axios({
|
|
114
|
-
method: "post",
|
|
115
|
-
url: uri,
|
|
116
|
-
data: buildFormData(data),
|
|
117
|
-
timeout: 1000 * timeout,
|
|
118
|
-
cancelToken: window['__grabToken'].token,
|
|
119
|
-
headers: {
|
|
120
|
-
'Content-Type': 'multipart/form-data',
|
|
121
|
-
'Authorization': `Bearer ${Bearer}`
|
|
122
|
-
},
|
|
123
|
-
onUploadProgress: ev => {
|
|
124
|
-
//TODO: Add progress
|
|
125
|
-
// if(progress) progress(ev.)
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
.then(resp => {
|
|
129
|
-
if(resp.data && "kind" in resp.data){
|
|
130
|
-
resolve(resp.data)
|
|
131
|
-
}else{
|
|
132
|
-
reject(resp.data)
|
|
133
|
-
}
|
|
134
|
-
})
|
|
135
|
-
.catch(err => reject(err));
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
return new Promise((resolve, reject) => {
|
|
139
|
-
axios.post(
|
|
140
|
-
uri,
|
|
141
|
-
{
|
|
142
|
-
...Cookies.get(),
|
|
143
|
-
...data,
|
|
144
|
-
__ustmp: new Date().getTime() / 1000
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
timeout: 1000 * timeout,
|
|
148
|
-
headers: {
|
|
149
|
-
'Content-Type': 'application/json',
|
|
150
|
-
'Authorization': `Bearer ${Bearer}`
|
|
151
|
-
},
|
|
152
|
-
cancelToken: window['__grabToken'].token
|
|
153
|
-
}
|
|
154
|
-
)
|
|
155
|
-
.then(resp => {
|
|
156
|
-
if(resp.data && "kind" in resp.data){
|
|
157
|
-
resolve(resp.data)
|
|
158
|
-
}else{
|
|
159
|
-
reject(resp.data)
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
.catch(err => reject(err));
|
|
163
|
-
})
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const el = (e : string) => document.querySelector(e);
|
|
167
|
-
|
|
168
|
-
const byName = (e : string) => document.querySelector(`*[name="${e}"]`);
|
|
169
|
-
|
|
170
|
-
const byId = (e : string) => document.getElementById(e);
|
|
171
|
-
|
|
172
|
-
const addProps = (children : any, prop : any) => {
|
|
173
|
-
let form = {}
|
|
174
|
-
let allowedFields = [Input, Select, Button];
|
|
175
|
-
let child = Children.deepMap(children, c => {
|
|
176
|
-
if(allowedFields.indexOf(c['type']) > -1 && c['props'] && !form[c['props'].name]){
|
|
177
|
-
form[c['props'].name] = c['props'].value || null;
|
|
178
|
-
}
|
|
179
|
-
let Clone = cloneElement(c as ReactElement<any>, prop);
|
|
180
|
-
return Clone;
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
children : child,
|
|
185
|
-
fields: form
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const ucfirst = ( str : string ) => {
|
|
190
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const filterStyleProps = (props : any) => {
|
|
194
|
-
|
|
195
|
-
const pks = Object.keys(props);
|
|
196
|
-
const css = Object.keys(cssProps);
|
|
197
|
-
let filter = {}
|
|
198
|
-
css.filter(x => pks.includes(x))
|
|
199
|
-
|
|
200
|
-
// .map(k => filter[k] = props[k].toString());
|
|
201
|
-
return filter;
|
|
202
|
-
// const allowed = Object.keys(props);
|
|
203
|
-
// let allowed = Object.keys(cssProps);
|
|
204
|
-
|
|
205
|
-
// return Object.keys(props)
|
|
206
|
-
// .filter( k => allowed.includes(k))
|
|
207
|
-
// .reduce( (o, k) => {
|
|
208
|
-
// // console.log(o)
|
|
209
|
-
// console.log(k, props[k])
|
|
210
|
-
// // o[k] = props[k].toString();
|
|
211
|
-
// // return o;
|
|
212
|
-
// })
|
|
213
|
-
// return [props].filter( row => (
|
|
214
|
-
// Object.keys(row)
|
|
215
|
-
// .map(key => css.includes(key))
|
|
216
|
-
// ));
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const filterHTMLProps = (props : any) => {
|
|
220
|
-
const pks = Object.keys(props);
|
|
221
|
-
const css = Object.keys(cssProps);
|
|
222
|
-
let filter = {}
|
|
223
|
-
pks.filter(x => {
|
|
224
|
-
if(x!= `for` && !css.includes(x)){
|
|
225
|
-
filter[x] = props[x]
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
return filter;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const uuid = (len=21) => nanoid(len)
|
|
232
|
-
|
|
233
|
-
const addScript = (src: string, callback: () => any) => {
|
|
234
|
-
var s = document.createElement('script')
|
|
235
|
-
s.setAttribute('src', src)
|
|
236
|
-
s.addEventListener('load', callback, false)
|
|
237
|
-
document.body.appendChild(s)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const shuffleArray = array => {
|
|
241
|
-
for (let i = array.length - 1; i > 0; i--) {
|
|
242
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
243
|
-
[array[i], array[j]] = [array[j], array[i]];
|
|
244
|
-
}
|
|
245
|
-
return array
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const getUriParams = () => {
|
|
249
|
-
var search = location.search.substring(1);
|
|
250
|
-
if(search=='') return JSON.parse('{}');
|
|
251
|
-
var xny = {};
|
|
252
|
-
if("URLSearchParams" in window){
|
|
253
|
-
var items = new URLSearchParams(search);
|
|
254
|
-
for(const [k, v] of items){
|
|
255
|
-
xny[k] = v || ``;
|
|
256
|
-
}
|
|
257
|
-
}else{
|
|
258
|
-
try{
|
|
259
|
-
xny = JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');
|
|
260
|
-
}catch(e){
|
|
261
|
-
xny = {};
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return xny;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const rgb2hex = rgb => `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}`
|
|
268
|
-
|
|
269
|
-
const getHostname = url => {
|
|
270
|
-
if(window.URL){
|
|
271
|
-
let u = new window.URL(url);
|
|
272
|
-
return u.hostname
|
|
273
|
-
}else{
|
|
274
|
-
var a = document.createElement(`a`)
|
|
275
|
-
a.href = url
|
|
276
|
-
return a.hostname.replace("www.", "")
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const imgPromiseFactory = ({decode = true, crossOrigin = ''}) =>
|
|
281
|
-
(src): Promise<void> => {
|
|
282
|
-
return new Promise((resolve, reject) => {
|
|
283
|
-
const i = new Image()
|
|
284
|
-
if (crossOrigin) i.crossOrigin = crossOrigin
|
|
285
|
-
i.onload = () => {
|
|
286
|
-
decode && i.decode ? i.decode().then(resolve).catch(reject) : resolve()
|
|
287
|
-
}
|
|
288
|
-
i.onerror = reject
|
|
289
|
-
i.src = src
|
|
290
|
-
})
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const parseFilename = nm => {
|
|
294
|
-
var re = /(?:\.([^.]+))?$/;
|
|
295
|
-
return {
|
|
296
|
-
name: nm.split('.').slice(0, -1).join('.'),
|
|
297
|
-
ext: re.exec(nm)[1]
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const camelCase = str => str.replace(":", "-").replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
|
|
302
|
-
|
|
303
|
-
const getMousePosition = e => {
|
|
304
|
-
const pos = {
|
|
305
|
-
x: (e as MouseEvent).clientX,
|
|
306
|
-
y: (e as MouseEvent).clientY,
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
const touch = (e as TouchEvent).changedTouches;
|
|
310
|
-
|
|
311
|
-
if (touch) {
|
|
312
|
-
pos.x = touch[0].clientX;
|
|
313
|
-
pos.y = touch[0].clientY;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (!pos.x || pos.x < 0) pos.x = 0;
|
|
317
|
-
|
|
318
|
-
if (!pos.y || pos.y < 0) pos.y = 0;
|
|
319
|
-
|
|
320
|
-
return pos;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const copyToClipboard = (str : string, callback: Function) => {
|
|
324
|
-
const el = document.createElement('textarea');
|
|
325
|
-
let storeContentEditable = el.contentEditable;
|
|
326
|
-
let storeReadOnly = el.readOnly;
|
|
327
|
-
el.value = str;
|
|
328
|
-
el.contentEditable = `true`;
|
|
329
|
-
el.readOnly = false;
|
|
330
|
-
el.setAttribute('readonly', `false`);
|
|
331
|
-
el.setAttribute('contenteditable', `true`);
|
|
332
|
-
el.style.position = 'absolute';
|
|
333
|
-
el.style.left = '-999999999px';
|
|
334
|
-
document.body.appendChild(el);
|
|
335
|
-
const selected =
|
|
336
|
-
document.getSelection().rangeCount > 0
|
|
337
|
-
? document.getSelection().getRangeAt(0)
|
|
338
|
-
: false;
|
|
339
|
-
el.select();
|
|
340
|
-
el.setSelectionRange(0, 999999);
|
|
341
|
-
document.execCommand('copy');
|
|
342
|
-
document.body.removeChild(el);
|
|
343
|
-
if (selected) {
|
|
344
|
-
document.getSelection().removeAllRanges();
|
|
345
|
-
document.getSelection().addRange(selected);
|
|
346
|
-
}
|
|
347
|
-
el.contentEditable = storeContentEditable;
|
|
348
|
-
el.readOnly = storeReadOnly;
|
|
349
|
-
if(callback) callback()
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Format bytes as human-readable text.
|
|
354
|
-
*
|
|
355
|
-
* @param bytes Number of bytes.
|
|
356
|
-
* @param si True to use metric (SI) units, aka powers of 1000. False to use
|
|
357
|
-
* binary (IEC), aka powers of 1024.
|
|
358
|
-
* @param dp Number of decimal places to display.
|
|
359
|
-
*
|
|
360
|
-
* @return Formatted string.
|
|
361
|
-
*/
|
|
362
|
-
const formatSize = (bytes, si=false, dp=1) => {
|
|
363
|
-
const thresh = si ? 1000 : 1024;
|
|
364
|
-
|
|
365
|
-
if (Math.abs(bytes) < thresh) {
|
|
366
|
-
return bytes + ' B';
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
370
|
-
let u = -1;
|
|
371
|
-
const r = 10**dp;
|
|
372
|
-
|
|
373
|
-
do {
|
|
374
|
-
bytes /= thresh;
|
|
375
|
-
++u;
|
|
376
|
-
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
return bytes.toFixed(dp) + ' ' + units[u];
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const slugify = (...args: (string | number)[]): string => {
|
|
383
|
-
const value = args.join(' ')
|
|
384
|
-
|
|
385
|
-
return value
|
|
386
|
-
.normalize('NFD') // split an accented letter in the base letter and the acent
|
|
387
|
-
.replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
|
|
388
|
-
.toLowerCase()
|
|
389
|
-
.trim()
|
|
390
|
-
.replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
|
|
391
|
-
.replace(/\s+/g, '-') // separator
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
export {
|
|
395
|
-
addProps,
|
|
396
|
-
addScript,
|
|
397
|
-
buildCSS,
|
|
398
|
-
cleanProps,
|
|
399
|
-
buildFormData,
|
|
400
|
-
byName,
|
|
401
|
-
byId,
|
|
402
|
-
el,
|
|
403
|
-
grab,
|
|
404
|
-
isEmail,
|
|
405
|
-
isIPv4,
|
|
406
|
-
isUrl,
|
|
407
|
-
imgPromiseFactory,
|
|
408
|
-
randstr,
|
|
409
|
-
setCSSVar,
|
|
410
|
-
getCookie,
|
|
411
|
-
setCookie,
|
|
412
|
-
removeCookie,
|
|
413
|
-
ucfirst,
|
|
414
|
-
filterStyleProps,
|
|
415
|
-
filterHTMLProps,
|
|
416
|
-
uuid,
|
|
417
|
-
shuffleArray,
|
|
418
|
-
getUriParams,
|
|
419
|
-
rgb2hex,
|
|
420
|
-
generateModalRoutes,
|
|
421
|
-
generatePreservedRoutes,
|
|
422
|
-
generateRegularRoutes,
|
|
423
|
-
getHostname,
|
|
424
|
-
parseFilename,
|
|
425
|
-
camelCase,
|
|
426
|
-
getMousePosition,
|
|
427
|
-
formatSize,
|
|
428
|
-
copyToClipboard,
|
|
429
|
-
slugify
|
|
430
|
-
}
|
|
431
|
-
|
package/src/core/router.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
export const patterns = {
|
|
2
|
-
route: [/^.*\/src\/pages\/|\.(jsx|tsx)$/g, ''],
|
|
3
|
-
splat: [/\[\.{3}\w+\]/g, '*'],
|
|
4
|
-
param: [/\[([^\]]+)\]/g, ':$1'],
|
|
5
|
-
slash: [/^index$|\./g, '/'],
|
|
6
|
-
optional: [/^-(:?[\w-]+)/, '$1?'],
|
|
7
|
-
} as const
|
|
8
|
-
|
|
9
|
-
type PreservedKey = '_app' | '404'
|
|
10
|
-
type BaseRoute = { id?: string; path?: string; children?: BaseRoute[] } & Record<string, any>
|
|
11
|
-
|
|
12
|
-
export const generatePreservedRoutes = <T>(files: Record<string, T | any>): Partial<Record<PreservedKey, T>> => {
|
|
13
|
-
return Object.keys(files).reduce((routes, key) => {
|
|
14
|
-
const path = key.replace(...patterns.route)
|
|
15
|
-
return { ...routes, [path]: files[key] }
|
|
16
|
-
}, {})
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const generateRegularRoutes = <T extends BaseRoute, M>(
|
|
20
|
-
files: Record<string, any>,
|
|
21
|
-
buildRoute: (module: M, key: string) => T
|
|
22
|
-
) => {
|
|
23
|
-
const filteredRoutes = Object.keys(files).filter((key) => !key.includes('/_') || /_layout\.(jsx|tsx)$/.test(key))
|
|
24
|
-
return filteredRoutes.reduce<T[]>((routes, key) => {
|
|
25
|
-
const module = files[key]
|
|
26
|
-
const route = { id: key.replace(...patterns.route), ...buildRoute(module, key) }
|
|
27
|
-
|
|
28
|
-
const segments = key
|
|
29
|
-
.replace(...patterns.route)
|
|
30
|
-
.replace(...patterns.splat)
|
|
31
|
-
.replace(...patterns.param)
|
|
32
|
-
.split('/')
|
|
33
|
-
.filter(Boolean)
|
|
34
|
-
|
|
35
|
-
segments.reduce((parent, segment, index) => {
|
|
36
|
-
const path = segment.replace(...patterns.slash).replace(...patterns.optional)
|
|
37
|
-
const root = index === 0
|
|
38
|
-
const leaf = index === segments.length - 1 && segments.length > 1
|
|
39
|
-
const node = !root && !leaf
|
|
40
|
-
const layout = segment === '_layout'
|
|
41
|
-
const group = /\(\w+\)/.test(path)
|
|
42
|
-
const insert = /^\w|\//.test(path) ? 'unshift' : 'push'
|
|
43
|
-
|
|
44
|
-
if (root) {
|
|
45
|
-
const last = segments.length === 1
|
|
46
|
-
if (last) {
|
|
47
|
-
routes.push({ path, ...route })
|
|
48
|
-
return parent
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (root || node) {
|
|
53
|
-
const current = root ? routes : parent.children
|
|
54
|
-
const found = current?.find((route) => route.path === path || route.id?.split('@')?.[0] === path)
|
|
55
|
-
const props = group ? (route?.component ? { id: path, path: '/' } : { id: path }) : { path }
|
|
56
|
-
if (found) found.children ??= []
|
|
57
|
-
else current?.[insert]({ ...props, children: [] })
|
|
58
|
-
return found || (current?.[insert === 'unshift' ? 0 : current.length - 1] as BaseRoute)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (layout) {
|
|
62
|
-
return Object.assign(parent, { ...route, id: `${parent.id || parent.path}@${route.id}` })
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (leaf) {
|
|
66
|
-
parent?.children?.[insert](route?.index ? route : { path, ...route })
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return parent
|
|
70
|
-
}, {} as BaseRoute)
|
|
71
|
-
|
|
72
|
-
return routes
|
|
73
|
-
}, [])
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const generateModalRoutes = <T>(files: Record<string, T | any>): Record<string, T> => {
|
|
77
|
-
return Object.keys(files).reduce((modals, key) => {
|
|
78
|
-
const path = key
|
|
79
|
-
.replace(...patterns.route)
|
|
80
|
-
.replace(/\+|\(\w+\)\//g, '')
|
|
81
|
-
.replace(/(\/)?index/g, '')
|
|
82
|
-
.replace(/\./g, '/')
|
|
83
|
-
|
|
84
|
-
return { ...modals, [`/${path}`]: files[key]?.default }
|
|
85
|
-
}, {})
|
|
86
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useReducer } from 'react'
|
|
2
|
-
import { UNDO, REDO, RESET } from '../actions'
|
|
3
|
-
|
|
4
|
-
const useAppReducer = (reducer, inititalState : Object, passedConfig = {}) => {
|
|
5
|
-
|
|
6
|
-
const initialStateWithUndoRedo = {
|
|
7
|
-
...inititalState,
|
|
8
|
-
pastDesignStates: [],
|
|
9
|
-
futureDesignStates: [],
|
|
10
|
-
hasRedo: false,
|
|
11
|
-
hasUndo: false,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const undoRedoResetReducer = (state, action) => {
|
|
15
|
-
|
|
16
|
-
const newPresetState = reducer(state, action) || initialStateWithUndoRedo
|
|
17
|
-
|
|
18
|
-
if([UNDO,REDO,RESET].includes(action.type)){
|
|
19
|
-
return newPresetState;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if(newPresetState.isDesignState){
|
|
23
|
-
|
|
24
|
-
const newState = {
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return newState;
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return newPresetState;
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return useReducer(undoRedoResetReducer, initialStateWithUndoRedo)
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default useAppReducer;
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { SyntheticEvent, useEffect, useState, useRef } from "react"
|
|
2
|
-
import ReactDOM from 'react-dom/client'
|
|
3
|
-
import Box from '../comps/box'
|
|
4
|
-
import { getMousePosition } from "../core"
|
|
5
|
-
|
|
6
|
-
const Menu = ({ ID, hide, e, items, width }) => {
|
|
7
|
-
|
|
8
|
-
const nodeRef = useRef(null);
|
|
9
|
-
const [p, setP] = useState(getMousePosition(e as MouseEvent));
|
|
10
|
-
const [visible, setVisible] = useState(false);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const checkBoundaries = (x: number, y: number) => {
|
|
14
|
-
if (nodeRef.current) {
|
|
15
|
-
const { innerWidth, innerHeight } = window;
|
|
16
|
-
const { offsetWidth, offsetHeight } = nodeRef.current;
|
|
17
|
-
if(x + offsetWidth > innerWidth) x -= offsetWidth //x + offsetWidth - innerWidth;
|
|
18
|
-
if (y + offsetHeight > innerHeight) y -= offsetHeight;
|
|
19
|
-
}
|
|
20
|
-
setP({ x, y })
|
|
21
|
-
setVisible(true)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
checkBoundaries(p.x, p.y);
|
|
26
|
-
}, [e])
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<Box
|
|
30
|
-
bref={nodeRef}
|
|
31
|
-
flex dir={`cols`}
|
|
32
|
-
fixed
|
|
33
|
-
top={p.y}
|
|
34
|
-
left={p.x}
|
|
35
|
-
w={width || 220}
|
|
36
|
-
opacity={visible ? 1 : 0}
|
|
37
|
-
as={`zuz-contextmenu ${ID}`}>
|
|
38
|
-
{(items as Array<any>).map((m, i) => m.id == `line` ? <Box as={`line`} key={`line-${i}-${m.id}`} /> : <button
|
|
39
|
-
key={`cm-${i}-${m.id}`}
|
|
40
|
-
onClick={ev => {
|
|
41
|
-
if(m.onClick){
|
|
42
|
-
m.onClick(ev, m)
|
|
43
|
-
}else{
|
|
44
|
-
console.log(`No onClick eventFound`)
|
|
45
|
-
}
|
|
46
|
-
hide()
|
|
47
|
-
}}>{m.label}</button>)}
|
|
48
|
-
</Box>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const useContextMenu = (
|
|
53
|
-
contextID : string,
|
|
54
|
-
contextWidth: number,
|
|
55
|
-
contextToken = `____uchides`
|
|
56
|
-
) => {
|
|
57
|
-
|
|
58
|
-
const ID = `contextmenu-${contextID}`
|
|
59
|
-
const [visible, setVisible] = useState(false)
|
|
60
|
-
const [root, setRoot] = useState(null)
|
|
61
|
-
|
|
62
|
-
const el = (e : string) => window.document.createElement(e)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const createRoot = () => {
|
|
66
|
-
if(!window.document.querySelector(`#${ID}`)){
|
|
67
|
-
let div = el(`div`)
|
|
68
|
-
div.id = ID
|
|
69
|
-
window.document.body.appendChild(div)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const hideAll = () => {
|
|
74
|
-
if(window[contextToken]){
|
|
75
|
-
window[contextToken].map((h : Object) => h['ID'] != ID && h['fnc']())
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const _hide = () => {
|
|
80
|
-
try{
|
|
81
|
-
root?.unmount()
|
|
82
|
-
document.querySelector(`#${ID}`).parentNode.removeChild(document.querySelector(`#${ID}`))
|
|
83
|
-
setRoot(null)
|
|
84
|
-
}catch(e){}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const hide = () => {
|
|
88
|
-
_hide()
|
|
89
|
-
hideAll()
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const show = (e : MouseEvent, items : Array<any>) => {
|
|
93
|
-
e.preventDefault(); e.stopPropagation();
|
|
94
|
-
hideAll()
|
|
95
|
-
root.render(<Menu e={e} width={contextWidth || 220} items={items} ID={ID} hide={hide} />)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
useEffect(() => {
|
|
99
|
-
createRoot()
|
|
100
|
-
if(!root) setRoot(ReactDOM.createRoot(document.getElementById(ID)))
|
|
101
|
-
}, [root])
|
|
102
|
-
|
|
103
|
-
useEffect(() => {
|
|
104
|
-
if(contextToken in window == false){
|
|
105
|
-
window[contextToken] = []
|
|
106
|
-
}
|
|
107
|
-
if(window[contextToken].findIndex(x => x.ID == ID) == -1){
|
|
108
|
-
window[contextToken].push({ ID: ID, fnc: _hide })
|
|
109
|
-
if(window[contextToken].length > document.querySelectorAll('div[id^="contextmenu-"]').length){
|
|
110
|
-
window[contextToken].shift()
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}, [])
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
show,
|
|
117
|
-
hide,
|
|
118
|
-
hideAll
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export default useContextMenu
|