@fastkit/vui 0.6.28 → 0.6.33

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.cjs.js CHANGED
@@ -3,14 +3,15 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var vueKit = require('@fastkit/vue-kit');
6
+ var vueRouter = require('vue-router');
6
7
  var vueUtils = require('@fastkit/vue-utils');
7
8
  var vue = require('vue');
8
9
  var vueColorScheme = require('@fastkit/vue-color-scheme');
9
10
  var vueLoading = require('@fastkit/vue-loading');
10
11
  var iconFont = require('@fastkit/icon-font');
11
12
  var helpers = require('@fastkit/helpers');
12
- var vueRouter = require('vue-router');
13
13
  var vueAppLayout = require('@fastkit/vue-app-layout');
14
+ var vueScroller = require('@fastkit/vue-scroller');
14
15
 
15
16
  const CONTROL_SIZES = ['sm', 'md', 'lg'];
16
17
  const CONTROL_FIELD_VARIANTS = ['outlined', 'filled', 'flat'];
@@ -434,7 +435,7 @@ function resolveRawVButtonIcon(raw, type = 'main') {
434
435
  }
435
436
 
436
437
  const vueButtonProps = vueUtils.createPropsOptions({ ...vueColorScheme.colorSchemeProps(),
437
- ...vueUtils.navigationableProps,
438
+ ...vueUtils.navigationableInheritProps,
438
439
  spacer: [Boolean, String],
439
440
  loading: Boolean,
440
441
  rounded: Boolean,
@@ -450,9 +451,8 @@ const LOADING_SIZE_MAP = {
450
451
  };
451
452
  const VButton = vue.defineComponent({
452
453
  name: 'VButton',
454
+ inheritAttrs: false,
453
455
  props: vueButtonProps,
454
- emits: { ...vueUtils.navigationableEmits
455
- },
456
456
 
457
457
  setup(props, ctx) {
458
458
  const vui = useVui();
@@ -478,48 +478,25 @@ const VButton = vue.defineComponent({
478
478
  variant: () => props.variant || (icon.value ? vui.setting('plainVariant') : defaults.variant)
479
479
  });
480
480
  const isPlain = vue.computed(() => color.variant.value.value === vui.setting('plainVariant') && color.color.value.value === defaults.color);
481
- const navigationable = vueUtils.useNavigationable(props);
482
- const isLoading = vue.computed(() => props.loading);
483
- const isDisabled = vue.computed(() => props.disabled);
481
+ const isLoading = vue.computed(() => props.loading); // const isDisabled = computed(() => props.disabled);
482
+
484
483
  const isRounded = vue.computed(() => props.rounded || !!icon.value);
485
484
  const spacer = vue.computed(() => {
486
485
  const _spacer = props.spacer;
487
486
  if (!_spacer) return;
488
487
  return _spacer === true ? 'left' : _spacer;
489
488
  });
490
- const classes = vue.computed(() => [color.colorClasses.value, navigationable.value.classes, spacer.value ? `v-button--spacer-${spacer.value}` : undefined, `v-button--${control.size.value}`, {
489
+ const classes = vue.computed(() => [color.colorClasses.value, // navigationable.value.classes,
490
+ spacer.value ? `v-button--spacer-${spacer.value}` : undefined, `v-button--${control.size.value}`, {
491
491
  'v-button--loading': isLoading.value,
492
492
  'v-button--icon': !!icon.value,
493
493
  'v-button--rounded': isRounded.value,
494
494
  'v-button--plain': isPlain.value
495
495
  }]);
496
496
  return () => {
497
- const {
498
- Tag,
499
- attrs
500
- } = navigationable.value;
501
- const children = vueUtils.renderSlotOrEmpty(ctx.slots, 'default');
502
- const _attrs = { ...attrs
503
- };
504
-
505
- if (isDisabled.value) {
506
- _attrs.disabled = true;
507
- }
508
-
509
- return vue.createVNode(Tag, vue.mergeProps({
497
+ const children = vueUtils.renderSlotOrEmpty(ctx.slots);
498
+ return vue.createVNode(vueUtils.VLink, vue.mergeProps(ctx.attrs, {
510
499
  "class": ['v-button', classes.value]
511
- }, _attrs, {
512
- "onClick": ev => {
513
- if (isDisabled.value || isLoading.value) {
514
- ev.preventDefault();
515
-
516
- if (isDisabled.value) {
517
- return;
518
- }
519
- }
520
-
521
- ctx.emit('click', ev);
522
- }
523
500
  }), {
524
501
  default: () => [vue.createVNode("span", {
525
502
  "class": "v-button__content"
@@ -534,7 +511,7 @@ const VButton = vue.defineComponent({
534
511
 
535
512
  });
536
513
 
537
- function _isSlot$8(s) {
514
+ function _isSlot$c(s) {
538
515
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
539
516
  }
540
517
 
@@ -782,7 +759,7 @@ const VPagination = vue.defineComponent({
782
759
  "class": classes,
783
760
  "to": to,
784
761
  "key": key
785
- }, _isSlot$8(children) ? children : {
762
+ }, _isSlot$c(children) ? children : {
786
763
  default: () => [children]
787
764
  });
788
765
  } else {
@@ -829,11 +806,11 @@ const VPagination = vue.defineComponent({
829
806
 
830
807
  function createListTileProps() {
831
808
  const icon = rawIconProp();
832
- return { ...vueUtils.navigationableProps,
809
+ return { ...vueUtils.navigationableInheritProps,
833
810
  ...vueUtils.createPropsOptions({
834
811
  startIcon: icon,
835
812
  endIcon: icon,
836
- fallbackTag: {
813
+ linkFallbackTag: {
837
814
  type: String,
838
815
  default: 'div'
839
816
  },
@@ -843,11 +820,12 @@ function createListTileProps() {
843
820
  })
844
821
  };
845
822
  }
846
- const listTileEmits = { ...vueUtils.navigationableEmits,
823
+ const listTileEmits = {
847
824
  changeActive: isActive => true
848
825
  };
849
826
  const VListTile = vue.defineComponent({
850
827
  name: 'VListTile',
828
+ inheritAttrs: false,
851
829
  props: createListTileProps(),
852
830
  emits: { ...listTileEmits
853
831
  },
@@ -863,10 +841,9 @@ const VListTile = vue.defineComponent({
863
841
  return icon;
864
842
  });
865
843
  const endIcon = vue.computed(() => resolveRawIconProp(false, props.endIcon));
866
- const navigationable = vueUtils.useNavigationable(props, () => props.fallbackTag, ctx);
867
- const hasTo = vue.computed(() => !!props.to);
844
+ const hasTo = vue.computed(() => !!ctx.attrs.to);
868
845
  const link = vueRouter.useLink({
869
- to: props.to || ''
846
+ to: ctx.attrs.to || ''
870
847
  });
871
848
  const isActive = vue.computed(() => {
872
849
  if (!hasTo.value) return false;
@@ -876,10 +853,7 @@ const VListTile = vue.defineComponent({
876
853
  const classes = vue.computed(() => {
877
854
  const _color = color.value;
878
855
  const hasColor = !!_color.value;
879
- const _navigationable = navigationable.value;
880
- const clickable = _navigationable.clickable;
881
- return [color.value.className, _navigationable.classes, {
882
- 'v-list-tile--clickable': clickable,
856
+ return [color.value.className, {
883
857
  'v-list-tile--plain': !hasColor,
884
858
  'v-list-tile--has-color': hasColor,
885
859
  'v-list-tile--active': isActive.value
@@ -893,16 +867,9 @@ const VListTile = vue.defineComponent({
893
867
  return () => {
894
868
  const _startIcon = startIcon.value;
895
869
  const _endIcon = endIcon.value;
896
- const {
897
- Tag,
898
- attrs
899
- } = navigationable.value;
900
- return vue.createVNode(Tag, vue.mergeProps({
901
- "class": ['v-list-tile', classes.value]
902
- }, attrs, {
903
- "onClick": ev => {
904
- ctx.emit('click', ev);
905
- }
870
+ return vue.createVNode(vueUtils.VLink, vue.mergeProps(ctx.attrs, {
871
+ "class": ['v-list-tile', classes.value],
872
+ "clickableClassName": "v-list-tile--clickable"
906
873
  }), {
907
874
  default: () => [_startIcon && vue.createVNode("span", {
908
875
  "class": "v-list-tile__icon v-list-tile__icon--start"
@@ -947,7 +914,7 @@ const VDrawerLayout = vue.defineComponent({
947
914
 
948
915
  });
949
916
 
950
- function _isSlot$7(s) {
917
+ function _isSlot$b(s) {
951
918
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
952
919
  }
953
920
 
@@ -982,7 +949,7 @@ const VHero = vue.defineComponent({
982
949
  }, {
983
950
  default: () => [vue.createVNode(HTagName, {
984
951
  "class": "v-hero__title"
985
- }, _isSlot$7(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
952
+ }, _isSlot$b(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
986
953
  default: () => [_slot]
987
954
  })]
988
955
  })]
@@ -992,13 +959,17 @@ const VHero = vue.defineComponent({
992
959
 
993
960
  });
994
961
 
995
- function _isSlot$6(s) {
962
+ function _isSlot$a(s) {
996
963
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
997
964
  }
998
965
 
999
966
  function createNavigationItemProps() {
1000
967
  return { ...createListTileProps(),
1001
- match: String
968
+ match: String // key: {
969
+ // type: [String, Number],
970
+ // required: true,
971
+ // },
972
+
1002
973
  };
1003
974
  }
1004
975
  function resolveNavigationItemInput(input) {
@@ -1023,7 +994,7 @@ function renderNavigationItemInput(input, extraProps) {
1023
994
  } = resolveNavigationItemInput(input);
1024
995
  return vue.createVNode(VNavigationItem, { ...props,
1025
996
  ...extraProps
1026
- }, _isSlot$6(label) ? label : {
997
+ }, _isSlot$a(label) ? label : {
1027
998
  default: () => [label]
1028
999
  });
1029
1000
  }
@@ -1043,7 +1014,7 @@ const VNavigationItem = vue.defineComponent({
1043
1014
  const c = props.children;
1044
1015
  return c && c.length ? c : undefined;
1045
1016
  });
1046
- const to = vue.computed(() => props.to);
1017
+ const to = vue.computed(() => ctx.attrs.to);
1047
1018
  const match = vue.computed(() => {
1048
1019
  const {
1049
1020
  match,
@@ -1118,6 +1089,7 @@ const VNavigationItem = vue.defineComponent({
1118
1089
  });
1119
1090
 
1120
1091
  function open() {
1092
+ if (!children.value) return;
1121
1093
  opened.value = true;
1122
1094
  }
1123
1095
 
@@ -1131,10 +1103,13 @@ const VNavigationItem = vue.defineComponent({
1131
1103
 
1132
1104
  const onClick = ev => {
1133
1105
  if (!to.value) {
1134
- toggle();
1106
+ return toggle();
1135
1107
  }
1136
1108
 
1137
- ctx.emit('click', ev);
1109
+ open(); // if (!to.value) {
1110
+ // toggle();
1111
+ // }
1112
+ // ctx.emit('click', ev);
1138
1113
  };
1139
1114
 
1140
1115
  const onChangeActive = isActive => {
@@ -1156,18 +1131,21 @@ const VNavigationItem = vue.defineComponent({
1156
1131
  ctx.emit('changeActive', isActive);
1157
1132
  };
1158
1133
 
1134
+ ctx.expose({
1135
+ close
1136
+ });
1159
1137
  return () => {
1160
1138
  let _slot;
1161
1139
 
1162
1140
  const _children = children.value;
1163
1141
  const fallbackTag = _children ? 'button' : undefined;
1164
- return vue.createVNode(vue.Fragment, null, [vue.createVNode(VListTile, vue.mergeProps(_props.value, {
1142
+ return vue.createVNode(vue.Fragment, null, [vue.createVNode(VListTile, vue.mergeProps(ctx.attrs, _props.value, {
1165
1143
  "fallbackTag": fallbackTag,
1166
1144
  "endIcon": _props.value.endIcon,
1167
1145
  "class": ['v-navigation-item', classes.value],
1168
1146
  "onClick": onClick,
1169
1147
  "onChangeActive": onChangeActive
1170
- }), _isSlot$6(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1148
+ }), _isSlot$a(_slot = vueUtils.renderSlotOrEmpty(ctx.slots, 'default')) ? _slot : {
1171
1149
  default: () => [_slot]
1172
1150
  }), _children && vue.createVNode(vueUtils.VExpandTransition, null, {
1173
1151
  default: () => [vue.withDirectives(vue.createVNode("div", {
@@ -1207,6 +1185,28 @@ const VNavigation = vue.defineComponent({
1207
1185
  const c = props.caption;
1208
1186
  return typeof c === 'function' ? c() : c;
1209
1187
  });
1188
+ const itemsRef = vue.ref([]);
1189
+ vue.onBeforeUpdate(() => {
1190
+ itemsRef.value = [];
1191
+ });
1192
+
1193
+ function setItemRef(item, itemRef) {
1194
+ itemsRef.value.push({
1195
+ key: item.key,
1196
+ ref: itemRef
1197
+ });
1198
+ }
1199
+
1200
+ function onItemActivated(item) {
1201
+ itemsRef.value.forEach(({
1202
+ key,
1203
+ ref
1204
+ }) => {
1205
+ if (key === item.key) return;
1206
+ ref.close();
1207
+ });
1208
+ }
1209
+
1210
1210
  return () => {
1211
1211
  const $caption = caption.value;
1212
1212
  return vue.createVNode("nav", {
@@ -1215,7 +1215,17 @@ const VNavigation = vue.defineComponent({
1215
1215
  "class": "v-navigation__caption"
1216
1216
  }, [$caption]), items.value.map(item => renderNavigationItemInput(item, {
1217
1217
  class: 'v-navigation__item',
1218
- startIconEmptySpace: startIconEmptySpace.value
1218
+ startIconEmptySpace: startIconEmptySpace.value,
1219
+ ref: ref => {
1220
+ setItemRef(item, ref);
1221
+ },
1222
+ onChangeActive: isActive => {
1223
+ if (isActive
1224
+ /* && item.children && item.children.length*/
1225
+ ) {
1226
+ onItemActivated(item);
1227
+ }
1228
+ }
1219
1229
  }))]);
1220
1230
  };
1221
1231
  }
@@ -1315,7 +1325,7 @@ const VCheckbox = vue.defineComponent({
1315
1325
 
1316
1326
  });
1317
1327
 
1318
- function _isSlot$5(s) {
1328
+ function _isSlot$9(s) {
1319
1329
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1320
1330
  }
1321
1331
 
@@ -1327,7 +1337,7 @@ const VCheckboxGroup = defineFormSelectorComponent({
1327
1337
  itemRenderer: ({
1328
1338
  attrs,
1329
1339
  slots
1330
- }) => vue.createVNode(VCheckbox, attrs, _isSlot$5(slots) ? slots : {
1340
+ }) => vue.createVNode(VCheckbox, attrs, _isSlot$9(slots) ? slots : {
1331
1341
  default: () => [slots]
1332
1342
  })
1333
1343
  });
@@ -1379,7 +1389,7 @@ const VRadio = vue.defineComponent({
1379
1389
 
1380
1390
  });
1381
1391
 
1382
- function _isSlot$4(s) {
1392
+ function _isSlot$8(s) {
1383
1393
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1384
1394
  }
1385
1395
 
@@ -1390,7 +1400,7 @@ const VRadioGroup = defineFormSelectorComponent({
1390
1400
  itemRenderer: ({
1391
1401
  attrs,
1392
1402
  slots
1393
- }) => vue.createVNode(VRadio, attrs, _isSlot$4(slots) ? slots : {
1403
+ }) => vue.createVNode(VRadio, attrs, _isSlot$8(slots) ? slots : {
1394
1404
  default: () => [slots]
1395
1405
  })
1396
1406
  });
@@ -1452,7 +1462,7 @@ const VSwitch = vue.defineComponent({
1452
1462
 
1453
1463
  });
1454
1464
 
1455
- function _isSlot$3(s) {
1465
+ function _isSlot$7(s) {
1456
1466
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1457
1467
  }
1458
1468
 
@@ -1464,7 +1474,7 @@ const VSwitchGroup = defineFormSelectorComponent({
1464
1474
  itemRenderer: ({
1465
1475
  attrs,
1466
1476
  slots
1467
- }) => vue.createVNode(VSwitch, attrs, _isSlot$3(slots) ? slots : {
1477
+ }) => vue.createVNode(VSwitch, attrs, _isSlot$7(slots) ? slots : {
1468
1478
  default: () => [slots]
1469
1479
  })
1470
1480
  });
@@ -2023,6 +2033,597 @@ const VForm = vue.defineComponent({
2023
2033
 
2024
2034
  });
2025
2035
 
2036
+ function _isSlot$6(s) {
2037
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2038
+ }
2039
+
2040
+ const VTab = vue.defineComponent({
2041
+ name: 'VTab',
2042
+ props: {
2043
+ value: {
2044
+ type: String,
2045
+ required: true
2046
+ },
2047
+ active: Boolean,
2048
+ to: [String, Object],
2049
+ icon: [String, Function]
2050
+ },
2051
+ emits: {
2052
+ click: ev => true
2053
+ },
2054
+
2055
+ setup(props, ctx) {
2056
+ const classesRef = vue.computed(() => ({
2057
+ 'v-tab--active': props.active
2058
+ }));
2059
+ const exposeValues = {
2060
+ value: props.value,
2061
+ active: props.active
2062
+ };
2063
+ ctx.expose(exposeValues);
2064
+ return () => {
2065
+ const {
2066
+ to,
2067
+ value,
2068
+ icon,
2069
+ active
2070
+ } = props;
2071
+ const classes = ['v-tab', classesRef.value];
2072
+
2073
+ const children = vue.createVNode("span", {
2074
+ "class": "v-tab__content"
2075
+ }, [icon && resolveRawIconProp(active, icon, {
2076
+ class: 'v-tab__icon'
2077
+ }), vueUtils.renderSlotOrEmpty(ctx.slots)]);
2078
+
2079
+ if (to) {
2080
+ const replace = typeof to === 'string' ? undefined : to.replace;
2081
+ return vue.createVNode(vueRouter.RouterLink, {
2082
+ "class": classes,
2083
+ "to": to,
2084
+ "replace": replace
2085
+ }, _isSlot$6(children) ? children : {
2086
+ default: () => [children]
2087
+ });
2088
+ } else {
2089
+ return vue.createVNode("button", {
2090
+ "class": classes,
2091
+ "type": "button",
2092
+ "value": value,
2093
+ "onClick": ev => {
2094
+ ctx.emit('click', ev);
2095
+ }
2096
+ }, [children]);
2097
+ }
2098
+ };
2099
+ }
2100
+
2101
+ });
2102
+
2103
+ function _isSlot$5(s) {
2104
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2105
+ }
2106
+
2107
+ const VTabs = vue.defineComponent({
2108
+ name: 'VTabs',
2109
+ props: {
2110
+ modelValue: String,
2111
+ items: {
2112
+ type: Array,
2113
+ required: true // validator: (value: VTabsItem[]) => {
2114
+ // return Array.isArray(value) && value.length > 0;
2115
+ // },
2116
+
2117
+ },
2118
+
2119
+ /**
2120
+ * 自動スクロールする際の余剰オフセット幅(px)
2121
+ */
2122
+ autoScrollOffset: {
2123
+ type: Number,
2124
+ default: 20
2125
+ },
2126
+
2127
+ /**
2128
+ * ルーター同期する場合設定する
2129
+ */
2130
+ router: Function,
2131
+
2132
+ /**
2133
+ * ルーティング連携を行う際に、クエリベースのURLマッチングを行う
2134
+ * タブのURLが /page1?tab=xxx のようになる時に設定する
2135
+ */
2136
+ withQuery: Boolean,
2137
+ ...vueUtils.defineSlotsProps(),
2138
+ color: String
2139
+ },
2140
+ emits: {
2141
+ 'update:modelValue': newValue => true,
2142
+ change: newValue => true
2143
+ },
2144
+
2145
+ setup(props, ctx) {
2146
+ const vui = useVui();
2147
+ const internalValueRef = vue.ref(null);
2148
+ const scrollerRef = vueKit.useVScrollerRef();
2149
+ const elRef = vue.ref(null);
2150
+ let scrollResult;
2151
+ const tabRefs = vue.ref([]);
2152
+ const currentRef = vue.computed({
2153
+ get: () => internalValueRef.value,
2154
+ set: value => {
2155
+ if (internalValueRef.value !== value) {
2156
+ internalValueRef.value = value;
2157
+ ctx.emit('update:modelValue', value);
2158
+ ctx.emit('change', value);
2159
+ }
2160
+ }
2161
+ });
2162
+ const colorScope = vueColorScheme.useScopeColorClass({
2163
+ color: () => props.color || vui.setting('tabDefault').color
2164
+ });
2165
+ const classes = vue.computed(() => [colorScope.value.className]);
2166
+ const computedItemsRef = vue.computed(() => {
2167
+ const current = currentRef.value;
2168
+ const {
2169
+ router
2170
+ } = props;
2171
+ return props.items.map(item => {
2172
+ const {
2173
+ value
2174
+ } = item;
2175
+ const active = current === value;
2176
+ let location;
2177
+
2178
+ if (router) {
2179
+ const to = router(value);
2180
+ const route = vui.router.resolve(to);
2181
+ location = {
2182
+ to,
2183
+ route
2184
+ };
2185
+ }
2186
+
2187
+ return { ...item,
2188
+ active,
2189
+ location
2190
+ };
2191
+ });
2192
+ });
2193
+
2194
+ const setTabRef = ref => {
2195
+ tabRefs.value.push(ref);
2196
+ }; // const isMountedRef = ref(false);
2197
+
2198
+
2199
+ function setupInternalValue(routable) {
2200
+ let value = props.modelValue;
2201
+
2202
+ if (value == null || value === '') {
2203
+ const firstItem = props.items[0];
2204
+ if (!firstItem) return;
2205
+ value = firstItem.value;
2206
+ }
2207
+
2208
+ if (internalValueRef.value !== value) {
2209
+ internalValueRef.value = value;
2210
+
2211
+ if (routable) {
2212
+ const {
2213
+ router
2214
+ } = props;
2215
+ if (!router) return;
2216
+ const hit = computedItemsRef.value.find(item => item.value === value);
2217
+ if (!hit) return;
2218
+ const {
2219
+ location
2220
+ } = hit;
2221
+ if (!location) return;
2222
+ const {
2223
+ to,
2224
+ route
2225
+ } = location;
2226
+ if (route.fullPath === vui.location.currentRoute.fullPath) return;
2227
+ vui.router[to.replace ? 'replace' : 'push'](to);
2228
+ } else if (!props.router && props.modelValue !== value) {
2229
+ ctx.emit('update:modelValue', value);
2230
+ ctx.emit('change', value);
2231
+ }
2232
+ }
2233
+ }
2234
+
2235
+ function to(value) {
2236
+ currentRef.value = value;
2237
+ }
2238
+
2239
+ function cancelScroll() {
2240
+ if (scrollResult) {
2241
+ scrollResult.cancel();
2242
+ scrollResult = undefined;
2243
+ }
2244
+ }
2245
+
2246
+ const findTab = tab => {
2247
+ return tabRefs.value.find(t => t.value === tab);
2248
+ };
2249
+
2250
+ function scrollToTab(tabValue) {
2251
+ const tab = findTab(tabValue);
2252
+ if (!tab) return;
2253
+ const $tab = tab.$el;
2254
+ if (!$tab) return;
2255
+ const scroller = scrollerRef.value;
2256
+ if (!scroller) return;
2257
+ const container = scroller.scroller.element();
2258
+ if (!container) return;
2259
+ const {
2260
+ autoScrollOffset
2261
+ } = props;
2262
+ const tabLeft = $tab.offsetLeft;
2263
+ const tabWidth = $tab.offsetWidth;
2264
+ const tabRight = tabLeft + tabWidth;
2265
+ let hiddenLeft = 0;
2266
+ let hiddenRight = 0;
2267
+ const {
2268
+ scrollLeft,
2269
+ offsetWidth: scrollerWidth
2270
+ } = container;
2271
+ hiddenLeft = Math.max(scrollLeft - tabLeft, 0);
2272
+ hiddenRight = Math.max(tabRight - scrollerWidth - scrollLeft, 0);
2273
+ if (hiddenLeft > 0) hiddenLeft += autoScrollOffset;
2274
+ if (hiddenRight > 0) hiddenRight += autoScrollOffset;
2275
+ let scrollAmmount = 0;
2276
+
2277
+ if (hiddenRight > 0) {
2278
+ scrollAmmount = hiddenRight;
2279
+ }
2280
+
2281
+ if (hiddenLeft > 0) {
2282
+ scrollAmmount = -hiddenLeft;
2283
+ }
2284
+
2285
+ if (Math.abs(scrollAmmount) > 0) {
2286
+ cancelScroll();
2287
+ scrollResult = scroller.scroller.by(scrollAmmount, 0, {
2288
+ duration: 150
2289
+ });
2290
+ }
2291
+ }
2292
+
2293
+ vue.watch(() => props.modelValue, () => setupInternalValue(true));
2294
+ vue.watch(() => props.items, () => setupInternalValue(), {
2295
+ deep: true
2296
+ });
2297
+ vue.watch(() => internalValueRef.value, newValue => {
2298
+ scrollToTab(newValue);
2299
+ });
2300
+ vui.location.watchRoute(route => {
2301
+ if (!props.router) return;
2302
+ const path = props.withQuery ? route.fullPath : route.path;
2303
+ const hit = computedItemsRef.value.find(({
2304
+ location
2305
+ }) => {
2306
+ return location && location.route.fullPath === path;
2307
+ });
2308
+
2309
+ if (hit) {
2310
+ currentRef.value = hit.value;
2311
+ }
2312
+ }, {
2313
+ immediate: true
2314
+ });
2315
+ vue.onMounted(() => {
2316
+ scrollToTab(currentRef.value);
2317
+ });
2318
+ vue.onBeforeUnmount(() => {
2319
+ cancelScroll();
2320
+ });
2321
+ vue.onBeforeUpdate(() => {
2322
+ tabRefs.value = [];
2323
+ });
2324
+ setupInternalValue();
2325
+ return () => {
2326
+ const items = computedItemsRef.value;
2327
+ const itemSlot = ctx.slots.item;
2328
+ const children = items.map(({
2329
+ value,
2330
+ active,
2331
+ label,
2332
+ icon,
2333
+ location
2334
+ }) => {
2335
+ if (!label) {
2336
+ label = itemSlot;
2337
+ }
2338
+
2339
+ const children = typeof label === 'function' ? label({
2340
+ value,
2341
+ active,
2342
+ vui
2343
+ }) : label;
2344
+
2345
+ const _to = location && location.to || undefined;
2346
+
2347
+ return vue.createVNode(VTab, {
2348
+ "value": value,
2349
+ "to": _to,
2350
+ "icon": icon,
2351
+ "active": active,
2352
+ "ref": setTabRef,
2353
+ "onClick": e => {
2354
+ if (!e.defaultPrevented) {
2355
+ to(value);
2356
+ }
2357
+ }
2358
+ }, _isSlot$5(children) ? children : {
2359
+ default: () => [children]
2360
+ });
2361
+ });
2362
+ return vue.createVNode("div", {
2363
+ "class": ['v-tabs', classes.value],
2364
+ "ref": elRef
2365
+ }, [vue.createVNode(vueKit.VScroller, {
2366
+ "class": "v-tabs__scroller",
2367
+ "containerClass": "v-tabs__scroller__container",
2368
+ "guide": true,
2369
+ "ref": scrollerRef
2370
+ }, {
2371
+ default: () => [vue.createVNode("div", {
2372
+ "class": "v-tabs__content"
2373
+ }, [children])]
2374
+ })]);
2375
+ };
2376
+ }
2377
+
2378
+ });
2379
+
2380
+ function _isSlot$4(s) {
2381
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2382
+ }
2383
+
2384
+ const VBreadcrumbs = vue.defineComponent({
2385
+ name: 'VBreadcrumbs',
2386
+ props: {
2387
+ items: {
2388
+ type: Array,
2389
+ default: () => []
2390
+ },
2391
+ divider: [String, Function] // ...defineSlotsProps<{}>(),
2392
+
2393
+ },
2394
+
2395
+ setup(props, ctx) {
2396
+ const vui = useVui();
2397
+ const computedItemsRef = vue.computed(() => {
2398
+ const items = props.items.map(rawItem => {
2399
+ return typeof rawItem === 'string' ? {
2400
+ text: rawItem
2401
+ } : rawItem;
2402
+ });
2403
+ return items.map(item => {
2404
+ const {
2405
+ to,
2406
+ text
2407
+ } = item;
2408
+ const {
2409
+ disabled = vui.location.match(to) || !vui.location.isAvairable(to)
2410
+ } = item;
2411
+ return { ...item,
2412
+ disabled,
2413
+ text: typeof text === 'function' ? text(vui) : text
2414
+ };
2415
+ });
2416
+ });
2417
+ const lengthRef = vue.computed(() => computedItemsRef.value.length);
2418
+
2419
+ const defaultDividerSlot = () => {
2420
+ return [vue.createVNode("i", {
2421
+ "class": "v-breadcrumbs__divider__icon"
2422
+ }, null)];
2423
+ };
2424
+
2425
+ return () => {
2426
+ if (lengthRef.value < 1) return;
2427
+ let dividerSlot;
2428
+ const propDivider = props.divider;
2429
+
2430
+ if (propDivider) {
2431
+ dividerSlot = typeof propDivider === 'function' ? propDivider : () => propDivider;
2432
+ } else {
2433
+ dividerSlot = defaultDividerSlot;
2434
+ }
2435
+
2436
+ const children = [];
2437
+ computedItemsRef.value.forEach((item, index) => {
2438
+ const {
2439
+ text,
2440
+ icon,
2441
+ disabled,
2442
+ to
2443
+ } = item;
2444
+
2445
+ if (index > 0) {
2446
+ const divider = dividerSlot(vui);
2447
+
2448
+ if (divider) {
2449
+ children.push(vue.createVNode("li", {
2450
+ "class": "v-breadcrumbs__divider",
2451
+ "key": `divider-${index}`
2452
+ }, [divider]));
2453
+ }
2454
+ }
2455
+
2456
+ const myChildren = [];
2457
+
2458
+ if (icon) {
2459
+ const $icon = resolveRawIconProp(false, icon, {
2460
+ class: 'v-breadcrumbs__icon'
2461
+ });
2462
+
2463
+ if ($icon) {
2464
+ myChildren.push($icon);
2465
+ }
2466
+ }
2467
+
2468
+ if (text) myChildren.push(text);
2469
+ const itemChild = to ? vue.createVNode(vueUtils.VLink, {
2470
+ "class": "v-breadcrumbs__link",
2471
+ "to": to,
2472
+ "exactActiveClass": "v-breadcrumbs__link--active"
2473
+ }, _isSlot$4(myChildren) ? myChildren : {
2474
+ default: () => [myChildren]
2475
+ }) : myChildren;
2476
+ children.push(vue.createVNode("li", {
2477
+ "class": ['v-breadcrumbs__item', {
2478
+ 'v-breadcrumbs__item--disabled': disabled
2479
+ }],
2480
+ "key": `link-${index}`
2481
+ }, [itemChild]));
2482
+ });
2483
+ return vue.createVNode("nav", {
2484
+ "class": "v-breadcrumbs"
2485
+ }, [vue.createVNode("ul", {
2486
+ "class": "v-breadcrumbs__list"
2487
+ }, [children])]);
2488
+ };
2489
+ }
2490
+
2491
+ });
2492
+
2493
+ function _isSlot$3(s) {
2494
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2495
+ }
2496
+
2497
+ const VContentSwitcher = vue.defineComponent({
2498
+ name: 'VContentSwitcher',
2499
+ props: {
2500
+ modelValue: String,
2501
+ order: {
2502
+ type: Array,
2503
+ default: () => []
2504
+ },
2505
+ autotop: [Boolean, Object]
2506
+ },
2507
+ emits: {
2508
+ 'update:modelValue': modelValue => true
2509
+ },
2510
+
2511
+ setup(props, ctx) {
2512
+ const internalValueRef = vue.ref('');
2513
+ const transitionRef = vue.ref('');
2514
+ const elRef = vue.ref(null);
2515
+ const anchorRef = vue.ref(null);
2516
+ const computedOrderRef = vue.computed(() => props.order.map(row => {
2517
+ return typeof row === 'string' ? row : row.value;
2518
+ }));
2519
+ const currentRef = vue.computed({
2520
+ get: () => internalValueRef.value,
2521
+ set: current => {
2522
+ if (internalValueRef.value !== current) {
2523
+ internalValueRef.value = current;
2524
+ ctx.emit('update:modelValue', current);
2525
+ }
2526
+ }
2527
+ });
2528
+ const autotopSettingsRef = vue.computed(() => {
2529
+ let {
2530
+ autotop: settings
2531
+ } = props;
2532
+ if (settings === true) settings = {};
2533
+ if (!settings) return;
2534
+ return { ...settings
2535
+ };
2536
+ });
2537
+
2538
+ function seeTop(options) {
2539
+ const scoller = vueScroller.getDocumentScroller();
2540
+ const {
2541
+ value: anchor
2542
+ } = anchorRef;
2543
+
2544
+ if (anchor) {
2545
+ scoller.toElement(anchor, options);
2546
+ }
2547
+ }
2548
+
2549
+ function getEl() {
2550
+ const el = elRef.value;
2551
+
2552
+ if (!el) {
2553
+ throw new Error('missing element');
2554
+ }
2555
+
2556
+ return el;
2557
+ }
2558
+
2559
+ vue.watch(() => props.modelValue, (value, beforeValue) => {
2560
+ if (value == null) return;
2561
+ internalValueRef.value = value;
2562
+ if (beforeValue == null) return;
2563
+ const order = computedOrderRef.value;
2564
+ const index = order.indexOf(value);
2565
+ const beforeIndex = order.indexOf(beforeValue);
2566
+ let transition = 'fade';
2567
+
2568
+ if (index !== -1 && beforeIndex !== -1) {
2569
+ if (index > beforeIndex) transition = 'v-content-switcher-next';
2570
+ if (index < beforeIndex) transition = 'v-content-switcher-prev';
2571
+ }
2572
+
2573
+ transitionRef.value = transition;
2574
+ }, {
2575
+ immediate: true
2576
+ });
2577
+ vue.watch(currentRef, () => {
2578
+ const autotopSettings = autotopSettingsRef.value;
2579
+
2580
+ if (autotopSettings && props.modelValue != null) {
2581
+ seeTop(autotopSettings);
2582
+ }
2583
+ });
2584
+ return () => {
2585
+ const current = currentRef.value;
2586
+ const children = vueUtils.renderSlotOrEmpty(ctx.slots) || [];
2587
+ const currentSlot = ctx.slots[current];
2588
+
2589
+ if (currentSlot) {
2590
+ children.push(vue.createVNode("div", {
2591
+ "class": "v-content-switcher__content",
2592
+ "key": current
2593
+ }, [currentSlot(this)]));
2594
+ }
2595
+
2596
+ return vue.createVNode("div", {
2597
+ "class": "v-content-switcher",
2598
+ "ref": elRef
2599
+ }, [vue.createVNode("div", {
2600
+ "class": "v-content-switcher__anchor",
2601
+ "ref": anchorRef
2602
+ }, null), vue.createVNode(vue.Transition, {
2603
+ "name": transitionRef.value,
2604
+ "onBeforeLeave": el => {
2605
+ getEl().style.height = el.offsetHeight + 'px';
2606
+ },
2607
+ "onEnter": el => {
2608
+ getEl().style.height = el.offsetHeight + 'px';
2609
+ },
2610
+ "onAfterEnter": () => {
2611
+ getEl().style.height = '';
2612
+ },
2613
+ "onEnterCancelled": () => {
2614
+ getEl().style.height = '';
2615
+ },
2616
+ "onLeaveCancelled": () => {
2617
+ getEl().style.height = '';
2618
+ }
2619
+ }, _isSlot$3(children) ? children : {
2620
+ default: () => [children]
2621
+ })]);
2622
+ };
2623
+ }
2624
+
2625
+ });
2626
+
2026
2627
  const DATA_TABLE_DEFAULTS = {
2027
2628
  itemKey: 'id',
2028
2629
  pageQuery: 'page',
@@ -2795,6 +3396,7 @@ class VuiService {
2795
3396
  location;
2796
3397
  constructor(options) {
2797
3398
  this.options = options;
3399
+ this.configure();
2798
3400
  const { selectionSeparator = () => ', ', autoScrollToElementOffsetTop = DEFAULT_AUTO_SCROLL_TO_ELEMENT_OFFSET_TOP, textareaRows = DEFAULT_TEXTAREA_ROWS, requiredChip = () => '*', } = options;
2799
3401
  this.selectionSeparator = selectionSeparator;
2800
3402
  this.autoScrollToElementOffsetTop = autoScrollToElementOffsetTop;
@@ -2805,6 +3407,13 @@ class VuiService {
2805
3407
  router: this.router,
2806
3408
  });
2807
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
+ }
2808
3417
  setting(key) {
2809
3418
  return this.options.uiSettings[key];
2810
3419
  }
@@ -2889,12 +3498,14 @@ exports.CONTROL_FIELD_VARIANTS = CONTROL_FIELD_VARIANTS;
2889
3498
  exports.CONTROL_SIZES = CONTROL_SIZES;
2890
3499
  exports.PAGINATION_ALIGNS = PAGINATION_ALIGNS;
2891
3500
  exports.VApp = VApp;
3501
+ exports.VBreadcrumbs = VBreadcrumbs;
2892
3502
  exports.VButton = VButton;
2893
3503
  exports.VCard = VCard;
2894
3504
  exports.VCardActions = VCardActions;
2895
3505
  exports.VCardContent = VCardContent;
2896
3506
  exports.VCheckbox = VCheckbox;
2897
3507
  exports.VCheckboxGroup = VCheckboxGroup;
3508
+ exports.VContentSwitcher = VContentSwitcher;
2898
3509
  exports.VDataTable = VDataTable;
2899
3510
  exports.VDrawerLayout = VDrawerLayout;
2900
3511
  exports.VForm = VForm;
@@ -2912,6 +3523,7 @@ exports.VRadioGroup = VRadioGroup;
2912
3523
  exports.VSelect = VSelect;
2913
3524
  exports.VSwitch = VSwitch;
2914
3525
  exports.VSwitchGroup = VSwitchGroup;
3526
+ exports.VTabs = VTabs;
2915
3527
  exports.VTextField = VTextField;
2916
3528
  exports.VTextarea = VTextarea;
2917
3529
  exports.VToolbar = VToolbar;