diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9dab3012f..f4fa3b773 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -790,6 +790,9 @@ importers:
postcss:
specifier: ^8.4.49
version: 8.5.3
+ postcss-import:
+ specifier: ^16.1.0
+ version: 16.1.0(postcss@8.5.3)
prettier:
specifier: 3.5.3
version: 3.5.3
@@ -9707,6 +9710,12 @@ packages:
peerDependencies:
postcss: ^8.0.0
+ postcss-import@16.1.0:
+ resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==}
+ engines: {node: '>=18.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
postcss-js@4.0.1:
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
@@ -22577,6 +22586,13 @@ snapshots:
read-cache: 1.0.0
resolve: 1.22.10
+ postcss-import@16.1.0(postcss@8.5.3):
+ dependencies:
+ postcss: 8.5.3
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.10
+
postcss-js@4.0.1(postcss@8.5.3):
dependencies:
camelcase-css: 2.0.1
diff --git a/unraid-ui/.gitignore b/unraid-ui/.gitignore
index 0755904a6..b15d1ce8a 100644
--- a/unraid-ui/.gitignore
+++ b/unraid-ui/.gitignore
@@ -1,2 +1,3 @@
!.env.development
-dist-wc/
\ No newline at end of file
+dist-wc/
+.storybook/static/*
\ No newline at end of file
diff --git a/unraid-ui/.storybook/main.ts b/unraid-ui/.storybook/main.ts
index cc2e29893..aace76651 100644
--- a/unraid-ui/.storybook/main.ts
+++ b/unraid-ui/.storybook/main.ts
@@ -1,26 +1,22 @@
-import { dirname, join } from "path";
-import type { StorybookConfig } from "@storybook/vue3-vite";
-
+import { dirname, join } from 'path';
+import type { StorybookConfig } from '@storybook/vue3-vite';
const config: StorybookConfig = {
- stories: ["../stories/**/*.stories.@(js|jsx|ts|tsx)"],
- addons: [
- "@storybook/addon-links",
- "@storybook/addon-essentials",
- "@storybook/addon-interactions"
- ],
+ stories: ['../stories/**/*.stories.@(js|jsx|ts|tsx)'],
+ addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'],
framework: {
- name: "@storybook/vue3-vite",
+ name: '@storybook/vue3-vite',
options: {
- docgen: "vue-component-meta",
+ docgen: 'vue-component-meta',
},
},
core: {
- builder: "@storybook/builder-vite",
+ builder: '@storybook/builder-vite',
},
docs: {
- autodocs: "tag",
+ autodocs: 'tag',
},
+ staticDirs: ['./static'],
async viteFinal(config) {
return {
...config,
@@ -49,4 +45,4 @@ const config: StorybookConfig = {
},
};
-export default config;
\ No newline at end of file
+export default config;
diff --git a/unraid-ui/.storybook/preview.ts b/unraid-ui/.storybook/preview.ts
index e8d22b379..727d4538e 100644
--- a/unraid-ui/.storybook/preview.ts
+++ b/unraid-ui/.storybook/preview.ts
@@ -1,8 +1,10 @@
import type { Preview } from '@storybook/vue3';
-import '../src/styles/globals.css';
import { registerAllComponents } from '../src/register';
+import '@/styles/index.css';
-registerAllComponents({});
+registerAllComponents({
+ pathToSharedCss: '/index.css',
+});
const preview: Preview = {
parameters: {
@@ -18,9 +20,11 @@ const preview: Preview = {
decorators: [
(story) => ({
components: { story },
+
template: `
`,
@@ -28,4 +32,4 @@ const preview: Preview = {
],
};
-export default preview;
+export default preview;
\ No newline at end of file
diff --git a/unraid-ui/package.json b/unraid-ui/package.json
index 6bed9e282..042d12e61 100644
--- a/unraid-ui/package.json
+++ b/unraid-ui/package.json
@@ -34,7 +34,10 @@
"preunraid:deploy": "pnpm build:wc",
"unraid:deploy": "just deploy",
"// Storybook": "",
+ "prestorybook": "pnpm storybook:css",
"storybook": "storybook dev -p 6006",
+ "storybook:css": "node scripts/build-style.mjs",
+ "prebuild-storybook": "pnpm storybook:css",
"build-storybook": "storybook build"
},
"peerDependencies": {
@@ -89,6 +92,7 @@
"eslint-plugin-vue": "^10.0.0",
"happy-dom": "^17.0.0",
"postcss": "^8.4.49",
+ "postcss-import": "^16.1.0",
"prettier": "3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"rimraf": "^6.0.1",
diff --git a/unraid-ui/scripts/build-style.mjs b/unraid-ui/scripts/build-style.mjs
new file mode 100644
index 000000000..aaadf385b
--- /dev/null
+++ b/unraid-ui/scripts/build-style.mjs
@@ -0,0 +1,30 @@
+import fs from 'fs/promises';
+import autoprefixer from 'autoprefixer';
+import postcss from 'postcss';
+import postcssImport from 'postcss-import';
+import tailwindcss from 'tailwindcss';
+
+/**
+ * Helper script for storybook to build the CSS file for the components. This is used to ensure that modals render using the shadow styles.
+ */
+
+process.env.VITE_TAILWIND_BASE_FONT_SIZE = 16;
+
+const inputPath = './src/styles/index.css';
+const outputPath = './.storybook/static/index.css'; // served from root: /index.css
+
+const css = await fs.readFile(inputPath, 'utf8');
+
+const result = await postcss([
+ postcssImport(),
+ tailwindcss({ config: './tailwind.config.ts' }),
+ autoprefixer(),
+]).process(css, {
+ from: inputPath,
+ to: outputPath,
+});
+
+await fs.mkdir('./.storybook/static', { recursive: true });
+await fs.writeFile(outputPath, result.css);
+
+console.log('✅ CSS built for Storybook:', outputPath);
\ No newline at end of file
diff --git a/unraid-ui/src/components.ts b/unraid-ui/src/components.ts
index 5734bca13..7abff68cb 100644
--- a/unraid-ui/src/components.ts
+++ b/unraid-ui/src/components.ts
@@ -18,3 +18,4 @@ export * from '@/components/common/tooltip';
export * from '@/components/common/toast';
export * from '@/components/common/popover';
export * from '@/components/brand';
+export * from '@/components/modals';
\ No newline at end of file
diff --git a/unraid-ui/src/components/form/combobox/ComboboxList.vue b/unraid-ui/src/components/form/combobox/ComboboxList.vue
index ff78e1b7a..1570abc25 100644
--- a/unraid-ui/src/components/form/combobox/ComboboxList.vue
+++ b/unraid-ui/src/components/form/combobox/ComboboxList.vue
@@ -5,15 +5,19 @@ import type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui';
import { ComboboxContent, ComboboxPortal, ComboboxViewport, useForwardPropsEmits } from 'reka-ui';
import { computed, type HTMLAttributes } from 'vue';
-const props = withDefaults(defineProps(), {
- position: 'popper',
- align: 'center',
- sideOffset: 4,
+defineOptions({
+ inheritAttrs: false,
});
-const emits = defineEmits();
const { teleportTarget } = useTeleport();
+const props = withDefaults(defineProps(), {
+ forceMount: true,
+ position: 'popper',
+ to: undefined,
+});
+const emits = defineEmits();
+
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
@@ -26,7 +30,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
+
+
+
+
\ No newline at end of file
diff --git a/unraid-ui/src/components/modals/index.ts b/unraid-ui/src/components/modals/index.ts
new file mode 100644
index 000000000..9e6d89df9
--- /dev/null
+++ b/unraid-ui/src/components/modals/index.ts
@@ -0,0 +1 @@
+export { default as Modals } from './ModalTarget.vue';
\ No newline at end of file
diff --git a/unraid-ui/src/composables/useTeleport.ts b/unraid-ui/src/composables/useTeleport.ts
index a1bbd50f1..066c31193 100644
--- a/unraid-ui/src/composables/useTeleport.ts
+++ b/unraid-ui/src/composables/useTeleport.ts
@@ -4,12 +4,15 @@ const useTeleport = () => {
const teleportTarget = ref('#modals');
const determineTeleportTarget = () => {
- const myModalsComponent = document.querySelector('unraid-modals');
+ const myModalsComponent = document.querySelector('unraid-modals') || document.querySelector('uui-modals');
+ console.log('myModalsComponent', myModalsComponent, 'has shadowRoot', myModalsComponent?.shadowRoot);
if (!myModalsComponent?.shadowRoot) return;
const potentialTarget = myModalsComponent.shadowRoot.querySelector('#modals');
if (!potentialTarget) return;
+ console.log('potentialTarget', potentialTarget);
+
teleportTarget.value = potentialTarget as HTMLElement;
console.log('[determineTeleportTarget] teleportTarget', teleportTarget.value);
};
diff --git a/unraid-ui/src/index.ts b/unraid-ui/src/index.ts
index f4c4f8f5a..95a19aede 100644
--- a/unraid-ui/src/index.ts
+++ b/unraid-ui/src/index.ts
@@ -14,5 +14,3 @@ export { default as tailwindConfig } from '../tailwind.config';
// Composables
export { default as useTeleport } from '@/composables/useTeleport';
-
-// Additional exports not in components.ts
diff --git a/unraid-ui/src/vite-env.d.ts b/unraid-ui/src/vite-env.d.ts
new file mode 100644
index 000000000..9a818b703
--- /dev/null
+++ b/unraid-ui/src/vite-env.d.ts
@@ -0,0 +1,6 @@
+///
+
+declare module '*.css?raw' {
+ const content: string;
+ export default content;
+}
\ No newline at end of file
diff --git a/unraid-ui/stories/components/form/Combobox.stories.ts b/unraid-ui/stories/components/form/Combobox.stories.ts
new file mode 100644
index 000000000..587f33a46
--- /dev/null
+++ b/unraid-ui/stories/components/form/Combobox.stories.ts
@@ -0,0 +1,89 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+import {
+ Combobox as ComboboxComponent,
+ ComboboxEmpty,
+ ComboboxGroup,
+ ComboboxInput,
+ ComboboxItem,
+ ComboboxList,
+ ComboboxTrigger,
+} from '../../../src/components/form/combobox';
+
+const meta = {
+ title: 'Components/Form/Combobox',
+ component: ComboboxComponent,
+} satisfies Meta;
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Combobox: Story = {
+ render: (args) => ({
+ components: {
+ ComboboxComponent,
+ ComboboxTrigger,
+ ComboboxInput,
+ ComboboxList,
+ ComboboxGroup,
+ ComboboxItem,
+ },
+ setup() {
+ return { args };
+ },
+ template: `
+
+
+
+
+
+
+ Apple
+ Banana
+ Orange
+ Grape
+
+
+
+ `,
+ }),
+};
+
+export const Grouped: Story = {
+ render: (args) => ({
+ components: {
+ ComboboxComponent,
+ ComboboxTrigger,
+ ComboboxInput,
+ ComboboxList,
+ ComboboxGroup,
+ ComboboxItem,
+ ComboboxEmpty,
+ },
+ setup() {
+ return { args };
+ },
+ template: `
+
+
+
+
+
+
+ No results found
+
+ Apple
+ Banana
+ Grape
+
+
+ Carrot
+ Potato
+ Celery
+
+
+
+
+ `,
+ }),
+};
\ No newline at end of file
diff --git a/unraid-ui/stories/components/form/Select.stories.ts b/unraid-ui/stories/components/form/Select.stories.ts
index be9d6f095..6a4c00cbc 100644
--- a/unraid-ui/stories/components/form/Select.stories.ts
+++ b/unraid-ui/stories/components/form/Select.stories.ts
@@ -7,7 +7,7 @@ import {
SelectLabel,
SelectTrigger,
SelectValue,
-} from '../../../src/components/form/select';
+} from '@/components/form/select';
const meta = {
title: 'Components/Form/Select',
@@ -67,7 +67,6 @@ export const Grouped: Story = {
},
template: `
-
diff --git a/web/composables/useTeleport.ts b/web/composables/useTeleport.ts
index fb965dbc2..228650a14 100644
--- a/web/composables/useTeleport.ts
+++ b/web/composables/useTeleport.ts
@@ -11,7 +11,6 @@ const useTeleport = () => {
if (!potentialTarget) return;
teleportTarget.value = potentialTarget;
- console.log("[determineTeleportTarget] teleportTarget", teleportTarget.value);
};
onMounted(() => {