@charmr/oauth-button-web
Version:
A lightweight, framework-agnostic OAuth login button as a custom Web Component. Easily drop it into any HTML, React, Angular, or Vue project.
72 lines (71 loc) • 2.56 kB
JavaScript
import { useController } from '@charmr/oauth-core';
import { isProvider } from '../utils/isProvider';
export class OAuthLoginButtonWeb extends HTMLElement {
static get observedAttributes() {
return ['provider', 'client-id', 'redirect-uri', 'button-text', 'store-provider'];
}
button;
startLogin = () => { };
getProps() {
return {
provider: this.getAttribute('provider'),
clientId: this.getAttribute('client-id') || '',
redirectUri: this.getAttribute('redirect-uri') || '',
buttonText: this.getAttribute('button-text'),
inlineStyle: this.getAttribute('style'),
};
}
constructor() {
super();
this.button = document.createElement('button');
this.appendChild(this.button);
}
connectedCallback() {
this.attachEvents();
this.updateController();
this.render();
}
attributeChangedCallback() {
this.updateController();
this.render();
}
attachEvents() {
this.button.addEventListener('click', () => {
const provider = this.getAttribute('provider');
const shouldStore = this.hasAttribute('store-provider');
if (provider && shouldStore) {
this.rememberProvider(provider);
}
this.startLogin();
});
}
rememberProvider(provider) {
sessionStorage.setItem('oauth_provider', provider);
}
updateController() {
const { provider, clientId, redirectUri } = this.getProps();
if (isProvider(provider)) {
const { startLogin } = useController({
provider,
clientId,
redirectUri,
onSuccess: (res) => {
this.dispatchEvent(new CustomEvent('oauth-success', { detail: res }));
},
onError: (err) => {
this.dispatchEvent(new CustomEvent('oauth-error', { detail: err }));
},
});
this.startLogin = startLogin;
}
else {
console.error(`OAuthLoginButtonWeb: "${provider}" is not a valid provider`);
}
}
render() {
const { provider, buttonText, inlineStyle } = this.getProps();
this.button.textContent = buttonText || `Continue with ${provider || 'OAuth'}`;
this.button.className = this.className || '';
this.button.style.cssText = `${inlineStyle || ''}; width: 100%; height: 100%; display: block;`;
}
}