Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new feature notice for dark mode #4922

Merged
merged 22 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d678eaa
Add new background color `curr-page`
dhruvkb Sep 12, 2024
f12ec72
Add `isDarkModeSeen` to UI store
dhruvkb Sep 12, 2024
abdedd3
Define new colors required in designs
dhruvkb Sep 12, 2024
bc12637
Add generic and dark-mode-specific new feature notice
dhruvkb Sep 12, 2024
00d5d79
Add glowing effect to theme selector
dhruvkb Sep 12, 2024
18d23d3
Only show the notice when the dark mode feature flag is enabled
dhruvkb Sep 13, 2024
63a39ce
Set dark mode to seen
dhruvkb Sep 13, 2024
a54f027
Enable content to be wrapped at extremely small widths
dhruvkb Sep 14, 2024
ee1090b
Covert the entire notice into a link
dhruvkb Sep 14, 2024
da73794
Use full screen width on mobile phones
dhruvkb Sep 14, 2024
de4972e
Maintain minimum gap between feature notice and hero text
dhruvkb Sep 14, 2024
580a875
Only write cookies after all values have been read
dhruvkb Sep 16, 2024
f8fc953
Merge branch 'main' into dark_mode_intro
dhruvkb Sep 16, 2024
a9654c5
Add fallback for current page color
dhruvkb Sep 16, 2024
b43865c
Interact with the theme selector to lose the new feature highlight
dhruvkb Sep 16, 2024
5be1b00
Fix extremely tiny difference in margins
dhruvkb Sep 16, 2024
b221d75
Limit growth of content to accommodate more images in gallery
dhruvkb Sep 16, 2024
90481bc
Replace border gradient with single tone
dhruvkb Sep 17, 2024
3a2fc23
Merge branch 'main' of https://github.com/WordPress/openverse into da…
dhruvkb Sep 18, 2024
cf129fb
Remove rendundant class
dhruvkb Sep 18, 2024
7e66053
Fix search bar width on XL breakpoint
dhruvkb Sep 18, 2024
1a6ace5
Update snapshots
dhruvkb Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
import { useUiStore } from "~/stores/ui"

import VFeatureNotice from "~/components/VFeatureNotice/VFeatureNotice.vue"

const uiStore = useUiStore()

const handleClick = () => {
uiStore.setIsDarkModeSeen(true)
}
</script>

<template>
<!-- TODO: Populate the post permalink. -->
<VFeatureNotice
see-more-href="https://make.wordpress.org/openverse/"
@click="handleClick"
>
{{ $t("notification.darkMode.text") }}
</VFeatureNotice>
</template>
37 changes: 37 additions & 0 deletions frontend/src/components/VFeatureNotice/VFeatureNotice.vue
dhruvkb marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
import VLink from "~/components/VLink.vue"

defineProps<{
seeMoreHref: string
}>()

const emit = defineEmits<{
click: [MouseEvent]
}>()

const handleClick = (e: MouseEvent) => {
emit("click", e)
}
</script>

<template>
<VLink
:href="seeMoreHref"
class="group flex h-10 w-full flex-row items-center gap-2 rounded-full border border-secondary pe-4 ps-2 hover:no-underline sm:w-[23.125rem]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I don't like to have a fixed width for an element that has text because it might overflow if a different language has longer text. But I tried Russian, which is usually longer, and it seems to fit. Hopefully, all other languages do, too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this because it was "Fixed" in Figma. When Francisco uses "Fixed" over "Hug", I usually see that as a sign that text is meant to wrap in those scenarios.

@click="handleClick"
>
<div
class="flex h-6 items-center rounded-full bg-primary px-2 text-xs font-semibold uppercase text-over-negative"
>
{{ $t("notification.new") }}
</div>
<div class="label-regular flex-grow text-default">
<!-- @slot Content goes here. -->
<slot />
</div>
<span
class="label-bold text-default group-hover:underline group-focus:underline"
>{{ $t("notification.more") }}</span
>
</VLink>
</template>
2 changes: 1 addition & 1 deletion frontend/src/components/VHomepageContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const {

<VStandaloneSearchBar
ref="searchBarRef"
class="mt-4 md:mt-6"
class="mt-4 md:mt-6 xl:max-w-[43.75rem]"
:has-popover="!!triggerElement && isContentSwitcherVisible"
@submit="handleSearch"
>
Expand Down
35 changes: 33 additions & 2 deletions frontend/src/components/VSelectField/VSelectField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ const props = withDefaults(
labelText: string
choices: Choice[]
showSelected?: boolean
/** whether to show a glowing pink outline, indicating a new feature */
showNewHighlight?: boolean
}>(),
{
modelValue: "",
blankText: "",
showSelected: true,
showHighlight: false,
}
)

Expand Down Expand Up @@ -72,9 +75,17 @@ const splitAttrs = computed(() => {

<template>
<div
class="relative m-0.5px box-content block w-fit rounded-sm border border-default text-sm focus-within:m-0 focus-within:border-1.5 focus-within:border-focus hover:border-hover focus-within:hover:border-focus"
:class="splitAttrs.classAttrs"
class="group/select relative m-0.5px box-content block w-fit rounded-sm border text-sm focus-within:m-0 focus-within:border-1.5 focus-within:border-focus hover:border-hover focus-within:hover:border-focus"
:class="[
splitAttrs.classAttrs,
showNewHighlight ? 'border-tx' : 'border-default',
]"
>
<div
v-if="showNewHighlight"
class="new-highlight pointer-events-none absolute -inset-1.5px animate-new-highlight rounded-sm border-1.5 border-tx group-focus-within/select:hidden group-hover/select:hidden"
aria-hidden="true"
/>
<div class="pointer-events-none absolute inset-y-0 start-2 my-auto h-fit">
<slot name="start" />
</div>
Expand All @@ -100,3 +111,23 @@ const splitAttrs = computed(() => {
</select>
</div>
</template>

<style>
@property --deg {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}

.new-highlight {
background:
linear-gradient(var(--color-bg-curr-page), var(--color-bg-curr-page))
content-box,
linear-gradient(
var(--deg),
var(--color-gray-new-highlight),
var(--color-new-highlight)
)
border-box;
}
</style>
7 changes: 7 additions & 0 deletions frontend/src/components/VThemeSelect/VThemeSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const colorMode = computed({
},
})

const isDarkModeSeen = computed(() => uiStore.isDarkModeSeen)
const setIsDarkModeSeen = () => {
uiStore.setIsDarkModeSeen(true)
}

const darkMode = useDarkMode()

/**
Expand Down Expand Up @@ -68,6 +73,8 @@ const choices: ComputedRef<Choice[]> = computed(() => {
:blank-text="$t('theme.theme')"
:label-text="$t('theme.theme')"
:show-selected="false"
:show-new-highlight="!isDarkModeSeen"
@click="setIsDarkModeSeen"
>
<template #start>
<VIcon :name="currentThemeIcon" />
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/layouts/content-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ provide(ShowScrollButtonKey, showScrollButton)
<style scoped>
.app {
grid-template-areas: "header" "main";
/* This is used by some elements. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition! It would be useful for the focus ring outlines.

--color-bg-curr-page: var(--color-bg);
}
.header-el {
grid-area: header;
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ defineOptions({
<style scoped>
.app {
grid-template-areas: "header" "main";
/* This is used by some elements. */
--color-bg-curr-page: var(--color-bg-complementary);
}
.header-el {
grid-area: header;
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/layouts/search-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ provide(ShowScrollButtonKey, showScrollButton)
}
.app {
grid-template-areas: "header" "main";
/* This is used by some elements. */
--color-bg-curr-page: var(--color-bg);
}
.header-el {
grid-area: header;
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/locales/scripts/en.json5
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
link: "the privacy page",
close: "Close the analytics notice banner.",
},
darkMode: {
text: "Dark mode is now available.",
},
new: "New",
more: "See more",
},
header: {
homeLink: "{openverse} Home",
Expand Down
30 changes: 23 additions & 7 deletions frontend/src/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useSearchStore } from "~/stores/search"
import { useUiStore } from "~/stores/ui"
import { useFeatureFlagStore } from "~/stores/feature-flag"

import VDarkModeFeatureNotice from "~/components/VFeatureNotice/VDarkModeFeatureNotice.vue"
import VHomeGallery from "~/components/VHomeGallery/VHomeGallery.vue"
import VHomepageContent from "~/components/VHomepageContent.vue"

Expand Down Expand Up @@ -48,6 +49,8 @@ onMounted(() => {

const isXl = computed(() => uiStore.isBreakpoint("xl"))

const isDarkModeSeen = computed(() => uiStore.isDarkModeSeen)

const searchType = ref<SearchType>(ALL_MEDIA)

const setSearchType = (type: SearchType) => {
Expand All @@ -61,6 +64,10 @@ const setSearchType = (type: SearchType) => {
}
}

const showThemeSwitcher = computed(() =>
featureFlagStore.isOn("dark_mode_ui_toggle")
)

const handleSearch = (searchTerm: string) => {
sendCustomEvent("SUBMIT_SEARCH", {
searchType: searchType.value,
Expand All @@ -78,14 +85,23 @@ const handleSearch = (searchTerm: string) => {

<template>
<main
class="index flex w-full flex-shrink-0 flex-grow flex-col justify-center gap-6 px-6 sm:px-0 lg:flex-row lg:items-center lg:justify-between lg:gap-0"
class="index flex w-full flex-shrink-0 flex-grow flex-col justify-center gap-6 px-6 sm:px-0 xl:flex-row xl:items-center xl:gap-0"
>
<VHomepageContent
class="sm:px-14 md:px-20 lg:px-26 xl:w-[53.375rem] xl:pe-0"
:handle-search="handleSearch"
:search-type="searchType"
:set-search-type="setSearchType"
/>
<div
class="flex flex-grow flex-col items-center justify-center gap-6 xl:h-[33rem] xl:flex-grow-0 xl:items-start"
>
<VDarkModeFeatureNotice
v-if="showThemeSwitcher && !isDarkModeSeen"
class="sm:mx-14 md:mx-20 lg:mx-26 xl:me-0"
/>

<VHomepageContent
class="my-auto sm:px-14 md:px-20 lg:px-26 xl:w-[53.375rem] xl:pe-0"
:handle-search="handleSearch"
:search-type="searchType"
:set-search-type="setSearchType"
/>
</div>

<!-- Image carousel -->
<VHomeGallery v-if="isXl" class="mx-10 me-12 flex h-full flex-grow" />
Expand Down
37 changes: 34 additions & 3 deletions frontend/src/stores/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export interface UiState {

/* The user-chosen color theme of the site. */
colorMode: ColorMode
/** whether the user has seen the dark mode toggle */
isDarkModeSeen: boolean
}

export const breakpoints = Object.keys(ALL_SCREEN_SIZES)
Expand All @@ -81,6 +83,7 @@ export const useUiStore = defineStore("ui", {
revealedSensitiveResults: [],
headerHeight: 80,
colorMode: "system",
isDarkModeSeen: false,
}),

getters: {
Expand All @@ -91,6 +94,7 @@ export const useUiStore = defineStore("ui", {
breakpoint: state.breakpoint,
dismissedBanners: Array.from(this.dismissedBanners),
colorMode: state.colorMode,
isDarkModeSeen: state.isDarkModeSeen,
}
},
areInstructionsVisible(state): boolean {
Expand Down Expand Up @@ -186,7 +190,11 @@ export const useUiStore = defineStore("ui", {
}

if (isColorMode(cookies.colorMode)) {
this.setColorMode(cookies.colorMode)
this.setColorMode(cookies.colorMode, false)
}

if (typeof cookies.isDarkModeSeen === "boolean") {
this.setIsDarkModeSeen(cookies.isDarkModeSeen, false)
}

this.writeToCookie()
Expand Down Expand Up @@ -279,10 +287,33 @@ export const useUiStore = defineStore("ui", {
this.shouldBlurSensitive = value
this.revealedSensitiveResults = []
},
setColorMode(colorMode: ColorMode) {

/**
* Update the user's preferred color mode.
*
* @param colorMode - the user's preferred color mode.
* @param saveToCookie - whether to save the new breakpoint in the cookie.
*/
setColorMode(colorMode: ColorMode, saveToCookie = true) {
this.colorMode = colorMode

this.writeToCookie()
if (saveToCookie) {
this.writeToCookie()
}
},

/**
* Update the value of whether the user has seen dark mode.
*
* @param value - the new value of whether the user has seen dark mode
* @param saveToCookie - whether to save the new breakpoint in the cookie.
*/
setIsDarkModeSeen(value: boolean, saveToCookie = true) {
this.isDarkModeSeen = value

if (saveToCookie) {
this.writeToCookie()
}
},
setHeaderHeight(height: number) {
this.headerHeight = Math.max(height, 80)
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/styles/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
--color-text-disabled: var(--color-gray-5);
--color-text-link: var(--color-pink-8);
--color-text-over-dark: var(--color-white);
--color-text-over-negative: var(--color-gray-1);
--color-text-secondary-over-dark: var(--color-gray-5);
--color-icon-warning: var(--color-warning-8);
--color-icon-info: var(--color-info-8);
Expand All @@ -167,6 +168,8 @@
--color-wave-active: var(--color-yellow-9);
--color-wave-inactive: var(--color-gray-12-20);
--color-modal-layer: var(--color-gray-12-80);
--color-new-highlight: var(--color-pink-6);
--color-gray-new-highlight: var(--color-gray-12-20);
}
}

Expand Down Expand Up @@ -203,6 +206,7 @@
--color-text-disabled: var(--color-gray-8);
--color-text-link: var(--color-yellow-4);
--color-text-over-dark: var(--color-gray-13);
--color-text-over-negative: var(--color-gray-12);
--color-text-secondary-over-dark: var(--color-gray-8);
--color-icon-warning: var(--color-warning-5);
--color-icon-info: var(--color-info-5);
Expand All @@ -211,6 +215,8 @@
--color-wave-active: var(--color-pink-4);
--color-wave-inactive: var(--color-gray-1-30);
--color-modal-layer: var(--color-gray-12-60);
--color-new-highlight: var(--color-yellow-3);
--color-gray-new-highlight: var(--color-gray-1-20);
}
}

Expand Down Expand Up @@ -248,6 +254,7 @@
--color-text-disabled: var(--color-gray-5);
--color-text-link: var(--color-pink-8);
--color-text-over-dark: var(--color-white);
--color-text-over-negative: var(--color-gray-1);
--color-text-secondary-over-dark: var(--color-gray-5);
--color-icon-warning: var(--color-warning-8);
--color-icon-info: var(--color-info-8);
Expand All @@ -256,6 +263,8 @@
--color-wave-active: var(--color-yellow-9);
--color-wave-inactive: var(--color-gray-12-20);
--color-modal-layer: var(--color-gray-12-80);
--color-new-highlight: var(--color-pink-6);
--color-gray-new-highlight: var(--color-gray-12-20);
}

:is(.dark-mode *),
Expand Down Expand Up @@ -292,6 +301,7 @@
--color-text-disabled: var(--color-gray-8);
--color-text-link: var(--color-yellow-4);
--color-text-over-dark: var(--color-gray-13);
--color-text-over-negative: var(--color-gray-12);
--color-text-secondary-over-dark: var(--color-gray-8);
--color-icon-warning: var(--color-warning-5);
--color-icon-info: var(--color-info-5);
Expand All @@ -300,6 +310,8 @@
--color-wave-active: var(--color-pink-4);
--color-wave-inactive: var(--color-gray-1-30);
--color-modal-layer: var(--color-gray-12-60);
--color-new-highlight: var(--color-yellow-3);
--color-gray-new-highlight: var(--color-gray-1-20);
}

body {
Expand Down
Loading