Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions src/lib/components/bottom-nav-settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@
class="flex h-full flex-col justify-start gap-6 overflow-auto px-4 py-8"
data-theme="dark"
>
<TimezoneSelect position="left" size="sm" />
<DarkModeMenu position="left" size="sm" />
<div class="flex items-center justify-between">
<p>Timezone</p>
<TimezoneSelect size="sm" />
</div>
<div class="flex items-center justify-between">
<p>{translate('common.theme')}</p>
<DarkModeMenu />
</div>
<hr class="border-subtle" />
<NavigationButton
onClick={onCodecServerClick}
Expand Down
6 changes: 5 additions & 1 deletion src/lib/components/bottom-nav.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@
<div
class="flex aspect-square w-[32px] min-w-[32px] items-center justify-center"
>
<Icon name="astronaut" height={24} width={24} />
<img
src="/ziggy-full-face.png"
alt={translate('common.user-profile')}
class="h-[32px] w-[32px]"
/>
</div>
{/if}
</button>
Expand Down
103 changes: 32 additions & 71 deletions src/lib/components/dark-mode-menu.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
<script lang="ts">
import type { ButtonStyles } from '$lib/holocene/button.svelte';
import Icon, { type IconName } from '$lib/holocene/icon';
import {
Menu,
MenuButton,
MenuContainer,
MenuItem,
} from '$lib/holocene/menu';
import Icon from '$lib/holocene/icon';
import ToggleButton from '$lib/holocene/toggle-button/toggle-button.svelte';
import ToggleButtons from '$lib/holocene/toggle-button/toggle-buttons.svelte';
import { translate } from '$lib/i18n/translate';
import { useDarkModePreference } from '$lib/utilities/dark-mode';
import {
Expand All @@ -15,77 +10,43 @@
} from '$lib/utilities/dark-mode/dark-mode';

interface Props {
position: 'left' | 'right';
hideLabel?: boolean;
size?: ButtonStyles['size'];
onchange?: (prefersDarkMode: boolean) => void;
}

const {
position = 'right',
hideLabel = false,
size = undefined,
onchange,
}: Props = $props();

const menuButtonText = $derived(
$useDarkModePreference == 'system'
? translate('common.system-default')
: $useDarkModePreference
? translate('common.night')
: translate('common.day'),
);

const menuButtonIcon: IconName = $derived(
$useDarkModePreference == 'system'
? 'system-window'
: $useDarkModePreference
? 'moon'
: 'sun',
);
const { onchange }: Props = $props();

const setDarkModePreference = (preference: DarkModePreference) => {
$useDarkModePreference = preference;
onchange?.(prefersDarkMode(preference));
};
</script>

<MenuContainer>
<MenuButton
controls="dark-mode-menu"
hasIndicator
label={menuButtonText}
variant="ghost"
data-testid="dark-mode-menu-button"
{size}
<ToggleButtons data-testid="dark-mode-toggle-buttons" class="pl-4">
<ToggleButton
aria-label={translate('common.system-default')}
data-testid="system-mode"
on:click={() => setDarkModePreference('system')}
active={$useDarkModePreference === 'system'}
size="xs"
>
<Icon name="system-window" />
</ToggleButton>
<ToggleButton
aria-label={translate('common.day')}
data-testid="day-mode"
on:click={() => setDarkModePreference(false)}
active={$useDarkModePreference === false}
size="xs"
>
<Icon name="sun" />
</ToggleButton>
<ToggleButton
aria-label={translate('common.night')}
data-testid="night-mode"
on:click={() => setDarkModePreference(true)}
active={$useDarkModePreference === true}
size="xs"
>
{#if !hideLabel}{menuButtonText}{/if}
<Icon slot="leading" name={menuButtonIcon} aria-hidden />
</MenuButton>
<Menu id="dark-mode-menu" {position} class="w-max">
<MenuItem
on:click={() => setDarkModePreference(true)}
selected={$useDarkModePreference === true}
data-testid="night-mode"
>
<Icon slot="leading" name="moon" />
Night
</MenuItem>
<MenuItem
on:click={() => setDarkModePreference(false)}
selected={$useDarkModePreference === false}
data-testid="day-mode"
>
<Icon slot="leading" name="sun" />
Day
</MenuItem>
<MenuItem
on:click={() => setDarkModePreference('system')}
selected={$useDarkModePreference === 'system'}
data-testid="system-mode"
>
<Icon slot="leading" name="system-window" />
System Default
</MenuItem>
</Menu>
</MenuContainer>
<Icon name="moon" />
</ToggleButton>
</ToggleButtons>
2 changes: 1 addition & 1 deletion src/lib/components/timezone-select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
});
</script>

<MenuContainer>
<MenuContainer class="max-md:w-full max-md:justify-items-end">
<MenuButton
label={translate('common.timezone', { timezone })}
controls="timezones-menu"
Expand Down
64 changes: 30 additions & 34 deletions src/lib/components/top-nav.svelte
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
<script lang="ts">
import { MediaQuery } from 'svelte/reactivity';

import { type ClassNameValue, twMerge as merge } from 'tailwind-merge';

import DarkModeMenu from '$lib/components/dark-mode-menu.svelte';
import DataEncoderStatus from '$lib/components/data-encoder-status.svelte';
import TimezoneSelect from '$lib/components/timezone-select.svelte';
import { translate } from '$lib/i18n/translate';

let screenWidth: number;

let className: ClassNameValue = '';
export { className as class };
export let onThemeChange: (prefersDarkMode: boolean) => void = () => {};

const md = new MediaQuery('min-width:768px');
</script>

<svelte:window bind:innerWidth={screenWidth} />
<nav
class={merge(
'surface-primary',
'sticky top-0 z-40',
'hidden md:flex',
'w-full',
'flex-col md:flex-row',
'items-center justify-end',
'border-b border-subtle',
'p-1 px-4 md:px-8',
className,
)}
data-testid="top-nav"
aria-label={translate('common.main')}
>
<div class="flex grow items-center">
<slot name="left" />
</div>
<div class="flex items-center gap-2">
<TimezoneSelect position={screenWidth < 768 ? 'left' : 'right'} />
<DataEncoderStatus />
<DarkModeMenu
onchange={onThemeChange}
hideLabel
position={screenWidth < 768 ? 'left' : 'right'}
/>
<slot />
</div>
</nav>
{#if md.current}
<nav
class={merge(
'surface-primary',
'sticky top-0 z-40',
'flex',
'w-full',
'flex-row',
'items-center justify-end',
'border-b border-subtle',
'px-8 py-1',
className,
)}
data-testid="top-nav"
aria-label={translate('common.main')}
>
<div class="flex grow items-center">
<slot name="left" />
</div>
<div class="flex items-center gap-2">
<TimezoneSelect />
<DataEncoderStatus />
<slot />
</div>
</nav>
{/if}
11 changes: 8 additions & 3 deletions src/lib/holocene/menu/menu-item.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@
'menu-item',
'm-1 px-3 py-2',
'flex items-center gap-2',
centered ? 'justify-center' : 'justify-between',
className,
)}
class:disabled
class:hoverable
class:justify-center={centered}
aria-hidden={disabled ? 'true' : 'false'}
aria-disabled={disabled}
tabindex={disabled ? -1 : 0}
Expand All @@ -142,7 +142,12 @@
on:keydown|stopPropagation={handleKeydown}
{...$$restProps}
>
<slot />
<div>
<slot />
</div>
{#if newTab}
<Icon height={20} width={20} name="external-link" slot="trailing" />
{/if}
</a>
{:else}
<li
Expand Down Expand Up @@ -187,7 +192,7 @@

<style lang="postcss">
.menu-item {
@apply cursor-pointer border border-transparent text-sm font-medium focus-visible:border-inverse focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/70 dark:focus-visible:border-interactive;
@apply cursor-pointer border border-transparent text-sm focus-visible:border-inverse focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/70 dark:focus-visible:border-interactive;

&.hoverable {
@apply hover:surface-interactive-secondary focus-visible:surface-interactive-secondary;
Expand Down
17 changes: 14 additions & 3 deletions src/lib/holocene/toggle-button/toggle-buttons.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
<script lang="ts">
import { setContext } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';

import { setContext, type Snippet } from 'svelte';
import { type ClassNameValue, twMerge } from 'tailwind-merge';

setContext<boolean>('group', true);

interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
class?: ClassNameValue;
children: Snippet;
}

let { class: className = '', children, ...rest }: Props = $props();
</script>

<div class="flex">
<slot />
<div class={twMerge('flex', className)} {...rest}>
{@render children()}
</div>
64 changes: 56 additions & 8 deletions src/lib/holocene/user-menu.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import DarkModeMenu from '$lib/components/dark-mode-menu.svelte';
import {
Menu,
MenuButton,
Expand All @@ -9,6 +10,7 @@
import { authUser } from '$lib/stores/auth-user';

import Icon from './icon/icon.svelte';
import MenuDivider from './menu/menu-divider.svelte';

export let logout: () => void;

Expand All @@ -19,9 +21,14 @@
}
</script>

{#if $authUser.accessToken}
<MenuContainer>
<MenuButton variant="ghost" hasIndicator controls="user-menu">
<MenuContainer>
<MenuButton
variant="ghost"
hasIndicator
data-testid="user-menu-trigger"
controls="user-menu"
>
{#if $authUser.accessToken}
<img
src={$authUser?.picture}
alt={$authUser?.profile ?? translate('common.user-profile')}
Expand All @@ -39,8 +46,16 @@
</div>
{/if}
</div>
</MenuButton>
<Menu id="user-menu" position="right">
{:else}
<img
src="/ziggy-full-face.png"
alt={translate('common.user-profile')}
class="h-[24px] w-[24px]"
/>
{/if}
</MenuButton>
<Menu id="user-menu" position="right" class="w-60">
{#if $authUser.accessToken}
<MenuItem hoverable={false}>
<div class="flex items-center justify-start gap-4">
<Icon name="astronaut" />
Expand All @@ -53,6 +68,39 @@
{translate('common.log-out')}
</div>
</MenuItem>
</Menu>
</MenuContainer>
{/if}
<MenuDivider />
{:else}
<MenuItem disabled>Anonymous Tardigrade</MenuItem>
<MenuDivider />
{/if}
<MenuItem hoverable={false}>
{translate('common.theme')}
<DarkModeMenu />
</MenuItem>
<MenuDivider />
<MenuItem
hoverable={false}
class="text-subtle"
newTab
href="https://t.mp/slack"
>
{translate('common.slack-community')}
</MenuItem>
<MenuItem
hoverable={false}
class="text-subtle"
newTab
href="https://community.temporal.io/"
>
{translate('common.community-forum')}
</MenuItem>
<MenuItem
hoverable={false}
class="text-subtle"
newTab
href="https://temporal.io/change-log"
>
{translate('common.change-log')}
</MenuItem>
</Menu>
</MenuContainer>
4 changes: 4 additions & 0 deletions src/lib/i18n/locales/en/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,8 @@ export const Strings = {
'Unable to complete operation after {{attempts}} attempts.',
'retry-support-message':
'Please refresh the page or contact support if the problem persists.',
theme: 'Theme',
'slack-community': 'Slack Community',
'community-forum': 'Community Forum',
'change-log': 'Change Log',
} as const;
Binary file added static/ziggy-full-face.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading