Skip to content

Commit 7578beb

Browse files
committed
fix css variables not updating correctly when system theme changes
1 parent dc21ac8 commit 7578beb

File tree

8 files changed

+85
-37
lines changed

8 files changed

+85
-37
lines changed

resources/js/Components/Common/Reporting/ReportingChart.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
TooltipComponent,
1818
} from 'echarts/components';
1919
import type { AggregatedTimeEntries, Organization } from '@/packages/api/src';
20-
import { useCssVar } from '@vueuse/core';
20+
import { useCssVariable } from '@/utils/useCssVariable';
2121
2222
use([
2323
CanvasRenderer,
@@ -47,8 +47,10 @@ const xAxisLabels = computed(() => {
4747
formatDate(el.key ?? '', organization?.value?.date_format)
4848
);
4949
});
50-
const accentColor = useCssVar('--theme-color-chart', null, { observe: true });
51-
const labelColor = useCssVar('--color-text-secondary', null, { observe: true });
50+
const accentColor = useCssVariable('--theme-color-chart');
51+
const labelColor = useCssVariable('--color-text-secondary');
52+
const markLineColor = useCssVariable('--color-border-secondary');
53+
const splitLineColor = useCssVariable('--color-border-tertiary');
5254
5355
const seriesData = computed(() => {
5456
return props?.groupedData?.map((el) => {
@@ -111,7 +113,7 @@ const option = computed(() => ({
111113
data: xAxisLabels.value,
112114
markLine: {
113115
lineStyle: {
114-
color: 'rgba(125,156,188,0.1)',
116+
color: markLineColor.value,
115117
type: 'dashed',
116118
},
117119
},
@@ -135,9 +137,13 @@ const option = computed(() => ({
135137
},
136138
yAxis: {
137139
type: 'value',
140+
axisLabel: {
141+
color: labelColor.value,
142+
fontFamily: 'Outfit, sans-serif',
143+
},
138144
splitLine: {
139145
lineStyle: {
140-
color: 'rgba(125,156,188,0.2)', // Set desired color here
146+
color: splitLineColor.value,
141147
},
142148
},
143149
},

resources/js/Components/Common/Reporting/ReportingPieChart.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
TooltipComponent,
1212
} from 'echarts/components';
1313
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
14-
import { useCssVar } from '@vueuse/core';
14+
import { useCssVariable } from '@/utils/useCssVariable';
1515
import type { Organization } from '@/packages/api/src';
1616
1717
use([
@@ -36,7 +36,7 @@ type ReportingChartDataEntry = {
3636
const props = defineProps<{
3737
data: ReportingChartDataEntry | null;
3838
}>();
39-
const labelColor = useCssVar('--color-text-secondary', null, { observe: true });
39+
const labelColor = useCssVariable('--color-text-secondary');
4040
4141
const seriesData = computed(() => {
4242
return props.data?.map((el) => {

resources/js/Components/Dashboard/ActivityGraphCard.vue

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
formatHumanReadableDuration,
2020
getDayJsInstance,
2121
} from '@/packages/ui/src/utils/time';
22-
import { useCssVar } from '@vueuse/core';
22+
import { useCssVariable } from '@/utils/useCssVariable';
2323
import { useQuery } from '@tanstack/vue-query';
2424
import { getCurrentOrganizationId } from '@/utils/useUser';
2525
import { api, type Organization } from '@/packages/api/src';
@@ -64,12 +64,9 @@ const max = computed(() => {
6464
}
6565
});
6666
67-
const backgroundColor = useCssVar('--color-card-background', null, {
68-
observe: true,
69-
});
70-
const itemBackgroundColor = useCssVar('--color-bg-tertiary', null, {
71-
observe: true,
72-
});
67+
const backgroundColor = useCssVariable('--theme-color-card-background');
68+
const itemBackgroundColor = useCssVariable('--color-bg-tertiary');
69+
const borderColor = useCssVariable('--color-border');
7370
7471
const option = computed(() => {
7572
return {
@@ -120,7 +117,7 @@ const option = computed(() => {
120117
[],
121118
itemStyle: {
122119
borderRadius: 5,
123-
borderColor: 'rgba(255,255,255,0.05)',
120+
borderColor: borderColor.value,
124121
borderWidth: 1,
125122
},
126123
tooltip: {

resources/js/Components/Dashboard/DayOverviewCardChart.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script setup lang="ts">
22
import VChart from 'vue-echarts';
3-
import { computed, ref } from 'vue';
4-
import { useCssVar } from '@vueuse/core';
3+
import { computed } from 'vue';
4+
import { useCssVariable } from '@/utils/useCssVariable';
55
66
const props = defineProps<{
77
history: number[];
88
}>();
99
10-
const accentColor = useCssVar('--theme-color-chart', null, { observe: true });
10+
const accentColor = useCssVariable('--theme-color-chart');
11+
const markLineColor = useCssVariable('--color-border-secondary');
1112
1213
const seriesData = computed(() => props.history.map((el) => {
1314
return {
@@ -22,7 +23,7 @@ const seriesData = computed(() => props.history.map((el) => {
2223
},
2324
};
2425
}));
25-
const option = ref({
26+
const option = computed(() => ({
2627
grid: {
2728
top: 0,
2829
right: 0,
@@ -35,7 +36,7 @@ const option = ref({
3536
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
3637
markLine: {
3738
lineStyle: {
38-
color: 'rgba(125,156,188,0.1)',
39+
color: markLineColor.value,
3940
type: 'dashed',
4041
},
4142
},
@@ -66,11 +67,11 @@ const option = ref({
6667
},
6768
series: [
6869
{
69-
data: seriesData,
70+
data: seriesData.value,
7071
type: 'bar',
7172
},
7273
],
73-
});
74+
}));
7475
</script>
7576

7677
<template>

resources/js/Components/Dashboard/ProjectsChartCard.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
TooltipComponent,
1212
} from 'echarts/components';
1313
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
14-
import { useCssVar } from "@vueuse/core";
14+
import { useCssVariable } from '@/utils/useCssVariable';
1515
import type { Organization } from "@/packages/api/src";
1616
1717
use([
@@ -24,7 +24,7 @@ use([
2424
]);
2525
2626
provide(THEME_KEY, 'dark');
27-
const labelColor = useCssVar('--color-text-secondary', null, { observe: true });
27+
const labelColor = useCssVariable('--color-text-secondary');
2828
2929
const props = defineProps<{
3030
weeklyProjectOverview: {

resources/js/Components/Dashboard/ThisWeekOverview.vue

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import ProjectsChartCard from '@/Components/Dashboard/ProjectsChartCard.vue';
1818
import { formatHumanReadableDuration } from '@/packages/ui/src/utils/time';
1919
import { formatCents } from '@/packages/ui/src/utils/money';
2020
import { getWeekStart } from '@/packages/ui/src/utils/settings';
21-
import { useCssVar } from '@vueuse/core';
21+
import { useCssVariable } from '@/utils/useCssVariable';
2222
import { getOrganizationCurrencyString } from '@/utils/money';
2323
import { useQuery } from '@tanstack/vue-query';
2424
import { getCurrentOrganizationId } from '@/utils/useUser';
@@ -60,7 +60,7 @@ const weekdays = computed(() => {
6060
}
6161
});
6262
63-
const accentColor = useCssVar('--theme-color-chart', null, { observe: true });
63+
const accentColor = useCssVariable('--theme-color-chart');
6464
6565
// Get the organization ID using the utility function
6666
const organizationId = computed(() => getCurrentOrganizationId());
@@ -176,10 +176,8 @@ const seriesData = computed(() => {
176176
});
177177
});
178178
179-
const markLineColor = useCssVar('--color-border-secondary', null, {
180-
observe: true,
181-
});
182-
const labelColor = useCssVar('--color-text-secondary', null, { observe: true });
179+
const markLineColor = useCssVariable('--color-border-secondary');
180+
const labelColor = useCssVariable('--color-text-secondary');
183181
const option = computed(() => {
184182
return {
185183
tooltip: {
@@ -215,6 +213,10 @@ const option = computed(() => {
215213
},
216214
yAxis: {
217215
type: 'value',
216+
axisLabel: {
217+
color: labelColor.value,
218+
fontFamily: 'Outfit, sans-serif',
219+
},
218220
splitLine: {
219221
lineStyle: {
220222
color: markLineColor.value,

resources/js/utils/theme.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ import { computed, watch } from "vue";
33

44
type themeOption = "system" | "light" | "dark";
55
const themeSetting = useStorage<themeOption>("theme", "system");
6-
// reload page when themeSettingChanges
7-
watch(
8-
themeSetting,
9-
() => {
10-
location.reload();
11-
}
12-
)
136
const preferredColor = usePreferredColorScheme();
147
const theme = computed(() => {
158
if(themeSetting.value === "system"){
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ref, onMounted, onUnmounted } from 'vue'
2+
3+
export function useCssVariable(variableName: string) {
4+
const value = ref('')
5+
let observer: MutationObserver | null = null
6+
let mediaQuery: MediaQueryList | null = null
7+
8+
const updateValue = () => {
9+
const computedStyle = getComputedStyle(document.documentElement)
10+
const cssValue = computedStyle.getPropertyValue(variableName).trim()
11+
value.value = cssValue
12+
}
13+
14+
onMounted(() => {
15+
// Initialize with current value
16+
updateValue()
17+
18+
// Watch for class changes on document.documentElement (where theme classes are applied)
19+
observer = new MutationObserver((mutations) => {
20+
mutations.forEach((mutation) => {
21+
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
22+
updateValue()
23+
}
24+
})
25+
})
26+
27+
observer.observe(document.documentElement, {
28+
attributes: true,
29+
attributeFilter: ['class']
30+
})
31+
32+
// Also watch for system color scheme changes
33+
if (window.matchMedia) {
34+
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
35+
mediaQuery.addEventListener('change', updateValue)
36+
}
37+
})
38+
39+
onUnmounted(() => {
40+
if (observer) {
41+
observer.disconnect()
42+
}
43+
if (mediaQuery) {
44+
mediaQuery.removeEventListener('change', updateValue)
45+
}
46+
})
47+
48+
return value
49+
}

0 commit comments

Comments
 (0)