Добавлены настройки темы по умолчанию

This commit is contained in:
Ilia Miheev
2026-06-21 00:36:31 +03:00
parent c9347b8d20
commit 810bf469f9
10 changed files with 51 additions and 29 deletions
+4 -1
View File
@@ -7,4 +7,7 @@ VITE_BANNER_SLOGAN=— qr-код без излишеств
VITE_BANNER_URL=https://github.com/IliaMiheev/iQR
# Акцентный цвет (hex, rgb или css-имя)
VITE_ACCENT_COLOR=#ff4500
VITE_ACCENT_COLOR="#ff4500"
# Тема по умолчанию: dark или light (если пользователь ещё не переключал)
VITE_DEFAULT_THEME=light
+2
View File
@@ -26,6 +26,7 @@ npm run dev
| `VITE_BANNER_SLOGAN` | Слоган в плашке | `— qr-код без излишеств` |
| `VITE_BANNER_URL` | Ссылка плашки | репозиторий iQR |
| `VITE_ACCENT_COLOR` | Акцентный цвет | `#ff4500` |
| `VITE_DEFAULT_THEME` | Тема по умолчанию (`dark` / `light`) | `dark` |
После изменения `.env` перезапустите `npm run dev`.
@@ -46,6 +47,7 @@ environment:
BANNER_SLOGAN: "— быстрые qr-коды"
BANNER_URL: "https://example.com"
ACCENT_COLOR: "#7c3aed"
DEFAULT_THEME: "light"
```
При старте контейнера генерируется `config.json`, поэтому пересборка образа для смены текстов не нужна.
+1
View File
@@ -9,4 +9,5 @@ services:
BANNER_SLOGAN: "— qr-код без излишеств"
BANNER_URL: "https://github.com/IliaMiheev/iQR"
ACCENT_COLOR: "#ff4500"
DEFAULT_THEME: "dark"
restart: unless-stopped
+3 -1
View File
@@ -6,6 +6,7 @@ BANNER_BRAND="${BANNER_BRAND:-iQR}"
BANNER_SLOGAN="${BANNER_SLOGAN:-— qr-код без излишеств}"
BANNER_URL="${BANNER_URL:-https://github.com/IliaMiheev/iQR}"
ACCENT_COLOR="${ACCENT_COLOR:-#ff4500}"
DEFAULT_THEME="${DEFAULT_THEME:-dark}"
cat > /usr/share/nginx/html/config.json <<EOF
{
@@ -13,7 +14,8 @@ cat > /usr/share/nginx/html/config.json <<EOF
"bannerBrand": "$(printf '%s' "$BANNER_BRAND" | sed 's/"/\\"/g')",
"bannerSlogan": "$(printf '%s' "$BANNER_SLOGAN" | sed 's/"/\\"/g')",
"bannerUrl": "$(printf '%s' "$BANNER_URL" | sed 's/"/\\"/g')",
"accentColor": "$(printf '%s' "$ACCENT_COLOR" | sed 's/"/\\"/g')"
"accentColor": "$(printf '%s' "$ACCENT_COLOR" | sed 's/"/\\"/g')",
"defaultTheme": "$(printf '%s' "$DEFAULT_THEME" | sed 's/"/\\"/g')"
}
EOF
+2 -2
View File
@@ -134,7 +134,7 @@ onUnmounted(() => {
<div class="qr-modal__backdrop" @click="closeQrModal" />
<aside class="qr-modal__toolbar" aria-label="Инструменты" @click.stop>
<button type="button" title="Увеличить" @click="zoomIn">+</button>
<button type="button" title="Уменьшить" @click="zoomOut"></button>
<button
type="button"
class="qr-modal__tool-btn"
@@ -153,7 +153,7 @@ onUnmounted(() => {
/>
</svg>
</button>
<button type="button" title="Уменьшить" @click="zoomOut"></button>
<button type="button" title="Увеличить" @click="zoomIn">+</button>
</aside>
<div class="qr-modal__dialog" @click.stop>
+13 -11
View File
@@ -474,8 +474,9 @@ html.light .qr-modal__backdrop {
border: 1px solid var(--surface-border);
border-radius: 50%;
background: var(--surface-solid);
color: var(--text);
color: var(--accent);
font-size: 22px;
font-weight: 700;
line-height: 1;
display: flex;
align-items: center;
@@ -486,7 +487,8 @@ html.light .qr-modal__backdrop {
}
.qr-modal__close:hover {
border-color: var(--accent);
background: var(--surface-hover);
border-color: var(--surface-border);
color: var(--accent);
transform: scale(1.05);
}
@@ -511,7 +513,7 @@ html.light .qr-modal__backdrop {
padding: 6px;
border-radius: 12px;
background: var(--surface-solid);
border: 1px solid var(--surface-border);
border: none;
box-shadow: var(--shadow-sm);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
@@ -531,11 +533,18 @@ html.light .qr-modal__backdrop {
border: 1px solid transparent;
border-radius: 8px;
box-shadow: none;
transition:
color 0.2s ease,
border-color 0.2s ease,
background-color 0.2s ease,
box-shadow 0.2s ease,
transform 0.15s ease;
}
.qr-modal__toolbar button:hover {
background: var(--surface-hover);
border-color: var(--surface-border);
color: var(--accent);
border-color: var(--accent);
transform: none;
box-shadow: none;
}
@@ -551,11 +560,6 @@ html.light .qr-modal__backdrop {
justify-content: center;
}
.qr-modal__tool-btn:hover {
color: var(--accent);
border-color: var(--accent) !important;
}
.qr-modal__status-slot {
position: relative;
display: flex;
@@ -617,7 +621,6 @@ html.light .qr-modal__backdrop {
#qr-code {
display: inline-flex;
padding: 16px;
border-radius: 16px;
background: var(--surface-solid);
border: 1px solid var(--surface-border);
@@ -643,7 +646,6 @@ canvas {
display: block;
border-radius: 8px;
background: var(--canvas-bg);
border: 1px solid var(--canvas-border);
image-rendering: pixelated;
transition: border-color 0.35s ease;
}
+4 -13
View File
@@ -1,7 +1,9 @@
import { ref, computed, onMounted } from 'vue'
import { inject, ref, computed } from 'vue'
import { resolveTheme } from '../config/applyTheme'
export function useTheme() {
const theme = ref('dark')
const config = inject('appConfig')
const theme = ref(resolveTheme(config))
const isLightTheme = computed(() => theme.value === 'light')
@@ -15,16 +17,5 @@ export function useTheme() {
applyTheme(theme.value === 'dark' ? 'light' : 'dark')
}
onMounted(() => {
const saved = localStorage.getItem('theme')
if (saved === 'dark' || saved === 'light') {
applyTheme(saved)
return
}
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
applyTheme(prefersDark ? 'dark' : 'light')
})
return { theme, isLightTheme, toggleTheme }
}
+12
View File
@@ -1,7 +1,19 @@
import { normalizeTheme } from './defaults'
export function resolveTheme(config) {
const saved = localStorage.getItem('theme')
if (saved === 'dark' || saved === 'light') {
return saved
}
return normalizeTheme(config.defaultTheme)
}
export function applyAppConfig(config) {
const root = document.documentElement
root.style.setProperty('--accent', config.accentColor)
root.className = resolveTheme(config)
const themeMeta = document.querySelector('meta[name="theme-color"]')
if (themeMeta) {
+6
View File
@@ -4,4 +4,10 @@ export const defaultConfig = {
bannerSlogan: '— qr-код без излишеств',
bannerUrl: 'https://github.com/IliaMiheev/iQR',
accentColor: '#ff4500',
defaultTheme: 'dark',
}
export function normalizeTheme(value) {
const normalized = String(value ?? '').trim().toLowerCase()
return normalized === 'light' ? 'light' : 'dark'
}
+4 -1
View File
@@ -1,4 +1,4 @@
import { defaultConfig } from './defaults'
import { defaultConfig, normalizeTheme } from './defaults'
function fromBuildEnv() {
const env = import.meta.env
@@ -9,6 +9,7 @@ function fromBuildEnv() {
bannerSlogan: env.VITE_BANNER_SLOGAN,
bannerUrl: env.VITE_BANNER_URL,
accentColor: env.VITE_ACCENT_COLOR,
defaultTheme: env.VITE_DEFAULT_THEME,
})
}
@@ -44,5 +45,7 @@ export async function loadConfig() {
}
}
config.defaultTheme = normalizeTheme(config.defaultTheme)
return config
}