@seamapi/react 1.47.0 → 1.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +1 -1
  2. package/dist/elements.js +3312 -3292
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +465 -1
  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/dates.d.ts +9 -0
  9. package/lib/dates.js +15 -0
  10. package/lib/dates.js.map +1 -1
  11. package/lib/icons/ArrowRight.d.ts +2 -0
  12. package/lib/icons/ArrowRight.js +7 -0
  13. package/lib/icons/ArrowRight.js.map +1 -0
  14. package/lib/icons/Info.d.ts +2 -0
  15. package/lib/icons/Info.js +7 -0
  16. package/lib/icons/Info.js.map +1 -0
  17. package/lib/icons/InfoDark.d.ts +2 -0
  18. package/lib/icons/InfoDark.js +7 -0
  19. package/lib/icons/InfoDark.js.map +1 -0
  20. package/lib/icons/TemperatureAdd.d.ts +2 -0
  21. package/lib/icons/TemperatureAdd.js +7 -0
  22. package/lib/icons/TemperatureAdd.js.map +1 -0
  23. package/lib/icons/TemperatureSubtract.d.ts +2 -0
  24. package/lib/icons/TemperatureSubtract.js +7 -0
  25. package/lib/icons/TemperatureSubtract.js.map +1 -0
  26. package/lib/seam/SeamProvider.d.ts +2 -2
  27. package/lib/seam/SeamProvider.js.map +1 -1
  28. package/lib/seam/access-codes/use-generate-access-code-code.d.ts +6 -0
  29. package/lib/seam/access-codes/use-generate-access-code-code.js +13 -0
  30. package/lib/seam/access-codes/use-generate-access-code-code.js.map +1 -0
  31. package/lib/seam/components/AccessCodeDetails/AccessCodeDetails.js.map +1 -1
  32. package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js +1 -1
  33. package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js.map +1 -1
  34. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleCard.d.ts +6 -0
  35. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleCard.js +41 -0
  36. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleCard.js.map +1 -0
  37. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleDeviceBar.d.ts +4 -0
  38. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleDeviceBar.js +29 -0
  39. package/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleDeviceBar.js.map +1 -0
  40. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleRow.js +2 -2
  41. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleRow.js.map +1 -1
  42. package/lib/seam/components/ClimateSettingScheduleTable/{ClimateSettingScheduleDetails.d.ts → ClimateSettingScheduleRowDetails.d.ts} +1 -1
  43. package/lib/seam/components/ClimateSettingScheduleTable/{ClimateSettingScheduleDetails.js → ClimateSettingScheduleRowDetails.js} +2 -2
  44. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleRowDetails.js.map +1 -0
  45. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.d.ts +6 -1
  46. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.js +21 -4
  47. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.js.map +1 -1
  48. package/lib/seam/components/DeviceTable/DeviceTable.js +2 -2
  49. package/lib/seam/components/DeviceTable/DeviceTable.js.map +1 -1
  50. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.d.ts +5 -0
  51. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.js +24 -0
  52. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.js.map +1 -0
  53. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js +1 -0
  54. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js.map +1 -1
  55. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.d.ts +5 -0
  56. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.js +21 -0
  57. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.js.map +1 -0
  58. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.d.ts +5 -0
  59. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.js +27 -0
  60. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.js.map +1 -0
  61. package/lib/seam/use-seam-client.js +2 -2
  62. package/lib/seam/use-seam-client.js.map +1 -1
  63. package/lib/ui/AccessCodeForm/AccessCodeFormDatePicker.js +1 -1
  64. package/lib/ui/AccessCodeForm/AccessCodeFormDatePicker.js.map +1 -1
  65. package/lib/ui/Menu/Menu.js +5 -5
  66. package/lib/ui/Menu/Menu.js.map +1 -1
  67. package/lib/ui/Switch/Switch.d.ts +8 -0
  68. package/lib/ui/Switch/Switch.js +15 -0
  69. package/lib/ui/Switch/Switch.js.map +1 -0
  70. package/lib/ui/TextField/TextField.js +1 -3
  71. package/lib/ui/TextField/TextField.js.map +1 -1
  72. package/lib/ui/Tooltip/Tooltip.d.ts +2 -0
  73. package/lib/ui/Tooltip/Tooltip.js +33 -0
  74. package/lib/ui/Tooltip/Tooltip.js.map +1 -0
  75. package/lib/ui/clipboard.js +1 -1
  76. package/lib/ui/clipboard.js.map +1 -1
  77. package/lib/ui/thermostat/ClimateSettingStatus.js +10 -3
  78. package/lib/ui/thermostat/ClimateSettingStatus.js.map +1 -1
  79. package/lib/ui/thermostat/TemperatureControl.d.ts +11 -0
  80. package/lib/ui/thermostat/TemperatureControl.js +42 -0
  81. package/lib/ui/thermostat/TemperatureControl.js.map +1 -0
  82. package/lib/ui/use-current-time.d.ts +2 -0
  83. package/lib/ui/use-current-time.js +12 -0
  84. package/lib/ui/use-current-time.js.map +1 -0
  85. package/lib/version.d.ts +1 -1
  86. package/lib/version.js +1 -1
  87. package/package.json +7 -7
  88. package/src/lib/dates.ts +17 -0
  89. package/src/lib/element.tsx +6 -4
  90. package/src/lib/icons/ArrowRight.tsx +36 -0
  91. package/src/lib/icons/Info.tsx +36 -0
  92. package/src/lib/icons/InfoDark.tsx +37 -0
  93. package/src/lib/icons/TemperatureAdd.tsx +38 -0
  94. package/src/lib/icons/TemperatureSubtract.tsx +35 -0
  95. package/src/lib/seam/SeamProvider.tsx +2 -3
  96. package/src/lib/seam/access-codes/use-generate-access-code-code.ts +38 -0
  97. package/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx +0 -2
  98. package/src/lib/seam/components/AccessCodeDetails/AccessCodeDevice.tsx +1 -4
  99. package/src/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleCard.tsx +101 -0
  100. package/src/lib/seam/components/ClimateSettingScheduleDetails/ClimateSettingScheduleDeviceBar.tsx +58 -0
  101. package/src/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleRow.tsx +2 -2
  102. package/src/lib/seam/components/ClimateSettingScheduleTable/{ClimateSettingScheduleDetails.tsx → ClimateSettingScheduleRowDetails.tsx} +1 -1
  103. package/src/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.element.ts +4 -0
  104. package/src/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.tsx +59 -6
  105. package/src/lib/seam/components/DeviceTable/DeviceTable.tsx +2 -2
  106. package/src/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.ts +47 -0
  107. package/src/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.ts +1 -0
  108. package/src/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.ts +48 -0
  109. package/src/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.ts +53 -0
  110. package/src/lib/seam/use-seam-client.ts +2 -2
  111. package/src/lib/ui/AccessCodeForm/AccessCodeFormDatePicker.tsx +2 -2
  112. package/src/lib/ui/Menu/Menu.tsx +5 -6
  113. package/src/lib/ui/Switch/Switch.tsx +38 -0
  114. package/src/lib/ui/TextField/TextField.tsx +1 -3
  115. package/src/lib/ui/Tooltip/Tooltip.tsx +64 -0
  116. package/src/lib/ui/clipboard.ts +1 -1
  117. package/src/lib/ui/thermostat/ClimateSettingStatus.tsx +12 -10
  118. package/src/lib/ui/thermostat/TemperatureControl.tsx +121 -0
  119. package/src/lib/ui/use-current-time.ts +16 -0
  120. package/src/lib/version.ts +1 -1
  121. package/src/styles/_colors.scss +4 -0
  122. package/src/styles/_main.scss +4 -0
  123. package/src/styles/_switch.scss +53 -0
  124. package/src/styles/_thermostat.scss +384 -2
  125. package/src/styles/_tooltip.scss +86 -0
  126. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleDetails.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ClimateSettingStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/thermostat/ClimateSettingStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAQ9D,MAAM,UAAU,oBAAoB,CAAC,EACnC,cAAc,EACd,eAAe,GAAG,YAAY,EAC9B,aAAa,GAAG,MAAM,GACI;IAC1B,OAAO,CACL,eAAK,SAAS,EAAC,6BAA6B,aACzC,aAAa,KAAK,MAAM,IAAI,CAC3B,KAAC,kBAAkB,IAAC,IAAI,EAAE,cAAc,CAAC,iBAAiB,GAAI,CAC/D,EACD,KAAC,OAAO,IACN,IAAI,EAAE,cAAc,CAAC,iBAAiB,EACtC,eAAe,EACb,eAAe,KAAK,YAAY;oBAC9B,CAAC,CAAC,cAAc,CAAC,4BAA4B;oBAC7C,CAAC,CAAC,cAAc,CAAC,yBAAyB,EAE9C,eAAe,EACb,eAAe,KAAK,YAAY;oBAC9B,CAAC,CAAC,cAAc,CAAC,4BAA4B;oBAC7C,CAAC,CAAC,cAAc,CAAC,yBAAyB,EAE9C,eAAe,EAAE,eAAe,GAChC,EACD,aAAa,KAAK,OAAO,IAAI,CAC5B,KAAC,kBAAkB,IAAC,IAAI,EAAE,cAAc,CAAC,iBAAiB,GAAI,CAC/D,IACG,CACP,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAE3B;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IAEtB,OAAO,CACL,eAAK,SAAS,EAAC,kCAAkC,aAC9C,IAAI,KAAK,MAAM,IAAI,KAAC,kBAAkB,KAAG,EACzC,IAAI,KAAK,MAAM,IAAI,KAAC,kBAAkB,KAAG,EACzC,IAAI,KAAK,UAAU,IAAI,KAAC,sBAAsB,KAAG,EACjD,IAAI,KAAK,KAAK,IAAI,KAAC,iBAAiB,KAAG,IACpC,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAShB;IACC,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,KAAK,CAAA;IACzE,MAAM,kBAAkB,GAAG,eAAe,KAAK,SAAS,CAAA;IACxD,MAAM,kBAAkB,GAAG,eAAe,KAAK,SAAS,CAAA;IACxD,MAAM,IAAI,GACR,eAAe,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAA;IAEzE,IAAI,IAAI,KAAK,MAAM,IAAI,kBAAkB;QACvC,OAAO,yBAAO,GAAG,eAAe,GAAG,IAAI,EAAE,GAAQ,CAAA;IAEnD,IAAI,IAAI,KAAK,MAAM,IAAI,kBAAkB;QACvC,OAAO,yBAAO,GAAG,eAAe,GAAG,IAAI,EAAE,GAAQ,CAAA;IAEnD,IAAI,IAAI,KAAK,UAAU,IAAI,kBAAkB,IAAI,kBAAkB;QACjE,OAAO,CACL,yBAAO,GAAG,eAAe,GAAG,IAAI,MAAM,eAAe,GAAG,IAAI,EAAE,GAAQ,CACvE,CAAA;IAEH,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,yBAAO,CAAC,CAAC,GAAG,GAAQ,CAAA;IAE/C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,GAAG;IACR,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;IACnB,GAAG,EAAE,KAAK;CACX,CAAA"}
1
+ {"version":3,"file":"ClimateSettingStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/thermostat/ClimateSettingStatus.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ interface TemperatureControlProps {
3
+ variant: 'heat' | 'cool';
4
+ value: number;
5
+ onChange: (temperature: number) => void;
6
+ min?: number;
7
+ max?: number;
8
+ unit?: 'fahrenheit' | 'celsius';
9
+ }
10
+ export declare function TemperatureControl({ variant, value, onChange, min, max, unit, }: TemperatureControlProps): JSX.Element;
11
+ export {};
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import { TemperatureAddIcon } from '../../../lib/icons/TemperatureAdd.js';
4
+ import { TemperatureSubtractIcon } from '../../../lib/icons/TemperatureSubtract.js';
5
+ export function TemperatureControl({ variant, value, onChange, min = 50, max = 90, unit = 'fahrenheit', }) {
6
+ const increment = () => {
7
+ onChange(Math.min(value + 1, max));
8
+ };
9
+ const decrement = () => {
10
+ onChange(Math.max(value - 1, min));
11
+ };
12
+ return (_jsxs("div", { className: 'seam-temperature-control', children: [_jsx("button", { className: 'seam-temperature-stepper-button', onClick: decrement, children: _jsx(TemperatureSubtractIcon, {}) }), _jsx(RangeSlider, { variant: variant, min: min, max: max, value: value, onChange: (temperature) => {
13
+ onChange(temperature);
14
+ }, unit: unit }), _jsx("button", { className: 'seam-temperature-stepper-button', onClick: increment, children: _jsx(TemperatureAddIcon, {}) })] }));
15
+ }
16
+ function RangeSlider({ variant, value, onChange, min, max, unit, }) {
17
+ const wrapRef = useRef(null);
18
+ const inputRef = useRef(null);
19
+ useEffect(() => {
20
+ if (wrapRef.current == null || inputRef.current == null)
21
+ return;
22
+ const wrap = wrapRef.current;
23
+ const input = inputRef.current;
24
+ wrap.style.setProperty('--temperature-current', input.value);
25
+ wrap.style.setProperty('--temperature-min', input.min);
26
+ wrap.style.setProperty('--temperature-max', input.max);
27
+ }, [value]);
28
+ const handleRangeChange = (event) => {
29
+ const wrap = wrapRef.current;
30
+ if (wrap == null)
31
+ return;
32
+ const temperature = event.target.value;
33
+ wrap.style.setProperty('--temperature-current', temperature);
34
+ onChange(Number(temperature));
35
+ };
36
+ return (_jsxs("div", { ref: wrapRef, className: 'seam-temperature-range-wrap', children: [_jsx("input", { ref: inputRef, type: 'range', min: min, max: max, value: value, onChange: handleRangeChange, className: 'seam-temperature-range', "data-variant": variant }), _jsxs("div", { className: 'seam-floating-temperature', children: [_jsx("span", { className: 'seam-floating-temperature-value', children: value }), _jsx("span", { className: 'seam-floating-temperature-unit', children: unit === 'fahrenheit' ? t.degreeFahrenheit : t.degreeCelsius })] })] }));
37
+ }
38
+ const t = {
39
+ degreeFahrenheit: 'ºF',
40
+ degreeCelsius: 'ºC',
41
+ };
42
+ //# sourceMappingURL=TemperatureControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemperatureControl.js","sourceRoot":"","sources":["../../../src/lib/ui/thermostat/TemperatureControl.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { DateTime } from 'luxon';
2
+ export declare function useCurrentTime(): DateTime;
@@ -0,0 +1,12 @@
1
+ import { DateTime } from 'luxon';
2
+ import { useCallback, useState } from 'react';
3
+ import { useInterval } from '../../lib/ui/use-interval.js';
4
+ export function useCurrentTime() {
5
+ const [date, setDate] = useState(DateTime.now());
6
+ const update = useCallback(() => {
7
+ setDate(DateTime.now());
8
+ }, [setDate]);
9
+ useInterval(update);
10
+ return date;
11
+ }
12
+ //# sourceMappingURL=use-current-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-current-time.js","sourceRoot":"","sources":["../../src/lib/ui/use-current-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEpD,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAW,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAA;IAE1D,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAA;IACzB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,WAAW,CAAC,MAAM,CAAC,CAAA;IAEnB,OAAO,IAAI,CAAA;AACb,CAAC"}
package/lib/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare const seamapiReactVersion = "1.47.0";
1
+ declare const seamapiReactVersion = "1.48.1";
2
2
  export default seamapiReactVersion;
package/lib/version.js CHANGED
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '1.47.0';
1
+ const seamapiReactVersion = '1.48.1';
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": "1.47.0",
3
+ "version": "1.48.1",
4
4
  "description": "Seam Components.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -122,7 +122,7 @@
122
122
  "@tanstack/react-query": "^4.28.0",
123
123
  "classnames": "^2.3.2",
124
124
  "luxon": "^3.3.0",
125
- "seamapi": "^8.6.0",
125
+ "seamapi": "^8.9.0",
126
126
  "uuid": "^9.0.0"
127
127
  },
128
128
  "devDependencies": {
@@ -133,7 +133,7 @@
133
133
  "@mui/icons-material": "^5.11.16",
134
134
  "@mui/material": "^5.12.2",
135
135
  "@rxfork/r2wc-react-to-web-component": "^2.3.0",
136
- "@seamapi/fake-seam-connect": "^1.6.0",
136
+ "@seamapi/fake-seam-connect": "^1.9.0",
137
137
  "@storybook/addon-designs": "^7.0.1",
138
138
  "@storybook/addon-essentials": "^7.0.2",
139
139
  "@storybook/addon-links": "^7.0.2",
@@ -159,11 +159,11 @@
159
159
  "eslint-config-standard": "^17.1.0",
160
160
  "eslint-config-standard-jsx": "^11.0.0",
161
161
  "eslint-config-standard-react": "^13.0.0",
162
- "eslint-config-standard-with-typescript": "^37.0.0",
162
+ "eslint-config-standard-with-typescript": "^39.0.0",
163
163
  "eslint-plugin-simple-import-sort": "^10.0.0",
164
164
  "eslint-plugin-storybook": "^0.6.11",
165
- "eslint-plugin-unused-imports": "^2.0.0",
166
- "execa": "^7.1.1",
165
+ "eslint-plugin-unused-imports": "^3.0.0",
166
+ "execa": "^8.0.1",
167
167
  "fast-glob": "^3.2.12",
168
168
  "http-proxy-middleware": "^2.0.6",
169
169
  "isomorphic-fetch": "^3.0.0",
@@ -182,7 +182,7 @@
182
182
  "tsc-alias": "^1.8.5",
183
183
  "tsconfig-paths-webpack-plugin": "^4.0.1",
184
184
  "tsx": "^3.12.7",
185
- "typescript": "^5.1.0",
185
+ "typescript": "~5.1.0",
186
186
  "vite": "^4.2.1",
187
187
  "vite-tsconfig-paths": "^4.0.8",
188
188
  "zustand-hoist": "^1.0.0"
package/src/lib/dates.ts CHANGED
@@ -138,3 +138,20 @@ export const createIsoDate = (date: string, timezone: string): string => {
138
138
  */
139
139
  export const getTimezoneFromIsoDate = (date: string): string | null =>
140
140
  DateTime.fromISO(date).zoneName
141
+
142
+ /**
143
+ * Takes an ISO datetime string (2023-07-20T00:00:00.000-07:00) and returns a string like
144
+ * (Jul 20, 12:00 AM PDT).
145
+ *
146
+ * @param date
147
+ * @returns string
148
+ *
149
+ */
150
+ export const formatDateAndTime = (date: string): string =>
151
+ DateTime.fromISO(date).toLocaleString({
152
+ month: 'short',
153
+ day: 'numeric',
154
+ hour: 'numeric',
155
+ minute: '2-digit',
156
+ timeZoneName: 'short',
157
+ })
@@ -28,8 +28,10 @@ export type ElementProps<T> = Record<
28
28
  'string' | 'number' | 'boolean' | 'array' | 'function' | 'json' | 'object'
29
29
  >
30
30
 
31
- type ProviderProps = SeamProviderPropsWithPublishableKey &
32
- SeamProviderPropsWithClientSessionToken
31
+ type ProviderProps = Omit<
32
+ SeamProviderPropsWithPublishableKey & SeamProviderPropsWithClientSessionToken,
33
+ 'children'
34
+ >
33
35
 
34
36
  const providerProps: ElementProps<ProviderProps> = {
35
37
  publishableKey: 'string',
@@ -53,7 +55,7 @@ export const defineCustomElement = ({
53
55
  ...providerProps,
54
56
  },
55
57
  })
56
- globalThis?.customElements?.define(name, element)
58
+ globalThis.customElements?.define(name, element)
57
59
  }
58
60
 
59
61
  function withProvider<P extends JSX.IntrinsicAttributes>(
@@ -82,7 +84,7 @@ function withProvider<P extends JSX.IntrinsicAttributes>(
82
84
  disableFontInjection={
83
85
  disableFontInjection ?? globalThis.disableSeamFontInjection
84
86
  }
85
- unminifiyCss={unminifiyCss ?? globalThis?.unminifiySeamCss}
87
+ unminifiyCss={unminifiyCss ?? globalThis.unminifiySeamCss}
86
88
  >
87
89
  <Component {...(props as P)} />
88
90
  </SeamProvider>
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Automaically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function ArrowRightIcon(props: SVGProps<SVGSVGElement>): JSX.Element {
7
+ return (
8
+ <svg
9
+ xmlns='http://www.w3.org/2000/svg'
10
+ width={18}
11
+ height={19}
12
+ fill='none'
13
+ {...props}
14
+ >
15
+ <mask
16
+ id='arrow-right_svg__a'
17
+ width={18}
18
+ height={19}
19
+ x={0}
20
+ y={0}
21
+ maskUnits='userSpaceOnUse'
22
+ style={{
23
+ maskType: 'alpha',
24
+ }}
25
+ >
26
+ <path fill='#D9D9D9' d='M0 .5h18v18H0z' />
27
+ </mask>
28
+ <g mask='url(#arrow-right_svg__a)'>
29
+ <path
30
+ fill='#B9BEC5'
31
+ d='m10.5 14-1.05-1.088 2.663-2.662H3v-1.5h9.113L9.45 6.088 10.5 5 15 9.5 10.5 14Z'
32
+ />
33
+ </g>
34
+ </svg>
35
+ )
36
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Automaically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function InfoIcon(props: SVGProps<SVGSVGElement>): JSX.Element {
7
+ return (
8
+ <svg
9
+ xmlns='http://www.w3.org/2000/svg'
10
+ width={18}
11
+ height={19}
12
+ fill='none'
13
+ {...props}
14
+ >
15
+ <mask
16
+ id='info_svg__a'
17
+ width={18}
18
+ height={19}
19
+ x={0}
20
+ y={0}
21
+ maskUnits='userSpaceOnUse'
22
+ style={{
23
+ maskType: 'alpha',
24
+ }}
25
+ >
26
+ <path fill='#D9D9D9' d='M0 .5h18v18H0z' />
27
+ </mask>
28
+ <g mask='url(#info_svg__a)'>
29
+ <path
30
+ fill='#D5D8DC'
31
+ d='M8.25 13.25h1.5v-4.5h-1.5v4.5Zm.75-6c.213 0 .39-.072.535-.216A.725.725 0 0 0 9.75 6.5a.728.728 0 0 0-.215-.535A.728.728 0 0 0 9 5.75a.725.725 0 0 0-.534.215.726.726 0 0 0-.216.535c0 .213.072.39.216.534A.724.724 0 0 0 9 7.25ZM9 17a7.3 7.3 0 0 1-2.925-.591 7.569 7.569 0 0 1-2.381-1.603 7.569 7.569 0 0 1-1.603-2.381A7.3 7.3 0 0 1 1.5 9.5a7.3 7.3 0 0 1 .591-2.925 7.569 7.569 0 0 1 1.603-2.381A7.58 7.58 0 0 1 6.075 2.59 7.307 7.307 0 0 1 9 2c1.037 0 2.012.197 2.925.59a7.58 7.58 0 0 1 2.381 1.604 7.569 7.569 0 0 1 1.603 2.381A7.3 7.3 0 0 1 16.5 9.5a7.3 7.3 0 0 1-.591 2.925 7.569 7.569 0 0 1-1.603 2.381 7.569 7.569 0 0 1-2.381 1.603A7.3 7.3 0 0 1 9 17Zm0-1.5c1.675 0 3.094-.581 4.256-1.744C14.42 12.594 15 11.175 15 9.5c0-1.675-.581-3.094-1.744-4.256C12.094 4.08 10.675 3.5 9 3.5c-1.675 0-3.094.581-4.256 1.744C3.58 6.406 3 7.825 3 9.5c0 1.675.581 3.094 1.744 4.256C5.906 14.92 7.325 15.5 9 15.5Z'
32
+ />
33
+ </g>
34
+ </svg>
35
+ )
36
+ }
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Automaically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function InfoDarkIcon(props: SVGProps<SVGSVGElement>): JSX.Element {
7
+ return (
8
+ <svg
9
+ xmlns='http://www.w3.org/2000/svg'
10
+ width={19}
11
+ height={19}
12
+ fill='none'
13
+ {...props}
14
+ >
15
+ <circle cx={9.755} cy={9.416} r={6.655} fill='#E9EDEF' />
16
+ <mask
17
+ id='info-dark_svg__a'
18
+ width={19}
19
+ height={19}
20
+ x={0}
21
+ y={0}
22
+ maskUnits='userSpaceOnUse'
23
+ style={{
24
+ maskType: 'alpha',
25
+ }}
26
+ >
27
+ <path fill='#D9D9D9' d='M.755.416h18v18h-18z' />
28
+ </mask>
29
+ <g mask='url(#info-dark_svg__a)'>
30
+ <path
31
+ fill='#9DA1A9'
32
+ d='M9.005 13.166h1.5v-4.5h-1.5v4.5Zm.75-6c.213 0 .391-.072.535-.216a.725.725 0 0 0 .215-.534.728.728 0 0 0-.215-.534.728.728 0 0 0-.535-.216.725.725 0 0 0-.534.216.726.726 0 0 0-.216.534c0 .213.072.39.216.534a.724.724 0 0 0 .534.216Zm0 9.75a7.3 7.3 0 0 1-2.925-.59 7.569 7.569 0 0 1-2.38-1.603 7.568 7.568 0 0 1-1.604-2.382 7.3 7.3 0 0 1-.59-2.925 7.3 7.3 0 0 1 .59-2.925 7.569 7.569 0 0 1 1.603-2.38A7.58 7.58 0 0 1 6.83 2.506a7.307 7.307 0 0 1 2.925-.59c1.038 0 2.013.196 2.925.59a7.579 7.579 0 0 1 2.382 1.603 7.569 7.569 0 0 1 1.602 2.381 7.3 7.3 0 0 1 .591 2.925 7.3 7.3 0 0 1-.59 2.925 7.569 7.569 0 0 1-1.603 2.382 7.569 7.569 0 0 1-2.382 1.602 7.3 7.3 0 0 1-2.925.591Zm0-1.5c1.675 0 3.094-.58 4.257-1.743 1.162-1.163 1.743-2.582 1.743-4.257 0-1.675-.58-3.093-1.743-4.256-1.163-1.162-2.582-1.744-4.257-1.744-1.675 0-3.093.582-4.256 1.744-1.162 1.163-1.744 2.581-1.744 4.256 0 1.675.582 3.094 1.744 4.257 1.163 1.162 2.581 1.743 4.256 1.743Z'
33
+ />
34
+ </g>
35
+ </svg>
36
+ )
37
+ }
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Automaically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function TemperatureAddIcon(
7
+ props: SVGProps<SVGSVGElement>
8
+ ): JSX.Element {
9
+ return (
10
+ <svg
11
+ xmlns='http://www.w3.org/2000/svg'
12
+ width={18}
13
+ height={18}
14
+ fill='none'
15
+ {...props}
16
+ >
17
+ <mask
18
+ id='temperature-add_svg__a'
19
+ width={18}
20
+ height={18}
21
+ x={0}
22
+ y={0}
23
+ maskUnits='userSpaceOnUse'
24
+ style={{
25
+ maskType: 'alpha',
26
+ }}
27
+ >
28
+ <path fill='#2196F3' d='M0 0h18v18H0z' />
29
+ </mask>
30
+ <g mask='url(#temperature-add_svg__a)'>
31
+ <path
32
+ fill='#9DA1A9'
33
+ d='M8.25 14.25v-4.5h-4.5v-1.5h4.5v-4.5h1.5v4.5h4.5v1.5h-4.5v4.5h-1.5Z'
34
+ />
35
+ </g>
36
+ </svg>
37
+ )
38
+ }
@@ -0,0 +1,35 @@
1
+ /*
2
+ * Automaically generated by SVGR from assets/icons/*.svg.
3
+ * Do not edit this file or add other components to this directory.
4
+ */
5
+ import type { SVGProps } from 'react'
6
+ export function TemperatureSubtractIcon(
7
+ props: SVGProps<SVGSVGElement>
8
+ ): JSX.Element {
9
+ return (
10
+ <svg
11
+ xmlns='http://www.w3.org/2000/svg'
12
+ width={18}
13
+ height={18}
14
+ fill='none'
15
+ {...props}
16
+ >
17
+ <mask
18
+ id='temperature-subtract_svg__a'
19
+ width={18}
20
+ height={18}
21
+ x={0}
22
+ y={0}
23
+ maskUnits='userSpaceOnUse'
24
+ style={{
25
+ maskType: 'alpha',
26
+ }}
27
+ >
28
+ <path fill='#2196F3' d='M0 0h18v18H0z' />
29
+ </mask>
30
+ <g mask='url(#temperature-subtract_svg__a)'>
31
+ <path fill='#9DA1A9' d='M3.75 9.75v-1.5h10.5v1.5H3.75Z' />
32
+ </g>
33
+ </svg>
34
+ )
35
+ }
@@ -25,11 +25,10 @@ export interface SeamContext {
25
25
  clientSessionToken?: string | undefined
26
26
  }
27
27
 
28
- export type SeamProviderProps = PropsWithChildren<
28
+ export type SeamProviderProps =
29
29
  | SeamProviderPropsWithClient
30
30
  | SeamProviderPropsWithPublishableKey
31
31
  | SeamProviderPropsWithClientSessionToken
32
- >
33
32
 
34
33
  export interface SeamProviderPropsWithClient extends SeamProviderBaseProps {
35
34
  client: Seam
@@ -48,7 +47,7 @@ export interface SeamProviderPropsWithClientSessionToken
48
47
  clientSessionToken: string
49
48
  }
50
49
 
51
- interface SeamProviderBaseProps {
50
+ interface SeamProviderBaseProps extends PropsWithChildren {
52
51
  disableCssInjection?: boolean | undefined
53
52
  disableFontInjection?: boolean | undefined
54
53
  unminifiyCss?: boolean | undefined
@@ -0,0 +1,38 @@
1
+ import { useMutation, type UseMutationResult } from '@tanstack/react-query'
2
+ import type {
3
+ AccessCode,
4
+ AccessCodeGenerateCodeRequest,
5
+ AccessCodeGenerateCodeResponse,
6
+ SeamError,
7
+ } from 'seamapi'
8
+
9
+ import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
10
+
11
+ export type UseGenerateAccessCodeCodeParams = never
12
+ export type UseGenerateAccessCodeCodeData = Pick<
13
+ AccessCode,
14
+ 'code' | 'device_id'
15
+ >
16
+ export type UseGenerateAccessCodeCodeMutationParams =
17
+ AccessCodeGenerateCodeRequest
18
+
19
+ export function useGenerateAccessCodeCode(): UseMutationResult<
20
+ UseGenerateAccessCodeCodeData,
21
+ SeamError,
22
+ UseGenerateAccessCodeCodeMutationParams
23
+ > {
24
+ const { client } = useSeamClient()
25
+
26
+ return useMutation<
27
+ AccessCodeGenerateCodeResponse['generated_code'],
28
+ SeamError,
29
+ AccessCodeGenerateCodeRequest
30
+ >({
31
+ mutationFn: async (
32
+ mutationParams: UseGenerateAccessCodeCodeMutationParams
33
+ ) => {
34
+ if (client === null) throw new NullSeamClientError()
35
+ return await client.accessCodes.generateCode(mutationParams)
36
+ },
37
+ })
38
+ }
@@ -87,9 +87,7 @@ export function AccessCodeDetails({
87
87
  <Duration accessCode={accessCode} />
88
88
  </div>
89
89
  </div>
90
-
91
90
  <Alerts alerts={alerts} className='seam-alerts-padded' />
92
-
93
91
  <AccessCodeDevice
94
92
  deviceId={accessCode.device_id}
95
93
  disableLockUnlock={disableLockUnlock}
@@ -56,10 +56,7 @@ function Content(props: {
56
56
  <DeviceImage device={device} />
57
57
  </div>
58
58
  <div className='seam-body'>
59
- <div className='seam-model'>
60
- {device.properties.model.manufacturer_display_name}{' '}
61
- {device.properties.model.display_name}
62
- </div>
59
+ <div>{device.properties.name}</div>
63
60
  <TextButton
64
61
  onClick={() => {
65
62
  onSelectDevice(device.device_id)
@@ -0,0 +1,101 @@
1
+ import { DateTime } from 'luxon'
2
+ import type { ClimateSettingSchedule } from 'seamapi'
3
+
4
+ import { formatDateAndTime } from 'lib/dates.js'
5
+ import { ClimateSettingScheduleIcon } from 'lib/icons/ClimateSettingSchedule.js'
6
+ import { useClimateSettingSchedule } from 'lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.js'
7
+ import { DotDivider } from 'lib/ui/layout/DotDivider.js'
8
+ import { ClimateSettingStatus } from 'lib/ui/thermostat/ClimateSettingStatus.js'
9
+ import { useCurrentTime } from 'lib/ui/use-current-time.js'
10
+
11
+ import { ClimateSettingScheduleDeviceBar } from './ClimateSettingScheduleDeviceBar.js'
12
+
13
+ interface ClimateSettingScheduleCardProps {
14
+ climateSettingScheduleId: string
15
+ }
16
+
17
+ export function ClimateSettingScheduleCard({
18
+ climateSettingScheduleId,
19
+ }: ClimateSettingScheduleCardProps): JSX.Element {
20
+ return (
21
+ <div className='seam-climate-setting-schedule-card'>
22
+ <Content climateSettingScheduleId={climateSettingScheduleId} />
23
+ </div>
24
+ )
25
+ }
26
+
27
+ function Content(props: {
28
+ climateSettingScheduleId: string
29
+ }): JSX.Element | null {
30
+ const { climateSettingScheduleId } = props
31
+
32
+ const { climateSettingSchedule } = useClimateSettingSchedule(
33
+ climateSettingScheduleId
34
+ )
35
+
36
+ if (climateSettingSchedule == null) {
37
+ return null
38
+ }
39
+
40
+ const name = climateSettingSchedule.name ?? t.fallbackName
41
+
42
+ return (
43
+ <div className='seam-climate-setting-schedule-content'>
44
+ <div className='seam-climate-setting-schedule-summary-container'>
45
+ <div className='seam-climate-setting-schedule-icon-block'>
46
+ <ClimateSettingScheduleIcon />
47
+ </div>
48
+ <div className='seam-climate-setting-schedule-summary'>
49
+ <h5 className='seam-climate-setting-schedule-heading'>{name}</h5>
50
+ <div className='seam-climate-setting-schedule-subheading'>
51
+ <ClimateSettingStatus climateSetting={climateSettingSchedule} />
52
+ <DotDivider />
53
+ <ClimateSettingScheduleTiming
54
+ climateSettingSchedule={climateSettingSchedule}
55
+ />
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <ClimateSettingScheduleDeviceBar
60
+ deviceId={climateSettingSchedule.device_id}
61
+ />
62
+ </div>
63
+ )
64
+ }
65
+
66
+ function ClimateSettingScheduleTiming(props: {
67
+ climateSettingSchedule: ClimateSettingSchedule
68
+ }): JSX.Element | null {
69
+ const { climateSettingSchedule } = props
70
+
71
+ const currentTime = useCurrentTime()
72
+
73
+ if (currentTime === null) return null
74
+
75
+ const startTime = DateTime.fromISO(climateSettingSchedule.schedule_starts_at)
76
+ const endTime = DateTime.fromISO(climateSettingSchedule.schedule_ends_at)
77
+
78
+ if (currentTime < startTime)
79
+ return (
80
+ <span>
81
+ {t.starts}{' '}
82
+ {formatDateAndTime(climateSettingSchedule.schedule_starts_at)}
83
+ </span>
84
+ )
85
+
86
+ if (startTime <= currentTime && currentTime <= endTime)
87
+ return (
88
+ <span>
89
+ {t.ends} {formatDateAndTime(climateSettingSchedule.schedule_starts_at)}
90
+ </span>
91
+ )
92
+
93
+ return <span>{t.expired}</span>
94
+ }
95
+
96
+ const t = {
97
+ starts: 'Starts',
98
+ ends: 'Ends',
99
+ expired: 'Expired',
100
+ fallbackName: 'Climate Setting Schedule',
101
+ }
@@ -0,0 +1,58 @@
1
+ import { isThermostatDevice, type ThermostatDevice } from 'seamapi'
2
+
3
+ import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
4
+ import { useDevice } from 'lib/seam/devices/use-device.js'
5
+ import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
6
+ import { ClimateSettingStatus } from 'lib/ui/thermostat/ClimateSettingStatus.js'
7
+
8
+ export function ClimateSettingScheduleDeviceBar({
9
+ deviceId,
10
+ }: {
11
+ deviceId: string
12
+ }): JSX.Element | null {
13
+ const { isLoading, device } = useDevice({
14
+ device_id: deviceId,
15
+ })
16
+
17
+ if (isLoading) {
18
+ return null
19
+ }
20
+
21
+ if (device == null) {
22
+ return null
23
+ }
24
+
25
+ if (!isThermostatDevice(device)) {
26
+ return null
27
+ }
28
+
29
+ return <Content device={device} />
30
+ }
31
+
32
+ function Content(props: { device: ThermostatDevice }): JSX.Element {
33
+ const { device } = props
34
+
35
+ return (
36
+ <div className='seam-climate-setting-schedule-device-bar'>
37
+ <div className='seam-climate-setting-schedule-device-content'>
38
+ <div className='seam-device-image'>
39
+ <DeviceImage device={device} />
40
+ </div>
41
+ <div className='seam-climate-setting-schedule-device-details'>
42
+ <div className='seam-device-name'>{device.properties.name}</div>
43
+ <div className='seam-device-current-climate-setting'>
44
+ {t.currentClimate}:
45
+ <ClimateSettingStatus
46
+ climateSetting={device.properties.current_climate_setting}
47
+ />
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <ChevronRightIcon />
52
+ </div>
53
+ )
54
+ }
55
+
56
+ const t = {
57
+ currentClimate: 'Current climate',
58
+ }