@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.
@@ -1,15 +1,26 @@
1
- import { createPropsOptions, createFormControlSettings, defineSlotsProps, useFormControl, renderSlotOrEmpty, createFormSelectorSettings, createFormControlProps, useFormSelectorControl, createFormSelectorItemSettings, useFormSelectorItemControl, createFormSelectorItemGroupProps, useFormSelectorItemGroupControl, resolveVNodeChildOrSlots, useParentFormNode, VMenu, createTextInputSettings, useTextInputControl, createTextareaSettings, useTextareaControl, createFormSettings, useForm, getDocumentScroller, useVScrollerRef, VScroller, useInjectTheme, VStackRoot, VueColorSchemePlugin, installVueStackPlugin } from '@fastkit/vue-kit';
1
+ import { createPropsOptions, createFormControlSettings, defineSlotsProps, useFormControl, renderSlotOrEmpty, createFormSelectorSettings, createFormControlProps, useFormSelectorControl, createFormSelectorItemSettings, useFormSelectorItemControl, createFormSelectorItemGroupProps, useFormSelectorItemGroupControl, resolveVNodeChildOrSlots, useParentFormNode, VMenu, createTextInputSettings, useTextInputControl, createTextareaSettings, useTextareaControl, createFormSettings, useForm, getDocumentScroller, useVScrollerRef, VScroller, useInjectTheme, VStackRoot, resolveVStackDynamicInput, VueColorSchemePlugin, installVueStackPlugin } from '@fastkit/vue-kit';
2
2
  export * from '@fastkit/vue-kit';
3
3
  export { VDialog, VMenu, VSnackbar } from '@fastkit/vue-kit';
4
+ import { inject, computed, provide, defineComponent, createVNode, mergeProps, isVNode, cloneVNode, ref, watch, withDirectives, createTextVNode, Fragment, vShow, onBeforeUpdate, vModelSelect, onMounted, onBeforeUnmount, Transition } from 'vue';
4
5
  import { useRouter, RouterLink, useLink, useRoute } from 'vue-router';
5
- import { createPropsOptions as createPropsOptions$1, defineSlotsProps as defineSlotsProps$1, renderSlotOrEmpty as renderSlotOrEmpty$1, navigationableInheritProps, VLink, rawNumberPropType, resolveNumberish, resizeDirectiveArgument, VExpandTransition, LocationService, setDefaultRouterLink } from '@fastkit/vue-utils';
6
- import { inject, computed, provide, defineComponent, createVNode, mergeProps, ref, watch, withDirectives, createTextVNode, isVNode, Fragment, vShow, onBeforeUpdate, vModelSelect, onMounted, onBeforeUnmount, Transition } from 'vue';
6
+ import { createPropsOptions as createPropsOptions$1, defineSlotsProps as defineSlotsProps$1, renderSlotOrEmpty as renderSlotOrEmpty$1, navigationableInheritProps, VLink, isFragment, rawNumberPropType, resolveNumberish, resizeDirectiveArgument, VExpandTransition, LocationService, setDefaultRouterLink } from '@fastkit/vue-utils';
7
7
  import { useScopeColorClass, colorSchemeProps, useColorClasses, toScopeColorClass } from '@fastkit/vue-color-scheme';
8
8
  import { VProgressCircular } from '@fastkit/vue-loading';
9
9
  export * from '@fastkit/vue-loading';
10
10
  export { ICON_NAMES } from '@fastkit/icon-font';
11
11
  import { isPromise } from '@fastkit/helpers';
12
12
  import { VAppContainer, VAppLayoutControl } from '@fastkit/vue-app-layout';
13
+ import { createTextableProps, createTextableEmits, TextableControl } from '@fastkit/vue-form-control';
14
+ import { useEditor, EditorContent, BubbleMenu } from '@tiptap/vue-3';
15
+ import StarterKit from '@tiptap/starter-kit';
16
+ import { BulletList } from '@tiptap/extension-bullet-list';
17
+ import { Bold } from '@tiptap/extension-bold';
18
+ import { Italic } from '@tiptap/extension-italic';
19
+ import { Underline } from '@tiptap/extension-underline';
20
+ import { History } from '@tiptap/extension-history';
21
+ import { Link } from '@tiptap/extension-link';
22
+ import { validateIf, url } from '@fastkit/rules';
23
+ import { OrderedList } from '@tiptap/extension-ordered-list';
13
24
  import { getDocumentScroller as getDocumentScroller$1 } from '@fastkit/vue-scroller';
14
25
 
15
26
  const CONTROL_SIZES = ['sm', 'md', 'lg'];
@@ -21,6 +32,7 @@ const VuiControlFieldInjectionKey = Symbol();
21
32
  const VuiColorProviderInjectionKey = Symbol();
22
33
  const VUI_TEXT_FIELD_SYMBOL = 'vui-text-field';
23
34
  const VUI_TEXTAREA_SYMBOL = 'vui-textarea';
35
+ const VUI_WYSIWYG_EDITOR_SYMBOL = 'vui-wysiwyg-editor';
24
36
  const VUI_SELECT_SYMBOL = 'vui-select';
25
37
  const VUI_OPTION_SYMBOL = 'vui-option';
26
38
  const VUI_CHECKBOX_GROUP_SYMBOL = 'vui-checkbox-group';
@@ -433,7 +445,8 @@ function resolveRawVButtonIcon(raw, type = 'main') {
433
445
  }, null);
434
446
  }
435
447
 
436
- const vueButtonProps = createPropsOptions$1({ ...colorSchemeProps(),
448
+ const vueButtonProps = createPropsOptions$1({ ...undefined,
449
+ ...colorSchemeProps(),
437
450
  ...navigationableInheritProps,
438
451
  spacer: [Boolean, String],
439
452
  loading: Boolean,
@@ -478,8 +491,10 @@ const VButton = defineComponent({
478
491
  });
479
492
  const isPlain = computed(() => color.variant.value.value === vui.setting('plainVariant') && color.color.value.value === defaults.color);
480
493
  const isLoading = computed(() => props.loading); // const isDisabled = computed(() => props.disabled);
494
+ // const isRounded = computed(() =>
495
+ // props.rounded != null ? props.rounded : !!icon.value,
496
+ // );
481
497
 
482
- const isRounded = computed(() => props.rounded || !!icon.value);
483
498
  const spacer = computed(() => {
484
499
  const _spacer = props.spacer;
485
500
  if (!_spacer) return;
@@ -489,7 +504,7 @@ const VButton = defineComponent({
489
504
  spacer.value ? `v-button--spacer-${spacer.value}` : undefined, `v-button--${control.size.value}`, {
490
505
  'v-button--loading': isLoading.value,
491
506
  'v-button--icon': !!icon.value,
492
- 'v-button--rounded': isRounded.value,
507
+ 'v-button--rounded': props.rounded,
493
508
  'v-button--plain': isPlain.value
494
509
  }]);
495
510
  return () => {
@@ -510,7 +525,64 @@ const VButton = defineComponent({
510
525
 
511
526
  });
512
527
 
513
- function _isSlot$c(s) {
528
+ const VButtonGroup = defineComponent({
529
+ name: 'VButtonGroup',
530
+ props: { ...colorSchemeProps(),
531
+ ...createControlProps(),
532
+ disabled: Boolean
533
+ },
534
+
535
+ setup(props, ctx) {
536
+ return () => {
537
+ let buttonLength = 0;
538
+ let tmp = renderSlotOrEmpty$1(ctx.slots) || [];
539
+
540
+ if (tmp.length === 1 && isFragment(tmp[0])) {
541
+ tmp = tmp[0].children;
542
+ }
543
+
544
+ const children = tmp.map(node => {
545
+ if (!isVNode(node) || node.type !== VButton) {
546
+ return {
547
+ isButton: false,
548
+ node
549
+ };
550
+ }
551
+
552
+ buttonLength++;
553
+ return {
554
+ isButton: true,
555
+ node
556
+ };
557
+ });
558
+ let buttonIndex = 0;
559
+ const $children = children.map(child => {
560
+ if (child.isButton) {
561
+ buttonIndex++;
562
+ const hasLeft = buttonIndex > 1;
563
+ const hasRight = buttonIndex < buttonLength;
564
+ const childProps = child.node.props;
565
+ return cloneVNode(child.node, { ...props,
566
+ ...childProps,
567
+ rouded: false,
568
+ class: ['v-button-group__item', {
569
+ 'v-button-group__item--has-left': hasLeft,
570
+ 'v-button-group__item--has-right': hasRight
571
+ }]
572
+ });
573
+ }
574
+
575
+ return child.node;
576
+ });
577
+ return createVNode("div", {
578
+ "class": "v-button-group"
579
+ }, [$children]);
580
+ };
581
+ }
582
+
583
+ });
584
+
585
+ function _isSlot$d(s) {
514
586
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
515
587
  }
516
588
 
@@ -758,7 +830,7 @@ const VPagination = defineComponent({
758
830
  "class": classes,
759
831
  "to": to,
760
832
  "key": key
761
- }, _isSlot$c(children) ? children : {
833
+ }, _isSlot$d(children) ? children : {
762
834
  default: () => [children]
763
835
  });
764
836
  } else {
@@ -913,7 +985,7 @@ const VDrawerLayout = defineComponent({
913
985
 
914
986
  });
915
987
 
916
- function _isSlot$b(s) {
988
+ function _isSlot$c(s) {
917
989
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
918
990
  }
919
991
 
@@ -948,7 +1020,7 @@ const VHero = defineComponent({
948
1020
  }, {
949
1021
  default: () => [createVNode(HTagName, {
950
1022
  "class": "v-hero__title"
951
- }, _isSlot$b(_slot = renderSlotOrEmpty$1(ctx.slots, 'default')) ? _slot : {
1023
+ }, _isSlot$c(_slot = renderSlotOrEmpty$1(ctx.slots, 'default')) ? _slot : {
952
1024
  default: () => [_slot]
953
1025
  })]
954
1026
  })]
@@ -958,7 +1030,7 @@ const VHero = defineComponent({
958
1030
 
959
1031
  });
960
1032
 
961
- function _isSlot$a(s) {
1033
+ function _isSlot$b(s) {
962
1034
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
963
1035
  }
964
1036
 
@@ -993,7 +1065,7 @@ function renderNavigationItemInput(input, extraProps) {
993
1065
  } = resolveNavigationItemInput(input);
994
1066
  return createVNode(VNavigationItem, { ...props,
995
1067
  ...extraProps
996
- }, _isSlot$a(label) ? label : {
1068
+ }, _isSlot$b(label) ? label : {
997
1069
  default: () => [label]
998
1070
  });
999
1071
  }
@@ -1016,9 +1088,11 @@ const VNavigationItem = defineComponent({
1016
1088
  const to = computed(() => ctx.attrs.to);
1017
1089
  const match = computed(() => {
1018
1090
  const {
1019
- match,
1020
- to
1091
+ match
1021
1092
  } = props;
1093
+ const {
1094
+ to
1095
+ } = ctx.attrs;
1022
1096
  if (match) return match;
1023
1097
  if (!to) return;
1024
1098
  if (typeof to === 'string') return to;
@@ -1144,7 +1218,7 @@ const VNavigationItem = defineComponent({
1144
1218
  "class": ['v-navigation-item', classes.value],
1145
1219
  "onClick": onClick,
1146
1220
  "onChangeActive": onChangeActive
1147
- }), _isSlot$a(_slot = renderSlotOrEmpty$1(ctx.slots, 'default')) ? _slot : {
1221
+ }), _isSlot$b(_slot = renderSlotOrEmpty$1(ctx.slots, 'default')) ? _slot : {
1148
1222
  default: () => [_slot]
1149
1223
  }), _children && createVNode(VExpandTransition, null, {
1150
1224
  default: () => [withDirectives(createVNode("div", {
@@ -1324,7 +1398,7 @@ const VCheckbox = defineComponent({
1324
1398
 
1325
1399
  });
1326
1400
 
1327
- function _isSlot$9(s) {
1401
+ function _isSlot$a(s) {
1328
1402
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
1329
1403
  }
1330
1404
 
@@ -1336,7 +1410,7 @@ const VCheckboxGroup = defineFormSelectorComponent({
1336
1410
  itemRenderer: ({
1337
1411
  attrs,
1338
1412
  slots
1339
- }) => createVNode(VCheckbox, attrs, _isSlot$9(slots) ? slots : {
1413
+ }) => createVNode(VCheckbox, attrs, _isSlot$a(slots) ? slots : {
1340
1414
  default: () => [slots]
1341
1415
  })
1342
1416
  });
@@ -1388,7 +1462,7 @@ const VRadio = defineComponent({
1388
1462
 
1389
1463
  });
1390
1464
 
1391
- function _isSlot$8(s) {
1465
+ function _isSlot$9(s) {
1392
1466
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
1393
1467
  }
1394
1468
 
@@ -1399,7 +1473,7 @@ const VRadioGroup = defineFormSelectorComponent({
1399
1473
  itemRenderer: ({
1400
1474
  attrs,
1401
1475
  slots
1402
- }) => createVNode(VRadio, attrs, _isSlot$8(slots) ? slots : {
1476
+ }) => createVNode(VRadio, attrs, _isSlot$9(slots) ? slots : {
1403
1477
  default: () => [slots]
1404
1478
  })
1405
1479
  });
@@ -1461,7 +1535,7 @@ const VSwitch = defineComponent({
1461
1535
 
1462
1536
  });
1463
1537
 
1464
- function _isSlot$7(s) {
1538
+ function _isSlot$8(s) {
1465
1539
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
1466
1540
  }
1467
1541
 
@@ -1473,7 +1547,7 @@ const VSwitchGroup = defineFormSelectorComponent({
1473
1547
  itemRenderer: ({
1474
1548
  attrs,
1475
1549
  slots
1476
- }) => createVNode(VSwitch, attrs, _isSlot$7(slots) ? slots : {
1550
+ }) => createVNode(VSwitch, attrs, _isSlot$8(slots) ? slots : {
1477
1551
  default: () => [slots]
1478
1552
  })
1479
1553
  });
@@ -1856,15 +1930,20 @@ const {
1856
1930
  props: props$2,
1857
1931
  emits: emits$2
1858
1932
  } = createTextInputSettings();
1859
- const VTextField = defineComponent({
1860
- name: 'VTextField',
1861
- props: { ...props$2,
1933
+
1934
+ function createTextFieldProps() {
1935
+ return { ...props$2,
1862
1936
  ...createFormControlProps(),
1863
1937
  ...createControlFieldProps(),
1864
1938
  ...createControlFieldProviderProps(),
1865
1939
  ...createControlProps(),
1866
1940
  ...defineSlotsProps()
1867
- },
1941
+ };
1942
+ }
1943
+
1944
+ const VTextField = defineComponent({
1945
+ name: 'VTextField',
1946
+ props: createTextFieldProps(),
1868
1947
  emits: emits$2,
1869
1948
 
1870
1949
  setup(props, ctx) {
@@ -1973,6 +2052,396 @@ const VTextarea = defineComponent({
1973
2052
 
1974
2053
  });
1975
2054
 
2055
+ function resolveRawWysiwygEditorTool(raw, vui) {
2056
+ return typeof raw === 'function' ? raw(vui) : raw;
2057
+ }
2058
+ function resolveRawWysiwygEditorTools(raws, vui) {
2059
+ const tools = [];
2060
+ const extensions = [];
2061
+ raws.forEach((raw) => {
2062
+ let resolved = resolveRawWysiwygEditorTool(raw, vui);
2063
+ if (!Array.isArray(resolved)) {
2064
+ resolved = [resolved];
2065
+ }
2066
+ resolved.forEach((tool) => {
2067
+ tools.push(tool);
2068
+ if (tool.extensions) {
2069
+ extensions.push(...tool.extensions);
2070
+ }
2071
+ });
2072
+ });
2073
+ return {
2074
+ tools,
2075
+ extensions,
2076
+ };
2077
+ }
2078
+
2079
+ function _isSlot$7(s) {
2080
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
2081
+ }
2082
+
2083
+ const VWysiwygEditor = defineComponent({
2084
+ name: 'VWysiwygEditor',
2085
+ props: { // ...props,
2086
+ ...createTextableProps(),
2087
+ ...createFormControlProps(),
2088
+ ...createControlFieldProps(),
2089
+ ...createControlFieldProviderProps(),
2090
+ ...createControlProps(),
2091
+ ...defineSlotsProps(),
2092
+ tools: {
2093
+ type: Array,
2094
+ default: () => []
2095
+ },
2096
+ floatingToolbar: Boolean,
2097
+ disabledMinHeight: Boolean,
2098
+ disabledMaxHeight: Boolean
2099
+ },
2100
+ emits: { ...createTextableEmits()
2101
+ },
2102
+
2103
+ setup(props, ctx) {
2104
+ const vui = useVui();
2105
+ const textRef = ref('');
2106
+ const toolButtonActiveColor = vui.setting('primaryScope');
2107
+ const wysiwygSettings = computed(() => resolveRawWysiwygEditorTools(props.tools, vui));
2108
+ const control = useControl(props);
2109
+ useControlField(props);
2110
+ const inputControl = new TextableControl(props, ctx, {
2111
+ nodeType: VUI_WYSIWYG_EDITOR_SYMBOL,
2112
+ validationValue: () => textRef.value
2113
+ });
2114
+ const extensions = [StarterKit.configure({
2115
+ bold: false,
2116
+ bulletList: false,
2117
+ orderedList: false,
2118
+ history: false,
2119
+ italic: false
2120
+ }), ...wysiwygSettings.value.extensions];
2121
+
2122
+ const updateEditable = () => {
2123
+ if (!editor.value) return;
2124
+ editor.value.setEditable(inputControl.canOperation);
2125
+ };
2126
+
2127
+ watch(() => inputControl.canOperation, updateEditable);
2128
+ watch(() => props.modelValue, modelValue => {
2129
+ editor.value && editor.value.commands.setContent(modelValue == null ? '' : modelValue);
2130
+ });
2131
+ const editor = useEditor({
2132
+ onCreate: ({
2133
+ editor
2134
+ }) => {
2135
+ textRef.value = editor.getText();
2136
+ updateEditable();
2137
+ },
2138
+ onFocus: ctx => {
2139
+ inputControl.focusHandler(ctx.event);
2140
+ },
2141
+ onBlur: ctx => {
2142
+ inputControl.blurHandler(ctx.event);
2143
+ },
2144
+ onUpdate: ev => {
2145
+ inputControl.value = ev.editor.getHTML();
2146
+ textRef.value = ev.editor.getText();
2147
+ },
2148
+ autofocus: props.autofocus,
2149
+ content: props.modelValue,
2150
+ extensions,
2151
+ editorProps: {
2152
+ attributes: {
2153
+ class: 'v-wysiwyg-editor__input__prose'
2154
+ }
2155
+ }
2156
+ }); // editor.value.state.doc.content
2157
+
2158
+ const focus = (position, options) => {
2159
+ return editor.value.chain().focus(position, options);
2160
+ };
2161
+
2162
+ const blur = () => {
2163
+ return editor.value.chain().blur();
2164
+ };
2165
+
2166
+ const wysiwygContext = computed(() => ({
2167
+ vui,
2168
+ editor: editor.value
2169
+ }));
2170
+
2171
+ const createTools = (bubbleMenu = false) => {
2172
+ let _slot;
2173
+
2174
+ const {
2175
+ value: settings
2176
+ } = wysiwygSettings;
2177
+ const {
2178
+ value: context
2179
+ } = wysiwygContext;
2180
+ const tools = bubbleMenu ? settings.tools.filter(t => !!t.floating) : settings.tools;
2181
+ const _editor = editor.value;
2182
+ const variant = vui.setting(bubbleMenu ? 'containedVariant' : 'plainVariant');
2183
+ return createVNode(VButtonGroup, {
2184
+ "class": {
2185
+ 'v-wysiwyg-editor__floating-toolbar': props.floatingToolbar
2186
+ },
2187
+ "variant": variant
2188
+ }, _isSlot$7(_slot = tools.map(({
2189
+ key,
2190
+ icon,
2191
+ onClick,
2192
+ disabled,
2193
+ active
2194
+ }) => {
2195
+ const isActive = !!_editor && resolveContextableValue(context, active);
2196
+ const isDisabled = !inputControl.canOperation || !!_editor && resolveContextableValue(context, disabled);
2197
+ let iconName;
2198
+
2199
+ if (typeof icon === 'function') {
2200
+ if (_editor) {
2201
+ iconName = icon(context);
2202
+ }
2203
+ } else {
2204
+ iconName = icon;
2205
+ }
2206
+
2207
+ if (!iconName) return;
2208
+ return createVNode(VButton, {
2209
+ "key": key,
2210
+ "icon": iconName,
2211
+ "onClick": ev => onClick(context, ev),
2212
+ "color": isActive ? toolButtonActiveColor : undefined,
2213
+ "disabled": isDisabled
2214
+ }, null);
2215
+ })) ? _slot : {
2216
+ default: () => [_slot]
2217
+ });
2218
+ };
2219
+
2220
+ return {
2221
+ editor,
2222
+ ...inputControl.expose(),
2223
+ ...control,
2224
+ focus,
2225
+ blur,
2226
+ createTools
2227
+ };
2228
+ },
2229
+
2230
+ render() {
2231
+ return createVNode(VFormControl, {
2232
+ "nodeControl": this.nodeControl,
2233
+ "focused": this.nodeControl.focused,
2234
+ "class": ['v-wysiwyg-editor', this.classes, `v-wysiwyg-editor--${this.size}`, {
2235
+ 'v-wysiwyg-editor--disabled-min-heihgt': this.disabledMinHeight,
2236
+ 'v-wysiwyg-editor--disabled-max-heihgt': this.disabledMaxHeight
2237
+ }],
2238
+ "label": this.label,
2239
+ "hint": this.hint,
2240
+ "hiddenInfo": this.hiddenInfo,
2241
+ "onClickLabel": ev => {
2242
+ this.focus('start', {
2243
+ scrollIntoView: true
2244
+ });
2245
+ }
2246
+ }, { ...this.$slots,
2247
+ default: () => {
2248
+ const {
2249
+ editor
2250
+ } = this;
2251
+ return createVNode("div", {
2252
+ "class": "v-wysiwyg-editor__wrapper"
2253
+ }, [!this.isReadonly && this.createTools(), createVNode("div", {
2254
+ "class": "v-wysiwyg-editor__body"
2255
+ }, [createVNode(VControlField, {
2256
+ "class": "v-wysiwyg-editor__input",
2257
+ "autoHeight": true,
2258
+ "startAdornment": this.startAdornment,
2259
+ "endAdornment": this.endAdornment
2260
+ }, { ...this.$slots,
2261
+ default: () => {
2262
+ let _slot2;
2263
+
2264
+ return createVNode(Fragment, null, [createVNode(EditorContent, {
2265
+ "class": "v-wysiwyg-editor__input__element wysiwyg",
2266
+ "editor": editor
2267
+ }, null), !this.floatingToolbar && !!editor && !this.isReadonly && createVNode(BubbleMenu, {
2268
+ "class": "v-wysiwyg-editor__bubble-menu",
2269
+ "editor": editor
2270
+ }, _isSlot$7(_slot2 = this.createTools(true)) ? _slot2 : {
2271
+ default: () => [_slot2]
2272
+ })]);
2273
+ }
2274
+ })])]);
2275
+ },
2276
+ infoAppends: () => {
2277
+ const {
2278
+ counterResult
2279
+ } = this;
2280
+ if (!counterResult) return;
2281
+ return createVNode(VTextCounter, counterResult, null);
2282
+ }
2283
+ });
2284
+ }
2285
+
2286
+ });
2287
+
2288
+ function resolveContextableValue(ctx, source) {
2289
+ return typeof source === 'function' ? source(ctx) : source;
2290
+ }
2291
+
2292
+ const WysiwygBulletListTool = (vui, options) => {
2293
+ const tool = {
2294
+ key: 'bulletList',
2295
+ icon: vui.icon('editorformatListBulleted'),
2296
+ active: ({ editor }) => editor.isActive('bulletList'),
2297
+ onClick: ({ editor }) => {
2298
+ editor.chain().focus().toggleBulletList().run();
2299
+ },
2300
+ floating: true,
2301
+ extensions: [BulletList.configure(options)],
2302
+ };
2303
+ return tool;
2304
+ };
2305
+
2306
+ const WysiwygFormatBoldTool = (vui, options) => {
2307
+ const tool = {
2308
+ key: 'formatBold',
2309
+ icon: vui.icon('editorformatBold'),
2310
+ active: ({ editor }) => editor.isActive('bold'),
2311
+ onClick: ({ editor }) => {
2312
+ editor.chain().focus().toggleBold().run();
2313
+ },
2314
+ floating: true,
2315
+ extensions: [Bold.configure(options)],
2316
+ };
2317
+ return tool;
2318
+ };
2319
+
2320
+ const WysiwygFormatItalicTool = (vui, options) => {
2321
+ const tool = {
2322
+ key: 'formatItalic',
2323
+ icon: vui.icon('editorformatItalic'),
2324
+ active: ({ editor }) => editor.isActive('italic'),
2325
+ onClick: ({ editor }) => {
2326
+ editor.chain().focus().toggleItalic().run();
2327
+ },
2328
+ floating: true,
2329
+ extensions: [Italic.configure(options)],
2330
+ };
2331
+ return tool;
2332
+ };
2333
+
2334
+ const WysiwygFormatUnderlineTool = (vui, options) => {
2335
+ const tool = {
2336
+ key: 'formatUnderline',
2337
+ icon: vui.icon('editorformatUnderline'),
2338
+ active: ({ editor }) => editor.isActive('underline'),
2339
+ onClick: ({ editor }) => {
2340
+ editor.chain().focus().toggleUnderline().run();
2341
+ },
2342
+ floating: true,
2343
+ extensions: [Underline.configure(options)],
2344
+ };
2345
+ return tool;
2346
+ };
2347
+
2348
+ const WysiwygHistoryTool = (vui, options) => {
2349
+ const undo = {
2350
+ key: 'history-undo',
2351
+ icon: vui.icon('editorUndo'),
2352
+ disabled: ({ editor }) => !editor.can().undo(),
2353
+ onClick: ({ editor }) => {
2354
+ editor.chain().focus().undo().run();
2355
+ },
2356
+ extensions: [History.configure(options)],
2357
+ };
2358
+ const redo = {
2359
+ key: 'history-redo',
2360
+ icon: vui.icon('editorRedo'),
2361
+ disabled: ({ editor }) => !editor.can().redo(),
2362
+ onClick: ({ editor }) => {
2363
+ editor.chain().focus().redo().run();
2364
+ },
2365
+ };
2366
+ return [undo, redo];
2367
+ };
2368
+
2369
+ const WysiwygLinkTool = (vui, options) => {
2370
+ const tool = {
2371
+ key: 'link',
2372
+ // icon: ({ editor }) => {
2373
+ // return vui.icon(editor.isActive('link') ? 'editorLinkOff' : 'editorLink');
2374
+ // },
2375
+ icon: vui.icon('editorLink'),
2376
+ active: ({ editor }) => editor.isActive('link'),
2377
+ // disabled: ({ editor }) => {
2378
+ // const { $from, $to } = editor.view.state.selection;
2379
+ // return $to.pos - $from.pos === 0;
2380
+ // },
2381
+ onClick: async ({ vui, editor }) => {
2382
+ const { href = '' } = editor.getAttributes('link');
2383
+ const result = await vui.prompt({
2384
+ input: {
2385
+ label: 'Link URL',
2386
+ rules: [validateIf, url],
2387
+ initialValue: href,
2388
+ size: 'sm',
2389
+ autofocus: true,
2390
+ },
2391
+ });
2392
+ if (result === undefined || result === false) {
2393
+ return;
2394
+ }
2395
+ const range = editor.chain().focus().extendMarkRange('link');
2396
+ if (!result) {
2397
+ range.unsetLink().run();
2398
+ }
2399
+ else {
2400
+ range
2401
+ .setLink({
2402
+ href: result,
2403
+ })
2404
+ .run();
2405
+ }
2406
+ },
2407
+ floating: true,
2408
+ extensions: [
2409
+ Link.configure({
2410
+ openOnClick: false,
2411
+ ...options,
2412
+ }),
2413
+ ],
2414
+ };
2415
+ return tool;
2416
+ };
2417
+
2418
+ const WysiwygOrderedListTool = (vui, options) => {
2419
+ const tool = {
2420
+ key: 'orderedList',
2421
+ icon: vui.icon('editorformatListNumbered'),
2422
+ active: ({ editor }) => editor.isActive('orderedList'),
2423
+ onClick: ({ editor }) => {
2424
+ editor.chain().focus().toggleOrderedList().run();
2425
+ },
2426
+ floating: true,
2427
+ extensions: [OrderedList.configure(options)],
2428
+ };
2429
+ return tool;
2430
+ };
2431
+
2432
+ const WysiwygTextColorTool = (vui) => {
2433
+ const tool = {
2434
+ key: 'textColor',
2435
+ icon: vui.icon('editorTextColor'),
2436
+ // icon: (gen) => vui.icon('editorTextColor'),
2437
+ onClick: (ctx) => {
2438
+ ctx.vui.alert('ok');
2439
+ },
2440
+ floating: true,
2441
+ };
2442
+ return tool;
2443
+ };
2444
+
1976
2445
  const {
1977
2446
  props,
1978
2447
  emits
@@ -1983,7 +2452,8 @@ const VForm = defineComponent({
1983
2452
  name: 'VForm',
1984
2453
  props: { ...props,
1985
2454
  ...createControlProps(),
1986
- ...defineSlotsProps()
2455
+ ...defineSlotsProps(),
2456
+ disableAutoScroll: Boolean
1987
2457
  },
1988
2458
  emits,
1989
2459
 
@@ -1992,6 +2462,7 @@ const VForm = defineComponent({
1992
2462
  const nodeControl = useForm(props, ctx, {
1993
2463
  nodeType: VUI_FORM_SYMBOL,
1994
2464
  onAutoValidateError: () => {
2465
+ if (props.disableAutoScroll) return;
1995
2466
  const scroller = getDocumentScroller();
1996
2467
  const {
1997
2468
  firstInvalidEl
@@ -3383,53 +3854,138 @@ const VToolbarTitle = defineComponent({
3383
3854
 
3384
3855
  });
3385
3856
 
3386
- const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3387
- const DEFAULT_TEXTAREA_ROWS = 3;
3388
- class VuiService {
3389
- options;
3390
- selectionSeparator;
3391
- autoScrollToElementOffsetTop;
3392
- textareaRows;
3393
- requiredChip;
3394
- router;
3395
- location;
3396
- constructor(options) {
3397
- this.options = options;
3398
- this.configure();
3399
- const { selectionSeparator = () => ', ', autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP, textareaRows = DEFAULT_TEXTAREA_ROWS, requiredChip = () => '*', } = options;
3400
- this.selectionSeparator = selectionSeparator;
3401
- this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3402
- this.textareaRows = textareaRows;
3403
- this.requiredChip = requiredChip;
3404
- this.router = options.router;
3405
- this.location = new LocationService({
3406
- router: this.router,
3407
- });
3408
- }
3409
- configure(options) {
3410
- options && Object.assign(this.options, options);
3411
- setDefaultRouterLink(this.getRouterLink());
3412
- }
3413
- getRouterLink() {
3414
- return this.options.RouterLink || RouterLink;
3415
- }
3416
- setting(key) {
3417
- return this.options.uiSettings[key];
3418
- }
3419
- icon(iconType) {
3420
- return this.options.icons[iconType];
3421
- }
3422
- getAutoScrollToElementOffsetTop() {
3423
- let { autoScrollToElementOffsetTop } = this;
3424
- if (typeof autoScrollToElementOffsetTop === 'function') {
3425
- autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3426
- }
3427
- return autoScrollToElementOffsetTop || 0;
3428
- }
3429
- getRequiredChip() {
3430
- const { requiredChip } = this;
3431
- return requiredChip && requiredChip();
3432
- }
3857
+ const DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP = -20;
3858
+ const DEFAULT_TEXTAREA_ROWS = 3;
3859
+ class VuiService {
3860
+ constructor(options, stackService) {
3861
+ this.options = options;
3862
+ this.configure();
3863
+ const {
3864
+ selectionSeparator = () => ', ',
3865
+ autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP,
3866
+ textareaRows = DEFAULT_TEXTAREA_ROWS,
3867
+ requiredChip = () => '*'
3868
+ } = options;
3869
+ this.selectionSeparator = selectionSeparator;
3870
+ this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
3871
+ this.textareaRows = textareaRows;
3872
+ this.requiredChip = requiredChip;
3873
+ this.router = options.router;
3874
+ this.location = new LocationService({
3875
+ router: this.router
3876
+ });
3877
+ this.stack = stackService;
3878
+ }
3879
+
3880
+ configure(options) {
3881
+ options && Object.assign(this.options, options);
3882
+ setDefaultRouterLink(this.getRouterLink());
3883
+ }
3884
+
3885
+ getRouterLink() {
3886
+ return this.options.RouterLink || RouterLink;
3887
+ }
3888
+
3889
+ setting(key) {
3890
+ return this.options.uiSettings[key];
3891
+ }
3892
+
3893
+ icon(iconType) {
3894
+ return this.options.icons[iconType];
3895
+ }
3896
+
3897
+ getAutoScrollToElementOffsetTop() {
3898
+ let {
3899
+ autoScrollToElementOffsetTop
3900
+ } = this;
3901
+
3902
+ if (typeof autoScrollToElementOffsetTop === 'function') {
3903
+ autoScrollToElementOffsetTop = autoScrollToElementOffsetTop();
3904
+ }
3905
+
3906
+ return autoScrollToElementOffsetTop || 0;
3907
+ }
3908
+
3909
+ getRequiredChip() {
3910
+ const {
3911
+ requiredChip
3912
+ } = this;
3913
+ return requiredChip && requiredChip();
3914
+ }
3915
+
3916
+ dialog(...args) {
3917
+ return this.stack.dialog(...args);
3918
+ }
3919
+
3920
+ alert(...args) {
3921
+ return this.stack.alert(...args);
3922
+ }
3923
+
3924
+ confirm(...args) {
3925
+ return this.stack.confirm(...args);
3926
+ }
3927
+
3928
+ snackbar(...args) {
3929
+ return this.stack.snackbar(...args);
3930
+ }
3931
+
3932
+ prompt(rawOptions = {}) {
3933
+ const options = typeof rawOptions === 'string' ? {
3934
+ input: {
3935
+ label: rawOptions
3936
+ }
3937
+ } : { ...rawOptions
3938
+ };
3939
+ options.input = { ...options.input
3940
+ };
3941
+ options.dense = true;
3942
+ let {
3943
+ initialValue: value = ''
3944
+ } = options.input;
3945
+ const {
3946
+ size
3947
+ } = options.input;
3948
+ delete options.input.initialValue;
3949
+ let form;
3950
+ options.actions = options.actions || [this.stack.action('cancel', undefined, {
3951
+ size
3952
+ }), this.stack.action('ok', undefined, {
3953
+ size,
3954
+ onClick: () => {
3955
+ if (form) {
3956
+ const ev = new Event('submit');
3957
+ form.handleSubmit(ev);
3958
+ }
3959
+ }
3960
+ })];
3961
+ const resolved = resolveVStackDynamicInput({ ...options,
3962
+ content: stack => {
3963
+ return createVNode(VForm, {
3964
+ "disableAutoScroll": true,
3965
+ "size": size,
3966
+ "onVnodeMounted": vnode => {
3967
+ form = vnode.component.ctx.form;
3968
+ },
3969
+ "onVnodeBeforeUnmount": () => {
3970
+ form = undefined;
3971
+ },
3972
+ "onSubmit": ev => {
3973
+ stack.resolve(value);
3974
+ }
3975
+ }, {
3976
+ default: () => [createVNode(VTextField, mergeProps(options.input, {
3977
+ "modelValue": value,
3978
+ "onChange": ev => {
3979
+ stack.value = ev;
3980
+ value = ev;
3981
+ }
3982
+ }), null)]
3983
+ });
3984
+ }
3985
+ });
3986
+ return this.dialog(resolved);
3987
+ }
3988
+
3433
3989
  }
3434
3990
 
3435
3991
  class VuiPlugin {
@@ -3473,7 +4029,7 @@ class VuiPlugin {
3473
4029
  ...stack
3474
4030
  }); // Vui
3475
4031
 
3476
- const $vui = new VuiService(opts);
4032
+ const $vui = new VuiService(opts, app.config.globalProperties.$vstack);
3477
4033
  app.provide(VuiInjectionKey, $vui);
3478
4034
  app.config.globalProperties.$vui = $vui;
3479
4035
 
@@ -3489,4 +4045,4 @@ function installVuiPlugin(app, opts) {
3489
4045
  return app.use(VuiPlugin, opts);
3490
4046
  }
3491
4047
 
3492
- export { CONTROL_FIELD_VARIANTS, CONTROL_SIZES, PAGINATION_ALIGNS, VApp, VBreadcrumbs, VButton, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSwitch, VSwitchGroup, VTabs, VTextField, VTextarea, VToolbar, VToolbarEdge, VToolbarMenu, VToolbarTitle, VUI_CHECKBOX_GROUP_SYMBOL, VUI_CHECKBOX_SYMBOL, VUI_FORM_SYMBOL, VUI_OPTION_SYMBOL, VUI_RADIO_GROUP_SYMBOL, VUI_RADIO_SYMBOL, VUI_SELECT_SYMBOL, VUI_SWITCH_GROUP_SYMBOL, VUI_SWITCH_SYMBOL, VUI_TEXTAREA_SYMBOL, VUI_TEXT_FIELD_SYMBOL, VuiColorProviderInjectionKey, VuiControlFieldInjectionKey, VuiControlInjectionKey, VuiInjectionKey, VuiPlugin, VuiService, configureDataTableDefaults, createCardProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };
4048
+ export { CONTROL_FIELD_VARIANTS, CONTROL_SIZES, PAGINATION_ALIGNS, VApp, VBreadcrumbs, VButton, VButtonGroup, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSwitch, VSwitchGroup, VTabs, VTextField, VTextarea, VToolbar, VToolbarEdge, VToolbarMenu, VToolbarTitle, VUI_CHECKBOX_GROUP_SYMBOL, VUI_CHECKBOX_SYMBOL, VUI_FORM_SYMBOL, VUI_OPTION_SYMBOL, VUI_RADIO_GROUP_SYMBOL, VUI_RADIO_SYMBOL, VUI_SELECT_SYMBOL, VUI_SWITCH_GROUP_SYMBOL, VUI_SWITCH_SYMBOL, VUI_TEXTAREA_SYMBOL, VUI_TEXT_FIELD_SYMBOL, VUI_WYSIWYG_EDITOR_SYMBOL, VWysiwygEditor, VuiColorProviderInjectionKey, VuiControlFieldInjectionKey, VuiControlInjectionKey, VuiInjectionKey, VuiPlugin, VuiService, WysiwygBulletListTool, WysiwygFormatBoldTool, WysiwygFormatItalicTool, WysiwygFormatUnderlineTool, WysiwygHistoryTool, WysiwygLinkTool, WysiwygOrderedListTool, WysiwygTextColorTool, configureDataTableDefaults, createCardProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };