From c8db28168cbf9af76ef362e70758e80e565eca33 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Thu, 3 Jul 2025 13:28:19 +0800 Subject: [PATCH] feat: Add Daisy-UI and optimize LED strip configuration UI - Install and configure Tailwind CSS 4.1 with Daisy-UI plugin - Redesign main navigation with responsive navbar and dark theme - Optimize LED strip configuration layout with modern card components - Improve screen preview performance with frame-based rendering - Reduce LED pixel size for better visual appearance - Remove excessive debug logging for better performance - Fix Tailwind CSS ESM compatibility issues with dynamic imports --- package.json | 2 + pnpm-lock.yaml | 23 +++ postcss.config.js | 1 - src/App.tsx | 52 +++-- .../displays/display-state-card.tsx | 65 ++++-- .../displays/display-state-index.tsx | 44 ++-- src/components/info/board-index.tsx | 44 ++-- src/components/info/board-info-panel.tsx | 47 +++-- .../display-info-panel.tsx | 49 +++-- .../led-strip-configuration.tsx | 49 ++++- .../led-strip-part.tsx | 26 +-- .../led-strip-configuration/screen-view.tsx | 105 ++-------- src/components/white-balance/color-slider.tsx | 2 +- .../white-balance/white-balance.tsx | 188 +++++++++++------- src/styles.css | 1 - tailwind.config.js | 17 +- vite.config.ts | 13 +- 17 files changed, 430 insertions(+), 298 deletions(-) diff --git a/package.json b/package.json index 35bb39e..8963586 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,12 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", + "@tailwindcss/vite": "^4.1.11", "@tauri-apps/cli": "^2.6.2", "@types/debug": "^4.1.12", "@types/node": "^24.0.7", "autoprefixer": "^10.4.21", + "daisyui": "^5.0.43", "postcss": "^8.5.6", "tailwindcss": "^4.1.11", "typescript": "^4.9.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66cdb27..5ec6eee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ importers: '@tailwindcss/postcss': specifier: ^4.1.11 version: 4.1.11 + '@tailwindcss/vite': + specifier: ^4.1.11 + version: 4.1.11(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@tauri-apps/cli': specifier: ^2.6.2 version: 2.6.2 @@ -45,6 +48,9 @@ importers: autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) + daisyui: + specifier: ^5.0.43 + version: 5.0.43 postcss: specifier: ^8.5.6 version: 8.5.6 @@ -511,6 +517,11 @@ packages: '@tailwindcss/postcss@4.1.11': resolution: {integrity: sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==} + '@tailwindcss/vite@4.1.11': + resolution: {integrity: sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + '@tauri-apps/api@2.6.0': resolution: {integrity: sha512-hRNcdercfgpzgFrMXWwNDBN0B7vNzOzRepy6ZAmhxi5mDLVPNrTpo9MGg2tN/F7JRugj4d2aF7E1rtPXAHaetg==} @@ -644,6 +655,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + daisyui@5.0.43: + resolution: {integrity: sha512-2pshHJ73vetSpsbAyaOncGnNYL0mwvgseS1EWy1I9Qpw8D11OuBoDNIWrPIME4UFcq2xuff3A9x+eXbuFR9fUQ==} + debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -1344,6 +1358,13 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.11 + '@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + dependencies: + '@tailwindcss/node': 4.1.11 + '@tailwindcss/oxide': 4.1.11 + tailwindcss: 4.1.11 + vite: 6.3.5(@types/node@24.0.7)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + '@tauri-apps/api@2.6.0': {} '@tauri-apps/cli-darwin-arm64@2.6.2': @@ -1466,6 +1487,8 @@ snapshots: csstype@3.1.3: {} + daisyui@5.0.43: {} + debug@4.4.1: dependencies: ms: 2.1.3 diff --git a/postcss.config.js b/postcss.config.js index 668a5b9..90d9fff 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,5 @@ module.exports = { plugins: { - '@tailwindcss/postcss': {}, autoprefixer: {}, }, } diff --git a/src/App.tsx b/src/App.tsx index 94219b7..8f23609 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,19 +21,47 @@ function App() { }); return ( -
-
- 基本信息 - 显示器信息 - 灯条配置 - 白平衡 +
+ {/* Navigation */} + - - - - - - + + {/* Main Content */} +
+ + + + + + +
); } diff --git a/src/components/displays/display-state-card.tsx b/src/components/displays/display-state-card.tsx index 43234c9..6d4cb8f 100644 --- a/src/components/displays/display-state-card.tsx +++ b/src/components/displays/display-state-card.tsx @@ -11,26 +11,59 @@ type ItemProps = { const Item: ParentComponent = (props) => { return ( -
-
{props.label}
-
{props.children}
-
+
+
{props.label}
+
{props.children}
+
); }; export const DisplayStateCard: Component = (props) => { return ( -
- {props.state.brightness} - {props.state.max_brightness} - {props.state.min_brightness} - {props.state.contrast} - {props.state.max_contrast} - {props.state.min_contrast} - {props.state.max_mode} - {props.state.min_mode} - {props.state.mode} - {props.state.last_modified_at.toISOString()} -
+
+
+
+ 显示器状态 +
实时
+
+ +
+ {/* 亮度信息 */} +
+

亮度设置

+
+ {props.state.brightness} + {props.state.max_brightness} + {props.state.min_brightness} +
+
+ + {/* 对比度信息 */} +
+

对比度设置

+
+ {props.state.contrast} + {props.state.max_contrast} + {props.state.min_contrast} +
+
+ + {/* 模式信息 */} +
+

模式设置

+
+ {props.state.mode} + {props.state.max_mode} + {props.state.min_mode} +
+
+ + {/* 更新时间 */} +
+ 最后更新: {props.state.last_modified_at.toLocaleString()} +
+
+
+
); }; diff --git a/src/components/displays/display-state-index.tsx b/src/components/displays/display-state-index.tsx index a1d5afb..4002388 100644 --- a/src/components/displays/display-state-index.tsx +++ b/src/components/displays/display-state-index.tsx @@ -36,17 +36,37 @@ export const DisplayStateIndex: Component = () => { }; }); return ( -
    - - {(state, index) => ( -
  1. - - - #{index() + 1} - -
  2. - )} -
    -
+
+
+

显示器状态

+
+
+
显示器数量
+
{states().length}
+
+
+
+ +
+ + {(state, index) => ( +
+ +
+ {index() + 1} +
+
+ )} +
+
+ + {states().length === 0 && ( +
+
🖥️
+

未检测到显示器

+

请检查显示器连接状态

+
+ )} +
); }; diff --git a/src/components/info/board-index.tsx b/src/components/info/board-index.tsx index 2265740..35bdfed 100644 --- a/src/components/info/board-index.tsx +++ b/src/components/info/board-index.tsx @@ -26,17 +26,37 @@ export const BoardIndex: Component = () => { }; }); return ( -
    - - {(board, index) => ( -
  1. - - - #{index() + 1} - -
  2. - )} -
    -
+
+
+

设备信息

+
+
+
设备总数
+
{boards().length}
+
+
+
+ +
+ + {(board, index) => ( +
+ +
+ {index() + 1} +
+
+ )} +
+
+ + {boards().length === 0 && ( +
+
🔍
+

未发现设备

+

请检查设备连接状态

+
+ )} +
); }; diff --git a/src/components/info/board-info-panel.tsx b/src/components/info/board-info-panel.tsx index a153d3c..3fd2218 100644 --- a/src/components/info/board-info-panel.tsx +++ b/src/components/info/board-info-panel.tsx @@ -7,10 +7,10 @@ type ItemProps = { const Item: ParentComponent = (props) => { return ( -
-
{props.label}
-
{props.children}
-
+
+
{props.label}
+
{props.children}
+
); }; @@ -41,20 +41,31 @@ export const BoardInfoPanel: Component<{ board: BoardInfo }> = (props) => { } }); + const statusBadgeClass = createMemo(() => { + const status = connectStatus(); + if (status === 'Connected') { + return 'badge badge-success badge-sm'; + } else if (status?.startsWith('Connecting')) { + return 'badge badge-warning badge-sm'; + } else { + return 'badge badge-error badge-sm'; + } + }); + return ( -
- {props.board.fullname} - {props.board.host} - - {props.board.address} - - - {props.board.port} - - - {connectStatus()} - - {ttl()} -
+
+
+
+ {props.board.fullname} +
{connectStatus()}
+
+
+ {props.board.host} + {props.board.address} + {props.board.port} + {ttl()} +
+
+
); }; diff --git a/src/components/led-strip-configuration/display-info-panel.tsx b/src/components/led-strip-configuration/display-info-panel.tsx index 14d7a3d..3f5286d 100644 --- a/src/components/led-strip-configuration/display-info-panel.tsx +++ b/src/components/led-strip-configuration/display-info-panel.tsx @@ -7,10 +7,10 @@ type DisplayInfoItemProps = { export const DisplayInfoItem: ParentComponent = (props) => { return ( -
-
{props.label}
-
{props.children}
-
+
+
{props.label}
+
{props.children}
+
); }; @@ -21,22 +21,29 @@ type DisplayInfoPanelProps = { export const DisplayInfoPanel: Component = (props) => { const [localProps, rootProps] = splitProps(props, ['display']); return ( -
- - {localProps.display.id} - - - ({localProps.display.x}, {localProps.display.y}) - - - {localProps.display.width} x {localProps.display.height} - - - {localProps.display.scale_factor} - - - {localProps.display.is_primary ? 'True' : 'False'} - -
+
+
+
+ 显示器信息 + {localProps.display.is_primary && ( +
主显示器
+ )} +
+
+ + {localProps.display.id} + + + ({localProps.display.x}, {localProps.display.y}) + + + {localProps.display.width} × {localProps.display.height} + + + {localProps.display.scale_factor}× + +
+
+
); }; diff --git a/src/components/led-strip-configuration/led-strip-configuration.tsx b/src/components/led-strip-configuration/led-strip-configuration.tsx index 5058912..8d55f01 100644 --- a/src/components/led-strip-configuration/led-strip-configuration.tsx +++ b/src/components/led-strip-configuration/led-strip-configuration.tsx @@ -91,14 +91,49 @@ export const LedStripConfiguration = () => { ]; return ( -
+
+
+

灯条配置

+
+
+
显示器数量
+
{displayStore.displays.length}
+
+
+
+ - - - {displayStore.displays.map((display) => { - return ; - })} - + {/* LED Strip Sorter Panel */} +
+
+
+ 灯条排序 +
实时预览
+
+ +
+ 💡 提示:拖拽灯条段落来调整顺序,双击可反转方向 +
+
+
+ + {/* Display Configuration Panel */} +
+
+
+ 显示器配置 +
可视化编辑
+
+ + {displayStore.displays.map((display) => { + return ; + })} + +
+ 💡 提示:鼠标滚轮调整灯条长度,悬停查看详细信息 +
+
+
); diff --git a/src/components/led-strip-configuration/led-strip-part.tsx b/src/components/led-strip-configuration/led-strip-part.tsx index 86187cd..1904874 100644 --- a/src/components/led-strip-configuration/led-strip-part.tsx +++ b/src/components/led-strip-configuration/led-strip-part.tsx @@ -34,7 +34,7 @@ export const Pixel: Component = (props) => { title={props.color} >
@@ -60,32 +60,16 @@ export const LedStripPart: Component = (props) => { ); if (index === -1) { - console.log('🔍 LED: Strip config not found', { - displayId: localProps.config.display_id, - border: localProps.config.border, - availableStrips: ledStripStore.strips.length - }); return; } const mapper = ledStripStore.mappers[index]; if (!mapper) { - console.log('🔍 LED: Mapper not found', { index, mappersCount: ledStripStore.mappers.length }); return; } const offset = mapper.start * 3; - console.log('🎨 LED: Updating colors', { - displayId: localProps.config.display_id, - border: localProps.config.border, - stripLength: localProps.config.len, - mapperPos: mapper.pos, - offset, - colorsArrayLength: ledStripStore.colors.length, - firstFewColors: Array.from(ledStripStore.colors.slice(offset, offset + 9)) - }); - const colors = new Array(localProps.config.len).fill(null).map((_, i) => { const index = offset + i * 3; const r = ledStripStore.colors[index] || 0; @@ -94,12 +78,6 @@ export const LedStripPart: Component = (props) => { return `rgb(${r}, ${g}, ${b})`; }); - console.log('🎨 LED: Generated colors', { - border: localProps.config.border, - colorsCount: colors.length, - sampleColors: colors.slice(0, 3) - }); - setColors(colors); }); @@ -143,7 +121,7 @@ export const LedStripPart: Component = (props) => { {...rootProps} ref={setAnchor} class={ - 'flex rounded-full flex-nowrap justify-around items-center overflow-hidden bg-gray-800/20 border border-gray-600/30 min-h-[16px] min-w-[16px] ' + + 'flex rounded-full flex-nowrap justify-around items-center overflow-hidden bg-gray-800/20 border border-gray-600/30 min-h-[32px] min-w-[32px] ' + rootProps.class } classList={{ diff --git a/src/components/led-strip-configuration/screen-view.tsx b/src/components/led-strip-configuration/screen-view.tsx index 6eefbcc..eba7892 100644 --- a/src/components/led-strip-configuration/screen-view.tsx +++ b/src/components/led-strip-configuration/screen-view.tsx @@ -36,18 +36,10 @@ export const ScreenView: Component = (props) => { const [isLoading, setIsLoading] = createSignal(false); let isMounted = true; - // Fetch screenshot data from backend + // Fetch screenshot data from backend with frame-based rendering const fetchScreenshot = async () => { - console.log('📸 FETCH: Starting screenshot fetch', { - isLoading: isLoading(), - isMounted, - hidden: hidden(), - timestamp: new Date().toLocaleTimeString() - }); - if (isLoading()) { - console.log('⏳ FETCH: Already loading, skipping'); - return; // Skip if already loading + return; // Skip if already loading - frame-based approach } try { @@ -57,9 +49,7 @@ export const ScreenView: Component = (props) => { const response = await fetch(`ambient-light://displays/${localProps.displayId}?width=400&height=225&t=${timestamp}`); if (!response.ok) { - console.error('❌ FETCH: Screenshot fetch failed', response.status, response.statusText); - const errorText = await response.text(); - console.error('❌ FETCH: Error response body:', errorText); + console.error('Screenshot fetch failed:', response.status); return; } @@ -69,71 +59,43 @@ export const ScreenView: Component = (props) => { const buffer = new Uint8ClampedArray(arrayBuffer); const expectedSize = width * height * 4; - - // Validate buffer size if (buffer.length !== expectedSize) { - console.error('❌ FETCH: Invalid buffer size!', { - received: buffer.length, - expected: expectedSize, - ratio: buffer.length / expectedSize - }); + console.error('Invalid buffer size:', buffer.length, 'expected:', expectedSize); return; } - console.log('📊 FETCH: Setting image data', { width, height, bufferSize: buffer.length }); - setImageData({ buffer, width, height }); - // Use setTimeout to ensure the signal update has been processed + // Draw immediately after data is set setTimeout(() => { - console.log('🖼️ FETCH: Triggering draw after data set'); draw(false); }, 0); - // Schedule next frame after rendering is complete + // Frame-based rendering: wait for current frame to complete before scheduling next const shouldContinue = !hidden() && isMounted; - console.log('🔄 FETCH: Scheduling next frame', { - hidden: hidden(), - isMounted, - shouldContinue, - nextFrameDelay: '1000ms' - }); - if (shouldContinue) { setTimeout(() => { if (isMounted) { - console.log('🔄 FETCH: Starting next frame'); - fetchScreenshot(); - } else { - console.log('❌ FETCH: Component unmounted, stopping loop'); + fetchScreenshot(); // Start next frame only after current one completes } - }, 1000); // Wait 1 second before next frame - } else { - console.log('❌ FETCH: Loop stopped - component hidden or unmounted'); + }, 500); // Reduced frequency to 500ms for better performance } } catch (error) { - console.error('❌ FETCH: Error fetching screenshot:', error); - // Even on error, schedule next frame + console.error('Error fetching screenshot:', error); + // On error, wait longer before retry const shouldContinueOnError = !hidden() && isMounted; - console.log('🔄 FETCH: Error recovery - scheduling next frame', { - error: error.message, - shouldContinue: shouldContinueOnError, - nextFrameDelay: '2000ms' - }); - if (shouldContinueOnError) { setTimeout(() => { if (isMounted) { - console.log('🔄 FETCH: Retrying after error'); fetchScreenshot(); } - }, 2000); // Wait longer on error + }, 2000); } } finally { setIsLoading(false); @@ -141,22 +103,10 @@ export const ScreenView: Component = (props) => { }; const resetSize = () => { - console.log('📏 CANVAS: Resizing', { - rootClientWidth: root.clientWidth, - rootClientHeight: root.clientHeight, - oldCanvasWidth: canvas.width, - oldCanvasHeight: canvas.height - }); - // Set canvas size first canvas.width = root.clientWidth; canvas.height = root.clientHeight; - console.log('📏 CANVAS: Size set', { - newCanvasWidth: canvas.width, - newCanvasHeight: canvas.height - }); - // Use a default aspect ratio if canvas dimensions are invalid const aspectRatio = (canvas.width > 0 && canvas.height > 0) ? canvas.width / canvas.height @@ -179,30 +129,15 @@ export const ScreenView: Component = (props) => { drawHeight, }); - - draw(true); }; const draw = (cached: boolean = false) => { const { drawX, drawY, drawWidth, drawHeight } = drawInfo(); - let _ctx = ctx(); let raw = imageData(); - console.log('🖼️ DRAW: Called with', { - cached, - hasContext: !!_ctx, - hasImageData: !!raw, - imageDataSize: raw ? `${raw.width}x${raw.height}` : 'none', - drawInfo: { drawX, drawY, drawWidth, drawHeight }, - canvasSize: `${canvas.width}x${canvas.height}`, - contextType: _ctx ? 'valid' : 'null', - rawBufferSize: raw ? raw.buffer.length : 0 - }); - if (_ctx && raw) { - console.log('🖼️ DRAW: Starting to draw image'); _ctx.clearRect(0, 0, canvas.width, canvas.height); // Apply transparency effect for cached images if needed @@ -220,34 +155,24 @@ export const ScreenView: Component = (props) => { // If the image size matches the draw size, use putImageData directly if (raw.width === drawWidth && raw.height === drawHeight) { - console.log('🖼️ DRAW: Using putImageData directly'); _ctx.putImageData(img, drawX, drawY); - console.log('✅ DRAW: putImageData completed'); } else { - console.log('🖼️ DRAW: Using scaling with temp canvas'); // Otherwise, use cached temporary canvas for scaling if (!tempCanvas || tempCanvas.width !== raw.width || tempCanvas.height !== raw.height) { tempCanvas = document.createElement('canvas'); tempCanvas.width = raw.width; tempCanvas.height = raw.height; tempCtx = tempCanvas.getContext('2d'); - console.log('🖼️ DRAW: Created new temp canvas'); } if (tempCtx) { tempCtx.putImageData(img, 0, 0); _ctx.drawImage(tempCanvas, drawX, drawY, drawWidth, drawHeight); - console.log('✅ DRAW: Scaled drawing completed'); } } } catch (error) { - console.error('❌ DRAW: Error in draw():', error); + console.error('Error in draw():', error); } - } else { - console.log('❌ DRAW: Cannot draw - missing context or image data', { - hasContext: !!_ctx, - hasImageData: !!raw - }); } }; @@ -255,11 +180,8 @@ export const ScreenView: Component = (props) => { // Initialize canvas and resize observer onMount(() => { - console.log('🚀 CANVAS: Component mounted'); const context = canvas.getContext('2d'); - console.log('🚀 CANVAS: Context obtained', !!context); setCtx(context); - console.log('🚀 CANVAS: Context signal set'); // Initial size setup resetSize(); @@ -270,16 +192,13 @@ export const ScreenView: Component = (props) => { resizeObserver.observe(root); // Start screenshot fetching after context is ready - console.log('🚀 SCREENSHOT: Starting screenshot fetching'); setTimeout(() => { - console.log('🚀 SCREENSHOT: Context ready, starting fetch'); fetchScreenshot(); // Initial fetch - will self-schedule subsequent frames }, 100); // Small delay to ensure context is ready onCleanup(() => { isMounted = false; // Stop scheduling new frames resizeObserver?.unobserve(root); - console.log('🧹 CLEANUP: Component unmounted'); }); }); diff --git a/src/components/white-balance/color-slider.tsx b/src/components/white-balance/color-slider.tsx index ec054a4..0240e5b 100644 --- a/src/components/white-balance/color-slider.tsx +++ b/src/components/white-balance/color-slider.tsx @@ -14,7 +14,7 @@ export const ColorSlider: Component = (props) => { step={0.01} value={props.value} class={ - 'w-full h-2 bg-gradient-to-r rounded-lg appearance-none cursor-pointer dark:bg-gray-700 drop-shadow ' + + 'range range-primary w-full bg-gradient-to-r ' + props.class } /> diff --git a/src/components/white-balance/white-balance.tsx b/src/components/white-balance/white-balance.tsx index cc106d5..7e5d29c 100644 --- a/src/components/white-balance/white-balance.tsx +++ b/src/components/white-balance/white-balance.tsx @@ -11,10 +11,9 @@ import transparentBg from '../../assets/transparent-grid-background.svg?url'; const Value: Component<{ value: number }> = (props) => { return ( - - {(props.value * 100).toFixed(0)} - % - +
+ {(props.value * 100).toFixed(0)}% +
); }; @@ -55,77 +54,118 @@ export const WhiteBalance = () => { }; return ( -
-
- +
+
+

白平衡调节

+
+ + +
-
- - - - - - + +
+ {/* 颜色测试区域 */} +
+
+
+ 颜色测试 +
点击测试
+
+
+ +
+
+ 💡 提示:点击颜色块进行单色测试,再次点击返回多色模式 +
+
+
+ + {/* 白平衡控制面板 */} +
+
+
+ RGB调节 +
实时调节
+
+ +
+
+ + + updateColorCalibration( + 'r', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'g', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + + updateColorCalibration( + 'b', + (ev.target as HTMLInputElement).valueAsNumber ?? 1, + ) + } + /> +
+ +
+ + +
+
+ +
+ 💡 提示:调节RGB滑块来校正LED灯条的白平衡,使白色更加纯净 +
+
+
-
+
); }; diff --git a/src/styles.css b/src/styles.css index 136983f..45f8e26 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,3 +1,2 @@ @import "tailwindcss"; - @config "../tailwind.config.js"; \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index fca1a87..7f28eab 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,9 +1,20 @@ +import daisyui from 'daisyui'; + /** @type {import('tailwindcss').Config} */ -module.exports = { - mode: 'jit', +export default { content: ['./src/**/*.{js,jsx,ts,tsx}'], theme: { extend: {}, }, - plugins: [], + plugins: [daisyui], + daisyui: { + themes: ["dark", "light"], + darkTheme: "dark", + base: true, + styled: true, + utils: true, + prefix: "", + logs: true, + themeRoot: ":root", + }, }; diff --git a/vite.config.ts b/vite.config.ts index d001ba2..9f24aa2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,8 +6,14 @@ const mobile = process.env.TAURI_PLATFORM === "ios"; // https://vitejs.dev/config/ -export default defineConfig(async () => ({ - plugins: [solidPlugin()], +export default defineConfig(async () => { + const tailwindcss = (await import("@tailwindcss/vite")).default; + + return { + plugins: [ + solidPlugin(), + tailwindcss(), + ], // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // prevent vite from obscuring rust errors @@ -28,4 +34,5 @@ export default defineConfig(async () => ({ // produce sourcemaps for debug builds sourcemap: !!process.env.TAURI_DEBUG, }, -})); + }; +});