@hashsome/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/entities/action-button.d.ts +17 -0
- package/dist/entities/action-button.js +56 -0
- package/dist/entities/action-button.js.map +1 -0
- package/dist/entities/artwork-ring.d.ts +17 -0
- package/dist/entities/artwork-ring.js +89 -0
- package/dist/entities/artwork-ring.js.map +1 -0
- package/dist/entities/climate-tile.d.ts +20 -0
- package/dist/entities/climate-tile.js +98 -0
- package/dist/entities/climate-tile.js.map +1 -0
- package/dist/entities/light-color.d.ts +52 -0
- package/dist/entities/light-color.js +148 -0
- package/dist/entities/light-color.js.map +1 -0
- package/dist/entities/light-tile.d.ts +24 -0
- package/dist/entities/light-tile.js +139 -0
- package/dist/entities/light-tile.js.map +1 -0
- package/dist/entities/media-browser.d.ts +15 -0
- package/dist/entities/media-browser.js +67 -0
- package/dist/entities/media-browser.js.map +1 -0
- package/dist/entities/media-controls.d.ts +20 -0
- package/dist/entities/media-controls.js +53 -0
- package/dist/entities/media-controls.js.map +1 -0
- package/dist/entities/media-player-bar.d.ts +14 -0
- package/dist/entities/media-player-bar.js +78 -0
- package/dist/entities/media-player-bar.js.map +1 -0
- package/dist/entities/media-player-body.d.ts +16 -0
- package/dist/entities/media-player-body.js +18 -0
- package/dist/entities/media-player-body.js.map +1 -0
- package/dist/entities/media-player-column.d.ts +18 -0
- package/dist/entities/media-player-column.js +34 -0
- package/dist/entities/media-player-column.js.map +1 -0
- package/dist/entities/media-player-page.d.ts +12 -0
- package/dist/entities/media-player-page.js +13 -0
- package/dist/entities/media-player-page.js.map +1 -0
- package/dist/entities/media-progress.d.ts +7 -0
- package/dist/entities/media-progress.js +30 -0
- package/dist/entities/media-progress.js.map +1 -0
- package/dist/entities/media-seek.d.ts +9 -0
- package/dist/entities/media-seek.js +19 -0
- package/dist/entities/media-seek.js.map +1 -0
- package/dist/entities/nav-dock.d.ts +13 -0
- package/dist/entities/nav-dock.js +22 -0
- package/dist/entities/nav-dock.js.map +1 -0
- package/dist/entities/nav-rail.d.ts +19 -0
- package/dist/entities/nav-rail.js +18 -0
- package/dist/entities/nav-rail.js.map +1 -0
- package/dist/entities/now-playing.d.ts +20 -0
- package/dist/entities/now-playing.js +34 -0
- package/dist/entities/now-playing.js.map +1 -0
- package/dist/entities/scene-button.d.ts +13 -0
- package/dist/entities/scene-button.js +6 -0
- package/dist/entities/scene-button.js.map +1 -0
- package/dist/entities/seek-line.d.ts +9 -0
- package/dist/entities/seek-line.js +71 -0
- package/dist/entities/seek-line.js.map +1 -0
- package/dist/entities/sensor-readout.d.ts +28 -0
- package/dist/entities/sensor-readout.js +95 -0
- package/dist/entities/sensor-readout.js.map +1 -0
- package/dist/entities/top-bar.d.ts +68 -0
- package/dist/entities/top-bar.js +248 -0
- package/dist/entities/top-bar.js.map +1 -0
- package/dist/entity-handle.d.ts +21 -0
- package/dist/entity-handle.js +16 -0
- package/dist/entity-handle.js.map +1 -0
- package/dist/gallery/fixtures.d.ts +4 -0
- package/dist/gallery/fixtures.js +119 -0
- package/dist/gallery/fixtures.js.map +1 -0
- package/dist/gallery/gallery.d.ts +9 -0
- package/dist/gallery/gallery.js +355 -0
- package/dist/gallery/gallery.js.map +1 -0
- package/dist/gallery/index.d.ts +2 -0
- package/dist/gallery/index.js +2 -0
- package/dist/gallery/index.js.map +1 -0
- package/dist/gallery/props-data.d.ts +10 -0
- package/dist/gallery/props-data.js +718 -0
- package/dist/gallery/props-data.js.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.js +53 -0
- package/dist/hooks.js.map +1 -0
- package/dist/icon-data.d.ts +6 -0
- package/dist/icon-data.js +59193 -0
- package/dist/icon-data.js.map +1 -0
- package/dist/icon.d.ts +9 -0
- package/dist/icon.js +28 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/cover.d.ts +5 -0
- package/dist/layout/cover.js +8 -0
- package/dist/layout/cover.js.map +1 -0
- package/dist/layout/date-time-field.d.ts +15 -0
- package/dist/layout/date-time-field.js +108 -0
- package/dist/layout/date-time-field.js.map +1 -0
- package/dist/layout/detail-provider.d.ts +22 -0
- package/dist/layout/detail-provider.js +26 -0
- package/dist/layout/detail-provider.js.map +1 -0
- package/dist/layout/drawer-controls.d.ts +46 -0
- package/dist/layout/drawer-controls.js +93 -0
- package/dist/layout/drawer-controls.js.map +1 -0
- package/dist/layout/energy-chart.d.ts +37 -0
- package/dist/layout/energy-chart.js +85 -0
- package/dist/layout/energy-chart.js.map +1 -0
- package/dist/layout/energy-usage.d.ts +6 -0
- package/dist/layout/energy-usage.js +18 -0
- package/dist/layout/energy-usage.js.map +1 -0
- package/dist/layout/entity-drawer.d.ts +15 -0
- package/dist/layout/entity-drawer.js +77 -0
- package/dist/layout/entity-drawer.js.map +1 -0
- package/dist/layout/fade-scroll.d.ts +14 -0
- package/dist/layout/fade-scroll.js +59 -0
- package/dist/layout/fade-scroll.js.map +1 -0
- package/dist/layout/grid.d.ts +9 -0
- package/dist/layout/grid.js +6 -0
- package/dist/layout/grid.js.map +1 -0
- package/dist/layout/history-section.d.ts +19 -0
- package/dist/layout/history-section.js +39 -0
- package/dist/layout/history-section.js.map +1 -0
- package/dist/layout/hold-progress.d.ts +2 -0
- package/dist/layout/hold-progress.js +9 -0
- package/dist/layout/hold-progress.js.map +1 -0
- package/dist/layout/icon-button-styles.d.ts +9 -0
- package/dist/layout/icon-button-styles.js +28 -0
- package/dist/layout/icon-button-styles.js.map +1 -0
- package/dist/layout/page.d.ts +17 -0
- package/dist/layout/page.js +29 -0
- package/dist/layout/page.js.map +1 -0
- package/dist/layout/plain-button.d.ts +11 -0
- package/dist/layout/plain-button.js +17 -0
- package/dist/layout/plain-button.js.map +1 -0
- package/dist/layout/room-header.d.ts +12 -0
- package/dist/layout/room-header.js +11 -0
- package/dist/layout/room-header.js.map +1 -0
- package/dist/layout/round-button.d.ts +13 -0
- package/dist/layout/round-button.js +19 -0
- package/dist/layout/round-button.js.map +1 -0
- package/dist/layout/sensor-history.d.ts +15 -0
- package/dist/layout/sensor-history.js +91 -0
- package/dist/layout/sensor-history.js.map +1 -0
- package/dist/layout/sensor-stats.d.ts +21 -0
- package/dist/layout/sensor-stats.js +79 -0
- package/dist/layout/sensor-stats.js.map +1 -0
- package/dist/layout/series-chart.d.ts +25 -0
- package/dist/layout/series-chart.js +46 -0
- package/dist/layout/series-chart.js.map +1 -0
- package/dist/layout/stepper.d.ts +10 -0
- package/dist/layout/stepper.js +12 -0
- package/dist/layout/stepper.js.map +1 -0
- package/dist/layout/swatch-row.d.ts +19 -0
- package/dist/layout/swatch-row.js +20 -0
- package/dist/layout/swatch-row.js.map +1 -0
- package/dist/layout/tile.d.ts +67 -0
- package/dist/layout/tile.js +207 -0
- package/dist/layout/tile.js.map +1 -0
- package/dist/layout/use-drawer.d.ts +33 -0
- package/dist/layout/use-drawer.js +34 -0
- package/dist/layout/use-drawer.js.map +1 -0
- package/dist/layout/use-hold.d.ts +21 -0
- package/dist/layout/use-hold.js +61 -0
- package/dist/layout/use-hold.js.map +1 -0
- package/dist/provider.d.ts +37 -0
- package/dist/provider.js +95 -0
- package/dist/provider.js.map +1 -0
- package/dist/status.d.ts +8 -0
- package/dist/status.js +27 -0
- package/dist/status.js.map +1 -0
- package/dist/theme/density.d.ts +16 -0
- package/dist/theme/density.js +7 -0
- package/dist/theme/density.js.map +1 -0
- package/dist/theme/global-styles.d.ts +5 -0
- package/dist/theme/global-styles.js +44 -0
- package/dist/theme/global-styles.js.map +1 -0
- package/dist/theme/index.d.ts +19 -0
- package/dist/theme/index.js +106 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/overrides.d.ts +28 -0
- package/dist/theme/overrides.js +24 -0
- package/dist/theme/overrides.js.map +1 -0
- package/dist/theme/tokens.d.ts +78 -0
- package/dist/theme/tokens.js +1 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/theme/use-typography.d.ts +4 -0
- package/dist/theme/use-typography.js +9 -0
- package/dist/theme/use-typography.js.map +1 -0
- package/dist/use-entity-history.d.ts +12 -0
- package/dist/use-entity-history.js +43 -0
- package/dist/use-entity-history.js.map +1 -0
- package/dist/use-media-browser.d.ts +31 -0
- package/dist/use-media-browser.js +87 -0
- package/dist/use-media-browser.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import type { ConnectionStatus, EntityRef, LinkStatus } from '@hashsome/core';
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
import type { IconName } from '../icon-data.ts';
|
|
5
|
+
/** One entry in the title's dashboard-switcher dropdown. */
|
|
6
|
+
export interface DashboardOption {
|
|
7
|
+
/** Matches the dashboard route id — switching navigates to `/{id}`, always its root. */
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
icon?: IconName;
|
|
11
|
+
}
|
|
12
|
+
export interface TopBarScene {
|
|
13
|
+
entity: EntityRef;
|
|
14
|
+
icon?: IconName;
|
|
15
|
+
/** A literal CSS color for this scene's dot (e.g. `#8B5CF6`) — scenes are meant to read as distinct at a glance, which the palette doesn't have enough colors for, so each app picks its own. Defaults to the theme's accent. */
|
|
16
|
+
color?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TopBarProps {
|
|
19
|
+
/** The dashboard's name. Becomes a dashboard switcher when `dashboards` has two or more entries. */
|
|
20
|
+
title: string;
|
|
21
|
+
/** Other dashboards to switch to from the title. Under 2 entries renders a plain title. */
|
|
22
|
+
dashboards?: DashboardOption[];
|
|
23
|
+
/** Compact circular buttons that fire `scene.turn_on` directly (not the `Tile`-based `SceneButton`); a bare entity ref uses the default icon and an auto-assigned color, or pass `{ entity, icon, color }` to pick either. */
|
|
24
|
+
scenes?: (EntityRef | TopBarScene)[];
|
|
25
|
+
/** Current weather as a pill with an icon for the sky and a rounded whole-degree reading. A weather entity, like `ha:weather.forecast_home`, shows its real condition; a plain sensor, e.g. an outdoor temperature, gets a fixed sun. */
|
|
26
|
+
weather?: EntityRef;
|
|
27
|
+
/** Your own component(s) for the right-hand side, after the weather: a security mode picker, a custom status. Whatever it is, it sits in the bar's row and is yours to style. */
|
|
28
|
+
extra?: ReactNode;
|
|
29
|
+
/** A sensor reflecting overall home/away status (e.g. a binary presence sensor), shown as a chip. */
|
|
30
|
+
presence?: EntityRef;
|
|
31
|
+
/** Individual people, as refs like `ha:person.dan`, shown as an overlapping avatar stack; anyone who is away is dimmed. */
|
|
32
|
+
people?: EntityRef[];
|
|
33
|
+
/** Avatars show the person's own picture; this only colors the initial of those without one — each person gets one color from the list, always the same one. Optional: a built-in set of six is used unless you want your own, e.g. `['#8B5CF6', '#34D399']`. */
|
|
34
|
+
presenceColors?: readonly string[];
|
|
35
|
+
/** Default `true`. */
|
|
36
|
+
showClock?: boolean;
|
|
37
|
+
/** Short date pill before the weather. Default `true`. */
|
|
38
|
+
showDate?: boolean;
|
|
39
|
+
/** `'auto'` follows the browser's locale (browsers don't read the OS 12/24h setting, so an `en-US` browser shows AM/PM); `'12h'`/`'24h'` force it. Default `'auto'`. */
|
|
40
|
+
clockFormat?: 'auto' | '12h' | '24h';
|
|
41
|
+
/** A status dot at the far right — green when the runtime and every integration are up; click it
|
|
42
|
+
* for the details. Default `true`. */
|
|
43
|
+
showStatus?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Shared chrome above a dashboard page's content: title (optionally a dashboard switcher), scene
|
|
46
|
+
* shortcuts, and live status (weather, presence, a clock). Composes freely — every prop but
|
|
47
|
+
* `title` is optional. */
|
|
48
|
+
export declare function TopBar({ title, dashboards, scenes, weather, extra, presence, people, presenceColors, showClock, showDate, clockFormat, showStatus, }: TopBarProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
49
|
+
export interface SystemStatusProps {
|
|
50
|
+
/** Overrides the live runtime link status — for demos (the gallery) rather than real dashboards. */
|
|
51
|
+
link?: LinkStatus;
|
|
52
|
+
/** Overrides the live per-integration statuses, keyed by integration id. */
|
|
53
|
+
statuses?: Readonly<Record<string, ConnectionStatus>>;
|
|
54
|
+
/** Start with the detail popover open. Default `false`. */
|
|
55
|
+
defaultOpen?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** One dot summarising the runtime link and every integration — green when all are up, amber while
|
|
58
|
+
* something connects, red when something is down; click for per-system detail. `TopBar` renders it
|
|
59
|
+
* from live status, so it only needs the props above for demos. */
|
|
60
|
+
export declare function SystemStatus({ link: linkOverride, statuses: statusesOverride, defaultOpen, }: SystemStatusProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
61
|
+
export interface PresenceStackProps {
|
|
62
|
+
/** People, as refs like `ha:person.dan`: one avatar each (their picture, or a colored initial). Someone who is away is dimmed and grayscale. */
|
|
63
|
+
entities: EntityRef[];
|
|
64
|
+
/** Only colors the initial of people without a picture; each gets one, always the same. Optional: a built-in set of six is used by default. */
|
|
65
|
+
colors?: readonly string[];
|
|
66
|
+
}
|
|
67
|
+
/** Overlapping avatar circles for a handful of `person.*` entities. */
|
|
68
|
+
export declare function PresenceStack({ entities, colors }: PresenceStackProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Box, Flex, Typography } from 'e-prim';
|
|
3
|
+
import { PlainButton } from '../layout/plain-button.js';
|
|
4
|
+
import { useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { useLocation, useNavigate } from 'react-router';
|
|
6
|
+
import { fallbackName } from '../entity-handle.js';
|
|
7
|
+
import { useConnectionStatus, useEntity, useEntityHandle, useIntegrationStatuses, } from '../hooks.js';
|
|
8
|
+
import { Icon } from '../icon.js';
|
|
9
|
+
import { statusLabels } from '../status.js';
|
|
10
|
+
import { SensorReadout } from './sensor-readout.js';
|
|
11
|
+
/** The colors presence avatars without a picture fall back to when `presenceColors` isn't given. */
|
|
12
|
+
const DEFAULT_PRESENCE_COLORS = ['#8B5CF6', '#34D399', '#60A5FA', '#F472B6', '#FBBF24', '#FB923C'];
|
|
13
|
+
/** Picks one of `colors` for `id`, the same one every time (a presence avatar's color). */
|
|
14
|
+
function colorForId(id, colors) {
|
|
15
|
+
let hash = 0;
|
|
16
|
+
for (let i = 0; i < id.length; i++) {
|
|
17
|
+
hash = (hash * 31 + id.charCodeAt(i)) >>> 0;
|
|
18
|
+
}
|
|
19
|
+
return colors[hash % colors.length];
|
|
20
|
+
}
|
|
21
|
+
/** Closes a popover (calls `close`) on a press outside `ref` or on Escape, while it is `open`. */
|
|
22
|
+
function useDismiss(open, close, ref) {
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!open) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const onPointer = (event) => {
|
|
28
|
+
if (!ref.current?.contains(event.target)) {
|
|
29
|
+
close();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const onKey = (event) => {
|
|
33
|
+
if (event.key === 'Escape') {
|
|
34
|
+
close();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
document.addEventListener('pointerdown', onPointer);
|
|
38
|
+
document.addEventListener('keydown', onKey);
|
|
39
|
+
return () => {
|
|
40
|
+
document.removeEventListener('pointerdown', onPointer);
|
|
41
|
+
document.removeEventListener('keydown', onKey);
|
|
42
|
+
};
|
|
43
|
+
// `close` is a fresh function each render but only ever sets state; re-subscribing for it would
|
|
44
|
+
// do nothing but churn listeners.
|
|
45
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
}, [open, ref]);
|
|
47
|
+
}
|
|
48
|
+
/** Shared chrome above a dashboard page's content: title (optionally a dashboard switcher), scene
|
|
49
|
+
* shortcuts, and live status (weather, presence, a clock). Composes freely — every prop but
|
|
50
|
+
* `title` is optional. */
|
|
51
|
+
export function TopBar({ title, dashboards, scenes, weather, extra, presence, people, presenceColors, showClock = true, showDate = true, clockFormat = 'auto', showStatus = true, }) {
|
|
52
|
+
return (_jsxs(Flex, { align: "center", justify: "space-between", gap: 4, py: 2, children: [_jsxs(Flex, { align: "center", gap: 3, children: [dashboards && dashboards.length > 1 ? (_jsx(DashboardSwitcher, { title: title, dashboards: dashboards })) : (_jsx(Typography, { as: "h1", variant: "title", children: title })), scenes?.length ? (_jsx(Flex, { align: "center", gap: 2.5, children: scenes.map((scene) => {
|
|
53
|
+
const { entity, icon, color } = typeof scene === 'string' ? { entity: scene } : scene;
|
|
54
|
+
return (_jsx(SceneDot, { entity: entity, ...(color ? { color } : {}), ...(icon ? { icon } : {}) }, entity));
|
|
55
|
+
}) })) : null] }), _jsxs(Flex, { align: "center", gap: 3, children: [showDate ? _jsx(DateChip, {}) : null, weather ? _jsx(WeatherChip, { entity: weather }) : null, extra, presence ? (_jsx(StatusChip, { children: _jsx(SensorReadout, { entity: presence, drawer: false }) })) : null, people?.length ? (_jsx(PresenceStack, { entities: people, ...(presenceColors ? { colors: presenceColors } : {}) })) : null, showClock ? _jsx(Clock, { format: clockFormat }) : null, showStatus ? _jsx(SystemStatus, {}) : null] })] }));
|
|
56
|
+
}
|
|
57
|
+
function DashboardSwitcher({ title, dashboards, }) {
|
|
58
|
+
const [open, setOpen] = useState(false);
|
|
59
|
+
const navigate = useNavigate();
|
|
60
|
+
const { pathname } = useLocation();
|
|
61
|
+
const ref = useRef(null);
|
|
62
|
+
useDismiss(open, () => setOpen(false), ref);
|
|
63
|
+
// The dashboard being shown: the one whose route the address is under, else the one the title names.
|
|
64
|
+
const current = dashboards.find((d) => pathname === `/${d.id}` || pathname.startsWith(`/${d.id}/`)) ??
|
|
65
|
+
dashboards.find((d) => d.title === title);
|
|
66
|
+
return (_jsxs(Flex, { ref: ref, position: "relative", children: [_jsxs(Flex, { as: "button", type: "button", onClick: () => setOpen((o) => !o), "aria-haspopup": "listbox", "aria-expanded": open, align: "center", justify: "center", gap: 2, cursor: "pointer", color: "text", background: "surface", border: true, height: 40, px: 4, radius: "chrome", children: [current?.icon ? _jsx(Icon, { name: current.icon, size: 20 }) : null, _jsx(Typography, { as: "h1", variant: "title", children: title }), _jsx(Icon, { name: "lu:chevron-down", size: 20 })] }), open ? (_jsx(Flex, { as: "ul", role: "listbox", direction: "column", background: "surfaceRaised", radius: "row", shadow: "drawer", p: 1.5, gap: 0.5, position: "absolute", zIndex: "dropdown", mt: 2, minWidth: "100%", css: { top: '100%', left: 0, listStyle: 'none', whiteSpace: 'nowrap' }, children: dashboards.map((d) => {
|
|
67
|
+
const active = d.id === current?.id;
|
|
68
|
+
return (_jsx("li", { role: "none", children: _jsxs(Flex, { as: "button", type: "button", role: "option", "aria-selected": active,
|
|
69
|
+
// Already here: marked, and nothing to switch to.
|
|
70
|
+
disabled: active, onClick: () => {
|
|
71
|
+
setOpen(false);
|
|
72
|
+
navigate(`/${d.id}`);
|
|
73
|
+
}, align: "center", gap: 2, width: "100%", radius: "small", px: 2, py: 1.5, color: "text", background: active ? 'surface' : 'transparent', cursor: active ? 'default' : 'pointer', css: { textAlign: 'left' }, children: [d.icon ? _jsx(Icon, { name: d.icon, size: 16 }) : null, _jsx(Typography, { as: "span", variant: "body", grow: 1, children: d.title }), active ? _jsx(Icon, { name: "lu:check", size: 16 }) : null] }) }, d.id));
|
|
74
|
+
}) })) : null] }));
|
|
75
|
+
}
|
|
76
|
+
const HEALTH_COLORS = {
|
|
77
|
+
ok: '#34D399',
|
|
78
|
+
pending: '#FBBF24',
|
|
79
|
+
down: '#F2554A',
|
|
80
|
+
};
|
|
81
|
+
function linkHealth(link) {
|
|
82
|
+
return link === 'open' ? 'ok' : link === 'connecting' ? 'pending' : 'down';
|
|
83
|
+
}
|
|
84
|
+
function integrationHealth(status) {
|
|
85
|
+
return status === 'connected' ? 'ok' : status === 'connecting' ? 'pending' : 'down';
|
|
86
|
+
}
|
|
87
|
+
const WORST = ['down', 'pending', 'ok'];
|
|
88
|
+
/** One dot summarising the runtime link and every integration — green when all are up, amber while
|
|
89
|
+
* something connects, red when something is down; click for per-system detail. `TopBar` renders it
|
|
90
|
+
* from live status, so it only needs the props above for demos. */
|
|
91
|
+
export function SystemStatus({ link: linkOverride, statuses: statusesOverride, defaultOpen = false, }) {
|
|
92
|
+
const liveLink = useConnectionStatus();
|
|
93
|
+
const liveStatuses = useIntegrationStatuses();
|
|
94
|
+
const link = linkOverride ?? liveLink;
|
|
95
|
+
const statuses = statusesOverride ?? liveStatuses;
|
|
96
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
97
|
+
const ref = useRef(null);
|
|
98
|
+
useDismiss(open, () => setOpen(false), ref);
|
|
99
|
+
const rows = [
|
|
100
|
+
{
|
|
101
|
+
name: 'Runtime',
|
|
102
|
+
health: linkHealth(link),
|
|
103
|
+
label: link === 'open' ? 'Connected' : link === 'connecting' ? 'Connecting…' : 'Unreachable',
|
|
104
|
+
},
|
|
105
|
+
...Object.entries(statuses).map(([id, status]) => ({
|
|
106
|
+
name: id.toUpperCase(),
|
|
107
|
+
health: integrationHealth(status),
|
|
108
|
+
label: status === 'connected'
|
|
109
|
+
? 'Connected'
|
|
110
|
+
: status === 'connecting'
|
|
111
|
+
? 'Connecting…'
|
|
112
|
+
: status === 'error'
|
|
113
|
+
? 'Error'
|
|
114
|
+
: 'Disconnected',
|
|
115
|
+
})),
|
|
116
|
+
];
|
|
117
|
+
const overall = WORST.find((h) => rows.some((row) => row.health === h)) ?? 'ok';
|
|
118
|
+
const summary = overall === 'ok'
|
|
119
|
+
? 'All systems operational'
|
|
120
|
+
: overall === 'pending'
|
|
121
|
+
? 'Connecting…'
|
|
122
|
+
: `${rows.filter((row) => row.health === 'down').length} system(s) down`;
|
|
123
|
+
return (_jsxs(Flex, { ref: ref, position: "relative", children: [_jsx(PlainButton, { "aria-label": summary, "aria-expanded": open, title: summary, onClick: () => setOpen((o) => !o), align: "center", justify: "center", width: 32, height: 32, radius: "full", children: _jsx(Flex, { as: "span", width: 12, height: 12, radius: "full", css: {
|
|
124
|
+
background: HEALTH_COLORS[overall],
|
|
125
|
+
boxShadow: `0 0 0 4px ${HEALTH_COLORS[overall]}33`,
|
|
126
|
+
} }) }), open ? (_jsxs(Flex, { direction: "column", gap: 2, background: "surfaceRaised", radius: "row", shadow: "drawer", p: 3.5, role: "status", position: "absolute", zIndex: "dropdown", mt: 2, minWidth: 220, css: { top: '100%', right: 0, whiteSpace: 'nowrap' }, children: [_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Flex, { as: "span", width: 8, height: 8, radius: "full", css: { background: HEALTH_COLORS[overall] } }), _jsx(Typography, { as: "span", variant: "bodyStrong", children: summary })] }), rows.map((row) => (_jsxs(Flex, { align: "center", justify: "space-between", gap: 6, children: [_jsx(Typography, { as: "span", variant: "body", children: row.name }), _jsx(Typography, { as: "span", variant: "label", css: { color: HEALTH_COLORS[row.health] }, children: row.label })] }, row.name)))] })) : null] }));
|
|
127
|
+
}
|
|
128
|
+
function StatusChip({ children }) {
|
|
129
|
+
return (_jsx(Flex, { align: "center", gap: 2, background: "surface", border: true, radius: "full", px: 3.5, py: 2.5, children: children }));
|
|
130
|
+
}
|
|
131
|
+
/** What a condition looks like in the pill: an icon, and a color where the weather has one. */
|
|
132
|
+
const CONDITION_LOOK = {
|
|
133
|
+
sunny: { icon: 'lu:sun', color: '#FBBF24' },
|
|
134
|
+
'clear-night': { icon: 'lu:moon', color: '#A5B4FC' },
|
|
135
|
+
partlycloudy: { icon: 'lu:cloud-sun', color: '#FBBF24' },
|
|
136
|
+
cloudy: { icon: 'lu:cloud' },
|
|
137
|
+
fog: { icon: 'lu:cloud-fog' },
|
|
138
|
+
rainy: { icon: 'lu:cloud-rain', color: '#60A5FA' },
|
|
139
|
+
pouring: { icon: 'lu:cloud-rain-wind', color: '#60A5FA' },
|
|
140
|
+
snowy: { icon: 'lu:cloud-snow', color: '#BAE6FD' },
|
|
141
|
+
'snowy-rainy': { icon: 'lu:cloud-snow', color: '#93C5FD' },
|
|
142
|
+
hail: { icon: 'lu:cloud-hail', color: '#93C5FD' },
|
|
143
|
+
lightning: { icon: 'lu:cloud-lightning', color: '#FBBF24' },
|
|
144
|
+
'lightning-rainy': { icon: 'lu:cloud-lightning', color: '#FBBF24' },
|
|
145
|
+
windy: { icon: 'lu:wind' },
|
|
146
|
+
exceptional: { icon: 'lu:triangle-alert', color: '#F2554A' },
|
|
147
|
+
unknown: { icon: 'lu:cloud' },
|
|
148
|
+
};
|
|
149
|
+
/** Current weather, as a pill: an icon for the sky and a rounded whole-degree reading. A `weather`
|
|
150
|
+
* entity gives the real condition; a plain `sensor.*` (an outdoor temperature) gets a fixed sun,
|
|
151
|
+
* since a sensor says nothing about the sky. */
|
|
152
|
+
function WeatherChip({ entity }) {
|
|
153
|
+
return useEntity(entity)?.kind === 'weather' ? (_jsx(WeatherPill, { entity: entity })) : (_jsx(SensorWeather, { entity: entity }));
|
|
154
|
+
}
|
|
155
|
+
function WeatherPill({ entity }) {
|
|
156
|
+
const handle = useEntityHandle('weather', entity);
|
|
157
|
+
const { status } = handle;
|
|
158
|
+
const weather = handle.entity;
|
|
159
|
+
const look = CONDITION_LOOK[weather?.condition ?? 'unknown'];
|
|
160
|
+
const ready = status === 'ready' && weather?.temperature !== undefined;
|
|
161
|
+
return (_jsxs(StatusChip, { children: [_jsx(Flex, { as: "span", css: look.color ? { color: look.color } : undefined, children: _jsx(Icon, { name: look.icon, size: 14 }) }), _jsx(Typography, { as: "span", variant: "label", children: ready
|
|
162
|
+
? `${Math.round(weather.temperature ?? 0)}°`
|
|
163
|
+
: statusLabels[status] })] }));
|
|
164
|
+
}
|
|
165
|
+
function SensorWeather({ entity }) {
|
|
166
|
+
const handle = useEntityHandle('sensor', entity);
|
|
167
|
+
const { status } = handle;
|
|
168
|
+
const sensor = handle.entity;
|
|
169
|
+
return (_jsxs(StatusChip, { children: [_jsx(Flex, { as: "span", css: { color: '#FBBF24' }, children: _jsx(Icon, { name: "lu:sun", size: 14 }) }), _jsx(Typography, { as: "span", variant: "label", children: status === 'ready' && sensor?.numeric !== undefined
|
|
170
|
+
? `${Math.round(sensor.numeric)}°`
|
|
171
|
+
: statusLabels[status] })] }));
|
|
172
|
+
}
|
|
173
|
+
function SceneDot({ entity, icon, color }) {
|
|
174
|
+
const handle = useEntityHandle('action', entity);
|
|
175
|
+
const label = handle.entity?.name ?? '';
|
|
176
|
+
return (_jsx(Flex, { as: "button", type: "button", "aria-label": label, title: label, onClick: () => void handle.command('trigger'), align: "center", justify: "center", width: 40, height: 40, radius: "full", cursor: "pointer", css: ({ palette }) => ({ background: color ?? palette.accent, color: '#fff' }), children: _jsx(Icon, { name: icon ?? 'lu:palette', size: 18 }) }));
|
|
177
|
+
}
|
|
178
|
+
function initials(name) {
|
|
179
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
180
|
+
return words
|
|
181
|
+
.slice(0, 2)
|
|
182
|
+
.map((word) => word.charAt(0).toUpperCase())
|
|
183
|
+
.join('');
|
|
184
|
+
}
|
|
185
|
+
function PresenceAvatar({ entity, colors }) {
|
|
186
|
+
const handle = useEntityHandle('person', entity);
|
|
187
|
+
const person = handle.entity;
|
|
188
|
+
const name = person?.name ?? '';
|
|
189
|
+
const picture = person?.pictureUrl;
|
|
190
|
+
// Someone who is out (or unreachable) reads as an inactive avatar: dimmed and without color.
|
|
191
|
+
const active = person === undefined || (person.home && person.availability === 'ready');
|
|
192
|
+
const where = person?.home ? 'home' : (person?.location ?? '');
|
|
193
|
+
const label = name ? (where ? `${name}, ${where}` : name) : fallbackName(entity);
|
|
194
|
+
return (_jsx(Flex, { role: "img", "aria-label": label, title: label, "data-active": active, align: "center", justify: "center", color: "accentText", radius: "full", width: 34, height: 34, overflow: "hidden", ml: -2.5, position: "relative", css: ({ palette }) => ({
|
|
195
|
+
background: picture ? undefined : colorForId(entity, colors),
|
|
196
|
+
...(active
|
|
197
|
+
? {}
|
|
198
|
+
: {
|
|
199
|
+
// Faded by a light overlay on top of its own color, not by opacity: a see-through
|
|
200
|
+
// avatar would show the one it overlaps underneath.
|
|
201
|
+
'&::after': {
|
|
202
|
+
content: '""',
|
|
203
|
+
position: 'absolute',
|
|
204
|
+
inset: 0,
|
|
205
|
+
background: palette.surface,
|
|
206
|
+
opacity: 0.6,
|
|
207
|
+
},
|
|
208
|
+
}),
|
|
209
|
+
}), children: picture ? (_jsx(Box, { as: "img", src: picture, alt: "", width: "100%", height: "100%", css: { objectFit: 'cover' } })) : (_jsx(Typography, { as: "span", variant: "bodyStrong", children: initials(name) })) }));
|
|
210
|
+
}
|
|
211
|
+
/** Overlapping avatar circles for a handful of `person.*` entities. */
|
|
212
|
+
export function PresenceStack({ entities, colors = DEFAULT_PRESENCE_COLORS }) {
|
|
213
|
+
return (_jsx(Flex, { align: "center", pl: 2.5, children: entities.map((entity) => (_jsx(PresenceAvatar, { entity: entity, colors: colors }, entity))) }));
|
|
214
|
+
}
|
|
215
|
+
/** Locale-resolved by default; `format` forces 12/24h since browsers don't expose the OS setting. When a locale uses AM/PM, `formatToParts` lets it render separately, smaller. */
|
|
216
|
+
function formatClock(now, format) {
|
|
217
|
+
const parts = new Intl.DateTimeFormat(undefined, {
|
|
218
|
+
hour: format === '24h' ? '2-digit' : 'numeric',
|
|
219
|
+
minute: '2-digit',
|
|
220
|
+
...(format === 'auto' ? {} : { hour12: format === '12h' }),
|
|
221
|
+
}).formatToParts(now);
|
|
222
|
+
const dayPeriod = parts.find((part) => part.type === 'dayPeriod')?.value ?? null;
|
|
223
|
+
const time = parts
|
|
224
|
+
.filter((part) => part.type !== 'dayPeriod')
|
|
225
|
+
.map((part) => part.value)
|
|
226
|
+
.join('')
|
|
227
|
+
.trim();
|
|
228
|
+
return { time, dayPeriod };
|
|
229
|
+
}
|
|
230
|
+
function useNow(intervalMs) {
|
|
231
|
+
const [now, setNow] = useState(() => new Date());
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
const id = setInterval(() => setNow(new Date()), intervalMs);
|
|
234
|
+
return () => clearInterval(id);
|
|
235
|
+
}, [intervalMs]);
|
|
236
|
+
return now;
|
|
237
|
+
}
|
|
238
|
+
function DateChip() {
|
|
239
|
+
const now = useNow(60_000);
|
|
240
|
+
const weekday = now.toLocaleDateString(undefined, { weekday: 'short' });
|
|
241
|
+
const day = now.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
242
|
+
return (_jsx(StatusChip, { children: _jsxs(Typography, { as: "span", variant: "label", children: [weekday, " \u00B7 ", day] }) }));
|
|
243
|
+
}
|
|
244
|
+
function Clock({ format }) {
|
|
245
|
+
const now = useNow(30_000);
|
|
246
|
+
const { time, dayPeriod } = formatClock(now, format);
|
|
247
|
+
return (_jsxs(Flex, { align: "flex-start", gap: 1, children: [_jsx(Typography, { as: "span", variant: "clock", children: time }), dayPeriod ? (_jsx(Typography, { as: "span", variant: "label", css: { textTransform: 'uppercase' }, children: dayPeriod })) : null] }));
|
|
248
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"top-bar.js","sourceRoot":"","sources":["../../src/entities/top-bar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type CommandArgs, type CommandName, type Entity, type EntityKind, type EntityRef, type KindEntity } from '@hashsome/core';
|
|
2
|
+
import { type EntityStatus } from './status.ts';
|
|
3
|
+
/**
|
|
4
|
+
* What a card needs for one entity of a kind: its current model object and the commands to change
|
|
5
|
+
* it. The cards' `entity` prop takes either an entity ref (resolved through `useEntityHandle`) or
|
|
6
|
+
* one of these, so a custom source — or a test — can drive a card with no backend at all.
|
|
7
|
+
*/
|
|
8
|
+
export interface EntityHandle<K extends EntityKind> {
|
|
9
|
+
/** `ready` once the entity exists, is the right kind, and is reachable. */
|
|
10
|
+
status: EntityStatus;
|
|
11
|
+
/** The entity, when one was found and is the right kind (whatever its availability). */
|
|
12
|
+
entity: KindEntity<K> | undefined;
|
|
13
|
+
/** Runs a named command; resolves once the backend has accepted it. */
|
|
14
|
+
command<N extends CommandName<K>>(name: N, ...args: CommandArgs<K, N>): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export type CommandSender = (name: string, args?: Record<string, unknown>) => Promise<void>;
|
|
17
|
+
/** Builds a handle from what the client reports: `undefined` entity = loading, `null` = missing. */
|
|
18
|
+
export declare function toHandle<K extends EntityKind>(kind: K, entity: Entity | null | undefined, send: CommandSender): EntityHandle<K>;
|
|
19
|
+
/** What to call an entity before (or without) its model: the local id of a ref, or nothing for a
|
|
20
|
+
* handle. Keeps a not-found card labelled with what was asked for instead of blank. */
|
|
21
|
+
export declare function fallbackName(source: EntityRef | object | undefined): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { parseEntityRef, } from '@hashsome/core';
|
|
2
|
+
import { entityStatus } from './status.js';
|
|
3
|
+
/** Builds a handle from what the client reports: `undefined` entity = loading, `null` = missing. */
|
|
4
|
+
export function toHandle(kind, entity, send) {
|
|
5
|
+
const matches = entity !== undefined && entity !== null && entity.kind === kind;
|
|
6
|
+
return {
|
|
7
|
+
status: matches || entity === undefined || entity === null ? entityStatus(entity) : 'unsupported',
|
|
8
|
+
entity: matches ? entity : undefined,
|
|
9
|
+
command: (name, ...args) => send(name, args[0]),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/** What to call an entity before (or without) its model: the local id of a ref, or nothing for a
|
|
13
|
+
* handle. Keeps a not-found card labelled with what was asked for instead of blank. */
|
|
14
|
+
export function fallbackName(source) {
|
|
15
|
+
return typeof source === 'string' ? parseEntityRef(source).id : '';
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-handle.js","sourceRoot":"","sources":["../src/entity-handle.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAOf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAoB9D,oGAAoG;AACpG,MAAM,UAAU,QAAQ,CACtB,IAAO,EACP,MAAiC,EACjC,IAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;IAChF,OAAO;QACL,MAAM,EACJ,OAAO,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa;QAC3F,MAAM,EAAE,OAAO,CAAC,CAAC,CAAE,MAAwB,CAAC,CAAC,CAAC,SAAS;QACvD,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAwC,CAAC;KACvF,CAAC;AACJ,CAAC;AAED;uFACuF;AACvF,MAAM,UAAU,YAAY,CAAC,MAAsC;IACjE,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { LocalClient, MockIntegration } from '@hashsome/core';
|
|
2
|
+
/** Mock entities covering every state the components handle. Refs are `ha:<id>`. */
|
|
3
|
+
export declare function createGalleryIntegration(): MockIntegration;
|
|
4
|
+
export declare function createGalleryClient(): LocalClient;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { LocalClient, mockAction, mockClimate, mockLibrary, mockLight, mockMediaPlayer, mockPerson, mockSensor, MockIntegration, } from '@hashsome/core';
|
|
2
|
+
/** Album art for the gallery's playing demo, served by the docs dev server from `docs/public/`. */
|
|
3
|
+
// Under the base path the site is served from (`/hash/` on GitHub Pages), not the domain's root.
|
|
4
|
+
const DEMO_ARTWORK = `${import.meta.env.BASE_URL}artwork.jpg`;
|
|
5
|
+
const power = (watts) => mockSensor({ name: 'Power', value: watts, unit: 'W', measurement: 'power' });
|
|
6
|
+
const energy = (kwh) => mockSensor({ name: 'Energy', value: kwh, unit: 'kWh', measurement: 'energy' });
|
|
7
|
+
/** Mock entities covering every state the components handle. Refs are `ha:<id>`. */
|
|
8
|
+
export function createGalleryIntegration() {
|
|
9
|
+
return new MockIntegration({
|
|
10
|
+
library: mockLibrary(),
|
|
11
|
+
entities: {
|
|
12
|
+
'light.plain_on': mockLight({ name: 'Lamp', on: true }),
|
|
13
|
+
'light.plain_off': mockLight({ name: 'Stairs Lamp' }),
|
|
14
|
+
'light.dimmable': mockLight({ name: 'Bathroom LED', on: true, brightness: 0.6 }),
|
|
15
|
+
'light.color': mockLight({
|
|
16
|
+
name: 'Night Lamp',
|
|
17
|
+
on: true,
|
|
18
|
+
brightness: 1,
|
|
19
|
+
color: { mode: 'temperature', kelvin: 2700 },
|
|
20
|
+
capabilities: {
|
|
21
|
+
colorTemperature: true,
|
|
22
|
+
color: true,
|
|
23
|
+
kelvinRange: { min: 2000, max: 6500 },
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
'light.cct': mockLight({
|
|
27
|
+
name: 'Desk Lamp',
|
|
28
|
+
on: true,
|
|
29
|
+
brightness: 0.78,
|
|
30
|
+
color: { mode: 'temperature', kelvin: 4000 },
|
|
31
|
+
capabilities: { colorTemperature: true, kelvinRange: { min: 2000, max: 6500 } },
|
|
32
|
+
}),
|
|
33
|
+
'light.unavailable': mockLight({ name: 'Porch Lamp', availability: 'unavailable' }),
|
|
34
|
+
'climate.heater': mockClimate({
|
|
35
|
+
name: 'Living Room Heater',
|
|
36
|
+
mode: 'heat',
|
|
37
|
+
action: 'heating',
|
|
38
|
+
humidity: 48,
|
|
39
|
+
targetTemperature: 17,
|
|
40
|
+
currentTemperature: 16.4,
|
|
41
|
+
capabilities: { modes: ['off', 'heat'], step: 0.5, range: { min: 5, max: 30 } },
|
|
42
|
+
}),
|
|
43
|
+
'climate.off': mockClimate({
|
|
44
|
+
name: 'Office Thermostat',
|
|
45
|
+
mode: 'off',
|
|
46
|
+
action: 'off',
|
|
47
|
+
humidity: 41,
|
|
48
|
+
targetTemperature: 21.5,
|
|
49
|
+
currentTemperature: 18.8,
|
|
50
|
+
preset: 'home',
|
|
51
|
+
capabilities: {
|
|
52
|
+
modes: ['off', 'heat', 'cool', 'auto'],
|
|
53
|
+
presets: ['home', 'away', 'sleep'],
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
'climate.unavailable': mockClimate({ name: 'Guest Heater', availability: 'unavailable' }),
|
|
57
|
+
'sensor.heater_power': power('1180'),
|
|
58
|
+
'sensor.heater_energy': energy('84.3'),
|
|
59
|
+
'sensor.thermostat_power': power('0'),
|
|
60
|
+
'sensor.thermostat_energy': energy('31.2'),
|
|
61
|
+
'sensor.lamp_power': power('9'),
|
|
62
|
+
'sensor.lamp_energy': energy('1.64'),
|
|
63
|
+
'sensor.led_power': power('7'),
|
|
64
|
+
'sensor.led_energy': energy('3.2'),
|
|
65
|
+
'sensor.temperature': mockSensor({ value: '18.04', unit: '°C', measurement: 'temperature' }),
|
|
66
|
+
'sensor.humidity': mockSensor({ value: '64.41', unit: '%', measurement: 'humidity' }),
|
|
67
|
+
'sensor.bedroom_humidity': mockSensor({
|
|
68
|
+
name: 'Bedroom humidity',
|
|
69
|
+
value: '22.3',
|
|
70
|
+
unit: '%',
|
|
71
|
+
measurement: 'humidity',
|
|
72
|
+
}),
|
|
73
|
+
'sensor.office_humidity': mockSensor({
|
|
74
|
+
name: 'Office humidity',
|
|
75
|
+
value: '45.8',
|
|
76
|
+
unit: '%',
|
|
77
|
+
measurement: 'humidity',
|
|
78
|
+
}),
|
|
79
|
+
'sensor.unavailable': mockSensor({
|
|
80
|
+
value: '0',
|
|
81
|
+
measurement: 'temperature',
|
|
82
|
+
availability: 'unavailable',
|
|
83
|
+
}),
|
|
84
|
+
'sensor.unknown': mockSensor({
|
|
85
|
+
value: '0',
|
|
86
|
+
measurement: 'humidity',
|
|
87
|
+
availability: 'unknown',
|
|
88
|
+
}),
|
|
89
|
+
'scene.tv_time': mockAction({ name: 'TV Time' }),
|
|
90
|
+
'script.shower': mockAction({ name: 'Shower' }),
|
|
91
|
+
'media_player.living_room': mockMediaPlayer({
|
|
92
|
+
name: 'Living Room',
|
|
93
|
+
playback: 'playing',
|
|
94
|
+
media: {
|
|
95
|
+
title: 'Blank Space',
|
|
96
|
+
artist: 'More More',
|
|
97
|
+
album: '1989',
|
|
98
|
+
artworkUrl: DEMO_ARTWORK,
|
|
99
|
+
},
|
|
100
|
+
volume: 0.4,
|
|
101
|
+
position: 64,
|
|
102
|
+
duration: 231,
|
|
103
|
+
positionUpdatedAt: new Date().toISOString(),
|
|
104
|
+
shuffle: false,
|
|
105
|
+
capabilities: { browse: true, search: true, seek: true, shuffle: true },
|
|
106
|
+
}),
|
|
107
|
+
'media_player.off': mockMediaPlayer({
|
|
108
|
+
name: 'Kitchen Speaker',
|
|
109
|
+
availability: 'unavailable',
|
|
110
|
+
playback: 'off',
|
|
111
|
+
}),
|
|
112
|
+
'person.dan': mockPerson({ name: 'Dan' }),
|
|
113
|
+
'person.alex': mockPerson({ name: 'Alex', location: 'not_home' }),
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
export function createGalleryClient() {
|
|
118
|
+
return new LocalClient([createGalleryIntegration()]);
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/gallery/fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documentation for every `@hashsome/ui` component: what it is and the states it supports, each a
|
|
3
|
+
* live, interactive demo backed by an in-browser mock — not a dashboard itself (that's what
|
|
4
|
+
* `example/dashboards/*` are for). Served standalone by `pnpm --filter @hashsome/ui docs`. Must
|
|
5
|
+
* be rendered inside a router (nav components use router links).
|
|
6
|
+
*/
|
|
7
|
+
export declare function Gallery({ density }: {
|
|
8
|
+
density?: 'comfortable' | 'compact';
|
|
9
|
+
}): import("@emotion/react/jsx-runtime").JSX.Element;
|