@toptal/picasso-rich-text-editor 100.0.6 → 100.0.7

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 +1 @@
1
- {"version":3,"file":"RichTextEditorEmojiPicker.d.ts","sourceRoot":"","sources":["../../../src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAErE,UAAU,KAAK;IACb,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACjC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAmBD,eAAO,MAAM,yBAAyB,+CAInC,KAAK,gBAwDP,CAAA"}
1
+ {"version":3,"file":"RichTextEditorEmojiPicker.d.ts","sourceRoot":"","sources":["../../../src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAErE,UAAU,KAAK;IACb,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACjC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAaD,eAAO,MAAM,yBAAyB,+CAInC,KAAK,gBA0DP,CAAA"}
@@ -2,15 +2,10 @@
2
2
  import React, { useEffect } from 'react';
3
3
  import data from '@emoji-mart/data';
4
4
  import Picker from '@emoji-mart/react';
5
- import cx from 'classnames';
6
5
  import { Container } from '@toptal/picasso-container';
6
+ import { twMerge } from '@toptal/picasso-tailwind-merge';
7
7
  import RichTextEditorButton from '../RichTextEditorButton';
8
8
  const TRIGGER_EMOJI_PICKER_ID = 'trigger-emoji-picker';
9
- const classes = {
10
- emojiPicker: 'absolute top-[34px] left-0 z-10 opacity-0 pointer-events-none',
11
- activeOpacity: 'opacity-100',
12
- activePointers: '[pointer-events:all]',
13
- };
14
9
  const handleEmojiPickerEscBehaviour = (event, setShowEmojiPicker) => {
15
10
  if (event.key === 'Escape') {
16
11
  setShowEmojiPicker(false);
@@ -43,7 +38,15 @@ export const RichTextEditorEmojiPicker = ({ customEmojis, onInsertEmoji, disable
43
38
  }, [showEmojiPicker, setShowEmojiPicker]);
44
39
  return (React.createElement(Container, { style: { position: 'relative' } },
45
40
  React.createElement(RichTextEditorButton, { onClick: handleEmojiPickerClick, icon: React.createElement(Container, { style: { pointerEvents: 'none' } }, "\uD83D\uDE42"), id: TRIGGER_EMOJI_PICKER_ID, disabled: disabled }),
46
- React.createElement(Container, { className: cx(classes.emojiPicker, showEmojiPicker && classes.activeOpacity, showEmojiPicker && classes.activePointers) },
41
+ React.createElement(Container
42
+ // twMerge drops the hidden-state classes when open; leaving
43
+ // `pointer-events-none` in place would let stylesheet order decide,
44
+ // and it wins, so clicks fall through the open picker to the editor
45
+ , {
46
+ // twMerge drops the hidden-state classes when open; leaving
47
+ // `pointer-events-none` in place would let stylesheet order decide,
48
+ // and it wins, so clicks fall through the open picker to the editor
49
+ className: twMerge('absolute top-[34px] left-0 z-10 opacity-0 pointer-events-none', showEmojiPicker && 'opacity-100 pointer-events-auto') },
47
50
  React.createElement(Picker, { data: data, custom: customEmojis, onEmojiSelect: handleEmojiInsert, onClickOutside: showEmojiPicker && closePicker }))));
48
51
  };
49
52
  //# sourceMappingURL=RichTextEditorEmojiPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextEditorEmojiPicker.js","sourceRoot":"","sources":["../../../src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACxC,OAAO,IAAI,MAAM,kBAAkB,CAAA;AACnC,OAAO,MAAM,MAAM,mBAAmB,CAAA;AACtC,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAErD,OAAO,oBAAoB,MAAM,yBAAyB,CAAA;AAS1D,MAAM,uBAAuB,GAAG,sBAAsB,CAAA;AAEtD,MAAM,OAAO,GAAG;IACd,WAAW,EAAE,+DAA+D;IAC5E,aAAa,EAAE,aAAa;IAC5B,cAAc,EAAE,sBAAsB;CACvC,CAAA;AAED,MAAM,6BAA6B,GAAG,CACpC,KAAoB,EACpB,kBAAiE,EACjE,EAAE;IACF,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC3B,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,EACxC,YAAY,EACZ,aAAa,EACb,QAAQ,GACF,EAAE,EAAE;IACV,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEnE,MAAM,sBAAsB,GAAG,GAAG,EAAE;QAClC,kBAAkB,CAAC,CAAC,eAAe,CAAC,CAAA;IACtC,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,CAAC,KAAY,EAAE,EAAE;QACzC,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAM;QACR,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YAC9C,6BAA6B,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjD,6BAA6B,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;YAC1D,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAA;IAEzC,OAAO,CACL,oBAAC,SAAS,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE;QACxC,oBAAC,oBAAoB,IACnB,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,oBAAC,SAAS,IAAC,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAgB,EACjE,EAAE,EAAE,uBAAuB,EAC3B,QAAQ,EAAE,QAAQ,GAClB;QACF,oBAAC,SAAS,IACR,SAAS,EAAE,EAAE,CACX,OAAO,CAAC,WAAW,EACnB,eAAe,IAAI,OAAO,CAAC,aAAa,EACxC,eAAe,IAAI,OAAO,CAAC,cAAc,CAC1C;YAED,oBAAC,MAAM,IACL,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,iBAAiB,EAChC,cAAc,EAAE,eAAe,IAAI,WAAW,GAC9C,CACQ,CACF,CACb,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"RichTextEditorEmojiPicker.js","sourceRoot":"","sources":["../../../src/RichTextEditorEmojiPicker/RichTextEditorEmojiPicker.tsx"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACxC,OAAO,IAAI,MAAM,kBAAkB,CAAA;AACnC,OAAO,MAAM,MAAM,mBAAmB,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,oBAAoB,MAAM,yBAAyB,CAAA;AAS1D,MAAM,uBAAuB,GAAG,sBAAsB,CAAA;AAEtD,MAAM,6BAA6B,GAAG,CACpC,KAAoB,EACpB,kBAAiE,EACjE,EAAE;IACF,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC3B,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,EACxC,YAAY,EACZ,aAAa,EACb,QAAQ,GACF,EAAE,EAAE;IACV,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEnE,MAAM,sBAAsB,GAAG,GAAG,EAAE;QAClC,kBAAkB,CAAC,CAAC,eAAe,CAAC,CAAA;IACtC,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,CAAC,KAAY,EAAE,EAAE;QACzC,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAM;QACR,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YAC9C,6BAA6B,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;QAC1D,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjD,6BAA6B,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;YAC1D,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAA;IAEzC,OAAO,CACL,oBAAC,SAAS,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE;QACxC,oBAAC,oBAAoB,IACnB,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,oBAAC,SAAS,IAAC,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAgB,EACjE,EAAE,EAAE,uBAAuB,EAC3B,QAAQ,EAAE,QAAQ,GAClB;QACF,oBAAC,SAAS;QACR,4DAA4D;QAC5D,oEAAoE;QACpE,oEAAoE;;YAFpE,4DAA4D;YAC5D,oEAAoE;YACpE,oEAAoE;YACpE,SAAS,EAAE,OAAO,CAChB,+DAA+D,EAC/D,eAAe,IAAI,iCAAiC,CACrD;YAED,oBAAC,MAAM,IACL,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,iBAAiB,EAChC,cAAc,EAAE,eAAe,IAAI,WAAW,GAC9C,CACQ,CACF,CACb,CAAA;AACH,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/picasso-rich-text-editor",
3
- "version": "100.0.6",
3
+ "version": "100.0.7",
4
4
  "description": "Picasso rich text editor",
5
5
  "author": "Toptal",
6
6
  "homepage": "https://github.com/toptal/picasso/tree/master/packages/picasso-rich-text-editor#readme",
@@ -28,8 +28,8 @@
28
28
  "react-dom": ">=17.0.0 < 19.0.0",
29
29
  "typescript": "^5.5.0",
30
30
  "@toptal/picasso-shared": "^100.1.0",
31
- "@toptal/picasso-tailwind-merge": "^100.0.0",
32
- "@toptal/picasso-tailwind": "^100.0.0"
31
+ "@toptal/picasso-tailwind": "^100.0.0",
32
+ "@toptal/picasso-tailwind-merge": "^100.0.0"
33
33
  },
34
34
  "dependencies": {
35
35
  "@emoji-mart/data": "^1.2.1",
@@ -45,17 +45,17 @@
45
45
  "hast-util-to-html": "^7.1.3",
46
46
  "lexical": "0.11.3",
47
47
  "@toptal/picasso-container": "100.0.1",
48
- "@toptal/picasso-button": "100.0.2",
49
48
  "@toptal/picasso-icons": "100.0.1",
50
- "@toptal/picasso-file-input": "100.0.3",
49
+ "@toptal/picasso-button": "100.0.2",
51
50
  "@toptal/picasso-image": "100.0.1",
51
+ "@toptal/picasso-file-input": "100.0.3",
52
52
  "@toptal/picasso-outlined-input": "100.0.2",
53
53
  "@toptal/picasso-list": "100.0.1",
54
54
  "@toptal/picasso-link": "100.0.1",
55
55
  "@toptal/picasso-select": "100.0.3",
56
- "@toptal/picasso-input-adornment": "100.0.1",
57
56
  "@toptal/picasso-typography": "100.0.1",
58
57
  "@toptal/picasso-modal": "100.1.2",
58
+ "@toptal/picasso-input-adornment": "100.0.1",
59
59
  "@toptal/picasso-form": "100.0.2",
60
60
  "@toptal/picasso-input": "100.0.2",
61
61
  "@toptal/picasso-utils": "100.0.1"
@@ -65,8 +65,8 @@
65
65
  "jsdom": "^26.1.0",
66
66
  "@testing-library/react-hooks": "^8.0.1",
67
67
  "@types/classnames": "^2.3.1",
68
- "@toptal/picasso-test-utils": "100.1.0",
69
- "@toptal/picasso-tailwind-merge": "100.0.0"
68
+ "@toptal/picasso-tailwind-merge": "100.0.0",
69
+ "@toptal/picasso-test-utils": "100.1.0"
70
70
  },
71
71
  "sideEffects": false,
72
72
  "exports": {
@@ -0,0 +1,38 @@
1
+ import React from 'react'
2
+ import { fireEvent, render, screen } from '@toptal/picasso-test-utils'
3
+
4
+ import { RichTextEditorEmojiPicker } from './RichTextEditorEmojiPicker'
5
+
6
+ const renderEmojiPicker = () =>
7
+ render(<RichTextEditorEmojiPicker onInsertEmoji={jest.fn()} />)
8
+
9
+ // The wrapper that shows and hides the picker sits two levels above the
10
+ // emoji-mart element: wrapper > EmojiMartPicker's div > em-emoji-picker
11
+ const getPickerWrapper = (container: HTMLElement) =>
12
+ container.querySelector('em-emoji-picker')?.parentElement
13
+ ?.parentElement as HTMLElement
14
+
15
+ describe('RichTextEditorEmojiPicker', () => {
16
+ it('keeps the picker hidden and click-through until opened', () => {
17
+ const { container } = renderEmojiPicker()
18
+
19
+ const wrapper = getPickerWrapper(container)
20
+
21
+ expect(wrapper).toHaveClass('opacity-0', 'pointer-events-none')
22
+ expect(wrapper).not.toHaveClass('pointer-events-auto')
23
+ })
24
+
25
+ it('opens the picker with pointer events on, so emoji clicks reach it', () => {
26
+ const { container } = renderEmojiPicker()
27
+
28
+ fireEvent.click(screen.getByRole('button'))
29
+
30
+ const wrapper = getPickerWrapper(container)
31
+
32
+ expect(wrapper).toHaveClass('opacity-100', 'pointer-events-auto')
33
+ // a leftover `pointer-events-none` wins on stylesheet order and swallows
34
+ // every click on the open picker
35
+ expect(wrapper).not.toHaveClass('pointer-events-none')
36
+ expect(wrapper).not.toHaveClass('opacity-0')
37
+ })
38
+ })
@@ -2,8 +2,8 @@
2
2
  import React, { useEffect } from 'react'
3
3
  import data from '@emoji-mart/data'
4
4
  import Picker from '@emoji-mart/react'
5
- import cx from 'classnames'
6
5
  import { Container } from '@toptal/picasso-container'
6
+ import { twMerge } from '@toptal/picasso-tailwind-merge'
7
7
 
8
8
  import RichTextEditorButton from '../RichTextEditorButton'
9
9
  import type { CustomEmojiGroup, Emoji } from '../plugins/EmojiPlugin'
@@ -16,12 +16,6 @@ interface Props {
16
16
 
17
17
  const TRIGGER_EMOJI_PICKER_ID = 'trigger-emoji-picker'
18
18
 
19
- const classes = {
20
- emojiPicker: 'absolute top-[34px] left-0 z-10 opacity-0 pointer-events-none',
21
- activeOpacity: 'opacity-100',
22
- activePointers: '[pointer-events:all]',
23
- }
24
-
25
19
  const handleEmojiPickerEscBehaviour = (
26
20
  event: KeyboardEvent,
27
21
  setShowEmojiPicker: React.Dispatch<React.SetStateAction<boolean>>
@@ -76,10 +70,12 @@ export const RichTextEditorEmojiPicker = ({
76
70
  disabled={disabled}
77
71
  />
78
72
  <Container
79
- className={cx(
80
- classes.emojiPicker,
81
- showEmojiPicker && classes.activeOpacity,
82
- showEmojiPicker && classes.activePointers
73
+ // twMerge drops the hidden-state classes when open; leaving
74
+ // `pointer-events-none` in place would let stylesheet order decide,
75
+ // and it wins, so clicks fall through the open picker to the editor
76
+ className={twMerge(
77
+ 'absolute top-[34px] left-0 z-10 opacity-0 pointer-events-none',
78
+ showEmojiPicker && 'opacity-100 pointer-events-auto'
83
79
  )}
84
80
  >
85
81
  <Picker