Skip to content

Instantly share code, notes, and snippets.

@lemonmade
Created November 29, 2018 17:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lemonmade/f3e0effffaa1068df18400e1777f2305 to your computer and use it in GitHub Desktop.
Save lemonmade/f3e0effffaa1068df18400e1777f2305 to your computer and use it in GitHub Desktop.
// in @shopify/polaris-adapter
enum Action {
Replace,
Augment,
Ignore,
}
type Behavior<Props> =
| {action: Action.Ignore}
| {
action: Action.Replace | Action.Augment;
perform(props: Props): React.ReactNode;
};
enum Feature {
PageHeader,
Modal,
Toast,
}
interface PageHeaderProps {}
interface ModalProps {
open: boolean;
}
interface ToastProps {}
type PropsForFeature<F extends Feature> = F extends Feature.PageHeader
? PageHeaderProps
: F extends Feature.Modal
? ModalProps
: F extends Feature.Toast
? ToastProps
: never;
interface Adapter {
behaviorForFeature<F extends Feature>(
feature: F,
): Behavior<PropsForFeature<F>>;
}
const {Provider, Consumer} = React.createContext<Adapter | undefined>(
undefined,
);
function PolarisAdapter({
adapter,
children,
}: {
adapter: Adapter;
children: React.ReactNode;
}) {
return <Provider value={adapter}>{children}</Provider>;
}
// in @shopify/app-bridge-react or w/e
const adapter: Adapter = {
behaviorForFeature<F extends Feature>(feature: F) {
if (feature === Feature.Modal) {
return {
action: Action.Replace,
perform(props: PropsForFeature<typeof feature>) {
return <AppBridgeModal {...props} />;
},
};
}
return {
action: Action.Ignore,
};
},
};
// All the app bridge stuff moves here
export function AppBridge({forceRedirect, apiKey, children}) {
return <PolarisAdapter adapter={adapter}>{children}</PolarisAdapter>;
}
// in @shopify/polaris
// in Modal for example
function Modal(props) {
return (
<Consumer>
{(adapter) => {
let adapterMarkup = null;
if (adapter) {
const behavior = adapter.behaviorForFeature(Feature.Modal);
if (behavior.action === Action.Replace) {
return behavior.perform(props);
} else if (behavior.action === Action.Augment) {
adapterMarkup = behavior.perform(props);
}
}
return (
<>
{adapterMarkup}
<RegularModalStuff />
</>
);
}}
</Consumer>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment