@seamapi/react 0.12.0 → 0.14.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 (56) hide show
  1. package/README.md +23 -2
  2. package/lib/SeamProvider.js +1 -1
  3. package/lib/SeamProvider.js.map +1 -1
  4. package/lib/icons/index.d.ts +2 -13
  5. package/lib/icons/index.js +1 -13
  6. package/lib/icons/index.js.map +1 -1
  7. package/lib/ui/AccessCodeTable/CodeDetails.js +7 -4
  8. package/lib/ui/AccessCodeTable/CodeDetails.js.map +1 -1
  9. package/lib/ui/DeviceDetails/BatteryStatus.js +9 -12
  10. package/lib/ui/DeviceDetails/BatteryStatus.js.map +1 -1
  11. package/lib/ui/DeviceDetails/DeviceDetails.js +3 -3
  12. package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
  13. package/lib/ui/DeviceDetails/DeviceImage.js +2 -2
  14. package/lib/ui/DeviceDetails/DeviceImage.js.map +1 -1
  15. package/lib/ui/DeviceDetails/ModelStatus.js +2 -4
  16. package/lib/ui/DeviceDetails/ModelStatus.js.map +1 -1
  17. package/lib/ui/Table/TableBody.d.ts +2 -4
  18. package/lib/ui/Table/TableBody.js +2 -2
  19. package/lib/ui/Table/TableBody.js.map +1 -1
  20. package/lib/ui/Table/TableHeader.d.ts +2 -4
  21. package/lib/ui/Table/TableHeader.js +2 -2
  22. package/lib/ui/Table/TableHeader.js.map +1 -1
  23. package/lib/ui/Table/TableTitle.d.ts +2 -4
  24. package/lib/ui/Table/TableTitle.js +2 -2
  25. package/lib/ui/Table/TableTitle.js.map +1 -1
  26. package/lib/ui/TextField/SearchTextField.js.map +1 -1
  27. package/lib/ui/layout/ContentHeader.js +1 -1
  28. package/lib/ui/layout/ContentHeader.js.map +1 -1
  29. package/lib/ui/typography/Caption.d.ts +2 -4
  30. package/lib/ui/typography/Caption.js +2 -2
  31. package/lib/ui/typography/Caption.js.map +1 -1
  32. package/lib/ui/typography/Title.d.ts +2 -4
  33. package/lib/ui/typography/Title.js +2 -2
  34. package/lib/ui/typography/Title.js.map +1 -1
  35. package/package.json +4 -6
  36. package/src/lib/SeamProvider.tsx +2 -2
  37. package/src/lib/icons/index.ts +1 -13
  38. package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +1 -1
  39. package/src/lib/ui/AccessCodeTable/CodeDetails.tsx +14 -7
  40. package/src/lib/ui/DeviceDetails/BatteryStatus.tsx +14 -14
  41. package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +7 -5
  42. package/src/lib/ui/DeviceDetails/DeviceImage.tsx +5 -5
  43. package/src/lib/ui/DeviceDetails/ModelStatus.tsx +3 -5
  44. package/src/lib/ui/DeviceDetails/OnlineStatus.tsx +2 -2
  45. package/src/lib/ui/IconButton.tsx +1 -1
  46. package/src/lib/ui/Table/TableBody.tsx +3 -3
  47. package/src/lib/ui/Table/TableCell.tsx +1 -1
  48. package/src/lib/ui/Table/TableHeader.tsx +3 -3
  49. package/src/lib/ui/Table/TableRow.tsx +1 -1
  50. package/src/lib/ui/Table/TableTitle.tsx +3 -3
  51. package/src/lib/ui/TextField/SearchTextField.tsx +4 -1
  52. package/src/lib/ui/TextField/TextField.tsx +1 -1
  53. package/src/lib/ui/layout/ContentHeader.tsx +3 -3
  54. package/src/lib/ui/layout/DotDivider.tsx +1 -1
  55. package/src/lib/ui/typography/Caption.tsx +3 -3
  56. package/src/lib/ui/typography/Title.tsx +3 -3
package/README.md CHANGED
@@ -34,10 +34,10 @@ $ npm install @seamapi/react
34
34
  3. Drop in Seam components.
35
35
 
36
36
  ```ts
37
- import { SeamProvider, DeviceManager } from '@seamapi/react'
38
-
39
37
  import '@seamapi/react/index.css'
40
38
 
39
+ import { SeamProvider, DeviceManager } from '@seamapi/react'
40
+
41
41
  export const App = () => {
42
42
  return (
43
43
  <SeamProvider publishableKey='your_publishable_key'>
@@ -66,6 +66,27 @@ Load the font from Google Fonts by placing the following in the `<head>` tag:
66
66
 
67
67
  [Source Sans Pro]: https://fonts.google.com/specimen/Source+Sans+Pro
68
68
 
69
+ ### Content Security Policy (CSP)
70
+
71
+ By self hosting the recommended fonts (or choosing not to use them),
72
+ and proxying the Seam endpoint, the components are compatible with the strictest CSP:
73
+
74
+ ```
75
+ default-src 'self'
76
+ ```
77
+
78
+ When using the default endpoint:
79
+
80
+ ```
81
+ default-src 'self'; connect-src https://connect.getseam.com
82
+ ```
83
+
84
+ When serving the fonts from Google Fonts:
85
+
86
+ ```
87
+ default-src 'self'; font-src 'self' https://fonts.gstatic.com; style-src 'self' https://fonts.googleapis.com
88
+ ```
89
+
69
90
  ## Development and Testing
70
91
 
71
92
  ### Quickstart
@@ -52,7 +52,7 @@ const defaultSeamContextValue = createDefaultSeamContextValue();
52
52
  export const seamContext = createContext(defaultSeamContextValue);
53
53
  export function useSeamContext() {
54
54
  const context = useContext(seamContext);
55
- if (context === undefined) {
55
+ if (context == null) {
56
56
  throw new Error('useSeamContext must be used inside a <SeamProvider/>');
57
57
  }
58
58
  return context;
@@ -1 +1 @@
1
- {"version":3,"file":"SeamProvider.js","sourceRoot":"","sources":["../src/lib/SeamProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SeamProvider.js","sourceRoot":"","sources":["../src/lib/SeamProvider.tsx"],"names":[],"mappings":"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"}
@@ -1,13 +1,2 @@
1
- export { AccessCodeKeyIcon } from './AccessCodeKey.js';
2
- export { ArrowBackIcon } from './ArrowBack.js';
3
- export { BatteryLevelCriticalIcon } from './BatteryLevelCritical.js';
4
- export { BatteryLevelFullIcon } from './BatteryLevelFull.js';
5
- export { BatteryLevelHighIcon } from './BatteryLevelHigh.js';
6
- export { BatteryLevelLowIcon } from './BatteryLevelLow.js';
7
- export { BatteryLevelWiredIcon } from './BatteryLevelWired.js';
8
- export { ChevronRightIcon } from './ChevronRight.js';
9
- export { DotsEllipsisMoreIcon } from './DotsEllipsisMore.js';
10
- export { OnlineStatusAccountOfflineIcon } from './OnlineStatusAccountOffline.js';
11
- export { OnlineStatusDeviceOfflineIcon } from './OnlineStatusDeviceOffline.js';
12
- export { OnlineStatusOnlineIcon } from './OnlineStatusOnline.js';
13
- export { SeamIcon } from './Seam.js';
1
+ declare const _default: null;
2
+ export default _default;
@@ -1,14 +1,2 @@
1
- export { AccessCodeKeyIcon } from './AccessCodeKey.js';
2
- export { ArrowBackIcon } from './ArrowBack.js';
3
- export { BatteryLevelCriticalIcon } from './BatteryLevelCritical.js';
4
- export { BatteryLevelFullIcon } from './BatteryLevelFull.js';
5
- export { BatteryLevelHighIcon } from './BatteryLevelHigh.js';
6
- export { BatteryLevelLowIcon } from './BatteryLevelLow.js';
7
- export { BatteryLevelWiredIcon } from './BatteryLevelWired.js';
8
- export { ChevronRightIcon } from './ChevronRight.js';
9
- export { DotsEllipsisMoreIcon } from './DotsEllipsisMore.js';
10
- export { OnlineStatusAccountOfflineIcon } from './OnlineStatusAccountOffline.js';
11
- export { OnlineStatusDeviceOfflineIcon } from './OnlineStatusDeviceOffline.js';
12
- export { OnlineStatusOnlineIcon } from './OnlineStatusOnline.js';
13
- export { SeamIcon } from './Seam.js';
1
+ export default null;
14
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/icons/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/icons/index.ts"],"names":[],"mappings":"AAAA,eAAe,IAAI,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import dayjs from 'dayjs';
2
+ import { DateTime } from 'luxon';
3
3
  import { DotDivider } from '../../../lib/ui/layout/DotDivider.js';
4
4
  export function CodeDetails(props) {
5
5
  const { accessCode } = props;
@@ -8,21 +8,24 @@ export function CodeDetails(props) {
8
8
  function Duration(props) {
9
9
  const { accessCode } = props;
10
10
  if (accessCode.type === 'ongoing') {
11
- return _jsxs("span", { children: [t.ends, ": Never"] });
11
+ return (_jsxs("span", { children: [t.ends, ": ", t.never] }));
12
12
  }
13
13
  const hasStarted = new Date(accessCode.starts_at).valueOf() < Date.now();
14
14
  if (hasStarted) {
15
15
  return (_jsxs("span", { children: [t.ends, ": ", formatDate(accessCode.ends_at), ' '] }));
16
16
  }
17
- // is in future
18
17
  return (_jsxs("span", { children: [t.starts, ": ", formatDate(accessCode.starts_at)] }));
19
18
  }
20
19
  function formatDate(date) {
21
- return dayjs(date).format('MMM D');
20
+ return DateTime.fromISO(date).toLocaleString({
21
+ month: 'long',
22
+ day: 'numeric',
23
+ });
22
24
  }
23
25
  const t = {
24
26
  code: 'Code',
25
27
  starts: 'Starts',
26
28
  ends: 'Ends',
29
+ never: 'Never',
27
30
  };
28
31
  //# sourceMappingURL=CodeDetails.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/AccessCodeTable/CodeDetails.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAExD,MAAM,UAAU,WAAW,CAAC,KAAiC;IAC3D,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAE5B,OAAO,CACL,eAAK,SAAS,EAAC,0BAA0B,yBAEvC,KAAC,UAAU,KAAG,EACd,KAAC,QAAQ,IAAC,UAAU,EAAE,UAAU,GAAI,EACpC,KAAC,UAAU,KAAG,EACb,CAAC,CAAC,IAAI,QAAI,UAAU,CAAC,IAAI,IACtB,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAiC;IACjD,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC5B,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;QACjC,OAAO,2BAAO,CAAC,CAAC,IAAI,eAAe,CAAA;KACpC;IAED,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxE,IAAI,UAAU,EAAE;QACd,OAAO,CACL,2BACG,CAAC,CAAC,IAAI,QAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IACzC,CACR,CAAA;KACF;IAED,eAAe;IACf,OAAO,CACL,2BACG,CAAC,CAAC,MAAM,QAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IACxC,CACR,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,CAAC,GAAG;IACR,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;CACb,CAAA"}
1
+ {"version":3,"file":"CodeDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/AccessCodeTable/CodeDetails.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAExD,MAAM,UAAU,WAAW,CAAC,KAAiC;IAC3D,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAE5B,OAAO,CACL,eAAK,SAAS,EAAC,0BAA0B,yBAEvC,KAAC,UAAU,KAAG,EACd,KAAC,QAAQ,IAAC,UAAU,EAAE,UAAU,GAAI,EACpC,KAAC,UAAU,KAAG,EACb,CAAC,CAAC,IAAI,QAAI,UAAU,CAAC,IAAI,IACtB,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAiC;IACjD,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;IAC5B,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;QACjC,OAAO,CACL,2BACG,CAAC,CAAC,IAAI,QAAI,CAAC,CAAC,KAAK,IACb,CACR,CAAA;KACF;IAED,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxE,IAAI,UAAU,EAAE;QACd,OAAO,CACL,2BACG,CAAC,CAAC,IAAI,QAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IACzC,CACR,CAAA;KACF;IAED,OAAO,CACL,2BACG,CAAC,CAAC,MAAM,QAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IACxC,CACR,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC;QAC3C,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;KACf,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,GAAG;IACR,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;CACf,CAAA"}
@@ -3,34 +3,31 @@ import { BatteryLevelCriticalIcon } from '../../../lib/icons/BatteryLevelCritica
3
3
  import { BatteryLevelFullIcon } from '../../../lib/icons/BatteryLevelFull.js';
4
4
  import { BatteryLevelHighIcon } from '../../../lib/icons/BatteryLevelHigh.js';
5
5
  import { BatteryLevelLowIcon } from '../../../lib/icons/BatteryLevelLow.js';
6
- /**
7
- * Thresholds to determine the battery status
8
- */
9
- const BATTERY_LEVEL = {
10
- FULL: 0.85,
11
- HIGH: 0.6,
12
- LOW: 0.3,
13
- };
14
6
  export function BatteryStatus(props) {
15
7
  const { device: { properties: { battery_level: batteryLevel }, }, } = props;
16
- if (batteryLevel === undefined) {
8
+ if (batteryLevel == null) {
17
9
  return null;
18
10
  }
19
11
  return (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'seam-label', children: [t.power, ":"] }), ' ', _jsx("div", { className: 'seam-battery-status', children: _jsx(Status, { batteryLevel: batteryLevel }) })] }));
20
12
  }
21
13
  function Status(props) {
22
14
  const { batteryLevel } = props;
23
- if (batteryLevel > BATTERY_LEVEL.FULL) {
15
+ if (batteryLevel > batteryThreshold.full) {
24
16
  return (_jsxs(_Fragment, { children: [_jsx(BatteryLevelFullIcon, {}), _jsx("span", { className: 'seam-status-text', children: t.full })] }));
25
17
  }
26
- if (batteryLevel > BATTERY_LEVEL.HIGH) {
18
+ if (batteryLevel > batteryThreshold.high) {
27
19
  return (_jsxs(_Fragment, { children: [_jsx(BatteryLevelHighIcon, {}), _jsx("span", { className: 'seam-status-text', children: t.high })] }));
28
20
  }
29
- if (batteryLevel > BATTERY_LEVEL.LOW) {
21
+ if (batteryLevel > batteryThreshold.low) {
30
22
  return (_jsxs(_Fragment, { children: [_jsx(BatteryLevelLowIcon, {}), _jsx("span", { className: 'seam-status-text', children: t.low })] }));
31
23
  }
32
24
  return (_jsxs(_Fragment, { children: [_jsx(BatteryLevelCriticalIcon, {}), _jsx("span", { className: 'seam-text-danger', children: t.critical })] }));
33
25
  }
26
+ const batteryThreshold = {
27
+ full: 0.85,
28
+ high: 0.6,
29
+ low: 0.3,
30
+ };
34
31
  const t = {
35
32
  power: 'Power',
36
33
  full: 'Good',
@@ -1 +1 @@
1
- {"version":3,"file":"BatteryStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/BatteryStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAElE;;GAEG;AACH,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG;IACT,GAAG,EAAE,GAAG;CACT,CAAA;AACD,MAAM,UAAU,aAAa,CAAC,KAA6B;IACzD,MAAM,EACJ,MAAM,EAAE,EACN,UAAU,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,GAC5C,GACF,GAAG,KAAK,CAAA;IAET,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,8BACE,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,cAAK,SAAS,EAAC,qBAAqB,YAClC,KAAC,MAAM,IAAC,YAAY,EAAE,YAAY,GAAI,GAClC,IACL,CACJ,CAAA;AACH,CAAC;AAED,SAAS,MAAM,CAAC,KAA+B;IAC7C,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IAE9B,IAAI,YAAY,GAAG,aAAa,CAAC,IAAI,EAAE;QACrC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,aAAa,CAAC,IAAI,EAAE;QACrC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,aAAa,CAAC,GAAG,EAAE;QACpC,OAAO,CACL,8BACE,KAAC,mBAAmB,KAAG,EACvB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,GAAG,GAAQ,IAChD,CACJ,CAAA;KACF;IAED,OAAO,CACL,8BACE,KAAC,wBAAwB,KAAG,EAC5B,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,QAAQ,GAAQ,IACrD,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,MAAM;CACjB,CAAA"}
1
+ {"version":3,"file":"BatteryStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/BatteryStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAElE,MAAM,UAAU,aAAa,CAAC,KAE7B;IACC,MAAM,EACJ,MAAM,EAAE,EACN,UAAU,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,GAC5C,GACF,GAAG,KAAK,CAAA;IAET,IAAI,YAAY,IAAI,IAAI,EAAE;QACxB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,8BACE,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,cAAK,SAAS,EAAC,qBAAqB,YAClC,KAAC,MAAM,IAAC,YAAY,EAAE,YAAY,GAAI,GAClC,IACL,CACJ,CAAA;AACH,CAAC;AAED,SAAS,MAAM,CAAC,KAA+B;IAC7C,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IAE9B,IAAI,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE;QACxC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE;QACxC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,gBAAgB,CAAC,GAAG,EAAE;QACvC,OAAO,CACL,8BACE,KAAC,mBAAmB,KAAG,EACvB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,GAAG,GAAQ,IAChD,CACJ,CAAA;KACF;IAED,OAAO,CACL,8BACE,KAAC,wBAAwB,KAAG,EAC5B,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,QAAQ,GAAQ,IACrD,CACJ,CAAA;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG;IACT,GAAG,EAAE,GAAG;CACT,CAAA;AAED,MAAM,CAAC,GAAG;IACR,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,MAAM;CACjB,CAAA"}
@@ -11,7 +11,7 @@ import useToggle from '../../../lib/use-toggle.js';
11
11
  export function DeviceDetails(props) {
12
12
  const { device } = props;
13
13
  const lockStatus = device.properties.locked ? t.locked : t.unlocked;
14
- const accessCodeLength = device.properties?.schlage_metadata?.access_code_length ?? null;
14
+ const accessCodeLength = device.properties?.schlage_metadata?.access_code_length;
15
15
  // TODO : Fetch access codes
16
16
  const accessCodes = [];
17
17
  const [showingAccessCodes, toggleAccessCodes] = useToggle();
@@ -22,7 +22,7 @@ export function DeviceDetails(props) {
22
22
  }
23
23
  function AccessCodeLength(props) {
24
24
  const { accessCodeLength } = props;
25
- if (accessCodeLength === null) {
25
+ if (accessCodeLength == null) {
26
26
  return null;
27
27
  }
28
28
  return (_jsxs("div", { className: 'seam-content seam-access-code-length', children: [_jsx("span", { className: 'seam-label', children: t.codeLength }), _jsxs("span", { className: 'seam-value', children: [accessCodeLength, " ", t.digits] })] }));
@@ -33,6 +33,6 @@ const t = {
33
33
  accessCodes: 'access codes',
34
34
  codeLength: 'Code length',
35
35
  digits: 'digits',
36
- lockStatus: 'lockStatus',
36
+ lockStatus: 'Lock status',
37
37
  };
38
38
  //# sourceMappingURL=DeviceDetails.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- const FALLBACK_IMAGE_URL = 'https://connect.getseam.com/assets/images/devices/unknown-lock.png';
3
2
  export function DeviceImage(props) {
4
3
  const { device } = props;
5
- const url = device.properties.image_url ?? FALLBACK_IMAGE_URL;
4
+ const url = device.properties.image_url ?? fallbackImageUrl;
6
5
  return _jsx("img", { src: url, alt: device.properties.name });
7
6
  }
7
+ const fallbackImageUrl = 'https://connect.getseam.com/assets/images/devices/unknown-lock.png';
8
8
  //# sourceMappingURL=DeviceImage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceImage.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceImage.tsx"],"names":[],"mappings":";AAEA,MAAM,kBAAkB,GACtB,oEAAoE,CAAA;AAEtE,MAAM,UAAU,WAAW,CAAC,KAA6B;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAExB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,kBAAkB,CAAA;IAE7D,OAAO,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,GAAI,CAAA;AACvD,CAAC"}
1
+ {"version":3,"file":"DeviceImage.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceImage.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,WAAW,CAAC,KAA6B;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAExB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,gBAAgB,CAAA;IAE3D,OAAO,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,GAAI,CAAA;AACvD,CAAC;AAED,MAAM,gBAAgB,GACpB,oEAAoE,CAAA"}
@@ -1,10 +1,8 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  export function ModelStatus(props) {
3
3
  const { device: { properties }, } = props;
4
- const model = properties?.august_metadata?.model ??
5
- properties?.schlage_metadata?.model ??
6
- null;
7
- if (model === null) {
4
+ const model = properties?.august_metadata?.model ?? properties?.schlage_metadata?.model;
5
+ if (model == null) {
8
6
  return null;
9
7
  }
10
8
  return (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'seam-label', children: [t.model, ":"] }), ' ', _jsx("div", { className: 'seam-device-model', children: model })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"ModelStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/ModelStatus.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,WAAW,CAAC,KAA6B;IACvD,MAAM,EACJ,MAAM,EAAE,EAAE,UAAU,EAAE,GACvB,GAAG,KAAK,CAAA;IAET,MAAM,KAAK,GACT,UAAU,EAAE,eAAe,EAAE,KAAK;QAClC,UAAU,EAAE,gBAAgB,EAAE,KAAK;QACnC,IAAI,CAAA;IAEN,IAAI,KAAK,KAAK,IAAI,EAAE;QAClB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,8BACE,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,cAAK,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAO,IAC/C,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,KAAK,EAAE,OAAO;CACf,CAAA"}
1
+ {"version":3,"file":"ModelStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/ModelStatus.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,WAAW,CAAC,KAA6B;IACvD,MAAM,EACJ,MAAM,EAAE,EAAE,UAAU,EAAE,GACvB,GAAG,KAAK,CAAA;IAET,MAAM,KAAK,GACT,UAAU,EAAE,eAAe,EAAE,KAAK,IAAI,UAAU,EAAE,gBAAgB,EAAE,KAAK,CAAA;IAE3E,IAAI,KAAK,IAAI,IAAI,EAAE;QACjB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,8BACE,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,cAAK,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAO,IAC/C,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,KAAK,EAAE,OAAO;CACf,CAAA"}
@@ -1,4 +1,2 @@
1
- import type { ReactNode } from 'react';
2
- export declare function TableBody(props: {
3
- children: ReactNode;
4
- }): JSX.Element;
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare function TableBody({ children }: PropsWithChildren): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function TableBody(props) {
3
- return _jsx("div", { className: 'seam-table-body', children: props.children });
2
+ export function TableBody({ children }) {
3
+ return _jsx("div", { className: 'seam-table-body', children: children });
4
4
  }
5
5
  //# sourceMappingURL=TableBody.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableBody.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableBody.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,SAAS,CAAC,KAA8B;IACtD,OAAO,cAAK,SAAS,EAAC,iBAAiB,YAAE,KAAK,CAAC,QAAQ,GAAO,CAAA;AAChE,CAAC"}
1
+ {"version":3,"file":"TableBody.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableBody.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAqB;IACvD,OAAO,cAAK,SAAS,EAAC,iBAAiB,YAAE,QAAQ,GAAO,CAAA;AAC1D,CAAC"}
@@ -1,4 +1,2 @@
1
- import type { ReactNode } from 'react';
2
- export declare function TableHeader(props: {
3
- children: ReactNode;
4
- }): JSX.Element;
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare function TableHeader({ children }: PropsWithChildren): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function TableHeader(props) {
3
- return _jsx("div", { className: 'seam-table-header', children: props.children });
2
+ export function TableHeader({ children }) {
3
+ return _jsx("div", { className: 'seam-table-header', children: children });
4
4
  }
5
5
  //# sourceMappingURL=TableHeader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableHeader.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,WAAW,CAAC,KAA8B;IACxD,OAAO,cAAK,SAAS,EAAC,mBAAmB,YAAE,KAAK,CAAC,QAAQ,GAAO,CAAA;AAClE,CAAC"}
1
+ {"version":3,"file":"TableHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableHeader.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAqB;IACzD,OAAO,cAAK,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAO,CAAA;AAC5D,CAAC"}
@@ -1,4 +1,2 @@
1
- import type { ReactNode } from 'react';
2
- export declare function TableTitle(props: {
3
- children: ReactNode;
4
- }): JSX.Element;
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare function TableTitle({ children }: PropsWithChildren): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function TableTitle(props) {
3
- return _jsx("h5", { className: 'seam-table-title', children: props.children });
2
+ export function TableTitle({ children }) {
3
+ return _jsx("h5", { className: 'seam-table-title', children: children });
4
4
  }
5
5
  //# sourceMappingURL=TableTitle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableTitle.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableTitle.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,UAAU,CAAC,KAA8B;IACvD,OAAO,aAAI,SAAS,EAAC,kBAAkB,YAAE,KAAK,CAAC,QAAQ,GAAM,CAAA;AAC/D,CAAC"}
1
+ {"version":3,"file":"TableTitle.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableTitle.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAqB;IACxD,OAAO,aAAI,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAM,CAAA;AACzD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchTextField.js","sourceRoot":"","sources":["../../../src/lib/ui/TextField/SearchTextField.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAuB,MAAM,2BAA2B,CAAA;AAE1E,MAAM,UAAU,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,UAAU,EAAkB;IAC1E,OAAO,CACL,KAAC,SAAS,OACJ,UAAU,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,wBAAwB,CAAC,GAC1D,CACH,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"SearchTextField.js","sourceRoot":"","sources":["../../../src/lib/ui/TextField/SearchTextField.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAuB,MAAM,2BAA2B,CAAA;AAE1E,MAAM,UAAU,eAAe,CAAC,EAC9B,SAAS,EACT,GAAG,UAAU,EACE;IACf,OAAO,CACL,KAAC,SAAS,OACJ,UAAU,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,wBAAwB,CAAC,GAC1D,CACH,CAAA;AACH,CAAC"}
@@ -4,7 +4,7 @@ export function ContentHeader(props) {
4
4
  return (_jsxs("div", { className: 'seam-content-header', children: [_jsx(BackIcon, { onClick: props.onClickBack }), _jsx("span", { className: 'seam-title', children: props.title })] }));
5
5
  }
6
6
  function BackIcon(props) {
7
- if (props.onClick === undefined) {
7
+ if (props.onClick == null) {
8
8
  return null;
9
9
  }
10
10
  return _jsx(ArrowBackIcon, { className: 'seam-back-icon', onClick: props.onClick });
@@ -1 +1 @@
1
- {"version":3,"file":"ContentHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/ContentHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,UAAU,aAAa,CAAC,KAG7B;IACC,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,EACxC,eAAM,SAAS,EAAC,YAAY,YAAE,KAAK,CAAC,KAAK,GAAQ,IAC7C,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAA+B;IAC/C,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE;QAC/B,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,KAAC,aAAa,IAAC,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAAA;AAC7E,CAAC"}
1
+ {"version":3,"file":"ContentHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/ContentHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,UAAU,aAAa,CAAC,KAG7B;IACC,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,EACxC,eAAM,SAAS,EAAC,YAAY,YAAE,KAAK,CAAC,KAAK,GAAQ,IAC7C,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAA+B;IAC/C,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,KAAC,aAAa,IAAC,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAAA;AAC7E,CAAC"}
@@ -1,4 +1,2 @@
1
- import type { ReactNode } from 'react';
2
- export declare function Caption(props: {
3
- children: ReactNode;
4
- }): JSX.Element;
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare function Caption({ children }: PropsWithChildren): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function Caption(props) {
3
- return _jsx("span", { className: 'seam-caption', children: props.children });
2
+ export function Caption({ children }) {
3
+ return _jsx("span", { className: 'seam-caption', children: children });
4
4
  }
5
5
  //# sourceMappingURL=Caption.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Caption.js","sourceRoot":"","sources":["../../../src/lib/ui/typography/Caption.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,OAAO,CAAC,KAA8B;IACpD,OAAO,eAAM,SAAS,EAAC,cAAc,YAAE,KAAK,CAAC,QAAQ,GAAQ,CAAA;AAC/D,CAAC"}
1
+ {"version":3,"file":"Caption.js","sourceRoot":"","sources":["../../../src/lib/ui/typography/Caption.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAqB;IACrD,OAAO,eAAM,SAAS,EAAC,cAAc,YAAE,QAAQ,GAAQ,CAAA;AACzD,CAAC"}
@@ -1,4 +1,2 @@
1
- import type { ReactNode } from 'react';
2
- export declare function Title(props: {
3
- children: ReactNode;
4
- }): JSX.Element;
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare function Title({ children }: PropsWithChildren): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function Title(props) {
3
- return _jsx("span", { className: 'seam-title', children: props.children });
2
+ export function Title({ children }) {
3
+ return _jsx("span", { className: 'seam-title', children: children });
4
4
  }
5
5
  //# sourceMappingURL=Title.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Title.js","sourceRoot":"","sources":["../../../src/lib/ui/typography/Title.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,KAAK,CAAC,KAA8B;IAClD,OAAO,eAAM,SAAS,EAAC,YAAY,YAAE,KAAK,CAAC,QAAQ,GAAQ,CAAA;AAC7D,CAAC"}
1
+ {"version":3,"file":"Title.js","sourceRoot":"","sources":["../../../src/lib/ui/typography/Title.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAqB;IACnD,OAAO,eAAM,SAAS,EAAC,YAAY,YAAE,QAAQ,GAAQ,CAAA;AACvD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/react",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Seam React component library.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -91,9 +91,9 @@
91
91
  },
92
92
  "dependencies": {
93
93
  "@tanstack/react-query": "^4.28.0",
94
- "seamapi": "^5.19.0-alpha.2",
95
94
  "classnames": "^2.3.2",
96
- "dayjs": "^1.11.7",
95
+ "luxon": "^3.3.0",
96
+ "seamapi": "^5.19.0-alpha.2",
97
97
  "uuid": "^9.0.0"
98
98
  },
99
99
  "devDependencies": {
@@ -115,7 +115,7 @@
115
115
  "@svgr/cli": "^7.0.0",
116
116
  "@testing-library/react": "^14.0.0",
117
117
  "@types/jest": "^29.5.0",
118
- "@types/ms": "^0.7.31",
118
+ "@types/luxon": "^3.3.0",
119
119
  "@types/node": "^18.11.18",
120
120
  "@types/react": "^18.0.33",
121
121
  "@types/react-dom": "^18.0.11",
@@ -134,11 +134,9 @@
134
134
  "eslint-plugin-storybook": "^0.6.11",
135
135
  "eslint-plugin-unused-imports": "^2.0.0",
136
136
  "fast-glob": "^3.2.12",
137
- "get-port": "^6.1.2",
138
137
  "http-proxy-middleware": "^2.0.6",
139
138
  "jest": "^29.5.0",
140
139
  "jest-environment-jsdom": "^29.5.0",
141
- "ms": "^2.1.3",
142
140
  "prettier": "^2.3.0",
143
141
  "prop-types": "^15.8.1",
144
142
  "react": "^18.2.0",
@@ -109,10 +109,10 @@ const defaultSeamContextValue = createDefaultSeamContextValue()
109
109
 
110
110
  export const seamContext = createContext<SeamContext>(defaultSeamContextValue)
111
111
 
112
- export function useSeamContext() {
112
+ export function useSeamContext(): SeamContext {
113
113
  const context = useContext(seamContext)
114
114
 
115
- if (context === undefined) {
115
+ if (context == null) {
116
116
  throw new Error('useSeamContext must be used inside a <SeamProvider/>')
117
117
  }
118
118
 
@@ -1,13 +1 @@
1
- export { AccessCodeKeyIcon } from './AccessCodeKey.js'
2
- export { ArrowBackIcon } from './ArrowBack.js'
3
- export { BatteryLevelCriticalIcon } from './BatteryLevelCritical.js'
4
- export { BatteryLevelFullIcon } from './BatteryLevelFull.js'
5
- export { BatteryLevelHighIcon } from './BatteryLevelHigh.js'
6
- export { BatteryLevelLowIcon } from './BatteryLevelLow.js'
7
- export { BatteryLevelWiredIcon } from './BatteryLevelWired.js'
8
- export { ChevronRightIcon } from './ChevronRight.js'
9
- export { DotsEllipsisMoreIcon } from './DotsEllipsisMore.js'
10
- export { OnlineStatusAccountOfflineIcon } from './OnlineStatusAccountOffline.js'
11
- export { OnlineStatusDeviceOfflineIcon } from './OnlineStatusDeviceOffline.js'
12
- export { OnlineStatusOnlineIcon } from './OnlineStatusOnline.js'
13
- export { SeamIcon } from './Seam.js'
1
+ export default null
@@ -17,7 +17,7 @@ import { Title } from 'lib/ui/typography/Title.js'
17
17
  export function AccessCodeTable(props: {
18
18
  accessCodes: AccessCode[]
19
19
  onClickBack?: () => void
20
- }) {
20
+ }): JSX.Element {
21
21
  const { accessCodes, onClickBack } = props
22
22
 
23
23
  return (
@@ -1,9 +1,9 @@
1
- import dayjs from 'dayjs'
1
+ import { DateTime } from 'luxon'
2
2
  import type { AccessCode } from 'seamapi'
3
3
 
4
4
  import { DotDivider } from 'lib/ui/layout/DotDivider.js'
5
5
 
6
- export function CodeDetails(props: { accessCode: AccessCode }) {
6
+ export function CodeDetails(props: { accessCode: AccessCode }): JSX.Element {
7
7
  const { accessCode } = props
8
8
 
9
9
  return (
@@ -17,10 +17,14 @@ export function CodeDetails(props: { accessCode: AccessCode }) {
17
17
  )
18
18
  }
19
19
 
20
- function Duration(props: { accessCode: AccessCode }) {
20
+ function Duration(props: { accessCode: AccessCode }): JSX.Element {
21
21
  const { accessCode } = props
22
22
  if (accessCode.type === 'ongoing') {
23
- return <span>{t.ends}: Never</span>
23
+ return (
24
+ <span>
25
+ {t.ends}: {t.never}
26
+ </span>
27
+ )
24
28
  }
25
29
 
26
30
  const hasStarted = new Date(accessCode.starts_at).valueOf() < Date.now()
@@ -32,7 +36,6 @@ function Duration(props: { accessCode: AccessCode }) {
32
36
  )
33
37
  }
34
38
 
35
- // is in future
36
39
  return (
37
40
  <span>
38
41
  {t.starts}: {formatDate(accessCode.starts_at)}
@@ -40,12 +43,16 @@ function Duration(props: { accessCode: AccessCode }) {
40
43
  )
41
44
  }
42
45
 
43
- function formatDate(date: string) {
44
- return dayjs(date).format('MMM D')
46
+ function formatDate(date: string): string {
47
+ return DateTime.fromISO(date).toLocaleString({
48
+ month: 'long',
49
+ day: 'numeric',
50
+ })
45
51
  }
46
52
 
47
53
  const t = {
48
54
  code: 'Code',
49
55
  starts: 'Starts',
50
56
  ends: 'Ends',
57
+ never: 'Never',
51
58
  }
@@ -5,22 +5,16 @@ import { BatteryLevelFullIcon } from 'lib/icons/BatteryLevelFull.js'
5
5
  import { BatteryLevelHighIcon } from 'lib/icons/BatteryLevelHigh.js'
6
6
  import { BatteryLevelLowIcon } from 'lib/icons/BatteryLevelLow.js'
7
7
 
8
- /**
9
- * Thresholds to determine the battery status
10
- */
11
- const BATTERY_LEVEL = {
12
- FULL: 0.85,
13
- HIGH: 0.6,
14
- LOW: 0.3,
15
- }
16
- export function BatteryStatus(props: { device: LockDevice }) {
8
+ export function BatteryStatus(props: {
9
+ device: LockDevice
10
+ }): JSX.Element | null {
17
11
  const {
18
12
  device: {
19
13
  properties: { battery_level: batteryLevel },
20
14
  },
21
15
  } = props
22
16
 
23
- if (batteryLevel === undefined) {
17
+ if (batteryLevel == null) {
24
18
  return null
25
19
  }
26
20
 
@@ -34,10 +28,10 @@ export function BatteryStatus(props: { device: LockDevice }) {
34
28
  )
35
29
  }
36
30
 
37
- function Status(props: { batteryLevel: number }) {
31
+ function Status(props: { batteryLevel: number }): JSX.Element {
38
32
  const { batteryLevel } = props
39
33
 
40
- if (batteryLevel > BATTERY_LEVEL.FULL) {
34
+ if (batteryLevel > batteryThreshold.full) {
41
35
  return (
42
36
  <>
43
37
  <BatteryLevelFullIcon />
@@ -46,7 +40,7 @@ function Status(props: { batteryLevel: number }) {
46
40
  )
47
41
  }
48
42
 
49
- if (batteryLevel > BATTERY_LEVEL.HIGH) {
43
+ if (batteryLevel > batteryThreshold.high) {
50
44
  return (
51
45
  <>
52
46
  <BatteryLevelHighIcon />
@@ -55,7 +49,7 @@ function Status(props: { batteryLevel: number }) {
55
49
  )
56
50
  }
57
51
 
58
- if (batteryLevel > BATTERY_LEVEL.LOW) {
52
+ if (batteryLevel > batteryThreshold.low) {
59
53
  return (
60
54
  <>
61
55
  <BatteryLevelLowIcon />
@@ -72,6 +66,12 @@ function Status(props: { batteryLevel: number }) {
72
66
  )
73
67
  }
74
68
 
69
+ const batteryThreshold = {
70
+ full: 0.85,
71
+ high: 0.6,
72
+ low: 0.3,
73
+ }
74
+
75
75
  const t = {
76
76
  power: 'Power',
77
77
  full: 'Good',
@@ -9,13 +9,13 @@ import { OnlineStatus } from 'lib/ui/DeviceDetails/OnlineStatus.js'
9
9
  import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
10
10
  import useToggle from 'lib/use-toggle.js'
11
11
 
12
- export function DeviceDetails(props: { device: LockDevice }) {
12
+ export function DeviceDetails(props: { device: LockDevice }): JSX.Element {
13
13
  const { device } = props
14
14
 
15
15
  const lockStatus = device.properties.locked ? t.locked : t.unlocked
16
16
 
17
17
  const accessCodeLength =
18
- device.properties?.schlage_metadata?.access_code_length ?? null
18
+ device.properties?.schlage_metadata?.access_code_length
19
19
 
20
20
  // TODO : Fetch access codes
21
21
  const accessCodes: AccessCode[] = []
@@ -73,9 +73,11 @@ export function DeviceDetails(props: { device: LockDevice }) {
73
73
  )
74
74
  }
75
75
 
76
- function AccessCodeLength(props: { accessCodeLength: number | null }) {
76
+ function AccessCodeLength(props: {
77
+ accessCodeLength: number | null | undefined
78
+ }): JSX.Element | null {
77
79
  const { accessCodeLength } = props
78
- if (accessCodeLength === null) {
80
+ if (accessCodeLength == null) {
79
81
  return null
80
82
  }
81
83
 
@@ -95,5 +97,5 @@ const t = {
95
97
  accessCodes: 'access codes',
96
98
  codeLength: 'Code length',
97
99
  digits: 'digits',
98
- lockStatus: 'lockStatus',
100
+ lockStatus: 'Lock status',
99
101
  }
@@ -1,12 +1,12 @@
1
1
  import type { LockDevice } from 'seamapi'
2
2
 
3
- const FALLBACK_IMAGE_URL =
4
- 'https://connect.getseam.com/assets/images/devices/unknown-lock.png'
5
-
6
- export function DeviceImage(props: { device: LockDevice }) {
3
+ export function DeviceImage(props: { device: LockDevice }): JSX.Element {
7
4
  const { device } = props
8
5
 
9
- const url = device.properties.image_url ?? FALLBACK_IMAGE_URL
6
+ const url = device.properties.image_url ?? fallbackImageUrl
10
7
 
11
8
  return <img src={url} alt={device.properties.name} />
12
9
  }
10
+
11
+ const fallbackImageUrl =
12
+ 'https://connect.getseam.com/assets/images/devices/unknown-lock.png'
@@ -1,16 +1,14 @@
1
1
  import type { LockDevice } from 'seamapi'
2
2
 
3
- export function ModelStatus(props: { device: LockDevice }) {
3
+ export function ModelStatus(props: { device: LockDevice }): JSX.Element | null {
4
4
  const {
5
5
  device: { properties },
6
6
  } = props
7
7
 
8
8
  const model =
9
- properties?.august_metadata?.model ??
10
- properties?.schlage_metadata?.model ??
11
- null
9
+ properties?.august_metadata?.model ?? properties?.schlage_metadata?.model
12
10
 
13
- if (model === null) {
11
+ if (model == null) {
14
12
  return null
15
13
  }
16
14
 
@@ -3,7 +3,7 @@ import type { LockDevice } from 'seamapi'
3
3
  import { OnlineStatusDeviceOfflineIcon } from 'lib/icons/OnlineStatusDeviceOffline.js'
4
4
  import { OnlineStatusOnlineIcon } from 'lib/icons/OnlineStatusOnline.js'
5
5
 
6
- export function OnlineStatus(props: { device: LockDevice }) {
6
+ export function OnlineStatus(props: { device: LockDevice }): JSX.Element {
7
7
  const { device } = props
8
8
  return (
9
9
  <>
@@ -15,7 +15,7 @@ export function OnlineStatus(props: { device: LockDevice }) {
15
15
  )
16
16
  }
17
17
 
18
- function Status(props: { isOnline: boolean }) {
18
+ function Status(props: { isOnline: boolean }): JSX.Element {
19
19
  const { isOnline } = props
20
20
 
21
21
  if (isOnline) {
@@ -1,5 +1,5 @@
1
1
  import type { ButtonProps } from 'lib/ui/types.js'
2
2
 
3
- export function IconButton(props: ButtonProps) {
3
+ export function IconButton(props: ButtonProps): JSX.Element {
4
4
  return <button {...props} className='seam-button seam-icon-button' />
5
5
  }
@@ -1,5 +1,5 @@
1
- import type { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
- export function TableBody(props: { children: ReactNode }) {
4
- return <div className='seam-table-body'>{props.children}</div>
3
+ export function TableBody({ children }: PropsWithChildren): JSX.Element {
4
+ return <div className='seam-table-body'>{children}</div>
5
5
  }
@@ -2,7 +2,7 @@ import classNames from 'classnames'
2
2
 
3
3
  import type { DivProps } from 'lib/ui/types.js'
4
4
 
5
- export function TableCell({ className, ...otherProps }: DivProps) {
5
+ export function TableCell({ className, ...otherProps }: DivProps): JSX.Element {
6
6
  return (
7
7
  <div className={classNames('seam-table-cell', className)} {...otherProps} />
8
8
  )
@@ -1,5 +1,5 @@
1
- import type { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
- export function TableHeader(props: { children: ReactNode }) {
4
- return <div className='seam-table-header'>{props.children}</div>
3
+ export function TableHeader({ children }: PropsWithChildren): JSX.Element {
4
+ return <div className='seam-table-header'>{children}</div>
5
5
  }
@@ -1,5 +1,5 @@
1
1
  import type { DivProps } from 'lib/ui/types.js'
2
2
 
3
- export function TableRow(props: DivProps) {
3
+ export function TableRow(props: DivProps): JSX.Element {
4
4
  return <div className='seam-table-row'>{props.children}</div>
5
5
  }
@@ -1,5 +1,5 @@
1
- import type { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
- export function TableTitle(props: { children: ReactNode }) {
4
- return <h5 className='seam-table-title'>{props.children}</h5>
3
+ export function TableTitle({ children }: PropsWithChildren): JSX.Element {
4
+ return <h5 className='seam-table-title'>{children}</h5>
5
5
  }
@@ -2,7 +2,10 @@ import classNames from 'classnames'
2
2
 
3
3
  import { TextField, type TextFieldProps } from 'lib/ui/TextField/index.js'
4
4
 
5
- export function SearchTextField({ className, ...otherProps }: TextFieldProps) {
5
+ export function SearchTextField({
6
+ className,
7
+ ...otherProps
8
+ }: TextFieldProps): JSX.Element {
6
9
  return (
7
10
  <TextField
8
11
  {...otherProps}
@@ -6,7 +6,7 @@ export type TextFieldProps = {
6
6
  onChange: (value: string) => void
7
7
  } & Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'>
8
8
 
9
- export function TextField(props: TextFieldProps) {
9
+ export function TextField(props: TextFieldProps): JSX.Element {
10
10
  const { value, onChange, className, ...inputProps } = props
11
11
  return (
12
12
  <input
@@ -3,7 +3,7 @@ import { ArrowBackIcon } from 'lib/icons/ArrowBack.js'
3
3
  export function ContentHeader(props: {
4
4
  title?: string
5
5
  onClickBack?: () => void
6
- }) {
6
+ }): JSX.Element {
7
7
  return (
8
8
  <div className='seam-content-header'>
9
9
  <BackIcon onClick={props.onClickBack} />
@@ -12,8 +12,8 @@ export function ContentHeader(props: {
12
12
  )
13
13
  }
14
14
 
15
- function BackIcon(props: { onClick?: () => void }) {
16
- if (props.onClick === undefined) {
15
+ function BackIcon(props: { onClick?: () => void }): JSX.Element | null {
16
+ if (props.onClick == null) {
17
17
  return null
18
18
  }
19
19
 
@@ -1,3 +1,3 @@
1
- export function DotDivider() {
1
+ export function DotDivider(): JSX.Element {
2
2
  return <span className='seam-dot-divider'>•</span>
3
3
  }
@@ -1,5 +1,5 @@
1
- import type { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
- export function Caption(props: { children: ReactNode }) {
4
- return <span className='seam-caption'>{props.children}</span>
3
+ export function Caption({ children }: PropsWithChildren): JSX.Element {
4
+ return <span className='seam-caption'>{children}</span>
5
5
  }
@@ -1,5 +1,5 @@
1
- import type { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
- export function Title(props: { children: ReactNode }) {
4
- return <span className='seam-title'>{props.children}</span>
3
+ export function Title({ children }: PropsWithChildren): JSX.Element {
4
+ return <span className='seam-title'>{children}</span>
5
5
  }