@koordinates/xstate-tree 4.8.1 → 4.10.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.
@@ -2,22 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useIsRouteActive = void 0;
4
4
  const providers_1 = require("./providers");
5
- /**
6
- * @public
7
- * Accepts Routes and returns true if any route is currently active. False if not.
8
- *
9
- * If used outside of a RoutingContext, an error will be thrown.
10
- * @param routes - the routes to check
11
- * @returns true if any route is active, false if not
12
- * @throws if used outside of an xstate-tree root
13
- */
14
- function useIsRouteActive(...routes) {
5
+ function useIsRouteActive(...args) {
15
6
  const activeRouteEvents = (0, providers_1.useActiveRouteEvents)();
16
7
  if (!activeRouteEvents) {
17
8
  throw new Error("useIsRouteActive must be used within a RoutingContext. Are you using it outside of an xstate-tree Root?");
18
9
  }
10
+ let routes;
11
+ let predicate;
12
+ if (args.length === 2 &&
13
+ Array.isArray(args[0]) &&
14
+ typeof args[1] === "function") {
15
+ routes = args[0];
16
+ predicate = args[1];
17
+ }
18
+ else {
19
+ routes = args;
20
+ }
19
21
  return activeRouteEvents.some((activeRouteEvent) => {
20
- return routes.some((route) => activeRouteEvent.type === route.event);
22
+ const matches = routes.some((route) => activeRouteEvent.type === route.event);
23
+ if (!matches)
24
+ return false;
25
+ return predicate
26
+ ? predicate(activeRouteEvent)
27
+ : true;
21
28
  });
22
29
  }
23
30
  exports.useIsRouteActive = useIsRouteActive;
@@ -180,6 +180,7 @@ export declare function buildRootComponent(machine: AnyXstateTreeMachine, routin
180
180
  basePath: string;
181
181
  getPathName?: () => string;
182
182
  getQueryString?: () => string;
183
+ shouldBlockActiveRouteUpdate?: (event: RoutingEvent<any>) => boolean;
183
184
  }): {
184
185
  (): JSX.Element | null;
185
186
  rootMachine: AnyXstateTreeMachine;
@@ -352,6 +353,13 @@ declare type IsEmptyObject<Obj, ExcludeOptional extends boolean = false> = undef
352
353
  never
353
354
  ] ? true : false;
354
355
 
356
+ /**
357
+ * @public
358
+ * Predicate invoked with the matching active route event to decide whether the
359
+ * route should be considered active.
360
+ */
361
+ declare type IsRouteActivePredicate<TRoutes extends AnyRoute[]> = (event: RoutingEvent<TRoutes[number]>) => boolean;
362
+
355
363
  /**
356
364
  * @public
357
365
  *
@@ -818,6 +826,20 @@ export declare function useActiveRouteEvents(): {
818
826
  */
819
827
  export declare function useIsRouteActive(...routes: AnyRoute[]): boolean;
820
828
 
829
+ /**
830
+ * @public
831
+ * Accepts an array of Routes and a predicate. Returns true if any of the
832
+ * routes is currently active AND the predicate returns true when called with
833
+ * the matching active route event.
834
+ *
835
+ * If used outside of a RoutingContext, an error will be thrown.
836
+ * @param routes - the routes to check
837
+ * @param predicate - called with the matching active route event; return true to treat the route as active
838
+ * @returns true if any route is active and the predicate returns true, false otherwise
839
+ * @throws if used outside of an xstate-tree root
840
+ */
841
+ export declare function useIsRouteActive<TRoutes extends AnyRoute[]>(routes: [...TRoutes], predicate: IsRouteActivePredicate<TRoutes>): boolean;
842
+
821
843
  /**
822
844
  * @public
823
845
  * Accepts a single Route and returns true if the route is currently active and marked as an index route.
package/lib/xstateTree.js CHANGED
@@ -331,7 +331,7 @@ function buildRootComponent(machine, routing) {
331
331
  };
332
332
  }, [activeRoute]);
333
333
  (0, react_2.useEffect)(() => {
334
- var _a, _b;
334
+ var _a, _b, _c;
335
335
  if (routing) {
336
336
  const { getPathName = () => routing.history.location.pathname, getQueryString = () => routing.history.location.search, } = routing;
337
337
  const initialMeta = {
@@ -341,8 +341,12 @@ function buildRootComponent(machine, routing) {
341
341
  const queryString = getQueryString();
342
342
  const result = (0, routing_1.handleLocationChange)(routing.routes, routing.basePath, getPathName(), getQueryString(), initialMeta);
343
343
  if (result) {
344
- setActiveRouteEvents(result.events);
345
- setActiveRoute({ ...result.matchedRoute });
344
+ const matchedEvent = result.events[result.events.length - 1];
345
+ const block = ((_c = routing.shouldBlockActiveRouteUpdate) === null || _c === void 0 ? void 0 : _c.call(routing, matchedEvent)) === true;
346
+ if (!block) {
347
+ setActiveRouteEvents(result.events);
348
+ setActiveRoute({ ...result.matchedRoute });
349
+ }
346
350
  }
347
351
  // Hack to ensure the initial location doesn't have undefined state
348
352
  // It's not supposed to, but it does for some reason
@@ -355,11 +359,15 @@ function buildRootComponent(machine, routing) {
355
359
  (0, react_2.useEffect)(() => {
356
360
  if (routing) {
357
361
  const unsub = routing.history.listen((location) => {
358
- var _a;
362
+ var _a, _b;
359
363
  const result = (0, routing_1.handleLocationChange)(routing.routes, routing.basePath, location.pathname, location.search, (_a = location.state) === null || _a === void 0 ? void 0 : _a.meta);
360
364
  if (result) {
361
- setActiveRouteEvents(result.events);
362
- setActiveRoute({ ...result.matchedRoute });
365
+ const matchedEvent = result.events[result.events.length - 1];
366
+ const block = ((_b = routing.shouldBlockActiveRouteUpdate) === null || _b === void 0 ? void 0 : _b.call(routing, matchedEvent)) === true;
367
+ if (!block) {
368
+ setActiveRouteEvents(result.events);
369
+ setActiveRoute({ ...result.matchedRoute });
370
+ }
363
371
  }
364
372
  });
365
373
  return () => {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@koordinates/xstate-tree",
3
3
  "main": "lib/index.js",
4
4
  "types": "lib/xstate-tree.d.ts",
5
- "version": "4.8.1",
5
+ "version": "4.10.0",
6
6
  "license": "MIT",
7
7
  "description": "Build UIs with Actors using xstate and React",
8
8
  "keywords": [