@zuzjs/ui 0.2.0 → 0.2.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.
Files changed (3) hide show
  1. package/dist/index.js +577 -452
  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,6 +495,420 @@ if (cssColors.length == 0) {
492
495
  });
493
496
  }
494
497
 
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
+ };
519
+ }
520
+ return dispatch;
521
+ };
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
+ });
536
+ }
537
+ if ("function" == typeof callback) {
538
+ return callback(state);
539
+ }
540
+ return state;
541
+ };
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
+ };
553
+ }
554
+ return {};
555
+ };
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]);
569
+ }
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
+ });
597
+
598
+ const useTheme = (mod = 'auto') => {
599
+ const state = useContext(AppContext);
600
+ return state['theme'] || {};
601
+ };
602
+
603
+ const useImage = (url, crossOrigin, referrerpolicy) => {
604
+ const statusRef = useRef('loading');
605
+ const imageRef = useRef();
606
+ const [_, setStateToken] = useState(0);
607
+ const oldUrl = useRef();
608
+ const oldCrossOrigin = useRef();
609
+ const oldReferrerPolicy = useRef();
610
+ if (oldUrl.current !== url || oldCrossOrigin.current !== crossOrigin || oldReferrerPolicy.current !== referrerpolicy) {
611
+ statusRef.current = 'loading';
612
+ imageRef.current = undefined;
613
+ oldUrl.current = url;
614
+ oldCrossOrigin.current = crossOrigin;
615
+ oldReferrerPolicy.current = referrerpolicy;
616
+ }
617
+ useLayoutEffect(function () {
618
+ if (!url)
619
+ return;
620
+ var img = document.createElement('img');
621
+ function onload() {
622
+ statusRef.current = 'loaded';
623
+ imageRef.current = img;
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);
639
+ };
640
+ }, [url, crossOrigin, referrerpolicy]);
641
+ return [imageRef.current, statusRef.current];
642
+ };
643
+
644
+ /** External Dependencies */
645
+ const useResizeObserver = (onResized) => {
646
+ const onResize = onResized ? onResized : () => { };
647
+ const onResizeCallback = useRef(onResize);
648
+ const resizeObserver = useRef();
649
+ const observerCallback = useCallback((entries) => {
650
+ entries.forEach((entry) => {
651
+ if (entry.contentRect) {
652
+ const { width, height } = entry.contentRect;
653
+ onResizeCallback.current({
654
+ entry,
655
+ width,
656
+ height,
657
+ });
658
+ }
659
+ });
660
+ }, []);
661
+ const updateOnResizeCallback = useCallback((newOnResizeCallback) => {
662
+ onResizeCallback.current = newOnResizeCallback;
663
+ }, []);
664
+ const initObserver = useCallback(() => {
665
+ if (!resizeObserver.current) {
666
+ resizeObserver.current = new ResizeObserver(observerCallback);
667
+ }
668
+ }, []);
669
+ const observeElement = useCallback((element, newOnResizeCallback) => {
670
+ if (element) {
671
+ if (!resizeObserver.current) {
672
+ initObserver();
673
+ }
674
+ resizeObserver.current.observe(element);
675
+ if (newOnResizeCallback) {
676
+ onResizeCallback.current = newOnResizeCallback;
677
+ }
678
+ }
679
+ }, []);
680
+ const unobserveElement = useCallback((element, newOnResizeCallback) => {
681
+ if (resizeObserver.current && element) {
682
+ resizeObserver.current.unobserve(element);
683
+ if (newOnResizeCallback) {
684
+ onResizeCallback.current = newOnResizeCallback;
685
+ }
686
+ }
687
+ }, []);
688
+ const removeObserver = useCallback(() => {
689
+ if (resizeObserver.current) {
690
+ resizeObserver.current.disconnect();
691
+ }
692
+ }, []);
693
+ useEffect(() => {
694
+ initObserver();
695
+ return removeObserver;
696
+ }, []);
697
+ return useMemo(() => [observeElement, unobserveElement, updateOnResizeCallback], []);
698
+ };
699
+
700
+ const useChooseEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
701
+
702
+ const EMPTY_BREAKPOINT = {
703
+ breakpoint: undefined,
704
+ minWidth: undefined,
705
+ maxWidth: undefined,
706
+ };
707
+ const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
708
+ const buildQueries = (breakpoints) => {
709
+ const sorted = Object.keys(breakpoints).sort((a, b) => breakpoints[b] - breakpoints[a]);
710
+ return sorted.map((breakpoint, index) => {
711
+ let query = '';
712
+ const minWidth = breakpoints[breakpoint];
713
+ const nextBreakpoint = sorted[index - 1];
714
+ const maxWidth = nextBreakpoint ? breakpoints[nextBreakpoint] : null;
715
+ if (minWidth >= 0) {
716
+ query = `(min-width: ${minWidth}px)`;
717
+ }
718
+ if (maxWidth !== null) {
719
+ if (query) {
720
+ query += ' and ';
721
+ }
722
+ query += `(max-width: ${maxWidth - 1}px)`;
723
+ }
724
+ const mediaQuery = {
725
+ breakpoint,
726
+ maxWidth: maxWidth ? maxWidth - 1 : null,
727
+ minWidth,
728
+ query,
729
+ };
730
+ return mediaQuery;
731
+ });
732
+ };
733
+ /** Memoize list of calculated media queries from config */
734
+ const mediaQueries = useMemo(() => buildQueries(config), [config]);
735
+ /** Get initial breakpoint value */
736
+ const [currentBreakpoint, setCurrentBreakpoint] = useState(() => {
737
+ /** Loop through all media queries */
738
+ for (let _a of mediaQueries) {
739
+ const { query } = _a, breakpoint = __rest(_a, ["query"]);
740
+ /**
741
+ * If we're in the browser and there's no default value,
742
+ * try to match actual breakpoint. If the default value
743
+ * should not be hydrated, use the actual breakpoint.
744
+ */
745
+ if (typeof window !== 'undefined' &&
746
+ !(defaultBreakpoint && hydrateInitial)) {
747
+ const mediaQuery = window.matchMedia(query);
748
+ if (mediaQuery.matches) {
749
+ return breakpoint;
750
+ }
751
+ }
752
+ else if (breakpoint.breakpoint === defaultBreakpoint) {
753
+ /** Otherwise, try to match default value */
754
+ return breakpoint;
755
+ }
756
+ }
757
+ return EMPTY_BREAKPOINT;
758
+ });
759
+ /** If there's a match, update the current breakpoint */
760
+ const updateBreakpoint = useCallback(({ matches }, breakpoint) => {
761
+ if (matches) {
762
+ setCurrentBreakpoint(breakpoint);
763
+ }
764
+ }, []);
765
+ /** On changes to mediaQueries, subscribe to changes using window.matchMedia */
766
+ useChooseEffect(() => {
767
+ const unsubscribers = mediaQueries.map((_a) => {
768
+ var { query } = _a, breakpoint = __rest(_a, ["query"]);
769
+ const list = window.matchMedia(query);
770
+ updateBreakpoint(list, breakpoint);
771
+ const handleChange = (event) => {
772
+ updateBreakpoint(event, breakpoint);
773
+ };
774
+ const supportsNewEventListeners = 'addEventListener' in list && 'removeEventListener' in list;
775
+ if (supportsNewEventListeners) {
776
+ list.addEventListener('change', handleChange);
777
+ }
778
+ else {
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
+
495
912
  const makeCSSValue = (k, v, o) => {
496
913
  let ignore = cssPropsIgnore.indexOf(o) == -1;
497
914
  if (k in cssPropsDirect && ignore == true) {
@@ -614,11 +1031,13 @@ const byName = (e) => document.querySelector(`*[name="${e}"]`);
614
1031
  const byId = (e) => document.getElementById(e);
615
1032
  const addProps = (children, prop) => {
616
1033
  let form = {};
1034
+ let allowedFields = [Input, Select, Button];
617
1035
  let child = Children.deepMap(children, c => {
618
- if (c['props'] && !form[c['props'].name]) {
1036
+ if (allowedFields.indexOf(c['type']) > -1 && c['props'] && !form[c['props'].name]) {
619
1037
  form[c['props'].name] = c['props'].value || null;
620
1038
  }
621
- return cloneElement(c, prop);
1039
+ let Clone = cloneElement(c, prop);
1040
+ return Clone;
622
1041
  });
623
1042
  return {
624
1043
  children: child,
@@ -629,379 +1048,74 @@ const ucfirst = (str) => {
629
1048
  return str.charAt(0).toUpperCase() + str.slice(1);
630
1049
  };
631
1050
  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();
665
-
666
- const useTheme = (mod = 'auto') => {
667
- const state = useContext(AppContext);
668
- return state['theme'] || {};
669
- };
670
-
671
- const useImage = (url, crossOrigin, referrerpolicy) => {
672
- const statusRef = useRef('loading');
673
- const imageRef = useRef();
674
- const [_, setStateToken] = useState(0);
675
- const oldUrl = useRef();
676
- const oldCrossOrigin = useRef();
677
- const oldReferrerPolicy = useRef();
678
- if (oldUrl.current !== url || oldCrossOrigin.current !== crossOrigin || oldReferrerPolicy.current !== referrerpolicy) {
679
- statusRef.current = 'loading';
680
- imageRef.current = undefined;
681
- oldUrl.current = url;
682
- oldCrossOrigin.current = crossOrigin;
683
- oldReferrerPolicy.current = referrerpolicy;
684
- }
685
- useLayoutEffect(function () {
686
- if (!url)
687
- return;
688
- var img = document.createElement('img');
689
- function onload() {
690
- statusRef.current = 'loaded';
691
- 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
- });
752
- };
753
- }
754
- return dispatch;
755
- };
756
-
757
- /** External Dependencies */
758
- const useResizeObserver = (onResized) => {
759
- const onResize = onResized ? onResized : () => { };
760
- const onResizeCallback = useRef(onResize);
761
- const resizeObserver = useRef();
762
- const observerCallback = useCallback((entries) => {
763
- entries.forEach((entry) => {
764
- if (entry.contentRect) {
765
- const { width, height } = entry.contentRect;
766
- onResizeCallback.current({
767
- entry,
768
- width,
769
- height,
770
- });
771
- }
772
- });
773
- }, []);
774
- const updateOnResizeCallback = useCallback((newOnResizeCallback) => {
775
- onResizeCallback.current = newOnResizeCallback;
776
- }, []);
777
- const initObserver = useCallback(() => {
778
- if (!resizeObserver.current) {
779
- resizeObserver.current = new ResizeObserver(observerCallback);
780
- }
781
- }, []);
782
- const observeElement = useCallback((element, newOnResizeCallback) => {
783
- if (element) {
784
- if (!resizeObserver.current) {
785
- initObserver();
786
- }
787
- resizeObserver.current.observe(element);
788
- if (newOnResizeCallback) {
789
- onResizeCallback.current = newOnResizeCallback;
790
- }
791
- }
792
- }, []);
793
- const unobserveElement = useCallback((element, newOnResizeCallback) => {
794
- if (resizeObserver.current && element) {
795
- resizeObserver.current.unobserve(element);
796
- if (newOnResizeCallback) {
797
- onResizeCallback.current = newOnResizeCallback;
798
- }
799
- }
800
- }, []);
801
- const removeObserver = useCallback(() => {
802
- if (resizeObserver.current) {
803
- resizeObserver.current.disconnect();
804
- }
805
- }, []);
806
- useEffect(() => {
807
- initObserver();
808
- return removeObserver;
809
- }, []);
810
- return useMemo(() => [observeElement, unobserveElement, updateOnResizeCallback], []);
811
- };
812
-
813
- const useChooseEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
814
-
815
- const EMPTY_BREAKPOINT = {
816
- breakpoint: undefined,
817
- minWidth: undefined,
818
- maxWidth: undefined,
819
- };
820
- const useDevice = (config, defaultBreakpoint, hydrateInitial = true) => {
821
- const buildQueries = (breakpoints) => {
822
- const sorted = Object.keys(breakpoints).sort((a, b) => breakpoints[b] - breakpoints[a]);
823
- return sorted.map((breakpoint, index) => {
824
- let query = '';
825
- const minWidth = breakpoints[breakpoint];
826
- const nextBreakpoint = sorted[index - 1];
827
- const maxWidth = nextBreakpoint ? breakpoints[nextBreakpoint] : null;
828
- if (minWidth >= 0) {
829
- query = `(min-width: ${minWidth}px)`;
830
- }
831
- if (maxWidth !== null) {
832
- if (query) {
833
- query += ' and ';
834
- }
835
- query += `(max-width: ${maxWidth - 1}px)`;
836
- }
837
- const mediaQuery = {
838
- breakpoint,
839
- maxWidth: maxWidth ? maxWidth - 1 : null,
840
- minWidth,
841
- query,
842
- };
843
- return mediaQuery;
844
- });
845
- };
846
- /** Memoize list of calculated media queries from config */
847
- const mediaQueries = useMemo(() => buildQueries(config), [config]);
848
- /** Get initial breakpoint value */
849
- const [currentBreakpoint, setCurrentBreakpoint] = useState(() => {
850
- /** Loop through all media queries */
851
- for (let _a of mediaQueries) {
852
- const { query } = _a, breakpoint = __rest(_a, ["query"]);
853
- /**
854
- * If we're in the browser and there's no default value,
855
- * try to match actual breakpoint. If the default value
856
- * should not be hydrated, use the actual breakpoint.
857
- */
858
- if (typeof window !== 'undefined' &&
859
- !(defaultBreakpoint && hydrateInitial)) {
860
- const mediaQuery = window.matchMedia(query);
861
- if (mediaQuery.matches) {
862
- return breakpoint;
863
- }
864
- }
865
- else if (breakpoint.breakpoint === defaultBreakpoint) {
866
- /** Otherwise, try to match default value */
867
- return breakpoint;
868
- }
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];
869
1079
  }
870
- return EMPTY_BREAKPOINT;
871
1080
  });
872
- /** If there's a match, update the current breakpoint */
873
- const updateBreakpoint = useCallback(({ matches }, breakpoint) => {
874
- if (matches) {
875
- setCurrentBreakpoint(breakpoint);
876
- }
877
- }, []);
878
- /** On changes to mediaQueries, subscribe to changes using window.matchMedia */
879
- useChooseEffect(() => {
880
- const unsubscribers = mediaQueries.map((_a) => {
881
- var { query } = _a, breakpoint = __rest(_a, ["query"]);
882
- const list = window.matchMedia(query);
883
- updateBreakpoint(list, breakpoint);
884
- const handleChange = (event) => {
885
- updateBreakpoint(event, breakpoint);
886
- };
887
- const supportsNewEventListeners = 'addEventListener' in list && 'removeEventListener' in list;
888
- if (supportsNewEventListeners) {
889
- list.addEventListener('change', handleChange);
890
- }
891
- else {
892
- list.addListener(handleChange);
893
- }
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;
1081
+ return filter;
912
1082
  };
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);
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);
@@ -1126,14 +1238,14 @@ const Form = forwardRef((props, ref) => {
1126
1238
  get
1127
1239
  }));
1128
1240
  useEffect(() => {
1241
+ let f = buildFields();
1242
+ setHTML(f.children);
1129
1243
  if (!forms[name]) {
1130
- let f = buildFields();
1131
- 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,58 @@ 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
+ const ContextMenu = forwardRef((props, ref) => {
1331
+ const { as, size, color, hover, pos, items } = props;
1332
+ return (jsx(Box, Object.assign({ hover: hover || {}, flex: true, fixed: true, top: (pos === null || pos === void 0 ? void 0 : pos.y) || 0, left: (pos === null || pos === void 0 ? void 0 : pos.x) || 0, bref: ref, as: `contextmenu-${as}`, ai: `c`, jc: `c`, size: size || 24, color: color || `#111111` }, { children: items && items.map((m, i) => jsx(Button, Object.assign({ onClick: m.on ? m.on : () => { } }, { children: m.label }), `cm-${i}-${m.id}`)) })));
1333
+ });
1334
+
1335
+ const buildElement = (el) => {
1336
+ switch (el.is) {
1337
+ case "Box":
1338
+ return jsx(Box, Object.assign({}, (el.props || {}), { children: el.children || null }), el.key || nanoid());
1339
+ }
1340
+ };
1341
+ const buildComponent = (data) => {
1342
+ return data.map(e => buildElement(e));
1343
+ };
1344
+
1345
+ const Header = forwardRef((props, ref) => {
1346
+ const data = [
1347
+ { is: `Box` }
1348
+ ];
1349
+ return (jsx(Fragment, { children: buildComponent(data) }));
1350
+ });
1351
+
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 };