From 6ddf19f9c8a9d66c3e38ce0cac9f0379597855b1 Mon Sep 17 00:00:00 2001
From: roble
Date: Sat, 25 Apr 2026 21:58:06 +0100
Subject: [PATCH 1/8] feat: implement themes module with CRUD operations and
service integration
---
.github/workflows/test.yml | 2 +-
CLAUDE.md | 2 +-
Taskfile.yml | 4 ++--
app/Providers/RouteServiceProvider.php | 15 ---------------
composer.json | 16 +++++++++++-----
module.json | 15 ---------------
routes/web.php | 16 +++++++++-------
.../Console/Commands/ApplyThemeCommand.php | 0
{app => src}/Filament/ThemesPlugin.php | 0
.../Http/Controllers/ThemesController.php | 0
.../Providers/ThemesServiceProvider.php | 19 +++++++++----------
{app => src}/Services/ThemeService.php | 0
12 files changed, 33 insertions(+), 56 deletions(-)
delete mode 100644 app/Providers/RouteServiceProvider.php
delete mode 100644 module.json
rename {app => src}/Console/Commands/ApplyThemeCommand.php (100%)
rename {app => src}/Filament/ThemesPlugin.php (100%)
rename {app => src}/Http/Controllers/ThemesController.php (100%)
rename {app => src}/Providers/ThemesServiceProvider.php (74%)
rename {app => src}/Services/ThemeService.php (100%)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f588c15..6542a63 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,4 +13,4 @@ jobs:
test:
uses: saucebase-dev/saucebase/.github/workflows/test-module.yml@main
with:
- module: Themes
+ module: themes
diff --git a/CLAUDE.md b/CLAUDE.md
index b36739c..1f71309 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -242,7 +242,7 @@ ls modules/Themes/resources/themes/
php -d memory_limit=2048M artisan test --compact modules/Themes/tests/
# E2E
-npx playwright test --project="@Themes*"
+npx playwright test --project="@themes*"
```
Key test files:
diff --git a/Taskfile.yml b/Taskfile.yml
index 9df1742..7802227 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -9,11 +9,11 @@ tasks:
test:e2e:
desc: Run E2E tests for Themes module
- cmd: npx playwright test --project="@Themes*" {{.CLI_ARGS}}
+ cmd: npx playwright test --project="@themes*" {{.CLI_ARGS}}
interactive: true
# ── Code Generation ────────────────────────────────────────────
types:generate:
desc: Generate TypeScript types from PHP DTOs and enums
- cmd: php artisan module:generate-types Themes
+ cmd: php artisan module:generate-types themes
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
deleted file mode 100644
index 165cb09..0000000
--- a/app/Providers/RouteServiceProvider.php
+++ /dev/null
@@ -1,15 +0,0 @@
-group(module_path('Themes', '/routes/web.php'));
- }
-}
diff --git a/composer.json b/composer.json
index 2ce03c1..108ebd8 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,9 @@
{
"name": "saucebase/themes",
- "description": "",
+ "description": "Themes module",
"type": "saucebase-module",
+ "license": "proprietary",
+ "version": "1.2.2",
"authors": [
{
"name": "Saucebase",
@@ -10,20 +12,24 @@
],
"extra": {
"laravel": {
- "providers": [],
+ "providers": [
+ "Modules\\Themes\\Providers\\ThemesServiceProvider"
+ ],
"aliases": {}
}
},
"autoload": {
"psr-4": {
- "Modules\\Themes\\": "app/",
+ "Modules\\Themes\\": "src/",
"Modules\\Themes\\Database\\Factories\\": "database/factories/",
- "Modules\\Themes\\Database\\Seeders\\": "database/seeders/"
+ "Modules\\Themes\\Database\\Seeders\\": "database/seeders/",
+ "Modules\\Themes\\Tests\\Support\\": "tests/Support/"
}
},
"autoload-dev": {
"psr-4": {
"Modules\\Themes\\Tests\\": "tests/"
}
- }
+ },
+ "minimum-stability": "stable"
}
diff --git a/module.json b/module.json
deleted file mode 100644
index 938ea17..0000000
--- a/module.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "Themes",
- "alias": "themes",
- "description": "Themes module",
- "author": "Saucebase",
- "version": "v1.2.2",
- "keywords": [
- "themes"
- ],
- "priority": 0,
- "providers": [
- "Modules\\Themes\\Providers\\ThemesServiceProvider"
- ],
- "files": []
-}
diff --git a/routes/web.php b/routes/web.php
index 2f79cb9..6ad5b22 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -3,12 +3,14 @@
use Illuminate\Support\Facades\Route;
use Modules\Themes\Http\Controllers\ThemesController;
-Route::post('/themes', [ThemesController::class, 'store'])
- ->middleware('throttle:10,1')
- ->name('themes.store');
+Route::middleware('web')->group(function (): void {
+ Route::post('/themes', [ThemesController::class, 'store'])
+ ->middleware('throttle:10,1')
+ ->name('themes.store');
-Route::put('/themes/{name}', [ThemesController::class, 'update'])
- ->name('themes.update');
+ Route::put('/themes/{name}', [ThemesController::class, 'update'])
+ ->name('themes.update');
-Route::delete('/themes/{name}', [ThemesController::class, 'destroy'])
- ->name('themes.destroy');
+ Route::delete('/themes/{name}', [ThemesController::class, 'destroy'])
+ ->name('themes.destroy');
+});
diff --git a/app/Console/Commands/ApplyThemeCommand.php b/src/Console/Commands/ApplyThemeCommand.php
similarity index 100%
rename from app/Console/Commands/ApplyThemeCommand.php
rename to src/Console/Commands/ApplyThemeCommand.php
diff --git a/app/Filament/ThemesPlugin.php b/src/Filament/ThemesPlugin.php
similarity index 100%
rename from app/Filament/ThemesPlugin.php
rename to src/Filament/ThemesPlugin.php
diff --git a/app/Http/Controllers/ThemesController.php b/src/Http/Controllers/ThemesController.php
similarity index 100%
rename from app/Http/Controllers/ThemesController.php
rename to src/Http/Controllers/ThemesController.php
diff --git a/app/Providers/ThemesServiceProvider.php b/src/Providers/ThemesServiceProvider.php
similarity index 74%
rename from app/Providers/ThemesServiceProvider.php
rename to src/Providers/ThemesServiceProvider.php
index c470735..a373ccc 100644
--- a/app/Providers/ThemesServiceProvider.php
+++ b/src/Providers/ThemesServiceProvider.php
@@ -9,17 +9,16 @@
class ThemesServiceProvider extends ModuleServiceProvider
{
- protected string $name = 'Themes';
-
- protected string $nameLower = 'themes';
-
- protected array $providers = [
- RouteServiceProvider::class,
- ];
+ public function boot(): void
+ {
+ parent::boot();
- protected array $commands = [
- ApplyThemeCommand::class,
- ];
+ if ($this->app->runningInConsole()) {
+ $this->commands([
+ ApplyThemeCommand::class,
+ ]);
+ }
+ }
protected function shareInertiaData(): void
{
diff --git a/app/Services/ThemeService.php b/src/Services/ThemeService.php
similarity index 100%
rename from app/Services/ThemeService.php
rename to src/Services/ThemeService.php
From 4eaa2781d51cb1178ae1549900dc050ac81acdb6 Mon Sep 17 00:00:00 2001
From: roble
Date: Sat, 25 Apr 2026 22:00:01 +0100
Subject: [PATCH 2/8] fix: improve sidebar sync detection to prevent
overwriting values on load
---
resources/js/components/ThemePanel.vue | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/resources/js/components/ThemePanel.vue b/resources/js/components/ThemePanel.vue
index 377160d..1e14567 100644
--- a/resources/js/components/ThemePanel.vue
+++ b/resources/js/components/ThemePanel.vue
@@ -230,14 +230,16 @@ function populateFieldsFromTheme(theme: Theme): void {
field.value = raw;
}
}
- // Apply sidebar sync now so originalValues captures the synced state,
- // preventing a false "live edits" indicator on fresh load.
- if (sidebarSynced.value) {
- applySidebarSync();
- for (const f of fields) {
- if (f.key.startsWith('sidebar') && f.type === 'color')
- fieldSynced[f.key] = true;
- }
+ // Detect actual sidebar sync state from loaded values — never force-apply sync.
+ // This prevents sidebar values from being overwritten with surface values on load.
+ const allSidebarSynced = SIDEBAR_SYNC_MAP.every(([sidebarKey, sourceKey]) => {
+ const s = fields.find((f) => f.key === sidebarKey);
+ const src = fields.find((f) => f.key === sourceKey);
+ return s?.value !== '' && src?.value !== '' && s?.value === src?.value;
+ });
+ for (const f of fields) {
+ if (f.key.startsWith('sidebar') && f.type === 'color')
+ fieldSynced[f.key] = allSidebarSynced;
}
originalValues.value = Object.fromEntries(
fields.map((f) => [f.key, f.value]),
@@ -649,7 +651,7 @@ const SIDEBAR_SYNC_MAP: [string, string][] = [
['sidebar-ring', 'ring'],
];
-const sidebarSynced = ref(true);
+const sidebarSynced = ref(false);
function applySidebarSync(): void {
for (const [sidebarKey, sourceKey] of SIDEBAR_SYNC_MAP) {
From d33a80daeebc78efdeb0b8782a8ba6b191e716ed Mon Sep 17 00:00:00 2001
From: roble
Date: Wed, 29 Apr 2026 21:35:53 +0100
Subject: [PATCH 3/8] fix: update file paths in documentation to reflect new
directory structure
---
CLAUDE.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 1f71309..422945c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -112,9 +112,9 @@ documentElement inline styles ← set by applyThemeVars() when a theme is activ
|------|------|
| `resources/themes/*.json` | Theme definitions — committed source of truth |
| `resources/css/theme.css` | (in `resources/css/`, not inside module) — baked CSS output |
-| `app/Console/Commands/ApplyThemeCommand.php` | Patches theme.css from JSON; writes `:root` and `.dark` blocks |
-| `app/Providers/ThemesServiceProvider.php` | Discovers themes, parses JSON, shares via Inertia |
-| `app/Http/Controllers/ThemesController.php` | REST API for save/update/delete of user themes |
+| `src/Console/Commands/ApplyThemeCommand.php` | Patches theme.css from JSON; writes `:root` and `.dark` blocks |
+| `src/Providers/ThemesServiceProvider.php` | Discovers themes, parses JSON, shares via Inertia |
+| `src/Http/Controllers/ThemesController.php` | REST API for save/update/delete of user themes |
| `resources/js/fields.ts` | Canonical list of all editable fields with type, vars, constraints |
| `resources/js/utils/theme.ts` | Core utilities: `applyThemeVars`, `computeShadows`, `computeRadiusScale`, `computeTrackingScale`, font loading |
| `resources/js/components/ThemePanel.vue` | Full visual editor — field rendering, per-field mode sync, save dropdown |
From b48db65ba6947adde2a6c387a213fb133b9f045f Mon Sep 17 00:00:00 2001
From: roble
Date: Wed, 29 Apr 2026 21:36:14 +0100
Subject: [PATCH 4/8] feat: add database seeding task for Themes module
---
Taskfile.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Taskfile.yml b/Taskfile.yml
index 7802227..d1d61d2 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -12,6 +12,12 @@ tasks:
cmd: npx playwright test --project="@themes*" {{.CLI_ARGS}}
interactive: true
+ # ── Database ──────────────────────────────────────────────────
+
+ db:seed:
+ desc: Seed the Themes module database
+ cmd: php artisan modules:seed --module=themes
+
# ── Code Generation ────────────────────────────────────────────
types:generate:
From 8fdf46867acf92defb2eeab286476f21dc1fd599 Mon Sep 17 00:00:00 2001
From: roble
Date: Fri, 22 May 2026 21:48:05 +0100
Subject: [PATCH 5/8] feat: add ThemePicker component and theme management
utilities
- Implemented ThemePicker.vue for selecting themes with search functionality.
- Created fields.ts to define theme-related fields and their properties.
- Developed theme.ts for managing theme application, including font loading and CSS variable handling.
---
resources/js/app.ts | 10 +---------
resources/js/vue/app.ts | 9 +++++++++
resources/js/{ => vue}/components/ColorInput.vue | 0
.../js/{ => vue}/components/ColorPickerPopover.vue | 0
resources/js/{ => vue}/components/DialogCommand.vue | 0
resources/js/{ => vue}/components/DialogSave.vue | 0
resources/js/{ => vue}/components/FontPicker.vue | 0
resources/js/{ => vue}/components/LinkToggle.vue | 0
resources/js/{ => vue}/components/SearchInput.vue | 0
resources/js/{ => vue}/components/SliderInput.vue | 0
.../js/{ => vue}/components/TailwindColorPicker.vue | 0
resources/js/{ => vue}/components/ThemeColorSwatch.vue | 0
resources/js/{ => vue}/components/ThemePanel.vue | 0
resources/js/{ => vue}/components/ThemePicker.vue | 0
resources/js/{ => vue}/fields.ts | 0
resources/js/{ => vue}/utils/theme.ts | 0
16 files changed, 10 insertions(+), 9 deletions(-)
create mode 100644 resources/js/vue/app.ts
rename resources/js/{ => vue}/components/ColorInput.vue (100%)
rename resources/js/{ => vue}/components/ColorPickerPopover.vue (100%)
rename resources/js/{ => vue}/components/DialogCommand.vue (100%)
rename resources/js/{ => vue}/components/DialogSave.vue (100%)
rename resources/js/{ => vue}/components/FontPicker.vue (100%)
rename resources/js/{ => vue}/components/LinkToggle.vue (100%)
rename resources/js/{ => vue}/components/SearchInput.vue (100%)
rename resources/js/{ => vue}/components/SliderInput.vue (100%)
rename resources/js/{ => vue}/components/TailwindColorPicker.vue (100%)
rename resources/js/{ => vue}/components/ThemeColorSwatch.vue (100%)
rename resources/js/{ => vue}/components/ThemePanel.vue (100%)
rename resources/js/{ => vue}/components/ThemePicker.vue (100%)
rename resources/js/{ => vue}/fields.ts (100%)
rename resources/js/{ => vue}/utils/theme.ts (100%)
diff --git a/resources/js/app.ts b/resources/js/app.ts
index 13179b5..3043f15 100644
--- a/resources/js/app.ts
+++ b/resources/js/app.ts
@@ -1,9 +1 @@
-import { registerGlobalComponent } from '@/lib/globalComponents';
-import '../css/app.css';
-import ThemePanel from './components/ThemePanel.vue';
-
-export function setup() {
- registerGlobalComponent('top', ThemePanel);
-}
-
-export function afterMount() {}
+export * from './vue/app';
diff --git a/resources/js/vue/app.ts b/resources/js/vue/app.ts
new file mode 100644
index 0000000..4d2ca36
--- /dev/null
+++ b/resources/js/vue/app.ts
@@ -0,0 +1,9 @@
+import { registerGlobalComponent } from '@/lib/globalComponents';
+import '@modules/themes/resources/css/app.css';
+import ThemePanel from './components/ThemePanel.vue';
+
+export function setup() {
+ registerGlobalComponent('top', ThemePanel);
+}
+
+export function afterMount() {}
diff --git a/resources/js/components/ColorInput.vue b/resources/js/vue/components/ColorInput.vue
similarity index 100%
rename from resources/js/components/ColorInput.vue
rename to resources/js/vue/components/ColorInput.vue
diff --git a/resources/js/components/ColorPickerPopover.vue b/resources/js/vue/components/ColorPickerPopover.vue
similarity index 100%
rename from resources/js/components/ColorPickerPopover.vue
rename to resources/js/vue/components/ColorPickerPopover.vue
diff --git a/resources/js/components/DialogCommand.vue b/resources/js/vue/components/DialogCommand.vue
similarity index 100%
rename from resources/js/components/DialogCommand.vue
rename to resources/js/vue/components/DialogCommand.vue
diff --git a/resources/js/components/DialogSave.vue b/resources/js/vue/components/DialogSave.vue
similarity index 100%
rename from resources/js/components/DialogSave.vue
rename to resources/js/vue/components/DialogSave.vue
diff --git a/resources/js/components/FontPicker.vue b/resources/js/vue/components/FontPicker.vue
similarity index 100%
rename from resources/js/components/FontPicker.vue
rename to resources/js/vue/components/FontPicker.vue
diff --git a/resources/js/components/LinkToggle.vue b/resources/js/vue/components/LinkToggle.vue
similarity index 100%
rename from resources/js/components/LinkToggle.vue
rename to resources/js/vue/components/LinkToggle.vue
diff --git a/resources/js/components/SearchInput.vue b/resources/js/vue/components/SearchInput.vue
similarity index 100%
rename from resources/js/components/SearchInput.vue
rename to resources/js/vue/components/SearchInput.vue
diff --git a/resources/js/components/SliderInput.vue b/resources/js/vue/components/SliderInput.vue
similarity index 100%
rename from resources/js/components/SliderInput.vue
rename to resources/js/vue/components/SliderInput.vue
diff --git a/resources/js/components/TailwindColorPicker.vue b/resources/js/vue/components/TailwindColorPicker.vue
similarity index 100%
rename from resources/js/components/TailwindColorPicker.vue
rename to resources/js/vue/components/TailwindColorPicker.vue
diff --git a/resources/js/components/ThemeColorSwatch.vue b/resources/js/vue/components/ThemeColorSwatch.vue
similarity index 100%
rename from resources/js/components/ThemeColorSwatch.vue
rename to resources/js/vue/components/ThemeColorSwatch.vue
diff --git a/resources/js/components/ThemePanel.vue b/resources/js/vue/components/ThemePanel.vue
similarity index 100%
rename from resources/js/components/ThemePanel.vue
rename to resources/js/vue/components/ThemePanel.vue
diff --git a/resources/js/components/ThemePicker.vue b/resources/js/vue/components/ThemePicker.vue
similarity index 100%
rename from resources/js/components/ThemePicker.vue
rename to resources/js/vue/components/ThemePicker.vue
diff --git a/resources/js/fields.ts b/resources/js/vue/fields.ts
similarity index 100%
rename from resources/js/fields.ts
rename to resources/js/vue/fields.ts
diff --git a/resources/js/utils/theme.ts b/resources/js/vue/utils/theme.ts
similarity index 100%
rename from resources/js/utils/theme.ts
rename to resources/js/vue/utils/theme.ts
From 789d8fb57f09f0cdc7c5002369baf647ef6b5d5a Mon Sep 17 00:00:00 2001
From: roble
Date: Sat, 23 May 2026 10:50:55 +0100
Subject: [PATCH 6/8] feat: update color mode handling to use appearance
storage key and add related tests
---
resources/js/vue/components/ThemePanel.vue | 5 +++--
resources/js/vue/components/ThemePicker.vue | 2 +-
tests/e2e/index.spec.ts | 20 ++++++++++++++++++++
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/resources/js/vue/components/ThemePanel.vue b/resources/js/vue/components/ThemePanel.vue
index 1e14567..da06220 100644
--- a/resources/js/vue/components/ThemePanel.vue
+++ b/resources/js/vue/components/ThemePanel.vue
@@ -37,7 +37,7 @@ import type { FieldState, Font, Theme } from '../types';
import { useDialog } from '@/composables/useDialog';
import { useHttp, usePage } from '@inertiajs/vue3';
-import { useDark } from '@vueuse/core';
+import { useColorMode } from '@vueuse/core';
import { trans } from 'laravel-vue-i18n';
import { toast } from 'vue-sonner';
import ColorInput from './ColorInput.vue';
@@ -75,7 +75,8 @@ const http = useHttp({
dark: {} as Record,
},
});
-const isDark = useDark();
+const colorMode = useColorMode({ storageKey: 'appearance' });
+const isDark = computed(() => colorMode.value === 'dark');
const { confirm } = useDialog();
const themesEnabled = computed(() => page.props?.themes != null);
diff --git a/resources/js/vue/components/ThemePicker.vue b/resources/js/vue/components/ThemePicker.vue
index 3b47a4e..10c1481 100644
--- a/resources/js/vue/components/ThemePicker.vue
+++ b/resources/js/vue/components/ThemePicker.vue
@@ -17,7 +17,7 @@ const props = defineProps<{
options: Theme[];
}>();
-const { system, store } = useColorMode();
+const { system, store } = useColorMode({ storageKey: 'appearance' });
const colorMode = computed(() =>
store.value === 'auto' ? system.value : store.value,
diff --git a/tests/e2e/index.spec.ts b/tests/e2e/index.spec.ts
index 804357f..fcd634a 100644
--- a/tests/e2e/index.spec.ts
+++ b/tests/e2e/index.spec.ts
@@ -227,4 +227,24 @@ test.describe('Theme panel', () => {
await expect(colorInput).toHaveValue('#aabbcc');
});
+
+ test('color mode dark button writes to appearance localStorage key, not vueuse-dark', async ({ page }) => {
+ await page.getByTestId('theme-panel-trigger').click();
+ await switchColorMode(page, 'dark');
+
+ const stored = await page.evaluate(() => localStorage.getItem('appearance'));
+ expect(stored).toBe('dark');
+
+ const wrongKey = await page.evaluate(() => localStorage.getItem('vueuse-dark'));
+ expect(wrongKey).toBeNull();
+ });
+
+ test('color mode dark button sets appearance cookie for server-side persistence', async ({ page }) => {
+ await page.getByTestId('theme-panel-trigger').click();
+ await switchColorMode(page, 'dark');
+
+ const cookies = await page.context().cookies();
+ const appearanceCookie = cookies.find((c) => c.name === 'appearance');
+ expect(appearanceCookie?.value).toBe('dark');
+ });
});
From 59c0cddcb0603edc31519126a3be2dd4b0eaeaeb Mon Sep 17 00:00:00 2001
From: roble
Date: Wed, 27 May 2026 19:34:19 +0100
Subject: [PATCH 7/8] refactor: improve code formatting and readability in
ThemePanel, ThemePicker, fields, and theme utility files
---
resources/js/vue/components/ThemePanel.vue | 29 ++++++++++++++-------
resources/js/vue/components/ThemePicker.vue | 2 +-
resources/js/vue/fields.ts | 9 ++++---
resources/js/vue/utils/theme.ts | 15 ++++++-----
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/resources/js/vue/components/ThemePanel.vue b/resources/js/vue/components/ThemePanel.vue
index da06220..dd6b046 100644
--- a/resources/js/vue/components/ThemePanel.vue
+++ b/resources/js/vue/components/ThemePanel.vue
@@ -93,7 +93,9 @@ const fontOptions = computed>(() => ({
const defaultThemeId = computed(() => themes.value[0]?.id ?? 'default');
const selectedThemeId = ref(
- (typeof localStorage !== 'undefined' ? localStorage.getItem(THEME_STORAGE_KEY) : null) ?? defaultThemeId.value,
+ (typeof localStorage !== 'undefined'
+ ? localStorage.getItem(THEME_STORAGE_KEY)
+ : null) ?? defaultThemeId.value,
);
const currentTheme = computed(
@@ -176,7 +178,8 @@ const fields = reactive(
themeFields().map((f) => ({ ...f, value: '' })),
);
-const uniqueGroups = themeFields().filter((f) => f.group)
+const uniqueGroups = themeFields()
+ .filter((f) => f.group)
.map((f) => f.group!)
.filter((g, i, arr) => arr.findIndex((x) => x.name === g.name) === i);
@@ -233,11 +236,15 @@ function populateFieldsFromTheme(theme: Theme): void {
}
// Detect actual sidebar sync state from loaded values — never force-apply sync.
// This prevents sidebar values from being overwritten with surface values on load.
- const allSidebarSynced = SIDEBAR_SYNC_MAP.every(([sidebarKey, sourceKey]) => {
- const s = fields.find((f) => f.key === sidebarKey);
- const src = fields.find((f) => f.key === sourceKey);
- return s?.value !== '' && src?.value !== '' && s?.value === src?.value;
- });
+ const allSidebarSynced = SIDEBAR_SYNC_MAP.every(
+ ([sidebarKey, sourceKey]) => {
+ const s = fields.find((f) => f.key === sidebarKey);
+ const src = fields.find((f) => f.key === sourceKey);
+ return (
+ s?.value !== '' && src?.value !== '' && s?.value === src?.value
+ );
+ },
+ );
for (const f of fields) {
if (f.key.startsWith('sidebar') && f.type === 'color')
fieldSynced[f.key] = allSidebarSynced;
@@ -845,10 +852,14 @@ const dialogCommandOpen = ref(false);
{{ $t('Add your own flavor') }}
-
+