@django-bridge/react 0.3.2 → 0.4.0-rc.1
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/dist/index.d.ts +31 -21
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { ReactNode, ReactElement, FunctionComponent, Context } from 'react';
|
|
2
2
|
import Telepath from 'telepath-unpack';
|
|
3
3
|
|
|
4
|
+
interface Metadata {
|
|
5
|
+
title: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
4
8
|
type MessageLevel = "info" | "success" | "warning" | "error";
|
|
5
9
|
interface TextMessage {
|
|
6
10
|
level: MessageLevel;
|
|
@@ -12,30 +16,30 @@ interface HTMLMessage {
|
|
|
12
16
|
}
|
|
13
17
|
type Message = TextMessage | HTMLMessage;
|
|
14
18
|
interface ReloadResponse {
|
|
15
|
-
|
|
19
|
+
action: "reload";
|
|
16
20
|
}
|
|
17
21
|
interface RedirectResponse {
|
|
18
|
-
|
|
22
|
+
action: "redirect";
|
|
19
23
|
path: string;
|
|
20
24
|
}
|
|
21
25
|
interface RenderResponse {
|
|
22
|
-
|
|
26
|
+
action: "render";
|
|
23
27
|
overlay: boolean;
|
|
24
|
-
|
|
28
|
+
metadata: Metadata;
|
|
25
29
|
view: string;
|
|
26
30
|
props: Record<string, unknown>;
|
|
27
31
|
context: Record<string, unknown>;
|
|
28
32
|
messages: Message[];
|
|
29
33
|
}
|
|
30
34
|
interface CloseOverlayResponse {
|
|
31
|
-
|
|
35
|
+
action: "close-overlay";
|
|
32
36
|
messages: Message[];
|
|
33
37
|
}
|
|
34
38
|
interface ServerErrorResponse {
|
|
35
|
-
|
|
39
|
+
action: "server-error";
|
|
36
40
|
}
|
|
37
41
|
interface NetworkErrorResponse {
|
|
38
|
-
|
|
42
|
+
action: "network-error";
|
|
39
43
|
}
|
|
40
44
|
type DjangoBridgeResponse = ReloadResponse | RedirectResponse | RenderResponse | CloseOverlayResponse | ServerErrorResponse | NetworkErrorResponse;
|
|
41
45
|
|
|
@@ -103,22 +107,10 @@ interface FormProps extends React.HTMLProps<HTMLFormElement> {
|
|
|
103
107
|
}
|
|
104
108
|
declare function Form({ children, onSubmit: callerOnSubmit, isDirty: isInitiallyDirty, disableDirtyCheck, ...props }: FormProps): ReactElement;
|
|
105
109
|
|
|
106
|
-
interface DirtyForm {
|
|
107
|
-
isDirty: boolean;
|
|
108
|
-
requestUnload: () => Promise<unknown>;
|
|
109
|
-
unloadRequested: boolean;
|
|
110
|
-
unloadBlocked: boolean;
|
|
111
|
-
confirmUnload: () => void;
|
|
112
|
-
cancelUnload: () => void;
|
|
113
|
-
unloadConfirmed: boolean;
|
|
114
|
-
}
|
|
115
|
-
declare const DirtyFormContext: React.Context<DirtyForm>;
|
|
116
|
-
declare function DirtyFormMarker(): React.ReactElement;
|
|
117
|
-
|
|
118
110
|
interface Frame<Props = Record<string, unknown>> {
|
|
119
111
|
id: number;
|
|
120
112
|
path: string;
|
|
121
|
-
|
|
113
|
+
metadata: Metadata;
|
|
122
114
|
view: string;
|
|
123
115
|
props: Props;
|
|
124
116
|
context: Record<string, unknown>;
|
|
@@ -135,10 +127,28 @@ interface NavigationController {
|
|
|
135
127
|
refreshProps: () => Promise<void>;
|
|
136
128
|
}
|
|
137
129
|
|
|
130
|
+
interface RenderFrameProps {
|
|
131
|
+
config: Config;
|
|
132
|
+
frame: Frame;
|
|
133
|
+
}
|
|
134
|
+
declare function RenderFrame({ config, frame }: RenderFrameProps): ReactElement;
|
|
135
|
+
|
|
136
|
+
interface DirtyForm {
|
|
137
|
+
isDirty: boolean;
|
|
138
|
+
requestUnload: () => Promise<unknown>;
|
|
139
|
+
unloadRequested: boolean;
|
|
140
|
+
unloadBlocked: boolean;
|
|
141
|
+
confirmUnload: () => void;
|
|
142
|
+
cancelUnload: () => void;
|
|
143
|
+
unloadConfirmed: boolean;
|
|
144
|
+
}
|
|
145
|
+
declare const DirtyFormContext: React.Context<DirtyForm>;
|
|
146
|
+
declare function DirtyFormMarker(): React.ReactElement;
|
|
147
|
+
|
|
138
148
|
interface AppProps {
|
|
139
149
|
config: Config;
|
|
140
150
|
initialResponse: DjangoBridgeResponse | JSON;
|
|
141
151
|
}
|
|
142
152
|
declare function App({ config, initialResponse }: AppProps): ReactElement;
|
|
143
153
|
|
|
144
|
-
export { App, type AppProps, BuildLinkElement, Config, type DirtyForm, DirtyFormContext, DirtyFormMarker, Form, FormSubmissionStatus, FormWidgetChangeNotificationContext, type Frame, Link, type Message, MessagesContext, type Navigation, NavigationContext, type NavigationController, OverlayContext, type DjangoBridgeResponse as Response, buildLinkElement };
|
|
154
|
+
export { App, type AppProps, BuildLinkElement, Config, type DirtyForm, DirtyFormContext, DirtyFormMarker, Form, FormSubmissionStatus, FormWidgetChangeNotificationContext, type Frame, Link, type Message, MessagesContext, type Metadata, type Navigation, NavigationContext, type NavigationController, OverlayContext, RenderFrame, type DjangoBridgeResponse as Response, buildLinkElement };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var fe=Object.create;var X=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ye=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var xe=(e,o)=>{for(var t in o)X(e,t,{get:o[t],enumerable:!0})},ce=(e,o,t,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of he(o))!Re.call(e,n)&&n!==t&&X(e,n,{get:()=>o[n],enumerable:!(s=Ce(o,n))||s.enumerable});return e};var k=(e,o,t)=>(t=e!=null?fe(ye(e)):{},ce(o||!e||!e.__esModule?X(t,"default",{value:e,enumerable:!0}):t,e)),we=e=>ce(X({},"__esModule",{value:!0}),e);var ke={};xe(ke,{App:()=>Fe,BuildLinkElement:()=>te,Config:()=>A,DirtyFormContext:()=>b,DirtyFormMarker:()=>V,Form:()=>oe,FormSubmissionStatus:()=>$,FormWidgetChangeNotificationContext:()=>Y,Link:()=>ue,MessagesContext:()=>B,NavigationContext:()=>D,OverlayContext:()=>G,buildLinkElement:()=>ee});module.exports=we(ke);var F=k(require("react"));var _=k(require("react"));var x=k(require("react")),U=require("react/jsx-runtime"),Q=x.default.createContext(()=>{}),b=x.default.createContext({isDirty:!1,requestUnload:()=>Promise.resolve(),unloadRequested:!1,unloadBlocked:!1,confirmUnload:()=>{},cancelUnload:()=>{},unloadConfirmed:!1});function Z({handleBrowserUnload:e=!1,children:o}){let[t,s]=x.default.useState(!1),[n,a]=x.default.useState({cb:()=>{}}),[p,g]=x.default.useState(!1),[c,v]=x.default.useState(!1),d=x.default.useRef(null),h=()=>d.current&&!!d.current.querySelector("div.dirty-form-marker")||!1;x.default.useEffect(()=>{if(e&&c){let m="This page has unsaved changes.",l=R=>h()?(R.returnValue=m,m):"";return window.addEventListener("beforeunload",l),()=>{window.removeEventListener("beforeunload",l)}}return()=>{}},[e,c]);let y=x.default.useContext(Q),u=x.default.useCallback(()=>{v(h()),y()},[y]),i=x.default.useMemo(()=>({isDirty:c,requestUnload:()=>c&&h()?(s(!0),new Promise(m=>{a({cb:m})})):Promise.resolve(),unloadRequested:t,unloadBlocked:c&&t,confirmUnload:()=>{t&&(g(!0),n.cb(),s(!1),a({cb:()=>{}}))},cancelUnload:()=>{t&&(s(!1),a({cb:()=>{}}))},unloadConfirmed:p}),[c,n,p,t]);return(0,U.jsx)("div",{ref:d,children:(0,U.jsx)(Q.Provider,{value:u,children:(0,U.jsx)(b.Provider,{value:i,children:o})})})}function V(){let e=x.default.useContext(Q);return x.default.useEffect(e),(0,U.jsx)("div",{className:"dirty-form-marker",style:{display:"none"}})}var O=k(require("react")),G=O.default.createContext({overlay:!1,closeRequested:!1,requestClose:()=>{console.error("OverlayContext.requestClose() called from outside an overlay")},onCloseCompleted:()=>{console.error("OverlayContext.onCloseCompleted() called from outside an overlay")}}),D=O.default.createContext({frameId:0,path:"/",props:{},context:{},navigate:()=>(console.error("navigate() called from outside a Django Bridge Browser"),Promise.resolve()),replacePath:()=>{console.error("replacePath() called from outside a Django Bridge Browser")},submitForm:()=>(console.error("submitForm() called from outside a Django Bridge Browser"),Promise.resolve()),openOverlay:()=>{throw console.error("openOverlay() called from outside a Django Bridge Browser"),new Error("Modal cannot be opened here")},refreshProps:()=>(console.error("refreshProps() called from outside a Django Bridge Browser"),Promise.resolve())}),Y=O.default.createContext(()=>{}),$=O.default.createContext(!1),B=O.default.createContext({messages:[],pushMessage:()=>{}});var E=require("react/jsx-runtime");function Pe({config:e,navigationController:o,openOverlay:t}){let{currentFrame:s,navigate:n,replacePath:a,submitForm:p,refreshProps:g}=o,{isDirty:c,requestUnload:v,cancelUnload:d}=_.default.useContext(b),h=_.default.useMemo(()=>({frameId:s.id,path:s.path,props:s.props,context:s.context,navigate:(i,m={})=>!c||m.skipDirtyFormCheck===!0?(m.skipDirtyFormCheck===!0&&d(),n(i,m.pushState)):v().then(()=>n(i,m.pushState)),replacePath:a,submitForm:p,openOverlay:t,refreshProps:g}),[s,a,p,t,c,v,d,n,g]),y=e.views.get(s.view);if(!y)return(0,E.jsxs)("p",{children:["Unknown view '",s.view,"'"]});let u=(0,E.jsx)(y,{...s.props});return e.contextProviders.forEach((i,m)=>{u=(0,E.jsx)(i.Provider,{value:s.context[m],children:u})}),(0,E.jsx)(D.Provider,{value:h,children:(0,E.jsx)("div",{children:u},s.id)})}var J=Pe;async function q(e,o){let t,s={"X-Requested-With":"DjangoBridge"};o&&(s["X-DjangoBridge-Overlay"]="true");try{t=await fetch(e,{headers:s})}catch{return{status:"network-error"}}return t.status===500?{status:"server-error"}:t.headers.get("X-DjangoBridge-Status")?t.json():{status:"reload"}}async function de(e,o,t){let s,n={"X-Requested-With":"DjangoBridge"};t&&(n["X-DjangoBridge-Overlay"]="true");try{s=await fetch(e,{method:"post",headers:n,body:o})}catch{return{status:"network-error"}}return s.status===500?{status:"server-error"}:s.headers.get("X-DjangoBridge-Status")?s.json():{status:"reload"}}var C=require("react");var z=1;function K(e,o,t,s,n={}){z+=1;let[a,p]=(0,C.useState)({id:z,path:s,title:"Loading",view:"loading",props:{},context:{}}),g=(0,C.useCallback)((r,f,w,P,M,N,H=!0,ge=!0)=>{let ne=a.id,se=w!==a.view||ge;if(se&&(z+=1,ne=z),!e&&(document.title=f,H)){let ie=0,ve=window.scrollY,le=window.history?.state;le?.prevPath===r&&(ie=le.prevScrollPosition??0),window.history.pushState({prevPath:window.location.pathname,prevScrollPosition:ve},"",r),window.scrollTo(0,ie)}let ae={id:ne,path:r,title:f,view:w,props:P,context:M};p(ae),n.onNavigation&&n.onNavigation(ae,se,N)},[n,a.id,a.view,e]),[c,v]=(0,C.useState)(null),d=(0,C.useCallback)((r,f,w=!0,P=!1)=>{if(r.status==="reload")if(!e)window.location.href=f;else return e.handleResponse(r,f);else{if(r.status==="redirect")return v(r.path),Promise.resolve();if(r.status==="render"){if(e&&!r.overlay)return e.handleResponse(r,f);let M=o(r.props),N=o(r.context),H=!P;H&&r.view===a.view&&a.shouldReloadCallback&&(H=a.shouldReloadCallback(f,M)),g(f,r.title,r.view,M,N,r.messages,w,H)}else if(r.status==="close-overlay")n.onOverlayClose&&n.onOverlayClose(r.messages);else{if(r.status==="server-error")return n.onServerError&&n.onServerError("server"),Promise.reject();if(r.status==="network-error")return n.onServerError&&n.onServerError("network"),Promise.reject()}}return Promise.resolve()},[n,a,e,g,o]),h=(0,C.useRef)(1),y=(0,C.useRef)(1),u=(0,C.useCallback)(async(r,f,w,P=!1)=>{h.current+=1;let M=h.current,N=await r();M<y.current||(y.current=M,N!==null&&await d(N,f,w,P))},[d]),i=(0,C.useCallback)((r,f=!0)=>{let w=r;if(!r.startsWith("/")){let P=new URL(r);if(P.origin!==window.location.origin)return window.location.href=r,Promise.resolve();w=P.pathname+P.search}return u(()=>q(w,!!e),w,f)},[u,e]),m=(0,C.useCallback)((r,f)=>{r===a.id&&(a.path=f,e||history.replaceState({},"",a.path))},[a,e]),l=(0,C.useCallback)((r,f)=>u(()=>de(r,f,!!e),r,!0),[u,e]),R=(0,C.useCallback)(()=>u(()=>q(a.path,!!e),a.path,!1,!0),[a.path,u,e]);return(0,C.useEffect)(()=>{d(t,s,!1)},[]),(0,C.useEffect)(()=>{c&&(v(null),i(c))},[i,c]),{parent:e,currentFrame:a,isLoading:a.view==="loading",handleResponse:d,navigate:i,replacePath:m,submitForm:l,refreshProps:R}}var I=k(require("react"));var me=require("react/jsx-runtime");function ee({children:e,href:o,skipDirtyFormCheck:t=!1,...s},{navigate:n},a){return(0,me.jsx)("a",{onClick:g=>{o&&(g.preventDefault(),n(o,{skipDirtyFormCheck:t}))},href:o||"#",ref:a,...s,children:e})}var te=I.default.createContext(ee),be=I.default.forwardRef((e,o)=>{let t=I.default.useContext(D);return I.default.useContext(te)(e,t,o)}),ue=be;var pe=k(require("telepath-unpack")),A=class{views;contextProviders;telepathRegistry;constructor(){this.views=new Map,this.contextProviders=new Map,this.telepathRegistry=new pe.default,this.addAdapter("Date",Date)}addView=(o,t)=>(this.views.set(o,t),this);addContextProvider=(o,t)=>(this.contextProviders.set(o,t),this);addAdapter=(o,t)=>(this.telepathRegistry.register(o,t),this);unpack=o=>this.telepathRegistry.unpack(o)};var L=k(require("react"));var j=require("react/jsx-runtime");function oe({children:e,onSubmit:o,isDirty:t=!1,disableDirtyCheck:s=!1,...n}){let{submitForm:a,navigate:p}=L.default.useContext(D),[g,c]=L.default.useState(!1),[v,d]=L.default.useState(t),{cancelUnload:h}=L.default.useContext(b),y=i=>{if(v&&h(),!(o&&(o(i),i.defaultPrevented))&&i.target instanceof HTMLFormElement){if(g){i.preventDefault();return}let m=new FormData(i.target);if(i.nativeEvent instanceof SubmitEvent&&i.nativeEvent.submitter){let{submitter:l}=i.nativeEvent;(l instanceof HTMLButtonElement||l instanceof HTMLInputElement)&&l.name&&l.value&&m.set(l.name,l.value)}if(i.target.method==="post")i.preventDefault(),c(!0),a(i.target.action,m).catch(()=>c(!1));else if(i.target.method==="get"){i.preventDefault();let l=Array.from(m.entries()).map(r=>`${encodeURIComponent(r[0])}=${encodeURIComponent(r[1])}`).join("&"),R=i.target.action+(i.target.action.indexOf("?")===-1?"?":"&")+l;c(!0),p(R).catch(()=>c(!1))}}},u=L.default.useCallback(()=>{d(!0)},[]);return(0,j.jsxs)("form",{onSubmit:y,...n,children:[v&&!s&&(0,j.jsx)(V,{}),(0,j.jsx)($.Provider,{value:g,children:(0,j.jsx)(Y.Provider,{value:u,children:e})})]})}var W=k(require("react"));var T=require("react/jsx-runtime");function re({config:e,initialResponse:o,initialPath:t,parentNavigationContoller:s,render:n,requestClose:a,closeRequested:p,onCloseCompleted:g,onServerError:c}){let{pushMessage:v}=W.default.useContext(B),d=K(s,e.unpack,o,t,{onNavigation:(i,m,l)=>{l.forEach(v)},onOverlayClose:i=>{i.forEach(v),a()},onServerError:c}),h=W.default.useContext(b),y=W.default.useCallback(({skipDirtyFormCheck:i=!1}={})=>{!i&&h.isDirty?h.requestUnload().then(()=>a()):a()},[h,a]),u=W.default.useMemo(()=>({overlay:!0,closeRequested:p,requestClose:y,onCloseCompleted:g}),[p,g,y]);return d.isLoading?(0,T.jsx)(T.Fragment,{}):(0,T.jsx)(G.Provider,{value:u,children:n((0,T.jsx)(J,{config:e,navigationController:d,openOverlay:()=>{}}))})}var S=require("react/jsx-runtime");function Fe({config:e,initialResponse:o}){let[t,s]=F.default.useState([]),n=F.default.useCallback(l=>{s(t.concat([l]))},[t]),a=F.default.useCallback(l=>{l==="server"?n({level:"error",text:"A server error occurred. Please try again later."}):l==="network"&&n({level:"error",text:"A network error occurred. Please check your internet connection or try again later."})},[n]),[p,g]=F.default.useState(null),[c,v]=F.default.useState(!1),d=F.default.useRef(null),h=(l,R,r)=>{R&&(v(!0),d.current=null),R?s(r):r.forEach(n)},y=window.location.pathname+window.location.search+window.location.hash,u=K(null,e.unpack,o,y,{onNavigation:h,onServerError:a});F.default.useEffect(()=>{let l=document.querySelector(".django-bridge-load");l instanceof HTMLElement&&(l.classList.add("django-bridge-load--hidden"),setTimeout(()=>{l.remove()},200));let R=()=>{u.navigate(document.location.pathname,!1)};return window.addEventListener("popstate",R),()=>{window.removeEventListener("popstate",R)}},[]);let i=async(l,R,{onClose:r}={})=>{let f=await q(l,!0);r&&(d.current=r),v(!1),g({render:R,initialResponse:f,initialPath:l})},m=F.default.useMemo(()=>({messages:t,pushMessage:n}),[t,n]);return(0,S.jsx)(Z,{handleBrowserUnload:!0,children:(0,S.jsxs)(B.Provider,{value:m,children:[p&&(0,S.jsx)(Z,{children:(0,S.jsx)(re,{config:e,initialResponse:p.initialResponse,initialPath:p.initialPath,parentNavigationContoller:u,render:l=>p.render(l),requestClose:()=>v(!0),closeRequested:c,onCloseCompleted:()=>{g(null),v(!1),d.current&&(d.current(),d.current=null)},onServerError:a})}),!u.isLoading&&(0,S.jsx)(J,{config:e,navigationController:u,openOverlay:(l,R,r)=>void i(l,R,r)})]})})}0&&(module.exports={App,BuildLinkElement,Config,DirtyFormContext,DirtyFormMarker,Form,FormSubmissionStatus,FormWidgetChangeNotificationContext,Link,MessagesContext,NavigationContext,OverlayContext,buildLinkElement});
|
|
1
|
+
"use strict";var he=Object.create;var X=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var Pe=(e,o)=>{for(var t in o)X(e,t,{get:o[t],enumerable:!0})},me=(e,o,t,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of ye(o))!we.call(e,n)&&n!==t&&X(e,n,{get:()=>o[n],enumerable:!(a=Re(o,n))||a.enumerable});return e};var k=(e,o,t)=>(t=e!=null?he(xe(e)):{},me(o||!e||!e.__esModule?X(t,"default",{value:e,enumerable:!0}):t,e)),be=e=>me(X({},"__esModule",{value:!0}),e);var Ee={};Pe(Ee,{App:()=>Me,BuildLinkElement:()=>re,Config:()=>A,DirtyFormContext:()=>b,DirtyFormMarker:()=>V,Form:()=>ne,FormSubmissionStatus:()=>$,FormWidgetChangeNotificationContext:()=>Y,Link:()=>ue,MessagesContext:()=>O,NavigationContext:()=>D,OverlayContext:()=>G,RenderFrame:()=>J,buildLinkElement:()=>te});module.exports=be(Ee);var F=k(require("react"));var oe=k(require("react"));var y=k(require("react")),U=require("react/jsx-runtime"),_=y.default.createContext(()=>{}),b=y.default.createContext({isDirty:!1,requestUnload:()=>Promise.resolve(),unloadRequested:!1,unloadBlocked:!1,confirmUnload:()=>{},cancelUnload:()=>{},unloadConfirmed:!1});function ee({handleBrowserUnload:e=!1,children:o}){let[t,a]=y.default.useState(!1),[n,i]=y.default.useState({cb:()=>{}}),[p,u]=y.default.useState(!1),[c,g]=y.default.useState(!1),d=y.default.useRef(null),C=()=>d.current&&!!d.current.querySelector("div.dirty-form-marker")||!1;y.default.useEffect(()=>{if(e&&c){let x="This page has unsaved changes.",s=R=>C()?(R.returnValue=x,x):"";return window.addEventListener("beforeunload",s),()=>{window.removeEventListener("beforeunload",s)}}return()=>{}},[e,c]);let h=y.default.useContext(_),m=y.default.useCallback(()=>{g(C()),h()},[h]),l=y.default.useMemo(()=>({isDirty:c,requestUnload:()=>c&&C()?(a(!0),new Promise(x=>{i({cb:x})})):Promise.resolve(),unloadRequested:t,unloadBlocked:c&&t,confirmUnload:()=>{t&&(u(!0),n.cb(),a(!1),i({cb:()=>{}}))},cancelUnload:()=>{t&&(a(!1),i({cb:()=>{}}))},unloadConfirmed:p}),[c,n,p,t]);return(0,U.jsx)("div",{ref:d,children:(0,U.jsx)(_.Provider,{value:m,children:(0,U.jsx)(b.Provider,{value:l,children:o})})})}function V(){let e=y.default.useContext(_);return y.default.useEffect(e),(0,U.jsx)("div",{className:"dirty-form-marker",style:{display:"none"}})}var S=k(require("react")),G=S.default.createContext({overlay:!1,closeRequested:!1,requestClose:()=>{console.error("OverlayContext.requestClose() called from outside an overlay")},onCloseCompleted:()=>{console.error("OverlayContext.onCloseCompleted() called from outside an overlay")}}),D=S.default.createContext({frameId:0,path:"/",props:{},context:{},navigate:()=>(console.error("navigate() called from outside a Django Bridge Browser"),Promise.resolve()),replacePath:()=>{console.error("replacePath() called from outside a Django Bridge Browser")},submitForm:()=>(console.error("submitForm() called from outside a Django Bridge Browser"),Promise.resolve()),openOverlay:()=>{throw console.error("openOverlay() called from outside a Django Bridge Browser"),new Error("Modal cannot be opened here")},refreshProps:()=>(console.error("refreshProps() called from outside a Django Bridge Browser"),Promise.resolve())}),Y=S.default.createContext(()=>{}),$=S.default.createContext(!1),O=S.default.createContext({messages:[],pushMessage:()=>{}});var B=require("react/jsx-runtime");function Fe({config:e,frame:o}){let t=e.views.get(o.view);if(!t)return(0,B.jsxs)("p",{children:["Unknown view '",o.view,"'"]});let a=(0,B.jsx)(t,{...o.props});return e.contextProviders.forEach((n,i)=>{a=(0,B.jsx)(n.Provider,{value:o.context[i],children:a})}),(0,B.jsx)("div",{children:a},o.id)}var J=Fe;var z=require("react/jsx-runtime");function ke({config:e,navigationController:o,openOverlay:t}){let{currentFrame:a,navigate:n,replacePath:i,submitForm:p,refreshProps:u}=o,{isDirty:c,requestUnload:g,cancelUnload:d}=oe.default.useContext(b),C=oe.default.useMemo(()=>({frameId:a.id,path:a.path,props:a.props,context:a.context,navigate:(h,m={})=>!c||m.skipDirtyFormCheck===!0?(m.skipDirtyFormCheck===!0&&d(),n(h,m.pushState)):g().then(()=>n(h,m.pushState)),replacePath:i,submitForm:p,openOverlay:t,refreshProps:u}),[a,i,p,t,c,g,d,n,u]);return(0,z.jsx)(D.Provider,{value:C,children:(0,z.jsx)("div",{children:(0,z.jsx)(J,{config:e,frame:a})},a.id)})}var K=ke;async function q(e,o){let t,a={"X-Requested-With":"DjangoBridge"};o&&(a["X-DjangoBridge-Overlay"]="true");try{t=await fetch(e,{headers:a})}catch{return{action:"network-error"}}return t.status===500?{action:"server-error"}:t.headers.get("X-DjangoBridge-Action")?t.json():{action:"reload"}}async function pe(e,o,t){let a,n={"X-Requested-With":"DjangoBridge"};t&&(n["X-DjangoBridge-Overlay"]="true");try{a=await fetch(e,{method:"post",headers:n,body:o})}catch{return{action:"network-error"}}return a.status===500?{action:"server-error"}:a.headers.get("X-DjangoBridge-Action")?a.json():{action:"reload"}}var v=require("react");var Q=1;function Z(e,o,t,a,n={}){Q+=1;let[i,p]=(0,v.useState)({id:Q,path:a,metadata:{title:"Loading"},view:"loading",props:{},context:{}}),u=(0,v.useCallback)((r,f,w,P,M,N,H=!0,ve=!0)=>{let ie=i.id,se=w!==i.view||ve;if(se&&(Q+=1,ie=Q),!e&&(document.title=f.title,H)){let ce=0,Ce=window.scrollY,de=window.history?.state;de?.prevPath===r&&(ce=de.prevScrollPosition??0),window.history.pushState({prevPath:window.location.pathname,prevScrollPosition:Ce},"",r),window.scrollTo(0,ce)}let le={id:ie,path:r,metadata:f,view:w,props:P,context:M};p(le),n.onNavigation&&n.onNavigation(le,se,N)},[n,i.id,i.view,e]),[c,g]=(0,v.useState)(null),d=(0,v.useCallback)((r,f,w=!0,P=!1)=>{if(r.action==="reload")if(!e)window.location.href=f;else return e.handleResponse(r,f);else{if(r.action==="redirect")return g(r.path),Promise.resolve();if(r.action==="render"){if(e&&!r.overlay)return e.handleResponse(r,f);let M=o(r.props),N=o(r.context),H=!P;H&&r.view===i.view&&i.shouldReloadCallback&&(H=i.shouldReloadCallback(f,M)),u(f,r.metadata,r.view,M,N,r.messages,w,H)}else if(r.action==="close-overlay")n.onOverlayClose&&n.onOverlayClose(r.messages);else{if(r.action==="server-error")return n.onServerError&&n.onServerError("server"),Promise.reject();if(r.action==="network-error")return n.onServerError&&n.onServerError("network"),Promise.reject()}}return Promise.resolve()},[n,i,e,u,o]),C=(0,v.useRef)(1),h=(0,v.useRef)(1),m=(0,v.useCallback)(async(r,f,w,P=!1)=>{C.current+=1;let M=C.current,N=await r();M<h.current||(h.current=M,N!==null&&await d(N,f,w,P))},[d]),l=(0,v.useCallback)((r,f=!0)=>{let w=r;if(!r.startsWith("/")){let P=new URL(r);if(P.origin!==window.location.origin)return window.location.href=r,Promise.resolve();w=P.pathname+P.search}return m(()=>q(w,!!e),w,f)},[m,e]),x=(0,v.useCallback)((r,f)=>{r===i.id&&(i.path=f,e||history.replaceState({},"",i.path))},[i,e]),s=(0,v.useCallback)((r,f)=>m(()=>pe(r,f,!!e),r,!0),[m,e]),R=(0,v.useCallback)(()=>m(()=>q(i.path,!!e),i.path,!1,!0),[i.path,m,e]);return(0,v.useEffect)(()=>{d(t,a,!1)},[]),(0,v.useEffect)(()=>{c&&(g(null),l(c))},[l,c]),{parent:e,currentFrame:i,isLoading:i.view==="loading",handleResponse:d,navigate:l,replacePath:x,submitForm:s,refreshProps:R}}var I=k(require("react"));var ge=require("react/jsx-runtime");function te({children:e,href:o,skipDirtyFormCheck:t=!1,...a},{navigate:n},i){return(0,ge.jsx)("a",{onClick:u=>{o&&(u.preventDefault(),n(o,{skipDirtyFormCheck:t}))},href:o||"#",ref:i,...a,children:e})}var re=I.default.createContext(te),De=I.default.forwardRef((e,o)=>{let t=I.default.useContext(D);return I.default.useContext(re)(e,t,o)}),ue=De;var fe=k(require("telepath-unpack")),A=class{views;contextProviders;telepathRegistry;constructor(){this.views=new Map,this.contextProviders=new Map,this.telepathRegistry=new fe.default,this.addAdapter("Date",Date)}addView=(o,t)=>(this.views.set(o,t),this);addContextProvider=(o,t)=>(this.contextProviders.set(o,t),this);addAdapter=(o,t)=>(this.telepathRegistry.register(o,t),this);unpack=o=>this.telepathRegistry.unpack(o)};var L=k(require("react"));var j=require("react/jsx-runtime");function ne({children:e,onSubmit:o,isDirty:t=!1,disableDirtyCheck:a=!1,...n}){let{submitForm:i,navigate:p}=L.default.useContext(D),[u,c]=L.default.useState(!1),[g,d]=L.default.useState(t),{cancelUnload:C}=L.default.useContext(b),h=l=>{if(g&&C(),!(o&&(o(l),l.defaultPrevented))&&l.target instanceof HTMLFormElement){if(u){l.preventDefault();return}let x=new FormData(l.target);if(l.nativeEvent instanceof SubmitEvent&&l.nativeEvent.submitter){let{submitter:s}=l.nativeEvent;(s instanceof HTMLButtonElement||s instanceof HTMLInputElement)&&s.name&&s.value&&x.set(s.name,s.value)}if(l.target.method==="post")l.preventDefault(),c(!0),i(l.target.action,x).catch(()=>c(!1));else if(l.target.method==="get"){l.preventDefault();let s=Array.from(x.entries()).map(r=>`${encodeURIComponent(r[0])}=${encodeURIComponent(r[1])}`).join("&"),R=l.target.action+(l.target.action.indexOf("?")===-1?"?":"&")+s;c(!0),p(R).catch(()=>c(!1))}}},m=L.default.useCallback(()=>{d(!0)},[]);return(0,j.jsxs)("form",{onSubmit:h,...n,children:[g&&!a&&(0,j.jsx)(V,{}),(0,j.jsx)($.Provider,{value:u,children:(0,j.jsx)(Y.Provider,{value:m,children:e})})]})}var W=k(require("react"));var T=require("react/jsx-runtime");function ae({config:e,initialResponse:o,initialPath:t,parentNavigationContoller:a,render:n,requestClose:i,closeRequested:p,onCloseCompleted:u,onServerError:c}){let{pushMessage:g}=W.default.useContext(O),d=Z(a,e.unpack,o,t,{onNavigation:(l,x,s)=>{s.forEach(g)},onOverlayClose:l=>{l.forEach(g),i()},onServerError:c}),C=W.default.useContext(b),h=W.default.useCallback(({skipDirtyFormCheck:l=!1}={})=>{!l&&C.isDirty?C.requestUnload().then(()=>i()):i()},[C,i]),m=W.default.useMemo(()=>({overlay:!0,closeRequested:p,requestClose:h,onCloseCompleted:u}),[p,u,h]);return d.isLoading?(0,T.jsx)(T.Fragment,{}):(0,T.jsx)(G.Provider,{value:m,children:n((0,T.jsx)(K,{config:e,navigationController:d,openOverlay:()=>{}}))})}var E=require("react/jsx-runtime");function Me({config:e,initialResponse:o}){let[t,a]=F.default.useState([]),n=F.default.useCallback(s=>{a(t.concat([s]))},[t]),i=F.default.useCallback(s=>{s==="server"?n({level:"error",text:"A server error occurred. Please try again later."}):s==="network"&&n({level:"error",text:"A network error occurred. Please check your internet connection or try again later."})},[n]),[p,u]=F.default.useState(null),[c,g]=F.default.useState(!1),d=F.default.useRef(null),C=(s,R,r)=>{R&&(g(!0),d.current=null),R?a(r):r.forEach(n)},h=window.location.pathname+window.location.search+window.location.hash,m=Z(null,e.unpack,o,h,{onNavigation:C,onServerError:i});F.default.useEffect(()=>{let s=document.querySelector(".django-bridge-load");s instanceof HTMLElement&&(s.classList.add("django-bridge-load--hidden"),setTimeout(()=>{s.remove()},200));let R=()=>{m.navigate(document.location.pathname,!1)};return window.addEventListener("popstate",R),()=>{window.removeEventListener("popstate",R)}},[]);let l=async(s,R,{onClose:r}={})=>{let f=await q(s,!0);r&&(d.current=r),g(!1),u({render:R,initialResponse:f,initialPath:s})},x=F.default.useMemo(()=>({messages:t,pushMessage:n}),[t,n]);return(0,E.jsx)(ee,{handleBrowserUnload:!0,children:(0,E.jsxs)(O.Provider,{value:x,children:[p&&(0,E.jsx)(ee,{children:(0,E.jsx)(ae,{config:e,initialResponse:p.initialResponse,initialPath:p.initialPath,parentNavigationContoller:m,render:s=>p.render(s),requestClose:()=>g(!0),closeRequested:c,onCloseCompleted:()=>{u(null),g(!1),d.current&&(d.current(),d.current=null)},onServerError:i})}),!m.isLoading&&(0,E.jsx)(K,{config:e,navigationController:m,openOverlay:(s,R,r)=>void l(s,R,r)})]})})}0&&(module.exports={App,BuildLinkElement,Config,DirtyFormContext,DirtyFormMarker,Form,FormSubmissionStatus,FormWidgetChangeNotificationContext,Link,MessagesContext,NavigationContext,OverlayContext,RenderFrame,buildLinkElement});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@django-bridge/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-rc.1",
|
|
4
4
|
"description": "The simple way to build Django applications with modern React frontends",
|
|
5
5
|
"repository": "https://github.com/django-bridge/django-bridge",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"react": "^18.2.0",
|
|
30
|
-
"telepath-unpack": "^0.0.
|
|
30
|
+
"telepath-unpack": "^0.0.4"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^12.0.0",
|