@seamapi/react 1.30.2 → 1.32.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 (94) hide show
  1. package/README.md +1 -1
  2. package/dist/elements.js +6286 -5829
  3. package/dist/elements.js.map +1 -1
  4. package/dist/index.css +106 -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/dates.d.ts +50 -0
  9. package/lib/dates.js +93 -1
  10. package/lib/dates.js.map +1 -1
  11. package/lib/icons/CheckboxBlank.d.ts +2 -0
  12. package/lib/icons/CheckboxBlank.js +5 -0
  13. package/lib/icons/CheckboxBlank.js.map +1 -0
  14. package/lib/icons/CheckboxFilled.d.ts +2 -0
  15. package/lib/icons/CheckboxFilled.js +5 -0
  16. package/lib/icons/CheckboxFilled.js.map +1 -0
  17. package/lib/icons/Edit.d.ts +2 -0
  18. package/lib/icons/Edit.js +7 -0
  19. package/lib/icons/Edit.js.map +1 -0
  20. package/lib/icons/RadioChecked.d.ts +2 -0
  21. package/lib/icons/RadioChecked.js +5 -0
  22. package/lib/icons/RadioChecked.js.map +1 -0
  23. package/lib/icons/RadioUnchecked.d.ts +2 -0
  24. package/lib/icons/RadioUnchecked.js +5 -0
  25. package/lib/icons/RadioUnchecked.js.map +1 -0
  26. package/lib/seam/components/AccessCodeForm/AccessCodeForm.js +66 -12
  27. package/lib/seam/components/AccessCodeForm/AccessCodeForm.js.map +1 -1
  28. package/lib/seam/components/AccessCodeForm/AccessCodeFormDatePicker.d.ts +13 -0
  29. package/lib/seam/components/AccessCodeForm/AccessCodeFormDatePicker.js +18 -0
  30. package/lib/seam/components/AccessCodeForm/AccessCodeFormDatePicker.js.map +1 -0
  31. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimes.d.ts +8 -0
  32. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimes.js +12 -0
  33. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimes.js.map +1 -0
  34. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimezonePicker.d.ts +8 -0
  35. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimezonePicker.js +25 -0
  36. package/lib/seam/components/AccessCodeForm/AccessCodeFormTimezonePicker.js.map +1 -0
  37. package/lib/seam/components/AccessCodeTable/AccessCodeTable.d.ts +2 -1
  38. package/lib/seam/components/AccessCodeTable/AccessCodeTable.js +2 -2
  39. package/lib/seam/components/AccessCodeTable/AccessCodeTable.js.map +1 -1
  40. package/lib/seam/components/DeviceTable/DeviceTable.d.ts +2 -1
  41. package/lib/seam/components/DeviceTable/DeviceTable.js +2 -2
  42. package/lib/seam/components/DeviceTable/DeviceTable.js.map +1 -1
  43. package/lib/ui/Checkbox.d.ts +9 -0
  44. package/lib/ui/Checkbox.js +17 -0
  45. package/lib/ui/Checkbox.js.map +1 -0
  46. package/lib/ui/DateTimePicker/DateTimePicker.d.ts +5 -0
  47. package/lib/ui/DateTimePicker/DateTimePicker.js +8 -0
  48. package/lib/ui/DateTimePicker/DateTimePicker.js.map +1 -0
  49. package/lib/ui/FormField.js +2 -1
  50. package/lib/ui/FormField.js.map +1 -1
  51. package/lib/ui/Menu/Menu.d.ts +2 -2
  52. package/lib/ui/Menu/Menu.js +1 -5
  53. package/lib/ui/Menu/Menu.js.map +1 -1
  54. package/lib/ui/RadioField/Radio.d.ts +7 -0
  55. package/lib/ui/RadioField/Radio.js +19 -0
  56. package/lib/ui/RadioField/Radio.js.map +1 -0
  57. package/lib/ui/RadioField/RadioField.d.ts +15 -0
  58. package/lib/ui/RadioField/RadioField.js +20 -0
  59. package/lib/ui/RadioField/RadioField.js.map +1 -0
  60. package/lib/ui/TextField/TextField.d.ts +4 -2
  61. package/lib/ui/TextField/TextField.js +2 -2
  62. package/lib/ui/TextField/TextField.js.map +1 -1
  63. package/lib/ui/layout/ContentHeader.d.ts +2 -1
  64. package/lib/version.d.ts +1 -1
  65. package/lib/version.js +1 -1
  66. package/package.json +9 -4
  67. package/src/lib/dates.ts +120 -1
  68. package/src/lib/icons/CheckboxBlank.tsx +22 -0
  69. package/src/lib/icons/CheckboxFilled.tsx +23 -0
  70. package/src/lib/icons/Edit.tsx +36 -0
  71. package/src/lib/icons/RadioChecked.tsx +21 -0
  72. package/src/lib/icons/RadioUnchecked.tsx +23 -0
  73. package/src/lib/seam/components/AccessCodeForm/AccessCodeForm.tsx +137 -23
  74. package/src/lib/seam/components/AccessCodeForm/AccessCodeFormDatePicker.tsx +68 -0
  75. package/src/lib/seam/components/AccessCodeForm/AccessCodeFormTimes.tsx +34 -0
  76. package/src/lib/seam/components/AccessCodeForm/AccessCodeFormTimezonePicker.tsx +70 -0
  77. package/src/lib/seam/components/AccessCodeTable/AccessCodeTable.element.ts +1 -0
  78. package/src/lib/seam/components/AccessCodeTable/AccessCodeTable.tsx +9 -5
  79. package/src/lib/seam/components/DeviceTable/DeviceTable.element.ts +1 -0
  80. package/src/lib/seam/components/DeviceTable/DeviceTable.tsx +9 -5
  81. package/src/lib/ui/Checkbox.tsx +44 -0
  82. package/src/lib/ui/DateTimePicker/DateTimePicker.tsx +30 -0
  83. package/src/lib/ui/FormField.tsx +2 -1
  84. package/src/lib/ui/Menu/Menu.tsx +4 -8
  85. package/src/lib/ui/RadioField/Radio.tsx +45 -0
  86. package/src/lib/ui/RadioField/RadioField.tsx +55 -0
  87. package/src/lib/ui/TextField/TextField.tsx +12 -2
  88. package/src/lib/ui/layout/ContentHeader.tsx +1 -1
  89. package/src/lib/version.ts +1 -1
  90. package/src/styles/_access-code-form.scss +88 -0
  91. package/src/styles/_checkbox.scss +25 -0
  92. package/src/styles/_inputs.scss +3 -0
  93. package/src/styles/_main.scss +4 -0
  94. package/src/styles/_radio-field.scss +31 -0
@@ -0,0 +1,70 @@
1
+ import { useState } from 'react'
2
+
3
+ import {
4
+ getBrowserTimezone,
5
+ getTimezoneLabel,
6
+ getTimezoneOffset,
7
+ getTimezones,
8
+ } from 'lib/dates.js'
9
+ import { Checkbox } from 'lib/ui/Checkbox.js'
10
+ import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
11
+ import { handleString } from 'lib/ui/TextField/TextField.js'
12
+
13
+ interface AccessCodeFormTimezonePickerProps {
14
+ value: string
15
+ onChange: (timezone: string) => void
16
+ onClose: () => void
17
+ }
18
+
19
+ export function AccessCodeFormTimezonePicker({
20
+ onChange,
21
+ value,
22
+ onClose,
23
+ }: AccessCodeFormTimezonePickerProps): JSX.Element {
24
+ const [manualTimezoneEnabled, setManualTimezoneEnabled] = useState(false)
25
+
26
+ const isBrowserTimezone = value === getBrowserTimezone()
27
+ const isManualTimezone = !isBrowserTimezone || manualTimezoneEnabled
28
+
29
+ const handleChangeManualTimezone = (enabled: boolean): void => {
30
+ setManualTimezoneEnabled(enabled)
31
+ if (!enabled) {
32
+ onChange(getBrowserTimezone())
33
+ }
34
+ }
35
+
36
+ const title = isManualTimezone ? t.titleManual : t.titleAuto
37
+
38
+ return (
39
+ <div className='seam-timezone-picker'>
40
+ <ContentHeader title={title} onBack={onClose} />
41
+ <div className='seam-content'>
42
+ <Checkbox
43
+ label={t.setTimezoneManuallyLabel}
44
+ checked={isManualTimezone}
45
+ onChange={handleChangeManualTimezone}
46
+ className='seam-manual-timezone-checkbox'
47
+ />
48
+
49
+ <select
50
+ value={value}
51
+ onChange={handleString(onChange)}
52
+ className='seam-timezone-select'
53
+ disabled={!isManualTimezone}
54
+ >
55
+ {getTimezones().map((timezone) => (
56
+ <option value={timezone} key={timezone}>
57
+ UTC {getTimezoneOffset(timezone)} {getTimezoneLabel(timezone)}
58
+ </option>
59
+ ))}
60
+ </select>
61
+ </div>
62
+ </div>
63
+ )
64
+ }
65
+
66
+ const t = {
67
+ titleAuto: 'Time Zone (automatic)',
68
+ titleManual: 'Time Zone (manual)',
69
+ setTimezoneManuallyLabel: 'Set time zone manually',
70
+ }
@@ -7,6 +7,7 @@ export const name = 'seam-access-code-table'
7
7
  export const props: ElementProps<AccessCodeTableProps> = {
8
8
  deviceId: 'string',
9
9
  disableLockUnlock: 'boolean',
10
+ disableSearch: 'boolean',
10
11
  accessCodeFilter: 'function',
11
12
  accessCodeComparator: 'function',
12
13
  onAccessCodeClick: 'function',
@@ -39,6 +39,7 @@ const disableCreateAccessCode = true
39
39
  export interface AccessCodeTableProps {
40
40
  deviceId: string
41
41
  disableLockUnlock?: boolean
42
+ disableSearch?: boolean
42
43
  accessCodeFilter?: (
43
44
  accessCode: AccessCode,
44
45
  searchInputValue: string
@@ -71,6 +72,7 @@ const defaultAccessCodeFilter = (
71
72
  export function AccessCodeTable({
72
73
  deviceId,
73
74
  disableLockUnlock = false,
75
+ disableSearch = false,
74
76
  onAccessCodeClick = () => {},
75
77
  preventDefaultOnAccessCodeClick = false,
76
78
  onBack,
@@ -150,11 +152,13 @@ export function AccessCodeTable({
150
152
  </IconButton>
151
153
  )}
152
154
  </div>
153
- <SearchTextField
154
- value={searchInputValue}
155
- onChange={setSearchInputValue}
156
- disabled={(accessCodes?.length ?? 0) === 0}
157
- />
155
+ {!disableSearch && (
156
+ <SearchTextField
157
+ value={searchInputValue}
158
+ onChange={setSearchInputValue}
159
+ disabled={(accessCodes?.length ?? 0) === 0}
160
+ />
161
+ )}
158
162
  </TableHeader>
159
163
  <TableBody>
160
164
  <Content
@@ -8,6 +8,7 @@ export const props: ElementProps<DeviceTableProps> = {
8
8
  deviceIds: 'json',
9
9
  connectedAccountIds: 'json',
10
10
  disableLockUnlock: 'boolean',
11
+ disableSearch: 'boolean',
11
12
  deviceFilter: 'function',
12
13
  deviceComparator: 'function',
13
14
  onDeviceClick: 'function',
@@ -28,6 +28,7 @@ export interface DeviceTableProps {
28
28
  deviceIds?: string[]
29
29
  connectedAccountIds?: string[]
30
30
  disableLockUnlock?: boolean
31
+ disableSearch?: boolean
31
32
  deviceFilter?: (device: Device, searchInputValue: string) => boolean
32
33
  deviceComparator?: (deviceA: Device, deviceB: Device) => number
33
34
  onDeviceClick?: (deviceId: string) => void
@@ -49,6 +50,7 @@ export function DeviceTable({
49
50
  deviceIds,
50
51
  connectedAccountIds,
51
52
  disableLockUnlock = false,
53
+ disableSearch = false,
52
54
  onDeviceClick = () => {},
53
55
  preventDefaultOnDeviceClick = false,
54
56
  onBack,
@@ -110,11 +112,13 @@ export function DeviceTable({
110
112
  <TableTitle>
111
113
  {t.devices} <Caption>({filteredDevices.length})</Caption>
112
114
  </TableTitle>
113
- <SearchTextField
114
- value={searchInputValue}
115
- onChange={setSearchInputValue}
116
- disabled={(devices?.length ?? 0) === 0}
117
- />
115
+ {!disableSearch && (
116
+ <SearchTextField
117
+ value={searchInputValue}
118
+ onChange={setSearchInputValue}
119
+ disabled={(devices?.length ?? 0) === 0}
120
+ />
121
+ )}
118
122
  </TableHeader>
119
123
  <TableBody>
120
124
  <Content devices={filteredDevices} onDeviceClick={handleDeviceClick} />
@@ -0,0 +1,44 @@
1
+ import classNames from 'classnames'
2
+ import { useRef } from 'react'
3
+
4
+ import { CheckboxBlankIcon } from 'lib/icons/CheckboxBlank.js'
5
+ import { CheckboxFilledIcon } from 'lib/icons/CheckboxFilled.js'
6
+
7
+ interface CheckboxProps {
8
+ label: string
9
+ checked?: boolean
10
+ onChange: (checked: boolean) => void
11
+ className?: string
12
+ }
13
+
14
+ export function Checkbox({
15
+ label,
16
+ checked,
17
+ onChange,
18
+ className,
19
+ }: CheckboxProps): JSX.Element {
20
+ const inputRef = useRef<HTMLInputElement>(null)
21
+
22
+ const toggle = (): void => {
23
+ if (inputRef.current != null) {
24
+ inputRef.current.click()
25
+ }
26
+ }
27
+
28
+ return (
29
+ <div className={classNames('seam-checkbox', className)} onClick={toggle}>
30
+ <span className='seam-checkbox-icon'>
31
+ {checked === true ? <CheckboxFilledIcon /> : <CheckboxBlankIcon />}
32
+ </span>
33
+ <input
34
+ type='checkbox'
35
+ ref={inputRef}
36
+ onChange={(event) => {
37
+ onChange(event.target.checked)
38
+ }}
39
+ checked={checked}
40
+ />
41
+ <span className=' seam-checkbox-label'>{label}</span>
42
+ </div>
43
+ )
44
+ }
@@ -0,0 +1,30 @@
1
+ import classNames from 'classnames'
2
+ import { forwardRef } from 'react'
3
+
4
+ import { TextField, type TextFieldProps } from 'lib/ui/TextField/TextField.js'
5
+
6
+ type DateTimePickerProps = Pick<
7
+ TextFieldProps,
8
+ 'size' | 'value' | 'className'
9
+ > & {
10
+ onChange: (value: string) => void
11
+ }
12
+
13
+ export const DateTimePicker = forwardRef<
14
+ HTMLInputElement | undefined,
15
+ DateTimePickerProps
16
+ >(function DateTextField(
17
+ { className, value, onChange, ...props },
18
+ ref
19
+ ): JSX.Element {
20
+ return (
21
+ <TextField
22
+ type='datetime-local'
23
+ className={classNames('seam-date-time-picker', className)}
24
+ ref={ref}
25
+ value={value}
26
+ onChange={onChange}
27
+ {...props}
28
+ />
29
+ )
30
+ })
@@ -1,6 +1,7 @@
1
1
  import classNames from 'classnames'
2
2
  import { cloneElement, useRef } from 'react'
3
3
 
4
+ import { DateTimePicker } from 'lib/ui/DateTimePicker/DateTimePicker.js'
4
5
  import { InputLabel } from 'lib/ui/InputLabel.js'
5
6
  import { TextField } from 'lib/ui/TextField/TextField.js'
6
7
 
@@ -38,7 +39,7 @@ export function FormField({
38
39
  })
39
40
  }
40
41
 
41
- if (component.type === TextField) {
42
+ if (component.type === TextField || component.type === DateTimePicker) {
42
43
  return cloneElement(component, {
43
44
  ...baseProps,
44
45
  ref: inputRef,
@@ -23,11 +23,11 @@ export interface MenuProps extends PropsWithChildren {
23
23
  }>
24
24
  }
25
25
 
26
- interface MenuContextValue {
26
+ interface MenuContext {
27
27
  close: () => void
28
28
  }
29
29
 
30
- const menuContext = createContext<MenuContextValue>({
30
+ const menuContext = createContext<MenuContext>({
31
31
  close: () => {},
32
32
  })
33
33
 
@@ -171,10 +171,6 @@ export function Menu({
171
171
  )
172
172
  }
173
173
 
174
- export function useMenu(): MenuContextValue {
175
- const context = useContext(menuContext)
176
- if (context == null) {
177
- throw new Error('useMenu must be used within a Menu.')
178
- }
179
- return context
174
+ export function useMenu(): MenuContext {
175
+ return useContext(menuContext)
180
176
  }
@@ -0,0 +1,45 @@
1
+ import { useRef } from 'react'
2
+
3
+ import { RadioCheckedIcon } from 'lib/icons/RadioChecked.js'
4
+ import { RadioUncheckedIcon } from 'lib/icons/RadioUnchecked.js'
5
+ import { useRadioField } from 'lib/ui/RadioField/RadioField.js'
6
+
7
+ interface RadioProps<Value extends string> {
8
+ value: Value
9
+ label: string
10
+ }
11
+
12
+ export function Radio<Value extends string>({
13
+ value,
14
+ label,
15
+ }: RadioProps<Value>): JSX.Element {
16
+ const { value: fieldValue, onChange, name } = useRadioField<Value>()
17
+
18
+ const checked = fieldValue === value
19
+
20
+ const inputRef = useRef<HTMLInputElement>()
21
+
22
+ const checkRadio = (): void => {
23
+ if (inputRef.current != null) {
24
+ inputRef.current.click()
25
+ }
26
+ }
27
+
28
+ return (
29
+ <label className='seam-radio' onClick={checkRadio}>
30
+ <span className='seam-radio-icon'>
31
+ {checked ? <RadioCheckedIcon /> : <RadioUncheckedIcon />}
32
+ </span>
33
+ <input
34
+ type='radio'
35
+ name={name}
36
+ value={value}
37
+ checked={checked}
38
+ onChange={(event) => {
39
+ onChange(event.target.value as Value)
40
+ }}
41
+ />
42
+ <span className='seam-radio-label'>{label}</span>
43
+ </label>
44
+ )
45
+ }
@@ -0,0 +1,55 @@
1
+ import { createContext, useContext } from 'react'
2
+
3
+ import { Radio } from 'lib/ui/RadioField/Radio.js'
4
+
5
+ interface RadioFieldProps<Value extends string> {
6
+ name: string
7
+ value: Value
8
+ onChange: (value: Value) => void
9
+ options: Array<RadioOption<Value>>
10
+ }
11
+
12
+ interface RadioOption<Value> {
13
+ label: string
14
+ value: Value
15
+ }
16
+
17
+ type RadioFieldContext<Value extends string> =
18
+ | Omit<RadioFieldProps<Value>, 'options'>
19
+ | undefined
20
+
21
+ const radioFieldContext = createContext<RadioFieldContext<any>>(undefined)
22
+
23
+ export function RadioField<Value extends string>({
24
+ value,
25
+ onChange,
26
+ name,
27
+ options,
28
+ }: RadioFieldProps<Value>): JSX.Element {
29
+ const { Provider } = radioFieldContext
30
+ return (
31
+ <Provider
32
+ value={{
33
+ value,
34
+ onChange,
35
+ name,
36
+ }}
37
+ >
38
+ <div className='seam-radio-field'>
39
+ {options.map(({ value, label }, index) => (
40
+ <Radio value={value} label={label} key={index} />
41
+ ))}
42
+ </div>
43
+ </Provider>
44
+ )
45
+ }
46
+
47
+ export function useRadioField<Value extends string>(): NonNullable<
48
+ RadioFieldContext<Value>
49
+ > {
50
+ const context = useContext<RadioFieldContext<Value>>(radioFieldContext)
51
+ if (context === undefined) {
52
+ throw new Error('useRadioField must be used within a <RadioField/>')
53
+ }
54
+ return context
55
+ }
@@ -4,6 +4,7 @@ import {
4
4
  type FocusEventHandler,
5
5
  forwardRef,
6
6
  type InputHTMLAttributes,
7
+ type MouseEventHandler,
7
8
  type MutableRefObject,
8
9
  useEffect,
9
10
  useImperativeHandle,
@@ -28,8 +29,10 @@ export interface TextFieldProps {
28
29
  clearable?: boolean
29
30
  onFocus?: FocusEventHandler<HTMLInputElement>
30
31
  onBlur?: FocusEventHandler<HTMLInputElement>
32
+ onClick?: MouseEventHandler<HTMLInputElement>
31
33
  helperText?: string
32
34
  hasError?: boolean
35
+ type?: 'text' | 'datetime-local'
33
36
  }
34
37
 
35
38
  export const TextField = forwardRef<
@@ -48,8 +51,10 @@ export const TextField = forwardRef<
48
51
  clearable = false,
49
52
  onFocus,
50
53
  onBlur,
54
+ onClick,
51
55
  hasError = false,
52
56
  helperText,
57
+ type = 'text',
53
58
  },
54
59
  ref
55
60
  ): JSX.Element {
@@ -90,11 +95,12 @@ export const TextField = forwardRef<
90
95
  className='seam-text-field-input'
91
96
  value={value}
92
97
  onChange={onChange == null ? undefined : handleString(onChange)}
93
- type='text'
94
98
  disabled={disabled}
95
99
  ref={setInputEl}
96
100
  onFocus={onFocus}
97
101
  onBlur={onBlur}
102
+ onClick={onClick}
103
+ type={type}
98
104
  {...inputProps}
99
105
  />
100
106
  {endAdornmentVisible && (
@@ -122,7 +128,11 @@ export const TextField = forwardRef<
122
128
 
123
129
  export const handleString =
124
130
  (setter: (v: string) => void) =>
125
- (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
131
+ (
132
+ event: ChangeEvent<
133
+ HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
134
+ >
135
+ ): void => {
126
136
  setter(event.currentTarget.value)
127
137
  }
128
138
 
@@ -1,6 +1,6 @@
1
1
  import { ArrowBackIcon } from 'lib/icons/ArrowBack.js'
2
2
 
3
- export interface ContentHeaderProps {
3
+ interface ContentHeaderProps {
4
4
  onBack?: () => void
5
5
  title?: string
6
6
  subheading?: string
@@ -1,3 +1,3 @@
1
- const seamapiReactVersion = '1.30.2'
1
+ const seamapiReactVersion = '1.32.0'
2
2
 
3
3
  export default seamapiReactVersion
@@ -3,6 +3,8 @@
3
3
  @mixin all {
4
4
  .seam-access-code-form {
5
5
  @include main;
6
+ @include schedule-picker;
7
+ @include timezone-picker;
6
8
  }
7
9
  }
8
10
 
@@ -42,6 +44,34 @@
42
44
  }
43
45
  }
44
46
 
47
+ .seam-selected-times {
48
+ margin-top: 4px;
49
+ margin-left: 36px;
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 24px;
53
+
54
+ > div {
55
+ display: grid;
56
+ grid-template-columns: auto auto;
57
+ grid-template-rows: auto auto;
58
+ grid-column-gap: 16px;
59
+
60
+ > span {
61
+ font-size: 14px;
62
+ line-height: 134%;
63
+ }
64
+
65
+ > .seam-label {
66
+ color: colors.$text-gray-2;
67
+ }
68
+
69
+ > .seam-time {
70
+ color: colors.$text-gray-1;
71
+ }
72
+ }
73
+ }
74
+
45
75
  .seam-actions {
46
76
  display: flex;
47
77
  gap: 8px;
@@ -53,3 +83,61 @@
53
83
  }
54
84
  }
55
85
  }
86
+
87
+ @mixin schedule-picker {
88
+ .seam-schedule-picker {
89
+ .seam-content {
90
+ padding: 0 24px;
91
+
92
+ .seam-timezone {
93
+ display: flex;
94
+ align-items: center;
95
+ font-size: 14px;
96
+ margin-bottom: 24px;
97
+
98
+ .seam-label {
99
+ color: colors.$text-gray-2;
100
+ margin-right: 4px;
101
+ }
102
+
103
+ .seam-selected {
104
+ color: colors.$primary;
105
+ cursor: pointer;
106
+ display: flex;
107
+ align-items: center;
108
+
109
+ svg {
110
+ scale: 0.6667;
111
+ transform: translate(-6px, 2px);
112
+
113
+ * {
114
+ fill: colors.$primary;
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ @mixin timezone-picker {
124
+ .seam-timezone-picker {
125
+ .seam-content {
126
+ padding: 0 24px;
127
+
128
+ .seam-manual-timezone-checkbox {
129
+ margin-bottom: 8px;
130
+ }
131
+
132
+ > .seam-timezone-select {
133
+ background: colors.$white;
134
+ padding: 0 12px;
135
+ width: 100%;
136
+ border: 1px solid colors.$text-gray-3;
137
+ border-radius: 8px;
138
+ height: 48px;
139
+ font-size: 16px;
140
+ }
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,25 @@
1
+ @use './colors';
2
+
3
+ @mixin all {
4
+ .seam-checkbox {
5
+ display: flex;
6
+ align-items: center;
7
+ gap: 8px;
8
+ cursor: pointer;
9
+ padding: 6px 0;
10
+
11
+ > .seam-checkbox-icon {
12
+ height: 24px;
13
+ width: 24px;
14
+ }
15
+
16
+ > input {
17
+ display: none;
18
+ }
19
+
20
+ > .seam-checkbox-label {
21
+ font-size: 16px;
22
+ line-height: 150%;
23
+ }
24
+ }
25
+ }
@@ -1,4 +1,5 @@
1
1
  @use './colors';
2
+ @use './typography';
2
3
 
3
4
  @mixin text-field {
4
5
  .seam-text-field {
@@ -24,6 +25,8 @@
24
25
  width: 100%;
25
26
  border-radius: 8px;
26
27
 
28
+ @include typography.font-family;
29
+
27
30
  &:focus {
28
31
  outline: none;
29
32
  }
@@ -16,6 +16,8 @@
16
16
  @use './access-code-form';
17
17
  @use './input-label';
18
18
  @use './form-field';
19
+ @use './radio-field';
20
+ @use './checkbox';
19
21
 
20
22
  .seam-components {
21
23
  // Reset
@@ -31,6 +33,8 @@
31
33
  @include layout.all;
32
34
  @include icons.all;
33
35
  @include menus.all;
36
+ @include checkbox.all;
37
+ @include radio-field.all;
34
38
 
35
39
  // Components
36
40
  @include device-details.all;
@@ -0,0 +1,31 @@
1
+ @use './colors';
2
+
3
+ @mixin all {
4
+ .seam-radio-field {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 4px;
8
+
9
+ > .seam-radio {
10
+ display: flex;
11
+ align-items: center;
12
+ gap: 4px;
13
+ padding: 0 8px;
14
+ cursor: pointer;
15
+
16
+ > input {
17
+ display: none;
18
+ }
19
+
20
+ > .seam-radio-icon {
21
+ height: 24px;
22
+ width: 24px;
23
+ }
24
+
25
+ > .seam-radio-label {
26
+ font-size: 16px;
27
+ line-height: 134%;
28
+ }
29
+ }
30
+ }
31
+ }