@antscorp/antsomi-ui 2.0.110 → 2.0.112
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.
- package/es/assets/css/main.scss +2 -0
- package/es/components/atoms/Eyedropper/Eyedropper.d.ts +2 -0
- package/es/components/atoms/Eyedropper/Eyedropper.js +53 -0
- package/es/components/atoms/Eyedropper/index.d.ts +0 -0
- package/es/components/atoms/Eyedropper/index.js +1 -0
- package/es/components/atoms/Eyedropper/styled.d.ts +9 -0
- package/es/components/atoms/Eyedropper/styled.js +45 -0
- package/es/components/atoms/Eyedropper/types.d.ts +5 -0
- package/es/components/atoms/Eyedropper/types.js +1 -0
- package/es/components/icons/ALignRightIcon.d.ts +3 -0
- package/es/components/icons/ALignRightIcon.js +7 -0
- package/es/components/icons/AlignCenterIcon.d.ts +3 -0
- package/es/components/icons/AlignCenterIcon.js +7 -0
- package/es/components/icons/AlignJustifyIcon.d.ts +3 -0
- package/es/components/icons/AlignJustifyIcon.js +7 -0
- package/es/components/icons/AlignLeftIcon.d.ts +3 -0
- package/es/components/icons/AlignLeftIcon.js +7 -0
- package/es/components/icons/ArrowDropDownIcon.d.ts +3 -0
- package/es/components/icons/ArrowDropDownIcon.js +7 -0
- package/es/components/icons/ChevronRightIcon.d.ts +3 -0
- package/es/components/icons/ChevronRightIcon.js +7 -0
- package/es/components/icons/ColorizeIcon.d.ts +3 -0
- package/es/components/icons/ColorizeIcon.js +7 -0
- package/es/components/icons/LazyIcon/LazyIcon.d.ts +9 -0
- package/es/components/icons/LazyIcon/LazyIcon.js +9 -0
- package/es/components/icons/LinkOffIcon.d.ts +3 -0
- package/es/components/icons/LinkOffIcon.js +7 -0
- package/es/components/icons/MinusIcon.d.ts +3 -0
- package/es/components/icons/MinusIcon.js +7 -0
- package/es/components/icons/index.d.ts +9 -0
- package/es/components/icons/index.js +9 -0
- package/es/components/index.scss +1 -0
- package/es/components/molecules/EmojiCollections/CommonCollection/index.js +2 -2
- package/es/components/molecules/EmojiCollections/types.d.ts +1 -0
- package/es/components/molecules/EmojiPopover/EmojiPopover.d.ts +2 -0
- package/es/components/molecules/EmojiPopover/EmojiPopover.js +10 -6
- package/es/components/molecules/EmojiPopover/styled.js +1 -1
- package/es/components/molecules/EyedropperButton/EyedropperButton.d.ts +11 -0
- package/es/components/molecules/EyedropperButton/EyedropperButton.js +34 -0
- package/es/components/molecules/EyedropperButton/index.d.ts +0 -0
- package/es/components/molecules/EyedropperButton/index.js +1 -0
- package/es/components/molecules/EyedropperButton/styled.d.ts +7 -0
- package/es/components/molecules/EyedropperButton/styled.js +23 -0
- package/es/components/molecules/FontSizeInput/FontSizeInput.d.ts +3 -0
- package/es/components/molecules/FontSizeInput/FontSizeInput.js +134 -0
- package/es/components/molecules/FontSizeInput/components/FontSizeControl.d.ts +8 -0
- package/es/components/molecules/FontSizeInput/components/FontSizeControl.js +14 -0
- package/es/components/molecules/FontSizeInput/components/FontSizeDropdown.d.ts +21 -0
- package/es/components/molecules/FontSizeInput/components/FontSizeDropdown.js +19 -0
- package/es/components/molecules/FontSizeInput/constants.d.ts +2 -0
- package/es/components/molecules/FontSizeInput/constants.js +5 -0
- package/es/components/molecules/FontSizeInput/index.d.ts +2 -0
- package/es/components/molecules/FontSizeInput/index.js +1 -0
- package/es/components/molecules/FontSizeInput/styled.d.ts +7 -0
- package/es/components/molecules/FontSizeInput/styled.js +39 -0
- package/es/components/molecules/FontSizeInput/types.d.ts +23 -0
- package/es/components/molecules/FontSizeInput/types.js +1 -0
- package/es/components/molecules/FontSizeInput/utils.d.ts +7 -0
- package/es/components/molecules/FontSizeInput/utils.js +9 -0
- package/es/components/molecules/SearchPopover/SearchPopover.d.ts +2 -1
- package/es/components/molecules/SearchPopover/SearchPopover.js +3 -3
- package/es/components/molecules/SearchPopover/styled.d.ts +12 -1
- package/es/components/molecules/SearchPopover/styled.js +1 -2
- package/es/components/molecules/SearchPopover/types.d.ts +4 -3
- package/es/components/molecules/VirtualizedMenu/VirtualizedMenu.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/components/Item/Item.js +6 -8
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.d.ts +10 -10
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.js +49 -289
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.d.ts +9 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.js +5 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.d.ts +23 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.js +81 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.js +32 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.d.ts +26 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.js +93 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.js +94 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.d.ts +7 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.js +132 -0
- package/es/components/molecules/VirtualizedMenu/styled.js +24 -3
- package/es/components/molecules/VirtualizedMenu/types.d.ts +2 -0
- package/es/components/molecules/VirtualizedMenu/utils.d.ts +2 -0
- package/es/components/molecules/VirtualizedMenu/utils.js +2 -0
- package/es/components/molecules/index.d.ts +1 -0
- package/es/components/molecules/index.js +1 -0
- package/es/components/molecules/index.scss +1 -0
- package/es/components/organism/TextEditor/TextEditor.d.ts +10 -0
- package/es/components/organism/TextEditor/TextEditor.js +403 -0
- package/es/components/organism/TextEditor/__mocks__/text-block.settings.json +320 -0
- package/es/components/organism/TextEditor/__mocks__/text-contennt.d.ts +1 -0
- package/es/components/organism/TextEditor/__mocks__/text-contennt.js +47 -0
- package/es/components/organism/TextEditor/constants.d.ts +196 -0
- package/es/components/organism/TextEditor/constants.js +398 -0
- package/es/components/organism/TextEditor/extensions/BackgroundColor.d.ts +25 -0
- package/es/components/organism/TextEditor/extensions/BackgroundColor.js +43 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.d.ts +18 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.js +81 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.d.ts +15 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.js +35 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/index.d.ts +2 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/index.js +2 -0
- package/es/components/organism/TextEditor/extensions/ClearFormatting.d.ts +16 -0
- package/es/components/organism/TextEditor/extensions/ClearFormatting.js +30 -0
- package/es/components/organism/TextEditor/extensions/Color.d.ts +6 -0
- package/es/components/organism/TextEditor/extensions/Color.js +34 -0
- package/es/components/organism/TextEditor/extensions/Emoji.d.ts +57 -0
- package/es/components/organism/TextEditor/extensions/Emoji.js +184 -0
- package/es/components/organism/TextEditor/extensions/FontFamily.d.ts +6 -0
- package/es/components/organism/TextEditor/extensions/FontFamily.js +36 -0
- package/es/components/organism/TextEditor/extensions/FontSize.d.ts +31 -0
- package/es/components/organism/TextEditor/extensions/FontSize.js +46 -0
- package/es/components/organism/TextEditor/extensions/FontWeight.d.ts +23 -0
- package/es/components/organism/TextEditor/extensions/FontWeight.js +41 -0
- package/es/components/organism/TextEditor/extensions/Indent.d.ts +21 -0
- package/es/components/organism/TextEditor/extensions/Indent.js +63 -0
- package/es/components/organism/TextEditor/extensions/LetterSpacing.d.ts +32 -0
- package/es/components/organism/TextEditor/extensions/LetterSpacing.js +48 -0
- package/es/components/organism/TextEditor/extensions/LineHeight.d.ts +20 -0
- package/es/components/organism/TextEditor/extensions/LineHeight.js +101 -0
- package/es/components/organism/TextEditor/extensions/Link.d.ts +22 -0
- package/es/components/organism/TextEditor/extensions/Link.js +197 -0
- package/es/components/organism/TextEditor/extensions/ListItem.d.ts +10 -0
- package/es/components/organism/TextEditor/extensions/ListItem.js +93 -0
- package/es/components/organism/TextEditor/extensions/ListItemMarker.d.ts +13 -0
- package/es/components/organism/TextEditor/extensions/ListItemMarker.js +174 -0
- package/es/components/organism/TextEditor/extensions/OrderedList.d.ts +56 -0
- package/es/components/organism/TextEditor/extensions/OrderedList.js +187 -0
- package/es/components/organism/TextEditor/extensions/SmartTag.d.ts +33 -0
- package/es/components/organism/TextEditor/extensions/SmartTag.js +194 -0
- package/es/components/organism/TextEditor/extensions/StyleMemory.d.ts +36 -0
- package/es/components/organism/TextEditor/extensions/StyleMemory.js +163 -0
- package/es/components/organism/TextEditor/extensions/TextTransform.d.ts +30 -0
- package/es/components/organism/TextEditor/extensions/TextTransform.js +36 -0
- package/es/components/organism/TextEditor/extensions/UnorderedList.d.ts +55 -0
- package/es/components/organism/TextEditor/extensions/UnorderedList.js +176 -0
- package/es/components/organism/TextEditor/hooks/index.d.ts +6 -0
- package/es/components/organism/TextEditor/hooks/index.js +6 -0
- package/es/components/organism/TextEditor/hooks/useColorSet.d.ts +4 -0
- package/es/components/organism/TextEditor/hooks/useColorSet.js +29 -0
- package/es/components/organism/TextEditor/hooks/useDocumentState.d.ts +18 -0
- package/es/components/organism/TextEditor/hooks/useDocumentState.js +42 -0
- package/es/components/organism/TextEditor/hooks/useMarkTracking.d.ts +26 -0
- package/es/components/organism/TextEditor/hooks/useMarkTracking.js +69 -0
- package/es/components/organism/TextEditor/hooks/usePersistence.d.ts +31 -0
- package/es/components/organism/TextEditor/hooks/usePersistence.js +169 -0
- package/es/components/organism/TextEditor/hooks/useStyleMemory.d.ts +6 -0
- package/es/components/organism/TextEditor/hooks/useStyleMemory.js +42 -0
- package/es/components/organism/TextEditor/hooks/useStylePresets.d.ts +34 -0
- package/es/components/organism/TextEditor/hooks/useStylePresets.js +83 -0
- package/es/components/organism/TextEditor/index.d.ts +18 -0
- package/es/components/organism/TextEditor/index.js +8 -0
- package/es/components/organism/TextEditor/index.scss +65 -0
- package/es/components/organism/TextEditor/provider.d.ts +15 -0
- package/es/components/organism/TextEditor/provider.js +36 -0
- package/es/components/organism/TextEditor/store.d.ts +20 -0
- package/es/components/organism/TextEditor/store.js +40 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/froala-legacy-format.settings.json +95 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.d.ts +111 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.js +82 -0
- package/es/components/organism/TextEditor/stories/shared.d.ts +64 -0
- package/es/components/organism/TextEditor/stories/shared.js +57 -0
- package/es/components/organism/TextEditor/styled.d.ts +9 -0
- package/es/components/organism/TextEditor/styled.js +61 -0
- package/es/components/organism/TextEditor/types.d.ts +324 -0
- package/es/components/organism/TextEditor/types.js +6 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.d.ts +3 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.js +114 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Button/Button.d.ts +9 -0
- package/es/components/organism/TextEditor/ui/Button/Button.js +35 -0
- package/es/components/organism/TextEditor/ui/Button/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/Button/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Button/types.d.ts +10 -0
- package/es/components/organism/TextEditor/ui/Button/types.js +1 -0
- package/es/components/organism/TextEditor/ui/ColorPicker/ColorPicker.d.ts +39 -0
- package/es/components/organism/TextEditor/ui/ColorPicker/ColorPicker.js +131 -0
- package/es/components/organism/TextEditor/ui/ColorPicker/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/ColorPicker/index.js +1 -0
- package/es/components/organism/TextEditor/ui/DropdownButton/DropdownButton.d.ts +17 -0
- package/es/components/organism/TextEditor/ui/DropdownButton/DropdownButton.js +51 -0
- package/es/components/organism/TextEditor/ui/DropdownButton/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/DropdownButton/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Emoji/EmojiList.d.ts +11 -0
- package/es/components/organism/TextEditor/ui/Emoji/EmojiList.js +66 -0
- package/es/components/organism/TextEditor/ui/Emoji/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/Emoji/index.js +2 -0
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.d.ts +4 -0
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.js +71 -0
- package/es/components/organism/TextEditor/ui/FontPopover/FontItem.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/FontPopover/FontItem.js +27 -0
- package/es/components/organism/TextEditor/ui/FontPopover/FontPopover.d.ts +16 -0
- package/es/components/organism/TextEditor/ui/FontPopover/FontPopover.js +102 -0
- package/es/components/organism/TextEditor/ui/FontPopover/styled.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/FontPopover/styled.js +36 -0
- package/es/components/organism/TextEditor/ui/FontPopover/types.d.ts +35 -0
- package/es/components/organism/TextEditor/ui/FontPopover/types.js +1 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.d.ts +16 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.js +61 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.js +1 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.d.ts +9 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.js +126 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Popover/Popover.d.ts +6 -0
- package/es/components/organism/TextEditor/ui/Popover/Popover.js +9 -0
- package/es/components/organism/TextEditor/ui/Popover/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/Popover/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Select/Select.d.ts +4 -0
- package/es/components/organism/TextEditor/ui/Select/Select.js +7 -0
- package/es/components/organism/TextEditor/ui/Select/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/Select/index.js +1 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/SplitButtonDropdown.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/SplitButtonDropdown.js +44 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/index.js +1 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/styled.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/styled.js +58 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/types.d.ts +19 -0
- package/es/components/organism/TextEditor/ui/SplitButtonDropdown/types.js +1 -0
- package/es/components/organism/TextEditor/ui/TextAlignSelect/TextAlignSelect.d.ts +30 -0
- package/es/components/organism/TextEditor/ui/TextAlignSelect/TextAlignSelect.js +75 -0
- package/es/components/organism/TextEditor/ui/TextAlignSelect/index.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/TextAlignSelect/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Toolbar/FormattingToolbar.d.ts +19 -0
- package/es/components/organism/TextEditor/ui/Toolbar/FormattingToolbar.js +85 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.d.ts +10 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.js +39 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/BoldAction.d.ts +6 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/BoldAction.js +19 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/BulletListAction.d.ts +6 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/BulletListAction.js +93 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/ClearFormattingAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/ClearFormattingAction.js +20 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/EmojiAction.d.ts +4 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/EmojiAction.js +32 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.d.ts +19 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.js +41 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontSizeAction.d.ts +8 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontSizeAction.js +51 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/HistoryAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/HistoryAction.js +21 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/IndentAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/IndentAction.js +17 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/ItalicAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/ItalicAction.js +18 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LetterSpacing.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LetterSpacing.js +28 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LineSpacingAction.d.ts +10 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LineSpacingAction.js +45 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LinkAction.d.ts +6 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/LinkAction.js +17 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/OrderedListAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/OrderedListAction.js +67 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/OutdentAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/OutdentAction.js +17 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SmartTagAction.d.ts +7 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SmartTagAction.js +18 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/StrikeAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/StrikeAction.js +18 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SubscriptAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SubscriptAction.js +26 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SuperscriptAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/SuperscriptAction.js +26 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextAlignAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextAlignAction.js +3 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextBackgroundColorAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextBackgroundColorAction.js +29 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextColorAction.d.ts +14 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextColorAction.js +22 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextTransformAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/TextTransformAction.js +36 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/UnderlineAction.d.ts +5 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/UnderlineAction.js +18 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/UnsetLink.d.ts +7 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/UnsetLink.js +18 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/index.d.ts +24 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/index.js +24 -0
- package/es/components/organism/TextEditor/ui/Toolbar/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/Toolbar/index.js +2 -0
- package/es/components/organism/TextEditor/utils/documentState.d.ts +73 -0
- package/es/components/organism/TextEditor/utils/documentState.js +149 -0
- package/es/components/organism/TextEditor/utils/font.d.ts +74 -0
- package/es/components/organism/TextEditor/utils/font.js +147 -0
- package/es/components/organism/TextEditor/utils/htmlProcessing.d.ts +87 -0
- package/es/components/organism/TextEditor/utils/htmlProcessing.js +460 -0
- package/es/components/organism/TextEditor/utils/indent.d.ts +11 -0
- package/es/components/organism/TextEditor/utils/indent.js +56 -0
- package/es/components/organism/TextEditor/utils/index.d.ts +8 -0
- package/es/components/organism/TextEditor/utils/index.js +16 -0
- package/es/components/organism/TextEditor/utils/link.d.ts +116 -0
- package/es/components/organism/TextEditor/utils/link.js +304 -0
- package/es/components/organism/TextEditor/utils/menu.d.ts +134 -0
- package/es/components/organism/TextEditor/utils/menu.js +321 -0
- package/es/components/organism/TextEditor/utils/selection.d.ts +25 -0
- package/es/components/organism/TextEditor/utils/selection.js +58 -0
- package/es/components/organism/TextEditor/utils/shared.d.ts +13 -0
- package/es/components/organism/TextEditor/utils/shared.js +52 -0
- package/es/components/organism/TextEditor/utils/smartTag.d.ts +49 -0
- package/es/components/organism/TextEditor/utils/smartTag.js +90 -0
- package/es/components/organism/TextEditor/utils/style.d.ts +78 -0
- package/es/components/organism/TextEditor/utils/style.js +193 -0
- package/es/components/organism/index.d.ts +1 -0
- package/es/components/organism/index.js +1 -0
- package/es/components/organism/index.scss +1 -0
- package/es/constants/index.d.ts +1 -0
- package/es/constants/index.js +1 -0
- package/es/constants/web.d.ts +8 -0
- package/es/constants/web.js +57 -0
- package/es/hooks/index.d.ts +4 -0
- package/es/hooks/index.js +4 -0
- package/es/hooks/useBroadcastedLocalStorage.d.ts +5 -0
- package/es/hooks/useBroadcastedLocalStorage.js +71 -0
- package/es/hooks/useElementSize.d.ts +7 -0
- package/es/hooks/useElementSize.js +56 -0
- package/es/hooks/useEyedropper/attach.d.ts +4 -0
- package/es/hooks/useEyedropper/attach.js +9 -0
- package/es/hooks/useEyedropper/eyedropper.d.ts +69 -0
- package/es/hooks/useEyedropper/eyedropper.js +205 -0
- package/es/hooks/useEyedropper/index.d.ts +2 -0
- package/es/hooks/useEyedropper/index.js +7 -0
- package/es/hooks/useEyedropper/support.d.ts +1 -0
- package/es/hooks/useEyedropper/support.js +3 -0
- package/es/hooks/useEyedropper/types.d.ts +9 -0
- package/es/hooks/useEyedropper/types.js +1 -0
- package/es/hooks/useEyedropper/useEyedropper.d.ts +8 -0
- package/es/hooks/useEyedropper/useEyedropper.js +50 -0
- package/es/hooks/useEyedropper/utils.d.ts +11 -0
- package/es/hooks/useEyedropper/utils.js +17 -0
- package/es/hooks/useIsMounted.d.ts +1 -0
- package/es/hooks/useIsMounted.js +11 -0
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/locales/i18n.d.ts +1 -1
- package/es/types/index.d.ts +9 -0
- package/es/utils/common.d.ts +15 -9
- package/es/utils/common.js +62 -24
- package/es/utils/index.d.ts +1 -0
- package/es/utils/index.js +1 -0
- package/es/utils/web.d.ts +80 -0
- package/es/utils/web.js +226 -0
- package/package.json +26 -17
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { DEFAULT_TEXT_STYLE } from '../constants';
|
|
3
|
+
import { convertPxToNumber } from '@antscorp/antsomi-ui/es/utils';
|
|
4
|
+
function convertLineHeight(lineHeight, fontSize = 22) {
|
|
5
|
+
// Handle null/undefined cases
|
|
6
|
+
if (lineHeight == null) {
|
|
7
|
+
return 1.2; // Default line-height in most browsers
|
|
8
|
+
}
|
|
9
|
+
if (typeof lineHeight === 'number') {
|
|
10
|
+
return lineHeight;
|
|
11
|
+
}
|
|
12
|
+
const value = String(lineHeight).trim();
|
|
13
|
+
// Handle percentage values (e.g., "150%" -> 1.5)
|
|
14
|
+
if (value.endsWith('%')) {
|
|
15
|
+
const percentValue = parseFloat(value.slice(0, -1));
|
|
16
|
+
if (isNaN(percentValue)) {
|
|
17
|
+
throw new Error(`Invalid percentage value: ${lineHeight}`);
|
|
18
|
+
}
|
|
19
|
+
return percentValue / 100;
|
|
20
|
+
}
|
|
21
|
+
// Handle pixel values (e.g., "24px" -> 1.5 with 16px font)
|
|
22
|
+
if (value.endsWith('px') && fontSize) {
|
|
23
|
+
const pixelValue = parseFloat(value.slice(0, -2));
|
|
24
|
+
if (isNaN(pixelValue)) {
|
|
25
|
+
throw new Error(`Invalid pixel value: ${lineHeight}`);
|
|
26
|
+
}
|
|
27
|
+
if (fontSize <= 0) {
|
|
28
|
+
throw new Error(`Invalid font size for px conversion: ${fontSize}`);
|
|
29
|
+
}
|
|
30
|
+
return pixelValue / fontSize;
|
|
31
|
+
}
|
|
32
|
+
// Handle em/rem values (e.g., "1.5em" -> 1.5)
|
|
33
|
+
if (value.endsWith('em') || value.endsWith('rem')) {
|
|
34
|
+
const numValue = parseFloat(value.slice(0, -2));
|
|
35
|
+
if (isNaN(numValue)) {
|
|
36
|
+
throw new Error(`Invalid em/rem value: ${lineHeight}`);
|
|
37
|
+
}
|
|
38
|
+
return numValue;
|
|
39
|
+
}
|
|
40
|
+
const numValue = parseFloat(value);
|
|
41
|
+
if (isNaN(numValue)) {
|
|
42
|
+
throw new Error(`Cannot convert line-height value "${lineHeight}" to number!`);
|
|
43
|
+
}
|
|
44
|
+
return numValue;
|
|
45
|
+
}
|
|
46
|
+
function canConvertLineHeight(lineHeight, fontSize = 16) {
|
|
47
|
+
try {
|
|
48
|
+
// Try to convert, if no error thrown then it's convertible
|
|
49
|
+
convertLineHeight(lineHeight, fontSize);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export const LineHeight = Extension.create({
|
|
57
|
+
name: 'lineHeight',
|
|
58
|
+
addOptions() {
|
|
59
|
+
return {
|
|
60
|
+
types: ['textStyle'],
|
|
61
|
+
defaultHeight: DEFAULT_TEXT_STYLE.lineHeight,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
addGlobalAttributes() {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
types: this.options.types,
|
|
68
|
+
attributes: {
|
|
69
|
+
lineHeight: {
|
|
70
|
+
default: this.options.defaultHeight,
|
|
71
|
+
parseHTML: element => {
|
|
72
|
+
const pxFontSize = convertPxToNumber(element.style.fontSize);
|
|
73
|
+
let { lineHeight } = element.style;
|
|
74
|
+
if (element.parentElement instanceof HTMLParagraphElement) {
|
|
75
|
+
const { lineHeight: parentParagraphLineHeight } = element.parentElement.style;
|
|
76
|
+
if (canConvertLineHeight(parentParagraphLineHeight)) {
|
|
77
|
+
lineHeight = parentParagraphLineHeight;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!canConvertLineHeight(lineHeight))
|
|
81
|
+
return null;
|
|
82
|
+
return convertLineHeight(lineHeight, pxFontSize);
|
|
83
|
+
},
|
|
84
|
+
renderHTML: attrs => {
|
|
85
|
+
if (!attrs.lineHeight || attrs.lineHeight === this.options.defaultHeight) {
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
return { style: `line-height: ${attrs.lineHeight}` };
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
},
|
|
95
|
+
addCommands() {
|
|
96
|
+
return {
|
|
97
|
+
setLineHeight: lineHeight => ({ chain }) => chain().setMark('textStyle', { lineHeight }).run(),
|
|
98
|
+
unsetLineHeight: () => ({ chain }) => chain().setMark('textStyle', { lineHeight: null }).removeEmptyTextStyle().run(),
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LinkAttrs } from '../types';
|
|
2
|
+
import { LinkOptions as TiptapLinkOptions } from '@tiptap/extension-link';
|
|
3
|
+
export type LinkOptions = TiptapLinkOptions;
|
|
4
|
+
declare module '@tiptap/core' {
|
|
5
|
+
interface Commands<ReturnType> {
|
|
6
|
+
customLink: {
|
|
7
|
+
setCustomLink: (params: {
|
|
8
|
+
attrs?: LinkAttrs;
|
|
9
|
+
content?: string;
|
|
10
|
+
}) => ReturnType;
|
|
11
|
+
deleteCustomLink: (predicate: (attrs: LinkAttrs) => boolean) => ReturnType;
|
|
12
|
+
unsetCustomLink: () => ReturnType;
|
|
13
|
+
updateCustomLinkAttrsGlobally: (predicate: (currentAttrs: LinkAttrs) => boolean, updateFn: (currentAttrs: LinkAttrs) => LinkAttrs | false) => ReturnType;
|
|
14
|
+
updateCustomLinkText: (params: {
|
|
15
|
+
predicate: (attrs: LinkAttrs) => boolean;
|
|
16
|
+
updated: (currentText: string) => string;
|
|
17
|
+
mergeAdjacentEqualFn?: (currentAttrs: LinkAttrs, candidateAttrs: LinkAttrs) => boolean;
|
|
18
|
+
}) => ReturnType;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export declare const CustomLink: import("@tiptap/core").Mark<TiptapLinkOptions, any>;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import TiptapLinkExtension from '@tiptap/extension-link';
|
|
2
|
+
import { CUSTOM_LINK_EXTENSION_NAME, LINK_TEXT_COLOR } from '../constants';
|
|
3
|
+
import { TextSelection } from '@tiptap/pm/state';
|
|
4
|
+
import { dataAttrArrayToObject } from '@antscorp/antsomi-ui/es/utils';
|
|
5
|
+
import { isEmpty, isEqual, map, toString } from 'lodash';
|
|
6
|
+
import { getLinkMarkRanges, getLinkRange, isLinkColor, textBetween } from '../utils';
|
|
7
|
+
import { mergeAdjacentRanges } from '../utils/shared';
|
|
8
|
+
export const CustomLink = TiptapLinkExtension.extend({
|
|
9
|
+
name: CUSTOM_LINK_EXTENSION_NAME,
|
|
10
|
+
inclusive: false,
|
|
11
|
+
addOptions() {
|
|
12
|
+
return {
|
|
13
|
+
...this.parent(),
|
|
14
|
+
openOnClick: false,
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
addAttributes() {
|
|
18
|
+
return {
|
|
19
|
+
...this.parent?.(),
|
|
20
|
+
title: { default: null, parseHTML: el => el.title },
|
|
21
|
+
data: {
|
|
22
|
+
default: null,
|
|
23
|
+
parseHTML: el => {
|
|
24
|
+
const { dataset } = el;
|
|
25
|
+
return { ...dataset };
|
|
26
|
+
},
|
|
27
|
+
renderHTML: (attrs) => {
|
|
28
|
+
const dataAttrs = map(attrs.data || {}, (value, key) => ({
|
|
29
|
+
key: `data-${key}`,
|
|
30
|
+
value: toString(value),
|
|
31
|
+
}));
|
|
32
|
+
return dataAttrArrayToObject(dataAttrs);
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
addCommands() {
|
|
38
|
+
return {
|
|
39
|
+
...this.parent?.(),
|
|
40
|
+
setCustomLink: ({ attrs, content }) => ({ state, chain }) => {
|
|
41
|
+
const { selection } = state;
|
|
42
|
+
const { from, to } = selection;
|
|
43
|
+
// Check if custom content is provided and different from current text
|
|
44
|
+
const currentText = textBetween(state, from, to);
|
|
45
|
+
const shouldUseCustomContent = content && currentText !== content;
|
|
46
|
+
if (shouldUseCustomContent) {
|
|
47
|
+
// Use custom content as string (replace content)
|
|
48
|
+
return chain()
|
|
49
|
+
.focus()
|
|
50
|
+
.deleteSelection()
|
|
51
|
+
.insertContent(content)
|
|
52
|
+
.command(({ tr }) => {
|
|
53
|
+
const endPos = tr.selection.from;
|
|
54
|
+
const startPos = endPos - content.length;
|
|
55
|
+
tr.setSelection(TextSelection.create(tr.doc, startPos, endPos));
|
|
56
|
+
return true;
|
|
57
|
+
})
|
|
58
|
+
.setLink({
|
|
59
|
+
...attrs,
|
|
60
|
+
href: attrs?.href || './',
|
|
61
|
+
})
|
|
62
|
+
.command(({ tr }) => {
|
|
63
|
+
const endPos = tr.selection.to;
|
|
64
|
+
tr.setSelection(TextSelection.create(tr.doc, endPos, endPos));
|
|
65
|
+
return true;
|
|
66
|
+
})
|
|
67
|
+
.run();
|
|
68
|
+
}
|
|
69
|
+
// Preserve existing content structure (atom nodes like smartTag)
|
|
70
|
+
// Just apply link mark on current selection without modifying content
|
|
71
|
+
return chain()
|
|
72
|
+
.focus()
|
|
73
|
+
.command(({ tr }) => {
|
|
74
|
+
// Ensure selection is set correctly
|
|
75
|
+
tr.setSelection(TextSelection.create(tr.doc, from, to));
|
|
76
|
+
return true;
|
|
77
|
+
})
|
|
78
|
+
.setLink({
|
|
79
|
+
...attrs,
|
|
80
|
+
href: attrs?.href || './',
|
|
81
|
+
})
|
|
82
|
+
.command(({ tr }) => {
|
|
83
|
+
const endPos = tr.selection.to;
|
|
84
|
+
tr.setSelection(TextSelection.create(tr.doc, endPos, endPos));
|
|
85
|
+
return true;
|
|
86
|
+
})
|
|
87
|
+
.run();
|
|
88
|
+
},
|
|
89
|
+
deleteCustomLink: predicate => ({ state, chain }) => {
|
|
90
|
+
const { doc } = state;
|
|
91
|
+
let linkMark;
|
|
92
|
+
doc.descendants((node, pos) => {
|
|
93
|
+
if (linkMark)
|
|
94
|
+
return;
|
|
95
|
+
linkMark = getLinkMarkRanges({
|
|
96
|
+
state,
|
|
97
|
+
from: pos,
|
|
98
|
+
to: pos + node.nodeSize,
|
|
99
|
+
}).find(range => predicate(range.mark.attrs));
|
|
100
|
+
});
|
|
101
|
+
if (!linkMark)
|
|
102
|
+
return false;
|
|
103
|
+
return chain()
|
|
104
|
+
.deleteRange({
|
|
105
|
+
from: linkMark.from,
|
|
106
|
+
to: linkMark.to,
|
|
107
|
+
})
|
|
108
|
+
.run();
|
|
109
|
+
},
|
|
110
|
+
unsetCustomLink: () => ({ editor, state, chain }) => {
|
|
111
|
+
const linkRange = getLinkRange({ state, pos: state.selection.from });
|
|
112
|
+
if (!linkRange)
|
|
113
|
+
return false;
|
|
114
|
+
const command = chain()
|
|
115
|
+
.setTextSelection({
|
|
116
|
+
from: linkRange.from,
|
|
117
|
+
to: linkRange.to,
|
|
118
|
+
})
|
|
119
|
+
.unsetLink()
|
|
120
|
+
.unsetUnderline();
|
|
121
|
+
if (isLinkColor(editor.getAttributes('textStyle').color)) {
|
|
122
|
+
command.unsetColor();
|
|
123
|
+
}
|
|
124
|
+
return command.run();
|
|
125
|
+
},
|
|
126
|
+
updateCustomLinkAttrsGlobally: (predicate, updateFn) => ({ state, tr, dispatch }) => {
|
|
127
|
+
const { doc, schema } = state;
|
|
128
|
+
if (!dispatch)
|
|
129
|
+
return true;
|
|
130
|
+
const linkType = schema.marks[CustomLink.name];
|
|
131
|
+
let somethingChanged = false;
|
|
132
|
+
const linkMarkRanges = getLinkMarkRanges({
|
|
133
|
+
state,
|
|
134
|
+
from: 0,
|
|
135
|
+
to: doc.content.size,
|
|
136
|
+
});
|
|
137
|
+
linkMarkRanges.forEach(markRange => {
|
|
138
|
+
const currentLinkAttrs = markRange.mark.attrs;
|
|
139
|
+
const from = () => tr.mapping.map(markRange.from);
|
|
140
|
+
const to = () => tr.mapping.map(markRange.to);
|
|
141
|
+
const isMatched = predicate(currentLinkAttrs);
|
|
142
|
+
if (!isMatched)
|
|
143
|
+
return;
|
|
144
|
+
const updated = updateFn(currentLinkAttrs);
|
|
145
|
+
if (!updated || isEmpty(updated))
|
|
146
|
+
return;
|
|
147
|
+
if (!isEmpty(updated)) {
|
|
148
|
+
somethingChanged = true;
|
|
149
|
+
// Create a new mark with updated attributes and add it
|
|
150
|
+
const newMark = linkType.create({
|
|
151
|
+
...markRange.mark.attrs,
|
|
152
|
+
...updated,
|
|
153
|
+
});
|
|
154
|
+
tr.addMark(from(), to(), newMark);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return somethingChanged;
|
|
158
|
+
},
|
|
159
|
+
updateCustomLinkText: ({ predicate, updated, mergeAdjacentEqualFn = isEqual }) => ({ state, tr, dispatch }) => {
|
|
160
|
+
if (!dispatch)
|
|
161
|
+
return true;
|
|
162
|
+
const linkMarkRanges = getLinkMarkRanges({
|
|
163
|
+
state,
|
|
164
|
+
from: 0,
|
|
165
|
+
to: state.doc.content.size,
|
|
166
|
+
}).filter(range => predicate(range.mark.attrs));
|
|
167
|
+
mergeAdjacentRanges(linkMarkRanges, (existingRanges, candidateRange) => existingRanges.some(range => mergeAdjacentEqualFn(range.mark.attrs, candidateRange.mark.attrs))).forEach(range => {
|
|
168
|
+
const currentText = textBetween(state, range.from, range.to);
|
|
169
|
+
const updatedText = updated(currentText);
|
|
170
|
+
if (currentText === updatedText)
|
|
171
|
+
return;
|
|
172
|
+
const previousLinkMark = range.data.at(0)?.mark;
|
|
173
|
+
if (!previousLinkMark)
|
|
174
|
+
return;
|
|
175
|
+
const from = () => tr.mapping.map(range.from);
|
|
176
|
+
const to = () => tr.mapping.map(range.to);
|
|
177
|
+
tr.insertText(updatedText, from(), to());
|
|
178
|
+
tr.addMark(from(), from() + updatedText.length, previousLinkMark);
|
|
179
|
+
});
|
|
180
|
+
return true;
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
addKeyboardShortcuts() {
|
|
185
|
+
return {
|
|
186
|
+
...this.parent?.(),
|
|
187
|
+
Enter: ({ editor }) => {
|
|
188
|
+
editor.chain().unsetUnderline().run();
|
|
189
|
+
const currentColor = editor.getAttributes('textStyle').color;
|
|
190
|
+
if (currentColor === LINK_TEXT_COLOR) {
|
|
191
|
+
editor.chain().unsetColor().run();
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom ListItem extension that extends the default TipTap ListItem
|
|
3
|
+
* with custom Backspace behavior to prevent merging paragraphs into lists
|
|
4
|
+
*
|
|
5
|
+
* This extension only overrides keyboard shortcuts while maintaining
|
|
6
|
+
* all other default ListItem functionality (HTML parsing, rendering, etc.)
|
|
7
|
+
*
|
|
8
|
+
* @see https://www.tiptap.dev/api/nodes/list-item
|
|
9
|
+
*/
|
|
10
|
+
export declare const CustomListItem: import("@tiptap/core").Node<import("@tiptap/extension-list").ListItemOptions, any>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ListItem } from '@tiptap/extension-list-item';
|
|
2
|
+
/**
|
|
3
|
+
* Custom ListItem extension that extends the default TipTap ListItem
|
|
4
|
+
* with custom Backspace behavior to prevent merging paragraphs into lists
|
|
5
|
+
*
|
|
6
|
+
* This extension only overrides keyboard shortcuts while maintaining
|
|
7
|
+
* all other default ListItem functionality (HTML parsing, rendering, etc.)
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.tiptap.dev/api/nodes/list-item
|
|
10
|
+
*/
|
|
11
|
+
export const CustomListItem = ListItem.extend({
|
|
12
|
+
addOptions() {
|
|
13
|
+
return {
|
|
14
|
+
HTMLAttributes: {
|
|
15
|
+
style: 'line-height:normal;',
|
|
16
|
+
},
|
|
17
|
+
bulletListTypeName: 'customUnorderedList',
|
|
18
|
+
orderedListTypeName: 'customOrderedList',
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
addKeyboardShortcuts() {
|
|
22
|
+
return {
|
|
23
|
+
// Keep default keyboard shortcuts from parent ListItem
|
|
24
|
+
Enter: () => this.editor.commands.splitListItem(this.name),
|
|
25
|
+
Tab: () => this.editor.commands.sinkListItem(this.name),
|
|
26
|
+
'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
|
|
27
|
+
/**
|
|
28
|
+
* Custom Backspace handler to prevent merging empty paragraphs into lists
|
|
29
|
+
*
|
|
30
|
+
* Behavior:
|
|
31
|
+
* 1. Check if cursor is at the start of a paragraph
|
|
32
|
+
* 2. Check if the node before is a list (ordered or unordered)
|
|
33
|
+
* 3. If both conditions are true and paragraph is empty, delete the paragraph
|
|
34
|
+
* 4. Otherwise, use default backspace behavior
|
|
35
|
+
*/
|
|
36
|
+
Backspace: () => {
|
|
37
|
+
const { state } = this.editor;
|
|
38
|
+
const { selection } = state;
|
|
39
|
+
const { $from, empty } = selection;
|
|
40
|
+
// Only handle if selection is empty (cursor position, not text selection)
|
|
41
|
+
if (!empty) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// Check if cursor is at the start of current node
|
|
45
|
+
const isAtStart = $from.parentOffset === 0;
|
|
46
|
+
if (!isAtStart) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Get current node (should be a paragraph)
|
|
50
|
+
const currentNode = $from.parent;
|
|
51
|
+
// Only handle paragraphs
|
|
52
|
+
if (currentNode.type.name !== 'paragraph') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// Get the index of current paragraph in its parent (usually doc)
|
|
56
|
+
const paragraphDepth = $from.depth;
|
|
57
|
+
const indexInParent = $from.index(paragraphDepth - 1);
|
|
58
|
+
// Check if there's a node before (index > 0)
|
|
59
|
+
if (indexInParent === 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
// Get parent node (usually doc) and the node before current paragraph
|
|
63
|
+
const parent = $from.node(paragraphDepth - 1);
|
|
64
|
+
const nodeBefore = parent.child(indexInParent - 1);
|
|
65
|
+
if (!nodeBefore) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
// Check if the node before is a list (ordered or unordered)
|
|
69
|
+
const isListBefore = nodeBefore.type.name === this.options.orderedListTypeName ||
|
|
70
|
+
nodeBefore.type.name === this.options.bulletListTypeName;
|
|
71
|
+
if (!isListBefore) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
// Check if current paragraph is empty
|
|
75
|
+
const isParagraphEmpty = currentNode.content.size === 0;
|
|
76
|
+
if (!isParagraphEmpty) {
|
|
77
|
+
// If paragraph has content, allow default backspace to handle
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// Calculate the exact positions of the paragraph node
|
|
81
|
+
// We need to delete from the position before the paragraph open tag
|
|
82
|
+
// to the position after the paragraph close tag
|
|
83
|
+
const paragraphPos = $from.before();
|
|
84
|
+
const paragraphEndPos = $from.after();
|
|
85
|
+
// Delete the entire paragraph node using deleteRange
|
|
86
|
+
return this.editor.commands.deleteRange({
|
|
87
|
+
from: paragraphPos,
|
|
88
|
+
to: paragraphEndPos,
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
export interface ListItemMarkerOptions {
|
|
3
|
+
paddingRight: number;
|
|
4
|
+
defaultFontSize: string;
|
|
5
|
+
defaultFontFamily: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Extension tạo marker tùy chỉnh cho danh sách trong p
|
|
9
|
+
*
|
|
10
|
+
* Extension này thay thế marker mặc định của danh sách bằng các marker
|
|
11
|
+
* có thể kế thừa style (font, size, color...) từ text node đầu tiên.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ListItemMarker: Extension<ListItemMarkerOptions, any>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { Plugin, PluginKey } from '@tiptap/pm/state';
|
|
3
|
+
import { Decoration, DecorationSet } from '@tiptap/pm/view';
|
|
4
|
+
import { kebabCase } from 'lodash';
|
|
5
|
+
function getMaxMarkerWidth(markers, font = '16px Arial') {
|
|
6
|
+
let max = 0;
|
|
7
|
+
const canvas = document.createElement('canvas');
|
|
8
|
+
const ctx = canvas.getContext('2d');
|
|
9
|
+
if (!ctx)
|
|
10
|
+
return max;
|
|
11
|
+
ctx.font = font;
|
|
12
|
+
for (const m of markers) {
|
|
13
|
+
const w = ctx.measureText(m).width;
|
|
14
|
+
if (w > max)
|
|
15
|
+
max = w;
|
|
16
|
+
}
|
|
17
|
+
return max;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Tạo các marker tùy chỉnh cho danh sách (bullet và ordered) với style kế thừa từ text node
|
|
21
|
+
*
|
|
22
|
+
* @param doc - ProseMirror document node
|
|
23
|
+
* @returns DecorationSet chứa tất cả các widget decoration cho marker
|
|
24
|
+
*/
|
|
25
|
+
const styleMarker = (doc, options) => {
|
|
26
|
+
const decorations = [];
|
|
27
|
+
doc.descendants((listNode, listNodePos) => {
|
|
28
|
+
const isBulletList = listNode.type.name === 'bulletList';
|
|
29
|
+
const isOrderedList = listNode.type.name === 'orderedList';
|
|
30
|
+
if (!isBulletList && !isOrderedList) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Khởi tạo marker dựa trên loại danh sách
|
|
34
|
+
const getMarker = (isOrderedList, index) => isOrderedList ? `${index + 1}.` : '•';
|
|
35
|
+
const markers = [];
|
|
36
|
+
const listItems = [];
|
|
37
|
+
listNode.descendants((listItem, listItemPos) => {
|
|
38
|
+
if (listItem.type.name !== 'listItem') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const itemInfo = {
|
|
42
|
+
node: listItem,
|
|
43
|
+
pos: listItemPos,
|
|
44
|
+
isEmpty: true,
|
|
45
|
+
};
|
|
46
|
+
listItems.push(itemInfo);
|
|
47
|
+
// Tìm paragraph đầu tiên và text node đầu tiên
|
|
48
|
+
let foundText = false;
|
|
49
|
+
let foundParagraph = false;
|
|
50
|
+
listItem.descendants((node, nodePos) => {
|
|
51
|
+
if (!foundParagraph && node.type.name === 'paragraph') {
|
|
52
|
+
foundParagraph = true;
|
|
53
|
+
itemInfo.paragraphPos = nodePos;
|
|
54
|
+
itemInfo.paragraphNode = node;
|
|
55
|
+
}
|
|
56
|
+
if (!foundText && node.type.name === 'text') {
|
|
57
|
+
foundText = true;
|
|
58
|
+
itemInfo.isEmpty = false;
|
|
59
|
+
itemInfo.textNode = node;
|
|
60
|
+
itemInfo.textNodePos = nodePos;
|
|
61
|
+
const textStyleMark = node.marks.find(nodeMark => nodeMark.type.name === 'textStyle');
|
|
62
|
+
if (textStyleMark) {
|
|
63
|
+
itemInfo.textStyleMark = textStyleMark;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const index = listItems.length;
|
|
68
|
+
const marker = getMarker(isOrderedList, index - 1);
|
|
69
|
+
markers.push(marker);
|
|
70
|
+
});
|
|
71
|
+
for (let i = 0; i < listItems.length; i++) {
|
|
72
|
+
const item = listItems[i];
|
|
73
|
+
if (!item.textStyleMark) {
|
|
74
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
75
|
+
if (listItems[j].textStyleMark) {
|
|
76
|
+
item.textStyleMark = listItems[j].textStyleMark;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
let font = `${options.defaultFontSize} ${options.defaultFontFamily}`;
|
|
83
|
+
for (const item of listItems) {
|
|
84
|
+
if (item.textStyleMark) {
|
|
85
|
+
const { fontSize, fontFamily } = item.textStyleMark.attrs;
|
|
86
|
+
if (fontSize && fontFamily) {
|
|
87
|
+
font = `${fontSize} ${fontFamily}`;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const maxWidth = getMaxMarkerWidth(markers, font);
|
|
93
|
+
const { paddingRight } = options;
|
|
94
|
+
const totalWidth = maxWidth + paddingRight;
|
|
95
|
+
listItems.forEach((item, index) => {
|
|
96
|
+
if (item.paragraphPos === undefined) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const marker = getMarker(isOrderedList, index);
|
|
100
|
+
const widget = document.createElement('span');
|
|
101
|
+
widget.innerHTML = marker;
|
|
102
|
+
// Đặt các thuộc tính style cơ bản
|
|
103
|
+
widget.style.setProperty('user-select', 'none');
|
|
104
|
+
widget.style.setProperty('text-decoration', 'none');
|
|
105
|
+
widget.style.setProperty('display', 'inline-block');
|
|
106
|
+
widget.style.setProperty('width', `${totalWidth}px`);
|
|
107
|
+
widget.style.setProperty('text-align', 'left');
|
|
108
|
+
// Sao chép tất cả các thuộc tính style từ mark textStyle
|
|
109
|
+
if (item.textStyleMark) {
|
|
110
|
+
for (const styleProp in item.textStyleMark.attrs) {
|
|
111
|
+
widget.style.setProperty(kebabCase(styleProp), String(item.textStyleMark.attrs[styleProp]));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Tính toán vị trí chính xác cho marker
|
|
115
|
+
const absoluteListItemPos = listNodePos + item.pos + 1;
|
|
116
|
+
const absoluteParagraphPos = absoluteListItemPos + item.paragraphPos;
|
|
117
|
+
const markerPos = absoluteParagraphPos + 1;
|
|
118
|
+
// Đặt marker widget tại vị trí đã tính toán (bên trong paragraph)
|
|
119
|
+
// Decoration.widget sẽ tạo một widget tại vị trí markerPos
|
|
120
|
+
decorations.push(Decoration.widget(markerPos, widget, {
|
|
121
|
+
ignoreSelection: true,
|
|
122
|
+
}));
|
|
123
|
+
if (item.paragraphNode) {
|
|
124
|
+
// Tính toán vị trí bắt đầu và kết thúc của paragraph
|
|
125
|
+
const paragraphStart = absoluteParagraphPos;
|
|
126
|
+
const paragraphEnd = paragraphStart + item.paragraphNode.nodeSize;
|
|
127
|
+
// Thêm decoration cho paragraph với style inline-block
|
|
128
|
+
decorations.push(Decoration.node(paragraphStart + 1, paragraphEnd + 1, {
|
|
129
|
+
style: 'display: inline;',
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
return DecorationSet.create(doc, decorations);
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Extension tạo marker tùy chỉnh cho danh sách trong p
|
|
138
|
+
*
|
|
139
|
+
* Extension này thay thế marker mặc định của danh sách bằng các marker
|
|
140
|
+
* có thể kế thừa style (font, size, color...) từ text node đầu tiên.
|
|
141
|
+
*/
|
|
142
|
+
export const ListItemMarker = Extension.create({
|
|
143
|
+
name: 'list-item-marker',
|
|
144
|
+
addOptions() {
|
|
145
|
+
return {
|
|
146
|
+
...this.parent?.(),
|
|
147
|
+
paddingRight: 10,
|
|
148
|
+
defaultFontSize: '16px',
|
|
149
|
+
defaultFontFamily: 'Arial',
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
addProseMirrorPlugins() {
|
|
153
|
+
const { options } = this;
|
|
154
|
+
return [
|
|
155
|
+
new Plugin({
|
|
156
|
+
key: new PluginKey('custom-list-item-marker'),
|
|
157
|
+
state: {
|
|
158
|
+
init(_, { doc }) {
|
|
159
|
+
return styleMarker(doc, options);
|
|
160
|
+
},
|
|
161
|
+
// Chỉ tính toán lại nếu document thay đổi
|
|
162
|
+
apply(tr, oldState) {
|
|
163
|
+
return tr.docChanged ? styleMarker(tr.doc, options) : oldState;
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
props: {
|
|
167
|
+
decorations(state) {
|
|
168
|
+
return this.getState(state);
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
];
|
|
173
|
+
},
|
|
174
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
import { OrderedListStyleType } from '../types';
|
|
3
|
+
type ListStyleType = OrderedListStyleType;
|
|
4
|
+
export interface CustomOrderedListOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The node type name for list items.
|
|
7
|
+
* @default 'listItem'
|
|
8
|
+
*/
|
|
9
|
+
itemTypeName: string;
|
|
10
|
+
/**
|
|
11
|
+
* The HTML attributes for an ordered list node.
|
|
12
|
+
* @default {}
|
|
13
|
+
*/
|
|
14
|
+
HTMLAttributes: Record<string, any>;
|
|
15
|
+
/**
|
|
16
|
+
* Keep the marks when splitting a list item.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
keepMarks: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Keep the attributes when splitting a list item.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
keepAttributes: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Default list style type
|
|
27
|
+
* @default 'decimal'
|
|
28
|
+
*/
|
|
29
|
+
defaultListStyleType: ListStyleType;
|
|
30
|
+
/**
|
|
31
|
+
* Available list style types
|
|
32
|
+
* @default ['decimal', 'lower-alpha', 'upper-alpha', 'lower-roman', 'upper-roman']
|
|
33
|
+
*/
|
|
34
|
+
availableListStyleTypes: ListStyleType[];
|
|
35
|
+
}
|
|
36
|
+
declare module '@tiptap/core' {
|
|
37
|
+
interface Commands<ReturnType> {
|
|
38
|
+
customOrderedList: {
|
|
39
|
+
/**
|
|
40
|
+
* Toggle a custom ordered list
|
|
41
|
+
*/
|
|
42
|
+
toggleCustomOrderedList: (options?: {
|
|
43
|
+
listStyleType?: ListStyleType;
|
|
44
|
+
}) => ReturnType;
|
|
45
|
+
/**
|
|
46
|
+
* Set list style type for current ordered list
|
|
47
|
+
*/
|
|
48
|
+
setOrderedListStyleType: (listStyleType: ListStyleType) => ReturnType;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* This extension allows you to create ordered lists with custom list-style-type.
|
|
54
|
+
*/
|
|
55
|
+
export declare const CustomOrderedList: Node<CustomOrderedListOptions, any>;
|
|
56
|
+
export {};
|