mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
feat: Add dark theme charts ref:
This commit is contained in:
@@ -489,7 +489,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -511,7 +511,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -530,7 +530,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -547,7 +547,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
@@ -679,7 +679,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -702,7 +702,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 130;
|
CURRENT_PROJECT_VERSION = 131;
|
||||||
DEVELOPMENT_TEAM = JND55328G8;
|
DEVELOPMENT_TEAM = JND55328G8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>130</string>
|
<string>131</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 2026.0402.1+44
|
version: 2026.0403.1+45
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.2
|
sdk: ^3.9.2
|
||||||
|
|||||||
@@ -504,12 +504,12 @@ function CompositionChart({ points }: { points: CompositionPoint[] }) {
|
|||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="humanFill" x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id="humanFill" x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="0%" stopColor="hsl(217, 91%, 60%)" stopOpacity={0.5} />
|
<stop offset="0%" stopColor="hsl(var(--chart-primary))" stopOpacity={0.5} />
|
||||||
<stop offset="100%" stopColor="hsl(217, 91%, 60%)" stopOpacity={0.1} />
|
<stop offset="100%" stopColor="hsl(var(--chart-primary))" stopOpacity={0.1} />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="overheadFill" x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id="overheadFill" x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="0%" stopColor="hsl(206, 22%, 75%)" stopOpacity={0.5} />
|
<stop offset="0%" stopColor="hsl(var(--chart-secondary))" stopOpacity={0.5} />
|
||||||
<stop offset="100%" stopColor="hsl(206, 22%, 75%)" stopOpacity={0.1} />
|
<stop offset="100%" stopColor="hsl(var(--chart-secondary))" stopOpacity={0.1} />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
@@ -517,21 +517,21 @@ function CompositionChart({ points }: { points: CompositionPoint[] }) {
|
|||||||
const y = (1 - val / maxVal) * innerH;
|
const y = (1 - val / maxVal) * innerH;
|
||||||
return (
|
return (
|
||||||
<g key={val}>
|
<g key={val}>
|
||||||
<line x1={0} y1={y} x2={innerW} y2={y} stroke="hsl(206, 22%, 87%)" strokeWidth={0.3} />
|
<line x1={0} y1={y} x2={innerW} y2={y} stroke="hsl(var(--chart-grid))" strokeWidth={0.3} />
|
||||||
<text x={-6} y={y} textAnchor="end" dominantBaseline="middle" fill="hsl(208, 19%, 55%)" fontSize={3.2} fontFamily="var(--font-sans)">
|
<text x={-6} y={y} textAnchor="end" dominantBaseline="middle" fill="hsl(var(--chart-label))" fontSize={3.2} fontFamily="var(--font-sans)">
|
||||||
{formatCompact(val)}
|
{formatCompact(val)}
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<line x1={0} y1={innerH} x2={innerW} y2={innerH} stroke="hsl(206, 22%, 87%)" strokeWidth={0.4} />
|
<line x1={0} y1={innerH} x2={innerW} y2={innerH} stroke="hsl(var(--chart-grid))" strokeWidth={0.4} />
|
||||||
|
|
||||||
<path d={overheadArea} fill="url(#overheadFill)" />
|
<path d={overheadArea} fill="url(#overheadFill)" />
|
||||||
<path d={humanArea} fill="url(#humanFill)" />
|
<path d={humanArea} fill="url(#humanFill)" />
|
||||||
|
|
||||||
{/* X labels */}
|
{/* X labels */}
|
||||||
{points.map((p, i) => (i % labelStep === 0 || i === count - 1) ? (
|
{points.map((p, i) => (i % labelStep === 0 || i === count - 1) ? (
|
||||||
<text key={i} x={xs[i] * innerW} y={innerH + 10} textAnchor="middle" fill="hsl(208, 19%, 55%)" fontSize={2.8} fontFamily="var(--font-sans)">
|
<text key={i} x={xs[i] * innerW} y={innerH + 10} textAnchor="middle" fill="hsl(var(--chart-label))" fontSize={2.8} fontFamily="var(--font-sans)">
|
||||||
{p.label.slice(5)}
|
{p.label.slice(5)}
|
||||||
</text>
|
</text>
|
||||||
) : null)}
|
) : null)}
|
||||||
@@ -550,7 +550,7 @@ function CompositionChart({ points }: { points: CompositionPoint[] }) {
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
{hover !== null && (
|
{hover !== null && (
|
||||||
<line x1={xs[hover] * innerW} y1={0} x2={xs[hover] * innerW} y2={innerH} stroke="hsl(217, 91%, 60%)" strokeWidth={0.3} strokeDasharray="1.5 1" />
|
<line x1={xs[hover] * innerW} y1={0} x2={xs[hover] * innerW} y2={innerH} stroke="hsl(var(--chart-primary))" strokeWidth={0.3} strokeDasharray="1.5 1" />
|
||||||
)}
|
)}
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
@@ -630,12 +630,12 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
>
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="areaFill" x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id="areaFill" x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="0%" stopColor="hsl(217, 91%, 60%)" stopOpacity={0.35} />
|
<stop offset="0%" stopColor="hsl(var(--chart-primary))" stopOpacity={0.35} />
|
||||||
<stop offset="100%" stopColor="hsl(217, 91%, 60%)" stopOpacity={0.03} />
|
<stop offset="100%" stopColor="hsl(var(--chart-primary))" stopOpacity={0.03} />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<linearGradient id="lineStroke" x1="0" y1="0" x2="1" y2="0">
|
<linearGradient id="lineStroke" x1="0" y1="0" x2="1" y2="0">
|
||||||
<stop offset="0%" stopColor="hsl(217, 91%, 65%)" />
|
<stop offset="0%" stopColor="hsl(var(--chart-primary-light))" />
|
||||||
<stop offset="100%" stopColor="hsl(217, 70%, 50%)" />
|
<stop offset="100%" stopColor="hsl(var(--chart-primary-dark))" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
@@ -644,8 +644,8 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
const y = (1 - val / maxValue) * innerH;
|
const y = (1 - val / maxValue) * innerH;
|
||||||
return (
|
return (
|
||||||
<g key={val}>
|
<g key={val}>
|
||||||
<line x1={0} y1={y} x2={innerW} y2={y} stroke="hsl(206, 22%, 87%)" strokeWidth={0.3} />
|
<line x1={0} y1={y} x2={innerW} y2={y} stroke="hsl(var(--chart-grid))" strokeWidth={0.3} />
|
||||||
<text x={-6} y={y} textAnchor="end" dominantBaseline="middle" fill="hsl(208, 19%, 55%)" fontSize={3.2} fontFamily="var(--font-sans)">
|
<text x={-6} y={y} textAnchor="end" dominantBaseline="middle" fill="hsl(var(--chart-label))" fontSize={3.2} fontFamily="var(--font-sans)">
|
||||||
{formatCompact(val)}
|
{formatCompact(val)}
|
||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
@@ -653,7 +653,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
})}
|
})}
|
||||||
|
|
||||||
{/* baseline */}
|
{/* baseline */}
|
||||||
<line x1={0} y1={innerH} x2={innerW} y2={innerH} stroke="hsl(206, 22%, 87%)" strokeWidth={0.4} />
|
<line x1={0} y1={innerH} x2={innerW} y2={innerH} stroke="hsl(var(--chart-grid))" strokeWidth={0.4} />
|
||||||
|
|
||||||
{/* area fill */}
|
{/* area fill */}
|
||||||
<path d={areaPath} fill="url(#areaFill)" />
|
<path d={areaPath} fill="url(#areaFill)" />
|
||||||
@@ -666,7 +666,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
cx={xs[peakIdx] * innerW}
|
cx={xs[peakIdx] * innerW}
|
||||||
cy={ys[peakIdx] * innerH}
|
cy={ys[peakIdx] * innerH}
|
||||||
r={1.5}
|
r={1.5}
|
||||||
fill="hsl(217, 91%, 60%)"
|
fill="hsl(var(--chart-primary))"
|
||||||
stroke="white"
|
stroke="white"
|
||||||
strokeWidth={0.6}
|
strokeWidth={0.6}
|
||||||
/>
|
/>
|
||||||
@@ -676,7 +676,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
x={xs[peakIdx] * innerW}
|
x={xs[peakIdx] * innerW}
|
||||||
y={ys[peakIdx] * innerH - 4}
|
y={ys[peakIdx] * innerH - 4}
|
||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
fill="hsl(217, 91%, 45%)"
|
fill="hsl(var(--chart-primary-accent))"
|
||||||
fontSize={3}
|
fontSize={3}
|
||||||
fontWeight={600}
|
fontWeight={600}
|
||||||
fontFamily="var(--font-sans)"
|
fontFamily="var(--font-sans)"
|
||||||
@@ -691,7 +691,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
x={xs[i] * innerW}
|
x={xs[i] * innerW}
|
||||||
y={innerH + 10}
|
y={innerH + 10}
|
||||||
textAnchor="middle"
|
textAnchor="middle"
|
||||||
fill="hsl(208, 19%, 55%)"
|
fill="hsl(var(--chart-label))"
|
||||||
fontSize={2.8}
|
fontSize={2.8}
|
||||||
fontFamily="var(--font-sans)"
|
fontFamily="var(--font-sans)"
|
||||||
>
|
>
|
||||||
@@ -723,7 +723,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
y1={0}
|
y1={0}
|
||||||
x2={xs[hover] * innerW}
|
x2={xs[hover] * innerW}
|
||||||
y2={innerH}
|
y2={innerH}
|
||||||
stroke="hsl(217, 91%, 60%)"
|
stroke="hsl(var(--chart-primary))"
|
||||||
strokeWidth={0.3}
|
strokeWidth={0.3}
|
||||||
strokeDasharray="1.5 1"
|
strokeDasharray="1.5 1"
|
||||||
/>
|
/>
|
||||||
@@ -732,7 +732,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max
|
|||||||
cy={ys[hover] * innerH}
|
cy={ys[hover] * innerH}
|
||||||
r={1.2}
|
r={1.2}
|
||||||
fill="white"
|
fill="white"
|
||||||
stroke="hsl(217, 91%, 60%)"
|
stroke="hsl(var(--chart-primary))"
|
||||||
strokeWidth={0.6}
|
strokeWidth={0.6}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const badgeVariants = cva(
|
|||||||
default: "border-transparent bg-primary text-primary-foreground",
|
default: "border-transparent bg-primary text-primary-foreground",
|
||||||
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
secondary: "border-transparent bg-secondary text-secondary-foreground",
|
||||||
destructive: "border-transparent bg-destructive text-destructive-foreground",
|
destructive: "border-transparent bg-destructive text-destructive-foreground",
|
||||||
outline: "text-foreground bg-white/60",
|
outline: "text-foreground bg-card/60",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) {
|
|||||||
<div
|
<div
|
||||||
data-slot="card"
|
data-slot="card"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-card/88 text-card-foreground flex flex-col gap-6 rounded-[1.5rem] border border-white/70 py-6 shadow-[0_18px_48px_rgba(16,33,47,0.08)] backdrop-blur-md",
|
"bg-card/88 text-card-foreground flex flex-col gap-6 rounded-[1.5rem] border border-border/50 py-6 shadow-[0_18px_48px_rgba(16,33,47,0.08)] dark:shadow-[0_18px_48px_rgba(0,0,0,0.3)] backdrop-blur-md",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -46,6 +46,40 @@
|
|||||||
--input: 220 20% 88%;
|
--input: 220 20% 88%;
|
||||||
--ring: 217 91% 60%;
|
--ring: 217 91% 60%;
|
||||||
--radius: 1rem;
|
--radius: 1rem;
|
||||||
|
--chart-grid: 220 20% 88%;
|
||||||
|
--chart-label: 220 13% 46%;
|
||||||
|
--chart-primary: 217 91% 60%;
|
||||||
|
--chart-primary-light: 217 91% 65%;
|
||||||
|
--chart-primary-dark: 217 70% 50%;
|
||||||
|
--chart-primary-accent: 217 91% 45%;
|
||||||
|
--chart-secondary: 206 22% 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 222 47% 8%;
|
||||||
|
--foreground: 220 20% 90%;
|
||||||
|
--card: 222 40% 12%;
|
||||||
|
--card-foreground: 220 20% 90%;
|
||||||
|
--primary: 217 91% 60%;
|
||||||
|
--primary-foreground: 0 0% 100%;
|
||||||
|
--secondary: 220 30% 18%;
|
||||||
|
--secondary-foreground: 220 20% 90%;
|
||||||
|
--muted: 220 20% 16%;
|
||||||
|
--muted-foreground: 220 13% 55%;
|
||||||
|
--accent: 217 91% 60%;
|
||||||
|
--accent-foreground: 0 0% 100%;
|
||||||
|
--destructive: 0 72% 51%;
|
||||||
|
--destructive-foreground: 0 0% 100%;
|
||||||
|
--border: 220 20% 20%;
|
||||||
|
--input: 220 20% 20%;
|
||||||
|
--ring: 217 91% 60%;
|
||||||
|
--chart-grid: 220 20% 22%;
|
||||||
|
--chart-label: 220 13% 50%;
|
||||||
|
--chart-primary: 217 91% 65%;
|
||||||
|
--chart-primary-light: 217 91% 70%;
|
||||||
|
--chart-primary-dark: 217 70% 55%;
|
||||||
|
--chart-primary-accent: 217 91% 55%;
|
||||||
|
--chart-secondary: 220 20% 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -54,14 +88,12 @@
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
|
color-scheme: light dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background:
|
background: hsl(var(--background));
|
||||||
radial-gradient(circle at top left, hsl(217 91% 60% / 0.10), transparent 30%),
|
|
||||||
radial-gradient(circle at top right, hsl(217 70% 50% / 0.08), transparent 24%),
|
|
||||||
linear-gradient(180deg, #f5f8fc 0%, hsl(var(--background)) 100%);
|
|
||||||
color: hsl(var(--foreground));
|
color: hsl(var(--foreground));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,11 @@ import "../index.css";
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<slot />
|
<slot />
|
||||||
|
<script>
|
||||||
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
function apply(e) { document.documentElement.classList.toggle("dark", e.matches); }
|
||||||
|
apply(mq);
|
||||||
|
mq.addEventListener("change", apply);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user