140 lines
4.6 KiB
TypeScript
140 lines
4.6 KiB
TypeScript
import * as React from "react"
|
||
|
||
/**
|
||
* GebOS line icons drawn on the lucide grid (24×24, currentColor stroke) for
|
||
* the motifs lucide has no equivalent of. Stroke is a hair lighter than
|
||
* lucide's 2 because these render large (≈48px) in feature bands.
|
||
*/
|
||
function LineIcon({
|
||
strokeWidth = 1.6,
|
||
children,
|
||
...props
|
||
}: React.ComponentProps<"svg">) {
|
||
return (
|
||
<svg
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
width="24"
|
||
height="24"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
strokeWidth={strokeWidth}
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
aria-hidden="true"
|
||
{...props}
|
||
>
|
||
{children}
|
||
</svg>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Euro glyph inside a ring: costs stay transparent and under control.
|
||
* lucide has the bare glyph only, so it is shrunk about the icon centre and
|
||
* its stroke width divided by the same factor to keep the ring's weight.
|
||
*/
|
||
function EuroCircleIcon({
|
||
strokeWidth = 1.6,
|
||
...props
|
||
}: React.ComponentProps<"svg">) {
|
||
const glyphScale = 0.52
|
||
return (
|
||
<LineIcon strokeWidth={strokeWidth} {...props}>
|
||
<circle cx="12" cy="12" r="9.6" />
|
||
<g
|
||
transform={`translate(12 12) scale(${glyphScale}) translate(-12 -12)`}
|
||
strokeWidth={Number(strokeWidth) / glyphScale}
|
||
>
|
||
<path d="M4 10h12" />
|
||
<path d="M4 14h9" />
|
||
<path d="M19 6a7.7 7.7 0 0 0-5.2-2A7.9 7.9 0 0 0 6 12c0 4.4 3.5 8 7.8 8 2 0 3.8-.8 5.2-2" />
|
||
</g>
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
/** Cycle arrows around a radio dot: hardware that arrives ready to run. */
|
||
function PreconfiguredIcon(props: React.ComponentProps<"svg">) {
|
||
return (
|
||
<LineIcon {...props}>
|
||
<path d="M3.2 10.13A9 9 0 0 1 20.8 10.13" />
|
||
<path d="M22.11 7.66 20.8 10.13 18.59 8.41" />
|
||
<path d="M20.8 13.87A9 9 0 0 1 3.2 13.87" />
|
||
<path d="M1.89 16.34 3.2 13.87 5.41 15.59" />
|
||
<circle cx="10" cy="12" r="1.2" fill="currentColor" stroke="none" />
|
||
<path d="M11.93 9.7A3 3 0 0 1 11.93 14.3" />
|
||
<path d="M13.41 7.94A5.3 5.3 0 0 1 13.41 16.06" />
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Wrench crossed with a screwdriver: install it yourself or hand it to a
|
||
* trade. Wrench contour is lucide's, mirrored onto the "\" diagonal so the
|
||
* jaw sits top-left; the screwdriver is drawn along +x and rotated onto "/",
|
||
* nudged clear of the jaw and filled with the card surface so it reads as
|
||
* lying on top of the wrench.
|
||
*/
|
||
function CrossedToolsIcon(props: React.ComponentProps<"svg">) {
|
||
return (
|
||
<LineIcon {...props}>
|
||
<path
|
||
transform="translate(24 0) scale(-1 1)"
|
||
d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"
|
||
/>
|
||
<path
|
||
transform="rotate(-45 12 12) translate(-0.6 1.2)"
|
||
fill="var(--card)"
|
||
d="M5.7 9.9H10.4V10.5H11.8V11.25H17.6L18.3 10.95H20.4V13.05H18.3L17.6 12.75H11.8V13.5H10.4V14.1H5.7A2.1 2.1 0 0 1 5.7 9.9Z"
|
||
/>
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
/** Cloud with a bolt: metering data flows and is processed without anyone. */
|
||
function CloudAutomationIcon(props: React.ComponentProps<"svg">) {
|
||
return (
|
||
<LineIcon {...props}>
|
||
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
|
||
<path d="M13.1 10.7 10.5 14.6h1.85l-.68 2.6 2.6-3.9h-1.85z" />
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
/** Dashboard gauge on a screen: every building and meter in one portal. */
|
||
function PortalGaugeIcon(props: React.ComponentProps<"svg">) {
|
||
return (
|
||
<LineIcon {...props}>
|
||
<rect x="4.6" y="4" width="14.8" height="13.8" rx="2.4" />
|
||
<path d="M3 20h18" />
|
||
<path d="M8.02 13.18A4 4 0 0 1 15.98 13.18" />
|
||
<path d="M12 13.6 13.89 10.9" />
|
||
<circle cx="12" cy="13.6" r="0.8" fill="currentColor" stroke="none" />
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Germany's silhouette: the metering data never leaves the country. Traced
|
||
* from the border's waypoints, projected equirectangular at 51° N so the
|
||
* proportions hold, then thinned to the points that survive at icon size.
|
||
*/
|
||
function GermanyIcon(props: React.ComponentProps<"svg">) {
|
||
return (
|
||
<LineIcon {...props}>
|
||
<path d="M8.62 1.7 10.34 2.23 11.5 3.6 13.21 3.33 12.74 4.59 13.73 4.72 17.03 2.93 18.42 4.67 18.24 7.23 19.67 12.07 19.38 12.84 14.98 14.47 17.06 18.96 16.04 20.06 16.32 21.55 14.98 21.34 11.75 22.3 9.76 21.39 7.22 21.61 7.24 19.68 8 17.86 5.98 17.41 4.77 15.06 4.33 12.33 4.72 10.2 5.95 9.26 5.73 8.33 6.32 8.06 6.57 6.46 6.23 6.19 9.09 4.77 9.34 3.12Z" />
|
||
</LineIcon>
|
||
)
|
||
}
|
||
|
||
export {
|
||
CloudAutomationIcon,
|
||
CrossedToolsIcon,
|
||
EuroCircleIcon,
|
||
GermanyIcon,
|
||
LineIcon,
|
||
PortalGaugeIcon,
|
||
PreconfiguredIcon,
|
||
}
|