brew-js-react 0.5.7 → 0.6.0

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 CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  Brew.js for React is a utility that allow brew.js features to be used on React App.
4
4
 
5
- See documentation at https://hackmd.io/@misonou/brew-js-react.
5
+ See documentation at https://misonou.github.io.
package/dialog.d.ts CHANGED
@@ -64,7 +64,7 @@ export interface DialogBaseProps<T, V = T> {
64
64
  * The dialog will be held open until the returned promise resolves.
65
65
  * When the promise rejects, the dialog will remain open.
66
66
  */
67
- onCommit?: (value: V | undefined) => T | Promise<T> | void;
67
+ onCommit?: (value: V | undefined, context: Zeta.RunAsyncContext) => T | Promise<T> | void;
68
68
  /**
69
69
  * Callback to be invoked when dialog has opened.
70
70
  */
package/dialog.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createElement, useEffect, useState } from "react";
2
2
  import ReactDOM from "react-dom";
3
3
  import ReactDOMClient from "@misonou/react-dom-client";
4
- import { either, extend, makeAsync, noop, pick, pipe, resolve } from "zeta-dom/util";
4
+ import { either, extend, noop, pick, resolve } from "zeta-dom/util";
5
5
  import { containsOrEquals, removeNode } from "zeta-dom/domUtil";
6
6
  import dom from "zeta-dom/dom";
7
- import { lock, notifyAsync, preventLeave, subscribeAsync } from "zeta-dom/domLock";
7
+ import { lock, preventLeave, runAsync, subscribeAsync } from "zeta-dom/domLock";
8
8
  import { closeFlyout, openFlyout } from "brew-js/domAction";
9
9
 
10
10
  /**
@@ -47,11 +47,9 @@ export function createDialog(props) {
47
47
  }
48
48
  if (props.onRender) {
49
49
  var dialogProps = extend({}, props, {
50
- closeDialog: function (value) {
51
- var promise = makeAsync(props.onCommit || pipe)(value);
52
- notifyAsync(dom.activeElement, promise);
53
- return promise.then(closeDialog);
54
- }
50
+ closeDialog: props.onCommit ? function (value) {
51
+ return runAsync(dom.activeElement, props.onCommit.bind(this, value)).then(closeDialog);
52
+ } : closeDialog
55
53
  });
56
54
  var content = createElement(props.onRender, dialogProps);
57
55
  if (props.wrapper) {
@@ -1,4 +1,4 @@
1
- /*! brew-js-react v0.5.7 | (c) misonou | https://misonou.github.io */
1
+ /*! brew-js-react v0.6.0 | (c) misonou | https://misonou.github.io */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("zeta-dom"), require("react"), require("react-dom"), require("brew-js"), require("zeta-dom-react"), require("waterpipe"), require("jquery"));
@@ -249,12 +249,10 @@ var _lib$util = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_dom_root_
249
249
  util_keys = _lib$util.keys,
250
250
  kv = _lib$util.kv,
251
251
  makeArray = _lib$util.makeArray,
252
- makeAsync = _lib$util.makeAsync,
253
252
  map = _lib$util.map,
254
253
  mapObject = _lib$util.mapObject,
255
254
  noop = _lib$util.noop,
256
255
  pick = _lib$util.pick,
257
- pipe = _lib$util.pipe,
258
256
  randomId = _lib$util.randomId,
259
257
  resolve = _lib$util.resolve,
260
258
  resolveAll = _lib$util.resolveAll,
@@ -262,6 +260,7 @@ var _lib$util = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_dom_root_
262
260
  setImmediateOnce = _lib$util.setImmediateOnce,
263
261
  single = _lib$util.single,
264
262
  throwNotFunction = _lib$util.throwNotFunction,
263
+ _throws = _lib$util["throws"],
265
264
  watch = _lib$util.watch,
266
265
  watchable = _lib$util.watchable;
267
266
 
@@ -296,12 +295,15 @@ var domUtil_lib$util = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_do
296
295
 
297
296
  var dom = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_dom_root_zeta_.dom;
298
297
  /* harmony default export */ const zeta_dom_dom = (dom);
298
+ var reportError = dom.reportError;
299
+
299
300
  ;// CONCATENATED MODULE: ./|umd|/zeta-dom/domLock.js
300
301
 
301
302
  var _lib$dom = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_dom_root_zeta_.dom,
302
303
  lock = _lib$dom.lock,
303
304
  notifyAsync = _lib$dom.notifyAsync,
304
305
  preventLeave = _lib$dom.preventLeave,
306
+ runAsync = _lib$dom.runAsync,
305
307
  subscribeAsync = _lib$dom.subscribeAsync;
306
308
 
307
309
  // EXTERNAL MODULE: external {"commonjs":"brew-js","commonjs2":"brew-js","amd":"brew-js","root":"brew"}
@@ -328,7 +330,7 @@ var closeFlyout = external_commonjs_brew_js_commonjs2_brew_js_amd_brew_js_root_b
328
330
  function createDialog(props) {
329
331
  var root = document.createElement('div');
330
332
  var reactRoot = fallback.createRoot(root);
331
- var _closeDialog = closeFlyout.bind(0, root);
333
+ var closeDialog = closeFlyout.bind(0, root);
332
334
  var promise;
333
335
  zeta_dom_dom.on(root, {
334
336
  flyoutshow: function flyoutshow() {
@@ -347,7 +349,7 @@ function createDialog(props) {
347
349
  subscribeAsync(root, true);
348
350
  return {
349
351
  root: root,
350
- close: _closeDialog,
352
+ close: closeDialog,
351
353
  open: function open() {
352
354
  if (promise) {
353
355
  return promise;
@@ -360,11 +362,9 @@ function createDialog(props) {
360
362
  }
361
363
  if (props.onRender) {
362
364
  var dialogProps = extend({}, props, {
363
- closeDialog: function closeDialog(value) {
364
- var promise = makeAsync(props.onCommit || pipe)(value);
365
- notifyAsync(zeta_dom_dom.activeElement, promise);
366
- return promise.then(_closeDialog);
367
- }
365
+ closeDialog: props.onCommit ? function (value) {
366
+ return runAsync(zeta_dom_dom.activeElement, props.onCommit.bind(this, value)).then(closeDialog);
367
+ } : closeDialog
368
368
  });
369
369
  var content = /*#__PURE__*/createElement(props.onRender, dialogProps);
370
370
  if (props.wrapper) {
@@ -419,7 +419,7 @@ var ViewStateProvider = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_reac
419
419
  useMemoizedFunction = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_react_amd_zeta_dom_react_root_zeta_react_.useMemoizedFunction,
420
420
  useObservableProperty = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_react_amd_zeta_dom_react_root_zeta_react_.useObservableProperty,
421
421
  useSingleton = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_react_amd_zeta_dom_react_root_zeta_react_.useSingleton,
422
- useUpdateTrigger = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_react_amd_zeta_dom_react_root_zeta_react_.useUpdateTrigger;
422
+ useValueTrigger = external_commonjs_zeta_dom_react_commonjs2_zeta_dom_react_amd_zeta_dom_react_root_zeta_react_.useValueTrigger;
423
423
 
424
424
  ;// CONCATENATED MODULE: ./|umd|/zeta-dom/events.js
425
425
 
@@ -536,7 +536,7 @@ function ViewContext(view, page, parent) {
536
536
  definePrototype(ViewContext, {
537
537
  getChildren: function getChildren() {
538
538
  return map(_(this).children, function (v) {
539
- return v.currentState;
539
+ return v.currentContext;
540
540
  });
541
541
  },
542
542
  on: function on(event, handler) {
@@ -559,9 +559,7 @@ definePrototype(ErrorBoundary, Component, {
559
559
  // emit error in next tick as ref callback may yet to be invoked
560
560
  // if error is thrown synchronously in first render
561
561
  setImmediate(function () {
562
- zeta_dom_dom.emit('error', self.context.container, {
563
- error: error
564
- }, true);
562
+ reportError(error, self.context.container);
565
563
  });
566
564
  // ensure promise sent to beforepageload event is resolved
567
565
  self.props.onComponentLoaded();
@@ -609,7 +607,7 @@ definePrototype(ViewContainer, Component, {
609
607
  arrRemove(parent, self);
610
608
  unwatch();
611
609
  setImmediate(function () {
612
- if (self.unmountView && !self.currentState.active) {
610
+ if (self.unmountView && !self.currentContext.active) {
613
611
  self.unmountView();
614
612
  }
615
613
  });
@@ -641,20 +639,21 @@ definePrototype(ViewContainer, Component, {
641
639
  }
642
640
  if (V && viewChanged) {
643
641
  (self.unmountView || noop)(true);
644
- var state = new ViewContext(V, app_app.page, self.context);
642
+ var context = new ViewContext(V, app_app.page, self.context);
643
+ var state = routeMap.get(V);
645
644
  var onComponentLoaded;
646
645
  var promise = new Promise(function (resolve) {
647
646
  onComponentLoaded = resolve;
648
647
  });
649
648
  var unmountView = onComponentLoaded;
650
649
  var initElement = executeOnce(function (element) {
651
- state.container = element;
650
+ context.container = element;
652
651
  promise.then(function () {
653
- if (self.currentState === state) {
652
+ if (self.currentContext === context) {
654
653
  unmountView = function unmountView() {
655
654
  self.prevView = self.currentView;
656
655
  app_app.emit('pageleave', element, {
657
- pathname: state.page.path,
656
+ pathname: context.page.path,
658
657
  view: V
659
658
  }, true);
660
659
  animateOut(element, 'show').then(function () {
@@ -664,21 +663,23 @@ definePrototype(ViewContainer, Component, {
664
663
  };
665
664
  animateIn(element, 'show', '[brew-view]', true);
666
665
  app_app.emit('pageenter', element, {
667
- pathname: state.page.path,
666
+ pathname: context.page.path,
668
667
  view: V
669
668
  }, true);
670
669
  }
671
670
  });
672
671
  notifyAsync(element, promise);
673
672
  });
674
- var viewProps = freeze({
675
- navigationType: view_event.navigationType,
676
- viewContext: state,
677
- viewData: view_event.data || {}
678
- });
673
+ var viewProps = function viewProps() {
674
+ return freeze({
675
+ navigationType: view_event.navigationType,
676
+ viewContext: context,
677
+ viewData: context.page.data || {}
678
+ });
679
+ };
679
680
  var view = /*#__PURE__*/createElement(StateContext.Provider, {
680
- key: routeMap.get(V).id,
681
- value: state
681
+ key: state.id,
682
+ value: context
682
683
  }, /*#__PURE__*/createElement(ViewStateContainer, null, /*#__PURE__*/createElement('div', extend({}, self.props.rootProps, {
683
684
  ref: initElement,
684
685
  'brew-view': ''
@@ -686,17 +687,17 @@ definePrototype(ViewContainer, Component, {
686
687
  onComponentLoaded: onComponentLoaded,
687
688
  viewProps: viewProps
688
689
  }))));
689
- extend(self, _(state), {
690
- currentState: state,
690
+ extend(self, _(context), {
691
+ currentContext: context,
691
692
  currentView: view,
692
693
  currentViewComponent: V,
693
694
  unmountView: executeOnce(function () {
694
695
  self.setActive(false);
695
- routeMap.get(V).rendered--;
696
+ state.rendered--;
696
697
  unmountView();
697
698
  })
698
699
  });
699
- routeMap.get(V).rendered++;
700
+ state.rendered++;
700
701
  (view_event.waitFor || noop)(promise);
701
702
  }
702
703
  (self.setPage || noop)(app_app.page);
@@ -756,19 +757,24 @@ function createViewComponent(factory) {
756
757
  factory = createElement.bind(null, factory);
757
758
  }
758
759
  return function fn(props) {
759
- var viewProps = props.viewProps;
760
- var children = !promise && factory(viewProps);
760
+ var viewContext = useContext(StateContext);
761
+ var viewProps = useState(props.viewProps);
762
+ var children = !promise && factory(viewProps[0]);
761
763
  if (isThenable(children)) {
762
764
  promise = children;
763
765
  children = null;
764
766
  catchAsync(promise);
765
767
  }
766
768
  var state = useAsync(function () {
767
- return promise.then(function (s) {
768
- return /*#__PURE__*/createElement(s["default"], viewProps);
769
- });
769
+ return promise;
770
770
  }, !!promise)[1];
771
771
  var loaded = !promise || !state.loading;
772
+ useEffect(function () {
773
+ // listen to property directly so that it is invoked after pagechange event handlers in actual component
774
+ return watch(viewContext, 'page', function () {
775
+ viewProps[1](props.viewProps);
776
+ });
777
+ }, []);
772
778
  useEffect(function () {
773
779
  if (loaded) {
774
780
  setImmediate(props.onComponentLoaded);
@@ -777,7 +783,7 @@ function createViewComponent(factory) {
777
783
  if (state.error) {
778
784
  throw state.error;
779
785
  }
780
- return children || state.value || /*#__PURE__*/createElement(Fragment);
786
+ return children || (state.value ? /*#__PURE__*/createElement(state.value["default"], viewProps[0]) : null);
781
787
  };
782
788
  }
783
789
  function useViewContext() {
@@ -936,20 +942,15 @@ function useRouteParam(name, defaultValue) {
936
942
  var container = useViewContext();
937
943
  var params = container.page.params;
938
944
  var value = params[name] || '';
939
- var ref = useRef(value);
940
- var forceUpdate = useUpdateTrigger();
945
+ var notifyChange = useValueTrigger(value);
941
946
  useEffect(function () {
942
947
  var setValue = function setValue() {
943
- var current = container.page.params[name] || '';
944
- if (current !== ref.current) {
945
- forceUpdate();
946
- }
948
+ notifyChange(container.page.params[name] || '');
947
949
  };
948
950
  // route parameter might be changed after state initialization and before useEffect hook is called
949
951
  setValue();
950
952
  return container.on('pagechange', setValue);
951
953
  }, [name]);
952
- ref.current = value;
953
954
  if (defaultValue && container.active && (!value || name === 'remainingSegments' && value === '/')) {
954
955
  app_app.navigate(app_app.route.getPath(extend({}, params, kv(name, defaultValue))), true);
955
956
  }
@@ -979,22 +980,20 @@ function useQueryParam(key, value, snapshotOnUpdate) {
979
980
  }
980
981
  var container = useViewContext();
981
982
  var getParams = function getParams() {
982
- return mapObject(key === false ? value : kv(key, value), function (v, i) {
983
+ return freeze(mapObject(key === false ? value : kv(key, value), function (v, i) {
983
984
  return getQueryParam(i, app_app.path) || v || '';
984
- });
985
+ }));
985
986
  };
986
- var state = useState([]);
987
+ var ref = useRef({});
987
988
  useMemo(function () {
988
- state[0].splice(0, 2, getParams());
989
+ ref.current = getParams();
989
990
  }, [key]);
990
- var current = state[0][0];
991
- var trackChanges = function trackChanges(values) {
992
- if (!equal(values, current)) {
993
- extend(current, values);
994
- state[1]([current]);
995
- }
996
- };
991
+ var current = ref.current;
992
+ var notifyChange = useValueTrigger(current, function (current, params) {
993
+ return equal(current, params) || !(ref.current = params);
994
+ });
997
995
  var setParams = useMemoizedFunction(function (values) {
996
+ var current = ref.current;
998
997
  if (key !== false) {
999
998
  values = kv(key, isFunction(values) ? values(current[key]) : values);
1000
999
  } else if (isFunction(values)) {
@@ -1009,19 +1008,19 @@ function useQueryParam(key, value, snapshotOnUpdate) {
1009
1008
  if (snapshotOnUpdate) {
1010
1009
  app_app.snapshot();
1011
1010
  }
1012
- catchAsync(app_app.navigate(search + url.hash, true));
1013
- trackChanges(getParams());
1011
+ catchAsync(app_app.navigate((search || '?') + url.hash, true));
1012
+ notifyChange(getParams());
1014
1013
  }
1015
1014
  }
1016
1015
  });
1017
1016
  useEffect(function () {
1018
1017
  return app_app.watch('path', function () {
1019
1018
  if (container.active) {
1020
- trackChanges(getParams());
1019
+ notifyChange(getParams());
1021
1020
  }
1022
1021
  });
1023
1022
  }, [key]);
1024
- return [key !== false ? current[key] : state[0][1] || (state[0][1] = freeze(extend({}, current))), setParams];
1023
+ return [key !== false ? current[key] : current, setParams];
1025
1024
  }
1026
1025
  function ViewStateContainer(props) {
1027
1026
  var cache = useState({})[0];
@@ -1221,6 +1220,22 @@ var observe_lib$dom = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_dom
1221
1220
 
1222
1221
 
1223
1222
  var StatefulMixin_ = createPrivateStore();
1223
+ var unmounted = new Set();
1224
+ function disposeUnmountedStates() {
1225
+ each(unmounted, function (i, v) {
1226
+ combineFn(StatefulMixin_(v).splice(0))();
1227
+ });
1228
+ unmounted.clear();
1229
+ }
1230
+ function MixinState(parent, element) {
1231
+ StatefulMixin_(this, [parent["delete"].bind(parent, element)]);
1232
+ parent.set(element, this);
1233
+ }
1234
+ definePrototype(MixinState, {
1235
+ onDispose: function onDispose(callback) {
1236
+ StatefulMixin_(this).push(throwNotFunction(callback));
1237
+ }
1238
+ });
1224
1239
  function MixinRefImpl(mixin) {
1225
1240
  this.mixin = mixin;
1226
1241
  }
@@ -1233,8 +1248,8 @@ function StatefulMixin() {
1233
1248
  Mixin.call(this);
1234
1249
  StatefulMixin_(this, {
1235
1250
  pending: {},
1236
- elements: new Set(),
1237
- states: new WeakMap(),
1251
+ elements: [],
1252
+ states: new Map(),
1238
1253
  flush: watch(this, false),
1239
1254
  dispose: []
1240
1255
  });
@@ -1259,36 +1274,37 @@ definePrototype(StatefulMixin, Mixin, {
1259
1274
  var self = this;
1260
1275
  var obj = StatefulMixin_(self);
1261
1276
  var newState = obj.pending;
1262
- var state;
1277
+ var element, state;
1263
1278
  return function (current) {
1264
1279
  if (current) {
1265
- state = obj.states.get(current) || extend(self.initState(), newState);
1266
- if (state.element !== current) {
1267
- state.element = current;
1268
- self.initElement(current, state);
1269
- obj.states.set(current, state);
1280
+ element = current;
1281
+ state = obj.states.get(element) || new MixinState(obj.states, element);
1282
+ obj.elements.push(element);
1283
+ if (!state.element) {
1284
+ self.initElement(element, extend(state, self.initState(), newState, {
1285
+ element: element
1286
+ }));
1270
1287
  } else if (util_keys(newState)[0]) {
1271
- self.mergeState(current, state, newState);
1288
+ self.mergeState(element, state, newState);
1272
1289
  }
1273
- self.onLayoutEffect(current, state);
1274
- obj.elements.add(current);
1290
+ self.onLayoutEffect(element, state);
1291
+ unmounted["delete"](state);
1275
1292
  } else if (state) {
1276
- var prev = state.element;
1277
- self.onBeforeUpdate(prev, state);
1278
- obj.elements["delete"](prev);
1293
+ unmounted.add(state);
1294
+ self.onBeforeUpdate(element, state);
1295
+ arrRemove(obj.elements, element);
1279
1296
  }
1297
+ setImmediateOnce(disposeUnmountedStates);
1280
1298
  };
1281
1299
  },
1282
1300
  elements: function elements() {
1283
- return map(StatefulMixin_(this).elements, pipe);
1301
+ return StatefulMixin_(this).elements.slice();
1284
1302
  },
1285
1303
  onDispose: function onDispose(callback) {
1286
1304
  StatefulMixin_(this).dispose.push(callback);
1287
1305
  },
1288
1306
  initState: function initState() {
1289
- return {
1290
- element: null
1291
- };
1307
+ return {};
1292
1308
  },
1293
1309
  initElement: function initElement(element, state) {},
1294
1310
  mergeState: function mergeState(element, state, newState) {
@@ -1301,9 +1317,12 @@ definePrototype(StatefulMixin, Mixin, {
1301
1317
  },
1302
1318
  dispose: function dispose() {
1303
1319
  var state = StatefulMixin_(this);
1320
+ each(state.states, function (i, v) {
1321
+ unmounted.add(v);
1322
+ });
1323
+ setImmediateOnce(disposeUnmountedStates);
1304
1324
  combineFn(state.dispose.splice(0))();
1305
1325
  state.flush();
1306
- state.states = {};
1307
1326
  state.pending = {};
1308
1327
  }
1309
1328
  });
@@ -1328,18 +1347,13 @@ function ClassNameMixin(classNames) {
1328
1347
  this.classNames = classNames || [];
1329
1348
  }
1330
1349
  definePrototype(ClassNameMixin, StatefulMixin, {
1331
- initState: function initState() {
1332
- return {
1333
- element: null,
1334
- classNames: fill(this.classNames, false)
1335
- };
1336
- },
1337
1350
  initElement: function initElement(element, state) {
1338
1351
  var self = this;
1352
+ state.classNames = fill(self.classNames, false);
1339
1353
  checkState(self, element, state);
1340
- watchOwnAttributes(element, 'class', function () {
1354
+ state.onDispose(watchOwnAttributes(element, 'class', function () {
1341
1355
  checkState(self, element, state, true);
1342
- });
1356
+ }).dispose);
1343
1357
  },
1344
1358
  onLayoutEffect: function onLayoutEffect(element, state) {
1345
1359
  setClass(element, state.classNames);
@@ -1432,9 +1446,9 @@ definePrototype(AnimateSequenceMixin, AnimateMixin, {
1432
1446
  var self = this;
1433
1447
  AnimateSequenceMixinSuper.initElement.call(self, element, state);
1434
1448
  if (self.selector) {
1435
- self.onDispose(watchElements(element, self.selector, function (addedNodes) {
1449
+ state.onDispose(watchElements(element, self.selector, function (addedNodes) {
1436
1450
  external_commonjs_jquery_commonjs2_jquery_amd_jquery_root_jQuery_(addedNodes).attr('is-animate-sequence', '');
1437
- }));
1451
+ }).dispose);
1438
1452
  }
1439
1453
  }
1440
1454
  });
@@ -1491,7 +1505,7 @@ definePrototype(FlyoutToggleMixin, ClassNameMixin, {
1491
1505
  initElement: function initElement(element, state) {
1492
1506
  var self = this;
1493
1507
  FlyoutToggleMixinSuper.initElement.call(self, element, state);
1494
- self.onDispose(zeta_dom_dom.on(element, {
1508
+ state.onDispose(zeta_dom_dom.on(element, {
1495
1509
  focusin: function focusin() {
1496
1510
  triggerFlyoutAction(self, state, 'focus', self.open, [null, zeta_dom_dom.activeElement]);
1497
1511
  },
@@ -1529,6 +1543,9 @@ function FlyoutMixin() {
1529
1543
  });
1530
1544
  }
1531
1545
  definePrototype(FlyoutMixin, ClassNameMixin, {
1546
+ get element() {
1547
+ return this.elements()[0] || null;
1548
+ },
1532
1549
  getOptions: function getOptions() {
1533
1550
  var self = this;
1534
1551
  var options = pick(self, ['closeOnBlur']);
@@ -1561,19 +1578,18 @@ definePrototype(FlyoutMixin, ClassNameMixin, {
1561
1578
  });
1562
1579
  },
1563
1580
  open: function open(value, source) {
1564
- return openFlyout(this.elements()[0], value, source, this.getOptions());
1581
+ return openFlyout(this.element, value, source, this.getOptions());
1565
1582
  },
1566
1583
  close: function close(value) {
1567
- return closeFlyout(this.elements()[0], value);
1584
+ return closeFlyout(this.element, value);
1568
1585
  },
1569
1586
  toggleSelf: function toggleSelf(source) {
1570
- return toggleFlyout(this.elements()[0], source, this.getOptions());
1587
+ return toggleFlyout(this.element, source, this.getOptions());
1571
1588
  },
1572
1589
  onOpen: function onOpen(callback) {
1573
- var element = this.elements()[0];
1574
1590
  return this.onToggleState(function (opened) {
1575
1591
  if (opened) {
1576
- return callback(valueMap.get(element));
1592
+ callback(valueMap.get(this.element));
1577
1593
  }
1578
1594
  });
1579
1595
  },
@@ -1585,8 +1601,11 @@ definePrototype(FlyoutMixin, ClassNameMixin, {
1585
1601
  },
1586
1602
  initElement: function initElement(element, state) {
1587
1603
  var self = this;
1604
+ if (self.elements()[1]) {
1605
+ _throws('FlyoutMixin only supports single element');
1606
+ }
1588
1607
  FlyoutMixinSuper.initElement.call(self, element, state);
1589
- self.onDispose(app_app.on(element, {
1608
+ state.onDispose(app_app.on(element, {
1590
1609
  flyoutshow: function flyoutshow(e) {
1591
1610
  valueMap.set(element, e.data);
1592
1611
  self.isFlyoutOpened = true;
@@ -1630,7 +1649,7 @@ definePrototype(FocusStateMixin, StatefulMixin, {
1630
1649
  callback(arg || target);
1631
1650
  }
1632
1651
  };
1633
- this.onDispose(zeta_dom_dom.on(element, {
1652
+ state.onDispose(zeta_dom_dom.on(element, {
1634
1653
  focusin: function focusin(e) {
1635
1654
  state.focused = e.source;
1636
1655
  setClass(element, 'focused', e.source);
@@ -1669,7 +1688,7 @@ definePrototype(LoadingStateMixin, ClassNameMixin, {
1669
1688
  var self = this;
1670
1689
  LoadingStateMixinSuper.initElement.call(self, element, state);
1671
1690
  getDirectiveComponent(element).enableLoadingClass = true;
1672
- self.onDispose(subscribeAsync(element, function (loading) {
1691
+ state.onDispose(subscribeAsync(element, function (loading) {
1673
1692
  self.loading = loading || !!any(self.elements(), function (v) {
1674
1693
  return v !== element && getClass(v, 'loading') === true;
1675
1694
  });
@@ -1691,6 +1710,13 @@ function ScrollableMixin() {
1691
1710
  self.scrolling = false;
1692
1711
  }
1693
1712
  definePrototype(ScrollableMixin, ClassNameMixin, {
1713
+ get element() {
1714
+ return this.elements()[0] || null;
1715
+ },
1716
+ get contentElement() {
1717
+ var element = this.element;
1718
+ return element && getDirectiveComponent(element).scrollable.scrollTarget;
1719
+ },
1694
1720
  withOptions: function withOptions(options) {
1695
1721
  this.options = options;
1696
1722
  return this;
@@ -1711,8 +1737,11 @@ definePrototype(ScrollableMixin, ClassNameMixin, {
1711
1737
  },
1712
1738
  initElement: function initElement(element, state) {
1713
1739
  var self = this;
1740
+ if (self.elements()[1]) {
1741
+ _throws('ScrollableMixin only supports single element');
1742
+ }
1714
1743
  ScrollableMixinSuper.initElement.call(self, element, state);
1715
- self.onDispose(app_app.on(element, {
1744
+ state.onDispose(app_app.on(element, {
1716
1745
  scrollIndexChange: function scrollIndexChange(e) {
1717
1746
  self.pageIndex = e.newIndex;
1718
1747
  },
@@ -1727,7 +1756,7 @@ definePrototype(ScrollableMixin, ClassNameMixin, {
1727
1756
  });
1728
1757
  each('destroy enable disable setOptions setStickyPosition refresh scrollPadding stop scrollLeft scrollTop scrollBy scrollTo scrollByPage scrollToPage scrollToElement', function (i, v) {
1729
1758
  defineHiddenProperty(ScrollableMixin.prototype, v, function () {
1730
- var obj = getDirectiveComponent(this.elements()[0]);
1759
+ var obj = getDirectiveComponent(this.element);
1731
1760
  return obj.scrollable[v].apply(null, arguments);
1732
1761
  });
1733
1762
  });