Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ public async Task BitNumberFieldOnIncrementTest(int countOfClicks)
Assert.AreEqual(countOfClicks, onIncrementEventCounter);
}

[Ignore]
[DataTestMethod,
DataRow(3),
DataRow(5)
Expand Down
74 changes: 47 additions & 27 deletions src/BlazorUI/Bit.BlazorUI/Utils/Theme/bit-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,68 @@ class BitTheme {
private static THEME_ATTRIBUTE = 'bit-theme';
private static THEME_STORAGE_KEY = 'bit-current-theme';

private static currentTheme = 'light';
private static onThemeChange: onThemeChangeType = () => { };
private static _darkTheme: string = 'dark';
private static _lightTheme: string = 'light';

private static _persist = false;
private static _currentTheme = BitTheme._lightTheme;
private static _onThemeChange: onThemeChangeType = () => { };

public static init(options: any) {
if (options.system) {
BitTheme.currentTheme = BitTheme.isSystemDark() ? 'dark' : 'light';
} else if (options.default) {
BitTheme.currentTheme = options.default;
if (options.onChange) {
BitTheme._onThemeChange = options.onChange;
}

if (options.persist) {
BitTheme.currentTheme = localStorage.getItem(BitTheme.THEME_STORAGE_KEY) || BitTheme.currentTheme;
BitTheme._persist = true;
BitTheme._currentTheme = localStorage.getItem(BitTheme.THEME_STORAGE_KEY) || BitTheme._currentTheme;
}

BitTheme.onThemeChange = options.onChange;
if (options.darkTheme) {
BitTheme._darkTheme = options.darkTheme;
}

BitTheme.set(BitTheme.currentTheme);
}
if (options.lightTheme) {
BitTheme._lightTheme = options.lightTheme;
}

public static onChange(fn: onThemeChangeType) {
BitTheme.onThemeChange = fn;
if (options.system) {
BitTheme._currentTheme = BitTheme.isSystemDark() ? BitTheme._darkTheme : BitTheme._lightTheme;
} else if (options.default) {
BitTheme._currentTheme = options.default;
}

BitTheme.set(BitTheme._currentTheme);
}

public static useSystem() {
BitTheme.currentTheme = BitTheme.isSystemDark() ? 'dark' : 'light';
BitTheme.set(BitTheme.currentTheme);
public static onChange(fn: onThemeChangeType) {
BitTheme._onThemeChange = fn;
}

public static get() {
BitTheme.currentTheme = document.documentElement.getAttribute(BitTheme.THEME_ATTRIBUTE) || '';
BitTheme._currentTheme = document.documentElement.getAttribute(BitTheme.THEME_ATTRIBUTE) || '';

return BitTheme.currentTheme;
return BitTheme._currentTheme;
}

public static set(themeName: string) {
BitTheme.currentTheme = themeName;
localStorage.setItem(BitTheme.THEME_STORAGE_KEY, themeName);
const oldTheme = document.documentElement.getAttribute(BitTheme.THEME_ATTRIBUTE) || '';
BitTheme._currentTheme = themeName;
if (BitTheme._persist) {
localStorage.setItem(BitTheme.THEME_STORAGE_KEY, themeName);
}

const oldTheme = document.documentElement.getAttribute(BitTheme.THEME_ATTRIBUTE) || '';
document.documentElement.setAttribute(BitTheme.THEME_ATTRIBUTE, themeName);

BitTheme.onThemeChange?.(themeName, oldTheme);
BitTheme._onThemeChange?.(themeName, oldTheme);
}

public static toggleDarkLight() {
BitTheme.currentTheme = BitTheme.currentTheme === 'light' ? 'dark' : 'light';
BitTheme._currentTheme = BitTheme._currentTheme === BitTheme._lightTheme ? BitTheme._darkTheme : BitTheme._lightTheme;

BitTheme.set(BitTheme.currentTheme);
BitTheme.set(BitTheme._currentTheme);

return BitTheme.currentTheme;
return BitTheme._currentTheme;
}

public static applyBitTheme(theme: any, element?: HTMLElement) {
Expand All @@ -66,6 +78,14 @@ class BitTheme {
}
}

if (document.documentElement.hasAttribute('use-system-theme')) {
BitTheme.useSystem();
}
(function () {
const options = {
persist: document.documentElement.hasAttribute('bit-theme-persist'),
darkTheme: document.documentElement.getAttribute('bit-theme-dark'),
lightTheme: document.documentElement.getAttribute('bit-theme-light'),
default: document.documentElement.getAttribute('bit-theme-default'),
system: document.documentElement.hasAttribute('bit-theme-system')
};

BitTheme.init(options);
}());
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@
}
}

.bit-theme-dark .github-codespaces-icon {
.bit-blazorui-dark-theme .github-codespaces-icon {
background-image: url('images/github-icon-dark.svg');
}

.bit-theme-light .github-codespaces-icon {
.bit-blazorui-light-theme .github-codespaces-icon {
background-image: url('images/github-icon-light.svg');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
<pre class="code"><code class="language-csharp">builder.Services.AddBitBlazorUIServices();</code></pre>
<br />
<BitText Typography="BitTypography.Body1">
And then add a specific attribute named <code>use-system-theme</code> to the <code>html</code> tag:
And then add a specific attribute named <code>bit-theme-system</code> to the <code>html</code> tag:
</BitText>
<br />
<pre><code class="language-cshtml">&lthtml use-system-theme&gt...&lt/html&gt</code></pre>
<pre class="code"><code class="language-cshtml">&lthtml bit-theme-system&gt...&lt/html&gt</code></pre>
<br />
<BitText Typography="BitTypography.Body1">
Now with this setup, the app will follow the system theme (dark or light) automatically.
Expand Down Expand Up @@ -78,11 +78,27 @@
<BitLink Href="https://github.com/bitfoundation/bitplatform/blob/main/src/BlazorUI/Bit.BlazorUI/Styles/Fluent" Target="_blank">
bit BlazorUI GitHub repo
</BitLink>.
<br />
You can simply override these values to customize the UI.
<br />
<br />
<strong>Note:</strong> If you're using <code>scss</code> in your project, you can use <code>bit-css-variables.scss</code>
You can simply override these values to customize the UI like what we did in our main website (<BitLink Href="https://bitplatform.dev">bitplatform.dev</BitLink>) in
<BitLink Href="https://github.com/bitfoundation/bitplatform/blob/develop/src/Websites/Platform/src/Bit.Websites.Platform.Client/Styles/app.scss">this file</BitLink>:
</BitText>
<br />
<pre class="code"><code class="language-css">
// overridden values:

:root[bit-theme="dark"] {
--bit-clr-sec: transparent;
--bit-clr-sec-hover: #061342;
--bit-clr-bg-pri: #060E2D;
--bit-clr-bg-sec: #0a153d;
--bit-clr-bg-pri-hover: #07154a;
--bit-clr-bg-pri-active: #061241;
--bit-clr-bg-sec-hover: #07154a;
--bit-clr-fg-sec: #dddddd;
}
</code></pre>
<br />
<BitText Typography="BitTypography.Body1">
<strong>Note:</strong> If you're using <code>scss</code> in your project, you can use <code>_bit-css-variables.scss</code>
file which introduces scss variables for each bit theme css variable. you can find the latest version of this file
<BitLink Href="https://github.com/bitfoundation/bitplatform/blob/main/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Styles/abstracts/_bit-css-variables.scss" Target="_blank">
here
Expand Down Expand Up @@ -155,10 +171,44 @@ _bitThemeManager.ApplyBitThemeAsync(myTheme);</code></pre>
In bit BlazorUI you can use the system theme as the default theme when the app starts up.
<br />
In order to enable this feature a specific attribute named
<code>use-system-theme</code> should be added to the <code>html</code> tag:
<code>bit-theme-system</code> should be added to the <code>html</code> tag:
</BitText>
<br />
<pre><code class="language-cshtml">&lthtml use-system-theme&gt...&lt/html&gt</code></pre>
<pre class="code"><code class="language-cshtml">&lthtml bit-theme-system&gt...&lt/html&gt</code></pre>
</section>

<section class="page-section">
<BitText Typography="BitTypography.H4" Class="subtitle">Persist Theme</BitText>
<BitText Typography="BitTypography.Body1">
In bit BlazorUI you can use persist the current theme in the local storage.
<br />
In order to enable this feature a specific attribute named
<code>bit-theme-persist</code> should be added to the <code>html</code> tag:
</BitText>
<br />
<pre class="code"><code class="language-cshtml">&lthtml bit-theme-persist&gt...&lt/html&gt</code></pre>
</section>

<section class="page-section">
<BitText Typography="BitTypography.H4" Class="subtitle">Default Theme</BitText>
<BitText Typography="BitTypography.Body1">
In bit BlazorUI you can change the default theme which is <code>light</code> using a specific attribute named
<code>bit-theme-default</code> on the <code>html</code> tag:
</BitText>
<br />
<pre class="code"><code class="language-cshtml">&lthtml bit-theme-default="dark"&gt...&lt/html&gt</code></pre>
</section>

<section class="page-section">
<BitText Typography="BitTypography.H4" Class="subtitle">Customizing theme names</BitText>
<BitText Typography="BitTypography.Body1">
In bit BlazorUI the default name of the available themes are <code>light</code> and <code>dark</code>.
you can change these default names using the following attributes on the <code>html</code> tag:
</BitText>
<br />
<pre class="code"><code class="language-cshtml">
&lthtml bit-theme-dark="custom-dark" bit-theme-light="custom-light" &gt...&lt/html&gt
</code></pre>
</section>

<section class="page-section">
Expand All @@ -169,7 +219,7 @@ _bitThemeManager.ApplyBitThemeAsync(myTheme);</code></pre>
You can use different properties of this class to further customize your UI:
</BitText>
<br />
<pre><code class="language-cshtml">&lthtml&gt
<pre class="code"><code class="language-cshtml">&lthtml&gt
&lthead&gt...&lt/head&gt
&ltbody class="@@BitCss.Class.Color.Background.Primary @@BitCss.Class.Color.Foreground.Primary"&gt
...
Expand All @@ -180,7 +230,7 @@ _bitThemeManager.ApplyBitThemeAsync(myTheme);</code></pre>
This class contians two main property for accessing CSS classes (<code>BitCss.Class</code>) and CSS variables (<code>BitCss.Var</code>).
</BitText>
<br />
<pre><code class="language-cshtml">&ltdiv style="border-color:var(@@BitCss.Var.Color.Border.Secondary)"&gt
<pre class="code"><code class="language-cshtml">&ltdiv style="border-color:var(@@BitCss.Var.Color.Border.Secondary)"&gt
hello world!
&lt/div&gt</code></pre>
</section>
Expand Down Expand Up @@ -243,66 +293,66 @@ _bitThemeManager.ApplyBitThemeAsync(myTheme);</code></pre>
The differnet functions available in this object are as follows:
</BitText>
<br />
<pre><code class="language-js">BitTheme.get()</code></pre>
<pre class="code"><code class="language-js">const currentTheme = BitTheme.get();</code></pre>
<BitText Typography="BitTypography.Body1">
Gets the current theme.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.set('dark')</code></pre>
<pre class="code"><code class="language-js">BitTheme.set('dark');</code></pre>
<BitText Typography="BitTypography.Body1">
Sets the current theme.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.toggleDarkLight()</code></pre>
<pre class="code"><code class="language-js">BitTheme.toggleDarkLight();</code></pre>
<BitText Typography="BitTypography.Body1">
Toggles the current theme between dark & light.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.useSystem()</code></pre>
<pre class="code"><code class="language-js">BitTheme.useSystem();</code></pre>
<BitText Typography="BitTypography.Body1">
Uses the current theme of the system (dark or light) as the app theme.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.onChange((newTheme, oldTheme) => {
<pre class="code"><code class="language-js">BitTheme.onChange((newTheme, oldTheme) => {
if (newTheme.includes('dark')) {
document.body.classList.add('bit-theme-dark');
document.body.classList.remove('bit-theme-light');
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#0d1117');
} else {
document.body.classList.add('bit-theme-light');
document.body.classList.remove('bit-theme-dark');
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#ffffff');
}
});</code></pre>
<BitText Typography="BitTypography.Body1">
An event that fires when the current theme changes.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.applyBitTheme({...}, el)</code></pre>
<pre class="code"><code class="language-js">BitTheme.applyBitTheme({ '--bit-clr-pri': '#1A86D8' }, myElement)</code></pre>
<BitText Typography="BitTypography.Body1">
Applies an instance of BitTheme to the specified or body element just like the
<code>ApplyBitThemeAsync</code> method of the <code>BitThemeManager</code>.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.isSystemDark()</code></pre>
<pre class="code"><code class="language-js">BitTheme.isSystemDark();</code></pre>
<BitText Typography="BitTypography.Body1">
Checks if the current theme of the system is dark.
</BitText>
<br />
<br />
<pre><code class="language-js">BitTheme.init({
<pre class="code"><code class="language-js">BitTheme.init({
system: true,
persist: true,
default: 'custom-dark',
darkTheme: 'custom-dark',
lightTheme: 'custom-light',
onChange: (newTheme: string, oldThem: string) => {
if (newTheme === 'dark') {
document.body.classList.add('bit-theme-dark');
document.body.classList.remove('bit-theme-light');
if (newTheme === 'custom-dark') {
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#0d1117');
} else {
document.body.classList.add('bit-theme-light');
document.body.classList.remove('bit-theme-dark');
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#ffffff');
}
}
});</code></pre>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import '../Styles/abstracts/_bit-css-variables.scss';

pre.code {
border: rem2(1px) solid $bit-color-border-primary;
padding: 24px 80px 24px 24px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ BitTheme.init({
persist: true,
onChange: (newTheme: string, oldThem: string) => {
if (newTheme === 'dark') {
document.body.classList.add('bit-theme-dark');
document.body.classList.remove('bit-theme-light');
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#0d1117');
document.body.classList.add('bit-blazorui-dark-theme');
document.body.classList.remove('bit-blazorui-light-theme');
document.querySelector("meta[name=theme-color]")?.setAttribute('content', '#0d1117');
} else {
document.body.classList.add('bit-theme-light');
document.body.classList.remove('bit-theme-dark');
document.querySelector("meta[name=theme-color]")!.setAttribute('content', '#ffffff');
document.body.classList.add('bit-blazorui-light-theme');
document.body.classList.remove('bit-blazorui-dark-theme');
document.querySelector("meta[name=theme-color]")?.setAttribute('content', '#ffffff');
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,6 @@
border-radius: 50%;
}

.bit-theme-dark .github-btn {
background-image: url('images/github-icon-dark.svg');
}

.bit-theme-light .github-btn {
background-image: url('images/github-icon-light.svg');
}

.toggle-theme-btn {
padding: 0;
border: none;
Expand Down Expand Up @@ -121,12 +113,24 @@
}
}

.bit-theme-dark .light-theme {
display: none;
.bit-blazorui-dark-theme {
.light-theme {
display: none;
}

.github-btn {
background-image: url('images/github-icon-dark.svg');
}
}

.bit-theme-light .dark-theme {
display: none;
.bit-blazorui-light-theme {
.dark-theme {
display: none;
}

.github-btn {
background-image: url('images/github-icon-light.svg');
}
}

::deep {
Expand Down
Loading
Loading