@camstack/ui-library 0.1.57 → 0.2.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/dist/composites/addon-global-settings-form.d.ts +1 -1
- package/dist/composites/agent-step-editor.d.ts +1 -1
- package/dist/composites/app-shell/app-shell.d.ts +1 -1
- package/dist/composites/app-shell/sidebar-item.d.ts +1 -1
- package/dist/composites/app-shell/sidebar.d.ts +1 -1
- package/dist/composites/audio-classification-list.d.ts +1 -1
- package/dist/composites/audio-level-waveform.d.ts +1 -1
- package/dist/composites/audio-waveform.d.ts +1 -1
- package/dist/composites/battery-badge.d.ts +4 -1
- package/dist/composites/breadcrumb.d.ts +2 -1
- package/dist/composites/camera-stream-player.d.ts +94 -2
- package/dist/composites/cap-settings/AutotrackSection.d.ts +1 -1
- package/dist/composites/cap-settings/ConsumablesPanel.d.ts +2 -0
- package/dist/composites/cap-settings/CoverageTrack.d.ts +12 -0
- package/dist/composites/cap-settings/EventBucketStrip.d.ts +25 -0
- package/dist/composites/cap-settings/EventHeatmap.d.ts +10 -0
- package/dist/composites/cap-settings/MaskShapeCanvas.d.ts +1 -1
- package/dist/composites/cap-settings/MotionZonesSettings.d.ts +1 -1
- package/dist/composites/cap-settings/PrivacyMaskSettings.d.ts +1 -1
- package/dist/composites/cap-settings/PtzPanel.d.ts +1 -1
- package/dist/composites/cap-settings/RecordingPanel.d.ts +2 -0
- package/dist/composites/cap-settings/RecordingRulesEditor.d.ts +7 -0
- package/dist/composites/cap-settings/RecordingSettings.d.ts +8 -0
- package/dist/composites/cap-settings/RecordingTimeline.d.ts +5 -0
- package/dist/composites/cap-settings/ScheduleBandsEditor.d.ts +7 -0
- package/dist/composites/cap-settings/TimelineControls.d.ts +21 -0
- package/dist/composites/cap-settings/event-thumb.d.ts +11 -0
- package/dist/composites/cap-settings/index.d.ts +4 -0
- package/dist/composites/cap-settings/recording-config-form.d.ts +34 -0
- package/dist/composites/cap-settings/recording-spans.d.ts +22 -0
- package/dist/composites/cap-settings/recording-timeline-model.d.ts +84 -0
- package/dist/composites/code-block.d.ts +1 -1
- package/dist/composites/config-form-builder.d.ts +1 -1
- package/dist/composites/config-form-field.d.ts +3 -3
- package/dist/composites/confirm-action-button.d.ts +1 -1
- package/dist/composites/confirm-dialog.d.ts +1 -1
- package/dist/composites/data-table/data-table-header.d.ts +1 -1
- package/dist/composites/data-table/data-table-pagination.d.ts +1 -1
- package/dist/composites/data-table/data-table-row.d.ts +1 -1
- package/dist/composites/data-table/data-table.d.ts +1 -1
- package/dist/composites/data-table.d.ts +1 -1
- package/dist/composites/detection-canvas.d.ts +1 -1
- package/dist/composites/detection-overlay.d.ts +1 -1
- package/dist/composites/detection-result-tree.d.ts +1 -1
- package/dist/composites/dev-shell.d.ts +1 -1
- package/dist/composites/device-activity-panel.d.ts +5 -1
- package/dist/composites/device-card.d.ts +1 -1
- package/dist/composites/device-controls/alarm-hero-card.d.ts +24 -0
- package/dist/composites/device-controls/atoms.d.ts +81 -0
- package/dist/composites/device-controls/brightness-panel.d.ts +3 -0
- package/dist/composites/device-controls/button-control.d.ts +18 -0
- package/dist/composites/device-controls/climate-panel.d.ts +16 -0
- package/dist/composites/device-controls/container-primary-hero.d.ts +24 -0
- package/dist/composites/device-controls/container-primary.d.ts +46 -0
- package/dist/composites/device-controls/control-panel.d.ts +10 -0
- package/dist/composites/device-controls/control-registry.d.ts +74 -0
- package/dist/composites/device-controls/cover-hero-card.d.ts +27 -0
- package/dist/composites/device-controls/cover-inline.d.ts +27 -0
- package/dist/composites/device-controls/cover-panel.d.ts +3 -0
- package/dist/composites/device-controls/dummy-hero-card.d.ts +6 -0
- package/dist/composites/device-controls/fan-hero-card.d.ts +21 -0
- package/dist/composites/device-controls/fan-panel.d.ts +3 -0
- package/dist/composites/device-controls/humidifier-control.d.ts +37 -0
- package/dist/composites/device-controls/image-control.d.ts +24 -0
- package/dist/composites/device-controls/index.d.ts +33 -0
- package/dist/composites/device-controls/lawn-mower-control.d.ts +24 -0
- package/dist/composites/device-controls/light-hero-card.d.ts +16 -0
- package/dist/composites/device-controls/lock-hero-card.d.ts +15 -0
- package/dist/composites/device-controls/lock-panel.d.ts +3 -0
- package/dist/composites/device-controls/media-player-hero-card.d.ts +17 -0
- package/dist/composites/device-controls/media-player-panel.d.ts +9 -0
- package/dist/composites/device-controls/offline-badge.d.ts +11 -0
- package/dist/composites/device-controls/panel-controls.d.ts +17 -0
- package/dist/composites/device-controls/popover-row-action.d.ts +9 -0
- package/dist/composites/device-controls/primary-child.d.ts +18 -0
- package/dist/composites/device-controls/radial-gauge.d.ts +20 -0
- package/dist/composites/device-controls/sensor-hero-card.d.ts +10 -0
- package/dist/composites/device-controls/sensor-inline-control.d.ts +11 -0
- package/dist/composites/device-controls/sensor-value-atom.d.ts +106 -0
- package/dist/composites/device-controls/switch-hero-card.d.ts +13 -0
- package/dist/composites/device-controls/switch-panel.d.ts +3 -0
- package/dist/composites/device-controls/tap-toggle.d.ts +17 -0
- package/dist/composites/device-controls/thermostat-hero-card.d.ts +17 -0
- package/dist/composites/device-controls/types.d.ts +17 -0
- package/dist/composites/device-controls/update-control.d.ts +11 -0
- package/dist/composites/device-controls/vacuum-control.d.ts +36 -0
- package/dist/composites/device-controls/valve-control.d.ts +46 -0
- package/dist/composites/device-controls/water-heater-control.d.ts +41 -0
- package/dist/composites/device-controls/weather-control.d.ts +41 -0
- package/dist/composites/device-export-panel.d.ts +1 -1
- package/dist/composites/device-grid.d.ts +1 -1
- package/dist/composites/device-item/actions.d.ts +12 -1
- package/dist/composites/device-item/child-layout.d.ts +32 -0
- package/dist/composites/device-item/child-section-accordion.d.ts +9 -0
- package/dist/composites/device-item/children-accordion.d.ts +1 -1
- package/dist/composites/device-item/container-children-context.d.ts +15 -0
- package/dist/composites/device-item/device-delete-action.d.ts +8 -0
- package/dist/composites/device-item/header.d.ts +8 -1
- package/dist/composites/device-item/helpers.d.ts +108 -2
- package/dist/composites/device-item/index.d.ts +4 -0
- package/dist/composites/device-item/preview.d.ts +3 -3
- package/dist/composites/device-item/reboot-quick-action.d.ts +9 -0
- package/dist/composites/device-item/status-dot.d.ts +4 -1
- package/dist/composites/device-list/batch-actions-bar.d.ts +15 -0
- package/dist/composites/device-list/batch-toolbar.d.ts +15 -0
- package/dist/composites/device-list/cards-layout.d.ts +18 -0
- package/dist/composites/device-list/columns.d.ts +68 -0
- package/dist/composites/device-list/device-mode.d.ts +115 -0
- package/dist/composites/device-list/filter-chips.d.ts +15 -6
- package/dist/composites/device-list/fuzzy-match.d.ts +27 -0
- package/dist/composites/device-list/generic-mode.d.ts +81 -0
- package/dist/composites/device-list/group.d.ts +19 -0
- package/dist/composites/device-list/hardware-cell.d.ts +7 -0
- package/dist/composites/device-list/hardware.d.ts +26 -0
- package/dist/composites/device-list/icon-action.d.ts +17 -0
- package/dist/composites/device-list/index.d.ts +23 -39
- package/dist/composites/device-list/multi-select.d.ts +22 -0
- package/dist/composites/device-list/sort.d.ts +18 -0
- package/dist/composites/device-list/sortable-header.d.ts +10 -0
- package/dist/composites/device-list/table-layout.d.ts +25 -0
- package/dist/composites/device-list/type-filter.d.ts +19 -0
- package/dist/composites/device-list/url-state.d.ts +7 -2
- package/dist/composites/device-meta.d.ts +38 -0
- package/dist/composites/discovery-panel.d.ts +4 -4
- package/dist/composites/doorbell-recent-panel.d.ts +1 -1
- package/dist/composites/empty-state.d.ts +1 -1
- package/dist/composites/error-box.d.ts +1 -1
- package/dist/composites/event-stream.d.ts +2 -2
- package/dist/composites/filter-bar.d.ts +1 -1
- package/dist/composites/form-field.d.ts +1 -1
- package/dist/composites/hls-quality.d.ts +35 -0
- package/dist/composites/hls-video.d.ts +26 -0
- package/dist/composites/hover-zoom-image.d.ts +18 -0
- package/dist/composites/image-selector.d.ts +1 -1
- package/dist/composites/index.d.ts +15 -4
- package/dist/composites/inference-config-selector.d.ts +1 -1
- package/dist/composites/kebab-menu.d.ts +1 -1
- package/dist/composites/key-value-list.d.ts +1 -1
- package/dist/composites/log-stream-scroll.d.ts +32 -0
- package/dist/composites/log-stream.d.ts +9 -2
- package/dist/composites/login-form.d.ts +1 -1
- package/dist/composites/node-picker.d.ts +1 -1
- package/dist/composites/page-header.d.ts +1 -1
- package/dist/composites/phase-icon.d.ts +1 -1
- package/dist/composites/pipeline-builder.d.ts +1 -1
- package/dist/composites/pipeline-runtime-selector.d.ts +1 -1
- package/dist/composites/pipeline-step.d.ts +3 -3
- package/dist/composites/pipeline-tree-matrix.d.ts +1 -1
- package/dist/composites/provider-badge.d.ts +1 -1
- package/dist/composites/ptz-overlay.d.ts +1 -1
- package/dist/composites/qr-code.d.ts +1 -1
- package/dist/composites/response-log.d.ts +1 -1
- package/dist/composites/scope-picker.d.ts +1 -1
- package/dist/composites/slide-over-panel.d.ts +1 -1
- package/dist/composites/snapshot-button.d.ts +1 -1
- package/dist/composites/stat-card.d.ts +1 -1
- package/dist/composites/state-values-stream.d.ts +1 -1
- package/dist/composites/status-badge.d.ts +1 -1
- package/dist/composites/step-timings.d.ts +1 -1
- package/dist/composites/step-tree-master.d.ts +1 -1
- package/dist/composites/stream-panel.d.ts +45 -10
- package/dist/composites/timezone-selector.d.ts +18 -0
- package/dist/composites/version-badge.d.ts +2 -2
- package/dist/composites/widget-panel.d.ts +28 -0
- package/dist/contexts/custom-field-renderers.d.ts +1 -1
- package/dist/contexts/device-context.d.ts +1 -1
- package/dist/contexts/player-overlays.d.ts +1 -1
- package/dist/contexts/system-context.d.ts +1 -1
- package/dist/contexts/vod-playback.d.ts +17 -0
- package/dist/contexts/widget-registry.d.ts +1 -1
- package/dist/contexts/zone-editing.d.ts +1 -1
- package/dist/generated/system-hooks.d.ts +386 -56
- package/dist/hooks/index.d.ts +8 -2
- package/dist/hooks/use-device-cap-slice.d.ts +19 -0
- package/dist/hooks/use-device-capability.d.ts +12 -0
- package/dist/hooks/use-device-list-page-size.d.ts +14 -0
- package/dist/hooks/use-device-webrtc.d.ts +36 -4
- package/dist/hooks/use-optimistic-slice.d.ts +11 -0
- package/dist/index.cjs +54834 -11195
- package/dist/index.d.ts +1 -0
- package/dist/index.js +54483 -11136
- package/dist/lib/format-control-datetime.d.ts +18 -0
- package/dist/lib/format-last-seen.d.ts +12 -0
- package/dist/lib/format-numeric.d.ts +9 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/primitives/bottom-sheet.d.ts +1 -1
- package/dist/primitives/collapsible-card.d.ts +1 -1
- package/dist/primitives/dialog.d.ts +19 -6
- package/dist/primitives/dropdown.d.ts +3 -3
- package/dist/primitives/floating-panel.d.ts +1 -1
- package/dist/primitives/mobile-drawer.d.ts +1 -1
- package/dist/primitives/popover.d.ts +3 -3
- package/dist/primitives/tabs.d.ts +4 -4
- package/dist/primitives/tooltip.d.ts +11 -5
- package/dist/theme/index.cjs +0 -3
- package/dist/theme/index.js +0 -2
- package/dist/theme/theme-provider.d.ts +1 -1
- package/package.json +13 -5
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/theme/index.cjs.map +0 -1
- package/dist/theme/index.js.map +0 -1
|
@@ -34,4 +34,4 @@ export interface DataTableProps<T> {
|
|
|
34
34
|
/** Per-row className resolver (e.g. status-coloured backgrounds). */
|
|
35
35
|
readonly rowClassName?: (row: T, rowIndex: number) => string | undefined;
|
|
36
36
|
}
|
|
37
|
-
export declare function DataTable<T>({ columns, rows, rowKey, onRowClick, minWidthPx, emptyMessage, className, bordered, rowClassName, }: DataTableProps<T>): import("react
|
|
37
|
+
export declare function DataTable<T>({ columns, rows, rowKey, onRowClick, minWidthPx, emptyMessage, className, bordered, rowClassName, }: DataTableProps<T>): import("react").JSX.Element | null;
|
|
@@ -26,4 +26,4 @@ export interface DetectionCanvasProps {
|
|
|
26
26
|
/** Border width for bboxes in px (default: 2) */
|
|
27
27
|
readonly borderWidth?: number;
|
|
28
28
|
}
|
|
29
|
-
export declare function DetectionCanvas({ src, imageWidth, imageHeight, detections, classColors, aspectRatio, className, placeholder, showConfidence, minConfidence, borderWidth, }: DetectionCanvasProps): import("react
|
|
29
|
+
export declare function DetectionCanvas({ src, imageWidth, imageHeight, detections, classColors, aspectRatio, className, placeholder, showConfidence, minConfidence, borderWidth, }: DetectionCanvasProps): import("react").JSX.Element;
|
|
@@ -6,4 +6,4 @@ export interface DetectionOverlayProps {
|
|
|
6
6
|
readonly showDetections?: boolean;
|
|
7
7
|
readonly showPhaseIndicator?: boolean;
|
|
8
8
|
}
|
|
9
|
-
export declare function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones, showMotionRaw, showDetections, showPhaseIndicator, }: DetectionOverlayProps): import("react
|
|
9
|
+
export declare function DetectionOverlay({ detections: { motion, motionRaw, detection, phase }, showMotionZones, showMotionRaw, showDetections, showPhaseIndicator, }: DetectionOverlayProps): import("react").JSX.Element | null;
|
|
@@ -8,4 +8,4 @@ export interface DetectionResultTreeProps {
|
|
|
8
8
|
/** Callback when a detection's visibility is toggled */
|
|
9
9
|
readonly onToggleVisibility?: (key: string, visible: boolean) => void;
|
|
10
10
|
}
|
|
11
|
-
export declare function DetectionResultTree({ detections, classColors, className, hiddenKeys, onToggleVisibility, }: DetectionResultTreeProps): import("react
|
|
11
|
+
export declare function DetectionResultTree({ detections, classColors, className, hiddenKeys, onToggleVisibility, }: DetectionResultTreeProps): import("react").JSX.Element;
|
|
@@ -16,5 +16,5 @@ interface DevShellContextValue {
|
|
|
16
16
|
logout: () => void;
|
|
17
17
|
}
|
|
18
18
|
export declare function useDevShell(): DevShellContextValue;
|
|
19
|
-
export declare function DevShell({ children, serverUrl, title
|
|
19
|
+
export declare function DevShell({ children, serverUrl, title }: DevShellProps): import("react").JSX.Element;
|
|
20
20
|
export {};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export interface DeviceActivityPanelProps {
|
|
2
2
|
readonly deviceId: number;
|
|
3
|
+
/** When this device is a Container, its own id — the Logs tab then shows the
|
|
4
|
+
* whole subtree (container + every child) by filtering `containerDeviceId`
|
|
5
|
+
* instead of `deviceId`. Omit/undefined for a non-container. */
|
|
6
|
+
readonly containerDeviceId?: number;
|
|
3
7
|
/** Initial event categories the user wants tracked. Defaults to "all". */
|
|
4
8
|
readonly defaultEventCategories?: readonly string[];
|
|
5
9
|
/** Initial state-cap whitelist. Empty = show every cap that fires. */
|
|
@@ -25,5 +29,5 @@ declare const TABS: readonly [{
|
|
|
25
29
|
readonly icon: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
26
30
|
}];
|
|
27
31
|
export type ActivityTabId = (typeof TABS)[number]['id'];
|
|
28
|
-
export declare function DeviceActivityPanel({ deviceId, defaultEventCategories, defaultStateCaps, initialTab, className, maxHeight, }: DeviceActivityPanelProps): import("react
|
|
32
|
+
export declare function DeviceActivityPanel({ deviceId, containerDeviceId, defaultEventCategories, defaultStateCaps, initialTab, className, maxHeight, }: DeviceActivityPanelProps): import("react").JSX.Element;
|
|
29
33
|
export {};
|
|
@@ -35,4 +35,4 @@ export interface DeviceCardProps {
|
|
|
35
35
|
/** Additional CSS classes */
|
|
36
36
|
className?: string;
|
|
37
37
|
}
|
|
38
|
-
export declare function DeviceCard({ title, subtitle, status, selected, onClick, badges, actions, offlineAction, className, }: DeviceCardProps): import("react
|
|
38
|
+
export declare function DeviceCard({ title, subtitle, status, selected, onClick, badges, actions, offlineAction, className, }: DeviceCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* Row-sized alarm control: the shared Disarm + arm-mode segment strip only —
|
|
5
|
+
* no glyph, no state label, no card padding. Cap-gated on `alarm-panel`.
|
|
6
|
+
* Drops into a 200 px control column without towering over sibling rows.
|
|
7
|
+
*/
|
|
8
|
+
export declare function AlarmInlineControl({ trpc, deviceId, optimistic }: DeviceControlProps): ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* AlarmHeroCard — segmented arm/disarm hero for AlarmPanel devices.
|
|
11
|
+
*
|
|
12
|
+
* Renders (Spec §3):
|
|
13
|
+
* - A shield glyph + state label tinted by lifecycle state (disarmed=muted,
|
|
14
|
+
* armed=green, arming/pending=amber, triggered=red).
|
|
15
|
+
* - The shared `AlarmSegments` strip: a Disarm button plus one arm button per
|
|
16
|
+
* `availableModes` entry (Home / Away / Night / …). The currently-active
|
|
17
|
+
* segment is highlighted; transitioning states highlight none.
|
|
18
|
+
*
|
|
19
|
+
* Cap-gated on `alarm-panel` — returns null when the device lacks the cap.
|
|
20
|
+
* PIN entry (when `requiresCode`) is deferred to a later task; the segments
|
|
21
|
+
* call arm/disarm without a code, and the provider rejects when a code is
|
|
22
|
+
* required — surfaced upstream.
|
|
23
|
+
*/
|
|
24
|
+
export declare function AlarmHeroCard({ trpc, deviceId, optimistic }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
export declare const FILL: "fill";
|
|
3
|
+
export declare const RIGHT: "right";
|
|
4
|
+
export declare const CENTER: "center";
|
|
5
|
+
export declare const FIT: "fit";
|
|
6
|
+
export type ControlAlign = typeof FILL | typeof RIGHT | typeof CENTER | typeof FIT;
|
|
7
|
+
interface ControlColumnProps extends ComponentPropsWithoutRef<'div'> {
|
|
8
|
+
readonly align: ControlAlign;
|
|
9
|
+
readonly children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/** The one control column every device-row/hero control sits in.
|
|
12
|
+
* FILL → the child stretches to the full fixed column width (steppers, selects, buttons, cover triad).
|
|
13
|
+
* RIGHT → the child keeps its natural width, flush to the right edge of the fixed column (readouts, toggles — card view).
|
|
14
|
+
* CENTER → the child keeps its natural width, centered in the fixed column (readouts, toggles).
|
|
15
|
+
* FIT → the column DROPS its fixed width and sizes to its content (table view). The control takes
|
|
16
|
+
* its natural width and lays out in sequence with the trailing trash + status dot, so a wide
|
|
17
|
+
* control (climate stepper + mode select, cover triad + %) never overflows a fixed box and
|
|
18
|
+
* collides with the neighbours. FILL has no effect under FIT — a stretchy child in a
|
|
19
|
+
* content-width wrapper simply takes its natural width.
|
|
20
|
+
* FILL, RIGHT and CENTER share the fixed `w-[140px]` box (card / minimal / hero views). */
|
|
21
|
+
export declare function ControlColumn({ align, children, className, ...rest }: ControlColumnProps): ReactNode;
|
|
22
|
+
interface ValueReadoutProps {
|
|
23
|
+
readonly value: string;
|
|
24
|
+
readonly unit?: string;
|
|
25
|
+
}
|
|
26
|
+
/** A value + inline unit suffix (no separator). E.g. `60s`, `22%`. */
|
|
27
|
+
export declare function ValueReadout({ value, unit }: ValueReadoutProps): ReactNode;
|
|
28
|
+
interface StepperProps {
|
|
29
|
+
readonly value: number | string;
|
|
30
|
+
readonly unit?: string;
|
|
31
|
+
readonly onDelta: (d: 1 | -1) => void;
|
|
32
|
+
}
|
|
33
|
+
/** Increment/decrement control with value + unit display. */
|
|
34
|
+
export declare function Stepper({ value, unit, onDelta }: StepperProps): ReactNode;
|
|
35
|
+
interface SlideToggleProps {
|
|
36
|
+
readonly on: boolean;
|
|
37
|
+
readonly targetLabel: string;
|
|
38
|
+
readonly onConfirm: () => void;
|
|
39
|
+
}
|
|
40
|
+
/** Safety slide: onConfirm fires only after the thumb is dragged past threshold, never on a plain tap. */
|
|
41
|
+
export declare function SlideToggle({ on, targetLabel, onConfirm }: SlideToggleProps): ReactNode;
|
|
42
|
+
interface ArcKnobProps {
|
|
43
|
+
readonly fraction: number;
|
|
44
|
+
readonly color: string;
|
|
45
|
+
/**
|
|
46
|
+
* Distance in px from the rotating container's top edge to the knob's top
|
|
47
|
+
* edge. The knob is 20px tall, so its CENTER sits at `knobTopPx + 10` px
|
|
48
|
+
* from the top. For the knob center to ride the ring's centre radius the
|
|
49
|
+
* caller passes `(containerCenter − ringRadius) − 10`. Defaults to the
|
|
50
|
+
* thermostat gauge value (176px container, radius 76 → 88 − 76 − 10 = 2).
|
|
51
|
+
*/
|
|
52
|
+
readonly knobTopPx?: number;
|
|
53
|
+
/**
|
|
54
|
+
* When provided, the knob becomes interactive: dragging it reports the new
|
|
55
|
+
* arc fraction (0..1) to the parent, which owns the value and re-renders the
|
|
56
|
+
* knob at the new `fraction`. When omitted the knob is a display-only
|
|
57
|
+
* indicator (no grab cursor, no pointer handlers).
|
|
58
|
+
*/
|
|
59
|
+
readonly onDragFraction?: (fraction: number) => void;
|
|
60
|
+
}
|
|
61
|
+
/** Half the ArcKnob's 20px (h-5) height. Callers seat the knob centre on a
|
|
62
|
+
* ring by computing `(containerCentre − ringRadius) − KNOB_HALF_PX`. */
|
|
63
|
+
export declare const KNOB_HALF_PX = 10;
|
|
64
|
+
/**
|
|
65
|
+
* White knob riding a circular arc at `fraction` (0..1). For thermostat/light/fan.
|
|
66
|
+
*
|
|
67
|
+
* Display-only by default. Pass `onDragFraction` to make the knob draggable:
|
|
68
|
+
* pointer capture is taken on the knob, and pointer moves are mapped to a new
|
|
69
|
+
* arc fraction reported back to the parent (the parent owns the value).
|
|
70
|
+
*/
|
|
71
|
+
export declare function ArcKnob({ fraction, color, knobTopPx, onDragFraction }: ArcKnobProps): ReactNode;
|
|
72
|
+
interface GripTrackProps {
|
|
73
|
+
readonly fraction: number;
|
|
74
|
+
readonly color?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Horizontal track with a white grip thumb at `fraction` (0..1). For seek/volume/brightness.
|
|
78
|
+
* @remarks display-only indicator; interactive drag is deferred to a later task.
|
|
79
|
+
*/
|
|
80
|
+
export declare function GripTrack({ fraction, color }: GripTrackProps): ReactNode;
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* ButtonControl (inline) — compact "Press" trigger for a device-list row.
|
|
5
|
+
*
|
|
6
|
+
* The `button` cap is fire-only (no status / runtimeState), so we bypass
|
|
7
|
+
* `useDeviceCapability` (which requires a slice) and resolve the cap
|
|
8
|
+
* handle directly from the device proxy. We guard on `cap === undefined`
|
|
9
|
+
* (device has no button cap) and render nothing in that case.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ButtonControl({ trpc, deviceId }: DeviceControlProps): ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* ButtonHeroCard — large press-actuator card for the device-detail hero area.
|
|
14
|
+
*
|
|
15
|
+
* Renders a centred "Press" button with real design-token classes. The cap is
|
|
16
|
+
* fire-only so no state display is needed — the affordance IS the control.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ButtonHeroCard({ trpc, deviceId }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ControlPanelProps } from './types.js';
|
|
3
|
+
import { HvacMode } from '@camstack/types';
|
|
4
|
+
/**
|
|
5
|
+
* Exhaustive colour map — one entry per HvacMode. Build will fail if a
|
|
6
|
+
* mode is added to the enum and not reflected here (Record<HvacMode, ...>
|
|
7
|
+
* + `satisfies` means TypeScript enforces full coverage).
|
|
8
|
+
*/
|
|
9
|
+
export declare const MODE_COLOR: Record<HvacMode, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Mode text-accent colour — applied to the compact (inline) temperature value
|
|
12
|
+
* as a subtle cue, replacing the old bordered/filled mode box so the control
|
|
13
|
+
* matches the borderless cover/lock inline visual language.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MODE_TEXT_COLOR: Record<HvacMode, string>;
|
|
16
|
+
export declare function ClimatePanel({ trpc, deviceId, features: _features, layout, optimistic, }: ControlPanelProps): ReactNode;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { UseDeviceProxyTrpc } from '../../hooks/use-device-proxy';
|
|
3
|
+
import { ContainerChild } from './container-primary';
|
|
4
|
+
/** A child row the hero can render + offer in the picker. */
|
|
5
|
+
export interface ContainerHeroChild extends ContainerChild {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly features?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface ContainerPrimaryHeroProps {
|
|
10
|
+
readonly trpc: UseDeviceProxyTrpc;
|
|
11
|
+
/** The container's entity-children (from `deviceManager.getChildren`). */
|
|
12
|
+
readonly children: readonly ContainerHeroChild[];
|
|
13
|
+
/** Container's LEGACY persisted primary-child override (numeric child id) —
|
|
14
|
+
* consulted only when no durable `primaryChildEntityId` is set. */
|
|
15
|
+
readonly linkDeviceId: number | null | undefined;
|
|
16
|
+
/** Container's DURABLE primary-child override (chosen child's entityId) —
|
|
17
|
+
* null/undefined ⇒ no durable override (falls back to linkDeviceId, then
|
|
18
|
+
* priority default). */
|
|
19
|
+
readonly primaryChildEntityId?: string | null | undefined;
|
|
20
|
+
/** Persist the chosen primary child. Called with the picked child's
|
|
21
|
+
* re-sync/rename-stable `entityId`. */
|
|
22
|
+
readonly onSetPrimary: (childEntityId: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function ContainerPrimaryHero({ trpc, children, linkDeviceId, primaryChildEntityId, onSetPrimary, }: ContainerPrimaryHeroProps): ReactNode;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ChildRef } from './primary-child';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal shape this module needs from a child device row. Structurally
|
|
4
|
+
* compatible with `DeviceItemDevice` / `DeviceInfo` — callers pass the raw
|
|
5
|
+
* `getChildren` rows through.
|
|
6
|
+
*/
|
|
7
|
+
export interface ContainerChild {
|
|
8
|
+
readonly id: number;
|
|
9
|
+
readonly stableId: string;
|
|
10
|
+
readonly type: string;
|
|
11
|
+
readonly sourceInfo?: {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Re-sync-stable identity of a child. Prefers the upstream-system dispatch key
|
|
17
|
+
* (`sourceInfo.id` — e.g. HA `entity_id`); falls back to `stableId` for
|
|
18
|
+
* providers that never populated SourceInfo. Both survive a re-sync that may
|
|
19
|
+
* reallocate the numeric `id`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function childEntityId(child: ContainerChild): string;
|
|
22
|
+
/** Project a raw child row onto the pure resolver's {@link ChildRef} shape. */
|
|
23
|
+
export declare function containerChildToRef(child: ContainerChild): ChildRef;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the entityId override from the container's persisted `linkDeviceId`.
|
|
26
|
+
* Returns the linked child's stable entityId, or `undefined` when there is no
|
|
27
|
+
* link or the link is stale (points to a numeric id no longer present) — in
|
|
28
|
+
* which case the resolver falls back to the priority default.
|
|
29
|
+
*/
|
|
30
|
+
export declare function overrideEntityIdFromLink(children: readonly ContainerChild[], linkDeviceId: number | null | undefined): string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Full container → primary-child resolution: project children to refs, resolve
|
|
33
|
+
* the override entityId, and delegate to the pure resolver. Returns `null` for a
|
|
34
|
+
* container with no children (caller degrades gracefully).
|
|
35
|
+
*
|
|
36
|
+
* Override precedence:
|
|
37
|
+
* 1. `primaryChildEntityId` — the DURABLE override (re-sync/rename-stable),
|
|
38
|
+
* passed straight to the resolver which matches on `entityId`. Wins when a
|
|
39
|
+
* non-empty string is supplied.
|
|
40
|
+
* 2. `linkDeviceId` — LEGACY numeric override, re-derived to an entityId from
|
|
41
|
+
* the live child set. Consulted only when there is no durable override.
|
|
42
|
+
*
|
|
43
|
+
* When neither resolves to a live child, the resolver falls back to the
|
|
44
|
+
* priority default.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveContainerPrimary(children: readonly ContainerChild[], linkDeviceId: number | null | undefined, primaryChildEntityId?: string | null | undefined): ChildRef | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ControlPanelProps } from './types.js';
|
|
3
|
+
/** Trim an HA date value to the `<input type=date>` shape ('YYYY-MM-DD'). */
|
|
4
|
+
export declare function toDateInput(value: string): string;
|
|
5
|
+
/** Trim an HA time value ('HH:MM:SS') to the `<input type=time>` shape ('HH:MM'). */
|
|
6
|
+
export declare function toTimeInput(value: string): string;
|
|
7
|
+
/** Trim an HA datetime value to the `<input type=datetime-local>` shape
|
|
8
|
+
* ('YYYY-MM-DDTHH:MM'). Accepts both 'T'- and space-separated forms. */
|
|
9
|
+
export declare function toDateTimeInput(value: string): string;
|
|
10
|
+
export declare function ControlPanel({ trpc, deviceId, features: _features, layout, optimistic, }: ControlPanelProps): ReactNode;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceType } from '@camstack/types';
|
|
3
|
+
import { UseDeviceProxyTrpc } from '../../hooks/use-device-proxy';
|
|
4
|
+
import { ControlAlign } from './atoms';
|
|
5
|
+
export { coverHighlight } from './cover-inline';
|
|
6
|
+
export interface DeviceControlProps {
|
|
7
|
+
readonly trpc: UseDeviceProxyTrpc;
|
|
8
|
+
readonly deviceId: number;
|
|
9
|
+
readonly features: readonly string[] | undefined;
|
|
10
|
+
/** Enable optimistic UI mode (default: true). Set to false to disable. */
|
|
11
|
+
readonly optimistic?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface DeviceTypeControl {
|
|
14
|
+
/** Compact, state-aware controls rendered directly in a device-list row. */
|
|
15
|
+
readonly InlineControl: (p: DeviceControlProps) => ReactNode;
|
|
16
|
+
/** Full control surface rendered as a card in the device-detail hero area. */
|
|
17
|
+
readonly HeroCard: (p: DeviceControlProps) => ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Exhaustive record over DeviceType. Omitting a member causes a
|
|
21
|
+
* TypeScript build error (same pattern as DEVICE_TYPE_ACTIONS).
|
|
22
|
+
*/
|
|
23
|
+
export declare const DEVICE_TYPE_CONTROL: Record<DeviceType, DeviceTypeControl>;
|
|
24
|
+
/**
|
|
25
|
+
* Per-type FILL flag.
|
|
26
|
+
*
|
|
27
|
+
* true — range / choice / button controls (cover ▲■▼ triad, thermostat
|
|
28
|
+
* setpoint stepper, media/control/button action buttons, alarm
|
|
29
|
+
* segmented control). The child STRETCHES to the full column width.
|
|
30
|
+
* false — readouts, tap-toggles, icon controls (lock), and dummy/placeholder
|
|
31
|
+
* types. The child keeps its NATURAL width; where it sits in the
|
|
32
|
+
* column (flush right vs centered) is decided by the caller via a
|
|
33
|
+
* `ControlPlacement` — see `resolveControlAlign`.
|
|
34
|
+
*
|
|
35
|
+
* Dummy types (Camera, Hub, Generic, Weather, Vacuum, Container, and placeholder
|
|
36
|
+
* types Notifier/Script/Automation whose InlineControl renders "—") are `false` —
|
|
37
|
+
* the dash placeholder must not be stretched to the full column width. (AlarmPanel
|
|
38
|
+
* has a real segmented inline control and is `true`.) When a later task gives a
|
|
39
|
+
* remaining placeholder type a real stretchy inline control, flip its flag to true.
|
|
40
|
+
*
|
|
41
|
+
* Exhaustive over DeviceType — a missing member is a TypeScript build error.
|
|
42
|
+
*/
|
|
43
|
+
export declare const CONTROL_FILLS: Record<DeviceType, boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Where a control sits, and whether the column carries the fixed `w-[140px]` box.
|
|
46
|
+
* 'right' — natural-width content flush to the fixed column's right edge (card / minimal views).
|
|
47
|
+
* 'center' — natural-width content centered in the fixed column.
|
|
48
|
+
* 'table' — the column DROPS its fixed width and sizes to its content (table view). Every type
|
|
49
|
+
* resolves to FIT so the control takes its natural width and lays out in sequence with
|
|
50
|
+
* the trailing trash + status dot, never overflowing a fixed box and colliding.
|
|
51
|
+
* FILL controls ignore 'right'/'center' (they always stretch to the fixed width); under 'table'
|
|
52
|
+
* a FILL control simply takes its natural width in the content-sized wrapper.
|
|
53
|
+
*/
|
|
54
|
+
export type ControlPlacement = 'right' | 'center' | 'table';
|
|
55
|
+
/**
|
|
56
|
+
* Runtime-string-safe lookup: a device row's `type` crosses the wire
|
|
57
|
+
* as a plain string, so an unrecognised value resolves to null instead
|
|
58
|
+
* of indexing the registry with an unverified key.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveDeviceControl(type: string): DeviceTypeControl | null;
|
|
61
|
+
/**
|
|
62
|
+
* Runtime-string-safe alignment lookup for the fixed-width control column.
|
|
63
|
+
*
|
|
64
|
+
* A device's `type` crosses the wire as a plain string;
|
|
65
|
+
* `DEVICE_TYPE_VALUES.has(type)` narrows it to `DeviceType` before indexing
|
|
66
|
+
* `CONTROL_FILLS`, making the cast sound. The `'table'` placement is
|
|
67
|
+
* content-width for EVERY type (returns `FIT`), so a wide control never
|
|
68
|
+
* overflows a fixed box — the FILL flag is irrelevant there. For the fixed-box
|
|
69
|
+
* placements a FILL type always stretches (`FILL`) and a natural-width type is
|
|
70
|
+
* placed by the caller's `placement` — `'center'` → `CENTER`, `'right'` →
|
|
71
|
+
* `RIGHT` (card / minimal view). An unrecognised type falls back to
|
|
72
|
+
* natural-width placement.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveControlAlign(type: string, placement: ControlPlacement): ControlAlign;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* CoverHeroCard — full control surface for the device-detail hero area.
|
|
5
|
+
*
|
|
6
|
+
* TWO VARIANTS based on whether the cover reports a position:
|
|
7
|
+
*
|
|
8
|
+
* With position (position !== null):
|
|
9
|
+
* - Window graphic with slats descending from top to (100-position)%
|
|
10
|
+
* - Visual (display-only) lever at the slat boundary with % label
|
|
11
|
+
* - Open / Stop / Close buttons with state-aware highlight
|
|
12
|
+
* - Interactive position range input (gated on CoverPositionable)
|
|
13
|
+
* - Tilt range input (gated on CoverTilt)
|
|
14
|
+
*
|
|
15
|
+
* Without position (open/close-only, position === null):
|
|
16
|
+
* - Window graphic showing state via clear pane (open) or full slats (closed)
|
|
17
|
+
* - NO lever, NO % label; the value slot shows the cover STATE text (no %)
|
|
18
|
+
* - Open / Stop / Close buttons with state-aware highlight
|
|
19
|
+
*
|
|
20
|
+
* Position support is detected via `CoverStatus.position !== null`.
|
|
21
|
+
* The interactive setPosition slider is gated on `DeviceFeature.CoverPositionable`.
|
|
22
|
+
*
|
|
23
|
+
* Follows the same `useDeviceCapability` pattern as CoverPanel / CoverInlineControl.
|
|
24
|
+
* Only hides when the device truly has no cover cap — a transient undefined slice
|
|
25
|
+
* renders a neutral "unknown" state with all buttons still mounted.
|
|
26
|
+
*/
|
|
27
|
+
export declare function CoverHeroCard({ trpc, deviceId, features, optimistic, }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { CoverState } from '@camstack/types';
|
|
3
|
+
import { DeviceControlProps } from './control-registry';
|
|
4
|
+
/** Button highlight variant for cover state-aware colouring. */
|
|
5
|
+
export type CoverHighlightVariant = 'accent' | 'filled' | 'neutral';
|
|
6
|
+
export interface CoverButtonHighlight {
|
|
7
|
+
readonly up: CoverHighlightVariant;
|
|
8
|
+
readonly stop: CoverHighlightVariant;
|
|
9
|
+
readonly down: CoverHighlightVariant;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pure helper — maps a live CoverState (or undefined when no slice yet)
|
|
13
|
+
* to per-button highlight variants.
|
|
14
|
+
*
|
|
15
|
+
* opening → up:accent (transient/active upward motion)
|
|
16
|
+
* closing → down:accent (transient/active downward motion)
|
|
17
|
+
* open → up:filled (stable fully-open state)
|
|
18
|
+
* closed → down:filled (stable fully-closed state)
|
|
19
|
+
* stopped / undefined → neutral (no active state)
|
|
20
|
+
*/
|
|
21
|
+
export declare function coverHighlight(state: CoverState | undefined): CoverButtonHighlight;
|
|
22
|
+
/**
|
|
23
|
+
* CoverInlineControl — compact, state-aware cover controls for a
|
|
24
|
+
* device-list row. Renders ↑ ■ ↓ buttons + optional % open badge.
|
|
25
|
+
* Reuses `useDeviceCapability` exactly as `CoverPanel` does.
|
|
26
|
+
*/
|
|
27
|
+
export declare function CoverInlineControl({ trpc, deviceId, optimistic }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/** Inline placeholder: renders nothing (no-op row atom for types with no inline control). */
|
|
4
|
+
export declare function DummyInline(_p: DeviceControlProps): ReactNode;
|
|
5
|
+
/** Hero card placeholder: shows a muted "Controls coming soon" card for unimplemented types. */
|
|
6
|
+
export declare function DummyHeroCard(_p: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* FanHeroCard — radial speed-dial hero for Fan devices.
|
|
5
|
+
*
|
|
6
|
+
* Renders:
|
|
7
|
+
* - RadialGauge: draggable speed ArcKnob riding a 270° ring at the speed
|
|
8
|
+
* fraction (drag snaps to the device's percentageStep), centered fan glyph +
|
|
9
|
+
* percentage readout. The gauge is the sole speed control — no slider.
|
|
10
|
+
* - Preset selector (centered) — ONLY when the device advertises
|
|
11
|
+
* DeviceFeature.FanPreset AND the slice exposes a non-empty
|
|
12
|
+
* `availablePresets`.
|
|
13
|
+
* - TAP TOGGLE for on/off (Spec §3 — NOT a SlideToggle; slide is safety-only).
|
|
14
|
+
* - Oscillate toggle button — ONLY when the device advertises
|
|
15
|
+
* DeviceFeature.FanOscillating AND the slice exposes a non-null
|
|
16
|
+
* `oscillating` value.
|
|
17
|
+
*
|
|
18
|
+
* Composes two caps: `switch` (on/off) + `fan-control` (speed / oscillate).
|
|
19
|
+
* Cap-gated on `switch` (always present on a Fan) — returns null without it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function FanHeroCard({ trpc, deviceId, features, optimistic, }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/** The `action` HA attribute drives the droplet / mist tint. */
|
|
4
|
+
export type HumidifierAction = 'humidifying' | 'drying' | 'idle' | 'off';
|
|
5
|
+
export interface HumidifierTint {
|
|
6
|
+
/** Tailwind class for the wash behind the droplet. */
|
|
7
|
+
readonly glow: string;
|
|
8
|
+
/** Tailwind text token driving the droplet via currentColor. */
|
|
9
|
+
readonly accent: string;
|
|
10
|
+
/** Whether to render the upward mist dashes (actively humidifying). */
|
|
11
|
+
readonly misting: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pure helper — maps the device's on-state + HA `action` to a tint.
|
|
15
|
+
* Exhaustive over the known action strings; an unknown / null action
|
|
16
|
+
* falls back to on/off heuristics.
|
|
17
|
+
*
|
|
18
|
+
* humidifying → primary (blue)
|
|
19
|
+
* drying → warning
|
|
20
|
+
* idle / off → muted
|
|
21
|
+
*/
|
|
22
|
+
export declare function humidifierTint(on: boolean, action: string | null): HumidifierTint;
|
|
23
|
+
/**
|
|
24
|
+
* HumidifierInlineControl — compact on/off toggle + current→target readout
|
|
25
|
+
* for a device-list row. Must NOT blow out the row width.
|
|
26
|
+
*/
|
|
27
|
+
export declare function HumidifierInlineControl({ trpc, deviceId, optimistic, }: DeviceControlProps): ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* HumidifierHeroCard — full control surface for the device-detail hero.
|
|
30
|
+
*
|
|
31
|
+
* Bespoke droplet + mist graphic + a large target-humidity readout +
|
|
32
|
+
* an on/off toggle + a target-humidity range slider (bounds from
|
|
33
|
+
* min/maxHumidity ?? 0..100) + a current-humidity readout + a mode
|
|
34
|
+
* `<select>` (only when modes are available). Gated on `available`.
|
|
35
|
+
* Only hides when the device truly has no humidifier cap.
|
|
36
|
+
*/
|
|
37
|
+
export declare function HumidifierHeroCard({ trpc, deviceId, optimistic }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* ImageInlineControl — compact thumbnail for a device-list row that expands
|
|
5
|
+
* into a floating preview on hover/focus (shared `HoverZoomImage`). Shows a
|
|
6
|
+
* muted ImageOff placeholder box when no url is available. Row-narrow.
|
|
7
|
+
*
|
|
8
|
+
* `DeviceControlProps` carries no device name, so the alt/caption is the
|
|
9
|
+
* generic 'Image'; the framed hero (ImageHeroCard) carries the real name.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ImageInlineControl({ trpc, deviceId }: DeviceControlProps): ReactNode;
|
|
12
|
+
export interface ImageHeroCardProps extends DeviceControlProps {
|
|
13
|
+
/** Optional device name for the image alt text. */
|
|
14
|
+
readonly deviceName?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* ImageHeroCard — read-only framed image for the device-detail hero.
|
|
18
|
+
*
|
|
19
|
+
* A still image in the cover-style framed box (rounded border,
|
|
20
|
+
* object-contain) when a url is present; a centered ImageOff + "No image"
|
|
21
|
+
* placeholder when null. Keeps the framed-box chrome for visual
|
|
22
|
+
* consistency with the other heroes.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ImageHeroCard({ trpc, deviceId, deviceName }: ImageHeroCardProps): ReactNode;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export { ControlColumn, ValueReadout, FILL, RIGHT, CENTER, type ControlAlign, Stepper, SlideToggle, ArcKnob, GripTrack, } from './atoms';
|
|
2
|
+
export { RadialGauge, type RadialGaugeProps } from './radial-gauge';
|
|
3
|
+
export { TapToggle, type TapToggleProps } from './tap-toggle';
|
|
4
|
+
export { ButtonControl, ButtonHeroCard } from './button-control';
|
|
5
|
+
export { CoverPanel } from './cover-panel';
|
|
6
|
+
export { LockPanel } from './lock-panel';
|
|
7
|
+
export { SwitchPanel } from './switch-panel';
|
|
8
|
+
export { BrightnessPanel } from './brightness-panel';
|
|
9
|
+
export { FanPanel } from './fan-panel';
|
|
10
|
+
export { ClimatePanel, MODE_COLOR } from './climate-panel';
|
|
11
|
+
export { MediaPlayerPanel, STATE_COLOR } from './media-player-panel';
|
|
12
|
+
export { ControlPanel } from './control-panel';
|
|
13
|
+
export { CONTROL_CAP_NAMES, type ControlCapName, type ControlPanelProps } from './types';
|
|
14
|
+
export { PopoverRowAction } from './popover-row-action';
|
|
15
|
+
export { SensorValueAtom, ROLE_DESCRIPTOR, type SensorDescriptor, type SensorValueAtomProps, } from './sensor-value-atom';
|
|
16
|
+
export { DEVICE_TYPE_CONTROL, CONTROL_FILLS, resolveDeviceControl, resolveControlAlign, coverHighlight, type DeviceTypeControl, type DeviceControlProps, type ControlPlacement, } from './control-registry';
|
|
17
|
+
export { OfflineBadge, type OfflineBadgeProps } from './offline-badge';
|
|
18
|
+
export { CoverInlineControl, type CoverHighlightVariant, type CoverButtonHighlight, } from './cover-inline';
|
|
19
|
+
export { CoverHeroCard } from './cover-hero-card';
|
|
20
|
+
export { VacuumInlineControl, VacuumHeroCard, vacuumStateMeta, tankAlert, type VacuumStateMeta, type TankKind, type TankAlert, } from './vacuum-control';
|
|
21
|
+
export { LawnMowerInlineControl, LawnMowerHeroCard, lawnMowerActivityMeta, type LawnMowerActivityMeta, } from './lawn-mower-control';
|
|
22
|
+
export { ValveInlineControl, ValveHeroCard, valveStateMeta, type ValveStateMeta, } from './valve-control';
|
|
23
|
+
export { HumidifierInlineControl, HumidifierHeroCard, humidifierTint, type HumidifierTint, type HumidifierAction, } from './humidifier-control';
|
|
24
|
+
export { WaterHeaterInlineControl, WaterHeaterHeroCard, waterHeaterTint, waterHeaterPhase, type WaterHeaterTint, type WaterHeaterPhase, } from './water-heater-control';
|
|
25
|
+
export { WeatherInlineControl, WeatherHeroCard, weatherTint, weatherConditionMeta, type WeatherTint, type WeatherConditionMeta, type WeatherGlyph, } from './weather-control';
|
|
26
|
+
export { ImageInlineControl, ImageHeroCard, type ImageHeroCardProps, } from './image-control';
|
|
27
|
+
export { DummyInline, DummyHeroCard } from './dummy-hero-card';
|
|
28
|
+
export { SensorInlineControl } from './sensor-inline-control';
|
|
29
|
+
export { SensorHeroCard } from './sensor-hero-card';
|
|
30
|
+
export { SwitchInlineControl, SwitchHeroCard, LockInlineControl, LockHeroCard, LightInlineControl, LightHeroCard, FanInlineControl, FanHeroCard, ThermostatInlineControl, ThermostatHeroCard, MediaPlayerInlineControl, MediaPlayerHeroCard, AlarmPanelInlineControl, AlarmHeroCard, ControlInlineControl, ControlHeroCard, } from './panel-controls';
|
|
31
|
+
export { resolvePrimaryChild, PRIORITY, type ChildRef } from './primary-child';
|
|
32
|
+
export { resolveContainerPrimary, overrideEntityIdFromLink, containerChildToRef, childEntityId, type ContainerChild, } from './container-primary';
|
|
33
|
+
export { ContainerPrimaryHero, type ContainerPrimaryHeroProps, type ContainerHeroChild, } from './container-primary-hero';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LawnMowerActivity } from '@camstack/types';
|
|
3
|
+
import { DeviceControlProps } from './control-registry';
|
|
4
|
+
export interface LawnMowerActivityMeta {
|
|
5
|
+
readonly label: string;
|
|
6
|
+
/** Tailwind text-colour token for the activity label. */
|
|
7
|
+
readonly tone: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Pure helper — maps a LawnMowerActivity (or undefined when no slice
|
|
11
|
+
* yet) to a human label + colour tone. Exhaustive switch: a new enum
|
|
12
|
+
* member fails the build.
|
|
13
|
+
*/
|
|
14
|
+
export declare function lawnMowerActivityMeta(activity: LawnMowerActivity | undefined): LawnMowerActivityMeta;
|
|
15
|
+
/**
|
|
16
|
+
* LawnMowerInlineControl — compact, activity-aware mower controls for a
|
|
17
|
+
* device-list row. Mow / Pause / Dock + battery badge.
|
|
18
|
+
*/
|
|
19
|
+
export declare function LawnMowerInlineControl({ trpc, deviceId }: DeviceControlProps): ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* LawnMowerHeroCard — full control surface for the device-detail hero
|
|
22
|
+
* area. Activity label + action buttons + battery readout.
|
|
23
|
+
*/
|
|
24
|
+
export declare function LawnMowerHeroCard({ trpc, deviceId }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* LightHeroCard — radial dimmer hero for Light devices.
|
|
5
|
+
*
|
|
6
|
+
* Renders:
|
|
7
|
+
* - RadialGauge: brightness ArcKnob riding a 270° ring at the level fraction,
|
|
8
|
+
* centered bulb glyph + percentage readout.
|
|
9
|
+
* - TAP TOGGLE for on/off (Spec §3 — NOT a SlideToggle; slide is safety-only).
|
|
10
|
+
* - Colour-temperature GripTrack strip — ONLY when the device advertises
|
|
11
|
+
* DeviceFeature.LightColorMired AND the `color` cap is bound.
|
|
12
|
+
*
|
|
13
|
+
* Composes three caps: `switch` (on/off), `brightness` (level), `color` (CT).
|
|
14
|
+
* Cap-gated on `switch` (always present on a Light) — returns null without it.
|
|
15
|
+
*/
|
|
16
|
+
export declare function LightHeroCard({ trpc, deviceId, features, optimistic, }: DeviceControlProps): ReactNode;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceControlProps } from './control-registry';
|
|
3
|
+
/**
|
|
4
|
+
* LockHeroCard — padlock hero for lock devices.
|
|
5
|
+
*
|
|
6
|
+
* Renders:
|
|
7
|
+
* - Padlock glyph: state-colored (locked=green, unlocked=amber, jammed=red)
|
|
8
|
+
* - SlideToggle (safety gesture): thumb must be dragged past threshold to
|
|
9
|
+
* confirm lock/unlock — a plain tap never triggers the action (Spec §3).
|
|
10
|
+
* - Open (unlatch) button: rendered ONLY when device.features includes
|
|
11
|
+
* DeviceFeature.LockOpen ('lock-open'). Absent otherwise.
|
|
12
|
+
*
|
|
13
|
+
* Cap-gated: returns null when the device has no lockControl cap.
|
|
14
|
+
*/
|
|
15
|
+
export declare function LockHeroCard({ trpc, deviceId, features, optimistic, }: DeviceControlProps): ReactNode;
|