@pushwoosh/dumb-components 1.0.61 → 1.0.63

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,5 +1,6 @@
1
1
  import Picker from '@emoji-mart/react';
2
2
  import React from 'react';
3
+ import { EmojiPickerStyled } from './EmojiPicker.styled';
3
4
  async function data() {
4
5
  const response = await fetch('https://cdn.jsdelivr.net/npm/@emoji-mart/data');
5
6
  return response.json();
@@ -7,11 +8,11 @@ async function data() {
7
8
  export const EmojiPicker = ({
8
9
  onEmojiSelect
9
10
  }) => {
10
- return React.createElement(Picker, {
11
+ return React.createElement(EmojiPickerStyled, null, React.createElement(Picker, {
11
12
  data: data,
12
13
  onEmojiSelect: emoji => {
13
14
  onEmojiSelect(emoji.native);
14
15
  },
15
16
  theme: "light"
16
- });
17
+ }));
17
18
  };
@@ -0,0 +1 @@
1
+ export declare const EmojiPickerStyled: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,5 @@
1
+ import styled from 'styled-components';
2
+ export const EmojiPickerStyled = styled.div.withConfig({
3
+ displayName: "EmojiPickerStyled",
4
+ componentId: "sc-1bxjwgk-0"
5
+ })(["min-width:352px;"]);
@@ -1,11 +1,11 @@
1
+ import { autoPlacement, offset, useFloating } from '@floating-ui/react-dom';
1
2
  import { isEqual } from 'es-toolkit';
2
- import React, { useEffect, useRef, useState } from 'react';
3
+ import React, { useEffect, useState } from 'react';
3
4
  import { Transforms } from 'slate';
4
5
  import { Collapse, elementAddListener, Horizontal, usePersistentFunction } from '@pushwoosh/kit-helpers';
5
6
  import { FieldBox } from '../FieldBox';
6
7
  import EmojiIcon from './assets/EmojiIcon.svg';
7
8
  import PersonalizationIcon from './assets/PersonalizationIcon.svg';
8
- import { DropContent } from './DropContent';
9
9
  import { EmojiPicker } from './EmojiPicker';
10
10
  import { ImSpan } from './RichMessageEditor.styled';
11
11
  import { getDcByPath } from './slate/helpers';
@@ -21,24 +21,24 @@ export const RichMessageEditor = ({
21
21
  onBlur,
22
22
  renderDynamicContent
23
23
  }) => {
24
- const rootRef = useRef(null);
25
24
  const [showDrop, setShowDrop] = useState();
26
25
  const [isFocused, setIsFocused] = useState(false);
27
- const showDropArea = val => {
28
- const rect = rootRef.current.getBoundingClientRect();
29
- setShowDrop({
30
- ...val,
31
- xValue: rect.right + 8,
32
- yValue: rect.top
33
- });
34
- };
26
+ const {
27
+ refs,
28
+ floatingStyles,
29
+ update
30
+ } = useFloating({
31
+ middleware: [offset(8), autoPlacement({
32
+ allowedPlacements: ['left', 'left-start', 'left-end', 'right', 'right-start', 'right-end']
33
+ })]
34
+ });
35
35
  const onSelectionChange = selection => {
36
36
  if (isEqual(selection.anchor, selection.focus)) {
37
37
  const {
38
38
  path
39
39
  } = selection.anchor;
40
40
  if (path.length > 2) {
41
- showDropArea({
41
+ setShowDrop({
42
42
  type: 'personalization',
43
43
  path: path.slice(0, -1)
44
44
  });
@@ -69,11 +69,11 @@ export const RichMessageEditor = ({
69
69
  return;
70
70
  }
71
71
  return elementAddListener(document, ['mousedown', 'touchstart', 'focusin'], event => {
72
- if (rootRef.current && !rootRef.current.contains(event.target)) {
72
+ if (refs.reference.current instanceof HTMLElement && !refs.reference.current.contains(event.target)) {
73
73
  clickAwayHandler();
74
74
  }
75
75
  });
76
- }, [clickAwayHandler, isFocused]);
76
+ }, [clickAwayHandler, isFocused, refs.reference]);
77
77
  return React.createElement(SlateEditor, {
78
78
  initialValue: initialValue,
79
79
  onChange: onChange,
@@ -84,18 +84,18 @@ export const RichMessageEditor = ({
84
84
  var _getDcByPath;
85
85
  return React.createElement(FieldBox, {
86
86
  title: title,
87
- boxRef: rootRef,
87
+ boxRef: refs.setReference,
88
88
  error: error,
89
89
  actions: React.createElement(Collapse, {
90
90
  expanded: isFocused
91
91
  }, React.createElement(Horizontal, {
92
92
  "$gap": 8
93
93
  }, canUsePersonalization && React.createElement(ImSpan, {
94
- onClick: () => showDropArea({
94
+ onClick: () => setShowDrop({
95
95
  type: 'personalization'
96
96
  })
97
97
  }, React.createElement(PersonalizationIcon, null), "Personalization"), canUseEmoji && React.createElement(ImSpan, {
98
- onClick: () => showDropArea({
98
+ onClick: () => setShowDrop({
99
99
  type: 'emoji'
100
100
  })
101
101
  }, React.createElement(EmojiIcon, null), "Emoji")))
@@ -110,9 +110,10 @@ export const RichMessageEditor = ({
110
110
  onSelectionChange(selection);
111
111
  }
112
112
  }
113
- }), showDrop && React.createElement(DropContent, {
114
- top: showDrop.yValue,
115
- left: showDrop.xValue
113
+ }), showDrop && React.createElement("div", {
114
+ style: floatingStyles,
115
+ ref: refs.setFloating,
116
+ key: showDrop.type
116
117
  }, showDrop.type === 'personalization' && (renderDynamicContent === null || renderDynamicContent === void 0 ? void 0 : renderDynamicContent({
117
118
  dc: showDrop.path ? (_getDcByPath = getDcByPath(editor.children, showDrop.path)) === null || _getDcByPath === void 0 ? void 0 : _getDcByPath.dc : undefined,
118
119
  onChange: newDC => {
@@ -125,7 +126,8 @@ export const RichMessageEditor = ({
125
126
  } else {
126
127
  insertDynamicContent(editor, newDC);
127
128
  }
128
- }
129
+ },
130
+ update
129
131
  })), showDrop.type === 'emoji' && React.createElement(EmojiPicker, {
130
132
  onEmojiSelect: s => editor.insertText(s)
131
133
  })));
@@ -1,2 +1 @@
1
1
  export declare const ImSpan: import("styled-components").StyledComponent<"span", any, {}, never>;
2
- export declare const DropContentStyled: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -3,8 +3,4 @@ import { Color } from '@pushwoosh/kit-constants';
3
3
  export const ImSpan = styled.span.withConfig({
4
4
  displayName: "ImSpan",
5
5
  componentId: "sc-kdvgj9-0"
6
- })(["color:", ";position:relative;padding-left:20px;font-size:12px;font-style:normal;font-weight:500;line-height:130%;text-transform:uppercase;cursor:pointer;> svg{position:absolute;left:0;top:-1px;}"], Color.SOFT);
7
- export const DropContentStyled = styled.div.withConfig({
8
- displayName: "DropContentStyled",
9
- componentId: "sc-kdvgj9-1"
10
- })(["position:fixed;z-index:10;"]);
6
+ })(["color:", ";position:relative;padding-left:20px;font-size:12px;font-style:normal;font-weight:500;line-height:130%;text-transform:uppercase;cursor:pointer;> svg{position:absolute;left:0;top:-1px;}"], Color.SOFT);
@@ -1,9 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { DynamicContent } from './slate/types';
3
- type DropValueCommon = {
4
- xValue: number;
5
- yValue: number;
6
- };
7
3
  export type DropValuePersonalization = {
8
4
  type: 'personalization';
9
5
  path?: number[];
@@ -11,7 +7,12 @@ export type DropValuePersonalization = {
11
7
  export type DropValueEmoji = {
12
8
  type: 'emoji';
13
9
  };
14
- export type DropValue = DropValueCommon & DropValueEmoji | DropValueCommon & DropValuePersonalization;
10
+ export type DropValue = DropValueEmoji | DropValuePersonalization;
11
+ export type RenderDynamicContentProps = {
12
+ dc?: DynamicContent;
13
+ onChange: (newDC: DynamicContent) => void;
14
+ update: () => void;
15
+ };
15
16
  export type RichMessageEditorProps = {
16
17
  title: ReactNode;
17
18
  initialValue: string;
@@ -21,9 +22,5 @@ export type RichMessageEditorProps = {
21
22
  canUsePersonalization?: boolean;
22
23
  canUseEmoji?: boolean;
23
24
  onBlur?: () => void;
24
- renderDynamicContent?: (props: {
25
- dc?: DynamicContent;
26
- onChange: (newDC: DynamicContent) => void;
27
- }) => ReactNode;
25
+ renderDynamicContent?: (props: RenderDynamicContentProps) => ReactNode;
28
26
  };
29
- export {};
@@ -23,6 +23,9 @@ const DynamicContentElementComponent = ({
23
23
  event.preventDefault();
24
24
  event.stopPropagation();
25
25
  const [paragraphIndex, elementIndex] = findPath(editor.children, element);
26
+ Transforms.delete(editor, {
27
+ at: [paragraphIndex, elementIndex]
28
+ });
26
29
  if (selected) {
27
30
  var _editor$children$para;
28
31
  const prevOffset = ((_editor$children$para = editor.children[paragraphIndex].children[elementIndex - 1]) === null || _editor$children$para === void 0 ? void 0 : _editor$children$para.text.length) || 0;
@@ -35,9 +38,6 @@ const DynamicContentElementComponent = ({
35
38
  focus: point
36
39
  });
37
40
  }
38
- Transforms.delete(editor, {
39
- at: [paragraphIndex, elementIndex]
40
- });
41
41
  }
42
42
  }, React.createElement("span", null, tagName || 'Not set'), children);
43
43
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.0.61",
3
+ "version": "1.0.63",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -1,5 +0,0 @@
1
- import { type FC, type PropsWithChildren } from 'react';
2
- export declare const DropContent: FC<PropsWithChildren<{
3
- top: number;
4
- left: number;
5
- }>>;
@@ -1,14 +0,0 @@
1
- import React from 'react';
2
- import { DropContentStyled } from './RichMessageEditor.styled';
3
- export const DropContent = ({
4
- top,
5
- left,
6
- children
7
- }) => {
8
- return React.createElement(DropContentStyled, {
9
- style: {
10
- top,
11
- left
12
- }
13
- }, children);
14
- };