@camstack/ui-library 0.1.56 → 0.1.58

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.
Files changed (126) hide show
  1. package/dist/composites/battery-badge.d.ts +3 -0
  2. package/dist/composites/camera-stream-player.d.ts +101 -1
  3. package/dist/composites/cap-settings/ConsumablesPanel.d.ts +2 -0
  4. package/dist/composites/cap-settings/CoverageTrack.d.ts +12 -0
  5. package/dist/composites/cap-settings/EventBucketStrip.d.ts +25 -0
  6. package/dist/composites/cap-settings/EventHeatmap.d.ts +10 -0
  7. package/dist/composites/cap-settings/MaskShapeCanvas.d.ts +48 -0
  8. package/dist/composites/cap-settings/MotionZonesSettings.d.ts +1 -1
  9. package/dist/composites/cap-settings/PrivacyMaskSettings.d.ts +2 -0
  10. package/dist/composites/cap-settings/RecordingPanel.d.ts +2 -0
  11. package/dist/composites/cap-settings/RecordingRulesEditor.d.ts +7 -0
  12. package/dist/composites/cap-settings/RecordingSettings.d.ts +8 -0
  13. package/dist/composites/cap-settings/RecordingTimeline.d.ts +5 -0
  14. package/dist/composites/cap-settings/TimelineControls.d.ts +21 -0
  15. package/dist/composites/cap-settings/event-thumb.d.ts +11 -0
  16. package/dist/composites/cap-settings/index.d.ts +7 -0
  17. package/dist/composites/cap-settings/recording-config-form.d.ts +5 -0
  18. package/dist/composites/cap-settings/recording-spans.d.ts +22 -0
  19. package/dist/composites/cap-settings/recording-timeline-model.d.ts +84 -0
  20. package/dist/composites/device-activity-panel.d.ts +5 -1
  21. package/dist/composites/device-controls/alarm-hero-card.d.ts +24 -0
  22. package/dist/composites/device-controls/atoms.d.ts +81 -0
  23. package/dist/composites/device-controls/brightness-panel.d.ts +3 -0
  24. package/dist/composites/device-controls/button-control.d.ts +18 -0
  25. package/dist/composites/device-controls/climate-panel.d.ts +16 -0
  26. package/dist/composites/device-controls/container-primary-hero.d.ts +24 -0
  27. package/dist/composites/device-controls/container-primary.d.ts +46 -0
  28. package/dist/composites/device-controls/control-panel.d.ts +10 -0
  29. package/dist/composites/device-controls/control-registry.d.ts +74 -0
  30. package/dist/composites/device-controls/cover-hero-card.d.ts +27 -0
  31. package/dist/composites/device-controls/cover-inline.d.ts +27 -0
  32. package/dist/composites/device-controls/cover-panel.d.ts +3 -0
  33. package/dist/composites/device-controls/dummy-hero-card.d.ts +6 -0
  34. package/dist/composites/device-controls/fan-hero-card.d.ts +21 -0
  35. package/dist/composites/device-controls/fan-panel.d.ts +3 -0
  36. package/dist/composites/device-controls/humidifier-control.d.ts +37 -0
  37. package/dist/composites/device-controls/image-control.d.ts +24 -0
  38. package/dist/composites/device-controls/index.d.ts +33 -0
  39. package/dist/composites/device-controls/lawn-mower-control.d.ts +24 -0
  40. package/dist/composites/device-controls/light-hero-card.d.ts +16 -0
  41. package/dist/composites/device-controls/lock-hero-card.d.ts +15 -0
  42. package/dist/composites/device-controls/lock-panel.d.ts +3 -0
  43. package/dist/composites/device-controls/media-player-hero-card.d.ts +17 -0
  44. package/dist/composites/device-controls/media-player-panel.d.ts +9 -0
  45. package/dist/composites/device-controls/offline-badge.d.ts +11 -0
  46. package/dist/composites/device-controls/panel-controls.d.ts +17 -0
  47. package/dist/composites/device-controls/popover-row-action.d.ts +9 -0
  48. package/dist/composites/device-controls/primary-child.d.ts +18 -0
  49. package/dist/composites/device-controls/radial-gauge.d.ts +20 -0
  50. package/dist/composites/device-controls/sensor-hero-card.d.ts +10 -0
  51. package/dist/composites/device-controls/sensor-inline-control.d.ts +11 -0
  52. package/dist/composites/device-controls/sensor-value-atom.d.ts +106 -0
  53. package/dist/composites/device-controls/switch-hero-card.d.ts +13 -0
  54. package/dist/composites/device-controls/switch-panel.d.ts +3 -0
  55. package/dist/composites/device-controls/tap-toggle.d.ts +17 -0
  56. package/dist/composites/device-controls/thermostat-hero-card.d.ts +17 -0
  57. package/dist/composites/device-controls/types.d.ts +17 -0
  58. package/dist/composites/device-controls/update-control.d.ts +11 -0
  59. package/dist/composites/device-controls/vacuum-control.d.ts +36 -0
  60. package/dist/composites/device-controls/valve-control.d.ts +46 -0
  61. package/dist/composites/device-controls/water-heater-control.d.ts +41 -0
  62. package/dist/composites/device-controls/weather-control.d.ts +41 -0
  63. package/dist/composites/device-export-panel.d.ts +8 -1
  64. package/dist/composites/device-item/actions.d.ts +12 -1
  65. package/dist/composites/device-item/child-layout.d.ts +32 -0
  66. package/dist/composites/device-item/child-section-accordion.d.ts +9 -0
  67. package/dist/composites/device-item/container-children-context.d.ts +15 -0
  68. package/dist/composites/device-item/device-delete-action.d.ts +8 -0
  69. package/dist/composites/device-item/header.d.ts +8 -1
  70. package/dist/composites/device-item/helpers.d.ts +117 -2
  71. package/dist/composites/device-item/index.d.ts +4 -0
  72. package/dist/composites/device-item/preview.d.ts +3 -3
  73. package/dist/composites/device-item/reboot-quick-action.d.ts +9 -0
  74. package/dist/composites/device-item/status-dot.d.ts +4 -1
  75. package/dist/composites/device-list/batch-actions-bar.d.ts +15 -0
  76. package/dist/composites/device-list/batch-toolbar.d.ts +15 -0
  77. package/dist/composites/device-list/cards-layout.d.ts +18 -0
  78. package/dist/composites/device-list/columns.d.ts +68 -0
  79. package/dist/composites/device-list/device-mode.d.ts +115 -0
  80. package/dist/composites/device-list/filter-chips.d.ts +24 -13
  81. package/dist/composites/device-list/fuzzy-match.d.ts +27 -0
  82. package/dist/composites/device-list/generic-mode.d.ts +81 -0
  83. package/dist/composites/device-list/group.d.ts +19 -0
  84. package/dist/composites/device-list/hardware-cell.d.ts +7 -0
  85. package/dist/composites/device-list/hardware.d.ts +26 -0
  86. package/dist/composites/device-list/icon-action.d.ts +17 -0
  87. package/dist/composites/device-list/index.d.ts +23 -30
  88. package/dist/composites/device-list/multi-select.d.ts +22 -0
  89. package/dist/composites/device-list/sort.d.ts +18 -0
  90. package/dist/composites/device-list/sortable-header.d.ts +10 -0
  91. package/dist/composites/device-list/table-layout.d.ts +25 -0
  92. package/dist/composites/device-list/type-filter.d.ts +19 -0
  93. package/dist/composites/device-list/url-state.d.ts +14 -4
  94. package/dist/composites/device-meta.d.ts +38 -0
  95. package/dist/composites/discovery-panel.d.ts +3 -3
  96. package/dist/composites/hls-quality.d.ts +35 -0
  97. package/dist/composites/hls-video.d.ts +26 -0
  98. package/dist/composites/hover-zoom-image.d.ts +18 -0
  99. package/dist/composites/index.d.ts +13 -2
  100. package/dist/composites/log-stream-scroll.d.ts +32 -0
  101. package/dist/composites/log-stream.d.ts +8 -1
  102. package/dist/composites/stream-panel.d.ts +60 -9
  103. package/dist/composites/timezone-selector.d.ts +18 -0
  104. package/dist/composites/widget-panel.d.ts +28 -0
  105. package/dist/contexts/vod-playback.d.ts +17 -0
  106. package/dist/generated/system-hooks.d.ts +358 -56
  107. package/dist/hooks/index.d.ts +6 -0
  108. package/dist/hooks/use-device-cap-slice.d.ts +19 -0
  109. package/dist/hooks/use-device-capability.d.ts +12 -0
  110. package/dist/hooks/use-device-list-page-size.d.ts +14 -0
  111. package/dist/hooks/use-device-webrtc.d.ts +101 -4
  112. package/dist/hooks/use-optimistic-slice.d.ts +11 -0
  113. package/dist/index.cjs +53123 -9819
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.d.ts +1 -0
  116. package/dist/index.js +52791 -9767
  117. package/dist/index.js.map +1 -1
  118. package/dist/lib/cap-error.d.ts +41 -0
  119. package/dist/lib/format-control-datetime.d.ts +18 -0
  120. package/dist/lib/format-last-seen.d.ts +12 -0
  121. package/dist/lib/format-numeric.d.ts +9 -0
  122. package/dist/lib/index.d.ts +4 -0
  123. package/dist/primitives/dialog.d.ts +13 -0
  124. package/dist/primitives/tooltip.d.ts +9 -3
  125. package/package.json +3 -1
  126. package/dist/composites/cap-settings/MotionGridCanvas.d.ts +0 -9
@@ -6,9 +6,9 @@
6
6
  * renders the channel list with status badges, refresh, adopt, and
7
7
  * release controls.
8
8
  *
9
- * Mirrors the Scrypted device-discovery affordance pattern: a single
10
- * generic UI used by every plugin that exposes children behind a
11
- * gateway. Keeps the operator UX consistent across integrations.
9
+ * A single generic UI used by every provider that exposes children
10
+ * behind a gateway. Keeps the operator UX consistent across
11
+ * integrations.
12
12
  */
13
13
  interface DiscoveryPanelProps {
14
14
  readonly deviceId: number;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Pure helpers for the HLS playback quality selector.
3
+ *
4
+ * Intentionally decoupled from hls.js types so this module can be
5
+ * imported and tested without a DOM or MSE environment.
6
+ */
7
+ export interface QualityOption {
8
+ readonly value: number;
9
+ readonly label: string;
10
+ }
11
+ export interface HlsLevelInfo {
12
+ readonly height?: number;
13
+ readonly bitrate?: number;
14
+ readonly name?: string;
15
+ }
16
+ /**
17
+ * Build a human-readable label for a single HLS level.
18
+ *
19
+ * Priority:
20
+ * 1. `name` (non-empty) → verbatim. The recorder stamps the master variant
21
+ * NAME with the recording profile (high/mid/low), and the VOD selector must
22
+ * match the live stream-profile selector's labels — the profile name wins
23
+ * over resolution/bitrate.
24
+ * 2. `height` (> 0) → e.g. "1080p"
25
+ * 3. `bitrate` (> 0) → e.g. "2500 kbps"
26
+ * 4. Fallback → "Level N" (1-based)
27
+ */
28
+ export declare function levelLabel(level: HlsLevelInfo, index: number): string;
29
+ /**
30
+ * Build the full list of quality options for the selector overlay.
31
+ *
32
+ * Always starts with the Auto entry (`value: -1`), followed by one
33
+ * entry per available HLS level in manifest order.
34
+ */
35
+ export declare function qualityOptions(levels: readonly HlsLevelInfo[]): QualityOption[];
@@ -0,0 +1,26 @@
1
+ import { QualityOption } from './hls-quality';
2
+ export interface HlsVideoProps {
3
+ /** Master `.m3u8` URL (typically relative, through the hub data-plane). */
4
+ readonly url: string;
5
+ /** Bearer token for the admin-gated data-plane route (optional). */
6
+ readonly authToken?: string | null;
7
+ /** Poster painted until the first frame decodes (optional). */
8
+ readonly posterUrl?: string;
9
+ /** Auto-play once the manifest is parsed (default: true). */
10
+ readonly autoPlay?: boolean;
11
+ readonly className?: string;
12
+ /**
13
+ * Called on MANIFEST_PARSED (and reset to `[]` on a new URL) with the
14
+ * full list of quality options (`qualityOptions(hls.levels)`). The caller
15
+ * renders the selector; this component owns only the hls instance.
16
+ * Emits `[]` when the manifest has ≤1 real level (no selector needed).
17
+ */
18
+ readonly onQualityOptions?: (options: readonly QualityOption[]) => void;
19
+ /**
20
+ * The level index to apply to `hls.currentLevel`. `-1` = Auto/ABR
21
+ * (default). When this prop changes, the component sets `hls.currentLevel`
22
+ * immediately. Has no effect in the native HLS fallback path.
23
+ */
24
+ readonly selectedLevel?: number;
25
+ }
26
+ export declare function HlsVideo({ url, authToken, posterUrl, autoPlay, className, onQualityOptions, selectedLevel }: HlsVideoProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ export interface HoverZoomImageProps {
3
+ /** Image URL (signed url for Image entities; snapshot object url for cameras). Null → placeholder. */
4
+ readonly src: string | null;
5
+ /** Accessible alt / default preview caption (e.g. the device name). */
6
+ readonly alt: string;
7
+ /** Optional small label under the enlarged preview. Defaults to `alt`. */
8
+ readonly caption?: string;
9
+ /** Text shown in the enlarged preview (and implied by the thumbnail's empty state) when there is no image. */
10
+ readonly placeholder?: string;
11
+ /** Sizing override for the thumbnail box. Defaults to a compact `h-7 w-7 rounded`. */
12
+ readonly thumbClassName?: string;
13
+ /** Enlarged-preview width in px. */
14
+ readonly expandedWidth?: number;
15
+ /** Enlarged-preview height in px (drives the flip-on-collision math). */
16
+ readonly expandedHeight?: number;
17
+ }
18
+ export declare function HoverZoomImage({ src, alt, caption, placeholder, thumbClassName, expandedWidth, expandedHeight, }: HoverZoomImageProps): ReactNode;
@@ -29,6 +29,10 @@ export * from './device-card';
29
29
  export * from './device-grid';
30
30
  export * from './device-item';
31
31
  export * from './device-list';
32
+ export { DeviceBatchToolbar } from './device-list/batch-toolbar';
33
+ export type { DeviceBatchToolbarProps } from './device-list/batch-toolbar';
34
+ export * from './device-meta';
35
+ export * from './device-controls';
32
36
  export { PipelineStep, ConfigSchemaField } from './pipeline-step';
33
37
  export type { PipelineStepDisplayConfig, PipelineStepProps } from './pipeline-step';
34
38
  export { PipelineRuntimeSelector } from './pipeline-runtime-selector';
@@ -52,6 +56,8 @@ export type { MountAddonPageOptions } from './mount-addon-page';
52
56
  export { ConfigFormBuilder } from './config-form-builder';
53
57
  export type { TranslationFn } from './config-form-builder';
54
58
  export { ConfigFormField, NodeSelectField, NodeMultiSelectField, isFieldVisible } from './config-form-field';
59
+ export { TimezoneSelector, TIMEZONES, findTimezone } from './timezone-selector';
60
+ export type { TimezoneSelectorProps, Timezone, TimezoneDstRule, Weekday } from './timezone-selector';
55
61
  export { AddonGlobalSettingsForm } from './addon-global-settings-form';
56
62
  export type { ProbeState } from './config-form-field';
57
63
  export { DetectionOverlay } from './detection-overlay';
@@ -60,6 +66,8 @@ export { CameraStreamPlayer } from './camera-stream-player';
60
66
  export type { CameraStreamPlayerProps, PlayerConnectionState, SignalingResult, ClientStreamHints } from './camera-stream-player';
61
67
  export { StreamPanel } from './stream-panel';
62
68
  export type { StreamPanelProps, StreamChoice, StreamStats } from './stream-panel';
69
+ export { HlsVideo } from './hls-video';
70
+ export type { HlsVideoProps } from './hls-video';
63
71
  export { StreamBrokerSelector } from './stream-broker-selector';
64
72
  export type { StreamBrokerSelectorProps } from './stream-broker-selector';
65
73
  export { DeviceExportPanel } from './device-export-panel';
@@ -97,6 +105,8 @@ export { PTZOverlay } from './ptz-overlay';
97
105
  export type { PTZOverlayProps } from './ptz-overlay';
98
106
  export { BatteryBadge } from './battery-badge';
99
107
  export type { BatteryBadgeProps, BatteryStatusLike } from './battery-badge';
108
+ export { HoverZoomImage } from './hover-zoom-image';
109
+ export type { HoverZoomImageProps } from './hover-zoom-image';
100
110
  export { SnapshotButton } from './snapshot-button';
101
111
  export type { SnapshotButtonProps, SnapshotButtonTrpc } from './snapshot-button';
102
112
  export { DoorbellRecentPanel } from './doorbell-recent-panel';
@@ -108,5 +118,6 @@ export { WidgetSlot } from './widget-slot';
108
118
  export type { WidgetSlotProps } from './widget-slot';
109
119
  export { ScopePicker, validateScopes } from './scope-picker';
110
120
  export type { ScopeAccess } from './scope-picker';
111
- export { PtzPanel, AutotrackSection, MotionZonesSettings } from './cap-settings';
112
- export type { CapSettingsComponentProps } from './cap-settings';
121
+ export { PtzPanel, ConsumablesPanel, AutotrackSection, MotionZonesSettings, MaskShapeCanvas, RecordingPanel } from './cap-settings';
122
+ export type { CapSettingsComponentProps, MaskShapeItem, MaskShapeCanvasProps } from './cap-settings';
123
+ export * from './widget-panel.js';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Pure scroll-geometry helpers for LogStream's follow-the-tail behaviour.
3
+ *
4
+ * Kept free of React/DOM lifecycle so the (subtle) "is the viewport pinned
5
+ * to the bottom?" decision is unit-testable in isolation. The component
6
+ * wires these into a `useLayoutEffect` (capture pinned-state BEFORE rows
7
+ * grow) + a user-scroll handler (re-pin when the operator returns to the
8
+ * bottom). See log-stream.tsx for the lifecycle.
9
+ */
10
+ /** Default distance (px) from the bottom within which we treat the
11
+ * viewport as "pinned". Generous enough to absorb sub-pixel rounding and
12
+ * the height of a partially-revealed last row, tight enough that a
13
+ * deliberate scroll-up of even one full row reads as "not pinned". */
14
+ export declare const PIN_THRESHOLD_PX = 40;
15
+ /** The slice of scroll geometry the pin decision needs. Matches the
16
+ * properties of an `HTMLElement` (`scrollTop` / `scrollHeight` /
17
+ * `clientHeight`) so callers can pass the element fields directly. */
18
+ export interface ScrollGeometry {
19
+ readonly scrollTop: number;
20
+ readonly scrollHeight: number;
21
+ readonly clientHeight: number;
22
+ }
23
+ /**
24
+ * True when the viewport is scrolled to (or within `threshold` px of) the
25
+ * bottom of its content.
26
+ *
27
+ * `scrollHeight - scrollTop - clientHeight` is the distance from the
28
+ * bottom: 0 when fully scrolled down, growing as the operator scrolls up.
29
+ * A `<=` comparison against the threshold means an exact-bottom geometry
30
+ * (distance 0) always counts as pinned even with a 0 threshold.
31
+ */
32
+ export declare function isPinnedToBottom(geometry: ScrollGeometry, threshold?: number): boolean;
@@ -14,6 +14,13 @@ export interface LogStreamProps {
14
14
  readonly addonId?: string;
15
15
  /** Lock to a specific device. When set, the device selector is hidden. */
16
16
  readonly deviceId?: number;
17
+ /**
18
+ * Lock to a container SUBTREE: filters by `containerDeviceId`, returning the
19
+ * container's own logs AND every accessory child's logs in one view (each
20
+ * child stamps its parent's id; a container stamps its own). Pass this
21
+ * INSTEAD of `deviceId` for a container's Logs tab.
22
+ */
23
+ readonly containerDeviceId?: number;
17
24
  /**
18
25
  * Lock to a specific integration. Filter is ALWAYS applied when
19
26
  * provided — current providers don't yet tag loggers with
@@ -52,7 +59,7 @@ export interface LogStreamProps {
52
59
  readonly onClose?: () => void;
53
60
  readonly className?: string;
54
61
  }
55
- export declare function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: propsDeviceId, integrationId: propsIntegrationId, requestId: propsRequestId, level: initialLevel, maxHeight, showScope, showFilters, limit, liveBuffer: externalBuffer, onClose, className, }: LogStreamProps): import("react/jsx-runtime").JSX.Element;
62
+ export declare function LogStream({ agentId: propsAgentId, addonId: propsAddonId, deviceId: propsDeviceId, containerDeviceId: propsContainerDeviceId, integrationId: propsIntegrationId, requestId: propsRequestId, level: initialLevel, maxHeight, showScope, showFilters, limit, liveBuffer: externalBuffer, onClose, className, }: LogStreamProps): import("react/jsx-runtime").JSX.Element;
56
63
  export interface FloatingLogStreamProps extends LogStreamProps {
57
64
  /** Position: 'bottom' anchors to parent bottom, 'overlay' is absolute positioned. */
58
65
  readonly position?: 'bottom' | 'overlay';
@@ -1,16 +1,16 @@
1
1
  import { ReactNode } from 'react';
2
- import { SignalingResult, ClientStreamHints } from './camera-stream-player';
2
+ import { CamProfile } from '@camstack/types';
3
+ import { SignalingResult, ClientOfferResult, ClientStreamHints, SessionSignalingState } from './camera-stream-player';
3
4
  import { DeviceDetections } from '../hooks/use-device-detections';
4
5
  /**
5
- * Discriminated WebRTC target — same shape as the backend cap. Kept
6
- * locally on the StreamChoice so consumers don't need to import from
7
- * `@camstack/types` to render a panel.
6
+ * Discriminated WebRTC target — same shape as the backend cap. The
7
+ * `profile` tier uses the canonical `CamProfile` enum.
8
8
  */
9
9
  export type StreamChoiceTarget = {
10
10
  readonly kind: 'adaptive';
11
11
  } | {
12
12
  readonly kind: 'profile';
13
- readonly profile: 'high' | 'mid' | 'low';
13
+ readonly profile: CamProfile;
14
14
  } | {
15
15
  readonly kind: 'cam-stream';
16
16
  readonly camStreamId: string;
@@ -42,10 +42,54 @@ export interface StreamStats {
42
42
  readonly uptimeMs: number;
43
43
  }
44
44
  export interface StreamPanelProps {
45
- readonly serverUrl: string;
46
- readonly createSession: (target: StreamChoiceTarget, hints?: ClientStreamHints) => Promise<SignalingResult>;
47
- readonly sendAnswer: (sessionId: string, sdpAnswer: string) => Promise<void>;
45
+ readonly serverUrl?: string;
46
+ readonly createSession?: (target: StreamChoiceTarget, hints?: ClientStreamHints) => Promise<SignalingResult>;
47
+ readonly sendAnswer?: (sessionId: string, sdpAnswer: string) => Promise<void>;
48
+ /**
49
+ * Client-offer signaling — PREFERRED over `createSession` for browsers.
50
+ * Closes over the selected target; the player builds the offer and this
51
+ * posts it. Lets iOS pass H.264 High/Main (incl. 4K) through untouched.
52
+ * Optional so non-browser callers (benchmark) can stay on server-offer.
53
+ */
54
+ readonly handleOffer?: (target: StreamChoiceTarget, sdpOffer: string, sessionId?: string) => Promise<ClientOfferResult>;
55
+ /** Browser-side ICE servers (STUN + TURN) for client-offer mode. */
56
+ readonly getIceServers?: () => Promise<readonly RTCIceServer[] | undefined>;
57
+ /** Trickle ICE — push a client candidate to the server (sessionId-scoped). */
58
+ readonly addIceCandidate?: (sessionId: string, candidate: RTCIceCandidateInit) => Promise<void>;
59
+ /** Trickle ICE — poll the server's gathered candidates (sessionId-scoped). */
60
+ readonly getIceCandidates?: (sessionId: string) => Promise<{
61
+ candidates: RTCIceCandidateInit[];
62
+ done: boolean;
63
+ }>;
48
64
  readonly closeSession?: (sessionId: string) => Promise<void>;
65
+ /**
66
+ * Poll a session's live signaling state (client-offer mode). A non-null
67
+ * `pendingRenegotiation` after an adaptive tier switch makes the player
68
+ * transparently re-offer on the same session. Optional — omit to disable
69
+ * adaptive re-offer (steady-state behaviour is unchanged).
70
+ */
71
+ readonly getSessionState?: (sessionId: string) => Promise<SessionSignalingState>;
72
+ /**
73
+ * When set, the panel switches to VOD mode: it renders an `HlsVideo`
74
+ * over this master `.m3u8` URL INSTEAD of the live WebRTC player, and
75
+ * the live signaling props are ignored. Lets the same hero player show
76
+ * recordings/clips (driven by the Recording tab) without a second
77
+ * player. Clearing it returns the panel to live mode.
78
+ */
79
+ readonly playbackUrl?: string;
80
+ /** Bearer token for the admin-gated data-plane playback route (optional). */
81
+ readonly playbackAuthToken?: string | null;
82
+ /**
83
+ * Short label for the clip/window being played — shown in the header in
84
+ * place of the stream selector while in VOD mode.
85
+ */
86
+ readonly playbackLabel?: string;
87
+ /**
88
+ * Invoked when the operator clicks the (re-purposed) play/stop button
89
+ * while in VOD mode. The caller clears its playback request to return
90
+ * the panel to the live stream.
91
+ */
92
+ readonly onExitPlayback?: () => void;
49
93
  /** Available streams. If omitted or single entry, no dropdown shown. */
50
94
  readonly streams?: readonly StreamChoice[];
51
95
  /** Currently active StreamChoice id. Defaults to first stream. */
@@ -74,6 +118,13 @@ export interface StreamPanelProps {
74
118
  readonly showPlayStop?: boolean;
75
119
  /** Snapshot source URL (data: URI). Only used when showPlayStop=true. */
76
120
  readonly snapshotSrc?: string | null;
121
+ /**
122
+ * Optional poster (snapshot data-URL) painted by the live `<video>` until
123
+ * its FIRST frame decodes — a cold-start fallback only. Independent of
124
+ * `snapshotSrc` (which is the play/stop preview). Caller-supplied; when
125
+ * omitted the video simply starts black until the first frame.
126
+ */
127
+ readonly posterUrl?: string;
77
128
  /** Whether snapshot is currently loading */
78
129
  readonly snapshotLoading?: boolean;
79
130
  /** Callback to refresh snapshot */
@@ -140,4 +191,4 @@ export interface StreamPanelProps {
140
191
  readonly chromeless?: boolean;
141
192
  readonly className?: string;
142
193
  }
143
- export declare function StreamPanel({ serverUrl, createSession, sendAnswer, closeSession, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, defaultShowDetections, defaultShowMotion, streamStats, autoPlay, showPlayStop, snapshotSrc, snapshotLoading, onRefreshSnapshot, showStreamStats, children, extraOverlay, ptzAvailable, ptzShown, ptzOverlay, onPtzToggle, intercomAvailable, intercomShown, onIntercomToggle, chromeless, className, }: StreamPanelProps): import("react/jsx-runtime").JSX.Element;
194
+ export declare function StreamPanel({ serverUrl, createSession, sendAnswer, handleOffer, getIceServers, addIceCandidate, getIceCandidates, closeSession, getSessionState, playbackUrl, playbackAuthToken, onExitPlayback, posterUrl, streams, activeStreamId: controlledStreamId, onStreamChange, deviceName, phase, pipelineMetrics, detections, defaultShowDetections, defaultShowMotion, streamStats, autoPlay, showPlayStop, snapshotSrc, snapshotLoading, onRefreshSnapshot, showStreamStats, children, extraOverlay, ptzAvailable, ptzShown, ptzOverlay, onPtzToggle, intercomAvailable, intercomShown, onIntercomToggle, chromeless, className, }: StreamPanelProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { TIMEZONES, findTimezone, Timezone, TimezoneDstRule, Weekday } from '@camstack/types';
2
+ export { TIMEZONES, findTimezone };
3
+ export type { Timezone, TimezoneDstRule, Weekday };
4
+ export interface TimezoneSelectorProps {
5
+ /** Currently selected IANA id (e.g. 'Europe/Rome'). */
6
+ readonly value: string;
7
+ /** Fired with the newly chosen IANA id. */
8
+ readonly onChange: (id: string) => void;
9
+ readonly disabled?: boolean;
10
+ }
11
+ /**
12
+ * Friendly timezone picker. Renders a native `<select>` grouped by
13
+ * region via `<optgroup>`, sourced from the curated `TIMEZONES`
14
+ * catalogue. The selected value is the IANA id; DST is implied by the
15
+ * chosen zone (each option carries its standard offset + DST rule),
16
+ * so there is no separate DST control.
17
+ */
18
+ export declare function TimezoneSelector({ value, onChange, disabled }: TimezoneSelectorProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { ReactNode } from 'react';
2
+ interface WidgetPanelProps {
3
+ /** Header title — rendered uppercase, letter-spaced, foreground. */
4
+ readonly title: string;
5
+ /** Optional leading icon node (size it `h-3.5 w-3.5` for alignment). */
6
+ readonly icon?: ReactNode;
7
+ /** Optional right-aligned header slot (timestamp, live badge, …). Ignored
8
+ * when `collapsible` is set — the chevron takes that slot. */
9
+ readonly headerRight?: ReactNode;
10
+ /** Render the header as a toggle that shows/hides the body. */
11
+ readonly collapsible?: boolean;
12
+ /** Initial open state for a collapsible panel (default open). */
13
+ readonly defaultOpen?: boolean;
14
+ /** Body padding/utility override (default `p-3`). */
15
+ readonly bodyClassName?: string;
16
+ readonly children: ReactNode;
17
+ }
18
+ export declare function WidgetPanel({ title, icon, headerRight, collapsible, defaultOpen, bodyClassName, children, }: WidgetPanelProps): import("react/jsx-runtime").JSX.Element;
19
+ interface WidgetMetricCardProps {
20
+ readonly label: string;
21
+ readonly icon?: ReactNode;
22
+ /** The metric value (text or node). */
23
+ readonly children: ReactNode;
24
+ /** Optional sub-line under the value (e.g. "3 segment ranges"). */
25
+ readonly footer?: ReactNode;
26
+ }
27
+ export declare function WidgetMetricCard({ label, icon, children, footer }: WidgetMetricCardProps): import("react/jsx-runtime").JSX.Element;
28
+ export {};
@@ -0,0 +1,17 @@
1
+ import { ReactNode } from 'react';
2
+ export interface VodPlaybackRequest {
3
+ /** Master `.m3u8` URL through the hub data-plane (relative). */
4
+ readonly url: string;
5
+ /** Short human label shown in the hero while playing (e.g. a timestamp). */
6
+ readonly label?: string;
7
+ }
8
+ export interface VodPlaybackContextValue {
9
+ readonly request: VodPlaybackRequest | null;
10
+ readonly play: (request: VodPlaybackRequest) => void;
11
+ readonly clear: () => void;
12
+ }
13
+ export declare function VodPlaybackProvider({ children }: {
14
+ readonly children: ReactNode;
15
+ }): import("react/jsx-runtime").JSX.Element;
16
+ /** @returns the VOD playback controller (inert no-op outside a provider). */
17
+ export declare function useVodPlayback(): VodPlaybackContextValue;