@zuzjs/ui 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, useEffect, useMemo, useReducer, useCallback, useContext, forwardRef, useRef, useState, useLayoutEffect, useDebugValue, cloneElement, useImperativeHandle, createElement } from 'react';
1
+ import { createContext, useEffect, useMemo, useReducer, useCallback, useContext, forwardRef, useRef, useState, useLayoutEffect, useDebugValue, cloneElement, useImperativeHandle, createElement, Component as Component$1, Children as Children$1 } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import PropTypes from 'prop-types';
4
4
  import Children from 'react-children-utilities';
@@ -59,16 +59,16 @@ class AppTheme {
59
59
  _AppTheme_darkTheme.set(this, void 0);
60
60
  this.get = () => {
61
61
  let self = this;
62
- if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "auto") {
63
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
64
- __classPrivateFieldSet(self, _AppTheme_mode, event.matches ? "dark" : "light", "f");
65
- __classPrivateFieldGet(self, _AppTheme_listen, "f").call(self, __classPrivateFieldGet(self, _AppTheme_mode, "f"));
66
- });
67
- return window.matchMedia &&
68
- window.matchMedia('(prefers-color-scheme: dark)').matches ?
69
- __classPrivateFieldGet(self, _AppTheme_darkTheme, "f") : __classPrivateFieldGet(self, _AppTheme_lightTheme, "f");
70
- }
71
- else if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "light") {
62
+ // if(self.#mode === "auto"){
63
+ // window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
64
+ // self.#mode = event.matches ? "dark" : "light";
65
+ // self.#listen(self.#mode);
66
+ // });
67
+ // return window.matchMedia &&
68
+ // window.matchMedia('(prefers-color-scheme: dark)').matches ?
69
+ // self.#darkTheme : self.#lightTheme;
70
+ // }else
71
+ if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "light") {
72
72
  return __classPrivateFieldGet(self, _AppTheme_lightTheme, "f");
73
73
  }
74
74
  else if (__classPrivateFieldGet(self, _AppTheme_mode, "f") === "dark") {
@@ -556,7 +556,7 @@ const UPDATE_FORM_FIELD = (formName, field, value, forms) => {
556
556
  };
557
557
 
558
558
  const Input = forwardRef((props, ref) => {
559
- const { as, accept, multiple, onChange, type, tag, placeholder, name, form, touched, onSubmit, defaultValue, fref } = props;
559
+ const { as, accept, multiple, onChange, onKeyUp, type, tag, placeholder, name, form, touched, onSubmit, defaultValue, fref } = props;
560
560
  const dispatch = useDispatch(STORE_FORM_KEY);
561
561
  const { forms } = useStore(state => state[STORE_FORM_KEY], false);
562
562
  let Tag = tag || 'input';
@@ -1343,6 +1343,131 @@ const Image = forwardRef((props, ref) => {
1343
1343
  return (jsx(ClassNames, { children: ({ css, cx }) => jsxs("picture", Object.assign({ className: cx(css `${buildCSS({ flex: true })}`) }, { children: [status == 'loading' && jsx(Box, { className: `${props.as ? `${props.as} ` : ``}${cx(css `background: #eee;${buildCSS(props)}`)}` }), status == 'loaded' && jsx("img", { src: props.src, className: `${props.as ? `${props.as} ` : ``}${cx(css `${buildCSS(props)}`)}`, ref: ref })] })) }));
1344
1344
  });
1345
1345
 
1346
+ const DEFAULT_COLUMNS = 2;
1347
+ class Masonry extends Component$1 {
1348
+ constructor(props) {
1349
+ super(props);
1350
+ this._lastRecalculateAnimationFrame = window.requestAnimationFrame(() => {
1351
+ this.reCalculateColumnCount();
1352
+ });
1353
+ // Correct scope for when methods are accessed externally
1354
+ this.reCalculateColumnCount = this.reCalculateColumnCount.bind(this);
1355
+ this.reCalculateColumnCountDebounce = this.reCalculateColumnCountDebounce.bind(this);
1356
+ // default state
1357
+ let columnCount;
1358
+ if (this.props && this.props.breakpointCols.default) {
1359
+ columnCount = this.props.breakpointCols.default;
1360
+ }
1361
+ else {
1362
+ columnCount = parseInt(this.props.breakpointCols) || DEFAULT_COLUMNS;
1363
+ }
1364
+ this.state = {
1365
+ columnCount
1366
+ };
1367
+ }
1368
+ componentDidMount() {
1369
+ this.reCalculateColumnCount();
1370
+ // window may not be available in some environments
1371
+ if (window) {
1372
+ window.addEventListener('resize', this.reCalculateColumnCountDebounce);
1373
+ }
1374
+ }
1375
+ componentDidUpdate() {
1376
+ this.reCalculateColumnCount();
1377
+ }
1378
+ componentWillUnmount() {
1379
+ if (window) {
1380
+ window.removeEventListener('resize', this.reCalculateColumnCountDebounce);
1381
+ }
1382
+ }
1383
+ reCalculateColumnCountDebounce() {
1384
+ if (!window || !window.requestAnimationFrame) { // IE10+
1385
+ this.reCalculateColumnCount();
1386
+ return;
1387
+ }
1388
+ if (window.cancelAnimationFrame) { // IE10+
1389
+ window.cancelAnimationFrame(this._lastRecalculateAnimationFrame);
1390
+ }
1391
+ }
1392
+ reCalculateColumnCount() {
1393
+ const windowWidth = window && window.innerWidth || Infinity;
1394
+ let breakpointColsObject = this.props.breakpointCols;
1395
+ // Allow passing a single number to `breakpointCols` instead of an object
1396
+ if (typeof breakpointColsObject !== 'object') {
1397
+ breakpointColsObject = {
1398
+ default: parseInt(breakpointColsObject) || DEFAULT_COLUMNS
1399
+ };
1400
+ }
1401
+ let matchedBreakpoint = Infinity;
1402
+ let columns = breakpointColsObject.default || DEFAULT_COLUMNS;
1403
+ for (let breakpoint in breakpointColsObject) {
1404
+ const optBreakpoint = parseInt(breakpoint);
1405
+ const isCurrentBreakpoint = optBreakpoint > 0 && windowWidth <= optBreakpoint;
1406
+ if (isCurrentBreakpoint && optBreakpoint < matchedBreakpoint) {
1407
+ matchedBreakpoint = optBreakpoint;
1408
+ columns = breakpointColsObject[breakpoint];
1409
+ }
1410
+ }
1411
+ columns = Math.max(1, parseInt(columns) || 1);
1412
+ if (this.state.columnCount !== columns) {
1413
+ this.setState({
1414
+ columnCount: columns
1415
+ });
1416
+ this.props.onChange && this.props.onChange({ columns: columns });
1417
+ }
1418
+ }
1419
+ itemsInColumns() {
1420
+ const currentColumnCount = this.state.columnCount;
1421
+ const itemsInColumns = new Array(currentColumnCount);
1422
+ // Force children to be handled as an array
1423
+ const items = Children$1.toArray(this.props.children);
1424
+ for (let i = 0; i < items.length; i++) {
1425
+ const columnIndex = i % currentColumnCount;
1426
+ if (!itemsInColumns[columnIndex]) {
1427
+ itemsInColumns[columnIndex] = [];
1428
+ }
1429
+ itemsInColumns[columnIndex].push(items[i]);
1430
+ }
1431
+ return itemsInColumns;
1432
+ }
1433
+ renderColumns() {
1434
+ const { column, columnAttrs = {}, columnClassName } = this.props;
1435
+ const childrenInColumns = this.itemsInColumns();
1436
+ const columnWidth = `${100 / childrenInColumns.length}%`;
1437
+ let className = columnClassName;
1438
+ if (className && typeof className !== 'string') {
1439
+ this.logDeprecated('The property "columnClassName" requires a string');
1440
+ // This is a deprecated default and will be removed soon.
1441
+ if (typeof className === 'undefined') {
1442
+ className = 'my-masonry-grid_column';
1443
+ }
1444
+ }
1445
+ const columnAttributes = Object.assign(Object.assign(Object.assign({}, column), columnAttrs), { style: Object.assign(Object.assign({}, columnAttrs.style), { width: columnWidth }), className });
1446
+ return childrenInColumns.map((items, i) => {
1447
+ return createElement("div", Object.assign({}, columnAttributes, { key: i }), items);
1448
+ });
1449
+ }
1450
+ logDeprecated(message) {
1451
+ console.error('[Masonry]', message);
1452
+ }
1453
+ render() {
1454
+ const _a = this.props, {
1455
+ // ignored
1456
+ children, breakpointCols, columnClassName, columnAttrs, column,
1457
+ // used
1458
+ className } = _a, rest = __rest(_a, ["children", "breakpointCols", "columnClassName", "columnAttrs", "column", "className"]);
1459
+ let classNameOutput = className;
1460
+ if (typeof className !== 'string') {
1461
+ this.logDeprecated('The property "className" requires a string');
1462
+ // This is a deprecated default and will be removed soon.
1463
+ if (typeof className === 'undefined') {
1464
+ classNameOutput = 'my-masonry-grid';
1465
+ }
1466
+ }
1467
+ return (jsx("div", Object.assign({}, rest, { className: classNameOutput }, { children: this.renderColumns() })));
1468
+ }
1469
+ }
1470
+
1346
1471
  const calcPlaceholderStyle = (width, height, duration = 1600) => ({
1347
1472
  backgroundSize: `${parseInt(width.toString()) * 10}px ${height}px`,
1348
1473
  animationDuration: `${(duration / 1000).toFixed(1)}s`,
@@ -1423,4 +1548,4 @@ const Header = forwardRef((props, ref) => {
1423
1548
  return (jsx(Fragment, { children: buildComponent(data) }));
1424
1549
  });
1425
1550
 
1426
- 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, generateModalRoutes, generatePreservedRoutes, generateRegularRoutes, getCookie, getUriParams, grab, isEmail, isIPv4, isUrl, randstr, removeCookie, rgb2hex, setCSSVar, setCookie, shuffleArray, ucfirst, useDevice, useDispatch, useImage, useResizeObserver, useStore, useTheme, useToast, uuid };
1551
+ export { App, Component as Block, Box, Button, Checkbox, ContextMenu, Cover, Form, Header, Heading, Icon, Image, Input, Masonry, Placeholder, AppProvider as Provider, Select, Spacer, Spinner, Text, Toaster, Tweet, addProps, addScript, buildCSS, buildFormData, byId, byName, createSlice, el, filterHTMLProps, filterStyleProps, generateModalRoutes, generatePreservedRoutes, generateRegularRoutes, getCookie, getUriParams, grab, isEmail, isIPv4, isUrl, randstr, removeCookie, rgb2hex, setCSSVar, setCookie, shuffleArray, ucfirst, useDevice, useDispatch, useImage, useResizeObserver, useStore, useTheme, useToast, uuid };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/ui",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -0,0 +1,192 @@
1
+ import { Component, Children } from "react"
2
+ import PropTypes from 'prop-types'
3
+
4
+ const DEFAULT_COLUMNS = 2;
5
+
6
+ class Masonry extends Component<any, any> {
7
+
8
+ constructor(props : { [ key: string ] : any }) {
9
+ super(props);
10
+ // Correct scope for when methods are accessed externally
11
+ this.reCalculateColumnCount = this.reCalculateColumnCount.bind(this);
12
+ this.reCalculateColumnCountDebounce = this.reCalculateColumnCountDebounce.bind(this);
13
+ // default state
14
+ let columnCount
15
+ if (this.props && this.props.breakpointCols.default) {
16
+ columnCount = this.props.breakpointCols.default
17
+ } else {
18
+ columnCount = parseInt(this.props.breakpointCols) || DEFAULT_COLUMNS
19
+ }
20
+ this.state = {
21
+ columnCount
22
+ };
23
+ }
24
+
25
+ componentDidMount() {
26
+ this.reCalculateColumnCount();
27
+ // window may not be available in some environments
28
+ if(window) {
29
+ window.addEventListener('resize', this.reCalculateColumnCountDebounce);
30
+ }
31
+ }
32
+
33
+ componentDidUpdate() {
34
+ this.reCalculateColumnCount();
35
+ }
36
+
37
+ componentWillUnmount() {
38
+ if(window) {
39
+ window.removeEventListener('resize', this.reCalculateColumnCountDebounce);
40
+ }
41
+ }
42
+
43
+ reCalculateColumnCountDebounce() {
44
+ if(!window || !window.requestAnimationFrame) { // IE10+
45
+ this.reCalculateColumnCount();
46
+ return;
47
+ }
48
+
49
+ if(window.cancelAnimationFrame) { // IE10+
50
+ window.cancelAnimationFrame(this._lastRecalculateAnimationFrame);
51
+ }
52
+
53
+ }
54
+
55
+ _lastRecalculateAnimationFrame = window.requestAnimationFrame(() => {
56
+ this.reCalculateColumnCount();
57
+ });
58
+
59
+ reCalculateColumnCount() {
60
+ const windowWidth = window && window.innerWidth || Infinity;
61
+ let breakpointColsObject = this.props.breakpointCols;
62
+
63
+ // Allow passing a single number to `breakpointCols` instead of an object
64
+ if(typeof breakpointColsObject !== 'object') {
65
+ breakpointColsObject = {
66
+ default: parseInt(breakpointColsObject) || DEFAULT_COLUMNS
67
+ }
68
+ }
69
+
70
+ let matchedBreakpoint = Infinity;
71
+ let columns = breakpointColsObject.default || DEFAULT_COLUMNS;
72
+
73
+ for(let breakpoint in breakpointColsObject) {
74
+ const optBreakpoint = parseInt(breakpoint);
75
+ const isCurrentBreakpoint = optBreakpoint > 0 && windowWidth <= optBreakpoint;
76
+
77
+ if(isCurrentBreakpoint && optBreakpoint < matchedBreakpoint) {
78
+ matchedBreakpoint = optBreakpoint;
79
+ columns = breakpointColsObject[breakpoint];
80
+ }
81
+ }
82
+
83
+ columns = Math.max(1, parseInt(columns) || 1);
84
+
85
+ if(this.state.columnCount !== columns) {
86
+ this.setState({
87
+ columnCount: columns
88
+ });
89
+ this.props.onChange && this.props.onChange({ columns: columns });
90
+ }
91
+ }
92
+
93
+ itemsInColumns() {
94
+ const currentColumnCount = this.state.columnCount;
95
+ const itemsInColumns = new Array(currentColumnCount);
96
+
97
+ // Force children to be handled as an array
98
+ const items = Children.toArray(this.props.children)
99
+
100
+ for (let i = 0; i < items.length; i++) {
101
+ const columnIndex = i % currentColumnCount;
102
+
103
+ if(!itemsInColumns[columnIndex]) {
104
+ itemsInColumns[columnIndex] = [];
105
+ }
106
+
107
+ itemsInColumns[columnIndex].push(items[i]);
108
+ }
109
+
110
+ return itemsInColumns;
111
+ }
112
+
113
+ renderColumns() {
114
+ const { column, columnAttrs = {}, columnClassName } = this.props;
115
+ const childrenInColumns = this.itemsInColumns();
116
+ const columnWidth = `${100 / childrenInColumns.length}%`;
117
+ let className = columnClassName;
118
+
119
+ if(className && typeof className !== 'string') {
120
+ this.logDeprecated('The property "columnClassName" requires a string');
121
+
122
+ // This is a deprecated default and will be removed soon.
123
+ if(typeof className === 'undefined') {
124
+ className = 'my-masonry-grid_column';
125
+ }
126
+ }
127
+
128
+ const columnAttributes = {
129
+ // NOTE: the column property is undocumented and considered deprecated.
130
+ // It is an alias of the `columnAttrs` property
131
+ ...column,
132
+ ...columnAttrs,
133
+ style: {
134
+ ...columnAttrs.style,
135
+ width: columnWidth
136
+ },
137
+ className
138
+ };
139
+
140
+ return childrenInColumns.map((items, i) => {
141
+ return <div
142
+ {...columnAttributes}
143
+
144
+ key={i}
145
+ >
146
+ {items}
147
+ </div>;
148
+ });
149
+ }
150
+
151
+ logDeprecated(message) {
152
+ console.error('[Masonry]', message);
153
+ }
154
+
155
+ render() {
156
+ const {
157
+ // ignored
158
+ children,
159
+ breakpointCols,
160
+ columnClassName,
161
+ columnAttrs,
162
+ column,
163
+
164
+ // used
165
+ className,
166
+
167
+ ...rest
168
+ } = this.props;
169
+
170
+ let classNameOutput = className;
171
+
172
+ if(typeof className !== 'string') {
173
+ this.logDeprecated('The property "className" requires a string');
174
+
175
+ // This is a deprecated default and will be removed soon.
176
+ if(typeof className === 'undefined') {
177
+ classNameOutput = 'my-masonry-grid';
178
+ }
179
+ }
180
+
181
+ return (
182
+ <div
183
+ {...rest}
184
+ className={classNameOutput}
185
+ >
186
+ {this.renderColumns()}
187
+ </div>
188
+ );
189
+ }
190
+ }
191
+
192
+ export default Masonry;
@@ -31,15 +31,16 @@ class AppTheme {
31
31
 
32
32
  get = () => {
33
33
  let self = this;
34
- if(self.#mode === "auto"){
35
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
36
- self.#mode = event.matches ? "dark" : "light";
37
- self.#listen(self.#mode);
38
- });
39
- return window.matchMedia &&
40
- window.matchMedia('(prefers-color-scheme: dark)').matches ?
41
- self.#darkTheme : self.#lightTheme;
42
- }else if(self.#mode === "light"){
34
+ // if(self.#mode === "auto"){
35
+ // window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
36
+ // self.#mode = event.matches ? "dark" : "light";
37
+ // self.#listen(self.#mode);
38
+ // });
39
+ // return window.matchMedia &&
40
+ // window.matchMedia('(prefers-color-scheme: dark)').matches ?
41
+ // self.#darkTheme : self.#lightTheme;
42
+ // }else
43
+ if(self.#mode === "light"){
43
44
  return self.#lightTheme;
44
45
  }else if(self.#mode === "dark"){
45
46
  return self.#darkTheme;
@@ -1,4 +1,4 @@
1
- import { useContext } from 'react'
1
+ import { useContext, useEffect } from 'react'
2
2
  import AppContext from '../context'
3
3
 
4
4
  const useTheme = (mod = 'auto') => {
package/src/index.tsx CHANGED
@@ -15,6 +15,7 @@ export { default as Heading } from './comps/heading'
15
15
  export { default as Icon } from './comps/icon'
16
16
  export { default as Input } from './comps/input'
17
17
  export { default as Image } from './comps/image'
18
+ export { default as Masonry } from './comps/masonry'
18
19
  export { default as Placeholder } from './comps/placeholder'
19
20
  export { default as Toaster } from './comps/toaster'
20
21
  export { default as Select } from './comps/select'