Improve project layout
This commit is contained in:
parent
20c81628f1
commit
23529dbd4b
8 changed files with 7 additions and 8 deletions
53
src/lib/components/ColorSchemeSwitcher.svelte
Normal file
53
src/lib/components/ColorSchemeSwitcher.svelte
Normal file
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from '@sveltestrap/sveltestrap';
|
||||
|
||||
type Theme = 'light' | 'dark' | 'auto';
|
||||
|
||||
let theme: Theme = 'auto';
|
||||
|
||||
// Set the theme based on user selection and store it in localStorage
|
||||
function setTheme(newTheme: Theme) {
|
||||
theme = newTheme;
|
||||
localStorage.setItem('theme', newTheme);
|
||||
applyTheme(newTheme);
|
||||
}
|
||||
|
||||
// Apply the selected theme to the document
|
||||
function applyTheme(selectedTheme: Theme) {
|
||||
if (selectedTheme === 'auto') {
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
document.documentElement.setAttribute('data-bs-theme', prefersDark ? 'dark' : 'light');
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-bs-theme', selectedTheme);
|
||||
}
|
||||
}
|
||||
|
||||
// On component mount, check localStorage and apply the saved theme
|
||||
onMount(() => {
|
||||
const savedTheme = (localStorage.getItem('theme') as Theme) || 'auto';
|
||||
applyTheme(savedTheme);
|
||||
theme = savedTheme;
|
||||
|
||||
// Listen for changes in the system color scheme preference
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
mediaQuery.addEventListener('change', () => {
|
||||
if (theme === 'auto') {
|
||||
applyTheme('auto');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<Dropdown inNavbar>
|
||||
<DropdownToggle nav caret>
|
||||
{theme === 'auto' ? '🌗' : theme === 'dark' ? '🌙' : '☀️'}
|
||||
</DropdownToggle>
|
||||
<DropdownMenu end>
|
||||
<DropdownItem active={theme === 'light'} on:click={() => setTheme('light')}
|
||||
>☀️ Light</DropdownItem
|
||||
>
|
||||
<DropdownItem active={theme === 'dark'} on:click={() => setTheme('dark')}>🌙 Dark</DropdownItem>
|
||||
<DropdownItem active={theme === 'auto'} on:click={() => setTheme('auto')}>🌗 Auto</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
58
src/lib/components/SettingsInput.svelte
Normal file
58
src/lib/components/SettingsInput.svelte
Normal file
|
@ -0,0 +1,58 @@
|
|||
<script lang="ts">
|
||||
import {
|
||||
Input,
|
||||
InputGroup,
|
||||
InputGroupText,
|
||||
Label,
|
||||
FormText,
|
||||
Col,
|
||||
Row
|
||||
} from '@sveltestrap/sveltestrap';
|
||||
|
||||
export let id: string;
|
||||
export let label: string;
|
||||
export let value: string | number;
|
||||
export let type: string = 'text';
|
||||
export let size: string = 'sm';
|
||||
export let required: boolean = false;
|
||||
export let min: number | undefined = undefined;
|
||||
export let max: number | undefined = undefined;
|
||||
export let step: number | string | undefined = undefined;
|
||||
export let suffix: string | undefined = undefined;
|
||||
export let helpText: string | undefined = undefined;
|
||||
export let disabled: boolean = false;
|
||||
export let valid: boolean | undefined = undefined;
|
||||
export let invalid: boolean | undefined = undefined;
|
||||
export let minlength: string | undefined = undefined;
|
||||
export let onChange: (() => void) | undefined = undefined;
|
||||
</script>
|
||||
|
||||
<Row>
|
||||
<Label md={6} for={id} {size}>{label}</Label>
|
||||
<Col md="6">
|
||||
<InputGroup {size}>
|
||||
<Input
|
||||
{id}
|
||||
{type}
|
||||
bind:value
|
||||
{required}
|
||||
{min}
|
||||
{max}
|
||||
{step}
|
||||
{disabled}
|
||||
{valid}
|
||||
{invalid}
|
||||
{minlength}
|
||||
bsSize={size}
|
||||
on:change={onChange}
|
||||
/>
|
||||
{#if suffix}
|
||||
<InputGroupText>{suffix}</InputGroupText>
|
||||
{/if}
|
||||
<slot />
|
||||
</InputGroup>
|
||||
{#if helpText}
|
||||
<FormText>{helpText}</FormText>
|
||||
{/if}
|
||||
</Col>
|
||||
</Row>
|
34
src/lib/components/SettingsSelect.svelte
Normal file
34
src/lib/components/SettingsSelect.svelte
Normal file
|
@ -0,0 +1,34 @@
|
|||
<script lang="ts">
|
||||
import { Input, Label, FormText, Col, Row } from '@sveltestrap/sveltestrap';
|
||||
|
||||
export let id: string;
|
||||
export let label: string;
|
||||
export let value: string | number;
|
||||
export let options: Array<[string, string | number]>;
|
||||
export let size: string = 'sm';
|
||||
export let helpText: string | undefined = undefined;
|
||||
export let selectClass: string | undefined = undefined;
|
||||
export let onChange: (() => void) | undefined = undefined;
|
||||
</script>
|
||||
|
||||
<Row>
|
||||
<Label md={6} for={id} {size}>{label}</Label>
|
||||
<Col md="6">
|
||||
<Input
|
||||
{id}
|
||||
type="select"
|
||||
bind:value
|
||||
name="select"
|
||||
bsSize={size}
|
||||
class={selectClass}
|
||||
on:change={onChange}
|
||||
>
|
||||
{#each options as [key, val]}
|
||||
<option value={val}>{key}</option>
|
||||
{/each}
|
||||
</Input>
|
||||
{#if helpText}
|
||||
<FormText>{helpText}</FormText>
|
||||
{/if}
|
||||
</Col>
|
||||
</Row>
|
15
src/lib/components/SettingsSwitch.svelte
Normal file
15
src/lib/components/SettingsSwitch.svelte
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { Input, Col } from '@sveltestrap/sveltestrap';
|
||||
|
||||
// Props
|
||||
export let id: string;
|
||||
export let checked: boolean;
|
||||
export let label: string;
|
||||
export let size: string = 'sm';
|
||||
export let disabled: boolean = false;
|
||||
export let col: { [key: string]: string } = { md: '6', xl: '12', xxl: '6' };
|
||||
</script>
|
||||
|
||||
<Col {...col}>
|
||||
<Input {id} bind:checked type="switch" bsSize={size} {label} {disabled} />
|
||||
</Col>
|
28
src/lib/components/ToggleHeader.svelte
Normal file
28
src/lib/components/ToggleHeader.svelte
Normal file
|
@ -0,0 +1,28 @@
|
|||
<script lang="ts">
|
||||
import { Fade } from '@sveltestrap/sveltestrap';
|
||||
import CaretRightFill from 'svelte-bootstrap-icons/lib/CaretRightFill.svelte';
|
||||
import CaretDownFill from 'svelte-bootstrap-icons/lib/CaretDownFill.svelte';
|
||||
|
||||
export let header;
|
||||
export let defaultOpen = false;
|
||||
export let isOpen = defaultOpen;
|
||||
</script>
|
||||
|
||||
<h4 style="cursor: pointer">
|
||||
<span
|
||||
role="link"
|
||||
on:click={() => (isOpen = !isOpen)}
|
||||
tabindex="0"
|
||||
on:keypress={() => (isOpen = !isOpen)}
|
||||
>
|
||||
{#if isOpen}
|
||||
<CaretDownFill></CaretDownFill>
|
||||
{:else}
|
||||
<CaretRightFill></CaretRightFill>
|
||||
{/if}
|
||||
{header}
|
||||
</span>
|
||||
</h4>
|
||||
<Fade {isOpen}>
|
||||
<slot></slot>
|
||||
</Fade>
|
5
src/lib/components/index.ts
Normal file
5
src/lib/components/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export { default as SettingsSwitch } from './SettingsSwitch.svelte';
|
||||
export { default as SettingsInput } from './SettingsInput.svelte';
|
||||
export { default as SettingsSelect } from './SettingsSelect.svelte';
|
||||
export { default as ToggleHeader } from './ToggleHeader.svelte';
|
||||
export { default as ColorSchemeSwitcher } from './ColorSchemeSwitcher.svelte';
|
Loading…
Add table
Add a link
Reference in a new issue