Skip to content

Commit 407585c

Browse files
mdatellemdatelle
andauthored
feat(web): install and configure nuxt ui (#1524)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a primary color palette and enhanced color theming for the UI. * Added and showcased new UI button variants with primary color styling on the main page. * Integrated the @nuxt/ui module to enable advanced UI components and theming options. * **Style** * Updated keyframe animations in global styles for improved CSS structure. * Refined color variables and UI color states for both light and dark modes. * **Chores** * Added @nuxt/ui as a project dependency. * Centralized UI configuration for easier theming management. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: mdatelle <[email protected]>
1 parent 05056e7 commit 407585c

File tree

8 files changed

+786
-50
lines changed

8 files changed

+786
-50
lines changed

pnpm-lock.yaml

Lines changed: 661 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unraid-ui/src/styles/globals.css

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
--color-unraid-green-900: #284126;
9999
--color-unraid-green-950: #122211;
100100

101-
102101
/* Header colors */
103102
--color-header-text-primary: var(--header-text-primary);
104103
--color-header-text-secondary: var(--header-text-secondary);
@@ -178,12 +177,6 @@
178177
--animate-mark-6: mark-6 1.5s ease infinite;
179178
--animate-mark-7: mark-7 1.5s ease infinite;
180179

181-
/* Keyframes */
182-
--keyframes-mark-2: 50% { transform: translateY(-40px) } to { transform: translateY(0) };
183-
--keyframes-mark-3: 50% { transform: translateY(-62px) } to { transform: translateY(0) };
184-
--keyframes-mark-6: 50% { transform: translateY(40px) } to { transform: translateY(0) };
185-
--keyframes-mark-7: 50% { transform: translateY(62px) } to { transform: translateY(0) };
186-
187180
/* Radius */
188181
--radius: 0.5rem;
189182

@@ -307,7 +300,45 @@
307300
}
308301
}
309302

303+
/* Keyframes */
304+
@keyframes mark-2 {
305+
50% {
306+
transform: translateY(-40px);
307+
}
308+
to {
309+
transform: translateY(0);
310+
}
311+
}
312+
313+
@keyframes mark-3 {
314+
50% {
315+
transform: translateY(-62px);
316+
}
317+
to {
318+
transform: translateY(0);
319+
}
320+
}
321+
322+
@keyframes mark-6 {
323+
50% {
324+
transform: translateY(40px);
325+
}
326+
to {
327+
transform: translateY(0);
328+
}
329+
}
330+
331+
@keyframes mark-7 {
332+
50% {
333+
transform: translateY(62px);
334+
}
335+
to {
336+
transform: translateY(0);
337+
}
338+
}
339+
310340
/* Define the theme colors that reference the existing CSS variables from web/themes */
341+
311342
@theme inline {
312343
--color-background: hsl(var(--background));
313344
--color-foreground: hsl(var(--foreground));

web/app.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
ui: {
3+
colors: {
4+
primary: 'primary',
5+
},
6+
},
7+
};

web/app.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<script lang="ts" setup>
22
import { onMounted } from 'vue';
3-
import { NuxtLayout, NuxtPage } from '#components';
3+
4+
import { NuxtLayout, NuxtPage, UApp } from '#components';
45
import { devConfig } from '~/helpers/env';
56
67
onMounted(() => {
78
document.documentElement.setAttribute('data-env', devConfig.NODE_ENV || 'production');
89
9-
1010
// Override text sizes back to 16px base in dev mode (from 10px base in globals.css)
1111
if (devConfig.NODE_ENV === 'development') {
1212
document.documentElement.style.setProperty('--text-xs', '0.75rem'); /* 12px */
@@ -28,7 +28,9 @@ onMounted(() => {
2828
</script>
2929

3030
<template>
31-
<NuxtLayout>
32-
<NuxtPage />
33-
</NuxtLayout>
31+
<UApp>
32+
<NuxtLayout>
33+
<NuxtPage />
34+
</NuxtLayout>
35+
</UApp>
3436
</template>

web/assets/main.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@import 'tailwindcss';
22
@import '@unraid/ui/styles';
3+
@import '@nuxt/ui';
34

45
/* Force generation of all color utilities for custom colors across packages */
56
@source inline("{bg,text,border,ring,fill,stroke}-{unraid-green,unraid-red}{,-50,-100,-200,-300,-400,-500,-600,-700,-800,-900,-950}");
@@ -11,6 +12,18 @@
1112
@custom-variant dark (&:where(.dark, .dark *));
1213

1314
@theme {
15+
--color-primary-50: #fff7ed;
16+
--color-primary-100: #ffedd5;
17+
--color-primary-200: #fed7aa;
18+
--color-primary-300: #fdba74;
19+
--color-primary-400: #fb923c;
20+
--color-primary-500: #ff6600;
21+
--color-primary-600: #ea580c;
22+
--color-primary-700: #c2410c;
23+
--color-primary-800: #9a3412;
24+
--color-primary-900: #7c2d12;
25+
--color-primary-950: #431407;
26+
1427
/* Header colors */
1528
--color-header-text-primary: var(--header-text-primary);
1629
--color-header-text-secondary: var(--header-text-secondary);
@@ -90,6 +103,18 @@
90103
border-color: hsl(var(--border));
91104
}
92105

106+
:root {
107+
--ui-primary: var(--color-primary-500);
108+
--ui-primary-hover: var(--color-primary-600);
109+
--ui-primary-active: var(--color-primary-700);
110+
}
111+
112+
.dark {
113+
--ui-primary: var(--color-primary-500);
114+
--ui-primary-hover: var(--color-primary-600);
115+
--ui-primary-active: var(--color-primary-700);
116+
}
117+
93118
body {
94119
--color-alpha: #1c1b1b;
95120
--color-beta: #f2f2f2;

web/nuxt.config.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import path from 'path';
22

3-
import removeConsole from 'vite-plugin-remove-console';
43
import tailwindcss from '@tailwindcss/vite';
4+
import removeConsole from 'vite-plugin-remove-console';
55

6-
import type { UserConfig, PluginOption } from 'vite';
6+
import type { PluginOption, UserConfig } from 'vite';
77

88
/**
99
* Used to avoid redeclaring variables in the webgui codebase.
@@ -49,10 +49,10 @@ const sharedTerserOptions = {
4949
*/
5050
const getSharedPlugins = (includeJQueryIsolation = false) => {
5151
const plugins: PluginOption[] = [];
52-
52+
5353
// Add Tailwind CSS plugin
5454
plugins.push(tailwindcss());
55-
55+
5656
// Remove console logs in production
5757
if (dropConsole) {
5858
plugins.push(
@@ -61,15 +61,15 @@ const getSharedPlugins = (includeJQueryIsolation = false) => {
6161
})
6262
);
6363
}
64-
64+
6565
// Add jQuery isolation plugin for custom elements
6666
if (includeJQueryIsolation) {
6767
plugins.push({
6868
name: 'jquery-isolation',
6969
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7070
generateBundle(options: any, bundle: any) {
7171
// Find the main JS file
72-
const jsFile = Object.keys(bundle).find(key => key.endsWith('.js'));
72+
const jsFile = Object.keys(bundle).find((key) => key.endsWith('.js'));
7373
if (jsFile && bundle[jsFile] && 'code' in bundle[jsFile]) {
7474
const originalCode = bundle[jsFile].code;
7575
// Wrap the entire bundle to preserve and restore jQuery
@@ -93,7 +93,7 @@ const getSharedPlugins = (includeJQueryIsolation = false) => {
9393
})();
9494
`;
9595
}
96-
}
96+
},
9797
});
9898
}
9999

@@ -115,17 +115,17 @@ const applySharedViteConfig = (config: UserConfig, includeJQueryIsolation = fals
115115
if (!config.plugins) config.plugins = [];
116116
if (!config.define) config.define = {};
117117
if (!config.build) config.build = {};
118-
118+
119119
// Add shared plugins
120120
config.plugins.push(...getSharedPlugins(includeJQueryIsolation));
121-
121+
122122
// Merge define values
123123
Object.assign(config.define, sharedDefine);
124-
124+
125125
// Apply build configuration
126126
config.build.minify = 'terser';
127127
config.build.terserOptions = sharedTerserOptions;
128-
128+
129129
return config;
130130
};
131131

@@ -143,20 +143,19 @@ export default defineNuxtConfig({
143143
port: 4321,
144144
},
145145

146-
css: [
147-
'@/assets/main.css',
148-
],
146+
css: ['@/assets/main.css'],
149147

150148
devtools: {
151149
enabled: process.env.NODE_ENV === 'development',
152150
},
153151

154-
modules: [
155-
'@vueuse/nuxt',
156-
'@pinia/nuxt',
157-
'nuxt-custom-elements',
158-
'@nuxt/eslint',
159-
],
152+
modules: ['@vueuse/nuxt', '@pinia/nuxt', 'nuxt-custom-elements', '@nuxt/eslint', '@nuxt/ui'],
153+
154+
ui: {
155+
theme: {
156+
colors: ['primary'],
157+
},
158+
},
160159

161160
// Disable auto-imports
162161
imports: {
@@ -181,20 +180,19 @@ export default defineNuxtConfig({
181180
terserOptions: sharedTerserOptions,
182181
},
183182
},
184-
183+
185184
customElements: {
186185
analyzer: process.env.NODE_ENV !== 'test',
187186
entries: [
188187
// @ts-expect-error The nuxt-custom-elements module types don't perfectly match our configuration object structure.
189-
// The custom elements configuration requires specific properties and methods that may not align with the
188+
// The custom elements configuration requires specific properties and methods that may not align with the
190189
// module's TypeScript definitions, particularly around the viteExtend function and tag configuration format.
191190
{
192191
name: 'UnraidComponents',
193192
viteExtend(config: UserConfig) {
194193
return applySharedViteConfig(config, true);
195194
},
196195
tags: [
197-
198196
{
199197
async: false,
200198
name: 'UnraidAuth',

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"@jsonforms/vue": "3.6.0",
9696
"@jsonforms/vue-vanilla": "3.6.0",
9797
"@jsonforms/vue-vuetify": "3.6.0",
98+
"@nuxt/ui": "^3.2.0",
9899
"@nuxtjs/color-mode": "3.5.2",
99100
"@pinia/nuxt": "0.11.1",
100101
"@unraid/shared-callbacks": "1.1.1",

web/pages/index.vue

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
<script lang="ts" setup>
2-
import { ref, onMounted, watch } from 'vue';
2+
import { onMounted, ref, watch } from 'vue';
33
import { storeToRefs } from 'pinia';
4-
import { useHead } from '#imports';
4+
55
import { ExclamationTriangleIcon } from '@heroicons/vue/24/solid';
66
import { BrandButton, Toaster } from '@unraid/ui';
7+
import { UButton } from '#components';
8+
import { useHead } from '#imports';
79
import { useDummyServerStore } from '~/_data/serverState';
810
import AES from 'crypto-js/aes';
911
1012
import type { SendPayloads } from '@unraid/shared-callbacks';
1113
12-
import LogViewerCe from '~/components/Logs/LogViewer.ce.vue';
13-
import SsoButtonCe from '~/components/SsoButton.ce.vue';
14-
import { useThemeStore } from '~/store/theme';
15-
import ModalsCe from '~/components/Modals.ce.vue';
14+
import WelcomeModalCe from '~/components/Activation/WelcomeModal.ce.vue';
15+
import ColorSwitcherCe from '~/components/ColorSwitcher.ce.vue';
1616
import ConnectSettingsCe from '~/components/ConnectSettings/ConnectSettings.ce.vue';
17+
import DowngradeOsCe from '~/components/DowngradeOs.ce.vue';
1718
import DummyServerSwitcher from '~/components/DummyServerSwitcher.vue';
18-
import ColorSwitcherCe from '~/components/ColorSwitcher.ce.vue';
1919
import HeaderOsVersionCe from '~/components/HeaderOsVersion.ce.vue';
20-
import UserProfileCe from '~/components/UserProfile.ce.vue';
21-
import UpdateOsCe from '~/components/UpdateOs.ce.vue';
22-
import DowngradeOsCe from '~/components/DowngradeOs.ce.vue';
20+
import LogViewerCe from '~/components/Logs/LogViewer.ce.vue';
21+
import ModalsCe from '~/components/Modals.ce.vue';
2322
import RegistrationCe from '~/components/Registration.ce.vue';
24-
import WelcomeModalCe from '~/components/Activation/WelcomeModal.ce.vue';
23+
import SsoButtonCe from '~/components/SsoButton.ce.vue';
24+
import UpdateOsCe from '~/components/UpdateOs.ce.vue';
25+
import UserProfileCe from '~/components/UserProfile.ce.vue';
26+
import { useThemeStore } from '~/store/theme';
2527
2628
const serverStore = useDummyServerStore();
2729
const { serverState } = storeToRefs(serverStore);
@@ -36,7 +38,7 @@ onMounted(() => {
3638
});
3739
3840
const valueToMakeCallback = ref<SendPayloads | undefined>();
39-
const callbackDestination = ref<string>('');
41+
const callbackDestination = ref<string | undefined>('');
4042
4143
const createCallbackUrl = (payload: SendPayloads, sendType: string) => {
4244
// params differs from callbackActions.send
@@ -178,6 +180,17 @@ watch(
178180
<pre>{{ callbackDestination }}</pre>
179181
</code>
180182
</div>
183+
<div>
184+
<hr class="border-black dark:border-white" >
185+
<h2 class="text-xl font-semibold font-mono">Nuxt UI Button - Primary Color Test</h2>
186+
<div class="flex gap-4 items-center">
187+
<UButton color="primary" variant="solid">Primary Solid</UButton>
188+
<UButton color="primary" variant="outline">Primary Outline</UButton>
189+
<UButton color="primary" variant="soft">Primary Soft</UButton>
190+
<UButton color="primary" variant="ghost">Primary Ghost</UButton>
191+
<UButton color="primary" variant="link">Primary Link</UButton>
192+
</div>
193+
</div>
181194
<div class="bg-background">
182195
<hr class="border-black dark:border-white" >
183196
<h2 class="text-xl font-semibold font-mono">Brand Button Component</h2>
@@ -208,7 +221,7 @@ watch(
208221
</div>
209222
</template>
210223

211-
<style >
224+
<style>
212225
/* Import unraid-ui globals first */
213226
@import '@unraid/ui/styles';
214227
@import '~/assets/main.css';

0 commit comments

Comments
 (0)