@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.
Files changed (90) hide show
  1. package/README.md +5 -4
  2. package/index.css +20 -0
  3. package/index.css.map +1 -1
  4. package/index.min.css +1 -1
  5. package/index.min.css.map +1 -1
  6. package/lib/copy-to-clipboard.d.ts +1 -0
  7. package/lib/copy-to-clipboard.js +4 -0
  8. package/lib/copy-to-clipboard.js.map +1 -0
  9. package/lib/ui/AccessCodeTable/AccessCodeTable.js +4 -4
  10. package/lib/ui/AccessCodeTable/AccessCodeTable.js.map +1 -1
  11. package/lib/ui/AccessCodeTable/CodeDetails.js +3 -1
  12. package/lib/ui/AccessCodeTable/CodeDetails.js.map +1 -1
  13. package/lib/ui/Alert/Alert.d.ts +6 -4
  14. package/lib/ui/Alert/Alert.js +7 -4
  15. package/lib/ui/Alert/Alert.js.map +1 -1
  16. package/lib/ui/Alert/Alerts.d.ts +4 -4
  17. package/lib/ui/Alert/Alerts.js +4 -2
  18. package/lib/ui/Alert/Alerts.js.map +1 -1
  19. package/lib/ui/DeviceDetails/DeviceDetails.js +2 -3
  20. package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
  21. package/lib/ui/DeviceTable/DeviceRow.d.ts +2 -2
  22. package/lib/ui/DeviceTable/DeviceRow.js +1 -2
  23. package/lib/ui/DeviceTable/DeviceRow.js.map +1 -1
  24. package/lib/ui/Menu/Menu.d.ts +9 -10
  25. package/lib/ui/Menu/Menu.js +23 -21
  26. package/lib/ui/Menu/Menu.js.map +1 -1
  27. package/lib/ui/Menu/MenuItem.d.ts +4 -4
  28. package/lib/ui/Menu/MenuItem.js +1 -1
  29. package/lib/ui/Menu/MenuItem.js.map +1 -1
  30. package/lib/ui/Menu/MoreActionsMenu.d.ts +5 -4
  31. package/lib/ui/Menu/MoreActionsMenu.js +6 -6
  32. package/lib/ui/Menu/MoreActionsMenu.js.map +1 -1
  33. package/lib/ui/SupportedDevices/SupportedDeviceRow.d.ts +1 -1
  34. package/lib/ui/SupportedDevices/SupportedDeviceRow.js +8 -14
  35. package/lib/ui/SupportedDevices/SupportedDeviceRow.js.map +1 -1
  36. package/lib/ui/SupportedDevices/SupportedDevices.js +2 -2
  37. package/lib/ui/SupportedDevices/SupportedDevices.js.map +1 -1
  38. package/lib/ui/SupportedDevices/SupportedDevicesHeader.d.ts +1 -1
  39. package/lib/ui/SupportedDevices/SupportedDevicesHeader.js +1 -1
  40. package/lib/ui/SupportedDevices/SupportedDevicesHeader.js.map +1 -1
  41. package/lib/ui/Table/TableFilterBar/TableFilterBar.d.ts +3 -2
  42. package/lib/ui/Table/TableFilterBar/TableFilterBar.js +1 -1
  43. package/lib/ui/Table/TableFilterBar/TableFilterBar.js.map +1 -1
  44. package/lib/ui/Table/TableFilterBar/TableFilterItem.d.ts +2 -1
  45. package/lib/ui/Table/TableFilterBar/TableFilterItem.js +1 -1
  46. package/lib/ui/Table/TableFilterBar/TableFilterItem.js.map +1 -1
  47. package/lib/ui/TextField/TextField.d.ts +1 -1
  48. package/lib/ui/TextField/TextField.js +2 -2
  49. package/lib/ui/TextField/TextField.js.map +1 -1
  50. package/lib/ui/device/BatteryStatus.d.ts +2 -1
  51. package/lib/ui/device/LockStatus.d.ts +2 -1
  52. package/lib/ui/device/OnlineStatus.d.ts +2 -1
  53. package/lib/ui/types.d.ts +1 -0
  54. package/lib/ui/typography/Title.d.ts +2 -2
  55. package/lib/ui/typography/Title.js +3 -2
  56. package/lib/ui/typography/Title.js.map +1 -1
  57. package/lib/use-toggle.d.ts +1 -2
  58. package/lib/use-toggle.js +1 -2
  59. package/lib/use-toggle.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/lib/copy-to-clipboard.ts +3 -0
  62. package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +5 -5
  63. package/src/lib/ui/AccessCodeTable/CodeDetails.tsx +6 -1
  64. package/src/lib/ui/Alert/Alert.tsx +21 -18
  65. package/src/lib/ui/Alert/Alerts.tsx +7 -5
  66. package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +3 -6
  67. package/src/lib/ui/DeviceTable/DeviceRow.tsx +5 -5
  68. package/src/lib/ui/Menu/Menu.tsx +34 -34
  69. package/src/lib/ui/Menu/MenuItem.tsx +6 -4
  70. package/src/lib/ui/Menu/MoreActionsMenu.tsx +15 -10
  71. package/src/lib/ui/SupportedDevices/SupportedDeviceRow.tsx +9 -20
  72. package/src/lib/ui/SupportedDevices/SupportedDevices.tsx +2 -2
  73. package/src/lib/ui/SupportedDevices/SupportedDevicesHeader.tsx +1 -1
  74. package/src/lib/ui/Table/TableFilterBar/TableFilterBar.tsx +5 -3
  75. package/src/lib/ui/Table/TableFilterBar/TableFilterItem.tsx +2 -2
  76. package/src/lib/ui/TextField/TextField.tsx +2 -2
  77. package/src/lib/ui/device/BatteryStatus.tsx +1 -1
  78. package/src/lib/ui/device/LockStatus.tsx +1 -1
  79. package/src/lib/ui/device/OnlineStatus.tsx +1 -1
  80. package/src/lib/ui/types.ts +1 -0
  81. package/src/lib/ui/typography/Title.tsx +13 -3
  82. package/src/lib/use-toggle.ts +3 -3
  83. package/src/styles/_access-code-table.scss +11 -0
  84. package/src/styles/_device-table.scss +5 -0
  85. package/src/styles/_supported-devices.scss +0 -1
  86. package/src/styles/_typography.scss +11 -0
  87. package/lib/copy.d.ts +0 -1
  88. package/lib/copy.js +0 -4
  89. package/lib/copy.js.map +0 -1
  90. 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 { type AlertProps } from 'lib/ui/Alert/Alert.js'
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
- type UseDevicesData,
4
- type UseDevicesParams,
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
- export interface DeviceRowProps {
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'>
@@ -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
- button: (props: {
18
- open: (event: React.MouseEvent<HTMLElement>) => void
19
- }) => React.ReactElement
20
- BackgroundProps?: Partial<{
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 MenuContextProps {
26
+ interface MenuContextValue {
26
27
  close: () => void
27
28
  }
28
29
 
29
- const MenuContext = createContext<MenuContextProps | undefined>(undefined)
30
+ const menuContext = createContext<MenuContextValue>({
31
+ close: () => {},
32
+ })
30
33
 
31
- const Menu = ({
34
+ export function Menu({
32
35
  verticalOffset = 5,
33
36
  horizontalOffset = 0,
34
37
  edgeOffset = 5,
35
38
  children,
36
- button,
37
- BackgroundProps,
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 = document.querySelectorAll('.seam-components')
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 open = (event: React.MouseEvent<HTMLElement>) => {
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, we'll need to set it relative
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, we'll position it to be
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
- window.addEventListener('scroll', setPositions)
112
- window.addEventListener('resize', setPositions)
113
+ globalThis?.addEventListener('scroll', setPositions)
114
+ globalThis?.addEventListener('resize', setPositions)
113
115
  return () => {
114
- window.removeEventListener('scroll', setPositions)
115
- window.removeEventListener('resize', setPositions)
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
- <MenuContext.Provider
130
+ <Provider
128
131
  value={{
129
132
  close: handleClose,
130
133
  }}
131
134
  >
132
- {button({ open })}
135
+ {renderButton({ onOpen: handleOpen })}
133
136
  {createPortal(
134
137
  <div
135
- className={classNames('seam-menu-bg', BackgroundProps?.className)}
138
+ className={classNames('seam-menu-bg', backgroundProps?.className)}
136
139
  style={{
137
140
  display: visible ? 'flex' : 'none',
138
141
  }}
139
- onClick={(e) => {
140
- e.stopPropagation()
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
- </MenuContext.Provider>
169
+ </Provider>
167
170
  )
168
171
  }
169
172
 
170
173
  export function useMenu() {
171
- const context = useContext(MenuContext)
172
- if (context === undefined) {
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 { ReactNode } from 'react'
1
+ import type { PropsWithChildren } from 'react'
2
2
 
3
3
  import { useMenu } from 'lib/ui/Menu/Menu.js'
4
4
 
5
- export interface MenuItemProps {
6
- children: ReactNode
5
+ interface MenuItemProps {
7
6
  onClick: () => void
8
7
  }
9
8
 
10
- export function MenuItem({ children, onClick }: MenuItemProps) {
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, { type MenuProps } from 'lib/ui/Menu/Menu.js'
5
+ import { Menu, type MenuProps } from 'lib/ui/Menu/Menu.js'
4
6
 
5
- export interface MoreActionsMenuProps {
6
- children: JSX.Element | JSX.Element[]
7
- MenuProps?: Partial<MenuProps>
7
+ interface MoreActionsMenuProps {
8
+ menuProps?: Partial<MenuProps>
8
9
  }
9
- export function MoreActionsMenu({ children, MenuProps }: MoreActionsMenuProps) {
10
+
11
+ export function MoreActionsMenu({
12
+ children,
13
+ menuProps,
14
+ }: PropsWithChildren<MoreActionsMenuProps>) {
10
15
  return (
11
16
  <Menu
12
- button={({ open }) => (
17
+ renderButton={({ onOpen }) => (
13
18
  <IconButton
14
- onClick={(e) => {
15
- e.stopPropagation()
16
- open(e)
19
+ onClick={(event) => {
20
+ event.stopPropagation()
21
+ onOpen(event)
17
22
  }}
18
23
  >
19
24
  <DotsEllipsisMoreIcon />
20
25
  </IconButton>
21
26
  )}
22
- {...MenuProps}
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 default function SupportedDeviceRow({
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<{
@@ -1,4 +1,4 @@
1
- export default function SupportedDevicesHeader() {
1
+ export function SupportedDevicesHeader() {
2
2
  return (
3
3
  <thead>
4
4
  <tr>
@@ -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
- export interface TableFiltersProps extends DivProps {
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
- }: TableFiltersProps) {
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 && <ClearFiltersButton onClick={onFilterClear} />}
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
- export interface TableFilterItemProps extends DivProps {
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 !== undefined,
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
- (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
25
- setter(e.currentTarget.value)
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
- export interface BatteryStatusProps {
8
+ interface BatteryStatusProps {
9
9
  device: LockDevice
10
10
  }
11
11
 
@@ -3,7 +3,7 @@ import type { LockDevice } from 'seamapi'
3
3
  import { LockLockedIcon } from 'lib/icons/LockLocked.js'
4
4
  import { LockUnlockedIcon } from 'lib/icons/LockUnlocked.js'
5
5
 
6
- export interface LockStatusProps {
6
+ interface LockStatusProps {
7
7
  device: LockDevice
8
8
  }
9
9
 
@@ -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 interface OnlineStatusProps {
6
+ interface OnlineStatusProps {
7
7
  device: LockDevice
8
8
  }
9
9
 
@@ -2,3 +2,4 @@ import type { HTMLAttributes, HtmlHTMLAttributes } from 'react'
2
2
 
3
3
  export type DivProps = HTMLAttributes<HTMLDivElement>
4
4
  export type ButtonProps = HtmlHTMLAttributes<HTMLButtonElement>
5
+ export type SpanProps = HtmlHTMLAttributes<HTMLSpanElement>
@@ -1,5 +1,15 @@
1
- import type { PropsWithChildren } from 'react'
1
+ import classNames from 'classnames'
2
2
 
3
- export function Title({ children }: PropsWithChildren): JSX.Element {
4
- return <span className='seam-title'>{children}</span>
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
  }
@@ -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 = (initialState: boolean = false): [boolean, () => void] => {
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;
@@ -21,6 +21,11 @@
21
21
  justify-content: center;
22
22
  align-items: flex-start;
23
23
  gap: 2px;
24
+ overflow: hidden;
25
+
26
+ .seam-title {
27
+ max-width: 380px;
28
+ }
24
29
 
25
30
  .seam-bottom {
26
31
  display: flex;
@@ -55,7 +55,6 @@ $row-padding: 8px;
55
55
  }
56
56
  }
57
57
 
58
- // stylelint-disable-next-line no-descending-specificity
59
58
  tr {
60
59
  th:first-of-type,
61
60
  td:first-of-type {
@@ -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
@@ -1,4 +0,0 @@
1
- export async function copy(value) {
2
- await window.navigator.clipboard.writeText(value);
3
- }
4
- //# sourceMappingURL=copy.js.map
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
@@ -1,3 +0,0 @@
1
- export async function copy(value: string) {
2
- await window.navigator.clipboard.writeText(value)
3
- }