packages/web: fix lucide github; optimize Vite deps in dev mode

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I75110e204c8eda63096bcfed619a6f5c6a6a6964
This commit is contained in:
raf 2026-04-14 08:31:56 +03:00
commit 6ec645f3de
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
10 changed files with 1080 additions and 402 deletions

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>

After

Width:  |  Height:  |  Size: 822 B

6
packages/web/src/@types/lucide.d.ts vendored Normal file
View file

@ -0,0 +1,6 @@
declare module 'lucide-solid/icons/*' {
import { LucideProps } from 'lucide-solid/dist/types/types';
import { Component } from 'solid-js';
const cmp: Component<LucideProps>;
export = cmp;
}

View file

@ -1,7 +1,10 @@
import { Component, For, createSignal, createMemo, Show } from 'solid-js';
import { ComparisonEntry, calculateChange } from '@ns/core';
import { formatBytes, formatNumber, formatTime, formatPercent } from '@ns/ui-utils';
import { ArrowRight, ArrowDown, ArrowUp, X } from 'lucide-solid';
import ArrowRightIcon from 'lucide-solid/icons/arrow-right';
import ArrowDownIcon from 'lucide-solid/icons/arrow-down';
import ArrowUpIcon from 'lucide-solid/icons/arrow-up';
import XIcon from 'lucide-solid/icons/x';
interface ComparisonViewProps {
entries: ComparisonEntry[];
@ -106,7 +109,7 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
</select>
</div>
<div class="compare-arrow">
<ArrowRight size={20} />
<ArrowRightIcon size={20} />
</div>
<div class="compare-selector">
<label>Current</label>
@ -127,7 +130,7 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
<div class="snapshot-item">
<span class="snapshot-name">{entry.name}</span>
<button class="delete-btn" onClick={() => props.onDelete(entry.id)}>
<X size={16} />
<XIcon size={16} />
</button>
</div>
)}
@ -195,10 +198,10 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
<Show when={row.isDifferent} fallback={<span class="neutral"></span>}>
<span class="change-value">
<Show when={row.isReduction}>
<ArrowDown size={14} />
<ArrowDownIcon size={14} />
</Show>
<Show when={!row.isReduction}>
<ArrowUp size={14} />
<ArrowUpIcon size={14} />
</Show>
{Math.abs(row.change).toFixed(2)}%
</span>
@ -221,13 +224,13 @@ const ComparisonView: Component<ComparisonViewProps> = props => {
<div class="comparison-summary">
<Show when={comparison()?.some(r => r.isReduction)}>
<div class="summary-good">
<ArrowDown size={16} />{' '}
<ArrowDownIcon size={16} />{' '}
{comparison()?.filter(r => r.isReduction && r.isDifferent).length} improved
</div>
</Show>
<Show when={comparison()?.some(r => !r.isReduction && r.isDifferent)}>
<div class="summary-bad">
<ArrowUp size={16} />{' '}
<ArrowUpIcon size={16} />{' '}
{comparison()?.filter(r => !r.isReduction && r.isDifferent).length} regressed
</div>
</Show>

View file

@ -1,6 +1,7 @@
import { createSignal, Show, For } from 'solid-js';
import { StatsData, ComparisonEntry } from '@ns/core';
import { BarChart2, Clock } from 'lucide-solid';
import BarChart2Icon from 'lucide-solid/icons/bar-chart-2';
import ClockIcon from 'lucide-solid/icons/clock';
interface FileUploadProps {
onFileLoad: (data: StatsData, raw: Record<string, unknown>) => void;
@ -44,7 +45,7 @@ export default function FileUpload(props: FileUploadProps) {
<div class="upload-container">
<div class="upload-card">
<div class="upload-icon">
<BarChart2 size={48} />
<BarChart2Icon size={48} />
</div>
<h2>Load Statistics</h2>
@ -97,7 +98,7 @@ export default function FileUpload(props: FileUploadProps) {
<Show when={props.snapshots && props.snapshots.length > 0}>
<div class="recent-analyses">
<h3>
<Clock size={16} />
<ClockIcon size={16} />
Recent Analyses
</h3>
<div class="snapshot-list">

View file

@ -1,5 +1,5 @@
import { Component, createSignal, type JSX, Show } from 'solid-js';
import { ChevronDown } from 'lucide-solid';
import ChevronDownIcon from 'lucide-solid/icons/chevron-down';
interface SectionProps {
title: string;
@ -16,7 +16,7 @@ const Section: Component<SectionProps> = props => {
<Show when={props.collapsible}>
<button class="section-header" onClick={() => setCollapsed(!collapsed())}>
<span class="section-title">{props.title}</span>
<ChevronDown size={16} class="section-toggle" />
<ChevronDownIcon size={16} class="section-toggle" />
</button>
</Show>
<Show when={!props.collapsible || !collapsed()}>

View file

@ -1,6 +1,9 @@
import { createSignal, Show, For, onMount, createEffect, lazy } from 'solid-js';
import { render } from 'solid-js/web';
import { Github, Save, Upload, Trash2, X } from 'lucide-solid';
import SaveIcon from 'lucide-solid/icons/save';
import UploadIcon from 'lucide-solid/icons/upload';
import Trash2Icon from 'lucide-solid/icons/trash-2';
import XIcon from 'lucide-solid/icons/x';
import FileUpload from './components/FileUpload';
import { StatsData, ComparisonEntry, parseStats } from '@ns/core';
import './styles.css';
@ -184,7 +187,7 @@ function App() {
onClick={() => setShowManageSnapshots(true)}
title="Manage Snapshots"
>
<Trash2 size={16} />
<Trash2Icon size={16} />
</button>
</Show>
</nav>
@ -255,7 +258,7 @@ function App() {
rel="noopener noreferrer"
class="footer-link"
>
<Github size={16} />
<img src="/assets/github.svg" alt="GitHub" width={16} height={16} />
Source
</a>
</footer>
@ -266,7 +269,7 @@ function App() {
<div class="modal-header">
<h3>Manage Snapshots</h3>
<button class="close-btn" onClick={() => setShowManageSnapshots(false)}>
<X size={20} />
<XIcon size={20} />
</button>
</div>
<div class="snapshot-list-manage">
@ -281,7 +284,7 @@ function App() {
</span>
</div>
<button class="delete-btn" onClick={() => deleteSnapshot(entry.id)}>
<X size={16} />
<XIcon size={16} />
</button>
</div>
)}
@ -290,7 +293,7 @@ function App() {
<Show when={snapshots().length > 0}>
<div class="modal-actions">
<button class="danger-btn" onClick={clearAllSnapshots}>
<Trash2 size={16} />
<Trash2Icon size={16} />
Clear All
</button>
</div>
@ -306,10 +309,10 @@ function App() {
onClick={() => setShowSaveDialog(true)}
title="Save Snapshot"
>
<Save size={20} />
<SaveIcon size={20} />
</button>
<button class="action-btn clear" onClick={() => setCurrentStats(null)} title="Load New">
<Upload size={20} />
<UploadIcon size={20} />
</button>
</div>
</Show>

View file

@ -168,6 +168,10 @@ body {
transition: color 0.2s;
}
.footer-link img {
fill: currentColor;
}
.footer-link:hover {
color: var(--text-primary);
}

View file

@ -1,8 +1,16 @@
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import { fileURLToPath } from 'node:url';
export default defineConfig({
plugins: [solidPlugin()],
resolve: {
alias: {
'lucide-solid/icons': fileURLToPath(
new URL('./node_modules/lucide-solid/dist/source/icons', import.meta.url),
),
},
},
base: process.env.GITHUB_PAGES ? '/nix-evaluator-stats/' : './',
server: {
port: 3000,