first
This commit is contained in:
15
packages/components/.editorconfig
Normal file
15
packages/components/.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
||||
26
packages/components/.gitignore
vendored
Normal file
26
packages/components/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
dist/
|
||||
www/
|
||||
loader/
|
||||
|
||||
*~
|
||||
*.sw[mnpcod]
|
||||
*.log
|
||||
*.lock
|
||||
*.tmp
|
||||
*.tmp.*
|
||||
log.txt
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
.stencil/
|
||||
.idea/
|
||||
.vscode/
|
||||
.sass-cache/
|
||||
.versions/
|
||||
node_modules/
|
||||
$RECYCLE.BIN/
|
||||
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
UserInterfaceState.xcuserstate
|
||||
.env
|
||||
13
packages/components/.prettierrc.json
Normal file
13
packages/components/.prettierrc.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false,
|
||||
"jsxSingleQuote": false,
|
||||
"quoteProps": "consistent",
|
||||
"printWidth": 180,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "all",
|
||||
"useTabs": false
|
||||
}
|
||||
49
packages/components/package.json
Normal file
49
packages/components/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "nostr-login-components",
|
||||
"version": "1.0.3",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.js",
|
||||
"es2015": "dist/esm/index.js",
|
||||
"es2017": "dist/esm/index.js",
|
||||
"types": "dist/types/index.d.ts",
|
||||
"collection": "dist/collection/collection-manifest.json",
|
||||
"collection:main": "dist/collection/index.js",
|
||||
"author": "a-fralou",
|
||||
"files": [
|
||||
"dist/",
|
||||
"loader/"
|
||||
],
|
||||
"exports": {
|
||||
".": "./dist/components/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "stencil build --docs --prod && node post-build-plugin.js",
|
||||
"dev": "stencil build --dev --watch --serve",
|
||||
"test": "stencil test --spec --e2e",
|
||||
"test.watch": "stencil test --spec --e2e --watchAll",
|
||||
"generate": "stencil generate",
|
||||
"format": "npx prettier --write src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.20.0",
|
||||
"@stencil/sass": "^3.0.12",
|
||||
"@stencil/store": "^2.0.16",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"qrcode": "^1.5.4",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"tailwindcss-rtl": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.6",
|
||||
"@types/node": "^16.18.11",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"jest": "^29.7.0",
|
||||
"jest-cli": "^29.7.0",
|
||||
"prettier": "^3.2.2",
|
||||
"puppeteer": "21.1.1",
|
||||
"stencil-tailwind-plugin": "^1.8.0",
|
||||
"typescript": "^5.3.3",
|
||||
"workbox-build": "^4.3.1"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
48
packages/components/post-build-plugin.js
Normal file
48
packages/components/post-build-plugin.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const folderPath = './dist/components';
|
||||
const cssFilePath = './dist/components/css.js';
|
||||
let countFileRead = 0;
|
||||
|
||||
// Function to get all JavaScript files in the directory
|
||||
function getFilesInDirectory(dir) {
|
||||
const files = fs.readdirSync(dir);
|
||||
return files.filter(file => file.endsWith('.js')); // Filter out only .js files
|
||||
}
|
||||
|
||||
// Function to process a single file
|
||||
function processFile(filePath, cssContent) {
|
||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
// Replace the CSS variable declarations and import them from css.js
|
||||
const updatedContent = fileContent.replace(/const\s+(\w+Css)\s*=\s*(`[^`]*`|".*?"|'.*?')(?:\s*;|(\s*\/\/.*?))?(?=\s*const|$)/g, (match, varName, varValue) => {
|
||||
// Save CSS variables and their values in cssContent
|
||||
if (countFileRead === 0) {
|
||||
cssContent.push(`export const baseCss = ${varValue};`);
|
||||
countFileRead = countFileRead + 1;
|
||||
}
|
||||
// Return the string with the import from css.js
|
||||
return `import { baseCss } from './css.js';\nconst ${varName} = baseCss;\n`;
|
||||
});
|
||||
|
||||
// Write the modified content back to the file
|
||||
fs.writeFileSync(filePath, updatedContent, 'utf8');
|
||||
}
|
||||
|
||||
// Main function to process all files
|
||||
function main() {
|
||||
const cssContent = [];
|
||||
const files = getFilesInDirectory(folderPath);
|
||||
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(folderPath, file);
|
||||
processFile(filePath, cssContent);
|
||||
});
|
||||
|
||||
// Write collected CSS variables to css.js
|
||||
fs.writeFileSync(cssFilePath, cssContent.join('\n'), 'utf8');
|
||||
console.log('Done! All CSS variables have been moved to css.js.');
|
||||
}
|
||||
|
||||
main();
|
||||
929
packages/components/src/components.d.ts
vendored
Normal file
929
packages/components/src/components.d.ts
vendored
Normal file
@@ -0,0 +1,929 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
/**
|
||||
* This is an autogenerated file created by the Stencil compiler.
|
||||
* It contains typing information for all components that exist in this project.
|
||||
*/
|
||||
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
|
||||
import { AuthMethod, BannerNotify, ConnectionString, Info, NlTheme, RecentType } from "./types/index";
|
||||
import { OptionType } from "./components/nl-select/nl-select";
|
||||
export { AuthMethod, BannerNotify, ConnectionString, Info, NlTheme, RecentType } from "./types/index";
|
||||
export { OptionType } from "./components/nl-select/nl-select";
|
||||
export namespace Components {
|
||||
interface ButtonBase {
|
||||
"darkMode": boolean;
|
||||
"disabled": boolean;
|
||||
"theme": NlTheme;
|
||||
"titleBtn": string;
|
||||
}
|
||||
interface NlAuth {
|
||||
"accounts": Info[];
|
||||
"authMethods": AuthMethod[];
|
||||
"authUrl": string;
|
||||
"bunkers": string;
|
||||
"connectionString": string;
|
||||
"connectionStringServices": ConnectionString[];
|
||||
"darkMode": boolean;
|
||||
"error": string;
|
||||
"hasExtension": boolean;
|
||||
"hasOTP": boolean;
|
||||
"iframeUrl": string;
|
||||
"isLoading": boolean;
|
||||
"isLoadingExtension": boolean;
|
||||
"isOTP": boolean;
|
||||
"localSignup": boolean;
|
||||
"njumpIframe": string;
|
||||
"recents": RecentType[];
|
||||
"signupNjump": boolean;
|
||||
"startScreen": string;
|
||||
"theme": NlTheme;
|
||||
"welcomeDescription": string;
|
||||
"welcomeTitle": string;
|
||||
}
|
||||
interface NlBanner {
|
||||
"accounts": Info[];
|
||||
"darkMode": boolean;
|
||||
"hiddenMode": boolean;
|
||||
"isLoading": boolean;
|
||||
"isOpen": boolean;
|
||||
"notify": BannerNotify | null;
|
||||
"theme": NlTheme;
|
||||
"titleBanner": string;
|
||||
"userInfo": Info | null;
|
||||
}
|
||||
interface NlButton {
|
||||
"darkMode": boolean;
|
||||
"disabled": boolean;
|
||||
"theme": NlTheme;
|
||||
"titleBtn": string;
|
||||
}
|
||||
interface NlChangeAccount {
|
||||
"accounts": Info[];
|
||||
"currentAccount": Info;
|
||||
"darkMode": boolean;
|
||||
"theme": 'default' | 'ocean' | 'lemonade' | 'purple';
|
||||
}
|
||||
interface NlConfirmLogout {
|
||||
"description": string;
|
||||
"titleModal": string;
|
||||
}
|
||||
interface NlConnect {
|
||||
"authMethods": AuthMethod[];
|
||||
"connectionStringServices": ConnectionString[];
|
||||
"hasOTP": boolean;
|
||||
"titleWelcome": string;
|
||||
}
|
||||
interface NlDialog {
|
||||
}
|
||||
interface NlIframe {
|
||||
"description": string;
|
||||
"iframeUrl": string;
|
||||
"titleModal": string;
|
||||
}
|
||||
interface NlImportFlow {
|
||||
"services": ConnectionString[];
|
||||
"titleImport": string;
|
||||
"titleInfo": string;
|
||||
}
|
||||
interface NlInfo {
|
||||
"darkMode": boolean;
|
||||
"theme": NlTheme;
|
||||
}
|
||||
interface NlInfoExtension {
|
||||
}
|
||||
interface NlLoading {
|
||||
"path": string;
|
||||
}
|
||||
interface NlLocalSignup {
|
||||
"description": string;
|
||||
"descriptionNjump": string;
|
||||
"signupNjump": boolean;
|
||||
"titleSignup": string;
|
||||
}
|
||||
interface NlLoginStatus {
|
||||
"info": RecentType | Info | undefined;
|
||||
}
|
||||
interface NlOtpMigrate {
|
||||
"services": ConnectionString[];
|
||||
"textImport": string;
|
||||
"titleImport": string;
|
||||
"titleInfo": string;
|
||||
}
|
||||
interface NlPreviouslyLogged {
|
||||
"accounts": Info[];
|
||||
"description": string;
|
||||
"recents": RecentType[];
|
||||
"titlePage": string;
|
||||
}
|
||||
interface NlSelect {
|
||||
"darkMode": boolean;
|
||||
"options": OptionType[];
|
||||
"selected": number;
|
||||
"theme": 'default' | 'ocean' | 'lemonade' | 'purple';
|
||||
}
|
||||
interface NlSignin {
|
||||
"description": string;
|
||||
"titleLogin": string;
|
||||
}
|
||||
interface NlSigninBunkerUrl {
|
||||
"description": string;
|
||||
"titleLogin": string;
|
||||
}
|
||||
interface NlSigninConnectionString {
|
||||
"connectionString": string;
|
||||
"description": string;
|
||||
"titleLogin": string;
|
||||
}
|
||||
interface NlSigninOtp {
|
||||
"description": string;
|
||||
"descriptionOTP": string;
|
||||
"titleLogin": string;
|
||||
"titleLoginOTP": string;
|
||||
}
|
||||
interface NlSigninReadOnly {
|
||||
"description": string;
|
||||
"titleLogin": string;
|
||||
}
|
||||
interface NlSignup {
|
||||
"bunkers": string;
|
||||
"description": string;
|
||||
"titleSignup": string;
|
||||
}
|
||||
interface NlWelcome {
|
||||
"description": string;
|
||||
"titleWelcome": string;
|
||||
}
|
||||
interface NlWelcomeSignin {
|
||||
"authMethods": AuthMethod[];
|
||||
"hasExtension": boolean;
|
||||
"hasOTP": boolean;
|
||||
"titleWelcome": string;
|
||||
}
|
||||
interface NlWelcomeSignup {
|
||||
"description": string;
|
||||
"titleWelcome": string;
|
||||
}
|
||||
}
|
||||
export interface NlAuthCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlAuthElement;
|
||||
}
|
||||
export interface NlBannerCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlBannerElement;
|
||||
}
|
||||
export interface NlChangeAccountCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlChangeAccountElement;
|
||||
}
|
||||
export interface NlConfirmLogoutCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlConfirmLogoutElement;
|
||||
}
|
||||
export interface NlConnectCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlConnectElement;
|
||||
}
|
||||
export interface NlIframeCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlIframeElement;
|
||||
}
|
||||
export interface NlImportFlowCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlImportFlowElement;
|
||||
}
|
||||
export interface NlLoadingCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlLoadingElement;
|
||||
}
|
||||
export interface NlLocalSignupCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlLocalSignupElement;
|
||||
}
|
||||
export interface NlOtpMigrateCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlOtpMigrateElement;
|
||||
}
|
||||
export interface NlPreviouslyLoggedCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlPreviouslyLoggedElement;
|
||||
}
|
||||
export interface NlSelectCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSelectElement;
|
||||
}
|
||||
export interface NlSigninCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSigninElement;
|
||||
}
|
||||
export interface NlSigninBunkerUrlCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSigninBunkerUrlElement;
|
||||
}
|
||||
export interface NlSigninConnectionStringCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSigninConnectionStringElement;
|
||||
}
|
||||
export interface NlSigninOtpCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSigninOtpElement;
|
||||
}
|
||||
export interface NlSigninReadOnlyCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSigninReadOnlyElement;
|
||||
}
|
||||
export interface NlSignupCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlSignupElement;
|
||||
}
|
||||
export interface NlWelcomeSigninCustomEvent<T> extends CustomEvent<T> {
|
||||
detail: T;
|
||||
target: HTMLNlWelcomeSigninElement;
|
||||
}
|
||||
declare global {
|
||||
interface HTMLButtonBaseElement extends Components.ButtonBase, HTMLStencilElement {
|
||||
}
|
||||
var HTMLButtonBaseElement: {
|
||||
prototype: HTMLButtonBaseElement;
|
||||
new (): HTMLButtonBaseElement;
|
||||
};
|
||||
interface HTMLNlAuthElementEventMap {
|
||||
"nlCloseModal": any;
|
||||
"nlChangeDarkMode": boolean;
|
||||
"nlNostrConnectDefaultCancel": void;
|
||||
}
|
||||
interface HTMLNlAuthElement extends Components.NlAuth, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlAuthElementEventMap>(type: K, listener: (this: HTMLNlAuthElement, ev: NlAuthCustomEvent<HTMLNlAuthElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlAuthElementEventMap>(type: K, listener: (this: HTMLNlAuthElement, ev: NlAuthCustomEvent<HTMLNlAuthElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlAuthElement: {
|
||||
prototype: HTMLNlAuthElement;
|
||||
new (): HTMLNlAuthElement;
|
||||
};
|
||||
interface HTMLNlBannerElementEventMap {
|
||||
"handleNotifyConfirmBanner": string;
|
||||
"handleNotifyConfirmBannerIframe": string;
|
||||
"handleLoginBanner": string;
|
||||
"handleLogoutBanner": string;
|
||||
"handleOpenWelcomeModal": string;
|
||||
"handleConfirmLogout": string;
|
||||
"handleImportModal": string;
|
||||
}
|
||||
interface HTMLNlBannerElement extends Components.NlBanner, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlBannerElementEventMap>(type: K, listener: (this: HTMLNlBannerElement, ev: NlBannerCustomEvent<HTMLNlBannerElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlBannerElementEventMap>(type: K, listener: (this: HTMLNlBannerElement, ev: NlBannerCustomEvent<HTMLNlBannerElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlBannerElement: {
|
||||
prototype: HTMLNlBannerElement;
|
||||
new (): HTMLNlBannerElement;
|
||||
};
|
||||
interface HTMLNlButtonElement extends Components.NlButton, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlButtonElement: {
|
||||
prototype: HTMLNlButtonElement;
|
||||
new (): HTMLNlButtonElement;
|
||||
};
|
||||
interface HTMLNlChangeAccountElementEventMap {
|
||||
"handleOpenWelcomeModal": string;
|
||||
"handleSwitchAccount": Info;
|
||||
}
|
||||
interface HTMLNlChangeAccountElement extends Components.NlChangeAccount, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlChangeAccountElementEventMap>(type: K, listener: (this: HTMLNlChangeAccountElement, ev: NlChangeAccountCustomEvent<HTMLNlChangeAccountElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlChangeAccountElementEventMap>(type: K, listener: (this: HTMLNlChangeAccountElement, ev: NlChangeAccountCustomEvent<HTMLNlChangeAccountElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlChangeAccountElement: {
|
||||
prototype: HTMLNlChangeAccountElement;
|
||||
new (): HTMLNlChangeAccountElement;
|
||||
};
|
||||
interface HTMLNlConfirmLogoutElementEventMap {
|
||||
"handleLogoutBanner": string;
|
||||
"handleBackUpModal": string;
|
||||
"nlCloseModal": any;
|
||||
}
|
||||
interface HTMLNlConfirmLogoutElement extends Components.NlConfirmLogout, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlConfirmLogoutElementEventMap>(type: K, listener: (this: HTMLNlConfirmLogoutElement, ev: NlConfirmLogoutCustomEvent<HTMLNlConfirmLogoutElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlConfirmLogoutElementEventMap>(type: K, listener: (this: HTMLNlConfirmLogoutElement, ev: NlConfirmLogoutCustomEvent<HTMLNlConfirmLogoutElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlConfirmLogoutElement: {
|
||||
prototype: HTMLNlConfirmLogoutElement;
|
||||
new (): HTMLNlConfirmLogoutElement;
|
||||
};
|
||||
interface HTMLNlConnectElementEventMap {
|
||||
"nlNostrConnect": ConnectionString;
|
||||
}
|
||||
interface HTMLNlConnectElement extends Components.NlConnect, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlConnectElementEventMap>(type: K, listener: (this: HTMLNlConnectElement, ev: NlConnectCustomEvent<HTMLNlConnectElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlConnectElementEventMap>(type: K, listener: (this: HTMLNlConnectElement, ev: NlConnectCustomEvent<HTMLNlConnectElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlConnectElement: {
|
||||
prototype: HTMLNlConnectElement;
|
||||
new (): HTMLNlConnectElement;
|
||||
};
|
||||
interface HTMLNlDialogElement extends Components.NlDialog, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlDialogElement: {
|
||||
prototype: HTMLNlDialogElement;
|
||||
new (): HTMLNlDialogElement;
|
||||
};
|
||||
interface HTMLNlIframeElementEventMap {
|
||||
"nlCloseModal": any;
|
||||
}
|
||||
interface HTMLNlIframeElement extends Components.NlIframe, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlIframeElementEventMap>(type: K, listener: (this: HTMLNlIframeElement, ev: NlIframeCustomEvent<HTMLNlIframeElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlIframeElementEventMap>(type: K, listener: (this: HTMLNlIframeElement, ev: NlIframeCustomEvent<HTMLNlIframeElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlIframeElement: {
|
||||
prototype: HTMLNlIframeElement;
|
||||
new (): HTMLNlIframeElement;
|
||||
};
|
||||
interface HTMLNlImportFlowElementEventMap {
|
||||
"nlImportAccount": ConnectionString;
|
||||
"nlExportKeys": void;
|
||||
}
|
||||
interface HTMLNlImportFlowElement extends Components.NlImportFlow, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlImportFlowElementEventMap>(type: K, listener: (this: HTMLNlImportFlowElement, ev: NlImportFlowCustomEvent<HTMLNlImportFlowElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlImportFlowElementEventMap>(type: K, listener: (this: HTMLNlImportFlowElement, ev: NlImportFlowCustomEvent<HTMLNlImportFlowElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlImportFlowElement: {
|
||||
prototype: HTMLNlImportFlowElement;
|
||||
new (): HTMLNlImportFlowElement;
|
||||
};
|
||||
interface HTMLNlInfoElement extends Components.NlInfo, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlInfoElement: {
|
||||
prototype: HTMLNlInfoElement;
|
||||
new (): HTMLNlInfoElement;
|
||||
};
|
||||
interface HTMLNlInfoExtensionElement extends Components.NlInfoExtension, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlInfoExtensionElement: {
|
||||
prototype: HTMLNlInfoExtensionElement;
|
||||
new (): HTMLNlInfoExtensionElement;
|
||||
};
|
||||
interface HTMLNlLoadingElementEventMap {
|
||||
"stopFetchHandler": boolean;
|
||||
"handleContinue": boolean;
|
||||
}
|
||||
interface HTMLNlLoadingElement extends Components.NlLoading, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlLoadingElementEventMap>(type: K, listener: (this: HTMLNlLoadingElement, ev: NlLoadingCustomEvent<HTMLNlLoadingElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlLoadingElementEventMap>(type: K, listener: (this: HTMLNlLoadingElement, ev: NlLoadingCustomEvent<HTMLNlLoadingElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlLoadingElement: {
|
||||
prototype: HTMLNlLoadingElement;
|
||||
new (): HTMLNlLoadingElement;
|
||||
};
|
||||
interface HTMLNlLocalSignupElementEventMap {
|
||||
"nlLocalSignup": string;
|
||||
"nlSignupNjump": void;
|
||||
"fetchHandler": boolean;
|
||||
}
|
||||
interface HTMLNlLocalSignupElement extends Components.NlLocalSignup, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlLocalSignupElementEventMap>(type: K, listener: (this: HTMLNlLocalSignupElement, ev: NlLocalSignupCustomEvent<HTMLNlLocalSignupElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlLocalSignupElementEventMap>(type: K, listener: (this: HTMLNlLocalSignupElement, ev: NlLocalSignupCustomEvent<HTMLNlLocalSignupElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlLocalSignupElement: {
|
||||
prototype: HTMLNlLocalSignupElement;
|
||||
new (): HTMLNlLocalSignupElement;
|
||||
};
|
||||
interface HTMLNlLoginStatusElement extends Components.NlLoginStatus, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlLoginStatusElement: {
|
||||
prototype: HTMLNlLoginStatusElement;
|
||||
new (): HTMLNlLoginStatusElement;
|
||||
};
|
||||
interface HTMLNlOtpMigrateElementEventMap {
|
||||
"nlImportAccount": ConnectionString;
|
||||
}
|
||||
interface HTMLNlOtpMigrateElement extends Components.NlOtpMigrate, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlOtpMigrateElementEventMap>(type: K, listener: (this: HTMLNlOtpMigrateElement, ev: NlOtpMigrateCustomEvent<HTMLNlOtpMigrateElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlOtpMigrateElementEventMap>(type: K, listener: (this: HTMLNlOtpMigrateElement, ev: NlOtpMigrateCustomEvent<HTMLNlOtpMigrateElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlOtpMigrateElement: {
|
||||
prototype: HTMLNlOtpMigrateElement;
|
||||
new (): HTMLNlOtpMigrateElement;
|
||||
};
|
||||
interface HTMLNlPreviouslyLoggedElementEventMap {
|
||||
"nlSwitchAccount": Info;
|
||||
"nlLoginRecentAccount": RecentType;
|
||||
"nlRemoveRecent": RecentType;
|
||||
}
|
||||
interface HTMLNlPreviouslyLoggedElement extends Components.NlPreviouslyLogged, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlPreviouslyLoggedElementEventMap>(type: K, listener: (this: HTMLNlPreviouslyLoggedElement, ev: NlPreviouslyLoggedCustomEvent<HTMLNlPreviouslyLoggedElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlPreviouslyLoggedElementEventMap>(type: K, listener: (this: HTMLNlPreviouslyLoggedElement, ev: NlPreviouslyLoggedCustomEvent<HTMLNlPreviouslyLoggedElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlPreviouslyLoggedElement: {
|
||||
prototype: HTMLNlPreviouslyLoggedElement;
|
||||
new (): HTMLNlPreviouslyLoggedElement;
|
||||
};
|
||||
interface HTMLNlSelectElementEventMap {
|
||||
"selectDomain": string;
|
||||
}
|
||||
interface HTMLNlSelectElement extends Components.NlSelect, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSelectElementEventMap>(type: K, listener: (this: HTMLNlSelectElement, ev: NlSelectCustomEvent<HTMLNlSelectElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSelectElementEventMap>(type: K, listener: (this: HTMLNlSelectElement, ev: NlSelectCustomEvent<HTMLNlSelectElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSelectElement: {
|
||||
prototype: HTMLNlSelectElement;
|
||||
new (): HTMLNlSelectElement;
|
||||
};
|
||||
interface HTMLNlSigninElementEventMap {
|
||||
"nlLogin": string;
|
||||
"nlCheckLogin": string;
|
||||
}
|
||||
interface HTMLNlSigninElement extends Components.NlSignin, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSigninElementEventMap>(type: K, listener: (this: HTMLNlSigninElement, ev: NlSigninCustomEvent<HTMLNlSigninElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSigninElementEventMap>(type: K, listener: (this: HTMLNlSigninElement, ev: NlSigninCustomEvent<HTMLNlSigninElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSigninElement: {
|
||||
prototype: HTMLNlSigninElement;
|
||||
new (): HTMLNlSigninElement;
|
||||
};
|
||||
interface HTMLNlSigninBunkerUrlElementEventMap {
|
||||
"nlLogin": string;
|
||||
"nlCheckLogin": string;
|
||||
}
|
||||
interface HTMLNlSigninBunkerUrlElement extends Components.NlSigninBunkerUrl, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSigninBunkerUrlElementEventMap>(type: K, listener: (this: HTMLNlSigninBunkerUrlElement, ev: NlSigninBunkerUrlCustomEvent<HTMLNlSigninBunkerUrlElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSigninBunkerUrlElementEventMap>(type: K, listener: (this: HTMLNlSigninBunkerUrlElement, ev: NlSigninBunkerUrlCustomEvent<HTMLNlSigninBunkerUrlElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSigninBunkerUrlElement: {
|
||||
prototype: HTMLNlSigninBunkerUrlElement;
|
||||
new (): HTMLNlSigninBunkerUrlElement;
|
||||
};
|
||||
interface HTMLNlSigninConnectionStringElementEventMap {
|
||||
"nlNostrConnectDefault": void;
|
||||
}
|
||||
interface HTMLNlSigninConnectionStringElement extends Components.NlSigninConnectionString, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSigninConnectionStringElementEventMap>(type: K, listener: (this: HTMLNlSigninConnectionStringElement, ev: NlSigninConnectionStringCustomEvent<HTMLNlSigninConnectionStringElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSigninConnectionStringElementEventMap>(type: K, listener: (this: HTMLNlSigninConnectionStringElement, ev: NlSigninConnectionStringCustomEvent<HTMLNlSigninConnectionStringElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSigninConnectionStringElement: {
|
||||
prototype: HTMLNlSigninConnectionStringElement;
|
||||
new (): HTMLNlSigninConnectionStringElement;
|
||||
};
|
||||
interface HTMLNlSigninOtpElementEventMap {
|
||||
"nlLoginOTPUser": string;
|
||||
"nlLoginOTPCode": string;
|
||||
"nlCheckLogin": string;
|
||||
}
|
||||
interface HTMLNlSigninOtpElement extends Components.NlSigninOtp, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSigninOtpElementEventMap>(type: K, listener: (this: HTMLNlSigninOtpElement, ev: NlSigninOtpCustomEvent<HTMLNlSigninOtpElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSigninOtpElementEventMap>(type: K, listener: (this: HTMLNlSigninOtpElement, ev: NlSigninOtpCustomEvent<HTMLNlSigninOtpElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSigninOtpElement: {
|
||||
prototype: HTMLNlSigninOtpElement;
|
||||
new (): HTMLNlSigninOtpElement;
|
||||
};
|
||||
interface HTMLNlSigninReadOnlyElementEventMap {
|
||||
"nlLoginReadOnly": string;
|
||||
"nlCheckLogin": string;
|
||||
}
|
||||
interface HTMLNlSigninReadOnlyElement extends Components.NlSigninReadOnly, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSigninReadOnlyElementEventMap>(type: K, listener: (this: HTMLNlSigninReadOnlyElement, ev: NlSigninReadOnlyCustomEvent<HTMLNlSigninReadOnlyElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSigninReadOnlyElementEventMap>(type: K, listener: (this: HTMLNlSigninReadOnlyElement, ev: NlSigninReadOnlyCustomEvent<HTMLNlSigninReadOnlyElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSigninReadOnlyElement: {
|
||||
prototype: HTMLNlSigninReadOnlyElement;
|
||||
new (): HTMLNlSigninReadOnlyElement;
|
||||
};
|
||||
interface HTMLNlSignupElementEventMap {
|
||||
"nlSignup": string;
|
||||
"nlCheckSignup": string;
|
||||
"fetchHandler": boolean;
|
||||
}
|
||||
interface HTMLNlSignupElement extends Components.NlSignup, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlSignupElementEventMap>(type: K, listener: (this: HTMLNlSignupElement, ev: NlSignupCustomEvent<HTMLNlSignupElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlSignupElementEventMap>(type: K, listener: (this: HTMLNlSignupElement, ev: NlSignupCustomEvent<HTMLNlSignupElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlSignupElement: {
|
||||
prototype: HTMLNlSignupElement;
|
||||
new (): HTMLNlSignupElement;
|
||||
};
|
||||
interface HTMLNlWelcomeElement extends Components.NlWelcome, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlWelcomeElement: {
|
||||
prototype: HTMLNlWelcomeElement;
|
||||
new (): HTMLNlWelcomeElement;
|
||||
};
|
||||
interface HTMLNlWelcomeSigninElementEventMap {
|
||||
"nlLoginExtension": void;
|
||||
}
|
||||
interface HTMLNlWelcomeSigninElement extends Components.NlWelcomeSignin, HTMLStencilElement {
|
||||
addEventListener<K extends keyof HTMLNlWelcomeSigninElementEventMap>(type: K, listener: (this: HTMLNlWelcomeSigninElement, ev: NlWelcomeSigninCustomEvent<HTMLNlWelcomeSigninElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLNlWelcomeSigninElementEventMap>(type: K, listener: (this: HTMLNlWelcomeSigninElement, ev: NlWelcomeSigninCustomEvent<HTMLNlWelcomeSigninElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
var HTMLNlWelcomeSigninElement: {
|
||||
prototype: HTMLNlWelcomeSigninElement;
|
||||
new (): HTMLNlWelcomeSigninElement;
|
||||
};
|
||||
interface HTMLNlWelcomeSignupElement extends Components.NlWelcomeSignup, HTMLStencilElement {
|
||||
}
|
||||
var HTMLNlWelcomeSignupElement: {
|
||||
prototype: HTMLNlWelcomeSignupElement;
|
||||
new (): HTMLNlWelcomeSignupElement;
|
||||
};
|
||||
interface HTMLElementTagNameMap {
|
||||
"button-base": HTMLButtonBaseElement;
|
||||
"nl-auth": HTMLNlAuthElement;
|
||||
"nl-banner": HTMLNlBannerElement;
|
||||
"nl-button": HTMLNlButtonElement;
|
||||
"nl-change-account": HTMLNlChangeAccountElement;
|
||||
"nl-confirm-logout": HTMLNlConfirmLogoutElement;
|
||||
"nl-connect": HTMLNlConnectElement;
|
||||
"nl-dialog": HTMLNlDialogElement;
|
||||
"nl-iframe": HTMLNlIframeElement;
|
||||
"nl-import-flow": HTMLNlImportFlowElement;
|
||||
"nl-info": HTMLNlInfoElement;
|
||||
"nl-info-extension": HTMLNlInfoExtensionElement;
|
||||
"nl-loading": HTMLNlLoadingElement;
|
||||
"nl-local-signup": HTMLNlLocalSignupElement;
|
||||
"nl-login-status": HTMLNlLoginStatusElement;
|
||||
"nl-otp-migrate": HTMLNlOtpMigrateElement;
|
||||
"nl-previously-logged": HTMLNlPreviouslyLoggedElement;
|
||||
"nl-select": HTMLNlSelectElement;
|
||||
"nl-signin": HTMLNlSigninElement;
|
||||
"nl-signin-bunker-url": HTMLNlSigninBunkerUrlElement;
|
||||
"nl-signin-connection-string": HTMLNlSigninConnectionStringElement;
|
||||
"nl-signin-otp": HTMLNlSigninOtpElement;
|
||||
"nl-signin-read-only": HTMLNlSigninReadOnlyElement;
|
||||
"nl-signup": HTMLNlSignupElement;
|
||||
"nl-welcome": HTMLNlWelcomeElement;
|
||||
"nl-welcome-signin": HTMLNlWelcomeSigninElement;
|
||||
"nl-welcome-signup": HTMLNlWelcomeSignupElement;
|
||||
}
|
||||
}
|
||||
declare namespace LocalJSX {
|
||||
interface ButtonBase {
|
||||
"darkMode"?: boolean;
|
||||
"disabled"?: boolean;
|
||||
"theme"?: NlTheme;
|
||||
"titleBtn"?: string;
|
||||
}
|
||||
interface NlAuth {
|
||||
"accounts"?: Info[];
|
||||
"authMethods"?: AuthMethod[];
|
||||
"authUrl"?: string;
|
||||
"bunkers"?: string;
|
||||
"connectionString"?: string;
|
||||
"connectionStringServices"?: ConnectionString[];
|
||||
"darkMode"?: boolean;
|
||||
"error"?: string;
|
||||
"hasExtension"?: boolean;
|
||||
"hasOTP"?: boolean;
|
||||
"iframeUrl"?: string;
|
||||
"isLoading"?: boolean;
|
||||
"isLoadingExtension"?: boolean;
|
||||
"isOTP"?: boolean;
|
||||
"localSignup"?: boolean;
|
||||
"njumpIframe"?: string;
|
||||
"onNlChangeDarkMode"?: (event: NlAuthCustomEvent<boolean>) => void;
|
||||
"onNlCloseModal"?: (event: NlAuthCustomEvent<any>) => void;
|
||||
"onNlNostrConnectDefaultCancel"?: (event: NlAuthCustomEvent<void>) => void;
|
||||
"recents"?: RecentType[];
|
||||
"signupNjump"?: boolean;
|
||||
"startScreen"?: string;
|
||||
"theme"?: NlTheme;
|
||||
"welcomeDescription"?: string;
|
||||
"welcomeTitle"?: string;
|
||||
}
|
||||
interface NlBanner {
|
||||
"accounts"?: Info[];
|
||||
"darkMode"?: boolean;
|
||||
"hiddenMode"?: boolean;
|
||||
"isLoading"?: boolean;
|
||||
"isOpen"?: boolean;
|
||||
"notify"?: BannerNotify | null;
|
||||
"onHandleConfirmLogout"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleImportModal"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleLoginBanner"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleLogoutBanner"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleNotifyConfirmBanner"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleNotifyConfirmBannerIframe"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"onHandleOpenWelcomeModal"?: (event: NlBannerCustomEvent<string>) => void;
|
||||
"theme"?: NlTheme;
|
||||
"titleBanner"?: string;
|
||||
"userInfo"?: Info | null;
|
||||
}
|
||||
interface NlButton {
|
||||
"darkMode"?: boolean;
|
||||
"disabled"?: boolean;
|
||||
"theme"?: NlTheme;
|
||||
"titleBtn"?: string;
|
||||
}
|
||||
interface NlChangeAccount {
|
||||
"accounts"?: Info[];
|
||||
"currentAccount"?: Info;
|
||||
"darkMode"?: boolean;
|
||||
"onHandleOpenWelcomeModal"?: (event: NlChangeAccountCustomEvent<string>) => void;
|
||||
"onHandleSwitchAccount"?: (event: NlChangeAccountCustomEvent<Info>) => void;
|
||||
"theme"?: 'default' | 'ocean' | 'lemonade' | 'purple';
|
||||
}
|
||||
interface NlConfirmLogout {
|
||||
"description"?: string;
|
||||
"onHandleBackUpModal"?: (event: NlConfirmLogoutCustomEvent<string>) => void;
|
||||
"onHandleLogoutBanner"?: (event: NlConfirmLogoutCustomEvent<string>) => void;
|
||||
"onNlCloseModal"?: (event: NlConfirmLogoutCustomEvent<any>) => void;
|
||||
"titleModal"?: string;
|
||||
}
|
||||
interface NlConnect {
|
||||
"authMethods"?: AuthMethod[];
|
||||
"connectionStringServices"?: ConnectionString[];
|
||||
"hasOTP"?: boolean;
|
||||
"onNlNostrConnect"?: (event: NlConnectCustomEvent<ConnectionString>) => void;
|
||||
"titleWelcome"?: string;
|
||||
}
|
||||
interface NlDialog {
|
||||
}
|
||||
interface NlIframe {
|
||||
"description"?: string;
|
||||
"iframeUrl"?: string;
|
||||
"onNlCloseModal"?: (event: NlIframeCustomEvent<any>) => void;
|
||||
"titleModal"?: string;
|
||||
}
|
||||
interface NlImportFlow {
|
||||
"onNlExportKeys"?: (event: NlImportFlowCustomEvent<void>) => void;
|
||||
"onNlImportAccount"?: (event: NlImportFlowCustomEvent<ConnectionString>) => void;
|
||||
"services"?: ConnectionString[];
|
||||
"titleImport"?: string;
|
||||
"titleInfo"?: string;
|
||||
}
|
||||
interface NlInfo {
|
||||
"darkMode"?: boolean;
|
||||
"theme"?: NlTheme;
|
||||
}
|
||||
interface NlInfoExtension {
|
||||
}
|
||||
interface NlLoading {
|
||||
"onHandleContinue"?: (event: NlLoadingCustomEvent<boolean>) => void;
|
||||
"onStopFetchHandler"?: (event: NlLoadingCustomEvent<boolean>) => void;
|
||||
"path"?: string;
|
||||
}
|
||||
interface NlLocalSignup {
|
||||
"description"?: string;
|
||||
"descriptionNjump"?: string;
|
||||
"onFetchHandler"?: (event: NlLocalSignupCustomEvent<boolean>) => void;
|
||||
"onNlLocalSignup"?: (event: NlLocalSignupCustomEvent<string>) => void;
|
||||
"onNlSignupNjump"?: (event: NlLocalSignupCustomEvent<void>) => void;
|
||||
"signupNjump"?: boolean;
|
||||
"titleSignup"?: string;
|
||||
}
|
||||
interface NlLoginStatus {
|
||||
"info"?: RecentType | Info | undefined;
|
||||
}
|
||||
interface NlOtpMigrate {
|
||||
"onNlImportAccount"?: (event: NlOtpMigrateCustomEvent<ConnectionString>) => void;
|
||||
"services"?: ConnectionString[];
|
||||
"textImport"?: string;
|
||||
"titleImport"?: string;
|
||||
"titleInfo"?: string;
|
||||
}
|
||||
interface NlPreviouslyLogged {
|
||||
"accounts"?: Info[];
|
||||
"description"?: string;
|
||||
"onNlLoginRecentAccount"?: (event: NlPreviouslyLoggedCustomEvent<RecentType>) => void;
|
||||
"onNlRemoveRecent"?: (event: NlPreviouslyLoggedCustomEvent<RecentType>) => void;
|
||||
"onNlSwitchAccount"?: (event: NlPreviouslyLoggedCustomEvent<Info>) => void;
|
||||
"recents"?: RecentType[];
|
||||
"titlePage"?: string;
|
||||
}
|
||||
interface NlSelect {
|
||||
"darkMode"?: boolean;
|
||||
"onSelectDomain"?: (event: NlSelectCustomEvent<string>) => void;
|
||||
"options"?: OptionType[];
|
||||
"selected"?: number;
|
||||
"theme"?: 'default' | 'ocean' | 'lemonade' | 'purple';
|
||||
}
|
||||
interface NlSignin {
|
||||
"description"?: string;
|
||||
"onNlCheckLogin"?: (event: NlSigninCustomEvent<string>) => void;
|
||||
"onNlLogin"?: (event: NlSigninCustomEvent<string>) => void;
|
||||
"titleLogin"?: string;
|
||||
}
|
||||
interface NlSigninBunkerUrl {
|
||||
"description"?: string;
|
||||
"onNlCheckLogin"?: (event: NlSigninBunkerUrlCustomEvent<string>) => void;
|
||||
"onNlLogin"?: (event: NlSigninBunkerUrlCustomEvent<string>) => void;
|
||||
"titleLogin"?: string;
|
||||
}
|
||||
interface NlSigninConnectionString {
|
||||
"connectionString"?: string;
|
||||
"description"?: string;
|
||||
"onNlNostrConnectDefault"?: (event: NlSigninConnectionStringCustomEvent<void>) => void;
|
||||
"titleLogin"?: string;
|
||||
}
|
||||
interface NlSigninOtp {
|
||||
"description"?: string;
|
||||
"descriptionOTP"?: string;
|
||||
"onNlCheckLogin"?: (event: NlSigninOtpCustomEvent<string>) => void;
|
||||
"onNlLoginOTPCode"?: (event: NlSigninOtpCustomEvent<string>) => void;
|
||||
"onNlLoginOTPUser"?: (event: NlSigninOtpCustomEvent<string>) => void;
|
||||
"titleLogin"?: string;
|
||||
"titleLoginOTP"?: string;
|
||||
}
|
||||
interface NlSigninReadOnly {
|
||||
"description"?: string;
|
||||
"onNlCheckLogin"?: (event: NlSigninReadOnlyCustomEvent<string>) => void;
|
||||
"onNlLoginReadOnly"?: (event: NlSigninReadOnlyCustomEvent<string>) => void;
|
||||
"titleLogin"?: string;
|
||||
}
|
||||
interface NlSignup {
|
||||
"bunkers"?: string;
|
||||
"description"?: string;
|
||||
"onFetchHandler"?: (event: NlSignupCustomEvent<boolean>) => void;
|
||||
"onNlCheckSignup"?: (event: NlSignupCustomEvent<string>) => void;
|
||||
"onNlSignup"?: (event: NlSignupCustomEvent<string>) => void;
|
||||
"titleSignup"?: string;
|
||||
}
|
||||
interface NlWelcome {
|
||||
"description"?: string;
|
||||
"titleWelcome"?: string;
|
||||
}
|
||||
interface NlWelcomeSignin {
|
||||
"authMethods"?: AuthMethod[];
|
||||
"hasExtension"?: boolean;
|
||||
"hasOTP"?: boolean;
|
||||
"onNlLoginExtension"?: (event: NlWelcomeSigninCustomEvent<void>) => void;
|
||||
"titleWelcome"?: string;
|
||||
}
|
||||
interface NlWelcomeSignup {
|
||||
"description"?: string;
|
||||
"titleWelcome"?: string;
|
||||
}
|
||||
interface IntrinsicElements {
|
||||
"button-base": ButtonBase;
|
||||
"nl-auth": NlAuth;
|
||||
"nl-banner": NlBanner;
|
||||
"nl-button": NlButton;
|
||||
"nl-change-account": NlChangeAccount;
|
||||
"nl-confirm-logout": NlConfirmLogout;
|
||||
"nl-connect": NlConnect;
|
||||
"nl-dialog": NlDialog;
|
||||
"nl-iframe": NlIframe;
|
||||
"nl-import-flow": NlImportFlow;
|
||||
"nl-info": NlInfo;
|
||||
"nl-info-extension": NlInfoExtension;
|
||||
"nl-loading": NlLoading;
|
||||
"nl-local-signup": NlLocalSignup;
|
||||
"nl-login-status": NlLoginStatus;
|
||||
"nl-otp-migrate": NlOtpMigrate;
|
||||
"nl-previously-logged": NlPreviouslyLogged;
|
||||
"nl-select": NlSelect;
|
||||
"nl-signin": NlSignin;
|
||||
"nl-signin-bunker-url": NlSigninBunkerUrl;
|
||||
"nl-signin-connection-string": NlSigninConnectionString;
|
||||
"nl-signin-otp": NlSigninOtp;
|
||||
"nl-signin-read-only": NlSigninReadOnly;
|
||||
"nl-signup": NlSignup;
|
||||
"nl-welcome": NlWelcome;
|
||||
"nl-welcome-signin": NlWelcomeSignin;
|
||||
"nl-welcome-signup": NlWelcomeSignup;
|
||||
}
|
||||
}
|
||||
export { LocalJSX as JSX };
|
||||
declare module "@stencil/core" {
|
||||
export namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
"button-base": LocalJSX.ButtonBase & JSXBase.HTMLAttributes<HTMLButtonBaseElement>;
|
||||
"nl-auth": LocalJSX.NlAuth & JSXBase.HTMLAttributes<HTMLNlAuthElement>;
|
||||
"nl-banner": LocalJSX.NlBanner & JSXBase.HTMLAttributes<HTMLNlBannerElement>;
|
||||
"nl-button": LocalJSX.NlButton & JSXBase.HTMLAttributes<HTMLNlButtonElement>;
|
||||
"nl-change-account": LocalJSX.NlChangeAccount & JSXBase.HTMLAttributes<HTMLNlChangeAccountElement>;
|
||||
"nl-confirm-logout": LocalJSX.NlConfirmLogout & JSXBase.HTMLAttributes<HTMLNlConfirmLogoutElement>;
|
||||
"nl-connect": LocalJSX.NlConnect & JSXBase.HTMLAttributes<HTMLNlConnectElement>;
|
||||
"nl-dialog": LocalJSX.NlDialog & JSXBase.HTMLAttributes<HTMLNlDialogElement>;
|
||||
"nl-iframe": LocalJSX.NlIframe & JSXBase.HTMLAttributes<HTMLNlIframeElement>;
|
||||
"nl-import-flow": LocalJSX.NlImportFlow & JSXBase.HTMLAttributes<HTMLNlImportFlowElement>;
|
||||
"nl-info": LocalJSX.NlInfo & JSXBase.HTMLAttributes<HTMLNlInfoElement>;
|
||||
"nl-info-extension": LocalJSX.NlInfoExtension & JSXBase.HTMLAttributes<HTMLNlInfoExtensionElement>;
|
||||
"nl-loading": LocalJSX.NlLoading & JSXBase.HTMLAttributes<HTMLNlLoadingElement>;
|
||||
"nl-local-signup": LocalJSX.NlLocalSignup & JSXBase.HTMLAttributes<HTMLNlLocalSignupElement>;
|
||||
"nl-login-status": LocalJSX.NlLoginStatus & JSXBase.HTMLAttributes<HTMLNlLoginStatusElement>;
|
||||
"nl-otp-migrate": LocalJSX.NlOtpMigrate & JSXBase.HTMLAttributes<HTMLNlOtpMigrateElement>;
|
||||
"nl-previously-logged": LocalJSX.NlPreviouslyLogged & JSXBase.HTMLAttributes<HTMLNlPreviouslyLoggedElement>;
|
||||
"nl-select": LocalJSX.NlSelect & JSXBase.HTMLAttributes<HTMLNlSelectElement>;
|
||||
"nl-signin": LocalJSX.NlSignin & JSXBase.HTMLAttributes<HTMLNlSigninElement>;
|
||||
"nl-signin-bunker-url": LocalJSX.NlSigninBunkerUrl & JSXBase.HTMLAttributes<HTMLNlSigninBunkerUrlElement>;
|
||||
"nl-signin-connection-string": LocalJSX.NlSigninConnectionString & JSXBase.HTMLAttributes<HTMLNlSigninConnectionStringElement>;
|
||||
"nl-signin-otp": LocalJSX.NlSigninOtp & JSXBase.HTMLAttributes<HTMLNlSigninOtpElement>;
|
||||
"nl-signin-read-only": LocalJSX.NlSigninReadOnly & JSXBase.HTMLAttributes<HTMLNlSigninReadOnlyElement>;
|
||||
"nl-signup": LocalJSX.NlSignup & JSXBase.HTMLAttributes<HTMLNlSignupElement>;
|
||||
"nl-welcome": LocalJSX.NlWelcome & JSXBase.HTMLAttributes<HTMLNlWelcomeElement>;
|
||||
"nl-welcome-signin": LocalJSX.NlWelcomeSignin & JSXBase.HTMLAttributes<HTMLNlWelcomeSigninElement>;
|
||||
"nl-welcome-signup": LocalJSX.NlWelcomeSignup & JSXBase.HTMLAttributes<HTMLNlWelcomeSignupElement>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.animate-spin-loading {
|
||||
background: var(--qa-dark-color);
|
||||
animation: spin2 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin2 {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
animation: blink 0.7s infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Component, h, Prop, Element } from '@stencil/core';
|
||||
import { NlTheme } from '@/types';
|
||||
import { IButton } from '@/types/button';
|
||||
|
||||
@Component({
|
||||
tag: 'button-base',
|
||||
styleUrl: 'button-base.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class ButtonBase implements IButton {
|
||||
@Element() element: HTMLElement;
|
||||
@Prop({ mutable: true }) theme: NlTheme = 'default';
|
||||
@Prop({ mutable: true }) darkMode: boolean = false;
|
||||
@Prop() titleBtn = 'Open modal';
|
||||
@Prop() disabled = false;
|
||||
|
||||
componentDidRender() {
|
||||
const svgElement = this.element.querySelector('svg');
|
||||
|
||||
if (svgElement) {
|
||||
svgElement.classList.add('flex-shrink-0', 'w-4', 'h-4', 'block');
|
||||
svgElement.removeAttribute('style'); // hack frieze svg
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class={`theme-${this.theme}`}>
|
||||
<div class="animate-spin-loading active"></div>
|
||||
<button
|
||||
disabled={this.disabled}
|
||||
type="button"
|
||||
class="nl-button py-2.5 px-3 w-full inline-flex justify-center items-center gap-x-2 text-sm font-medium rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
|
||||
>
|
||||
<slot name="icon-start" />
|
||||
{this.titleBtn}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
61
packages/components/src/components/button-base/readme.md
Normal file
61
packages/components/src/components/button-base/readme.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# button-base
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | -------------- |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `disabled` | `disabled` | | `boolean` | `false` |
|
||||
| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
| `titleBtn` | `title-btn` | | `string` | `'Open modal'` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-banner](../nl-banner)
|
||||
- [nl-button](../nl-button)
|
||||
- [nl-confirm-logout](../nl-confirm-logout)
|
||||
- [nl-connect](../nl-connect)
|
||||
- [nl-import-flow](../nl-import-flow)
|
||||
- [nl-loading](../nl-loading)
|
||||
- [nl-local-signup](../nl-local-signup)
|
||||
- [nl-otp-migrate](../nl-otp-migrate)
|
||||
- [nl-signin](../nl-signin)
|
||||
- [nl-signin-bunker-url](../nl-signin-bunker-url)
|
||||
- [nl-signin-otp](../nl-signin-otp)
|
||||
- [nl-signin-read-only](../nl-signin-read-only)
|
||||
- [nl-signup](../nl-signup)
|
||||
- [nl-welcome](../nl-welcome)
|
||||
- [nl-welcome-signin](../nl-welcome-signin)
|
||||
- [nl-welcome-signup](../nl-welcome-signup)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-banner --> button-base
|
||||
nl-button --> button-base
|
||||
nl-confirm-logout --> button-base
|
||||
nl-connect --> button-base
|
||||
nl-import-flow --> button-base
|
||||
nl-loading --> button-base
|
||||
nl-local-signup --> button-base
|
||||
nl-otp-migrate --> button-base
|
||||
nl-signin --> button-base
|
||||
nl-signin-bunker-url --> button-base
|
||||
nl-signin-otp --> button-base
|
||||
nl-signin-read-only --> button-base
|
||||
nl-signup --> button-base
|
||||
nl-welcome --> button-base
|
||||
nl-welcome-signin --> button-base
|
||||
nl-welcome-signup --> button-base
|
||||
style button-base fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
3
packages/components/src/components/nl-auth/nl-auth.css
Normal file
3
packages/components/src/components/nl-auth/nl-auth.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
332
packages/components/src/components/nl-auth/nl-auth.tsx
Normal file
332
packages/components/src/components/nl-auth/nl-auth.tsx
Normal file
@@ -0,0 +1,332 @@
|
||||
import { Component, Event, EventEmitter, Fragment, h, Prop, Watch } from '@stencil/core';
|
||||
import { AuthMethod, ConnectionString, CURRENT_MODULE, Info, NlTheme, RecentType } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-auth',
|
||||
styleUrl: 'nl-auth.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class NlAuth {
|
||||
@Prop({ mutable: true }) theme: NlTheme = 'default';
|
||||
@Prop() bunkers: string = '';
|
||||
@Prop() startScreen: string = CURRENT_MODULE.WELCOME;
|
||||
@Prop() authMethods: AuthMethod[] = [];
|
||||
@Prop() hasExtension: boolean = false;
|
||||
@Prop() hasOTP: boolean = false;
|
||||
@Prop() isLoading: boolean = false;
|
||||
@Prop() isLoadingExtension: boolean = false;
|
||||
@Prop() isOTP: boolean = false;
|
||||
@Prop() authUrl: string = '';
|
||||
@Prop() iframeUrl: string = '';
|
||||
@Prop() error: string = '';
|
||||
@Prop() localSignup: boolean = false;
|
||||
@Prop() signupNjump: boolean = false;
|
||||
@Prop() njumpIframe: string = '';
|
||||
@Prop({ mutable: true }) accounts: Info[] = [];
|
||||
@Prop({ mutable: true }) recents: RecentType[] = [];
|
||||
@Prop({ mutable: true }) darkMode: boolean = false;
|
||||
@Prop() welcomeTitle: string = '';
|
||||
@Prop() welcomeDescription: string = '';
|
||||
@Prop() connectionString: string = '';
|
||||
@Prop() connectionStringServices: ConnectionString[] = [];
|
||||
|
||||
@Event() nlCloseModal: EventEmitter;
|
||||
@Event() nlChangeDarkMode: EventEmitter<boolean>;
|
||||
@Event() nlNostrConnectDefaultCancel: EventEmitter<void>;
|
||||
|
||||
prevPath: string = '';
|
||||
|
||||
@Watch('isLoading')
|
||||
watchLoadingHandler(newValue: boolean) {
|
||||
state.isLoading = newValue;
|
||||
}
|
||||
|
||||
@Watch('isLoadingExtension')
|
||||
watchLoadingExtensionHandler(newValue: boolean) {
|
||||
state.isLoadingExtension = newValue;
|
||||
}
|
||||
|
||||
@Watch('isOTP')
|
||||
watchOTPHandler(newValue: boolean) {
|
||||
state.isOTP = newValue;
|
||||
}
|
||||
|
||||
@Watch('authUrl')
|
||||
watchAuthUrlHandler(newValue: string) {
|
||||
state.authUrl = newValue;
|
||||
}
|
||||
|
||||
@Watch('iframeUrl')
|
||||
watchIframeUrlHandler(newValue: string) {
|
||||
state.iframeUrl = newValue;
|
||||
}
|
||||
|
||||
@Watch('njumpIframe')
|
||||
watchNjumpIframeHandler(newValue: string) {
|
||||
state.njumpIframe = newValue;
|
||||
}
|
||||
|
||||
@Watch('error')
|
||||
watchErrorHandler(newValue: string) {
|
||||
state.error = newValue;
|
||||
}
|
||||
|
||||
handleClose() {
|
||||
this.nlCloseModal.emit();
|
||||
}
|
||||
|
||||
handleChangeDarkMode() {
|
||||
this.nlChangeDarkMode.emit(!this.darkMode);
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
// init state
|
||||
state.path = [this.startScreen as CURRENT_MODULE];
|
||||
state.error = '';
|
||||
state.iframeUrl = '';
|
||||
state.authUrl = '';
|
||||
state.isLoading = false;
|
||||
state.isLoadingExtension = false;
|
||||
state.isOTP = false;
|
||||
|
||||
console.log('path', state.path);
|
||||
}
|
||||
|
||||
handleClickToBack() {
|
||||
state.path.pop();
|
||||
state.path = [...state.path];
|
||||
|
||||
// reset
|
||||
state.isLoading = false;
|
||||
state.isLoadingExtension = false;
|
||||
state.authUrl = '';
|
||||
state.isOTP = false;
|
||||
}
|
||||
|
||||
switchSignSignUpStrategy(str: CURRENT_MODULE) {
|
||||
if (CURRENT_MODULE.LOCAL_SIGNUP === str) {
|
||||
state.path = [CURRENT_MODULE.WELCOME, CURRENT_MODULE.WELCOME_SIGNUP, str];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
state.path = [CURRENT_MODULE.WELCOME, str];
|
||||
}
|
||||
|
||||
render() {
|
||||
const classWrapper = `w-full h-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto flex items-center ${this.darkMode ? 'dark' : ''}`;
|
||||
const currentModule = state.path.at(-1);
|
||||
|
||||
if (currentModule !== this.prevPath && this.prevPath === CURRENT_MODULE.CONNECTION_STRING) {
|
||||
this.nlNostrConnectDefaultCancel.emit();
|
||||
}
|
||||
this.prevPath = currentModule;
|
||||
|
||||
const renderModule = () => {
|
||||
if (state.isOTP) return <nl-signin-otp />;
|
||||
|
||||
// @ts-ignore
|
||||
// const t: CURRENT_MODULE = 'import' // lastValuePath
|
||||
|
||||
switch (currentModule) {
|
||||
case CURRENT_MODULE.WELCOME:
|
||||
return <nl-welcome titleWelcome={this.welcomeTitle || undefined} description={this.welcomeDescription || undefined} />;
|
||||
case CURRENT_MODULE.LOGIN:
|
||||
return <nl-signin />;
|
||||
case CURRENT_MODULE.SIGNUP:
|
||||
return <nl-signup bunkers={this.bunkers} />;
|
||||
case CURRENT_MODULE.LOCAL_SIGNUP:
|
||||
return <nl-local-signup signupNjump={this.signupNjump} />;
|
||||
case CURRENT_MODULE.CONFIRM_LOGOUT:
|
||||
return <nl-confirm-logout />;
|
||||
case CURRENT_MODULE.IMPORT_FLOW:
|
||||
return <nl-import-flow services={this.connectionStringServices} />;
|
||||
case CURRENT_MODULE.IMPORT_OTP:
|
||||
return <nl-otp-migrate services={this.connectionStringServices} />;
|
||||
case CURRENT_MODULE.INFO:
|
||||
return <nl-info theme={this.theme} darkMode={this.darkMode} />;
|
||||
case CURRENT_MODULE.EXTENSION:
|
||||
return <nl-info-extension />;
|
||||
case CURRENT_MODULE.LOGIN_READ_ONLY:
|
||||
return <nl-signin-read-only />;
|
||||
case CURRENT_MODULE.LOGIN_BUNKER_URL:
|
||||
return <nl-signin-bunker-url />;
|
||||
case CURRENT_MODULE.LOGIN_OTP:
|
||||
return <nl-signin-otp />;
|
||||
case CURRENT_MODULE.WELCOME_LOGIN:
|
||||
return <nl-welcome-signin hasOTP={this.hasOTP} authMethods={this.authMethods} hasExtension={this.hasExtension} />;
|
||||
case CURRENT_MODULE.WELCOME_SIGNUP:
|
||||
return <nl-welcome-signup />;
|
||||
case CURRENT_MODULE.CONNECTION_STRING:
|
||||
return <nl-signin-connection-string connectionString={this.connectionString} />;
|
||||
case CURRENT_MODULE.CONNECT:
|
||||
return <nl-connect connectionStringServices={this.connectionStringServices} authMethods={this.authMethods} />;
|
||||
case CURRENT_MODULE.PREVIOUSLY_LOGGED:
|
||||
return <nl-previously-logged accounts={this.accounts} recents={this.recents} />;
|
||||
case CURRENT_MODULE.IFRAME:
|
||||
return <nl-iframe iframeUrl={this.authUrl} />;
|
||||
default:
|
||||
return <nl-welcome />;
|
||||
}
|
||||
};
|
||||
|
||||
const showLogin =
|
||||
state.isOTP ||
|
||||
(currentModule !== CURRENT_MODULE.INFO &&
|
||||
currentModule !== CURRENT_MODULE.CONFIRM_LOGOUT &&
|
||||
currentModule !== CURRENT_MODULE.IMPORT_FLOW &&
|
||||
currentModule !== CURRENT_MODULE.WELCOME &&
|
||||
currentModule !== CURRENT_MODULE.EXTENSION &&
|
||||
currentModule !== CURRENT_MODULE.IFRAME &&
|
||||
currentModule !== CURRENT_MODULE.PREVIOUSLY_LOGGED);
|
||||
|
||||
const showSignup =
|
||||
currentModule !== CURRENT_MODULE.IFRAME &&
|
||||
(!this.authMethods.length || (!this.localSignup && this.authMethods.includes('connect')) || (this.localSignup && this.authMethods.includes('local')));
|
||||
|
||||
return (
|
||||
<div class={`theme-${this.theme}`} dir="ltr">
|
||||
<div class={classWrapper}>
|
||||
<div onClick={() => this.handleClose()} class="absolute top-0 left-0 w-full h-full bg-gray-500 bg-opacity-75 z-[80]" />
|
||||
|
||||
<div class="nl-bg relative z-[81] w-full flex flex-col rounded-xl sm:max-w-lg sm:w-full sm:mx-auto">
|
||||
<div class={`flex justify-between items-center py-3 px-4`}>
|
||||
<div class="flex gap-2 items-center">
|
||||
<svg class="w-7 h-7" width="225" height="224" viewBox="0 0 225 224" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="224.047" height="224" rx="64" fill={this.theme === 'laan' ? (this.darkMode ? 'white' : 'black') : '#6951FA'} />
|
||||
<path
|
||||
d="M162.441 135.941V88.0593C170.359 85.1674 176 77.5348 176 68.6696C176 57.2919 166.708 48 155.33 48C143.953 48 134.661 57.2444 134.661 68.6696C134.661 77.5822 140.302 85.1674 148.219 88.0593V135.941C147.698 136.13 147.176 136.367 146.655 136.604L87.3956 77.3452C88.6282 74.6904 89.2919 71.7511 89.2919 68.6696C89.2919 57.2444 80.0474 48 68.6696 48C57.2919 48 48 57.2444 48 68.6696C48 77.5822 53.6415 85.1674 61.5585 88.0593V135.941C53.6415 138.833 48 146.465 48 155.33C48 166.708 57.2444 176 68.6696 176C80.0948 176 89.3393 166.708 89.3393 155.33C89.3393 146.418 83.6978 138.833 75.7807 135.941V88.0593C76.3022 87.8696 76.8237 87.6326 77.3452 87.3956L136.604 146.655C135.372 149.31 134.708 152.249 134.708 155.33C134.708 166.708 143.953 176 155.378 176C166.803 176 176.047 166.708 176.047 155.33C176.047 146.418 170.406 138.833 162.489 135.941H162.441Z"
|
||||
fill={this.theme === 'laan' ? (this.darkMode ? 'black' : 'white') : 'white'}
|
||||
/>
|
||||
</svg>
|
||||
<p class="font-bold nl-logo text-base">
|
||||
Nostr <span class="font-light">Login</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
onClick={() => this.handleChangeDarkMode()}
|
||||
type="button"
|
||||
class="nl-action-button flex justify-center items-center w-7 h-7 text-sm font-semibold rounded-full border border-transparent"
|
||||
>
|
||||
<span class="sr-only">Change theme</span>
|
||||
{this.darkMode ? (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-5 h-5">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-5 h-5">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
{!state.isLoading && (
|
||||
<button
|
||||
onClick={() => (state.path = [...state.path, CURRENT_MODULE.INFO])}
|
||||
type="button"
|
||||
class="nl-action-button flex justify-center items-center w-7 h-7 text-sm font-semibold rounded-full border border-transparent"
|
||||
>
|
||||
<span class="sr-only">Info</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-5 h-5">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => this.handleClose()}
|
||||
type="button"
|
||||
class="nl-action-button flex justify-center items-center w-7 h-7 text-sm font-semibold rounded-full border border-transparent"
|
||||
>
|
||||
<span class="sr-only">Close</span>
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M18 6 6 18" />
|
||||
<path d="m6 6 12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{state.path.length > 1 && !state.isLoading && (
|
||||
<div class="p-4">
|
||||
<button
|
||||
onClick={() => this.handleClickToBack()}
|
||||
type="button"
|
||||
class="nl-action-button flex justify-center items-center w-7 h-7 text-sm font-semibold rounded-full border border-transparent dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
|
||||
data-hs-overlay="#hs-vertically-centered-modal"
|
||||
>
|
||||
<span class="sr-only">Back</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{state.isLoading || state.authUrl ? (
|
||||
<nl-loading path={currentModule} />
|
||||
) : (
|
||||
<Fragment>
|
||||
{renderModule()}
|
||||
{showLogin && (
|
||||
<Fragment>
|
||||
{currentModule === CURRENT_MODULE.WELCOME_SIGNUP || currentModule === CURRENT_MODULE.SIGNUP || currentModule === CURRENT_MODULE.LOCAL_SIGNUP ? (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<p class="nl-footer font-light text-center text-sm pt-3 max-w-96 mx-auto">
|
||||
If you already have a profile please{' '}
|
||||
<span onClick={() => this.switchSignSignUpStrategy(CURRENT_MODULE.WELCOME_LOGIN)} class="cursor-pointer text-blue-400">
|
||||
log in
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
showSignup && (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<p class="nl-footer font-light text-center text-sm pt-3 max-w-96 mx-auto">
|
||||
If you don't have a profile please{' '}
|
||||
<span
|
||||
onClick={() =>
|
||||
this.localSignup ? this.switchSignSignUpStrategy(CURRENT_MODULE.LOCAL_SIGNUP) : this.switchSignSignUpStrategy(CURRENT_MODULE.WELCOME_SIGNUP)
|
||||
}
|
||||
class="cursor-pointer text-blue-400"
|
||||
>
|
||||
sign up
|
||||
</span>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
112
packages/components/src/components/nl-auth/readme.md
Normal file
112
packages/components/src/components/nl-auth/readme.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# nl-auth
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------------------- | ---------------------- | ----------- | -------------------------------------------------------------------- | ------------------------ |
|
||||
| `accounts` | -- | | `Info[]` | `[]` |
|
||||
| `authMethods` | -- | | `AuthMethod[]` | `[]` |
|
||||
| `authUrl` | `auth-url` | | `string` | `''` |
|
||||
| `bunkers` | `bunkers` | | `string` | `''` |
|
||||
| `connectionString` | `connection-string` | | `string` | `''` |
|
||||
| `connectionStringServices` | -- | | `ConnectionString[]` | `[]` |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `error` | `error` | | `string` | `''` |
|
||||
| `hasExtension` | `has-extension` | | `boolean` | `false` |
|
||||
| `hasOTP` | `has-o-t-p` | | `boolean` | `false` |
|
||||
| `iframeUrl` | `iframe-url` | | `string` | `''` |
|
||||
| `isLoading` | `is-loading` | | `boolean` | `false` |
|
||||
| `isLoadingExtension` | `is-loading-extension` | | `boolean` | `false` |
|
||||
| `isOTP` | `is-o-t-p` | | `boolean` | `false` |
|
||||
| `localSignup` | `local-signup` | | `boolean` | `false` |
|
||||
| `njumpIframe` | `njump-iframe` | | `string` | `''` |
|
||||
| `recents` | -- | | `RecentType[]` | `[]` |
|
||||
| `signupNjump` | `signup-njump` | | `boolean` | `false` |
|
||||
| `startScreen` | `start-screen` | | `string` | `CURRENT_MODULE.WELCOME` |
|
||||
| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
| `welcomeDescription` | `welcome-description` | | `string` | `''` |
|
||||
| `welcomeTitle` | `welcome-title` | | `string` | `''` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ----------------------------- | ----------- | ---------------------- |
|
||||
| `nlChangeDarkMode` | | `CustomEvent<boolean>` |
|
||||
| `nlCloseModal` | | `CustomEvent<any>` |
|
||||
| `nlNostrConnectDefaultCancel` | | `CustomEvent<void>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-signin-otp](../nl-signin-otp)
|
||||
- [nl-welcome](../nl-welcome)
|
||||
- [nl-signin](../nl-signin)
|
||||
- [nl-signup](../nl-signup)
|
||||
- [nl-local-signup](../nl-local-signup)
|
||||
- [nl-confirm-logout](../nl-confirm-logout)
|
||||
- [nl-import-flow](../nl-import-flow)
|
||||
- [nl-otp-migrate](../nl-otp-migrate)
|
||||
- [nl-info](../nl-info)
|
||||
- [nl-info-extension](../nl-info-extension)
|
||||
- [nl-signin-read-only](../nl-signin-read-only)
|
||||
- [nl-signin-bunker-url](../nl-signin-bunker-url)
|
||||
- [nl-welcome-signin](../nl-welcome-signin)
|
||||
- [nl-welcome-signup](../nl-welcome-signup)
|
||||
- [nl-signin-connection-string](../nl-signin-connection-string)
|
||||
- [nl-connect](../nl-connect)
|
||||
- [nl-previously-logged](../nl-previously-logged)
|
||||
- [nl-iframe](../nl-iframe)
|
||||
- [nl-loading](../nl-loading)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-auth --> nl-signin-otp
|
||||
nl-auth --> nl-welcome
|
||||
nl-auth --> nl-signin
|
||||
nl-auth --> nl-signup
|
||||
nl-auth --> nl-local-signup
|
||||
nl-auth --> nl-confirm-logout
|
||||
nl-auth --> nl-import-flow
|
||||
nl-auth --> nl-otp-migrate
|
||||
nl-auth --> nl-info
|
||||
nl-auth --> nl-info-extension
|
||||
nl-auth --> nl-signin-read-only
|
||||
nl-auth --> nl-signin-bunker-url
|
||||
nl-auth --> nl-welcome-signin
|
||||
nl-auth --> nl-welcome-signup
|
||||
nl-auth --> nl-signin-connection-string
|
||||
nl-auth --> nl-connect
|
||||
nl-auth --> nl-previously-logged
|
||||
nl-auth --> nl-iframe
|
||||
nl-auth --> nl-loading
|
||||
nl-signin-otp --> button-base
|
||||
nl-welcome --> button-base
|
||||
nl-signin --> button-base
|
||||
nl-signup --> nl-select
|
||||
nl-signup --> button-base
|
||||
nl-local-signup --> button-base
|
||||
nl-confirm-logout --> button-base
|
||||
nl-import-flow --> button-base
|
||||
nl-import-flow --> nl-select
|
||||
nl-otp-migrate --> nl-select
|
||||
nl-otp-migrate --> button-base
|
||||
nl-signin-read-only --> button-base
|
||||
nl-signin-bunker-url --> button-base
|
||||
nl-welcome-signin --> button-base
|
||||
nl-welcome-signup --> button-base
|
||||
nl-connect --> button-base
|
||||
nl-previously-logged --> nl-login-status
|
||||
nl-loading --> button-base
|
||||
style nl-auth fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,4 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
345
packages/components/src/components/nl-banner/nl-banner.tsx
Normal file
345
packages/components/src/components/nl-banner/nl-banner.tsx
Normal file
@@ -0,0 +1,345 @@
|
||||
import { Component, Event, EventEmitter, Fragment, h, Prop, State, Watch } from '@stencil/core';
|
||||
import { BannerNotify, BannerNotifyMode, Info, METHOD_MODULE, NlTheme } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-banner',
|
||||
styleUrl: 'nl-banner.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class NlBanner {
|
||||
@Prop({ mutable: true }) theme: NlTheme = 'default';
|
||||
@Prop({ mutable: true }) darkMode: boolean = false;
|
||||
@Prop({ mutable: true }) hiddenMode: boolean = false;
|
||||
@Prop() titleBanner: string = '';
|
||||
@Prop({ mutable: true }) isOpen: boolean = false;
|
||||
|
||||
@Prop() isLoading: boolean = false;
|
||||
@Prop() notify: BannerNotify | null = null;
|
||||
@Prop() userInfo: Info | null = null;
|
||||
@Prop({ mutable: true }) accounts: Info[] = [];
|
||||
|
||||
@State() isUserImgError = false;
|
||||
|
||||
@State() domain: string = '';
|
||||
@State() mode: BannerNotifyMode = '';
|
||||
@State() url: string = '';
|
||||
@State() isOpenConfirm: boolean = false;
|
||||
|
||||
@Event() handleNotifyConfirmBanner: EventEmitter<string>;
|
||||
@Event() handleNotifyConfirmBannerIframe: EventEmitter<string>;
|
||||
@Event() handleLoginBanner: EventEmitter<string>;
|
||||
@Event() handleLogoutBanner: EventEmitter<string>;
|
||||
@Event() handleOpenWelcomeModal: EventEmitter<string>;
|
||||
@Event() handleConfirmLogout: EventEmitter<string>;
|
||||
@Event() handleImportModal: EventEmitter<string>;
|
||||
|
||||
@Watch('notify')
|
||||
watchNotifyHandler(notify: BannerNotify) {
|
||||
this.isOpen = true;
|
||||
this.isOpenConfirm = true;
|
||||
this.domain = this.userInfo?.domain || this.userInfo?.nip05?.split('@')?.[1] || '';
|
||||
|
||||
this.mode = notify.mode;
|
||||
this.url = notify.url;
|
||||
if (!this.mode) {
|
||||
this.isOpenConfirm = false;
|
||||
this.isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
handleOpen() {
|
||||
if (this.userInfo) {
|
||||
this.isOpen = true;
|
||||
} else {
|
||||
this.handleOpenWelcomeModal.emit();
|
||||
}
|
||||
}
|
||||
|
||||
handleClose() {
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
handleLogin() {
|
||||
this.handleLoginBanner.emit(METHOD_MODULE.LOGIN);
|
||||
this.handleClose();
|
||||
}
|
||||
|
||||
handleSignup() {
|
||||
this.handleLoginBanner.emit(METHOD_MODULE.SIGNUP);
|
||||
this.handleClose();
|
||||
}
|
||||
|
||||
handleImport() {
|
||||
this.handleImportModal.emit();
|
||||
this.handleClose();
|
||||
}
|
||||
|
||||
handleLogout() {
|
||||
const isBackupKey = localStorage.getItem('backupKey');
|
||||
|
||||
if (isBackupKey) {
|
||||
this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT);
|
||||
this.handleClose();
|
||||
localStorage.removeItem('backupKey');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.userInfo.authMethod === 'local') {
|
||||
this.handleConfirmLogout.emit();
|
||||
} else {
|
||||
this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT);
|
||||
}
|
||||
|
||||
this.handleClose();
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
switch (this.mode) {
|
||||
case 'authUrl':
|
||||
this.handleNotifyConfirmBanner.emit(this.url);
|
||||
break;
|
||||
case 'iframeAuthUrl':
|
||||
this.handleNotifyConfirmBannerIframe.emit(this.url);
|
||||
break;
|
||||
}
|
||||
this.handleClose();
|
||||
}
|
||||
|
||||
render() {
|
||||
const isShowImg = Boolean(this.userInfo?.picture);
|
||||
const userName = this.userInfo?.name || this.userInfo?.nip05?.split('@')?.[0] || this.userInfo?.pubkey || '';
|
||||
const isShowUserName = Boolean(userName);
|
||||
const isTemporary = this.userInfo && this.userInfo.authMethod === 'local';
|
||||
const isBackupKey = localStorage.getItem('backupKey');
|
||||
|
||||
const defaultUserAvatar = (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const content = (
|
||||
<Fragment>
|
||||
<div class="block w-[48px] h-[46px] relative z-10">
|
||||
<div onClick={() => this.handleOpen()} class={`flex w-52 h-[46px] items-center pl-[11px]`}>
|
||||
<span
|
||||
class={`${this.isLoading ? 'w-5 h-5 border-[2px] mr-3.5 ml-[2px] opacity-1' : 'w-0 h-0 border-[0px] mr-0 opacity-0 ml-0'} animate-spin transition-all duration-300 ease-in-out inline-block border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full`}
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
|
||||
{this.userInfo ? (
|
||||
<div class={`uppercase font-bold w-6 h-6 mr-2 rounded-full border border-gray-200 flex justify-center items-center`}>
|
||||
{isShowImg ? (
|
||||
this.isUserImgError ? (
|
||||
defaultUserAvatar
|
||||
) : (
|
||||
<img class="w-full rounded-full" src={this.userInfo.picture} alt="Logo" onError={() => (this.isUserImgError = true)} />
|
||||
)
|
||||
) : isShowUserName ? (
|
||||
userName[0]
|
||||
) : (
|
||||
defaultUserAvatar
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center items-center">
|
||||
<svg class="w-6 h-6" width="225" height="224" viewBox="0 0 225 224" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="224.047" height="224" rx="64" fill={this.theme === 'laan' ? (this.darkMode ? 'white' : 'black') : '#6951FA'} />
|
||||
<path
|
||||
d="M162.441 135.941V88.0593C170.359 85.1674 176 77.5348 176 68.6696C176 57.2919 166.708 48 155.33 48C143.953 48 134.661 57.2444 134.661 68.6696C134.661 77.5822 140.302 85.1674 148.219 88.0593V135.941C147.698 136.13 147.176 136.367 146.655 136.604L87.3956 77.3452C88.6282 74.6904 89.2919 71.7511 89.2919 68.6696C89.2919 57.2444 80.0474 48 68.6696 48C57.2919 48 48 57.2444 48 68.6696C48 77.5822 53.6415 85.1674 61.5585 88.0593V135.941C53.6415 138.833 48 146.465 48 155.33C48 166.708 57.2444 176 68.6696 176C80.0948 176 89.3393 166.708 89.3393 155.33C89.3393 146.418 83.6978 138.833 75.7807 135.941V88.0593C76.3022 87.8696 76.8237 87.6326 77.3452 87.3956L136.604 146.655C135.372 149.31 134.708 152.249 134.708 155.33C134.708 166.708 143.953 176 155.378 176C166.803 176 176.047 166.708 176.047 155.33C176.047 146.418 170.406 138.833 162.489 135.941H162.441Z"
|
||||
fill={this.theme === 'laan' ? (this.darkMode ? 'black' : 'white') : 'white'}
|
||||
/>
|
||||
</svg>
|
||||
{this.isOpen && (
|
||||
<span class="px-2">
|
||||
<b>Nostr</b> Login
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{this.isOpen && isShowUserName && <div class="show-slow truncate w-16 text-xs">{userName}</div>}
|
||||
{this.isOpen && isShowUserName && <nl-login-status info={this.userInfo} />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => this.handleClose()}
|
||||
type="button"
|
||||
class={`${this.isOpen ? 'z-20' : 'z-0'} nl-action-button absolute right-2 top-2 z-0 show-slow grid place-items-center w-7 h-7 text-sm font-semibold rounded-full border border-transparent`}
|
||||
>
|
||||
<span class="sr-only">Close</span>
|
||||
<svg
|
||||
class="flex-shrink-0 w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M18 6 6 18" />
|
||||
<path d="m6 6 12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="p-3 show-slow">
|
||||
{this.isOpenConfirm ? (
|
||||
<div>
|
||||
<div class="w-8 h-8 p-1/2 rounded-full border border-gray-200 bg-white mb-2 mt-2 show-slow m-auto">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#5a68ff" class="w-full">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="mb-2 text-center max-w-40 min-w-40 mx-auto">
|
||||
{this.mode === 'timeout' ? 'Keys not responding, check your key storage app' : `Confirmation required at ${this.domain}`}
|
||||
</p>
|
||||
|
||||
{this.mode === 'timeout' ? (
|
||||
<a
|
||||
onClick={() => this.handleClose()}
|
||||
href={`https://${this.domain}`}
|
||||
target="_blank"
|
||||
class="nl-button text-nowrap py-2.5 px-3 w-full inline-flex justify-center items-center gap-x-2 text-sm font-medium rounded-lg disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
|
||||
>
|
||||
Go to {this.domain}
|
||||
</a>
|
||||
) : this.mode === 'rebind' ? (
|
||||
<iframe src={this.url} width={'180'} height={'80'} frameBorder={'0'}></iframe>
|
||||
) : (
|
||||
<button-base onClick={() => this.handleConfirm()} titleBtn="Confirm" />
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div>
|
||||
{this.titleBanner && <p class="mb-2 text-center show-slow max-w-40 min-w-40 mx-auto">{this.titleBanner}</p>}
|
||||
{isTemporary && (
|
||||
<Fragment>
|
||||
{!isBackupKey && <p class="mb-2 text-center show-slow text-red-400 max-w-40 min-w-40 mx-auto">Your profile may be lost if you close this tab</p>}
|
||||
<div class="mb-2">
|
||||
<button-base onClick={() => this.handleImport()} theme="lemonade" titleBtn="Back up profile" />
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
<div class="mb-2">
|
||||
<nl-change-account currentAccount={this.userInfo} accounts={this.accounts} />
|
||||
</div>
|
||||
{/* {Boolean(this.listNotifies.length) && (
|
||||
<div
|
||||
onClick={() => this.handleRetryConfirm()}
|
||||
class="show-slow border border-yellow-600 text-yellow-600 bg-yellow-100 p-2 rounded-lg mb-2 cursor-pointer w-44 text-xs m-auto text-center"
|
||||
>
|
||||
Requests: {this.listNotifies.length}
|
||||
</div>
|
||||
)} */}
|
||||
{!this.userInfo ? (
|
||||
<div>
|
||||
<button-base onClick={() => this.handleLogin()} titleBtn="Log in">
|
||||
<svg
|
||||
style={{ display: 'none' }}
|
||||
slot="icon-start"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="flex-shrink-0 w-4 h-4"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
<button-base onClick={() => this.handleSignup()} titleBtn="Sign up">
|
||||
<svg
|
||||
style={{ display: 'none' }}
|
||||
slot="icon-start"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="flex-shrink-0 w-4 h-4"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
</div>
|
||||
) : (
|
||||
<button-base onClick={() => this.handleLogout()} titleBtn="Log out" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
// https://gist.github.com/Haprog/848fc451c25da00b540e6d34c301e96a
|
||||
function deepQuerySelectorAll(selector: string, root?: Element) {
|
||||
root = root || document.body;
|
||||
const results = Array.from(root.querySelectorAll(selector));
|
||||
const pushNestedResults = function (root) {
|
||||
deepQuerySelectorAll(selector, root).forEach(elem => {
|
||||
if (!results.includes(elem)) {
|
||||
results.push(elem);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (root.shadowRoot) {
|
||||
pushNestedResults(root.shadowRoot);
|
||||
}
|
||||
for (const elem of Array.from(root.querySelectorAll('*'))) {
|
||||
if (elem.shadowRoot) {
|
||||
pushNestedResults(elem.shadowRoot);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const dialogs = deepQuerySelectorAll('dialog');
|
||||
const needDialog = !!dialogs.find(d => (d as HTMLDialogElement).open && !d.classList.contains('nl-banner-dialog'));
|
||||
|
||||
return (
|
||||
<div class={`theme-${this.theme} ${!this.isOpen && this.hiddenMode ? 'hidden' : ''}`}>
|
||||
<div class={this.darkMode && 'dark'} dir="ltr">
|
||||
{this.isOpenConfirm && needDialog ? (
|
||||
<nl-dialog>
|
||||
<div
|
||||
class={`nl-banner ${this.isOpen ? 'w-52 h-auto right-2 rounded-r-lg isOpen ' : 'rounded-r-none hover:rounded-r-lg cursor-pointer'} z-50 w-12 h-12 fixed top-52 right-0 inline-block gap-x-2 text-sm font-medium rounded-lg hover:right-2 transition-all duration-300 ease-in-out`}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
</nl-dialog>
|
||||
) : (
|
||||
<div
|
||||
class={`nl-banner ${this.isOpen ? 'w-52 h-auto right-2 rounded-r-lg isOpen' : 'rounded-r-none hover:rounded-r-lg cursor-pointer'} z-50 w-12 h-12 fixed top-52 right-0 inline-block gap-x-2 text-sm font-medium rounded-lg hover:right-2 transition-all duration-300 ease-in-out`}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
56
packages/components/src/components/nl-banner/readme.md
Normal file
56
packages/components/src/components/nl-banner/readme.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# nl-banner
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | -------------- | ----------- | -------------------------------------------------------------------- | ----------- |
|
||||
| `accounts` | -- | | `Info[]` | `[]` |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `hiddenMode` | `hidden-mode` | | `boolean` | `false` |
|
||||
| `isLoading` | `is-loading` | | `boolean` | `false` |
|
||||
| `isOpen` | `is-open` | | `boolean` | `false` |
|
||||
| `notify` | -- | | `BannerNotify` | `null` |
|
||||
| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
| `titleBanner` | `title-banner` | | `string` | `''` |
|
||||
| `userInfo` | -- | | `Info` | `null` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| --------------------------------- | ----------- | --------------------- |
|
||||
| `handleConfirmLogout` | | `CustomEvent<string>` |
|
||||
| `handleImportModal` | | `CustomEvent<string>` |
|
||||
| `handleLoginBanner` | | `CustomEvent<string>` |
|
||||
| `handleLogoutBanner` | | `CustomEvent<string>` |
|
||||
| `handleNotifyConfirmBanner` | | `CustomEvent<string>` |
|
||||
| `handleNotifyConfirmBannerIframe` | | `CustomEvent<string>` |
|
||||
| `handleOpenWelcomeModal` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-login-status](../nl-login-status)
|
||||
- [button-base](../button-base)
|
||||
- [nl-change-account](../nl-change-account)
|
||||
- [nl-dialog](../nl-dialog)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-banner --> nl-login-status
|
||||
nl-banner --> button-base
|
||||
nl-banner --> nl-change-account
|
||||
nl-banner --> nl-dialog
|
||||
nl-change-account --> nl-login-status
|
||||
style nl-banner fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
18
packages/components/src/components/nl-button/nl-button.tsx
Normal file
18
packages/components/src/components/nl-button/nl-button.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Component, h, Prop } from '@stencil/core';
|
||||
import { NlTheme } from '@/types';
|
||||
import { IButton } from '@/types/button';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-button',
|
||||
shadow: true,
|
||||
})
|
||||
export class NlButton implements IButton {
|
||||
@Prop() theme: NlTheme = 'default';
|
||||
@Prop() darkMode: boolean = false;
|
||||
@Prop() titleBtn = 'Open modal';
|
||||
@Prop() disabled = false;
|
||||
|
||||
render() {
|
||||
return <button-base theme={this.theme} darkMode={this.darkMode} titleBtn={this.titleBtn} disabled={this.disabled} />;
|
||||
}
|
||||
}
|
||||
31
packages/components/src/components/nl-button/readme.md
Normal file
31
packages/components/src/components/nl-button/readme.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# nl-button
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | -------------- |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `disabled` | `disabled` | | `boolean` | `false` |
|
||||
| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
| `titleBtn` | `title-btn` | | `string` | `'Open modal'` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-button --> button-base
|
||||
style nl-button fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import { Component, h, Listen, Prop, State, Watch, Element, Event, EventEmitter } from '@stencil/core';
|
||||
import { Info } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-change-account',
|
||||
styleUrl: 'nl-change-account.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NLChangeAccount {
|
||||
@State() isOpen: boolean = false;
|
||||
@State() options: Info[] = [];
|
||||
@Prop() accounts: Info[] = [];
|
||||
@Prop() currentAccount: Info = null;
|
||||
|
||||
@Element() element: HTMLElement;
|
||||
@Event() handleOpenWelcomeModal: EventEmitter<string>;
|
||||
@Event() handleSwitchAccount: EventEmitter<Info>;
|
||||
|
||||
buttonRef: HTMLButtonElement;
|
||||
ulRef: HTMLUListElement;
|
||||
wrapperRef: HTMLDivElement;
|
||||
|
||||
@Listen('click', { target: 'window' })
|
||||
handleWindowClick() {
|
||||
if (this.wrapperRef.querySelector('.listClass')) {
|
||||
this.isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
toggleDropdown() {
|
||||
this.isOpen = !this.isOpen;
|
||||
this.calculateDropdownPosition();
|
||||
}
|
||||
|
||||
@State() mode: boolean = false;
|
||||
@Prop() darkMode: boolean = false;
|
||||
@State() themeState: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default';
|
||||
@Prop() theme: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default';
|
||||
@Watch('theme')
|
||||
watchPropHandler(newValue: 'default' | 'ocean' | 'lemonade' | 'purple') {
|
||||
this.themeState = newValue;
|
||||
}
|
||||
|
||||
@Watch('darkMode')
|
||||
watchModeHandler(newValue: boolean) {
|
||||
this.mode = newValue;
|
||||
}
|
||||
|
||||
@Watch('accounts')
|
||||
watchAccountsHandler(newValue: Info[]) {
|
||||
this.options = newValue;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.themeState = this.theme;
|
||||
this.mode = this.darkMode;
|
||||
}
|
||||
|
||||
calculateDropdownPosition() {
|
||||
if (this.isOpen && this.buttonRef) {
|
||||
const buttonRect = this.buttonRef.getBoundingClientRect();
|
||||
this.ulRef.style.top = `${buttonRect.height}px`;
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(el: Info) {
|
||||
this.handleSwitchAccount.emit(el);
|
||||
}
|
||||
|
||||
handleOpenModal() {
|
||||
this.handleOpenWelcomeModal.emit();
|
||||
}
|
||||
|
||||
render() {
|
||||
const listClass = `${this.isOpen ? 'listClass flex flex-col gap-2' : 'hidden'} w-full nl-select-list absolute z-10 left-0 shadow-md rounded-lg p-2 mt-1 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full`;
|
||||
const arrowClass = `${this.isOpen ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-gray-500`;
|
||||
const filteredOptions =
|
||||
this.options && this.currentAccount ? this.options.filter(el => el.pubkey !== this.currentAccount.pubkey || el.authMethod !== this.currentAccount.authMethod) : [];
|
||||
|
||||
return (
|
||||
<div class={`theme-${this.themeState}`}>
|
||||
<div class="relative" ref={el => (this.wrapperRef = el)}>
|
||||
<button
|
||||
ref={el => (this.buttonRef = el)}
|
||||
onClick={() => this.toggleDropdown()}
|
||||
type="button"
|
||||
class="nl-select peer py-3 px-4 flex items-center w-full justify-between border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
>
|
||||
<span class="text-gray-500">Switch profile</span>
|
||||
<svg
|
||||
class={arrowClass}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m6 9 6 6 6-6" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<ul ref={el => (this.ulRef = el)} class={listClass}>
|
||||
{this.options &&
|
||||
filteredOptions.map(el => {
|
||||
const isShowImg = Boolean(el?.picture);
|
||||
const userName = el.name || el.nip05 || el.pubkey;
|
||||
const isShowUserName = Boolean(userName);
|
||||
|
||||
return (
|
||||
<li onClick={() => this.handleChange(el)} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm">
|
||||
<div class="uppercase font-bold w-full max-w-6 h-6 rounded-full border border-gray-400 flex justify-center items-center">
|
||||
{isShowImg ? (
|
||||
<img class="w-full rounded-full" src={el.picture} alt="Logo" />
|
||||
) : isShowUserName ? (
|
||||
userName[0]
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
{/*<div class="truncate overflow-hidden w-full">{userName}</div>*/}
|
||||
|
||||
<div class="overflow-hidden flex flex-col w-full">
|
||||
<div class="truncate overflow-hidden">{userName}</div>
|
||||
<nl-login-status info={el} />
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
<li class="first:pt-0 pt-2 border-t-[1px] first:border-none border-gray-300">
|
||||
<div onClick={() => this.handleOpenModal()} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm">
|
||||
<div class="uppercase font-bold w-6 h-6 rounded-full border border-gray-400 flex justify-center items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||
</svg>
|
||||
</div>
|
||||
Add profile
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# nl-change-account
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------------- | ----------- | ----------- | ------------------------------------------------ | ----------- |
|
||||
| `accounts` | -- | | `Info[]` | `[]` |
|
||||
| `currentAccount` | -- | | `Info` | `null` |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `theme` | `theme` | | `"default" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ------------------------ | ----------- | --------------------- |
|
||||
| `handleOpenWelcomeModal` | | `CustomEvent<string>` |
|
||||
| `handleSwitchAccount` | | `CustomEvent<Info>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-banner](../nl-banner)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-login-status](../nl-login-status)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-change-account --> nl-login-status
|
||||
nl-banner --> nl-change-account
|
||||
style nl-change-account fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Component, Event, EventEmitter, Prop, h } from '@stencil/core';
|
||||
import { CURRENT_MODULE, METHOD_MODULE } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-confirm-logout',
|
||||
styleUrl: 'nl-confirm-logout.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlConfirmLogout {
|
||||
@Prop() titleModal = "Delete keys?";
|
||||
@Prop() description = "Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible.";
|
||||
@Event() handleLogoutBanner: EventEmitter<string>;
|
||||
@Event() handleBackUpModal: EventEmitter<string>;
|
||||
@Event() nlCloseModal: EventEmitter;
|
||||
|
||||
handleLogout() {
|
||||
this.handleLogoutBanner.emit(METHOD_MODULE.LOGOUT);
|
||||
this.nlCloseModal.emit();
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
this.nlCloseModal.emit();
|
||||
}
|
||||
|
||||
handleBackUp() {
|
||||
state.path = [CURRENT_MODULE.IMPORT_FLOW];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-4xl">{this.titleModal}</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
|
||||
<div class="mt-3 ml-auto mr-auto w-60 flex flex-col gap-2">
|
||||
{/* <button-base onClick={() => this.handleCancel()} titleBtn="Cancel" /> */}
|
||||
<button-base onClick={() => this.handleBackUp()} titleBtn="Backup keys" theme="lemonade" />
|
||||
<button-base onClick={() => this.handleLogout()} theme="crab" titleBtn="Logout and delete keys" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# nl-confirm-logout
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `"Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible."` |
|
||||
| `titleModal` | `title-modal` | | `string` | `"Delete keys?"` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| -------------------- | ----------- | --------------------- |
|
||||
| `handleBackUpModal` | | `CustomEvent<string>` |
|
||||
| `handleLogoutBanner` | | `CustomEvent<string>` |
|
||||
| `nlCloseModal` | | `CustomEvent<any>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-confirm-logout --> button-base
|
||||
nl-auth --> nl-confirm-logout
|
||||
style nl-confirm-logout fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
178
packages/components/src/components/nl-connect/nl-connect.tsx
Normal file
178
packages/components/src/components/nl-connect/nl-connect.tsx
Normal file
@@ -0,0 +1,178 @@
|
||||
import { Component, Event, EventEmitter, Fragment, h, Prop, State } from '@stencil/core';
|
||||
import { AuthMethod, ConnectionString, CURRENT_MODULE } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-connect',
|
||||
styleUrl: 'nl-connect.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlConnect {
|
||||
@Prop() titleWelcome = 'Connect to key store';
|
||||
@Prop() authMethods: AuthMethod[] = [];
|
||||
@Prop() hasOTP: boolean = false;
|
||||
@Prop() connectionStringServices: ConnectionString[] = [];
|
||||
|
||||
@State() isOpenAdvancedLogin: boolean = false;
|
||||
@Event() nlNostrConnect: EventEmitter<ConnectionString>;
|
||||
|
||||
handleChangeScreen(screen) {
|
||||
state.path = [...state.path, screen];
|
||||
}
|
||||
|
||||
handleOpenAdvanced() {
|
||||
this.isOpenAdvancedLogin = !this.isOpenAdvancedLogin;
|
||||
}
|
||||
|
||||
allowAuthMethod(m: AuthMethod) {
|
||||
return !this.authMethods.length || this.authMethods.includes(m);
|
||||
}
|
||||
|
||||
componentWillLoad() {}
|
||||
|
||||
handleOpenLink(e: Event, cs: ConnectionString) {
|
||||
e.preventDefault();
|
||||
this.nlNostrConnect.emit(cs);
|
||||
}
|
||||
|
||||
handleConnectionString() {
|
||||
this.handleChangeScreen(CURRENT_MODULE.CONNECTION_STRING)
|
||||
}
|
||||
|
||||
render() {
|
||||
const arrowClass = `${this.isOpenAdvancedLogin ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-blue-500`;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-3xl">{this.titleWelcome}</h1>
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
{Boolean(this.connectionStringServices.length) && (
|
||||
<div class="max-w-96 mx-auto pt-5">
|
||||
<p class="nl-description font-medium text-sm pb-1.5">Select key store:</p>
|
||||
<ul class="p-2 rounded-lg border border-gray-200 flex flex-col w-full gap-0.5">
|
||||
{this.connectionStringServices.map(el => {
|
||||
return (
|
||||
<li>
|
||||
<a
|
||||
href={el.link}
|
||||
target="_blank"
|
||||
onClick={e => this.handleOpenLink(e, el)}
|
||||
class="flex items-center gap-x-3.5 w-full hover:bg-gray-300 flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm justify-between"
|
||||
>
|
||||
<div class="w-full max-w-7 h-7 flex relative">
|
||||
<div class="uppercase font-bold w-full h-full rounded-full border border-gray-400 flex justify-center items-center">
|
||||
{Boolean(el.img) ? (
|
||||
<img class="w-full rounded-full" src={el.img} alt={el.name} />
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#9ca3af" class="w-4 h-4 block">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-hidden flex flex-col w-full">
|
||||
<div class="nl-title truncate overflow-hidden">{el.name}</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
<div class="max-w-52 mx-auto pb-5">
|
||||
{(this.allowAuthMethod('connect') || this.allowAuthMethod('readOnly')) && (
|
||||
<div class="flex justify-center">
|
||||
<div
|
||||
onClick={() => this.handleOpenAdvanced()}
|
||||
class="text-blue-500 mt-3 decoration-dashed cursor-pointer inline-flex gap-2 items-center pb-1 border-dashed border-b-[1px] border-blue-500 text-sm font-light"
|
||||
>
|
||||
Advanced
|
||||
<svg
|
||||
class={arrowClass}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m6 9 6 6 6-6" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
class={`${this.isOpenAdvancedLogin ? 'max-h-[500px] mt-3 duration-300' : 'max-h-0 mt-0 duration-[0.25s]'} transition-max-height ease-in flex gap-3 flex-col overflow-hidden`}
|
||||
>
|
||||
{/* {this.hasExtension && !this.allowAuthMethod('extension') && this.renderSignInWithExtension()} */}
|
||||
{this.allowAuthMethod('connect') && (
|
||||
<button-base titleBtn="User name" onClick={() => this.handleChangeScreen(CURRENT_MODULE.LOGIN)}>
|
||||
<svg
|
||||
style={{ display: 'none' }}
|
||||
slot="icon-start"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
// class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
|
||||
{this.allowAuthMethod('connect') && (
|
||||
<button-base titleBtn="Connection string" onClick={() => this.handleConnectionString()}>
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
|
||||
{this.allowAuthMethod('connect') && (
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.LOGIN_BUNKER_URL)} titleBtn="Bunker URL">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
43
packages/components/src/components/nl-connect/readme.md
Normal file
43
packages/components/src/components/nl-connect/readme.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# nl-connect
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------------------- | --------------- | ----------- | -------------------- | ------------------------ |
|
||||
| `authMethods` | -- | | `AuthMethod[]` | `[]` |
|
||||
| `connectionStringServices` | -- | | `ConnectionString[]` | `[]` |
|
||||
| `hasOTP` | `has-o-t-p` | | `boolean` | `false` |
|
||||
| `titleWelcome` | `title-welcome` | | `string` | `'Connect to key store'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ---------------- | ----------- | ------------------------------- |
|
||||
| `nlNostrConnect` | | `CustomEvent<ConnectionString>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-connect --> button-base
|
||||
nl-auth --> nl-connect
|
||||
style nl-connect fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
26
packages/components/src/components/nl-dialog/nl-dialog.tsx
Normal file
26
packages/components/src/components/nl-dialog/nl-dialog.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Component, h } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-dialog',
|
||||
styleUrl: 'nl-dialog.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class NlDialog {
|
||||
private dialogElement?: HTMLDialogElement;
|
||||
|
||||
componentDidLoad() {
|
||||
this.dialogElement?.showModal();
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.dialogElement?.close();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<dialog ref={el => (this.dialogElement = el as HTMLDialogElement)} class={'m-auto nl-banner-dialog'} style={{ border: '0', backgroundColor: 'transparent' }}>
|
||||
<slot></slot>
|
||||
</dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
23
packages/components/src/components/nl-dialog/readme.md
Normal file
23
packages/components/src/components/nl-dialog/readme.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# nl-dialog
|
||||
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-banner](../nl-banner)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-banner --> nl-dialog
|
||||
style nl-dialog fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
40
packages/components/src/components/nl-iframe/nl-iframe.tsx
Normal file
40
packages/components/src/components/nl-iframe/nl-iframe.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Component, Event, EventEmitter, Prop, h } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-iframe',
|
||||
styleUrl: 'nl-iframe.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlConfirmLogout {
|
||||
@Prop() titleModal = 'Confirm';
|
||||
@Prop() description = 'Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible.';
|
||||
@Prop() iframeUrl = '';
|
||||
@Event() nlCloseModal: EventEmitter;
|
||||
|
||||
handleCancel() {
|
||||
this.nlCloseModal.emit();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
{/* <h1 class="nl-title font-bold text-center text-4xl">{this.titleModal}</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{this.description}</p> */}
|
||||
|
||||
<div class="mt-3 flex flex-col gap-2">
|
||||
{this.iframeUrl && (
|
||||
<iframe
|
||||
src={this.iframeUrl}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '600px',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
></iframe>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
39
packages/components/src/components/nl-iframe/readme.md
Normal file
39
packages/components/src/components/nl-iframe/readme.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# nl-iframe
|
||||
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Your profile keys are stored in this browser tab and will be deleted if you log out, and your profile will be inaccessible.'` |
|
||||
| `iframeUrl` | `iframe-url` | | `string` | `''` |
|
||||
| `titleModal` | `title-modal` | | `string` | `'Confirm'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| -------------- | ----------- | ------------------ |
|
||||
| `nlCloseModal` | | `CustomEvent<any>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-auth --> nl-iframe
|
||||
style nl-iframe fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
import { Component, h, Fragment, State, Prop, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
import { ConnectionString } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-import-flow',
|
||||
styleUrl: 'nl-import-flow.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlImportFlow {
|
||||
@Prop({ mutable: true }) titleInfo = 'Back up your keys';
|
||||
@Prop() titleImport = 'Choose a service';
|
||||
@Prop() services: ConnectionString[] = [];
|
||||
|
||||
@State() isContinued = false;
|
||||
@State() isKeyBackup = false;
|
||||
|
||||
@State() isCopy = false;
|
||||
|
||||
@Event() nlImportAccount: EventEmitter<ConnectionString>;
|
||||
@Event() nlExportKeys: EventEmitter<void>;
|
||||
|
||||
handleDomainSelect(event: CustomEvent<string>) {
|
||||
const s = this.services.find(s => s.domain === event.detail);
|
||||
state.nlImport = s;
|
||||
}
|
||||
|
||||
handleCreateAccount(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
this.nlImportAccount.emit(state.nlImport);
|
||||
}
|
||||
|
||||
handleContinue() {
|
||||
this.isContinued = true;
|
||||
}
|
||||
|
||||
handleContinueKeyBackup() {
|
||||
this.isKeyBackup = true;
|
||||
}
|
||||
|
||||
async copyToClipboard() {
|
||||
this.nlExportKeys.emit();
|
||||
this.isCopy = true;
|
||||
|
||||
setTimeout(() => {
|
||||
this.isCopy = false;
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.isContinued && !this.isKeyBackup) {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleInfo}</h1>
|
||||
<p class="nl-description font-light text-sm pt-2 pb-2 max-w-96 mx-auto">
|
||||
Nostr profiles are controlled by cryptographic keys.
|
||||
<br />
|
||||
<br />
|
||||
Your keys are currently only stored in this browser tab, and may be lost if you close it.
|
||||
<br />
|
||||
<br />
|
||||
You should backup your keys.
|
||||
<br />
|
||||
<br />
|
||||
We recommend to import your keys into a key store service, to protect them and to use with other apps.
|
||||
{/* <br />
|
||||
<br />
|
||||
You can also export your keys and save them in your password manager. */}
|
||||
</p>
|
||||
<div class="ml-auto mr-auto mb-2 w-72">
|
||||
<button-base onClick={() => this.handleContinue()} titleBtn="Import to key store" />
|
||||
</div>
|
||||
<div class="ml-auto mr-auto w-72">
|
||||
<button-base onClick={() => this.handleContinueKeyBackup()} titleBtn="Export keys" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isKeyBackup) {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">Key export</h1>
|
||||
<p class="nl-description font-light text-sm pt-2 pb-2 max-w-96 mx-auto">
|
||||
Copy your keys and store them in a safe place, like a password manager.
|
||||
<br />
|
||||
<br />
|
||||
You can sign into other Nostr apps by pasting your keys into them.
|
||||
<br />
|
||||
<br />
|
||||
Your keys must be kept secret, never share them with anyone.
|
||||
</p>
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="ml-auto mr-auto mb-2 w-72">
|
||||
<button-base onClick={() => this.copyToClipboard()} titleBtn={this.isCopy ? 'Copied!' : 'Copy to clipboard'} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const options = this.services.filter(s => s.canImport).map(s => ({ name: s.domain!, value: s.domain! }));
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleImport}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">
|
||||
Your Nostr keys will be imported into the service you choose. You will manage your keys on their website.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto mb-5">
|
||||
<div class="mb-0.5">
|
||||
<nl-select onSelectDomain={e => this.handleDomainSelect(e)} selected={0} options={options}></nl-select>
|
||||
</div>
|
||||
<p class="nl-title font-light text-sm mb-2">Default provider is a fine choice to start with.</p>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base disabled={state.isLoading} onClick={e => this.handleCreateAccount(e)} titleBtn="Start importing">
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg slot="icon-start" style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
45
packages/components/src/components/nl-import-flow/readme.md
Normal file
45
packages/components/src/components/nl-import-flow/readme.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# nl-import-flow
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | -------------- | ----------- | -------------------- | --------------------- |
|
||||
| `services` | -- | | `ConnectionString[]` | `[]` |
|
||||
| `titleImport` | `title-import` | | `string` | `'Choose a service'` |
|
||||
| `titleInfo` | `title-info` | | `string` | `'Back up your keys'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ----------------- | ----------- | ------------------------------- |
|
||||
| `nlExportKeys` | | `CustomEvent<void>` |
|
||||
| `nlImportAccount` | | `CustomEvent<ConnectionString>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
- [nl-select](../nl-select)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-import-flow --> button-base
|
||||
nl-import-flow --> nl-select
|
||||
nl-auth --> nl-import-flow
|
||||
style nl-import-flow fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Component, h } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-info-extension',
|
||||
styleUrl: 'nl-info-extension.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlInfoExtension {
|
||||
render() {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
{state.isLoadingExtension ? (
|
||||
<div>
|
||||
<h1 class="nl-title font-bold text-center text-4xl">Signing in...</h1>
|
||||
<div class="mt-10 mb-10 ml-auto mr-auto w-20">
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading ml-auto mr-auto inline-block w-20 h-20 border-[4px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
</div>
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<h1 class="nl-title font-bold text-center text-4xl">Install browser extension!</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">
|
||||
Try{' '}
|
||||
<a href="https://getalby.com" target="_blank">
|
||||
Alby
|
||||
</a>
|
||||
,{' '}
|
||||
<a href="https://chromewebstore.google.com/detail/nos2x/kpgefcfmnafjgpblomihpgmejjdanjjp" target="_blank">
|
||||
nos2x
|
||||
</a>{' '}
|
||||
or{' '}
|
||||
<a href="https://apps.apple.com/us/app/nostore/id1666553677" target="_blank">
|
||||
Nostore
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# nl-info-extension
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-auth --> nl-info-extension
|
||||
style nl-info-extension fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
3
packages/components/src/components/nl-info/nl-info.css
Normal file
3
packages/components/src/components/nl-info/nl-info.css
Normal file
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
46
packages/components/src/components/nl-info/nl-info.tsx
Normal file
46
packages/components/src/components/nl-info/nl-info.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Component, h, Prop } from '@stencil/core';
|
||||
import { NlTheme } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-info',
|
||||
styleUrl: 'nl-info.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlInfo {
|
||||
@Prop() theme: NlTheme = 'default';
|
||||
@Prop() darkMode: boolean = false;
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<svg class="w-12 h-12 mx-auto mb-2" width="225" height="224" viewBox="0 0 225 224" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="224.047" height="224" rx="64" fill={this.theme === 'laan' ? (this.darkMode ? 'white' : 'black') : '#6951FA'} />
|
||||
<path
|
||||
d="M162.441 135.941V88.0593C170.359 85.1674 176 77.5348 176 68.6696C176 57.2919 166.708 48 155.33 48C143.953 48 134.661 57.2444 134.661 68.6696C134.661 77.5822 140.302 85.1674 148.219 88.0593V135.941C147.698 136.13 147.176 136.367 146.655 136.604L87.3956 77.3452C88.6282 74.6904 89.2919 71.7511 89.2919 68.6696C89.2919 57.2444 80.0474 48 68.6696 48C57.2919 48 48 57.2444 48 68.6696C48 77.5822 53.6415 85.1674 61.5585 88.0593V135.941C53.6415 138.833 48 146.465 48 155.33C48 166.708 57.2444 176 68.6696 176C80.0948 176 89.3393 166.708 89.3393 155.33C89.3393 146.418 83.6978 138.833 75.7807 135.941V88.0593C76.3022 87.8696 76.8237 87.6326 77.3452 87.3956L136.604 146.655C135.372 149.31 134.708 152.249 134.708 155.33C134.708 166.708 143.953 176 155.378 176C166.803 176 176.047 166.708 176.047 155.33C176.047 146.418 170.406 138.833 162.489 135.941H162.441Z"
|
||||
fill={this.theme === 'laan' ? (this.darkMode ? 'black' : 'white') : 'white'}
|
||||
/>
|
||||
</svg>
|
||||
<h1 class="nl-title font-bold text-center text-4xl">
|
||||
Nostr <span class="font-light">Login</span>
|
||||
</h1>
|
||||
<p class="text-green-800 dark:text-green-200 font-light text-center text-lg pt-2 max-w-96 mx-auto">Version: 1.7.11</p>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">
|
||||
Learn more about Nostr{' '}
|
||||
<a target="_blank" href="https://nostr.how">
|
||||
here
|
||||
</a>
|
||||
.<br />
|
||||
This is an{' '}
|
||||
<a target="_blank" href="https://github.com/nostrband/nostr-login">
|
||||
open-source
|
||||
</a>{' '}
|
||||
tool by{' '}
|
||||
<a target="_blank" href="https://nostr.band">
|
||||
Nostr.Band
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
29
packages/components/src/components/nl-info/readme.md
Normal file
29
packages/components/src/components/nl-info/readme.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# nl-info
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------- | ----------- | ----------- | -------------------------------------------------------------------- | ----------- |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `theme` | `theme` | | `"crab" \| "default" \| "laan" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-auth --> nl-info
|
||||
style nl-info fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
93
packages/components/src/components/nl-loading/nl-loading.tsx
Normal file
93
packages/components/src/components/nl-loading/nl-loading.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Component, Event, EventEmitter, Prop, h } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
import { CURRENT_MODULE } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-loading',
|
||||
styleUrl: 'nl-loading.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlLoading {
|
||||
@Event() stopFetchHandler: EventEmitter<boolean>;
|
||||
@Event() handleContinue: EventEmitter<boolean>;
|
||||
@Prop() path: string;
|
||||
|
||||
handleStop(e) {
|
||||
e.preventDefault();
|
||||
this.stopFetchHandler.emit();
|
||||
}
|
||||
|
||||
handleContinueClick(e) {
|
||||
e.preventDefault();
|
||||
// reset();
|
||||
this.handleContinue.emit();
|
||||
}
|
||||
|
||||
render() {
|
||||
let title = 'Connecting...';
|
||||
let text = 'Establishing connection to your key storage.';
|
||||
if (state.njumpIframe) {
|
||||
title = '';
|
||||
text = '';
|
||||
} else if (this.path === CURRENT_MODULE.LOCAL_SIGNUP) {
|
||||
title = 'Creating...';
|
||||
text = 'Publishing your profile on Nostr.';
|
||||
} else if (state.authUrl) {
|
||||
if (state.isLoading) {
|
||||
title = 'Confirming...';
|
||||
text = 'Please confirm the connection in your key storage app.';
|
||||
} else {
|
||||
title = 'Almost ready!';
|
||||
text = 'Continue to confirm the connection to your key storage.';
|
||||
}
|
||||
}
|
||||
|
||||
const showButton = this.path !== CURRENT_MODULE.LOCAL_SIGNUP;
|
||||
const showIframe = !state.isLoading && state.iframeUrl && state.authUrl;
|
||||
const iframeUrl = state.iframeUrl ? `${state.iframeUrl}?connect=${encodeURIComponent(state.authUrl)}` : '';
|
||||
|
||||
return (
|
||||
<div class="p-4 overflow-y-auto">
|
||||
{title && (<h1 class="nl-title font-bold text-center text-4xl">{title}</h1>)}
|
||||
{text && (<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{text}</p>)}
|
||||
{!state.njumpIframe && !state.authUrl && state.isLoading && (
|
||||
<div class="mt-10 mb-10 ml-auto mr-auto w-20">
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading ml-auto mr-auto inline-block w-20 h-20 border-[4px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
</div>
|
||||
)}
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
{iframeUrl && (
|
||||
<div class="mt-3 ml-auto mr-auto w-72 flex justify-center">
|
||||
<iframe src={iframeUrl} width="180px" height="80px" style={{ display: showIframe ? 'block' : 'none', border: '0' }}></iframe>
|
||||
</div>
|
||||
)}
|
||||
{state.njumpIframe && (
|
||||
<div class="mt-3 ml-auto mr-auto flex justify-center">
|
||||
<iframe srcdoc={state.njumpIframe} width="600px" style={{ border: '0', height: "80vh", borderRadius: "8px" }}></iframe>
|
||||
</div>
|
||||
)}
|
||||
{!showIframe && showButton && (
|
||||
<div class="mt-3 ml-auto mr-auto w-72">
|
||||
<button-base
|
||||
onClick={e => {
|
||||
if (state.authUrl && !state.isLoading) {
|
||||
this.handleContinueClick(e);
|
||||
} else {
|
||||
this.handleStop(e);
|
||||
}
|
||||
}}
|
||||
titleBtn={!state.isLoading ? 'Continue' : 'Cancel'}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
41
packages/components/src/components/nl-loading/readme.md
Normal file
41
packages/components/src/components/nl-loading/readme.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# nl-loading
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------- | --------- | ----------- | -------- | ----------- |
|
||||
| `path` | `path` | | `string` | `undefined` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ------------------ | ----------- | ---------------------- |
|
||||
| `handleContinue` | | `CustomEvent<boolean>` |
|
||||
| `stopFetchHandler` | | `CustomEvent<boolean>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-loading --> button-base
|
||||
nl-auth --> nl-loading
|
||||
style nl-loading fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import { Component, h, Fragment, State, Prop, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-local-signup',
|
||||
styleUrl: 'nl-local-signup.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlLocalSignup {
|
||||
@Prop() titleSignup = 'Create Nostr profile';
|
||||
@Prop() description = 'Choose any username, you can always change it later.';
|
||||
@Prop() descriptionNjump = 'Proceed to creating your Nostr profile in a new tab.';
|
||||
@Prop() signupNjump = false;
|
||||
|
||||
@State() isAvailable = false;
|
||||
|
||||
@Event() nlLocalSignup: EventEmitter<string>;
|
||||
@Event() nlSignupNjump: EventEmitter<void>;
|
||||
// @Event() nlCheckSignup: EventEmitter<string>;
|
||||
@Event() fetchHandler: EventEmitter<boolean>;
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
state.nlSignup.signupName = (event.target as HTMLInputElement).value;
|
||||
// this.nlCheckSignup.emit(`${(event.target as HTMLInputElement).value}@${state.nlSignup.domain}`);
|
||||
}
|
||||
|
||||
handleCreateAccount(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.signupNjump) {
|
||||
this.nlSignupNjump.emit();
|
||||
} else {
|
||||
this.nlLocalSignup.emit(`${state.nlSignup.signupName}`);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleSignup}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.signupNjump ? this.descriptionNjump : this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
{!this.signupNjump && (
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="Enter username"
|
||||
value={state.nlSignup.signupName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke={this.isAvailable ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base disabled={state.isLoading} onClick={e => this.handleCreateAccount(e)} titleBtn={this.signupNjump ? 'Get started' : 'Create profile'}>
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg slot="icon-start" style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
45
packages/components/src/components/nl-local-signup/readme.md
Normal file
45
packages/components/src/components/nl-local-signup/readme.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# nl-local-signup
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------------ | ------------------- | ----------- | --------- | -------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Choose any username, you can always change it later.'` |
|
||||
| `descriptionNjump` | `description-njump` | | `string` | `'Proceed to creating your Nostr profile in a new tab.'` |
|
||||
| `signupNjump` | `signup-njump` | | `boolean` | `false` |
|
||||
| `titleSignup` | `title-signup` | | `string` | `'Create Nostr profile'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| --------------- | ----------- | ---------------------- |
|
||||
| `fetchHandler` | | `CustomEvent<boolean>` |
|
||||
| `nlLocalSignup` | | `CustomEvent<string>` |
|
||||
| `nlSignupNjump` | | `CustomEvent<void>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-local-signup --> button-base
|
||||
nl-auth --> nl-local-signup
|
||||
style nl-local-signup fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Info, RecentType } from '@/types';
|
||||
import { Component, h, Prop } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-login-status',
|
||||
// styleUrl: 'nl-login-status.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlLoginStatus {
|
||||
@Prop() info: RecentType | Info | undefined;
|
||||
|
||||
render() {
|
||||
let text = '';
|
||||
let color = '';
|
||||
if (this.info.authMethod === 'extension') {
|
||||
text = 'Extension';
|
||||
color = 'border-yellow-300 text-yellow-500 bg-yellow-100';
|
||||
} else if (this.info.authMethod === 'readOnly') {
|
||||
text = 'Read only';
|
||||
color = 'border-gray-300 text-gray-400 bg-gray-100';
|
||||
} else if (this.info.authMethod === 'connect') {
|
||||
text = 'Connect';
|
||||
color = 'border-teal-300 text-teal-600 bg-teal-100';
|
||||
} else if (this.info.authMethod === 'local') {
|
||||
text = 'Temporary';
|
||||
color = 'border-red-300 text-red-600 bg-red-100';
|
||||
} else if (this.info.authMethod === 'otp') {
|
||||
text = 'Delegated';
|
||||
color = 'border-orange-300 text-orange-600 bg-orange-100';
|
||||
} else {
|
||||
console.log('unknown auth method', this.info);
|
||||
throw new Error('Unknown auth method');
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span class={`${color} rounded-xl border w-auto text-[10px] px-1 `}>{text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
32
packages/components/src/components/nl-login-status/readme.md
Normal file
32
packages/components/src/components/nl-login-status/readme.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# nl-login-status
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
|
||||
| `info` | -- | | `Info \| { name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }` | `undefined` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-banner](../nl-banner)
|
||||
- [nl-change-account](../nl-change-account)
|
||||
- [nl-previously-logged](../nl-previously-logged)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-banner --> nl-login-status
|
||||
nl-change-account --> nl-login-status
|
||||
nl-previously-logged --> nl-login-status
|
||||
style nl-login-status fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Component, h, Fragment, Prop, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
import { ConnectionString } from '@/types';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-otp-migrate',
|
||||
styleUrl: 'nl-otp-migrate.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlImportFlow {
|
||||
@Prop({ mutable: true }) titleInfo = 'Import keys to storage service';
|
||||
@Prop() titleImport = 'Choose a service';
|
||||
@Prop() textImport = 'You will be prompted to import keys to the chosen service, and this website will connect to your keys.';
|
||||
@Prop() services: ConnectionString[] = [];
|
||||
|
||||
@Event() nlImportAccount: EventEmitter<ConnectionString>;
|
||||
|
||||
handleDomainSelect(event: CustomEvent<string>) {
|
||||
const s = this.services.find(s => s.domain === event.detail);
|
||||
state.nlImport = s;
|
||||
}
|
||||
|
||||
handleCreateAccount(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
this.nlImportAccount.emit(state.nlImport);
|
||||
}
|
||||
|
||||
render() {
|
||||
const options = this.services.filter(s => s.canImport).map(s => ({ name: s.domain!, value: s.domain! }));
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleImport}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.textImport}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto mb-5">
|
||||
<div class="mb-0.5">
|
||||
<nl-select onSelectDomain={e => this.handleDomainSelect(e)} selected={0} options={options}></nl-select>
|
||||
</div>
|
||||
<p class="nl-title font-light text-sm mb-2">Default provider is a fine choice to start with.</p>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base disabled={state.isLoading} onClick={e => this.handleCreateAccount(e)} titleBtn="Start importing">
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg slot="icon-start" style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
47
packages/components/src/components/nl-otp-migrate/readme.md
Normal file
47
packages/components/src/components/nl-otp-migrate/readme.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# nl-otp-migrate
|
||||
|
||||
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | -------------- | ----------- | -------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `services` | -- | | `ConnectionString[]` | `[]` |
|
||||
| `textImport` | `text-import` | | `string` | `'You will be prompted to import keys to the chosen service, and this website will connect to your keys.'` |
|
||||
| `titleImport` | `title-import` | | `string` | `'Choose a service'` |
|
||||
| `titleInfo` | `title-info` | | `string` | `'Import keys to storage service'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ----------------- | ----------- | ------------------------------- |
|
||||
| `nlImportAccount` | | `CustomEvent<ConnectionString>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-select](../nl-select)
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-otp-migrate --> nl-select
|
||||
nl-otp-migrate --> button-base
|
||||
nl-auth --> nl-otp-migrate
|
||||
style nl-otp-migrate fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,4 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
import { Component, h, Fragment, Prop, Event, EventEmitter, Watch } from '@stencil/core';
|
||||
import { CURRENT_MODULE, Info, RecentType } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-previously-logged',
|
||||
styleUrl: 'nl-previously-logged.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlPreviouslyLogged {
|
||||
@Prop() titlePage = 'Your profiles';
|
||||
@Prop() description = 'Switch between active profiles or choose a recent one for fast login.';
|
||||
|
||||
@Prop() accounts: Info[] = [];
|
||||
@Prop() recents: RecentType[] = [];
|
||||
|
||||
@Event() nlSwitchAccount: EventEmitter<Info>;
|
||||
@Event() nlLoginRecentAccount: EventEmitter<RecentType>;
|
||||
@Event() nlRemoveRecent: EventEmitter<RecentType>;
|
||||
|
||||
handleGoToWelcome() {
|
||||
state.path = [CURRENT_MODULE.WELCOME];
|
||||
}
|
||||
|
||||
switchToWelcomeIfEmpty() {
|
||||
if (!this.recents.length && !this.accounts.length) {
|
||||
state.path = [CURRENT_MODULE.WELCOME];
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('accounts')
|
||||
watchAccounts() {
|
||||
this.switchToWelcomeIfEmpty();
|
||||
}
|
||||
|
||||
@Watch('recents')
|
||||
watchRecents() {
|
||||
this.switchToWelcomeIfEmpty();
|
||||
}
|
||||
|
||||
handleRemoveRecent(user: Info) {
|
||||
this.nlRemoveRecent.emit(user);
|
||||
}
|
||||
|
||||
handleSwitch(el: Info) {
|
||||
this.nlSwitchAccount.emit(el);
|
||||
}
|
||||
|
||||
handleLoginRecentAccount(el: RecentType) {
|
||||
this.nlLoginRecentAccount.emit(el);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 pt-0 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-4xl">{this.titlePage}</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
{Boolean(this.accounts.length) && (
|
||||
<div class="max-w-96 mx-auto">
|
||||
<p class="nl-description font-medium text-sm pb-1.5">Active profiles</p>
|
||||
<ul class="p-2 rounded-lg border border-blue-200 flex flex-col w-full gap-0.5">
|
||||
{this.accounts.map(el => {
|
||||
const isShowImg = Boolean(el?.picture);
|
||||
const userName = el.name || el.nip05 || el.pubkey;
|
||||
const isShowUserName = Boolean(userName);
|
||||
|
||||
return (
|
||||
<li onClick={() => this.handleSwitch(el)} class="group hover:bg-gray-400 flex cursor-pointer gap-x-3.5 py-2 px-3 rounded-lg text-sm items-center justify-between">
|
||||
<div class="flex items-center gap-x-3.5 w-full">
|
||||
<div class="w-full max-w-7 h-7 flex relative">
|
||||
<div class="absolute top-[-2px] right-[-2px] bg-white border-2 border-white rounded-xl">
|
||||
<div class="active h-1.5 w-1.5 bg-green-500 rounded-xl"></div>
|
||||
</div>
|
||||
<div class="group-hover:border-blue-400 uppercase font-bold w-full h-full rounded-full border border-gray-400 flex justify-center items-center">
|
||||
{isShowImg ? (
|
||||
<img class="w-full rounded-full" src={el.picture} alt="Logo" />
|
||||
) : isShowUserName ? (
|
||||
userName[0]
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden flex flex-col w-full">
|
||||
<div class="nl-title truncate overflow-hidden">{userName}</div>
|
||||
<nl-login-status info={el} />
|
||||
</div>
|
||||
</div>
|
||||
{/* <div class="w-full max-w-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full hover:text-blue-600">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 9V5.25A2.25 2.25 0 0 1 10.5 3h6a2.25 2.25 0 0 1 2.25 2.25v13.5A2.25 2.25 0 0 1 16.5 21h-6a2.25 2.25 0 0 1-2.25-2.25V15M12 9l3 3m0 0-3 3m3-3H2.25"
|
||||
/>
|
||||
</svg>
|
||||
</div> */}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{Boolean(this.recents.length) && (
|
||||
<div class="max-w-96 mx-auto pt-5">
|
||||
<p class="nl-description font-medium text-sm pb-1.5">Recent profiles</p>
|
||||
<ul class="p-2 rounded-lg border border-gray-200 flex flex-col w-full gap-0.5">
|
||||
{this.recents.map(el => {
|
||||
const isShowImg = Boolean(el?.picture);
|
||||
const userName = el.name || el.nip05 || el.pubkey;
|
||||
const isShowUserName = Boolean(userName);
|
||||
|
||||
return (
|
||||
<li
|
||||
onClick={() => this.handleLoginRecentAccount(el)}
|
||||
class="flex items-center gap-x-3.5 w-full hover:bg-gray-400 flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm justify-between"
|
||||
>
|
||||
<div class="w-full max-w-7 h-7 flex relative">
|
||||
<div class="absolute top-[-3px] right-[-3px] bg-white border border-white rounded-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3 h-3">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="uppercase font-bold w-full h-full rounded-full border border-gray-400 flex justify-center items-center">
|
||||
{isShowImg ? (
|
||||
<img class="w-full rounded-full" src={el.picture} alt="Logo" />
|
||||
) : isShowUserName ? (
|
||||
userName[0]
|
||||
) : (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-hidden flex flex-col w-full">
|
||||
<div class="nl-title truncate overflow-hidden">{userName}</div>
|
||||
<nl-login-status info={el} />
|
||||
</div>
|
||||
<svg
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
this.handleRemoveRecent(el);
|
||||
}}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
class="w-full max-w-6 h-6 text-red-500 hover:text-red-600 ml-auto"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
|
||||
/>
|
||||
</svg>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<p class="nl-footer font-light text-center text-sm max-w-96 mx-auto">
|
||||
You can also{' '}
|
||||
<span onClick={() => this.handleGoToWelcome()} class="cursor-pointer pb-3 text-blue-500">
|
||||
add another profile
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# nl-previously-logged
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------------- | ------------------------------------------------------------------------- |
|
||||
| `accounts` | -- | | `Info[]` | `[]` |
|
||||
| `description` | `description` | | `string` | `'Switch between active profiles or choose a recent one for fast login.'` |
|
||||
| `recents` | -- | | `RecentType[]` | `[]` |
|
||||
| `titlePage` | `title-page` | | `string` | `'Your profiles'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ---------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `nlLoginRecentAccount` | | `CustomEvent<{ name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }>` |
|
||||
| `nlRemoveRecent` | | `CustomEvent<{ name?: string; picture?: string; nip05?: string; pubkey: string; bunkerUrl?: string; authMethod: AuthMethod; domain?: string; signerPubkey?: string; }>` |
|
||||
| `nlSwitchAccount` | | `CustomEvent<Info>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-login-status](../nl-login-status)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-previously-logged --> nl-login-status
|
||||
nl-auth --> nl-previously-logged
|
||||
style nl-previously-logged fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
118
packages/components/src/components/nl-select/nl-select.tsx
Normal file
118
packages/components/src/components/nl-select/nl-select.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import { Component, h, Listen, Prop, State, Watch, Element, Event, EventEmitter } from '@stencil/core';
|
||||
|
||||
export type OptionType = {
|
||||
name: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
@Component({
|
||||
tag: 'nl-select',
|
||||
styleUrl: 'nl-select.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSelect {
|
||||
@State() isOpen: boolean = false;
|
||||
@State() value: OptionType = null;
|
||||
@Prop() options: OptionType[];
|
||||
@Prop() selected: number;
|
||||
|
||||
@Element() element: HTMLElement;
|
||||
|
||||
@Event() selectDomain: EventEmitter<string>;
|
||||
|
||||
buttonRef: HTMLButtonElement;
|
||||
ulRef: HTMLUListElement;
|
||||
wrapperRef: HTMLDivElement;
|
||||
|
||||
@Listen('click', { target: 'window' })
|
||||
handleWindowClick() {
|
||||
if (this.wrapperRef.querySelector('.listClass')) {
|
||||
this.isOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
toggleDropdown() {
|
||||
this.isOpen = !this.isOpen;
|
||||
this.calculateDropdownPosition();
|
||||
}
|
||||
|
||||
@State() mode: boolean = false;
|
||||
@Prop() darkMode: boolean = false;
|
||||
@State() themeState: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default';
|
||||
@Prop() theme: 'default' | 'ocean' | 'lemonade' | 'purple' = 'default';
|
||||
@Watch('theme')
|
||||
watchPropHandler(newValue: 'default' | 'ocean' | 'lemonade' | 'purple') {
|
||||
this.themeState = newValue;
|
||||
}
|
||||
|
||||
@Watch('darkMode')
|
||||
watchModeHandler(newValue: boolean) {
|
||||
this.mode = newValue;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.themeState = this.theme;
|
||||
this.mode = this.darkMode;
|
||||
|
||||
this.value = this.options[this.selected];
|
||||
this.selectDomain.emit(this.value.value);
|
||||
}
|
||||
|
||||
calculateDropdownPosition() {
|
||||
if (this.isOpen && this.buttonRef) {
|
||||
const buttonRect = this.buttonRef.getBoundingClientRect();
|
||||
this.ulRef.style.top = `${buttonRect.height}px`;
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(el: OptionType) {
|
||||
this.value = el;
|
||||
this.isOpen = false;
|
||||
|
||||
this.selectDomain.emit(this.value.value);
|
||||
}
|
||||
|
||||
render() {
|
||||
const listClass = `${this.isOpen ? 'listClass' : 'hidden'} min-w-[15rem] nl-select-list absolute left-0 shadow-md rounded-lg p-2 mt-1 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full`;
|
||||
const arrowClass = `${this.isOpen ? 'rotate-180' : 'rotate-0'} duration-300 flex-shrink-0 w-4 h-4 text-gray-500`;
|
||||
|
||||
return (
|
||||
<div class={`theme-${this.themeState}`}>
|
||||
<div class="relative" ref={el => (this.wrapperRef = el)}>
|
||||
<button
|
||||
ref={el => (this.buttonRef = el)}
|
||||
onClick={() => this.toggleDropdown()}
|
||||
type="button"
|
||||
class="nl-select peer py-3 px-4 flex items-center w-full justify-between border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
>
|
||||
<span class="truncate overflow-hidden">{this.value.name}</span>
|
||||
<svg
|
||||
class={arrowClass}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m6 9 6 6 6-6" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<ul ref={el => (this.ulRef = el)} class={listClass}>
|
||||
{this.options.map(el => {
|
||||
return (
|
||||
<li onClick={() => this.handleChange(el)} class="nl-select-option flex cursor-pointer items-center gap-x-3.5 py-2 px-3 rounded-lg text-sm">
|
||||
{el.name}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
42
packages/components/src/components/nl-select/readme.md
Normal file
42
packages/components/src/components/nl-select/readme.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# nl-select
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------- | ----------- | ----------- | ------------------------------------------------ | ----------- |
|
||||
| `darkMode` | `dark-mode` | | `boolean` | `false` |
|
||||
| `options` | -- | | `OptionType[]` | `undefined` |
|
||||
| `selected` | `selected` | | `number` | `undefined` |
|
||||
| `theme` | `theme` | | `"default" \| "lemonade" \| "ocean" \| "purple"` | `'default'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| -------------- | ----------- | --------------------- |
|
||||
| `selectDomain` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-import-flow](../nl-import-flow)
|
||||
- [nl-otp-migrate](../nl-otp-migrate)
|
||||
- [nl-signup](../nl-signup)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-import-flow --> nl-select
|
||||
nl-otp-migrate --> nl-select
|
||||
nl-signup --> nl-select
|
||||
style nl-select fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signin-bunker-url',
|
||||
styleUrl: 'nl-signin-bunker-url.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSigninBunkerUrl {
|
||||
@Prop() titleLogin = 'Connect with bunker url';
|
||||
@Prop() description = 'Please enter a bunker url provided by key store.';
|
||||
@State() isGood = false;
|
||||
|
||||
@Event() nlLogin: EventEmitter<string>;
|
||||
@Event() nlCheckLogin: EventEmitter<string>;
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
state.nlSigninBunkerUrl.loginName = (event.target as HTMLInputElement).value;
|
||||
|
||||
this.nlCheckLogin.emit((event.target as HTMLInputElement).value);
|
||||
}
|
||||
|
||||
handleLogin(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
this.nlLogin.emit(state.nlSigninBunkerUrl.loginName);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleLogin}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="bunker://..."
|
||||
value={state.nlSigninBunkerUrl.loginName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke={this.isGood ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base titleBtn="Connect" disabled={state.isLoading} onClick={e => this.handleLogin(e)}>
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 9V5.25A2.25 2.25 0 0 1 10.5 3h6a2.25 2.25 0 0 1 2.25 2.25v13.5A2.25 2.25 0 0 1 16.5 21h-6a2.25 2.25 0 0 1-2.25-2.25V15M12 9l3 3m0 0-3 3m3-3H2.25"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# nl-signin-bunker-url
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------- | ---------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Please enter a bunker url provided by key store.'` |
|
||||
| `titleLogin` | `title-login` | | `string` | `'Connect with bunker url'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| -------------- | ----------- | --------------------- |
|
||||
| `nlCheckLogin` | | `CustomEvent<string>` |
|
||||
| `nlLogin` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-signin-bunker-url --> button-base
|
||||
nl-auth --> nl-signin-bunker-url
|
||||
style nl-signin-bunker-url fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import { Component, h, Prop, Fragment, State, Event, EventEmitter } from '@stencil/core';
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signin-connection-string',
|
||||
styleUrl: 'nl-signin-connection-string.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSigninConnectionString {
|
||||
@Prop() titleLogin = 'Connection string';
|
||||
@Prop() description = 'Scan or copy the connection string with key store app';
|
||||
@Prop() connectionString = '';
|
||||
@State() isCopy = false;
|
||||
@Event() nlNostrConnectDefault: EventEmitter<void>;
|
||||
|
||||
private canvasElement: HTMLCanvasElement;
|
||||
|
||||
componentDidLoad() {
|
||||
this.nlNostrConnectDefault.emit();
|
||||
this.generateQRCode();
|
||||
}
|
||||
|
||||
async generateQRCode() {
|
||||
if (this.connectionString && this.canvasElement) {
|
||||
try {
|
||||
await QRCode.toCanvas(this.canvasElement, this.connectionString);
|
||||
} catch (error) {
|
||||
console.error('Error generating QR Code:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async copyToClipboard() {
|
||||
try {
|
||||
await navigator.clipboard.writeText(this.connectionString);
|
||||
|
||||
this.isCopy = true;
|
||||
|
||||
setTimeout(() => {
|
||||
this.isCopy = false;
|
||||
}, 1500);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy connectionString: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleLogin}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<canvas class="mx-auto mb-2" ref={el => (this.canvasElement = el as HTMLCanvasElement)}></canvas>
|
||||
|
||||
<div class="px-4">
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 pe-11 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="npub or name@domain"
|
||||
value={this.connectionString}
|
||||
disabled
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-4 h-4 text-gray-500">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||
/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{this.isCopy ? (
|
||||
<div class="absolute inset-y-0 end-0 flex items-center p-2 rounded-lg">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="#00cc00" class="flex-shrink-0 w-4 h-4 text-gray-500">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
) : (
|
||||
<div class="absolute inset-y-0 end-0 flex items-center cursor-pointer p-2 rounded-lg" onClick={() => this.copyToClipboard()}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-4 h-4 text-gray-500">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M16.5 8.25V6a2.25 2.25 0 0 0-2.25-2.25H6A2.25 2.25 0 0 0 3.75 6v8.25A2.25 2.25 0 0 0 6 16.5h2.25m8.25-8.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-7.5A2.25 2.25 0 0 1 8.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 0 0-2.25 2.25v6"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div class="mt-10 justify-center items-center flex gap-2">
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-[20px] h-[20px] border-[2px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
<span class="nl-footer">Waiting for connection</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# nl-signin-connection-string
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------------ | ------------------- | ----------- | -------- | --------------------------------------------------------- |
|
||||
| `connectionString` | `connection-string` | | `string` | `''` |
|
||||
| `description` | `description` | | `string` | `'Scan or copy the connection string with key store app'` |
|
||||
| `titleLogin` | `title-login` | | `string` | `'Connection string'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ----------------------- | ----------- | ------------------- |
|
||||
| `nlNostrConnectDefault` | | `CustomEvent<void>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-auth --> nl-signin-connection-string
|
||||
style nl-signin-connection-string fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signin-otp',
|
||||
styleUrl: 'nl-signin-otp.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSigninOtp {
|
||||
@Prop() titleLogin = 'Log in with DM';
|
||||
@Prop() description = 'Please enter your user name or npub, and we will send you a direct message with a one-time code.';
|
||||
@Prop() titleLoginOTP = 'Enter the code';
|
||||
@Prop() descriptionOTP = 'Please enter the one-time code we sent to you as a direct message on Nostr.';
|
||||
@State() isGood = false;
|
||||
|
||||
@Event() nlLoginOTPUser: EventEmitter<string>;
|
||||
@Event() nlLoginOTPCode: EventEmitter<string>;
|
||||
@Event() nlCheckLogin: EventEmitter<string>;
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
if (!state.isOTP) {
|
||||
state.nlSigninOTP.loginName = (event.target as HTMLInputElement).value;
|
||||
this.nlCheckLogin.emit(state.nlSigninOTP.loginName);
|
||||
} else {
|
||||
state.nlSigninOTP.code = (event.target as HTMLInputElement).value;
|
||||
}
|
||||
}
|
||||
|
||||
handleLogin(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
if (state.isOTP) this.nlLoginOTPCode.emit(state.nlSigninOTP.code);
|
||||
else this.nlLoginOTPUser.emit(state.nlSigninOTP.loginName);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{state.isOTP ? this.titleLoginOTP : this.titleLogin}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{state.isOTP ? this.descriptionOTP : this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder={state.isOTP ? 'code from direct message' : 'npub or name@domain'}
|
||||
value={state.isOTP ? state.nlSigninOTP.code : state.nlSigninOTP.loginName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke={this.isGood ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||
/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base titleBtn="Log in" disabled={state.isLoading} onClick={e => this.handleLogin(e)}>
|
||||
{state.isLoading && (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
45
packages/components/src/components/nl-signin-otp/readme.md
Normal file
45
packages/components/src/components/nl-signin-otp/readme.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# nl-signin-otp
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ---------------- | ------------------- | ----------- | -------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Please enter your user name or npub, and we will send you a direct message with a one-time code.'` |
|
||||
| `descriptionOTP` | `description-o-t-p` | | `string` | `'Please enter the one-time code we sent to you as a direct message on Nostr.'` |
|
||||
| `titleLogin` | `title-login` | | `string` | `'Log in with DM'` |
|
||||
| `titleLoginOTP` | `title-login-o-t-p` | | `string` | `'Enter the code'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ---------------- | ----------- | --------------------- |
|
||||
| `nlCheckLogin` | | `CustomEvent<string>` |
|
||||
| `nlLoginOTPCode` | | `CustomEvent<string>` |
|
||||
| `nlLoginOTPUser` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-signin-otp --> button-base
|
||||
nl-auth --> nl-signin-otp
|
||||
style nl-signin-otp fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signin-read-only',
|
||||
styleUrl: 'nl-signin-read-only.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSigninReadOnly {
|
||||
@Prop() titleLogin = 'Log in to read only';
|
||||
@Prop() description = 'Please enter the user name or npub of any Nostr user.';
|
||||
@State() isGood = false;
|
||||
|
||||
@Event() nlLoginReadOnly: EventEmitter<string>;
|
||||
@Event() nlCheckLogin: EventEmitter<string>;
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
state.nlSigninReadOnly.loginName = (event.target as HTMLInputElement).value;
|
||||
this.nlCheckLogin.emit((event.target as HTMLInputElement).value); // .emit(this.loginName);
|
||||
}
|
||||
|
||||
handleLogin(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
this.nlLoginReadOnly.emit(state.nlSigninReadOnly.loginName);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleLogin}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="npub or name@domain"
|
||||
value={state.nlSigninReadOnly.loginName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke={this.isGood ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||
/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base titleBtn="Log in" disabled={state.isLoading} onClick={e => this.handleLogin(e)}>
|
||||
{state.isLoading && (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
# nl-signin-read-only
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------- | --------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Please enter the user name or npub of any Nostr user.'` |
|
||||
| `titleLogin` | `title-login` | | `string` | `'Log in to read only'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ----------------- | ----------- | --------------------- |
|
||||
| `nlCheckLogin` | | `CustomEvent<string>` |
|
||||
| `nlLoginReadOnly` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-signin-read-only --> button-base
|
||||
nl-auth --> nl-signin-read-only
|
||||
style nl-signin-read-only fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
96
packages/components/src/components/nl-signin/nl-signin.tsx
Normal file
96
packages/components/src/components/nl-signin/nl-signin.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import { Component, h, State, Prop, Fragment, Event, EventEmitter } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signin',
|
||||
styleUrl: 'nl-signin.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSignin {
|
||||
@Prop() titleLogin = 'Connect to key store';
|
||||
@Prop() description = 'Please enter your user name.';
|
||||
@State() isGood = false;
|
||||
|
||||
@Event() nlLogin: EventEmitter<string>;
|
||||
@Event() nlCheckLogin: EventEmitter<string>;
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
state.nlSignin.loginName = (event.target as HTMLInputElement).value;
|
||||
this.nlCheckLogin.emit((event.target as HTMLInputElement).value);
|
||||
}
|
||||
|
||||
handleLogin(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
this.nlLogin.emit(state.nlSignin.loginName);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleLogin}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="name@domain.com"
|
||||
value={state.nlSignin.loginName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
{/* <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="flex-shrink-0 w-4 h-4 text-gray-500">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
|
||||
/>
|
||||
</svg> */}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke={this.isGood ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base titleBtn="Connect" disabled={state.isLoading} onClick={e => this.handleLogin(e)}>
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 9V5.25A2.25 2.25 0 0 1 10.5 3h6a2.25 2.25 0 0 1 2.25 2.25v13.5A2.25 2.25 0 0 1 16.5 21h-6a2.25 2.25 0 0 1-2.25-2.25V15M12 9l3 3m0 0-3 3m3-3H2.25"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
42
packages/components/src/components/nl-signin/readme.md
Normal file
42
packages/components/src/components/nl-signin/readme.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# nl-signin
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | ------------- | ----------- | -------- | -------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Please enter your user name.'` |
|
||||
| `titleLogin` | `title-login` | | `string` | `'Connect to key store'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| -------------- | ----------- | --------------------- |
|
||||
| `nlCheckLogin` | | `CustomEvent<string>` |
|
||||
| `nlLogin` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-signin --> button-base
|
||||
nl-auth --> nl-signin
|
||||
style nl-signin fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
125
packages/components/src/components/nl-signup/nl-signup.tsx
Normal file
125
packages/components/src/components/nl-signup/nl-signup.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
import { Component, h, Fragment, State, Prop, Event, EventEmitter, Watch } from '@stencil/core';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-signup',
|
||||
styleUrl: 'nl-signup.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlSignup {
|
||||
@Prop() titleSignup = 'Create keys with key store';
|
||||
@Prop() description = 'Choose some username and a key store service.';
|
||||
@Prop() bunkers: string = 'nsec.app,highlighter.com';
|
||||
|
||||
@State() isAvailable = false;
|
||||
|
||||
@Event() nlSignup: EventEmitter<string>;
|
||||
@Event() nlCheckSignup: EventEmitter<string>;
|
||||
@Event() fetchHandler: EventEmitter<boolean>;
|
||||
|
||||
formatServers(bunkers: string) {
|
||||
return bunkers.split(',').map(d => ({
|
||||
name: '@' + d,
|
||||
value: d,
|
||||
}));
|
||||
}
|
||||
|
||||
handleInputChange(event: Event) {
|
||||
state.nlSignup.signupName = (event.target as HTMLInputElement).value;
|
||||
this.nlCheckSignup.emit(`${(event.target as HTMLInputElement).value}@${state.nlSignup.domain}`);
|
||||
}
|
||||
|
||||
handleDomainSelect(event: CustomEvent<string>) {
|
||||
state.nlSignup.domain = event.detail;
|
||||
this.nlCheckSignup.emit(`${state.nlSignup.signupName}@${event.detail}`);
|
||||
}
|
||||
|
||||
handleCreateAccount(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
this.nlSignup.emit(`${state.nlSignup.signupName}@${state.nlSignup.domain}`);
|
||||
}
|
||||
|
||||
@Watch('bunkers')
|
||||
watchBunkersHandler(newValue: string) {
|
||||
state.nlSignup.servers = this.formatServers(newValue);
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
state.nlSignup.servers = this.formatServers(this.bunkers);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-2xl">{this.titleSignup}</h1>
|
||||
<p class="nl-description font-light text-center text-sm pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-72 mx-auto">
|
||||
<div class="relative mb-2">
|
||||
<input
|
||||
onInput={e => this.handleInputChange(e)}
|
||||
type="text"
|
||||
class="nl-input peer py-3 px-4 ps-11 block w-full border-transparent rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none dark:border-transparent"
|
||||
placeholder="Name"
|
||||
value={state.nlSignup.signupName}
|
||||
/>
|
||||
<div class="absolute inset-y-0 start-0 flex items-center pointer-events-none ps-4 peer-disabled:opacity-50 peer-disabled:pointer-events-none">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke={this.isAvailable ? '#00cc00' : 'currentColor'}
|
||||
class="flex-shrink-0 w-4 h-4 text-gray-500"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
{/* {inputStatus && (
|
||||
<p class={classError}>{textError}</p>
|
||||
)} */}
|
||||
<div class="mb-2">
|
||||
{/*<select class="nl-select border-transparent py-3 px-4 pe-9 block w-full rounded-lg text-sm disabled:opacity-50 disabled:pointer-events-none">*/}
|
||||
{/* <option selected value="@nsec.app">*/}
|
||||
{/* @nsec.app*/}
|
||||
{/* </option>*/}
|
||||
{/*</select>*/}
|
||||
<nl-select onSelectDomain={e => this.handleDomainSelect(e)} selected={0} options={state.nlSignup.servers}></nl-select>
|
||||
</div>
|
||||
{/* <p class="nl-title font-light text-sm mb-2">Choose a service to manage your Nostr keys.</p> */}
|
||||
|
||||
<div class="ps-4 pe-4 overflow-y-auto">
|
||||
<p class="nl-error font-light text-center text-sm max-w-96 mx-auto">{state.error}</p>
|
||||
</div>
|
||||
|
||||
<button-base disabled={state.isLoading} onClick={e => this.handleCreateAccount(e)} titleBtn="Create profile">
|
||||
{state.isLoading ? (
|
||||
<span
|
||||
slot="icon-start"
|
||||
class="animate-spin-loading inline-block w-4 h-4 border-[3px] border-current border-t-transparent text-slate-900 dark:text-gray-300 rounded-full"
|
||||
role="status"
|
||||
aria-label="loading"
|
||||
></span>
|
||||
) : (
|
||||
<svg slot="icon-start" style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
46
packages/components/src/components/nl-signup/readme.md
Normal file
46
packages/components/src/components/nl-signup/readme.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# nl-signup
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| ------------- | -------------- | ----------- | -------- | ------------------------------------------------- |
|
||||
| `bunkers` | `bunkers` | | `string` | `'nsec.app,highlighter.com'` |
|
||||
| `description` | `description` | | `string` | `'Choose some username and a key store service.'` |
|
||||
| `titleSignup` | `title-signup` | | `string` | `'Create keys with key store'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| --------------- | ----------- | ---------------------- |
|
||||
| `fetchHandler` | | `CustomEvent<boolean>` |
|
||||
| `nlCheckSignup` | | `CustomEvent<string>` |
|
||||
| `nlSignup` | | `CustomEvent<string>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [nl-select](../nl-select)
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-signup --> nl-select
|
||||
nl-signup --> button-base
|
||||
nl-auth --> nl-signup
|
||||
style nl-signup fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Component, Event, EventEmitter, Fragment, h, Prop } from '@stencil/core';
|
||||
import { AuthMethod, CURRENT_MODULE } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-welcome-signin',
|
||||
styleUrl: 'nl-welcome-signin.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlWelcomeSignIn {
|
||||
@Prop() titleWelcome = 'Log in';
|
||||
@Prop() hasExtension: boolean = false;
|
||||
@Prop() authMethods: AuthMethod[] = [];
|
||||
@Prop() hasOTP: boolean = false;
|
||||
@Event() nlLoginExtension: EventEmitter<void>;
|
||||
|
||||
handleChangeScreen(screen) {
|
||||
state.path = [...state.path, screen];
|
||||
if (screen === CURRENT_MODULE.EXTENSION) this.nlLoginExtension.emit();
|
||||
}
|
||||
|
||||
allowAuthMethod(m: AuthMethod) {
|
||||
return !this.authMethods.length || this.authMethods.includes(m);
|
||||
}
|
||||
|
||||
renderSignInWithExtension() {
|
||||
return (
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.EXTENSION)} titleBtn="With extension">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M3 8.25V18a2.25 2.25 0 0 0 2.25 2.25h13.5A2.25 2.25 0 0 0 21 18V8.25m-18 0V6a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 6v2.25m-18 0h18M5.25 6h.008v.008H5.25V6ZM7.5 6h.008v.008H7.5V6Zm2.25 0h.008v.008H9.75V6Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-3xl">{this.titleWelcome}</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-52 mx-auto pb-5">
|
||||
<div class="flex gap-3 flex-col">
|
||||
{this.allowAuthMethod('connect') && (
|
||||
<button-base titleBtn="Connect" onClick={() => this.handleChangeScreen(CURRENT_MODULE.CONNECT)}>
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M8.25 9V5.25A2.25 2.25 0 0 1 10.5 3h6a2.25 2.25 0 0 1 2.25 2.25v13.5A2.25 2.25 0 0 1 16.5 21h-6a2.25 2.25 0 0 1-2.25-2.25V15M12 9l3 3m0 0-3 3m3-3H2.25"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
|
||||
{this.allowAuthMethod('readOnly') && (
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.LOGIN_READ_ONLY)} titleBtn="Read only">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
||||
/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
|
||||
{this.hasOTP && this.allowAuthMethod('otp') && (
|
||||
<button-base titleBtn="One-time code" onClick={() => this.handleChangeScreen(CURRENT_MODULE.LOGIN_OTP)}>
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
</button-base>
|
||||
)}
|
||||
|
||||
{this.hasExtension && this.allowAuthMethod('extension') && this.renderSignInWithExtension()}
|
||||
{!this.allowAuthMethod('connect') && !this.hasExtension && <p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">No Nostr extension!</p>}
|
||||
{!this.allowAuthMethod('connect') && this.hasExtension && !this.allowAuthMethod('extension') && (
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">Use advanced options.</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
# nl-welcome-signin
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------- | --------------- | ----------- | -------------- | ---------- |
|
||||
| `authMethods` | -- | | `AuthMethod[]` | `[]` |
|
||||
| `hasExtension` | `has-extension` | | `boolean` | `false` |
|
||||
| `hasOTP` | `has-o-t-p` | | `boolean` | `false` |
|
||||
| `titleWelcome` | `title-welcome` | | `string` | `'Log in'` |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Type |
|
||||
| ------------------ | ----------- | ------------------- |
|
||||
| `nlLoginExtension` | | `CustomEvent<void>` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-welcome-signin --> button-base
|
||||
nl-auth --> nl-welcome-signin
|
||||
style nl-welcome-signin fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Component, Fragment, h, Prop } from '@stencil/core';
|
||||
import { CURRENT_MODULE } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-welcome-signup',
|
||||
styleUrl: 'nl-welcome-signup.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlWelcomeSignUp {
|
||||
@Prop() titleWelcome = 'Sign up';
|
||||
@Prop() description = 'Nostr profiles are based on cryptographic keys. You can create keys right here, or with a key storage app.';
|
||||
|
||||
handleChangeScreen(screen) {
|
||||
state.path = [...state.path, screen];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-3xl">{this.titleWelcome}</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-52 mx-auto pb-5">
|
||||
<div class="flex gap-3 flex-col">
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.LOCAL_SIGNUP)} titleBtn="Create keys">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.SIGNUP)} titleBtn="With key store">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# nl-welcome-signup
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------- | --------------- | ----------- | -------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'Nostr profiles are based on cryptographic keys. You can create keys right here, or with a key storage app.'` |
|
||||
| `titleWelcome` | `title-welcome` | | `string` | `'Sign up'` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-welcome-signup --> button-base
|
||||
nl-auth --> nl-welcome-signup
|
||||
style nl-welcome-signup fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
54
packages/components/src/components/nl-welcome/nl-welcome.tsx
Normal file
54
packages/components/src/components/nl-welcome/nl-welcome.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Component, Fragment, h, Prop } from '@stencil/core';
|
||||
import { CURRENT_MODULE } from '@/types';
|
||||
import { state } from '@/store';
|
||||
|
||||
@Component({
|
||||
tag: 'nl-welcome',
|
||||
styleUrl: 'nl-welcome.css',
|
||||
shadow: false,
|
||||
})
|
||||
export class NlWelcome {
|
||||
@Prop() titleWelcome = 'Welcome to Nostr!';
|
||||
@Prop() description = 'This website is part of the Nostr network. Log in with your Nostr profile or sign up to join.';
|
||||
|
||||
handleChangeScreen(screen) {
|
||||
state.path = [...state.path, screen];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Fragment>
|
||||
<div class="p-4 overflow-y-auto">
|
||||
<h1 class="nl-title font-bold text-center text-4xl">{this.titleWelcome}</h1>
|
||||
<p class="nl-description font-light text-center text-lg pt-2 max-w-96 mx-auto">{this.description}</p>
|
||||
</div>
|
||||
|
||||
<div class="max-w-52 mx-auto pb-5">
|
||||
<div class="flex gap-3 flex-col mb-2">
|
||||
<button-base titleBtn="Log in" onClick={() => this.handleChangeScreen(CURRENT_MODULE.WELCOME_LOGIN)}>
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
</div>
|
||||
|
||||
{/* <div class="nl-divider py-3 flex items-center text-xs uppercase before:flex-[1_1_0%] before:border-t before:me-6 after:flex-[1_1_0%] after:border-t after:ms-6">Or</div> */}
|
||||
|
||||
<button-base onClick={() => this.handleChangeScreen(CURRENT_MODULE.WELCOME_SIGNUP)} titleBtn="Sign up">
|
||||
<svg style={{ display: 'none' }} slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M18 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0ZM3 19.235v-.11a6.375 6.375 0 0 1 12.75 0v.109A12.318 12.318 0 0 1 9.374 21c-2.331 0-4.512-.645-6.374-1.766Z"
|
||||
/>
|
||||
</svg>
|
||||
</button-base>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
34
packages/components/src/components/nl-welcome/readme.md
Normal file
34
packages/components/src/components/nl-welcome/readme.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# nl-welcome
|
||||
|
||||
<!-- Auto Generated Below -->
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Attribute | Description | Type | Default |
|
||||
| -------------- | --------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `description` | `description` | | `string` | `'This website is part of the Nostr network. Log in with your Nostr profile or sign up to join.'` |
|
||||
| `titleWelcome` | `title-welcome` | | `string` | `'Welcome to Nostr!'` |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Used by
|
||||
|
||||
- [nl-auth](../nl-auth)
|
||||
|
||||
### Depends on
|
||||
|
||||
- [button-base](../button-base)
|
||||
|
||||
### Graph
|
||||
```mermaid
|
||||
graph TD;
|
||||
nl-welcome --> button-base
|
||||
nl-auth --> nl-welcome
|
||||
style nl-welcome fill:#f9f,stroke:#333,stroke-width:4px
|
||||
```
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
*Built with [StencilJS](https://stenciljs.com/)*
|
||||
315
packages/components/src/index.html
Normal file
315
packages/components/src/index.html
Normal file
@@ -0,0 +1,315 @@
|
||||
<!doctype html>
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
|
||||
<title>Modal Auth Develop</title>
|
||||
<style>
|
||||
.nl-button {
|
||||
margin-top: 100px;
|
||||
}
|
||||
div {
|
||||
background: #9fc6db;
|
||||
}
|
||||
</style>
|
||||
<script type="module">
|
||||
import './build/components.esm.js';
|
||||
|
||||
// const initialModals = async opt => {
|
||||
// const bunkerUrl = await launch(opt);
|
||||
//
|
||||
// console.log({ bunkerUrl });
|
||||
// };
|
||||
//
|
||||
// initialModals({
|
||||
// theme: 'purple',
|
||||
// startScreen: 'signup',
|
||||
// });
|
||||
//
|
||||
// const nlElements = document.getElementsByTagName('nl-button');
|
||||
//
|
||||
// for (let i = 0; i < nlElements.length; i++) {
|
||||
// const theme = nlElements[i].getAttribute('nl-theme');
|
||||
// const startScreen = nlElements[i].getAttribute('start-screen');
|
||||
//
|
||||
// nlElements[i].addEventListener('click', function () {
|
||||
// initialModals({
|
||||
// theme,
|
||||
// startScreen,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
const listNotifies = [];
|
||||
|
||||
const banner = document.createElement('nl-banner');
|
||||
|
||||
const launch = opt => {
|
||||
const dialog = document.createElement('dialog');
|
||||
const modal = document.createElement('nl-auth');
|
||||
|
||||
// dialog.appendChild(modal);
|
||||
document.body.appendChild(modal);
|
||||
|
||||
const startLoadingModal = document.getElementById('startloadingmodal');
|
||||
|
||||
startLoadingModal.addEventListener('click', () => {
|
||||
modal.isLoading = true;
|
||||
});
|
||||
|
||||
const setAuthUrl = document.getElementById('setauthurl');
|
||||
|
||||
setAuthUrl.addEventListener('click', () => {
|
||||
modal.isLoading = false;
|
||||
modal.authUrl = 'authUrl';
|
||||
});
|
||||
|
||||
return new Promise(resolve => {
|
||||
modal.addEventListener('handleGetValue', event => {
|
||||
const inputValue = event.detail;
|
||||
|
||||
resolve(inputValue);
|
||||
});
|
||||
|
||||
modal.addEventListener('handleCloseModal', event => {
|
||||
dialog.close();
|
||||
const inputValue = event.detail;
|
||||
|
||||
resolve(inputValue);
|
||||
});
|
||||
|
||||
modal.addEventListener('handleRemoveWindowNostr', () => {
|
||||
console.log('handleRemoveWindowNostr');
|
||||
});
|
||||
|
||||
modal.addEventListener('nlLocalSignup', () => {
|
||||
console.log('nlLocalSignup');
|
||||
|
||||
modal.isLoading = true;
|
||||
|
||||
setTimeout(() => {
|
||||
modal.isLoading = false;
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
modal.addEventListener('nlCloseModal', () => {
|
||||
console.log('close modal');
|
||||
modal.remove();
|
||||
});
|
||||
|
||||
modal.addEventListener('nlChangeDarkMode', () => {
|
||||
console.log('handleChangeDarkMode');
|
||||
modal.darkMode = true;
|
||||
});
|
||||
|
||||
modal.addEventListener('changeScreen', () => {
|
||||
console.log('changeScreen');
|
||||
});
|
||||
|
||||
modal.addEventListener('stopFetchHandler', () => {
|
||||
modal.isLoading = false;
|
||||
console.log('stopFetchHandler');
|
||||
// FIXME reset the modal state, return to welcome screen
|
||||
});
|
||||
|
||||
modal.addEventListener('handleContinue', () => {
|
||||
modal.authUrl = '';
|
||||
});
|
||||
|
||||
const recent = JSON.parse(localStorage.getItem('__nostrlogin_recent'));
|
||||
const accounts = JSON.parse(localStorage.getItem('__nostrlogin_accounts'));
|
||||
|
||||
modal.accounts = accounts;
|
||||
modal.recents = recent;
|
||||
|
||||
// dialog.showModal();
|
||||
if (opt && opt.theme) {
|
||||
modal.theme = opt.theme;
|
||||
}
|
||||
|
||||
if (opt && opt.startScreen) {
|
||||
modal.setAttribute('start-screen', opt.startScreen);
|
||||
}
|
||||
|
||||
if (opt && opt.isSignInWithExtension !== undefined) {
|
||||
modal.isSignInWithExtension = opt.isSignInWithExtension;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
document.body.appendChild(banner);
|
||||
|
||||
const btnLogin = document.getElementById('login');
|
||||
|
||||
btnLogin.addEventListener('click', () => {
|
||||
banner.userInfo = {
|
||||
pubkey: 'bcce12ab52dfbeefdf0a964efdb78ec05d2daf5d8865bcf427facf96071cf1d1',
|
||||
sk: '60355cb7ac0aff92e566e9311e54e2b1cfe40178740cb10b4314bbe3f282859a',
|
||||
relays: ['wss://relay.nsec.app'],
|
||||
token: '',
|
||||
authMethod: 'local',
|
||||
nip05: 'misterband@nsec.app',
|
||||
picture:
|
||||
'https://img.freepik.com/free-photo/the-adorable-illustration-of-kittens-playing-in-the-forest-generative-ai_260559-483.jpg?size=338&ext=jpg&ga=GA1.1.1413502914.1713830400&semt=ais',
|
||||
name: 'misterband',
|
||||
};
|
||||
});
|
||||
|
||||
banner.addEventListener('handleLogoutBanner', () => {
|
||||
banner.userInfo = null;
|
||||
});
|
||||
|
||||
banner.addEventListener('handleOpenWelcomeModal', () => {
|
||||
const recent = JSON.parse(localStorage.getItem('__nostrlogin_recent'));
|
||||
const accounts = JSON.parse(localStorage.getItem('__nostrlogin_accounts'));
|
||||
|
||||
let options = {
|
||||
// theme: 'lemonade',
|
||||
isSignInWithExtension: false,
|
||||
};
|
||||
|
||||
if (Boolean(recent?.length) || Boolean(accounts?.length)) {
|
||||
options = { ...options, startScreen: 'switch-account' };
|
||||
}
|
||||
|
||||
console.log({ options });
|
||||
launch(options);
|
||||
});
|
||||
|
||||
banner.addEventListener('handleConfirmLogout', () => {
|
||||
let options = {
|
||||
startScreen: 'confirm-logout',
|
||||
};
|
||||
|
||||
launch(options);
|
||||
});
|
||||
|
||||
banner.addEventListener('handleBackUpModal', () => {
|
||||
let options = {
|
||||
startScreen: 'backup-flow',
|
||||
};
|
||||
|
||||
launch(options);
|
||||
});
|
||||
|
||||
banner.addEventListener('handleSetConfirmBanner', event => {
|
||||
listNotifies.push(event.detail);
|
||||
|
||||
banner.listNotifies = listNotifies;
|
||||
});
|
||||
|
||||
banner.addEventListener('handleRetryConfirmBanner', () => {
|
||||
listNotifies.pop();
|
||||
|
||||
banner.listNotifies = listNotifies;
|
||||
});
|
||||
|
||||
banner.addEventListener('handleNotifyConfirmBanner', () => {
|
||||
console.log('handleNotifyConfirmBanner');
|
||||
});
|
||||
|
||||
const startLoading = document.getElementById('startloading');
|
||||
const stopLoading = document.getElementById('stoploading');
|
||||
const notify = document.getElementById('notify');
|
||||
|
||||
startLoading.addEventListener('click', () => {
|
||||
banner.isLoading = true;
|
||||
});
|
||||
|
||||
stopLoading.addEventListener('click', () => {
|
||||
banner.isLoading = false;
|
||||
});
|
||||
|
||||
notify.addEventListener('click', () => {
|
||||
banner.notify = {
|
||||
confirm: Date.now(),
|
||||
url: 'test.html',
|
||||
// timeOut: { link: 'link.test' },
|
||||
};
|
||||
});
|
||||
|
||||
const testBtn = document.createElement('nl-button');
|
||||
|
||||
document.body.appendChild(testBtn);
|
||||
|
||||
setTimeout(() => {
|
||||
testBtn.titleBtn = 'test text 1111111';
|
||||
setTimeout(() => {
|
||||
testBtn.nlTheme = 'purple';
|
||||
}, 2000);
|
||||
}, 2000);
|
||||
|
||||
const addAccounts = document.getElementById('add-accounts');
|
||||
|
||||
addAccounts.addEventListener('click', () => {
|
||||
localStorage.setItem(
|
||||
'__nostrlogin_accounts',
|
||||
JSON.stringify([
|
||||
{
|
||||
pubkey: 'bcce12ab52dfbeefdf0a964efdb78ec05d2daf5d8865bcf427facf96071cf1d1',
|
||||
sk: '60355cb7ac0aff92e566e9311e54e2b1cfe40178740cb10b4314bbe3f282859a',
|
||||
relays: ['wss://relay.nsec.app'],
|
||||
token: '',
|
||||
authMethod: 'local',
|
||||
nip05: 'misterband@nsec.app',
|
||||
picture:
|
||||
'https://img.freepik.com/free-photo/the-adorable-illustration-of-kittens-playing-in-the-forest-generative-ai_260559-483.jpg?size=338&ext=jpg&ga=GA1.1.1413502914.1713830400&semt=ais',
|
||||
name: 'misterband',
|
||||
},
|
||||
{
|
||||
pubkey: '03eb6c27a82f5aff10aa143f7c16bfc7956b03301b6d23a87c9709a3738878fd',
|
||||
sk: 'e98af98f7bfa062be0357372739d5fd47f243e84611a40e7f941eb492788c477',
|
||||
relays: ['wss://relay.nsec.app'],
|
||||
token: '',
|
||||
authMethod: 'connect',
|
||||
nip05: 'testlongnameforbanner@nsec.app',
|
||||
name: 'testlongnameforbanner',
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
const addRecent = document.getElementById('add-recent');
|
||||
|
||||
addRecent.addEventListener('click', () => {
|
||||
localStorage.setItem(
|
||||
'__nostrlogin_recent',
|
||||
JSON.stringify([
|
||||
{
|
||||
pubkey: 'bcce12ab52dfbeefdf0a964efdb78ec05d2daf5d8865bcf427facf96071cf1d1',
|
||||
authMethod: 'readOnly',
|
||||
picture:
|
||||
'https://img.freepik.com/free-photo/the-adorable-illustration-of-kittens-playing-in-the-forest-generative-ai_260559-483.jpg?size=338&ext=jpg&ga=GA1.1.1413502914.1713830400&semt=ais',
|
||||
name: 'misterband',
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<button id="login">login</button>
|
||||
<button id="startloading">start loading</button>
|
||||
<button id="stoploading">stop loading</button>
|
||||
<button id="notify">notify</button>
|
||||
|
||||
<button id="add-accounts">add __nostrlogin_accounts</button>
|
||||
<button id="add-recent">add __nostrlogin_recent</button>
|
||||
|
||||
<div style="position: fixed; z-index: 9999">
|
||||
<button id="startloadingmodal">start loading modal</button>
|
||||
<button id="setauthurl">nostr login auth url</button>
|
||||
</div>
|
||||
<!-- <nl-banner></nl-banner>-->
|
||||
<!-- <nl-button title-btn="Sign up" start-screen="signup"></nl-button>-->
|
||||
<!-- <nl-button nl-theme="ocean"></nl-button>-->
|
||||
<!-- <button-base nl-theme="ocean">-->
|
||||
<!-- <svg slot="icon-start" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">-->
|
||||
<!-- <path-->
|
||||
<!-- stroke-linecap="round"-->
|
||||
<!-- stroke-linejoin="round"-->
|
||||
<!-- d="M3 8.25V18a2.25 2.25 0 0 0 2.25 2.25h13.5A2.25 2.25 0 0 0 21 18V8.25m-18 0V6a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 6v2.25m-18 0h18M5.25 6h.008v.008H5.25V6ZM7.5 6h.008v.008H7.5V6Zm2.25 0h.008v.008H9.75V6Z"-->
|
||||
<!-- />-->
|
||||
<!-- </svg>-->
|
||||
<!-- </button-base>-->
|
||||
</body>
|
||||
</html>
|
||||
4
packages/components/src/index.ts
Normal file
4
packages/components/src/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { NlAuth } from './components/nl-auth/nl-auth';
|
||||
export { NlButton } from './components/nl-button/nl-button';
|
||||
export { NlBanner } from './components/nl-banner/nl-banner';
|
||||
export { ButtonBase } from './components/button-base/button-base';
|
||||
69
packages/components/src/store/index.ts
Normal file
69
packages/components/src/store/index.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { createStore } from '@stencil/store';
|
||||
import { CURRENT_MODULE, ConnectionString } from '@/types';
|
||||
|
||||
const { state, onChange, reset } = createStore({
|
||||
screen: CURRENT_MODULE.WELCOME,
|
||||
prevScreen: CURRENT_MODULE.WELCOME,
|
||||
path: [CURRENT_MODULE.WELCOME],
|
||||
error: '',
|
||||
isLoading: false,
|
||||
isLoadingExtension: false,
|
||||
isOTP: false,
|
||||
authUrl: '',
|
||||
iframeUrl: '',
|
||||
njumpIframe: '',
|
||||
|
||||
// State NlSignin
|
||||
nlSignin: {
|
||||
loginName: '',
|
||||
},
|
||||
|
||||
// State NlSignup
|
||||
nlSignup: {
|
||||
signupName: '',
|
||||
domain: '',
|
||||
servers: [
|
||||
{ name: '@nsec.app', value: 'nsec.app' },
|
||||
{ name: '@highlighter.com', value: 'highlighter.com' },
|
||||
],
|
||||
},
|
||||
|
||||
// State NlSigninBunkerUrl
|
||||
nlSigninBunkerUrl: {
|
||||
loginName: '',
|
||||
},
|
||||
|
||||
// State NlSigninReadOnly
|
||||
nlSigninReadOnly: {
|
||||
loginName: '',
|
||||
},
|
||||
|
||||
// State NlSigninOTP
|
||||
nlSigninOTP: {
|
||||
loginName: '',
|
||||
code: '',
|
||||
},
|
||||
|
||||
nlImport: null as (ConnectionString | null),
|
||||
});
|
||||
|
||||
// control show screens & manage history (like as router)
|
||||
// ??? edit to better solution
|
||||
onChange('screen', () => {
|
||||
state.error = '';
|
||||
state.nlSignin.loginName = '';
|
||||
state.nlSignup.signupName = '';
|
||||
state.nlSignup.domain = '';
|
||||
|
||||
// if (value === CURRENT_MODULE.LOGIN || value === CURRENT_MODULE.SIGNUP || value === CURRENT_MODULE.LOGIN_BUNKER_URL || value === CURRENT_MODULE.LOGIN_READ_ONLY) {
|
||||
// state.prevScreen = CURRENT_MODULE.WELCOME;
|
||||
// }
|
||||
});
|
||||
|
||||
// on('set', (_, value, oldValue) => {
|
||||
// if (value === CURRENT_MODULE.INFO) {
|
||||
// state.prevScreen = oldValue;
|
||||
// }
|
||||
// });
|
||||
|
||||
export { state, reset };
|
||||
753
packages/components/src/styles/tailwind.css
Normal file
753
packages/components/src/styles/tailwind.css
Normal file
@@ -0,0 +1,753 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/*Theme default*/
|
||||
.theme-default .nl-bg {
|
||||
@apply bg-white shadow-sm;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-bg {
|
||||
@apply bg-gray-800 shadow-slate-700/[.7];
|
||||
}
|
||||
|
||||
.theme-default .nl-logo,
|
||||
.theme-default .nl-title,
|
||||
.theme-default .nl-description {
|
||||
@apply text-gray-800;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-logo,
|
||||
.theme-default .dark .nl-title,
|
||||
.theme-default .dark .nl-description {
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
.theme-default .nl-description a {
|
||||
@apply underline text-blue-800;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-description a {
|
||||
@apply underline text-blue-200;
|
||||
}
|
||||
|
||||
.theme-default .nl-action-button {
|
||||
@apply text-gray-800 hover:bg-gray-100 outline-none;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-action-button {
|
||||
@apply text-white hover:bg-gray-700 outline-none;
|
||||
}
|
||||
|
||||
.theme-default .nl-title {
|
||||
@apply text-gray-800;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-title {
|
||||
@apply text-gray-200;
|
||||
}
|
||||
|
||||
.theme-default .nl-button {
|
||||
@apply border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-button {
|
||||
@apply bg-slate-900 border-gray-700 text-gray-300 hover:bg-gray-800;
|
||||
}
|
||||
|
||||
.theme-default .nl-divider {
|
||||
@apply text-gray-400 before:border-t before:border-gray-200 after:border-gray-200;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-divider {
|
||||
@apply text-gray-500 before:border-gray-600 after:border-gray-600;
|
||||
}
|
||||
|
||||
.theme-default .nl-footer {
|
||||
@apply text-gray-800;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-footer {
|
||||
@apply text-gray-200;
|
||||
}
|
||||
|
||||
.theme-default .nl-error {
|
||||
@apply text-red-800;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-error {
|
||||
@apply text-red-200;
|
||||
}
|
||||
|
||||
.theme-default .nl-input {
|
||||
@apply bg-gray-100 focus:border-purple-500 focus:ring-purple-500;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-input {
|
||||
@apply bg-gray-700 text-gray-400 focus:ring-gray-600;
|
||||
}
|
||||
|
||||
.theme-default .nl-select {
|
||||
@apply bg-gray-100 focus:border-purple-500 focus:ring-purple-500;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-select {
|
||||
@apply bg-gray-700 text-gray-400 focus:ring-gray-600;
|
||||
}
|
||||
|
||||
.theme-default .nl-select-list {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-select-list {
|
||||
@apply bg-gray-700;
|
||||
}
|
||||
|
||||
.theme-default .nl-select-option {
|
||||
@apply text-gray-800 hover:bg-gray-200;
|
||||
}
|
||||
|
||||
.theme-default .nl-select-option.active-option {
|
||||
@apply text-blue-900 bg-gray-300;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-select-option {
|
||||
@apply text-gray-400 hover:bg-gray-800 hover:text-gray-300;
|
||||
}
|
||||
|
||||
.theme-default .nl-text-error {
|
||||
@apply text-red-400;
|
||||
}
|
||||
|
||||
.theme-default .nl-text-success {
|
||||
@apply text-teal-400;
|
||||
}
|
||||
|
||||
.theme-default .nl-banner {
|
||||
@apply border border-gray-200 bg-white text-gray-800 shadow-sm;
|
||||
}
|
||||
|
||||
.theme-default .dark .nl-banner {
|
||||
@apply bg-slate-900 border-gray-700 text-gray-300;
|
||||
}
|
||||
|
||||
/*Theme ocean*/
|
||||
.theme-ocean .nl-bg {
|
||||
@apply bg-blue-200 shadow-sm;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-bg {
|
||||
@apply bg-sky-950 shadow-slate-700/[.7];
|
||||
}
|
||||
|
||||
.theme-ocean .nl-logo,
|
||||
.theme-ocean .nl-title,
|
||||
.theme-ocean .nl-description {
|
||||
@apply text-sky-950;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-logo,
|
||||
.theme-ocean .dark .nl-title,
|
||||
.theme-ocean .dark .nl-description {
|
||||
@apply text-sky-200;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-action-button {
|
||||
@apply text-sky-950 hover:bg-sky-100 outline-none;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-action-button {
|
||||
@apply text-sky-200 hover:bg-sky-900 outline-none;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-button {
|
||||
@apply border border-sky-200 bg-sky-100 text-sky-950 shadow-sm hover:bg-sky-50;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-button {
|
||||
@apply bg-sky-800 border-sky-950 text-sky-200 hover:bg-sky-900;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-divider {
|
||||
@apply text-sky-950 after:border-sky-950 before:border-sky-950;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-divider {
|
||||
@apply text-sky-200 before:border-sky-200 after:border-sky-200;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-footer {
|
||||
@apply text-sky-950;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-footer {
|
||||
@apply text-sky-200;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-error {
|
||||
@apply text-red-800;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-error {
|
||||
@apply text-red-200;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-input {
|
||||
@apply bg-sky-100 focus:border-sky-500 focus:ring-sky-500;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-input {
|
||||
@apply bg-sky-900 text-sky-400 focus:ring-sky-600;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-select {
|
||||
@apply bg-sky-100 focus:border-sky-500 focus:ring-sky-500;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-select {
|
||||
@apply bg-sky-900 text-sky-400 focus:ring-sky-600;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-select-list {
|
||||
@apply bg-sky-100;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-select-list {
|
||||
@apply bg-sky-700;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-select-option {
|
||||
@apply text-sky-800 hover:bg-sky-200;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-select-option {
|
||||
@apply text-sky-400 hover:bg-sky-800 hover:text-sky-300;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-text-error {
|
||||
@apply text-red-600;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-text-error {
|
||||
@apply text-red-400;
|
||||
}
|
||||
|
||||
.theme-ocean .nl-text-success {
|
||||
@apply text-teal-600;
|
||||
}
|
||||
|
||||
.theme-ocean .dark .nl-text-success {
|
||||
@apply text-teal-400;
|
||||
}
|
||||
|
||||
/*Theme lemonade*/
|
||||
.theme-lemonade .nl-bg {
|
||||
@apply bg-green-200 shadow-sm;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-bg {
|
||||
@apply bg-green-950 shadow-slate-700/[.7];
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-logo,
|
||||
.theme-lemonade .nl-title,
|
||||
.theme-lemonade .nl-description {
|
||||
@apply text-green-950;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-logo,
|
||||
.theme-lemonade .dark .nl-title,
|
||||
.theme-lemonade .dark .nl-description {
|
||||
@apply text-green-200;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-action-button {
|
||||
@apply text-green-950 hover:bg-green-100 outline-none;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-action-button {
|
||||
@apply text-green-200 hover:bg-green-900 outline-none;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-button {
|
||||
@apply border border-green-200 bg-green-100 text-green-950 shadow-sm hover:bg-green-50;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-button {
|
||||
@apply bg-green-800 border-green-950 text-green-200 hover:bg-green-900;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-divider {
|
||||
@apply text-green-950 after:border-green-950 before:border-green-950;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-divider {
|
||||
@apply text-green-200 before:border-green-200 after:border-green-200;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-footer {
|
||||
@apply text-green-950;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-footer {
|
||||
@apply text-green-200;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-error {
|
||||
@apply text-red-800;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-error {
|
||||
@apply text-red-200;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-input {
|
||||
@apply bg-green-100 focus:border-green-500 focus:ring-green-500;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-input {
|
||||
@apply bg-green-900 text-green-400 focus:ring-green-600;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-select {
|
||||
@apply bg-green-100 focus:border-green-500 focus:ring-green-500;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-select {
|
||||
@apply bg-green-900 text-green-400 focus:ring-green-600;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-select-list {
|
||||
@apply bg-green-100;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-select-list {
|
||||
@apply bg-green-700;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-select-option {
|
||||
@apply text-green-800 hover:bg-green-200;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-select-option {
|
||||
@apply text-green-400 hover:bg-green-800 hover:text-green-300;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-text-error {
|
||||
@apply text-red-600;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-text-error {
|
||||
@apply text-red-400;
|
||||
}
|
||||
|
||||
.theme-lemonade .nl-text-success {
|
||||
@apply text-teal-600;
|
||||
}
|
||||
|
||||
.theme-lemonade .dark .nl-text-success {
|
||||
@apply text-teal-400;
|
||||
}
|
||||
|
||||
/*Theme purple*/
|
||||
.theme-purple .nl-bg {
|
||||
@apply bg-purple-200 shadow-sm;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-bg {
|
||||
@apply bg-purple-950 shadow-slate-700/[.7];
|
||||
}
|
||||
|
||||
.theme-purple .nl-logo,
|
||||
.theme-purple .nl-title,
|
||||
.theme-purple .nl-description {
|
||||
@apply text-purple-950;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-logo,
|
||||
.theme-purple .dark .nl-title,
|
||||
.theme-purple .dark .nl-description {
|
||||
@apply text-purple-200;
|
||||
}
|
||||
|
||||
.theme-purple .nl-action-button {
|
||||
@apply text-purple-950 hover:bg-purple-100 outline-none;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-action-button {
|
||||
@apply text-purple-200 hover:bg-purple-900 outline-none;
|
||||
}
|
||||
|
||||
.theme-purple .nl-button {
|
||||
@apply border border-purple-200 bg-purple-100 text-purple-950 shadow-sm hover:bg-purple-50;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-button {
|
||||
@apply bg-purple-800 border-purple-950 text-purple-200 hover:bg-purple-900;
|
||||
}
|
||||
|
||||
.theme-purple .nl-divider {
|
||||
@apply text-purple-950 after:border-purple-950 before:border-purple-950;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-divider {
|
||||
@apply text-purple-200 before:border-purple-200 after:border-purple-200;
|
||||
}
|
||||
|
||||
.theme-purple .nl-footer {
|
||||
@apply text-purple-950;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-footer {
|
||||
@apply text-purple-200;
|
||||
}
|
||||
|
||||
.theme-purple .nl-error {
|
||||
@apply text-red-800;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-error {
|
||||
@apply text-red-200;
|
||||
}
|
||||
|
||||
.theme-purple .nl-input {
|
||||
@apply bg-purple-100 focus:border-purple-500 focus:ring-purple-500;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-input {
|
||||
@apply bg-purple-900 text-purple-400 focus:ring-purple-600;
|
||||
}
|
||||
|
||||
.theme-purple .nl-select {
|
||||
@apply bg-purple-100 focus:border-purple-500 focus:ring-purple-500;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-select {
|
||||
@apply bg-purple-900 text-purple-400 focus:ring-purple-600;
|
||||
}
|
||||
|
||||
.theme-purple .nl-select-list {
|
||||
@apply bg-purple-100;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-select-list {
|
||||
@apply bg-purple-700;
|
||||
}
|
||||
|
||||
.theme-purple .nl-select-option {
|
||||
@apply text-purple-800 hover:bg-purple-200;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-select-option {
|
||||
@apply text-purple-400 hover:bg-purple-800 hover:text-purple-300;
|
||||
}
|
||||
|
||||
.theme-purple .nl-text-error {
|
||||
@apply text-red-600;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-text-error {
|
||||
@apply text-red-400;
|
||||
}
|
||||
|
||||
.theme-purple .nl-text-success {
|
||||
@apply text-teal-600;
|
||||
}
|
||||
|
||||
.theme-purple .dark .nl-text-success {
|
||||
@apply text-teal-400;
|
||||
}
|
||||
|
||||
/*Theme crab*/
|
||||
.theme-crab .nl-button {
|
||||
@apply border border-red-200 bg-red-100 text-red-950 shadow-sm hover:bg-red-50;
|
||||
}
|
||||
|
||||
.theme-crab .dark .nl-button {
|
||||
@apply bg-red-800 border-red-950 text-red-200 hover:bg-red-900;
|
||||
}
|
||||
|
||||
/*Theme laan*/
|
||||
.theme-laan {
|
||||
@apply font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-bg {
|
||||
@apply bg-white shadow-sm;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-bg {
|
||||
@apply bg-black shadow-gray-700;
|
||||
}
|
||||
|
||||
.theme-laan .nl-logo,
|
||||
.theme-laan .nl-title,
|
||||
.theme-laan .nl-description {
|
||||
@apply text-black font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-logo,
|
||||
.theme-laan .dark .nl-title,
|
||||
.theme-laan .dark .nl-description {
|
||||
@apply text-white font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-description a {
|
||||
@apply underline;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-description a {
|
||||
@apply underline;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-action-button {
|
||||
@apply text-black hover:bg-gray-100 outline-none font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-action-button {
|
||||
@apply text-white hover:bg-gray-900 outline-none font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-title {
|
||||
@apply text-black font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-title {
|
||||
@apply text-white font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-button {
|
||||
@apply border-2 border-black bg-transparent text-black shadow-none font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-button:hover {
|
||||
@apply bg-gray-100;
|
||||
border-color: rgb(255, 0, 0);
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-button {
|
||||
@apply border-2 bg-transparent text-white shadow-none font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-button:hover {
|
||||
@apply bg-gray-900;
|
||||
border-color: rgb(255, 0, 0);
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-divider {
|
||||
@apply text-gray-500 before:border-t before:border-gray-400 after:border-gray-400 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-divider {
|
||||
@apply text-gray-400 before:border-gray-600 after:border-gray-600 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-footer {
|
||||
@apply text-black font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-footer {
|
||||
@apply text-white font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-error {
|
||||
@apply font-mono;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-error {
|
||||
@apply font-mono;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-input {
|
||||
@apply bg-gray-100 border-gray-400 text-black font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-input:focus {
|
||||
border-color: rgb(255, 0, 0);
|
||||
box-shadow: 0 0 0 1px rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-input {
|
||||
@apply bg-gray-900 border-gray-600 text-white font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-input:focus {
|
||||
border-color: rgb(255, 0, 0);
|
||||
box-shadow: 0 0 0 1px rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-select {
|
||||
@apply bg-gray-100 border-gray-400 text-black font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-select:focus {
|
||||
border-color: rgb(255, 0, 0);
|
||||
box-shadow: 0 0 0 1px rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-select {
|
||||
@apply bg-gray-900 border-gray-600 text-white font-mono;
|
||||
border-color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-select:focus {
|
||||
border-color: rgb(255, 0, 0);
|
||||
box-shadow: 0 0 0 1px rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-select-list {
|
||||
@apply bg-white border border-gray-400 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-select-list {
|
||||
@apply bg-black border-gray-600 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-select-option {
|
||||
@apply text-black hover:bg-gray-100 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .nl-select-option.active-option {
|
||||
@apply bg-gray-200;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-select-option {
|
||||
@apply text-white hover:bg-gray-900 font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-select-option.active-option {
|
||||
@apply bg-gray-800;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-text-error {
|
||||
@apply font-mono;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-text-success {
|
||||
@apply font-mono;
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
|
||||
.theme-laan .nl-banner {
|
||||
@apply border border-gray-400 bg-white text-black shadow-sm font-mono;
|
||||
}
|
||||
|
||||
.theme-laan .dark .nl-banner {
|
||||
@apply bg-black border-gray-600 text-white font-mono;
|
||||
}
|
||||
|
||||
/* Override ALL non-compliant colors for Laan theme */
|
||||
/* Blue colors -> Red */
|
||||
.theme-laan .text-blue-400,
|
||||
.theme-laan .text-blue-500,
|
||||
.theme-laan .text-blue-600 {
|
||||
color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan .hover\:text-blue-600:hover {
|
||||
color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan .border-blue-200,
|
||||
.theme-laan .border-blue-400 {
|
||||
border-color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan .group-hover\:border-blue-400:hover {
|
||||
border-color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
/* Teal colors -> Red */
|
||||
.theme-laan .border-teal-300,
|
||||
.theme-laan .text-teal-600,
|
||||
.theme-laan .bg-teal-100 {
|
||||
border-color: rgb(255, 0, 0) !important;
|
||||
color: rgb(255, 0, 0) !important;
|
||||
background-color: rgba(255, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Yellow colors -> Red */
|
||||
.theme-laan .border-yellow-300,
|
||||
.theme-laan .border-yellow-600,
|
||||
.theme-laan .text-yellow-500,
|
||||
.theme-laan .text-yellow-600,
|
||||
.theme-laan .bg-yellow-100 {
|
||||
border-color: rgb(255, 0, 0) !important;
|
||||
color: rgb(255, 0, 0) !important;
|
||||
background-color: rgba(255, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Orange colors -> Red */
|
||||
.theme-laan .border-orange-300,
|
||||
.theme-laan .text-orange-600,
|
||||
.theme-laan .bg-orange-100 {
|
||||
border-color: rgb(255, 0, 0) !important;
|
||||
color: rgb(255, 0, 0) !important;
|
||||
background-color: rgba(255, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Green colors -> Red */
|
||||
.theme-laan .bg-green-500,
|
||||
.theme-laan .text-green-800,
|
||||
.theme-laan .text-green-200 {
|
||||
background-color: rgb(255, 0, 0) !important;
|
||||
color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
/* Slate colors -> Grey/Black/White */
|
||||
.theme-laan .text-slate-900 {
|
||||
color: rgb(0, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan .dark .text-slate-900 {
|
||||
color: rgb(255, 255, 255) !important;
|
||||
}
|
||||
|
||||
/* Cursor pointer with red hover */
|
||||
.theme-laan .cursor-pointer {
|
||||
color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan .cursor-pointer:hover {
|
||||
color: rgb(200, 0, 0) !important;
|
||||
}
|
||||
|
||||
/* All links should be red */
|
||||
.theme-laan a,
|
||||
.theme-laan [class*="text-blue"] {
|
||||
color: rgb(255, 0, 0) !important;
|
||||
}
|
||||
|
||||
.theme-laan a:hover,
|
||||
.theme-laan [class*="text-blue"]:hover {
|
||||
color: rgb(200, 0, 0) !important;
|
||||
}
|
||||
|
||||
.show-slow {
|
||||
opacity: 0;
|
||||
display: none;
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
||||
.isOpen .show-slow {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
transition: 0.2s;
|
||||
transition-delay: 0.2s;
|
||||
}
|
||||
7
packages/components/src/types/button.ts
Normal file
7
packages/components/src/types/button.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { NlTheme } from './index';
|
||||
|
||||
export interface IButton {
|
||||
theme: NlTheme;
|
||||
titleBtn: string;
|
||||
disabled: boolean;
|
||||
}
|
||||
90
packages/components/src/types/index.ts
Normal file
90
packages/components/src/types/index.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
export enum CURRENT_MODULE {
|
||||
WELCOME = 'welcome',
|
||||
WELCOME_LOGIN = 'welcome-login',
|
||||
WELCOME_SIGNUP = 'welcome-signup',
|
||||
INFO = 'info',
|
||||
LOGIN_BUNKER_URL = 'login-bunker-url',
|
||||
LOGIN_READ_ONLY = 'login-read-only',
|
||||
CONFIRM_LOGOUT = 'confirm-logout',
|
||||
IMPORT_FLOW = 'import',
|
||||
IMPORT_OTP = 'import-otp',
|
||||
LOGIN = 'login',
|
||||
SIGNUP = 'signup',
|
||||
LOCAL_SIGNUP = 'local-signup',
|
||||
EXTENSION = 'extension',
|
||||
LOADING = 'loading',
|
||||
PREVIOUSLY_LOGGED = 'switch-account',
|
||||
LOGIN_OTP = 'otp',
|
||||
CONNECT = 'connect',
|
||||
CONNECTION_STRING = 'connection-string',
|
||||
IFRAME = 'iframe',
|
||||
}
|
||||
|
||||
export enum METHOD_MODULE {
|
||||
LOGIN = 'login',
|
||||
SIGNUP = 'signup',
|
||||
LOGOUT = 'logout',
|
||||
CONFIRM = 'confirm',
|
||||
}
|
||||
|
||||
export type AuthMethod = 'connect' | 'readOnly' | 'extension' | 'local' | 'otp';
|
||||
|
||||
export interface Info {
|
||||
// must be present
|
||||
pubkey: string;
|
||||
|
||||
// new nip46
|
||||
signerPubkey?: string;
|
||||
|
||||
// connect or local methods
|
||||
sk?: string;
|
||||
|
||||
// connect method only
|
||||
relays?: string[];
|
||||
|
||||
// connect/readOnly
|
||||
nip05?: string;
|
||||
domain?: string;
|
||||
|
||||
// connect w/ bunkerUrl
|
||||
bunkerUrl?: string;
|
||||
|
||||
// from kind:0 profile
|
||||
picture?: string;
|
||||
name?: string;
|
||||
|
||||
// nip46 bunker URL secret
|
||||
token?: string;
|
||||
|
||||
// session type
|
||||
authMethod: AuthMethod;
|
||||
|
||||
// what otp auth reply returned,
|
||||
// may be empty if cookies are used, or may contain session
|
||||
// token to be used for future api calls
|
||||
otpData?: string;
|
||||
|
||||
// for iframe comms
|
||||
iframeUrl?: string;
|
||||
}
|
||||
|
||||
export type RecentType = Pick<Info, 'nip05' | 'picture' | 'pubkey' | 'name' | 'bunkerUrl' | 'authMethod' | 'domain' | 'signerPubkey'>;
|
||||
|
||||
export type NlTheme = 'default' | 'ocean' | 'lemonade' | 'purple' | 'crab' | 'laan';
|
||||
|
||||
export interface ConnectionString {
|
||||
name: string;
|
||||
img: string;
|
||||
link: string;
|
||||
relay: string;
|
||||
domain?: string;
|
||||
canImport?: boolean;
|
||||
iframeUrl?: string;
|
||||
}
|
||||
|
||||
export type BannerNotifyMode = '' | 'timeout' | 'authUrl' | 'iframeAuthUrl' | 'rebind';
|
||||
|
||||
export interface BannerNotify {
|
||||
mode: BannerNotifyMode;
|
||||
url?: string;
|
||||
}
|
||||
40
packages/components/stencil.config.ts
Normal file
40
packages/components/stencil.config.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Config } from '@stencil/core';
|
||||
import { sass } from '@stencil/sass';
|
||||
import tailwind, { tailwindHMR, setPluginConfigurationDefaults } from 'stencil-tailwind-plugin';
|
||||
import tailwindcss from 'tailwindcss';
|
||||
import tailwindConf from './tailwind.config';
|
||||
import autoprefixer from 'autoprefixer';
|
||||
|
||||
setPluginConfigurationDefaults({
|
||||
tailwindConf,
|
||||
tailwindCssPath: './src/styles/tailwind.css',
|
||||
postcss: {
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
autoprefixer()
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
export const config: Config = {
|
||||
namespace: 'components',
|
||||
globalStyle: 'src/styles/tailwind.css',
|
||||
outputTargets: [
|
||||
{
|
||||
type: 'dist-custom-elements',
|
||||
customElementsExportBehavior: 'auto-define-custom-elements',
|
||||
},
|
||||
{
|
||||
type: "www",
|
||||
buildDir: 'build'
|
||||
}
|
||||
],
|
||||
testing: {
|
||||
browserHeadless: "new",
|
||||
},
|
||||
plugins: [
|
||||
sass(),
|
||||
tailwind(),
|
||||
tailwindHMR()
|
||||
],
|
||||
};
|
||||
68
packages/components/tailwind.config.js
Normal file
68
packages/components/tailwind.config.js
Normal file
@@ -0,0 +1,68 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
|
||||
module.exports = {
|
||||
content: ['./src/components/**/*.{ts,tsx,html}'],
|
||||
darkMode: 'class',
|
||||
plugins: [
|
||||
require('@tailwindcss/forms')
|
||||
],
|
||||
theme: {
|
||||
fontSize: {
|
||||
sm: ['14px', '20px'],
|
||||
xs: ['12px', '16px'],
|
||||
base: ['16px', '24px'],
|
||||
lg: ['18px', '28px'],
|
||||
xl: ['20px', '28px'],
|
||||
"2xl": ['24px', '32px'],
|
||||
"3xl": ['30px', '36px'],
|
||||
"4xl": ['36px', '40px'],
|
||||
"5xl": ['48px', '1'],
|
||||
"6xl": ['60px', '1'],
|
||||
"7xl": ['72px', '1'],
|
||||
"8xl": ['96px', '1'],
|
||||
"9xl": ['128px', '1'],
|
||||
},
|
||||
extend: {
|
||||
maxWidth: {
|
||||
"lg": "512px",
|
||||
},
|
||||
spacing: {
|
||||
"0": "0px",
|
||||
"1": "4px",
|
||||
"2": "8px",
|
||||
"3": "12px",
|
||||
"4": "16px",
|
||||
"5": "20px",
|
||||
"6": "24px",
|
||||
"7": "28px",
|
||||
"8": "32px",
|
||||
"9": "36px",
|
||||
"10": "40px",
|
||||
"11": "44px",
|
||||
"12": "48px",
|
||||
"14": "56px",
|
||||
"16": "64px",
|
||||
"20": "80px",
|
||||
"24": "96px",
|
||||
"28": "112px",
|
||||
"32": "128px",
|
||||
"36": "144px",
|
||||
"40": "160px",
|
||||
"44": "176px",
|
||||
"48": "192px",
|
||||
"52": "208px",
|
||||
"56": "224px",
|
||||
"60": "240px",
|
||||
"64": "256px",
|
||||
"72": "288px",
|
||||
"80": "320px",
|
||||
"96": "384px",
|
||||
"px": "1px",
|
||||
"0.5": "2px",
|
||||
"1.5": "6px",
|
||||
"2.5": "10px",
|
||||
"3.5": "14px"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
packages/components/tsconfig.json
Normal file
29
packages/components/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowUnreachableCode": false,
|
||||
"declaration": false,
|
||||
"experimentalDecorators": true,
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2017"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"module": "esnext",
|
||||
"target": "es2017",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "h",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user