@camstack/ui-library 0.1.57 → 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.
- package/dist/composites/battery-badge.d.ts +3 -0
- package/dist/composites/camera-stream-player.d.ts +62 -2
- 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/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/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 +5 -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/device-activity-panel.d.ts +5 -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-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/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 +3 -3
- 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/index.d.ts +12 -1
- package/dist/composites/log-stream-scroll.d.ts +32 -0
- package/dist/composites/log-stream.d.ts +8 -1
- package/dist/composites/stream-panel.d.ts +45 -10
- package/dist/composites/timezone-selector.d.ts +18 -0
- package/dist/composites/widget-panel.d.ts +28 -0
- package/dist/contexts/vod-playback.d.ts +17 -0
- package/dist/generated/system-hooks.d.ts +330 -56
- package/dist/hooks/index.d.ts +6 -0
- 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 +52175 -10927
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +51796 -10813
- package/dist/index.js.map +1 -1
- 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/dialog.d.ts +13 -0
- package/dist/primitives/tooltip.d.ts +9 -3
- package/package.json +3 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { UseDeviceProxyTrpc } from '../../hooks/use-device-proxy';
|
|
3
|
+
import { DeviceItemDevice, DeviceItemParent } from '../device-item/helpers';
|
|
4
|
+
import { DeviceListView } from './url-state';
|
|
5
|
+
import { TableContext } from './columns';
|
|
6
|
+
import { MultiSelectOption } from './multi-select';
|
|
7
|
+
export interface DeviceListAddonOption {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly icon?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export interface DeviceListDeviceProps {
|
|
13
|
+
/** Discriminant — omit (or 'devices') for the default registry-device list. */
|
|
14
|
+
readonly mode?: 'devices';
|
|
15
|
+
/**
|
|
16
|
+
* Where this table is rendered — selects the visible column subset (table
|
|
17
|
+
* view only). Defaults to `'devices'` (all columns) so every existing
|
|
18
|
+
* call site renders unchanged.
|
|
19
|
+
*/
|
|
20
|
+
readonly context?: TableContext;
|
|
21
|
+
readonly devices: readonly DeviceItemDevice[];
|
|
22
|
+
readonly trpc: UseDeviceProxyTrpc;
|
|
23
|
+
readonly defaultView?: DeviceListView;
|
|
24
|
+
/**
|
|
25
|
+
* Integration filter options + an optional TYPE-filter override.
|
|
26
|
+
*
|
|
27
|
+
* The type filter defaults to the EXHAUSTIVE device-type set
|
|
28
|
+
* (`allDeviceTypeFilterOptions`), so a newly added `DeviceType` appears
|
|
29
|
+
* automatically on every general list and nothing is ever missing. A
|
|
30
|
+
* surface that lists only a known subset (e.g. the export panel restricts
|
|
31
|
+
* to an exporter's supported kinds) may pass `typeOptions` to narrow the
|
|
32
|
+
* dropdown to that subset — built from the same shared meta so labels +
|
|
33
|
+
* icons stay identical.
|
|
34
|
+
*/
|
|
35
|
+
readonly filters?: {
|
|
36
|
+
readonly addons?: readonly DeviceListAddonOption[];
|
|
37
|
+
readonly typeOptions?: readonly MultiSelectOption[];
|
|
38
|
+
};
|
|
39
|
+
/** Pre-applied addon filter — hides the addon-chip group. */
|
|
40
|
+
readonly forceAddon?: string;
|
|
41
|
+
readonly resolveIntegrationIcon?: (addonId: string) => ReactNode | null;
|
|
42
|
+
readonly resolveParent?: (parentId: number) => DeviceItemParent | null;
|
|
43
|
+
readonly onNavigate?: (deviceId: number) => void;
|
|
44
|
+
readonly pageSize?: {
|
|
45
|
+
readonly cards: number;
|
|
46
|
+
readonly table: number;
|
|
47
|
+
};
|
|
48
|
+
readonly urlScope?: 'root' | 'nested';
|
|
49
|
+
/** LocalStorage key prefix. Default 'devices' for root scope, 'integrations:nested' for nested. */
|
|
50
|
+
readonly lsKey?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Optional trailing per-row control rendered beside each row's
|
|
53
|
+
* built-in actions (both card + table views, top-level rows only —
|
|
54
|
+
* accessory sub-rows are excluded). Threaded straight through to
|
|
55
|
+
* `<DeviceItem renderRowAction>`. Omitted ⇒ every current call site
|
|
56
|
+
* (Devices, IntegrationDetail, Integrations nested) renders unchanged.
|
|
57
|
+
* Used by `<DeviceExportPanel>` to surface a per-device Expose toggle.
|
|
58
|
+
*/
|
|
59
|
+
readonly renderRowAction?: (device: DeviceItemDevice) => ReactNode;
|
|
60
|
+
/**
|
|
61
|
+
* Built-in confirmed per-row DELETE — a first-class TABLE feature. When
|
|
62
|
+
* provided, every top-level table row renders a red trash button in the
|
|
63
|
+
* merged actions cell; clicking it opens the shared centered confirm
|
|
64
|
+
* dialog ("Delete device?") and calls `onDeleteDevice(device)` only on
|
|
65
|
+
* confirm. Accessory sub-rows are excluded (same gate as `renderRowAction`).
|
|
66
|
+
* Context gating is "consumer passes the handler or not" — omit it (default)
|
|
67
|
+
* and no trash renders, so existing call sites are unchanged. Cap-agnostic:
|
|
68
|
+
* delete is generic and never branches on the device's capabilities. The
|
|
69
|
+
* confirm is built in, so consumers must NOT add their own. Table-only for
|
|
70
|
+
* now (card delete is a follow-up).
|
|
71
|
+
*/
|
|
72
|
+
readonly onDeleteDevice?: (device: DeviceItemDevice) => void;
|
|
73
|
+
/**
|
|
74
|
+
* When `true`, renders a leading checkbox on each top-level row
|
|
75
|
+
* (accessory sub-rows are excluded — same gate as `renderRowAction`).
|
|
76
|
+
* Selection state may be controlled via `selectedIds`; when omitted
|
|
77
|
+
* the list maintains internal state.
|
|
78
|
+
*/
|
|
79
|
+
readonly selectable?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Controlled set of selected device ids. Provide together with
|
|
82
|
+
* `onSelectionChange` for a fully controlled selection surface.
|
|
83
|
+
* Omit to let `<DeviceList>` manage internal state.
|
|
84
|
+
*/
|
|
85
|
+
readonly selectedIds?: ReadonlySet<number>;
|
|
86
|
+
/**
|
|
87
|
+
* Called on every toggle with the NEW full selection set.
|
|
88
|
+
* Invoked for both controlled and uncontrolled usage.
|
|
89
|
+
*/
|
|
90
|
+
readonly onSelectionChange?: (ids: ReadonlySet<number>) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Opt into self-managed BATCH MODE. When provided, the list renders an
|
|
93
|
+
* "Select" activation button; batch mode is OFF by default (no
|
|
94
|
+
* checkboxes, no bulk toolbar). Activating it reveals the leading
|
|
95
|
+
* row checkboxes plus a responsive bulk-actions bar wired to these
|
|
96
|
+
* callbacks (full toolbar at `sm+`, a compact menu at L1). Selection
|
|
97
|
+
* state is managed internally for the duration of the activated
|
|
98
|
+
* session and cleared on exit. Mutually independent from the
|
|
99
|
+
* lower-level `selectable`/`selectedIds` controlled API.
|
|
100
|
+
*/
|
|
101
|
+
readonly batchActions?: DeviceListBatchActions;
|
|
102
|
+
}
|
|
103
|
+
/** Self-managed batch-mode bulk-action callbacks (see `batchActions`). */
|
|
104
|
+
export interface DeviceListBatchActions {
|
|
105
|
+
readonly remove: (input: {
|
|
106
|
+
deviceId: number;
|
|
107
|
+
}) => void;
|
|
108
|
+
readonly disable: (input: {
|
|
109
|
+
deviceId: number;
|
|
110
|
+
}) => void;
|
|
111
|
+
readonly enable: (input: {
|
|
112
|
+
deviceId: number;
|
|
113
|
+
}) => void;
|
|
114
|
+
}
|
|
115
|
+
export declare function DeviceModeList(props: DeviceListDeviceProps): ReactNode;
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { DeviceListView } from './url-state';
|
|
3
|
+
import { MultiSelectOption } from './multi-select';
|
|
3
4
|
export interface FilterChipsAddonOption {
|
|
4
5
|
readonly id: string;
|
|
5
6
|
readonly name: string;
|
|
6
7
|
readonly icon?: ReactNode;
|
|
7
8
|
}
|
|
8
9
|
export interface FilterChipsProps {
|
|
9
|
-
readonly view
|
|
10
|
-
readonly onViewChange
|
|
11
|
-
|
|
12
|
-
readonly
|
|
13
|
-
|
|
10
|
+
readonly view?: DeviceListView;
|
|
11
|
+
readonly onViewChange?: (view: DeviceListView) => void;
|
|
12
|
+
/** Hide the cards/table view toggle (generic lists have a single view). */
|
|
13
|
+
readonly hideView?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Ready-made options for the shared multi-select type filter. Built once by
|
|
16
|
+
* the caller from the exhaustive device-type meta (`allDeviceTypeFilterOptions`)
|
|
17
|
+
* so the option set is complete + identical everywhere. Omit to hide the
|
|
18
|
+
* type filter entirely.
|
|
19
|
+
*/
|
|
20
|
+
readonly typeOptions?: readonly MultiSelectOption[];
|
|
21
|
+
readonly selectedTypes: readonly string[];
|
|
22
|
+
readonly onTypesChange: (types: readonly string[]) => void;
|
|
14
23
|
readonly addons?: readonly FilterChipsAddonOption[];
|
|
15
24
|
/** Currently-selected integration ids (multi-select). */
|
|
16
25
|
readonly selectedAddons: readonly string[];
|
|
@@ -18,4 +27,4 @@ export interface FilterChipsProps {
|
|
|
18
27
|
/** When true, the addon group is hidden (used by Integrations expand-row inner DeviceList). */
|
|
19
28
|
readonly hideAddons?: boolean;
|
|
20
29
|
}
|
|
21
|
-
export declare function FilterChips({ view, onViewChange,
|
|
30
|
+
export declare function FilterChips({ view, onViewChange, hideView, typeOptions, selectedTypes, onTypesChange, addons, selectedAddons, onAddonsChange, hideAddons, }: FilterChipsProps): ReactNode;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fuzzy-match — case and separator-insensitive text search helper.
|
|
3
|
+
*
|
|
4
|
+
* Normalization rule: lowercase + strip all runs of hyphens, underscores and
|
|
5
|
+
* whitespace entirely. This makes `Tapparella cucina` and `tapparella-cucina`
|
|
6
|
+
* both normalize to `tapparellacucina`, so a substring match succeeds in
|
|
7
|
+
* either direction.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Strips hyphens, underscores and whitespace runs from `s` and lowercases it.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* normalizeForSearch('Tapparella cucina') // 'tapparellacucina'
|
|
14
|
+
* normalizeForSearch('tapparella-cucina') // 'tapparellacucina'
|
|
15
|
+
* normalizeForSearch('tapparella_cucina') // 'tapparellacucina'
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeForSearch(s: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Returns `true` when the normalized form of `target` contains the normalized
|
|
20
|
+
* form of `query`. An empty query always matches.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* fuzzyMatch('Tapparella cucina', 'tapparella-cucina') // true
|
|
24
|
+
* fuzzyMatch('tapparella cucina', 'Tapparella-Cucina') // true
|
|
25
|
+
* fuzzyMatch('xyz', 'tapparella-cucina') // false
|
|
26
|
+
*/
|
|
27
|
+
export declare function fuzzyMatch(query: string, target: string): boolean;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
import { MultiSelectOption } from './multi-select';
|
|
4
|
+
/**
|
|
5
|
+
* Generic-mode props — a paginated, searchable, render-prop list that reuses
|
|
6
|
+
* the same chrome (search box + <Pagination>) as the device list but over an
|
|
7
|
+
* arbitrary item type. Used by the HA adoption modal for discovered-device
|
|
8
|
+
* candidates; selection + per-row controls live in the caller's `renderItem`.
|
|
9
|
+
*/
|
|
10
|
+
/** One column of the generic-mode TABLE rendering. */
|
|
11
|
+
export interface DeviceListColumn<T> {
|
|
12
|
+
readonly key: string;
|
|
13
|
+
readonly header: ReactNode;
|
|
14
|
+
readonly cell: (item: T) => ReactNode;
|
|
15
|
+
/** Extra classes on the `<th>` (width, responsive hiding, alignment). */
|
|
16
|
+
readonly headerClassName?: string;
|
|
17
|
+
/** Extra classes on the `<td>`. */
|
|
18
|
+
readonly cellClassName?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DeviceListGenericProps<T> {
|
|
21
|
+
readonly mode: 'generic';
|
|
22
|
+
readonly items: readonly T[];
|
|
23
|
+
readonly getKey: (item: T) => string;
|
|
24
|
+
readonly getSearchText: (item: T) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Row body. Provide EITHER `columns` (renders a table matching the device
|
|
27
|
+
* list's table styling) OR `renderItem` (a free-form row list). `columns`
|
|
28
|
+
* wins when both are set.
|
|
29
|
+
*/
|
|
30
|
+
readonly renderItem?: (item: T) => ReactNode;
|
|
31
|
+
/** Table columns — when set, the list renders as a bordered table. */
|
|
32
|
+
readonly columns?: readonly DeviceListColumn<T>[];
|
|
33
|
+
/** Full-width expansion row rendered under an item when `isExpanded` is true. */
|
|
34
|
+
readonly renderExpanded?: (item: T) => ReactNode;
|
|
35
|
+
readonly isExpanded?: (item: T) => boolean;
|
|
36
|
+
/** Per-row class (table `<tr>` or list wrapper) — e.g. selected/adopted state. */
|
|
37
|
+
readonly rowClassName?: (item: T) => string;
|
|
38
|
+
/** Click handler for a whole table row — when set, the `<tr>` becomes a
|
|
39
|
+
* clickable button (cursor + keyboard) that navigates/opens the item.
|
|
40
|
+
* Per-cell interactive controls must `stopPropagation` to avoid double-firing. */
|
|
41
|
+
readonly onRowClick?: (item: T) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Optional type-filter projection. When provided, the list renders a compact
|
|
44
|
+
* MULTI-SELECT dropdown over the DISTINCT values present in `items` and keeps
|
|
45
|
+
* items matching ANY selected value (empty selection = no filter). Return
|
|
46
|
+
* `null` for items that carry no type. Omit to hide the filter entirely.
|
|
47
|
+
*/
|
|
48
|
+
readonly getFilterType?: (item: T) => string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Enrich a raw filter value into a display `{ label, icon }` for the
|
|
51
|
+
* multi-select (e.g. via the device-type meta map). Defaults to the raw
|
|
52
|
+
* value as label, no icon. Ignored when `filterOptions` is supplied.
|
|
53
|
+
*/
|
|
54
|
+
readonly mapFilterOption?: (value: string) => {
|
|
55
|
+
readonly label: string;
|
|
56
|
+
readonly icon?: LucideIcon;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Ready-made, COMPLETE option set for the type filter. When supplied, it
|
|
60
|
+
* overrides the present-values-only set the list would otherwise derive from
|
|
61
|
+
* `items` — so e.g. the adoption modal shows every `DeviceType` (via
|
|
62
|
+
* `allDeviceTypeFilterOptions`), not just the types of the current
|
|
63
|
+
* candidates. `getFilterType` still selects each item's value for matching.
|
|
64
|
+
*/
|
|
65
|
+
readonly filterOptions?: readonly MultiSelectOption[];
|
|
66
|
+
/** Label for the type multi-select trigger. Default 'Type'. */
|
|
67
|
+
readonly filterLabel?: string;
|
|
68
|
+
readonly isLoading?: boolean;
|
|
69
|
+
readonly searchPlaceholder?: string;
|
|
70
|
+
readonly emptyLabel?: string;
|
|
71
|
+
readonly pageSize?: number;
|
|
72
|
+
/** Optional control rendered next to the search box (e.g. a Refresh button). */
|
|
73
|
+
readonly toolbar?: ReactNode;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Generic render-prop list: search + pagination chrome shared with the device
|
|
77
|
+
* list, over an arbitrary item type. Local (non-URL) state — intended for
|
|
78
|
+
* modal/ephemeral surfaces. Selection + per-row controls are the caller's, via
|
|
79
|
+
* `renderItem`.
|
|
80
|
+
*/
|
|
81
|
+
export declare function GenericModeList<T>(props: DeviceListGenericProps<T>): ReactNode;
|
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { DeviceItemDevice } from '../device-item/helpers';
|
|
2
|
+
/**
|
|
3
|
+
* countableDevices — the subset of `devices` that should be counted in
|
|
4
|
+
* the device-list footer "Showing N of **M** devices".
|
|
5
|
+
*
|
|
6
|
+
* A device is countable when:
|
|
7
|
+
* - it has no parent (`parentDeviceId === null`), OR
|
|
8
|
+
* - its parent's type is a hub-like owner (`hub` / `nvr`) — an NVR's
|
|
9
|
+
* cameras and a hub's children are real, individually-operable devices.
|
|
10
|
+
*
|
|
11
|
+
* Excluded:
|
|
12
|
+
* - devices whose parent has type `container` — a Container is a grouping
|
|
13
|
+
* shell for entity-children (e.g. a HA device's entities); the children
|
|
14
|
+
* are represented by the parent row and must NOT inflate the total.
|
|
15
|
+
* - orphan devices (parent id present but not in the input list) are
|
|
16
|
+
* treated as countable — better to over-count by one than hide them.
|
|
17
|
+
*
|
|
18
|
+
* Pure: builds a `Map<id, device>` once and then filters in a single pass.
|
|
19
|
+
*/
|
|
20
|
+
export declare function countableDevices(devices: readonly DeviceItemDevice[]): readonly DeviceItemDevice[];
|
|
2
21
|
export interface GroupedDevices {
|
|
3
22
|
readonly topLevel: readonly DeviceItemDevice[];
|
|
4
23
|
readonly accessoriesByParent: ReadonlyMap<number, readonly DeviceItemDevice[]>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DeviceItemDevice } from '../device-item/helpers';
|
|
2
|
+
/** Coerce a single metadata value to a trimmed, non-empty display string.
|
|
3
|
+
* Strings pass through (trimmed); finite numbers + booleans coerce; every
|
|
4
|
+
* other shape (object, array, null, undefined, NaN) yields `null` so callers
|
|
5
|
+
* skip it rather than render a useless `[object Object]`. */
|
|
6
|
+
export declare function metadataValueString(value: unknown): string | null;
|
|
7
|
+
/** Read one metadata key as a safe display string (null when absent/empty). */
|
|
8
|
+
export declare function metadataString(metadata: Readonly<Record<string, unknown>> | null | undefined, key: string): string | null;
|
|
9
|
+
/** Compact cell text: `manufacturer · model`, or whichever is present, or
|
|
10
|
+
* `null` when neither is a usable string (caller renders the empty state). */
|
|
11
|
+
export declare function hardwareLabel(device: DeviceItemDevice): string | null;
|
|
12
|
+
/** A single key/value pair for the metadata tooltip dump. */
|
|
13
|
+
export interface MetadataEntry {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly value: string;
|
|
16
|
+
}
|
|
17
|
+
/** All string-coercible, non-empty metadata entries in insertion order — the
|
|
18
|
+
* full identity blob for the tooltip. Empty array when there's nothing to show. */
|
|
19
|
+
export declare function metadataEntries(metadata: Readonly<Record<string, unknown>> | null | undefined): readonly MetadataEntry[];
|
|
20
|
+
/** True when the device advertises a non-empty `manufacturer`. Drives the
|
|
21
|
+
* direction-independent "missing sorts last" rule in `sortRows`. */
|
|
22
|
+
export declare function hasManufacturer(device: DeviceItemDevice): boolean;
|
|
23
|
+
/** Ascending, case-insensitive comparator on `manufacturer` then `model`. The
|
|
24
|
+
* "missing manufacturer sorts last" rule is applied direction-independently by
|
|
25
|
+
* the caller (`sortRows`); this comparator only orders the values themselves. */
|
|
26
|
+
export declare function compareHardware(a: DeviceItemDevice, b: DeviceItemDevice): number;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ComponentType, ReactNode } from 'react';
|
|
2
|
+
export interface IconActionProps {
|
|
3
|
+
/** Lucide icon component (or any component accepting `className?: string`). */
|
|
4
|
+
readonly icon: ComponentType<{
|
|
5
|
+
className?: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Human-readable label — exposed via aria-label + title, NOT as visible text. */
|
|
8
|
+
readonly label: string;
|
|
9
|
+
/** Click handler. */
|
|
10
|
+
readonly onClick: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* When true, applies a red/destructive accent to the button. Use for Delete
|
|
13
|
+
* and other irreversible actions — Delete keeps red even icon-only.
|
|
14
|
+
*/
|
|
15
|
+
readonly danger?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function IconAction({ icon: Icon, label, onClick, danger }: IconActionProps): ReactNode;
|
|
@@ -1,40 +1,24 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
readonly table: number;
|
|
26
|
-
};
|
|
27
|
-
readonly urlScope?: 'root' | 'nested';
|
|
28
|
-
/** LocalStorage key prefix. Default 'devices' for root scope, 'integrations:nested' for nested. */
|
|
29
|
-
readonly lsKey?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Optional trailing per-row control rendered beside each row's
|
|
32
|
-
* built-in actions (both card + table views, top-level rows only —
|
|
33
|
-
* accessory sub-rows are excluded). Threaded straight through to
|
|
34
|
-
* `<DeviceItem renderRowAction>`. Omitted ⇒ every current call site
|
|
35
|
-
* (Devices, IntegrationDetail, Integrations nested) renders unchanged.
|
|
36
|
-
* Used by `<DeviceExportPanel>` to surface a per-device Expose toggle.
|
|
37
|
-
*/
|
|
38
|
-
readonly renderRowAction?: (device: DeviceItemDevice) => ReactNode;
|
|
39
|
-
}
|
|
40
|
-
export declare function DeviceList(props: DeviceListProps): ReactNode;
|
|
2
|
+
import { DeviceListDeviceProps } from './device-mode';
|
|
3
|
+
import { DeviceListGenericProps } from './generic-mode';
|
|
4
|
+
export { countableDevices } from './group';
|
|
5
|
+
export { fuzzyMatch, normalizeForSearch } from './fuzzy-match';
|
|
6
|
+
export { DEVICE_COLUMNS, columnsForContext, COLUMN_PRIORITY, COLUMN_BREAKPOINT_CLASS } from './columns';
|
|
7
|
+
export type { DeviceColumnId, TableContext } from './columns';
|
|
8
|
+
export { nextSort, sortRows } from './sort';
|
|
9
|
+
export type { DeviceSort, SortDirection, SortableColumnId } from './sort';
|
|
10
|
+
export { hardwareLabel, metadataEntries, metadataString } from './hardware';
|
|
11
|
+
export { IconAction, type IconActionProps } from './icon-action';
|
|
12
|
+
export type { DeviceListAddonOption, DeviceListDeviceProps, DeviceListBatchActions } from './device-mode';
|
|
13
|
+
export type { DeviceListColumn, DeviceListGenericProps } from './generic-mode';
|
|
14
|
+
/**
|
|
15
|
+
* Default registry-device list, or a generic render-prop list (`mode:'generic'`).
|
|
16
|
+
* Existing call sites pass no `mode` and resolve to the device variant unchanged.
|
|
17
|
+
*/
|
|
18
|
+
export type DeviceListProps<T = unknown> = DeviceListDeviceProps | DeviceListGenericProps<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Dispatcher: default registry-device list, or a generic render-prop list when
|
|
21
|
+
* `mode:'generic'`. The two paths are separate component instances so their
|
|
22
|
+
* hooks never interleave (a given call site's mode is stable).
|
|
23
|
+
*/
|
|
24
|
+
export declare function DeviceList<T = unknown>(props: DeviceListProps<T>): ReactNode;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface MultiSelectOption {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly icon?: LucideIcon;
|
|
7
|
+
}
|
|
8
|
+
export interface MultiSelectDropdownProps {
|
|
9
|
+
/** Trigger label, e.g. "Type". A count badge is appended when items are selected. */
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly options: readonly MultiSelectOption[];
|
|
12
|
+
readonly selected: readonly string[];
|
|
13
|
+
readonly onChange: (selected: readonly string[]) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compact multi-select dropdown — a single chip-sized trigger ("Label · N")
|
|
17
|
+
* that opens a checklist. Self-contained (outside-click / Escape dismiss), so
|
|
18
|
+
* it stays compressed regardless of how many options exist or how little
|
|
19
|
+
* horizontal room the container has. Shared by the device list's generic-mode
|
|
20
|
+
* type filter and any other multi-select needs.
|
|
21
|
+
*/
|
|
22
|
+
export declare function MultiSelectDropdown({ label, options, selected, onChange }: MultiSelectDropdownProps): ReactNode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DeviceItemDevice } from '../device-item/helpers';
|
|
2
|
+
/** Columns that expose a clickable sort header. */
|
|
3
|
+
export type SortableColumnId = 'name' | 'type' | 'manufacturer';
|
|
4
|
+
export type SortDirection = 'asc' | 'desc';
|
|
5
|
+
export interface DeviceSort {
|
|
6
|
+
readonly columnId: SortableColumnId;
|
|
7
|
+
readonly dir: SortDirection;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Toggle a column's sort on header click: none → asc → desc → none.
|
|
11
|
+
* Clicking a DIFFERENT column starts it fresh at `asc`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function nextSort(current: DeviceSort | null, columnId: SortableColumnId): DeviceSort | null;
|
|
14
|
+
/**
|
|
15
|
+
* Return a NEW array of the top-level rows in sorted order. `null` ⇒ a fresh
|
|
16
|
+
* copy in the original order. Stable + immutable; the input is never mutated.
|
|
17
|
+
*/
|
|
18
|
+
export declare function sortRows(rows: readonly DeviceItemDevice[], sort: DeviceSort | null): readonly DeviceItemDevice[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceSort, SortableColumnId } from './sort';
|
|
3
|
+
interface SortableHeaderButtonProps {
|
|
4
|
+
readonly columnId: SortableColumnId;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly sort: DeviceSort | null;
|
|
7
|
+
readonly onSort: (columnId: SortableColumnId) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function SortableHeaderButton({ columnId, label, sort, onSort, }: SortableHeaderButtonProps): ReactNode;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DeviceItemDevice } from '../device-item/helpers';
|
|
3
|
+
import { CardsLayoutProps } from './cards-layout';
|
|
4
|
+
import { DeviceColumnId } from './columns';
|
|
5
|
+
import { DeviceSort, SortableColumnId } from './sort';
|
|
6
|
+
interface TableLayoutProps extends CardsLayoutProps {
|
|
7
|
+
/** Built-in confirmed delete (table feature). Null ⇒ no trash. Only
|
|
8
|
+
* top-level rows carry it (accessory sub-rows are excluded — same gate
|
|
9
|
+
* as `renderRowAction`). */
|
|
10
|
+
readonly onDeleteDevice: ((device: DeviceItemDevice) => void) | null;
|
|
11
|
+
readonly autoExpandedParents: ReadonlySet<number>;
|
|
12
|
+
/** Full unfiltered device list — used to resolve parent.type for the
|
|
13
|
+
* adopted-row indent. We can't rely on `resolveParent` returning the
|
|
14
|
+
* parent's type (callers historically only project id+name). */
|
|
15
|
+
readonly devices: readonly DeviceItemDevice[];
|
|
16
|
+
/** Context-selected columns to render (header + cells). `name` always on. */
|
|
17
|
+
readonly visibleColumns: readonly DeviceColumnId[];
|
|
18
|
+
/** Active sort (top-level rows), or `null` for the default incoming order.
|
|
19
|
+
* Owned by the device-mode wrapper so the sort applies before pagination. */
|
|
20
|
+
readonly sort: DeviceSort | null;
|
|
21
|
+
/** Header-click handler — toggles the column's sort (asc→desc→none). */
|
|
22
|
+
readonly onSort: (columnId: SortableColumnId) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function TableLayout({ rows, accessoriesByParent, autoExpandedParents, devices, visibleColumns, trpc, resolveIntegrationIcon, resolveParent, onNavigate, renderRowAction, onDeleteDevice, selectable, rowClickSelects, activeSelected, onToggleSelection, sort, onSort, }: TableLayoutProps): ReactNode;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { MultiSelectOption } from './multi-select';
|
|
3
|
+
export interface ResponsiveTypeFilterProps {
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly options: readonly MultiSelectOption[];
|
|
6
|
+
readonly selected: readonly string[];
|
|
7
|
+
readonly onChange: (selected: readonly string[]) => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Shared, multi-select type filter that adapts to its OWN available width
|
|
11
|
+
* (measured via ResizeObserver, NOT the viewport — the adoption modal and the
|
|
12
|
+
* Devices page differ at the same screen size):
|
|
13
|
+
* - wide enough → inline toggle chips (Devices page stays chips)
|
|
14
|
+
* - too narrow → the compact <MultiSelectDropdown> (adoption modal collapses)
|
|
15
|
+
*
|
|
16
|
+
* One component for every list consumer, so the filter looks and behaves the
|
|
17
|
+
* same everywhere and only the FORM changes with available room.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ResponsiveTypeFilter({ label, options, selected, onChange }: ResponsiveTypeFilterProps): ReactNode;
|
|
@@ -8,7 +8,12 @@ export interface DeviceListUrlState {
|
|
|
8
8
|
* comma-joined `addon` value so existing single-value links keep working.
|
|
9
9
|
*/
|
|
10
10
|
readonly addons: readonly string[];
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Selected device types. Multi-select: empty array = no type filter.
|
|
13
|
+
* Serialised in the URL / localStorage as a single comma-joined `type`
|
|
14
|
+
* value so existing single-value links keep working.
|
|
15
|
+
*/
|
|
16
|
+
readonly types: readonly string[];
|
|
12
17
|
readonly q: string;
|
|
13
18
|
}
|
|
14
19
|
export interface UseDeviceListUrlStateOptions {
|
|
@@ -22,7 +27,7 @@ export interface UseDeviceListUrlStateResult {
|
|
|
22
27
|
readonly setView: (view: DeviceListView) => void;
|
|
23
28
|
readonly setPage: (page: number) => void;
|
|
24
29
|
readonly setAddons: (addons: readonly string[]) => void;
|
|
25
|
-
readonly
|
|
30
|
+
readonly setTypes: (types: readonly string[]) => void;
|
|
26
31
|
readonly setQ: (q: string) => void;
|
|
27
32
|
readonly clearFilters: () => void;
|
|
28
33
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LucideIcon } from 'lucide-react';
|
|
2
|
+
import { DeviceType, DeviceRole } from '@camstack/types';
|
|
3
|
+
import { MultiSelectOption } from './device-list/multi-select';
|
|
4
|
+
/**
|
|
5
|
+
* Single source of truth for rendering a device TYPE or ROLE: its icon + label.
|
|
6
|
+
*
|
|
7
|
+
* Both maps are `Record<DeviceType | DeviceRole, …>`, so adding a new enum
|
|
8
|
+
* member makes the object literal incomplete and the build FAILS until the new
|
|
9
|
+
* type/role is given an icon + label here. That is the whole point — UI never
|
|
10
|
+
* silently falls back to a generic glyph for a freshly-added type/role.
|
|
11
|
+
*
|
|
12
|
+
* Lives in `@camstack/ui-library` because the icons are `lucide-react`
|
|
13
|
+
* components; the labels are the user-facing defaults (wire i18n at the call
|
|
14
|
+
* site if a translation is needed).
|
|
15
|
+
*/
|
|
16
|
+
export interface DeviceTypeMeta {
|
|
17
|
+
readonly icon: LucideIcon;
|
|
18
|
+
readonly label: string;
|
|
19
|
+
}
|
|
20
|
+
export interface DeviceRoleMeta {
|
|
21
|
+
readonly icon: LucideIcon;
|
|
22
|
+
readonly label: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const DEVICE_TYPE_META: Record<DeviceType, DeviceTypeMeta>;
|
|
25
|
+
export declare const DEVICE_ROLE_META: Record<DeviceRole, DeviceRoleMeta>;
|
|
26
|
+
/** Meta for a known `DeviceType`. */
|
|
27
|
+
export declare function deviceTypeMeta(type: DeviceType): DeviceTypeMeta;
|
|
28
|
+
/** Meta for a known `DeviceRole`. */
|
|
29
|
+
export declare function deviceRoleMeta(role: DeviceRole): DeviceRoleMeta;
|
|
30
|
+
/**
|
|
31
|
+
* Runtime-string-safe lookup: device data crosses process / network boundaries
|
|
32
|
+
* as plain strings, so an unrecognised value falls back to the `Generic` meta
|
|
33
|
+
* instead of throwing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function deviceTypeMetaOf(type: string): DeviceTypeMeta;
|
|
36
|
+
/** Runtime-string-safe role lookup; unknown roles fall back to `GenericSensor`. */
|
|
37
|
+
export declare function deviceRoleMetaOf(role: string): DeviceRoleMeta;
|
|
38
|
+
export declare function allDeviceTypeFilterOptions(): readonly MultiSelectOption[];
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* renders the channel list with status badges, refresh, adopt, and
|
|
7
7
|
* release controls.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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;
|