solid-router
Version:
A declarative router for solid-js
215 lines (177 loc) • 4.64 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var dom = require('solid-js/dom');
var history = require('history');
var solidJs = require('solid-js');
var pathToRegexp = require('path-to-regexp');
const _ck$ = ["children"];
const HistoryContext = solidJs.createContext();
function ContextProvider(props) {
const history = props.history;
const [locationSignal, setLocationSignal] = solidJs.createSignal(history.location);
const locationHandler = history.listen(location => {
setLocationSignal(location);
});
solidJs.onCleanup(() => {
locationHandler();
});
return dom.createComponent(HistoryContext.Provider, {
value: {
history,
locationSignal
},
children: () => props.children
}, _ck$);
}
const _ck$$1 = ["children", "history"];
function BrowserContextProvider(props) {
return dom.createComponent(ContextProvider, {
history: () => history.createBrowserHistory(props.options),
children: () => props.children
}, _ck$$1);
}
function getArrayOf(array) {
if (Array.isArray(array)) {
return array;
}
if (!!array) {
return [array];
}
return [];
}
const RouteContext = solidJs.createContext();
function useLocationSignal() {
const {
locationSignal
} = solidJs.useContext(HistoryContext);
return locationSignal;
}
function useRouteMatchSignal(routeOrPath) {
const locationSignal = useLocationSignal();
let route;
if (typeof routeOrPath === 'string') {
route = {
path: routeOrPath,
options: {}
};
} else {
route = routeOrPath;
}
if (!route.path) {
route.path = '*';
}
const matcher = pathToRegexp.match(route.path, route.options);
return () => {
const pathname = locationSignal().pathname;
return matcher(pathname);
};
}
const _ck$$2 = ["children"];
function Router(props) {
const routes = getArrayOf(props.children);
const routeMatchSignals = routes.map(useRouteMatchSignal);
const useFallback = ('fallback' in props);
const evalConditions = solidJs.createMemo(() => {
return routeMatchSignals.reduce((result, matcher, index) => {
if (result.index === -1) {
const match = matcher();
if (match) {
return {
index,
params: match.params
};
}
}
return result;
}, {
index: -1,
params: {}
});
});
return solidJs.suspend(solidJs.createMemo(() => {
const {
index,
params
} = evalConditions();
return solidJs.sample(() => dom.createComponent(RouteContext.Provider, {
value: params,
children: () => index < 0 ? useFallback && props.fallback : routes[index].children
}, _ck$$2));
}));
}
function Route(props) {
return props;
}
function useHistory() {
const {
history
} = solidJs.useContext(HistoryContext);
return history;
}
const _tmpl$ = dom.template(`<a></a>`, 2);
function Link(props) {
const history = useHistory();
function handleClick(e) {
e.preventDefault();
history.push(props.href);
}
return (() => {
const _el$ = _tmpl$.cloneNode(true);
_el$.__click = handleClick;
dom.spread(_el$, props, false, false);
return _el$;
})();
}
dom.delegateEvents(["click"]);
function Redirect(props) {
const history = useHistory();
solidJs.createEffect(() => {
history.push(props.href);
});
return props.children;
}
const _tmpl$$1 = dom.template(`<a></a>`, 2);
function NavLink({
href,
activeClass = '',
className = '',
children,
options,
...props
}) {
const history = useHistory();
const routeMatchSignal = useRouteMatchSignal({
path: href,
options
});
function handleClick(e) {
e.preventDefault();
history.push(href);
}
return solidJs.createMemo(() => {
const isMatched = !!routeMatchSignal();
return solidJs.sample(() => (() => {
const _el$ = _tmpl$$1.cloneNode(true);
_el$.__click = handleClick;
_el$.className = isMatched ? `${className} ${activeClass}` : className;
_el$.setAttribute("href", href);
dom.spread(_el$, props, false, true);
dom.insert(_el$, children);
return _el$;
})());
});
}
dom.delegateEvents(["click"]);
function useParams() {
return solidJs.useContext(RouteContext);
}
exports.ContextProvider = BrowserContextProvider;
exports.Link = Link;
exports.NavLink = NavLink;
exports.Redirect = Redirect;
exports.Route = Route;
exports.Router = Router;
exports.useHistory = useHistory;
exports.useLocationSignal = useLocationSignal;
exports.useParams = useParams;
exports.useRouteMatchSignalCreator = useRouteMatchSignal;