brew-js-react 0.5.7 → 0.6.1

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/hooks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createElement, useEffect, useMemo, useRef, useState } from "react";
2
- import { ViewStateProvider, useMemoizedFunction, useObservableProperty, useUpdateTrigger } from "zeta-dom-react";
2
+ import { ViewStateProvider, useMemoizedFunction, useObservableProperty, useValueTrigger } from "zeta-dom-react";
3
3
  import { catchAsync, definePrototype, delay, each, equal, extend, freeze, isFunction, isPlainObject, keys, kv, mapObject, throwNotFunction } from "zeta-dom/util";
4
4
  import { ZetaEventContainer } from "zeta-dom/events";
5
5
  import { getQueryParam, setQueryParam } from "brew-js/util/common";
@@ -84,20 +84,15 @@ export function useRouteParam(name, defaultValue) {
84
84
  const container = useViewContext();
85
85
  const params = container.page.params;
86
86
  const value = params[name] || '';
87
- const ref = useRef(value);
88
- const forceUpdate = useUpdateTrigger();
87
+ const notifyChange = useValueTrigger(value);
89
88
  useEffect(function () {
90
89
  var setValue = function () {
91
- var current = container.page.params[name] || '';
92
- if (current !== ref.current) {
93
- forceUpdate();
94
- }
90
+ notifyChange(container.page.params[name] || '');
95
91
  };
96
92
  // route parameter might be changed after state initialization and before useEffect hook is called
97
93
  setValue();
98
94
  return container.on('pagechange', setValue);
99
95
  }, [name]);
100
- ref.current = value;
101
96
  if (defaultValue && container.active && (!value || (name === 'remainingSegments' && value === '/'))) {
102
97
  app.navigate(app.route.getPath(extend({}, params, kv(name, defaultValue))), true);
103
98
  }
@@ -129,22 +124,20 @@ export function useQueryParam(key, value, snapshotOnUpdate) {
129
124
  }
130
125
  var container = useViewContext();
131
126
  var getParams = function () {
132
- return mapObject(key === false ? value : kv(key, value), function (v, i) {
127
+ return freeze(mapObject(key === false ? value : kv(key, value), function (v, i) {
133
128
  return getQueryParam(i, app.path) || v || '';
134
- });
129
+ }));
135
130
  };
136
- var state = useState([]);
131
+ var ref = useRef({});
137
132
  useMemo(function () {
138
- state[0].splice(0, 2, getParams());
133
+ ref.current = getParams();
139
134
  }, [key]);
140
- var current = state[0][0];
141
- var trackChanges = function (values) {
142
- if (!equal(values, current)) {
143
- extend(current, values);
144
- state[1]([current]);
145
- }
146
- };
135
+ var current = ref.current;
136
+ var notifyChange = useValueTrigger(current, function (current, params) {
137
+ return equal(current, params) || !(ref.current = params);
138
+ });
147
139
  var setParams = useMemoizedFunction(function (values) {
140
+ var current = ref.current;
148
141
  if (key !== false) {
149
142
  values = kv(key, isFunction(values) ? values(current[key]) : values);
150
143
  } else if (isFunction(values)) {
@@ -159,19 +152,19 @@ export function useQueryParam(key, value, snapshotOnUpdate) {
159
152
  if (snapshotOnUpdate) {
160
153
  app.snapshot();
161
154
  }
162
- catchAsync(app.navigate(search + url.hash, true));
163
- trackChanges(getParams());
155
+ catchAsync(app.navigate((search || '?') + url.hash, true));
156
+ notifyChange(getParams());
164
157
  }
165
158
  }
166
159
  });
167
160
  useEffect(function () {
168
161
  return app.watch('path', function () {
169
162
  if (container.active) {
170
- trackChanges(getParams());
163
+ notifyChange(getParams());
171
164
  }
172
165
  });
173
166
  }, [key]);
174
- return [key !== false ? current[key] : (state[0][1] || (state[0][1] = freeze(extend({}, current)))), setParams];
167
+ return [key !== false ? current[key] : current, setParams];
175
168
  }
176
169
 
177
170
  export function ViewStateContainer(props) {
package/mixin.d.ts CHANGED
@@ -56,7 +56,7 @@ export function useScrollIntoViewMixin(): ScrollIntoViewMixin;
56
56
  * Returns a mixin that provides methods controlling the applied element as a flyout.
57
57
  * @param options A dictionary specifying options.
58
58
  */
59
- export function useFlyoutMixin(options?: FlyoutMixinOptions): FlyoutMixin;
59
+ export function useFlyoutMixin<S = any, R = any>(options?: FlyoutMixinOptions): FlyoutMixin<S, R>;
60
60
 
61
61
  /**
62
62
  * Returns a mixin that enables intro and/or outro animation for applied elements.
@@ -31,9 +31,9 @@ definePrototype(AnimateSequenceMixin, AnimateMixin, {
31
31
  var self = this;
32
32
  AnimateSequenceMixinSuper.initElement.call(self, element, state);
33
33
  if (self.selector) {
34
- self.onDispose(watchElements(element, self.selector, function (addedNodes) {
34
+ state.onDispose(watchElements(element, self.selector, function (addedNodes) {
35
35
  $(addedNodes).attr('is-animate-sequence', '');
36
- }));
36
+ }).dispose);
37
37
  }
38
38
  }
39
39
  });
@@ -21,18 +21,13 @@ export default function ClassNameMixin(classNames) {
21
21
  }
22
22
 
23
23
  definePrototype(ClassNameMixin, StatefulMixin, {
24
- initState: function () {
25
- return {
26
- element: null,
27
- classNames: fill(this.classNames, false)
28
- };
29
- },
30
24
  initElement: function (element, state) {
31
25
  var self = this;
26
+ state.classNames = fill(self.classNames, false);
32
27
  checkState(self, element, state);
33
- watchOwnAttributes(element, 'class', function () {
28
+ state.onDispose(watchOwnAttributes(element, 'class', function () {
34
29
  checkState(self, element, state, true);
35
- });
30
+ }).dispose);
36
31
  },
37
32
  onLayoutEffect: function (element, state) {
38
33
  setClass(element, state.classNames);
@@ -4,6 +4,8 @@ import Mixin from "./Mixin";
4
4
  import { AnimationEffect } from "./AnimateMixin";
5
5
  import { useFlyoutMixin } from "../mixin";
6
6
 
7
+ export type HintedType<T> = T | {} | number | string | boolean | symbol | bigint | null | undefined;
8
+
7
9
  export interface FlyoutMixinOptions {
8
10
  /**
9
11
  * Whether flyout is modal.
@@ -34,7 +36,11 @@ export interface FlyoutMixinOptions {
34
36
  *
35
37
  * Mixin should be created using {@link useFlyoutMixin} and applied to element by {@link Mixin.use}.
36
38
  */
37
- export default class FlyoutMixin extends ClassNameMixin {
39
+ export default class FlyoutMixin<S = any, R = any> extends ClassNameMixin {
40
+ /**
41
+ * Gets the flyout element.
42
+ */
43
+ readonly element: Element | null;
38
44
  /**
39
45
  * Gets whether the flyout is open.
40
46
  */
@@ -52,7 +58,7 @@ export default class FlyoutMixin extends ClassNameMixin {
52
58
  * Gets a {@link FlyoutToggleMixin} object that when applied to an element,
53
59
  * clicking that element will toggle the flyout.
54
60
  */
55
- readonly toggle: FlyoutToggleMixin;
61
+ readonly toggle: FlyoutToggleMixin<S, R>;
56
62
  /**
57
63
  * Whether flyout content, or what element, by specifying CSS selector, will be initially focused.
58
64
  * Default is `true` if source element is not an text input element.
@@ -73,7 +79,7 @@ export default class FlyoutMixin extends ClassNameMixin {
73
79
  * Adds a listener to handle the opening of the flyout.
74
80
  * @param callback Callback to be called, receiving value passed to {@link FlyoutMixin.open}.
75
81
  */
76
- onOpen(callback: (state: any) => void): Zeta.UnregisterCallback;
82
+ onOpen(callback: (state: HintedType<S>) => void): Zeta.UnregisterCallback;
77
83
  /**
78
84
  * Adds a listener to monitor the opening and closing of the flyout.
79
85
  * It differs from {@link FlyoutMixin.onVisibilityChanged} that the callback is called immediately when the flyout is being closed.
@@ -92,17 +98,24 @@ export default class FlyoutMixin extends ClassNameMixin {
92
98
  * @param source Source element that triggered the flyout.
93
99
  * @returns A promise that resolves when the flyout is being closed.
94
100
  */
95
- open(state?: any, source?: Element): Promise<any>;
101
+ open(state?: S, source?: Element): Promise<HintedType<R>>;
96
102
  /**
97
103
  * Closes the flyout.
98
104
  * @param state Value to be sent to the promise returned by {@link FlyoutMixin.open}.
99
105
  * @returns A promise that resolves after closing animation completes.
100
106
  */
101
- close(state?: any): Promise<void>;
107
+ close(state?: R): Promise<void>;
108
+ /**
109
+ * Toggles the flyout.
110
+ * @param source Source element which triggered the flyout.
111
+ * @returns A promise that resolves when the flyout is being closed.
112
+ */
113
+ toggleSelf(source?: Element): Promise<HintedType<R>>;
102
114
  /**
103
115
  * Toggles the flyout.
116
+ * @param flag Whether the flyout should be open or closed.
104
117
  * @param source Source element which triggered the flyout.
105
118
  * @returns A promise that resolves when the flyout is being closed.
106
119
  */
107
- toggleSelf(source?: Element): Promise<any>;
120
+ toggleSelf(flag: boolean, source?: Element): Promise<HintedType<R>>;
108
121
  }
@@ -1,5 +1,5 @@
1
- import { definePrototype, extend, makeArray, pick } from "zeta-dom/util";
2
- import { closeFlyout, openFlyout, toggleFlyout } from "brew-js/domAction";
1
+ import { definePrototype, extend, makeArray, pick, resolve, throws } from "zeta-dom/util";
2
+ import { closeFlyout, isFlyoutOpen, openFlyout, toggleFlyout } from "brew-js/domAction";
3
3
  import { app } from "../app.js";
4
4
  import ClassNameMixin from "./ClassNameMixin.js";
5
5
  import FlyoutToggleMixin from "./FlyoutToggleMixin.js";
@@ -7,6 +7,14 @@ import FlyoutToggleMixin from "./FlyoutToggleMixin.js";
7
7
  const FlyoutMixinSuper = ClassNameMixin.prototype;
8
8
  const valueMap = new WeakMap();
9
9
 
10
+ function toggleSelf(self, flag, value, source) {
11
+ if (!flag && !isFlyoutOpen(self.element)) {
12
+ return resolve();
13
+ }
14
+ var options = self.getOptions();
15
+ return flag ? openFlyout(self.element, value, source, options) : toggleFlyout(self.element, source, options);
16
+ }
17
+
10
18
  export default function FlyoutMixin() {
11
19
  var self = this;
12
20
  ClassNameMixin.call(self, ['open', 'closing', 'visible', 'tweening-in', 'tweening-out']);
@@ -25,6 +33,9 @@ export default function FlyoutMixin() {
25
33
  }
26
34
 
27
35
  definePrototype(FlyoutMixin, ClassNameMixin, {
36
+ get element() {
37
+ return this.elements()[0] || null;
38
+ },
28
39
  getOptions: function () {
29
40
  var self = this;
30
41
  var options = pick(self, ['closeOnBlur']);
@@ -57,19 +68,22 @@ definePrototype(FlyoutMixin, ClassNameMixin, {
57
68
  });
58
69
  },
59
70
  open: function (value, source) {
60
- return openFlyout(this.elements()[0], value, source, this.getOptions());
71
+ return toggleSelf(this, true, value, source);
61
72
  },
62
73
  close: function (value) {
63
- return closeFlyout(this.elements()[0], value);
74
+ return closeFlyout(this.element, value);
64
75
  },
65
- toggleSelf: function (source) {
66
- return toggleFlyout(this.elements()[0], source, this.getOptions());
76
+ toggleSelf: function (flag, source) {
77
+ if (typeof flag !== 'boolean') {
78
+ source = flag;
79
+ flag = !isFlyoutOpen(this.element);
80
+ }
81
+ return toggleSelf(this, flag, undefined, source);
67
82
  },
68
83
  onOpen: function (callback) {
69
- var element = this.elements()[0];
70
84
  return this.onToggleState(function (opened) {
71
85
  if (opened) {
72
- return callback(valueMap.get(element));
86
+ callback(valueMap.get(this.element));
73
87
  }
74
88
  });
75
89
  },
@@ -81,8 +95,11 @@ definePrototype(FlyoutMixin, ClassNameMixin, {
81
95
  },
82
96
  initElement: function (element, state) {
83
97
  var self = this;
98
+ if (self.elements()[1]) {
99
+ throws('FlyoutMixin only supports single element');
100
+ }
84
101
  FlyoutMixinSuper.initElement.call(self, element, state);
85
- self.onDispose(app.on(element, {
102
+ state.onDispose(app.on(element, {
86
103
  flyoutshow: function (e) {
87
104
  valueMap.set(element, e.data);
88
105
  self.isFlyoutOpened = true;
@@ -1,12 +1,12 @@
1
1
  import ClassNameMixin from "./ClassNameMixin";
2
- import FlyoutMixin from "./FlyoutMixin";
2
+ import FlyoutMixin, { HintedType } from "./FlyoutMixin";
3
3
 
4
4
  /**
5
5
  * Enables applied element as toggle buttons for the associated flyout.
6
6
  *
7
7
  * Instances of this mixin is exposed by {@link FlyoutMixin.toggle}.
8
8
  */
9
- export default class FlyoutToggleMixin extends ClassNameMixin {
9
+ export default class FlyoutToggleMixin<S = any, R = any> extends ClassNameMixin {
10
10
  /**
11
11
  * Specifies the condition on when the flyout should toggle. It can be either:
12
12
  *
@@ -24,17 +24,24 @@ export default class FlyoutToggleMixin extends ClassNameMixin {
24
24
  * @param source Source element that triggered the flyout.
25
25
  * @returns A promise that resolves when the flyout is being closed.
26
26
  */
27
- open(state?: any, source?: Element): Promise<any>;
27
+ open(state?: S, source?: Element): Promise<HintedType<R>>;
28
28
  /**
29
29
  * Closes the associated flyout.
30
30
  * @param state Value to be sent to the promise returned by {@link FlyoutMixin.open}.
31
31
  * @returns A promise that resolves after closing animation completes.
32
32
  */
33
- close(state?: any): Promise<void>;
33
+ close(state?: R): Promise<void>;
34
34
  /**
35
35
  * Toggles the associated flyout.
36
36
  * @param source Source element which triggered the flyout.
37
37
  * @returns A promise that resolves when the flyout is being closed.
38
38
  */
39
- toggle(source?: Element): Promise<any>;
39
+ toggle(source?: Element): Promise<HintedType<R>>;
40
+ /**
41
+ * Toggles the associated flyout.
42
+ * @param flag Whether the flyout should be open or closed.
43
+ * @param source Source element which triggered the flyout.
44
+ * @returns A promise that resolves when the flyout is being closed.
45
+ */
46
+ toggle(flag: boolean, source?: Element): Promise<HintedType<R>>;
40
47
  }
@@ -26,13 +26,13 @@ definePrototype(FlyoutToggleMixin, ClassNameMixin, {
26
26
  close: function (value) {
27
27
  return this.flyoutMixin.close(value);
28
28
  },
29
- toggle: function (source) {
30
- return this.flyoutMixin.toggleSelf(source);
29
+ toggle: function (flag, source) {
30
+ return this.flyoutMixin.toggleSelf(flag, source);
31
31
  },
32
32
  initElement: function (element, state) {
33
33
  var self = this;
34
34
  FlyoutToggleMixinSuper.initElement.call(self, element, state);
35
- self.onDispose(dom.on(element, {
35
+ state.onDispose(dom.on(element, {
36
36
  focusin: function () {
37
37
  triggerFlyoutAction(self, state, 'focus', self.open, [null, dom.activeElement]);
38
38
  },
@@ -23,7 +23,7 @@ definePrototype(FocusStateMixin, StatefulMixin, {
23
23
  callback(arg || target);
24
24
  }
25
25
  };
26
- this.onDispose(dom.on(element, {
26
+ state.onDispose(dom.on(element, {
27
27
  focusin: function (e) {
28
28
  state.focused = e.source;
29
29
  setClass(element, 'focused', e.source);
@@ -16,7 +16,7 @@ definePrototype(LoadingStateMixin, ClassNameMixin, {
16
16
  var self = this;
17
17
  LoadingStateMixinSuper.initElement.call(self, element, state);
18
18
  getDirectiveComponent(element).enableLoadingClass = true;
19
- self.onDispose(subscribeAsync(element, function (loading) {
19
+ state.onDispose(subscribeAsync(element, function (loading) {
20
20
  self.loading = loading || !!any(self.elements(), function (v) {
21
21
  return v !== element && getClass(v, 'loading') === true;
22
22
  });
@@ -52,6 +52,14 @@ export default class ScrollableMixin extends ClassNameMixin implements JQueryScr
52
52
  * the element will act as content to be scrolled.
53
53
  */
54
54
  readonly target: StaticAttributeMixin;
55
+ /**
56
+ * Gets the element with scrollable plugin enabled.
57
+ */
58
+ readonly element: Element | null;
59
+ /**
60
+ * Gets the element which its scrolling position is currently controlled.
61
+ */
62
+ readonly contentElement: Element | null;
55
63
  /**
56
64
  * Gets the index of the currently visible element matched by {@link ScrollableMixinOptions.pagedItemSelector} options.
57
65
  */
@@ -1,4 +1,4 @@
1
- import { defineHiddenProperty, definePrototype, each, extend } from "zeta-dom/util";
1
+ import { defineHiddenProperty, definePrototype, each, extend, throws } from "zeta-dom/util";
2
2
  import { getDirectiveComponent } from "brew-js/directive";
3
3
  import { app } from "../app.js";
4
4
  import Mixin from "./Mixin.js";
@@ -15,6 +15,13 @@ export default function ScrollableMixin() {
15
15
  }
16
16
 
17
17
  definePrototype(ScrollableMixin, ClassNameMixin, {
18
+ get element() {
19
+ return this.elements()[0] || null;
20
+ },
21
+ get contentElement() {
22
+ var element = this.element;
23
+ return element && getDirectiveComponent(element).scrollable.scrollTarget;
24
+ },
18
25
  withOptions: function (options) {
19
26
  this.options = options;
20
27
  return this;
@@ -35,8 +42,11 @@ definePrototype(ScrollableMixin, ClassNameMixin, {
35
42
  },
36
43
  initElement: function (element, state) {
37
44
  var self = this;
45
+ if (self.elements()[1]) {
46
+ throws('ScrollableMixin only supports single element');
47
+ }
38
48
  ScrollableMixinSuper.initElement.call(self, element, state);
39
- self.onDispose(app.on(element, {
49
+ state.onDispose(app.on(element, {
40
50
  scrollIndexChange: function (e) {
41
51
  self.pageIndex = e.newIndex;
42
52
  },
@@ -52,7 +62,7 @@ definePrototype(ScrollableMixin, ClassNameMixin, {
52
62
 
53
63
  each('destroy enable disable setOptions setStickyPosition refresh scrollPadding stop scrollLeft scrollTop scrollBy scrollTo scrollByPage scrollToPage scrollToElement', function (i, v) {
54
64
  defineHiddenProperty(ScrollableMixin.prototype, v, function () {
55
- var obj = getDirectiveComponent(this.elements()[0]);
65
+ var obj = getDirectiveComponent(this.element);
56
66
  return obj.scrollable[v].apply(null, arguments);
57
67
  });
58
68
  });
@@ -9,6 +9,12 @@ export interface MixinState {
9
9
  * Additional state.
10
10
  */
11
11
  [x: string]: any;
12
+
13
+ /**
14
+ * Registers callback to clean up resources when the element is unmounted.
15
+ * @param callback A callback.
16
+ */
17
+ onDispose(callback: Zeta.UnregisterCallback): void;
12
18
  }
13
19
 
14
20
  export interface MixinRef<T extends StatefulMixin = StatefulMixin> {
@@ -29,7 +35,7 @@ export default abstract class StatefulMixin<T extends MixinState = MixinState> e
29
35
  * By default, existing values on the actual state object will be overwritten in subsequent update.
30
36
  * To handle changes, overrides the {@link StatefulMixin.mergeState} method.
31
37
  */
32
- protected get state(): Exclude<Partial<T>, 'element'>;
38
+ protected get state(): Exclude<Partial<T>, 'element' | 'onDispose'>;
33
39
 
34
40
  /**
35
41
  * Gets an array of mounted elements which this mixin has been applied.
@@ -37,12 +43,14 @@ export default abstract class StatefulMixin<T extends MixinState = MixinState> e
37
43
  elements(): HTMLElement[];
38
44
  /**
39
45
  * Registers callback to clean up resources when the host component is unmounted.
46
+ * For individual element, use {@link MixinState.onDispose}.
40
47
  * @param callback A callback.
41
48
  */
42
49
  onDispose(callback: Zeta.UnregisterCallback): void;
43
50
 
44
51
  /**
45
52
  * Override this method to create state object with initial values.
53
+ * @deprecated Initialize state in {@link StatefulMixin.initElement} instead.
46
54
  */
47
55
  protected initState(): T;
48
56
  /**
@@ -1,7 +1,26 @@
1
- import { combineFn, createPrivateStore, definePrototype, extend, keys, map, pipe, watch } from "zeta-dom/util";
1
+ import { arrRemove, combineFn, createPrivateStore, definePrototype, each, extend, keys, setImmediateOnce, throwNotFunction, watch } from "zeta-dom/util";
2
2
  import Mixin from "./Mixin.js";
3
3
 
4
4
  const _ = createPrivateStore();
5
+ const unmounted = new Set();
6
+
7
+ function disposeUnmountedStates() {
8
+ each(unmounted, function (i, v) {
9
+ combineFn(_(v).splice(0))();
10
+ });
11
+ unmounted.clear();
12
+ }
13
+
14
+ function MixinState(parent, element) {
15
+ _(this, [parent.delete.bind(parent, element)]);
16
+ parent.set(element, this);
17
+ }
18
+
19
+ definePrototype(MixinState, {
20
+ onDispose: function (callback) {
21
+ _(this).push(throwNotFunction(callback));
22
+ }
23
+ });
5
24
 
6
25
  function MixinRefImpl(mixin) {
7
26
  this.mixin = mixin;
@@ -17,8 +36,8 @@ export default function StatefulMixin() {
17
36
  Mixin.call(this);
18
37
  _(this, {
19
38
  pending: {},
20
- elements: new Set(),
21
- states: new WeakMap(),
39
+ elements: [],
40
+ states: new Map(),
22
41
  flush: watch(this, false),
23
42
  dispose: []
24
43
  });
@@ -44,34 +63,35 @@ definePrototype(StatefulMixin, Mixin, {
44
63
  var self = this;
45
64
  var obj = _(self);
46
65
  var newState = obj.pending;
47
- var state;
66
+ var element, state;
48
67
  return function (current) {
49
68
  if (current) {
50
- state = obj.states.get(current) || extend(self.initState(), newState);
51
- if (state.element !== current) {
52
- state.element = current;
53
- self.initElement(current, state);
54
- obj.states.set(current, state);
69
+ element = current;
70
+ state = obj.states.get(element) || new MixinState(obj.states, element);
71
+ obj.elements.push(element);
72
+ if (!state.element) {
73
+ self.initElement(element, extend(state, self.initState(), newState, { element }));
55
74
  } else if (keys(newState)[0]) {
56
- self.mergeState(current, state, newState);
75
+ self.mergeState(element, state, newState);
57
76
  }
58
- self.onLayoutEffect(current, state);
59
- obj.elements.add(current);
77
+ self.onLayoutEffect(element, state);
78
+ unmounted.delete(state);
60
79
  } else if (state) {
61
- var prev = state.element;
62
- self.onBeforeUpdate(prev, state);
63
- obj.elements.delete(prev);
80
+ unmounted.add(state);
81
+ self.onBeforeUpdate(element, state);
82
+ arrRemove(obj.elements, element);
64
83
  }
84
+ setImmediateOnce(disposeUnmountedStates);
65
85
  };
66
86
  },
67
87
  elements: function () {
68
- return map(_(this).elements, pipe);
88
+ return _(this).elements.slice();
69
89
  },
70
90
  onDispose: function (callback) {
71
91
  _(this).dispose.push(callback);
72
92
  },
73
93
  initState: function () {
74
- return { element: null };
94
+ return {};
75
95
  },
76
96
  initElement: function (element, state) {
77
97
  },
@@ -87,9 +107,12 @@ definePrototype(StatefulMixin, Mixin, {
87
107
  },
88
108
  dispose: function () {
89
109
  var state = _(this);
110
+ each(state.states, function (i, v) {
111
+ unmounted.add(v);
112
+ });
113
+ setImmediateOnce(disposeUnmountedStates);
90
114
  combineFn(state.dispose.splice(0))();
91
115
  state.flush();
92
- state.states = {};
93
116
  state.pending = {};
94
117
  }
95
118
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brew-js-react",
3
- "version": "0.5.7",
3
+ "version": "0.6.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -15,8 +15,8 @@
15
15
  "@misonou/react-dom-client": "^1.1.1",
16
16
  "brew-js": ">=0.6.5",
17
17
  "waterpipe": "^2.5.0",
18
- "zeta-dom": ">=0.4.10",
19
- "zeta-dom-react": ">=0.4.14"
18
+ "zeta-dom": ">=0.5.1",
19
+ "zeta-dom-react": ">=0.5.6"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "react": ">=16.8.0",