@zuzjs/ui 0.2.4 → 0.2.6

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.
Files changed (67) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +214 -15
  3. package/package.json +4 -2
  4. package/src/actions/addForm.tsx +0 -0
  5. package/src/actions/index.tsx +29 -0
  6. package/src/actions/redo.tsx +1 -0
  7. package/src/actions/reset.tsx +1 -0
  8. package/src/actions/undo.tsx +1 -0
  9. package/src/comps/app.tsx +34 -0
  10. package/src/comps/box.tsx +23 -0
  11. package/src/comps/button.tsx +45 -0
  12. package/src/comps/checkbox.tsx +74 -0
  13. package/src/comps/component.tsx +32 -0
  14. package/src/comps/contextmenu.tsx +43 -0
  15. package/src/comps/cover.tsx +34 -0
  16. package/src/comps/form.tsx +89 -0
  17. package/src/comps/heading.tsx +31 -0
  18. package/src/comps/icon.tsx +36 -0
  19. package/src/comps/image.tsx +26 -0
  20. package/src/comps/input.tsx +80 -0
  21. package/src/comps/masonry.tsx +192 -0
  22. package/src/comps/placeholder.tsx +58 -0
  23. package/src/comps/root.tsx +32 -0
  24. package/src/comps/select.tsx +63 -0
  25. package/src/comps/spacer.tsx +20 -0
  26. package/src/comps/spinner.tsx +36 -0
  27. package/src/comps/text.tsx +27 -0
  28. package/src/comps/toaster.tsx +115 -0
  29. package/src/comps/tweet.tsx +48 -0
  30. package/src/context/AppContext.tsx +3 -0
  31. package/src/context/AppProvider.tsx +101 -0
  32. package/src/context/_AppProvider.tsx +116 -0
  33. package/src/context/combineReducers.tsx +47 -0
  34. package/src/context/combineState.tsx +14 -0
  35. package/src/context/createSlice.tsx +40 -0
  36. package/src/context/index.tsx +6 -0
  37. package/src/context/reduceReducers.tsx +6 -0
  38. package/src/context/store/appbase.tsx +19 -0
  39. package/src/context/store/theme.tsx +53 -0
  40. package/src/core/defaultTheme.ts +89 -0
  41. package/src/core/extractCurrentDesignState.tsx +0 -0
  42. package/src/core/index.ts +285 -0
  43. package/src/core/router.ts +86 -0
  44. package/src/core/styles.ts +361 -0
  45. package/src/hooks/index.tsx +8 -0
  46. package/src/hooks/useAppReducer.tsx +40 -0
  47. package/src/hooks/useChooseEffect.tsx +6 -0
  48. package/src/hooks/useDevice.tsx +164 -0
  49. package/src/hooks/useDispatch.tsx +37 -0
  50. package/src/hooks/useImage.tsx +58 -0
  51. package/src/hooks/useResizeObserver.tsx +84 -0
  52. package/src/hooks/useRouter.tsx +45 -0
  53. package/src/hooks/useSelector.tsx +9 -0
  54. package/src/hooks/useStore.tsx +27 -0
  55. package/src/hooks/useTheme.tsx +9 -0
  56. package/src/hooks/useToast.tsx +11 -0
  57. package/src/index.tsx +33 -0
  58. package/src/kit/Builder.tsx +18 -0
  59. package/src/kit/Component.tsx +32 -0
  60. package/src/kit/Header.tsx +21 -0
  61. package/src/redux/slices/app.js +26 -0
  62. package/src/redux/slices/form.js +46 -0
  63. package/src/redux/store.js +33 -0
  64. package/src/scss/constants.scss +4 -0
  65. package/src/scss/mixins.scss +3 -0
  66. package/src/scss/props.scss +60 -0
  67. package/src/scss/style.scss +106 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # zuzjs
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useEffect, useMemo, useReducer, useCallback, useContext, forwardRef, useRef, useState, useLayoutEffect, useDebugValue, cloneElement, useImperativeHandle, createElement } from 'react';
1
+ import { createContext, useEffect, useMemo, useReducer, useCallback, useContext, forwardRef, useRef, useState, useLayoutEffect, useDebugValue, cloneElement, useImperativeHandle, createElement, Component as Component$1, Children as Children$1 } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import PropTypes from 'prop-types';
4
4
  import Children from 'react-children-utilities';
@@ -59,16 +59,16 @@ class AppTheme {
59
59
  _AppTheme_darkTheme.set(this, void 0);
60
60
  this.get = () => {
61
61
  let self = this;
62
- if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "auto") {
63
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
64
- __classPrivateFieldSet(self, _AppTheme_mode, event.matches ? "dark" : "light", "f");
65
- __classPrivateFieldGet(self, _AppTheme_listen, "f").call(self, __classPrivateFieldGet(self, _AppTheme_mode, "f"));
66
- });
67
- return window.matchMedia &&
68
- window.matchMedia('(prefers-color-scheme: dark)').matches ?
69
- __classPrivateFieldGet(self, _AppTheme_darkTheme, "f") : __classPrivateFieldGet(self, _AppTheme_lightTheme, "f");
70
- }
71
- else if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "light") {
62
+ // if(self.#mode === "auto"){
63
+ // window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
64
+ // self.#mode = event.matches ? "dark" : "light";
65
+ // self.#listen(self.#mode);
66
+ // });
67
+ // return window.matchMedia &&
68
+ // window.matchMedia('(prefers-color-scheme: dark)').matches ?
69
+ // self.#darkTheme : self.#lightTheme;
70
+ // }else
71
+ if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "light") {
72
72
  return __classPrivateFieldGet(self, _AppTheme_lightTheme, "f");
73
73
  }
74
74
  else if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "dark") {
@@ -251,6 +251,7 @@ const cssProps = {
251
251
  "@charset": "@charset",
252
252
  "clear": "clear",
253
253
  "clip": "clip",
254
+ "clipPath": "clip-path",
254
255
  "color": "color",
255
256
  "columnCount": "column-count",
256
257
  "columnFill": "column-fill",
@@ -555,12 +556,12 @@ const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
555
556
  };
556
557
 
557
558
  const Input = forwardRef((props, ref) => {
558
- const { as, accept, multiple, onChange, type, tag, placeholder, name, form, touched, onSubmit, defaultValue } = props;
559
+ const { as, accept, multiple, onChange, onKeyUp, type, tag, placeholder, name, form, touched, onSubmit, defaultValue, fref } = props;
559
560
  const dispatch = useDispatch(STORE_FORM_KEY);
560
561
  const { forms } = useStore(state => state[STORE_FORM_KEY], false);
561
562
  let Tag = tag || 'input';
562
563
  const El = Tag;
563
- const _ref = useRef();
564
+ const _ref = fref || useRef();
564
565
  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);`;
565
566
  return (jsx(ClassNames, { children: ({ css, cx }) => jsx(El, { type: type || `text`, placeholder: placeholder || 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, defaultValue: defaultValue || ``, onKeyUp: (e) => {
566
567
  let k = e['keyCode'] || ['which'];
@@ -572,7 +573,7 @@ const Input = forwardRef((props, ref) => {
572
573
  e.currentTarget.files
573
574
  : e.currentTarget.value;
574
575
  dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val == "" ? null : val, forms)));
575
- onChange && onChange(e.target.value == "" ? null : e.target.value);
576
+ onChange && onChange(val == "" ? null : val);
576
577
  }, onBlur: e => {
577
578
  }, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)) }) }));
578
579
  });
@@ -909,6 +910,79 @@ const Button = forwardRef((props, ref) => {
909
910
  } }));
910
911
  });
911
912
 
913
+ const patterns = {
914
+ route: [/^.*\/src\/pages\/|\.(jsx|tsx)$/g, ''],
915
+ splat: [/\[\.{3}\w+\]/g, '*'],
916
+ param: [/\[([^\]]+)\]/g, ':$1'],
917
+ slash: [/^index$|\./g, '/'],
918
+ optional: [/^-(:?[\w-]+)/, '$1?'],
919
+ };
920
+ const generatePreservedRoutes = (files) => {
921
+ return Object.keys(files).reduce((routes, key) => {
922
+ const path = key.replace(...patterns.route);
923
+ return Object.assign(Object.assign({}, routes), { [path]: files[key] });
924
+ }, {});
925
+ };
926
+ const generateRegularRoutes = (files, buildRoute) => {
927
+ const filteredRoutes = Object.keys(files).filter((key) => !key.includes('/_') || /_layout\.(jsx|tsx)$/.test(key));
928
+ return filteredRoutes.reduce((routes, key) => {
929
+ const module = files[key];
930
+ const route = Object.assign({ id: key.replace(...patterns.route) }, buildRoute(module, key));
931
+ const segments = key
932
+ .replace(...patterns.route)
933
+ .replace(...patterns.splat)
934
+ .replace(...patterns.param)
935
+ .split('/')
936
+ .filter(Boolean);
937
+ segments.reduce((parent, segment, index) => {
938
+ var _a, _b;
939
+ const path = segment.replace(...patterns.slash).replace(...patterns.optional);
940
+ const root = index === 0;
941
+ const leaf = index === segments.length - 1 && segments.length > 1;
942
+ const node = !root && !leaf;
943
+ const layout = segment === '_layout';
944
+ const group = /\(\w+\)/.test(path);
945
+ const insert = /^\w|\//.test(path) ? 'unshift' : 'push';
946
+ if (root) {
947
+ const last = segments.length === 1;
948
+ if (last) {
949
+ routes.push(Object.assign({ path }, route));
950
+ return parent;
951
+ }
952
+ }
953
+ if (root || node) {
954
+ const current = root ? routes : parent.children;
955
+ const found = current === null || current === void 0 ? void 0 : current.find((route) => { var _a, _b; return route.path === path || ((_b = (_a = route.id) === null || _a === void 0 ? void 0 : _a.split('@')) === null || _b === void 0 ? void 0 : _b[0]) === path; });
956
+ const props = group ? ((route === null || route === void 0 ? void 0 : route.component) ? { id: path, path: '/' } : { id: path }) : { path };
957
+ if (found)
958
+ (_a = found.children) !== null && _a !== void 0 ? _a : (found.children = []);
959
+ else
960
+ current === null || current === void 0 ? void 0 : current[insert](Object.assign(Object.assign({}, props), { children: [] }));
961
+ return found || (current === null || current === void 0 ? void 0 : current[insert === 'unshift' ? 0 : current.length - 1]);
962
+ }
963
+ if (layout) {
964
+ return Object.assign(parent, Object.assign(Object.assign({}, route), { id: `${parent.id || parent.path}@${route.id}` }));
965
+ }
966
+ if (leaf) {
967
+ (_b = parent === null || parent === void 0 ? void 0 : parent.children) === null || _b === void 0 ? void 0 : _b[insert]((route === null || route === void 0 ? void 0 : route.index) ? route : Object.assign({ path }, route));
968
+ }
969
+ return parent;
970
+ }, {});
971
+ return routes;
972
+ }, []);
973
+ };
974
+ const generateModalRoutes = (files) => {
975
+ return Object.keys(files).reduce((modals, key) => {
976
+ var _a;
977
+ const path = key
978
+ .replace(...patterns.route)
979
+ .replace(/\+|\(\w+\)\//g, '')
980
+ .replace(/(\/)?index/g, '')
981
+ .replace(/\./g, '/');
982
+ return Object.assign(Object.assign({}, modals), { [`/${path}`]: (_a = files[key]) === null || _a === void 0 ? void 0 : _a.default });
983
+ }, {});
984
+ };
985
+
912
986
  const makeCSSValue = (k, v, o) => {
913
987
  let ignore = cssPropsIgnore.indexOf(o) == -1;
914
988
  if (k in cssPropsDirect && ignore == true) {
@@ -1269,6 +1343,131 @@ const Image = forwardRef((props, ref) => {
1269
1343
  return (jsx(ClassNames, { children: ({ css, cx }) => jsxs("picture", Object.assign({ className: cx(css `${buildCSS({ flex: true })}`) }, { children: [status == 'loading' && jsx(Box, { className: `${props.as ? `${props.as} ` : ``}${cx(css `background: #eee;${buildCSS(props)}`)}` }), status == 'loaded' && jsx("img", { src: props.src, className: `${props.as ? `${props.as} ` : ``}${cx(css `${buildCSS(props)}`)}`, ref: ref })] })) }));
1270
1344
  });
1271
1345
 
1346
+ const DEFAULT_COLUMNS = 2;
1347
+ class Masonry extends Component$1 {
1348
+ constructor(props) {
1349
+ super(props);
1350
+ this._lastRecalculateAnimationFrame = window.requestAnimationFrame(() => {
1351
+ this.reCalculateColumnCount();
1352
+ });
1353
+ // Correct scope for when methods are accessed externally
1354
+ this.reCalculateColumnCount = this.reCalculateColumnCount.bind(this);
1355
+ this.reCalculateColumnCountDebounce = this.reCalculateColumnCountDebounce.bind(this);
1356
+ // default state
1357
+ let columnCount;
1358
+ if (this.props && this.props.breakpointCols.default) {
1359
+ columnCount = this.props.breakpointCols.default;
1360
+ }
1361
+ else {
1362
+ columnCount = parseInt(this.props.breakpointCols) || DEFAULT_COLUMNS;
1363
+ }
1364
+ this.state = {
1365
+ columnCount
1366
+ };
1367
+ }
1368
+ componentDidMount() {
1369
+ this.reCalculateColumnCount();
1370
+ // window may not be available in some environments
1371
+ if (window) {
1372
+ window.addEventListener('resize', this.reCalculateColumnCountDebounce);
1373
+ }
1374
+ }
1375
+ componentDidUpdate() {
1376
+ this.reCalculateColumnCount();
1377
+ }
1378
+ componentWillUnmount() {
1379
+ if (window) {
1380
+ window.removeEventListener('resize', this.reCalculateColumnCountDebounce);
1381
+ }
1382
+ }
1383
+ reCalculateColumnCountDebounce() {
1384
+ if (!window || !window.requestAnimationFrame) { // IE10+
1385
+ this.reCalculateColumnCount();
1386
+ return;
1387
+ }
1388
+ if (window.cancelAnimationFrame) { // IE10+
1389
+ window.cancelAnimationFrame(this._lastRecalculateAnimationFrame);
1390
+ }
1391
+ }
1392
+ reCalculateColumnCount() {
1393
+ const windowWidth = window && window.innerWidth || Infinity;
1394
+ let breakpointColsObject = this.props.breakpointCols;
1395
+ // Allow passing a single number to `breakpointCols` instead of an object
1396
+ if (typeof breakpointColsObject !== 'object') {
1397
+ breakpointColsObject = {
1398
+ default: parseInt(breakpointColsObject) || DEFAULT_COLUMNS
1399
+ };
1400
+ }
1401
+ let matchedBreakpoint = Infinity;
1402
+ let columns = breakpointColsObject.default || DEFAULT_COLUMNS;
1403
+ for (let breakpoint in breakpointColsObject) {
1404
+ const optBreakpoint = parseInt(breakpoint);
1405
+ const isCurrentBreakpoint = optBreakpoint > 0 && windowWidth <= optBreakpoint;
1406
+ if (isCurrentBreakpoint && optBreakpoint < matchedBreakpoint) {
1407
+ matchedBreakpoint = optBreakpoint;
1408
+ columns = breakpointColsObject[breakpoint];
1409
+ }
1410
+ }
1411
+ columns = Math.max(1, parseInt(columns) || 1);
1412
+ if (this.state.columnCount !== columns) {
1413
+ this.setState({
1414
+ columnCount: columns
1415
+ });
1416
+ this.props.onChange && this.props.onChange({ columns: columns });
1417
+ }
1418
+ }
1419
+ itemsInColumns() {
1420
+ const currentColumnCount = this.state.columnCount;
1421
+ const itemsInColumns = new Array(currentColumnCount);
1422
+ // Force children to be handled as an array
1423
+ const items = Children$1.toArray(this.props.children);
1424
+ for (let i = 0; i < items.length; i++) {
1425
+ const columnIndex = i % currentColumnCount;
1426
+ if (!itemsInColumns[columnIndex]) {
1427
+ itemsInColumns[columnIndex] = [];
1428
+ }
1429
+ itemsInColumns[columnIndex].push(items[i]);
1430
+ }
1431
+ return itemsInColumns;
1432
+ }
1433
+ renderColumns() {
1434
+ const { column, columnAttrs = {}, columnClassName } = this.props;
1435
+ const childrenInColumns = this.itemsInColumns();
1436
+ const columnWidth = `${100 / childrenInColumns.length}%`;
1437
+ let className = columnClassName;
1438
+ if (className && typeof className !== 'string') {
1439
+ this.logDeprecated('The property "columnClassName" requires a string');
1440
+ // This is a deprecated default and will be removed soon.
1441
+ if (typeof className === 'undefined') {
1442
+ className = 'my-masonry-grid_column';
1443
+ }
1444
+ }
1445
+ const columnAttributes = Object.assign(Object.assign(Object.assign({}, column), columnAttrs), { style: Object.assign(Object.assign({}, columnAttrs.style), { width: columnWidth }), className });
1446
+ return childrenInColumns.map((items, i) => {
1447
+ return createElement("div", Object.assign({}, columnAttributes, { key: i }), items);
1448
+ });
1449
+ }
1450
+ logDeprecated(message) {
1451
+ console.error('[Masonry]', message);
1452
+ }
1453
+ render() {
1454
+ const _a = this.props, {
1455
+ // ignored
1456
+ children, breakpointCols, columnClassName, columnAttrs, column,
1457
+ // used
1458
+ className } = _a, rest = __rest(_a, ["children", "breakpointCols", "columnClassName", "columnAttrs", "column", "className"]);
1459
+ let classNameOutput = className;
1460
+ if (typeof className !== 'string') {
1461
+ this.logDeprecated('The property "className" requires a string');
1462
+ // This is a deprecated default and will be removed soon.
1463
+ if (typeof className === 'undefined') {
1464
+ classNameOutput = 'my-masonry-grid';
1465
+ }
1466
+ }
1467
+ return (jsx("div", Object.assign({}, rest, { className: classNameOutput }, { children: this.renderColumns() })));
1468
+ }
1469
+ }
1470
+
1272
1471
  const calcPlaceholderStyle = (width, height, duration = 1600) => ({
1273
1472
  backgroundSize: `${parseInt(width.toString()) * 10}px ${height}px`,
1274
1473
  animationDuration: `${(duration / 1000).toFixed(1)}s`,
@@ -1349,4 +1548,4 @@ const Header = forwardRef((props, ref) => {
1349
1548
  return (jsx(Fragment, { children: buildComponent(data) }));
1350
1549
  });
1351
1550
 
1352
- export { App, Component as Block, Box, Button, Checkbox, ContextMenu, Cover, Form, Header, Heading, Icon, Image, Input, Placeholder, AppProvider as Provider, Select, Spacer, Spinner, Text, Toaster, Tweet, addProps, addScript, buildCSS, buildFormData, byId, byName, createSlice, el, filterHTMLProps, filterStyleProps, getCookie, getUriParams, grab, isEmail, isIPv4, isUrl, randstr, removeCookie, rgb2hex, setCSSVar, setCookie, shuffleArray, ucfirst, useDevice, useDispatch, useImage, useResizeObserver, useStore, useTheme, useToast, uuid };
1551
+ export { App, Component as Block, Box, Button, Checkbox, ContextMenu, Cover, Form, Header, Heading, Icon, Image, Input, Masonry, Placeholder, AppProvider as Provider, Select, Spacer, Spinner, Text, Toaster, Tweet, addProps, addScript, buildCSS, buildFormData, byId, byName, createSlice, el, filterHTMLProps, filterStyleProps, generateModalRoutes, generatePreservedRoutes, generateRegularRoutes, getCookie, getUriParams, grab, isEmail, isIPv4, isUrl, randstr, removeCookie, rgb2hex, setCSSVar, setCookie, shuffleArray, ucfirst, useDevice, useDispatch, useImage, useResizeObserver, useStore, useTheme, useToast, uuid };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/ui",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -34,12 +34,14 @@
34
34
  "devDependencies": {
35
35
  "@rollup/plugin-commonjs": "^24.0.1",
36
36
  "postcss": "^8.4.21",
37
+ "react-router-dom": "^6.14.2",
37
38
  "rimraf": "^4.4.1",
38
39
  "rollup": "^3.20.2",
39
40
  "rollup-plugin-livereload": "^2.0.5",
40
41
  "rollup-plugin-scss": "^4.0.0",
41
42
  "rollup-plugin-typescript2": "^0.34.1",
42
43
  "rollup-plugin-uglify": "^6.0.4",
43
- "sass": "^1.60.0"
44
+ "sass": "^1.60.0",
45
+ "vite-plugin-environment": "^1.1.3"
44
46
  }
45
47
  }
File without changes
@@ -0,0 +1,29 @@
1
+ import { UNDO } from './undo'
2
+ import { REDO } from './redo'
3
+ import { RESET } from './reset'
4
+
5
+ export const ADD_FORM = (name, fields, forms) => ({
6
+ forms: {
7
+ ...forms,
8
+ [name] : { touched: false, loading: false, ...fields }
9
+ }
10
+ })
11
+
12
+ export const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
13
+ if(forms[formName]){
14
+ let _forms = {
15
+ ...forms
16
+ }
17
+ _forms[formName][field] = value;
18
+ return {
19
+ forms: _forms
20
+ }
21
+ }
22
+ return {}
23
+ }
24
+
25
+ export {
26
+ UNDO,
27
+ REDO,
28
+ RESET
29
+ }
@@ -0,0 +1 @@
1
+ export const REDO = 'REDO';
@@ -0,0 +1 @@
1
+ export const RESET = 'RESET';
@@ -0,0 +1 @@
1
+ export const UNDO = 'UNDO';
@@ -0,0 +1,34 @@
1
+ import {
2
+ forwardRef,
3
+ useEffect
4
+ } from 'react';
5
+ import { setCSSVar, buildCSS } from '../core'
6
+ import { Provider } from '../context'
7
+ import { ClassNames } from '@emotion/react'
8
+ import { useStore } from '../hooks'
9
+
10
+ const AppMain = forwardRef((props : { [ key: string ] : any }, ref) => {
11
+
12
+ // const { dispatch } = useStore()
13
+
14
+ // if("theme" in props && !theme){
15
+ // dispatch(setTheme(props.theme));
16
+ // }
17
+
18
+ return (
19
+ <ClassNames>
20
+ {({ css, cx }) => <main className={`${props.as ? props.as : `zuz-app`} ${cx(css`${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`}>{props.children}</main>}
21
+ </ClassNames>
22
+ )
23
+ })
24
+
25
+ const App = forwardRef((props : { [ key: string ] : any }, ref) => {
26
+
27
+ return (
28
+ <Provider>
29
+ <AppMain />
30
+ </Provider>
31
+ )
32
+ })
33
+
34
+ export default App
@@ -0,0 +1,23 @@
1
+ import {
2
+ forwardRef,
3
+ useEffect
4
+ } from 'react';
5
+ import { ClassNames } from '@emotion/react'
6
+ import { buildCSS } from '../core'
7
+
8
+ const Box = forwardRef((props : { [ key: string ] : any }, ref) => {
9
+
10
+ const _noClick = () => {}
11
+
12
+ return (
13
+ <ClassNames>
14
+ {({ css, cx }) => <div
15
+ id={props.id || undefined}
16
+ onClick={props.onClick || _noClick}
17
+ className={`${props.as ? `${props.as} ` : ``}${cx(css`${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`}
18
+ ref={props.bref || ref}>{props.html ? <span dangerouslySetInnerHTML={{ __html: props.html }} /> : props.children}</div>}
19
+ </ClassNames>
20
+ )
21
+ })
22
+
23
+ export default Box;
@@ -0,0 +1,45 @@
1
+ import React, {
2
+ forwardRef,
3
+ LegacyRef
4
+ } from 'react';
5
+ import { ClassNames } from '@emotion/react'
6
+ import {
7
+ buildCSS,
8
+ filterStyleProps
9
+ } from '../core'
10
+ import { useStore } from '../hooks'
11
+ import { STORE_FORM_KEY } from '../context/AppProvider'
12
+ const Button = forwardRef((props: { [ key: string ] : any }, ref : LegacyRef<HTMLButtonElement>) => {
13
+
14
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false);
15
+ const _otherProps = {}
16
+ if(props.html){
17
+ _otherProps['dangerouslySetInnerHTML'] = { __html: props.html }
18
+ }
19
+
20
+ return (
21
+ <ClassNames>
22
+ {({ css, cx }) => {
23
+ return (
24
+ <button
25
+ title={"title" in props ? props.title : undefined}
26
+ type={props.type}
27
+ className={`button${props.as ? ` ${props.as}` : ``} ${cx(css`
28
+ padding: 5px 10px;
29
+ border-radius: 2px;
30
+ ${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`}
31
+ ref={ref}
32
+ onClick={e => {
33
+ if(props.form && props.type && props.type == 'submit'){
34
+ props.onSubmit(forms[props.form]);
35
+ }else{
36
+ props.onClick ? props.onClick(e) : () => console.warn('onClick Missing')
37
+ }
38
+ }} disabled={props.disabled || false} >{props.html ? <span dangerouslySetInnerHTML={{ __html: props.html }} /> : props.children}</button>
39
+ )
40
+ }}
41
+ </ClassNames>
42
+ )
43
+ })
44
+
45
+ export default Button;
@@ -0,0 +1,74 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import PropTypes from 'prop-types'
3
+ import { nanoid } from 'nanoid'
4
+ import Box from './box'
5
+ import Button from './button'
6
+ import useTheme from '../hooks/useTheme'
7
+ import useDispatch from '../hooks/useDispatch'
8
+ import useStore from '../hooks/useStore'
9
+ import { STORE_FORM_KEY } from '../context/AppProvider'
10
+ import {
11
+ UPDATE_FORM_FIELD
12
+ } from '../actions'
13
+ import { ClassNames } from '@emotion/react'
14
+
15
+ function Checkbox(props) {
16
+
17
+ const {
18
+ checked,
19
+ as,
20
+ name,
21
+ form,
22
+ touched,
23
+ onChange
24
+ } = props;
25
+
26
+ const [_checked, setChecked] = useState(checked || false)
27
+ const theme = useTheme();
28
+
29
+ const dispatch = useDispatch(STORE_FORM_KEY)
30
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false)
31
+
32
+ const switchCheck = useCallback(() => {
33
+ let nextVal = !_checked;
34
+ onChange && onChange(nextVal)
35
+ setChecked(nextVal)
36
+ dispatch( dispatch( UPDATE_FORM_FIELD( form || 'orphan', name, nextVal, forms ) ) );
37
+ }, [_checked])
38
+
39
+ const defaultCSS = `cursor: pointer;&:before {
40
+ background: ${!_checked ? `transparent` : theme.color} !important;
41
+ }`
42
+
43
+ const _name = useMemo(() => name || nanoid(), [name])
44
+
45
+ return (
46
+ <ClassNames>
47
+ {({ css, cx }) => <>
48
+ <input
49
+ onChange={switchCheck}
50
+ id={`zuz${_name}`}
51
+ // className={`${_checked ? 'y' : 'n'} ${as ? ` ${as} ` : ``}f ${cx(css`opacity: 0;position: absolute;&:checked {${defaultCSSChecked}}`)}`}
52
+ className={`zuz-checkbox`}
53
+ name={_name}
54
+ type={`checkbox`}
55
+ value={`checked`}
56
+ />
57
+ <label
58
+ className={`${as ? `${as} ` : ``}f ${cx(css`${defaultCSS}`)}`}
59
+ htmlFor={`zuz${_name}`} />
60
+ </>}
61
+ </ClassNames>
62
+ // <Button
63
+ // overflow={`hidden`}
64
+ // name={name || nanoid()}
65
+ // onClick={switchCheck}
66
+ // w={38} h={22} r={20} bg={`#ddd`} rel>
67
+ // <Box w={38} h={22} anim={`0.2`} abs top={0} r={20} left={0} transform={`translateX(${_checked ? 0 : -16}px)`} bg={theme.color}>
68
+ // <Box w={18} h={18} abs right={2} top={2} bg={`#fff`} r={20} boxShadow={`0px 0px 0px 5px ${_checked ? theme.color : `#ddd`}`} />
69
+ // </Box>
70
+ // </Button>
71
+ );
72
+ }
73
+
74
+ export default Checkbox;
@@ -0,0 +1,32 @@
1
+ import React, {
2
+ forwardRef
3
+ } from 'react';
4
+ import styled from '@emotion/styled'
5
+ import { css } from '@emotion/react'
6
+ import {
7
+ buildCSS,
8
+ filterHTMLProps
9
+ } from '../core'
10
+
11
+ // const CoreBlock = styled.section`display: block;`
12
+ // const buildComponent = (props: any) => Block.withComponent(props.for || `div`)`${buildCSS(props)}`
13
+
14
+ const Component = forwardRef((props: any, ref: any) => {
15
+
16
+ const Tag = props.for;
17
+ const Block = (
18
+ typeof props.for == 'string' ?
19
+ styled[props.for || `div`] : Tag
20
+ )`${buildCSS(props)}`;
21
+ // const Block = styled.`${buildCSS(props)}`;
22
+ // const Block = CoreBlock.withComponent(props.for)`background: red`
23
+ // console.log(props)
24
+ // console.log(Styles)
25
+
26
+
27
+ // return <button>{props.children}</button>
28
+ return <Block className={props.as || ``} {...filterHTMLProps(props)} />
29
+
30
+ })
31
+
32
+ export default Component;
@@ -0,0 +1,43 @@
1
+ import {
2
+ FC,
3
+ LegacyRef,
4
+ forwardRef,
5
+ useRef,
6
+ SyntheticEvent,
7
+ } from 'react';
8
+ import Box from './box'
9
+ import Button from './button'
10
+
11
+ const ContextMenu = forwardRef((props : { [ key: string ] : any }, ref : LegacyRef<HTMLHeadingElement>) => {
12
+
13
+ const {
14
+ as,
15
+ size,
16
+ color,
17
+ hover,
18
+ pos,
19
+ items
20
+ } = props;
21
+
22
+ return (
23
+ <Box
24
+ hover={hover || {}}
25
+ flex
26
+ fixed
27
+ top={pos?.y || 0}
28
+ left={pos?.x || 0}
29
+ bref={ref}
30
+ as={`contextmenu-${as}`}
31
+ ai={`c`}
32
+ jc={`c`}
33
+ size={size || 24}
34
+ color={color || `#111111`}
35
+ >
36
+ {items && items.map((m, i) => <Button
37
+ key={`cm-${i}-${m.id}`}
38
+ onClick={m.on ? m.on : () => {}}>{m.label}</Button>)}
39
+ </Box>
40
+ )
41
+ })
42
+
43
+ export default ContextMenu;
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import Box from './box'
3
+ import Spinner from './spinner'
4
+ import Heading from './heading'
5
+ import PropTypes from 'prop-types'
6
+
7
+ const Cover = (props) => {
8
+
9
+ return (
10
+ <Box key={`cover-cloud`} abs fill
11
+ bgFilter={props.backdrop ? `saturate(${props.backdrop.saturate}%) blur(${props.backdrop.blur}px)` : undefined}
12
+ zIndex={`2`}
13
+ bg={props.bg}>
14
+ <Box key={`cover-shadow`} abs abc aic jcc flex dir={`cols`} gap={20}>
15
+ <Spinner key={`cover-spinner`} />
16
+ {props.label && <Heading key={`cover-label`} size={16} as={`f`} opacity={0.7}>{props.label}</Heading>}
17
+ </Box>
18
+ </Box>
19
+ );
20
+ }
21
+
22
+ Cover.defaultProps = {
23
+ bg: `rgba(0,0,0,0.5)`,
24
+ backdrop: { saturate: 80, blur: 10 },
25
+ label: null
26
+ }
27
+
28
+ Cover.propTypes = {
29
+ bg: PropTypes.string,
30
+ backdrop: PropTypes.object,
31
+ label: PropTypes.string,
32
+ }
33
+
34
+ export default Cover;