@camstack/ui-library 1.1.16 → 1.1.18

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.
@@ -7,6 +7,17 @@ interface CoverageTrackProps {
7
7
  readonly playheadMs: number | null;
8
8
  /** Called with the absolute ms a click maps to within the window. */
9
9
  readonly onSeek: (clickMs: number) => void;
10
+ /**
11
+ * Drag-scrub callbacks (R9, frame-push mode). When `onScrubEnd` is
12
+ * provided the track switches to pointer-driven scrubbing: pointer-down
13
+ * begins a drag, moves report the hovered epoch, release commits it —
14
+ * a motionless press+release behaves like a seek. `onSeek` is then
15
+ * suppressed (the pointer flow owns the gesture). Omit all three for the
16
+ * classic click-to-seek behaviour.
17
+ */
18
+ readonly onScrubStart?: () => void;
19
+ readonly onScrubMove?: (ms: number) => void;
20
+ readonly onScrubEnd?: (ms: number) => void;
10
21
  }
11
- export declare function CoverageTrack({ windowFrom, windowTo, spans, playheadMs, onSeek, }: CoverageTrackProps): import("react").JSX.Element;
22
+ export declare function CoverageTrack({ windowFrom, windowTo, spans, playheadMs, onSeek, onScrubStart, onScrubMove, onScrubEnd, }: CoverageTrackProps): import("react").JSX.Element;
12
23
  export {};
@@ -6,6 +6,9 @@ interface ChildrenAccordionProps {
6
6
  readonly accessoryChildren: readonly DeviceItemDevice[];
7
7
  readonly adoptedChildren: readonly DeviceItemDevice[];
8
8
  readonly onNavigate: (id: number) => void;
9
+ /** Parent row's name — used to strip the redundant baked-in prefix from each
10
+ * child's DISPLAY name (the underlying `child.name` is untouched). */
11
+ readonly parentName: string;
9
12
  }
10
- export declare function ChildrenAccordion({ trpc, accessoryChildren, adoptedChildren, onNavigate, }: ChildrenAccordionProps): ReactNode;
13
+ export declare function ChildrenAccordion({ trpc, accessoryChildren, adoptedChildren, onNavigate, parentName, }: ChildrenAccordionProps): ReactNode;
11
14
  export {};
@@ -1,6 +1,6 @@
1
- import { ReactNode } from 'react';
1
+ import { ChildLayout, DeviceDisplayOverride, SourceInfo } from '@camstack/types';
2
2
  import { LucideIcon } from 'lucide-react';
3
- import { SourceInfo, ChildLayout } from '@camstack/types';
3
+ import { ReactNode } from 'react';
4
4
  import { UseDeviceProxyTrpc } from '../../hooks/use-device-proxy';
5
5
  /**
6
6
  * Mirror of the canonical `DeviceInfo` wire shape (see
@@ -30,10 +30,16 @@ export interface DeviceItemDevice {
30
30
  /** Upstream-system identity (dispatch key + system tag + optional uniqueId).
31
31
  * Flows from `DeviceInfo.sourceInfo` via structural cast / parse;
32
32
  * optional so rows from providers that pre-date SourceInfo still work.
33
- * Does NOT carry rendering hints (unit, precision) those live in the
34
- * cap STATUS SLICE for generic numeric-sensor, or are canonical constants
35
- * in ROLE_DESCRIPTOR for typed sensor roles. */
33
+ * Live rendering hints (unit, precision) come from the cap STATUS SLICE for
34
+ * generic numeric-sensor, or canonical constants in ROLE_DESCRIPTOR for typed
35
+ * roles; an operator's per-device customization rides `display` (below). */
36
36
  readonly sourceInfo?: SourceInfo;
37
+ /** Operator-authored per-device display override (icon/label/unit/precision/
38
+ * hidden). Mirrors `DeviceInfo.display` so the wire row passes through. The
39
+ * renderers resolve it via `resolveSensorDisplay` (unit/precision, render-time
40
+ * conversion) + `displayRoleLabel` / `deviceLeadIcon` (label/icon); `hidden`
41
+ * filters the row out of list surfaces. Absent ⇒ role/slice defaults. */
42
+ readonly display?: DeviceDisplayOverride;
37
43
  /** Soft-link to another device id. For a CONTAINER device this is the
38
44
  * LEGACY picker-chosen primary child (numeric id); the row/hero resolve the
39
45
  * primary child via `resolveContainerPrimary(children, linkDeviceId)`.
@@ -194,6 +200,22 @@ export interface VariantDefaults {
194
200
  }
195
201
  export declare function resolveFlags(props: DeviceItemProps): VariantDefaults;
196
202
  export declare function deviceLeadIcon(device: DeviceItemDevice): LucideIcon;
203
+ /**
204
+ * Role label for a device row, honouring an operator's per-device `display.label`
205
+ * override (falls back to the `DEVICE_ROLE_META` label). NOT the device name —
206
+ * this is the small secondary role caption on accessory/sensor rows.
207
+ */
208
+ export declare function displayRoleLabel(device: DeviceItemDevice): string;
209
+ export declare function stripParentNamePrefix(name: string, parentName: string): string;
210
+ /**
211
+ * Display name for a child device rendered UNDER its container/parent row.
212
+ * Precedence: an operator's explicit per-device `display.label` wins over the
213
+ * auto-strip (mirrors {@link displayRoleLabel}); otherwise the parent-name
214
+ * prefix is stripped via {@link stripParentNamePrefix}. Shared by the
215
+ * device-detail children list AND the devices list-table so both surfaces
216
+ * render the bare child label identically.
217
+ */
218
+ export declare function childListName(child: Pick<DeviceItemDevice, 'name' | 'display'>, parentName: string): string;
197
219
  /**
198
220
  * Icon for each `DeviceFeature` advertised on a device row. Used by
199
221
  * the features popover (`<DeviceItemFeatures>`) to render compact
@@ -1,9 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { DeviceItemProps } from './helpers';
3
- export type { DeviceItemDevice, DeviceItemParent, DeviceItemKind, DeviceItemVariant, DeviceItemView, DeviceItemProps, } from './helpers';
4
- export { deriveDeviceKind } from './helpers';
3
+ export type { ChildLayoutSection, GroupedChildren } from './child-layout';
4
+ export { groupChildrenByLayout } from './child-layout';
5
5
  export { ChildSectionAccordion } from './child-section-accordion';
6
6
  export { ContainerChildrenProvider, useContainerChildren } from './container-children-context';
7
- export { groupChildrenByLayout } from './child-layout';
8
- export type { GroupedChildren, ChildLayoutSection } from './child-layout';
7
+ export type { DeviceItemDevice, DeviceItemKind, DeviceItemParent, DeviceItemProps, DeviceItemVariant, DeviceItemView, } from './helpers';
8
+ export { childListName, deriveDeviceKind, stripParentNamePrefix } from './helpers';
9
9
  export declare function DeviceItem(props: DeviceItemProps): ReactNode;
@@ -22,4 +22,13 @@ export interface GroupedDevices {
22
22
  readonly topLevel: readonly DeviceItemDevice[];
23
23
  readonly accessoriesByParent: ReadonlyMap<number, readonly DeviceItemDevice[]>;
24
24
  }
25
- export declare function groupTopLevelAndAccessories(devices: readonly DeviceItemDevice[]): GroupedDevices;
25
+ /** Options for `groupTopLevelAndAccessories`. */
26
+ export interface GroupDevicesOptions {
27
+ /** Include devices carrying an operator `display.hidden` override. Default
28
+ * false — hidden devices are omitted from BOTH top-level and accessory
29
+ * lists. NOTE: distinct from the HA `accessories` cap `hiddenChildIds`
30
+ * mechanism (container-scoped, provider-persisted) — this is the device-level
31
+ * `display.hidden` flag. A future "show hidden" toggle flips this one prop. */
32
+ readonly includeHidden?: boolean;
33
+ }
34
+ export declare function groupTopLevelAndAccessories(devices: readonly DeviceItemDevice[], options?: GroupDevicesOptions): GroupedDevices;
@@ -35,4 +35,15 @@ export declare function deviceRoleMeta(role: DeviceRole): DeviceRoleMeta;
35
35
  export declare function deviceTypeMetaOf(type: string): DeviceTypeMeta;
36
36
  /** Runtime-string-safe role lookup; unknown roles fall back to `GenericSensor`. */
37
37
  export declare function deviceRoleMetaOf(role: string): DeviceRoleMeta;
38
+ /**
39
+ * Icons an operator may pick for a per-device `display.icon` override, keyed by
40
+ * a stable kebab-case name. Built ONLY from the lucide icons already imported by
41
+ * this module — no new imports, no dynamic indexing — so it stays bundle-size
42
+ * neutral and the picker offers a curated, sensor-relevant set. Unknown keys
43
+ * resolve to `undefined` (caller keeps the role/type default).
44
+ */
45
+ export declare const DISPLAY_ICON_REGISTRY: Readonly<Record<string, LucideIcon>>;
46
+ /** Resolve a `display.icon` name to a lucide component, or `undefined` when the
47
+ * name is not in the curated `DISPLAY_ICON_REGISTRY`. */
48
+ export declare function resolveDisplayIcon(name: string): LucideIcon | undefined;
38
49
  export declare function allDeviceTypeFilterOptions(): readonly MultiSelectOption[];
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+ import { RecordedControlCommand, RecordedPlaybackMode } from '../lib/recorded-control-protocol';
3
+ export interface RecordedPlaybackContextValue {
4
+ /**
5
+ * Host-side binding for the player's `onControlChannel` prop. `null` in the
6
+ * inert default — a StreamPanel outside the provider passes `undefined` to
7
+ * the player and no datachannel is created (behaviour unchanged).
8
+ */
9
+ readonly bindControlChannel: ((channel: RTCDataChannel) => void) | null;
10
+ /** True while a bound channel is open — frame-push control is available. */
11
+ readonly channelOpen: boolean;
12
+ /** Last server-reported playback mode (`live` until told otherwise). */
13
+ readonly mode: RecordedPlaybackMode;
14
+ /** Last server-reported playback position (~1 Hz), or null while live. */
15
+ readonly positionMs: number | null;
16
+ /** Send a control command. Returns false when the channel isn't open. */
17
+ readonly send: (cmd: RecordedControlCommand) => boolean;
18
+ }
19
+ export declare function RecordedPlaybackProvider({ children }: {
20
+ readonly children: ReactNode;
21
+ }): import("react").JSX.Element;
22
+ /** @returns the recorded-playback control surface (inert outside a provider). */
23
+ export declare function useRecordedPlayback(): RecordedPlaybackContextValue;
@@ -399,6 +399,12 @@ export declare const useDeviceManagerSetPrimaryChildEntityId: typeof trpc.device
399
399
  export declare const useDeviceManagerSetChildLayout: typeof trpc.deviceManager.setChildLayout.useMutation;
400
400
  /** Generated alias around `trpc.deviceManager.setDeviceLinks.useMutation`. */
401
401
  export declare const useDeviceManagerSetDeviceLinks: typeof trpc.deviceManager.setDeviceLinks.useMutation;
402
+ /** Generated alias around `trpc.deviceManager.setDisplay.useMutation`. */
403
+ export declare const useDeviceManagerSetDisplay: typeof trpc.deviceManager.setDisplay.useMutation;
404
+ /** Generated alias around `trpc.deviceManager.getRoleDisplayDefaults.useQuery`. */
405
+ export declare const useDeviceManagerGetRoleDisplayDefaults: typeof trpc.deviceManager.getRoleDisplayDefaults.useQuery;
406
+ /** Generated alias around `trpc.deviceManager.setRoleDisplayDefaults.useMutation`. */
407
+ export declare const useDeviceManagerSetRoleDisplayDefaults: typeof trpc.deviceManager.setRoleDisplayDefaults.useMutation;
402
408
  /** Generated alias around `trpc.deviceManager.getWireableFields.useQuery`. */
403
409
  export declare const useDeviceManagerGetWireableFields: typeof trpc.deviceManager.getWireableFields.useQuery;
404
410
  /** Generated alias around `trpc.deviceManager.setRole.useMutation`. */