@seamapi/react 0.25.0 → 0.26.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.
- package/README.md +5 -4
- package/index.css +20 -0
- package/index.css.map +1 -1
- package/index.min.css +1 -1
- package/index.min.css.map +1 -1
- package/lib/copy-to-clipboard.d.ts +1 -0
- package/lib/copy-to-clipboard.js +4 -0
- package/lib/copy-to-clipboard.js.map +1 -0
- package/lib/ui/AccessCodeTable/AccessCodeTable.js +4 -4
- package/lib/ui/AccessCodeTable/AccessCodeTable.js.map +1 -1
- package/lib/ui/AccessCodeTable/CodeDetails.js +3 -1
- package/lib/ui/AccessCodeTable/CodeDetails.js.map +1 -1
- package/lib/ui/Alert/Alert.d.ts +6 -4
- package/lib/ui/Alert/Alert.js +7 -4
- package/lib/ui/Alert/Alert.js.map +1 -1
- package/lib/ui/Alert/Alerts.d.ts +4 -4
- package/lib/ui/Alert/Alerts.js +4 -2
- package/lib/ui/Alert/Alerts.js.map +1 -1
- package/lib/ui/DeviceDetails/DeviceDetails.js +2 -3
- package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
- package/lib/ui/DeviceTable/DeviceRow.d.ts +2 -2
- package/lib/ui/DeviceTable/DeviceRow.js +1 -2
- package/lib/ui/DeviceTable/DeviceRow.js.map +1 -1
- package/lib/ui/Menu/Menu.d.ts +9 -10
- package/lib/ui/Menu/Menu.js +23 -21
- package/lib/ui/Menu/Menu.js.map +1 -1
- package/lib/ui/Menu/MenuItem.d.ts +4 -4
- package/lib/ui/Menu/MenuItem.js +1 -1
- package/lib/ui/Menu/MenuItem.js.map +1 -1
- package/lib/ui/Menu/MoreActionsMenu.d.ts +5 -4
- package/lib/ui/Menu/MoreActionsMenu.js +6 -6
- package/lib/ui/Menu/MoreActionsMenu.js.map +1 -1
- package/lib/ui/SupportedDevices/SupportedDeviceRow.d.ts +1 -1
- package/lib/ui/SupportedDevices/SupportedDeviceRow.js +8 -14
- package/lib/ui/SupportedDevices/SupportedDeviceRow.js.map +1 -1
- package/lib/ui/SupportedDevices/SupportedDevices.js +2 -2
- package/lib/ui/SupportedDevices/SupportedDevices.js.map +1 -1
- package/lib/ui/SupportedDevices/SupportedDevicesHeader.d.ts +1 -1
- package/lib/ui/SupportedDevices/SupportedDevicesHeader.js +1 -1
- package/lib/ui/SupportedDevices/SupportedDevicesHeader.js.map +1 -1
- package/lib/ui/Table/TableFilterBar/TableFilterBar.d.ts +3 -2
- package/lib/ui/Table/TableFilterBar/TableFilterBar.js +1 -1
- package/lib/ui/Table/TableFilterBar/TableFilterBar.js.map +1 -1
- package/lib/ui/Table/TableFilterBar/TableFilterItem.d.ts +2 -1
- package/lib/ui/Table/TableFilterBar/TableFilterItem.js +1 -1
- package/lib/ui/Table/TableFilterBar/TableFilterItem.js.map +1 -1
- package/lib/ui/TextField/TextField.d.ts +1 -1
- package/lib/ui/TextField/TextField.js +2 -2
- package/lib/ui/TextField/TextField.js.map +1 -1
- package/lib/ui/device/BatteryStatus.d.ts +2 -1
- package/lib/ui/device/LockStatus.d.ts +2 -1
- package/lib/ui/device/OnlineStatus.d.ts +2 -1
- package/lib/ui/types.d.ts +1 -0
- package/lib/ui/typography/Title.d.ts +2 -2
- package/lib/ui/typography/Title.js +3 -2
- package/lib/ui/typography/Title.js.map +1 -1
- package/lib/use-toggle.d.ts +1 -2
- package/lib/use-toggle.js +1 -2
- package/lib/use-toggle.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/copy-to-clipboard.ts +3 -0
- package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +5 -5
- package/src/lib/ui/AccessCodeTable/CodeDetails.tsx +6 -1
- package/src/lib/ui/Alert/Alert.tsx +21 -18
- package/src/lib/ui/Alert/Alerts.tsx +7 -5
- package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +3 -6
- package/src/lib/ui/DeviceTable/DeviceRow.tsx +5 -5
- package/src/lib/ui/Menu/Menu.tsx +34 -34
- package/src/lib/ui/Menu/MenuItem.tsx +6 -4
- package/src/lib/ui/Menu/MoreActionsMenu.tsx +15 -10
- package/src/lib/ui/SupportedDevices/SupportedDeviceRow.tsx +9 -20
- package/src/lib/ui/SupportedDevices/SupportedDevices.tsx +2 -2
- package/src/lib/ui/SupportedDevices/SupportedDevicesHeader.tsx +1 -1
- package/src/lib/ui/Table/TableFilterBar/TableFilterBar.tsx +5 -3
- package/src/lib/ui/Table/TableFilterBar/TableFilterItem.tsx +2 -2
- package/src/lib/ui/TextField/TextField.tsx +2 -2
- package/src/lib/ui/device/BatteryStatus.tsx +1 -1
- package/src/lib/ui/device/LockStatus.tsx +1 -1
- package/src/lib/ui/device/OnlineStatus.tsx +1 -1
- package/src/lib/ui/types.ts +1 -0
- package/src/lib/ui/typography/Title.tsx +13 -3
- package/src/lib/use-toggle.ts +3 -3
- package/src/styles/_access-code-table.scss +11 -0
- package/src/styles/_device-table.scss +5 -0
- package/src/styles/_supported-devices.scss +0 -1
- package/src/styles/_typography.scss +11 -0
- package/lib/copy.d.ts +0 -1
- package/lib/copy.js +0 -4
- package/lib/copy.js.map +0 -1
- package/src/lib/copy.ts +0 -3
|
@@ -7,7 +7,7 @@ import { useAccessCodes } from 'lib/seam/access-codes/use-access-codes.js'
|
|
|
7
7
|
import { isLockDevice } from 'lib/seam/devices/types.js'
|
|
8
8
|
import { useToggleLock } from 'lib/seam/devices/use-toggle-lock.js'
|
|
9
9
|
import { AccessCodeTable } from 'lib/ui/AccessCodeTable/AccessCodeTable.js'
|
|
10
|
-
import {
|
|
10
|
+
import type { AlertProps } from 'lib/ui/Alert/Alert.js'
|
|
11
11
|
import { Alerts } from 'lib/ui/Alert/Alerts.js'
|
|
12
12
|
import { Button } from 'lib/ui/Button.js'
|
|
13
13
|
import { BatteryStatus } from 'lib/ui/device/BatteryStatus.js'
|
|
@@ -15,7 +15,7 @@ import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
|
|
|
15
15
|
import { OnlineStatus } from 'lib/ui/device/OnlineStatus.js'
|
|
16
16
|
import { DeviceModel } from 'lib/ui/DeviceDetails/DeviceModel.js'
|
|
17
17
|
import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
|
|
18
|
-
import useToggle from 'lib/use-toggle.js'
|
|
18
|
+
import { useToggle } from 'lib/use-toggle.js'
|
|
19
19
|
|
|
20
20
|
export interface DeviceDetailsProps {
|
|
21
21
|
deviceId: string
|
|
@@ -121,10 +121,7 @@ function LockDeviceDetails(props: { device: LockDevice; onBack?: () => void }) {
|
|
|
121
121
|
</div>
|
|
122
122
|
</div>
|
|
123
123
|
</div>
|
|
124
|
-
|
|
125
|
-
{alerts.length > 0 && (
|
|
126
|
-
<Alerts alerts={alerts} className='seam-alerts-space-top' />
|
|
127
|
-
)}
|
|
124
|
+
<Alerts alerts={alerts} className='seam-alerts-space-top' />
|
|
128
125
|
</div>
|
|
129
126
|
<div className='seam-box'>
|
|
130
127
|
<div
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isLockDevice } from 'lib/seam/devices/types.js'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import type {
|
|
3
|
+
UseDevicesData,
|
|
4
|
+
UseDevicesParams,
|
|
5
5
|
} from 'lib/seam/devices/use-devices.js'
|
|
6
6
|
import { BatteryStatus } from 'lib/ui/device/BatteryStatus.js'
|
|
7
7
|
import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
|
|
@@ -18,7 +18,7 @@ interface Props {
|
|
|
18
18
|
onBack?: () => void
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
interface DeviceRowProps {
|
|
22
22
|
device: UseDevicesData[number]
|
|
23
23
|
onClick: () => void
|
|
24
24
|
}
|
|
@@ -39,7 +39,7 @@ export function DeviceRow({
|
|
|
39
39
|
<DeviceImage device={device} />
|
|
40
40
|
</TableCell>
|
|
41
41
|
<TableCell className='seam-body-cell'>
|
|
42
|
-
<Title>{device.properties.name}</Title>
|
|
42
|
+
<Title className='seam-truncated-text'>{device.properties.name}</Title>
|
|
43
43
|
<div className='seam-bottom'>
|
|
44
44
|
<span className='seam-device-model'>{deviceModel}</span>
|
|
45
45
|
<div className='seam-device-statuses'>
|
package/src/lib/ui/Menu/Menu.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import classNames from 'classnames'
|
|
2
2
|
import {
|
|
3
3
|
createContext,
|
|
4
|
+
type MouseEvent,
|
|
5
|
+
type PropsWithChildren,
|
|
4
6
|
useCallback,
|
|
5
7
|
useContext,
|
|
6
8
|
useEffect,
|
|
@@ -10,32 +12,34 @@ import {
|
|
|
10
12
|
import { createPortal } from 'react-dom'
|
|
11
13
|
|
|
12
14
|
export interface MenuProps {
|
|
13
|
-
children: JSX.Element | JSX.Element[]
|
|
14
15
|
verticalOffset?: number
|
|
15
16
|
horizontalOffset?: number
|
|
16
17
|
edgeOffset?: number
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}) =>
|
|
20
|
-
|
|
18
|
+
renderButton: (props: {
|
|
19
|
+
onOpen: (event: MouseEvent<HTMLElement>) => void
|
|
20
|
+
}) => JSX.Element
|
|
21
|
+
backgroundProps?: Partial<{
|
|
21
22
|
className?: string
|
|
22
23
|
}>
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
interface
|
|
26
|
+
interface MenuContextValue {
|
|
26
27
|
close: () => void
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const menuContext = createContext<MenuContextValue>({
|
|
31
|
+
close: () => {},
|
|
32
|
+
})
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
export function Menu({
|
|
32
35
|
verticalOffset = 5,
|
|
33
36
|
horizontalOffset = 0,
|
|
34
37
|
edgeOffset = 5,
|
|
35
38
|
children,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}: MenuProps)
|
|
39
|
+
renderButton,
|
|
40
|
+
backgroundProps,
|
|
41
|
+
}: PropsWithChildren<MenuProps>) {
|
|
42
|
+
const { Provider } = menuContext
|
|
39
43
|
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
|
|
40
44
|
const [documentEl, setDocumentEl] = useState<null | Element>(null)
|
|
41
45
|
const [contentEl, setContentEl] = useState<HTMLDivElement | null>(null)
|
|
@@ -43,7 +47,9 @@ const Menu = ({
|
|
|
43
47
|
const [left, setLeft] = useState(0)
|
|
44
48
|
|
|
45
49
|
useEffect(() => {
|
|
46
|
-
const containers =
|
|
50
|
+
const containers =
|
|
51
|
+
globalThis?.document?.querySelectorAll('.seam-components')
|
|
52
|
+
if (containers == null) return
|
|
47
53
|
const el = containers[containers.length - 1]
|
|
48
54
|
if (el != null) {
|
|
49
55
|
setDocumentEl(el)
|
|
@@ -54,7 +60,7 @@ const Menu = ({
|
|
|
54
60
|
setAnchorEl(null)
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
const
|
|
63
|
+
const handleOpen = (event: MouseEvent<HTMLElement>) => {
|
|
58
64
|
setAnchorEl(event.currentTarget)
|
|
59
65
|
}
|
|
60
66
|
|
|
@@ -80,16 +86,14 @@ const Menu = ({
|
|
|
80
86
|
const right = left + contentWidth
|
|
81
87
|
const bottom = top + contentHeight
|
|
82
88
|
|
|
83
|
-
// If the content would overflow right,
|
|
84
|
-
// to the right of the container.
|
|
89
|
+
// If the content would overflow right, set it relative to the right of the container.
|
|
85
90
|
const isOverflowingRight = right > containerRight
|
|
86
91
|
const visibleLeft = isOverflowingRight
|
|
87
92
|
? containerRight - contentWidth - horizontalOffset - edgeOffset
|
|
88
93
|
: left
|
|
89
94
|
setLeft(visibleLeft)
|
|
90
95
|
|
|
91
|
-
// If the content would overflow bottom,
|
|
92
|
-
// above the anchor.
|
|
96
|
+
// If the content would overflow bottom, position it above the anchor.
|
|
93
97
|
const isOverFlowingBottom = bottom > containerBottom
|
|
94
98
|
const visibleTop = isOverFlowingBottom
|
|
95
99
|
? anchorTop - contentHeight - verticalOffset
|
|
@@ -104,18 +108,17 @@ const Menu = ({
|
|
|
104
108
|
edgeOffset,
|
|
105
109
|
])
|
|
106
110
|
|
|
107
|
-
const isOpen = Boolean(anchorEl)
|
|
108
|
-
|
|
109
111
|
useLayoutEffect(() => {
|
|
110
112
|
setPositions()
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
globalThis?.addEventListener('scroll', setPositions)
|
|
114
|
+
globalThis?.addEventListener('resize', setPositions)
|
|
113
115
|
return () => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
globalThis?.removeEventListener('scroll', setPositions)
|
|
117
|
+
globalThis?.removeEventListener('resize', setPositions)
|
|
116
118
|
}
|
|
117
119
|
}, [setPositions])
|
|
118
120
|
|
|
121
|
+
const isOpen = anchorEl != null
|
|
119
122
|
const hasSetPosition = top !== 0 && left !== 0
|
|
120
123
|
const visible = isOpen && hasSetPosition
|
|
121
124
|
|
|
@@ -124,20 +127,20 @@ const Menu = ({
|
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
return (
|
|
127
|
-
<
|
|
130
|
+
<Provider
|
|
128
131
|
value={{
|
|
129
132
|
close: handleClose,
|
|
130
133
|
}}
|
|
131
134
|
>
|
|
132
|
-
{
|
|
135
|
+
{renderButton({ onOpen: handleOpen })}
|
|
133
136
|
{createPortal(
|
|
134
137
|
<div
|
|
135
|
-
className={classNames('seam-menu-bg',
|
|
138
|
+
className={classNames('seam-menu-bg', backgroundProps?.className)}
|
|
136
139
|
style={{
|
|
137
140
|
display: visible ? 'flex' : 'none',
|
|
138
141
|
}}
|
|
139
|
-
onClick={(
|
|
140
|
-
|
|
142
|
+
onClick={(event) => {
|
|
143
|
+
event.stopPropagation()
|
|
141
144
|
handleClose()
|
|
142
145
|
}}
|
|
143
146
|
>
|
|
@@ -163,17 +166,14 @@ const Menu = ({
|
|
|
163
166
|
{children}
|
|
164
167
|
</div>
|
|
165
168
|
</div>
|
|
166
|
-
</
|
|
169
|
+
</Provider>
|
|
167
170
|
)
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
export function useMenu() {
|
|
171
|
-
const context = useContext(
|
|
172
|
-
if (context
|
|
174
|
+
const context = useContext(menuContext)
|
|
175
|
+
if (context == null) {
|
|
173
176
|
throw new Error('useMenu must be used within a Menu.')
|
|
174
177
|
}
|
|
175
|
-
|
|
176
178
|
return context
|
|
177
179
|
}
|
|
178
|
-
|
|
179
|
-
export default Menu
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PropsWithChildren } from 'react'
|
|
2
2
|
|
|
3
3
|
import { useMenu } from 'lib/ui/Menu/Menu.js'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
children: ReactNode
|
|
5
|
+
interface MenuItemProps {
|
|
7
6
|
onClick: () => void
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
export function MenuItem({
|
|
9
|
+
export function MenuItem({
|
|
10
|
+
onClick,
|
|
11
|
+
children,
|
|
12
|
+
}: PropsWithChildren<MenuItemProps>) {
|
|
11
13
|
const { close: closeMenu } = useMenu()
|
|
12
14
|
|
|
13
15
|
return (
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
+
import type { PropsWithChildren } from 'react'
|
|
2
|
+
|
|
1
3
|
import { DotsEllipsisMoreIcon } from 'lib/icons/DotsEllipsisMore.js'
|
|
2
4
|
import { IconButton } from 'lib/ui/IconButton.js'
|
|
3
|
-
import Menu,
|
|
5
|
+
import { Menu, type MenuProps } from 'lib/ui/Menu/Menu.js'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
MenuProps?: Partial<MenuProps>
|
|
7
|
+
interface MoreActionsMenuProps {
|
|
8
|
+
menuProps?: Partial<MenuProps>
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
export function MoreActionsMenu({
|
|
12
|
+
children,
|
|
13
|
+
menuProps,
|
|
14
|
+
}: PropsWithChildren<MoreActionsMenuProps>) {
|
|
10
15
|
return (
|
|
11
16
|
<Menu
|
|
12
|
-
|
|
17
|
+
renderButton={({ onOpen }) => (
|
|
13
18
|
<IconButton
|
|
14
|
-
onClick={(
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
onClick={(event) => {
|
|
20
|
+
event.stopPropagation()
|
|
21
|
+
onOpen(event)
|
|
17
22
|
}}
|
|
18
23
|
>
|
|
19
24
|
<DotsEllipsisMoreIcon />
|
|
20
25
|
</IconButton>
|
|
21
26
|
)}
|
|
22
|
-
{...
|
|
27
|
+
{...menuProps}
|
|
23
28
|
>
|
|
24
29
|
{children}
|
|
25
30
|
</Menu>
|
|
@@ -6,22 +6,8 @@ export interface SupportedDeviceRowProps {
|
|
|
6
6
|
deviceModel: DeviceModel
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
deviceModel
|
|
11
|
-
}: SupportedDeviceRowProps) {
|
|
12
|
-
function getColorFromSupportLevel() {
|
|
13
|
-
switch (deviceModel.support_level) {
|
|
14
|
-
case 'Live':
|
|
15
|
-
return 'green'
|
|
16
|
-
case 'Beta':
|
|
17
|
-
return 'blue'
|
|
18
|
-
case 'Unsupported':
|
|
19
|
-
return 'orange'
|
|
20
|
-
default:
|
|
21
|
-
return 'gray'
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
9
|
+
export function SupportedDeviceRow({ deviceModel }: SupportedDeviceRowProps) {
|
|
10
|
+
const statusColor = supportLevelColors[deviceModel.support_level] ?? 'gray'
|
|
25
11
|
return (
|
|
26
12
|
<tr>
|
|
27
13
|
<td>
|
|
@@ -33,10 +19,7 @@ export default function SupportedDeviceRow({
|
|
|
33
19
|
<td>{deviceModel.connection_type}</td>
|
|
34
20
|
<td>
|
|
35
21
|
<div
|
|
36
|
-
className={classNames(
|
|
37
|
-
'seam-status-pill',
|
|
38
|
-
`status-${getColorFromSupportLevel()}`
|
|
39
|
-
)}
|
|
22
|
+
className={classNames('seam-status-pill', `status-${statusColor}`)}
|
|
40
23
|
>
|
|
41
24
|
<span>{deviceModel.support_level}</span>
|
|
42
25
|
</div>
|
|
@@ -44,3 +27,9 @@ export default function SupportedDeviceRow({
|
|
|
44
27
|
</tr>
|
|
45
28
|
)
|
|
46
29
|
}
|
|
30
|
+
|
|
31
|
+
const supportLevelColors = {
|
|
32
|
+
Live: 'green',
|
|
33
|
+
Beta: 'blue',
|
|
34
|
+
Unsupported: 'orange',
|
|
35
|
+
}
|
|
@@ -4,8 +4,8 @@ import axios from 'axios'
|
|
|
4
4
|
import { Button } from 'lib/ui/Button.js'
|
|
5
5
|
import type { DeviceModel } from 'lib/ui/SupportedDevices/types.js'
|
|
6
6
|
|
|
7
|
-
import SupportedDeviceRow from './SupportedDeviceRow.js'
|
|
8
|
-
import SupportedDevicesHeader from './SupportedDevicesHeader.js'
|
|
7
|
+
import { SupportedDeviceRow } from './SupportedDeviceRow.js'
|
|
8
|
+
import { SupportedDevicesHeader } from './SupportedDevicesHeader.js'
|
|
9
9
|
|
|
10
10
|
export function SupportedDevices() {
|
|
11
11
|
const { data, isLoading, isError, refetch } = useQuery<{
|
|
@@ -2,7 +2,7 @@ import { ArrowRestartIcon } from 'lib/icons/ArrowRestart.js'
|
|
|
2
2
|
import { IconButton } from 'lib/ui/IconButton.js'
|
|
3
3
|
import type { ButtonProps, DivProps } from 'lib/ui/types.js'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
interface TableFilterBarProps extends DivProps {
|
|
6
6
|
isFilterCleared?: boolean
|
|
7
7
|
onFilterClear?: () => void
|
|
8
8
|
}
|
|
@@ -12,12 +12,14 @@ export function TableFilterBar({
|
|
|
12
12
|
onFilterClear,
|
|
13
13
|
children,
|
|
14
14
|
...props
|
|
15
|
-
}:
|
|
15
|
+
}: TableFilterBarProps) {
|
|
16
16
|
const showClearFilterButton = isFilterCleared === false
|
|
17
17
|
return (
|
|
18
18
|
<div className='seam-table-filter-bar' {...props}>
|
|
19
19
|
{children}{' '}
|
|
20
|
-
{showClearFilterButton
|
|
20
|
+
{showClearFilterButton ? (
|
|
21
|
+
<ClearFiltersButton onClick={onFilterClear} />
|
|
22
|
+
) : null}
|
|
21
23
|
</div>
|
|
22
24
|
)
|
|
23
25
|
}
|
|
@@ -2,7 +2,7 @@ import classNames from 'classnames'
|
|
|
2
2
|
|
|
3
3
|
import type { DivProps } from 'lib/ui/types.js'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
interface TableFilterItemProps extends DivProps {
|
|
6
6
|
selected?: boolean
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -15,7 +15,7 @@ export function TableFilterItem({
|
|
|
15
15
|
<div
|
|
16
16
|
onClick={onClick}
|
|
17
17
|
className={classNames('seam-table-filter-item', {
|
|
18
|
-
'seam-clickable': onClick
|
|
18
|
+
'seam-clickable': onClick != null,
|
|
19
19
|
'seam-selected': selected,
|
|
20
20
|
})}
|
|
21
21
|
{...props}
|
|
@@ -21,6 +21,6 @@ export function TextField(props: TextFieldProps): JSX.Element {
|
|
|
21
21
|
|
|
22
22
|
export const handleString =
|
|
23
23
|
(setter: (v: string) => void) =>
|
|
24
|
-
(
|
|
25
|
-
setter(
|
|
24
|
+
(event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
|
|
25
|
+
setter(event.currentTarget.value)
|
|
26
26
|
}
|
|
@@ -5,7 +5,7 @@ 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
|
-
|
|
8
|
+
interface BatteryStatusProps {
|
|
9
9
|
device: LockDevice
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -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
|
-
|
|
6
|
+
interface OnlineStatusProps {
|
|
7
7
|
device: LockDevice
|
|
8
8
|
}
|
|
9
9
|
|
package/src/lib/ui/types.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import classNames from 'classnames'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import type { SpanProps } from 'lib/ui/types.js'
|
|
4
|
+
|
|
5
|
+
export function Title({
|
|
6
|
+
children,
|
|
7
|
+
className,
|
|
8
|
+
...props
|
|
9
|
+
}: SpanProps): JSX.Element {
|
|
10
|
+
return (
|
|
11
|
+
<span className={classNames('seam-title', className)} {...props}>
|
|
12
|
+
{children}
|
|
13
|
+
</span>
|
|
14
|
+
)
|
|
5
15
|
}
|
package/src/lib/use-toggle.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { useCallback, useState } from 'react'
|
|
|
3
3
|
/**
|
|
4
4
|
* Simple util to quickly handle on/off states.
|
|
5
5
|
*/
|
|
6
|
-
const useToggle = (
|
|
6
|
+
export const useToggle = (
|
|
7
|
+
initialState: boolean = false
|
|
8
|
+
): [boolean, () => void] => {
|
|
7
9
|
const [isTrue, setIsTrue] = useState(initialState)
|
|
8
10
|
|
|
9
11
|
// use callback otherwise it would yield unexpected results in promises
|
|
@@ -14,5 +16,3 @@ const useToggle = (initialState: boolean = false): [boolean, () => void] => {
|
|
|
14
16
|
|
|
15
17
|
return [isTrue, toggle]
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
export default useToggle
|
|
@@ -26,11 +26,22 @@
|
|
|
26
26
|
justify-content: center;
|
|
27
27
|
align-items: flex-start;
|
|
28
28
|
gap: 2px;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
|
|
31
|
+
.seam-title {
|
|
32
|
+
max-width: 380px;
|
|
33
|
+
}
|
|
29
34
|
|
|
30
35
|
.seam-code-details {
|
|
31
36
|
font-size: 14px;
|
|
32
37
|
line-height: 134%;
|
|
33
38
|
color: colors.$text-gray-1;
|
|
39
|
+
display: flex;
|
|
40
|
+
|
|
41
|
+
.seam-device-name {
|
|
42
|
+
max-width: 190px;
|
|
43
|
+
width: auto;
|
|
44
|
+
}
|
|
34
45
|
|
|
35
46
|
.seam-dot-divider {
|
|
36
47
|
margin: 0 4px;
|
|
@@ -35,10 +35,21 @@
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
@mixin truncated-text {
|
|
39
|
+
.seam-truncated-text {
|
|
40
|
+
display: block;
|
|
41
|
+
width: 100%;
|
|
42
|
+
white-space: nowrap;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
text-overflow: ellipsis;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
38
48
|
@mixin all {
|
|
39
49
|
@include headers;
|
|
40
50
|
@include caption;
|
|
41
51
|
@include danger-text;
|
|
42
52
|
@include font-family;
|
|
43
53
|
@include defaults;
|
|
54
|
+
@include truncated-text;
|
|
44
55
|
}
|
package/lib/copy.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function copy(value: string): Promise<void>;
|
package/lib/copy.js
DELETED
package/lib/copy.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copy.js","sourceRoot":"","sources":["../src/lib/copy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAa;IACtC,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AACnD,CAAC"}
|
package/src/lib/copy.ts
DELETED