@pega/cosmos-react-rte 9.33.1 → 9.34.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 (28) hide show
  1. package/lib/components/Editor/Toolbar/AlignmentSelect.d.ts.map +1 -1
  2. package/lib/components/Editor/Toolbar/AlignmentSelect.js +12 -9
  3. package/lib/components/Editor/Toolbar/AlignmentSelect.js.map +1 -1
  4. package/lib/components/Editor/Toolbar/AnchorButton.d.ts.map +1 -1
  5. package/lib/components/Editor/Toolbar/AnchorButton.js +37 -18
  6. package/lib/components/Editor/Toolbar/AnchorButton.js.map +1 -1
  7. package/lib/components/Editor/Toolbar/ColorPickerButton.d.ts.map +1 -1
  8. package/lib/components/Editor/Toolbar/ColorPickerButton.js +22 -11
  9. package/lib/components/Editor/Toolbar/ColorPickerButton.js.map +1 -1
  10. package/lib/components/Editor/Toolbar/FontFamilySelect.d.ts.map +1 -1
  11. package/lib/components/Editor/Toolbar/FontFamilySelect.js +11 -8
  12. package/lib/components/Editor/Toolbar/FontFamilySelect.js.map +1 -1
  13. package/lib/components/Editor/Toolbar/FontSizeSelect.d.ts.map +1 -1
  14. package/lib/components/Editor/Toolbar/FontSizeSelect.js +11 -8
  15. package/lib/components/Editor/Toolbar/FontSizeSelect.js.map +1 -1
  16. package/lib/components/Editor/Toolbar/TableButton.d.ts.map +1 -1
  17. package/lib/components/Editor/Toolbar/TableButton.js +71 -37
  18. package/lib/components/Editor/Toolbar/TableButton.js.map +1 -1
  19. package/lib/components/Editor/Toolbar/TextSelect.d.ts.map +1 -1
  20. package/lib/components/Editor/Toolbar/TextSelect.js +12 -9
  21. package/lib/components/Editor/Toolbar/TextSelect.js.map +1 -1
  22. package/lib/components/RichTextEditor/Toolbar/AnchorButton.d.ts.map +1 -1
  23. package/lib/components/RichTextEditor/Toolbar/AnchorButton.js +51 -36
  24. package/lib/components/RichTextEditor/Toolbar/AnchorButton.js.map +1 -1
  25. package/lib/components/RichTextEditor/Toolbar/TextSelect.d.ts.map +1 -1
  26. package/lib/components/RichTextEditor/Toolbar/TextSelect.js +14 -9
  27. package/lib/components/RichTextEditor/Toolbar/TextSelect.js.map +1 -1
  28. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"AlignmentSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AlignmentSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAsD3D,UAAU,oBAAoB;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,eAAe,GAAI,0BAA0B,oBAAoB,4CAwJtE,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"AlignmentSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AlignmentSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAwD3D,UAAU,oBAAoB;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,eAAe,GAAI,0BAA0B,oBAAoB,4CAyKtE,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect, useCallback } from 'react';
3
3
  import styled, { css } from 'styled-components';
4
- import { Popover, Icon, registerIcon, useOuterEvent, Menu, Button, defaultThemeProp, useI18n, Tooltip, isInstance } from '@pega/cosmos-react-core';
4
+ import { Popover, TouchDialog, Icon, registerIcon, useOuterEvent, Menu, Button, defaultThemeProp, useI18n, Tooltip, isInstance, isTouchDevice } from '@pega/cosmos-react-core';
5
5
  import * as arrowMicroDownIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-micro-down.icon';
6
6
  import * as alignLeftIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-left.icon';
7
7
  import * as alignCenterIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-center.icon';
@@ -39,7 +39,8 @@ const AlignmentSelect = ({ editor, ...restProps }) => {
39
39
  const buttonRef = useRef(null);
40
40
  const popoverRef = useRef(null);
41
41
  const menuRef = useRef(null);
42
- useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef], () => {
42
+ const touchDialogRef = useRef(null);
43
+ useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef, touchDialogRef], () => {
43
44
  setOpen(false);
44
45
  });
45
46
  const handleEscapeClose = useCallback(() => {
@@ -92,6 +93,12 @@ const AlignmentSelect = ({ editor, ...restProps }) => {
92
93
  const alignment = ALIGNMENTS.find(a => a.id === activeAlignment);
93
94
  return alignment ? t(alignment.labelKey) : t('rte_align_left');
94
95
  };
96
+ const menuContent = (_jsx(Menu, { items: ALIGNMENTS.map(({ id, icon, labelKey }) => ({
97
+ id,
98
+ primary: t(labelKey),
99
+ visual: _jsx(Icon, { name: icon }),
100
+ selected: id === activeAlignment
101
+ })), focusControlEl: isTouchDevice ? undefined : buttonRef.current ?? undefined, mode: 'single-select', ref: menuRef, onItemClick: onAlignmentSelect }));
95
102
  return (_jsxs(_Fragment, { children: [_jsxs(StyledAlignmentSelect, { ...restProps, variant: 'simple', type: 'button', icon: false, ref: buttonRef, "data-toolbar-item": 'true', onMouseDown: (e) => {
96
103
  e.preventDefault();
97
104
  if (!open) {
@@ -123,15 +130,11 @@ const AlignmentSelect = ({ editor, ...restProps }) => {
123
130
  if (isInstance(relatedTarget, Node) &&
124
131
  !buttonRef.current?.contains(relatedTarget) &&
125
132
  !popoverRef.current?.contains(relatedTarget) &&
126
- !menuRef.current?.contains(relatedTarget)) {
133
+ !menuRef.current?.contains(relatedTarget) &&
134
+ !touchDialogRef.current?.contains(relatedTarget)) {
127
135
  setOpen(false);
128
136
  }
129
- }, onClick: (e) => e.stopPropagation(), "aria-expanded": open, "aria-label": `${t('rte_alignment')}. ${getActiveLabel()} ${t('selected').toLocaleLowerCase()}`, "aria-haspopup": true, children: [_jsx(Icon, { name: getActiveIcon() }), _jsx(Icon, { name: 'arrow-micro-down' })] }), buttonRef.current && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: t('rte_alignment') })), _jsx(Popover, { show: open, as: StyledSelectMenu, target: buttonRef.current, placement: 'bottom-start', ref: popoverRef, children: _jsx(Menu, { items: ALIGNMENTS.map(({ id, icon, labelKey }) => ({
130
- id,
131
- primary: t(labelKey),
132
- visual: _jsx(Icon, { name: icon }),
133
- selected: id === activeAlignment
134
- })), focusControlEl: buttonRef.current ?? undefined, mode: 'single-select', ref: menuRef, onItemClick: onAlignmentSelect }) })] }));
137
+ }, onClick: (e) => e.stopPropagation(), "aria-expanded": open, "aria-label": `${t('rte_alignment')}. ${getActiveLabel()} ${t('selected').toLocaleLowerCase()}`, "aria-haspopup": true, children: [_jsx(Icon, { name: getActiveIcon() }), _jsx(Icon, { name: 'arrow-micro-down' })] }), buttonRef.current && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: t('rte_alignment') })), isTouchDevice ? (_jsx(TouchDialog, { ref: touchDialogRef, open: open, heading: t('rte_alignment'), onDismiss: () => setOpen(false), children: menuContent })) : (_jsx(Popover, { show: open, as: StyledSelectMenu, target: buttonRef.current, placement: 'bottom-start', ref: popoverRef, children: menuContent }))] }));
135
138
  };
136
139
  export default AlignmentSelect;
137
140
  //# sourceMappingURL=AlignmentSelect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AlignmentSelect.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AlignmentSelect.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState, useEffect, useCallback } from 'react';\nimport type { MouseEvent, KeyboardEvent, FocusEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport styled, { css } from 'styled-components';\n\nimport {\n Popover,\n Icon,\n registerIcon,\n useOuterEvent,\n Menu,\n Button,\n defaultThemeProp,\n useI18n,\n Tooltip,\n isInstance\n} from '@pega/cosmos-react-core';\nimport type { TranslationPack } from '@pega/cosmos-react-core';\nimport * as arrowMicroDownIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-micro-down.icon';\nimport * as alignLeftIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-left.icon';\nimport * as alignCenterIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-center.icon';\nimport * as alignRightIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-right.icon';\n\nimport useEscapeKey from '../hooks/useEscapeKey';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nregisterIcon(arrowMicroDownIcon, alignLeftIcon, alignCenterIcon, alignRightIcon);\n\nconst StyledAlignmentSelect = styled(Button)(({ theme }) => {\n return css`\n color: ${theme.base.palette['foreground-color']};\n display: inline-flex;\n align-items: center;\n height: calc(3.5 * ${theme.base.spacing});\n padding: 0 calc(0.5 * ${theme.base.spacing});\n `;\n});\n\nStyledAlignmentSelect.defaultProps = defaultThemeProp;\n\nconst StyledSelectMenu = styled.div(({ theme }) => {\n return css`\n min-width: calc(20 * ${theme.base.spacing});\n `;\n});\n\nStyledSelectMenu.defaultProps = defaultThemeProp;\n\ntype AlignmentOption = 'left' | 'center' | 'right';\n\nconst ALIGNMENTS: { id: AlignmentOption; icon: string; labelKey: keyof TranslationPack }[] = [\n { id: 'left', icon: 'align-left', labelKey: 'rte_align_left' },\n { id: 'center', icon: 'align-center', labelKey: 'rte_align_center' },\n { id: 'right', icon: 'align-right', labelKey: 'rte_align_right' }\n];\n\ninterface AlignmentSelectProps {\n editor: TiptapEditor;\n 'data-testid'?: string;\n}\n\nconst AlignmentSelect = ({ editor, ...restProps }: AlignmentSelectProps) => {\n const t = useI18n();\n const [open, setOpen] = useState(false);\n const [activeAlignment, setActiveAlignment] = useState<AlignmentOption>('left');\n const selecting = useRef(false);\n const openedByClick = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n\n useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef], () => {\n setOpen(false);\n });\n\n const handleEscapeClose = useCallback(() => {\n setOpen(false);\n buttonRef.current?.focus();\n }, []);\n\n useEscapeKey(open, handleEscapeClose, editor);\n useCloseOnEditorClick(open, handleEscapeClose);\n\n const updateActiveAlignment = useCallback(() => {\n if (editor.isActive({ textAlign: 'center' })) {\n setActiveAlignment('center');\n } else if (editor.isActive({ textAlign: 'right' })) {\n setActiveAlignment('right');\n } else {\n setActiveAlignment('left');\n }\n }, [editor]);\n\n useEffect(() => {\n updateActiveAlignment();\n editor.on('selectionUpdate', updateActiveAlignment);\n editor.on('transaction', updateActiveAlignment);\n return () => {\n editor.off('selectionUpdate', updateActiveAlignment);\n editor.off('transaction', updateActiveAlignment);\n };\n }, [editor, updateActiveAlignment]);\n\n const onAlignmentSelect = (alignmentId: string, e: MouseEvent<Element>) => {\n e.stopPropagation();\n e.preventDefault();\n\n editor.chain().focus().setTextAlign(alignmentId).run();\n\n if (!openedByClick.current) {\n buttonRef.current?.focus();\n }\n setOpen(false);\n selecting.current = true;\n setTimeout(() => {\n selecting.current = false;\n if (!editor.isFocused && openedByClick.current) {\n editor.commands.focus();\n }\n }, 0);\n };\n\n const getActiveIcon = () => {\n const alignment = ALIGNMENTS.find(a => a.id === activeAlignment);\n return alignment?.icon || 'align-left';\n };\n\n const getActiveLabel = () => {\n const alignment = ALIGNMENTS.find(a => a.id === activeAlignment);\n return alignment ? t(alignment.labelKey) : t('rte_align_left');\n };\n\n return (\n <>\n <StyledAlignmentSelect\n {...restProps}\n variant='simple'\n type='button'\n icon={false}\n ref={buttonRef}\n data-toolbar-item='true'\n onMouseDown={(e: MouseEvent) => {\n e.preventDefault();\n if (!open) {\n openedByClick.current = true;\n }\n setOpen(!open);\n }}\n onKeyDown={(e: KeyboardEvent) => {\n if (e.key === 'Enter' && !selecting.current) {\n e.preventDefault();\n setOpen(true);\n openedByClick.current = false;\n } else if (e.key === 'Enter') {\n e.preventDefault();\n selecting.current = false;\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n setOpen(false);\n } else if (e.key === 'Escape' && open) {\n e.preventDefault();\n setOpen(false);\n }\n }}\n onFocus={(e: FocusEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onBlur={(e: FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverRef.current?.contains(relatedTarget) &&\n !menuRef.current?.contains(relatedTarget)\n ) {\n setOpen(false);\n }\n }}\n onClick={(e: MouseEvent) => e.stopPropagation()}\n aria-expanded={open}\n aria-label={`${t('rte_alignment')}. ${getActiveLabel()} ${t('selected').toLocaleLowerCase()}`}\n aria-haspopup\n >\n <Icon name={getActiveIcon()} />\n <Icon name='arrow-micro-down' />\n </StyledAlignmentSelect>\n {buttonRef.current && (\n <Tooltip target={buttonRef.current} showDelay='none' hideDelay='none'>\n {t('rte_alignment')}\n </Tooltip>\n )}\n <Popover\n show={open}\n as={StyledSelectMenu}\n target={buttonRef.current}\n placement='bottom-start'\n ref={popoverRef}\n >\n <Menu\n items={ALIGNMENTS.map(({ id, icon, labelKey }) => ({\n id,\n primary: t(labelKey),\n visual: <Icon name={icon} />,\n selected: id === activeAlignment\n }))}\n focusControlEl={buttonRef.current ?? undefined}\n mode='single-select'\n ref={menuRef}\n onItemClick={onAlignmentSelect}\n />\n </Popover>\n </>\n );\n};\n\nexport default AlignmentSelect;\n"]}
1
+ {"version":3,"file":"AlignmentSelect.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AlignmentSelect.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState, useEffect, useCallback } from 'react';\nimport type { MouseEvent, KeyboardEvent, FocusEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport styled, { css } from 'styled-components';\n\nimport {\n Popover,\n TouchDialog,\n Icon,\n registerIcon,\n useOuterEvent,\n Menu,\n Button,\n defaultThemeProp,\n useI18n,\n Tooltip,\n isInstance,\n isTouchDevice\n} from '@pega/cosmos-react-core';\nimport type { TranslationPack } from '@pega/cosmos-react-core';\nimport * as arrowMicroDownIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-micro-down.icon';\nimport * as alignLeftIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-left.icon';\nimport * as alignCenterIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-center.icon';\nimport * as alignRightIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/align-right.icon';\n\nimport useEscapeKey from '../hooks/useEscapeKey';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nregisterIcon(arrowMicroDownIcon, alignLeftIcon, alignCenterIcon, alignRightIcon);\n\nconst StyledAlignmentSelect = styled(Button)(({ theme }) => {\n return css`\n color: ${theme.base.palette['foreground-color']};\n display: inline-flex;\n align-items: center;\n height: calc(3.5 * ${theme.base.spacing});\n padding: 0 calc(0.5 * ${theme.base.spacing});\n `;\n});\n\nStyledAlignmentSelect.defaultProps = defaultThemeProp;\n\nconst StyledSelectMenu = styled.div(({ theme }) => {\n return css`\n min-width: calc(20 * ${theme.base.spacing});\n `;\n});\n\nStyledSelectMenu.defaultProps = defaultThemeProp;\n\ntype AlignmentOption = 'left' | 'center' | 'right';\n\nconst ALIGNMENTS: { id: AlignmentOption; icon: string; labelKey: keyof TranslationPack }[] = [\n { id: 'left', icon: 'align-left', labelKey: 'rte_align_left' },\n { id: 'center', icon: 'align-center', labelKey: 'rte_align_center' },\n { id: 'right', icon: 'align-right', labelKey: 'rte_align_right' }\n];\n\ninterface AlignmentSelectProps {\n editor: TiptapEditor;\n 'data-testid'?: string;\n}\n\nconst AlignmentSelect = ({ editor, ...restProps }: AlignmentSelectProps) => {\n const t = useI18n();\n const [open, setOpen] = useState(false);\n const [activeAlignment, setActiveAlignment] = useState<AlignmentOption>('left');\n const selecting = useRef(false);\n const openedByClick = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const touchDialogRef = useRef<HTMLDivElement>(null);\n\n useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef, touchDialogRef], () => {\n setOpen(false);\n });\n\n const handleEscapeClose = useCallback(() => {\n setOpen(false);\n buttonRef.current?.focus();\n }, []);\n\n useEscapeKey(open, handleEscapeClose, editor);\n useCloseOnEditorClick(open, handleEscapeClose);\n\n const updateActiveAlignment = useCallback(() => {\n if (editor.isActive({ textAlign: 'center' })) {\n setActiveAlignment('center');\n } else if (editor.isActive({ textAlign: 'right' })) {\n setActiveAlignment('right');\n } else {\n setActiveAlignment('left');\n }\n }, [editor]);\n\n useEffect(() => {\n updateActiveAlignment();\n editor.on('selectionUpdate', updateActiveAlignment);\n editor.on('transaction', updateActiveAlignment);\n return () => {\n editor.off('selectionUpdate', updateActiveAlignment);\n editor.off('transaction', updateActiveAlignment);\n };\n }, [editor, updateActiveAlignment]);\n\n const onAlignmentSelect = (alignmentId: string, e: MouseEvent<Element>) => {\n e.stopPropagation();\n e.preventDefault();\n\n editor.chain().focus().setTextAlign(alignmentId).run();\n\n if (!openedByClick.current) {\n buttonRef.current?.focus();\n }\n setOpen(false);\n selecting.current = true;\n setTimeout(() => {\n selecting.current = false;\n if (!editor.isFocused && openedByClick.current) {\n editor.commands.focus();\n }\n }, 0);\n };\n\n const getActiveIcon = () => {\n const alignment = ALIGNMENTS.find(a => a.id === activeAlignment);\n return alignment?.icon || 'align-left';\n };\n\n const getActiveLabel = () => {\n const alignment = ALIGNMENTS.find(a => a.id === activeAlignment);\n return alignment ? t(alignment.labelKey) : t('rte_align_left');\n };\n\n const menuContent = (\n <Menu\n items={ALIGNMENTS.map(({ id, icon, labelKey }) => ({\n id,\n primary: t(labelKey),\n visual: <Icon name={icon} />,\n selected: id === activeAlignment\n }))}\n focusControlEl={isTouchDevice ? undefined : buttonRef.current ?? undefined}\n mode='single-select'\n ref={menuRef}\n onItemClick={onAlignmentSelect}\n />\n );\n\n return (\n <>\n <StyledAlignmentSelect\n {...restProps}\n variant='simple'\n type='button'\n icon={false}\n ref={buttonRef}\n data-toolbar-item='true'\n onMouseDown={(e: MouseEvent) => {\n e.preventDefault();\n if (!open) {\n openedByClick.current = true;\n }\n setOpen(!open);\n }}\n onKeyDown={(e: KeyboardEvent) => {\n if (e.key === 'Enter' && !selecting.current) {\n e.preventDefault();\n setOpen(true);\n openedByClick.current = false;\n } else if (e.key === 'Enter') {\n e.preventDefault();\n selecting.current = false;\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n setOpen(false);\n } else if (e.key === 'Escape' && open) {\n e.preventDefault();\n setOpen(false);\n }\n }}\n onFocus={(e: FocusEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onBlur={(e: FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverRef.current?.contains(relatedTarget) &&\n !menuRef.current?.contains(relatedTarget) &&\n !touchDialogRef.current?.contains(relatedTarget)\n ) {\n setOpen(false);\n }\n }}\n onClick={(e: MouseEvent) => e.stopPropagation()}\n aria-expanded={open}\n aria-label={`${t('rte_alignment')}. ${getActiveLabel()} ${t('selected').toLocaleLowerCase()}`}\n aria-haspopup\n >\n <Icon name={getActiveIcon()} />\n <Icon name='arrow-micro-down' />\n </StyledAlignmentSelect>\n {buttonRef.current && (\n <Tooltip target={buttonRef.current} showDelay='none' hideDelay='none'>\n {t('rte_alignment')}\n </Tooltip>\n )}\n {isTouchDevice ? (\n <TouchDialog\n ref={touchDialogRef}\n open={open}\n heading={t('rte_alignment')}\n onDismiss={() => setOpen(false)}\n >\n {menuContent}\n </TouchDialog>\n ) : (\n <Popover\n show={open}\n as={StyledSelectMenu}\n target={buttonRef.current}\n placement='bottom-start'\n ref={popoverRef}\n >\n {menuContent}\n </Popover>\n )}\n </>\n );\n};\n\nexport default AlignmentSelect;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AnchorButton.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AnchorButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAiB3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAU5D,UAAU,iBAAiB;IACzB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,GAAI,+BAA+B,iBAAiB,GAAG,YAAY,4CAwTpF,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"AnchorButton.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AnchorButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAqB3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA6B5D,UAAU,iBAAiB;IACzB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,GAAI,+BAA+B,iBAAiB,GAAG,YAAY,4CAyUpF,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1,15 +1,32 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect, useLayoutEffect, useCallback } from 'react';
3
- import { Button, CardContent, Grid, Icon, registerIcon, Input, useOuterEvent, Form, useI18n, Text, useElement, useEscape, isInstance } from '@pega/cosmos-react-core';
3
+ import styled from 'styled-components';
4
+ import { Button, CardContent, Grid, Icon, registerIcon, Input, useOuterEvent, Form, useI18n, Text, useElement, useEscape, isInstance, TouchDialog, isTouchDevice, defaultThemeProp } from '@pega/cosmos-react-core';
4
5
  import * as chainIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/chain.icon';
5
6
  import ToolbarButton from '../../RichTextEditor/Toolbar/ToolbarButton';
6
7
  import { getKeyCommand } from '../../RichTextEditor/Toolbar/utils';
7
8
  import { StyledEditPopover } from '../Editor.styles';
8
9
  import useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';
9
10
  registerIcon(chainIcon);
11
+ const StyledTouchDialogContent = styled(CardContent)(({ theme }) => `
12
+ flex: 1;
13
+
14
+ > div {
15
+ display: flex;
16
+ flex-direction: column;
17
+ min-height: 100%;
18
+ }
19
+
20
+ > div > div:not([aria-hidden='true']):nth-last-child(2) {
21
+ margin-top: auto;
22
+ padding-block-end: ${theme.base.spacing};
23
+ }
24
+ `);
25
+ StyledTouchDialogContent.defaultProps = defaultThemeProp;
10
26
  const AnchorButton = ({ osx, editor, ...restProps }) => {
11
27
  const t = useI18n();
12
28
  const buttonRef = useRef(null);
29
+ const touchDialogRef = useRef(null);
13
30
  const [textInputEl, setTextInputEl] = useElement();
14
31
  const [urlInputEl, setUrlInputEl] = useElement();
15
32
  const [popoverEl, setPopoverEl] = useElement();
@@ -37,7 +54,7 @@ const AnchorButton = ({ osx, editor, ...restProps }) => {
37
54
  setAnchorMenu(false);
38
55
  originalSelectionRef.current = null;
39
56
  }, []);
40
- useOuterEvent('mousedown', [popoverEl, buttonRef], () => {
57
+ useOuterEvent('mousedown', [popoverEl, buttonRef, touchDialogRef], () => {
41
58
  if (anchorMenu) {
42
59
  resetMenu();
43
60
  }
@@ -202,6 +219,21 @@ const AnchorButton = ({ osx, editor, ...restProps }) => {
202
219
  urlInputEl?.removeEventListener('keydown', onKeyDown);
203
220
  };
204
221
  }, [textInputEl, urlInputEl]);
222
+ const linkFormContent = (_jsx(Form, { as: 'div', actions: _jsxs(_Fragment, { children: [_jsx(Button, { variant: 'secondary', onClick: cancelAnchorCreation, type: 'button', children: t('cancel') }), _jsx(Button, { variant: 'primary', disabled: !url || !urlMatch, onClick: (e) => {
223
+ e.preventDefault();
224
+ createLink();
225
+ }, children: t('apply') })] }), children: _jsxs(Grid, { container: { rowGap: 2 }, children: [_jsx(Input, { label: t('rte_link_text'), value: linkText, onClick: preventDef, onChange: (e) => {
226
+ setLinkText(e.target.value);
227
+ }, ref: setTextInputEl }), _jsx(Input, { label: t('rte_link_url'), value: url, onClick: preventDef, onChange: (e) => {
228
+ const urlInput = e.target.value;
229
+ setUrl(urlInput);
230
+ // Clear error while typing, validate on blur
231
+ if (!urlMatch) {
232
+ setUrlMatch(true);
233
+ }
234
+ }, onBlur: () => {
235
+ setUrlMatch(!url || isValidUrl(url));
236
+ }, info: url && !urlMatch ? t('rte_invalid_url') : '', status: url && !urlMatch ? 'error' : undefined, ref: setUrlInputEl })] }) }));
205
237
  return (_jsxs(_Fragment, { children: [_jsx(ToolbarButton, { ref: buttonRef, onMouseDown: e => {
206
238
  e.preventDefault();
207
239
  openMenu();
@@ -214,24 +246,11 @@ const AnchorButton = ({ osx, editor, ...restProps }) => {
214
246
  const { relatedTarget } = e;
215
247
  if (isInstance(relatedTarget, Node) &&
216
248
  !buttonRef.current?.contains(relatedTarget) &&
217
- !popoverEl?.contains(relatedTarget)) {
249
+ !popoverEl?.contains(relatedTarget) &&
250
+ !touchDialogRef.current?.contains(relatedTarget)) {
218
251
  resetMenu();
219
252
  }
220
- }, active: isLinkActive(), tooltip: tooltip, label: t('rte_link'), ...restProps, children: _jsx(Icon, { name: 'chain' }) }), _jsx(StyledEditPopover, { show: anchorMenu, target: buttonRef.current, ref: setPopoverEl, placement: 'bottom', children: _jsx(CardContent, { children: _jsx(Form, { as: 'div', actions: _jsxs(_Fragment, { children: [_jsx(Button, { variant: 'secondary', onClick: cancelAnchorCreation, type: 'button', children: t('cancel') }), _jsx(Button, { variant: 'primary', disabled: !url || !urlMatch, onClick: (e) => {
221
- e.preventDefault();
222
- createLink();
223
- }, children: t('apply') })] }), children: _jsxs(Grid, { container: { rowGap: 2 }, children: [_jsx(Text, { variant: 'h2', children: t('rte_add_link') }), _jsx(Input, { label: t('rte_link_text'), value: linkText, onClick: preventDef, onChange: (e) => {
224
- setLinkText(e.target.value);
225
- }, ref: setTextInputEl }), _jsx(Input, { label: t('rte_link_url'), value: url, onClick: preventDef, onChange: (e) => {
226
- const urlInput = e.target.value;
227
- setUrl(urlInput);
228
- // Clear error while typing, validate on blur
229
- if (!urlMatch) {
230
- setUrlMatch(true);
231
- }
232
- }, onBlur: () => {
233
- setUrlMatch(!url || isValidUrl(url));
234
- }, info: url && !urlMatch ? t('rte_invalid_url') : '', status: url && !urlMatch ? 'error' : undefined, ref: setUrlInputEl })] }) }) }) })] }));
253
+ }, active: isLinkActive(), tooltip: tooltip, label: t('rte_link'), ...restProps, children: _jsx(Icon, { name: 'chain' }) }), isTouchDevice ? (_jsx(TouchDialog, { ref: touchDialogRef, open: anchorMenu, heading: t('rte_add_link'), onDismiss: () => cancelAnchorCreation(), children: _jsx(StyledTouchDialogContent, { children: linkFormContent }) })) : (_jsx(StyledEditPopover, { show: anchorMenu, target: buttonRef.current, ref: setPopoverEl, placement: 'bottom', children: _jsxs(CardContent, { children: [_jsx(Text, { variant: 'h2', children: t('rte_add_link') }), linkFormContent] }) }))] }));
235
254
  };
236
255
  export default AnchorButton;
237
256
  //# sourceMappingURL=AnchorButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnchorButton.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AnchorButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState, useEffect, useLayoutEffect, useCallback } from 'react';\nimport type { ChangeEvent, MouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\n\nimport {\n Button,\n CardContent,\n Grid,\n Icon,\n registerIcon,\n Input,\n useOuterEvent,\n Form,\n useI18n,\n Text,\n useElement,\n useEscape,\n isInstance\n} from '@pega/cosmos-react-core';\nimport type { ForwardProps } from '@pega/cosmos-react-core';\nimport * as chainIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/chain.icon';\n\nimport ToolbarButton from '../../RichTextEditor/Toolbar/ToolbarButton';\nimport { getKeyCommand } from '../../RichTextEditor/Toolbar/utils';\nimport { StyledEditPopover } from '../Editor.styles';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nregisterIcon(chainIcon);\n\ninterface AnchorButtonProps {\n osx: boolean;\n editor: TiptapEditor;\n}\n\nconst AnchorButton = ({ osx, editor, ...restProps }: AnchorButtonProps & ForwardProps) => {\n const t = useI18n();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [textInputEl, setTextInputEl] = useElement<HTMLInputElement>();\n const [urlInputEl, setUrlInputEl] = useElement<HTMLInputElement>();\n const [popoverEl, setPopoverEl] = useElement<HTMLDivElement>();\n const [linkText, setLinkText] = useState('');\n const [url, setUrl] = useState('');\n const [urlMatch, setUrlMatch] = useState(true);\n const [anchorMenu, setAnchorMenu] = useState(false);\n const [shouldFocusInput, setShouldFocusInput] = useState(false);\n // Store the original selection range when menu opens so we can restore it when creating the link\n const originalSelectionRef = useRef<{ from: number; to: number } | null>(null);\n const tooltip = getKeyCommand(osx, ({ ctrl }) => `${t('rte_link')} (${ctrl}K)`);\n\n const openMenu = (opts: { focusInput?: boolean } = {}) => {\n // Save the original selection before opening the menu\n const { from, to } = editor.state.selection;\n originalSelectionRef.current = { from, to };\n setAnchorMenu(true);\n if (opts.focusInput) {\n setShouldFocusInput(true);\n }\n };\n\n const resetMenu = useCallback(() => {\n setLinkText('');\n setUrl('');\n setUrlMatch(true);\n setAnchorMenu(false);\n originalSelectionRef.current = null;\n }, []);\n\n useOuterEvent('mousedown', [popoverEl, buttonRef], () => {\n if (anchorMenu) {\n resetMenu();\n }\n });\n\n // Close menu when clicking inside the editor iframe\n const handleEditorClick = useCallback(() => {\n if (anchorMenu) {\n resetMenu();\n }\n }, [anchorMenu, resetMenu]);\n useCloseOnEditorClick(anchorMenu, handleEditorClick);\n\n const isValidUrl = (urlString: string): boolean => {\n if (!urlString.trim()) return false;\n const allowedProtocols = /^(https?|mailto|tel):/i;\n const hasProtocol = /^[a-z][a-z0-9.+-]*:/i.test(urlString);\n\n try {\n const testUrl = hasProtocol ? urlString : `https://${urlString}`;\n if (hasProtocol && !allowedProtocols.test(urlString)) {\n return false;\n }\n const urlObj = new URL(testUrl);\n return URL.canParse?.(testUrl) ?? Boolean(urlObj.href);\n } catch {\n return false;\n }\n };\n\n const createLink = useCallback(() => {\n if (!url || !isValidUrl(url)) {\n return;\n }\n\n // Only allow safe protocols to prevent XSS (e.g., javascript: URLs)\n const allowedProtocols = /^(https?|mailto|tel):/i;\n const hasProtocol = /^[a-z][a-z0-9.+-]*:/i.test(url);\n\n let normalizedUrl: string;\n if (hasProtocol) {\n // Reject URLs with disallowed protocols\n if (!allowedProtocols.test(url)) {\n return;\n }\n normalizedUrl = url;\n } else {\n normalizedUrl = `https://${url}`;\n }\n\n // Use the original selection to determine if text was selected in the editor\n const originalSelection = originalSelectionRef.current;\n\n if (originalSelection && originalSelection.from !== originalSelection.to) {\n // Text was originally selected - restore selection and apply link\n // Then collapse selection to end and clear stored mark so subsequent typing isn't linked\n editor\n .chain()\n .focus()\n .setTextSelection({ from: originalSelection.from, to: originalSelection.to })\n .setLink({ href: normalizedUrl })\n .setTextSelection(originalSelection.to)\n .unsetMark('link')\n .run();\n } else if (linkText) {\n // No text was originally selected, insert new link with the text entered in modal\n editor\n .chain()\n .focus()\n .insertContent({\n type: 'text',\n text: linkText,\n marks: [{ type: 'link', attrs: { href: normalizedUrl } }]\n })\n .unsetMark('link')\n .insertContent(' ')\n .run();\n }\n resetMenu();\n }, [url, linkText, editor, resetMenu]);\n\n useEffect(() => {\n if (anchorMenu && originalSelectionRef.current) {\n // Use the stored original selection to populate the modal\n // This avoids issues where focus shift may collapse the editor selection\n const { from, to } = originalSelectionRef.current;\n const text = editor.state.doc.textBetween(from, to);\n const linkMark = editor.getAttributes('link');\n\n if (linkMark.href) {\n setUrl(linkMark.href);\n setLinkText(text || '');\n } else {\n setLinkText(text || '');\n }\n } else if (!anchorMenu) {\n resetMenu();\n }\n }, [anchorMenu, editor, resetMenu]);\n\n const preventDef = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n const isLinkActive = () => {\n return editor.isActive('link') && editor.isFocused;\n };\n\n const cancelAnchorCreation = useCallback(\n (event?: KeyboardEvent | MouseEvent) => {\n if (\n ((event && 'key' in event && event.key === 'Escape') ||\n event?.type === 'click' ||\n !event) &&\n anchorMenu\n ) {\n if (event && 'key' in event && event.key === 'Escape') {\n event.stopPropagation();\n }\n\n resetMenu();\n buttonRef.current?.focus();\n }\n },\n [anchorMenu, resetMenu]\n );\n\n // Ctrl+K shortcut to open link dialog from within the editor iframe\n useEffect(() => {\n const handleCtrlK = (e: KeyboardEvent) => {\n if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n openMenu({ focusInput: true });\n }\n };\n\n const iframeWindow = editor.view.dom.ownerDocument.defaultView;\n iframeWindow?.addEventListener('keydown', handleCtrlK);\n return () => iframeWindow?.removeEventListener('keydown', handleCtrlK);\n }, [editor]);\n\n // Escape to close popover - listen on both iframe and parent document\n // since focus may be in either location depending on how the popover was opened\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && anchorMenu) {\n e.preventDefault();\n cancelAnchorCreation();\n }\n };\n const iframeWindow = editor.view.dom.ownerDocument.defaultView;\n iframeWindow?.addEventListener('keydown', handleEscape);\n document.addEventListener('keydown', handleEscape);\n return () => {\n iframeWindow?.removeEventListener('keydown', handleEscape);\n document.removeEventListener('keydown', handleEscape);\n };\n }, [editor, anchorMenu, cancelAnchorCreation]);\n\n useEscape(cancelAnchorCreation, popoverEl);\n\n useLayoutEffect(() => {\n if (textInputEl && shouldFocusInput) {\n textInputEl.focus();\n setShouldFocusInput(false);\n }\n }, [textInputEl, shouldFocusInput]);\n\n useEffect(() => {\n // These events must be added here so they run before the native event in useArrows (used in the toolbar).\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') {\n e.stopPropagation();\n }\n };\n textInputEl?.addEventListener('keydown', onKeyDown);\n urlInputEl?.addEventListener('keydown', onKeyDown);\n return () => {\n textInputEl?.removeEventListener('keydown', onKeyDown);\n urlInputEl?.removeEventListener('keydown', onKeyDown);\n };\n }, [textInputEl, urlInputEl]);\n\n return (\n <>\n <ToolbarButton\n ref={buttonRef}\n onMouseDown={e => {\n e.preventDefault();\n openMenu();\n }}\n onKeyDown={(e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n openMenu({ focusInput: true });\n }\n }}\n onBlur={(e: React.FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverEl?.contains(relatedTarget)\n ) {\n resetMenu();\n }\n }}\n active={isLinkActive()}\n tooltip={tooltip}\n label={t('rte_link')}\n {...restProps}\n >\n <Icon name='chain' />\n </ToolbarButton>\n <StyledEditPopover\n show={anchorMenu}\n target={buttonRef.current}\n ref={setPopoverEl}\n placement='bottom'\n >\n <CardContent>\n <Form\n as='div'\n actions={\n <>\n <Button variant='secondary' onClick={cancelAnchorCreation} type='button'>\n {t('cancel')}\n </Button>\n <Button\n variant='primary'\n disabled={!url || !urlMatch}\n onClick={(e: MouseEvent) => {\n e.preventDefault();\n createLink();\n }}\n >\n {t('apply')}\n </Button>\n </>\n }\n >\n <Grid container={{ rowGap: 2 }}>\n <Text variant='h2'>{t('rte_add_link')}</Text>\n <Input\n label={t('rte_link_text')}\n value={linkText}\n onClick={preventDef}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n setLinkText(e.target.value);\n }}\n ref={setTextInputEl}\n />\n <Input\n label={t('rte_link_url')}\n value={url}\n onClick={preventDef}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n const urlInput = e.target.value;\n setUrl(urlInput);\n // Clear error while typing, validate on blur\n if (!urlMatch) {\n setUrlMatch(true);\n }\n }}\n onBlur={() => {\n setUrlMatch(!url || isValidUrl(url));\n }}\n info={url && !urlMatch ? t('rte_invalid_url') : ''}\n status={url && !urlMatch ? 'error' : undefined}\n ref={setUrlInputEl}\n />\n </Grid>\n </Form>\n </CardContent>\n </StyledEditPopover>\n </>\n );\n};\n\nexport default AnchorButton;\n"]}
1
+ {"version":3,"file":"AnchorButton.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/AnchorButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState, useEffect, useLayoutEffect, useCallback } from 'react';\nimport type { ChangeEvent, MouseEvent, KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport styled from 'styled-components';\n\nimport {\n Button,\n CardContent,\n Grid,\n Icon,\n registerIcon,\n Input,\n useOuterEvent,\n Form,\n useI18n,\n Text,\n useElement,\n useEscape,\n isInstance,\n TouchDialog,\n isTouchDevice,\n defaultThemeProp\n} from '@pega/cosmos-react-core';\nimport type { ForwardProps } from '@pega/cosmos-react-core';\nimport * as chainIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/chain.icon';\n\nimport ToolbarButton from '../../RichTextEditor/Toolbar/ToolbarButton';\nimport { getKeyCommand } from '../../RichTextEditor/Toolbar/utils';\nimport { StyledEditPopover } from '../Editor.styles';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nregisterIcon(chainIcon);\n\nconst StyledTouchDialogContent = styled(CardContent)(\n ({ theme }) => `\n flex: 1;\n\n > div {\n display: flex;\n flex-direction: column;\n min-height: 100%;\n }\n\n > div > div:not([aria-hidden='true']):nth-last-child(2) {\n margin-top: auto;\n padding-block-end: ${theme.base.spacing};\n }\n`\n);\n\nStyledTouchDialogContent.defaultProps = defaultThemeProp;\n\ninterface AnchorButtonProps {\n osx: boolean;\n editor: TiptapEditor;\n}\n\nconst AnchorButton = ({ osx, editor, ...restProps }: AnchorButtonProps & ForwardProps) => {\n const t = useI18n();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const touchDialogRef = useRef<HTMLDivElement>(null);\n const [textInputEl, setTextInputEl] = useElement<HTMLInputElement>();\n const [urlInputEl, setUrlInputEl] = useElement<HTMLInputElement>();\n const [popoverEl, setPopoverEl] = useElement<HTMLDivElement>();\n const [linkText, setLinkText] = useState('');\n const [url, setUrl] = useState('');\n const [urlMatch, setUrlMatch] = useState(true);\n const [anchorMenu, setAnchorMenu] = useState(false);\n const [shouldFocusInput, setShouldFocusInput] = useState(false);\n // Store the original selection range when menu opens so we can restore it when creating the link\n const originalSelectionRef = useRef<{ from: number; to: number } | null>(null);\n const tooltip = getKeyCommand(osx, ({ ctrl }) => `${t('rte_link')} (${ctrl}K)`);\n\n const openMenu = (opts: { focusInput?: boolean } = {}) => {\n // Save the original selection before opening the menu\n const { from, to } = editor.state.selection;\n originalSelectionRef.current = { from, to };\n setAnchorMenu(true);\n if (opts.focusInput) {\n setShouldFocusInput(true);\n }\n };\n\n const resetMenu = useCallback(() => {\n setLinkText('');\n setUrl('');\n setUrlMatch(true);\n setAnchorMenu(false);\n originalSelectionRef.current = null;\n }, []);\n\n useOuterEvent('mousedown', [popoverEl, buttonRef, touchDialogRef], () => {\n if (anchorMenu) {\n resetMenu();\n }\n });\n\n // Close menu when clicking inside the editor iframe\n const handleEditorClick = useCallback(() => {\n if (anchorMenu) {\n resetMenu();\n }\n }, [anchorMenu, resetMenu]);\n useCloseOnEditorClick(anchorMenu, handleEditorClick);\n\n const isValidUrl = (urlString: string): boolean => {\n if (!urlString.trim()) return false;\n const allowedProtocols = /^(https?|mailto|tel):/i;\n const hasProtocol = /^[a-z][a-z0-9.+-]*:/i.test(urlString);\n\n try {\n const testUrl = hasProtocol ? urlString : `https://${urlString}`;\n if (hasProtocol && !allowedProtocols.test(urlString)) {\n return false;\n }\n const urlObj = new URL(testUrl);\n return URL.canParse?.(testUrl) ?? Boolean(urlObj.href);\n } catch {\n return false;\n }\n };\n\n const createLink = useCallback(() => {\n if (!url || !isValidUrl(url)) {\n return;\n }\n\n // Only allow safe protocols to prevent XSS (e.g., javascript: URLs)\n const allowedProtocols = /^(https?|mailto|tel):/i;\n const hasProtocol = /^[a-z][a-z0-9.+-]*:/i.test(url);\n\n let normalizedUrl: string;\n if (hasProtocol) {\n // Reject URLs with disallowed protocols\n if (!allowedProtocols.test(url)) {\n return;\n }\n normalizedUrl = url;\n } else {\n normalizedUrl = `https://${url}`;\n }\n\n // Use the original selection to determine if text was selected in the editor\n const originalSelection = originalSelectionRef.current;\n\n if (originalSelection && originalSelection.from !== originalSelection.to) {\n // Text was originally selected - restore selection and apply link\n // Then collapse selection to end and clear stored mark so subsequent typing isn't linked\n editor\n .chain()\n .focus()\n .setTextSelection({ from: originalSelection.from, to: originalSelection.to })\n .setLink({ href: normalizedUrl })\n .setTextSelection(originalSelection.to)\n .unsetMark('link')\n .run();\n } else if (linkText) {\n // No text was originally selected, insert new link with the text entered in modal\n editor\n .chain()\n .focus()\n .insertContent({\n type: 'text',\n text: linkText,\n marks: [{ type: 'link', attrs: { href: normalizedUrl } }]\n })\n .unsetMark('link')\n .insertContent(' ')\n .run();\n }\n resetMenu();\n }, [url, linkText, editor, resetMenu]);\n\n useEffect(() => {\n if (anchorMenu && originalSelectionRef.current) {\n // Use the stored original selection to populate the modal\n // This avoids issues where focus shift may collapse the editor selection\n const { from, to } = originalSelectionRef.current;\n const text = editor.state.doc.textBetween(from, to);\n const linkMark = editor.getAttributes('link');\n\n if (linkMark.href) {\n setUrl(linkMark.href);\n setLinkText(text || '');\n } else {\n setLinkText(text || '');\n }\n } else if (!anchorMenu) {\n resetMenu();\n }\n }, [anchorMenu, editor, resetMenu]);\n\n const preventDef = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n const isLinkActive = () => {\n return editor.isActive('link') && editor.isFocused;\n };\n\n const cancelAnchorCreation = useCallback(\n (event?: KeyboardEvent | MouseEvent) => {\n if (\n ((event && 'key' in event && event.key === 'Escape') ||\n event?.type === 'click' ||\n !event) &&\n anchorMenu\n ) {\n if (event && 'key' in event && event.key === 'Escape') {\n event.stopPropagation();\n }\n\n resetMenu();\n buttonRef.current?.focus();\n }\n },\n [anchorMenu, resetMenu]\n );\n\n // Ctrl+K shortcut to open link dialog from within the editor iframe\n useEffect(() => {\n const handleCtrlK = (e: KeyboardEvent) => {\n if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n openMenu({ focusInput: true });\n }\n };\n\n const iframeWindow = editor.view.dom.ownerDocument.defaultView;\n iframeWindow?.addEventListener('keydown', handleCtrlK);\n return () => iframeWindow?.removeEventListener('keydown', handleCtrlK);\n }, [editor]);\n\n // Escape to close popover - listen on both iframe and parent document\n // since focus may be in either location depending on how the popover was opened\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && anchorMenu) {\n e.preventDefault();\n cancelAnchorCreation();\n }\n };\n const iframeWindow = editor.view.dom.ownerDocument.defaultView;\n iframeWindow?.addEventListener('keydown', handleEscape);\n document.addEventListener('keydown', handleEscape);\n return () => {\n iframeWindow?.removeEventListener('keydown', handleEscape);\n document.removeEventListener('keydown', handleEscape);\n };\n }, [editor, anchorMenu, cancelAnchorCreation]);\n\n useEscape(cancelAnchorCreation, popoverEl);\n\n useLayoutEffect(() => {\n if (textInputEl && shouldFocusInput) {\n textInputEl.focus();\n setShouldFocusInput(false);\n }\n }, [textInputEl, shouldFocusInput]);\n\n useEffect(() => {\n // These events must be added here so they run before the native event in useArrows (used in the toolbar).\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') {\n e.stopPropagation();\n }\n };\n textInputEl?.addEventListener('keydown', onKeyDown);\n urlInputEl?.addEventListener('keydown', onKeyDown);\n return () => {\n textInputEl?.removeEventListener('keydown', onKeyDown);\n urlInputEl?.removeEventListener('keydown', onKeyDown);\n };\n }, [textInputEl, urlInputEl]);\n\n const linkFormContent = (\n <Form\n as='div'\n actions={\n <>\n <Button variant='secondary' onClick={cancelAnchorCreation} type='button'>\n {t('cancel')}\n </Button>\n <Button\n variant='primary'\n disabled={!url || !urlMatch}\n onClick={(e: MouseEvent) => {\n e.preventDefault();\n createLink();\n }}\n >\n {t('apply')}\n </Button>\n </>\n }\n >\n <Grid container={{ rowGap: 2 }}>\n <Input\n label={t('rte_link_text')}\n value={linkText}\n onClick={preventDef}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n setLinkText(e.target.value);\n }}\n ref={setTextInputEl}\n />\n <Input\n label={t('rte_link_url')}\n value={url}\n onClick={preventDef}\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n const urlInput = e.target.value;\n setUrl(urlInput);\n // Clear error while typing, validate on blur\n if (!urlMatch) {\n setUrlMatch(true);\n }\n }}\n onBlur={() => {\n setUrlMatch(!url || isValidUrl(url));\n }}\n info={url && !urlMatch ? t('rte_invalid_url') : ''}\n status={url && !urlMatch ? 'error' : undefined}\n ref={setUrlInputEl}\n />\n </Grid>\n </Form>\n );\n\n return (\n <>\n <ToolbarButton\n ref={buttonRef}\n onMouseDown={e => {\n e.preventDefault();\n openMenu();\n }}\n onKeyDown={(e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n openMenu({ focusInput: true });\n }\n }}\n onBlur={(e: React.FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverEl?.contains(relatedTarget) &&\n !touchDialogRef.current?.contains(relatedTarget)\n ) {\n resetMenu();\n }\n }}\n active={isLinkActive()}\n tooltip={tooltip}\n label={t('rte_link')}\n {...restProps}\n >\n <Icon name='chain' />\n </ToolbarButton>\n {isTouchDevice ? (\n <TouchDialog\n ref={touchDialogRef}\n open={anchorMenu}\n heading={t('rte_add_link')}\n onDismiss={() => cancelAnchorCreation()}\n >\n <StyledTouchDialogContent>{linkFormContent}</StyledTouchDialogContent>\n </TouchDialog>\n ) : (\n <StyledEditPopover\n show={anchorMenu}\n target={buttonRef.current}\n ref={setPopoverEl}\n placement='bottom'\n >\n <CardContent>\n <Text variant='h2'>{t('rte_add_link')}</Text>\n {linkFormContent}\n </CardContent>\n </StyledEditPopover>\n )}\n </>\n );\n};\n\nexport default AnchorButton;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPickerButton.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/ColorPickerButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAuG3D,UAAU,sBAAsB;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,QAAA,MAAM,iBAAiB,GAAI,gCAAgC,sBAAsB,4CAuMhF,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"ColorPickerButton.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/ColorPickerButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAmH3D,UAAU,sBAAsB;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID,QAAA,MAAM,iBAAiB,GAAI,gCAAgC,sBAAsB,4CAoNhF,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect, useCallback } from 'react';
3
3
  import styled, { css } from 'styled-components';
4
- import { Button, RadioButtonGroup, RadioButton, ColorPicker, defaultThemeProp, useI18n, useUID, Tooltip, Popover, useOuterEvent, Text, Flex, calculateFontSize, isInstance, readableColor } from '@pega/cosmos-react-core';
4
+ import { Button, RadioButtonGroup, RadioButton, ColorPicker, defaultThemeProp, useI18n, useUID, Tooltip, TouchDialog, Popover, useOuterEvent, Text, Flex, calculateFontSize, isInstance, readableColor, isTouchDevice } from '@pega/cosmos-react-core';
5
5
  import useEscapeKey from '../hooks/useEscapeKey';
6
6
  import useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';
7
7
  const StyledColorButton = styled(Button)(({ theme }) => {
@@ -65,19 +65,28 @@ const StyledPopoverContent = styled.div(({ theme }) => {
65
65
  `;
66
66
  });
67
67
  StyledPopoverContent.defaultProps = defaultThemeProp;
68
- const StyledButtonGroup = styled.div(({ theme }) => {
68
+ const StyledButtonGroup = styled.div(({ theme, $touch }) => {
69
69
  return css `
70
70
  display: flex;
71
71
  gap: calc(0.5 * ${theme.base.spacing});
72
- justify-content: flex-end;
72
+ justify-content: space-between;
73
+ margin-top: auto;
74
+ width: 100%;
75
+ padding-block-end: ${$touch ? theme.base.spacing : 0};
73
76
  `;
74
77
  });
75
78
  StyledButtonGroup.defaultProps = defaultThemeProp;
79
+ const StyledColorPickerContent = styled(Flex) `
80
+ flex: 1;
81
+ min-height: 0;
82
+ `;
83
+ StyledColorPickerContent.defaultProps = defaultThemeProp;
76
84
  const ColorPickerButton = ({ editor, type, ...restProps }) => {
77
85
  const t = useI18n();
78
86
  const titleId = useUID();
79
87
  const buttonRef = useRef(null);
80
88
  const popoverRef = useRef(null);
89
+ const touchDialogRef = useRef(null);
81
90
  const [open, setOpen] = useState(false);
82
91
  const [colorType, setColorType] = useState('custom');
83
92
  const [customColor, setCustomColor] = useState('#000000');
@@ -114,7 +123,7 @@ const ColorPickerButton = ({ editor, type, ...restProps }) => {
114
123
  const resetMenu = () => {
115
124
  setOpen(false);
116
125
  };
117
- useOuterEvent('mousedown', [popoverRef, buttonRef], (event) => {
126
+ useOuterEvent('mousedown', [popoverRef, buttonRef, touchDialogRef], (event) => {
118
127
  // Don't close if clicking inside a nested popover (like ColorPicker's palette)
119
128
  const { target } = event;
120
129
  if (isInstance(target, HTMLElement) && target.closest('[data-popper-placement]')) {
@@ -164,6 +173,12 @@ const ColorPickerButton = ({ editor, type, ...restProps }) => {
164
173
  const label = type === 'text' ? t('rte_text_color') : t('rte_background_color');
165
174
  const modalTitle = type === 'text' ? t('rte_font_color') : t('rte_background_color');
166
175
  const isHighlight = type === 'highlight';
176
+ const colorPickerContent = (_jsxs(StyledColorPickerContent, { container: { direction: 'column', gap: 1 }, children: [_jsxs(RadioButtonGroup, { name: 'colorType', label: t('rte_color_type'), labelHidden: true, onChange: (e) => {
177
+ const { value } = e.target;
178
+ if (value === 'auto' || value === 'custom') {
179
+ setColorType(value);
180
+ }
181
+ }, inline: true, children: [_jsx(RadioButton, { label: t('rte_color_auto'), value: 'auto', checked: colorType === 'auto' }), _jsx(RadioButton, { label: t('rte_color_custom'), value: 'custom', checked: colorType === 'custom' })] }), _jsx(ColorPicker, { label: t('rte_color'), labelHidden: true, value: customColor, onChange: color => setCustomColor(color.hex), disabled: colorType === 'auto' }), _jsxs(StyledButtonGroup, { "$touch": isTouchDevice, children: [_jsx(Button, { variant: 'secondary', onKeyDown: handleCancelKeyDown, onMouseDown: handleCancelMouseDown, type: 'button', children: t('cancel') }), _jsx(Button, { variant: 'primary', onClick: handleSubmit, children: t('submit') })] })] }));
167
182
  return (_jsxs(_Fragment, { children: [_jsx(StyledColorButton, { ...restProps, variant: 'simple', type: 'button', ref: buttonRef, "data-toolbar-item": 'true', onMouseDown: (e) => {
168
183
  e.preventDefault();
169
184
  openMenu();
@@ -176,15 +191,11 @@ const ColorPickerButton = ({ editor, type, ...restProps }) => {
176
191
  const { relatedTarget } = e;
177
192
  if (isInstance(relatedTarget, Node) &&
178
193
  !buttonRef.current?.contains(relatedTarget) &&
179
- !popoverRef.current?.contains(relatedTarget)) {
194
+ !popoverRef.current?.contains(relatedTarget) &&
195
+ !touchDialogRef.current?.contains(relatedTarget)) {
180
196
  resetMenu();
181
197
  }
182
- }, "aria-label": label, "aria-haspopup": 'dialog', "aria-expanded": open, children: isHighlight ? (_jsx(StyledHighlightColorIcon, { "$color": currentColor, children: "A" })) : (_jsx(StyledTextColorIcon, { "$color": currentColor, children: "A" })) }), buttonRef.current && !open && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: label })), _jsx(Popover, { show: open, target: buttonRef.current, ref: popoverRef, placement: 'bottom', children: _jsx(StyledPopoverContent, { role: 'dialog', "aria-labelledby": titleId, children: _jsxs(Flex, { container: { direction: 'column', gap: 1 }, children: [_jsx(Text, { variant: 'h4', id: titleId, children: modalTitle }), _jsxs(RadioButtonGroup, { name: 'colorType', label: t('rte_color_type'), labelHidden: true, onChange: (e) => {
183
- const { value } = e.target;
184
- if (value === 'auto' || value === 'custom') {
185
- setColorType(value);
186
- }
187
- }, inline: true, children: [_jsx(RadioButton, { label: t('rte_color_auto'), value: 'auto', checked: colorType === 'auto' }), _jsx(RadioButton, { label: t('rte_color_custom'), value: 'custom', checked: colorType === 'custom' })] }), _jsx(ColorPicker, { label: t('rte_color'), labelHidden: true, value: customColor, onChange: color => setCustomColor(color.hex), disabled: colorType === 'auto' }), _jsxs(StyledButtonGroup, { children: [_jsx(Button, { variant: 'secondary', onKeyDown: handleCancelKeyDown, onMouseDown: handleCancelMouseDown, type: 'button', children: t('cancel') }), _jsx(Button, { variant: 'primary', onClick: handleSubmit, children: t('submit') })] })] }) }) })] }));
198
+ }, "aria-label": label, "aria-haspopup": 'dialog', "aria-expanded": open, children: isHighlight ? (_jsx(StyledHighlightColorIcon, { "$color": currentColor, children: "A" })) : (_jsx(StyledTextColorIcon, { "$color": currentColor, children: "A" })) }), buttonRef.current && !open && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: label })), isTouchDevice ? (_jsx(TouchDialog, { ref: touchDialogRef, open: open, heading: modalTitle, onDismiss: resetMenu, onAfterClose: () => buttonRef.current?.focus(), children: colorPickerContent })) : (_jsx(Popover, { show: open, target: buttonRef.current, ref: popoverRef, placement: 'bottom', children: _jsxs(StyledPopoverContent, { role: 'dialog', "aria-labelledby": titleId, children: [_jsx(Text, { variant: 'h4', id: titleId, children: modalTitle }), colorPickerContent] }) }))] }));
188
199
  };
189
200
  export default ColorPickerButton;
190
201
  //# sourceMappingURL=ColorPickerButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPickerButton.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/ColorPickerButton.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState, useEffect, useCallback } from 'react';\nimport type { MouseEvent, KeyboardEvent as ReactKeyboardEvent, ChangeEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport styled, { css } from 'styled-components';\n\nimport {\n Button,\n RadioButtonGroup,\n RadioButton,\n ColorPicker,\n defaultThemeProp,\n useI18n,\n useUID,\n Tooltip,\n Popover,\n useOuterEvent,\n Text,\n Flex,\n calculateFontSize,\n isInstance,\n readableColor\n} from '@pega/cosmos-react-core';\n\nimport useEscapeKey from '../hooks/useEscapeKey';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nconst StyledColorButton = styled(Button)(({ theme }) => {\n return css`\n color: ${theme.base.palette['foreground-color']};\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: calc(3.5 * ${theme.base.spacing});\n min-width: calc(3.5 * ${theme.base.spacing});\n padding: 0;\n `;\n});\n\nconst StyledTextColorIcon = styled.span<{ $color?: string }>(({ theme, $color }) => {\n const fontSizes = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n return css`\n display: flex;\n flex-direction: column;\n align-items: center;\n font-weight: bold;\n font-size: ${fontSizes.s};\n line-height: 1;\n\n &::after {\n content: '';\n display: block;\n width: 100%;\n height: calc(0.375 * ${theme.base.spacing});\n background-color: ${$color || theme.base.palette['foreground-color']};\n border-radius: calc(0.125 * ${theme.base.spacing});\n margin-top: calc(0.125 * ${theme.base.spacing});\n }\n `;\n});\n\nStyledTextColorIcon.defaultProps = defaultThemeProp;\n\nconst StyledHighlightColorIcon = styled.span<{ $color?: string }>(({ theme, $color }) => {\n const fontSizes = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n const textColor = $color ? readableColor($color) : 'inherit';\n return css`\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n font-size: ${fontSizes.s};\n min-width: 1.25em;\n min-height: 1.25em;\n padding: 0.125em 0.25em;\n border: calc(0.125 * ${theme.base.spacing}) solid\n ${theme.components['form-control']['border-color']};\n border-radius: calc(0.25 * ${theme.base['border-radius']});\n background-color: ${$color || 'transparent'};\n color: ${textColor};\n `;\n});\n\nStyledHighlightColorIcon.defaultProps = defaultThemeProp;\n\nStyledColorButton.defaultProps = defaultThemeProp;\n\nconst StyledPopoverContent = styled.div(({ theme }) => {\n return css`\n padding: ${theme.base.spacing};\n min-width: calc(14 * ${theme.base.spacing});\n `;\n});\n\nStyledPopoverContent.defaultProps = defaultThemeProp;\n\nconst StyledButtonGroup = styled.div(({ theme }) => {\n return css`\n display: flex;\n gap: calc(0.5 * ${theme.base.spacing});\n justify-content: flex-end;\n `;\n});\n\nStyledButtonGroup.defaultProps = defaultThemeProp;\n\ninterface ColorPickerButtonProps {\n editor: TiptapEditor;\n type: 'text' | 'highlight';\n 'data-testid'?: string;\n}\n\ntype ColorType = 'auto' | 'custom';\n\nconst ColorPickerButton = ({ editor, type, ...restProps }: ColorPickerButtonProps) => {\n const t = useI18n();\n const titleId = useUID();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const [colorType, setColorType] = useState<ColorType>('custom');\n const [customColor, setCustomColor] = useState('#000000');\n\n // Focus first radio button when popover opens\n useEffect(() => {\n if (open) {\n // Use setTimeout to wait for popover to render\n const timer = setTimeout(() => {\n if (popoverRef.current) {\n const firstRadio =\n popoverRef.current.querySelector<HTMLInputElement>('input[type=\"radio\"]');\n firstRadio?.focus();\n }\n }, 0);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n const getCurrentColor = (): string | undefined => {\n const attrs =\n type === 'text' ? editor.getAttributes('textStyle') : editor.getAttributes('highlight');\n const { color } = attrs;\n return typeof color === 'string' ? color : undefined;\n };\n\n const currentColor = getCurrentColor();\n\n const openMenu = () => {\n // Initialize state based on current color, default to custom\n if (currentColor) {\n setCustomColor(currentColor);\n } else {\n setCustomColor('#000000');\n }\n setColorType('custom');\n setOpen(true);\n };\n\n const resetMenu = () => {\n setOpen(false);\n };\n\n useOuterEvent('mousedown', [popoverRef, buttonRef], (event: Event) => {\n // Don't close if clicking inside a nested popover (like ColorPicker's palette)\n const { target } = event;\n if (isInstance(target, HTMLElement) && target.closest('[data-popper-placement]')) {\n return;\n }\n if (open) {\n resetMenu();\n }\n });\n\n const handleSubmit = () => {\n if (colorType === 'auto') {\n if (type === 'text') {\n editor.chain().focus().unsetColor().run();\n } else {\n editor.chain().focus().unsetHighlight().run();\n }\n } else if (type === 'text') {\n editor.chain().focus().setColor(customColor).run();\n } else {\n editor.chain().focus().setHighlight({ color: customColor }).run();\n }\n resetMenu();\n };\n\n const handleCancelKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Enter' && open) {\n event.preventDefault();\n resetMenu();\n buttonRef.current?.focus();\n }\n };\n\n const handleCancelMouseDown = (event: MouseEvent<HTMLButtonElement>) => {\n if (open) {\n event.preventDefault();\n resetMenu();\n buttonRef.current?.focus();\n }\n };\n\n const handleEscapeClose = useCallback(() => {\n resetMenu();\n buttonRef.current?.focus();\n }, []);\n\n useEscapeKey(open, handleEscapeClose, editor);\n useCloseOnEditorClick(open, handleEscapeClose);\n\n const label = type === 'text' ? t('rte_text_color') : t('rte_background_color');\n const modalTitle = type === 'text' ? t('rte_font_color') : t('rte_background_color');\n const isHighlight = type === 'highlight';\n\n return (\n <>\n <StyledColorButton\n {...restProps}\n variant='simple'\n type='button'\n ref={buttonRef}\n data-toolbar-item='true'\n onMouseDown={(e: MouseEvent) => {\n e.preventDefault();\n openMenu();\n }}\n onKeyDown={(e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n openMenu();\n }\n }}\n onBlur={(e: React.FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverRef.current?.contains(relatedTarget)\n ) {\n resetMenu();\n }\n }}\n aria-label={label}\n aria-haspopup='dialog'\n aria-expanded={open}\n >\n {isHighlight ? (\n <StyledHighlightColorIcon $color={currentColor}>A</StyledHighlightColorIcon>\n ) : (\n <StyledTextColorIcon $color={currentColor}>A</StyledTextColorIcon>\n )}\n </StyledColorButton>\n {buttonRef.current && !open && (\n <Tooltip target={buttonRef.current} showDelay='none' hideDelay='none'>\n {label}\n </Tooltip>\n )}\n <Popover show={open} target={buttonRef.current} ref={popoverRef} placement='bottom'>\n <StyledPopoverContent role='dialog' aria-labelledby={titleId}>\n <Flex container={{ direction: 'column', gap: 1 }}>\n <Text variant='h4' id={titleId}>\n {modalTitle}\n </Text>\n <RadioButtonGroup\n name='colorType'\n label={t('rte_color_type')}\n labelHidden\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n const { value } = e.target;\n if (value === 'auto' || value === 'custom') {\n setColorType(value);\n }\n }}\n inline\n >\n <RadioButton\n label={t('rte_color_auto')}\n value='auto'\n checked={colorType === 'auto'}\n />\n <RadioButton\n label={t('rte_color_custom')}\n value='custom'\n checked={colorType === 'custom'}\n />\n </RadioButtonGroup>\n <ColorPicker\n label={t('rte_color')}\n labelHidden\n value={customColor}\n onChange={color => setCustomColor(color.hex)}\n disabled={colorType === 'auto'}\n />\n <StyledButtonGroup>\n <Button\n variant='secondary'\n onKeyDown={handleCancelKeyDown}\n onMouseDown={handleCancelMouseDown}\n type='button'\n >\n {t('cancel')}\n </Button>\n <Button variant='primary' onClick={handleSubmit}>\n {t('submit')}\n </Button>\n </StyledButtonGroup>\n </Flex>\n </StyledPopoverContent>\n </Popover>\n </>\n );\n};\n\nexport default ColorPickerButton;\n"]}
1
+ {"version":3,"file":"ColorPickerButton.js","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/ColorPickerButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGjE,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EACL,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,OAAO,EACP,WAAW,EACX,OAAO,EACP,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,qBAAqB,MAAM,gCAAgC,CAAC;AAEnE,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACrD,OAAO,GAAG,CAAA;aACC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;;;;yBAI1B,KAAK,CAAC,IAAI,CAAC,OAAO;4BACf,KAAK,CAAC,IAAI,CAAC,OAAO;;GAE3C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;IACjF,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACvF,OAAO,GAAG,CAAA;;;;;iBAKK,SAAS,CAAC,CAAC;;;;;;;6BAOC,KAAK,CAAC,IAAI,CAAC,OAAO;0BACrB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;oCACtC,KAAK,CAAC,IAAI,CAAC,OAAO;iCACrB,KAAK,CAAC,IAAI,CAAC,OAAO;;GAEhD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,mBAAmB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEpD,MAAM,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;IACtF,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IACvF,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,OAAO,GAAG,CAAA;;;;;iBAKK,SAAS,CAAC,CAAC;;;;2BAID,KAAK,CAAC,IAAI,CAAC,OAAO;QACrC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC;iCACvB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;wBACpC,MAAM,IAAI,aAAa;aAClC,SAAS;GACnB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,wBAAwB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAEzD,iBAAiB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAElD,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACpD,OAAO,GAAG,CAAA;eACG,KAAK,CAAC,IAAI,CAAC,OAAO;2BACN,KAAK,CAAC,IAAI,CAAC,OAAO;GAC1C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,oBAAoB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAErD,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAuB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;IAC/E,OAAO,GAAG,CAAA;;sBAEU,KAAK,CAAC,IAAI,CAAC,OAAO;;;;yBAIf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;GACrD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,iBAAiB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAElD,MAAM,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;;;CAG5C,CAAC;AAEF,wBAAwB,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAUzD,MAAM,iBAAiB,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,EAA0B,EAAE,EAAE;IACnF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;IACzB,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,QAAQ,CAAC,CAAC;IAChE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE1D,8CAA8C;IAC9C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE,CAAC;YACT,+CAA+C;YAC/C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;oBACvB,MAAM,UAAU,GACd,UAAU,CAAC,OAAO,CAAC,aAAa,CAAmB,qBAAqB,CAAC,CAAC;oBAC5E,UAAU,EAAE,KAAK,EAAE,CAAC;gBACtB,CAAC;YACH,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,eAAe,GAAG,GAAuB,EAAE;QAC/C,MAAM,KAAK,GACT,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAC1F,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QACxB,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,6DAA6D;QAC7D,IAAI,YAAY,EAAE,CAAC;YACjB,cAAc,CAAC,YAAY,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;QACD,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,aAAa,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,CAAC,KAAY,EAAE,EAAE;QACnF,+EAA+E;QAC/E,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QACzB,IAAI,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;YACjF,OAAO;QACT,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,SAAS,EAAE,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,CAAC;YAChD,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QACpE,CAAC;QACD,SAAS,EAAE,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,CAAC,KAA4C,EAAE,EAAE;QAC3E,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,IAAI,EAAE,CAAC;YAClC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,SAAS,EAAE,CAAC;YACZ,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,CAAC,KAAoC,EAAE,EAAE;QACrE,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,SAAS,EAAE,CAAC;YACZ,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,SAAS,EAAE,CAAC;QACZ,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,YAAY,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC9C,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAE/C,MAAM,KAAK,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;IACrF,MAAM,WAAW,GAAG,IAAI,KAAK,WAAW,CAAC;IACzC,MAAM,kBAAkB,GAAG,CACzB,MAAC,wBAAwB,IAAC,SAAS,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,aAClE,MAAC,gBAAgB,IACf,IAAI,EAAC,WAAW,EAChB,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,EAC1B,WAAW,QACX,QAAQ,EAAE,CAAC,CAAgC,EAAE,EAAE;oBAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;oBAC3B,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC3C,YAAY,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC,EACD,MAAM,mBAEN,KAAC,WAAW,IAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAC,MAAM,EAAC,OAAO,EAAE,SAAS,KAAK,MAAM,GAAI,EACvF,KAAC,WAAW,IACV,KAAK,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAC5B,KAAK,EAAC,QAAQ,EACd,OAAO,EAAE,SAAS,KAAK,QAAQ,GAC/B,IACe,EACnB,KAAC,WAAW,IACV,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,EACrB,WAAW,QACX,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,EAC5C,QAAQ,EAAE,SAAS,KAAK,MAAM,GAC9B,EACF,MAAC,iBAAiB,cAAS,aAAa,aACtC,KAAC,MAAM,IACL,OAAO,EAAC,WAAW,EACnB,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,qBAAqB,EAClC,IAAI,EAAC,QAAQ,YAEZ,CAAC,CAAC,QAAQ,CAAC,GACL,EACT,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,YAAY,YAC5C,CAAC,CAAC,QAAQ,CAAC,GACL,IACS,IACK,CAC5B,CAAC;IAEF,OAAO,CACL,8BACE,KAAC,iBAAiB,OACZ,SAAS,EACb,OAAO,EAAC,QAAQ,EAChB,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,SAAS,uBACI,MAAM,EACxB,WAAW,EAAE,CAAC,CAAa,EAAE,EAAE;oBAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,QAAQ,EAAE,CAAC;gBACb,CAAC,EACD,SAAS,EAAE,CAAC,CAAqB,EAAE,EAAE;oBACnC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;wBACtB,CAAC,CAAC,cAAc,EAAE,CAAC;wBACnB,QAAQ,EAAE,CAAC;oBACb,CAAC;gBACH,CAAC,EACD,MAAM,EAAE,CAAC,CAAmB,EAAE,EAAE;oBAC9B,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;oBAC5B,IACE,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC;wBAC/B,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC;wBAC3C,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC;wBAC5C,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,EAChD,CAAC;wBACD,SAAS,EAAE,CAAC;oBACd,CAAC;gBACH,CAAC,gBACW,KAAK,mBACH,QAAQ,mBACP,IAAI,YAElB,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,wBAAwB,cAAS,YAAY,kBAA8B,CAC7E,CAAC,CAAC,CAAC,CACF,KAAC,mBAAmB,cAAS,YAAY,kBAAyB,CACnE,GACiB,EACnB,SAAS,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAC7B,KAAC,OAAO,IAAC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,EAAC,MAAM,EAAC,SAAS,EAAC,MAAM,YAClE,KAAK,GACE,CACX,EACA,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,WAAW,IACV,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,YAE7C,kBAAkB,GACP,CACf,CAAC,CAAC,CAAC,CACF,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAC,QAAQ,YACjF,MAAC,oBAAoB,IAAC,IAAI,EAAC,QAAQ,qBAAkB,OAAO,aAC1D,KAAC,IAAI,IAAC,OAAO,EAAC,IAAI,EAAC,EAAE,EAAE,OAAO,YAC3B,UAAU,GACN,EACN,kBAAkB,IACE,GACf,CACX,IACA,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC","sourcesContent":["import { useRef, useState, useEffect, useCallback } from 'react';\nimport type { MouseEvent, KeyboardEvent as ReactKeyboardEvent, ChangeEvent } from 'react';\nimport type { Editor as TiptapEditor } from '@tiptap/core';\nimport styled, { css } from 'styled-components';\n\nimport {\n Button,\n RadioButtonGroup,\n RadioButton,\n ColorPicker,\n defaultThemeProp,\n useI18n,\n useUID,\n Tooltip,\n TouchDialog,\n Popover,\n useOuterEvent,\n Text,\n Flex,\n calculateFontSize,\n isInstance,\n readableColor,\n isTouchDevice\n} from '@pega/cosmos-react-core';\n\nimport useEscapeKey from '../hooks/useEscapeKey';\nimport useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';\n\nconst StyledColorButton = styled(Button)(({ theme }) => {\n return css`\n color: ${theme.base.palette['foreground-color']};\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: calc(3.5 * ${theme.base.spacing});\n min-width: calc(3.5 * ${theme.base.spacing});\n padding: 0;\n `;\n});\n\nconst StyledTextColorIcon = styled.span<{ $color?: string }>(({ theme, $color }) => {\n const fontSizes = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n return css`\n display: flex;\n flex-direction: column;\n align-items: center;\n font-weight: bold;\n font-size: ${fontSizes.s};\n line-height: 1;\n\n &::after {\n content: '';\n display: block;\n width: 100%;\n height: calc(0.375 * ${theme.base.spacing});\n background-color: ${$color || theme.base.palette['foreground-color']};\n border-radius: calc(0.125 * ${theme.base.spacing});\n margin-top: calc(0.125 * ${theme.base.spacing});\n }\n `;\n});\n\nStyledTextColorIcon.defaultProps = defaultThemeProp;\n\nconst StyledHighlightColorIcon = styled.span<{ $color?: string }>(({ theme, $color }) => {\n const fontSizes = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n const textColor = $color ? readableColor($color) : 'inherit';\n return css`\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: bold;\n font-size: ${fontSizes.s};\n min-width: 1.25em;\n min-height: 1.25em;\n padding: 0.125em 0.25em;\n border: calc(0.125 * ${theme.base.spacing}) solid\n ${theme.components['form-control']['border-color']};\n border-radius: calc(0.25 * ${theme.base['border-radius']});\n background-color: ${$color || 'transparent'};\n color: ${textColor};\n `;\n});\n\nStyledHighlightColorIcon.defaultProps = defaultThemeProp;\n\nStyledColorButton.defaultProps = defaultThemeProp;\n\nconst StyledPopoverContent = styled.div(({ theme }) => {\n return css`\n padding: ${theme.base.spacing};\n min-width: calc(14 * ${theme.base.spacing});\n `;\n});\n\nStyledPopoverContent.defaultProps = defaultThemeProp;\n\nconst StyledButtonGroup = styled.div<{ $touch?: boolean }>(({ theme, $touch }) => {\n return css`\n display: flex;\n gap: calc(0.5 * ${theme.base.spacing});\n justify-content: space-between;\n margin-top: auto;\n width: 100%;\n padding-block-end: ${$touch ? theme.base.spacing : 0};\n `;\n});\n\nStyledButtonGroup.defaultProps = defaultThemeProp;\n\nconst StyledColorPickerContent = styled(Flex)`\n flex: 1;\n min-height: 0;\n`;\n\nStyledColorPickerContent.defaultProps = defaultThemeProp;\n\ninterface ColorPickerButtonProps {\n editor: TiptapEditor;\n type: 'text' | 'highlight';\n 'data-testid'?: string;\n}\n\ntype ColorType = 'auto' | 'custom';\n\nconst ColorPickerButton = ({ editor, type, ...restProps }: ColorPickerButtonProps) => {\n const t = useI18n();\n const titleId = useUID();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const touchDialogRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const [colorType, setColorType] = useState<ColorType>('custom');\n const [customColor, setCustomColor] = useState('#000000');\n\n // Focus first radio button when popover opens\n useEffect(() => {\n if (open) {\n // Use setTimeout to wait for popover to render\n const timer = setTimeout(() => {\n if (popoverRef.current) {\n const firstRadio =\n popoverRef.current.querySelector<HTMLInputElement>('input[type=\"radio\"]');\n firstRadio?.focus();\n }\n }, 0);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n const getCurrentColor = (): string | undefined => {\n const attrs =\n type === 'text' ? editor.getAttributes('textStyle') : editor.getAttributes('highlight');\n const { color } = attrs;\n return typeof color === 'string' ? color : undefined;\n };\n\n const currentColor = getCurrentColor();\n\n const openMenu = () => {\n // Initialize state based on current color, default to custom\n if (currentColor) {\n setCustomColor(currentColor);\n } else {\n setCustomColor('#000000');\n }\n setColorType('custom');\n setOpen(true);\n };\n\n const resetMenu = () => {\n setOpen(false);\n };\n\n useOuterEvent('mousedown', [popoverRef, buttonRef, touchDialogRef], (event: Event) => {\n // Don't close if clicking inside a nested popover (like ColorPicker's palette)\n const { target } = event;\n if (isInstance(target, HTMLElement) && target.closest('[data-popper-placement]')) {\n return;\n }\n if (open) {\n resetMenu();\n }\n });\n\n const handleSubmit = () => {\n if (colorType === 'auto') {\n if (type === 'text') {\n editor.chain().focus().unsetColor().run();\n } else {\n editor.chain().focus().unsetHighlight().run();\n }\n } else if (type === 'text') {\n editor.chain().focus().setColor(customColor).run();\n } else {\n editor.chain().focus().setHighlight({ color: customColor }).run();\n }\n resetMenu();\n };\n\n const handleCancelKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Enter' && open) {\n event.preventDefault();\n resetMenu();\n buttonRef.current?.focus();\n }\n };\n\n const handleCancelMouseDown = (event: MouseEvent<HTMLButtonElement>) => {\n if (open) {\n event.preventDefault();\n resetMenu();\n buttonRef.current?.focus();\n }\n };\n\n const handleEscapeClose = useCallback(() => {\n resetMenu();\n buttonRef.current?.focus();\n }, []);\n\n useEscapeKey(open, handleEscapeClose, editor);\n useCloseOnEditorClick(open, handleEscapeClose);\n\n const label = type === 'text' ? t('rte_text_color') : t('rte_background_color');\n const modalTitle = type === 'text' ? t('rte_font_color') : t('rte_background_color');\n const isHighlight = type === 'highlight';\n const colorPickerContent = (\n <StyledColorPickerContent container={{ direction: 'column', gap: 1 }}>\n <RadioButtonGroup\n name='colorType'\n label={t('rte_color_type')}\n labelHidden\n onChange={(e: ChangeEvent<HTMLInputElement>) => {\n const { value } = e.target;\n if (value === 'auto' || value === 'custom') {\n setColorType(value);\n }\n }}\n inline\n >\n <RadioButton label={t('rte_color_auto')} value='auto' checked={colorType === 'auto'} />\n <RadioButton\n label={t('rte_color_custom')}\n value='custom'\n checked={colorType === 'custom'}\n />\n </RadioButtonGroup>\n <ColorPicker\n label={t('rte_color')}\n labelHidden\n value={customColor}\n onChange={color => setCustomColor(color.hex)}\n disabled={colorType === 'auto'}\n />\n <StyledButtonGroup $touch={isTouchDevice}>\n <Button\n variant='secondary'\n onKeyDown={handleCancelKeyDown}\n onMouseDown={handleCancelMouseDown}\n type='button'\n >\n {t('cancel')}\n </Button>\n <Button variant='primary' onClick={handleSubmit}>\n {t('submit')}\n </Button>\n </StyledButtonGroup>\n </StyledColorPickerContent>\n );\n\n return (\n <>\n <StyledColorButton\n {...restProps}\n variant='simple'\n type='button'\n ref={buttonRef}\n data-toolbar-item='true'\n onMouseDown={(e: MouseEvent) => {\n e.preventDefault();\n openMenu();\n }}\n onKeyDown={(e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n openMenu();\n }\n }}\n onBlur={(e: React.FocusEvent) => {\n const { relatedTarget } = e;\n if (\n isInstance(relatedTarget, Node) &&\n !buttonRef.current?.contains(relatedTarget) &&\n !popoverRef.current?.contains(relatedTarget) &&\n !touchDialogRef.current?.contains(relatedTarget)\n ) {\n resetMenu();\n }\n }}\n aria-label={label}\n aria-haspopup='dialog'\n aria-expanded={open}\n >\n {isHighlight ? (\n <StyledHighlightColorIcon $color={currentColor}>A</StyledHighlightColorIcon>\n ) : (\n <StyledTextColorIcon $color={currentColor}>A</StyledTextColorIcon>\n )}\n </StyledColorButton>\n {buttonRef.current && !open && (\n <Tooltip target={buttonRef.current} showDelay='none' hideDelay='none'>\n {label}\n </Tooltip>\n )}\n {isTouchDevice ? (\n <TouchDialog\n ref={touchDialogRef}\n open={open}\n heading={modalTitle}\n onDismiss={resetMenu}\n onAfterClose={() => buttonRef.current?.focus()}\n >\n {colorPickerContent}\n </TouchDialog>\n ) : (\n <Popover show={open} target={buttonRef.current} ref={popoverRef} placement='bottom'>\n <StyledPopoverContent role='dialog' aria-labelledby={titleId}>\n <Text variant='h4' id={titleId}>\n {modalTitle}\n </Text>\n {colorPickerContent}\n </StyledPopoverContent>\n </Popover>\n )}\n </>\n );\n};\n\nexport default ColorPickerButton;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"FontFamilySelect.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/FontFamilySelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAoE3D,UAAU,qBAAqB;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,gBAAgB,GAAI,0BAA0B,qBAAqB,4CAwJxE,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"FontFamilySelect.d.ts","sourceRoot":"","sources":["../../../../src/components/Editor/Toolbar/FontFamilySelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAqE3D,UAAU,qBAAqB;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,gBAAgB,GAAI,0BAA0B,qBAAqB,4CAyKxE,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState, useCallback } from 'react';
3
3
  import styled, { css } from 'styled-components';
4
- import { Popover, Icon, registerIcon, useOuterEvent, Menu, Button, defaultThemeProp, useI18n, Tooltip, calculateFontSize, isInstance } from '@pega/cosmos-react-core';
4
+ import { Popover, TouchDialog, Icon, registerIcon, useOuterEvent, Menu, Button, defaultThemeProp, useI18n, Tooltip, calculateFontSize, isInstance, isTouchDevice } from '@pega/cosmos-react-core';
5
5
  import * as arrowMicroDownIcon from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-micro-down.icon';
6
6
  import useEscapeKey from '../hooks/useEscapeKey';
7
7
  import useCloseOnEditorClick from '../hooks/useCloseOnEditorClick';
@@ -49,7 +49,8 @@ const FontFamilySelect = ({ editor, ...restProps }) => {
49
49
  const buttonRef = useRef(null);
50
50
  const popoverRef = useRef(null);
51
51
  const menuRef = useRef(null);
52
- useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef], () => {
52
+ const touchDialogRef = useRef(null);
53
+ useOuterEvent('mousedown', [buttonRef, popoverRef, menuRef, touchDialogRef], () => {
53
54
  if (open) {
54
55
  setOpen(false);
55
56
  }
@@ -106,6 +107,11 @@ const FontFamilySelect = ({ editor, ...restProps }) => {
106
107
  const match = FONT_FAMILIES.find(f => f.value === fontFamily);
107
108
  return match?.id ?? 'default';
108
109
  };
110
+ const menuContent = (_jsx(Menu, { items: FONT_FAMILIES.map(font => ({
111
+ id: font.id,
112
+ primary: getFontLabel(font),
113
+ selected: font.id === getActiveFontId()
114
+ })), focusControlEl: isTouchDevice ? undefined : buttonRef.current ?? undefined, mode: 'single-select', ref: menuRef, onItemClick: onFontSelect }));
109
115
  return (_jsxs(_Fragment, { children: [_jsxs(StyledFontSelect, { ...restProps, variant: 'simple', type: 'button', icon: false, ref: buttonRef, "data-toolbar-item": 'true', onMouseDown: (e) => {
110
116
  e.preventDefault();
111
117
  if (!open) {
@@ -137,14 +143,11 @@ const FontFamilySelect = ({ editor, ...restProps }) => {
137
143
  if (isInstance(relatedTarget, Node) &&
138
144
  !buttonRef.current?.contains(relatedTarget) &&
139
145
  !popoverRef.current?.contains(relatedTarget) &&
140
- !menuRef.current?.contains(relatedTarget)) {
146
+ !menuRef.current?.contains(relatedTarget) &&
147
+ !touchDialogRef.current?.contains(relatedTarget)) {
141
148
  setOpen(false);
142
149
  }
143
- }, onClick: (e) => e.stopPropagation(), "aria-expanded": open, "aria-label": `${t('rte_font_family')}. ${getActiveFont()} ${t('selected').toLocaleLowerCase()}`, "aria-haspopup": true, children: [_jsx("span", { children: getActiveFont() }), _jsx(Icon, { name: 'arrow-micro-down' })] }), buttonRef.current && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: t('rte_font_family') })), _jsx(Popover, { show: open, as: StyledSelectMenu, target: buttonRef.current, placement: 'bottom-start', ref: popoverRef, children: _jsx(Menu, { items: FONT_FAMILIES.map(font => ({
144
- id: font.id,
145
- primary: getFontLabel(font),
146
- selected: font.id === getActiveFontId()
147
- })), focusControlEl: buttonRef.current ?? undefined, mode: 'single-select', ref: menuRef, onItemClick: onFontSelect }) })] }));
150
+ }, onClick: (e) => e.stopPropagation(), "aria-expanded": open, "aria-label": `${t('rte_font_family')}. ${getActiveFont()} ${t('selected').toLocaleLowerCase()}`, "aria-haspopup": true, children: [_jsx("span", { children: getActiveFont() }), _jsx(Icon, { name: 'arrow-micro-down' })] }), buttonRef.current && (_jsx(Tooltip, { target: buttonRef.current, showDelay: 'none', hideDelay: 'none', children: t('rte_font_family') })), isTouchDevice ? (_jsx(TouchDialog, { ref: touchDialogRef, open: open, heading: t('rte_font_family'), onDismiss: () => setOpen(false), children: menuContent })) : (_jsx(Popover, { show: open, as: StyledSelectMenu, target: buttonRef.current, placement: 'bottom-start', ref: popoverRef, children: menuContent }))] }));
148
151
  };
149
152
  export default FontFamilySelect;
150
153
  //# sourceMappingURL=FontFamilySelect.js.map