UNPKG

@focus-reactive/sanity-plugin-inline-svg-input

Version:
214 lines (202 loc) 6.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }); var sanity = require("sanity"), jsxRuntime = require("react/jsx-runtime"), react = require("react"), styled = require("styled-components"), DOMPurify = require("dompurify"), ui = require("@sanity/ui"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var styled__default = /* @__PURE__ */ _interopDefaultCompat(styled), DOMPurify__default = /* @__PURE__ */ _interopDefaultCompat(DOMPurify); const Container$1 = styled__default.default.div` --svg-bg-color: rgba(23, 23, 23, 0.05); background-image: linear-gradient(45deg, var(--svg-bg-color) 25%, transparent 25%), linear-gradient(-45deg, var(--svg-bg-color) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--svg-bg-color) 75%), linear-gradient(-45deg, transparent 75%, var(--svg-bg-color) 75%); background-size: 20px 20px; background-position: 0 0, 0 10px, 10px -10px, -10px 0; display: flex; justify-content: center; align-items: center; min-height: 250px; border: 1px solid var(--card-border-color); border-radius: 3px; position: relative; &:focus-within { border-color: var(--card-focus-ring-color); } &.dark { --svg-bg-color: rgb(255, 255, 255, 0.1); } input[type='file'] { opacity: 0; z-index: -1; position: absolute; } input[type='file']:focus + label { outline: 2px solid; } * { box-sizing: border-box; } `, SvgWrapper = styled__default.default.div` display: flex; max-height: 320px; > div { display: flex; align-items: center; justify-content: center; } svg { max-height: 80%; max-width: 80%; display: flex; margin: auto; width: 100%; height: 100%; } `, ButtonStyle = styled.css` border-radius: 0.1875rem; font: inherit; outline: none; border: 0; padding: 0.85rem 1.75rem; margin: 0; color: #fff; cursor: pointer; font-size: 1rem; font-weight: 500; `, AddButton = styled__default.default.label` ${ButtonStyle}; color: #fff; background-color: #4285f4; &:hover { background-color: #3a6fc8; } `, RemoveButton = styled__default.default.button` ${ButtonStyle}; position: absolute; top: 10px; right: 10px; color: #fff; background-color: #db4437; &:hover { background-color: #b43b31; } `, InlineSvgInput = ({ id, value, schemaType, onChange, focused }) => { const inputRef = react.useRef(null), scheme = ui.usePrefersDark() ? "dark" : "light", isDarkMode = ui.useTheme().sanity.color.dark, handleChange = (event) => { var _a, _b; const file = (_b = (_a = event.target) == null ? void 0 : _a.files) == null ? void 0 : _b[0]; if (!file) return; const reader = new FileReader(); reader.onload = (readerEvent) => { readerEvent.target && onChange(sanity.set(readerEvent.target.result)); }, reader.readAsText(file); }, focus = () => { inputRef.current && inputRef.current.focus(); }; react.useEffect(() => { focused && focus(); }, [focused]); const clickedRemoveSvg = () => (confirm("Are you sure you want to remove the SVG?") && (onChange(sanity.unset()), inputRef.current && (inputRef.current.value = "")), !1); return /* @__PURE__ */ jsxRuntime.jsx(Container$1, { className: isDarkMode ? "dark" : "light", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.ThemeProvider, { scheme, children: [ /* @__PURE__ */ jsxRuntime.jsx( "input", { accept: ".svg", id, ref: inputRef, type: "file", placeholder: schemaType.placeholder, onChange: handleChange, name: "inline-svg" } ), !value && /* @__PURE__ */ jsxRuntime.jsx(AddButton, { htmlFor: id, children: "Upload SVG" }), value && /* @__PURE__ */ jsxRuntime.jsxs(SvgWrapper, { children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: DOMPurify__default.default.sanitize(value) } }), /* @__PURE__ */ jsxRuntime.jsx(RemoveButton, { onClick: clickedRemoveSvg, children: "Remove SVG" }) ] }) ] }) }); }, inlineSvgType = sanity.defineType({ name: "inlineSvg", title: "Inline SVG", type: "string", components: { input: InlineSvgInput } }), InlineSvgPreview = styled__default.default.div` svg { width: 100%; height: 100%; } `, InlineSvgPreviewComponent = ({ value, className, style }) => value ? /* @__PURE__ */ jsxRuntime.jsx( InlineSvgPreview, { dangerouslySetInnerHTML: { __html: DOMPurify__default.default.sanitize(value) }, className, style } ) : null, Container = styled__default.default.div` display: flex; align-items: center; box-sizing: border-box; * { box-sizing: border-box; } `, IconStyle = styled.css` width: 35px; height: 35px; margin-right: 8px; flex-shrink: 0; `, Icon = styled__default.default(InlineSvgPreviewComponent)` ${IconStyle} `, IconStub = styled__default.default.div` ${IconStyle} `, Title = styled__default.default.span` display: block; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; overflow: clip; font-size: 1rem; line-height: calc(21 / 16); color: ${({ empty }) => empty ? "#6e7683" : "inherit"}}; `, Subtitle = styled__default.default.span` display: block; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; overflow: clip; font-size: 0.8125rem; line-height: calc(17 / 13); color: #6e7683; `, TextContainer = styled__default.default.div` overflow: hidden; `, InlineSvgPreviewItem = ({ icon, title, subtitle }) => title && typeof title != "string" || subtitle && typeof subtitle != "string" ? /* @__PURE__ */ jsxRuntime.jsx(Container, { children: "`InlineSvgPreviewItem` supports only string values for `title` and `subtitle` props." }) : /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [ icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { value: icon }) : /* @__PURE__ */ jsxRuntime.jsx(IconStub, {}), /* @__PURE__ */ jsxRuntime.jsxs(TextContainer, { children: [ title ? /* @__PURE__ */ jsxRuntime.jsx(Title, { children: title }) : /* @__PURE__ */ jsxRuntime.jsx(Title, { empty: !0, children: "Untitled" }), subtitle && /* @__PURE__ */ jsxRuntime.jsx(Subtitle, { children: subtitle }) ] }) ] }), inlineSvgInput = sanity.definePlugin((config = {}) => ({ name: "sanity-plugin-inline-svg-input", schema: { types: [inlineSvgType] } })); exports.InlineSvgPreviewComponent = InlineSvgPreviewComponent; exports.InlineSvgPreviewItem = InlineSvgPreviewItem; exports.inlineSvgInput = inlineSvgInput; //# sourceMappingURL=index.js.map