@seamapi/react 1.46.4 → 1.48.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 (62) hide show
  1. package/README.md +15 -4
  2. package/dist/elements.js +3624 -3588
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +65 -0
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.min.css +1 -1
  7. package/dist/index.min.css.map +1 -1
  8. package/lib/icons/Info.d.ts +2 -0
  9. package/lib/icons/Info.js +7 -0
  10. package/lib/icons/Info.js.map +1 -0
  11. package/lib/icons/InfoDark.d.ts +2 -0
  12. package/lib/icons/InfoDark.js +7 -0
  13. package/lib/icons/InfoDark.js.map +1 -0
  14. package/lib/seam/components/AccessCodeDetails/AccessCodeDetails.js.map +1 -1
  15. package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js +1 -1
  16. package/lib/seam/components/AccessCodeDetails/AccessCodeDevice.js.map +1 -1
  17. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.d.ts +6 -1
  18. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.js +21 -4
  19. package/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.js.map +1 -1
  20. package/lib/seam/components/DeviceDetails/DeviceModel.js +2 -2
  21. package/lib/seam/components/DeviceDetails/DeviceModel.js.map +1 -1
  22. package/lib/seam/components/DeviceTable/DeviceRow.js +2 -2
  23. package/lib/seam/components/DeviceTable/DeviceRow.js.map +1 -1
  24. package/lib/seam/components/DeviceTable/DeviceTable.js +2 -2
  25. package/lib/seam/components/DeviceTable/DeviceTable.js.map +1 -1
  26. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.d.ts +5 -0
  27. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.js +24 -0
  28. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.js.map +1 -0
  29. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js +1 -0
  30. package/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.js.map +1 -1
  31. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.d.ts +5 -0
  32. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.js +21 -0
  33. package/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.js.map +1 -0
  34. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.d.ts +5 -0
  35. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.js +27 -0
  36. package/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.js.map +1 -0
  37. package/lib/ui/Tooltip/Tooltip.d.ts +2 -0
  38. package/lib/ui/Tooltip/Tooltip.js +33 -0
  39. package/lib/ui/Tooltip/Tooltip.js.map +1 -0
  40. package/lib/ui/thermostat/ClimateSettingStatus.js +10 -3
  41. package/lib/ui/thermostat/ClimateSettingStatus.js.map +1 -1
  42. package/lib/version.d.ts +1 -1
  43. package/lib/version.js +1 -1
  44. package/package.json +4 -4
  45. package/src/lib/icons/Info.tsx +36 -0
  46. package/src/lib/icons/InfoDark.tsx +37 -0
  47. package/src/lib/seam/components/AccessCodeDetails/AccessCodeDetails.tsx +0 -2
  48. package/src/lib/seam/components/AccessCodeDetails/AccessCodeDevice.tsx +1 -1
  49. package/src/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.element.ts +4 -0
  50. package/src/lib/seam/components/ClimateSettingScheduleTable/ClimateSettingScheduleTable.tsx +59 -6
  51. package/src/lib/seam/components/DeviceDetails/DeviceModel.tsx +1 -0
  52. package/src/lib/seam/components/DeviceTable/DeviceRow.tsx +1 -0
  53. package/src/lib/seam/components/DeviceTable/DeviceTable.tsx +2 -2
  54. package/src/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedule.ts +47 -0
  55. package/src/lib/seam/thermostats/climate-setting-schedules/use-climate-setting-schedules.ts +1 -0
  56. package/src/lib/seam/thermostats/climate-setting-schedules/use-create-climate-setting-schedule.ts +48 -0
  57. package/src/lib/seam/thermostats/climate-setting-schedules/use-delete-climate-setting-schedule.ts +53 -0
  58. package/src/lib/ui/Tooltip/Tooltip.tsx +64 -0
  59. package/src/lib/ui/thermostat/ClimateSettingStatus.tsx +12 -10
  60. package/src/lib/version.ts +1 -1
  61. package/src/styles/_main.scss +2 -0
  62. package/src/styles/_tooltip.scss +83 -0
@@ -0,0 +1,53 @@
1
+ import {
2
+ useMutation,
3
+ type UseMutationResult,
4
+ useQueryClient,
5
+ } from '@tanstack/react-query'
6
+ import type {
7
+ ClimateSettingScheduleDeleteRequest,
8
+ ClimateSettingScheduleDeleteResponse,
9
+ SeamError,
10
+ } from 'seamapi'
11
+
12
+ import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js'
13
+
14
+ export type UseDeleteClimateSettingScheduleMutationParams =
15
+ ClimateSettingScheduleDeleteRequest
16
+
17
+ export type UseDeleteClimateSettingScheduleData =
18
+ ClimateSettingScheduleDeleteResponse
19
+
20
+ export function useDeleteClimateSettingSchedule(): UseMutationResult<
21
+ UseDeleteClimateSettingScheduleData,
22
+ SeamError,
23
+ UseDeleteClimateSettingScheduleMutationParams
24
+ > {
25
+ const { client } = useSeamClient()
26
+ const queryClient = useQueryClient()
27
+
28
+ return useMutation<
29
+ UseDeleteClimateSettingScheduleData,
30
+ SeamError,
31
+ ClimateSettingScheduleDeleteRequest
32
+ >({
33
+ mutationFn: async (
34
+ mutationParams: UseDeleteClimateSettingScheduleMutationParams
35
+ ) => {
36
+ if (client === null) throw new NullSeamClientError()
37
+ await client.thermostats.climateSettingSchedules.delete(mutationParams)
38
+ },
39
+ onSuccess: (_data, variables) => {
40
+ void queryClient.invalidateQueries([
41
+ 'thermostats',
42
+ 'climate_setting_schedules',
43
+ 'get',
44
+ { climate_setting_schedule_id: variables.climate_setting_schedule_id },
45
+ ])
46
+ void queryClient.invalidateQueries([
47
+ 'thermostats',
48
+ 'climate_setting_schedules',
49
+ 'list',
50
+ ])
51
+ },
52
+ })
53
+ }
@@ -0,0 +1,64 @@
1
+ import {
2
+ type MouseEventHandler,
3
+ type PropsWithChildren,
4
+ useEffect,
5
+ useState,
6
+ } from 'react'
7
+
8
+ import { InfoIcon } from 'lib/icons/Info.js'
9
+ import { InfoDarkIcon } from 'lib/icons/InfoDark.js'
10
+
11
+ export function Tooltip({ children }: PropsWithChildren): JSX.Element {
12
+ const [isOpen, setIsOpen] = useState(false)
13
+
14
+ useEffect(() => {
15
+ const handleClose = (): void => {
16
+ setIsOpen(false)
17
+ }
18
+
19
+ const handleEscape = (event: KeyboardEvent): void => {
20
+ if (event.key === 'Escape') {
21
+ handleClose()
22
+ }
23
+ }
24
+ if (isOpen) {
25
+ globalThis.document?.addEventListener('click', handleClose)
26
+ globalThis.addEventListener?.('keydown', handleEscape)
27
+ }
28
+
29
+ return () => {
30
+ globalThis.document?.removeEventListener('click', handleClose)
31
+ globalThis.removeEventListener?.('keydown', handleEscape)
32
+ }
33
+ }, [isOpen, setIsOpen])
34
+
35
+ const handleToggle: MouseEventHandler<HTMLButtonElement> = (event): void => {
36
+ event.stopPropagation()
37
+ setIsOpen((prev) => !prev)
38
+ }
39
+
40
+ return (
41
+ <div className='seam-tooltip'>
42
+ <div className='seam-tooltip-trigger-wrap'>
43
+ <button onClick={handleToggle} className='seam-tooltip-button'>
44
+ <div className='seam-tooltip-button-icon seam-tooltip-button-icon-default'>
45
+ <InfoIcon />
46
+ </div>
47
+ <div className='seam-tooltip-button-icon seam-tooltip-button-icon-hover'>
48
+ <InfoDarkIcon />
49
+ </div>
50
+ </button>
51
+ </div>
52
+
53
+ <div
54
+ className='seam-tooltip-popover'
55
+ aria-expanded={isOpen}
56
+ onClick={(event) => {
57
+ event.stopPropagation()
58
+ }}
59
+ >
60
+ <p className='seam-tooltip-text'>{children}</p>
61
+ </div>
62
+ </div>
63
+ )
64
+ }
@@ -23,16 +23,16 @@ export function ClimateSettingStatus({
23
23
  )}
24
24
  <Content
25
25
  mode={climateSetting.hvac_mode_setting}
26
- coolingSetPoint={
26
+ coolingSetPoint={formatTemperatureValue(
27
27
  temperatureUnit === 'fahrenheit'
28
28
  ? climateSetting.cooling_set_point_fahrenheit
29
29
  : climateSetting.cooling_set_point_celsius
30
- }
31
- heatingSetPoint={
30
+ )}
31
+ heatingSetPoint={formatTemperatureValue(
32
32
  temperatureUnit === 'fahrenheit'
33
33
  ? climateSetting.heating_set_point_fahrenheit
34
34
  : climateSetting.heating_set_point_celsius
35
- }
35
+ )}
36
36
  temperatureUnit={temperatureUnit}
37
37
  />
38
38
  {iconPlacement === 'right' && (
@@ -59,12 +59,8 @@ function ClimateSettingIcon(props: {
59
59
 
60
60
  function Content(props: {
61
61
  mode: ClimateSetting['hvac_mode_setting']
62
- coolingSetPoint:
63
- | ClimateSetting['cooling_set_point_fahrenheit']
64
- | ClimateSetting['cooling_set_point_celsius']
65
- heatingSetPoint:
66
- | ClimateSetting['heating_set_point_fahrenheit']
67
- | ClimateSetting['heating_set_point_celsius']
62
+ coolingSetPoint: string
63
+ heatingSetPoint: string
68
64
  temperatureUnit: 'fahrenheit' | 'celsius'
69
65
  }): JSX.Element | null {
70
66
  const { mode, coolingSetPoint, heatingSetPoint, temperatureUnit } = props
@@ -89,6 +85,12 @@ function Content(props: {
89
85
  return null
90
86
  }
91
87
 
88
+ const formatTemperatureValue = (value: number | undefined): string => {
89
+ if (value == null) return '0'
90
+ if (Number.isInteger(value)) return value.toFixed()
91
+ return value.toFixed(1)
92
+ }
93
+
92
94
  const t = {
93
95
  degreeFahrenheit: '°F',
94
96
  degreeCelsius: '°C',
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '1.46.4'
1
+ const seamapiReactVersion = '1.48.0'
2
2
 
3
3
  export default seamapiReactVersion
@@ -18,6 +18,7 @@
18
18
  @use './radio-field';
19
19
  @use './checkbox';
20
20
  @use './thermostat';
21
+ @use './tooltip';
21
22
  @use './seam-table';
22
23
 
23
24
  .seam-components {
@@ -36,6 +37,7 @@
36
37
  @include menus.all;
37
38
  @include checkbox.all;
38
39
  @include radio-field.all;
40
+ @include tooltip.all;
39
41
 
40
42
  // Components
41
43
  @include device-details.all;
@@ -0,0 +1,83 @@
1
+ @use './colors';
2
+
3
+ @mixin all {
4
+ .seam-tooltip {
5
+ position: relative;
6
+
7
+ .seam-tooltip-button {
8
+ appearance: none;
9
+ width: 18px;
10
+ height: 18px;
11
+ border: none;
12
+ box-shadow: none;
13
+ background: none;
14
+ padding: 0;
15
+ margin: 0;
16
+ display: flex;
17
+ justify-content: center;
18
+ align-items: center;
19
+ border-radius: 90px;
20
+ cursor: pointer;
21
+
22
+ & .seam-tooltip-button-icon {
23
+ position: absolute;
24
+ transition: opacity 0.15s ease-in-out;
25
+ }
26
+
27
+ .seam-tooltip-button-icon-hover {
28
+ opacity: 0;
29
+ }
30
+
31
+ &:hover,
32
+ &:focus {
33
+ .seam-tooltip-button-icon-default {
34
+ opacity: 0;
35
+ }
36
+
37
+ .seam-tooltip-button-icon-hover {
38
+ opacity: 1;
39
+ }
40
+ }
41
+
42
+ &:focus {
43
+ outline: none;
44
+ }
45
+ }
46
+
47
+ .seam-tooltip-popover {
48
+ width: 230px;
49
+ padding: 10px;
50
+ gap: 10px;
51
+ position: absolute;
52
+ bottom: 28px;
53
+ left: 2px;
54
+ display: flex;
55
+ border-radius: 8px;
56
+ background: colors.$white;
57
+ box-shadow:
58
+ 0 2px 16px 2px rgb(15 22 28 / 15%),
59
+ 0 0 1px 0 rgb(0 0 0 / 30%);
60
+ transform-origin: bottom left;
61
+ transition: 0.1s ease-in-out;
62
+ opacity: 0;
63
+ transform: scale(0.9);
64
+ visibility: hidden;
65
+ pointer-events: none;
66
+ z-index: -1;
67
+
68
+ &[aria-expanded='true'] {
69
+ opacity: 1;
70
+ transform: scale(1);
71
+ visibility: visible;
72
+ pointer-events: auto;
73
+ z-index: 9;
74
+ }
75
+ }
76
+
77
+ .seam-tooltip-text {
78
+ font-size: 14px;
79
+ font-weight: 400;
80
+ line-height: 134%;
81
+ }
82
+ }
83
+ }