@fastkit/vui 0.7.54 → 0.7.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vui.mjs CHANGED
@@ -1,13 +1,13 @@
1
- import { createPropsOptions, createFormControlSettings, defineSlotsProps, useFormControl, VTooltip, 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';
1
+ import { createPropsOptions, createFormControlSettings, defineSlotsProps, useFormControl, VTooltip, renderSlotOrEmpty, createFormSelectorSettings, createFormControlProps, useFormSelectorControl, resolveVNodeChildOrSlots, createFormSelectorItemSettings, useFormSelectorItemControl, createFormSelectorItemGroupProps, useFormSelectorItemGroupControl, 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, VTooltip } from '@fastkit/vue-kit';
4
4
  import { inject, computed, provide, createVNode, mergeProps, defineComponent, isVNode, ref, watch, onMounted, onBeforeUnmount, cloneVNode, withDirectives, createTextVNode, Fragment, vShow, onBeforeUpdate, vModelSelect, Transition, reactive } from 'vue';
5
5
  import { useRouter, RouterLink, useLink, useRoute } from 'vue-router';
6
6
  import { createPropsOptions as createPropsOptions$1, renderSlotOrEmpty as renderSlotOrEmpty$1, defineSlotsProps as defineSlotsProps$1, htmlAttributesPropOptions, navigationableInheritProps, useNavigationable, VLink, isFragment, rawNumberPropType, resolveNumberish, resizeDirectiveArgument, VExpandTransition, LocationService, setDefaultRouterLink } from '@fastkit/vue-utils';
7
7
  import { getDocumentScroller as getDocumentScroller$1 } from '@fastkit/vue-scroller';
8
- import { useScopeColorClass, colorSchemeProps, useColorClasses, toScopeColorClass } from '@fastkit/vue-color-scheme';
9
8
  import { VProgressCircular } from '@fastkit/vue-loading';
10
9
  export * from '@fastkit/vue-loading';
10
+ import { useScopeColorClass, colorSchemeProps, useColorClasses, toScopeColorClass } from '@fastkit/vue-color-scheme';
11
11
  import { loadImage, IN_WINDOW, isPromise } from '@fastkit/helpers';
12
12
  export { ICON_NAMES } from '@fastkit/icon-font';
13
13
  import { VAppContainer, VAppLayoutControl } from '@fastkit/vue-app-layout';
@@ -24,7 +24,12 @@ import { validateIf, url } from '@fastkit/rules';
24
24
  import { OrderedList } from '@tiptap/extension-ordered-list';
25
25
 
26
26
  const CONTROL_SIZES = ['sm', 'md', 'lg'];
27
- const CONTROL_FIELD_VARIANTS = ['outlined', 'filled', 'flat'];
27
+ const CONTROL_FIELD_VARIANTS = ['outlined', 'filled', 'flat'];
28
+ const CONTROL_LOADING_SPINNER_SIZES = {
29
+ sm: 16,
30
+ md: 20,
31
+ lg: 24,
32
+ };
28
33
 
29
34
  const VuiInjectionKey = Symbol();
30
35
  const VuiControlInjectionKey = Symbol();
@@ -79,6 +84,7 @@ function createControlProps() {
79
84
  return CONTROL_SIZES.includes(value);
80
85
  },
81
86
  },
87
+ loading: Boolean,
82
88
  });
83
89
  }
84
90
  function useControl(props, opts = {}) {
@@ -230,7 +236,8 @@ function createRequiredChipRenderer(required, props, vui = useVui()) {
230
236
  const VFormControl = defineComponent({
231
237
  name: 'VFormControl',
232
238
  props: { ...props$8,
233
- ...defineSlotsProps()
239
+ ...defineSlotsProps(),
240
+ error: Boolean
234
241
  },
235
242
  emits: emits$8,
236
243
 
@@ -271,7 +278,7 @@ const VFormControl = defineComponent({
271
278
  'v-form-control--untouched': control.untouched,
272
279
  'v-form-control--invalid': control.invalid,
273
280
  'v-form-control--valid': control.valid
274
- }, colorProvider.className(control.invalid && !control.readonly ? 'error' : 'primary')]);
281
+ }, colorProvider.className(props.error ? 'error' : control.invalid && !control.readonly ? 'error' : 'primary')]);
275
282
  const getRequiredChip = createRequiredChipRenderer(() => control.required, props, vui);
276
283
  return () => {
277
284
  const label = control.renderLabel();
@@ -334,6 +341,10 @@ function defineFormSelectorComponent(opts) {
334
341
  type: Boolean,
335
342
  default: true
336
343
  },
344
+ // eslint-disable-next-line vue/require-prop-types
345
+ loadingMessage: {},
346
+ // eslint-disable-next-line vue/require-prop-types
347
+ failedToLoadItemsMessage: {},
337
348
  ...defineSlotsProps()
338
349
  },
339
350
  emits,
@@ -344,8 +355,19 @@ function defineFormSelectorComponent(opts) {
344
355
  defaultMultiple
345
356
  });
346
357
  const control = useControl(props);
358
+ const vui = useVui();
359
+ const loadingMessageRef = computed(() => {
360
+ const slot = resolveVNodeChildOrSlots(props.loadingMessage, vui.setting('loadingMessage'), 'Loading...');
361
+ return slot && slot(vui);
362
+ });
363
+ const failedToLoadItemsMessageRef = computed(() => {
364
+ const slot = resolveVNodeChildOrSlots(props.failedToLoadItemsMessage, vui.setting('failedToLoadDataMessage'), 'Failed to load data.');
365
+ return slot && slot(vui);
366
+ });
347
367
  return { ...selectorControl.expose(),
348
- ...control
368
+ ...control,
369
+ loadingMessageRef,
370
+ failedToLoadItemsMessageRef
349
371
  };
350
372
  },
351
373
 
@@ -363,11 +385,22 @@ function defineFormSelectorComponent(opts) {
363
385
  "label": this.label,
364
386
  "hint": this.hint,
365
387
  "hinttip": this.hinttip,
366
- "requiredChip": this.requiredChip
388
+ "requiredChip": this.requiredChip,
389
+ "error": selectorControl.itemsLoadFailed
367
390
  }, { ...this.$slots,
368
391
  default: () => createVNode("div", {
369
392
  "class": "v-form-selector__body"
370
- }, [this.propItems.map(attrs => {
393
+ }, [selectorControl.itemsLoadFailed && createVNode("div", {
394
+ "key": "failed",
395
+ "class": "v-form-selector__placeholder v-form-selector__placeholder--error"
396
+ }, [this.failedToLoadItemsMessageRef]), selectorControl.itemsLoading && createVNode("div", {
397
+ "key": "loading",
398
+ "class": "v-form-selector__placeholder"
399
+ }, [createVNode(VProgressCircular, {
400
+ "indeterminate": true,
401
+ "class": "mr-1",
402
+ "size": CONTROL_LOADING_SPINNER_SIZES[this.size || 'md']
403
+ }, null), this.loadingMessageRef]), this.propItems.map(attrs => {
371
404
  const selected = selectorControl.isSelected(attrs.value);
372
405
  return itemRenderer({
373
406
  selected,
@@ -1107,7 +1140,6 @@ const vueButtonProps = createPropsOptions$1({ ...htmlAttributesPropOptions,
1107
1140
  ...colorSchemeProps(),
1108
1141
  ...navigationableInheritProps,
1109
1142
  spacer: [Boolean, String],
1110
- loading: Boolean,
1111
1143
  rounded: Boolean,
1112
1144
  icon: [String, Function],
1113
1145
  startIcon: [String, Function],
@@ -2333,7 +2365,8 @@ const VControlField = defineComponent({
2333
2365
  props: { ...createControlFieldProps(),
2334
2366
  focused: Boolean,
2335
2367
  autoHeight: Boolean,
2336
- ...defineSlotsProps()
2368
+ ...defineSlotsProps(),
2369
+ error: Boolean
2337
2370
  },
2338
2371
  // _slots: inputBoxSlots,
2339
2372
  emits: {
@@ -2357,11 +2390,11 @@ const VControlField = defineComponent({
2357
2390
  const classes = computed(() => {
2358
2391
  const classes = ['v-control-field', `v-control-field--${inputBox.variant.value}`, {
2359
2392
  'v-control-field--disabled': disabled.value,
2360
- 'v-control-field--invalid': invalid.value,
2393
+ 'v-control-field--invalid': invalid.value || props.error,
2361
2394
  'v-control-field--readonly': readonly.value,
2362
2395
  'v-control-field--focused': props.focused,
2363
2396
  'v-control-field--auto-height': autoHeight.value
2364
- }, control.classes.value, colorProvider.className(invalid.value && !readonly.value ? 'error' : 'primary')];
2397
+ }, control.classes.value, colorProvider.className(props.error ? 'error' : invalid.value && !readonly.value ? 'error' : 'primary')];
2365
2398
  return classes;
2366
2399
  });
2367
2400
  const resolvedSlots = computed(() => {
@@ -2374,11 +2407,21 @@ const VControlField = defineComponent({
2374
2407
  });
2375
2408
 
2376
2409
  const renderAdornment = position => {
2377
- const result = renderSlotOrEmpty(resolvedSlots.value, position);
2378
- if (!result) return;
2410
+ let child;
2411
+
2412
+ if (position === 'end' && props.loading) {
2413
+ child = createVNode(VProgressCircular, {
2414
+ "indeterminate": true,
2415
+ "size": CONTROL_LOADING_SPINNER_SIZES[props.size || 'md']
2416
+ }, null);
2417
+ } else {
2418
+ child = renderSlotOrEmpty(resolvedSlots.value, position);
2419
+ }
2420
+
2421
+ if (!child) return;
2379
2422
  return createVNode("div", {
2380
2423
  "class": ['v-control-field__adornment', `v-control-field__adornment--${position}`]
2381
- }, [result]);
2424
+ }, [child]);
2382
2425
  };
2383
2426
 
2384
2427
  const handleClick = ev => {
@@ -2421,7 +2464,9 @@ const VSelect = defineComponent({
2421
2464
  ...createControlProps(),
2422
2465
  ...defineSlotsProps(),
2423
2466
  ...createPropsOptions({
2424
- placeholder: String
2467
+ placeholder: String,
2468
+ loadingMessage: {},
2469
+ failedToLoadItemsMessage: {}
2425
2470
  })
2426
2471
  },
2427
2472
  emits: emits$3,
@@ -2448,6 +2493,14 @@ const VSelect = defineComponent({
2448
2493
  const vui = useVui();
2449
2494
  const iconName = vui.icon('menuDown');
2450
2495
  const fieldRef = ref(null);
2496
+ const loadingMessageRef = computed(() => {
2497
+ const slot = resolveVNodeChildOrSlots(props.loadingMessage, vui.setting('loadingMessage'), 'Loading...');
2498
+ return slot && slot(vui);
2499
+ });
2500
+ const failedToLoadItemsMessageRef = computed(() => {
2501
+ const slot = resolveVNodeChildOrSlots(props.failedToLoadItemsMessage, vui.setting('failedToLoadDataMessage'), 'Failed to load data.');
2502
+ return slot && slot(vui);
2503
+ });
2451
2504
 
2452
2505
  const focus = opts => {
2453
2506
  fieldRef.value && fieldRef.value.focus(opts);
@@ -2456,7 +2509,15 @@ const VSelect = defineComponent({
2456
2509
  const renderSelections = selectedItems => {
2457
2510
  const children = [];
2458
2511
 
2459
- if (selectedItems.length) {
2512
+ if (inputControl.itemsLoadFailed) {
2513
+ children.push(createVNode("span", {
2514
+ "class": "v-select__placeholder"
2515
+ }, [failedToLoadItemsMessageRef.value]));
2516
+ } else if (inputControl.itemsLoading) {
2517
+ children.push(createVNode("span", {
2518
+ "class": "v-select__placeholder"
2519
+ }, [loadingMessageRef.value]));
2520
+ } else if (selectedItems.length) {
2460
2521
  selectedItems.forEach((item, index) => {
2461
2522
  if (index > 0) {
2462
2523
  children.push(vui.selectionSeparator());
@@ -2531,8 +2592,11 @@ const VSelect = defineComponent({
2531
2592
  }) => [createVNode(VControlField, {
2532
2593
  "class": "v-select__input",
2533
2594
  "ref": this.fieldRef(),
2595
+ "loading": selectorControl.itemsLoading,
2596
+ "error": selectorControl.itemsLoadFailed,
2534
2597
  "startAdornment": this.startAdornment,
2535
2598
  "endAdornment": this.endAdornment,
2599
+ "size": this.size,
2536
2600
  "focused": this.menuOpened,
2537
2601
  "onClick": ev => {
2538
2602
  if (this.canOperation && !control.isActive) {
@@ -2572,19 +2636,37 @@ const VSelect = defineComponent({
2572
2636
  }, [createVNode("div", {
2573
2637
  "class": "v-select__selections__inner"
2574
2638
  }, [this.renderSelections(selectedItems)])])],
2575
- endAdornment: () => this.clearable && this.nodeControl.value != null && createVNode(VButton, {
2576
- "key": "clear",
2577
- "icon": this.$vui.icon('clear'),
2578
- "rounded": true,
2579
- "onClick": ev => {
2580
- ev.stopPropagation();
2581
- this.nodeControl.clear();
2639
+ endAdornment: () => {
2640
+ if (selectorControl.itemsLoadFailed) {
2641
+ return createVNode(VButton, {
2642
+ "key": "reload",
2643
+ "icon": this.$vui.icon('reload'),
2644
+ "rounded": true,
2645
+ "onClick": ev => {
2646
+ ev.stopPropagation();
2647
+ selectorControl.loadItems();
2648
+ }
2649
+ }, null);
2650
+ }
2651
+
2652
+ if (this.clearable && this.nodeControl.value != null) {
2653
+ return createVNode(VButton, {
2654
+ "key": "clear",
2655
+ "icon": this.$vui.icon('clear'),
2656
+ "rounded": true,
2657
+ "onClick": ev => {
2658
+ ev.stopPropagation();
2659
+ this.nodeControl.clear();
2660
+ }
2661
+ }, null);
2582
2662
  }
2583
- }, null) || createVNode(VIcon, {
2584
- "key": "icon",
2585
- "name": this.iconName,
2586
- "rotate": this.menuOpened ? 180 : 0
2587
- }, null)
2663
+
2664
+ return createVNode(VIcon, {
2665
+ "key": "icon",
2666
+ "name": this.iconName,
2667
+ "rotate": this.menuOpened ? 180 : 0
2668
+ }, null);
2669
+ }
2588
2670
  })]
2589
2671
  })
2590
2672
  });
@@ -2661,7 +2743,8 @@ const VTextField = defineComponent({
2661
2743
  default: () => createVNode(VControlField, {
2662
2744
  "class": "v-text-field__input",
2663
2745
  "startAdornment": this.startAdornment,
2664
- "endAdornment": this.endAdornment
2746
+ "endAdornment": this.endAdornment,
2747
+ "size": this.size
2665
2748
  }, { ...this.$slots,
2666
2749
  default: () => this.textInputControl.createInputElement({
2667
2750
  class: 'v-text-field__input__element'
@@ -2765,6 +2848,7 @@ const VTextarea = defineComponent({
2765
2848
  }, { ...this.$slots,
2766
2849
  default: () => createVNode(VControlField, {
2767
2850
  "class": "v-textarea__input",
2851
+ "size": this.size,
2768
2852
  "autoHeight": true,
2769
2853
  "startAdornment": this.startAdornment,
2770
2854
  "endAdornment": this.endAdornment
@@ -2860,8 +2944,8 @@ const VWysiwygEditor = defineComponent({
2860
2944
  watch(() => inputControl.canOperation, updateEditable);
2861
2945
  watch(() => props.modelValue, modelValue => {
2862
2946
  const $editor = editor.value;
2863
- if (!$editor) return;
2864
- $editor.commands.setContent(modelValue == null ? '' : modelValue);
2947
+ if (!$editor || $editor.getHTML() === modelValue) return;
2948
+ $editor.commands.setContent(modelValue == null ? '' : modelValue, false);
2865
2949
  textRef.value = $editor.getText();
2866
2950
  });
2867
2951
  const editor = useEditor({
@@ -3004,7 +3088,8 @@ const VWysiwygEditor = defineComponent({
3004
3088
  "class": "v-wysiwyg-editor__input",
3005
3089
  "autoHeight": true,
3006
3090
  "startAdornment": this.startAdornment,
3007
- "endAdornment": this.endAdornment
3091
+ "endAdornment": this.endAdornment,
3092
+ "size": this.size
3008
3093
  }, { ...this.$slots,
3009
3094
  default: () => {
3010
3095
  let _slot2;
@@ -4051,7 +4136,7 @@ const VDataTable = defineComponent({
4051
4136
  message = props.noDataMessage || vui.setting('noDataMessage') || 'No data was available.'; // データはありませんでした。
4052
4137
  }
4053
4138
 
4054
- return typeof message === 'function' ? message() : message;
4139
+ return typeof message === 'function' ? message(vui) : message;
4055
4140
  });
4056
4141
  const classesRef = computed(() => [{
4057
4142
  'v-data-table--fixed-header': props.fixedHeader
@@ -4956,4 +5041,4 @@ function installVuiPlugin(app, opts) {
4956
5041
  return app.use(VuiPlugin, opts);
4957
5042
  }
4958
5043
 
4959
- export { AVATAR_SIZES, CHIP_SIZES, CONTROL_FIELD_VARIANTS, CONTROL_SIZES, PAGINATION_ALIGNS, VApp, VAvatar, VBreadcrumbs, VBusyImage, VButton, VButtonGroup, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VChip, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VFormControl, VGridContainer, VGridItem, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VNumberField, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSkeltonLoaderBone, 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, createAvatarProps, createCardProps, createChipProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, createRequiredChipRenderer, createVFormProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, mergeVuiPluginOptions, mergeVuiServiceIconSettings, mergeVuiServiceOptions, mergeVuiServiceUISettings, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, resolveRawWysiwygEditorTools, splitAttrs, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };
5044
+ export { AVATAR_SIZES, CHIP_SIZES, CONTROL_FIELD_VARIANTS, CONTROL_LOADING_SPINNER_SIZES, CONTROL_SIZES, PAGINATION_ALIGNS, VApp, VAvatar, VBreadcrumbs, VBusyImage, VButton, VButtonGroup, VCard, VCardActions, VCardContent, VCheckbox, VCheckboxGroup, VChip, VContentSwitcher, VDataTable, VDrawerLayout, VForm, VFormControl, VGridContainer, VGridItem, VHero, VIcon, VListTile, VNavigation, VNavigationItem, VNumberField, VOption, VOptionGroup, VPagination, VPaper, VRadio, VRadioGroup, VSelect, VSkeltonLoaderBone, 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, createAvatarProps, createCardProps, createChipProps, createControlFieldProviderProps, createControlProps, createElevationProps, createListTileProps, createNavigationItemProps, createPaperBaseProps, createPaperProps, createRequiredChipRenderer, createVFormProps, defineFormSelectorComponent, iconProps, installVuiPlugin, listTileEmits, mergeVuiPluginOptions, mergeVuiServiceIconSettings, mergeVuiServiceOptions, mergeVuiServiceUISettings, paginationProps, rawIconProp, renderNavigationItemInput, resolveNavigationItemInput, resolveRawIconProp, resolveRawWysiwygEditorTools, splitAttrs, useControl, useControlField, useElevation, useVui, useVuiColorProvider, vueButtonProps };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastkit/vui",
3
- "version": "0.7.54",
3
+ "version": "0.7.57",
4
4
  "description": "@fastkit/vui",
5
5
  "buildOptions": {
6
6
  "name": "Vui",
@@ -32,11 +32,11 @@
32
32
  "vue": "^3.2.26"
33
33
  },
34
34
  "dependencies": {
35
- "@fastkit/color-scheme": "0.7.54",
36
- "@fastkit/icon-font": "0.7.54",
37
- "@fastkit/tiny-logger": "0.7.54",
38
- "@fastkit/vite-kit": "0.7.54",
39
- "@fastkit/vue-kit": "0.7.54",
35
+ "@fastkit/color-scheme": "0.7.57",
36
+ "@fastkit/icon-font": "0.7.57",
37
+ "@fastkit/tiny-logger": "0.7.57",
38
+ "@fastkit/vite-kit": "0.7.57",
39
+ "@fastkit/vue-kit": "0.7.57",
40
40
  "@tiptap/extension-link": "^2.0.0-beta.36",
41
41
  "@tiptap/extension-underline": "^2.0.0-beta.23",
42
42
  "@tiptap/starter-kit": "^2.0.0-beta.183",
package/src/.DS_Store ADDED
Binary file
Binary file
@@ -50,7 +50,6 @@ export const vueButtonProps = createPropsOptions({
50
50
  ...colorSchemeProps(),
51
51
  ...navigationableInheritProps,
52
52
  spacer: [Boolean, String] as PropType<RawVButtonSpacer>,
53
- loading: Boolean,
54
53
  rounded: Boolean,
55
54
  icon: [String, Function] as PropType<RawVButtonIcon>,
56
55
  startIcon: [String, Function] as PropType<RawVButtonIcon>,
@@ -1,5 +1,5 @@
1
1
  import './VControlField.scss';
2
- import { computed, PropType, ref, defineComponent } from 'vue';
2
+ import { computed, PropType, ref, defineComponent, VNodeChild } from 'vue';
3
3
  import {
4
4
  useParentFormNode,
5
5
  VNodeChildOrSlot,
@@ -16,6 +16,8 @@ import {
16
16
  useControlField,
17
17
  } from '../../composables';
18
18
  import { useVuiColorProvider } from '../../injections';
19
+ import { VProgressCircular } from '../loading';
20
+ import { CONTROL_LOADING_SPINNER_SIZES } from '../../schemes';
19
21
 
20
22
  const ADORNMENT_POSITIONS = ['start', 'end'] as const;
21
23
 
@@ -56,6 +58,7 @@ export const VControlField = defineComponent({
56
58
  focused: Boolean,
57
59
  autoHeight: Boolean,
58
60
  ...defineSlotsProps<InputBoxSlots>(),
61
+ error: Boolean,
59
62
  },
60
63
  // _slots: inputBoxSlots,
61
64
  emits: {
@@ -83,14 +86,18 @@ export const VControlField = defineComponent({
83
86
  `v-control-field--${inputBox.variant.value}`,
84
87
  {
85
88
  'v-control-field--disabled': disabled.value,
86
- 'v-control-field--invalid': invalid.value,
89
+ 'v-control-field--invalid': invalid.value || props.error,
87
90
  'v-control-field--readonly': readonly.value,
88
91
  'v-control-field--focused': props.focused,
89
92
  'v-control-field--auto-height': autoHeight.value,
90
93
  },
91
94
  control.classes.value,
92
95
  colorProvider.className(
93
- invalid.value && !readonly.value ? 'error' : 'primary',
96
+ props.error
97
+ ? 'error'
98
+ : invalid.value && !readonly.value
99
+ ? 'error'
100
+ : 'primary',
94
101
  ),
95
102
  ];
96
103
  return classes;
@@ -106,15 +113,25 @@ export const VControlField = defineComponent({
106
113
  });
107
114
 
108
115
  const renderAdornment = (position: AdornmentPosition) => {
109
- const result = renderSlotOrEmpty(resolvedSlots.value, position);
110
- if (!result) return;
116
+ let child: VNodeChild | undefined;
117
+ if (position === 'end' && props.loading) {
118
+ child = (
119
+ <VProgressCircular
120
+ indeterminate
121
+ size={CONTROL_LOADING_SPINNER_SIZES[props.size || 'md']}
122
+ />
123
+ );
124
+ } else {
125
+ child = renderSlotOrEmpty(resolvedSlots.value, position);
126
+ }
127
+ if (!child) return;
111
128
  return (
112
129
  <div
113
130
  class={[
114
131
  'v-control-field__adornment',
115
132
  `v-control-field__adornment--${position}`,
116
133
  ]}>
117
- {result}
134
+ {child}
118
135
  </div>
119
136
  );
120
137
  };
@@ -20,7 +20,7 @@ import { VPagination } from '../VPagination';
20
20
  import { VCheckbox } from '../VCheckbox';
21
21
  import { VIcon, resolveRawIconProp } from '../VIcon';
22
22
  import { VProgressCircular } from '../loading';
23
- import { resizeDirectiveArgument } from '@fastkit/vue-utils';
23
+ import { resizeDirectiveArgument, VNodeChildOrSlot } from '@fastkit/vue-utils';
24
24
  import { VAppLayoutControl } from '@fastkit/vue-app-layout';
25
25
  import { VPaper } from '../VPaper';
26
26
 
@@ -182,9 +182,9 @@ export const VDataTable = defineComponent({
182
182
  fixedHeader: Boolean,
183
183
  maxHeight: [Number, String],
184
184
  // eslint-disable-next-line vue/require-prop-types
185
- noDataMessage: {} as PropType<VNodeChild | (() => VNodeChild)>,
185
+ noDataMessage: {} as PropType<VNodeChildOrSlot>,
186
186
  // eslint-disable-next-line vue/require-prop-types
187
- noResultsMessage: {} as PropType<VNodeChild | (() => VNodeChild)>,
187
+ noResultsMessage: {} as PropType<VNodeChildOrSlot>,
188
188
  },
189
189
  emits: {
190
190
  input: (selecteds: string[]) => true,
@@ -233,7 +233,7 @@ export const VDataTable = defineComponent({
233
233
  });
234
234
 
235
235
  const emptyMessage = computed(() => {
236
- let message: VNodeChild | (() => VNodeChild);
236
+ let message: VNodeChildOrSlot;
237
237
  if (searchQueryValues.value.length) {
238
238
  message =
239
239
  props.noResultsMessage ||
@@ -245,7 +245,7 @@ export const VDataTable = defineComponent({
245
245
  vui.setting('noDataMessage') ||
246
246
  'No data was available.'; // データはありませんでした。
247
247
  }
248
- return typeof message === 'function' ? message() : message;
248
+ return typeof message === 'function' ? message(vui) : message;
249
249
  });
250
250
 
251
251
  const classesRef = computed(() => [
@@ -51,6 +51,7 @@ export const VFormControl = defineComponent({
51
51
  default: FormControl;
52
52
  }
53
53
  >(),
54
+ error: Boolean,
54
55
  },
55
56
  emits,
56
57
  setup(props, ctx) {
@@ -94,7 +95,11 @@ export const VFormControl = defineComponent({
94
95
  'v-form-control--valid': control.valid,
95
96
  },
96
97
  colorProvider.className(
97
- control.invalid && !control.readonly ? 'error' : 'primary',
98
+ props.error
99
+ ? 'error'
100
+ : control.invalid && !control.readonly
101
+ ? 'error'
102
+ : 'primary',
98
103
  ),
99
104
  ]);
100
105
 
@@ -1,5 +1,5 @@
1
1
  import './VSelect.scss';
2
- import { ref, VNodeChild, defineComponent } from 'vue';
2
+ import { ref, VNodeChild, defineComponent, PropType, computed } from 'vue';
3
3
  import {
4
4
  createFormSelectorSettings,
5
5
  useFormSelectorControl,
@@ -8,6 +8,8 @@ import {
8
8
  FormControlSlots,
9
9
  FormSelectorItemControl,
10
10
  createPropsOptions,
11
+ VNodeChildOrSlot,
12
+ resolveVNodeChildOrSlots,
11
13
  } from '@fastkit/vue-kit';
12
14
  import { VFormControl } from '../VFormControl';
13
15
  import {
@@ -40,6 +42,8 @@ export const VSelect = defineComponent({
40
42
  ...defineSlotsProps<FormControlSlots & InputBoxSlots>(),
41
43
  ...createPropsOptions({
42
44
  placeholder: String,
45
+ loadingMessage: {} as PropType<VNodeChildOrSlot>,
46
+ failedToLoadItemsMessage: {} as PropType<VNodeChildOrSlot>,
43
47
  }),
44
48
  },
45
49
  emits,
@@ -62,6 +66,22 @@ export const VSelect = defineComponent({
62
66
  const vui = useVui();
63
67
  const iconName = vui.icon('menuDown');
64
68
  const fieldRef = ref<HTMLElement | null>(null);
69
+ const loadingMessageRef = computed(() => {
70
+ const slot = resolveVNodeChildOrSlots(
71
+ props.loadingMessage,
72
+ vui.setting('loadingMessage'),
73
+ 'Loading...',
74
+ );
75
+ return slot && slot(vui);
76
+ });
77
+ const failedToLoadItemsMessageRef = computed(() => {
78
+ const slot = resolveVNodeChildOrSlots(
79
+ props.failedToLoadItemsMessage,
80
+ vui.setting('failedToLoadDataMessage'),
81
+ 'Failed to load data.',
82
+ );
83
+ return slot && slot(vui);
84
+ });
65
85
 
66
86
  const focus = (opts?: FocusOptions): void => {
67
87
  fieldRef.value && fieldRef.value.focus(opts);
@@ -69,7 +89,17 @@ export const VSelect = defineComponent({
69
89
 
70
90
  const renderSelections = (selectedItems: FormSelectorItemControl[]) => {
71
91
  const children: VNodeChild[] = [];
72
- if (selectedItems.length) {
92
+ if (inputControl.itemsLoadFailed) {
93
+ children.push(
94
+ <span class="v-select__placeholder">
95
+ {failedToLoadItemsMessageRef.value}
96
+ </span>,
97
+ );
98
+ } else if (inputControl.itemsLoading) {
99
+ children.push(
100
+ <span class="v-select__placeholder">{loadingMessageRef.value}</span>,
101
+ );
102
+ } else if (selectedItems.length) {
73
103
  selectedItems.forEach((item, index) => {
74
104
  if (index > 0) {
75
105
  children.push(vui.selectionSeparator());
@@ -136,9 +166,12 @@ export const VSelect = defineComponent({
136
166
  <VControlField
137
167
  class="v-select__input"
138
168
  ref={this.fieldRef()}
169
+ loading={selectorControl.itemsLoading}
170
+ error={selectorControl.itemsLoadFailed}
139
171
  startAdornment={this.startAdornment}
140
172
  endAdornment={this.endAdornment}
141
173
  // tabindex={this.computedTabindex}
174
+ size={this.size}
142
175
  focused={this.menuOpened}
143
176
  onClick={(ev) => {
144
177
  if (this.canOperation && !control.isActive) {
@@ -185,24 +218,43 @@ export const VSelect = defineComponent({
185
218
  </div>
186
219
  </div>,
187
220
  ],
188
- endAdornment: () =>
189
- (this.clearable && this.nodeControl.value != null && (
190
- <VButton
191
- key="clear"
192
- icon={this.$vui.icon('clear')}
193
- rounded
194
- onClick={(ev) => {
195
- ev.stopPropagation();
196
- this.nodeControl.clear();
197
- }}
198
- />
199
- )) || (
221
+ endAdornment: () => {
222
+ if (selectorControl.itemsLoadFailed) {
223
+ return (
224
+ <VButton
225
+ key="reload"
226
+ icon={this.$vui.icon('reload')}
227
+ rounded
228
+ onClick={(ev) => {
229
+ ev.stopPropagation();
230
+ selectorControl.loadItems();
231
+ }}
232
+ />
233
+ );
234
+ }
235
+
236
+ if (this.clearable && this.nodeControl.value != null) {
237
+ return (
238
+ <VButton
239
+ key="clear"
240
+ icon={this.$vui.icon('clear')}
241
+ rounded
242
+ onClick={(ev) => {
243
+ ev.stopPropagation();
244
+ this.nodeControl.clear();
245
+ }}
246
+ />
247
+ );
248
+ }
249
+
250
+ return (
200
251
  <VIcon
201
252
  key="icon"
202
253
  name={this.iconName}
203
254
  rotate={this.menuOpened ? 180 : 0}
204
255
  />
205
- ),
256
+ );
257
+ },
206
258
  }}
207
259
  />,
208
260
  ],
@@ -82,6 +82,7 @@ export const VTextField = defineComponent({
82
82
  class="v-text-field__input"
83
83
  startAdornment={this.startAdornment}
84
84
  endAdornment={this.endAdornment}
85
+ size={this.size}
85
86
  v-slots={{
86
87
  ...this.$slots,
87
88
  default: () =>
@@ -68,6 +68,7 @@ export const VTextarea = defineComponent({
68
68
  default: () => (
69
69
  <VControlField
70
70
  class="v-textarea__input"
71
+ size={this.size}
71
72
  autoHeight
72
73
  startAdornment={this.startAdornment}
73
74
  endAdornment={this.endAdornment}