@fastkit/vui 0.6.34 → 0.6.38

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