@empoleon/tiptap
Version:
Rich text editor based on tiptap
183 lines (179 loc) • 6.47 kB
JavaScript
;
var web = require('solid-js/web');
var core = require('@empoleon/core');
var hooks = require('@empoleon/hooks');
var Icons = require('../icons/Icons.cjs');
var RichTextEditor_context = require('../RichTextEditor.context.cjs');
var RichTextEditorControl = require('./RichTextEditorControl.cjs');
var RichTextEditor_module = require('../RichTextEditor.module.css.cjs');
var solidJs = require('solid-js');
var _tmpl$ = /*#__PURE__*/web.template(`<div>`);
const LinkIcon = props => web.createComponent(Icons.IconLink, props);
const defaultProps = {};
const RichTextEditorLinkControl = core.factory(_props => {
const props = core.useProps("RichTextEditorLinkControl", defaultProps, _props);
const [local, others] = solidJs.splitProps(props, ["classNames", "className", "style", "styles", "vars", "icon", "popoverProps", "disableTooltips", "initialExternal", "ref"]);
const ctx = RichTextEditor_context.useRichTextEditorContext();
const stylesApiProps = {
classNames: local.classNames,
styles: local.styles
};
const [url, setUrl] = hooks.useInputState("");
const [external, setExternal] = solidJs.createSignal(local.initialExternal);
const [opened, {
open,
close
}] = hooks.useDisclosure(false);
const handleOpen = () => {
open();
const linkData = ctx.editor?.getAttributes("link");
setUrl(linkData?.href || "");
setExternal(linkData?.href ? linkData?.target === "_blank" : local.initialExternal);
};
const handleClose = () => {
close();
setUrl("");
setExternal(local.initialExternal);
};
const setLink = () => {
handleClose();
url() === "" ? ctx.editor?.chain().focus().extendMarkRange("link").unsetLink().run() : ctx.editor?.chain().focus().extendMarkRange("link").setLink({
href: url(),
target: external() ? "_blank" : null
}).run();
};
const handleInputKeydown = event => {
if (event.key === "Enter") {
event.preventDefault();
setLink();
}
};
hooks.useWindowEvent("edit-link", handleOpen, false);
const {
resolvedClassNames,
resolvedStyles
} = core.useResolvedStylesApi({
classNames: local.classNames,
styles: local.styles,
props
});
return web.createComponent(core.Popover, web.mergeProps({
trapFocus: true,
shadow: "md",
withinPortal: true,
get opened() {
return opened();
},
onChange: _opened => !_opened && handleClose(),
offset: -44,
zIndex: 1e4
}, () => local.popoverProps, {
get children() {
return [web.createComponent(core.Popover.Target, {
get children() {
return web.createComponent(RichTextEditorControl.RichTextEditorControlBase, web.mergeProps({
get icon() {
return local.icon || LinkIcon;
}
}, others, {
get ["aria-label"]() {
return ctx.labels.linkControlLabel;
},
get title() {
return ctx.labels.linkControlLabel;
},
onClick: handleOpen,
get active() {
return ctx.editor?.isActive("link");
},
ref(r$) {
var _ref$ = local.ref;
typeof _ref$ === "function" ? _ref$(r$) : local.ref = r$;
},
classNames: resolvedClassNames,
styles: resolvedStyles,
get className() {
return local.className;
},
get style() {
return local.style;
},
get variant() {
return ctx.variant;
}
}));
}
}), web.createComponent(core.Popover.Dropdown, web.mergeProps(() => ctx.getStyles("linkEditorDropdown", stylesApiProps), {
get children() {
var _el$ = _tmpl$();
web.spread(_el$, web.mergeProps(() => ctx.getStyles("linkEditor", stylesApiProps)), false, true);
web.insert(_el$, web.createComponent(core.TextInput, {
get placeholder() {
return ctx.labels.linkEditorInputPlaceholder;
},
get ["aria-label"]() {
return ctx.labels.linkEditorInputLabel;
},
type: "url",
get value() {
return url();
},
onChange: setUrl,
get classNames() {
return {
input: ctx.getStyles("linkEditorInput", stylesApiProps).className
};
},
onKeyDown: handleInputKeydown,
get rightSection() {
return web.createComponent(core.Tooltip, {
get label() {
return external() ? ctx.labels.linkEditorExternalLink : ctx.labels.linkEditorInternalLink;
},
events: {
hover: true,
focus: true,
touch: true
},
withinPortal: true,
withArrow: true,
get disabled() {
return local.disableTooltips;
},
zIndex: 1e4,
children: props2 => web.createComponent(core.UnstyledButton, web.mergeProps({
onClick: () => setExternal(e => !e),
"data-active": external || void 0
}, () => ctx.getStyles("linkEditorExternalControl", stylesApiProps), props2, {
get children() {
return web.createComponent(Icons.IconExternalLink, {
get style() {
return {
width: core.rem(14),
height: core.rem(14)
};
}
});
}
}))
});
}
}), null);
web.insert(_el$, web.createComponent(core.Button, web.mergeProps({
variant: "default",
onClick: setLink
}, () => ctx.getStyles("linkEditorSave", stylesApiProps), {
get children() {
return ctx.labels.linkEditorSave;
}
})), null);
return _el$;
}
}))];
}
}));
});
RichTextEditorLinkControl.classes = RichTextEditor_module;
RichTextEditorLinkControl.displayName = "@empoleon/tiptap/RichTextEditorLinkControl";
exports.RichTextEditorLinkControl = RichTextEditorLinkControl;
//# sourceMappingURL=RichTextEditorLinkControl.cjs.map