@pushwoosh/dumb-components 1.1.144 → 1.1.145

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.
@@ -1,13 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from 'react';
2
+ import { autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
3
+ import { useEffect, useState } from 'react';
4
+ import { createPortal } from 'react-dom';
3
5
  import { Color } from '@pushwoosh/kit-constants';
4
- import { Horizontal, useClickAway, Vertical } from '@pushwoosh/kit-helpers';
6
+ import { Horizontal, Vertical } from '@pushwoosh/kit-helpers';
5
7
  import { CalendarIcon } from '@pushwoosh/kit-icons';
6
8
  import { stringifyValue } from './helpers';
7
9
  import { PopoverContent, PresetsContainer } from './styles';
8
10
  import { Button } from '../../Button';
9
11
  import { Chip } from '../../Chip';
10
- import { Popover } from '../../Popover';
12
+ import { useLayer, useOnClickOutside } from '../../hooks';
11
13
  import { CalendarSuperForm } from '../CalendarSuperForm';
12
14
  import { Lang, useLang } from '../polyglot';
13
15
  export const CalendarDropdown = props => {
@@ -22,8 +24,6 @@ export const CalendarDropdown = props => {
22
24
  } = props;
23
25
  const isRangePicker = mode === 'range-date' || mode === 'range-datetime';
24
26
  const withTime = mode === 'single-datetime' || mode === 'range-datetime';
25
- const buttonRef = useRef(null);
26
- const popoverRef = useRef(null);
27
27
  const [isShaking, setIsShaking] = useState(false);
28
28
  const [isOpen, setIsOpen] = useState(false);
29
29
  const lang = useLang();
@@ -41,10 +41,31 @@ export const CalendarDropdown = props => {
41
41
  setValue(props.value ?? (isRangePicker ? [] : undefined));
42
42
  setTimezone(initialTimezone);
43
43
  };
44
- useClickAway(isOpen, popoverRef, closePopover);
45
44
  const openPopover = () => {
46
45
  setIsOpen(true);
47
46
  };
47
+ const {
48
+ refs,
49
+ floatingStyles
50
+ } = useFloating({
51
+ open: isOpen,
52
+ strategy: 'fixed',
53
+ placement: 'bottom-start',
54
+ transform: false,
55
+ middleware: [offset(4), flip(), shift({
56
+ padding: 8
57
+ })],
58
+ whileElementsMounted: autoUpdate
59
+ });
60
+ const {
61
+ zIndex
62
+ } = useLayer({
63
+ isOpen,
64
+ onClose: closePopover
65
+ });
66
+ useOnClickOutside([refs.reference, refs.floating], () => {
67
+ if (isOpen) closePopover();
68
+ });
48
69
  const onChangeHandler = val => {
49
70
  var _props$onChange;
50
71
  setValue(val);
@@ -65,7 +86,7 @@ export const CalendarDropdown = props => {
65
86
  return _jsxs(Horizontal, {
66
87
  "$justifyContent": "start",
67
88
  children: [_jsx(Button, {
68
- boxRef: buttonRef,
89
+ boxRef: refs.setReference,
69
90
  type: "button",
70
91
  view: buttonView,
71
92
  size: buttonSize,
@@ -77,108 +98,106 @@ export const CalendarDropdown = props => {
77
98
  onClick: () => isOpen ? closePopover() : openPopover(),
78
99
  isOpen: isOpen,
79
100
  children: buttonTextCustom ?? buttonText
80
- }), _jsx(Popover, {
81
- open: isOpen,
82
- anchorEl: buttonRef,
83
- internalWindowRef: popoverRef,
84
- windowWidth: isRangePicker ? 500 : 260,
85
- position: "bottom-start",
86
- zIndex: 10010,
87
- children: _jsx(PopoverContent, {
88
- "$isShaking": isShaking,
89
- onAnimationEnd: () => setIsShaking(false),
90
- children: _jsxs(Vertical, {
91
- children: [presets && presets.length > 0 && _jsx(PresetsContainer, {
92
- children: presets.map((preset, i) => _jsx(Chip, {
93
- onClick: () => onChangeHandler(preset.value),
94
- children: preset.label
95
- }, i))
96
- }), _jsxs(Horizontal, {
97
- "$padding": 16,
98
- "$border": {
99
- bottom: `1px solid ${Color.DIVIDER}`
101
+ }), isOpen && createPortal(_jsx(PopoverContent, {
102
+ ref: refs.setFloating,
103
+ style: {
104
+ ...floatingStyles,
105
+ zIndex
106
+ },
107
+ "$isShaking": isShaking,
108
+ "$width": isRangePicker ? 500 : 260,
109
+ onAnimationEnd: () => setIsShaking(false),
110
+ children: _jsxs(Vertical, {
111
+ children: [presets && presets.length > 0 && _jsx(PresetsContainer, {
112
+ children: presets.map((preset, i) => _jsx(Chip, {
113
+ onClick: () => onChangeHandler(preset.value),
114
+ children: preset.label
115
+ }, i))
116
+ }), _jsxs(Horizontal, {
117
+ "$padding": 16,
118
+ "$border": {
119
+ bottom: `1px solid ${Color.DIVIDER}`
120
+ },
121
+ children: [mode === 'single-date' && _jsx(CalendarSuperForm, {
122
+ mode: "single-date",
123
+ ...calendarProps,
124
+ value: value,
125
+ onChange: onChangeHandler
126
+ }), mode === 'single-datetime' && _jsx(CalendarSuperForm, {
127
+ mode: "single-datetime",
128
+ ...calendarProps,
129
+ value: value,
130
+ onChange: onChangeHandler,
131
+ timezone: timezone,
132
+ onChangeTimezone: val => {
133
+ setTimezone(val);
134
+ if ('onChangeTimezone' in calendarProps) {
135
+ calendarProps.onChangeTimezone(val);
136
+ }
137
+ }
138
+ }), mode === 'range-date' && _jsx(CalendarSuperForm, {
139
+ mode: "range-date",
140
+ ...calendarProps,
141
+ value: value,
142
+ onChange: onChangeHandler
143
+ }), mode === 'range-datetime' && _jsx(CalendarSuperForm, {
144
+ mode: "range-datetime",
145
+ ...calendarProps,
146
+ value: value,
147
+ onChange: onChangeHandler,
148
+ timezone: timezone,
149
+ onChangeTimezone: val => {
150
+ setTimezone(val);
151
+ if ('onChangeTimezone' in calendarProps) {
152
+ calendarProps.onChangeTimezone(val);
153
+ }
154
+ }
155
+ })]
156
+ }), _jsxs(Horizontal, {
157
+ "$padding": 16,
158
+ "$justifyContent": "end",
159
+ "$gap": 8,
160
+ children: [_jsx(Button, {
161
+ color: "secondary",
162
+ size: "compact",
163
+ onClick: () => {
164
+ if (noValue) {
165
+ closePopover();
166
+ } else {
167
+ setValue(isRangePicker ? [] : undefined);
168
+ setTimezone(initialTimezone);
169
+ }
100
170
  },
101
- children: [mode === 'single-date' && _jsx(CalendarSuperForm, {
102
- mode: "single-date",
103
- ...calendarProps,
104
- value: value,
105
- onChange: onChangeHandler
106
- }), mode === 'single-datetime' && _jsx(CalendarSuperForm, {
107
- mode: "single-datetime",
108
- ...calendarProps,
109
- value: value,
110
- onChange: onChangeHandler,
111
- timezone: timezone,
112
- onChangeTimezone: val => {
113
- setTimezone(val);
114
- if ('onChangeTimezone' in calendarProps) {
115
- calendarProps.onChangeTimezone(val);
116
- }
171
+ children: noValue ? _jsx(Lang, {
172
+ message: "DUMB.CALENDAR.CANCEL"
173
+ }) : _jsx(Lang, {
174
+ message: "DUMB.CALENDAR.RESET"
175
+ })
176
+ }), _jsx(Button, {
177
+ color: "primary",
178
+ size: "compact",
179
+ onClick: () => {
180
+ let isInvalid;
181
+ if (isRangePicker) {
182
+ const range = value;
183
+ const length = (range === null || range === void 0 ? void 0 : range.length) ?? 0;
184
+ isInvalid = allowEmpty ? length === 1 : length !== 2;
185
+ } else {
186
+ isInvalid = allowEmpty ? false : !value;
117
187
  }
118
- }), mode === 'range-date' && _jsx(CalendarSuperForm, {
119
- mode: "range-date",
120
- ...calendarProps,
121
- value: value,
122
- onChange: onChangeHandler
123
- }), mode === 'range-datetime' && _jsx(CalendarSuperForm, {
124
- mode: "range-datetime",
125
- ...calendarProps,
126
- value: value,
127
- onChange: onChangeHandler,
128
- timezone: timezone,
129
- onChangeTimezone: val => {
130
- setTimezone(val);
131
- if ('onChangeTimezone' in calendarProps) {
132
- calendarProps.onChangeTimezone(val);
133
- }
188
+ if (isInvalid) {
189
+ setIsShaking(true);
190
+ } else {
191
+ props.onSubmit(value, timezone);
192
+ closePopover();
134
193
  }
135
- })]
136
- }), _jsxs(Horizontal, {
137
- "$padding": 16,
138
- "$justifyContent": "end",
139
- "$gap": 8,
140
- children: [_jsx(Button, {
141
- color: "secondary",
142
- size: "compact",
143
- onClick: () => {
144
- if (noValue) {
145
- closePopover();
146
- } else {
147
- setValue(isRangePicker ? [] : undefined);
148
- setTimezone(initialTimezone);
149
- }
150
- },
151
- children: noValue ? _jsx(Lang, {
152
- message: "DUMB.CALENDAR.CANCEL"
153
- }) : _jsx(Lang, {
154
- message: "DUMB.CALENDAR.RESET"
155
- })
156
- }), _jsx(Button, {
157
- color: "primary",
158
- size: "compact",
159
- onClick: () => {
160
- let isInvalid;
161
- if (isRangePicker) {
162
- const range = value;
163
- const length = (range === null || range === void 0 ? void 0 : range.length) ?? 0;
164
- isInvalid = allowEmpty ? length === 1 : length !== 2;
165
- } else {
166
- isInvalid = allowEmpty ? false : !value;
167
- }
168
- if (isInvalid) {
169
- setIsShaking(true);
170
- } else {
171
- props.onSubmit(value, timezone);
172
- closePopover();
173
- }
174
- },
175
- children: _jsx(Lang, {
176
- message: "DUMB.CALENDAR.APPLY"
177
- })
178
- })]
194
+ },
195
+ children: _jsx(Lang, {
196
+ message: "DUMB.CALENDAR.APPLY"
197
+ })
179
198
  })]
180
- })
199
+ })]
181
200
  })
182
- })]
201
+ }), document.body)]
183
202
  });
184
203
  };
@@ -1,4 +1,5 @@
1
1
  export declare const PopoverContent: import("styled-components").StyledComponent<"div", any, {
2
2
  $isShaking?: boolean;
3
+ $width: number;
3
4
  }, never>;
4
5
  export declare const PresetsContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -1,10 +1,12 @@
1
1
  import styled, { keyframes, css } from 'styled-components';
2
- import { Shadow, Color } from '@pushwoosh/kit-constants';
2
+ import { Shadow, Color, ShapeRadius } from '@pushwoosh/kit-constants';
3
3
  const shakeAnimation = keyframes(["0%,100%{transform:translateX(0);}10%,30%,50%,70%,90%{transform:translateX(-4px);}20%,40%,60%,80%{transform:translateX(4px);}"]);
4
4
  export const PopoverContent = styled.div.withConfig({
5
5
  displayName: "PopoverContent",
6
6
  componentId: "sc-h6jz87-0"
7
- })(["overflow:hidden;box-shadow:", ";background:", ";", ""], Shadow.REGULAR, Color.CLEAR, ({
7
+ })(["width:", "px;overflow:hidden;border:1px solid ", ";border-radius:", ";box-shadow:", ";background:", ";", ""], ({
8
+ $width
9
+ }) => $width, Color.FORM, ShapeRadius.DIALOG, Shadow.REGULAR, Color.CLEAR, ({
8
10
  $isShaking
9
11
  }) => $isShaking && css(["animation:", " 0.4s ease-in-out;"], shakeAnimation));
10
12
  export const PresetsContainer = styled.div.withConfig({
@@ -1,31 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useMemo } from 'react';
3
- import { Select } from '../../../Select';
3
+ import { Combobox } from '../../../Combobox';
4
4
  import { getSortedTimezones } from '../../helpers-tz';
5
5
  export const CalendarTimezoneSelect = ({
6
6
  timezone,
7
7
  onChange,
8
8
  isDisabled
9
9
  }) => {
10
- const timezonesOptions = useMemo(() => {
11
- return getSortedTimezones();
12
- }, []);
13
- return _jsx(Select, {
14
- value: timezonesOptions.find(op => op.value === timezone),
15
- onChange: value => onChange(value.value),
16
- options: timezonesOptions,
17
- isDisabled: isDisabled,
18
- menuPortalTarget: document.body,
19
- menuPosition: "fixed",
20
- styles: {
21
- menuPortal: base => ({
22
- ...base,
23
- zIndex: 10020
24
- }),
25
- menu: provided => ({
26
- ...provided,
27
- width: '300px'
28
- })
29
- }
10
+ const timezonesOptions = useMemo(() => getSortedTimezones(), []);
11
+ const value = useMemo(() => timezonesOptions.find(op => op.value === timezone) ?? null, [timezonesOptions, timezone]);
12
+ return _jsx(Combobox, {
13
+ select: true,
14
+ items: timezonesOptions,
15
+ value: value,
16
+ onChange: option => {
17
+ if (option) onChange(option.value);
18
+ },
19
+ getLabel: option => option.label,
20
+ getKey: option => option.value,
21
+ filter: (option, query) => option.label.toLowerCase().includes(query.toLowerCase()),
22
+ disabled: isDisabled
30
23
  });
31
24
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.144",
3
+ "version": "1.1.145",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -47,6 +47,8 @@ export function SuggestionsDropdown({
47
47
  id: listboxId,
48
48
  role: "listbox",
49
49
  onScroll: onScroll,
50
+ onMouseDown: event => event.stopPropagation(),
51
+ onTouchStart: event => event.stopPropagation(),
50
52
  children: [loading && _jsx(DropdownEmpty, {
51
53
  children: loadingText
52
54
  }), !loading && createLabel && _jsx(DropdownItem, {