@fastkit/vui 0.6.35 → 0.6.36

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.
@@ -3,16 +3,25 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var vueKit = require('@fastkit/vue-kit');
6
+ var vue = require('vue');
6
7
  var vueRouter = require('vue-router');
7
8
  var vueUtils = require('@fastkit/vue-utils');
8
- var vue = require('vue');
9
9
  var vueColorScheme = require('@fastkit/vue-color-scheme');
10
10
  var vueLoading = require('@fastkit/vue-loading');
11
11
  var iconFont = require('@fastkit/icon-font');
12
12
  var helpers = require('@fastkit/helpers');
13
13
  var vueAppLayout = require('@fastkit/vue-app-layout');
14
+ var vueFormControl = require('@fastkit/vue-form-control');
14
15
  var vue3 = require('@tiptap/vue-3');
15
16
  var StarterKit = require('@tiptap/starter-kit');
17
+ var extensionBulletList = require('@tiptap/extension-bullet-list');
18
+ var extensionBold = require('@tiptap/extension-bold');
19
+ var extensionItalic = require('@tiptap/extension-italic');
20
+ var extensionUnderline = require('@tiptap/extension-underline');
21
+ var extensionHistory = require('@tiptap/extension-history');
22
+ var extensionLink = require('@tiptap/extension-link');
23
+ var rules = require('@fastkit/rules');
24
+ var extensionOrderedList = require('@tiptap/extension-ordered-list');
16
25
  var vueScroller = require('@fastkit/vue-scroller');
17
26
 
18
27
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
@@ -28,6 +37,7 @@ const VuiControlFieldInjectionKey = Symbol();
28
37
  const VuiColorProviderInjectionKey = Symbol();
29
38
  const VUI_TEXT_FIELD_SYMBOL = 'vui-text-field';
30
39
  const VUI_TEXTAREA_SYMBOL = 'vui-textarea';
40
+ const VUI_WYSIWYG_EDITOR_SYMBOL = 'vui-wysiwyg-editor';
31
41
  const VUI_SELECT_SYMBOL = 'vui-select';
32
42
  const VUI_OPTION_SYMBOL = 'vui-option';
33
43
  const VUI_CHECKBOX_GROUP_SYMBOL = 'vui-checkbox-group';
@@ -529,7 +539,13 @@ const VButtonGroup = vue.defineComponent({
529
539
  setup(props, ctx) {
530
540
  return () => {
531
541
  let buttonLength = 0;
532
- const children = (vueUtils.renderSlotOrEmpty(ctx.slots) || []).map(node => {
542
+ let tmp = vueUtils.renderSlotOrEmpty(ctx.slots) || [];
543
+
544
+ if (tmp.length === 1 && vueUtils.isFragment(tmp[0])) {
545
+ tmp = tmp[0].children;
546
+ }
547
+
548
+ const children = tmp.map(node => {
533
549
  if (!vue.isVNode(node) || node.type !== VButton) {
534
550
  return {
535
551
  isButton: false,
@@ -542,16 +558,7 @@ const VButtonGroup = vue.defineComponent({
542
558
  isButton: true,
543
559
  node
544
560
  };
545
- }); // const children = renderSlotOrEmpty(ctx.slots) || [];
546
- // const $children = children.map((child) => {
547
- // if (!isVNode(child) || child.type !== VButton) return child;
548
- // const $child = cloneVNode(child, {
549
- // ...props,
550
- // ...child.props,
551
- // });
552
- // return $child;
553
- // });
554
-
561
+ });
555
562
  let buttonIndex = 0;
556
563
  const $children = children.map(child => {
557
564
  if (child.isButton) {
@@ -579,7 +586,7 @@ const VButtonGroup = vue.defineComponent({
579
586
 
580
587
  });
581
588
 
582
- function _isSlot$c(s) {
589
+ function _isSlot$d(s) {
583
590
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
584
591
  }
585
592
 
@@ -827,7 +834,7 @@ const VPagination = vue.defineComponent({
827
834
  "class": classes,
828
835
  "to": to,
829
836
  "key": key
830
- }, _isSlot$c(children) ? children : {
837
+ }, _isSlot$d(children) ? children : {
831
838
  default: () => [children]
832
839
  });
833
840
  } else {
@@ -982,7 +989,7 @@ const VDrawerLayout = vue.defineComponent({
982
989
 
983
990
  });
984
991
 
985
- function _isSlot$b(s) {
992
+ function _isSlot$c(s) {
986
993
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
987
994
  }
988
995
 
@@ -1017,7 +1024,7 @@ const VHero = vue.defineComponent({
1017
1024
  }, {
1018
1025
  default: () => [vue.createVNode(HTagName, {
1019
1026
  "class": "v-hero__title"
1020
- }, _isSlot$b(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1027
+ }, _isSlot$c(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1021
1028
  default: () => [_slot]
1022
1029
  })]
1023
1030
  })]
@@ -1027,7 +1034,7 @@ const VHero = vue.defineComponent({
1027
1034
 
1028
1035
  });
1029
1036
 
1030
- function _isSlot$a(s) {
1037
+ function _isSlot$b(s) {
1031
1038
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1032
1039
  }
1033
1040
 
@@ -1062,7 +1069,7 @@ function renderNavigationItemInput(input, extraProps) {
1062
1069
  } = resolveNavigationItemInput(input);
1063
1070
  return vue.createVNode(VNavigationItem, { ...props,
1064
1071
  ...extraProps
1065
- }, _isSlot$a(label) ? label : {
1072
+ }, _isSlot$b(label) ? label : {
1066
1073
  default: () => [label]
1067
1074
  });
1068
1075
  }
@@ -1215,7 +1222,7 @@ const VNavigationItem = vue.defineComponent({
1215
1222
  "class": ['v-navigation-item', classes.value],
1216
1223
  "onClick": onClick,
1217
1224
  "onChangeActive": onChangeActive
1218
- }), _isSlot$a(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1225
+ }), _isSlot$b(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1219
1226
  default: () => [_slot]
1220
1227
  }), _children && vue.createVNode(vueUtils.VExpandTransition, null, {
1221
1228
  default: () => [vue.withDirectives(vue.createVNode("div", {
@@ -1395,7 +1402,7 @@ const VCheckbox = vue.defineComponent({
1395
1402
 
1396
1403
  });
1397
1404
 
1398
- function _isSlot$9(s) {
1405
+ function _isSlot$a(s) {
1399
1406
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1400
1407
  }
1401
1408
 
@@ -1407,7 +1414,7 @@ const VCheckboxGroup = defineFormSelectorComponent({
1407
1414
  itemRenderer: ({
1408
1415
  attrs,
1409
1416
  slots
1410
- }) => vue.createVNode(VCheckbox, attrs, _isSlot$9(slots) ? slots : {
1417
+ }) => vue.createVNode(VCheckbox, attrs, _isSlot$a(slots) ? slots : {
1411
1418
  default: () => [slots]
1412
1419
  })
1413
1420
  });
@@ -1459,7 +1466,7 @@ const VRadio = vue.defineComponent({
1459
1466
 
1460
1467
  });
1461
1468
 
1462
- function _isSlot$8(s) {
1469
+ function _isSlot$9(s) {
1463
1470
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1464
1471
  }
1465
1472
 
@@ -1470,7 +1477,7 @@ const VRadioGroup = defineFormSelectorComponent({
1470
1477
  itemRenderer: ({
1471
1478
  attrs,
1472
1479
  slots
1473
- }) => vue.createVNode(VRadio, attrs, _isSlot$8(slots) ? slots : {
1480
+ }) => vue.createVNode(VRadio, attrs, _isSlot$9(slots) ? slots : {
1474
1481
  default: () => [slots]
1475
1482
  })
1476
1483
  });
@@ -1532,7 +1539,7 @@ const VSwitch = vue.defineComponent({
1532
1539
 
1533
1540
  });
1534
1541
 
1535
- function _isSlot$7(s) {
1542
+ function _isSlot$8(s) {
1536
1543
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1537
1544
  }
1538
1545
 
@@ -1544,7 +1551,7 @@ const VSwitchGroup = defineFormSelectorComponent({
1544
1551
  itemRenderer: ({
1545
1552
  attrs,
1546
1553
  slots
1547
- }) => vue.createVNode(VSwitch, attrs, _isSlot$7(slots) ? slots : {
1554
+ }) => vue.createVNode(VSwitch, attrs, _isSlot$8(slots) ? slots : {
1548
1555
  default: () => [slots]
1549
1556
  })
1550
1557
  });
@@ -1927,15 +1934,20 @@ const {
1927
1934
  props: props$2,
1928
1935
  emits: emits$2
1929
1936
  } = vueKit.createTextInputSettings();
1930
- const VTextField = vue.defineComponent({
1931
- name: 'VTextField',
1932
- props: { ...props$2,
1937
+
1938
+ function createTextFieldProps() {
1939
+ return { ...props$2,
1933
1940
  ...vueKit.createFormControlProps(),
1934
1941
  ...createControlFieldProps(),
1935
1942
  ...createControlFieldProviderProps(),
1936
1943
  ...createControlProps(),
1937
1944
  ...vueKit.defineSlotsProps()
1938
- },
1945
+ };
1946
+ }
1947
+
1948
+ const VTextField = vue.defineComponent({
1949
+ name: 'VTextField',
1950
+ props: createTextFieldProps(),
1939
1951
  emits: emits$2,
1940
1952
 
1941
1953
  setup(props, ctx) {
@@ -2044,86 +2056,377 @@ const VTextarea = vue.defineComponent({
2044
2056
 
2045
2057
  });
2046
2058
 
2059
+ function resolveRawWysiwygEditorTool(raw, vui) {
2060
+ return typeof raw === 'function' ? raw(vui) : raw;
2061
+ }
2062
+ function resolveRawWysiwygEditorTools(raws, vui) {
2063
+ const tools = [];
2064
+ const extensions = [];
2065
+ raws.forEach((raw) => {
2066
+ let resolved = resolveRawWysiwygEditorTool(raw, vui);
2067
+ if (!Array.isArray(resolved)) {
2068
+ resolved = [resolved];
2069
+ }
2070
+ resolved.forEach((tool) => {
2071
+ tools.push(tool);
2072
+ if (tool.extensions) {
2073
+ extensions.push(...tool.extensions);
2074
+ }
2075
+ });
2076
+ });
2077
+ return {
2078
+ tools,
2079
+ extensions,
2080
+ };
2081
+ }
2082
+
2083
+ function _isSlot$7(s) {
2084
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2085
+ }
2086
+
2047
2087
  const VWysiwygEditor = vue.defineComponent({
2048
2088
  name: 'VWysiwygEditor',
2049
2089
  props: { // ...props,
2090
+ ...vueFormControl.createTextableProps(),
2050
2091
  ...vueKit.createFormControlProps(),
2051
2092
  ...createControlFieldProps(),
2052
2093
  ...createControlFieldProviderProps(),
2053
2094
  ...createControlProps(),
2054
- ...vueKit.defineSlotsProps()
2095
+ ...vueKit.defineSlotsProps(),
2096
+ tools: {
2097
+ type: Array,
2098
+ default: () => []
2099
+ }
2100
+ },
2101
+ emits: { ...vueFormControl.createTextableEmits()
2055
2102
  },
2056
2103
 
2057
- // emits,
2058
2104
  setup(props, ctx) {
2105
+ const vui = useVui();
2106
+ const textRef = vue.ref('');
2107
+ const toolButtonActiveColor = vui.setting('primaryScope');
2108
+ const wysiwygSettings = vue.computed(() => resolveRawWysiwygEditorTools(props.tools, vui));
2109
+ const control = useControl(props);
2110
+ useControlField(props);
2111
+ const inputControl = new vueFormControl.TextableControl(props, ctx, {
2112
+ nodeType: VUI_WYSIWYG_EDITOR_SYMBOL,
2113
+ validationValue: () => textRef.value
2114
+ });
2115
+ const extensions = [StarterKit__default.configure({
2116
+ bold: false,
2117
+ bulletList: false,
2118
+ orderedList: false,
2119
+ history: false,
2120
+ italic: false
2121
+ }), ...wysiwygSettings.value.extensions];
2122
+
2123
+ const updateEditable = () => {
2124
+ if (!editor.value) return;
2125
+ editor.value.setEditable(inputControl.canOperation);
2126
+ };
2127
+
2128
+ vue.watch(() => inputControl.canOperation, updateEditable);
2059
2129
  const editor = vue3.useEditor({
2060
- content: '<p>I’m running Tiptap with Vue.js. 🎉</p>',
2061
- extensions: [StarterKit__default]
2062
- }); // const vui = useVui();
2063
- // const inputControl = useTiptapControl(props, ctx, {
2064
- // nodeType: VUI_TEXTAREA_SYMBOL,
2065
- // defaultRows: vui.tiptapRows,
2066
- // });
2067
- // const control = useControl(props);
2068
- // useControlField(props);
2130
+ onCreate: ({
2131
+ editor
2132
+ }) => {
2133
+ textRef.value = editor.getText();
2134
+ updateEditable();
2135
+ },
2136
+ onFocus: ctx => {
2137
+ inputControl.focusHandler(ctx.event);
2138
+ },
2139
+ onBlur: ctx => {
2140
+ inputControl.blurHandler(ctx.event);
2141
+ },
2142
+ onUpdate: ev => {
2143
+ inputControl.value = ev.editor.getHTML();
2144
+ textRef.value = ev.editor.getText();
2145
+ },
2146
+ autofocus: props.autofocus,
2147
+ content: props.modelValue,
2148
+ extensions,
2149
+ editorProps: {
2150
+ attributes: {
2151
+ class: 'v-wysiwyg-editor__input__prose'
2152
+ }
2153
+ }
2154
+ });
2069
2155
 
2070
- return {
2071
- editor // ...inputControl.expose(),
2072
- // ...control,
2156
+ const focus = (position, options) => {
2157
+ return editor.value.chain().focus(position, options);
2158
+ };
2073
2159
 
2160
+ const blur = () => {
2161
+ return editor.value.chain().blur();
2162
+ };
2163
+
2164
+ const wysiwygContext = vue.computed(() => ({
2165
+ vui,
2166
+ editor: editor.value
2167
+ }));
2168
+
2169
+ const createTools = (floating = false) => {
2170
+ let _slot;
2171
+
2172
+ const {
2173
+ value: settings
2174
+ } = wysiwygSettings;
2175
+ const {
2176
+ value: context
2177
+ } = wysiwygContext;
2178
+ const tools = floating ? settings.tools.filter(t => !!t.floating) : settings.tools;
2179
+ const _editor = editor.value;
2180
+ const variant = vui.setting(floating ? 'containedVariant' : 'plainVariant');
2181
+ return vue.createVNode(VButtonGroup, {
2182
+ "variant": variant
2183
+ }, _isSlot$7(_slot = tools.map(({
2184
+ key,
2185
+ icon,
2186
+ onClick,
2187
+ disabled,
2188
+ active
2189
+ }) => {
2190
+ const isActive = !!_editor && resolveContextableValue(context, active);
2191
+ const isDisabled = !inputControl.canOperation || !!_editor && resolveContextableValue(context, disabled);
2192
+ let iconName;
2193
+
2194
+ if (typeof icon === 'function') {
2195
+ if (_editor) {
2196
+ iconName = icon(context);
2197
+ }
2198
+ } else {
2199
+ iconName = icon;
2200
+ }
2201
+
2202
+ if (!iconName) return;
2203
+ return vue.createVNode(VButton, {
2204
+ "key": key,
2205
+ "icon": iconName,
2206
+ "onClick": ev => onClick(context, ev),
2207
+ "color": isActive ? toolButtonActiveColor : undefined,
2208
+ "disabled": isDisabled
2209
+ }, null);
2210
+ })) ? _slot : {
2211
+ default: () => [_slot]
2212
+ });
2213
+ };
2214
+
2215
+ return {
2216
+ editor,
2217
+ ...inputControl.expose(),
2218
+ ...control,
2219
+ focus,
2220
+ blur,
2221
+ createTools
2074
2222
  };
2075
2223
  },
2076
2224
 
2077
2225
  render() {
2078
2226
  return vue.createVNode(VFormControl, {
2079
2227
  "nodeControl": this.nodeControl,
2228
+ "focused": this.nodeControl.focused,
2229
+ "class": ['v-wysiwyg-editor', this.classes],
2080
2230
  "label": this.label,
2081
2231
  "hint": this.hint,
2082
2232
  "hiddenInfo": this.hiddenInfo,
2083
- "onClickLabel": ev => {// this.focus();
2233
+ "onClickLabel": ev => {
2234
+ this.focus('start', {
2235
+ scrollIntoView: true
2236
+ });
2084
2237
  }
2085
2238
  }, { ...this.$slots,
2086
- default: () => vue.createVNode(VControlField, {
2087
- "class": "v-wysiwyg-editor__input",
2088
- "autoHeight": true,
2089
- "startAdornment": this.startAdornment,
2090
- "endAdornment": this.endAdornment
2091
- }, { ...this.$slots,
2092
- default: () => {
2093
- const {
2094
- editor
2095
- } = this;
2096
- return vue.createVNode(vue.Fragment, null, [vue.createVNode(vue3.EditorContent, {
2097
- "class": "v-wysiwyg-editor__input__element wysiwyg",
2098
- "editor": editor
2099
- }, null), !!editor && vue.createVNode(vue3.BubbleMenu, {
2100
- "class": "v-wysiwyg-editor__bubble-menu",
2101
- "editor": editor
2102
- }, {
2103
- default: () => [vue.createVNode(VButton, {
2104
- "size": "sm",
2105
- "onClick": () => {
2106
- editor.chain().focus().toggleBold().run();
2107
- }
2108
- }, {
2109
- default: () => [vue.createTextVNode("Bold")]
2110
- })]
2111
- })]);
2112
- } // this.tiptapControl.createInputElement({
2113
- // class: 'v-wysiwyg-editor__input__element',
2114
- // }),
2115
-
2116
- }) // infoAppends: () => {
2117
- // const { counterResult } = this;
2118
- // if (!counterResult) return;
2119
- // return <VTextCounter {...counterResult} />;
2120
- // },
2121
-
2239
+ default: () => {
2240
+ const {
2241
+ editor
2242
+ } = this;
2243
+ return vue.createVNode(vue.Fragment, null, [!this.isReadonly && this.createTools(), vue.createVNode(VControlField, {
2244
+ "class": "v-wysiwyg-editor__input",
2245
+ "autoHeight": true,
2246
+ "startAdornment": this.startAdornment,
2247
+ "endAdornment": this.endAdornment
2248
+ }, { ...this.$slots,
2249
+ default: () => {
2250
+ let _slot2;
2251
+
2252
+ return vue.createVNode(vue.Fragment, null, [vue.createVNode(vue3.EditorContent, {
2253
+ "class": "v-wysiwyg-editor__input__element wysiwyg",
2254
+ "editor": editor
2255
+ }, null), !!editor && !this.isReadonly && vue.createVNode(vue3.BubbleMenu, {
2256
+ "class": "v-wysiwyg-editor__bubble-menu",
2257
+ "editor": editor
2258
+ }, _isSlot$7(_slot2 = this.createTools(true)) ? _slot2 : {
2259
+ default: () => [_slot2]
2260
+ })]);
2261
+ }
2262
+ })]);
2263
+ },
2264
+ infoAppends: () => {
2265
+ const {
2266
+ counterResult
2267
+ } = this;
2268
+ if (!counterResult) return;
2269
+ return vue.createVNode(VTextCounter, counterResult, null);
2270
+ }
2122
2271
  });
2123
2272
  }
2124
2273
 
2125
2274
  });
2126
2275
 
2276
+ function resolveContextableValue(ctx, source) {
2277
+ return typeof source === 'function' ? source(ctx) : source;
2278
+ }
2279
+
2280
+ const WysiwygBulletListTool = (vui, options) => {
2281
+ const tool = {
2282
+ key: 'bulletList',
2283
+ icon: vui.icon('editorformatListBulleted'),
2284
+ active: ({ editor }) => editor.isActive('bulletList'),
2285
+ onClick: ({ editor }) => {
2286
+ editor.chain().focus().toggleBulletList().run();
2287
+ },
2288
+ floating: true,
2289
+ extensions: [extensionBulletList.BulletList.configure(options)],
2290
+ };
2291
+ return tool;
2292
+ };
2293
+
2294
+ const WysiwygFormatBoldTool = (vui, options) => {
2295
+ const tool = {
2296
+ key: 'formatBold',
2297
+ icon: vui.icon('editorformatBold'),
2298
+ active: ({ editor }) => editor.isActive('bold'),
2299
+ onClick: ({ editor }) => {
2300
+ editor.chain().focus().toggleBold().run();
2301
+ },
2302
+ floating: true,
2303
+ extensions: [extensionBold.Bold.configure(options)],
2304
+ };
2305
+ return tool;
2306
+ };
2307
+
2308
+ const WysiwygFormatItalicTool = (vui, options) => {
2309
+ const tool = {
2310
+ key: 'formatItalic',
2311
+ icon: vui.icon('editorformatItalic'),
2312
+ active: ({ editor }) => editor.isActive('italic'),
2313
+ onClick: ({ editor }) => {
2314
+ editor.chain().focus().toggleItalic().run();
2315
+ },
2316
+ floating: true,
2317
+ extensions: [extensionItalic.Italic.configure(options)],
2318
+ };
2319
+ return tool;
2320
+ };
2321
+
2322
+ const WysiwygFormatUnderlineTool = (vui, options) => {
2323
+ const tool = {
2324
+ key: 'formatUnderline',
2325
+ icon: vui.icon('editorformatUnderline'),
2326
+ active: ({ editor }) => editor.isActive('underline'),
2327
+ onClick: ({ editor }) => {
2328
+ editor.chain().focus().toggleUnderline().run();
2329
+ },
2330
+ floating: true,
2331
+ extensions: [extensionUnderline.Underline.configure(options)],
2332
+ };
2333
+ return tool;
2334
+ };
2335
+
2336
+ const WysiwygHistoryTool = (vui, options) => {
2337
+ const undo = {
2338
+ key: 'history-undo',
2339
+ icon: vui.icon('editorUndo'),
2340
+ disabled: ({ editor }) => !editor.can().undo(),
2341
+ onClick: ({ editor }) => {
2342
+ editor.chain().focus().undo().run();
2343
+ },
2344
+ extensions: [extensionHistory.History.configure(options)],
2345
+ };
2346
+ const redo = {
2347
+ key: 'history-redo',
2348
+ icon: vui.icon('editorRedo'),
2349
+ disabled: ({ editor }) => !editor.can().redo(),
2350
+ onClick: ({ editor }) => {
2351
+ editor.chain().focus().redo().run();
2352
+ },
2353
+ };
2354
+ return [undo, redo];
2355
+ };
2356
+
2357
+ const WysiwygLinkTool = (vui, options) => {
2358
+ const tool = {
2359
+ key: 'link',
2360
+ icon: ({ editor }) => {
2361
+ return vui.icon(editor.isActive('link') ? 'editorLinkOff' : 'editorLink');
2362
+ },
2363
+ // icon: vui.icon('editorLink'),
2364
+ active: ({ editor }) => editor.isActive('link'),
2365
+ onClick: async ({ vui, editor }) => {
2366
+ const { href = '' } = editor.getAttributes('link');
2367
+ const result = await vui.prompt({
2368
+ input: {
2369
+ label: 'Link URL',
2370
+ rules: [rules.validateIf, rules.url],
2371
+ initialValue: href,
2372
+ size: 'sm',
2373
+ autofocus: true,
2374
+ },
2375
+ });
2376
+ if (result === undefined || result === false) {
2377
+ return;
2378
+ }
2379
+ const range = editor.chain().focus().extendMarkRange('link');
2380
+ console.log(range);
2381
+ if (!result) {
2382
+ range.unsetLink().run();
2383
+ }
2384
+ else {
2385
+ range
2386
+ .setLink({
2387
+ href: result,
2388
+ })
2389
+ .run();
2390
+ }
2391
+ },
2392
+ floating: true,
2393
+ extensions: [
2394
+ extensionLink.Link.configure({
2395
+ openOnClick: false,
2396
+ ...options,
2397
+ }),
2398
+ ],
2399
+ };
2400
+ return tool;
2401
+ };
2402
+
2403
+ const WysiwygOrderedListTool = (vui, options) => {
2404
+ const tool = {
2405
+ key: 'orderedList',
2406
+ icon: vui.icon('editorformatListNumbered'),
2407
+ active: ({ editor }) => editor.isActive('orderedList'),
2408
+ onClick: ({ editor }) => {
2409
+ editor.chain().focus().toggleOrderedList().run();
2410
+ },
2411
+ floating: true,
2412
+ extensions: [extensionOrderedList.OrderedList.configure(options)],
2413
+ };
2414
+ return tool;
2415
+ };
2416
+
2417
+ const WysiwygTextColorTool = (vui) => {
2418
+ const tool = {
2419
+ key: 'textColor',
2420
+ icon: vui.icon('editorTextColor'),
2421
+ // icon: (gen) => vui.icon('editorTextColor'),
2422
+ onClick: (ctx) => {
2423
+ ctx.vui.alert('ok');
2424
+ },
2425
+ floating: true,
2426
+ };
2427
+ return tool;
2428
+ };
2429
+
2127
2430
  const {
2128
2431
  props,
2129
2432
  emits
@@ -2134,7 +2437,8 @@ const VForm = vue.defineComponent({
2134
2437
  name: 'VForm',
2135
2438
  props: { ...props,
2136
2439
  ...createControlProps(),
2137
- ...vueKit.defineSlotsProps()
2440
+ ...vueKit.defineSlotsProps(),
2441
+ disableAutoScroll: Boolean
2138
2442
  },
2139
2443
  emits,
2140
2444
 
@@ -2143,6 +2447,7 @@ const VForm = vue.defineComponent({
2143
2447
  const nodeControl = vueKit.useForm(props, ctx, {
2144
2448
  nodeType: VUI_FORM_SYMBOL,
2145
2449
  onAutoValidateError: () => {
2450
+ if (props.disableAutoScroll) return;
2146
2451
  const scroller = vueKit.getDocumentScroller();
2147
2452
  const {
2148
2453
  firstInvalidEl
@@ -3534,53 +3839,138 @@ const VToolbarTitle = vue.defineComponent({
3534
3839
 
3535
3840
  });
3536
3841
 
3537
- const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3538
- const DEFAULT_TEXTAREA_ROWS = 3;
3539
- class VuiService {
3540
- options;
3541
- selectionSeparator;
3542
- autoScrollToElementOffsetTop;
3543
- textareaRows;
3544
- requiredChip;
3545
- router;
3546
- location;
3547
- constructor(options) {
3548
- this.options = options;
3549
- this.configure();
3550
- const { selectionSeparator = () => ', ', autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP, textareaRows = DEFAULT_TEXTAREA_ROWS, requiredChip = () => '*', } = options;
3551
- this.selectionSeparator = selectionSeparator;
3552
- this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3553
- this.textareaRows = textareaRows;
3554
- this.requiredChip = requiredChip;
3555
- this.router = options.router;
3556
- this.location = new vueUtils.LocationService({
3557
- router: this.router,
3558
- });
3559
- }
3560
- configure(options) {
3561
- options && Object.assign(this.options, options);
3562
- vueUtils.setDefaultRouterLink(this.getRouterLink());
3563
- }
3564
- getRouterLink() {
3565
- return this.options.RouterLink || vueRouter.RouterLink;
3566
- }
3567
- setting(key) {
3568
- return this.options.uiSettings[key];
3569
- }
3570
- icon(iconType) {
3571
- return this.options.icons[iconType];
3572
- }
3573
- getAutoScrollToElementOffsetTop() {
3574
- let { autoScrollToElementOffsetTop } = this;
3575
- if (typeof autoScrollToElementOffsetTop === 'function') {
3576
- autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3577
- }
3578
- return autoScrollToElementOffsetTop || 0;
3579
- }
3580
- getRequiredChip() {
3581
- const { requiredChip } = this;
3582
- return requiredChip && requiredChip();
3583
- }
3842
+ const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3843
+ const DEFAULT_TEXTAREA_ROWS = 3;
3844
+ class VuiService {
3845
+ constructor(options, stackService) {
3846
+ this.options = options;
3847
+ this.configure();
3848
+ const {
3849
+ selectionSeparator = () => ', ',
3850
+ autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP,
3851
+ textareaRows = DEFAULT_TEXTAREA_ROWS,
3852
+ requiredChip = () => '*'
3853
+ } = options;
3854
+ this.selectionSeparator = selectionSeparator;
3855
+ this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3856
+ this.textareaRows = textareaRows;
3857
+ this.requiredChip = requiredChip;
3858
+ this.router = options.router;
3859
+ this.location = new vueUtils.LocationService({
3860
+ router: this.router
3861
+ });
3862
+ this.stack = stackService;
3863
+ }
3864
+
3865
+ configure(options) {
3866
+ options && Object.assign(this.options, options);
3867
+ vueUtils.setDefaultRouterLink(this.getRouterLink());
3868
+ }
3869
+
3870
+ getRouterLink() {
3871
+ return this.options.RouterLink || vueRouter.RouterLink;
3872
+ }
3873
+
3874
+ setting(key) {
3875
+ return this.options.uiSettings[key];
3876
+ }
3877
+
3878
+ icon(iconType) {
3879
+ return this.options.icons[iconType];
3880
+ }
3881
+
3882
+ getAutoScrollToElementOffsetTop() {
3883
+ let {
3884
+ autoScrollToElementOffsetTop
3885
+ } = this;
3886
+
3887
+ if (typeof autoScrollToElementOffsetTop === 'function') {
3888
+ autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3889
+ }
3890
+
3891
+ return autoScrollToElementOffsetTop || 0;
3892
+ }
3893
+
3894
+ getRequiredChip() {
3895
+ const {
3896
+ requiredChip
3897
+ } = this;
3898
+ return requiredChip && requiredChip();
3899
+ }
3900
+
3901
+ dialog(...args) {
3902
+ return this.stack.dialog(...args);
3903
+ }
3904
+
3905
+ alert(...args) {
3906
+ return this.stack.alert(...args);
3907
+ }
3908
+
3909
+ confirm(...args) {
3910
+ return this.stack.confirm(...args);
3911
+ }
3912
+
3913
+ snackbar(...args) {
3914
+ return this.stack.snackbar(...args);
3915
+ }
3916
+
3917
+ prompt(rawOptions = {}) {
3918
+ const options = typeof rawOptions === 'string' ? {
3919
+ input: {
3920
+ label: rawOptions
3921
+ }
3922
+ } : { ...rawOptions
3923
+ };
3924
+ options.input = { ...options.input
3925
+ };
3926
+ options.dense = true;
3927
+ let {
3928
+ initialValue: value = ''
3929
+ } = options.input;
3930
+ const {
3931
+ size
3932
+ } = options.input;
3933
+ delete options.input.initialValue;
3934
+ let form;
3935
+ options.actions = options.actions || [this.stack.action('cancel', undefined, {
3936
+ size
3937
+ }), this.stack.action('ok', undefined, {
3938
+ size,
3939
+ onClick: () => {
3940
+ if (form) {
3941
+ const ev = new Event('submit');
3942
+ form.handleSubmit(ev);
3943
+ }
3944
+ }
3945
+ })];
3946
+ const resolved = vueKit.resolveVStackDynamicInput({ ...options,
3947
+ content: stack => {
3948
+ return vue.createVNode(VForm, {
3949
+ "disableAutoScroll": true,
3950
+ "size": size,
3951
+ "onVnodeMounted": vnode => {
3952
+ form = vnode.component.ctx.form;
3953
+ },
3954
+ "onVnodeBeforeUnmount": () => {
3955
+ form = undefined;
3956
+ },
3957
+ "onSubmit": ev => {
3958
+ stack.resolve(value);
3959
+ }
3960
+ }, {
3961
+ default: () => [vue.createVNode(VTextField, vue.mergeProps(options.input, {
3962
+ "modelValue": value,
3963
+ "onChange": ev => {
3964
+ stack.value = ev;
3965
+ value = ev;
3966
+ }
3967
+ }), null)]
3968
+ });
3969
+ }
3970
+ });
3971
+ return this.dialog(resolved);
3972
+ }
3973
+
3584
3974
  }
3585
3975
 
3586
3976
  class VuiPlugin {
@@ -3624,7 +4014,7 @@ class VuiPlugin {
3624
4014
  ...stack
3625
4015
  }); // Vui
3626
4016
 
3627
- const $vui = new VuiService(opts);
4017
+ const $vui = new VuiService(opts, app.config.globalProperties.$vstack);
3628
4018
  app.provide(VuiInjectionKey, $vui);
3629
4019
  app.config.globalProperties.$vui = $vui;
3630
4020
 
@@ -3692,6 +4082,7 @@ exports.VUI_SWITCH_GROUP_SYMBOL = VUI_SWITCH_GROUP_SYMBOL;
3692
4082
  exports.VUI_SWITCH_SYMBOL = VUI_SWITCH_SYMBOL;
3693
4083
  exports.VUI_TEXTAREA_SYMBOL = VUI_TEXTAREA_SYMBOL;
3694
4084
  exports.VUI_TEXT_FIELD_SYMBOL = VUI_TEXT_FIELD_SYMBOL;
4085
+ exports.VUI_WYSIWYG_EDITOR_SYMBOL = VUI_WYSIWYG_EDITOR_SYMBOL;
3695
4086
  exports.VWysiwygEditor = VWysiwygEditor;
3696
4087
  exports.VuiColorProviderInjectionKey = VuiColorProviderInjectionKey;
3697
4088
  exports.VuiControlFieldInjectionKey = VuiControlFieldInjectionKey;
@@ -3699,6 +4090,14 @@ exports.VuiControlInjectionKey = VuiControlInjectionKey;
3699
4090
  exports.VuiInjectionKey = VuiInjectionKey;
3700
4091
  exports.VuiPlugin = VuiPlugin;
3701
4092
  exports.VuiService = VuiService;
4093
+ exports.WysiwygBulletListTool = WysiwygBulletListTool;
4094
+ exports.WysiwygFormatBoldTool = WysiwygFormatBoldTool;
4095
+ exports.WysiwygFormatItalicTool = WysiwygFormatItalicTool;
4096
+ exports.WysiwygFormatUnderlineTool = WysiwygFormatUnderlineTool;
4097
+ exports.WysiwygHistoryTool = WysiwygHistoryTool;
4098
+ exports.WysiwygLinkTool = WysiwygLinkTool;
4099
+ exports.WysiwygOrderedListTool = WysiwygOrderedListTool;
4100
+ exports.WysiwygTextColorTool = WysiwygTextColorTool;
3702
4101
  exports.configureDataTableDefaults = configureDataTableDefaults;
3703
4102
  exports.createCardProps = createCardProps;
3704
4103
  exports.createControlFieldProviderProps = createControlFieldProviderProps;