Add theme toggler

This commit is contained in:
Stanislav Romanov 2022-09-07 17:03:33 +03:00
parent 0880d75397
commit 3532555313
11 changed files with 140 additions and 20 deletions

View file

@ -8,12 +8,17 @@
--color-gray-dark: 66 66 66;
--color-gray: 97 97 97;
--color-gray-light: 199 199 199;
--color-gray-lightest: 209 209 209;
--color-gray-lighter: 209 209 209;
--color-gray-lightest: 245 245 245;
}
body {
@apply text-gray-dark;
}
p {
@apply mb-4;
}
}
.royal-table {

View file

@ -1,7 +1,7 @@
<div class="flex items-center -space-x-px" role="group" ...attributes>
{{yield
(hash
button=(component "button" group=this onClick=this.buttonPressed)
Button=(component "button" group=this)
)
}}
</div>

View file

@ -1,14 +1,27 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { action, get } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { hbs } from 'ember-template-imports';
import { Loading } from 'ember-mdi';
import { on } from '@ember/modifier';
import eq from '../helpers/eq';
export const commonClasses =
'inline-flex items-center px-3 py-2 leading-4 text-sm cursor-pointer border hover:opacity-80 active:opacity-60 focus:outline-none text-black border-gray-dark';
export const primaryStyleClasses = 'text-primary border-primary';
export const sizes = {
sm: 'text-sm py-0.5',
md: 'px-3 py-2',
lg: 'px-4 py-3',
};
export const iconSizes = {
sm: 18,
md: 22,
lg: 24,
};
export const styles = {
default: 'border rounded',
primary: 'border rounded text-primary border-primary',
};
export default class ButtonComponent extends Component {
static template = hbs`
@ -16,22 +29,20 @@ export default class ButtonComponent extends Component {
disabled={{this.disabled}}
type={{this.type}}
class="
{{commonClasses}}
{{if (eq this.style 'primary') primaryStyleClasses}}
{{if @group 'first:rounded-l-md last:rounded-r-md' 'rounded-md'}}
inline-flex items-center justify-center
{{get sizes this.size}}
{{get styles this.style}}
"
...attributes
{{on 'click' this.handleClick}}
>
{{#if this.isPending}}
<Loading @spin={{true}} class="mx-1" />
<Loading @spin={{true}} @size={{get iconSizes this.size}} />
{{else if @icon}}
<@icon class="mx-1" />
<@icon @size={{get iconSizes this.size}} />
{{/if}}
{{#if this.text}}
<span class="mx-1">
{{this.text}}
</span>
{{this.text}}
{{/if}}
</button>
`;
@ -43,7 +54,7 @@ export default class ButtonComponent extends Component {
}
get size() {
return this.args.size ?? 'default';
return this.args.size ?? 'md';
}
get isActive() {

View file

@ -0,0 +1 @@
<div class="border-b my-4"/>

View file

@ -0,0 +1,13 @@
<div class='grid grid-cols-3 gap-1 p-1 rounded bg-gray-lightest'>
{{#each this.themes as |item|}}
{{#let (eq item.id this.theme) as |selected|}}
<Button
@text={{item.name}}
@icon={{item.icon}}
@onClick={{fn this.changeTheme item.id}}
@size='sm'
class='border-none {{if selected "bg-white shadow-sm"}}'
/>
{{/let}}
{{/each}}
</div>

View file

@ -0,0 +1,32 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { WhiteBalanceSunny, ThemeLightDark, WeatherNight } from 'ember-mdi';
import { tracked } from '@glimmer/tracking';
export default class ThemeTogglerComponent extends Component {
@service session;
@tracked theme;
constructor() {
super(...arguments);
this.theme = document.documentElement.dataset.theme;
}
get themes() {
return [
{ id: 'light', name: 'Light', icon: WhiteBalanceSunny },
{ id: 'system', name: 'System', icon: ThemeLightDark },
{ id: 'dark', name: 'Dark', icon: WeatherNight },
];
}
@action
changeTheme(theme) {
localStorage.setItem('theme', theme);
this.theme = theme;
document.documentElement.dataset.theme = theme;
}
}

View file

@ -8,7 +8,7 @@
{{content-for "head"}}
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css" onload="localStorage&&localStorage.theme&&(document.documentElement.dataset.theme=localStorage.theme)">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/meiliadmin.css">
{{content-for "head-footer"}}

View file

@ -11,7 +11,7 @@
'flex items-center px-4 py-2 font-semibold text-lg text-gray-dark'
as |classLink|
}}
<nav class='flex flex-col flex-1'>
<nav class='flex flex-col flex-1 mb-4'>
{{!-- <div class='px-4 py-2 text-sm text-gray'>Indexes</div>
{{#each @model.results as |item|}}
<LinkTo
@ -36,7 +36,7 @@
Keys
</LinkTo>
<div class="border-b my-4"></div>
<Divider />
<a
href='https://docs.meilisearch.com/'
@ -56,15 +56,20 @@
<Icons::Github class='fill-gray mr-2' />
MeiliAdmin
</a>
<Divider />
<button
type='button'
{{on 'click' this.invalidateSession}}
class='{{classLink}} mt-auto'
class={{classLink}}
>
<Icons::Logout class='fill-gray mr-2' />
Logout
</button>
</nav>
<ThemeToggler />
{{/let}}
</div>

View file

@ -5,13 +5,14 @@ module.exports = {
darkMode: 'media',
theme: {
extend: {
borderColor: (theme) => theme('colors.gray.lightest'),
borderColor: (theme) => theme('colors.gray.lighter'),
colors: {
gray: {
darkest: 'rgb(var(--color-gray-darkest) / <alpha-value>)',
dark: 'rgb(var(--color-gray-dark) / <alpha-value>)',
DEFAULT: 'rgb(var(--color-gray) / <alpha-value>)',
light: 'rgb(var(--color-gray-light) / <alpha-value>)',
lighter: 'rgb(var(--color-gray-lighter) / <alpha-value>)',
lightest: 'rgb(var(--color-gray-lightest) / <alpha-value>)',
},
primary: {

View file

@ -0,0 +1,26 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | divider', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Divider />`);
assert.dom(this.element).hasText('');
// Template block usage:
await render(hbs`
<Divider>
template block text
</Divider>
`);
assert.dom(this.element).hasText('template block text');
});
});

View file

@ -0,0 +1,26 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'meiliadmin/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | theme-toggler', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<ThemeToggler />`);
assert.dom(this.element).hasText('');
// Template block usage:
await render(hbs`
<ThemeToggler>
template block text
</ThemeToggler>
`);
assert.dom(this.element).hasText('template block text');
});
});