remix-toploader
Version:
Remix and React Router Top Loading bar using NProgress.
1 lines • 8 kB
Source Map (JSON)
{"version":3,"sources":["../src/remix-loader.tsx","../src/loader.tsx","../src/router-loader.tsx","../src/index.tsx"],"sourcesContent":["import { useFetchers, useNavigation } from \"@remix-run/react\";\r\nimport Loader from \"./loader\";\r\nimport * as React from \"react\";\r\nexport const RemixTopLoader = () => {\r\n return <Loader useFetchers={useFetchers} useNavigation={useNavigation} />;\r\n};\r\n","import * as React from \"react\";\r\nimport * as NProgress from \"nprogress\";\r\n\r\nexport type LoaderProps = {\r\n /**\r\n * Color for the TopLoader.\r\n * @default \"#29d\"\r\n */\r\n color?: string;\r\n /**\r\n * The initial position for the TopLoader in percentage, 0.08 is 8%.\r\n * @default 0.08\r\n */\r\n initialPosition?: number;\r\n /**\r\n * The increament delay speed in milliseconds.\r\n * @default 200\r\n */\r\n crawlSpeed?: number;\r\n /**\r\n * The height for the TopLoader in pixels (px).\r\n * @default 3\r\n */\r\n height?: number;\r\n /**\r\n * Auto increamenting behaviour for the TopLoader.\r\n * @default true\r\n */\r\n crawl?: boolean;\r\n /**\r\n * To show spinner or not.\r\n * @default true\r\n */\r\n showSpinner?: boolean;\r\n /**\r\n * Animation settings using easing (a CSS easing string).\r\n * @default \"ease\"\r\n */\r\n easing?: string;\r\n /**\r\n * Animation speed in ms for the TopLoader.\r\n * @default 200\r\n */\r\n speed?: number;\r\n /**\r\n * Defines a shadow for the TopLoader.\r\n * @default \"0 0 10px ${color},0 0 5px ${color}\"\r\n *\r\n * @ you can disable it by setting it to `false`\r\n */\r\n shadow?: string | false;\r\n /**\r\n * Defines a template for the TopLoader.\r\n * @default \"<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div>\r\n * <div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>\"\r\n */\r\n template?: string;\r\n /**\r\n * Defines zIndex for the TopLoader.\r\n * @default 1600\r\n *\r\n */\r\n zIndex?: number;\r\n /**\r\n * To show the TopLoader at bottom.\r\n * @default false\r\n *\r\n */\r\n showAtBottom?: boolean;\r\n /**\r\n * To show the TopLoader for hash anchors.\r\n * @default true\r\n *\r\n */\r\n showForHashAnchor?: boolean;\r\n useNavigation: any;\r\n useFetchers: any;\r\n};\r\n\r\nconst Loader = ({\r\n color = \"#29d\",\r\n height = 3,\r\n showSpinner,\r\n crawl,\r\n crawlSpeed,\r\n initialPosition,\r\n easing,\r\n speed,\r\n shadow,\r\n template,\r\n zIndex = 1600,\r\n showAtBottom = false,\r\n useFetchers,\r\n useNavigation,\r\n}: LoaderProps): React.JSX.Element => {\r\n const transition = useNavigation();\r\n\r\n const fetchers = useFetchers();\r\n const state = React.useMemo<\"idle\" | \"loading\">(\r\n function getGlobalState() {\r\n const states = [\r\n transition.state,\r\n ...fetchers.map((fetcher) => fetcher.state),\r\n ];\r\n if (states.every((state) => state === \"idle\")) return \"idle\";\r\n return \"loading\";\r\n },\r\n [transition.state, fetchers]\r\n );\r\n\r\n const boxShadow =\r\n !shadow && shadow !== undefined\r\n ? \"\"\r\n : shadow\r\n ? `box-shadow:${shadow}`\r\n : `box-shadow:0 0 10px ${color},0 0 5px ${color}`;\r\n\r\n // Check if to show at bottom\r\n const positionStyle = showAtBottom ? \"bottom: 0;\" : \"top: 0;\";\r\n const spinnerPositionStyle = showAtBottom ? \"bottom: 15px;\" : \"top: 15px;\";\r\n\r\n const styles = (\r\n <style>\r\n {`#nprogress{pointer-events:none}#nprogress .bar{background:${color};position:fixed;z-index:${zIndex};${positionStyle}left:0;width:100%;height:${height}px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;${boxShadow};opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translate(0px,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:${zIndex};${spinnerPositionStyle}right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:${color};border-left-color:${color};border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}`}\r\n </style>\r\n );\r\n\r\n React.useEffect(() => {\r\n // and when it's something else it means it's either submitting a form or\r\n // waiting for the loaders of the next location so we start it\r\n NProgress.configure({\r\n showSpinner: showSpinner ?? true,\r\n trickle: crawl ?? true,\r\n trickleSpeed: crawlSpeed ?? 200,\r\n minimum: initialPosition ?? 0.08,\r\n easing: easing ?? \"ease\",\r\n speed: speed ?? 200,\r\n template:\r\n template ??\r\n '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>',\r\n });\r\n if (state === \"loading\") NProgress.start();\r\n // when the state is idle then we can to complete the progress bar\r\n if (state === \"idle\") NProgress.done();\r\n }, [transition.state]);\r\n\r\n return styles;\r\n};\r\nexport default Loader;\r\n","import { useFetchers, useNavigation } from \"react-router\";\r\nimport Loader from \"./loader\";\r\nimport * as React from \"react\";\r\nexport const RouterTopLoader = () => {\r\n return <Loader useFetchers={useFetchers} useNavigation={useNavigation} />;\r\n};\r\n","import { RemixTopLoader } from \"./remix-loader\";\r\nimport { RouterTopLoader } from \"./router-loader\";\r\n\r\nexport { RemixTopLoader, RouterTopLoader };\r\nexport default RemixTopLoader;\r\n"],"mappings":"+EAAA,OAAS,eAAAA,EAAa,iBAAAC,MAAqB,mBCA3C,UAAYC,MAAW,QACvB,UAAYC,MAAe,YA8E3B,IAAMC,EAASC,EAAA,CAAC,CACd,MAAAC,EAAQ,OACR,OAAAC,EAAS,EACT,YAAAC,EACA,MAAAC,EACA,WAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,OAAAC,EAAS,KACT,aAAAC,EAAe,GACf,YAAAC,EACA,cAAAC,CACF,IAAsC,CACpC,IAAMC,EAAaD,EAAc,EAE3BE,EAAWH,EAAY,EACvBI,EAAc,UAClBjB,EAAA,UAA0B,CAKxB,MAJe,CACbe,EAAW,MACX,GAAGC,EAAS,IAAKE,GAAYA,EAAQ,KAAK,CAC5C,EACW,MAAOD,GAAUA,IAAU,MAAM,EAAU,OAC/C,SACT,EAPA,kBAQA,CAACF,EAAW,MAAOC,CAAQ,CAC7B,EAEMG,EACJ,CAACV,GAAUA,IAAW,OAClB,GACAA,EACA,cAAcA,CAAM,GACpB,uBAAuBR,CAAK,YAAYA,CAAK,GAM7CmB,EACJ,gBAAC,aACE,6DAA6DnB,CAAK,2BAA2BU,CAAM,IALlFC,EAAe,aAAe,SAKqE,4BAA4BV,CAAM,sFAAsFiB,CAAS,oNAAoNR,CAAM,IAJvbC,EAAe,gBAAkB,YAI8a,kIAAkIX,CAAK,sBAAsBA,CAAK,weAC5oB,EAGF,OAAM,YAAU,IAAM,CAGV,YAAU,CAClB,YAAaE,GAAA,KAAAA,EAAe,GAC5B,QAASC,GAAA,KAAAA,EAAS,GAClB,aAAcC,GAAA,KAAAA,EAAc,IAC5B,QAASC,GAAA,KAAAA,EAAmB,IAC5B,OAAQC,GAAA,KAAAA,EAAU,OAClB,MAAOC,GAAA,KAAAA,EAAS,IAChB,SACEE,GAAA,KAAAA,EACA,qIACJ,CAAC,EACGO,IAAU,WAAqB,QAAM,EAErCA,IAAU,QAAkB,OAAK,CACvC,EAAG,CAACF,EAAW,KAAK,CAAC,EAEdK,CACT,EApEe,UAqERC,EAAQtB,EDlJf,UAAYuB,MAAW,QAChB,IAAMC,EAAiBC,EAAA,IACrB,gBAACC,EAAA,CAAO,YAAaC,EAAa,cAAeC,EAAe,EAD3C,kBEH9B,OAAS,eAAAC,EAAa,iBAAAC,MAAqB,eAE3C,UAAYC,MAAW,QAChB,IAAMC,EAAkBC,EAAA,IACtB,gBAACC,EAAA,CAAO,YAAaC,EAAa,cAAeC,EAAe,EAD1C,mBCC/B,IAAOC,EAAQC","names":["useFetchers","useNavigation","React","NProgress","Loader","__name","color","height","showSpinner","crawl","crawlSpeed","initialPosition","easing","speed","shadow","template","zIndex","showAtBottom","useFetchers","useNavigation","transition","fetchers","state","fetcher","boxShadow","styles","loader_default","React","RemixTopLoader","__name","loader_default","useFetchers","useNavigation","useFetchers","useNavigation","React","RouterTopLoader","__name","loader_default","useFetchers","useNavigation","src_default","RemixTopLoader"]}