@zipify/wysiwyg 1.0.0-dev.20 → 1.0.0-dev.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zipify/wysiwyg",
3
- "version": "1.0.0-dev.20",
3
+ "version": "1.0.0-dev.23",
4
4
  "description": "Zipify modification of TipTap text editor",
5
5
  "main": "dist/wysiwyg.js",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"wysiwyg.css","mappings":";AAoCA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;;;ACnCA;IACA;IACA;IACA;AACA;;;ACJA;IACA;IACA;AACA;;;AC0CA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;;IAEA;IACA;IACA;IACA;AACA;AAEA;;IAEA;AACA;AAEA;IACA;AACA;AAEA;;;IAGA;IACA;AACA;;;ACpGA;IACA;IACA;AACA;;;AC6BA;IACA;AACA;AAEA;IACA;AACA;;ACzEA;EACE,kBAAkB;EAClB,sBAAsB;EACtB,eAAe;EACf,2BAA2B;EAC3B,yBAAyB;EACzB,uBAAuB;AACzB;;AAEA;EACE,gBAAgB;EAChB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,UAAU;EACV,SAAS;EACT,OAAO;EACP,MAAM;EACN,SAAS;EACT,QAAQ;EACR,sBAAsB;EACtB,uBAAuB;EACvB,UAAU;AACZ;;AAEA;EACE,6BAA6B;EAC7B,8BAA8B;EAC9B,uBAAuB;EACvB,kBAAkB;EAClB,MAAM;EACN,OAAO;EACP,SAAS;EACT,QAAQ;EACR,UAAU;EACV,SAAS;EACT,iCAAiC;AACnC;;AAEA;EACE,kBAAkB;EAClB,iCAAiC;EACjC,kBAAkB;EAClB,cAAc;EACd,YAAY,EAAE,mGAAmG;EACjH,WAAW;EACX,eAAe,EAAE,kDAAkD;EACnE,gBAAgB,EAAE,0CAA0C;EAC5D,qBAAqB;EACrB,wBAAwB;AAC1B;;AAEA;;EAEE,QAAQ;EACR,SAAS;AACX;;AAEA;;EAEE,YAAY;EACZ,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,WAAW;EACX,oBAAoB;AACtB;;AAEA;EACE,8BAA8B;EAC9B,YAAY;EACZ,WAAW;EACX,cAAc;EACd,kBAAkB;EAClB,WAAW;EACX,eAAe;EACf,gBAAgB;EAChB,WAAW;EACX,UAAU;EACV,SAAS;EACT,oBAAoB;EACpB,kBAAkB;EAClB,cAAc;EACd,aAAa;AACf;;AAEA;EACE,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,kBAAkB;EAClB,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY;EACZ,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,oBAAoB;EACpB,WAAW;AACb;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,QAAQ;EACR,SAAS;EACT,oBAAoB;EACpB,gBAAgB;AAClB;;AAEA;EACE,oBAAoB;EACpB,iBAAiB;EACjB,yBAAyB;AAC3B;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,gBAAgB;AAClB;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,kBAAkB;EAClB,SAAS;EACT,UAAU;EACV,UAAU;EACV,+BAA+B;AACjC;;AAEA;EACE,0DAA0D;EAC1D,YAAY;EACZ,6BAA6B;AAC/B;;AAEA;EACE,MAAM;EACN,WAAW;AACb;;AAEA;EACE,QAAQ;EACR,WAAW;AACb;;AAEA;EACE,OAAO;EACP,YAAY;AACd;;AAEA;EACE,YAAY;EACZ,SAAS;EACT,UAAU;AACZ;;AAEA;EACE,WAAW;EACX,OAAO;EACP,QAAQ;EACR,WAAW;EACX,aAAa;EACb,eAAe;EACf,WAAW;AACb;;AAEA,gBAAgB;AAChB;EACE,WAAW;EACX,OAAO;AACT;;AAEA;EACE,cAAc;EACd,eAAe;EACf,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,YAAY;EACZ,kBAAkB;EAClB,kBAAkB;AACpB;;AAEA;EACE,eAAe;EACf,OAAO;EACP,kBAAkB;EAClB,kBAAkB;EAClB,qBAAqB;EACrB,wBAAwB;AAC1B;;;AC/KA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;;;ACrCA;IACA;IACA;IACA;IACA;IACA;AACA;;;ACoDA;IACA;IACA;IACA;IACA;IACA;IACA;;IAEA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;;AAEA;AAEA;;IAEA;AACA;;AAEA;AACA;AAEA;IACA;AACA;;AAEA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;;;ACjEA;IACA;IACA;IACA;;IAEA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;AACA;AAEA;;IAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;AAEA;;;IAGA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;AACA;AAEA;;IAEA;IACA;IACA;IACA;IACA;AACA;AAEA;;IAEA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;;IAEA;AACA;;;ACpKA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;AACA;AAEA;IACA;AACA;;AAEA;AAEA;;IAEA;AACA;AAEA;IACA;IACA;AACA;AAEA;IACA;AACA;;;ACjDA;IACA;IACA;AACA;AAEA;IACA;IACA;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;AACA;AAEA;;IAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;;;ACpEA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;;;ACZA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;;;ACvBA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;;;IAGA;AACA;;;ACjDA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;IACA;IACA;AACA;;;AC1CA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;;;ACsCA;IACA;IACA;AACA;;;ACkCA;IACA;IACA;IACA;AACA;;;ACtBA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;;;IAGA;AACA;;;ACPA;IACA;AACA;AAEA;IACA;IACA;IACA;AACA;;;AC9CA;IACA;AACA;;;ACSA;IACA;AACA;AAEA;IACA;AACA;;;ACmBA;IACA;AACA;AAEA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;AACA;;;ACvBA;IACA;IACA;AACA;;;AC/CA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;;;ACnCA;IACA;IACA;AACA;;;AC2GA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;;;AC7FA;IACA;IACA;IACA;IACA;AACA;AAEA;;IAEA;IACA;IACA;IACA;IACA;IACA;AACA;AAEA;IACA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;AACA;AAEA;IACA;AACA;AAEA;;IAEA;AACA;;AC9FA;IACI,yBAAyB,OAAO,aAAa;IAC7C,0BAA0B,MAAM,aAAa;IAC7C,0BAA0B,MAAM,aAAa;IAC7C,0BAA0B,MAAM,aAAa;IAC7C,6BAA6B,GAAG,YAAY;IAC5C,6BAA6B,GAAG,YAAY;IAC5C,6BAA6B,GAAG,YAAY;IAC5C,6BAA6B,GAAG,YAAY;IAC5C,6BAA6B,GAAG,YAAY;IAC5C,8BAA8B,GAAG,YAAY;IAC7C,yBAAyB;IACzB,+BAA+B;IAC/B,6BAA6B,EAAE,YAAY;IAC3C,2BAA2B,EAAE,YAAY;;IAEzC,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;IACrB,oBAAoB;IACpB,oBAAoB;;IAEpB,0BAA0B;IAC1B,8BAA8B;;IAE9B,wBAAwB;IACxB,uBAAuB;;IAEvB,0BAA0B;IAC1B,yBAAyB;AAC7B;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BE;;AC9DF;IACI,aAAa;AACjB;;AAEA;IACI,+BAA+B;IAC/B,+BAA+B;IAC/B,WAAW;IACX,SAAS;IACT,oBAAoB;AACxB;;AAEA;IACI,gEAAgE;IAChE,gEAAgE;IAChE,mDAAmD;IACnD,6DAA6D;IAC7D,4EAA4E;IAC5E,+EAA+E;AACnF;;AAEA;;IAEI;QACI,0EAA0E;QAC1E,6EAA6E;QAC7E,gFAAgF;IACpF;AACJ;;AAEA;;IAEI;QACI,wEAAwE;QACxE,2EAA2E;QAC3E,8EAA8E;IAClF;AACJ;;AAEA;;IAEI;QACI,wEAAwE;QACxE,2EAA2E;QAC3E,8EAA8E;IAClF;AACJ;;AAEA,uBAAuB;;AAEvB;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,qBAAqB;IACrB,yBAAyB;IACzB,oCAAoC;IACpC,4BAA4B;IAC5B,+BAA+B,EAAE,2CAA2C;AAChF;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,0BAA0B;IAC1B,uBAAuB;IACvB,oBAAoB;IACpB,qBAAqB;IACrB,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,oBAAoB;IACpB,kBAAkB;IAClB,SAAS;AACb;;AAEA;IACI,WAAW;IACX,cAAc;IACd,kBAAkB;IAClB,SAAS;IACT,WAAW;IACX,0BAA0B;IAC1B,iEAAiE;AACrE;;AAEA;;IAEI;QACI,kBAAkB;IACtB;AACJ;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI;AACJ;;AC7HA;IACI,mBAAmB;IACnB,gBAAgB;IAChB,uBAAuB;IACvB,eAAe;AACnB;;ACLA;IACI,kBAAkB;AACtB;;ACFA;IACI,mCAAmC;AACvC;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,iCAAiC;AACrC","sources":["webpack://@zipify/wysiwyg/./lib/components/toolbar/ToolbarDivider.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/ToolbarRow.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/ToolbarGroup.vue","webpack://@zipify/wysiwyg/./lib/components/base/Button.vue","webpack://@zipify/wysiwyg/./lib/components/base/ButtonToggle.vue","webpack://@zipify/wysiwyg/./lib/components/base/Icon.vue","webpack://@zipify/wysiwyg/./node_modules/simplebar/dist/simplebar.css","webpack://@zipify/wysiwyg/./lib/components/base/ScrollView.vue","webpack://@zipify/wysiwyg/./lib/components/base/FieldLabel.vue","webpack://@zipify/wysiwyg/./lib/components/base/Range.vue","webpack://@zipify/wysiwyg/./lib/components/base/NumberField.vue","webpack://@zipify/wysiwyg/./lib/components/base/Modal.vue","webpack://@zipify/wysiwyg/./lib/components/base/TextField.vue","webpack://@zipify/wysiwyg/./lib/components/base/Checkbox.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/DropdownActivator.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/DropdownOption.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/DropdownGroup.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/DropdownDivider.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/DropdownMenu.vue","webpack://@zipify/wysiwyg/./lib/components/base/dropdown/Dropdown.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/StylePresetControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/FontFamilyControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/FontSizeControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/AlignmentDeviceControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/LineHeightControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/ListControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/link/LinkControlHeader.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/link/LinkControlApply.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/controls/link/LinkControl.vue","webpack://@zipify/wysiwyg/./lib/components/toolbar/Toolbar.vue","webpack://@zipify/wysiwyg/./lib/styles/variables.css","webpack://@zipify/wysiwyg/./lib/styles/content.css","webpack://@zipify/wysiwyg/./lib/styles/helpers/text.css","webpack://@zipify/wysiwyg/./lib/styles/helpers/common.css","webpack://@zipify/wysiwyg/./lib/styles/helpers/offsets.css"],"sourcesContent":["<template>\n <div class=\"zw-toolbar__divider\" :class=\"classes\" />\n</template>\n\n<script>\nimport { computed } from '@vue/composition-api';\n\nexport default {\n name: 'ToolbarDivider',\n\n props: {\n vertical: {\n type: Boolean,\n required: false,\n default: false\n },\n\n horizontal: {\n type: Boolean,\n required: false,\n default: false\n }\n },\n\n setup(props) {\n const classes = computed(() => ({\n 'zw-toolbar__divider--vertical': props.vertical,\n 'zw-toolbar__divider--horizontal': props.horizontal\n }));\n\n return { classes };\n }\n};\n</script>\n\n<style scoped>\n.zw-toolbar__divider {\n border-color: rgba(var(--zw-color-n90), 0.1);\n border-style: solid;\n border-width: 0;\n}\n\n.zw-toolbar__divider--vertical {\n border-left-width: 1px;\n}\n\n.zw-toolbar__divider--horizontal {\n border-bottom-width: 1px;\n}\n</style>\n","<template>\n <div class=\"zw-toolbar__row\">\n <slot />\n </div>\n</template>\n\n<script>\nexport default {\n name: 'ToolbarRow'\n};\n</script>\n\n<style scoped>\n.zw-toolbar__row {\n display: flex;\n column-gap: var(--zw-offset-xs);\n padding: var(--zw-offset-xxs) var(--zw-offset-xs);\n}\n</style>\n","<template>\n <div class=\"zw-toolbar__group\">\n <slot />\n </div>\n</template>\n\n<script>\nexport default {\n name: 'ToolbarGroup'\n};\n</script>\n\n<style scoped>\n.zw-toolbar__group {\n display: flex;\n column-gap: var(--zw-offset-xxs);\n}\n</style>\n","<template>\n <button\n class=\"zw-button\"\n type=\"button\"\n :class=\"classes\"\n :disabled=\"disabled\"\n @click=\"$emit('click', $event)\"\n >\n <slot />\n </button>\n</template>\n\n<script>\nimport { computed } from '@vue/composition-api';\n\nexport default {\n name: 'Button',\n\n props: {\n skin: {\n type: String,\n required: false,\n validator: (skin) => ['toolbar', 'primary', 'secondary', 'none'].includes(skin),\n default: 'none'\n },\n\n active: {\n type: Boolean,\n required: false,\n default: false\n },\n\n disabled: {\n type: Boolean,\n required: false,\n default: false\n },\n\n icon: {\n type: Boolean,\n required: false,\n default: false\n }\n },\n\n setup(props) {\n const classes = computed(() => ({\n [`zw-button--${props.skin}`]: props.skin !== 'none',\n 'zw-button--active': props.active,\n 'zw-button--icon': props.icon\n }));\n\n return { classes };\n }\n};\n</script>\n\n<style scoped>\n.zw-button {\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n background-color: transparent;\n border: 0;\n padding: 0;\n white-space: nowrap;\n appearance: none;\n user-select: none;\n text-transform: none;\n letter-spacing: normal;\n color: inherit;\n transition: 0.1s opacity ease-out;\n will-change: opacity;\n}\n\n.zw-button::-moz-focus-inner {\n border: 0 !important;\n}\n\n.zw-button:hover,\n.zw-button:focus {\n text-decoration: none;\n outline: none;\n}\n\n.zw-button:disabled {\n user-select: none;\n box-shadow: none;\n cursor: not-allowed;\n opacity: 0.35;\n}\n\n.zw-button--toolbar {\n border-radius: 1px;\n min-height: 28px;\n font-weight: var(--zw-font-weight-semibold);\n font-size: var(--zw-font-size-xs);\n line-height: var(--zw-line-height-xxs);\n color: rgb(var(--zw-color-n70));\n transition-property: background-color, color, opacity;\n will-change: background-color, color, opacity;\n}\n\n.zw-button--primary {\n background-color: rgb(var(--zw-color-green));\n color: rgb(var(--zw-color-white));\n padding: var(--zw-offset-xxs) var(--zw-offset-sm);\n line-height: var(--zw-line-height-md);\n}\n\n.zw-button--primary,\n.zw-button--secondary {\n color: rgb(var(--zw-color-white));\n padding: var(--zw-offset-xxs) var(--zw-offset-sm);\n font-weight: 600;\n font-size: var(--zw-font-size-xs);\n}\n\n.zw-button--primary:not(:disabled):hover,\n.zw-button--secondary:not(:disabled):hover {\n opacity: 0.9;\n}\n\n.zw-button--toolbar:not(.zw-button--icon) {\n padding: var(--zw-offset-xxs) var(--zw-offset-xs);\n}\n\n.zw-button--toolbar:not(:disabled):hover,\n.zw-button--toolbar:not(:disabled):focus,\n.zw-button--toolbar.zw-button--active:not(:disabled) {\n color: rgb(var(--zw-color-white));\n background-color: rgb(var(--zw-color-n5));\n}\n</style>\n","<template>\n <div class=\"zw-button-toggle\">\n <slot\n v-for=\"option of options\"\n name=\"option\"\n :option=\"option\"\n :isActive=\"option.id === value\"\n :activate=\"() => $emit('change', option.id)\"\n />\n </div>\n</template>\n\n<script>\nexport default {\n name: 'ButtonToggle',\n\n model: {\n event: 'change'\n },\n\n props: {\n value: {\n type: String,\n required: true\n },\n\n options: {\n type: Array,\n required: true\n }\n }\n};\n</script>\n\n<style scoped>\n.zw-button-toggle {\n display: flex;\n column-gap: var(--zw-offset-xxs);\n}\n</style>\n","<template>\n <div\n class=\"zw-icon\"\n :class=\"iconClasses\"\n :style=\"iconStyles\"\n v-html=\"source\"\n />\n</template>\n\n<script>\nimport { computed } from '@vue/composition-api';\nimport { importIcon } from '../../utils';\n\nexport default {\n name: 'Icon',\n\n props: {\n name: {\n type: String,\n required: true\n },\n\n size: {\n type: [String, Number],\n required: false,\n default: ''\n },\n\n autoColor: {\n type: Boolean,\n required: false,\n default: false\n }\n },\n\n setup(props) {\n const source = computed(() => importIcon(props.name));\n\n const iconSize = computed(() => {\n if (isNaN(Number(props.size))) return props.size;\n\n return `${props.size}px`;\n });\n\n const iconStyles = computed(() => {\n if (!props.size) return null;\n\n return {\n '--zw-icon-width': iconSize.value,\n '--zw-icon-height': iconSize.value\n };\n });\n\n const iconClasses = computed(() => ({\n 'zw-icon--auto-color': props.autoColor\n }));\n\n return {\n source,\n iconStyles,\n iconClasses\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-icon {\n display: flex;\n}\n\n.zw-icon--auto-color {\n --zw-icon-foreground: currentColor;\n}\n</style>\n","[data-simplebar] {\n position: relative;\n flex-direction: column;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-content: flex-start;\n align-items: flex-start;\n}\n\n.simplebar-wrapper {\n overflow: hidden;\n width: inherit;\n height: inherit;\n max-width: inherit;\n max-height: inherit;\n}\n\n.simplebar-mask {\n direction: inherit;\n position: absolute;\n overflow: hidden;\n padding: 0;\n margin: 0;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n width: auto !important;\n height: auto !important;\n z-index: 0;\n}\n\n.simplebar-offset {\n direction: inherit !important;\n box-sizing: inherit !important;\n resize: none !important;\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n padding: 0;\n margin: 0;\n -webkit-overflow-scrolling: touch;\n}\n\n.simplebar-content-wrapper {\n direction: inherit;\n box-sizing: border-box !important;\n position: relative;\n display: block;\n height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */\n width: auto;\n max-width: 100%; /* Not required for horizontal scroll to trigger */\n max-height: 100%; /* Needed for vertical scroll to trigger */\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.simplebar-content-wrapper::-webkit-scrollbar,\n.simplebar-hide-scrollbar::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n\n.simplebar-content:before,\n.simplebar-content:after {\n content: ' ';\n display: table;\n}\n\n.simplebar-placeholder {\n max-height: 100%;\n max-width: 100%;\n width: 100%;\n pointer-events: none;\n}\n\n.simplebar-height-auto-observer-wrapper {\n box-sizing: inherit !important;\n height: 100%;\n width: 100%;\n max-width: 1px;\n position: relative;\n float: left;\n max-height: 1px;\n overflow: hidden;\n z-index: -1;\n padding: 0;\n margin: 0;\n pointer-events: none;\n flex-grow: inherit;\n flex-shrink: 0;\n flex-basis: 0;\n}\n\n.simplebar-height-auto-observer {\n box-sizing: inherit;\n display: block;\n opacity: 0;\n position: absolute;\n top: 0;\n left: 0;\n height: 1000%;\n width: 1000%;\n min-height: 1px;\n min-width: 1px;\n overflow: hidden;\n pointer-events: none;\n z-index: -1;\n}\n\n.simplebar-track {\n z-index: 1;\n position: absolute;\n right: 0;\n bottom: 0;\n pointer-events: none;\n overflow: hidden;\n}\n\n[data-simplebar].simplebar-dragging .simplebar-content {\n pointer-events: none;\n user-select: none;\n -webkit-user-select: none;\n}\n\n[data-simplebar].simplebar-dragging .simplebar-track {\n pointer-events: all;\n}\n\n.simplebar-scrollbar {\n position: absolute;\n left: 0;\n right: 0;\n min-height: 10px;\n}\n\n.simplebar-scrollbar:before {\n position: absolute;\n content: '';\n background: black;\n border-radius: 7px;\n left: 2px;\n right: 2px;\n opacity: 0;\n transition: opacity 0.2s linear;\n}\n\n.simplebar-scrollbar.simplebar-visible:before {\n /* When hovered, remove all transitions from drag handle */\n opacity: 0.5;\n transition: opacity 0s linear;\n}\n\n.simplebar-track.simplebar-vertical {\n top: 0;\n width: 11px;\n}\n\n.simplebar-track.simplebar-vertical .simplebar-scrollbar:before {\n top: 2px;\n bottom: 2px;\n}\n\n.simplebar-track.simplebar-horizontal {\n left: 0;\n height: 11px;\n}\n\n.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before {\n height: 100%;\n left: 2px;\n right: 2px;\n}\n\n.simplebar-track.simplebar-horizontal .simplebar-scrollbar {\n right: auto;\n left: 0;\n top: 2px;\n height: 7px;\n min-height: 0;\n min-width: 10px;\n width: auto;\n}\n\n/* Rtl support */\n[data-simplebar-direction='rtl'] .simplebar-track.simplebar-vertical {\n right: auto;\n left: 0;\n}\n\n.hs-dummy-scrollbar-size {\n direction: rtl;\n position: fixed;\n opacity: 0;\n visibility: hidden;\n height: 500px;\n width: 500px;\n overflow-y: hidden;\n overflow-x: scroll;\n}\n\n.simplebar-hide-scrollbar {\n position: fixed;\n left: 0;\n visibility: hidden;\n overflow-y: scroll;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n","<template>\n <div class=\"zw-scroll-view\" data-simplebar-auto-hide=\"false\" ref=\"hostRef\">\n <slot />\n </div>\n</template>\n\n<script>\nimport SimpleBar from 'simplebar';\nimport { onMounted, provide, ref } from '@vue/composition-api';\nimport { SCROLL_VIEW } from './composables';\n\nexport default {\n name: 'ScrollView',\n\n setup() {\n const hostRef = ref(null);\n const scrollerRef = ref(null);\n\n provide(SCROLL_VIEW, scrollerRef);\n\n onMounted(() => {\n const options = SimpleBar.getOptions(hostRef.value.attributes);\n const simpleBar = new SimpleBar(hostRef.value, options);\n\n scrollerRef.value = simpleBar.getScrollElement();\n });\n\n return { hostRef };\n }\n};\n</script>\n\n<style scoped>\n@import url(\"~simplebar/dist/simplebar.css\");\n\n.zw-scroll-view::v-deep .simplebar-placeholder {\n display: none;\n}\n\n.zw-scroll-view::v-deep .simplebar-track {\n width: 4px;\n background-color: rgb(var(--zw-color-n20));\n pointer-events: initial;\n}\n\n.zw-scroll-view::v-deep .simplebar-scrollbar {\n width: 4px;\n}\n\n.zw-scroll-view::v-deep .simplebar-scrollbar::before {\n top: 0;\n left: 0;\n background-color: rgb(var(--zw-color-n5));\n cursor: pointer;\n height: 100%;\n width: 100%;\n opacity: 1;\n border-radius: 0;\n}\n</style>\n","<template>\n <label class=\"zw-field-label\" :for=\"fieldId\">\n <slot />\n </label>\n</template>\n\n<script>\nexport default {\n name: 'FieldLabel',\n\n props: {\n fieldId: {\n type: String,\n required: false,\n default: null\n }\n }\n};\n</script>\n\n<style scoped>\n.zw-field-label {\n font-weight: var(--zw-font-weight-thin);\n font-size: var(--zw-font-size-xxs);\n line-height: var(--zw-line-height-xxs);\n color: rgb(var(--zw-color-n70));\n display: block;\n}\n</style>\n","<template>\n <input\n class=\"zw-range\"\n type=\"range\"\n :id=\"fieldId\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :value=\"tempValue\"\n :style=\"inputStyles\"\n @input=\"update($event)\"\n >\n</template>\n\n<script>\nimport { computed, toRef } from '@vue/composition-api';\nimport { useTempValue } from './composables';\n\nexport default {\n name: 'Range',\n\n props: {\n min: {\n type: [String, Number],\n required: true\n },\n\n max: {\n type: [String, Number],\n required: true\n },\n\n step: {\n type: [String, Number],\n required: true\n },\n\n value: {\n type: [String, Number],\n required: true\n },\n\n fieldId: {\n type: String,\n required: false,\n default: ''\n }\n },\n\n setup(props, { emit }) {\n const tempValue = useTempValue({\n valueRef: toRef(props, 'value'),\n format: Number\n });\n const inputStyles = computed(() => {\n const min = Number(props.min);\n const max = Number(props.max);\n const step = Number(props.step);\n const value = Math.ceil(tempValue.value / step) * step;\n const progress = (value - min) / (max - min);\n\n return { '--zw-range-progress': `${progress * 100}%` };\n });\n\n function update(event) {\n tempValue.value = Number(event.target.value);\n emit('input', tempValue.value);\n }\n\n return {\n inputStyles,\n tempValue,\n update\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-range {\n width: 100%;\n height: 32px;\n background: none;\n cursor: pointer;\n flex-grow: 1;\n -webkit-appearance: none;\n\n --zw-range-track-background-color: transparent;\n --zw-range-track-background-image: linear-gradient(to right, #B3B3B3 var(--zw-range-progress), #3B3B3B var(--zw-range-progress));\n --zw-range-thumb-background: rgb(var(--zw-color-white));\n --zw-range-thumb-box-shadow: -1px -1px 3px rgba(59, 59, 59, 0.35), 1px 1px 3px rgba(59, 59, 59, 0.35);\n}\n\n.zw-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 4px;\n border: 0;\n border-radius: 0;\n background-size: 100%;\n background-color: var(--zw-range-track-background-color);\n background-image: var(--zw-range-track-background-image);\n}\n\n.zw-range::-moz-range-track {\n width: 100%;\n height: 4px;\n border: 0;\n border-radius: 0;\n background-size: 100%;\n background-color: var(--zw-range-track-background-color);\n background-image: var(--zw-range-track-background-image);\n}\n\n.zw-range::-ms-track {\n width: 100%;\n height: 4px;\n border: 0;\n border-radius: 0;\n background-size: 100%;\n background-color: var(--zw-range-track-background-color);\n background-image: var(--zw-range-track-background-image);\n}\n\n.zw-range::-webkit-slider-thumb {\n height: 13px;\n width: 13px;\n border-radius: 100%;\n margin-top: -5px;\n background: var(--zw-range-thumb-background);\n box-shadow: var(--zw-range-thumb-box-shadow);\n -webkit-appearance: none;\n transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.zw-range::-moz-range-thumb {\n height: 13px;\n width: 13px;\n border-radius: 100%;\n margin-top: -5px;\n background: var(--zw-range-thumb-background);\n box-shadow: var(--zw-range-thumb-box-shadow);\n -webkit-appearance: none;\n transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.zw-range::-ms-thumb {\n height: 13px;\n width: 13px;\n border-radius: 100%;\n margin-top: -5px;\n background: var(--zw-range-thumb-background);\n box-shadow: var(--zw-range-thumb-box-shadow);\n -webkit-appearance: none;\n transition: box-shadow 150ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* Browser hacks */\n\n.zw-range::-moz-focus-outer,\n.zw-range::-moz-range-thumb {\n border: 0;\n}\n\n/* In IE don't know how it count margin for thumb */\n/* but it works */\n\n.zw-range::-ms-thumb {\n margin-top: -2px;\n}\n\n/* END browser hacks */\n\n.zw-range:focus {\n outline: none;\n}\n\n.zw-range:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n --zw-range-track-background-color: #3B3B3B;\n --zw-range-track-background-image: linear-gradient(to right, #B3B3B3 var(--zw-range-progress), #3B3B3B var(--zw-range-progress));\n}\n\n.zw-range:disabled {\n --zw-range-thumb-background: #B3B3B3;\n --zw-range-thumb-box-shadow: 0 0 6px rgba(0, 0, 0, 0.35);\n}\n\n.zw-range:not(:disabled):hover {\n --zw-range-thumb-box-shadow: 0 0 0 8px rgba(240, 240, 240, 0.15);\n}\n\n.zw-range:not(:disabled):active {\n --zw-range-thumb-box-shadow: 0 0 0 12px rgba(240, 240, 240, 0.15);\n}\n</style>\n","<template>\n <div :class=\"elementClasses\" class=\"zw-number-field\">\n <input\n type=\"number\"\n class=\"zw-number-field__input\"\n :id=\"fieldId\"\n :disabled=\"disabled\"\n :value=\"tempValue\"\n @change=\"onChange\"\n >\n\n <div class=\"zw-number-field__controls\">\n <div class=\"zw-number-field__buttons\">\n <Button\n class=\"zw-number-field__increment-button\"\n @click=\"incrementValue\"\n :disabled=\"disabled\"\n data-test-selector=\"increment-button\"\n type=\"button\"\n />\n\n <Button\n class=\"zw-number-field__decrement-button\"\n @click=\"decrementValue\"\n :disabled=\"disabled\"\n data-test-selector=\"decrement-button\"\n type=\"button\"\n />\n </div>\n\n <p class=\"zw-number-field__units\" v-if=\"units\">\n {{ units }}\n </p>\n </div>\n </div>\n</template>\n\n<script>\nimport { computed, toRef } from '@vue/composition-api';\nimport Button from './Button';\nimport { useNumberValue } from './composables';\n\nexport default {\n name: 'NumberField',\n\n components: {\n Button\n },\n\n props: {\n value: {\n required: true,\n type: [Number, String]\n },\n\n min: {\n type: [Number, String],\n required: false,\n default: null\n },\n\n max: {\n type: [Number, String],\n required: false,\n default: null\n },\n\n digits: {\n type: [Number, String],\n required: false,\n default: 2\n },\n\n step: {\n type: [Number, String],\n required: false,\n default: 1\n },\n\n units: {\n type: String,\n required: false,\n default: ''\n },\n\n disabled: {\n type: Boolean,\n required: false,\n default: false\n },\n\n fieldId: {\n type: String,\n required: false,\n default: ''\n }\n },\n\n setup(props, { emit }) {\n const toOptionalNumber = (number) => number === null ? null : Number(number);\n\n const numberValue = useNumberValue({\n valueRef: toRef(props, 'value'),\n onChange: (value) => emit('input', value),\n digits: Number(props.digits),\n min: toOptionalNumber(props.min),\n max: toOptionalNumber(props.max)\n });\n\n const onChange = (event) => numberValue.change(event.target.value);\n const incrementValue = () => numberValue.increment(Number(props.step));\n const decrementValue = () => numberValue.decrement(Number(props.step));\n\n const elementClasses = computed(() => ({\n 'zw-number-field--disabled': props.disabled\n }));\n\n return {\n elementClasses,\n tempValue: numberValue.temp,\n onChange,\n incrementValue,\n decrementValue\n };\n }\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.zw-number-field {\n --border-color: rgb(var(--zw-color-n60));\n --text-color: rgb(var(--zw-color-n85));\n --buttons-color: rgb(var(--zw-color-n70));\n\n padding: 2px 4px;\n border: solid 1px var(--border-color);\n align-items: stretch;\n display: flex;\n}\n\n.zw-number-field:hover {\n --border-color: rgb(var(--zw-color-n80));\n --text-color: rgb(var(--zw-color-n85));\n}\n\n.zw-number-field:focus,\n.zw-number-field:focus-within {\n --border-color: rgb(var(--zw-color-white));\n --text-color: rgb(var(--zw-color-white));\n}\n\n.zw-number-field__input {\n color: var(--text-color);\n background-color: rgb(var(--zw-color-n15));\n border: 0;\n display: block;\n width: 100%;\n outline: none !important;\n line-height: var(--zw-line-height-md);\n font-size: var(--zw-font-size-xs);\n -moz-appearance: textfield;\n}\n\n.zw-number-field__buttons {\n display: none;\n flex-direction: column;\n height: 100%;\n}\n\n.zw-number-field:hover .zw-number-field__buttons,\n.zw-number-field:focus .zw-number-field__buttons,\n.zw-number-field:focus-within .zw-number-field__buttons {\n display: flex;\n}\n\n.zw-number-field__input::placeholder {\n color: var(--text-color);\n}\n\n.zw-number-field__input::-webkit-outer-spin-button,\n.zw-number-field__input::-webkit-inner-spin-button {\n color: var(--text-color);\n -webkit-appearance: none;\n}\n\n.zw-number-field__controls {\n min-width: var(--zw-offset-sm);\n}\n\n.zw-number-field--disabled {\n opacity: 0.5;\n}\n\n.zw-number-field--disabled,\n.zw-number-field--disabled .zw-number-field__input {\n cursor: not-allowed;\n}\n\n.zw-number-field__increment-button,\n.zw-number-field__decrement-button {\n width: 100%;\n height: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.zw-number-field__increment-button::after,\n.zw-number-field__decrement-button::after {\n content: \"\";\n border-left: 3px solid transparent;\n border-right: 3px solid transparent;\n}\n\n.zw-number-field__increment-button::after {\n border-bottom: 3px solid var(--buttons-color);\n}\n\n.zw-number-field__decrement-button::after {\n border-top: 3px solid var(--buttons-color);\n}\n\n.zw-number-field__increment-button:hover,\n.zw-number-field__decrement-button:hover {\n background-color: rgb(var(--zw-color-n20));\n --buttons-color: rgb(var(--zw-color-white));\n}\n\n.zw-number-field__units {\n color: rgb(var(--zw-color-n70));\n font-size: var(--zw-font-size-xs);\n line-height: var(--zw-line-height-md);\n text-align: center;\n display: inline-block;\n width: 100%;\n}\n\n.zw-number-field:hover .zw-number-field__units,\n.zw-number-field:focus .zw-number-field__units {\n display: none;\n}\n</style>\n","<template>\n <transition name=\"zw-modal-\" :duration=\"$options.transition\">\n <div\n class=\"zw-modal\"\n ref=\"hostRef\"\n :style=\"modalStyles\"\n v-if=\"isOpened\"\n v-out-click=\"close\"\n >\n <slot />\n </div>\n </transition>\n</template>\n\n<script>\nimport { computed, ref } from '@vue/composition-api';\nimport { outClick } from '../../directives';\nimport { useDeselectionLock, useModalToggler } from './composables';\n\nexport default {\n name: 'Modal',\n\n transition: {\n enter: 200,\n leave: 100\n },\n\n directives: {\n outClick\n },\n\n props: {\n toggler: {\n type: Object,\n required: false,\n default: null\n },\n\n maxHeight: {\n type: [Number, String],\n required: false,\n default: 1000\n },\n\n maxWidth: {\n type: [Number, String],\n required: false,\n default: 1000\n }\n },\n\n setup(props) {\n const toggler = props.toggler || useModalToggler();\n const hostRef = ref(null);\n\n const modalStyles = computed(() => ({\n '--zw-modal-max-height': `${props.maxHeight}px`,\n '--zw-modal-max-width': `${props.maxWidth}px`\n }));\n\n useDeselectionLock({\n isActiveRef: toggler.isOpened,\n hostRef\n });\n\n return {\n hostRef,\n modalStyles,\n close: toggler.close,\n isOpened: toggler.isOpened\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-modal {\n border-radius: 2px;\n box-shadow: 0 0 4px rgba(var(--zw-color-black), 0.3);\n background-color: rgb(var(--zw-color-n15));\n max-height: var(--zw-modal-max-height);\n max-width: var(--zw-modal-max-width);\n z-index: 1000;\n will-change: transform;\n}\n\n.zw-modal--enter-active {\n transition: opacity 0.15s ease-out;\n}\n\n.zw-modal--enter,\n.zw-modal--leave-to {\n opacity: 0;\n}\n\n.zw-modal--leave-active {\n transition: opacity 0.1s ease-in;\n}\n\n/* Scrollbar overrides in modal */\n\n.zw-modal::v-deep .simplebar-offset,\n.zw-modal::v-deep .simplebar-mask {\n position: initial;\n}\n\n.zw-modal::v-deep .simplebar-content {\n max-height: var(--zw-modal-max-height);\n padding: 0 !important;\n}\n\n.zw-modal::v-deep .simplebar-content-wrapper {\n overscroll-behavior: contain;\n}\n</style>\n","<template>\n <div class=\"zw-field\">\n <label class=\"zw-field__label\" :for=\"fieldId\" data-test-selector=\"label\">\n {{ label }}\n </label>\n\n <input\n class=\"zw-field__input\"\n type=\"text\"\n :value=\"value\"\n :id=\"fieldId\"\n :placeholder=\"placeholder\"\n @input=\"onInput\"\n data-test-selector=\"input\"\n >\n\n <p class=\"zw-field__label--error\" v-if=\"error\" data-test-selector=\"error\">\n {{ error }}\n </p>\n </div>\n</template>\n\n<script>\nimport { computed } from '@vue/composition-api';\n\nexport default {\n name: 'TextField',\n\n props: {\n value: {\n type: [Number, String],\n required: true\n },\n\n label: {\n type: String,\n required: true\n },\n\n placeholder: {\n type: String,\n required: false,\n default: ''\n },\n\n error: {\n type: String,\n required: false,\n default: null\n }\n },\n\n setup(props, { emit }) {\n const onInput = (event) => emit('input', event.target.value);\n const fieldId = computed(() => {\n return props.label.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\n });\n\n return { onInput, fieldId };\n }\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.zw-field {\n display: flex;\n flex-direction: column;\n}\n\n.zw-field__input {\n --border-color: rgb(var(--zw-color-n60));\n --text-color: rgb(var(--zw-color-n85));\n\n border: 1px solid var(--border-color);\n background-color: transparent;\n color: var(--text-color);\n font-size: var(--zw-font-size-xxs);\n outline: none;\n padding: 6px;\n line-height: var(--zw-line-height-xxs);\n}\n\n.zw-field__input:hover {\n --border-color: rgb(var(--zw-color-n80));\n --text-color: rgb(var(--zw-color-n85));\n}\n\n.zw-field__input:focus,\n.zw-field__input:focus-within {\n --border-color: rgb(var(--zw-color-white));\n --text-color: rgb(var(--zw-color-white));\n}\n\n.zw-field__label {\n display: inline-block;\n font-size: var(--zw-font-size-xxs);\n padding-bottom: var(--zw-offset-xxs);\n line-height: var(--zw-line-height-xxs);\n}\n\n.zw-field__label--error {\n font-size: var(--zw-font-size-xxs);\n margin: var(--zw-offset-xxs) 0 0;\n color: rgb(var(--zw-color-red));\n}\n</style>\n","<template>\n <label class=\"zw-checkbox\">\n <input class=\"zw-checkbox__field\" type=\"checkbox\" :checked=\"value\" @change=\"onCheckedChanged\">\n <span class=\"zw-checkbox__indicator zw-margin-right--xs\" />\n <span class=\"zw-checkbox__label\">{{ label }}</span>\n </label>\n</template>\n\n<script>\nexport default {\n name: 'Checkbox',\n\n props: {\n value: {\n type: Boolean,\n required: true\n },\n\n label: {\n type: String,\n required: false,\n default: null\n }\n },\n\n setup(_, { emit }) {\n const onCheckedChanged = (event) => {\n emit('input', event.target.checked);\n };\n\n return { onCheckedChanged };\n }\n};\n</script>\n\n<style scoped>\n.zw-checkbox {\n display: inline-flex;\n align-items: center;\n position: relative;\n cursor: pointer;\n padding: var(--zw-offset-xxs) var(--zw-offset-xxs) var(--zw-offset-xxs) 0;\n}\n\n.zw-checkbox__field + .zw-checkbox__indicator {\n color: var(--zw-color-n200);\n box-shadow: inset 0 0 0 2px currentColor;\n}\n\n.zw-checkbox:hover .zw-checkbox__indicator {\n box-shadow: inset 0 0 0 2px rgb(var(--zw-color-green));\n}\n\n.zw-checkbox__field:checked + .zw-checkbox__indicator {\n color: rgb(var(--zw-color-green))\n}\n\n.zw-checkbox .zw-checkbox__field:checked + .zw-checkbox__indicator {\n background-color: rgb(var(--zw-color-green));\n}\n\n.zw-checkbox .zw-checkbox__indicator::after {\n content: \"\";\n display: block;\n height: 16px;\n transform: scale(0.6);\n transition: transform 0.2s ease-out;\n width: 16px;\n background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNiAyNiIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiPgogIDxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0uMyAxNGMtLjItLjItLjMtLjUtLjMtLjdzLjEtLjUuMy0uN2wxLjQtMS40Yy40LS40IDEtLjQgMS40IDBsLjEuMSA1LjUgNS45Yy4yLjIuNS4yLjcgMEwyMi44IDMuM2guMWMuNC0uNCAxLS40IDEuNCAwbDEuNCAxLjRjLjQuNC40IDEgMCAxLjRsLTE2IDE2LjZjLS4yLjItLjQuMy0uNy4zLS4zIDAtLjUtLjEtLjctLjNMLjUgMTQuMy4zIDE0eiIvPgo8L3N2Zz4K\");\n background-repeat: no-repeat;\n background-size: 16px;\n background-position: center center;\n}\n\n.zw-checkbox__field:not(:checked) + .zw-checkbox__indicator::after {\n transform: scale(0);\n}\n\n.zw-checkbox__field {\n position: absolute;\n opacity: 0;\n height: 0;\n width: 0;\n}\n\n.zw-checkbox__label {\n font-size: var(--zw-font-size-xs);\n}\n</style>\n","<template>\n <div>\n <slot :open=\"open\" :isOpened=\"isOpened\">\n <Button\n skin=\"toolbar\"\n class=\"zw-dropdown__activator\"\n :class=\"dropdownClasses\"\n :active=\"isOpened\"\n @click=\"open\"\n >\n <span class=\"zw-dropdown__activator-title zw-text--truncate\">\n {{ activeOptionTitle }}\n </span>\n\n <Icon\n class=\"zw-dropdown__activator-arrow\"\n name=\"arrow\"\n size=\"8px\"\n auto-color\n />\n </Button>\n </slot>\n </div>\n</template>\n\n<script>\nimport { computed, inject, toRef } from '@vue/composition-api';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport { InjectionTokens } from './injectionTokens';\nimport { useDropdownEntityTitle } from './composables';\n\nexport default {\n name: 'DropdownActivator',\n\n components: {\n Icon,\n Button\n },\n\n model: {\n event: 'change'\n },\n\n props: {\n color: {\n type: String,\n required: false,\n default: 'none'\n }\n },\n\n setup(props) {\n const activeOptionManager = inject(InjectionTokens.ACTIVE_MANAGER);\n const dropdownToggler = inject(InjectionTokens.TOGGLER);\n const color = toRef(props, 'color');\n\n const activeOptionTitle = useDropdownEntityTitle(activeOptionManager.activeOption);\n\n const dropdownClasses = computed(() => ({\n 'zw-dropdown__activator--active': dropdownToggler.isOpened.value,\n 'zw-dropdown__activator--gray': color.value === 'gray'\n }));\n\n return {\n activeOptionTitle,\n isOpened: dropdownToggler.isOpened,\n open: dropdownToggler.open,\n dropdownClasses\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-dropdown__activator {\n width: 100%;\n}\n\n.zw-dropdown__activator-title {\n margin-right: var(--zw-offset-xs);\n}\n\n.zw-dropdown__activator-arrow {\n margin-left: auto;\n}\n\n.zw-dropdown__activator--active .zw-dropdown__activator-arrow {\n transform: rotateX(180deg);\n}\n\n.zw-dropdown__activator--gray {\n background-color: rgb(var(--zw-color-n20));\n font-size: var(--zw-font-size-xxs);\n color: rgb(var(--zw-color-white));\n}\n</style>\n","<template>\n <Button\n class=\"zw-dropdown__option zw-text--truncate\"\n ref=\"optionRef\"\n :class=\"classes\"\n @click=\"activate\"\n >\n <slot>{{ optionTitle }}</slot>\n </Button>\n</template>\n\n<script>\nimport { computed, inject, nextTick, onMounted, ref, toRef } from '@vue/composition-api';\nimport Button from '../Button';\nimport { useScrollView } from '../composables';\nimport { InjectionTokens } from './injectionTokens';\nimport { useDropdownEntityTitle } from './composables';\n\nexport default {\n name: 'DropdownOption',\n\n components: {\n Button\n },\n\n props: {\n option: {\n type: Object,\n required: true\n }\n },\n\n setup(props) {\n const activeOptionManager = inject(InjectionTokens.ACTIVE_MANAGER);\n const dropdownToggler = inject(InjectionTokens.TOGGLER);\n const session = inject(InjectionTokens.SESSION);\n\n const optionRef = ref(null);\n const scrollView = useScrollView();\n const optionTitle = useDropdownEntityTitle(toRef(props, 'option'));\n const isActive = computed(() => props.option.id === activeOptionManager.activeOption.value?.id);\n const classes = computed(() => ({ 'zw-dropdown__option--active': isActive.value }));\n\n function activate() {\n activeOptionManager.activateOption(props.option);\n dropdownToggler.close();\n }\n\n onMounted(async () => {\n if (isActive.value && !session.scrolled) {\n session.scrolled = true; // Prevent multiple scrolling to option\n\n await nextTick();\n const el = optionRef.value.$el;\n const offset = el.offsetHeight * 1.5;\n\n scrollView.scrollToElement(el, { offset });\n }\n });\n\n return {\n optionTitle,\n classes,\n isActive,\n optionRef,\n activate\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-dropdown__option {\n width: 100%;\n display: block;\n color: rgb(var(--zw-color-white));\n padding-top: var(--zw-offset-xxs);\n padding-right: var(--zw-offset-sm);\n padding-left: calc(var(--zw-offset-sm) + var(--zw-option-offset, 0px));\n padding-bottom: var(--zw-offset-xxs);\n text-align: left;\n transition: 0.1s background-color ease-out;\n will-change: background-color;\n}\n\n.zw-dropdown__option:hover,\n.zw-dropdown__option:focus,\n.zw-dropdown__option--active {\n background-color: rgb(var(--zw-color-n30));\n}\n</style>\n","<template>\n <div class=\"zw-dropdown__group\">\n <p class=\"zw-dropdown__group-title\">\n {{ groupTitle }}\n </p>\n\n <slot name=\"option\" :option=\"option\" v-for=\"option of group.options\">\n <DropdownOption :option=\"option\" />\n </slot>\n </div>\n</template>\n\n<script>\nimport { toRef } from '@vue/composition-api';\nimport DropdownOption from './DropdownOption';\nimport { useDropdownEntityTitle } from './composables';\n\nexport default {\n name: 'DropdownGroup',\n\n components: {\n DropdownOption\n },\n\n props: {\n group: {\n type: Object,\n required: true\n }\n },\n\n setup(props) {\n const groupTitle = useDropdownEntityTitle(toRef(props, 'group'));\n\n return { groupTitle };\n }\n};\n</script>\n\n<style scoped>\n.zw-dropdown__group {\n padding-top: var(--zw-offset-xs);\n padding-bottom: var(--zw-offset-xs);\n --zw-option-offset: var(--zw-offset-xs);\n}\n\n.zw-dropdown__group-title {\n color: var(--zw-color-n70);\n font-weight: var(--zw-font-weight-semibold);\n padding-left: var(--zw-offset-sm);\n padding-right: var(--zw-offset-sm);\n margin-top: 0;\n margin-bottom: var(--zw-offset-xs);\n}\n</style>\n","<template>\n <div class=\"zw-dropdown__divider\" />\n</template>\n\n<script>\nexport default {\n name: 'DropdownDivider'\n};\n</script>\n\n<style scoped>\n.zw-dropdown__divider {\n padding: 0 var(--zw-offset-sm);\n}\n\n.zw-dropdown__divider::before {\n content: \"\";\n display: block;\n border-bottom: 1px solid rgb(var(--zw-color-n30));\n}\n</style>\n","<template>\n <ScrollView>\n <div class=\"zw-dropdown__menu\" data-test-selector=\"dropdownMenu\">\n <template v-for=\"(option, index) of options\">\n <template v-if=\"option.options\">\n <DropdownGroup :key=\"option.id\" :group=\"option\">\n <template #option=\"attrs\">\n <slot v-bind=\"attrs\" name=\"option\" />\n </template>\n </DropdownGroup>\n\n <DropdownDivider\n :key=\"option.id + ' divider'\"\n v-if=\"index + 1 !== options.length\"\n />\n </template>\n\n <slot name=\"option\" :option=\"option\" v-else>\n <DropdownOption :option=\"option\" />\n </slot>\n </template>\n </div>\n </ScrollView>\n</template>\n\n<script>\nimport { provide } from '@vue/composition-api';\nimport ScrollView from '../ScrollView';\nimport { InjectionTokens } from './injectionTokens';\nimport DropdownGroup from './DropdownGroup';\nimport DropdownOption from './DropdownOption';\nimport DropdownDivider from './DropdownDivider';\n\nexport default {\n name: 'DropdownMenu',\n\n components: {\n ScrollView,\n DropdownGroup,\n DropdownOption,\n DropdownDivider\n },\n\n props: {\n options: {\n type: Array,\n required: true\n }\n },\n\n setup() {\n provide(InjectionTokens.SESSION, {});\n }\n};\n</script>\n\n<style>\n.zw-dropdown__menu {\n padding-top: var(--zw-offset-xs);\n padding-bottom: var(--zw-offset-xs);\n}\n</style>\n","<template>\n <div class=\"zw-dropdown\" ref=\"dropdownRef\">\n <DropdownActivator :color=\"color\">\n <template #default=\"attrs\">\n <slot name=\"activator\" v-bind=\"attrs\" />\n </template>\n </DropdownActivator>\n\n <Modal max-height=\"300\" :max-width=\"maxWidth\" :toggler=\"toggler\" ref=\"modalRef\">\n <DropdownMenu :options=\"options\">\n <template #option=\"attrs\">\n <slot name=\"option\" v-bind=\"attrs\" />\n </template>\n </DropdownMenu>\n </Modal>\n </div>\n</template>\n\n<script>\nimport { provide, toRef, ref } from '@vue/composition-api';\nimport Modal from '../Modal';\nimport { useModalToggler } from '../composables';\nimport { InjectionTokens } from './injectionTokens';\nimport DropdownActivator from './DropdownActivator';\nimport DropdownMenu from './DropdownMenu';\nimport { useActiveOptionManager } from './composables';\n\nexport default {\n name: 'Dropdown',\n\n components: {\n Modal,\n DropdownActivator,\n DropdownMenu\n },\n\n model: {\n event: 'change'\n },\n\n props: {\n value: {\n type: [String, Number],\n required: false,\n default: null\n },\n\n options: {\n type: Array,\n required: true\n },\n\n maxWidth: {\n type: Number,\n required: false,\n default: 156\n },\n\n color: {\n type: String,\n required: false,\n default: 'none'\n }\n },\n\n setup(props, { emit }) {\n const dropdownRef = ref(null);\n const modalRef = ref(null);\n\n const activeOptionManager = useActiveOptionManager({\n optionsRef: toRef(props, 'options'),\n inputRef: toRef(props, 'value'),\n stateless: props.value === null,\n onChange: (value) => emit('change', value.id)\n });\n\n const toggler = useModalToggler({\n wrapperRef: dropdownRef,\n modalRef\n });\n\n provide(InjectionTokens.ACTIVE_MANAGER, activeOptionManager);\n provide(InjectionTokens.TOGGLER, toggler);\n\n return {\n dropdownRef,\n modalRef,\n toggler\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-dropdown {\n position: relative;\n font-size: var(--zw-font-size-xs);\n line-height: var(--zw-line-height-xxs);\n}\n</style>\n","<template>\n <div class=\"zw-style-preset-control\">\n <Dropdown\n class=\"zw-style-preset-control__dropdown\"\n :value=\"preset.id\"\n :options=\"options\"\n @change=\"apply\"\n v-tooltip=\"'Text Type'\"\n />\n\n <Button\n class=\"zw-style-preset-control__reset\"\n :disabled=\"!isCustomized\"\n icon\n @click=\"removeCustomization\"\n v-tooltip=\"'Reset Styles'\"\n >\n <Icon name=\"reset-styles\" size=\"28px\" auto-color />\n </Button>\n </div>\n</template>\n\n<script>\nimport { computed, inject } from '@vue/composition-api';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { Dropdown, Button, Icon } from '../../base';\nimport { tooltip } from '../../../directives';\n\nexport default {\n name: 'StylePresetControl',\n\n components: {\n Icon,\n Button,\n Dropdown\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const editor = inject(InjectionTokens.EDITOR);\n\n const presets = editor.commands.getPresetList();\n const preset = editor.commands.getPreset();\n const customization = editor.commands.getPresetCustomization();\n\n const isCustomized = computed(() => {\n const { attributes, marks } = customization.value;\n\n return !!attributes.length || !!marks.length;\n });\n\n const options = computed(() => {\n return presets.value.map((preset) => ({\n id: preset.id,\n title: preset.name\n }));\n });\n\n const apply = (value) => editor.chain().focus().applyPreset(value).run();\n const removeCustomization = () => editor.chain().focus().removePresetCustomization().run();\n\n return {\n options,\n preset,\n isCustomized,\n apply,\n removeCustomization\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-style-preset-control {\n display: flex;\n align-items: center;\n}\n\n.zw-style-preset-control__dropdown {\n width: 96px;\n}\n\n.zw-style-preset-control__reset {\n color: rgb(var(--zw-color-n70));\n}\n\n.zw-style-preset-control__reset:not(:disabled):hover,\n.zw-style-preset-control__reset:not(:disabled):focus,\n.zw-style-preset-control__reset:not(:disabled):focus-within {\n color: rgb(var(--zw-color-white));\n}\n</style>\n","<template>\n <Dropdown\n class=\"zw-font-family-control\"\n :options=\"options\"\n :value=\"currentValue\"\n @change=\"apply\"\n v-tooltip=\"'Font Name'\"\n >\n <template #option=\"{ option }\">\n <DropdownOption\n class=\"zw-font-family-control__option\"\n :option=\"option\"\n :style=\"renderOptionStyles(option)\"\n v-tooltip=\"option.id\"\n />\n </template>\n </Dropdown>\n</template>\n\n<script>\nimport { computed, inject } from '@vue/composition-api';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { tooltip } from '../../../directives';\nimport { Dropdown, DropdownOption } from '../../base';\nimport { useRecentFonts } from './composables';\n\nexport default {\n name: 'FontFamilyControl',\n\n components: {\n Dropdown,\n DropdownOption\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const fonts = inject(InjectionTokens.FONTS);\n const editor = inject(InjectionTokens.EDITOR);\n\n const recentFontNames = useRecentFonts({ limit: 5 });\n\n const recentFontsCategory = computed(() => ({\n id: 'Recently Used',\n options: recentFontNames.fonts.value.map((name) => ({ id: name }))\n }));\n\n const options = computed(() => {\n const list = {};\n\n for (const font of fonts) {\n list[font.category] ??= { id: font.category, options: [] };\n list[font.category].options.push({ id: font.name });\n }\n\n if (recentFontNames.isEmpty.value) {\n return Object.values(list);\n }\n\n return [recentFontsCategory.value, ...Object.values(list)];\n });\n\n function renderOptionStyles(option) {\n return { '--zw-font-family-option': `\"${option.id}\"` };\n }\n\n const currentValue = editor.commands.getFontFamily();\n\n const apply = (fontFamily) => {\n recentFontNames.add(fontFamily);\n editor.chain().focus().applyFontFamily(fontFamily).run();\n };\n\n return {\n options,\n currentValue,\n renderOptionStyles,\n apply\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-font-family-control {\n width: 96px;\n}\n\n.zw-font-family-control__option {\n font-weight: 400;\n font-family: var(--zw-font-family-option);\n width: 150px;\n}\n</style>\n","<template>\n <Dropdown\n class=\"zw-font-size-control\"\n :options=\"options\"\n :value=\"currentValue\"\n @change=\"apply\"\n v-tooltip=\"{ text: 'Font Size', hotkey: 'Mod Shift +/-' }\"\n />\n</template>\n\n<script>\nimport { computed, inject } from '@vue/composition-api';\nimport { Dropdown } from '../../base';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { tooltip } from '../../../directives';\n\nexport default {\n name: 'FontSizeControl',\n\n components: {\n Dropdown\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const fontSizes = inject(InjectionTokens.FONT_SIZES);\n const editor = inject(InjectionTokens.EDITOR);\n\n const options = computed(() => {\n return fontSizes.map((size) => ({ id: size, title: `${size}px` }));\n });\n\n const currentValue = editor.commands.getFontSize();\n const apply = (value) => editor.chain().focus().applyFontSize(value).run();\n\n return {\n options,\n currentValue,\n apply\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-font-size-control {\n width: 64px;\n}\n</style>\n","<template>\n <div class=\"zw-position--relative\" ref=\"wrapperRef\">\n <Button\n icon\n skin=\"toolbar\"\n :active=\"isOpened\"\n @click=\"toggler.open\"\n v-tooltip=\"'Alignment'\"\n >\n <Icon :name=\"`alignment-${currentValue}`\" size=\"28px\" auto-color />\n </Button>\n\n <Modal class=\"zw-alignment-control__modal\" ref=\"modalRef\" :toggler=\"toggler\">\n <AlignmentControl class=\"zw-alignment-control__toggle\" @applied=\"toggler.close\" />\n </Modal>\n </div>\n</template>\n\n<script>\nimport { inject, ref } from '@vue/composition-api';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { Button, Icon, Modal, useModalToggler } from '../../base';\nimport { tooltip } from '../../../directives';\nimport AlignmentControl from './AlignmentControl';\n\nexport default {\n name: 'AlignmentDeviceControl',\n\n components: {\n Button,\n Icon,\n Modal,\n AlignmentControl\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const editor = inject(InjectionTokens.EDITOR);\n const currentValue = editor.commands.getAlignment();\n const wrapperRef = ref(null);\n const modalRef = ref(null);\n\n const toggler = useModalToggler({ wrapperRef, modalRef });\n\n return {\n wrapperRef,\n modalRef,\n currentValue,\n toggler,\n isOpened: toggler.isOpened\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-alignment-control__modal {\n padding: var(--zw-offset-xxs);\n}\n\n.zw-alignment-control__toggle {\n flex-direction: column;\n}\n</style>\n","<template>\n <div class=\"zw-position--relative\" ref=\"wrapperRef\">\n <Button\n icon\n skin=\"toolbar\"\n :active=\"isOpened\"\n @click=\"toggler.open\"\n v-tooltip=\"'Line Height'\"\n >\n <Icon name=\"line-height\" size=\"28px\" auto-color />\n </Button>\n\n <Modal class=\"zw-line-height-control__modal\" ref=\"modalRef\" :toggler=\"toggler\">\n <FieldLabel class=\"zw-margin-bottom--xs\" field-id=\"wswg-line-height\">\n Line Height\n </FieldLabel>\n\n <div class=\"zw-line-height-control__row\">\n <Range\n class=\"zw-line-height-control__range\"\n step=\"0.1\"\n min=\"1\"\n max=\"3\"\n :value=\"currentValue\"\n @input=\"apply\"\n />\n\n <NumberField\n step=\"0.1\"\n min=\"1\"\n max=\"3\"\n class=\"zw-line-height-control__field\"\n field-id=\"wswg-line-height\"\n :value=\"currentValue\"\n @input=\"apply\"\n />\n </div>\n </Modal>\n </div>\n</template>\n\n<script>\nimport { inject, ref } from '@vue/composition-api';\nimport { Button, Icon, Modal, Range, NumberField, FieldLabel, useModalToggler } from '../../base';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { tooltip } from '../../../directives';\n\nexport default {\n name: 'LineHeightControl',\n\n components: {\n Range,\n Modal,\n Icon,\n Button,\n NumberField,\n FieldLabel\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const wrapperRef = ref(null);\n const modalRef = ref(null);\n const editor = inject(InjectionTokens.EDITOR);\n const toggler = useModalToggler({ wrapperRef, modalRef });\n const currentValue = editor.commands.getLineHeight();\n const apply = (value) => editor.commands.applyLineHeight(String(value));\n\n return {\n wrapperRef,\n modalRef,\n isOpened: toggler.isOpened,\n toggler,\n currentValue,\n apply\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-line-height-control__modal {\n padding: var(--zw-offset-sm);\n}\n\n.zw-line-height-control__row {\n display: flex;\n align-items: center;\n}\n\n.zw-line-height-control__range {\n width: 156px;\n}\n\n.zw-line-height-control__field {\n width: 52px;\n margin-left: var(--zw-offset-sm);\n}\n</style>\n","<template>\n <Dropdown\n :value=\"currentValue\"\n :options=\"$options.listTypes\"\n @change=\"apply\"\n >\n <template #activator=\"{ open, isOpened }\">\n <Button\n icon\n skin=\"toolbar\"\n :active=\"isOpened || isList\"\n @click=\"open\"\n v-tooltip=\"'Bullet Styles'\"\n >\n <Icon :name=\"currentIcon\" size=\"28px\" auto-color />\n </Button>\n </template>\n\n <template #option=\"{ option }\">\n <DropdownOption class=\"zw-list-control__option\" :option=\"option\">\n <Icon :name=\"option.icon\" size=\"28px\" auto-color />\n </DropdownOption>\n </template>\n </Dropdown>\n</template>\n\n<script>\nimport { computed, inject } from '@vue/composition-api';\nimport { InjectionTokens } from '../../../injectionTokens';\nimport { Dropdown, DropdownOption, Button, Icon } from '../../base';\nimport { ListTypes } from '../../../enums';\nimport { tooltip } from '../../../directives';\n\nexport default {\n name: 'ListControl',\n\n listTypes: ListTypes.values.map((type) => ({\n id: type,\n icon: `list-${type}`\n })),\n\n components: {\n Dropdown,\n DropdownOption,\n Button,\n Icon\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const editor = inject(InjectionTokens.EDITOR);\n const selectionValue = editor.commands.getListType();\n const isList = computed(() => !!selectionValue.value);\n const currentValue = computed(() => selectionValue.value || 'none');\n\n const currentIcon = computed(() => {\n const type = selectionValue.value || ListTypes.DISC;\n\n return `list-${type}`;\n });\n\n const apply = (type) => editor.chain().focus().applyList(type).run();\n\n return {\n isList,\n currentValue,\n currentIcon,\n apply\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-list-control__option {\n padding: 0 var(--zw-offset-xs);\n display: flex;\n}\n</style>\n","<template>\n <div class=\"zw-link-modal-header\">\n <span class=\"zw-link-modal-header__title\">Link</span>\n\n <Button class=\"zw-link-modal-header__unlink-button\" :disabled=\"!isLink\" @click=\"removeLink\">\n <Icon class=\"zw-link-modal-header__unlink-icon\" name=\"unlink\" size=\"14px\" auto-color />\n Remove\n </Button>\n </div>\n</template>\n\n<script>\nimport { computed, inject } from '@vue/composition-api';\nimport { Icon, Button } from '../../../base';\nimport { InjectionTokens } from '../../../../injectionTokens';\n\nexport default {\n name: 'LinkControlHeader',\n\n components: { Icon, Button },\n\n setup(_, { emit }) {\n const editor = inject(InjectionTokens.EDITOR);\n const isLink = computed(() => editor.isActive('link'));\n\n const removeLink = () => emit('remove-link');\n\n return { isLink, removeLink };\n }\n};\n</script>\n\n<style scoped>\n.zw-link-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--zw-offset-sm);\n border-bottom: 2px solid rgb(var(--zw-color-n5));\n}\n\n.zw-link-modal-header__title {\n text-transform: uppercase;\n font-weight: var(--zw-font-weight-semibold);\n font-size: var(--zw-font-size-xxs);\n color: rgb(var(--zw-color-white));\n}\n\n.zw-link-modal-header__unlink-icon {\n margin-right: var(--zw-offset-xxs);\n}\n\n.zw-link-modal-header__unlink-button {\n color: rgb(var(--zw-color-n80));\n font-size: var(--zw-font-size-xxs);\n transition: 0.1s opacity ease-out;\n will-change: opacity;\n}\n\n.zw-link-modal-header__unlink-button:disabled {\n opacity: 0.35;\n}\n\n.zw-link-modal-header__unlink-button:hover {\n color: rgb(var(--zw-color-white));\n}\n</style>\n","<template>\n <div class=\"zw-link-modal__apply\">\n <Button class=\"zw-margin-right--xs\" skin=\"secondary\" @click=\"cancel\">\n Cancel\n </Button>\n\n <Button @click=\"apply\" skin=\"primary\">\n Save\n </Button>\n </div>\n</template>\n\n<script>\nimport { Button } from '../../../base';\n\nexport default {\n name: 'LinkControlApply',\n\n components: { Button },\n\n setup(_, { emit }) {\n const cancel = () => emit('cancel');\n const apply = () => emit('apply');\n\n return { cancel, apply };\n }\n};\n</script>\n\n<style scoped>\n.zw-link-modal__apply {\n display: flex;\n justify-content: flex-end;\n}\n</style>\n","<template>\n <div class=\"zw-position--relative\" ref=\"wrapperRef\">\n <Button icon skin=\"toolbar\" :active=\"isActive\" @click=\"toggler.open\" v-tooltip=\"'Link'\">\n <Icon name=\"link\" size=\"28px\" auto-color />\n </Button>\n\n <Modal class=\"zw-link-modal\" :toggler=\"toggler\" ref=\"modalRef\">\n <LinkControlHeader @remove-link=\"removeLink\" />\n\n <div class=\"zw-link-modal__body\">\n <TextField\n class=\"zw-margin-bottom--sm\"\n :value=\"link.linkData.value.text\"\n label=\"Text to display\"\n placeholder=\"Type Text\"\n :error=\"nameValidator.error.value\"\n @input=\"link.updateText\"\n />\n\n <LinkControlDestination\n class=\"zw-margin-bottom--md\"\n :link=\"link\"\n :validator=\"urlValidator\"\n @reset-errors=\"resetErrors\"\n />\n\n <LinkControlApply @cancel=\"toggler.close\" @apply=\"applyLink\" />\n </div>\n </Modal>\n </div>\n</template>\n\n<script>\nimport { computed, ref, inject } from '@vue/composition-api';\nimport { InjectionTokens } from '../../../../injectionTokens';\nimport { tooltip } from '../../../../directives';\nimport { useValidator } from '../../../base/composables';\nimport { Button, Icon, Modal, TextField, useModalToggler } from '../../../base';\nimport LinkControlHeader from './LinkControlHeader';\nimport LinkControlApply from './LinkControlApply';\nimport { useLink } from './composables';\nimport { LinkControlDestination } from './destination';\n\nexport default {\n name: 'LinkControl',\n\n components: {\n LinkControlDestination,\n LinkControlApply,\n LinkControlHeader,\n TextField,\n Modal,\n Icon,\n Button\n },\n\n directives: {\n tooltip\n },\n\n setup() {\n const wrapperRef = ref(null);\n const modalRef = ref(null);\n const nameError = ref(false);\n const urlError = ref(false);\n\n const editor = inject(InjectionTokens.EDITOR);\n\n const link = useLink();\n\n const resetErrors = () => {\n nameError.value = null;\n urlError.value = null;\n };\n\n const onBeforeOpened = () => {\n editor.commands.extendMarkRange('link');\n resetErrors();\n link.prepareInitialFields();\n };\n\n const toggler = useModalToggler({\n onBeforeOpened: () => onBeforeOpened(),\n wrapperRef,\n modalRef\n });\n\n const isActive = computed(() => toggler.isOpened.value || editor.isActive('link'));\n const isEmpty = () => {\n return link.linkData.value.text ? false : 'Can\\'t be empty';\n };\n const isUrl = () => {\n if (link.currentDestination.value.id !== 'url') return false;\n\n return /(^(https?:\\/\\/|\\/)(?:www\\.|(?!www))?[^\\s])/.test(link.destinationHrefs.value.url) ? false : 'Please enter a valid URL';\n };\n\n const nameValidator = useValidator({\n validations: [isEmpty],\n value: link.linkData.value.text\n });\n\n const urlValidator = useValidator({\n validations: [isUrl],\n value: link.linkData.value.text\n });\n\n const applyLink = () => {\n urlError.value = urlValidator.validate();\n nameError.value = nameValidator.validate();\n\n if (urlError.value || nameError.value) return;\n\n link.apply();\n toggler.close();\n };\n\n const removeLink = () => {\n link.removeLink();\n toggler.close();\n };\n\n return {\n wrapperRef,\n modalRef,\n link,\n toggler,\n isActive,\n nameValidator,\n urlValidator,\n nameError,\n resetErrors,\n applyLink,\n removeLink\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-link-modal {\n width: 266px;\n}\n\n.zw-link-modal__body {\n padding: var(--zw-offset-sm);\n}\n\n::v-deep .zw-link-modal-dropdown__option {\n width: 234px;\n}\n</style>\n","<template>\n <keep-alive>\n <transition name=\"zw-toolbar-\" duration=\"150\">\n <div class=\"zw-toolbar\" :style=\"toolbarStyles\" ref=\"toolbarRef\" v-if=\"isVisible\">\n <component :is=\"toolbarComponent\" />\n </div>\n </transition>\n </keep-alive>\n</template>\n\n<script>\nimport { computed, ref, watch } from '@vue/composition-api';\nimport { Devices } from '../../enums';\nimport ToolbarFull from './ToolbarFull';\nimport ToolbarDevice from './ToolbarDevice';\n\nexport default {\n name: 'Toolbar',\n\n props: {\n device: {\n type: String,\n required: true\n },\n\n toolbar: {\n type: Object,\n required: true\n }\n },\n\n setup(props) {\n const toolbarComponent = computed(() => {\n return props.device === Devices.DESKTOP ? ToolbarFull : ToolbarDevice;\n });\n const isVisible = computed(() => props.toolbar.isActiveRef.value);\n const toolbarRef = ref(null);\n\n watch(toolbarRef, (toolbarEl) => {\n toolbarEl && props.toolbar.mount(toolbarEl);\n });\n\n const toolbarStyles = computed(() => ({\n '--zw-toolbar-offset-y': `${props.toolbar.offsets[1]}px`\n }));\n\n return {\n toolbarComponent,\n isVisible,\n toolbarRef,\n toolbarStyles\n };\n }\n};\n</script>\n\n<style scoped>\n.zw-toolbar {\n border-radius: 2px;\n background-color: rgb(var(--zw-color-n15));\n color: rgb(var(--zw-color-n70));\n z-index: 999999;\n}\n\n.zw-toolbar::before,\n.zw-toolbar::after {\n content: \"\";\n display: block;\n width: 100%;\n height: calc(var(--zw-toolbar-offset-y) + 4px);\n position: absolute;\n --zw-toolbar-safe-zone: calc(-1 * var(--zw-toolbar-offset-y));\n}\n\n.zw-toolbar::before {\n top: var(--zw-toolbar-safe-zone);\n}\n\n.zw-toolbar::after {\n bottom: var(--zw-toolbar-safe-zone);\n}\n\n.zw-toolbar--enter-active,\n.zw-toolbar--leave-active {\n transition: opacity 150ms ease-out;\n}\n\n.zw-toolbar--leave-active {\n transition: opacity 0s ease-in;\n}\n\n.zw-toolbar--enter,\n.zw-toolbar--leave-to {\n opacity: 0;\n}\n</style>\n",".zw-wysiwyg {\n --zw-color-n5: 13, 13, 13; /* #0D0D0D; */\n --zw-color-n15: 38, 38, 38; /* #262626; */\n --zw-color-n20: 59, 59, 59; /* #3B3B3B; */\n --zw-color-n30: 77, 77, 77; /* #4D4D4D; */\n --zw-color-n60: 153, 153, 153; /* #999999 */\n --zw-color-n70: 179, 179, 179; /* #B3B3B3 */\n --zw-color-n80: 196, 196, 196; /* #C4C4C4 */\n --zw-color-n85: 217, 217, 217; /* #D9D9D9 */\n --zw-color-n90: 230, 230, 230; /* #E6E6E6 */\n --zw-color-n200: 194, 200, 209; /* #C2C8D1 */\n --zw-color-black: 0, 0, 0;\n --zw-color-white: 255, 255, 255;\n --zw-color-green: 59, 180, 74; /* #3BB44A */\n --zw-color-red: 234, 58, 58; /* #EA3A3A */\n\n --zw-offset-xxs: 4px;\n --zw-offset-xs: 8px;\n --zw-offset-xsm: 12px;\n --zw-offset-sm: 16px;\n --zw-offset-md: 24px;\n\n --zw-font-weight-thin: 400;\n --zw-font-weight-semibold: 500;\n\n --zw-font-size-xxs: 12px;\n --zw-font-size-xs: 14px;\n\n --zw-line-height-xxs: 1.21;\n --zw-line-height-md: 1.72;\n}\n\n/*\n$builder-N5: #0D0D0D;\n$builder-N10: #1A1A1A;\n$builder-N15: #262626;\n$builder-N20: #3B3B3B;\n$builder-N30: #4D4D4D;\n$builder-N40: #666;\n$builder-N50: #808080;\n$builder-N60: #999;\n$builder-N70: #B3B3B3;\n$builder-N80: #C4C4C4;\n$builder-N85: #D9D9D9;\n$builder-N90: #E6E6E6;\n$builder-N94: #F0F0F0;\n$builder-N96: #F5F5F5;\n$builder-N98: #FAFAFA;\n$builder-N200: #C2C8D1;\n$builder-R50: #EA3A3A;\n\n$font-size-xxs: 12px;\n$font-size-xs: 14px;\n$font-size-sm: 16px;\n$font-size-md: 18px;\n$font-size-lmd: 20px;\n$font-size-lg: 24px;\n\n$font-height--xxs: 1.2;\n$font-height--xs: 1.33;\n$font-height--sm: 1.43;\n$font-height--md: 1.72;\n */\n",".zw-wysiwyg [contenteditable] {\n outline: none;\n}\n\n.zw-wysiwyg__placeholder:first-child:last-child::before {\n content: attr(data-placeholder);\n color: rgb(var(--zw-color-n70));\n float: left;\n height: 0;\n pointer-events: none;\n}\n\n.zw-style {\n font-weight: var(--zw-font-weight, var(--zw-preset-font-weight));\n font-family: var(--zw-font-family, var(--zw-preset-font-family));\n color: var(--zw-font-color, var(--zw-preset-color));\n font-style: var(--zw-font-style, var(--zw-preset-font-style));\n text-decoration: var(--zw-text-decoration, var(--zw-preset-text-decoration));\n background-color: var(--zw-background-color, var(--zw-preset-background-color));\n}\n\n@media (min-width: 1200px) {\n\n .zw-style {\n font-size: var(--zw-font-size-desktop, var(--zw-preset-desktop-font-size));\n text-align: var(--zw-text-align-desktop, var(--zw-preset-desktop-text-align));\n line-height: var(--zw-line-height-desktop, var(--zw-preset-desktop-line-height));\n }\n}\n\n@media (min-width: 769px) and (max-width: 1199.98px) {\n\n .zw-style {\n font-size: var(--zw-font-size-tablet, var(--zw-preset-tablet-font-size));\n text-align: var(--zw-text-align-tablet, var(--zw-preset-tablet-text-align));\n line-height: var(--zw-line-height-tablet, var(--zw-preset-tablet-line-height));\n }\n}\n\n@media (max-width: 768.98px) {\n\n .zw-style {\n font-size: var(--zw-font-size-mobile, var(--zw-preset-mobile-font-size));\n text-align: var(--zw-text-align-mobile, var(--zw-preset-mobile-text-align));\n line-height: var(--zw-line-height-mobile, var(--zw-preset-mobile-line-height));\n }\n}\n\n/* ProseMirror styles */\n\n.ProseMirror {\n position: relative;\n}\n\n.ProseMirror {\n word-wrap: break-word;\n white-space: pre-wrap;\n white-space: break-spaces;\n -webkit-font-variant-ligatures: none;\n font-variant-ligatures: none;\n font-feature-settings: \"liga\" 0; /* the above doesn't seem to work in Edge */\n}\n\n.ProseMirror [contenteditable=\"false\"] {\n white-space: normal;\n}\n\n.ProseMirror [contenteditable=\"false\"] [contenteditable=\"true\"] {\n white-space: pre-wrap;\n}\n\n.ProseMirror pre {\n white-space: pre-wrap;\n}\n\nimg.ProseMirror-separator {\n display: inline !important;\n border: none !important;\n margin: 0 !important;\n width: 1px !important;\n height: 1px !important;\n}\n\n.ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n margin: 0;\n}\n\n.ProseMirror-gapcursor::after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid #000;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n\n to {\n visibility: hidden;\n }\n}\n\n.ProseMirror-hideselection *::selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n background: transparent;\n}\n\n.ProseMirror-hideselection * {\n caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n}\n\n.tippy-box[data-animation=fade][data-state=hidden] {\n opacity: 0\n}\n",".zw-text--truncate {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n}\n",".zw-position--relative {\n position: relative;\n}\n",".zw-margin-bottom--xxs {\n margin-bottom: var(--zw-offset-xxs);\n}\n\n.zw-margin-bottom--xs {\n margin-bottom: var(--zw-offset-xs);\n}\n\n.zw-margin-bottom--sm {\n margin-bottom: var(--zw-offset-sm);\n}\n\n.zw-margin-bottom--md {\n margin-bottom: var(--zw-offset-md);\n}\n\n.zw-margin-right--xs {\n margin-right: var(--zw-offset-xs);\n}\n"],"names":[],"sourceRoot":""}