Skip to content

Commit e4f243d

Browse files
[6.x] Theme selector (#13293)
Co-authored-by: Jack McDade <jack@jackmcdade.com>
1 parent 8c5119c commit e4f243d

38 files changed

Lines changed: 2226 additions & 70 deletions

config/cp.php

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<?php
22

3-
use Statamic\CP\Color;
4-
53
return [
64

75
/*
@@ -95,47 +93,6 @@
9593

9694
'support_url' => env('STATAMIC_SUPPORT_URL', 'https://statamic.com/support'),
9795

98-
/*
99-
|--------------------------------------------------------------------------
100-
| Theme
101-
|--------------------------------------------------------------------------
102-
|
103-
| Adjust the colors used in the Control Panel. Use the Color class
104-
| to easily access the Tailwind CSS color palette.
105-
|
106-
*/
107-
108-
'theme' => [
109-
// 'grays' => Color::Zinc,
110-
111-
// 'primary' => Color::Zinc[800],
112-
// 'success' => Color::Green[400],
113-
// 'danger' => Color::Red[600],
114-
115-
// 'ui-accent-bg' => Color::Zinc[800],
116-
// 'ui-accent-text' => Color::Zinc[800],
117-
// 'dark-ui-accent-bg' => Color::Zinc[950],
118-
// 'dark-ui-accent-text' => Color::Zinc[400],
119-
120-
// 'body-bg' => Color::Zinc[100],
121-
// 'body-border' => Color::Transparent,
122-
// 'dark-body-bg' => Color::Zinc[900],
123-
// 'dark-body-border' => Color::Zinc[950],
124-
125-
// 'global-header-bg' => Color::Zinc[800],
126-
// 'dark-global-header-bg' => Color::Zinc[800],
127-
128-
// 'content-bg' => "linear-gradient(to right, hsl(0,0%,99%), #ffffff)",
129-
// 'content-border' => Color::Zinc[200],
130-
// 'dark-content-bg' => Color::Zinc[900],
131-
// 'dark-content-border' => Color::Zinc[950],
132-
133-
// 'progress-bar' => Color::Volt,
134-
135-
// 'switch-bg' => Color::Green[500],
136-
// 'dark-switch-bg' => Color::Green[600],
137-
],
138-
13996
/*
14097
|--------------------------------------------------------------------------
14198
| White Labeling

resources/css/app.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
@import './dark.css';
2222
@import './tailwind-animate.css';
2323

24+
@source inline('bg-{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-{50,150,850,925,950,{100..900..100}}');
2425

2526
@custom-variant dark (&:where(.dark, .dark *));
2627

resources/css/ui.css

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,71 @@
3030
--color-ui-accent-text: var(--theme-color-ui-accent-text);
3131
--color-switch-bg: var(--theme-color-switch-bg);
3232

33+
/* Custom color shades for all Tailwind color families */
34+
--color-slate-150: oklch(0.9485 0.01 251.702);
35+
--color-slate-850: oklch(0.236 0.041 263.801);
36+
--color-slate-925: oklch(0.1945 0.042 265.573);
37+
--color-zinc-150: oklch(0.956 0.0022 286.32);
38+
--color-zinc-850: oklch(0.236 0.006 286.015);
39+
--color-zinc-925: oklch(0.1982 0.0042 285.73);
40+
--color-neutral-150: oklch(0.946 0 0);
41+
--color-neutral-850: oklch(0.236 0 0);
42+
--color-neutral-925: oklch(0.1947 0 0);
43+
--color-stone-150: oklch(0.9465 0.002 77.571);
44+
--color-stone-850: oklch(0.236 0.006 48.043);
45+
--color-stone-925: oklch(0.2042 0.0057 55.203);
46+
--color-red-150: oklch(0.9105 0.047 18.026);
47+
--color-red-850: oklch(0.42 0.159 26.311);
48+
--color-red-925: oklch(0.3724 0.1326 25.778);
49+
--color-orange-150: oklch(0.9275 0.057 72.931);
50+
--color-orange-850: oklch(0.439 0.14 37.738);
51+
--color-orange-925: oklch(0.3837 0.1155 37.845);
52+
--color-amber-150: oklch(0.943 0.0895 95.682);
53+
--color-amber-850: oklch(0.444 0.125 46.053);
54+
--color-amber-925: oklch(0.3909 0.1060 45.858);
55+
--color-yellow-150: oklch(0.959 0.1 102.367);
56+
--color-yellow-850: oklch(0.449 0.105 59.808);
57+
--color-yellow-925: oklch(0.3979 0.0900 57.042);
58+
--color-lime-150: oklch(0.9525 0.097 123.325);
59+
--color-lime-850: oklch(0.429 0.113 131.296);
60+
--color-lime-925: oklch(0.3826 0.0960 131.242);
61+
--color-green-150: oklch(0.9435 0.064 156.369);
62+
--color-green-850: oklch(0.421 0.107 151.932);
63+
--color-green-925: oklch(0.3713 0.0899 152.603);
64+
--color-emerald-150: oklch(0.9275 0.0725 163.601);
65+
--color-emerald-850: oklch(0.405 0.086 167.427);
66+
--color-emerald-925: oklch(0.3582 0.0726 169.341);
67+
--color-teal-150: oklch(0.9315 0.0735 180.614);
68+
--color-teal-850: oklch(0.412 0.071 189.308);
69+
--color-teal-925: oklch(0.3674 0.0601 188.891);
70+
--color-cyan-150: oklch(0.9365 0.0625 204.215);
71+
--color-cyan-850: oklch(0.424 0.078 225.706);
72+
--color-cyan-925: oklch(0.3816 0.0676 227.696);
73+
--color-sky-150: oklch(0.926 0.042 233.863);
74+
--color-sky-850: oklch(0.417 0.1 240.833);
75+
--color-sky-925: oklch(0.3743 0.0859 241.124);
76+
--color-blue-150: oklch(0.907 0.0455 254.857);
77+
--color-blue-850: oklch(0.402 0.173 265.587);
78+
--color-blue-925: oklch(0.3624 0.1366 265.935);
79+
--color-indigo-150: oklch(0.9 0.0495 273.414);
80+
--color-indigo-850: oklch(0.379 0.17 277.532);
81+
--color-indigo-925: oklch(0.3416 0.1348 279.158);
82+
--color-violet-150: oklch(0.9185 0.043 293.936);
83+
--color-violet-850: oklch(0.406 0.211 293.252);
84+
--color-violet-925: oklch(0.3634 0.1808 293.291);
85+
--color-purple-150: oklch(0.924 0.048 306.939);
86+
--color-purple-850: oklch(0.41 0.197 304.356);
87+
--color-purple-925: oklch(0.3656 0.1714 304.599);
88+
--color-fuchsia-150: oklch(0.9275 0.0565 319.236);
89+
--color-fuchsia-850: oklch(0.427 0.191 325.102);
90+
--color-fuchsia-925: oklch(0.3825 0.1642 325.620);
91+
--color-pink-150: oklch(0.9235 0.0445 342.745);
92+
--color-pink-850: oklch(0.434 0.17 3.114);
93+
--color-pink-925: oklch(0.3868 0.1455 2.557);
94+
--color-rose-150: oklch(0.9165 0.044 11.291);
95+
--color-rose-850: oklch(0.433 0.174 11.985);
96+
--color-rose-925: oklch(0.3862 0.1498 10.413);
97+
3398
/* Temp */
3499
--color-dark-100: #dfe1e5;
35100
--color-dark-150: #bbbdc0;

resources/js/bootstrap/fieldtypes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import WidthFieldtype from '../components/fieldtypes/WidthFieldtype.vue';
5757
import VideoFieldtype from '../components/fieldtypes/VideoFieldtype.vue';
5858
import SetPicker from '../components/fieldtypes/replicator/SetPicker.vue';
5959
import TimeFieldtype from '../components/fieldtypes/TimeFieldtype.vue';
60+
import ThemeFieldtype from '../components/fieldtypes/ThemeFieldtype.vue';
6061

6162
export default function registerFieldtypes(app) {
6263
app.component('relationship-input', RelationshipInput);
@@ -138,4 +139,5 @@ export default function registerFieldtypes(app) {
138139
app.component('set-picker', SetPicker);
139140
app.component('revealer-fieldtype', RevealerFieldtype);
140141
app.component('template-fieldtype', TemplateFieldtype);
142+
app.component('theme-fieldtype', ThemeFieldtype);
141143
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script setup lang="ts">
2+
import Fieldtype from '@/components/fieldtypes/fieldtype';
3+
import { ref, watch } from 'vue';
4+
import type { Tab } from '../themes/Selector.vue';
5+
import Selector from '../themes/Selector.vue';
6+
import { Theme, ThemeValue } from '@/components/themes/types';
7+
import { valueToTheme } from '@/components/themes';
8+
9+
const emit = defineEmits(Fieldtype.emits);
10+
const props = defineProps(Fieldtype.props);
11+
const { update, expose } = Fieldtype.use(emit, props);
12+
13+
const toTheme = (value: unknown) => valueToTheme(value as ThemeValue | null);
14+
const selectedTheme = ref<Theme | null>(toTheme(props.value));
15+
watch(() => props.value, (newValue) => selectedTheme.value = toTheme(newValue));
16+
17+
const tab = ref<Tab>((() => {
18+
const theme = selectedTheme.value;
19+
if (!theme) return 'themes';
20+
return theme.id === 'custom' ? 'custom' : 'themes';
21+
})());
22+
23+
function selected(theme: Theme | null) {
24+
selectedTheme.value = theme;
25+
26+
if (! theme) {
27+
update(null);
28+
return;
29+
}
30+
31+
const normalizedColors = {
32+
...theme.colors,
33+
...Object.fromEntries(
34+
Object.entries(theme.darkColors || {}).map(([key, value]) => [`dark-${key}`, value])
35+
)
36+
};
37+
38+
update({
39+
id: theme.id,
40+
name: theme.name,
41+
colors: normalizedColors
42+
});
43+
}
44+
45+
defineExpose(expose);
46+
</script>
47+
48+
<template>
49+
<Selector
50+
v-model:tab="tab"
51+
:model-value="selectedTheme"
52+
@update:model-value="selected"
53+
/>
54+
</template>

0 commit comments

Comments
 (0)