1 | (function (global, factory) {
|
2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
|
3 | typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
|
4 | (global = global || self, factory(global.CuriReactDOM = {}, global.React));
|
5 | }(this, function (exports, React) { 'use strict';
|
6 |
|
7 | React = React && React.hasOwnProperty('default') ? React['default'] : React;
|
8 |
|
9 | var key = {
|
10 | router: null,
|
11 | response: null,
|
12 | navigation: null
|
13 | };
|
14 | var context = React.createContext(key);
|
15 | var Provider = context.Provider, Curious = context.Consumer;
|
16 |
|
17 | function curiProvider(router) {
|
18 | function initialState() {
|
19 | var _a = router.current(), response = _a.response, navigation = _a.navigation;
|
20 | return {
|
21 | router: router,
|
22 | response: response,
|
23 | navigation: navigation
|
24 | };
|
25 | }
|
26 | return function Router(props) {
|
27 | var _a = React.useState(initialState), state = _a[0], setState = _a[1];
|
28 | React.useEffect(function () {
|
29 | var removed = false;
|
30 | var stopResponding = router.observe(function (emitted) {
|
31 | if (!removed) {
|
32 | setState(emitted);
|
33 | }
|
34 | }, { initial: false });
|
35 | return function () {
|
36 | removed = true;
|
37 | stopResponding();
|
38 | };
|
39 | }, []);
|
40 | return React.createElement(Provider, { value: state }, props.children);
|
41 | };
|
42 | }
|
43 |
|
44 | function useCuri() {
|
45 | return React.useContext(context);
|
46 | }
|
47 |
|
48 | function useActive(props) {
|
49 | var _a = useCuri(), router = _a.router, response = _a.response;
|
50 | if (process.env.NODE_ENV !== "production") {
|
51 | if (!router.route.active) {
|
52 | throw new Error("You are attempting to use the \"active\" route interaction, but have not included it in your Curi router.\n\nimport curi from \"@curi/router\";\nimport active from \"@curi/route-active\";\n\nconst router = curi(history, routes, {\n route: [active()]\n});");
|
53 | }
|
54 | }
|
55 | var isActive = router.route.active(props.name, response, {
|
56 | params: props.params,
|
57 | partial: props.partial,
|
58 | locationCheck: props.locationCheck
|
59 | });
|
60 | return isActive;
|
61 | }
|
62 |
|
63 | function useBlock(active, fn) {
|
64 | var router = useCuri().router;
|
65 | React.useEffect(function () {
|
66 | if (active) {
|
67 | router.history.confirmWith(fn);
|
68 | return function () {
|
69 | router.history.removeConfirmation();
|
70 | };
|
71 | }
|
72 | }, [active, fn]);
|
73 | }
|
74 |
|
75 | function useLocation(props) {
|
76 | var router = useCuri().router;
|
77 | var pathname = React.useMemo(function () {
|
78 | return props.name ? router.route.pathname(props.name, props.params) : "";
|
79 | }, [
|
80 | props.name
|
81 | ].concat(Object.keys(props.params || {}).map(function (key) { return props.params[key]; })));
|
82 | return {
|
83 | pathname: pathname,
|
84 | hash: props.hash,
|
85 | query: props.query,
|
86 | state: props.state
|
87 | };
|
88 | }
|
89 |
|
90 | function useHref(props) {
|
91 | var location = useLocation(props);
|
92 | var router = useCuri().router;
|
93 | return router.history.toHref(location);
|
94 | }
|
95 |
|
96 | function useNavigating() {
|
97 | var router = useCuri().router;
|
98 | var _a = React.useState(undefined), cancel = _a[0], setCancel = _a[1];
|
99 | var _b = React.useState(false), removed = _b[0], setRemoved = _b[1];
|
100 | React.useEffect(function () {
|
101 | return function () {
|
102 | setRemoved(true);
|
103 | };
|
104 | }, []);
|
105 | React.useEffect(function () {
|
106 | return router.cancel(function (cancelFn) {
|
107 | if (!removed) {
|
108 | setCancel(function () { return cancelFn; });
|
109 | }
|
110 | });
|
111 | }, []);
|
112 | return cancel;
|
113 | }
|
114 |
|
115 | function defaultCanNavigate() {
|
116 | return true;
|
117 | }
|
118 | function useNavigationHandler(props, setNavigating, canNavigate) {
|
119 | if (canNavigate === void 0) { canNavigate = defaultCanNavigate; }
|
120 | var router = useCuri().router;
|
121 | var cancel = React.useRef(undefined);
|
122 | function handler(event) {
|
123 | if (props.onNav) {
|
124 | props.onNav(event);
|
125 | }
|
126 | if (canNavigate(event, props.forward)) {
|
127 | event.preventDefault();
|
128 | var cancelled = void 0, finished = void 0;
|
129 |
|
130 | if (typeof props.children === "function") {
|
131 | cancelled = finished = function () {
|
132 | cancel.current = undefined;
|
133 | setNavigating(false);
|
134 | };
|
135 | setNavigating(true);
|
136 | }
|
137 | cancel.current = router.navigate({
|
138 | method: props.method || "ANCHOR",
|
139 | name: props.name,
|
140 | params: props.params,
|
141 | query: props.query,
|
142 | state: props.state,
|
143 | hash: props.hash,
|
144 | cancelled: cancelled,
|
145 | finished: finished
|
146 | });
|
147 | }
|
148 | }
|
149 | return { handler: handler, cancel: cancel };
|
150 | }
|
151 |
|
152 | function useNavigationFocus(ref, props) {
|
153 | if (props === void 0) { props = {}; }
|
154 | var response = useCuri().response;
|
155 | React.useEffect(function () {
|
156 | var ele = ref.current;
|
157 | if (ele === null) {
|
158 | if (process.env.NODE_ENV !== "production") {
|
159 | console.warn("There is no element to focus. Did you forget to add the ref to an element?");
|
160 | }
|
161 | return;
|
162 | }
|
163 | if (props.preserve && ele.contains(document.activeElement)) {
|
164 | return;
|
165 | }
|
166 | if (process.env.NODE_ENV !== "production") {
|
167 | if (!ele.hasAttribute("tabIndex") && ele.tabIndex === -1) {
|
168 | console.warn('The component that is passed the ref must have a "tabIndex" prop or be focusable by default in order to be focused. ' +
|
169 | "Otherwise, the document's <body> will be focused instead.");
|
170 | }
|
171 | }
|
172 | var _a = props.preventScroll, preventScroll = _a === void 0 ? false : _a;
|
173 | var timeout = setTimeout(function () {
|
174 |
|
175 | ele.focus({ preventScroll: preventScroll });
|
176 | });
|
177 | return function () {
|
178 | clearTimeout(timeout);
|
179 | };
|
180 | }, [response]);
|
181 | }
|
182 |
|
183 | |
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | var __assign = function() {
|
199 | __assign = Object.assign || function __assign(t) {
|
200 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
201 | s = arguments[i];
|
202 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
203 | }
|
204 | return t;
|
205 | };
|
206 | return __assign.apply(this, arguments);
|
207 | };
|
208 |
|
209 | function canNavigate(event, forward) {
|
210 | return (!event.defaultPrevented &&
|
211 | event.button === 0 &&
|
212 | !(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) &&
|
213 | (!forward || !forward.target));
|
214 | }
|
215 |
|
216 | var HookLink = React.forwardRef(function (props, ref) {
|
217 | var _a = React.useState(false), navigating = _a[0], setNavigating = _a[1];
|
218 | var href = useHref(props);
|
219 | var _b = useNavigationHandler(props, setNavigating, canNavigate), handler = _b.handler, cancel = _b.cancel;
|
220 | React.useEffect(function () {
|
221 | return function () {
|
222 | if (cancel.current) {
|
223 | cancel.current();
|
224 | }
|
225 | };
|
226 | }, []);
|
227 | var _c = props.anchor, Anchor = _c === void 0 ? "a" : _c, children = props.children, forward = props.forward;
|
228 | return (
|
229 |
|
230 | React.createElement(Anchor, __assign({ onClick: handler, href: href, ref: ref }, forward), typeof children === "function"
|
231 | ? children(navigating)
|
232 | : children));
|
233 | });
|
234 |
|
235 | exports.Link = HookLink;
|
236 | exports.useNavigationFocus = useNavigationFocus;
|
237 | exports.curiProvider = curiProvider;
|
238 | exports.Curious = Curious;
|
239 | exports.useCuri = useCuri;
|
240 | exports.useActive = useActive;
|
241 | exports.useBlock = useBlock;
|
242 | exports.useLocation = useLocation;
|
243 | exports.useHref = useHref;
|
244 | exports.useNavigating = useNavigating;
|
245 | exports.useNavigationHandler = useNavigationHandler;
|
246 |
|
247 | Object.defineProperty(exports, '__esModule', { value: true });
|
248 |
|
249 | }));
|