refactor: ♻️ Port all buttons to new UI library

This commit is contained in:
Jesse Wierzbinski 2024-06-27 14:09:05 -10:00
parent 13faf840dd
commit 091615b04e
No known key found for this signature in database
20 changed files with 120 additions and 155 deletions

View file

@ -1,23 +0,0 @@
<template>
<button v-bind="$props" type="button" :disabled="loading"
:class="['relative isolate text-base/6 font-semibold px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing.3)-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] sm:text-sm/6 focus:outline-none focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-[--btn-bg] before:absolute before:inset-0 before:-z-10 before:rounded-[calc(theme(borderRadius.lg)-1px)] before:shadow before:hidden after:absolute after:-z-10 after:-inset-px after:rounded-md before:disabled:shadow-none after:disabled:shadow-none text-white cursor-default rounded-md duration-200 hover:shadow disabled:opacity-70 content-none disabled:cursor-not-allowed shadow-sm bg-[--btn-bg] before:bg-[--btn-bg] after:active:bg-[--btn-hover-overlay] after:hover:bg-[--btn-hover-overlay]', loading && '[&>*]:invisible']">
<div v-if="loading" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 !visible size-5">
<iconify-icon icon="tabler:loader-2" height="none" class="animate-spin size-5" />
</div>
<slot />
</button>
</template>
<script lang="ts" setup>
import type { ButtonHTMLAttributes } from "vue";
interface Props extends /* @vue-ignore */ ButtonHTMLAttributes {}
defineProps<
Props & {
loading?: boolean;
}
>();
</script>
<style></style>

View file

@ -1,12 +1,12 @@
<template>
<ButtonBase
class="hover:bg-white/5 text-xs max-w-full w-full h-full !p-0">
<iconify-icon :icon="icon" class="size-6" width="none" />
<ButtonBase class="hover:bg-white/5 text-xs max-w-full w-full h-full !p-0">
<Icon :icon="icon" class="!size-6" />
</ButtonBase>
</template>
<script lang="ts" setup>
import ButtonBase from "~/packages/ui/components/buttons/button.vue";
import Icon from "~/packages/ui/components/icons/icon.vue";
defineProps<{
icon: string;

View file

@ -1,23 +0,0 @@
<template>
<ButtonBase
class="[--btn-border:theme(colors.primary.950/90%)] [--btn-bg:theme(colors.primary.600)] [--btn-hover-overlay:theme(colors.white/5%)] [--btn-icon:theme(colors.primary.400)] active:[--btn-icon:theme(colors.primary.300)] hover:[--btn-icon:theme(colors.primary.300)] after:shadow-[shadow:inset_0_1px_theme(colors.white/15%)] border border-white/5"
v-bind="$props">
<slot />
</ButtonBase>
</template>
<script lang="ts" setup>
import type { ButtonHTMLAttributes } from "vue";
import ButtonBase from "~/packages/ui/components/buttons/button.vue";
// import ButtonBase from "./button-base.vue";
interface Props extends /* @vue-ignore */ ButtonHTMLAttributes {}
defineProps<
Props & {
loading?: boolean;
}
>();
</script>
<style></style>

View file

@ -1,22 +0,0 @@
<template>
<ButtonBase
class="[--btn-border:theme(colors.zinc.950/90%)] [--btn-bg:theme(colors.zinc.800)] [--btn-hover-overlay:theme(colors.white/5%)] [--btn-icon:theme(colors.zinc.400)] active:[--btn-icon:theme(colors.zinc.300)] hover:[--btn-icon:theme(colors.zinc.300)] after:shadow-[shadow:inset_0_1px_theme(colors.white/15%)] border border-white/5"
v-bind="$props" :loading="loading">
<slot />
</ButtonBase>
</template>
<script lang="ts" setup>
import type { ButtonHTMLAttributes } from "vue";
import ButtonBase from "./button-base.vue";
interface Props extends /* @vue-ignore */ ButtonHTMLAttributes {}
defineProps<
Props & {
loading?: boolean;
}
>();
</script>
<style></style>

View file

@ -34,12 +34,12 @@
<Button title="Add content warning" @click="cw = !cw" :toggled="cw">
<iconify-icon width="1.25rem" height="1.25rem" icon="tabler:rating-18-plus" aria-hidden="true" />
</Button>
<ButtonPrimary :loading="loading" @click="send" class="ml-auto rounded-full"
<ButtonBase theme="primary" :loading="loading" @click="send" class="ml-auto rounded-full"
:disabled="!canSubmit || loading">
<span>{{
{{
respondingType === "edit" ? "Edit!" : "Send!"
}}</span>
</ButtonPrimary>
}}
</ButtonBase>
</div>
</div>
</template>
@ -47,8 +47,8 @@
<script lang="ts" setup>
import type { Instance, Status } from "@lysand-org/client/types";
import { nanoid } from "nanoid";
import ButtonBase from "~/packages/ui/components/buttons/button.vue";
import { OverlayScrollbarsComponent } from "#imports";
import ButtonPrimary from "../buttons/button-primary.vue";
import RichTextboxInput from "../inputs/rich-textbox-input.vue";
import Note from "../social-elements/notes/note.vue";
import Button from "./button.vue";

View file

@ -42,10 +42,10 @@
<textarea :disabled="data.progress < 1.0" @keydown.enter.stop v-model="data.alt_text"
placeholder="Add alt text"
class="w-full p-2 text-sm prose prose-invert bg-dark-900 rounded focus:!ring-0 !ring-none !border-none !outline-none placeholder:text-zinc-500 appearance-none focus:!border-none focus:!outline-none" />
<ButtonSecondary @click="updateAltText(data.id, data.alt_text)" class="w-full"
<Button theme="secondary" @click="updateAltText(data.id, data.alt_text)" class="w-full"
:loading="data.progress < 1.0">
<span>Edit</span>
</ButtonSecondary>
</Button>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
@ -57,7 +57,7 @@
<script lang="ts" setup>
import { Popover } from "@ark-ui/vue";
import { nanoid } from "nanoid";
import ButtonSecondary from "../buttons/button-secondary.vue";
import Button from "~/packages/ui/components/buttons/button.vue";
const files = defineModel<
{

View file

@ -1,15 +1,14 @@
<template>
<slot name="error" v-if="error" v-bind="{ error }">
<div id="error" class="grid min-h-screen place-items-center px-6 py-24 sm:py-32 lg:px-8">
<div class="text-center prose prose-invert">
<p class="text-base font-semibold text-primary-400">404</p>
<div class="text-center prose prose-invert max-w-md w-full">
<h1 class="mt-4 text-3xl font-bold tracking-tight text-gray-100 sm:text-5xl">{{ error.title }}
</h1>
<p class="mt-6 text-base leading-7 text-gray-400" v-html="error.message"></p>
<div class="mt-10 grid grid-cols-2 gap-x-6 mx-auto max-w-md">
<ButtonPrimary class="w-full" @click="back">Go back</ButtonPrimary>
<Button theme="primary" class="w-full" @click="back">Go back</Button>
<a href="https://github.com/lysand-org/lysand-fe/issues" target="_blank">
<ButtonSecondary class="w-full">Report an issue</ButtonSecondary>
<Button theme="secondary" class="w-full">Report an issue</Button>
</a>
</div>
</div>
@ -19,8 +18,7 @@
</template>
<script lang="ts" setup>
import ButtonPrimary from "../buttons/button-primary.vue";
import ButtonSecondary from "../buttons/button-secondary.vue";
import Button from "~/packages/ui/components/buttons/button.vue";
const error = ref<{
title: string;

View file

@ -13,13 +13,13 @@
<span class="font-semibold text-gray-300">{{ provider.name }}</span>
</div>
<div>
<ButtonPrimary :loading="loading" v-if="!linkedProviders?.find(p => p.id === provider.id)"
@click="link(provider.id)">
<span>Link</span>
</ButtonPrimary>
<ButtonSecondary :loading="loading" v-else @click="unlink(provider.id)">
<span>Unlink</span>
</ButtonSecondary>
<Button theme="primary" :loading="loading"
v-if="!linkedProviders?.find(p => p.id === provider.id)" @click="link(provider.id)">
Link
</Button>
<Button theme="secondary" :loading="loading" v-else @click="unlink(provider.id)">
Unlink
</Button>
</div>
</div>
</div>
@ -29,9 +29,8 @@
<script lang="ts" setup>
import type { ResponseError } from "@lysand-org/client";
import Button from "~/packages/ui/components/buttons/button.vue";
import Avatar from "../avatars/avatar.vue";
import ButtonPrimary from "../buttons/button-primary.vue";
import ButtonSecondary from "../buttons/button-secondary.vue";
const client = useClient();
const ssoConfig = useSSOConfig();

View file

@ -30,12 +30,12 @@
</div>
<div class="px-4 mt-4 grid grid-cols-2 gap-2">
<ButtonPrimary class="w-full" type="submit" :loading="loading">
<Button theme="primary" class="w-full" type="submit" :loading="loading">
<span>Save</span>
</ButtonPrimary>
<ButtonSecondary class="w-full" @click="revert" type="button" :loading="loading">
</Button>
<Button theme="secondary" class="w-full" @click="revert" type="button" :loading="loading">
<span>Revert</span>
</ButtonSecondary>
</Button>
</div>
</form>
<div>
@ -46,9 +46,8 @@
<script lang="ts" setup>
import type { ResponseError } from "@lysand-org/client";
import Button from "~/packages/ui/components/buttons/button.vue";
import Avatar from "../avatars/avatar.vue";
import ButtonPrimary from "../buttons/button-primary.vue";
import ButtonSecondary from "../buttons/button-secondary.vue";
import RichTextboxInput from "../inputs/rich-textbox-input.vue";
import TextInput from "../inputs/text-input.vue";
import Oidc from "./oidc.vue";

View file

@ -20,7 +20,7 @@
</span>
</div>
</div>
<ButtonBase theme="secondary" v-else class="w-full !justify-start">
<ButtonBase theme="secondary" v-else class="w-full !justify-start overflow-hidden">
<Icon icon="tabler:login" class="!size-6" />
<span class="shrink-0 line-clamp-1">Sign In</span>
</ButtonBase>
@ -61,21 +61,21 @@
</Menu.Item>
<Menu.Item value="" v-if="currentIdentity">
<NuxtLink href="/settings" class="w-full">
<ButtonBase theme="secondary" class="w-full !justify-start">
<ButtonBase theme="outline" class="w-full !justify-start">
<Icon icon="tabler:adjustments" class="!size-6" />
<span class="shrink-0 line-clamp-1">Settings</span>
</ButtonBase>
</NuxtLink>
</Menu.Item>
<Menu.Item value="">
<ButtonBase @click="$emit('signIn')" theme="secondary" class="w-full !justify-start">
<ButtonBase @click="$emit('signIn')" theme="outline" class="w-full !justify-start">
<Icon icon="tabler:user-plus" class="!size-6" />
<span class="shrink-0 line-clamp-1">Add new account</span>
</ButtonBase>
</Menu.Item>
<Menu.Item value="" v-if="!currentIdentity">
<NuxtLink href="/register" class="w-full">
<ButtonBase theme="secondary" class="w-full !justify-start">
<ButtonBase theme="outline" class="w-full !justify-start">
<Icon icon="tabler:certificate" class="!size-6" />
<span class="shrink-0 line-clamp-1">Create new account</span>
</ButtonBase>

View file

@ -12,7 +12,7 @@
Timelines</h3>
<NuxtLink v-for="timeline in visibleTimelines" :key="timeline.href" :to="timeline.href">
<ButtonBase theme="secondary" class="w-full !justify-start">
<ButtonBase theme="outline" class="w-full !justify-start overflow-hidden rounded-sm">
<Icon :icon="timeline.icon" class="!size-6" />
<span class="shrink-0 line-clamp-1">{{ timeline.name }}</span>
</ButtonBase>
@ -27,13 +27,13 @@
<AccountPicker @sign-in="signIn().finally(() => loadingAuth = false)"
@sign-out="id => signOut(id).finally(() => loadingAuth = false)" />
<NuxtLink href="/register" v-if="!identity">
<ButtonBase theme="secondary" class="w-full !justify-start">
<ButtonBase theme="outline" class="w-full !justify-start overflow-hidden rounded-sm">
<Icon icon="tabler:certificate" class="!size-6" />
<span class="shrink-0 line-clamp-1">Register</span>
</ButtonBase>
</NuxtLink>
<NuxtLink href="/settings" v-if="identity">
<ButtonBase @click="$emit('signIn')" theme="secondary" class="w-full !justify-start">
<ButtonBase @click="$emit('signIn')" theme="secondary" class="w-full !justify-start overflow-hidden">
<Icon icon="tabler:adjustments" class="!size-6" />
<span class="shrink-0 line-clamp-1">Settings</span>
</ButtonBase>
@ -41,7 +41,8 @@
<h3 v-if="identity"
class="font-semibold text-gray-300 text-xs uppercase opacity-0 group-hover:opacity-100 duration-200">
Posts</h3>
<ButtonBase v-if="identity" @click="compose" title="Open composer (shortcut: n)" theme="gradient" class="!justify-start">
<ButtonBase v-if="identity" @click="compose" title="Open composer (shortcut: n)" theme="gradient"
class="!justify-start overflow-hidden">
<Icon icon="tabler:writing" class="!size-6" />
<span class="shrink-0 line-clamp-1">Compose</span>
<kbd class="text-xs font-semibold rounded bg-dark-500 font-mono px-1 flex flex-row ml-auto">
@ -50,7 +51,8 @@
aria-hidden="true" />
</kbd>
</ButtonBase>
<ButtonBase v-if="$pwa?.needRefresh" @click="$pwa?.updateServiceWorker()" title="Update service worker" theme="primary" class="w-full !justify-start">
<ButtonBase v-if="$pwa?.needRefresh" @click="$pwa?.updateServiceWorker()" title="Update service worker"
theme="primary" class="w-full !justify-start overflow-hidden">
<Icon icon="tabler:refresh" class="!size-6" />
<span class="shrink-0 line-clamp-1">Update</span>
</ButtonBase>

View file

@ -20,14 +20,14 @@
<!-- Spoiler text is it's specified -->
<span v-if="note?.spoiler_text" class="mt-2 break-all">{{ note.spoiler_text
}}</span>
<ButtonSecondary @click="collapsed = false" class="mt-4">Show content</ButtonSecondary>
<Button theme="secondary" @click="collapsed = false" class="mt-4">Show content</Button>
</div>
</template>
<script lang="ts" setup>
import type { Status } from "@lysand-org/client/types";
import ButtonSecondary from "~/components/buttons/button-secondary.vue";
import Skeleton from "~/components/skeleton/Skeleton.vue";
import Button from "~/packages/ui/components/buttons/button.vue";
import Attachment from "./attachment.vue";
import Note from "./note.vue";

View file

@ -18,10 +18,12 @@
</div>
<div v-if="notification?.type === 'follow_request' && relationship?.requested_by"
class="w-full grid grid-cols-2 gap-4 p-2 ">
<ButtonPrimary :loading="isWorkingOnFollowRequest" @click="acceptFollowRequest"><span>Accept</span>
</ButtonPrimary>
<ButtonSecondary :loading="isWorkingOnFollowRequest" @click="rejectFollowRequest"><span>Reject</span>
</ButtonSecondary>
<Button theme="primary" :loading="isWorkingOnFollowRequest"
@click="acceptFollowRequest"><span>Accept</span>
</Button>
<Button theme="secondary" :loading="isWorkingOnFollowRequest"
@click="rejectFollowRequest"><span>Reject</span>
</Button>
</div>
</div>
</div>
@ -30,9 +32,8 @@
<script lang="ts" setup>
import type { Notification } from "@lysand-org/client/types";
import Avatar from "~/components/avatars/avatar.vue";
import ButtonPrimary from "~/components/buttons/button-primary.vue";
import ButtonSecondary from "~/components/buttons/button-secondary.vue";
import Skeleton from "~/components/skeleton/Skeleton.vue";
import Button from "~/packages/ui/components/buttons/button.vue";
import Note from "../notes/note.vue";
import SmallCard from "../users/SmallCard.vue";

View file

@ -7,20 +7,20 @@
<Avatar :src="account?.avatar" :alt="`${account?.acct}'s avatar'`"
class="h-32 w-32 -mt-[4.5rem] z-10 shrink-0 rounded ring-2 ring-dark-800" />
<ButtonSecondary v-if="account && account?.id === identity?.account?.id">Edit Profile
</ButtonSecondary>
<ButtonSecondary :loading="isLoading" @click="follow()"
<Button theme="secondary" v-if="account && account?.id === identity?.account?.id">Edit Profile
</Button>
<Button theme="secondary" :loading="isLoading" @click="follow()"
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && !relationship.requested">
<span>Follow</span>
</ButtonSecondary>
<ButtonSecondary :loading="isLoading" @click="unfollow()"
</Button>
<Button theme="secondary" :loading="isLoading" @click="unfollow()"
v-if="account && account?.id !== identity?.account?.id && relationship && relationship.following">
<span>Unfollow</span>
</ButtonSecondary>
<ButtonSecondary :loading="isLoading" :disabled="true"
</Button>
<Button theme="secondary" :loading="isLoading" :disabled="true"
v-if="account && account?.id !== identity?.account?.id && relationship && !relationship.following && relationship.requested">
<span>Requested</span>
</ButtonSecondary>
</Button>
</div>
<div class="mt-2 px-4">
@ -100,8 +100,8 @@
<script lang="ts" setup>
import type { Account } from "@lysand-org/client/types";
import Avatar from "~/components/avatars/avatar.vue";
import ButtonSecondary from "~/components/buttons/button-secondary.vue";
import Skeleton from "~/components/skeleton/Skeleton.vue";
import Button from "~/packages/ui/components/buttons/button.vue";
import Badge from "./Badge.vue";
const props = defineProps<{