Skip to content

Commit

Permalink
Replace computed with ref and onMounted (#5237)
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat authored Dec 3, 2024
1 parent 34934c2 commit c41449e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 11 deletions.
14 changes: 8 additions & 6 deletions frontend/src/components/VLicense/VLicense.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { useI18n } from "#imports"
import { computed } from "vue"
import { useDarkMode } from "~/composables/use-dark-mode"
import { useIconNames } from "~/composables/use-icon-names"
import type { License } from "~/constants/license"
import { getFullLicenseName, getElements } from "~/utils/license"
import { getFullLicenseName } from "~/utils/license"
import { camelCase } from "~/utils/case"
import VIcon from "~/components/VIcon/VIcon.vue"
Expand All @@ -37,11 +37,13 @@ const props = withDefaults(
}
)
const { effectiveColorMode } = useDarkMode()
const { t } = useI18n({ useScope: "global" })
const iconNames = computed(() => getElements(props.license))
const { iconNames } = useIconNames({
license: props.license,
filterOutCc: false,
})
const licenseName = computed(() => {
const licenseKey =
props.license === "sampling+" ? props.license : camelCase(props.license)
Expand All @@ -60,7 +62,7 @@ const licenseName = computed(() => {
:key="name"
:class="{ 'license-bg text-black': bgFilled }"
view-box="0 0 30 30"
:name="`licenses/${name}-${effectiveColorMode}`"
:name="name"
:size="4"
/>
</div>
Expand Down
13 changes: 8 additions & 5 deletions frontend/src/components/VLicense/VLicenseElements.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useI18n } from "#imports"
import { computed } from "vue"
import type { License } from "~/constants/license"
import { useDarkMode } from "~/composables/use-dark-mode"
import { useIconNames } from "~/composables/use-icon-names"
import { useUiStore } from "~/stores/ui"
import { camelCase } from "~/utils/case"
import { getElements } from "~/utils/license"
Expand All @@ -28,13 +28,16 @@ const props = withDefaults(
}
)
const { effectiveColorMode } = useDarkMode()
const i18n = useI18n({ useScope: "global" })
const elementNames = computed(() =>
getElements(props.license).filter((icon) => icon !== "cc")
)
const { iconNames } = useIconNames({
license: props.license,
filterOutCc: true,
})
const isSmall = computed(() => props.size === "small")
const uiStore = useUiStore()
const isMobile = computed(() => !uiStore.isDesktopLayout)
Expand All @@ -47,14 +50,14 @@ const getLicenseDescription = (element: string) => {
<template>
<ul class="flex flex-col gap-y-2 md:gap-y-4">
<li
v-for="element in elementNames"
v-for="(element, idx) in elementNames"
:key="element"
class="flex items-center gap-x-3 text-sm md:text-base"
>
<VIcon
view-box="0 0 30 30"
:size="isSmall || isMobile ? 5 : 6"
:name="`licenses/${element}-${effectiveColorMode}`"
:name="iconNames[idx]"
/>
<span v-if="elementNames.length > 1" class="sr-only">{{
element.toUpperCase()
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/composables/use-dark-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ export function useDarkMode() {
return colorMode.value
})

/**
* The server does not have access to media queries, so the `system` color mode defaults to "light".
*/
const serverColorMode = computed(() => {
return !darkModeToggleable.value || colorMode.value === "system"
? "light"
: colorMode.value
})

const cssClass = computed(() => {
return {
light: LIGHT_MODE_CLASS,
Expand All @@ -77,6 +86,7 @@ export function useDarkMode() {
colorMode,
osColorMode,
effectiveColorMode,
serverColorMode,
cssClass,
}
}
49 changes: 49 additions & 0 deletions frontend/src/composables/use-icon-names.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { getElements } from "#imports"

import { computed, onMounted, ref, watch } from "vue"

import type { License } from "~/constants/license"
import { useDarkMode } from "~/composables/use-dark-mode"

/**
* Generate the names for `VIcon` components based on the license and color mode.
* The value is updated on mounted and when the color mode changes.
*
* This is necessary to prevent client-server mismatch: the server does not have access
* to media queries, so the `system` color mode always defaults to "light".
* @param license - the license to generate icons for
* @param filterOutCc - whether to filter out the `cc` from the list of icons
*/
export const useIconNames = ({
license,
filterOutCc,
}: {
license: License
filterOutCc: boolean
}) => {
const getIconNames = (elements: string[], colorMode: "dark" | "light") => {
return elements.map((element) => `licenses/${element}-${colorMode}`)
}
const { effectiveColorMode, serverColorMode } = useDarkMode()

const icons = computed(() => {
const elements = getElements(license)
return filterOutCc
? elements.filter((element) => element !== "cc")
: elements
})

const iconNames = ref(getIconNames(icons.value, serverColorMode.value))

onMounted(() => {
watch(
effectiveColorMode,
() => {
iconNames.value = getIconNames(icons.value, effectiveColorMode.value)
},
{ immediate: true }
)
})

return { iconNames }
}

0 comments on commit c41449e

Please sign in to comment.