UNPKG

vue-showdown

Version:

Use showdown as a vue component

195 lines (188 loc) 5.76 kB
/*! * vue-showdown - Use showdown as a vue component * * @version v4.2.0 * @link https://vue-showdown.js.org * @license MIT * @copyright 2018-2023 meteorlxy */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('showdown'), require('vue')) : typeof define === 'function' && define.amd ? define(['exports', 'showdown', 'vue'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VueShowdown = {}, global.showdown, global.Vue)); })(this, (function (exports, showdown, vue) { 'use strict'; /** * The VueShowdown component * * @example * ```html * <template> * <VueShowdown markdown="# Hello, world" /> * </template> * * <script> * import { defineComponent } from 'vue'; * import { VueShowdown } from 'vue-showdown'; * * export default defineComponent({ * components: { * VueShowdown, * }, * }); * </script> * ``` * * @public */ const VueShowdown = vue.defineComponent({ name: 'VueShowdown', props: { /** * Raw markdown content */ markdown: { type: String, required: false, default: null, }, /** * HTML tag of the markdown wrapper */ tag: { type: String, required: false, default: 'div', }, /** * Showdown flavor * * @see https://github.com/showdownjs/showdown#flavors */ flavor: { type: String, required: false, default: null, }, /** * Showdown options * * @see https://github.com/showdownjs/showdown#valid-options */ options: { type: Object, required: false, default: () => ({}), }, /** * Showdown extensions * * @see https://github.com/showdownjs/showdown#extensions */ extensions: { type: Array, required: false, default: null, }, /** * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) */ vueTemplate: { type: Boolean, required: false, default: false, }, /** * Define components which are available in the Vue template. Require `vueTemplate` to be enabled */ vueTemplateComponents: { type: Object, required: false, default: () => ({}), }, /** * Define data which is available in the Vue template. Require `vueTemplate` to be enabled */ vueTemplateData: { type: Object, required: false, default: () => ({}), }, }, setup(props, { slots }) { // the showdown converter instance ref const converter = vue.computed(() => { const instance = new showdown.Converter({ extensions: props.extensions ?? undefined, }); if (props.flavor !== null) { instance.setFlavor(props.flavor); } Object.entries(props.options).forEach(([key, value]) => { instance.setOption(key, value); }); return instance; }); // the raw markdown string const inputMarkdown = vue.computed(() => { // from props if (props.markdown !== null) { return props.markdown; } // from default slot const slot = slots.default?.()[0]; if (slot?.type === vue.Text) { return slot.children; } // fall back to empty string return ''; }); // the parsed HTML string const outputHtml = vue.computed(() => converter.value.makeHtml(inputMarkdown.value)); return () => props.vueTemplate ? vue.h({ components: props.vueTemplateComponents, setup: () => props.vueTemplateData, template: `<${props.tag}>${outputHtml.value}</${props.tag}>`, }) : vue.h(props.tag, { innerHTML: outputHtml.value, }); }, }); /** * The VueShowdown plugin * * @example * ```ts * import { createApp } from 'vue'; * import { VueShowdownPlugin } from 'vue-showdown'; * * const app = createApp(); * app.use(VueShowdownPlugin); * ``` * * @public */ const VueShowdownPlugin = { install(app, { flavor = null, options = {}, } = {}) { // set default flavor if (flavor !== null) { showdown.setFlavor(flavor); } // set default options (override flavor) Object.entries(options).forEach(([key, value]) => { showdown.setOption(key, value); }); // register vue-showdown component globally // eslint-disable-next-line vue/match-component-file-name app.component('VueShowdown', VueShowdown); }, }; if (typeof window !== 'undefined') { window.VueShowdown = VueShowdown; window.VueShowdownPlugin = VueShowdownPlugin; } exports.showdown = showdown; exports.VueShowdown = VueShowdown; exports.VueShowdownPlugin = VueShowdownPlugin; }));