Skip to content

Commit

Permalink
Merge pull request #65 from getAlby/feat/simplify-styles
Browse files Browse the repository at this point in the history
feat: simplify styles, dark mode support
  • Loading branch information
rolznz authored Oct 2, 2023
2 parents 1022f23 + 41872ca commit efb3fea
Show file tree
Hide file tree
Showing 29 changed files with 365 additions and 399 deletions.
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ import {Button, Modal, launchModal} from '@getalby/bitcoin-connect-react';
Bitcoin Connect exposes the following web components for allowing users to connect their desired Lightning wallet:

- `<bc-button/>` - launches the Bitcoin Connect Modal on click
- Optional Arguments:
- `icon-only` - display the button as an icon without "Connect wallet"
- `disabled` - mark the button as disabled
- `<bc-modal/>` - render the modal on its own.
- Optional Arguments:
- `open` - make the modal appear
Expand All @@ -80,20 +77,40 @@ Bitcoin Connect exposes the following events:

### Styling

The following CSS variables can be configured:
These variables must be set at the root or on a container element wrapping any bitcoin connect components.

```css
html {
--bc-color-brand: #196ce7;
}
```

Optional CSS variables for further customization:

```css
html {
--bc-color-primary: #21ecc7;
--bc-color-secondary: #21ecc7;
--bc-color-bg-primary: black;
--bc-color-bg-secondary: black;
--bc-color-text-primary: black;
--bc-color-text-secondary: #f4f4f4;
--bc-color-text-tertiary: white;
--bc-color-brand-dark: #3994ff; /* use a different brand color in dark mode */
--bc-brand-mix: 100%; /* how much to mix the brand color with default foreground color */
}
```

> 💡 using near-white or black brand colors? either set a lower `bc-brand-mix` or make sure to use an off-white for `bc-color-brand` and off-black for `bc-color-brand-dark` to avoid conflicts with the modal background color.
### Dark mode

#### Automatic (Recommended)

Bitcoin Connect uses `prefers-color-scheme` to automatically detect light/dark mode.

#### Manual

In case your site uses a manual theme switcher, you can force a theme by following these steps:

> see an example [here](./dev/vite/index.html)
1. set `globalThis.bcDarkMode = "class"` **before** any bitcoin connect components are rendered
2. `"dark"` must be added as a classname to the document to enable dark mode (e.g. `<html class="dark">` or `document.documentElement.classList.add('dark')`) otherwise light mode will be forced.

## Demos

### Pure HTML Demo
Expand Down
131 changes: 83 additions & 48 deletions dev/vite/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,58 @@
window.addEventListener('bc:modalclosed', () =>
console.info('Received modalclosed event from html')
);
const bcTheme = window.localStorage.getItem('bcTheme');
if (bcTheme) {
window.bcDarkMode = 'class';
document.documentElement.classList.add(bcTheme);
} else {
document.documentElement.classList.add('system');
}
</script>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
@media (prefers-color-scheme: dark) {
background-color: black;
color: white;
}
}
.dark body {
background-color: black;
color: white;
}
.light body {
background-color: white;
color: black;
}
.theme-default-dark {
--bc-color-bg-primary: #222;
--bc-color-bg-secondary: #000;
--bc-color-text-secondary: #808080;
.dark #button-theme-dark {
background-color: skyblue;
}
.theme-geyser-light {
--bc-color-primary: #10caa8;
--bc-color-secondary: #10caa8;
--bc-color-tertiary: #21ecc7;
--bc-color-bg-primary: white;
--bc-color-bg-secondary: black;
--bc-color-text-primary: black;
--bc-color-text-secondary: #1a202c;
--bc-color-text-tertiary: white;
.light #button-theme-light {
background-color: skyblue;
}
.theme-geyser-dark {
--bc-color-primary: #21ecc7;
--bc-color-secondary: #21ecc7;
--bc-color-bg-primary: black;
--bc-color-bg-secondary: black;
--bc-color-text-primary: black;
--bc-color-text-secondary: #f4f4f4;
--bc-color-text-tertiary: white;
.system #button-theme-system {
background-color: skyblue;
}

.theme-geyser {
--bc-color-brand: #21ecc7;
--bc-brand-mix: 75%;
}
.theme-orange-dark {
--bc-color-primary: #ffc837;
--bc-color-secondary: #ff8008;
--bc-color-bg-primary: black;
--bc-color-bg-secondary: black;
--bc-color-text-primary: black;
--bc-color-text-secondary: #ca9;
.theme-orange {
--bc-color-brand: #ff8008;
}
.theme-stacker-news {
--bc-color-brand: #fada5e;
--bc-brand-mix: 75%;
}
.theme-white {
--bc-color-brand: #ffffff;
--bc-brand-mix: 50%;
}
.theme-black {
--bc-color-brand: #000000;
--bc-brand-mix: 50%;
}
</style>
</head>
Expand All @@ -69,32 +85,51 @@ <h1>Programmatic Access</h1>
</button>
<bc-modal></bc-modal>

<h1>Light / Dark Mode</h1>

<button
id="button-theme-system"
onclick="window.localStorage.removeItem('bcTheme');window.location.reload();"
>
System
</button>
<button
id="button-theme-dark"
onclick="window.localStorage.setItem('bcTheme', 'dark');window.location.reload();"
>
Force Dark
</button>
<button
id="button-theme-light"
onclick="window.localStorage.setItem('bcTheme', 'light');window.location.reload();"
>
Force Light
</button>

<h1>Components</h1>

<h2>Button</h2>
<h3>Light</h3>
<bc-button></bc-button><br /><br />
<div class="theme-geyser-light">
<bc-button></bc-button>
<br /><br />
<div class="theme-geyser">
<bc-button></bc-button>
</div>
<br /><br />
<h3>Dark</h3>
<div style="background-color: #111; padding: 8px">
<div class="theme-default-dark">
<bc-button></bc-button>
</div>
<br /><br />

<div class="theme-geyser-dark">
<bc-button></bc-button>
</div>
<br /><br />

<div class="theme-orange-dark">
<bc-button></bc-button>
</div>
<div class="theme-orange">
<bc-button></bc-button>
</div>
<br /><br />
<div class="theme-stacker-news">
<bc-button></bc-button>
</div>
<br /><br />
<div class="theme-white">
<bc-button></bc-button>
</div>
<br /><br />
<div class="theme-black">
<bc-button></bc-button>
</div>
<h3>Icon only</h3>
<bc-button icon-only></bc-button>

<h2>Modal header</h2>
<div style="width: 448px">
Expand Down
98 changes: 29 additions & 69 deletions src/components/bc-button.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import {html} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {customElement, state} from 'lit/decorators.js';
import './bc-modal.js';
import {BitcoinConnectElement} from './BitcoinConnectElement.js';
import {bcIcon} from './icons/bcIcon.js';
import {withTwind} from './twind/withTwind.js';
import {loadingIconPrimary} from './icons/loadingIcon.js';
import {loadingIcon} from './icons/loadingIcon.js';
import {satIcon} from './icons/satIcon.js';
import {bcConnectedIcon} from './icons/bcConnectedIcon.js';
import {color} from './css/colors.js';
import {innerBorder} from './templates/innerBorder.js';
import {hoverClasses} from './css/hoverClasses.js';
import {classes} from './css/classes.js';

/**
* A button that when clicked launches the modal.
Expand All @@ -19,86 +17,48 @@ export class Button extends withTwind()(BitcoinConnectElement) {
@state()
private _modalOpen = false;

@property({
attribute: 'icon-only',
type: Boolean,
})
iconOnly?: boolean;
@property({
attribute: 'connected-icon-only',
type: Boolean,
})
connectedIconOnly?: boolean;

@property({
type: Boolean,
})
disabled = false;

constructor() {
super();
}

// FIXME:
// - inner border icon should be a gradient
// - some hardcoded transparent whites should be transparent(primaryColor)
// TODO:
// - extract common button styles
// - extract common inner border styles
override render() {
const isLoading = this._connecting || (!this._connected && this._modalOpen);
const iconOnly =
this.iconOnly || (this.connectedIconOnly && this._connected);
const brandColorLuminance = this._getBrandColorLuminance();

return html`<div>
<div
class="relative inline-flex ${hoverClasses} cursor-pointer ${this
._connected && !iconOnly
? 'rounded-lg gap-2 justify-center items-center'
: ''}"
style="${this._connected && !iconOnly
? `background: linear-gradient(180deg, #fff6 0%, #fff0 100%), linear-gradient(180deg, ${color(
'bg-secondary'
)}, ${color('bg-secondary')} 100%)`
: ''}"
class="relative inline-flex ${classes.interactive} cursor-pointer
rounded-lg gap-2 justify-center items-center ${classes[
'bg-background'
]}"
@click=${this._onClick}
>
${this._connected ? innerBorder() : null}
<div
class="absolute top-0 left-0 w-full h-full rounded-lg pointer-events-none"
style="background: linear-gradient(180deg, #fff6 0%, #fff0 100%)"
></div>
${innerBorder()}
<button
class="${iconOnly ? 'w-8 h-8' : `h-10 px-4`}
class="h-10 px-4 ${classes['bg-brand']}
${brandColorLuminance > 0.5 ? 'text-black' : 'text-white'}
relative font-medium font-sans shadow rounded-lg flex gap-2 justify-center items-center
${this.disabled ? 'bg-gray-300 opacity-50' : ''}"
style="${!this.disabled &&
`
background: linear-gradient(180deg, ${color(
'tertiary',
color('primary')
)} 0%, ${color('tertiary', color('secondary'))} 100%);
color: ${color('text-primary')};
`}"
?disabled=${this.disabled}
"
>
${innerBorder()}
${isLoading
? loadingIconPrimary
: this._connected
? iconOnly
? bcConnectedIcon
: null
: bcIcon}
${!iconOnly
? html`<span class="font-semibold">
${isLoading
? html`Connecting...`
: this._connected
? html`${this._alias || 'Connected'}`
: html`Connect Wallet`}
</span>`
: null}
${isLoading ? html`${loadingIcon}` : this._connected ? null : bcIcon}
<span class="font-semibold">
${isLoading
? html`Connecting...`
: this._connected
? html`${this._alias || 'Connected'}`
: html`Connect Wallet`}
</span>
</button>
${this._connected && !iconOnly && this._balance !== undefined
${this._connected && this._balance !== undefined
? html`<span
class="font-medium font-sans mr-2 flex justify-center items-center gap-0.5"
style="color: ${color('text-tertiary')}"
class="font-medium font-sans mr-2 flex justify-center items-center gap-0.5 ${classes[
'text-brand-mixed'
]}"
>${satIcon}<span class="font-mono">${this._balance}</span></span
>`
: null}
Expand Down
Loading

0 comments on commit efb3fea

Please sign in to comment.