@homecode/ui 5.1.1 → 5.1.2

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.
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Component, createRef } from 'react';
2
+ import { Component, createRef, useState, useRef, useLayoutEffect } from 'react';
3
3
  import { createStore } from 'justorm/react';
4
4
  import Time from 'timen';
5
5
  import compare from 'compareq';
@@ -19,18 +19,60 @@ const DIR_NAME = {
19
19
  '1': 'left',
20
20
  '-1': 'right',
21
21
  };
22
+ function galleryStoreTarget(store) {
23
+ const o = store;
24
+ if (o.originalObject == null) {
25
+ throw new Error('Gallery: justorm store missing originalObject');
26
+ }
27
+ return o.originalObject;
28
+ }
22
29
  function getInitialState(items, startIndex) {
23
30
  return circularSlice(items, startIndex, 3);
24
31
  }
25
32
  function Arr({ className, size, icon, ...rest }) {
26
33
  return (jsx(Button, { className: cn(S.arr, className), size: size, variant: "clear", ...rest, children: jsx(Icon, { type: icon, size: size }) }));
27
34
  }
28
- function Item({ src, size, isLoaded, isError, onLoad, onError }) {
35
+ function Item({ src, size }) {
36
+ const [loaded, setLoaded] = useState(false);
37
+ const [isError, setIsError] = useState(false);
29
38
  const style = {};
30
- if (isLoaded)
39
+ const imgRef = useRef(null);
40
+ useLayoutEffect(() => {
41
+ const img = imgRef.current;
42
+ if (!img || isError)
43
+ return;
44
+ let cancelled = false;
45
+ const notify = () => {
46
+ if (!cancelled)
47
+ setLoaded(true);
48
+ };
49
+ // Cached images may never fire `load` after mount; `decode()` covers that path.
50
+ if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) {
51
+ notify();
52
+ return () => {
53
+ cancelled = true;
54
+ };
55
+ }
56
+ if (typeof img.decode === 'function') {
57
+ img.decode().then(notify).catch(() => { });
58
+ return () => {
59
+ cancelled = true;
60
+ };
61
+ }
62
+ requestAnimationFrame(() => {
63
+ if (!cancelled &&
64
+ img.complete &&
65
+ (img.naturalWidth > 0 || img.naturalHeight > 0))
66
+ notify();
67
+ });
68
+ return () => {
69
+ cancelled = true;
70
+ };
71
+ }, [src, isError]);
72
+ if (loaded)
31
73
  style.backgroundImage = `url(${src})`;
32
- return (jsx("div", { className: S.item, style: style, children: !isLoaded &&
33
- (isError ? (jsx(Icon, { type: "brokenImage", className: S.brokenImage })) : (jsxs(Fragment, { children: [jsx("img", { src: src, onLoad: onLoad, onError: onError }), jsx(Spinner, { size: size })] }))) }));
74
+ return (jsx("div", { className: S.item, style: style, children: !loaded &&
75
+ (isError ? (jsx(Icon, { type: "brokenImage", className: S.brokenImage })) : (jsxs(Fragment, { children: [jsx("img", { ref: imgRef, src: src, onLoad: () => setLoaded(true), onError: () => setIsError(true) }), jsx(Spinner, { size: size })] }))) }));
34
76
  }
35
77
  class Gallery extends Component {
36
78
  store;
@@ -46,14 +88,12 @@ class Gallery extends Component {
46
88
  };
47
89
  constructor(props) {
48
90
  super(props);
49
- const { startIndex, items } = props;
91
+ const { startIndex } = props;
50
92
  this.recenter();
51
93
  this.index = startIndex;
52
94
  this.store = createStore(this, {
53
95
  items: this.getStateItems(),
54
96
  movingDirection: 0,
55
- loading: {},
56
- errors: {},
57
97
  isDragging: false,
58
98
  });
59
99
  }
@@ -69,7 +109,9 @@ class Gallery extends Component {
69
109
  !compare(prevProps.items, items)) {
70
110
  this.index = startIndex;
71
111
  this.recenter();
72
- this.store.items = this.getStateItems();
112
+ const next = this.getStateItems();
113
+ Object.assign(galleryStoreTarget(this.store), { items: next });
114
+ this.setState({});
73
115
  }
74
116
  }
75
117
  getStateItems() {
@@ -144,20 +186,20 @@ class Gallery extends Component {
144
186
  }, DURATION);
145
187
  switch(direction) {
146
188
  this.index += direction * -1;
147
- this.store.items = circularSlice(this.items, this.index, 3);
148
- this.store.movingDirection = 0;
189
+ const nextItems = circularSlice(this.items, this.index, 3);
190
+ // justorm v3: proxy set skips when compareq sees no change; bypass via originalObject.
191
+ Object.assign(galleryStoreTarget(this.store), {
192
+ items: nextItems,
193
+ movingDirection: 0,
194
+ });
149
195
  this.removeTransformDelta();
196
+ this.setState({});
150
197
  const { onChange } = this.props;
151
- const { items, loading } = this.store;
152
198
  onChange?.(this.index, this.items[this.index]);
153
- items.forEach(src => {
154
- if (typeof loading[src] !== 'boolean')
155
- loading[src] = false;
156
- });
157
199
  }
158
200
  render() {
159
201
  const { className, size, showArrows, showDots, initialBounce, cover, ...rest } = this.props;
160
- const { items, movingDirection, loading, errors, isDragging } = this.store;
202
+ const { items, movingDirection, isDragging } = this.store;
161
203
  const dirName = DIR_NAME[movingDirection];
162
204
  const isSingle = this.isSingle();
163
205
  const props = omit(rest, ['items', 'onChange', 'animation', 'startIndex']);
@@ -171,7 +213,7 @@ class Gallery extends Component {
171
213
  props.onPointerLeave = this.onPointerUp;
172
214
  }
173
215
  }
174
- return (jsxs("div", { className: classes, ...props, children: [jsx("div", { className: innerClasses, ref: this.innerRef, children: items.map((src, i) => (jsx(Item, { src: src, size: size, isLoaded: loading[src], isError: errors[src], onLoad: () => (loading[src] = true), onError: () => (errors[src] = true) }, `${i}_${src}`))) }), !isSingle && showArrows && !isDragging && (jsxs(Fragment, { children: [jsx(Arr, { className: S.left, size: size, icon: "chevronLeft", onClick: () => this.move(1) }), jsx(Arr, { className: S.right, size: size, icon: "chevronRight", onClick: () => this.move(-1) })] })), showDots && (jsx(Lazy, { hideSpinner: true, loader: () => import('./Dots/Dots.js'),
216
+ return (jsxs("div", { className: classes, ...props, children: [jsx("div", { className: innerClasses, ref: this.innerRef, children: items.map((src, i) => (jsx(Item, { src: src, size: size }, `${i}_${src}`))) }), !isSingle && showArrows && !isDragging && (jsxs(Fragment, { children: [jsx(Arr, { className: S.left, size: size, icon: "chevronLeft", onClick: () => this.move(1) }), jsx(Arr, { className: S.right, size: size, icon: "chevronRight", onClick: () => this.move(-1) })] })), showDots && (jsx(Lazy, { hideSpinner: true, loader: () => import('./Dots/Dots.js'),
175
217
  // @ts-ignore
176
218
  index: this.index % items.length, count: items.length }))] }));
177
219
  }
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".Gallery_item__P4qTJ,.Gallery_root__-Crit{height:100%;width:100%}.Gallery_root__-Crit{overflow:hidden;position:relative}.Gallery_inner__4FAPt{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;height:100%;position:absolute;touch-action:none;transform:translate3d(-33.33333%,0,0);width:calc(300% + 1px)}.Gallery_single__Wfd9h .Gallery_inner__4FAPt{transform:none;width:100%}.Gallery_single__Wfd9h .Gallery_item__P4qTJ{width:100%}.Gallery_inner__4FAPt.Gallery_left__zrrmv,.Gallery_inner__4FAPt.Gallery_right__dpZ-m{transition:transform 0s ease-out;transition-duration:.2s}.Gallery_inner__4FAPt.Gallery_left__zrrmv{transform:translateZ(0)!important}.Gallery_inner__4FAPt.Gallery_right__dpZ-m{transform:translate3d(-66.66667%,0,0)!important}.Gallery_inner__4FAPt.Gallery_initialBounce__nZnKd{animation:Gallery_bounce__buqva 1s ease-out}.Gallery_item__P4qTJ{align-items:center;background-position:50%;background-repeat:no-repeat;background-size:contain;display:flex;justify-content:center;width:33.33333%}.Gallery_cover__ZGx5X .Gallery_item__P4qTJ{background-size:cover}.Gallery_item__P4qTJ>img{opacity:0;pointer-events:none;position:absolute}.Gallery_brokenImage__Bj3O-{height:50%;opacity:.2;width:50%}.Gallery_arr__knicI{background:transparent!important;height:100%;min-height:100%;opacity:0;padding:10%;position:absolute;top:0;transition:opacity .1s ease-out}.Gallery_arr__knicI.Gallery_left__zrrmv{justify-content:flex-start;left:0}.Gallery_arr__knicI.Gallery_right__dpZ-m{justify-content:flex-end;right:0;width:77%}.Gallery_arr__knicI:hover{opacity:1}@keyframes Gallery_bounce__buqva{0%{left:0}50%{left:-20%}80%{left:10%}to{left:0}}";
3
+ var css_248z = ".Gallery_item__P4qTJ,.Gallery_root__-Crit{height:100%;width:100%}.Gallery_root__-Crit{overflow:hidden;position:relative}.Gallery_inner__4FAPt{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:flex;height:100%;position:absolute;touch-action:none;transform:translate3d(-33.33333%,0,0);width:calc(300% + 1px)}.Gallery_single__Wfd9h .Gallery_inner__4FAPt{transform:none;width:100%}.Gallery_single__Wfd9h .Gallery_item__P4qTJ{width:100%}.Gallery_inner__4FAPt.Gallery_left__zrrmv,.Gallery_inner__4FAPt.Gallery_right__dpZ-m{transition:transform 0s ease-out;transition-duration:.2s}.Gallery_inner__4FAPt.Gallery_left__zrrmv{transform:translateZ(0)!important}.Gallery_inner__4FAPt.Gallery_right__dpZ-m{transform:translate3d(-66.66667%,0,0)!important}.Gallery_inner__4FAPt.Gallery_initialBounce__nZnKd{animation:Gallery_bounce__buqva 1s ease-out}.Gallery_item__P4qTJ{align-items:center;background-position:50%;background-repeat:no-repeat;background-size:contain;display:flex;justify-content:center;width:33.33333%}.Gallery_cover__ZGx5X .Gallery_item__P4qTJ{background-size:cover}.Gallery_item__P4qTJ>img{opacity:0;pointer-events:none;position:absolute}.Gallery_brokenImage__Bj3O-{height:50%;opacity:.2;width:50%}.Gallery_arr__knicI{background:transparent!important;height:100%;min-height:100%;opacity:0;padding:10%;position:absolute;top:0;transition:opacity .1s ease-out;z-index:1}.Gallery_arr__knicI.Gallery_left__zrrmv{justify-content:flex-start;left:0}.Gallery_arr__knicI.Gallery_right__dpZ-m{justify-content:flex-end;right:0;width:77%}.Gallery_arr__knicI:hover{opacity:1}@keyframes Gallery_bounce__buqva{0%{left:0}50%{left:-20%}80%{left:10%}to{left:0}}";
4
4
  var S = {"root":"Gallery_root__-Crit","item":"Gallery_item__P4qTJ","inner":"Gallery_inner__4FAPt","single":"Gallery_single__Wfd9h","left":"Gallery_left__zrrmv","right":"Gallery_right__dpZ-m","initialBounce":"Gallery_initialBounce__nZnKd","bounce":"Gallery_bounce__buqva","cover":"Gallery_cover__ZGx5X","brokenImage":"Gallery_brokenImage__Bj3O-","arr":"Gallery_arr__knicI"};
5
5
  styleInject(css_248z);
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "5.1.1",
3
+ "version": "5.1.2",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "tests": "jest",