@seamapi/react 2.0.2 → 2.1.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.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/dist/elements.js +2556 -2508
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +40 -0
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.min.css +1 -1
  7. package/dist/index.min.css.map +1 -1
  8. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.d.ts +6 -0
  9. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js +21 -0
  10. package/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js.map +1 -0
  11. package/lib/seam/components/index.d.ts +1 -0
  12. package/lib/seam/components/index.js +1 -0
  13. package/lib/seam/components/index.js.map +1 -1
  14. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.d.ts +6 -1
  15. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js +12 -1
  16. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js.map +1 -1
  17. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.d.ts +15 -0
  18. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js +42 -0
  19. package/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js.map +1 -0
  20. package/lib/ui/thermostat/ClimateSettingControlGroup.d.ts +9 -0
  21. package/lib/ui/thermostat/ClimateSettingControlGroup.js +8 -0
  22. package/lib/ui/thermostat/ClimateSettingControlGroup.js.map +1 -0
  23. package/lib/ui/thermostat/TemperatureControlGroup.d.ts +1 -2
  24. package/lib/version.d.ts +1 -1
  25. package/lib/version.js +1 -1
  26. package/package.json +1 -1
  27. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts +9 -0
  28. package/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx +65 -0
  29. package/src/lib/seam/components/elements.ts +1 -0
  30. package/src/lib/seam/components/index.ts +1 -0
  31. package/src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx +30 -2
  32. package/src/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.tsx +149 -0
  33. package/src/lib/ui/thermostat/ClimateSettingControlGroup.tsx +32 -0
  34. package/src/lib/ui/thermostat/TemperatureControlGroup.tsx +1 -1
  35. package/src/lib/version.ts +1 -1
  36. package/src/styles/_climate-setting-schedule-form.scss +24 -0
  37. package/src/styles/_main.scss +2 -0
  38. package/src/styles/_supported-device-table-manufacturer-keys.scss +19 -0
  39. package/src/styles/_thermostat.scss +15 -0
@@ -3,6 +3,7 @@ import classNames from 'classnames';
3
3
  import { useState } from 'react';
4
4
  import { useForm } from 'react-hook-form';
5
5
  import { getSystemTimeZone } from '../../../lib/dates.js';
6
+ import { ClimateSettingScheduleFormClimateSetting } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js';
6
7
  import { ClimateSettingScheduleFormDeviceSelect } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormDeviceSelect.js';
7
8
  import { ClimateSettingScheduleFormNameAndSchedule } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormNameAndSchedule.js';
8
9
  import { ClimateSettingScheduleFormTimeZonePicker } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleFormTimeZonePicker.js';
@@ -10,13 +11,18 @@ export function ClimateSettingScheduleForm({ className, ...props }) {
10
11
  return (_jsx("div", { className: classNames('seam-climate-setting-schedule-form', className), children: _jsx(Content, { ...props }) }));
11
12
  }
12
13
  function Content({ onBack, }) {
13
- const { control, watch } = useForm({
14
+ const { control, watch, resetField } = useForm({
14
15
  defaultValues: {
15
16
  deviceId: '',
16
17
  name: '',
17
18
  startDate: '',
18
19
  endDate: '',
19
20
  timeZone: getSystemTimeZone(),
21
+ hvacModeSetting: 'heat_cool',
22
+ setPoints: {
23
+ heatingSetPoint: 70,
24
+ coolingSetPoint: 75,
25
+ },
20
26
  },
21
27
  });
22
28
  const deviceId = watch('deviceId');
@@ -41,6 +47,11 @@ function Content({ onBack, }) {
41
47
  setPage('name_and_schedule');
42
48
  } }));
43
49
  }
50
+ if (page === 'climate_setting') {
51
+ return (_jsx(ClimateSettingScheduleFormClimateSetting, { title: t.addNewClimateSettingSchedule, control: control, watch: watch, resetField: resetField, deviceId: deviceId, onBack: () => {
52
+ setPage('name_and_schedule');
53
+ }, onCancel: onBack, onSave: () => { } }));
54
+ }
44
55
  return _jsx(_Fragment, {});
45
56
  }
46
57
  export const t = {
@@ -1 +1 @@
1
- {"version":3,"file":"ClimateSettingScheduleForm.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,sCAAsC,EAAE,MAAM,qEAAqE,CAAA;AAC5H,OAAO,EAAE,yCAAyC,EAAE,MAAM,wEAAwE,CAAA;AAClI,OAAO,EAAE,wCAAwC,EAAE,MAAM,uEAAuE,CAAA;AA0BhI,MAAM,UAAU,0BAA0B,CAAC,EACzC,SAAS,EACT,GAAG,KAAK,EACwB;IAChC,OAAO,CACL,cACE,SAAS,EAAE,UAAU,CAAC,oCAAoC,EAAE,SAAS,CAAC,YAEtE,KAAC,OAAO,OAAK,KAAK,GAAI,GAClB,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,EACf,MAAM,GAC6C;IACnD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QACjC,aAAa,EAAE;YACb,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,iBAAiB,EAAE;SAC9B;KACF,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAElC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAM9B,eAAe,CAAC,CAAA;IAElB,IAAI,IAAI,KAAK,eAAe,EAAE;QAC5B,OAAO,CACL,KAAC,sCAAsC,IACrC,KAAK,EAAE,CAAC,CAAC,4BAA4B,EACrC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,GAAG,EAAE;gBACb,OAAO,CAAC,mBAAmB,CAAC,CAAA;YAC9B,CAAC,GACD,CACH,CAAA;KACF;IAED,IAAI,IAAI,KAAK,mBAAmB,EAAE;QAChC,OAAO,CACL,KAAC,yCAAyC,IACxC,KAAK,EAAE,CAAC,CAAC,4BAA4B,EACrC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,CAAC,eAAe,CAAC,CAAA;YAC1B,CAAC,EACD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,CAAC,iBAAiB,CAAC,CAAA;YAC5B,CAAC,EACD,gBAAgB,EAAE,GAAG,EAAE;gBACrB,OAAO,CAAC,kBAAkB,CAAC,CAAA;YAC7B,CAAC,EACD,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAA;KACF;IAED,IAAI,IAAI,KAAK,kBAAkB,EAAE;QAC/B,OAAO,CACL,KAAC,wCAAwC,IACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,CAAC,mBAAmB,CAAC,CAAA;YAC9B,CAAC,GACD,CACH,CAAA;KACF;IAED,OAAO,mBAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,4BAA4B,EAAE,gCAAgC;CAC/D,CAAA"}
1
+ {"version":3,"file":"ClimateSettingScheduleForm.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,wCAAwC,EAAE,MAAM,uEAAuE,CAAA;AAChI,OAAO,EAAE,sCAAsC,EAAE,MAAM,qEAAqE,CAAA;AAC5H,OAAO,EAAE,yCAAyC,EAAE,MAAM,wEAAwE,CAAA;AAClI,OAAO,EAAE,wCAAwC,EAAE,MAAM,uEAAuE,CAAA;AA+BhI,MAAM,UAAU,0BAA0B,CAAC,EACzC,SAAS,EACT,GAAG,KAAK,EACwB;IAChC,OAAO,CACL,cACE,SAAS,EAAE,UAAU,CAAC,oCAAoC,EAAE,SAAS,CAAC,YAEtE,KAAC,OAAO,OAAK,KAAK,GAAI,GAClB,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,EACf,MAAM,GAC6C;IACnD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAC7C,aAAa,EAAE;YACb,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,iBAAiB,EAAE;YAC7B,eAAe,EAAE,WAA8B;YAC/C,SAAS,EAAE;gBACT,eAAe,EAAE,EAAE;gBACnB,eAAe,EAAE,EAAE;aACpB;SACF;KACF,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAElC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAM9B,eAAe,CAAC,CAAA;IAElB,IAAI,IAAI,KAAK,eAAe,EAAE;QAC5B,OAAO,CACL,KAAC,sCAAsC,IACrC,KAAK,EAAE,CAAC,CAAC,4BAA4B,EACrC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,GAAG,EAAE;gBACb,OAAO,CAAC,mBAAmB,CAAC,CAAA;YAC9B,CAAC,GACD,CACH,CAAA;KACF;IAED,IAAI,IAAI,KAAK,mBAAmB,EAAE;QAChC,OAAO,CACL,KAAC,yCAAyC,IACxC,KAAK,EAAE,CAAC,CAAC,4BAA4B,EACrC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,CAAC,eAAe,CAAC,CAAA;YAC1B,CAAC,EACD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,CAAC,iBAAiB,CAAC,CAAA;YAC5B,CAAC,EACD,gBAAgB,EAAE,GAAG,EAAE;gBACrB,OAAO,CAAC,kBAAkB,CAAC,CAAA;YAC7B,CAAC,EACD,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAA;KACF;IAED,IAAI,IAAI,KAAK,kBAAkB,EAAE;QAC/B,OAAO,CACL,KAAC,wCAAwC,IACvC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,GAAG,EAAE;gBACZ,OAAO,CAAC,mBAAmB,CAAC,CAAA;YAC9B,CAAC,GACD,CACH,CAAA;KACF;IAED,IAAI,IAAI,KAAK,iBAAiB,EAAE;QAC9B,OAAO,CACL,KAAC,wCAAwC,IACvC,KAAK,EAAE,CAAC,CAAC,4BAA4B,EACrC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,CAAC,mBAAmB,CAAC,CAAA;YAC9B,CAAC,EACD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC,GAChB,CACH,CAAA;KACF;IAED,OAAO,mBAAK,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,4BAA4B,EAAE,gCAAgC;CAC/D,CAAA"}
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import { type Control, type UseFormResetField, type UseFormWatch } from 'react-hook-form';
3
+ import type { ClimateSettingScheduleFormFields } from '../../../lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js';
4
+ interface ClimateSettingScheduleFormClimateSettingProps {
5
+ title: string;
6
+ control: Control<ClimateSettingScheduleFormFields>;
7
+ watch: UseFormWatch<ClimateSettingScheduleFormFields>;
8
+ resetField: UseFormResetField<ClimateSettingScheduleFormFields>;
9
+ deviceId: string;
10
+ onBack: () => void;
11
+ onCancel: (() => void) | undefined;
12
+ onSave: () => void;
13
+ }
14
+ export declare function ClimateSettingScheduleFormClimateSetting({ title, control, watch, resetField, deviceId, onBack, onCancel, onSave, }: ClimateSettingScheduleFormClimateSettingProps): JSX.Element;
15
+ export {};
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Controller, } from 'react-hook-form';
3
+ import { useDevice } from '../../../lib/seam/devices/use-device.js';
4
+ import { Button } from '../../../lib/ui/Button.js';
5
+ import { FormField } from '../../../lib/ui/FormField.js';
6
+ import { InputLabel } from '../../../lib/ui/InputLabel.js';
7
+ import { ContentHeader } from '../../../lib/ui/layout/ContentHeader.js';
8
+ import { ClimateModeMenu } from '../../../lib/ui/thermostat/ClimateModeMenu.js';
9
+ import { TemperatureControlGroup } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
10
+ export function ClimateSettingScheduleFormClimateSetting({ title, control, watch, resetField, deviceId, onBack, onCancel, onSave, }) {
11
+ const { device } = useDevice({
12
+ device_id: deviceId,
13
+ });
14
+ const hvacModeSetting = watch('hvacModeSetting');
15
+ return (_jsxs(_Fragment, { children: [_jsx(ContentHeader, { title: title, onBack: onBack, subheading: device?.properties.name }), _jsxs("div", { className: 'seam-main', children: [_jsx("div", { className: 'seam-climate-setting-schedule-form-climate-setting', children: _jsxs("div", { className: 'seam-content', children: [_jsxs("div", { children: [_jsx(InputLabel, { children: t.climateSetting }), _jsx("span", { className: 'seam-label', children: t.climateSettingSubHeading })] }), _jsx(FormContent, { control: control, resetField: resetField, hvacModeSetting: hvacModeSetting })] }) }), _jsxs("div", { className: 'seam-actions', children: [_jsx(Button, { onClick: onCancel, children: t.cancel }), _jsx(Button, { variant: 'solid', onClick: onSave, children: t.save })] })] })] }));
16
+ }
17
+ function FormContent({ control, resetField, hvacModeSetting, }) {
18
+ return (_jsxs(_Fragment, { children: [_jsx(FormField, { children: _jsx(Controller, { name: 'hvacModeSetting', control: control, render: ({ field: { value, onChange } }) => {
19
+ return (_jsx(ClimateModeMenu, { mode: value, onChange: (mode) => {
20
+ resetField('setPoints');
21
+ onChange(mode);
22
+ } }));
23
+ } }) }), hvacModeSetting !== 'off' && (_jsx(FormField, { className: 'seam-climate-setting-slider-container', children: _jsx(Controller, { name: 'setPoints', control: control, render: ({ field: { value, onChange } }) => (_jsx(TemperatureControlGroup, { coolValue: value.coolingSetPoint, heatValue: value.heatingSetPoint, delta: 5, maxCool: 90, maxHeat: 100, minCool: 50, minHeat: 70, mode: hvacModeSetting, onCoolValueChange: (coolingSetPoint) => {
24
+ onChange({
25
+ ...value,
26
+ coolingSetPoint,
27
+ });
28
+ }, onHeatValueChange: (heatingSetPoint) => {
29
+ onChange({
30
+ ...value,
31
+ heatingSetPoint,
32
+ });
33
+ } })) }) }))] }));
34
+ }
35
+ const t = {
36
+ climateSetting: 'Climate setting',
37
+ climateSettingSubHeading: 'Choose mode and adjust the climate',
38
+ cancel: 'Cancel',
39
+ save: 'Save',
40
+ next: 'Next',
41
+ };
42
+ //# sourceMappingURL=ClimateSettingScheduleFormClimateSetting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClimateSettingScheduleFormClimateSetting.js","sourceRoot":"","sources":["../../../src/lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { HvacModeSetting } from 'seamapi';
3
+ import { type TemperatureControlGroupProps } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
4
+ type ClimateSettingControlGroupProps = Omit<TemperatureControlGroupProps, 'mode'> & {
5
+ mode: HvacModeSetting;
6
+ onModeChange: (mode: HvacModeSetting) => void;
7
+ };
8
+ export declare function ClimateSettingControlGroup(props: ClimateSettingControlGroupProps): JSX.Element;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ClimateModeMenu } from '../../../lib/ui/thermostat/ClimateModeMenu.js';
3
+ import { TemperatureControlGroup, } from '../../../lib/ui/thermostat/TemperatureControlGroup.js';
4
+ export function ClimateSettingControlGroup(props) {
5
+ const { mode, onModeChange, ...rest } = props;
6
+ return (_jsxs("div", { className: 'seam-climate-setting-control-group', children: [_jsx(ClimateModeMenu, { mode: mode, onChange: onModeChange }), mode !== 'off' && (_jsx("div", { className: 'seam-climate-setting-slider-container', children: _jsx(TemperatureControlGroup, { mode: mode, ...rest }) }))] }));
7
+ }
8
+ //# sourceMappingURL=ClimateSettingControlGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClimateSettingControlGroup.js","sourceRoot":"","sources":["../../../src/lib/ui/thermostat/ClimateSettingControlGroup.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AACtE,OAAO,EACL,uBAAuB,GAExB,MAAM,8CAA8C,CAAA;AAUrD,MAAM,UAAU,0BAA0B,CACxC,KAAsC;IAEtC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;IAC7C,OAAO,CACL,eAAK,SAAS,EAAC,oCAAoC,aACjD,KAAC,eAAe,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,GAAI,EAEtD,IAAI,KAAK,KAAK,IAAI,CACjB,cAAK,SAAS,EAAC,uCAAuC,YACpD,KAAC,uBAAuB,IAAC,IAAI,EAAE,IAAI,KAAM,IAAI,GAAI,GAC7C,CACP,IACG,CACP,CAAA;AACH,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" resolution-mode="require"/>
2
2
  import type { HvacModeSetting } from 'seamapi';
3
- interface TemperatureControlGroupProps {
3
+ export interface TemperatureControlGroupProps {
4
4
  mode: Exclude<HvacModeSetting, 'off'>;
5
5
  heatValue: number;
6
6
  onHeatValueChange: (temperature: number) => void;
@@ -13,4 +13,3 @@ interface TemperatureControlGroupProps {
13
13
  maxCool: number;
14
14
  }
15
15
  export declare function TemperatureControlGroup({ mode, heatValue, onHeatValueChange, coolValue, onCoolValueChange, delta, minHeat, maxHeat, minCool, maxCool, }: TemperatureControlGroupProps): JSX.Element;
16
- export {};
package/lib/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare const seamapiReactVersion = "2.0.2";
1
+ declare const seamapiReactVersion = "2.1.0";
2
2
  export default seamapiReactVersion;
package/lib/version.js CHANGED
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '2.0.2';
1
+ const seamapiReactVersion = '2.1.0';
2
2
  export default seamapiReactVersion;
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/react",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "Seam Components.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -0,0 +1,9 @@
1
+ import type { ElementProps } from 'lib/element.js'
2
+
3
+ import type { SupportedDeviceTableManufacturerKeysProps } from './SupportedDeviceTableManufacturerKeys.js'
4
+
5
+ export const name = 'seam-supported-device-table-manufacturer-keys'
6
+
7
+ export const props: ElementProps<SupportedDeviceTableManufacturerKeysProps> = {}
8
+
9
+ export { SupportedDeviceTableManufacturerKeys as Component } from './SupportedDeviceTableManufacturerKeys.js'
@@ -0,0 +1,65 @@
1
+ import type { Manufacturer } from '@seamapi/types/devicedb'
2
+ import classNames from 'classnames'
3
+
4
+ import { useComponentTelemetry } from 'lib/telemetry/index.js'
5
+
6
+ import { CopyIcon } from 'lib/icons/Copy.js'
7
+ import {
8
+ type CommonProps,
9
+ withRequiredCommonProps,
10
+ } from 'lib/seam/components/common-props.js'
11
+ import { copyToClipboard } from 'lib/ui/clipboard.js'
12
+ import { MenuItem } from 'lib/ui/Menu/MenuItem.js'
13
+
14
+ import { useManufacturers } from './use-manufacturers.js'
15
+
16
+ export interface SupportedDeviceTableManufacturerKeysProps
17
+ extends CommonProps {}
18
+
19
+ export const NestedSupportedDeviceTableManufacturerKeys =
20
+ withRequiredCommonProps(SupportedDeviceTableManufacturerKeys)
21
+
22
+ export function SupportedDeviceTableManufacturerKeys({
23
+ className,
24
+ }: SupportedDeviceTableManufacturerKeysProps = {}): JSX.Element {
25
+ useComponentTelemetry('SupportedDeviceTableManufacturerKeys')
26
+
27
+ const { manufacturers } = useManufacturers()
28
+
29
+ return (
30
+ <div
31
+ className={classNames(
32
+ 'supported-device-table-manufacturer-keys',
33
+ className
34
+ )}
35
+ >
36
+ {manufacturers?.map((manufacturer) => (
37
+ <ManufacturerKey
38
+ key={manufacturer.manufacturer_id}
39
+ manufacturer={manufacturer}
40
+ />
41
+ ))}
42
+ </div>
43
+ )
44
+ }
45
+
46
+ function ManufacturerKey({
47
+ manufacturer,
48
+ }: {
49
+ manufacturer: Manufacturer
50
+ }): JSX.Element {
51
+ const key = manufacturer.display_name
52
+ return (
53
+ <div className='seam-manufacturer-key'>
54
+ <div className='seam-manufacturer-key-value'>{key}</div>
55
+ <MenuItem
56
+ className='seam-copy-button'
57
+ onClick={() => {
58
+ void copyToClipboard(key)
59
+ }}
60
+ >
61
+ <CopyIcon />
62
+ </MenuItem>
63
+ </div>
64
+ )
65
+ }
@@ -8,3 +8,4 @@ export * as DeviceDetails from './DeviceDetails/DeviceDetails.element.js'
8
8
  export * as DeviceTable from './DeviceTable/DeviceTable.element.js'
9
9
  export * as EditAccessCodeForm from './EditAccessCodeForm/EditAccessCodeForm.element.js'
10
10
  export * as SupportedDeviceTable from './SupportedDeviceTable/SupportedDeviceTable.element.js'
11
+ export * as SupportedDeviceTableManufacturerKeys from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.js'
@@ -9,3 +9,4 @@ export * from './DeviceDetails/DeviceDetails.js'
9
9
  export * from './DeviceTable/DeviceTable.js'
10
10
  export * from './EditAccessCodeForm/EditAccessCodeForm.js'
11
11
  export * from './SupportedDeviceTable/SupportedDeviceTable.js'
12
+ export * from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js'
@@ -1,9 +1,10 @@
1
1
  import classNames from 'classnames'
2
2
  import { useState } from 'react'
3
3
  import { useForm } from 'react-hook-form'
4
- import type { ClimateSetting } from 'seamapi'
4
+ import type { ClimateSetting, HvacModeSetting } from 'seamapi'
5
5
 
6
6
  import { getSystemTimeZone } from 'lib/dates.js'
7
+ import { ClimateSettingScheduleFormClimateSetting } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormClimateSetting.js'
7
8
  import { ClimateSettingScheduleFormDeviceSelect } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormDeviceSelect.js'
8
9
  import { ClimateSettingScheduleFormNameAndSchedule } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormNameAndSchedule.js'
9
10
  import { ClimateSettingScheduleFormTimeZonePicker } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleFormTimeZonePicker.js'
@@ -30,6 +31,11 @@ export interface ClimateSettingScheduleFormFields {
30
31
  startDate: string
31
32
  endDate: string
32
33
  timeZone: string
34
+ hvacModeSetting: HvacModeSetting
35
+ setPoints: {
36
+ heatingSetPoint: number
37
+ coolingSetPoint: number
38
+ }
33
39
  }
34
40
 
35
41
  export function ClimateSettingScheduleForm({
@@ -48,13 +54,18 @@ export function ClimateSettingScheduleForm({
48
54
  function Content({
49
55
  onBack,
50
56
  }: Omit<ClimateSettingScheduleFormProps, 'className'>): JSX.Element {
51
- const { control, watch } = useForm({
57
+ const { control, watch, resetField } = useForm({
52
58
  defaultValues: {
53
59
  deviceId: '',
54
60
  name: '',
55
61
  startDate: '',
56
62
  endDate: '',
57
63
  timeZone: getSystemTimeZone(),
64
+ hvacModeSetting: 'heat_cool' as HvacModeSetting,
65
+ setPoints: {
66
+ heatingSetPoint: 70,
67
+ coolingSetPoint: 75,
68
+ },
58
69
  },
59
70
  })
60
71
 
@@ -114,6 +125,23 @@ function Content({
114
125
  )
115
126
  }
116
127
 
128
+ if (page === 'climate_setting') {
129
+ return (
130
+ <ClimateSettingScheduleFormClimateSetting
131
+ title={t.addNewClimateSettingSchedule}
132
+ control={control}
133
+ watch={watch}
134
+ resetField={resetField}
135
+ deviceId={deviceId}
136
+ onBack={() => {
137
+ setPage('name_and_schedule')
138
+ }}
139
+ onCancel={onBack}
140
+ onSave={() => {}}
141
+ />
142
+ )
143
+ }
144
+
117
145
  return <></>
118
146
  }
119
147
 
@@ -0,0 +1,149 @@
1
+ import {
2
+ type Control,
3
+ Controller,
4
+ type UseFormResetField,
5
+ type UseFormWatch,
6
+ } from 'react-hook-form'
7
+ import type { HvacModeSetting } from 'seamapi'
8
+
9
+ import { useDevice } from 'lib/seam/devices/use-device.js'
10
+ import { Button } from 'lib/ui/Button.js'
11
+ import type { ClimateSettingScheduleFormFields } from 'lib/ui/ClimateSettingForm/ClimateSettingScheduleForm.js'
12
+ import { FormField } from 'lib/ui/FormField.js'
13
+ import { InputLabel } from 'lib/ui/InputLabel.js'
14
+ import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
15
+ import { ClimateModeMenu } from 'lib/ui/thermostat/ClimateModeMenu.js'
16
+ import { TemperatureControlGroup } from 'lib/ui/thermostat/TemperatureControlGroup.js'
17
+
18
+ interface ClimateSettingScheduleFormClimateSettingProps {
19
+ title: string
20
+ control: Control<ClimateSettingScheduleFormFields>
21
+ watch: UseFormWatch<ClimateSettingScheduleFormFields>
22
+ resetField: UseFormResetField<ClimateSettingScheduleFormFields>
23
+ deviceId: string
24
+ onBack: () => void
25
+ onCancel: (() => void) | undefined
26
+ onSave: () => void
27
+ }
28
+
29
+ export function ClimateSettingScheduleFormClimateSetting({
30
+ title,
31
+ control,
32
+ watch,
33
+ resetField,
34
+ deviceId,
35
+ onBack,
36
+ onCancel,
37
+ onSave,
38
+ }: ClimateSettingScheduleFormClimateSettingProps): JSX.Element {
39
+ const { device } = useDevice({
40
+ device_id: deviceId,
41
+ })
42
+
43
+ const hvacModeSetting = watch('hvacModeSetting')
44
+
45
+ return (
46
+ <>
47
+ <ContentHeader
48
+ title={title}
49
+ onBack={onBack}
50
+ subheading={device?.properties.name}
51
+ />
52
+ <div className='seam-main'>
53
+ <div className='seam-climate-setting-schedule-form-climate-setting'>
54
+ <div className='seam-content'>
55
+ <div>
56
+ <InputLabel>{t.climateSetting}</InputLabel>
57
+ <span className='seam-label'>{t.climateSettingSubHeading}</span>
58
+ </div>
59
+ <FormContent
60
+ control={control}
61
+ resetField={resetField}
62
+ hvacModeSetting={hvacModeSetting}
63
+ />
64
+ </div>
65
+ </div>
66
+ <div className='seam-actions'>
67
+ <Button onClick={onCancel}>{t.cancel}</Button>
68
+ <Button variant='solid' onClick={onSave}>
69
+ {t.save}
70
+ </Button>
71
+ </div>
72
+ </div>
73
+ </>
74
+ )
75
+ }
76
+
77
+ interface FormContentProps {
78
+ control: Control<ClimateSettingScheduleFormFields>
79
+ resetField: UseFormResetField<ClimateSettingScheduleFormFields>
80
+ hvacModeSetting: HvacModeSetting
81
+ }
82
+
83
+ function FormContent({
84
+ control,
85
+ resetField,
86
+ hvacModeSetting,
87
+ }: FormContentProps): JSX.Element {
88
+ return (
89
+ <>
90
+ <FormField>
91
+ <Controller
92
+ name='hvacModeSetting'
93
+ control={control}
94
+ render={({ field: { value, onChange } }) => {
95
+ return (
96
+ <ClimateModeMenu
97
+ mode={value}
98
+ onChange={(mode) => {
99
+ resetField('setPoints')
100
+ onChange(mode)
101
+ }}
102
+ />
103
+ )
104
+ }}
105
+ />
106
+ </FormField>
107
+ {hvacModeSetting !== 'off' && (
108
+ <FormField className='seam-climate-setting-slider-container'>
109
+ <Controller
110
+ name='setPoints'
111
+ control={control}
112
+ render={({ field: { value, onChange } }) => (
113
+ <TemperatureControlGroup
114
+ coolValue={value.coolingSetPoint}
115
+ heatValue={value.heatingSetPoint}
116
+ delta={5}
117
+ maxCool={90}
118
+ maxHeat={100}
119
+ minCool={50}
120
+ minHeat={70}
121
+ mode={hvacModeSetting}
122
+ onCoolValueChange={(coolingSetPoint) => {
123
+ onChange({
124
+ ...value,
125
+ coolingSetPoint,
126
+ })
127
+ }}
128
+ onHeatValueChange={(heatingSetPoint) => {
129
+ onChange({
130
+ ...value,
131
+ heatingSetPoint,
132
+ })
133
+ }}
134
+ />
135
+ )}
136
+ />
137
+ </FormField>
138
+ )}
139
+ </>
140
+ )
141
+ }
142
+
143
+ const t = {
144
+ climateSetting: 'Climate setting',
145
+ climateSettingSubHeading: 'Choose mode and adjust the climate',
146
+ cancel: 'Cancel',
147
+ save: 'Save',
148
+ next: 'Next',
149
+ }
@@ -0,0 +1,32 @@
1
+ import type { HvacModeSetting } from 'seamapi'
2
+
3
+ import { ClimateModeMenu } from 'lib/ui/thermostat/ClimateModeMenu.js'
4
+ import {
5
+ TemperatureControlGroup,
6
+ type TemperatureControlGroupProps,
7
+ } from 'lib/ui/thermostat/TemperatureControlGroup.js'
8
+
9
+ type ClimateSettingControlGroupProps = Omit<
10
+ TemperatureControlGroupProps,
11
+ 'mode'
12
+ > & {
13
+ mode: HvacModeSetting
14
+ onModeChange: (mode: HvacModeSetting) => void
15
+ }
16
+
17
+ export function ClimateSettingControlGroup(
18
+ props: ClimateSettingControlGroupProps
19
+ ): JSX.Element {
20
+ const { mode, onModeChange, ...rest } = props
21
+ return (
22
+ <div className='seam-climate-setting-control-group'>
23
+ <ClimateModeMenu mode={mode} onChange={onModeChange} />
24
+
25
+ {mode !== 'off' && (
26
+ <div className='seam-climate-setting-slider-container'>
27
+ <TemperatureControlGroup mode={mode} {...rest} />
28
+ </div>
29
+ )}
30
+ </div>
31
+ )
32
+ }
@@ -10,7 +10,7 @@ import {
10
10
  } from 'lib/temperature-bounds.js'
11
11
  import { TemperatureControl } from 'lib/ui/thermostat/TemperatureControl.js'
12
12
 
13
- interface TemperatureControlGroupProps {
13
+ export interface TemperatureControlGroupProps {
14
14
  mode: Exclude<HvacModeSetting, 'off'>
15
15
  heatValue: number
16
16
  onHeatValueChange: (temperature: number) => void
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '2.0.2'
1
+ const seamapiReactVersion = '2.1.0'
2
2
 
3
3
  export default seamapiReactVersion
@@ -4,6 +4,7 @@
4
4
  .seam-climate-setting-schedule-form {
5
5
  @include main;
6
6
  @include name-and-schedule;
7
+ @include climate-setting;
7
8
  }
8
9
  }
9
10
 
@@ -55,3 +56,26 @@
55
56
  }
56
57
  }
57
58
  }
59
+
60
+ @mixin climate-setting {
61
+ .seam-climate-setting-schedule-form-climate-setting {
62
+ .seam-content {
63
+ display: flex;
64
+ flex-direction: column;
65
+ gap: 16px;
66
+ width: 100%;
67
+ margin-top: 24px;
68
+ margin-bottom: 24px;
69
+
70
+ .seam-label {
71
+ color: colors.$text-gray-2;
72
+ font-size: 14px;
73
+ }
74
+
75
+ .seam-climate-setting-slider-container {
76
+ display: flex;
77
+ justify-content: center;
78
+ }
79
+ }
80
+ }
81
+ }
@@ -13,6 +13,7 @@
13
13
  @use './device-table';
14
14
  @use './access-code-details';
15
15
  @use './supported-device-table';
16
+ @use './supported-device-table-manufacturer-keys';
16
17
  @use './access-code-form';
17
18
  @use './input-label';
18
19
  @use './form-field';
@@ -59,6 +60,7 @@
59
60
  @include climate-setting-schedule-form.all;
60
61
  @include alert.all;
61
62
  @include supported-device-table.all;
63
+ @include supported-device-table-manufacturer-keys.all;
62
64
  @include thermostat.all;
63
65
  @include seam-table.all;
64
66
  @include climate-setting-schedule-details.all;
@@ -0,0 +1,19 @@
1
+ @mixin all {
2
+ .supported-device-table-manufacturer-keys {
3
+ font-size: 18px;
4
+
5
+ .seam-manufacturer-key {
6
+ display: table-row;
7
+ }
8
+
9
+ .seam-manufacturer-key-value {
10
+ display: table-cell;
11
+ }
12
+
13
+ .seam-copy-button {
14
+ display: table-cell;
15
+ cursor: pointer;
16
+ padding-left: 10px;
17
+ }
18
+ }
19
+ }
@@ -1,5 +1,19 @@
1
1
  @use './colors';
2
2
 
3
+ @mixin climate-setting-control-group {
4
+ .seam-climate-setting-control-group {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 16px;
8
+ width: 100%;
9
+
10
+ .seam-climate-setting-slider-container {
11
+ display: flex;
12
+ justify-content: center;
13
+ }
14
+ }
15
+ }
16
+
3
17
  @mixin temperature-control-group {
4
18
  .seam-temperature-control-group {
5
19
  display: flex;
@@ -690,6 +704,7 @@
690
704
  }
691
705
 
692
706
  @mixin all {
707
+ @include climate-setting-control-group;
693
708
  @include temperature-control-group;
694
709
  @include temperature-control;
695
710
  @include climate-setting-status;