@fastkit/vui 0.6.33 → 0.6.37

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,31 @@
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');
15
+ var vue3 = require('@tiptap/vue-3');
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');
14
25
  var vueScroller = require('@fastkit/vue-scroller');
15
26
 
27
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
28
+
29
+ var StarterKit__default = /*#__PURE__*/_interopDefaultLegacy(StarterKit);
30
+
16
31
  const CONTROL_SIZES = ['sm', 'md', 'lg'];
17
32
  const CONTROL_FIELD_VARIANTS = ['outlined', 'filled', 'flat'];
18
33
 
@@ -22,6 +37,7 @@ const VuiControlFieldInjectionKey = Symbol();
22
37
  const VuiColorProviderInjectionKey = Symbol();
23
38
  const VUI_TEXT_FIELD_SYMBOL = 'vui-text-field';
24
39
  const VUI_TEXTAREA_SYMBOL = 'vui-textarea';
40
+ const VUI_WYSIWYG_EDITOR_SYMBOL = 'vui-wysiwyg-editor';
25
41
  const VUI_SELECT_SYMBOL = 'vui-select';
26
42
  const VUI_OPTION_SYMBOL = 'vui-option';
27
43
  const VUI_CHECKBOX_GROUP_SYMBOL = 'vui-checkbox-group';
@@ -479,8 +495,10 @@ const VButton = vue.defineComponent({
479
495
  });
480
496
  const isPlain = vue.computed(() => color.variant.value.value === vui.setting('plainVariant') && color.color.value.value === defaults.color);
481
497
  const isLoading = vue.computed(() => props.loading); // const isDisabled = computed(() => props.disabled);
498
+ // const isRounded = computed(() =>
499
+ // props.rounded != null ? props.rounded : !!icon.value,
500
+ // );
482
501
 
483
- const isRounded = vue.computed(() => props.rounded || !!icon.value);
484
502
  const spacer = vue.computed(() => {
485
503
  const _spacer = props.spacer;
486
504
  if (!_spacer) return;
@@ -490,7 +508,7 @@ const VButton = vue.defineComponent({
490
508
  spacer.value ? `v-button--spacer-${spacer.value}` : undefined, `v-button--${control.size.value}`, {
491
509
  'v-button--loading': isLoading.value,
492
510
  'v-button--icon': !!icon.value,
493
- 'v-button--rounded': isRounded.value,
511
+ 'v-button--rounded': props.rounded,
494
512
  'v-button--plain': isPlain.value
495
513
  }]);
496
514
  return () => {
@@ -511,7 +529,64 @@ const VButton = vue.defineComponent({
511
529
 
512
530
  });
513
531
 
514
- function _isSlot$c(s) {
532
+ const VButtonGroup = vue.defineComponent({
533
+ name: 'VButtonGroup',
534
+ props: { ...vueColorScheme.colorSchemeProps(),
535
+ ...createControlProps(),
536
+ disabled: Boolean
537
+ },
538
+
539
+ setup(props, ctx) {
540
+ return () => {
541
+ let buttonLength = 0;
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 => {
549
+ if (!vue.isVNode(node) || node.type !== VButton) {
550
+ return {
551
+ isButton: false,
552
+ node
553
+ };
554
+ }
555
+
556
+ buttonLength++;
557
+ return {
558
+ isButton: true,
559
+ node
560
+ };
561
+ });
562
+ let buttonIndex = 0;
563
+ const $children = children.map(child => {
564
+ if (child.isButton) {
565
+ buttonIndex++;
566
+ const hasLeft = buttonIndex > 1;
567
+ const hasRight = buttonIndex < buttonLength;
568
+ const childProps = child.node.props;
569
+ return vue.cloneVNode(child.node, { ...props,
570
+ ...childProps,
571
+ rouded: false,
572
+ class: ['v-button-group__item', {
573
+ 'v-button-group__item--has-left': hasLeft,
574
+ 'v-button-group__item--has-right': hasRight
575
+ }]
576
+ });
577
+ }
578
+
579
+ return child.node;
580
+ });
581
+ return vue.createVNode("div", {
582
+ "class": "v-button-group"
583
+ }, [$children]);
584
+ };
585
+ }
586
+
587
+ });
588
+
589
+ function _isSlot$d(s) {
515
590
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
516
591
  }
517
592
 
@@ -759,7 +834,7 @@ const VPagination = vue.defineComponent({
759
834
  "class": classes,
760
835
  "to": to,
761
836
  "key": key
762
- }, _isSlot$c(children) ? children : {
837
+ }, _isSlot$d(children) ? children : {
763
838
  default: () => [children]
764
839
  });
765
840
  } else {
@@ -914,7 +989,7 @@ const VDrawerLayout = vue.defineComponent({
914
989
 
915
990
  });
916
991
 
917
- function _isSlot$b(s) {
992
+ function _isSlot$c(s) {
918
993
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
919
994
  }
920
995
 
@@ -949,7 +1024,7 @@ const VHero = vue.defineComponent({
949
1024
  }, {
950
1025
  default: () => [vue.createVNode(HTagName, {
951
1026
  "class": "v-hero__title"
952
- }, _isSlot$b(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1027
+ }, _isSlot$c(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
953
1028
  default: () => [_slot]
954
1029
  })]
955
1030
  })]
@@ -959,7 +1034,7 @@ const VHero = vue.defineComponent({
959
1034
 
960
1035
  });
961
1036
 
962
- function _isSlot$a(s) {
1037
+ function _isSlot$b(s) {
963
1038
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
964
1039
  }
965
1040
 
@@ -994,7 +1069,7 @@ function renderNavigationItemInput(input, extraProps) {
994
1069
  } = resolveNavigationItemInput(input);
995
1070
  return vue.createVNode(VNavigationItem, { ...props,
996
1071
  ...extraProps
997
- }, _isSlot$a(label) ? label : {
1072
+ }, _isSlot$b(label) ? label : {
998
1073
  default: () => [label]
999
1074
  });
1000
1075
  }
@@ -1017,9 +1092,11 @@ const VNavigationItem = vue.defineComponent({
1017
1092
  const to = vue.computed(() => ctx.attrs.to);
1018
1093
  const match = vue.computed(() => {
1019
1094
  const {
1020
- match,
1021
- to
1095
+ match
1022
1096
  } = props;
1097
+ const {
1098
+ to
1099
+ } = ctx.attrs;
1023
1100
  if (match) return match;
1024
1101
  if (!to) return;
1025
1102
  if (typeof to === 'string') return to;
@@ -1145,7 +1222,7 @@ const VNavigationItem = vue.defineComponent({
1145
1222
  "class": ['v-navigation-item', classes.value],
1146
1223
  "onClick": onClick,
1147
1224
  "onChangeActive": onChangeActive
1148
- }), _isSlot$a(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1225
+ }), _isSlot$b(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1149
1226
  default: () => [_slot]
1150
1227
  }), _children && vue.createVNode(vueUtils.VExpandTransition, null, {
1151
1228
  default: () => [vue.withDirectives(vue.createVNode("div", {
@@ -1325,7 +1402,7 @@ const VCheckbox = vue.defineComponent({
1325
1402
 
1326
1403
  });
1327
1404
 
1328
- function _isSlot$9(s) {
1405
+ function _isSlot$a(s) {
1329
1406
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1330
1407
  }
1331
1408
 
@@ -1337,7 +1414,7 @@ const VCheckboxGroup = defineFormSelectorComponent({
1337
1414
  itemRenderer: ({
1338
1415
  attrs,
1339
1416
  slots
1340
- }) => vue.createVNode(VCheckbox, attrs, _isSlot$9(slots) ? slots : {
1417
+ }) => vue.createVNode(VCheckbox, attrs, _isSlot$a(slots) ? slots : {
1341
1418
  default: () => [slots]
1342
1419
  })
1343
1420
  });
@@ -1389,7 +1466,7 @@ const VRadio = vue.defineComponent({
1389
1466
 
1390
1467
  });
1391
1468
 
1392
- function _isSlot$8(s) {
1469
+ function _isSlot$9(s) {
1393
1470
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1394
1471
  }
1395
1472
 
@@ -1400,7 +1477,7 @@ const VRadioGroup = defineFormSelectorComponent({
1400
1477
  itemRenderer: ({
1401
1478
  attrs,
1402
1479
  slots
1403
- }) => vue.createVNode(VRadio, attrs, _isSlot$8(slots) ? slots : {
1480
+ }) => vue.createVNode(VRadio, attrs, _isSlot$9(slots) ? slots : {
1404
1481
  default: () => [slots]
1405
1482
  })
1406
1483
  });
@@ -1462,7 +1539,7 @@ const VSwitch = vue.defineComponent({
1462
1539
 
1463
1540
  });
1464
1541
 
1465
- function _isSlot$7(s) {
1542
+ function _isSlot$8(s) {
1466
1543
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1467
1544
  }
1468
1545
 
@@ -1474,7 +1551,7 @@ const VSwitchGroup = defineFormSelectorComponent({
1474
1551
  itemRenderer: ({
1475
1552
  attrs,
1476
1553
  slots
1477
- }) => vue.createVNode(VSwitch, attrs, _isSlot$7(slots) ? slots : {
1554
+ }) => vue.createVNode(VSwitch, attrs, _isSlot$8(slots) ? slots : {
1478
1555
  default: () => [slots]
1479
1556
  })
1480
1557
  });
@@ -1857,15 +1934,20 @@ const {
1857
1934
  props: props$2,
1858
1935
  emits: emits$2
1859
1936
  } = vueKit.createTextInputSettings();
1860
- const VTextField = vue.defineComponent({
1861
- name: 'VTextField',
1862
- props: { ...props$2,
1937
+
1938
+ function createTextFieldProps() {
1939
+ return { ...props$2,
1863
1940
  ...vueKit.createFormControlProps(),
1864
1941
  ...createControlFieldProps(),
1865
1942
  ...createControlFieldProviderProps(),
1866
1943
  ...createControlProps(),
1867
1944
  ...vueKit.defineSlotsProps()
1868
- },
1945
+ };
1946
+ }
1947
+
1948
+ const VTextField = vue.defineComponent({
1949
+ name: 'VTextField',
1950
+ props: createTextFieldProps(),
1869
1951
  emits: emits$2,
1870
1952
 
1871
1953
  setup(props, ctx) {
@@ -1974,6 +2056,396 @@ const VTextarea = vue.defineComponent({
1974
2056
 
1975
2057
  });
1976
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
+
2087
+ const VWysiwygEditor = vue.defineComponent({
2088
+ name: 'VWysiwygEditor',
2089
+ props: { // ...props,
2090
+ ...vueFormControl.createTextableProps(),
2091
+ ...vueKit.createFormControlProps(),
2092
+ ...createControlFieldProps(),
2093
+ ...createControlFieldProviderProps(),
2094
+ ...createControlProps(),
2095
+ ...vueKit.defineSlotsProps(),
2096
+ tools: {
2097
+ type: Array,
2098
+ default: () => []
2099
+ },
2100
+ floatingToolbar: Boolean,
2101
+ disabledMinHeight: Boolean,
2102
+ disabledMaxHeight: Boolean
2103
+ },
2104
+ emits: { ...vueFormControl.createTextableEmits()
2105
+ },
2106
+
2107
+ setup(props, ctx) {
2108
+ const vui = useVui();
2109
+ const textRef = vue.ref('');
2110
+ const toolButtonActiveColor = vui.setting('primaryScope');
2111
+ const wysiwygSettings = vue.computed(() => resolveRawWysiwygEditorTools(props.tools, vui));
2112
+ const control = useControl(props);
2113
+ useControlField(props);
2114
+ const inputControl = new vueFormControl.TextableControl(props, ctx, {
2115
+ nodeType: VUI_WYSIWYG_EDITOR_SYMBOL,
2116
+ validationValue: () => textRef.value
2117
+ });
2118
+ const extensions = [StarterKit__default.configure({
2119
+ bold: false,
2120
+ bulletList: false,
2121
+ orderedList: false,
2122
+ history: false,
2123
+ italic: false
2124
+ }), ...wysiwygSettings.value.extensions];
2125
+
2126
+ const updateEditable = () => {
2127
+ if (!editor.value) return;
2128
+ editor.value.setEditable(inputControl.canOperation);
2129
+ };
2130
+
2131
+ vue.watch(() => inputControl.canOperation, updateEditable);
2132
+ vue.watch(() => props.modelValue, modelValue => {
2133
+ editor.value && editor.value.commands.setContent(modelValue == null ? '' : modelValue);
2134
+ });
2135
+ const editor = vue3.useEditor({
2136
+ onCreate: ({
2137
+ editor
2138
+ }) => {
2139
+ textRef.value = editor.getText();
2140
+ updateEditable();
2141
+ },
2142
+ onFocus: ctx => {
2143
+ inputControl.focusHandler(ctx.event);
2144
+ },
2145
+ onBlur: ctx => {
2146
+ inputControl.blurHandler(ctx.event);
2147
+ },
2148
+ onUpdate: ev => {
2149
+ inputControl.value = ev.editor.getHTML();
2150
+ textRef.value = ev.editor.getText();
2151
+ },
2152
+ autofocus: props.autofocus,
2153
+ content: props.modelValue,
2154
+ extensions,
2155
+ editorProps: {
2156
+ attributes: {
2157
+ class: 'v-wysiwyg-editor__input__prose'
2158
+ }
2159
+ }
2160
+ }); // editor.value.state.doc.content
2161
+
2162
+ const focus = (position, options) => {
2163
+ return editor.value.chain().focus(position, options);
2164
+ };
2165
+
2166
+ const blur = () => {
2167
+ return editor.value.chain().blur();
2168
+ };
2169
+
2170
+ const wysiwygContext = vue.computed(() => ({
2171
+ vui,
2172
+ editor: editor.value
2173
+ }));
2174
+
2175
+ const createTools = (bubbleMenu = false) => {
2176
+ let _slot;
2177
+
2178
+ const {
2179
+ value: settings
2180
+ } = wysiwygSettings;
2181
+ const {
2182
+ value: context
2183
+ } = wysiwygContext;
2184
+ const tools = bubbleMenu ? settings.tools.filter(t => !!t.floating) : settings.tools;
2185
+ const _editor = editor.value;
2186
+ const variant = vui.setting(bubbleMenu ? 'containedVariant' : 'plainVariant');
2187
+ return vue.createVNode(VButtonGroup, {
2188
+ "class": {
2189
+ 'v-wysiwyg-editor__floating-toolbar': props.floatingToolbar
2190
+ },
2191
+ "variant": variant
2192
+ }, _isSlot$7(_slot = tools.map(({
2193
+ key,
2194
+ icon,
2195
+ onClick,
2196
+ disabled,
2197
+ active
2198
+ }) => {
2199
+ const isActive = !!_editor && resolveContextableValue(context, active);
2200
+ const isDisabled = !inputControl.canOperation || !!_editor && resolveContextableValue(context, disabled);
2201
+ let iconName;
2202
+
2203
+ if (typeof icon === 'function') {
2204
+ if (_editor) {
2205
+ iconName = icon(context);
2206
+ }
2207
+ } else {
2208
+ iconName = icon;
2209
+ }
2210
+
2211
+ if (!iconName) return;
2212
+ return vue.createVNode(VButton, {
2213
+ "key": key,
2214
+ "icon": iconName,
2215
+ "onClick": ev => onClick(context, ev),
2216
+ "color": isActive ? toolButtonActiveColor : undefined,
2217
+ "disabled": isDisabled
2218
+ }, null);
2219
+ })) ? _slot : {
2220
+ default: () => [_slot]
2221
+ });
2222
+ };
2223
+
2224
+ return {
2225
+ editor,
2226
+ ...inputControl.expose(),
2227
+ ...control,
2228
+ focus,
2229
+ blur,
2230
+ createTools
2231
+ };
2232
+ },
2233
+
2234
+ render() {
2235
+ return vue.createVNode(VFormControl, {
2236
+ "nodeControl": this.nodeControl,
2237
+ "focused": this.nodeControl.focused,
2238
+ "class": ['v-wysiwyg-editor', this.classes, `v-wysiwyg-editor--${this.size}`, {
2239
+ 'v-wysiwyg-editor--disabled-min-heihgt': this.disabledMinHeight,
2240
+ 'v-wysiwyg-editor--disabled-max-heihgt': this.disabledMaxHeight
2241
+ }],
2242
+ "label": this.label,
2243
+ "hint": this.hint,
2244
+ "hiddenInfo": this.hiddenInfo,
2245
+ "onClickLabel": ev => {
2246
+ this.focus('start', {
2247
+ scrollIntoView: true
2248
+ });
2249
+ }
2250
+ }, { ...this.$slots,
2251
+ default: () => {
2252
+ const {
2253
+ editor
2254
+ } = this;
2255
+ return vue.createVNode("div", {
2256
+ "class": "v-wysiwyg-editor__wrapper"
2257
+ }, [!this.isReadonly && this.createTools(), vue.createVNode("div", {
2258
+ "class": "v-wysiwyg-editor__body"
2259
+ }, [vue.createVNode(VControlField, {
2260
+ "class": "v-wysiwyg-editor__input",
2261
+ "autoHeight": true,
2262
+ "startAdornment": this.startAdornment,
2263
+ "endAdornment": this.endAdornment
2264
+ }, { ...this.$slots,
2265
+ default: () => {
2266
+ let _slot2;
2267
+
2268
+ return vue.createVNode(vue.Fragment, null, [vue.createVNode(vue3.EditorContent, {
2269
+ "class": "v-wysiwyg-editor__input__element wysiwyg",
2270
+ "editor": editor
2271
+ }, null), !this.floatingToolbar && !!editor && !this.isReadonly && vue.createVNode(vue3.BubbleMenu, {
2272
+ "class": "v-wysiwyg-editor__bubble-menu",
2273
+ "editor": editor
2274
+ }, _isSlot$7(_slot2 = this.createTools(true)) ? _slot2 : {
2275
+ default: () => [_slot2]
2276
+ })]);
2277
+ }
2278
+ })])]);
2279
+ },
2280
+ infoAppends: () => {
2281
+ const {
2282
+ counterResult
2283
+ } = this;
2284
+ if (!counterResult) return;
2285
+ return vue.createVNode(VTextCounter, counterResult, null);
2286
+ }
2287
+ });
2288
+ }
2289
+
2290
+ });
2291
+
2292
+ function resolveContextableValue(ctx, source) {
2293
+ return typeof source === 'function' ? source(ctx) : source;
2294
+ }
2295
+
2296
+ const WysiwygBulletListTool = (vui, options) => {
2297
+ const tool = {
2298
+ key: 'bulletList',
2299
+ icon: vui.icon('editorformatListBulleted'),
2300
+ active: ({ editor }) => editor.isActive('bulletList'),
2301
+ onClick: ({ editor }) => {
2302
+ editor.chain().focus().toggleBulletList().run();
2303
+ },
2304
+ floating: true,
2305
+ extensions: [extensionBulletList.BulletList.configure(options)],
2306
+ };
2307
+ return tool;
2308
+ };
2309
+
2310
+ const WysiwygFormatBoldTool = (vui, options) => {
2311
+ const tool = {
2312
+ key: 'formatBold',
2313
+ icon: vui.icon('editorformatBold'),
2314
+ active: ({ editor }) => editor.isActive('bold'),
2315
+ onClick: ({ editor }) => {
2316
+ editor.chain().focus().toggleBold().run();
2317
+ },
2318
+ floating: true,
2319
+ extensions: [extensionBold.Bold.configure(options)],
2320
+ };
2321
+ return tool;
2322
+ };
2323
+
2324
+ const WysiwygFormatItalicTool = (vui, options) => {
2325
+ const tool = {
2326
+ key: 'formatItalic',
2327
+ icon: vui.icon('editorformatItalic'),
2328
+ active: ({ editor }) => editor.isActive('italic'),
2329
+ onClick: ({ editor }) => {
2330
+ editor.chain().focus().toggleItalic().run();
2331
+ },
2332
+ floating: true,
2333
+ extensions: [extensionItalic.Italic.configure(options)],
2334
+ };
2335
+ return tool;
2336
+ };
2337
+
2338
+ const WysiwygFormatUnderlineTool = (vui, options) => {
2339
+ const tool = {
2340
+ key: 'formatUnderline',
2341
+ icon: vui.icon('editorformatUnderline'),
2342
+ active: ({ editor }) => editor.isActive('underline'),
2343
+ onClick: ({ editor }) => {
2344
+ editor.chain().focus().toggleUnderline().run();
2345
+ },
2346
+ floating: true,
2347
+ extensions: [extensionUnderline.Underline.configure(options)],
2348
+ };
2349
+ return tool;
2350
+ };
2351
+
2352
+ const WysiwygHistoryTool = (vui, options) => {
2353
+ const undo = {
2354
+ key: 'history-undo',
2355
+ icon: vui.icon('editorUndo'),
2356
+ disabled: ({ editor }) => !editor.can().undo(),
2357
+ onClick: ({ editor }) => {
2358
+ editor.chain().focus().undo().run();
2359
+ },
2360
+ extensions: [extensionHistory.History.configure(options)],
2361
+ };
2362
+ const redo = {
2363
+ key: 'history-redo',
2364
+ icon: vui.icon('editorRedo'),
2365
+ disabled: ({ editor }) => !editor.can().redo(),
2366
+ onClick: ({ editor }) => {
2367
+ editor.chain().focus().redo().run();
2368
+ },
2369
+ };
2370
+ return [undo, redo];
2371
+ };
2372
+
2373
+ const WysiwygLinkTool = (vui, options) => {
2374
+ const tool = {
2375
+ key: 'link',
2376
+ // icon: ({ editor }) => {
2377
+ // return vui.icon(editor.isActive('link') ? 'editorLinkOff' : 'editorLink');
2378
+ // },
2379
+ icon: vui.icon('editorLink'),
2380
+ active: ({ editor }) => editor.isActive('link'),
2381
+ // disabled: ({ editor }) => {
2382
+ // const { $from, $to } = editor.view.state.selection;
2383
+ // return $to.pos - $from.pos === 0;
2384
+ // },
2385
+ onClick: async ({ vui, editor }) => {
2386
+ const { href = '' } = editor.getAttributes('link');
2387
+ const result = await vui.prompt({
2388
+ input: {
2389
+ label: 'Link URL',
2390
+ rules: [rules.validateIf, rules.url],
2391
+ initialValue: href,
2392
+ size: 'sm',
2393
+ autofocus: true,
2394
+ },
2395
+ });
2396
+ if (result === undefined || result === false) {
2397
+ return;
2398
+ }
2399
+ const range = editor.chain().focus().extendMarkRange('link');
2400
+ if (!result) {
2401
+ range.unsetLink().run();
2402
+ }
2403
+ else {
2404
+ range
2405
+ .setLink({
2406
+ href: result,
2407
+ })
2408
+ .run();
2409
+ }
2410
+ },
2411
+ floating: true,
2412
+ extensions: [
2413
+ extensionLink.Link.configure({
2414
+ openOnClick: false,
2415
+ ...options,
2416
+ }),
2417
+ ],
2418
+ };
2419
+ return tool;
2420
+ };
2421
+
2422
+ const WysiwygOrderedListTool = (vui, options) => {
2423
+ const tool = {
2424
+ key: 'orderedList',
2425
+ icon: vui.icon('editorformatListNumbered'),
2426
+ active: ({ editor }) => editor.isActive('orderedList'),
2427
+ onClick: ({ editor }) => {
2428
+ editor.chain().focus().toggleOrderedList().run();
2429
+ },
2430
+ floating: true,
2431
+ extensions: [extensionOrderedList.OrderedList.configure(options)],
2432
+ };
2433
+ return tool;
2434
+ };
2435
+
2436
+ const WysiwygTextColorTool = (vui) => {
2437
+ const tool = {
2438
+ key: 'textColor',
2439
+ icon: vui.icon('editorTextColor'),
2440
+ // icon: (gen) => vui.icon('editorTextColor'),
2441
+ onClick: (ctx) => {
2442
+ ctx.vui.alert('ok');
2443
+ },
2444
+ floating: true,
2445
+ };
2446
+ return tool;
2447
+ };
2448
+
1977
2449
  const {
1978
2450
  props,
1979
2451
  emits
@@ -1984,7 +2456,8 @@ const VForm = vue.defineComponent({
1984
2456
  name: 'VForm',
1985
2457
  props: { ...props,
1986
2458
  ...createControlProps(),
1987
- ...vueKit.defineSlotsProps()
2459
+ ...vueKit.defineSlotsProps(),
2460
+ disableAutoScroll: Boolean
1988
2461
  },
1989
2462
  emits,
1990
2463
 
@@ -1993,6 +2466,7 @@ const VForm = vue.defineComponent({
1993
2466
  const nodeControl = vueKit.useForm(props, ctx, {
1994
2467
  nodeType: VUI_FORM_SYMBOL,
1995
2468
  onAutoValidateError: () => {
2469
+ if (props.disableAutoScroll) return;
1996
2470
  const scroller = vueKit.getDocumentScroller();
1997
2471
  const {
1998
2472
  firstInvalidEl
@@ -3384,53 +3858,138 @@ const VToolbarTitle = vue.defineComponent({
3384
3858
 
3385
3859
  });
3386
3860
 
3387
- const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3388
- const DEFAULT_TEXTAREA_ROWS = 3;
3389
- class VuiService {
3390
- options;
3391
- selectionSeparator;
3392
- autoScrollToElementOffsetTop;
3393
- textareaRows;
3394
- requiredChip;
3395
- router;
3396
- location;
3397
- constructor(options) {
3398
- this.options = options;
3399
- this.configure();
3400
- const { selectionSeparator = () => ', ', autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP, textareaRows = DEFAULT_TEXTAREA_ROWS, requiredChip = () => '*', } = options;
3401
- this.selectionSeparator = selectionSeparator;
3402
- this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3403
- this.textareaRows = textareaRows;
3404
- this.requiredChip = requiredChip;
3405
- this.router = options.router;
3406
- this.location = new vueUtils.LocationService({
3407
- router: this.router,
3408
- });
3409
- }
3410
- configure(options) {
3411
- options && Object.assign(this.options, options);
3412
- vueUtils.setDefaultRouterLink(this.getRouterLink());
3413
- }
3414
- getRouterLink() {
3415
- return this.options.RouterLink || vueRouter.RouterLink;
3416
- }
3417
- setting(key) {
3418
- return this.options.uiSettings[key];
3419
- }
3420
- icon(iconType) {
3421
- return this.options.icons[iconType];
3422
- }
3423
- getAutoScrollToElementOffsetTop() {
3424
- let { autoScrollToElementOffsetTop } = this;
3425
- if (typeof autoScrollToElementOffsetTop === 'function') {
3426
- autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3427
- }
3428
- return autoScrollToElementOffsetTop || 0;
3429
- }
3430
- getRequiredChip() {
3431
- const { requiredChip } = this;
3432
- return requiredChip && requiredChip();
3433
- }
3861
+ const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3862
+ const DEFAULT_TEXTAREA_ROWS = 3;
3863
+ class VuiService {
3864
+ constructor(options, stackService) {
3865
+ this.options = options;
3866
+ this.configure();
3867
+ const {
3868
+ selectionSeparator = () => ', ',
3869
+ autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP,
3870
+ textareaRows = DEFAULT_TEXTAREA_ROWS,
3871
+ requiredChip = () => '*'
3872
+ } = options;
3873
+ this.selectionSeparator = selectionSeparator;
3874
+ this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3875
+ this.textareaRows = textareaRows;
3876
+ this.requiredChip = requiredChip;
3877
+ this.router = options.router;
3878
+ this.location = new vueUtils.LocationService({
3879
+ router: this.router
3880
+ });
3881
+ this.stack = stackService;
3882
+ }
3883
+
3884
+ configure(options) {
3885
+ options && Object.assign(this.options, options);
3886
+ vueUtils.setDefaultRouterLink(this.getRouterLink());
3887
+ }
3888
+
3889
+ getRouterLink() {
3890
+ return this.options.RouterLink || vueRouter.RouterLink;
3891
+ }
3892
+
3893
+ setting(key) {
3894
+ return this.options.uiSettings[key];
3895
+ }
3896
+
3897
+ icon(iconType) {
3898
+ return this.options.icons[iconType];
3899
+ }
3900
+
3901
+ getAutoScrollToElementOffsetTop() {
3902
+ let {
3903
+ autoScrollToElementOffsetTop
3904
+ } = this;
3905
+
3906
+ if (typeof autoScrollToElementOffsetTop === 'function') {
3907
+ autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3908
+ }
3909
+
3910
+ return autoScrollToElementOffsetTop || 0;
3911
+ }
3912
+
3913
+ getRequiredChip() {
3914
+ const {
3915
+ requiredChip
3916
+ } = this;
3917
+ return requiredChip && requiredChip();
3918
+ }
3919
+
3920
+ dialog(...args) {
3921
+ return this.stack.dialog(...args);
3922
+ }
3923
+
3924
+ alert(...args) {
3925
+ return this.stack.alert(...args);
3926
+ }
3927
+
3928
+ confirm(...args) {
3929
+ return this.stack.confirm(...args);
3930
+ }
3931
+
3932
+ snackbar(...args) {
3933
+ return this.stack.snackbar(...args);
3934
+ }
3935
+
3936
+ prompt(rawOptions = {}) {
3937
+ const options = typeof rawOptions === 'string' ? {
3938
+ input: {
3939
+ label: rawOptions
3940
+ }
3941
+ } : { ...rawOptions
3942
+ };
3943
+ options.input = { ...options.input
3944
+ };
3945
+ options.dense = true;
3946
+ let {
3947
+ initialValue: value = ''
3948
+ } = options.input;
3949
+ const {
3950
+ size
3951
+ } = options.input;
3952
+ delete options.input.initialValue;
3953
+ let form;
3954
+ options.actions = options.actions || [this.stack.action('cancel', undefined, {
3955
+ size
3956
+ }), this.stack.action('ok', undefined, {
3957
+ size,
3958
+ onClick: () => {
3959
+ if (form) {
3960
+ const ev = new Event('submit');
3961
+ form.handleSubmit(ev);
3962
+ }
3963
+ }
3964
+ })];
3965
+ const resolved = vueKit.resolveVStackDynamicInput({ ...options,
3966
+ content: stack => {
3967
+ return vue.createVNode(VForm, {
3968
+ "disableAutoScroll": true,
3969
+ "size": size,
3970
+ "onVnodeMounted": vnode => {
3971
+ form = vnode.component.ctx.form;
3972
+ },
3973
+ "onVnodeBeforeUnmount": () => {
3974
+ form = undefined;
3975
+ },
3976
+ "onSubmit": ev => {
3977
+ stack.resolve(value);
3978
+ }
3979
+ }, {
3980
+ default: () => [vue.createVNode(VTextField, vue.mergeProps(options.input, {
3981
+ "modelValue": value,
3982
+ "onChange": ev => {
3983
+ stack.value = ev;
3984
+ value = ev;
3985
+ }
3986
+ }), null)]
3987
+ });
3988
+ }
3989
+ });
3990
+ return this.dialog(resolved);
3991
+ }
3992
+
3434
3993
  }
3435
3994
 
3436
3995
  class VuiPlugin {
@@ -3474,7 +4033,7 @@ class VuiPlugin {
3474
4033
  ...stack
3475
4034
  }); // Vui
3476
4035
 
3477
- const $vui = new VuiService(opts);
4036
+ const $vui = new VuiService(opts, app.config.globalProperties.$vstack);
3478
4037
  app.provide(VuiInjectionKey, $vui);
3479
4038
  app.config.globalProperties.$vui = $vui;
3480
4039
 
@@ -3500,6 +4059,7 @@ exports.PAGINATION_ALIGNS = PAGINATION_ALIGNS;
3500
4059
  exports.VApp = VApp;
3501
4060
  exports.VBreadcrumbs = VBreadcrumbs;
3502
4061
  exports.VButton = VButton;
4062
+ exports.VButtonGroup = VButtonGroup;
3503
4063
  exports.VCard = VCard;
3504
4064
  exports.VCardActions = VCardActions;
3505
4065
  exports.VCardContent = VCardContent;
@@ -3541,12 +4101,22 @@ exports.VUI_SWITCH_GROUP_SYMBOL = VUI_SWITCH_GROUP_SYMBOL;
3541
4101
  exports.VUI_SWITCH_SYMBOL = VUI_SWITCH_SYMBOL;
3542
4102
  exports.VUI_TEXTAREA_SYMBOL = VUI_TEXTAREA_SYMBOL;
3543
4103
  exports.VUI_TEXT_FIELD_SYMBOL = VUI_TEXT_FIELD_SYMBOL;
4104
+ exports.VUI_WYSIWYG_EDITOR_SYMBOL = VUI_WYSIWYG_EDITOR_SYMBOL;
4105
+ exports.VWysiwygEditor = VWysiwygEditor;
3544
4106
  exports.VuiColorProviderInjectionKey = VuiColorProviderInjectionKey;
3545
4107
  exports.VuiControlFieldInjectionKey = VuiControlFieldInjectionKey;
3546
4108
  exports.VuiControlInjectionKey = VuiControlInjectionKey;
3547
4109
  exports.VuiInjectionKey = VuiInjectionKey;
3548
4110
  exports.VuiPlugin = VuiPlugin;
3549
4111
  exports.VuiService = VuiService;
4112
+ exports.WysiwygBulletListTool = WysiwygBulletListTool;
4113
+ exports.WysiwygFormatBoldTool = WysiwygFormatBoldTool;
4114
+ exports.WysiwygFormatItalicTool = WysiwygFormatItalicTool;
4115
+ exports.WysiwygFormatUnderlineTool = WysiwygFormatUnderlineTool;
4116
+ exports.WysiwygHistoryTool = WysiwygHistoryTool;
4117
+ exports.WysiwygLinkTool = WysiwygLinkTool;
4118
+ exports.WysiwygOrderedListTool = WysiwygOrderedListTool;
4119
+ exports.WysiwygTextColorTool = WysiwygTextColorTool;
3550
4120
  exports.configureDataTableDefaults = configureDataTableDefaults;
3551
4121
  exports.createCardProps = createCardProps;
3552
4122
  exports.createControlFieldProviderProps = createControlFieldProviderProps;