mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
add outline and secondary variants to TimeTrackerStartStop button to reduce visual complexity
This commit is contained in:
@@ -53,7 +53,7 @@ test('test that starting and stopping an empty time entry shows a new time entry
|
||||
// Test that description update works
|
||||
|
||||
async function assertThatTimeEntryRowIsStopped(newTimeEntry: Locator) {
|
||||
await expect(newTimeEntry.getByTestId('timer_button')).toHaveClass(/bg-accent-300\/70/);
|
||||
await expect(newTimeEntry.getByTestId('timer_button')).toHaveClass(/bg-tertiary/);
|
||||
}
|
||||
|
||||
test('test that updating a description of a time entry in the overview works on blur', async ({
|
||||
@@ -224,7 +224,7 @@ test('test that starting a time entry from the overview works', async ({ page })
|
||||
|
||||
const newTimeEntry = timeEntryRows.first();
|
||||
const startButton = newTimeEntry.getByTestId('timer_button');
|
||||
await expect(startButton).toHaveClass(/bg-accent-300\/70/);
|
||||
await expect(startButton).toHaveClass(/bg-tertiary/);
|
||||
|
||||
await Promise.all([
|
||||
page.waitForResponse(async (response) => {
|
||||
|
||||
@@ -51,6 +51,7 @@ const isRunningInDifferentOrganization = computed(() => {
|
||||
<TimeTrackerStartStop
|
||||
:active="isActive"
|
||||
size="base"
|
||||
variant="outline"
|
||||
@changed="setActiveState"></TimeTrackerStartStop>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -66,7 +66,9 @@ async function startTaskTimer() {
|
||||
</ProjectBadge>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<TimeTrackerStartStop @changed="startTaskTimer"></TimeTrackerStartStop>
|
||||
<TimeTrackerStartStop
|
||||
variant="outline"
|
||||
@changed="startTaskTimer"></TimeTrackerStartStop>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -163,7 +163,8 @@ async function handleDeleteTimeEntry() {
|
||||
@changed="updateStartEndTime"></TimeEntryRowDurationInput>
|
||||
<TimeTrackerStartStop
|
||||
:active="!!(timeEntry.start && !timeEntry.end)"
|
||||
class="opacity-20 flex focus-visible:opacity-100 group-hover:opacity-100"
|
||||
variant="secondary"
|
||||
class="opacity-60 flex focus-visible:opacity-100 group-hover:opacity-100"
|
||||
@changed="onStartStopClick"></TimeTrackerStartStop>
|
||||
<TimeEntryMoreOptionsDropdown
|
||||
@edit="handleEdit"
|
||||
|
||||
@@ -1,38 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import { computed } from 'vue';
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
import { cn } from './utils/cn';
|
||||
|
||||
const timeTrackerVariants = cva(
|
||||
'flex items-center justify-center transition focus:outline-0 rounded-full',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
primary:
|
||||
'text-white ring-accent-200/10 focus-visible:ring-ring focus-visible:ring-2 ring-4 sm:ring-[6px]',
|
||||
secondary:
|
||||
'bg-tertiary text-text-tertiary hover:text-text-primary focus:ring-2 focus:ring-border-tertiary',
|
||||
outline:
|
||||
'border border-border-primary text-text-tertiary hover:text-text-primary hover:bg-tertiary/50',
|
||||
},
|
||||
size: {
|
||||
small: 'w-6 h-6',
|
||||
base: 'w-9 h-9 hover:scale-110',
|
||||
large: 'w-11 h-11 hover:scale-110',
|
||||
},
|
||||
active: {
|
||||
true: '',
|
||||
false: '',
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
variant: 'primary',
|
||||
active: true,
|
||||
class: 'bg-red-400/80 hover:bg-red-500/80 focus:bg-red-500/80',
|
||||
},
|
||||
{
|
||||
variant: 'primary',
|
||||
active: false,
|
||||
class: 'bg-accent-300/70 hover:bg-accent-400/70 focus:bg-accent-700',
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
variant: 'primary',
|
||||
size: 'base',
|
||||
active: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
type TimeTrackerVariants = VariantProps<typeof timeTrackerVariants>;
|
||||
|
||||
const emit = defineEmits(['changed']);
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
size?: 'base' | 'large' | 'small';
|
||||
variant?: TimeTrackerVariants['variant'];
|
||||
size?: TimeTrackerVariants['size'];
|
||||
active?: boolean;
|
||||
}>(),
|
||||
{
|
||||
variant: 'primary',
|
||||
size: 'base',
|
||||
active: false,
|
||||
}
|
||||
);
|
||||
const buttonSizeClasses = {
|
||||
small: 'w-6 h-6 bg-accent-200/40 hover:bg-accent-300/70',
|
||||
base: 'w-8 h-8 bg-accent-200/40 hover:scale-110 hover:bg-accent-300/70 ring-accent-200/10 focus-visible:ring-ring ring-4 hover:ring-4',
|
||||
large: 'w-11 h-11 ring-accent-200/10 focus-visible:ring-ring focus-visible:ring-2 ring-4 sm:ring-[6px] hover:scale-110',
|
||||
};
|
||||
|
||||
const iconClass = {
|
||||
small: 'w-2.5 h-2.5',
|
||||
base: 'w-3.5 h-3.5',
|
||||
base: 'w-3 h-3',
|
||||
large: 'w-4 h-4',
|
||||
};
|
||||
|
||||
const buttonColorClasses = computed(() => {
|
||||
if (props.active) {
|
||||
return 'bg-red-400/80 hover:bg-red-500/80 focus:bg-red-500/80';
|
||||
} else {
|
||||
return 'bg-accent-300/70 hover:bg-accent-400/70 focus:bg-accent-700';
|
||||
}
|
||||
});
|
||||
|
||||
function toggleState() {
|
||||
emit('changed', !props.active);
|
||||
}
|
||||
@@ -41,18 +75,12 @@ function toggleState() {
|
||||
<template>
|
||||
<button
|
||||
data-testid="timer_button"
|
||||
:class="
|
||||
twMerge(
|
||||
buttonSizeClasses[size],
|
||||
buttonColorClasses,
|
||||
'flex items-center justify-center py-1 transition focus:outline-0 rounded-full text-white '
|
||||
)
|
||||
"
|
||||
:class="cn(timeTrackerVariants({ variant, size, active }))"
|
||||
@click="toggleState">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<svg
|
||||
v-if="props.active"
|
||||
:class="iconClass[size]"
|
||||
:class="iconClass[size ?? 'base']"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -64,7 +92,7 @@ function toggleState() {
|
||||
</svg>
|
||||
<svg
|
||||
v-else
|
||||
:class="iconClass[size]"
|
||||
:class="iconClass[size ?? 'base']"
|
||||
viewBox="0 0 7 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
--color-bg-primary: oklch(0.14 0.0041 285.97);
|
||||
--color-bg-secondary: oklch(0.18 0.005 285.97);
|
||||
--color-bg-tertiary: oklch(0.22 0.0112 285.97);
|
||||
--color-bg-quaternary: oklch(0.175 0.005 285.97);
|
||||
--color-bg-quaternary: oklch(0.26 0.015 285.97);
|
||||
--color-bg-background: oklch(0.1 0 0);
|
||||
--color-text-primary: #ffffff;
|
||||
--color-text-secondary: #e3e4e6;
|
||||
|
||||
Reference in New Issue
Block a user