@camstack/ui-library 1.2.220 → 1.2.222

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.
@@ -76,7 +76,7 @@ export declare const COLUMN_BREAKPOINT_CLASS: Record<DeviceColumnId, string>;
76
76
  * left to scroll under the pin — the pinned column simply holds its width
77
77
  * permanently and pushes Preview off the right edge. On a phone the viewport
78
78
  * is narrower than the pinned column alone, which is the reported defect:
79
- * "il nome alla sinistra è fixed, dovrebbe scorrere naturalmente."
79
+ * "il nome alla sinistra è fixed, dovrebbe scorrere naturalmente." [the name on the left is fixed, it should scroll naturally.]
80
80
  *
81
81
  * So the pin starts at `md`, the same width at which `features` returns and a
82
82
  * column exists to scroll under it. Below `md` the name column scrolls with
package/dist/index.cjs CHANGED
@@ -19762,7 +19762,7 @@ function zoomLabel(spanMs) {
19762
19762
  *
19763
19763
  * *"Possiamo utilizzare lo stesso componente della sezione recording con la
19764
19764
  * timebar dove selezionare un periodo e mostrare le clip solo di quella banda
19765
- * selezionata, espandibile."* — the operator, 2026-09-20. So this is not a
19765
+ * selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] — the operator, 2026-09-20. So this is not a
19766
19766
  * second timebar: it is `TimelineControls` and `EventHeatmap`, the two pieces
19767
19767
  * `RecordingTimeline` is itself built from, over the same
19768
19768
  * `recording-timeline-model` (`dayWindow`, `panWindow`,
@@ -20611,7 +20611,7 @@ function resolveClipsView(input) {
20611
20611
  * Io in realtà utilizzerei la stessa tab recordings, lì abbiamo già tutto il
20612
20612
  * necessario, una nuova sezione alla fine per le clips dove possiamo
20613
20613
  * selezionare le source con un multiselect common, non componenti nuovi
20614
- * anonimi."* So every piece of chrome here is a component this repo already
20614
+ * anonimi."* [The UI is horrible, it does not follow our UI at all … I would actually use the same recordings tab, we already have everything necessary there, a new section at the end for the clips where we can select the sources with a common multiselect, no new anonymous components.] So every piece of chrome here is a component this repo already
20615
20615
  * has: `Select`, `DataTable`, `EmptyState`, `ErrorBox`, `Pagination`, `Card`,
20616
20616
  * `Badge`, `Button`, `Skeleton`. What the chrome CARRIES is unchanged, and it
20617
20617
  * is the feature:
@@ -20633,7 +20633,7 @@ function resolveClipsView(input) {
20633
20633
  * It shipped with its own `‹ day ›` pair and the operator replaced it the same
20634
20634
  * way he replaced the chrome: *"Possiamo utilizzare lo stesso componente della
20635
20635
  * sezione recording con la timebar dove selezionare un periodo e mostrare le
20636
- * clip solo di quella banda selezionata, espandibile."* So the list follows a
20636
+ * clip solo di quella banda selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] So the list follows a
20637
20637
  * BAND (D564) — `TimelineControls` for the day, the zoom and the pan,
20638
20638
  * `EventHeatmap` for picking a narrower window out of it, both of them the
20639
20639
  * pieces `RecordingTimeline` is itself built from, over the same
@@ -20656,7 +20656,7 @@ function resolveClipsView(input) {
20656
20656
  * configuration that lives somewhere else. The operator put it exactly:
20657
20657
  * *"non è affatto necessario lo stato di abilitato o meno delle sources. Loro
20658
20658
  * vivono lì, ad esempio hksv c'è se la camera è esportata su homekit, reolink
20659
- * la dà di suo così come il camstack."* HKSV is there if the camera is
20659
+ * la dà di suo così come il camstack."* [the enabled-or-not state of the sources is not necessary at all. They live there, for example hksv is there if the camera is exported to homekit, reolink provides it on its own, as does camstack.] HKSV is there if the camera is
20660
20660
  * exported to HomeKit; the Reolink source is there because Reolink is that
20661
20661
  * camera's provider; CamStack's is always there. None of that is a decision to
20662
20662
  * make in a clips list, so this surface offers no switch and writes no
@@ -20667,7 +20667,7 @@ function resolveClipsView(input) {
20667
20667
  *
20668
20668
  * The operator asked for *"un multiselect common"* while `listClips` still
20669
20669
  * took `sources?: string[]`. It now takes ONE `provider` —
20670
- * *"l'utilizzatore è uno solo"* — and a multi-pick control over a
20670
+ * *"l'utilizzatore è uno solo"* [there is only one user] — and a multi-pick control over a
20671
20671
  * one-at-a-time argument offers a sum the hub cannot answer. So the control is
20672
20672
  * the shared single-choice one, `Select`: the same component the Recordings
20673
20673
  * page's own camera picker uses, which is what *"segue la nostra UI"* means
@@ -32895,7 +32895,7 @@ function resolveTableLayout({ mode, columnCount, isNarrow }) {
32895
32895
  * where labels can be inferred. The operator can still see every
32896
32896
  * stat / action — no horizontal scroll, no clipped text. The user
32897
32897
  * directive: "molta informazione in poco spazio quando la width è
32898
- * bassa."
32898
+ * bassa." [a lot of information in little space when the width is low.]
32899
32899
  *
32900
32900
  * • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
32901
32901
  * 2-column grids, side panels become visible, button labels return.
@@ -39438,12 +39438,17 @@ function PopoverRowAction({ icon: Icon, title, children }) {
39438
39438
  }
39439
39439
  //#endregion
39440
39440
  //#region src/lib/resolve-sensor-display.ts
39441
+ /** Table keys are canonical spellings; providers often send `C` / `F` / `celsius`. */
39442
+ function canonUnit(raw) {
39443
+ if (raw === void 0) return void 0;
39444
+ return (0, _camstack_types.normalizeUnit)(raw) ?? raw;
39445
+ }
39441
39446
  var identity = (raw) => raw;
39442
39447
  function resolveSensorDisplay(input) {
39443
39448
  const perCap = input.capName !== void 0 ? input.display?.perCap?.[input.capName] : void 0;
39444
39449
  const precision = perCap?.precision ?? input.display?.precision ?? input.roleDefault?.precision ?? input.slicePrecision;
39445
- const sourceUnit = input.sliceUnit ?? input.canonicalUnit;
39446
- const overrideUnit = perCap?.unit ?? input.display?.unit ?? input.roleDefault?.unit;
39450
+ const sourceUnit = canonUnit(input.sliceUnit ?? input.canonicalUnit);
39451
+ const overrideUnit = canonUnit(perCap?.unit ?? input.display?.unit ?? input.roleDefault?.unit);
39447
39452
  if (overrideUnit !== void 0 && sourceUnit !== void 0 && overrideUnit !== sourceUnit && (0, _camstack_types.canConvertUnit)(sourceUnit, overrideUnit)) return {
39448
39453
  unit: overrideUnit,
39449
39454
  precision,
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import * as __mfHostReactDOMClient from "react-dom/client";
13
13
  import { createRoot } from "react-dom/client";
14
14
  import * as __mfHostTrpcClient from "@trpc/client";
15
15
  import { createTRPCClient, createWSClient, httpLink, splitLink, wsLink } from "@trpc/client";
16
- import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DISPLAY_ICON_GROUPS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, searchDisplayIcons, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
16
+ import { ALL_CAPABILITY_DEFINITIONS, CAM_PROFILE_ORDER, CLIP_STILL_DISPOSITION_HEADER, CLIP_STILL_REASON_CODE_HEADER, CLIP_STILL_REASON_HEADER, CONTAINER_CHILD_PRIORITY, DEFAULT_EVENTS_BAND_BUFFER_SEC, DEFAULT_EVENT_COLOR, DEVICE_TYPE_CONTROL_KIND, DISPLAY_ICON_GROUPS, DeviceExportStatusSchema, DeviceFeature, DeviceRole, DeviceType, EVENT_TAXONOMY, EXTENSION_SLOTS, EXTENSION_SLOT_IDS, EventCategory, ExposedDeviceSchema, FIRST_LEVEL_MACRO_CLASSES, KNOWN_CAP_NAMES, MAX_SENSOR_TRIGGER_DEVICES, MODEL_PROVIDER_IDS, NAVIGATION_LIGHT_LEVEL_MAX, NAVIGATION_LIGHT_LEVEL_MIN, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, RECORDING_AUDIO_TRIGGER_OFFERED_DBFS, RECORDING_SOURCE_CAMSTACK_ADDON, RecordingConfigSchema, RecordingStatusSchema, SOURCE_CAP_ACTIVE_FIELD, STATIONARY_OVERLAY_STYLE, TIMEZONES, buildModelVariantGroups, canConvertUnit, clusterStepSettingFieldsFor, createDeviceProxy, createLazyTrpcSource, createSliceHandle, deriveRecordingMode, describeModelVariant, findTimezone, formatParkedFor, normalizeUnit, publicEventCategories, resolveContainerPrimaryChild, resolveDeviceControlKind, resolveRecordingProfiles, resolveVariantModelId, resolveViewableDeviceIds, searchDisplayIcons, selectAssignedProfileSlots, tryConvertUnit } from "@camstack/types";
17
17
  import { createSystem } from "@camstack/sdk";
18
18
  import { z } from "zod";
19
19
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
@@ -19738,7 +19738,7 @@ function zoomLabel(spanMs) {
19738
19738
  *
19739
19739
  * *"Possiamo utilizzare lo stesso componente della sezione recording con la
19740
19740
  * timebar dove selezionare un periodo e mostrare le clip solo di quella banda
19741
- * selezionata, espandibile."* — the operator, 2026-09-20. So this is not a
19741
+ * selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] — the operator, 2026-09-20. So this is not a
19742
19742
  * second timebar: it is `TimelineControls` and `EventHeatmap`, the two pieces
19743
19743
  * `RecordingTimeline` is itself built from, over the same
19744
19744
  * `recording-timeline-model` (`dayWindow`, `panWindow`,
@@ -20587,7 +20587,7 @@ function resolveClipsView(input) {
20587
20587
  * Io in realtà utilizzerei la stessa tab recordings, lì abbiamo già tutto il
20588
20588
  * necessario, una nuova sezione alla fine per le clips dove possiamo
20589
20589
  * selezionare le source con un multiselect common, non componenti nuovi
20590
- * anonimi."* So every piece of chrome here is a component this repo already
20590
+ * anonimi."* [The UI is horrible, it does not follow our UI at all … I would actually use the same recordings tab, we already have everything necessary there, a new section at the end for the clips where we can select the sources with a common multiselect, no new anonymous components.] So every piece of chrome here is a component this repo already
20591
20591
  * has: `Select`, `DataTable`, `EmptyState`, `ErrorBox`, `Pagination`, `Card`,
20592
20592
  * `Badge`, `Button`, `Skeleton`. What the chrome CARRIES is unchanged, and it
20593
20593
  * is the feature:
@@ -20609,7 +20609,7 @@ function resolveClipsView(input) {
20609
20609
  * It shipped with its own `‹ day ›` pair and the operator replaced it the same
20610
20610
  * way he replaced the chrome: *"Possiamo utilizzare lo stesso componente della
20611
20611
  * sezione recording con la timebar dove selezionare un periodo e mostrare le
20612
- * clip solo di quella banda selezionata, espandibile."* So the list follows a
20612
+ * clip solo di quella banda selezionata, espandibile."* [We can use the same component as the recording section with the timebar where a period can be selected and show the clips of that selected band only, expandable.] So the list follows a
20613
20613
  * BAND (D564) — `TimelineControls` for the day, the zoom and the pan,
20614
20614
  * `EventHeatmap` for picking a narrower window out of it, both of them the
20615
20615
  * pieces `RecordingTimeline` is itself built from, over the same
@@ -20632,7 +20632,7 @@ function resolveClipsView(input) {
20632
20632
  * configuration that lives somewhere else. The operator put it exactly:
20633
20633
  * *"non è affatto necessario lo stato di abilitato o meno delle sources. Loro
20634
20634
  * vivono lì, ad esempio hksv c'è se la camera è esportata su homekit, reolink
20635
- * la dà di suo così come il camstack."* HKSV is there if the camera is
20635
+ * la dà di suo così come il camstack."* [the enabled-or-not state of the sources is not necessary at all. They live there, for example hksv is there if the camera is exported to homekit, reolink provides it on its own, as does camstack.] HKSV is there if the camera is
20636
20636
  * exported to HomeKit; the Reolink source is there because Reolink is that
20637
20637
  * camera's provider; CamStack's is always there. None of that is a decision to
20638
20638
  * make in a clips list, so this surface offers no switch and writes no
@@ -20643,7 +20643,7 @@ function resolveClipsView(input) {
20643
20643
  *
20644
20644
  * The operator asked for *"un multiselect common"* while `listClips` still
20645
20645
  * took `sources?: string[]`. It now takes ONE `provider` —
20646
- * *"l'utilizzatore è uno solo"* — and a multi-pick control over a
20646
+ * *"l'utilizzatore è uno solo"* [there is only one user] — and a multi-pick control over a
20647
20647
  * one-at-a-time argument offers a sum the hub cannot answer. So the control is
20648
20648
  * the shared single-choice one, `Select`: the same component the Recordings
20649
20649
  * page's own camera picker uses, which is what *"segue la nostra UI"* means
@@ -32871,7 +32871,7 @@ function resolveTableLayout({ mode, columnCount, isNarrow }) {
32871
32871
  * where labels can be inferred. The operator can still see every
32872
32872
  * stat / action — no horizontal scroll, no clipped text. The user
32873
32873
  * directive: "molta informazione in poco spazio quando la width è
32874
- * bassa."
32874
+ * bassa." [a lot of information in little space when the width is low.]
32875
32875
  *
32876
32876
  * • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
32877
32877
  * 2-column grids, side panels become visible, button labels return.
@@ -39414,12 +39414,17 @@ function PopoverRowAction({ icon: Icon, title, children }) {
39414
39414
  }
39415
39415
  //#endregion
39416
39416
  //#region src/lib/resolve-sensor-display.ts
39417
+ /** Table keys are canonical spellings; providers often send `C` / `F` / `celsius`. */
39418
+ function canonUnit(raw) {
39419
+ if (raw === void 0) return void 0;
39420
+ return normalizeUnit(raw) ?? raw;
39421
+ }
39417
39422
  var identity = (raw) => raw;
39418
39423
  function resolveSensorDisplay(input) {
39419
39424
  const perCap = input.capName !== void 0 ? input.display?.perCap?.[input.capName] : void 0;
39420
39425
  const precision = perCap?.precision ?? input.display?.precision ?? input.roleDefault?.precision ?? input.slicePrecision;
39421
- const sourceUnit = input.sliceUnit ?? input.canonicalUnit;
39422
- const overrideUnit = perCap?.unit ?? input.display?.unit ?? input.roleDefault?.unit;
39426
+ const sourceUnit = canonUnit(input.sliceUnit ?? input.canonicalUnit);
39427
+ const overrideUnit = canonUnit(perCap?.unit ?? input.display?.unit ?? input.roleDefault?.unit);
39423
39428
  if (overrideUnit !== void 0 && sourceUnit !== void 0 && overrideUnit !== sourceUnit && canConvertUnit(sourceUnit, overrideUnit)) return {
39424
39429
  unit: overrideUnit,
39425
39430
  precision,
@@ -14,7 +14,7 @@
14
14
  * where labels can be inferred. The operator can still see every
15
15
  * stat / action — no horizontal scroll, no clipped text. The user
16
16
  * directive: "molta informazione in poco spazio quando la width è
17
- * bassa."
17
+ * bassa." [a lot of information in little space when the width is low.]
18
18
  *
19
19
  * • **L2 — Standard** (`sm` — `640–1023px`, tablet + small laptop)
20
20
  * 2-column grids, side panels become visible, button labels return.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.220",
3
+ "version": "1.2.222",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",