-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
581f17f
commit f022ddc
Showing
3 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import {render} from 'preact'; | ||
import EmbedButton from 'src/components/embed-button'; | ||
import {CreateButtonInSelectorProps} from 'src/components/embed-button/types'; | ||
import {CreateWidgetInSelectorProps} from 'src/components/widget/types'; | ||
import {WidgetConfig} from 'src/components/widget/types/WidgetConfig'; | ||
import {loadFonts} from 'src/loadFonts'; | ||
import {FormLoader} from 'src/loaders/FormLoader'; | ||
import {WidgetLoader} from 'src/loaders/Widgetloader'; | ||
import resetcss from 'src/resetCss'; | ||
|
||
interface GlobalExport { | ||
createButton: (options: CreateButtonInSelectorProps) => void; | ||
createWidget: (options: CreateWidgetInSelectorProps) => void; | ||
setOptions: (options: Partial<WidgetConfig>) => void; | ||
showWidget: () => void; | ||
} | ||
|
||
declare const window: Window & { | ||
everyDotOrgDonateButton?: GlobalExport; | ||
}; | ||
|
||
export default function formOnlyMode() { | ||
const DEFAULT_HASH_OPEN_WIDGET = 'donate'; | ||
|
||
const baseOptions: Partial<WidgetConfig> = {}; | ||
const options = { | ||
show: false, | ||
openAt: DEFAULT_HASH_OPEN_WIDGET | ||
}; | ||
const instanceOptions: Partial<WidgetConfig> = {}; | ||
|
||
const getNode = (element?: Element, selector?: string) => | ||
element ? element : selector ? document.querySelector(selector) : null; | ||
|
||
loadFonts(); | ||
|
||
/** | ||
* Helper function to debug donate button issues | ||
*/ | ||
function log(...messages: unknown[]): void { | ||
console.info('Every.org Donate Button:', ...messages); | ||
} | ||
|
||
let formContainer: HTMLElement; | ||
let formMountPoint: HTMLElement; | ||
|
||
const mountWidget = () => { | ||
const shadowWidgetWrapper = document.createElement('div'); | ||
shadowWidgetWrapper.id = 'shadow-wrapper'; | ||
formContainer.append(shadowWidgetWrapper); | ||
|
||
formMountPoint = document.createElement('div'); | ||
shadowWidgetWrapper.attachShadow({mode: 'open'}).append(formMountPoint); | ||
|
||
const everyStyles: HTMLStyleElement | null = | ||
document.querySelector('#every-styles'); | ||
|
||
if (everyStyles) { | ||
const rules = Object.values(everyStyles.sheet?.cssRules ?? {}) | ||
.map((rule) => rule.cssText) | ||
.join('\n'); | ||
|
||
const everyShadowStyles = document.createElement('style'); | ||
everyShadowStyles.id = 'every-shadow-styles'; | ||
everyShadowStyles.innerHTML = resetcss + rules; | ||
|
||
formMountPoint.append(everyShadowStyles); | ||
} | ||
}; | ||
|
||
const renderWidget = () => { | ||
if (!formMountPoint) { | ||
mountWidget(); | ||
} | ||
|
||
const finalOptions: Partial<WidgetConfig> = { | ||
...options, | ||
...baseOptions, | ||
...instanceOptions | ||
}; | ||
|
||
render(<FormLoader options={finalOptions} />, formMountPoint); | ||
}; | ||
|
||
function setOptions(newOptions: Partial<WidgetConfig>) { | ||
Object.assign(baseOptions, newOptions); | ||
renderWidget(); | ||
} | ||
|
||
const createWidgetInSelector = ({ | ||
element, | ||
selector, | ||
...options | ||
}: CreateWidgetInSelectorProps) => { | ||
if (!element && !selector) { | ||
log('createWidget():', 'must provide element or selector'); | ||
} | ||
|
||
const node = getNode(element, selector); | ||
if (!node) { | ||
log('createWidget():', 'element or selector not found'); | ||
return; | ||
} | ||
|
||
if (!options.nonprofitSlug) { | ||
log('createWidget():', 'must provide nonprofitSlug'); | ||
return; | ||
} | ||
|
||
formContainer = node as HTMLElement; | ||
|
||
Object.assign(baseOptions, options); | ||
renderWidget(); | ||
}; | ||
|
||
window.everyDotOrgDonateButton = { | ||
createButton: () => { | ||
log( | ||
'createButton function is not available in formOnlyMode. Use createWidget instead.' | ||
); | ||
}, | ||
showWidget: () => { | ||
log( | ||
'showWidget function is not available in formOnlyMode. Use createWidget instead.' | ||
); | ||
}, | ||
setOptions, | ||
createWidget: createWidgetInSelector | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import {PaymentProcess} from 'src/components/widget/components/PaymentProcess'; | ||
import {ContextProvider} from 'src/components/widget/context'; | ||
import {useConfigContext} from 'src/components/widget/hooks/useConfigContext'; | ||
import {useFundraiser} from 'src/components/widget/hooks/useFundraiser'; | ||
import {useNonprofit} from 'src/components/widget/hooks/useNonprofit'; | ||
import {LoadingIcon} from 'src/components/widget/icons/LoadingIcon'; | ||
import {FundraiserFetching} from 'src/components/widget/types/Fundraiser'; | ||
import {NonprofitFetching} from 'src/components/widget/types/Nonprofit'; | ||
import {WidgetConfig} from 'src/components/widget/types/WidgetConfig'; | ||
|
||
interface FormLoaderProps { | ||
options: Partial<WidgetConfig>; | ||
} | ||
|
||
export const FormLoader = ({options = {}}: FormLoaderProps) => { | ||
return ( | ||
<ContextProvider | ||
options={options} | ||
hide={() => { | ||
// do nothing | ||
}} | ||
> | ||
<From /> | ||
</ContextProvider> | ||
); | ||
}; | ||
|
||
const From = () => { | ||
const {fundraiserSlug} = useConfigContext(); | ||
const findraiser = useFundraiser(); | ||
const nonprofit = useNonprofit(); | ||
|
||
if ( | ||
nonprofit === NonprofitFetching || | ||
(fundraiserSlug && findraiser === FundraiserFetching) | ||
) { | ||
return <LoadingIcon size={24} />; | ||
} | ||
|
||
return <PaymentProcess />; | ||
}; |