Skip to content

Commit d06ec6f

Browse files
author
mdatelle
committed
refactor: simplify Button component and begin BrandButton swap out.
1 parent c4df56c commit d06ec6f

File tree

15 files changed

+151
-107
lines changed

15 files changed

+151
-107
lines changed

unraid-ui/src/components/common/badge/badge.variants.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,8 @@ export const badgeVariants = cva(
88
red: 'bg-unraid-red text-white hover:bg-orange-dark',
99
yellow: 'bg-yellow-100 text-black hover:bg-yellow-200',
1010
green: 'bg-green-200 text-green-800 hover:bg-green-300',
11-
blue: 'bg-blue-100 text-blue-800 hover:bg-blue-200',
12-
indigo: 'bg-indigo-100 text-indigo-800 hover:bg-indigo-200',
13-
purple: 'bg-purple-100 text-purple-800 hover:bg-purple-200',
14-
pink: 'bg-pink-100 text-pink-800 hover:bg-pink-200',
1511
orange: 'bg-orange text-white hover:bg-orange-dark',
16-
black: 'bg-black text-white hover:bg-gray-800',
17-
white: 'bg-white text-black hover:bg-gray-100',
1812
transparent: 'bg-transparent text-black hover:bg-gray-100',
19-
current: 'bg-current text-current hover:bg-gray-100',
2013
gray: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
2114
custom: '',
2215
},

unraid-ui/src/components/common/button/Button.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface ButtonProps {
77
variant?: ButtonVariants['variant'];
88
size?: ButtonVariants['size'];
99
class?: string;
10+
icon?: any;
1011
}
1112
1213
const props = withDefaults(defineProps<ButtonProps>(), {
@@ -21,6 +22,7 @@ const buttonClass = computed(() => {
2122

2223
<template>
2324
<button :class="buttonClass">
25+
<component :is="icon" v-if="icon" class="w-4 h-4" />
2426
<slot />
2527
</button>
2628
</template>

unraid-ui/src/components/common/button/button.variants.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
import { cva, type VariantProps } from 'class-variance-authority';
22

33
export const buttonVariants = cva(
4-
'inline-flex items-center justify-center rounded-md text-base font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
4+
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
55
{
66
variants: {
77
variant: {
8-
primary: 'bg-primary text-primary-foreground hover:bg-primary/90',
9-
brand:
8+
primary:
109
'bg-gradient-to-r from-unraid-red to-orange text-white opacity-100 transition-all hover:opacity-60 focus:opacity-60',
11-
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
12-
outline:
13-
'border border-input border-2 bg-transparent hover:bg-accent hover:text-accent-foreground',
14-
'outline-brand':
10+
secondary:
1511
'text-orange bg-transparent border-orange border-2 hover:text-white focus:text-white hover:bg-gradient-to-r hover:from-unraid-red hover:to-orange hover:text-white hover:bg-gradient-to-r hover:from-unraid-red hover:to-orange transition-[background,color,opacity] duration-300 ease-in-out rounded-md hover:opacity-100 focus:opacity-100',
16-
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
17-
ghost: 'hover:bg-accent hover:text-accent-foreground',
18-
link: 'text-primary underline-offset-4 hover:underline',
12+
link: 'text-black underline-offset-4 hover:underline',
1913
},
2014
size: {
2115
sm: 'h-9 rounded-md px-3',

unraid-ui/stories/components/common/Button.stories.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import type { Meta, StoryObj } from "@storybook/vue3";
2-
import ButtonComponent from "../../../src/components/common/button/Button.vue";
1+
import { ArrowDownTrayIcon, KeyIcon, RocketLaunchIcon } from '@heroicons/vue/24/outline';
2+
import type { Meta, StoryObj } from '@storybook/vue3';
3+
import ButtonComponent from '../../../src/components/common/button/Button.vue';
34

45
const meta = {
5-
title: "Components/Common",
6+
title: 'Components/Common/Button',
67
component: ButtonComponent,
8+
tags: ['autodocs'],
79
} satisfies Meta<typeof ButtonComponent>;
810

911
export default meta;
@@ -12,9 +14,9 @@ type Story = StoryObj<typeof meta>;
1214

1315
export const Button: Story = {
1416
args: {
15-
variant: "primary",
16-
size: "md",
17-
default: "Click me",
17+
variant: 'primary',
18+
size: 'md',
19+
default: 'Click me',
1820
},
1921
render: (args) => ({
2022
components: { ButtonComponent },
@@ -32,3 +34,51 @@ export const Button: Story = {
3234
`,
3335
}),
3436
};
37+
38+
export const ButtonLeftIcon: Story = {
39+
args: {
40+
variant: 'primary',
41+
size: 'md',
42+
default: 'Click me',
43+
icon: ArrowDownTrayIcon,
44+
},
45+
render: (args) => ({
46+
components: { ButtonComponent },
47+
setup() {
48+
return { args };
49+
},
50+
template: `
51+
<ButtonComponent
52+
:variant="args.variant"
53+
:size="args.size"
54+
:class="args.class"
55+
:icon="args.icon"
56+
>
57+
{{ args.default }}
58+
</ButtonComponent>
59+
`,
60+
}),
61+
};
62+
63+
export const ButtonIcon: Story = {
64+
args: {
65+
variant: 'primary',
66+
size: 'icon',
67+
default: '',
68+
},
69+
render: (args) => ({
70+
components: { ButtonComponent, RocketLaunchIcon },
71+
setup() {
72+
return { args };
73+
},
74+
template: `
75+
<ButtonComponent
76+
:variant="args.variant"
77+
:size="args.size"
78+
:class="args.class"
79+
>
80+
<RocketLaunchIcon class="w-4 h-4" />
81+
</ButtonComponent>
82+
`,
83+
}),
84+
};

web/components/Activation/Modal.vue

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import { storeToRefs } from 'pinia';
33
44
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/solid';
5-
import { BrandButton } from '@unraid/ui';
5+
import { Button } from '@unraid/ui';
66
7-
import type { BrandButtonProps } from '@unraid/ui';
7+
import type { ButtonProps } from '@unraid/ui';
88
import type { ComposerTranslation } from 'vue-i18n';
99
1010
import ActivationPartnerLogo from '~/components/Activation/PartnerLogo.vue';
@@ -24,25 +24,25 @@ const purchaseStore = usePurchaseStore();
2424
const title = computed<string>(() => props.t("Let's activate your Unraid OS License"));
2525
const description = computed<string>(() =>
2626
props.t(
27-
`On the following screen, your license will be activated. Youll then create an Unraid.net Account to manage your license going forward.`
27+
`On the following screen, your license will be activated. You'll then create an Unraid.net Account to manage your license going forward.`
2828
)
2929
);
30-
const docsButtons = computed<BrandButtonProps[]>(() => {
30+
const docsButtons = computed<ButtonProps[]>(() => {
3131
return [
3232
{
33-
variant: 'underline',
33+
variant: 'link',
3434
external: true,
3535
href: 'https://docs.unraid.net/unraid-os/faq/licensing-faq/',
3636
iconRight: ArrowTopRightOnSquareIcon,
37-
size: '14px',
37+
size: 'md',
3838
text: props.t('More about Licensing'),
3939
},
4040
{
41-
variant: 'underline',
41+
variant: 'link',
4242
external: true,
4343
href: 'https://docs.unraid.net/account/',
4444
iconRight: ArrowTopRightOnSquareIcon,
45-
size: '14px',
45+
size: 'md',
4646
text: props.t('More about Unraid.net Accounts'),
4747
},
4848
];
@@ -74,7 +74,7 @@ const handleKeydown = (event: KeyboardEvent) => {
7474
7575
if (sequenceIndex === keySequence.length) {
7676
activationCodeStore.setActivationModalHidden(true);
77-
window.location.href = '/Tools/Registration';
77+
window.location.href = '/Tools/Registration';
7878
}
7979
};
8080
@@ -108,11 +108,9 @@ onUnmounted(() => {
108108

109109
<template #footer>
110110
<div class="w-full flex gap-8px justify-center mx-auto">
111-
<BrandButton
112-
:text="t('Activate Now')"
113-
:icon-right="ArrowTopRightOnSquareIcon"
114-
@click="purchaseStore.activate"
115-
/>
111+
<Button :icon="ArrowTopRightOnSquareIcon" @click="purchaseStore.activate">{{
112+
t('Activate Now')
113+
}}</Button>
116114
</div>
117115
</template>
118116

@@ -121,7 +119,7 @@ onUnmounted(() => {
121119
<ActivationSteps :active-step="2" class="hidden sm:flex mt-6" />
122120

123121
<div class="flex flex-col sm:flex-row justify-center gap-4 mx-auto w-full">
124-
<BrandButton v-for="button in docsButtons" :key="button.text" v-bind="button" />
122+
<Button v-for="(button, index) in docsButtons" :key="index" v-bind="button"></Button>
125123
</div>
126124
</div>
127125
</template>

web/components/Auth.ce.vue

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<script lang="ts" setup>
2-
import { BrandButton } from '@unraid/ui';
3-
import { useServerStore } from '~/store/server';
4-
import { storeToRefs } from 'pinia';
52
import { useI18n } from 'vue-i18n';
3+
import { storeToRefs } from 'pinia';
4+
5+
import { Button } from '@unraid/ui';
6+
7+
import { useServerStore } from '~/store/server';
68
79
const { t } = useI18n();
810
@@ -17,14 +19,16 @@ const { authAction, stateData } = storeToRefs(serverStore);
1719
<span class="text-14px" v-html="t(stateData.message)" />
1820
</span>
1921
<span v-if="authAction">
20-
<BrandButton
22+
<Button
23+
variant="brand"
2124
:disabled="authAction?.disabled"
2225
:icon="authAction.icon"
23-
size="12px"
24-
:text="t(authAction.text)"
26+
size="md"
2527
:title="authAction?.title ? t(authAction?.title) : undefined"
2628
@click="authAction.click?.()"
27-
/>
29+
>
30+
{{ t(authAction.text) }}
31+
</Button>
2832
</span>
2933
</div>
3034
</template>

web/components/ConnectSettings/AllowedOrigins.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts" setup>
2-
import { BrandButton, Input } from '@unraid/ui';
2+
import { Button, Input } from '@unraid/ui';
33
44
import { useUnraidApiSettingsStore } from '~/store/unraidApiSettings';
55
@@ -42,8 +42,7 @@ const setAllowedOrigins = () => {
4242
type="text"
4343
placeholder="https://abc.myreverseproxy.com,https://xyz.rvrsprx.com"
4444
/>
45-
<BrandButton type="button" variant="outline" text="Apply" @click="setAllowedOrigins()">
46-
</BrandButton>
45+
<Button type="button" variant="secondary" @click="setAllowedOrigins()">Apply</Button>
4746
<div v-for="(error, index) of errors" :key="index">
4847
<p>{{ error }}</p>
4948
</div>

web/components/ConnectSettings/ConnectSettings.ce.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
import { useMutation, useQuery } from '@vue/apollo-composable';
77
8-
import { BrandButton, jsonFormsRenderers, Label } from '@unraid/ui';
8+
import { Button, jsonFormsRenderers, Label } from '@unraid/ui';
99
import { JsonForms } from '@jsonforms/vue';
1010
1111
import type { ConnectSettingsValues } from '~/composables/gql/graphql';
@@ -119,15 +119,15 @@ const onChange = ({ data }: { data: Record<string, unknown> }) => {
119119
<p v-else-if="restartRequired">The API will restart after settings are applied.</p>
120120
</div>
121121
<div class="col-start-2 ml-10 space-y-4">
122-
<BrandButton
123-
variant="outline-primary"
122+
<Button
123+
variant="outline-brand"
124124
padding="lean"
125-
size="12px"
125+
size="md"
126126
class="leading-normal"
127127
@click="submitSettingsUpdate"
128128
>
129129
Apply
130-
</BrandButton>
130+
</Button>
131131
<p v-if="mutateSettingsError" class="text-sm text-unraid-red-500">
132132
✕ Error: {{ mutateSettingsError.message }}
133133
</p>

web/components/DownloadApiLogs.ce.vue

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script setup lang="ts">
2+
import { useI18n } from 'vue-i18n';
3+
24
import { ArrowDownTrayIcon, ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/solid';
3-
import { BrandButton } from '@unraid/ui';
5+
import { Button } from '@unraid/ui';
46
import { CONNECT_FORUMS, CONTACT, DISCORD, WEBGUI_GRAPHQL } from '~/helpers/urls';
5-
import { useI18n } from 'vue-i18n';
67
78
const { t } = useI18n();
89
@@ -26,15 +27,16 @@ const downloadUrl = computed(() => {
2627
</span>
2728
<span class="flex flex-col gap-y-16px">
2829
<div class="flex">
29-
<BrandButton
30+
<Button
31+
variant="brand"
3032
class="grow-0 shrink-0"
3133
download
3234
:external="true"
3335
:href="downloadUrl.toString()"
3436
:icon="ArrowDownTrayIcon"
35-
size="12px"
36-
:text="t('Download unraid-api Logs')"
37-
/>
37+
size="md"
38+
>{{ t('Download unraid-api Logs') }}</Button
39+
>
3840
</div>
3941

4042
<div class="flex flex-row items-baseline gap-8px">

web/components/KeyActions.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { storeToRefs } from 'pinia';
33
44
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/solid';
5-
import { BrandButton, cn } from '@unraid/ui';
5+
import { Button, cn } from '@unraid/ui';
66
77
import type { ServerStateDataAction } from '~/types/server';
88
import type { ComposerTranslation } from 'vue-i18n';
@@ -47,18 +47,19 @@ const filteredKeyActions = computed((): ServerStateDataAction[] | undefined => {
4747
<template>
4848
<ul v-if="filteredKeyActions" class="flex flex-col gap-y-8px">
4949
<li v-for="action in filteredKeyActions" :key="action.name">
50-
<BrandButton
50+
<Button
5151
:class="cn('w-full', props.maxWidth ? 'sm:max-w-300px' : '')"
5252
:disabled="action?.disabled"
5353
:external="action?.external"
5454
:href="action?.href"
5555
:icon="action.icon"
5656
:icon-right="ArrowTopRightOnSquareIcon"
5757
:icon-right-hover-display="true"
58-
:text="t(action.text)"
5958
:title="action.title ? t(action.title) : undefined"
6059
@click="action.click?.()"
61-
/>
60+
>
61+
{{ t(action.text) }}
62+
</Button>
6263
</li>
6364
</ul>
6465
</template>

0 commit comments

Comments
 (0)