@zuzjs/ui 0.4.1 → 0.4.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.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # zuzjs-ui
package/dist/bin.js CHANGED
@@ -91,12 +91,23 @@ const rebuildAll = () => {
91
91
  }
92
92
  }
93
93
  else {
94
+ const mediaQueries = {};
94
95
  files.map(f => {
95
96
  const r = rebuild(f);
96
97
  if (r && r.length > 0) {
97
- as.push(cssBuilder.Build([r], true).sheet);
98
+ const _built = cssBuilder.Build([r], true);
99
+ as.push(_built.sheet);
100
+ Object.keys(_built.mediaQuery).map(mq => {
101
+ if (!mediaQueries[mq])
102
+ mediaQueries[mq] = [];
103
+ mediaQueries[mq] = [
104
+ ...mediaQueries[mq],
105
+ ..._built.mediaQuery[mq]
106
+ ];
107
+ });
98
108
  }
99
109
  });
110
+ as.push(cssBuilder.buildMediaQueries(mediaQueries));
100
111
  }
101
112
  const sheet = as.join(`\n`);
102
113
  if (!fs.existsSync(path.join(process.cwd(), `src`, `app`, `css`))) {
@@ -1,12 +1,14 @@
1
1
  import { ComponentPropsWithoutRef, ElementType } from "react";
2
2
  import { dynamicObject } from "../types";
3
+ import { TRANSITION_CURVES, TRANSITIONS } from "../types/enums";
3
4
  export interface animationProps {
5
+ transition?: TRANSITIONS;
4
6
  from?: dynamicObject;
5
7
  to?: dynamicObject;
6
8
  when?: boolean;
7
9
  duration?: number;
8
10
  delay?: number;
9
- curve?: string;
11
+ curve?: string | TRANSITION_CURVES;
10
12
  }
11
13
  interface BaseProps<T extends ElementType> {
12
14
  tag?: T;
@@ -1,23 +1,23 @@
1
1
  import { createElement, forwardRef } from "react";
2
2
  import { css, cleanProps } from "../funs";
3
- import { buildWithStyles } from "../funs/css";
3
+ import { buildWithStyles, getAnimationCurve, getAnimationTransition } from "../funs/css";
4
4
  const With = forwardRef(({ tag, as, animate, className, propsToRemove, style, ...rest }, ref) => {
5
5
  const Comp = tag || 'div';
6
6
  let cx = [];
7
7
  if (as) {
8
8
  cx = css().Build(`string` == typeof as ? as : as.join(` `)).cx;
9
9
  }
10
- const { from, to, when, duration, delay, curve } = animate || {};
10
+ const { transition, from, to, when, duration, delay, curve } = animate || {};
11
11
  let _style = {};
12
- const _transition = from && to ? { transition: `all ${duration || `0.2`}s ${curve || `linear`} ${delay || 0}s` } : {};
12
+ const _transition = transition || (from && to) ? { transition: `all ${duration || `0.2`}s ${getAnimationCurve(curve)} ${delay || 0}s` } : {};
13
13
  if (undefined === when) {
14
- _style = { ...from, ...to };
14
+ _style = transition ? getAnimationTransition(transition, true) : { ...from, ...to };
15
15
  }
16
16
  else if (true === when) {
17
- _style = { ...(to || {}) };
17
+ _style = transition ? getAnimationTransition(transition, false) : { ...(to || {}) };
18
18
  }
19
19
  else {
20
- _style = from || {};
20
+ _style = transition ? getAnimationTransition(transition, false, true) : from || {};
21
21
  }
22
22
  return createElement(Comp, {
23
23
  style: {
@@ -8,6 +8,7 @@ export interface CoverProps extends ComponentPropsWithoutRef<`div`> {
8
8
  color?: string;
9
9
  as?: string;
10
10
  animate?: animationProps;
11
+ when?: boolean;
11
12
  }
12
13
  declare const Cover: import("react").ForwardRefExoticComponent<CoverProps & import("react").RefAttributes<HTMLDivElement>>;
13
14
  export default Cover;
@@ -2,11 +2,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import With from "./base";
4
4
  import Spinner from "./spinner";
5
- import { hexToRgba } from "../funs";
6
5
  const Cover = forwardRef((props, ref) => {
7
6
  const { spinner, message, color, as, ...rest } = props;
8
- return (_jsxs(With, { className: `zuz-cover flex aic jcc cols abs fill`, ref: ref, style: {
9
- backgroundColor: hexToRgba(color || `#ffffff`, .9)
10
- }, as: as, ...rest, children: [_jsx(Spinner, { ...spinner }), _jsx(With, { tag: `h1`, className: `label`, children: message || `loading` })] }));
7
+ if (`when` in props && props.when == false) {
8
+ return null;
9
+ }
10
+ return (_jsxs(With, { className: `zuz-cover flex aic jcc cols abs fillx nope nous`, ref: ref, style: {
11
+ backgroundColor: `var(--cover-bg)`
12
+ }, as: as, ...rest, children: [_jsx(Spinner, { ...{
13
+ ...spinner
14
+ } }), _jsx(With, { tag: `h1`, className: `label`, style: { color: `var(--cover-label)` }, children: message || `loading` })] }));
11
15
  });
12
16
  export default Cover;
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -16,5 +16,8 @@ export interface FormProps {
16
16
  message?: string;
17
17
  };
18
18
  }
19
- declare const Form: import("react").ForwardRefExoticComponent<FormProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
19
+ export interface FormHandler {
20
+ setLoading: (mode: boolean) => void;
21
+ }
22
+ declare const Form: import("react").ForwardRefExoticComponent<FormProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<FormHandler>>;
20
23
  export default Form;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { forwardRef, useEffect, useRef, useState, useTransition } from "react";
3
+ import { forwardRef, useEffect, useImperativeHandle, useRef, useState, useTransition } from "react";
4
4
  import With from "./base";
5
5
  import { isEmail, withPost } from "../funs";
6
6
  import Sheet from "./sheet";
@@ -134,7 +134,15 @@ const Form = forwardRef((props, ref) => {
134
134
  });
135
135
  }
136
136
  };
137
+ useImperativeHandle(ref, () => ({
138
+ setLoading(mod) {
139
+ setLoading(mod);
140
+ },
141
+ showError(errorMsg) {
142
+ sheet.current.show(errorMsg, 4, SHEET.Error);
143
+ }
144
+ }));
137
145
  useEffect(_init, []);
138
- return _jsxs(With, { as: as, className: `rel`, ref: _ref, propsToRemove: [`withData`, `action`, `onSubmit`, `onSuccess`, `onError`], ...rest, children: [_jsx(Sheet, { ref: sheet }), loading && _jsx(Cover, { message: cover.message || `working`, ...{ spinner, color: cover.color || `#ffffff` } }), children] });
146
+ return _jsxs(With, { as: as, className: `rel`, ref: _ref, propsToRemove: [`withData`, `action`, `onSubmit`, `onSuccess`, `onError`], ...rest, children: [_jsx(Sheet, { ref: sheet }), loading && _jsx(Cover, { message: cover ? cover.message || undefined : `working`, ...{ spinner, color: cover ? `color` in cover ? cover.color : `#ffffff` : `#ffffff` } }), children] });
139
147
  });
140
148
  export default Form;
@@ -0,0 +1,18 @@
1
+ import { animationProps } from "./base";
2
+ import { FORMVALIDATION } from "../types/enums";
3
+ import { dynamicObject } from "../types";
4
+ export interface SelectProps {
5
+ as?: string;
6
+ name?: string;
7
+ animate?: animationProps;
8
+ required?: FORMVALIDATION;
9
+ options: dynamicObject[];
10
+ label?: string;
11
+ defaultValue?: string | dynamicObject;
12
+ onChange?: (v: string | dynamicObject) => void;
13
+ }
14
+ export interface SelectHandler {
15
+ onChange?: (v: string | dynamicObject) => void;
16
+ }
17
+ declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<SelectHandler>>;
18
+ export default Select;
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { forwardRef, useEffect, useMemo, useRef, useState } from "react";
4
+ import With from "./base";
5
+ import { uuid } from "../funs";
6
+ const chevronExpand = () => _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "currentColor", className: "bi bi-chevron-expand", viewBox: "0 0 16 16", children: _jsx("path", { fillRule: "evenodd", d: "M3.646 9.146a.5.5 0 01.708 0L8 12.793l3.646-3.647a.5.5 0 01.708.708l-4 4a.5.5 0 01-.708 0l-4-4a.5.5 0 010-.708zm0-2.292a.5.5 0 00.708 0L8 3.207l3.646 3.647a.5.5 0 00.708-.708l-4-4a.5.5 0 00-.708 0l-4 4a.5.5 0 000 .708z" }) });
7
+ const Select = forwardRef((props, ref) => {
8
+ const { as, options, name, label, defaultValue, onChange, ...rest } = props;
9
+ const _ref = useRef(null);
10
+ const _id = useMemo(() => name || uuid(), []);
11
+ const [choosing, setChoosing] = useState(false);
12
+ const [value, setValue] = useState(defaultValue || options[0]);
13
+ const updateValue = (o) => {
14
+ setValue(o);
15
+ onChange && onChange(o);
16
+ };
17
+ useEffect(() => {
18
+ document.body.addEventListener(`click`, (e) => {
19
+ setChoosing(false);
20
+ });
21
+ }, []);
22
+ return _jsxs(_Fragment, { children: [_jsxs(With, { popovertarget: _id, tag: `button`, as: as, className: `zuz-select rel flex aic`, ref: _ref, onClick: (e) => setChoosing(true), ...rest, children: [_jsx(With, { tag: `h2`, className: `zuz-selected`, children: value ? `string` == typeof value ? value : value.value : label || `Choose` }), chevronExpand()] }), _jsx(With, { popover: true, id: _id, className: `zuz-select-options abs flex cols`, style: {
23
+ pointerEvents: choosing ? `auto` : `none`,
24
+ }, animate: {
25
+ from: { height: 0, opacity: 0 },
26
+ to: { height: `auto`, opacity: 1 },
27
+ when: choosing,
28
+ curve: `spring`,
29
+ duration: .4
30
+ }, children: options.map((o) => _jsx(With, { onClick: (e) => updateValue(o), className: value && (`string` == typeof o ? o : o.value) == (`string` == typeof value ? value : value.value) ? `selected` : ``, tag: `button`, children: `string` == typeof o ? o : o.label }, `option-${(`string` == typeof o ? o : o.label).replace(/\s+/g, `-`)}-${`string` == typeof o ? o : o.value}`)) })] });
31
+ });
32
+ export default Select;
@@ -7,8 +7,13 @@ export interface SheetProps {
7
7
  title?: string;
8
8
  message?: string | ReactNode;
9
9
  }
10
+ export interface SheetActionHandler {
11
+ label: string;
12
+ handler: () => void;
13
+ }
10
14
  export interface SheetHandler {
11
- show: (message: string, duration?: number, type?: SHEET) => void;
15
+ showDialog: (title: string | ReactNode, message: string | ReactNode, action?: SheetActionHandler, onShow?: () => void) => void;
16
+ show: (message: string | ReactNode, duration?: number, type?: SHEET) => void;
12
17
  hide: () => void;
13
18
  }
14
19
  declare const Sheet: import("react").ForwardRefExoticComponent<SheetProps & import("react").RefAttributes<SheetHandler>>;
@@ -1,18 +1,26 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
4
4
  import With from "./base";
5
5
  import { SHEET } from "../types/enums";
6
+ import Cover from "./cover";
6
7
  let _sheetTimeout = null;
7
8
  let _sheetWobbleTimeout = null;
8
9
  const Sheet = forwardRef((props, ref) => {
9
10
  const { as, ...rest } = props;
10
11
  const [visible, setVisible] = useState(false);
12
+ const [title, setTitle] = useState(``);
11
13
  const [msg, setMsg] = useState(``);
14
+ const [action, setAction] = useState(null);
12
15
  const [_errorType, setErrorType] = useState(SHEET.Default);
16
+ const [loading, setLoading] = useState(false);
13
17
  const divRef = useRef(null);
18
+ const lastTransform = useRef(null);
14
19
  useImperativeHandle(ref, () => ({
15
- show(message, duration, type) {
20
+ setLoading(mode) {
21
+ setLoading(mode);
22
+ },
23
+ showDialog(title, message, action, onShow) {
16
24
  if (_sheetTimeout) {
17
25
  clearTimeout(_sheetTimeout);
18
26
  if (_sheetWobbleTimeout) {
@@ -25,6 +33,33 @@ const Sheet = forwardRef((props, ref) => {
25
33
  _sheetWobbleTimeout = null;
26
34
  }, 500);
27
35
  }
36
+ setErrorType(SHEET.Dialog);
37
+ setMsg(message);
38
+ setTitle(title);
39
+ if (action)
40
+ setAction(action);
41
+ setVisible(true);
42
+ setTimeout(() => onShow ? onShow() : () => { }, 1000);
43
+ },
44
+ show(message, duration, type) {
45
+ if (_sheetTimeout) {
46
+ clearTimeout(_sheetTimeout);
47
+ if (_sheetWobbleTimeout) {
48
+ clearTimeout(_sheetWobbleTimeout);
49
+ }
50
+ lastTransform.current = divRef.current.style.transform;
51
+ divRef.current.style.transform = ``;
52
+ divRef.current.classList.remove(`wobble`);
53
+ setTimeout(() => {
54
+ divRef.current.classList.add(`wobble`);
55
+ divRef.current.style.transform = `${lastTransform.current} scale(.9)`.trim();
56
+ }, 50);
57
+ _sheetWobbleTimeout = setTimeout(() => {
58
+ divRef.current.classList.remove(`wobble`);
59
+ divRef.current.style.transform = lastTransform.current || ``;
60
+ _sheetWobbleTimeout = null;
61
+ }, 500);
62
+ }
28
63
  _sheetTimeout = setTimeout(() => {
29
64
  setVisible(false);
30
65
  _sheetTimeout = null;
@@ -40,6 +75,27 @@ const Sheet = forwardRef((props, ref) => {
40
75
  }));
41
76
  useEffect(() => {
42
77
  }, []);
43
- return _jsx(With, { as: as, className: `zuz-sheet toast-${_errorType.toLowerCase()} zuz-toast${visible ? ` is-visible` : ``} fixed`.trim(), ...rest, ref: divRef, children: msg == `` ? `Lorem ipsum dolor sit amet, consectetur adipiscing...` : msg });
78
+ return _jsxs(_Fragment, { children: [_errorType == SHEET.Dialog && _jsx(With, { className: `zuz-sheet-overlay fixed fill`, animate: {
79
+ from: { y: `-100vh`, opacity: 0 },
80
+ to: { y: 0, opacity: 1 },
81
+ when: visible,
82
+ duration: 0.1,
83
+ } }), _jsxs(With, { animate: _errorType == SHEET.Dialog ? {
84
+ from: { scale: 0, x: `-50%`, y: `-50%`, opacity: 0 },
85
+ to: { scale: 1, x: `-50%`, y: `-50%`, opacity: 1 },
86
+ when: visible,
87
+ duration: 0.3,
88
+ delay: 0.1,
89
+ curve: `spring`
90
+ } : {
91
+ from: { scale: 0, x: `-50%`, y: `-10vh`, opacity: 0 },
92
+ to: { scale: 1, x: `-50%`, y: 0, opacity: 1 },
93
+ when: visible,
94
+ duration: 0.3,
95
+ delay: 0.1,
96
+ curve: `spring`
97
+ }, as: as, className: `zuz-sheet toast-${_errorType.toLowerCase()} fixed`.trim(), ...rest, ref: divRef, children: [_errorType == SHEET.Dialog && _jsx(Cover, { ...({
98
+ when: loading,
99
+ }) }), _errorType == SHEET.Dialog && _jsxs(With, { className: `zuz-sheet-head flex aic rel`, children: [_jsx(With, { className: `zuz-sheet-${title ? `title` : `dot`}`, children: title || `` }), _jsx(With, { tag: `button`, onClick: (e) => setVisible(false), className: `zuz-sheet-closer abs`, children: "\u00D7" })] }), visible && msg == `` ? `Lorem ipsum dolor sit amet, consectetur adipiscing...` : msg] })] });
44
100
  });
45
101
  export default Sheet;
@@ -7,8 +7,8 @@ const Spinner = forwardRef((props, ref) => {
7
7
  const { as, type, width, speed, size, color, background, foreground, ...rest } = props;
8
8
  const defaultColor = `#000000`;
9
9
  const buildSimple = () => {
10
- const c = hexToRgba(color || defaultColor);
11
- const bg = hexToRgba(color || defaultColor, .3);
10
+ const c = color && color.startsWith(`var`) ? color : hexToRgba(color || defaultColor);
11
+ const bg = color && color.startsWith(`var`) ? color : hexToRgba(color || defaultColor, .3);
12
12
  const pops = {
13
13
  width: size || 50,
14
14
  height: size || 50,
@@ -1,5 +1,6 @@
1
1
  import { dynamicObject } from "../types";
2
2
  import Hashids from "hashids";
3
+ import { TRANSITION_CURVES, TRANSITIONS } from "../types/enums.js";
3
4
  declare class CSS {
4
5
  cx: string[];
5
6
  cache: dynamicObject;
@@ -15,7 +16,11 @@ declare class CSS {
15
16
  seperator: string;
16
17
  pseudoList: string[];
17
18
  ids: string[];
19
+ mediaQueries: dynamicObject;
20
+ _mediaQueries: dynamicObject;
21
+ _mediaQueriesLabels: dynamicObject;
18
22
  constructor(options?: dynamicObject | undefined);
23
+ buildMediaQueries(queries: dynamicObject): string;
19
24
  styleSheet(cache: dynamicObject, pseudo?: string): string;
20
25
  _styleSheet(cache: dynamicObject): string;
21
26
  cleanKey(key: string): string;
@@ -30,7 +35,10 @@ declare class CSS {
30
35
  Build(css: string | string[][], cli?: boolean): {
31
36
  cx: string[];
32
37
  sheet: string;
38
+ mediaQuery: dynamicObject;
33
39
  };
34
40
  }
35
41
  export default CSS;
36
42
  export declare const buildWithStyles: (source: dynamicObject) => dynamicObject;
43
+ export declare const getAnimationCurve: (curve?: string | TRANSITION_CURVES) => string;
44
+ export declare const getAnimationTransition: (transition: TRANSITIONS, to?: boolean, from?: boolean) => dynamicObject;
package/dist/funs/css.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { __SALT, FIELNAME_KEY, isColor, isHexColor, isNumber, LINE_KEY, setDeep } from "./index.js";
2
2
  import { cssAnimationCurves, cssDirect, cssProps, cssTransformKeys, cssWithKeys } from "./stylesheet.js";
3
3
  import Hashids from "hashids";
4
+ import { TRANSITION_CURVES, TRANSITIONS } from "../types/enums.js";
4
5
  class CSS {
5
6
  cx;
6
7
  cache;
@@ -16,8 +17,26 @@ class CSS {
16
17
  seperator;
17
18
  pseudoList;
18
19
  ids;
20
+ mediaQueries;
21
+ _mediaQueries;
22
+ _mediaQueriesLabels;
19
23
  constructor(options) {
20
24
  const opts = options || {};
25
+ this._mediaQueries = {};
26
+ this._mediaQueriesLabels = {
27
+ ph: `Extra Small Devices (Phones)`,
28
+ sm: `Small Devices (Tablets)`,
29
+ md: `Medium Devices (Small Laptops)`,
30
+ lg: `Large Devices (Laptops and Desktops)`,
31
+ xl: `Extra Large Devices (Large Desktops)`,
32
+ };
33
+ this.mediaQueries = {
34
+ ph: `(max-width: 599px)`,
35
+ sm: `(min-width: 600px) and (max-width: 767px)`,
36
+ md: `(min-width: 768px) and (max-width: 991px)`,
37
+ lg: `(min-width: 992px) and (max-width: 1199px)`,
38
+ xl: `(min-width: 1200px)`,
39
+ };
21
40
  this.cx = [];
22
41
  this.cache = {};
23
42
  this.unit = opts.unit || `px`;
@@ -41,25 +60,59 @@ class CSS {
41
60
  this.PROPS = cssProps;
42
61
  this.DIRECT = cssDirect;
43
62
  }
63
+ buildMediaQueries(queries) {
64
+ const self = this;
65
+ const scss = [`\n`];
66
+ Object.keys(queries).forEach((key) => {
67
+ scss.push(`/**\n*${self._mediaQueriesLabels[key]}\n*/`);
68
+ scss.push(`@media screen and ${self.mediaQueries[key]}{`);
69
+ scss.push(queries[key].join(`\n`));
70
+ scss.push(`}`);
71
+ });
72
+ return scss.join(`\n`);
73
+ }
44
74
  styleSheet(cache, pseudo = ``) {
45
75
  const self = this;
46
76
  const scss = [];
47
77
  const build = (key, value) => {
48
- let css = `${self.pseudoList.includes(`@${key}`) ? `&:` : `.`}${key}{`;
49
- if (`object` == typeof value) {
50
- for (const prop in value) {
51
- if (`object` == typeof value[prop]) {
52
- css += build(prop, value[prop]);
78
+ const __build = (_key, _value) => {
79
+ let _css = `${self.pseudoList.includes(`@${_key}`) ? `&:` : `.`}${_key}{`;
80
+ if (`object` == typeof _value) {
81
+ for (const prop in _value) {
82
+ if (`object` == typeof _value[prop]) {
83
+ _css += __build(prop, _value[prop]);
84
+ }
85
+ else {
86
+ _css += _value[prop];
87
+ }
88
+ }
89
+ }
90
+ else {
91
+ _css += _value;
92
+ }
93
+ _css += `}`;
94
+ return _css;
95
+ };
96
+ let css = ``;
97
+ if (`object` == typeof value && Object.keys(value)[0] in this.mediaQueries) {
98
+ const mq = Object.keys(value)[0];
99
+ let __css = `.${key}{`;
100
+ const _value = value[mq];
101
+ for (const prop in _value) {
102
+ if (`object` == typeof _value[prop]) {
103
+ __css += __build(prop, _value[prop]);
53
104
  }
54
105
  else {
55
- css += value[prop];
106
+ __css += _value[prop];
56
107
  }
57
108
  }
109
+ __css += `}`;
110
+ this._mediaQueries[mq] = this._mediaQueries[mq] || [];
111
+ this._mediaQueries[mq].push(__css);
58
112
  }
59
113
  else {
60
- css += value;
114
+ css += __build(key, value);
61
115
  }
62
- css += `}`;
63
116
  return css;
64
117
  };
65
118
  for (const key in cache) {
@@ -168,7 +221,8 @@ class CSS {
168
221
  const _id = `z${self.hashids.encode(_indices)}`;
169
222
  if (!_[_id]) {
170
223
  const cleaned = self.deepClean(cache[_k], level + 1);
171
- if (level == 0 && self.pseudoList.includes(`@${__k}`)) {
224
+ if (level == 0 &&
225
+ (self.pseudoList.includes(`@${__k}`) || __k in self.mediaQueries)) {
172
226
  self.cx.push(_id);
173
227
  _[_id] = { [__k]: cleaned };
174
228
  }
@@ -388,6 +442,17 @@ class CSS {
388
442
  }
389
443
  else {
390
444
  const value = (_k, pseudo = ``) => {
445
+ let _mediaQuery = null;
446
+ if (_k.includes(`@`)) {
447
+ const [_x, _y] = _k.split(`@`);
448
+ _k = _x;
449
+ _mediaQuery = _y;
450
+ if (_y.includes(`:`)) {
451
+ const [_a, _b] = _y.split(`:`);
452
+ _k = `${_x}:${_b}`;
453
+ _mediaQuery = _a;
454
+ }
455
+ }
391
456
  if (_k.includes(`:`)) {
392
457
  const [key, _val] = _k.split(`:`);
393
458
  if (key in self.PROPS) {
@@ -395,6 +460,10 @@ class CSS {
395
460
  const _id = self.makeID(key, _val + pseudo, _out);
396
461
  if (pseudo == ``)
397
462
  self.cx.push(_id);
463
+ if (_mediaQuery) {
464
+ self.mediaQueries[_mediaQuery].push({ [_id]: _out });
465
+ return {};
466
+ }
398
467
  return { [_id]: _out };
399
468
  }
400
469
  else if (key in self.DIRECT) {
@@ -408,6 +477,9 @@ class CSS {
408
477
  return acc;
409
478
  }, []).join(`,`);
410
479
  }
480
+ else if (key == `ratio`) {
481
+ _out = self.DIRECT[key].replace(`__VALUE__`, val.replace(`,`, `/`));
482
+ }
411
483
  else if (key == `anim`) {
412
484
  let delay = `0s`;
413
485
  let curve = `linear`;
@@ -439,6 +511,10 @@ class CSS {
439
511
  const _id = self.makeID(key, key + pseudo, _out);
440
512
  if (pseudo == ``)
441
513
  self.cx.push(_id);
514
+ if (_mediaQuery) {
515
+ self.mediaQueries[_mediaQuery].push({ [_id]: _out });
516
+ return {};
517
+ }
442
518
  return { [_id]: _out };
443
519
  }
444
520
  }
@@ -447,6 +523,10 @@ class CSS {
447
523
  const _id = self.makeID(_k, _k + pseudo, _out);
448
524
  if (pseudo == ``)
449
525
  self.cx.push(_id);
526
+ if (_mediaQuery) {
527
+ self.mediaQueries[_mediaQuery].push({ [_id]: _out });
528
+ return {};
529
+ }
450
530
  return { [_id]: _out };
451
531
  }
452
532
  else if (_k.trim().match(/^[a-zA-Z0-9\-]+$/g)) {
@@ -474,10 +554,12 @@ class CSS {
474
554
  let self = this;
475
555
  self.cx = [];
476
556
  self.cache = {};
557
+ self._mediaQueries = {};
477
558
  if (undefined == css)
478
559
  return {
479
560
  cx: self.cx,
480
- sheet: ``
561
+ sheet: ``,
562
+ mediaQuery: {}
481
563
  };
482
564
  if (`string` == typeof css) {
483
565
  css = [[css]];
@@ -488,9 +570,11 @@ class CSS {
488
570
  });
489
571
  });
490
572
  const _cleaned = self.deepClean(self.cache);
573
+ const _stylesheet = self.styleSheet(_cleaned);
491
574
  const _ = {
492
575
  cx: self.cx,
493
- sheet: self.styleSheet(_cleaned)
576
+ sheet: _stylesheet,
577
+ mediaQuery: self._mediaQueries
494
578
  };
495
579
  return _;
496
580
  }
@@ -523,3 +607,34 @@ export const buildWithStyles = (source) => {
523
607
  }
524
608
  return _;
525
609
  };
610
+ export const getAnimationCurve = (curve) => {
611
+ if (!curve)
612
+ return `linear`;
613
+ switch (curve.toUpperCase()) {
614
+ case TRANSITION_CURVES.Spring:
615
+ return `cubic-bezier(0.2, -0.36, 0, 1.46)`;
616
+ break;
617
+ default:
618
+ return `linear`;
619
+ }
620
+ };
621
+ export const getAnimationTransition = (transition, to, from) => {
622
+ let _from, _to;
623
+ switch (transition) {
624
+ case TRANSITIONS.SlideInLeft:
625
+ case TRANSITIONS.SlideInRight:
626
+ _from = { x: transition == TRANSITIONS.SlideInLeft ? -20 : 20, opacity: 0 };
627
+ _to = { x: 0, opacity: 1 };
628
+ break;
629
+ case TRANSITIONS.SlideInTop:
630
+ case TRANSITIONS.SlideInBottom:
631
+ _from = { y: transition == TRANSITIONS.SlideInTop ? -20 : 20, opacity: 0 };
632
+ _to = { y: 0, opacity: 1 };
633
+ break;
634
+ case TRANSITIONS.ScaleIn:
635
+ _from = { scale: 0, opacity: 0 };
636
+ _to = { scale: 1, opacity: 1 };
637
+ break;
638
+ }
639
+ return to ? { ..._from, ..._to } : from ? _from : _to;
640
+ };
@@ -6,6 +6,8 @@ export declare const LINE_KEY = "__LINE__";
6
6
  export declare const toHash: (n: number, len?: number) => string;
7
7
  export declare const fromHash: (n: string) => number;
8
8
  export declare const css: () => CSS;
9
+ export declare const uuid: (len?: number) => string;
10
+ export declare const numberInRange: (min: number, max: number) => number;
9
11
  export declare const hexColorRegex: RegExp;
10
12
  export declare const rgbaColorRegex: RegExp;
11
13
  export declare const hslColorRegex: RegExp;
@@ -25,3 +27,8 @@ export declare const setDeep: (object: dynamicObject, path: string, value: any,
25
27
  export declare const removeDuplicatesFromArray: <T>(array: T[]) => T[];
26
28
  export declare const extendGlobals: () => void;
27
29
  export declare const withPost: (uri: string, data: dynamicObject, timeout?: number, fd?: dynamicObject) => Promise<unknown>;
30
+ export declare const useDevice: () => {
31
+ isMobile: boolean;
32
+ isTablet: boolean;
33
+ isDesktop: boolean;
34
+ };
@@ -3,6 +3,8 @@ import CSS from './css.js';
3
3
  import axios from "axios";
4
4
  import { colorNames } from "./colors.js";
5
5
  import Hashids from "hashids";
6
+ import { nanoid } from "nanoid";
7
+ import Cookies from "js-cookie";
6
8
  let __css;
7
9
  export const __SALT = `zuzjs-ui`;
8
10
  export const FIELNAME_KEY = `__FILENAME__`;
@@ -10,6 +12,10 @@ export const LINE_KEY = `__LINE__`;
10
12
  export const toHash = (n, len = 6) => new Hashids(__SALT, len).encode(n);
11
13
  export const fromHash = (n) => Number(new Hashids(__SALT).decode(n));
12
14
  export const css = () => __css ? __css : __css = new CSS();
15
+ export const uuid = (len) => nanoid(len);
16
+ export const numberInRange = (min, max) => {
17
+ return Math.floor(Math.random() * (max - min + 1)) + min;
18
+ };
13
19
  export const hexColorRegex = /^#([A-Fa-f0-9]{3}){1,2}$/;
14
20
  export const rgbaColorRegex = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*((0|1|0?\.\d+)\s*))?\)$/;
15
21
  export const hslColorRegex = /^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)$/;
@@ -103,7 +109,10 @@ export const withPost = async (uri, data, timeout = 60, fd = {}) => {
103
109
  axios({
104
110
  method: 'post',
105
111
  url: uri,
106
- data: data,
112
+ data: {
113
+ ...data,
114
+ ...Cookies.get(),
115
+ },
107
116
  timeout: timeout * 1000,
108
117
  headers: {
109
118
  'Content-Type': 'multipart/form-data',
@@ -125,6 +134,7 @@ export const withPost = async (uri, data, timeout = 60, fd = {}) => {
125
134
  return new Promise((resolve, reject) => {
126
135
  axios.post(uri, {
127
136
  ...data,
137
+ ...Cookies.get(),
128
138
  __stmp: new Date().getTime() / 1000
129
139
  }, {
130
140
  timeout: 1000 * timeout,
@@ -143,3 +153,13 @@ export const withPost = async (uri, data, timeout = 60, fd = {}) => {
143
153
  .catch(err => reject(err));
144
154
  });
145
155
  };
156
+ export const useDevice = () => {
157
+ const userAgent = navigator.userAgent;
158
+ const mobile = /Mobi|Android/i.test(userAgent);
159
+ const tablet = /Tablet|iPad/i.test(userAgent);
160
+ return {
161
+ isMobile: mobile,
162
+ isTablet: tablet,
163
+ isDesktop: !mobile && !tablet
164
+ };
165
+ };
@@ -267,6 +267,7 @@ export const cssDirect = {
267
267
  "rel": "position:relative;",
268
268
  "abs": "position:absolute;",
269
269
  "fixed": "position:fixed;",
270
+ "sticky": "position:sticky;",
270
271
  "abc": "top: 50%;left: 50%;transform: translate(-50%, -50%);",
271
272
  "tdn": "text-decoration:none;",
272
273
  "tdu": "text-decoration:underline;",
@@ -283,6 +284,10 @@ export const cssDirect = {
283
284
  "scale": "transform: scale(__VALUE__);",
284
285
  "anim": "transition: all __VALUE__ __CURVE__ __DELAY__;",
285
286
  "hide": "display: none;",
287
+ "block": "display: block;",
288
+ "inlineblock": "display: inline-block;",
289
+ "blur": "filter: blur(__VALUE__);",
290
+ "ratio": "aspect-ratio: __VALUE__;",
286
291
  };
287
292
  export const cssAnimationCurves = {
288
293
  ease: 'ease',
package/dist/index.d.ts CHANGED
@@ -6,8 +6,11 @@ export { default as ContextMenu } from "./comps/contextmenu";
6
6
  export { default as Cover } from "./comps/cover";
7
7
  export { default as Form } from "./comps/form";
8
8
  export { default as Heading } from "./comps/heading";
9
+ export { default as Text } from "./comps/heading";
9
10
  export { default as Icon } from "./comps/icon";
10
11
  export { default as Image } from "./comps/image";
11
12
  export { default as Input } from "./comps/input";
13
+ export { default as Select } from "./comps/select";
12
14
  export { default as Sheet } from "./comps/sheet";
13
15
  export { default as Spinner } from "./comps/spinner";
16
+ export { SHEET, FORMVALIDATION, FORMVALIDATION_STYLE, SPINNER, TRANSITIONS, TRANSITION_CURVES } from "./types/enums";
package/dist/index.js CHANGED
@@ -6,8 +6,11 @@ export { default as ContextMenu } from "./comps/contextmenu";
6
6
  export { default as Cover } from "./comps/cover";
7
7
  export { default as Form } from "./comps/form";
8
8
  export { default as Heading } from "./comps/heading";
9
+ export { default as Text } from "./comps/heading";
9
10
  export { default as Icon } from "./comps/icon";
10
11
  export { default as Image } from "./comps/image";
11
12
  export { default as Input } from "./comps/input";
13
+ export { default as Select } from "./comps/select";
12
14
  export { default as Sheet } from "./comps/sheet";
13
15
  export { default as Spinner } from "./comps/spinner";
16
+ export { SHEET, FORMVALIDATION, FORMVALIDATION_STYLE, SPINNER, TRANSITIONS, TRANSITION_CURVES } from "./types/enums";
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- button{user-select:none;cursor:pointer}input{user-select:none}input:-webkit-autofill{background-color:rgba(0,0,0,0) !important;-webkit-box-shadow:0 0 0px 1000px rgba(0,0,0,0) inset;box-shadow:0 0 0px 1000px rgba(0,0,0,0) inset}:root{--checkbox-checked: rgb(46, 161, 42);--checkbox-unchecked: rgb(203, 203, 203);--checkbox-thumb: #fff;--checkbox-thumb-shadow: #000;--checkbox-thumb-shadow-size: 2px}.flex{display:flex}.flex.cols{flex-direction:column}.flex.aic{align-items:center}.flex.jcc{justify-content:center}.abs{position:absolute}.fixed{position:fixed}.fill{top:0px;left:0px;bottom:0px;right:0px}.rel{position:relative}.input-with-error{box-shadow:inset 0px 0px 0px 1px #ff8b8b}.zuz-checkbox{height:25px;width:45px;cursor:pointer}.zuz-checkbox input[type=checkbox]{z-index:0;left:10px;top:10px;opacity:0}.zuz-checkbox:before{content:"";position:absolute;width:45px;height:25px;background:var(--checkbox-unchecked);border-radius:50px;z-index:1;transition:all .3s linear 0s}.zuz-checkbox:after{content:"";position:absolute;width:21px;height:21px;background:var(--checkbox-thumb);border-radius:50px;z-index:2;top:2px;left:2px;box-shadow:0px 0px --checkbox-thumb-shadow-size --checkbox-thumb-shadow;transition:all .2s linear 0s}.zuz-checkbox.is-checked:before{box-shadow:inset 0px 0px 0px 15px var(--checkbox-checked)}.zuz-checkbox.is-checked:after{transform:translateX(20px)}.zuz-spinner{animation:spin infinite}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.zuz-cover{backdrop-filter:blur(4px);z-index:99999;gap:15px}.zuz-cover .label{font-size:14px;animation:breath 1s linear infinite}@keyframes breath{0%{opacity:.5}50%{opacity:1}100%{opacity:.5}}.zuz-sheet{top:0px;left:50%;transform:translate(-50%, -10vh);z-index:2147483647;transition:all .5s cubic-bezier(0.68, -0.2, 0.27, 1.5) 0s}.zuz-sheet.toast-default{background:#333;color:#fff}.zuz-sheet.toast-error{background:#ff4747;color:#fff}.zuz-sheet.toast-success{background:#23ac28;color:#fff}.zuz-sheet.toast-warn{background:#ffba00}.zuz-sheet.is-visible{transform:translate(-50%, 0vh)}.zuz-sheet.is-visible.wobble{transform:translate(-50%, 10px);transition:all .5s cubic-bezier(0.68, -0.2, 0.27, 1.5) 0s}.zuz-sheet.zuz-toast{top:-20px;border-radius:0px 0px 5px 5px;padding:25px 15px 5px 15px;font-size:14px}.zuz-context-menu{z-index:99;background:var(--context-background);border-radius:var(--context-radius);padding:10px;box-shadow:var(--context-shadow)}.zuz-context-menu .context-line{height:1px;background:var(--context-seperator);margin:3px 6px}.zuz-context-menu .context-menu-item{width:220px;padding:6px 10px;gap:10px;cursor:pointer;font-size:var(--context-label-size);border-radius:var(--context-radius)}.zuz-context-menu .context-menu-item .ico{font-size:var(--context-icon-size)}.zuz-context-menu .context-menu-item:hover{background:var(--context-hover)}
1
+ *,*::before,*::after{box-sizing:border-box}button{user-select:none;cursor:pointer}input{user-select:none}input:-webkit-autofill{background-color:rgba(0,0,0,0) !important;-webkit-box-shadow:0 0 0px 1000px rgba(0,0,0,0) inset;box-shadow:0 0 0px 1000px rgba(0,0,0,0) inset}[popover]{margin:0;padding:0;border:0}:root{--checkbox-checked: rgb(46, 161, 42);--checkbox-unchecked: rgb(203, 203, 203);--checkbox-thumb: #fff;--checkbox-thumb-shadow: #000;--checkbox-thumb-shadow-size: 2px;--select: #fff;--select-options: #fff;--select-option-font-size: 16px;--select-hover: #eee;--select-selected: #ddd;--select-padding: 6px 8px;--select-radius: 5px;--cover-bg: rgba(255,255,255,0.8);--cover-label: #111;--dialog-bg: #fff;--dialog-radius: 10px;--dialog-padding: 10px;--dialog-title-font-size: 16px;--dialog-closer-font-size: 36px;--dialog-closer-hover: rgba(255,255,255,0.2)}.flex{display:flex}.flex.cols{flex-direction:column}.flex.aic{align-items:center}.flex.jcc{justify-content:center}.abs{position:absolute}.fixed{position:fixed}.fill{top:0px;left:0px;bottom:0px;right:0px}.fillx{top:-10px;left:-10px;bottom:-10px;right:-10px}.nope{pointer-events:none}.nous{user-select:none}.rel{position:relative}.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.input-with-error{box-shadow:inset 0px 0px 0px 1px #ff8b8b}.zuz-checkbox{height:25px;width:45px;cursor:pointer}.zuz-checkbox input[type=checkbox]{z-index:0;left:10px;top:10px;opacity:0}.zuz-checkbox:before{content:"";position:absolute;width:45px;height:25px;background:var(--checkbox-unchecked);border-radius:50px;z-index:1;transition:all .3s linear 0s}.zuz-checkbox:after{content:"";position:absolute;width:21px;height:21px;background:var(--checkbox-thumb);border-radius:50px;z-index:2;top:2px;left:2px;box-shadow:0px 0px --checkbox-thumb-shadow-size --checkbox-thumb-shadow;transition:all .2s linear 0s}.zuz-checkbox.is-checked:before{box-shadow:inset 0px 0px 0px 15px var(--checkbox-checked)}.zuz-checkbox.is-checked:after{transform:translateX(20px)}.zuz-spinner{animation:spin infinite}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.zuz-cover{backdrop-filter:blur(4px);z-index:99999;gap:15px}.zuz-cover .label{font-size:14px;animation:breath 1s linear infinite}@keyframes breath{0%{opacity:.5}50%{opacity:1}100%{opacity:.5}}.zuz-toast,.zuz-sheet.toast-warn,.zuz-sheet.toast-success,.zuz-sheet.toast-error,.zuz-sheet.toast-default{border-radius:6px;padding:6px 12px;font-size:14px;white-space:pre}.zuz-sheet{top:50%;left:50%;transform:translate(-50%, -50%);z-index:214748364;transform-origin:top left;transition:all .5s cubic-bezier(0.2, -0.36, 0, 1.46) 0s}.zuz-sheet.wobble{transform-origin:inherit !important}.zuz-sheet.toast-default{background:#333;color:#fff;top:10px !important}.zuz-sheet.toast-error{background:#ff4747;color:#fff;top:10px}.zuz-sheet.toast-success{background:#23ac28;color:#fff;top:10px}.zuz-sheet.toast-warn{background:#ffba00;top:10px}.zuz-sheet.toast-dialog{background:var(--dialog-bg);border-radius:var(--dialog-radius);padding:var(--dialog-padding);overflow:hidden}.zuz-sheet .zuz-sheet-head{margin-bottom:20px}.zuz-sheet .zuz-sheet-head .zuz-sheet-title{flex:1;font-size:var(--dialog-title-font-size);opacity:.5;text-align:center;padding:0px 45px}.zuz-sheet .zuz-sheet-head .zuz-sheet-dot{flex:1}.zuz-sheet .zuz-sheet-head .zuz-sheet-closer{width:32px;height:32px;cursor:pointer;font-size:var(--dialog-closer-font-size);background:rgba(0,0,0,0);border:0px;line-height:0;padding:0px;font-weight:normal;border-radius:20px;opacity:.35;top:50%;right:0px;transform:translateY(-50%)}.zuz-sheet .zuz-sheet-head .zuz-sheet-closer:hover{background:var(--dialog-closer-hover);opacity:1}.zuz-sheet-overlay{background:rgba(0,0,0,.7);z-index:111;backdrop-filter:blur(10px)}.zuz-context-menu{z-index:99;background:var(--context-background);border-radius:var(--context-radius);padding:10px;box-shadow:var(--context-shadow)}.zuz-context-menu .context-line{height:1px;background:var(--context-seperator);margin:3px 6px}.zuz-context-menu .context-menu-item{width:220px;padding:6px 10px;gap:10px;cursor:pointer;font-size:var(--context-label-size);border-radius:var(--context-radius)}.zuz-context-menu .context-menu-item .ico{font-size:var(--context-icon-size)}.zuz-context-menu .context-menu-item:hover{background:var(--context-hover)}.zuz-select{gap:5px;background:var(--select);border-radius:var(--select-radius)}.zuz-select .zuz-selected{flex:1}.zuz-select-options{max-height:400px;overflow-x:hidden;gap:2px;background:var(--select-options);border-radius:var(--select-radius);padding:4px 0px}.zuz-select-options button{background:rgba(0,0,0,0);border:0px;text-align:left;padding:var(--select-padding);border-radius:var(--select-radius);font-size:var(--select-option-font-size)}.zuz-select-options button:hover{background:var(--select-hover)}.zuz-select-options button.selected{background:var(--select-selected)}
@@ -12,8 +12,19 @@ export declare enum FORMVALIDATION {
12
12
  MatchField = "MATCHFIELD"
13
13
  }
14
14
  export declare enum SHEET {
15
+ Dialog = "DIALOG",
15
16
  Default = "DEFAULT",
16
17
  Error = "ERROR",
17
18
  Success = "SUCCESS",
18
19
  Warn = "WARN"
19
20
  }
21
+ export declare enum TRANSITION_CURVES {
22
+ Spring = "SPRING"
23
+ }
24
+ export declare enum TRANSITIONS {
25
+ ScaleIn = "SCALE_IN",
26
+ SlideInTop = "SLIDE_FROM_TOP",
27
+ SlideInRight = "SLIDE_FROM_RIGHT",
28
+ SlideInBottom = "SLIDE_FROM_BOTTOM",
29
+ SlideInLeft = "SLIDE_FROM_LEFT"
30
+ }
@@ -16,8 +16,21 @@ export var FORMVALIDATION;
16
16
  })(FORMVALIDATION || (FORMVALIDATION = {}));
17
17
  export var SHEET;
18
18
  (function (SHEET) {
19
+ SHEET["Dialog"] = "DIALOG";
19
20
  SHEET["Default"] = "DEFAULT";
20
21
  SHEET["Error"] = "ERROR";
21
22
  SHEET["Success"] = "SUCCESS";
22
23
  SHEET["Warn"] = "WARN";
23
24
  })(SHEET || (SHEET = {}));
25
+ export var TRANSITION_CURVES;
26
+ (function (TRANSITION_CURVES) {
27
+ TRANSITION_CURVES["Spring"] = "SPRING";
28
+ })(TRANSITION_CURVES || (TRANSITION_CURVES = {}));
29
+ export var TRANSITIONS;
30
+ (function (TRANSITIONS) {
31
+ TRANSITIONS["ScaleIn"] = "SCALE_IN";
32
+ TRANSITIONS["SlideInTop"] = "SLIDE_FROM_TOP";
33
+ TRANSITIONS["SlideInRight"] = "SLIDE_FROM_RIGHT";
34
+ TRANSITIONS["SlideInBottom"] = "SLIDE_FROM_BOTTOM";
35
+ TRANSITIONS["SlideInLeft"] = "SLIDE_FROM_LEFT";
36
+ })(TRANSITIONS || (TRANSITIONS = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/ui",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "keywords": [
5
5
  "react",
6
6
  "zuz",
@@ -37,6 +37,7 @@
37
37
  "chokidar": "^3.6.0",
38
38
  "commander": "^12.1.0",
39
39
  "hashids": "^2.3.0",
40
+ "js-cookie": "^3.0.5",
40
41
  "md5": "^2.3.0",
41
42
  "nanoid": "^5.0.7",
42
43
  "picocolors": "^1.0.1",