@zuzjs/ui 0.2.0 → 0.2.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.
Files changed (3) hide show
  1. package/dist/index.js +516 -413
  2. package/dist/styles.css +252 -0
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createContext, useEffect, useMemo, useReducer, useCallback, cloneElement, useContext, useRef, useState, useLayoutEffect, useDebugValue, forwardRef, useImperativeHandle, createElement } from 'react';
2
- import { jsx, jsxs } from 'react/jsx-runtime';
1
+ import { createContext, useEffect, useMemo, useReducer, useCallback, useContext, forwardRef, useRef, useState, useLayoutEffect, useDebugValue, cloneElement, useImperativeHandle, createElement } from 'react';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import PropTypes from 'prop-types';
4
4
  import Children from 'react-children-utilities';
5
5
  import Cookies from 'js-cookie';
@@ -448,7 +448,9 @@ const cssPropsVals = {
448
448
  "c": "center",
449
449
  //Flex Directions
450
450
  "cols": "column",
451
+ "colsr": "column-reverse",
451
452
  "rows": "row",
453
+ "rowsr": "row-reverse",
452
454
  //Positions
453
455
  "rel": "relative",
454
456
  "abs": "absolute",
@@ -459,6 +461,7 @@ const cssPropsDirect = {
459
461
  'abs': 'position: absolute;',
460
462
  'sticky': 'position: sticky;',
461
463
  'flex': 'display: flex;',
464
+ 'fwrap': 'flex-wrap: wrap;',
462
465
  'aic': 'align-items: center;',
463
466
  'ass': 'align-self: flex-start;',
464
467
  'asc': 'align-self: center;',
@@ -492,176 +495,105 @@ if (cssColors.length == 0) {
492
495
  });
493
496
  }
494
497
 
495
- const makeCSSValue = (k, v, o) => {
496
- let ignore = cssPropsIgnore.indexOf(o) == -1;
497
- if (k in cssPropsDirect && ignore == true) {
498
- // return cssPropsDirect[k];
499
- return cssPropsDirect[k].indexOf(`__VALUE__`) > -1 ?
500
- cssPropsDirect[k].replaceAll(`__VALUE__`, `${v}${"number" == typeof v ? `px` : ``}`)
501
- : cssPropsDirect[k];
502
- }
503
- let unit = "number" == typeof v && ignore ? `px` : ``;
504
- if (cssColors.indexOf(v) > -1) {
505
- v = `var(--colors-${v.replaceAll(`.`, `-`)})`;
506
- unit = ``;
507
- }
508
- else if (v in cssPropsVals) {
509
- v = cssPropsVals[v];
498
+ const useDispatch = (key) => {
499
+ const state = useContext(AppContext);
500
+ const dispatch = state['dispatch'];
501
+ const prepareState = (prevState, nextState) => {
502
+ const nextKeys = Object.keys(nextState);
503
+ nextKeys.map(k => {
504
+ if (prevState[k] !== nextState[k]) {
505
+ prevState[k] = nextState[k];
506
+ }
507
+ });
508
+ return Object.assign(Object.assign({}, prevState), nextState);
509
+ };
510
+ if (key) {
511
+ return (payload = {}) => {
512
+ dispatch({
513
+ action: key,
514
+ payload: {
515
+ [key]: prepareState(state[key], payload)
516
+ }
517
+ });
518
+ };
510
519
  }
511
- return `${k}:${v}${unit};`;
512
- };
513
- const buildCSS = (props) => {
514
- let css = ``;
515
- Object.keys(props).map(k => {
516
- css += k in cssProps ? makeCSSValue(cssProps[k], props[k], k) : '';
517
- });
518
- return css;
519
- };
520
- const setCSSVar = (key, val) => {
521
- document.documentElement.style.setProperty(`--${key}`, val);
520
+ return dispatch;
522
521
  };
523
- const isUrl = (u) => {
524
- let url;
525
- try {
526
- url = new URL(u);
522
+
523
+ const useStore = (callback, withFilter = true) => {
524
+ // if(withInititalState){
525
+ // return useContext(AppContext)
526
+ // }
527
+ let _state = useContext(AppContext);
528
+ let state = withFilter ? {} : _state;
529
+ if (withFilter) {
530
+ const filters = ['defaultState', 'theme', 'dispatch', `${STORE_KEY}base`, `${STORE_KEY}forms`];
531
+ Object.keys(_state).map(k => {
532
+ if (filters.indexOf(k) == -1) {
533
+ state[k] = _state[k];
534
+ }
535
+ });
527
536
  }
528
- catch (_) {
529
- return false;
537
+ if ("function" == typeof callback) {
538
+ return callback(state);
530
539
  }
531
- return url.protocol === 'http:' || url.protocol === 'https:';
532
- };
533
- const isEmail = (e) => {
534
- let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
535
- return reg.test(e);
536
- };
537
- const isIPv4 = (ipaddress) => {
538
- 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);
540
+ return state;
539
541
  };
540
- const randstr = function (len) {
541
- var text = "";
542
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
543
- len = len || 10;
544
- for (var i = 0; i < len; i++) {
545
- text += possible.charAt(Math.floor(Math.random() * possible.length));
542
+
543
+ const ADD_FORM = (name, fields, forms) => ({
544
+ forms: Object.assign(Object.assign({}, forms), { [name]: Object.assign({ touched: false, loading: false }, fields) })
545
+ });
546
+ const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
547
+ if (forms[formName]) {
548
+ let _forms = Object.assign({}, forms);
549
+ _forms[formName][field] = value;
550
+ return {
551
+ forms: _forms
552
+ };
546
553
  }
547
- return text;
548
- };
549
- const setCookie = (key, value, expiry) => Cookies.set(key, value, { expires: expiry || 7 });
550
- const getCookie = (key) => Cookies.get(key) || null;
551
- const removeCookie = (key) => Cookies.remove(key);
552
- const buildFormData = (data) => {
553
- var formData = new FormData();
554
- var _data = Cookies.get();
555
- Object.keys(_data).map(k => formData.append(k, _data[k]));
556
- Object.keys(data).filter(x => x != 'files').map(k => formData.append(k, data[k]));
557
- if ('files' in data)
558
- [data['files']].map((f) => formData.append('files[]', f));
559
- return formData;
554
+ return {};
560
555
  };
561
- const grab = async (uri, data, timeout = 60, fd = null, progress, bearer = `__ha`) => {
562
- var Bearer = getCookie(bearer) || `${randstr(8)}^${randstr(8)}`;
563
- window['__grabToken'] = axios.CancelToken.source();
564
- if (fd) {
565
- return new Promise((resolve, reject) => {
566
- axios({
567
- method: "post",
568
- url: uri,
569
- data: buildFormData(data),
570
- timeout: 1000 * timeout,
571
- cancelToken: window['__grabToken'].token,
572
- headers: {
573
- 'Content-Type': 'multipart/form-data',
574
- 'Authorization': `Bearer ${Bearer}`
575
- },
576
- onUploadProgress: ev => {
577
- //TODO: Add progress
578
- // if(progress) progress(ev.)
579
- }
580
- })
581
- .then(resp => {
582
- if (resp.data && "kind" in resp.data) {
583
- resolve(resp.data);
584
- }
585
- else {
586
- reject(resp.data);
556
+
557
+ const Input = forwardRef((props, ref) => {
558
+ const { as, accept, multiple, onChange, type, tag, placeholder, name, form, touched, onSubmit, defaultValue } = props;
559
+ const dispatch = useDispatch(STORE_FORM_KEY);
560
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false);
561
+ let Tag = tag || 'input';
562
+ const El = Tag;
563
+ const _ref = useRef();
564
+ 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
+ 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
+ let k = e['keyCode'] || ['which'];
567
+ if (El != 'textarea' && k == 13 && form && onSubmit) {
568
+ onSubmit(forms[form]);
587
569
  }
588
- })
589
- .catch(err => reject(err));
590
- });
591
- }
592
- return new Promise((resolve, reject) => {
593
- axios.post(uri, Object.assign(Object.assign(Object.assign({}, Cookies.get()), data), { __ustmp: new Date().getTime() / 1000 }), {
594
- timeout: 1000 * timeout,
595
- headers: {
596
- 'Content-Type': 'application/json',
597
- 'Authorization': `Bearer ${Bearer}`
598
- },
599
- cancelToken: window['__grabToken'].token
600
- })
601
- .then(resp => {
602
- if (resp.data && "kind" in resp.data) {
603
- resolve(resp.data);
604
- }
605
- else {
606
- reject(resp.data);
607
- }
608
- })
609
- .catch(err => reject(err));
610
- });
611
- };
612
- const el = (e) => document.querySelector(e);
613
- const byName = (e) => document.querySelector(`*[name="${e}"]`);
614
- const byId = (e) => document.getElementById(e);
615
- const addProps = (children, prop) => {
616
- let form = {};
617
- let child = Children.deepMap(children, c => {
618
- if (c['props'] && !form[c['props'].name]) {
619
- form[c['props'].name] = c['props'].value || null;
620
- }
621
- return cloneElement(c, prop);
622
- });
623
- return {
624
- children: child,
625
- fields: form
626
- };
627
- };
628
- const ucfirst = (str) => {
629
- return str.charAt(0).toUpperCase() + str.slice(1);
630
- };
631
- const filterStyleProps = (props) => {
632
- const pks = Object.keys(props);
633
- const css = Object.keys(cssProps);
634
- let filter = {};
635
- css.filter(x => pks.includes(x));
636
- // .map(k => filter[k] = props[k].toString());
637
- return filter;
638
- // const allowed = Object.keys(props);
639
- // let allowed = Object.keys(cssProps);
640
- // return Object.keys(props)
641
- // .filter( k => allowed.includes(k))
642
- // .reduce( (o, k) => {
643
- // // console.log(o)
644
- // console.log(k, props[k])
645
- // // o[k] = props[k].toString();
646
- // // return o;
647
- // })
648
- // return [props].filter( row => (
649
- // Object.keys(row)
650
- // .map(key => css.includes(key))
651
- // ));
652
- };
653
- const filterHTMLProps = (props) => {
654
- const pks = Object.keys(props);
655
- const css = Object.keys(cssProps);
656
- let filter = {};
657
- pks.filter(x => {
658
- if (x != `for` && !css.includes(x)) {
659
- filter[x] = props[x];
660
- }
661
- });
662
- return filter;
663
- };
664
- const uuid = () => nanoid();
570
+ }, onChange: e => {
571
+ let val = type == 'file' ?
572
+ e.currentTarget.files
573
+ : e.currentTarget.value;
574
+ dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val == "" ? null : val, forms)));
575
+ onChange && onChange(e.target.value == "" ? null : e.target.value);
576
+ }, onBlur: e => {
577
+ }, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)) }) }));
578
+ });
579
+
580
+ const Select = forwardRef((props, ref) => {
581
+ const { as, onChange, name, form, touched, options, defaultValue } = props;
582
+ const _ref = useRef();
583
+ const dispatch = useDispatch(STORE_FORM_KEY);
584
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false);
585
+ 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);`;
586
+ useEffect(() => {
587
+ var _a;
588
+ 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)));
589
+ }, []);
590
+ return (jsx(ClassNames, { children: ({ css, cx }) => jsx("select", Object.assign({ onChange: e => {
591
+ let val = e.currentTarget.value;
592
+ dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val, forms)));
593
+ onChange && onChange(val);
594
+ }, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)), onBlur: e => {
595
+ }, 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", Object.assign({ value: o.value }, { children: o.label }), `select-${name}-option-${o.value}`)) })) }));
596
+ });
665
597
 
666
598
  const useTheme = (mod = 'auto') => {
667
599
  const state = useContext(AppContext);
@@ -689,69 +621,24 @@ const useImage = (url, crossOrigin, referrerpolicy) => {
689
621
  function onload() {
690
622
  statusRef.current = 'loaded';
691
623
  imageRef.current = img;
692
- setStateToken(Math.random());
693
- }
694
- function onerror() {
695
- statusRef.current = 'failed';
696
- imageRef.current = undefined;
697
- setStateToken(Math.random());
698
- }
699
- img.addEventListener('load', onload);
700
- img.addEventListener('error', onerror);
701
- crossOrigin && (img.crossOrigin = crossOrigin);
702
- referrerpolicy && (img.referrerPolicy = referrerpolicy);
703
- img.src = url;
704
- return function cleanup() {
705
- img.removeEventListener('load', onload);
706
- img.removeEventListener('error', onerror);
707
- };
708
- }, [url, crossOrigin, referrerpolicy]);
709
- return [imageRef.current, statusRef.current];
710
- };
711
-
712
- const useStore = (callback, withFilter = true) => {
713
- // if(withInititalState){
714
- // return useContext(AppContext)
715
- // }
716
- let _state = useContext(AppContext);
717
- let state = withFilter ? {} : _state;
718
- if (withFilter) {
719
- const filters = ['defaultState', 'theme', 'dispatch', `${STORE_KEY}base`, `${STORE_KEY}forms`];
720
- Object.keys(_state).map(k => {
721
- if (filters.indexOf(k) == -1) {
722
- state[k] = _state[k];
723
- }
724
- });
725
- }
726
- if ("function" == typeof callback) {
727
- return callback(state);
728
- }
729
- return state;
730
- };
731
-
732
- const useDispatch = (key) => {
733
- const state = useContext(AppContext);
734
- const dispatch = state['dispatch'];
735
- const prepareState = (prevState, nextState) => {
736
- const nextKeys = Object.keys(nextState);
737
- nextKeys.map(k => {
738
- if (prevState[k] !== nextState[k]) {
739
- prevState[k] = nextState[k];
740
- }
741
- });
742
- return Object.assign(Object.assign({}, prevState), nextState);
743
- };
744
- if (key) {
745
- return (payload = {}) => {
746
- dispatch({
747
- action: key,
748
- payload: {
749
- [key]: prepareState(state[key], payload)
750
- }
751
- });
624
+ setStateToken(Math.random());
625
+ }
626
+ function onerror() {
627
+ statusRef.current = 'failed';
628
+ imageRef.current = undefined;
629
+ setStateToken(Math.random());
630
+ }
631
+ img.addEventListener('load', onload);
632
+ img.addEventListener('error', onerror);
633
+ crossOrigin && (img.crossOrigin = crossOrigin);
634
+ referrerpolicy && (img.referrerPolicy = referrerpolicy);
635
+ img.src = url;
636
+ return function cleanup() {
637
+ img.removeEventListener('load', onload);
638
+ img.removeEventListener('error', onerror);
752
639
  };
753
- }
754
- return dispatch;
640
+ }, [url, crossOrigin, referrerpolicy]);
641
+ return [imageRef.current, statusRef.current];
755
642
  };
756
643
 
757
644
  /** External Dependencies */
@@ -889,119 +776,346 @@ const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
889
776
  list.addEventListener('change', handleChange);
890
777
  }
891
778
  else {
892
- list.addListener(handleChange);
779
+ list.addListener(handleChange);
780
+ }
781
+ /** Map the unsubscribers array to a list of unsubscriber methods */
782
+ return () => {
783
+ if (supportsNewEventListeners) {
784
+ list.removeEventListener('change', handleChange);
785
+ }
786
+ else {
787
+ list.removeListener(handleChange);
788
+ }
789
+ };
790
+ });
791
+ /** Return a function that when called, will call all unsubscribers */
792
+ return () => unsubscribers.forEach((unsubscriber) => unsubscriber());
793
+ }, [mediaQueries, updateBreakpoint]);
794
+ /** Print a nice debug value for React Devtools */
795
+ useDebugValue(currentBreakpoint, (c) => typeof c.breakpoint === 'string'
796
+ ? `${c.breakpoint} (${c.minWidth} ≤ x${c.maxWidth ? ` < ${c.maxWidth + 1}` : ''})`
797
+ : '');
798
+ return currentBreakpoint;
799
+ };
800
+
801
+ var _Toaster_container, _Toaster_startTop, _Toaster_tout, _Toaster_defaultTimeLeft;
802
+ class Toaster {
803
+ constructor(config) {
804
+ _Toaster_container.set(this, void 0);
805
+ _Toaster_startTop.set(this, void 0);
806
+ _Toaster_tout.set(this, void 0);
807
+ _Toaster_defaultTimeLeft.set(this, void 0);
808
+ this.show = (message, duration) => {
809
+ let self = this;
810
+ self.toast({
811
+ message: message,
812
+ duration: duration
813
+ });
814
+ };
815
+ __classPrivateFieldSet(this, _Toaster_startTop, 20, "f");
816
+ __classPrivateFieldSet(this, _Toaster_defaultTimeLeft, 4, "f");
817
+ const rootID = (config === null || config === void 0 ? void 0 : config.root) || `toast-container`;
818
+ if (document.querySelector(`#${rootID}`))
819
+ return;
820
+ var root = document.createElement('div');
821
+ root.id = rootID;
822
+ document.body.appendChild(root);
823
+ __classPrivateFieldSet(this, _Toaster_container, document.querySelector(`#${rootID}`), "f");
824
+ }
825
+ dismiss(ID) {
826
+ let self = this;
827
+ __classPrivateFieldGet(self, _Toaster_tout, "f") && clearTimeout(__classPrivateFieldGet(self, _Toaster_tout, "f"));
828
+ setTimeout(() => {
829
+ let tost = document.querySelector(`#${ID}`);
830
+ tost && tost.classList.remove("visible");
831
+ // tost && tost.classList.add("hidden");
832
+ setTimeout(() => {
833
+ try {
834
+ document.getElementById(ID).parentNode.removeChild(document.getElementById(ID));
835
+ }
836
+ catch (e) { }
837
+ self.arrangeToasts();
838
+ }, 200);
839
+ }, 200);
840
+ }
841
+ toast(config) {
842
+ var self = this;
843
+ var ID = 'toast-' + nanoid(), toast = document.createElement('div'); document.createElement('div');
844
+ toast.id = ID;
845
+ toast.style.backgroundColor = `#111`;
846
+ toast.style.color = `#fff`;
847
+ toast.style.transform = `translate(-50%, -300px) scale(0.5)`;
848
+ toast.style.position = `fixed`;
849
+ toast.style.padding = `6px 12px`;
850
+ toast.style.fontSize = `14px`;
851
+ toast.style.left = `50%`;
852
+ toast.style.maxWidth = `95%`;
853
+ toast.style.zIndex = `2147483647`;
854
+ toast.classList.add('zuz-toast');
855
+ toast.classList.add('fixed');
856
+ toast.classList.add('f');
857
+ toast.innerHTML = config.message || `You haven't passed "message" in this toast`;
858
+ __classPrivateFieldGet(self, _Toaster_container, "f").appendChild(toast);
859
+ self.arrangeToasts()
860
+ .then(() => {
861
+ setTimeout(() => {
862
+ let tost = document.querySelector("#" + ID);
863
+ tost.classList.add("showing");
864
+ setTimeout(() => self.dismiss(ID), ((config === null || config === void 0 ? void 0 : config.duration) == undefined ? __classPrivateFieldGet(self, _Toaster_defaultTimeLeft, "f") : (config === null || config === void 0 ? void 0 : config.duration) == -1 ? 86400 : config === null || config === void 0 ? void 0 : config.duration) * 1000);
865
+ setTimeout(() => {
866
+ let tost = document.querySelector("#" + ID);
867
+ tost.classList.remove("showing");
868
+ tost.classList.add("visible");
869
+ }, 200);
870
+ }, 10);
871
+ });
872
+ }
873
+ arrangeToasts() {
874
+ var self = this, top = __classPrivateFieldGet(self, _Toaster_startTop, "f");
875
+ return new Promise((resolve, reject) => {
876
+ var toasts = document.querySelectorAll(".zuz-toast"), i = toasts.length;
877
+ while (i--) {
878
+ toasts[i]['style'].top = `${top}px`;
879
+ top += parseInt(getComputedStyle(toasts[i]).height.replace('px', '')) + 6;
880
+ }
881
+ resolve(null);
882
+ });
883
+ }
884
+ }
885
+ _Toaster_container = new WeakMap(), _Toaster_startTop = new WeakMap(), _Toaster_tout = new WeakMap(), _Toaster_defaultTimeLeft = new WeakMap();
886
+
887
+ const useToast = () => {
888
+ const toaster = useMemo(() => new Toaster(), []);
889
+ return toaster;
890
+ };
891
+
892
+ const Button = forwardRef((props, ref) => {
893
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false);
894
+ if (props.html) {
895
+ ({ __html: props.html });
896
+ }
897
+ return (jsx(ClassNames, { children: ({ css, cx }) => {
898
+ return (jsx("button", Object.assign({ title: "title" in props ? props.title : undefined, type: props.type, className: `button${props.as ? ` ${props.as}` : ``} ${cx(css `
899
+ padding: 5px 10px;
900
+ border-radius: 2px;
901
+ ${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: ref, onClick: e => {
902
+ if (props.form && props.type && props.type == 'submit') {
903
+ props.onSubmit(forms[props.form]);
904
+ }
905
+ else {
906
+ props.onClick ? props.onClick(e) : () => console.warn('onClick Missing');
907
+ }
908
+ }, disabled: props.disabled || false }, { children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : props.children })));
909
+ } }));
910
+ });
911
+
912
+ const makeCSSValue = (k, v, o) => {
913
+ let ignore = cssPropsIgnore.indexOf(o) == -1;
914
+ if (k in cssPropsDirect && ignore == true) {
915
+ // return cssPropsDirect[k];
916
+ return cssPropsDirect[k].indexOf(`__VALUE__`) > -1 ?
917
+ cssPropsDirect[k].replaceAll(`__VALUE__`, `${v}${"number" == typeof v ? `px` : ``}`)
918
+ : cssPropsDirect[k];
919
+ }
920
+ let unit = "number" == typeof v && ignore ? `px` : ``;
921
+ if (cssColors.indexOf(v) > -1) {
922
+ v = `var(--colors-${v.replaceAll(`.`, `-`)})`;
923
+ unit = ``;
924
+ }
925
+ else if (v in cssPropsVals) {
926
+ v = cssPropsVals[v];
927
+ }
928
+ return `${k}:${v}${unit};`;
929
+ };
930
+ const buildCSS = (props) => {
931
+ let css = ``;
932
+ Object.keys(props).map(k => {
933
+ css += k in cssProps ? makeCSSValue(cssProps[k], props[k], k) : '';
934
+ });
935
+ return css;
936
+ };
937
+ const setCSSVar = (key, val) => {
938
+ document.documentElement.style.setProperty(`--${key}`, val);
939
+ };
940
+ const isUrl = (u) => {
941
+ let url;
942
+ try {
943
+ url = new URL(u);
944
+ }
945
+ catch (_) {
946
+ return false;
947
+ }
948
+ return url.protocol === 'http:' || url.protocol === 'https:';
949
+ };
950
+ const isEmail = (e) => {
951
+ let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
952
+ return reg.test(e);
953
+ };
954
+ const isIPv4 = (ipaddress) => {
955
+ 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);
956
+ };
957
+ const randstr = function (len) {
958
+ var text = "";
959
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
960
+ len = len || 10;
961
+ for (var i = 0; i < len; i++) {
962
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
963
+ }
964
+ return text;
965
+ };
966
+ const setCookie = (key, value, expiry) => Cookies.set(key, value, { expires: expiry || 7 });
967
+ const getCookie = (key) => Cookies.get(key) || null;
968
+ const removeCookie = (key) => Cookies.remove(key);
969
+ const buildFormData = (data) => {
970
+ var formData = new FormData();
971
+ var _data = Cookies.get();
972
+ Object.keys(_data).map(k => formData.append(k, _data[k]));
973
+ Object.keys(data).filter(x => x != 'files').map(k => formData.append(k, data[k]));
974
+ if ('files' in data)
975
+ [data['files']].map((f) => formData.append('files[]', f));
976
+ return formData;
977
+ };
978
+ const grab = async (uri, data, timeout = 60, fd = null, progress, bearer = `__ha`) => {
979
+ var Bearer = getCookie(bearer) || `${randstr(8)}^${randstr(8)}`;
980
+ window['__grabToken'] = axios.CancelToken.source();
981
+ if (fd) {
982
+ return new Promise((resolve, reject) => {
983
+ axios({
984
+ method: "post",
985
+ url: uri,
986
+ data: buildFormData(data),
987
+ timeout: 1000 * timeout,
988
+ cancelToken: window['__grabToken'].token,
989
+ headers: {
990
+ 'Content-Type': 'multipart/form-data',
991
+ 'Authorization': `Bearer ${Bearer}`
992
+ },
993
+ onUploadProgress: ev => {
994
+ //TODO: Add progress
995
+ // if(progress) progress(ev.)
996
+ }
997
+ })
998
+ .then(resp => {
999
+ if (resp.data && "kind" in resp.data) {
1000
+ resolve(resp.data);
1001
+ }
1002
+ else {
1003
+ reject(resp.data);
1004
+ }
1005
+ })
1006
+ .catch(err => reject(err));
1007
+ });
1008
+ }
1009
+ return new Promise((resolve, reject) => {
1010
+ axios.post(uri, Object.assign(Object.assign(Object.assign({}, Cookies.get()), data), { __ustmp: new Date().getTime() / 1000 }), {
1011
+ timeout: 1000 * timeout,
1012
+ headers: {
1013
+ 'Content-Type': 'application/json',
1014
+ 'Authorization': `Bearer ${Bearer}`
1015
+ },
1016
+ cancelToken: window['__grabToken'].token
1017
+ })
1018
+ .then(resp => {
1019
+ if (resp.data && "kind" in resp.data) {
1020
+ resolve(resp.data);
1021
+ }
1022
+ else {
1023
+ reject(resp.data);
893
1024
  }
894
- /** Map the unsubscribers array to a list of unsubscriber methods */
895
- return () => {
896
- if (supportsNewEventListeners) {
897
- list.removeEventListener('change', handleChange);
898
- }
899
- else {
900
- list.removeListener(handleChange);
901
- }
902
- };
903
- });
904
- /** Return a function that when called, will call all unsubscribers */
905
- return () => unsubscribers.forEach((unsubscriber) => unsubscriber());
906
- }, [mediaQueries, updateBreakpoint]);
907
- /** Print a nice debug value for React Devtools */
908
- useDebugValue(currentBreakpoint, (c) => typeof c.breakpoint === 'string'
909
- ? `${c.breakpoint} (${c.minWidth} ≤ x${c.maxWidth ? ` < ${c.maxWidth + 1}` : ''})`
910
- : '');
911
- return currentBreakpoint;
1025
+ })
1026
+ .catch(err => reject(err));
1027
+ });
912
1028
  };
913
-
914
- var _Toaster_container, _Toaster_startTop, _Toaster_tout, _Toaster_defaultTimeLeft;
915
- class Toaster {
916
- // #toast: Function;
917
- // show : Function;
918
- constructor(config) {
919
- _Toaster_container.set(this, void 0);
920
- _Toaster_startTop.set(this, void 0);
921
- _Toaster_tout.set(this, void 0);
922
- _Toaster_defaultTimeLeft.set(this, void 0);
923
- this.show = (message, duration) => {
924
- let self = this;
925
- self.toast({
926
- message: message,
927
- duration: duration
928
- });
929
- };
930
- __classPrivateFieldSet(this, _Toaster_startTop, 20, "f");
931
- __classPrivateFieldSet(this, _Toaster_defaultTimeLeft, 4, "f");
932
- const rootID = (config === null || config === void 0 ? void 0 : config.root) || `toast-container`;
933
- if (document.querySelector(`#${rootID}`))
934
- return;
935
- var root = document.createElement('div');
936
- root.id = rootID;
937
- document.body.appendChild(root);
938
- __classPrivateFieldSet(this, _Toaster_container, document.querySelector(`#${rootID}`), "f");
939
- }
940
- dismiss(ID) {
941
- let self = this;
942
- __classPrivateFieldGet(self, _Toaster_tout, "f") && clearTimeout(__classPrivateFieldGet(self, _Toaster_tout, "f"));
943
- setTimeout(() => {
944
- let tost = document.querySelector(`#${ID}`);
945
- tost && tost.classList.remove("visible");
946
- // tost && tost.classList.add("hidden");
947
- setTimeout(() => {
948
- try {
949
- document.getElementById(ID).parentNode.removeChild(document.getElementById(ID));
950
- }
951
- catch (e) { }
952
- self.arrangeToasts();
953
- }, 200);
954
- }, 200);
1029
+ const el = (e) => document.querySelector(e);
1030
+ const byName = (e) => document.querySelector(`*[name="${e}"]`);
1031
+ const byId = (e) => document.getElementById(e);
1032
+ const addProps = (children, prop) => {
1033
+ let form = {};
1034
+ let allowedFields = [Input, Select, Button];
1035
+ let child = Children.deepMap(children, c => {
1036
+ if (allowedFields.indexOf(c['type']) > -1 && c['props'] && !form[c['props'].name]) {
1037
+ form[c['props'].name] = c['props'].value || null;
1038
+ }
1039
+ let Clone = cloneElement(c, prop);
1040
+ return Clone;
1041
+ });
1042
+ return {
1043
+ children: child,
1044
+ fields: form
1045
+ };
1046
+ };
1047
+ const ucfirst = (str) => {
1048
+ return str.charAt(0).toUpperCase() + str.slice(1);
1049
+ };
1050
+ const filterStyleProps = (props) => {
1051
+ const pks = Object.keys(props);
1052
+ const css = Object.keys(cssProps);
1053
+ let filter = {};
1054
+ css.filter(x => pks.includes(x));
1055
+ // .map(k => filter[k] = props[k].toString());
1056
+ return filter;
1057
+ // const allowed = Object.keys(props);
1058
+ // let allowed = Object.keys(cssProps);
1059
+ // return Object.keys(props)
1060
+ // .filter( k => allowed.includes(k))
1061
+ // .reduce( (o, k) => {
1062
+ // // console.log(o)
1063
+ // console.log(k, props[k])
1064
+ // // o[k] = props[k].toString();
1065
+ // // return o;
1066
+ // })
1067
+ // return [props].filter( row => (
1068
+ // Object.keys(row)
1069
+ // .map(key => css.includes(key))
1070
+ // ));
1071
+ };
1072
+ const filterHTMLProps = (props) => {
1073
+ const pks = Object.keys(props);
1074
+ const css = Object.keys(cssProps);
1075
+ let filter = {};
1076
+ pks.filter(x => {
1077
+ if (x != `for` && !css.includes(x)) {
1078
+ filter[x] = props[x];
1079
+ }
1080
+ });
1081
+ return filter;
1082
+ };
1083
+ const uuid = () => nanoid();
1084
+ const addScript = (src, callback) => {
1085
+ var s = document.createElement('script');
1086
+ s.setAttribute('src', src);
1087
+ s.addEventListener('load', callback, false);
1088
+ document.body.appendChild(s);
1089
+ };
1090
+ const shuffleArray = array => {
1091
+ for (let i = array.length - 1; i > 0; i--) {
1092
+ const j = Math.floor(Math.random() * (i + 1));
1093
+ [array[i], array[j]] = [array[j], array[i]];
955
1094
  }
956
- toast(config) {
957
- var self = this;
958
- var ID = 'toast-' + nanoid(), toast = document.createElement('div'); document.createElement('div');
959
- toast.id = ID;
960
- toast.style.backgroundColor = `#111`;
961
- toast.style.color = `#fff`;
962
- toast.style.transform = `translate(-50%, -300px) scale(0.5)`;
963
- toast.style.position = `fixed`;
964
- toast.style.padding = `6px 12px`;
965
- toast.style.fontSize = `16px`;
966
- toast.style.left = `50%`;
967
- toast.style.zIndex = `2147483647`;
968
- toast.classList.add('zuz-toast');
969
- toast.classList.add('fixed');
970
- toast.classList.add('f');
971
- toast.innerHTML = config.message || `You haven't passed "message" in this toast`;
972
- __classPrivateFieldGet(self, _Toaster_container, "f").appendChild(toast);
973
- self.arrangeToasts()
974
- .then(() => {
975
- setTimeout(() => {
976
- let tost = document.querySelector("#" + ID);
977
- tost.classList.add("showing");
978
- setTimeout(() => self.dismiss(ID), ((config === null || config === void 0 ? void 0 : config.duration) == undefined ? __classPrivateFieldGet(self, _Toaster_defaultTimeLeft, "f") : (config === null || config === void 0 ? void 0 : config.duration) == -1 ? 86400 : config === null || config === void 0 ? void 0 : config.duration) * 1000);
979
- setTimeout(() => {
980
- let tost = document.querySelector("#" + ID);
981
- tost.classList.remove("showing");
982
- tost.classList.add("visible");
983
- }, 200);
984
- }, 10);
985
- });
1095
+ return array;
1096
+ };
1097
+ const getUriParams = () => {
1098
+ var search = location.search.substring(1);
1099
+ if (search == '')
1100
+ return JSON.parse('{}');
1101
+ var xny = {};
1102
+ if ("URLSearchParams" in window) {
1103
+ var items = new URLSearchParams(search);
1104
+ for (const [k, v] of items) {
1105
+ xny[k] = v || ``;
1106
+ }
986
1107
  }
987
- arrangeToasts() {
988
- var self = this, top = __classPrivateFieldGet(self, _Toaster_startTop, "f");
989
- return new Promise((resolve, reject) => {
990
- var toasts = document.querySelectorAll(".zuz-toast"), i = toasts.length;
991
- while (i--) {
992
- toasts[i]['style'].top = `${top}px`;
993
- top += parseInt(getComputedStyle(toasts[i]).height.replace('px', '')) + 6;
994
- }
995
- resolve(null);
996
- });
1108
+ else {
1109
+ try {
1110
+ xny = JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}');
1111
+ }
1112
+ catch (e) {
1113
+ xny = {};
1114
+ }
997
1115
  }
998
- }
999
- _Toaster_container = new WeakMap(), _Toaster_startTop = new WeakMap(), _Toaster_tout = new WeakMap(), _Toaster_defaultTimeLeft = new WeakMap();
1000
-
1001
- const useToast = () => {
1002
- const toaster = useMemo(() => new Toaster(), []);
1003
- return toaster;
1116
+ return xny;
1004
1117
  };
1118
+ const rgb2hex = rgb => `#${rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(n => parseInt(n, 10).toString(16).padStart(2, '0')).join('')}`;
1005
1119
 
1006
1120
  const AppMain = forwardRef((props, ref) => {
1007
1121
  // const { dispatch } = useStore()
@@ -1019,26 +1133,6 @@ const Box = forwardRef((props, ref) => {
1019
1133
  return (jsx(ClassNames, { children: ({ css, cx }) => jsx("div", Object.assign({ 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 }, { children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : props.children })) }));
1020
1134
  });
1021
1135
 
1022
- const Button = forwardRef((props, ref) => {
1023
- const { forms } = useStore(state => state[STORE_FORM_KEY], false);
1024
- if (props.html) {
1025
- ({ __html: props.html });
1026
- }
1027
- return (jsx(ClassNames, { children: ({ css, cx }) => {
1028
- return (jsx("button", Object.assign({ title: "title" in props ? props.title : undefined, type: props.type, className: `button${props.as ? ` ${props.as}` : ``} ${cx(css `
1029
- padding: 5px 10px;
1030
- border-radius: 2px;
1031
- ${buildCSS(props)} &:hover {${buildCSS(props.hover || {})}} &:active {${buildCSS(props.active || {})}}`)}`, ref: ref, onClick: e => {
1032
- if (props.form && props.type && props.type == 'submit') {
1033
- props.onSubmit(forms[props.form]);
1034
- }
1035
- else {
1036
- props.onClick ? props.onClick(e) : () => console.warn('onClick Missing');
1037
- }
1038
- }, disabled: props.disabled || false }, { children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : props.children })));
1039
- } }));
1040
- });
1041
-
1042
1136
  // const CoreBlock = styled.section`display: block;`
1043
1137
  // const buildComponent = (props: any) => Block.withComponent(props.for || `div`)`${buildCSS(props)}`
1044
1138
  const Component = forwardRef((props, ref) => {
@@ -1053,6 +1147,37 @@ const Component = forwardRef((props, ref) => {
1053
1147
  return jsx(Block, Object.assign({ className: props.as || `` }, filterHTMLProps(props)));
1054
1148
  });
1055
1149
 
1150
+ function Checkbox(props) {
1151
+ const { checked, as, name, form, touched, onChange } = props;
1152
+ const [_checked, setChecked] = useState(checked || false);
1153
+ const theme = useTheme();
1154
+ const dispatch = useDispatch(STORE_FORM_KEY);
1155
+ const { forms } = useStore(state => state[STORE_FORM_KEY], false);
1156
+ const switchCheck = useCallback(() => {
1157
+ let nextVal = !_checked;
1158
+ onChange && onChange(nextVal);
1159
+ setChecked(nextVal);
1160
+ dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, nextVal, forms)));
1161
+ }, [_checked]);
1162
+ const defaultCSS = `cursor: pointer;&:before {
1163
+ background: ${!_checked ? `transparent` : theme.color} !important;
1164
+ }`;
1165
+ const _name = useMemo(() => name || nanoid(), [name]);
1166
+ return (jsx(ClassNames, { children: ({ css, cx }) => jsxs(Fragment, { children: [jsx("input", { onChange: switchCheck, id: `zuz${_name}`,
1167
+ // className={`${_checked ? 'y' : 'n'} ${as ? ` ${as} ` : ``}f ${cx(css`opacity: 0;position: absolute;&:checked {${defaultCSSChecked}}`)}`}
1168
+ className: `zuz-checkbox`, name: _name, type: `checkbox`, value: `checked` }), jsx("label", { className: `${as ? `${as} ` : ``}f ${cx(css `${defaultCSS}`)}`, htmlFor: `zuz${_name}` })] }) })
1169
+ // <Button
1170
+ // overflow={`hidden`}
1171
+ // name={name || nanoid()}
1172
+ // onClick={switchCheck}
1173
+ // w={38} h={22} r={20} bg={`#ddd`} rel>
1174
+ // <Box w={38} h={22} anim={`0.2`} abs top={0} r={20} left={0} transform={`translateX(${_checked ? 0 : -16}px)`} bg={theme.color}>
1175
+ // <Box w={18} h={18} abs right={2} top={2} bg={`#fff`} r={20} boxShadow={`0px 0px 0px 5px ${_checked ? theme.color : `#ddd`}`} />
1176
+ // </Box>
1177
+ // </Button>
1178
+ );
1179
+ }
1180
+
1056
1181
  const Spinner = (props) => {
1057
1182
  return (jsxs(Box, Object.assign({ 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 })] })));
1058
1183
  };
@@ -1079,7 +1204,7 @@ const Heading = forwardRef((props, ref) => {
1079
1204
  });
1080
1205
 
1081
1206
  const Cover = (props) => {
1082
- return (jsx(Box, Object.assign({ 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, Object.assign({ abs: true, abc: true, aic: true, jcc: true, flex: true, dir: `cols`, gap: 20 }, { children: [jsx(Spinner, {}), props.label && jsx(Heading, Object.assign({ size: 16, as: `f`, opacity: 0.7 }, { children: props.label }))] })) })));
1207
+ return (jsx(Box, Object.assign({ 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, Object.assign({ abs: true, abc: true, aic: true, jcc: true, flex: true, dir: `cols`, gap: 20 }, { children: [jsx(Spinner, {}, `cover-spinner`), props.label && jsx(Heading, Object.assign({ size: 16, as: `f`, opacity: 0.7 }, { children: props.label }), `cover-label`)] }), `cover-shadow`) }), `cover-cloud`));
1083
1208
  };
1084
1209
  Cover.defaultProps = {
1085
1210
  bg: `rgba(0,0,0,0.5)`,
@@ -1092,21 +1217,8 @@ Cover.propTypes = {
1092
1217
  label: PropTypes.string,
1093
1218
  };
1094
1219
 
1095
- const ADD_FORM = (name, fields, forms) => ({
1096
- forms: Object.assign(Object.assign({}, forms), { [name]: Object.assign({ touched: false, loading: false }, fields) })
1097
- });
1098
- const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
1099
- if (forms[formName]) {
1100
- let _forms = Object.assign({}, forms);
1101
- _forms[formName][field] = value;
1102
- return {
1103
- forms: _forms
1104
- };
1105
- }
1106
- return {};
1107
- };
1108
-
1109
1220
  const Form = forwardRef((props, ref) => {
1221
+ var _a;
1110
1222
  const { name, children, onSubmit, cover, debug } = props;
1111
1223
  const [_html, setHTML] = useState(null);
1112
1224
  const [_loading, setLoading] = useState((debug === null || debug === void 0 ? void 0 : debug.loading) || false);
@@ -1131,9 +1243,9 @@ const Form = forwardRef((props, ref) => {
1131
1243
  setHTML(f.children);
1132
1244
  dispatch(ADD_FORM(name, f.fields, forms));
1133
1245
  }
1134
- }, [children]);
1246
+ }, [children, (_a = forms[name]) === null || _a === void 0 ? void 0 : _a.loading]);
1135
1247
  return createElement(Box, Object.assign(Object.assign({ rel: true }, props), { as: name }), [
1136
- _loading ? jsx(Cover, { backdrop: (cover === null || cover === void 0 ? void 0 : cover.filter) || { saturate: 80, blur: 10 }, bg: (cover === null || cover === void 0 ? void 0 : cover.bg) || `rgba(0,0,0,0.5)` }) : null,
1248
+ _loading ? jsx(Cover, { backdrop: (cover === null || cover === void 0 ? void 0 : cover.filter) || { saturate: 80, blur: 10 }, bg: (cover === null || cover === void 0 ? void 0 : cover.bg) || `rgba(0,0,0,0.5)` }, `form-${name}-cover`) : null,
1137
1249
  _html
1138
1250
  ]);
1139
1251
  });
@@ -1152,36 +1264,13 @@ const Icon = forwardRef((props, ref) => {
1152
1264
  return (jsx(Box, Object.assign({ 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}`)) })));
1153
1265
  });
1154
1266
 
1155
- const Input = forwardRef((props, ref) => {
1156
- const { as, accept, multiple, onChange, type, tag, placeholder, name, form, touched, onSubmit, defaultValue } = props;
1157
- const dispatch = useDispatch(STORE_FORM_KEY);
1158
- const { forms } = useStore(state => state[STORE_FORM_KEY], false);
1159
- let Tag = tag || 'input';
1160
- const El = Tag;
1161
- const _ref = useRef();
1162
- 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);`;
1163
- 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) => {
1164
- let k = e['keyCode'] || ['which'];
1165
- if (k == 13 && form && onSubmit) {
1166
- onSubmit();
1167
- }
1168
- }, onChange: e => {
1169
- let val = type == 'file' ?
1170
- e.currentTarget.files
1171
- : e.currentTarget.value;
1172
- dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val == "" ? null : val, forms)));
1173
- onChange && onChange(e.target.value == "" ? null : e.target.value);
1174
- }, onBlur: e => {
1175
- }, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)) }) }));
1176
- });
1177
-
1178
1267
  const Image = forwardRef((props, ref) => {
1179
1268
  const [photo, status] = useImage(props.src, 'anonymous', 'origin');
1180
1269
  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 })] })) }));
1181
1270
  });
1182
1271
 
1183
1272
  const calcPlaceholderStyle = (width, height, duration = 1600) => ({
1184
- backgroundSize: `${width * 10}px ${height}px`,
1273
+ backgroundSize: `${parseInt(width.toString()) * 10}px ${height}px`,
1185
1274
  animationDuration: `${(duration / 1000).toFixed(1)}s`,
1186
1275
  });
1187
1276
  const Placeholder = forwardRef(({ width, height, duration, bg, bgFrom, bgTo }, ref) => {
@@ -1197,24 +1286,6 @@ Placeholder.propTypes = {
1197
1286
  bgTo: PropTypes.string
1198
1287
  };
1199
1288
 
1200
- const Select = forwardRef((props, ref) => {
1201
- const { as, onChange, name, form, touched, options, defaultValue } = props;
1202
- const _ref = useRef();
1203
- const dispatch = useDispatch(STORE_FORM_KEY);
1204
- const { forms } = useStore(state => state[STORE_FORM_KEY], false);
1205
- 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);`;
1206
- useEffect(() => {
1207
- var _a;
1208
- 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)));
1209
- }, []);
1210
- return (jsx(ClassNames, { children: ({ css, cx }) => jsx("select", Object.assign({ onChange: e => {
1211
- let val = e.currentTarget.value;
1212
- dispatch(dispatch(UPDATE_FORM_FIELD(form || 'orphan', name, val, forms)));
1213
- onChange && onChange(val);
1214
- }, onFocus: e => touched == false && dispatch(UPDATE_FORM_FIELD(form || 'orphan', `touched`, true, forms)), onBlur: e => {
1215
- }, 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", Object.assign({ value: o.value }, { children: o.label }), `select-${name}-option-${o.value}`)) })) }));
1216
- });
1217
-
1218
1289
  const Spacer = ({ w, h }) => {
1219
1290
  return (jsx(Box, { as: `spacer`, w: w || 0, h: h || 0 }));
1220
1291
  };
@@ -1224,4 +1295,36 @@ const Text = forwardRef((props, ref) => {
1224
1295
  return (jsx(ClassNames, { children: ({ css, cx }) => jsx("p", Object.assign({ className: `${as ? `${as} ` : ``}${cx(css `${buildCSS(props)}`)}`, ref: ref }, { children: props.html ? jsx("span", { dangerouslySetInnerHTML: { __html: props.html } }) : children })) }));
1225
1296
  });
1226
1297
 
1227
- export { App, Component as Block, Box, Button, Cover, Form, Heading, Icon, Image, Input, Placeholder, AppProvider as Provider, Select, Spacer, Spinner, Text, Toaster, addProps, buildCSS, buildFormData, byId, byName, createSlice, el, filterHTMLProps, filterStyleProps, getCookie, grab, isEmail, isIPv4, isUrl, randstr, removeCookie, setCSSVar, setCookie, ucfirst, useDevice, useDispatch, useImage, useResizeObserver, useStore, useTheme, useToast, uuid };
1298
+ const Tweet = (props) => {
1299
+ const [rand, setRand] = useState(Math.random());
1300
+ const _tweet = useRef();
1301
+ const renderTweet = () => {
1302
+ const twttr = window['twttr'];
1303
+ twttr.ready().then(({ widgets }) => {
1304
+ const { options, onTweetLoadSuccess, onTweetLoadError } = props;
1305
+ widgets
1306
+ .createTweetEmbed(props.id, _tweet.current, options || {})
1307
+ .then((twitterWidgetElement) => {
1308
+ // this.setState({
1309
+ // isLoading: false
1310
+ // })
1311
+ // onTweetLoadSuccess && onTweetLoadSuccess(twitterWidgetElement)
1312
+ })
1313
+ .catch(() => { });
1314
+ });
1315
+ };
1316
+ useEffect(() => {
1317
+ const twttr = window['twttr'];
1318
+ if (!(twttr && twttr.ready)) {
1319
+ addScript(`https://platform.twitter.com/widgets.js`, renderTweet);
1320
+ }
1321
+ else {
1322
+ renderTweet();
1323
+ }
1324
+ }, []);
1325
+ useEffect(() => {
1326
+ }, [rand]);
1327
+ return (jsx(Box, { as: `tweet`, weight: 1, bref: _tweet }));
1328
+ };
1329
+
1330
+ export { App, Component as Block, Box, Button, Checkbox, Cover, Form, 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 };
package/dist/styles.css CHANGED
@@ -105,6 +105,213 @@ button {
105
105
  text-decoration: underline;
106
106
  }
107
107
 
108
+ .flex {
109
+ display: flex;
110
+ }
111
+ .flex.ass {
112
+ align-self: flex-start;
113
+ }
114
+ .flex.asc {
115
+ align-self: center;
116
+ }
117
+ .flex.ase {
118
+ align-self: flex-end;
119
+ }
120
+ .flex.ais {
121
+ align-items: flex-start;
122
+ }
123
+ .flex.aic {
124
+ align-items: center;
125
+ }
126
+ .flex.aie {
127
+ align-items: flex-end;
128
+ }
129
+ .flex.jcs {
130
+ justify-content: flex-start;
131
+ }
132
+ .flex.jcc {
133
+ justify-content: center;
134
+ }
135
+ .flex.jce {
136
+ justify-content: flex-end;
137
+ }
138
+
139
+ /*
140
+ COLORS
141
+ It will generate .cfff { color: #fff; } from 'fff'
142
+ */
143
+ .cfff {
144
+ color: #fff;
145
+ }
146
+
147
+ .c111 {
148
+ color: #111;
149
+ }
150
+
151
+ .c222 {
152
+ color: #222;
153
+ }
154
+
155
+ .c333 {
156
+ color: #333;
157
+ }
158
+
159
+ .c444 {
160
+ color: #444;
161
+ }
162
+
163
+ .c555 {
164
+ color: #555;
165
+ }
166
+
167
+ .c666 {
168
+ color: #666;
169
+ }
170
+
171
+ .c777 {
172
+ color: #777;
173
+ }
174
+
175
+ .c888 {
176
+ color: #888;
177
+ }
178
+
179
+ .c999 {
180
+ color: #999;
181
+ }
182
+
183
+ /*
184
+ FONT SIZES
185
+ It will generate .s10 { font-size: 12px; } from '12'
186
+ */
187
+ .s10 {
188
+ font-size: 10px;
189
+ }
190
+
191
+ .s12 {
192
+ font-size: 12px;
193
+ }
194
+
195
+ .s14 {
196
+ font-size: 14px;
197
+ }
198
+
199
+ .s16 {
200
+ font-size: 16px;
201
+ }
202
+
203
+ .s18 {
204
+ font-size: 18px;
205
+ }
206
+
207
+ .s20 {
208
+ font-size: 20px;
209
+ }
210
+
211
+ .s22 {
212
+ font-size: 22px;
213
+ }
214
+
215
+ .s24 {
216
+ font-size: 24px;
217
+ }
218
+
219
+ .s26 {
220
+ font-size: 26px;
221
+ }
222
+
223
+ .s28 {
224
+ font-size: 28px;
225
+ }
226
+
227
+ .s30 {
228
+ font-size: 30px;
229
+ }
230
+
231
+ .s32 {
232
+ font-size: 32px;
233
+ }
234
+
235
+ .s34 {
236
+ font-size: 34px;
237
+ }
238
+
239
+ .s36 {
240
+ font-size: 36px;
241
+ }
242
+
243
+ .s38 {
244
+ font-size: 38px;
245
+ }
246
+
247
+ .s40 {
248
+ font-size: 40px;
249
+ }
250
+
251
+ .s42 {
252
+ font-size: 42px;
253
+ }
254
+
255
+ .s44 {
256
+ font-size: 44px;
257
+ }
258
+
259
+ .s46 {
260
+ font-size: 46px;
261
+ }
262
+
263
+ .s48 {
264
+ font-size: 48px;
265
+ }
266
+
267
+ .s50 {
268
+ font-size: 50px;
269
+ }
270
+
271
+ .s52 {
272
+ font-size: 52px;
273
+ }
274
+
275
+ .s54 {
276
+ font-size: 54px;
277
+ }
278
+
279
+ .s56 {
280
+ font-size: 56px;
281
+ }
282
+
283
+ .s58 {
284
+ font-size: 58px;
285
+ }
286
+
287
+ .s60 {
288
+ font-size: 60px;
289
+ }
290
+
291
+ .s62 {
292
+ font-size: 62px;
293
+ }
294
+
295
+ .s64 {
296
+ font-size: 64px;
297
+ }
298
+
299
+ .s66 {
300
+ font-size: 66px;
301
+ }
302
+
303
+ .s68 {
304
+ font-size: 68px;
305
+ }
306
+
307
+ .s70 {
308
+ font-size: 70px;
309
+ }
310
+
311
+ .s72 {
312
+ font-size: 72px;
313
+ }
314
+
108
315
  @-webkit-keyframes rotating /* Safari and Chrome */ {
109
316
  from {
110
317
  -webkit-transform: rotate(0deg);
@@ -159,4 +366,49 @@ button {
159
366
  }
160
367
  .zuz-toast.visible {
161
368
  transform: translate(-50%, 0px) scale(1) !important;
369
+ }
370
+
371
+ .zuz-checkbox {
372
+ opacity: 0;
373
+ position: absolute;
374
+ }
375
+ .zuz-checkbox + label {
376
+ position: relative;
377
+ display: inline-block;
378
+ user-select: none;
379
+ transition: 0.4s ease;
380
+ height: 26px;
381
+ width: 44px;
382
+ border-radius: 60px;
383
+ background: #eee;
384
+ }
385
+ .zuz-checkbox + label:before {
386
+ content: "";
387
+ position: absolute;
388
+ display: block;
389
+ transition: 0.2s cubic-bezier(0.24, 0, 0.5, 1);
390
+ height: 26px;
391
+ width: 44px;
392
+ top: 0;
393
+ left: 0;
394
+ border-radius: 30px;
395
+ }
396
+ .zuz-checkbox + label:after {
397
+ content: "";
398
+ position: absolute;
399
+ display: block;
400
+ transition: 0.35s cubic-bezier(0.54, 1.6, 0.5, 1);
401
+ background: #fff;
402
+ height: 22px;
403
+ width: 22px;
404
+ top: 2px;
405
+ left: 2px;
406
+ border-radius: 60px;
407
+ }
408
+ .zuz-checkbox:checked + label:before {
409
+ background: green;
410
+ transition: width 0.2s cubic-bezier(0, 0, 0, 0.1);
411
+ }
412
+ .zuz-checkbox:checked + label:after {
413
+ left: 20px;
162
414
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/ui",
3
- "version": "0.2.0",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {