@seamapi/react 0.17.0 → 0.19.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 (73) hide show
  1. package/README.md +23 -0
  2. package/lib/seam/access-codes/use-access-code.d.ts +3 -6
  3. package/lib/seam/access-codes/use-access-code.js +4 -19
  4. package/lib/seam/access-codes/use-access-code.js.map +1 -1
  5. package/lib/seam/access-codes/use-access-codes.d.ts +1 -5
  6. package/lib/seam/access-codes/use-access-codes.js +2 -1
  7. package/lib/seam/access-codes/use-access-codes.js.map +1 -1
  8. package/lib/seam/devices/use-device.d.ts +2 -2
  9. package/lib/seam/devices/use-device.js.map +1 -1
  10. package/lib/seam/devices/use-devices.js +2 -1
  11. package/lib/seam/devices/use-devices.js.map +1 -1
  12. package/lib/sort-by.d.ts +5 -0
  13. package/lib/sort-by.js +9 -0
  14. package/lib/sort-by.js.map +1 -0
  15. package/lib/ui/AccessCodeDetails/AccessCodeDetails.d.ts +4 -2
  16. package/lib/ui/AccessCodeDetails/AccessCodeDetails.js +11 -10
  17. package/lib/ui/AccessCodeDetails/AccessCodeDetails.js.map +1 -1
  18. package/lib/ui/AccessCodeDetails/AccessCodeDevice.d.ts +4 -2
  19. package/lib/ui/AccessCodeDetails/AccessCodeDevice.js +3 -6
  20. package/lib/ui/AccessCodeDetails/AccessCodeDevice.js.map +1 -1
  21. package/lib/ui/AccessCodeTable/AccessCodeTable.d.ts +2 -1
  22. package/lib/ui/AccessCodeTable/AccessCodeTable.js +15 -10
  23. package/lib/ui/AccessCodeTable/AccessCodeTable.js.map +1 -1
  24. package/lib/ui/AccessCodeTable/AccessCodeTableContent.d.ts +1 -0
  25. package/lib/ui/AccessCodeTable/AccessCodeTableContent.js +2 -2
  26. package/lib/ui/AccessCodeTable/AccessCodeTableContent.js.map +1 -1
  27. package/lib/ui/Button.d.ts +1 -1
  28. package/lib/ui/DeviceDetails/DeviceDetails.d.ts +3 -1
  29. package/lib/ui/DeviceDetails/DeviceDetails.js +12 -14
  30. package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
  31. package/lib/ui/DeviceDetails/DeviceModel.js +1 -1
  32. package/lib/ui/DeviceDetails/DeviceModel.js.map +1 -1
  33. package/lib/ui/DeviceTable/DeviceTable.d.ts +1 -1
  34. package/lib/ui/DeviceTable/DeviceTable.js +18 -8
  35. package/lib/ui/DeviceTable/DeviceTable.js.map +1 -1
  36. package/lib/ui/Table/TableCell.d.ts +1 -1
  37. package/lib/ui/Table/TableCell.js +2 -2
  38. package/lib/ui/Table/TableCell.js.map +1 -1
  39. package/lib/ui/TextField/SearchTextField.d.ts +1 -1
  40. package/lib/ui/TextField/SearchTextField.js +2 -2
  41. package/lib/ui/TextField/SearchTextField.js.map +1 -1
  42. package/lib/ui/device/BatteryStatus.d.ts +1 -1
  43. package/lib/ui/layout/ContentHeader.d.ts +1 -0
  44. package/lib/ui/layout/ContentHeader.js +3 -5
  45. package/lib/ui/layout/ContentHeader.js.map +1 -1
  46. package/package.json +2 -5
  47. package/src/lib/seam/access-codes/use-access-code.ts +18 -29
  48. package/src/lib/seam/access-codes/use-access-codes.ts +8 -10
  49. package/src/lib/seam/devices/use-device.ts +4 -1
  50. package/src/lib/seam/devices/use-devices.ts +2 -4
  51. package/src/lib/sort-by.ts +11 -0
  52. package/src/lib/ui/AccessCodeDetails/AccessCodeDetails.tsx +28 -18
  53. package/src/lib/ui/AccessCodeDetails/AccessCodeDevice.tsx +11 -6
  54. package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +29 -14
  55. package/src/lib/ui/AccessCodeTable/AccessCodeTableContent.tsx +4 -7
  56. package/src/lib/ui/Button.tsx +1 -1
  57. package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +22 -18
  58. package/src/lib/ui/DeviceDetails/DeviceModel.tsx +1 -1
  59. package/src/lib/ui/DeviceTable/DeviceTable.tsx +39 -10
  60. package/src/lib/ui/Table/TableCell.tsx +2 -4
  61. package/src/lib/ui/TextField/SearchTextField.tsx +2 -2
  62. package/src/lib/ui/device/BatteryStatus.tsx +2 -2
  63. package/src/lib/ui/device/LockStatus.tsx +1 -1
  64. package/src/lib/ui/device/OnlineStatus.tsx +1 -1
  65. package/src/lib/ui/layout/ContentHeader.tsx +7 -7
  66. package/lib/NavigationProvider.d.ts +0 -27
  67. package/lib/NavigationProvider.js +0 -36
  68. package/lib/NavigationProvider.js.map +0 -1
  69. package/lib/NavigationView.d.ts +0 -5
  70. package/lib/NavigationView.js +0 -25
  71. package/lib/NavigationView.js.map +0 -1
  72. package/src/lib/NavigationProvider.tsx +0 -86
  73. package/src/lib/NavigationView.tsx +0 -32
@@ -1,4 +1,6 @@
1
- import { useNavigation } from 'lib/NavigationProvider.js'
1
+ import { useState } from 'react'
2
+ import type { CommonDeviceProperties, Device } from 'seamapi'
3
+
2
4
  import { isLockDevice } from 'lib/seam/devices/types.js'
3
5
  import {
4
6
  useDevices,
@@ -9,6 +11,7 @@ import { BatteryStatus } from 'lib/ui/device/BatteryStatus.js'
9
11
  import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
10
12
  import { LockStatus } from 'lib/ui/device/LockStatus.js'
11
13
  import { OnlineStatus } from 'lib/ui/device/OnlineStatus.js'
14
+ import { DeviceDetails } from 'lib/ui/DeviceDetails/DeviceDetails.js'
12
15
  import { getDeviceModel } from 'lib/ui/DeviceDetails/DeviceModel.js'
13
16
  import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
14
17
  import { TableBody } from 'lib/ui/Table/TableBody.js'
@@ -25,19 +28,43 @@ interface Props {
25
28
  onBack?: () => void
26
29
  }
27
30
 
28
- export function DeviceTable({ onBack, ...props }: DeviceTableProps) {
31
+ export function DeviceTable({
32
+ onBack,
33
+ ...props
34
+ }: DeviceTableProps): JSX.Element | null {
29
35
  const { devices, isLoading, isError, error } = useDevices(props)
30
- const { show } = useNavigation()
31
36
 
32
- if (isLoading) return <p>...</p>
33
- if (isError) return <p>{error?.message}</p>
34
- if (devices == null) return null
37
+ const [selectedDevice, selectDevice] =
38
+ useState<Device<CommonDeviceProperties> | null>(null)
39
+
40
+ if (selectedDevice != null) {
41
+ return (
42
+ <DeviceDetails
43
+ device={selectedDevice}
44
+ onBack={() => {
45
+ selectDevice(null)
46
+ }}
47
+ />
48
+ )
49
+ }
50
+
51
+ if (isLoading) {
52
+ return <p>...</p>
53
+ }
54
+
55
+ if (isError) {
56
+ return <p>{error?.message}</p>
57
+ }
58
+
59
+ if (devices == null) {
60
+ return null
61
+ }
35
62
 
36
63
  const deviceCount = devices.length
37
64
 
38
65
  return (
39
66
  <div className='seam-device-table'>
40
- <ContentHeader />
67
+ <ContentHeader onBack={onBack} />
41
68
  <TableHeader>
42
69
  <TableTitle>
43
70
  {t.devices} <Caption>({deviceCount})</Caption>
@@ -49,7 +76,7 @@ export function DeviceTable({ onBack, ...props }: DeviceTableProps) {
49
76
  device={device}
50
77
  key={device.device_id}
51
78
  onClick={() => {
52
- show({ name: 'device_detail', deviceId: device.device_id })
79
+ selectDevice(device)
53
80
  }}
54
81
  />
55
82
  ))}
@@ -61,10 +88,12 @@ export function DeviceTable({ onBack, ...props }: DeviceTableProps) {
61
88
  function DeviceRow(props: {
62
89
  device: UseDevicesData[number]
63
90
  onClick: () => void
64
- }) {
91
+ }): JSX.Element | null {
65
92
  const { device, onClick } = props
66
93
 
67
- if (!isLockDevice(device)) return null
94
+ if (!isLockDevice(device)) {
95
+ return null
96
+ }
68
97
 
69
98
  const deviceModel = getDeviceModel(device) ?? t.unknownLock
70
99
 
@@ -2,8 +2,6 @@ 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): JSX.Element {
6
- return (
7
- <div className={classNames('seam-table-cell', className)} {...otherProps} />
8
- )
5
+ export function TableCell({ className, ...props }: DivProps): JSX.Element {
6
+ return <div className={classNames('seam-table-cell', className)} {...props} />
9
7
  }
@@ -4,11 +4,11 @@ import { TextField, type TextFieldProps } from 'lib/ui/TextField/TextField.js'
4
4
 
5
5
  export function SearchTextField({
6
6
  className,
7
- ...otherProps
7
+ ...props
8
8
  }: TextFieldProps): JSX.Element {
9
9
  return (
10
10
  <TextField
11
- {...otherProps}
11
+ {...props}
12
12
  className={classNames(className, 'seam-search-text-field')}
13
13
  />
14
14
  )
@@ -9,7 +9,7 @@ export interface BatteryStatusProps {
9
9
  device: LockDevice
10
10
  }
11
11
 
12
- export function BatteryStatus(props: BatteryStatusProps) {
12
+ export function BatteryStatus(props: BatteryStatusProps): JSX.Element {
13
13
  const {
14
14
  device: {
15
15
  properties: { battery_level: batteryLevel },
@@ -23,7 +23,7 @@ export function BatteryStatus(props: BatteryStatusProps) {
23
23
  )
24
24
  }
25
25
 
26
- function Content(props: { batteryLevel?: number }) {
26
+ function Content(props: { batteryLevel?: number }): JSX.Element | null {
27
27
  const { batteryLevel } = props
28
28
 
29
29
  if (batteryLevel == null) {
@@ -21,7 +21,7 @@ export function LockStatus(props: LockStatusProps): JSX.Element {
21
21
  )
22
22
  }
23
23
 
24
- function Content(props: { isLocked: boolean }) {
24
+ function Content(props: { isLocked: boolean }): JSX.Element {
25
25
  const { isLocked } = props
26
26
  if (isLocked) {
27
27
  return (
@@ -21,7 +21,7 @@ export function OnlineStatus(props: OnlineStatusProps): JSX.Element {
21
21
  )
22
22
  }
23
23
 
24
- function Content(props: { isOnline: boolean }) {
24
+ function Content(props: { isOnline: boolean }): JSX.Element {
25
25
  const { isOnline } = props
26
26
  if (isOnline) {
27
27
  return (
@@ -1,17 +1,17 @@
1
1
  import { ArrowBackIcon } from 'lib/icons/ArrowBack.js'
2
- import { useNavigation } from 'lib/NavigationProvider.js'
3
2
 
4
- export function ContentHeader(props: { title?: string }): JSX.Element | null {
5
- const { title } = props
6
-
7
- const { goBack } = useNavigation()
8
- if (!title && !goBack) {
3
+ export function ContentHeader(props: {
4
+ title?: string
5
+ onBack?: () => void
6
+ }): JSX.Element | null {
7
+ const { title, onBack } = props
8
+ if (title == null && onBack == null) {
9
9
  return null
10
10
  }
11
11
 
12
12
  return (
13
13
  <div className='seam-content-header'>
14
- {goBack && <BackIcon onClick={goBack} />}
14
+ <BackIcon onClick={onBack} />
15
15
  <span className='seam-title'>{title}</span>
16
16
  </div>
17
17
  )
@@ -1,27 +0,0 @@
1
- interface DeviceTableView {
2
- name: 'device_table';
3
- }
4
- interface DeviceDetailView {
5
- name: 'device_detail';
6
- deviceId: string;
7
- }
8
- interface AccessCodeTableView {
9
- name: 'access_code_table';
10
- deviceId: string;
11
- }
12
- interface AccessCodeDetailView {
13
- name: 'access_code_detail';
14
- accessCodeId: string;
15
- }
16
- export type View = DeviceTableView | DeviceDetailView | AccessCodeTableView | AccessCodeDetailView;
17
- export interface NavigationStackProps {
18
- children: JSX.Element;
19
- }
20
- interface NavigationContextProps {
21
- views: View[];
22
- show: (view: View) => void;
23
- goBack?: () => void;
24
- }
25
- export default function NavigationProvider({ children }: NavigationStackProps): import("react/jsx-runtime").JSX.Element;
26
- export declare function useNavigation(): NavigationContextProps;
27
- export {};
@@ -1,36 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useState } from 'react';
3
- const NavigationContext = React.createContext(undefined);
4
- export default function NavigationProvider({ children }) {
5
- const [views, setViews] = useState([]);
6
- const pushView = (view) => {
7
- setViews((current) => [view, ...current]);
8
- };
9
- const popView = () => {
10
- setViews((current) => {
11
- if (current.length === 0) {
12
- return current;
13
- }
14
- const [_showing, ...others] = current;
15
- return others;
16
- });
17
- };
18
- const hasViews = views.length > 0;
19
- return (_jsx(NavigationContext.Provider, { value: {
20
- views,
21
- show: pushView,
22
- goBack: hasViews ? popView : undefined,
23
- }, children: children }));
24
- }
25
- export function useNavigation() {
26
- const context = React.useContext(NavigationContext);
27
- if (context === undefined) {
28
- return {
29
- show: () => { },
30
- goBack: undefined,
31
- views: [],
32
- };
33
- }
34
- return context;
35
- }
36
- //# sourceMappingURL=NavigationProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavigationProvider.js","sourceRoot":"","sources":["../src/lib/NavigationProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAqCvC,MAAM,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAE3C,SAAS,CAAC,CAAA;AAEZ,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,QAAQ,EAAwB;IAC3E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAA;IAE9C,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAE,EAAE;QAC9B,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAA;IAC3C,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE;YACnB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;gBACxB,OAAO,OAAO,CAAA;aACf;YAED,MAAM,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,GAAG,OAAO,CAAA;YACrC,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAEjC,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IACzB,KAAK,EAAE;YACL,KAAK;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SACvC,YAEA,QAAQ,GACkB,CAC9B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAA;IACnD,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,OAAO;YACL,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,EAAE;SACV,CAAA;KACF;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -1,5 +0,0 @@
1
- interface NavigationViewProps {
2
- children: JSX.Element;
3
- }
4
- export declare function NavigationView({ children: rootView }: NavigationViewProps): JSX.Element;
5
- export {};
@@ -1,25 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { AccessCodeTable, DeviceDetails, DeviceTable } from '../lib/index.js';
3
- import { useNavigation } from '../lib/NavigationProvider.js';
4
- import AccessCodeDetails from '../lib/ui/AccessCodeDetails/AccessCodeDetails.js';
5
- export function NavigationView({ children: rootView }) {
6
- const { views } = useNavigation();
7
- const firstView = views[0];
8
- if (firstView != null) {
9
- return _jsx(Subview, { view: firstView });
10
- }
11
- return rootView;
12
- }
13
- function Subview({ view }) {
14
- switch (view.name) {
15
- case 'device_detail':
16
- return _jsx(DeviceDetails, { deviceId: view.deviceId });
17
- case 'access_code_detail':
18
- return _jsx(AccessCodeDetails, { accessCodeId: view.accessCodeId });
19
- case 'device_table':
20
- return _jsx(DeviceTable, {});
21
- case 'access_code_table':
22
- return _jsx(AccessCodeTable, { deviceId: view.deviceId });
23
- }
24
- }
25
- //# sourceMappingURL=NavigationView.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NavigationView.js","sourceRoot":"","sources":["../src/lib/NavigationView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1E,OAAO,EAAE,aAAa,EAAa,MAAM,2BAA2B,CAAA;AACpE,OAAO,iBAAiB,MAAM,+CAA+C,CAAA;AAM7E,MAAM,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAuB;IACxE,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,EAAE,CAAA;IAEjC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,SAAS,IAAI,IAAI,EAAE;QACrB,OAAO,KAAC,OAAO,IAAC,IAAI,EAAE,SAAS,GAAI,CAAA;KACpC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,OAAO,CAAC,EAAE,IAAI,EAAkB;IACvC,QAAQ,IAAI,CAAC,IAAI,EAAE;QACjB,KAAK,eAAe;YAClB,OAAO,KAAC,aAAa,IAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,GAAI,CAAA;QACnD,KAAK,oBAAoB;YACvB,OAAO,KAAC,iBAAiB,IAAC,YAAY,EAAE,IAAI,CAAC,YAAY,GAAI,CAAA;QAC/D,KAAK,cAAc;YACjB,OAAO,KAAC,WAAW,KAAG,CAAA;QACxB,KAAK,mBAAmB;YACtB,OAAO,KAAC,eAAe,IAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,GAAI,CAAA;KACtD;AACH,CAAC"}
@@ -1,86 +0,0 @@
1
- import React, { useState } from 'react'
2
-
3
- interface DeviceTableView {
4
- name: 'device_table'
5
- }
6
-
7
- interface DeviceDetailView {
8
- name: 'device_detail'
9
- deviceId: string
10
- }
11
-
12
- interface AccessCodeTableView {
13
- name: 'access_code_table'
14
- deviceId: string
15
- }
16
-
17
- interface AccessCodeDetailView {
18
- name: 'access_code_detail'
19
- accessCodeId: string
20
- }
21
-
22
- export type View =
23
- | DeviceTableView
24
- | DeviceDetailView
25
- | AccessCodeTableView
26
- | AccessCodeDetailView
27
-
28
- export interface NavigationStackProps {
29
- children: JSX.Element
30
- }
31
-
32
- interface NavigationContextProps {
33
- views: View[]
34
- show: (view: View) => void
35
- goBack?: () => void
36
- }
37
-
38
- const NavigationContext = React.createContext<
39
- NavigationContextProps | undefined
40
- >(undefined)
41
-
42
- export default function NavigationProvider({ children }: NavigationStackProps) {
43
- const [views, setViews] = useState<View[]>([])
44
-
45
- const pushView = (view: View) => {
46
- setViews((current) => [view, ...current])
47
- }
48
-
49
- const popView = () => {
50
- setViews((current) => {
51
- if (current.length === 0) {
52
- return current
53
- }
54
-
55
- const [_showing, ...others] = current
56
- return others
57
- })
58
- }
59
-
60
- const hasViews = views.length > 0
61
-
62
- return (
63
- <NavigationContext.Provider
64
- value={{
65
- views,
66
- show: pushView,
67
- goBack: hasViews ? popView : undefined,
68
- }}
69
- >
70
- {children}
71
- </NavigationContext.Provider>
72
- )
73
- }
74
-
75
- export function useNavigation(): NavigationContextProps {
76
- const context = React.useContext(NavigationContext)
77
- if (context === undefined) {
78
- return {
79
- show: () => {},
80
- goBack: undefined,
81
- views: [],
82
- }
83
- }
84
-
85
- return context
86
- }
@@ -1,32 +0,0 @@
1
- import { AccessCodeTable, DeviceDetails, DeviceTable } from 'lib/index.js'
2
-
3
- import { useNavigation, type View } from 'lib/NavigationProvider.js'
4
- import AccessCodeDetails from 'lib/ui/AccessCodeDetails/AccessCodeDetails.js'
5
-
6
- interface NavigationViewProps {
7
- children: JSX.Element
8
- }
9
-
10
- export function NavigationView({ children: rootView }: NavigationViewProps) {
11
- const { views } = useNavigation()
12
-
13
- const firstView = views[0]
14
- if (firstView != null) {
15
- return <Subview view={firstView} />
16
- }
17
-
18
- return rootView
19
- }
20
-
21
- function Subview({ view }: { view: View }) {
22
- switch (view.name) {
23
- case 'device_detail':
24
- return <DeviceDetails deviceId={view.deviceId} />
25
- case 'access_code_detail':
26
- return <AccessCodeDetails accessCodeId={view.accessCodeId} />
27
- case 'device_table':
28
- return <DeviceTable />
29
- case 'access_code_table':
30
- return <AccessCodeTable deviceId={view.deviceId} />
31
- }
32
- }