@seamapi/react 1.59.0 → 1.60.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.
@@ -127,15 +127,27 @@ export class TelemetryClient {
127
127
 
128
128
  get #context(): Context {
129
129
  return {
130
- ...(this.#user?.traits == null ? {} : { traits: this.#user.traits }),
131
- app: {
130
+ traits: this.#user?.traits ?? undefined,
131
+ locale: globalThis.navigator?.language ?? undefined,
132
+ timezone:
133
+ Intl?.DateTimeFormat()?.resolvedOptions()?.timeZone ?? undefined,
134
+ userAgent: globalThis.navigator?.userAgent ?? undefined,
135
+ screen: {
136
+ width: globalThis.screen?.width ?? undefined,
137
+ height: globalThis.screen?.height ?? undefined,
138
+ density:
139
+ globalThis.devicePixelRatio != null
140
+ ? Math.round(globalThis.devicePixelRatio * 100) / 100
141
+ : undefined,
142
+ },
143
+ library: {
132
144
  version: version ?? undefined,
133
145
  name:
134
146
  // Assume if one of the elements is defined then this is loaded inside a web component.
135
147
  // This method will be inaccurate if the element bundle is loaded alongside
136
148
  // an app using the React components, however this use case is unlikely.
137
149
  // Choose seam-device-details as this component is unlikely to ever be removed.
138
- globalThis.customElements.get('seam-device-details') != null
150
+ globalThis.customElements?.get('seam-device-details') != null
139
151
  ? '@seamapi/react/elements'
140
152
  : '@seamapi/react',
141
153
  },
@@ -233,7 +245,16 @@ interface CommonSpec {
233
245
  // https://segment.com/docs/connections/spec/common/#context
234
246
  interface Context {
235
247
  traits?: Traits
236
- app: {
248
+ locale?: string
249
+ timezone?: string
250
+ userAgent?: string
251
+ userAgentData?: string
252
+ screen: {
253
+ width?: number
254
+ height?: number
255
+ density?: number
256
+ }
257
+ library: {
237
258
  name: string
238
259
  version: string | undefined
239
260
  }
@@ -73,11 +73,10 @@ export function Menu({
73
73
  const { right: containerRight, bottom: containerBottom } =
74
74
  documentEl.getBoundingClientRect()
75
75
 
76
- const {
77
- top: anchorTop,
78
- left: anchorLeft,
79
- height: anchorHeight,
80
- } = anchorEl.getBoundingClientRect()
76
+ const { height: anchorHeight } = anchorEl.getBoundingClientRect()
77
+
78
+ const anchorTop = anchorEl.offsetTop
79
+ const anchorLeft = anchorEl.offsetLeft
81
80
 
82
81
  const { width: contentWidth, height: contentHeight } =
83
82
  contentEl.getBoundingClientRect()
@@ -0,0 +1,9 @@
1
+ import classNames from 'classnames'
2
+
3
+ interface SpinnerProps {
4
+ size?: 'small' | 'medium' | 'large'
5
+ }
6
+
7
+ export function Spinner({ size = 'small' }: SpinnerProps): JSX.Element {
8
+ return <div className={classNames('seam-spinner', `size-${size}`)} />
9
+ }
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '1.59.0'
1
+ const seamapiReactVersion = '1.60.0'
2
2
 
3
3
  export default seamapiReactVersion
@@ -20,6 +20,7 @@
20
20
  @use './thermostat';
21
21
  @use './tooltip';
22
22
  @use './seam-table';
23
+ @use './spinner';
23
24
  @use './switch';
24
25
  @use './climate-setting-schedule-form';
25
26
  @use './climate-setting-schedule-details';
@@ -42,6 +43,7 @@
42
43
  @include checkbox.all;
43
44
  @include radio-field.all;
44
45
  @include tooltip.all;
46
+ @include spinner.all;
45
47
  @include switch.all;
46
48
  @include timezone-picker.all;
47
49
 
@@ -0,0 +1,44 @@
1
+ @use './colors';
2
+
3
+ @keyframes spin {
4
+ 0% {
5
+ transform: rotate(0deg);
6
+ }
7
+
8
+ 100% {
9
+ transform: rotate(360deg);
10
+ }
11
+ }
12
+
13
+ @mixin all {
14
+ $default-size: 16px;
15
+ $default-border-width: 2px;
16
+
17
+ .seam-spinner {
18
+ width: $default-size;
19
+ height: $default-size;
20
+ border: $default-border-width solid colors.$primary;
21
+ border-top: $default-border-width solid colors.$white;
22
+ display: inline-block;
23
+ border-radius: 50%;
24
+ animation: spin 0.5s linear infinite;
25
+
26
+ &.size-small {
27
+ width: $default-size;
28
+ height: $default-size;
29
+ border-width: $default-border-width;
30
+ }
31
+
32
+ &.size-medium {
33
+ width: 24px;
34
+ height: 24px;
35
+ border-width: 3px;
36
+ }
37
+
38
+ &.size-large {
39
+ width: 32px;
40
+ height: 32px;
41
+ border-width: 3px;
42
+ }
43
+ }
44
+ }