sprintify-ui 0.10.12 → 0.10.14

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.
Files changed (58) hide show
  1. package/dist/sprintify-ui.es.js +15478 -15451
  2. package/dist/types/components/BaseActionButtons.vue.d.ts +13 -0
  3. package/dist/types/components/BaseAlert.vue.d.ts +1 -1
  4. package/dist/types/components/BaseAssign.vue.d.ts +2 -2
  5. package/dist/types/components/BaseAutocomplete.vue.d.ts +8 -8
  6. package/dist/types/components/BaseAutocompleteFetch.vue.d.ts +18 -18
  7. package/dist/types/components/BaseBadge.vue.d.ts +2 -2
  8. package/dist/types/components/BaseBelongsTo.vue.d.ts +18 -18
  9. package/dist/types/components/BaseBelongsToFetch.vue.d.ts +11 -11
  10. package/dist/types/components/BaseButton.vue.d.ts +2 -2
  11. package/dist/types/components/BaseButtonGroup.vue.d.ts +3 -3
  12. package/dist/types/components/BaseColor.vue.d.ts +2 -2
  13. package/dist/types/components/BaseCounter.vue.d.ts +1 -1
  14. package/dist/types/components/BaseDataIterator.vue.d.ts +2 -2
  15. package/dist/types/components/BaseDataTable.vue.d.ts +18 -14
  16. package/dist/types/components/BaseDatePicker.vue.d.ts +3 -3
  17. package/dist/types/components/BaseDateSelect.vue.d.ts +2 -2
  18. package/dist/types/components/BaseDialog.vue.d.ts +9 -9
  19. package/dist/types/components/BaseDropdownAutocomplete.vue.d.ts +2 -2
  20. package/dist/types/components/BaseField.vue.d.ts +2 -2
  21. package/dist/types/components/BaseFieldI18n.vue.d.ts +1 -1
  22. package/dist/types/components/BaseFileUploader.vue.d.ts +1 -1
  23. package/dist/types/components/BaseHasMany.vue.d.ts +18 -18
  24. package/dist/types/components/BaseHasManyFetch.vue.d.ts +7 -7
  25. package/dist/types/components/BaseHeader.vue.d.ts +4 -1
  26. package/dist/types/components/BaseInput.vue.d.ts +2 -2
  27. package/dist/types/components/BaseInputPercent.vue.d.ts +2 -2
  28. package/dist/types/components/BaseLoadingCover.vue.d.ts +1 -1
  29. package/dist/types/components/BaseMediaLibrary.vue.d.ts +1 -1
  30. package/dist/types/components/BaseMenu.vue.d.ts +2 -2
  31. package/dist/types/components/BaseMenuItem.vue.d.ts +4 -4
  32. package/dist/types/components/BaseNavbarItemContent.vue.d.ts +1 -1
  33. package/dist/types/components/BaseNavbarSideItemContent.vue.d.ts +1 -1
  34. package/dist/types/components/BasePanel.vue.d.ts +1 -1
  35. package/dist/types/components/BasePassword.vue.d.ts +2 -2
  36. package/dist/types/components/BaseRadioGroup.vue.d.ts +2 -2
  37. package/dist/types/components/BaseRichText.vue.d.ts +2 -2
  38. package/dist/types/components/BaseSelect.vue.d.ts +2 -2
  39. package/dist/types/components/BaseSwitch.vue.d.ts +3 -3
  40. package/dist/types/components/BaseTableColumn.vue.d.ts +3 -3
  41. package/dist/types/components/BaseTagAutocomplete.vue.d.ts +4 -4
  42. package/dist/types/components/BaseTagAutocompleteFetch.vue.d.ts +17 -17
  43. package/dist/types/components/BaseTextarea.vue.d.ts +2 -2
  44. package/dist/types/components/BaseTextareaAutoresize.vue.d.ts +2 -2
  45. package/dist/types/components/BaseTimePicker.vue.d.ts +2 -2
  46. package/dist/types/components/BaseTooltip.vue.d.ts +8 -0
  47. package/dist/types/components/index.d.ts +2 -1
  48. package/dist/types/composables/tooltip.d.ts +1 -1
  49. package/package.json +1 -1
  50. package/src/components/BaseActionButtons.vue +77 -0
  51. package/src/components/BaseDataTable.stories.js +26 -2
  52. package/src/components/BaseDataTable.vue +6 -21
  53. package/src/components/BaseHeader.stories.js +3 -0
  54. package/src/components/BaseHeader.vue +24 -78
  55. package/src/components/BaseNavbarSideItem.vue +15 -13
  56. package/src/components/BaseTooltip.vue +10 -2
  57. package/src/components/index.ts +2 -0
  58. package/src/composables/tooltip.ts +22 -10
@@ -42,10 +42,10 @@ declare function __VLS_template(): {
42
42
  $props: Partial<{
43
43
  filter: (option: import("@/types").NormalizedOption) => boolean;
44
44
  size: "xs" | "sm" | "md" | "lg" | "xl";
45
- name: string;
46
- disabled: boolean;
47
45
  required: boolean;
48
46
  inline: boolean;
47
+ disabled: boolean;
48
+ name: string;
49
49
  placeholder: string;
50
50
  hasError: boolean;
51
51
  max: number;
@@ -56,9 +56,9 @@ declare function __VLS_template(): {
56
56
  focusOnMount: boolean;
57
57
  twContainer: string | string[];
58
58
  }> & Omit<{
59
- readonly options: RawOption[];
60
- readonly disabled: boolean;
61
59
  readonly inline: boolean;
60
+ readonly disabled: boolean;
61
+ readonly options: RawOption[];
62
62
  readonly modelValue: RawOption[] | null;
63
63
  readonly hasError: boolean;
64
64
  readonly visibleFocus: boolean;
@@ -71,16 +71,16 @@ declare function __VLS_template(): {
71
71
  readonly twContainer: string | string[];
72
72
  readonly filter?: ((option: import("@/types").NormalizedOption) => boolean) | undefined;
73
73
  readonly size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
74
- readonly name?: string | undefined;
75
74
  readonly required?: boolean | undefined;
75
+ readonly name?: string | undefined;
76
76
  readonly placeholder?: string | undefined;
77
77
  readonly max?: number | undefined;
78
78
  readonly onClose?: ((...args: any[]) => any) | undefined;
79
+ readonly onOpen?: ((...args: any[]) => any) | undefined;
79
80
  readonly "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
80
81
  readonly onScrollBottom?: ((...args: any[]) => any) | undefined;
81
82
  readonly onTyping?: ((...args: any[]) => any) | undefined;
82
- readonly onOpen?: ((...args: any[]) => any) | undefined;
83
- } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, "filter" | "size" | "name" | "disabled" | "required" | "inline" | "placeholder" | "hasError" | "max" | "visibleFocus" | "loading" | "loadingBottom" | "dropdownShow" | "focusOnMount" | "twContainer">;
83
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, "filter" | "size" | "required" | "inline" | "disabled" | "name" | "placeholder" | "hasError" | "max" | "visibleFocus" | "loading" | "loadingBottom" | "dropdownShow" | "focusOnMount" | "twContainer">;
84
84
  $attrs: {
85
85
  [x: string]: unknown;
86
86
  };
@@ -93,7 +93,7 @@ declare function __VLS_template(): {
93
93
  $root: import("vue").ComponentPublicInstance | null;
94
94
  $parent: import("vue").ComponentPublicInstance | null;
95
95
  $host: Element | null;
96
- $emit: ((event: "close", ...args: any[]) => void) & ((event: "update:modelValue", ...args: any[]) => void) & ((event: "scrollBottom", ...args: any[]) => void) & ((event: "typing", ...args: any[]) => void) & ((event: "open", ...args: any[]) => void);
96
+ $emit: ((event: "close", ...args: any[]) => void) & ((event: "open", ...args: any[]) => void) & ((event: "update:modelValue", ...args: any[]) => void) & ((event: "scrollBottom", ...args: any[]) => void) & ((event: "typing", ...args: any[]) => void);
97
97
  $el: HTMLDivElement;
98
98
  $options: import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
99
99
  modelValue: {
@@ -174,10 +174,10 @@ declare function __VLS_template(): {
174
174
  };
175
175
  }>> & Readonly<{
176
176
  onClose?: ((...args: any[]) => any) | undefined;
177
+ onOpen?: ((...args: any[]) => any) | undefined;
177
178
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
178
179
  onScrollBottom?: ((...args: any[]) => any) | undefined;
179
180
  onTyping?: ((...args: any[]) => any) | undefined;
180
- onOpen?: ((...args: any[]) => any) | undefined;
181
181
  }>, {
182
182
  focus: () => void;
183
183
  blur: () => void;
@@ -186,17 +186,17 @@ declare function __VLS_template(): {
186
186
  setKeywords: (input: string) => void;
187
187
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
188
188
  close: (...args: any[]) => void;
189
+ open: (...args: any[]) => void;
189
190
  "update:modelValue": (...args: any[]) => void;
190
191
  scrollBottom: (...args: any[]) => void;
191
192
  typing: (...args: any[]) => void;
192
- open: (...args: any[]) => void;
193
193
  }, string, {
194
194
  filter: (option: import("@/types").NormalizedOption) => boolean;
195
195
  size: "xs" | "sm" | "md" | "lg" | "xl";
196
- name: string;
197
- disabled: boolean;
198
196
  required: boolean;
199
197
  inline: boolean;
198
+ disabled: boolean;
199
+ name: string;
200
200
  placeholder: string;
201
201
  hasError: boolean;
202
202
  max: number;
@@ -229,10 +229,10 @@ declare function __VLS_template(): {
229
229
  } & Readonly<{
230
230
  filter: (option: import("@/types").NormalizedOption) => boolean;
231
231
  size: "xs" | "sm" | "md" | "lg" | "xl";
232
- name: string;
233
- disabled: boolean;
234
232
  required: boolean;
235
233
  inline: boolean;
234
+ disabled: boolean;
235
+ name: string;
236
236
  placeholder: string;
237
237
  hasError: boolean;
238
238
  max: number;
@@ -321,11 +321,11 @@ declare function __VLS_template(): {
321
321
  };
322
322
  }>> & Readonly<{
323
323
  onClose?: ((...args: any[]) => any) | undefined;
324
+ onOpen?: ((...args: any[]) => any) | undefined;
324
325
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
325
326
  onScrollBottom?: ((...args: any[]) => any) | undefined;
326
327
  onTyping?: ((...args: any[]) => any) | undefined;
327
- onOpen?: ((...args: any[]) => any) | undefined;
328
- }>, "blur" | "close" | "focus" | "open" | "setKeywords" | ("filter" | "size" | "name" | "disabled" | "required" | "inline" | "placeholder" | "hasError" | "max" | "visibleFocus" | "loading" | "loadingBottom" | "dropdownShow" | "focusOnMount" | "twContainer")> & import("vue").ShallowUnwrapRef<{
328
+ }>, "blur" | "close" | "focus" | "open" | "setKeywords" | ("filter" | "size" | "required" | "inline" | "disabled" | "name" | "placeholder" | "hasError" | "max" | "visibleFocus" | "loading" | "loadingBottom" | "dropdownShow" | "focusOnMount" | "twContainer")> & import("vue").ShallowUnwrapRef<{
329
329
  focus: () => void;
330
330
  blur: () => void;
331
331
  close: () => void;
@@ -476,8 +476,8 @@ declare const __VLS_component: import("vue").DefineComponent<import("vue").Extra
476
476
  onScrollBottom?: ((...args: any[]) => any) | undefined;
477
477
  onTyping?: ((...args: any[]) => any) | undefined;
478
478
  }>, {
479
- disabled: boolean;
480
479
  required: boolean;
480
+ disabled: boolean;
481
481
  placeholder: string;
482
482
  hasError: boolean;
483
483
  max: number;
@@ -115,9 +115,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
115
115
  class: string | string[];
116
116
  type: string;
117
117
  size: "xs" | "sm" | "md" | "lg" | "xl";
118
- name: string;
119
- disabled: boolean;
120
118
  required: boolean;
119
+ disabled: boolean;
120
+ name: string;
121
121
  modelValue: string | null | undefined;
122
122
  autocomplete: boolean;
123
123
  preventSubmit: boolean;
@@ -115,9 +115,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
115
115
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
116
116
  }>, {
117
117
  size: "xs" | "sm" | "md" | "lg" | "xl";
118
- name: string;
119
- disabled: boolean;
120
118
  required: boolean;
119
+ disabled: boolean;
120
+ name: string;
121
121
  modelValue: string | null;
122
122
  placeholder: string;
123
123
  hasError: boolean;
@@ -105,9 +105,9 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
105
105
  }>, {
106
106
  class: string | string[];
107
107
  size: "xs" | "sm" | "md" | "lg" | "xl";
108
- name: string;
109
- disabled: boolean;
110
108
  required: boolean;
109
+ disabled: boolean;
110
+ name: string;
111
111
  modelValue: string | null | undefined;
112
112
  placeholder: string;
113
113
  hasError: boolean;
@@ -4,8 +4,14 @@ type __VLS_Props = {
4
4
  text?: string | null | undefined;
5
5
  class?: string[] | string | null | undefined;
6
6
  floatingOptions?: UseFloatingOptions;
7
+ /**
8
+ * Whether the tooltip content is interactive or not.
9
+ * When true, hovering the tooltip content will keep it visible.
10
+ */
7
11
  interactive?: boolean;
12
+ delay?: number;
8
13
  dark?: boolean;
14
+ offset?: number;
9
15
  };
10
16
  declare function __VLS_template(): {
11
17
  attrs: Partial<{}>;
@@ -27,6 +33,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}
27
33
  visible: boolean;
28
34
  floatingOptions: UseFloatingOptions;
29
35
  interactive: boolean;
36
+ delay: number;
37
+ offset: number;
30
38
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
39
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
32
40
  export default _default;
@@ -1,3 +1,4 @@
1
+ import BaseActionButtons from './BaseActionButtons.vue';
1
2
  import BaseActionItem from './BaseActionItem.vue';
2
3
  import BaseAddressForm from './BaseAddressForm.vue';
3
4
  import BaseAlert from './BaseAlert.vue';
@@ -105,4 +106,4 @@ import BaseLayoutStacked from './BaseLayoutStacked.vue';
105
106
  import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
106
107
  import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
107
108
  import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
108
- export { BaseActionItem, BaseAddressForm, BaseAlert, BaseApp, BaseAppDialogs, BaseAppSnackbars, BaseAssign, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBelongsToFetch, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseCollapse, BaseColor, BaseContainer, BaseCounter, BaseCropper, BaseCropperModal, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDisplayRelativeTime, BaseDropdown, BaseDropdownAutocomplete, BaseEmptyState, BaseField, BaseFieldI18n, BaseFilePicker, BaseFilePickerCrop, BaseFileUploader, BaseForm, BaseGantt, BaseHasMany, BaseHasManyFetch, BaseHeader, BaseIcon, BaseIconPicker, BaseInput, BaseInputLabel, BaseInputPercent, BaseJsonReader, BaseLazy, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BaseNavbarSideItem, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseStepper, BaseStepperItem, BaseSwitch, BaseSystemAlert, BaseTable, BaseTableBody, BaseTableCell, BaseTableHead, BaseTableHeader, BaseTableRow, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseTimePicker, BaseTooltip, BaseUniqueCode, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
109
+ export { BaseActionButtons, BaseActionItem, BaseAddressForm, BaseAlert, BaseApp, BaseAppDialogs, BaseAppSnackbars, BaseAssign, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBelongsToFetch, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseCollapse, BaseColor, BaseContainer, BaseCounter, BaseCropper, BaseCropperModal, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDisplayRelativeTime, BaseDropdown, BaseDropdownAutocomplete, BaseEmptyState, BaseField, BaseFieldI18n, BaseFilePicker, BaseFilePickerCrop, BaseFileUploader, BaseForm, BaseGantt, BaseHasMany, BaseHasManyFetch, BaseHeader, BaseIcon, BaseIconPicker, BaseInput, BaseInputLabel, BaseInputPercent, BaseJsonReader, BaseLazy, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BaseNavbarSideItem, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseStepper, BaseStepperItem, BaseSwitch, BaseSystemAlert, BaseTable, BaseTableBody, BaseTableCell, BaseTableHead, BaseTableHeader, BaseTableRow, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseTimePicker, BaseTooltip, BaseUniqueCode, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
@@ -3,5 +3,5 @@ type ReturnType = UseFloatingReturn & {
3
3
  showTooltip: Ref<boolean>;
4
4
  };
5
5
  import { Ref } from "vue";
6
- declare function useTooltip(reference: Readonly<Ref<MaybeElement<any>>>, floating: Readonly<Ref<MaybeElement<HTMLElement>>>, interactive?: boolean, options?: UseFloatingOptions | undefined): ReturnType;
6
+ declare function useTooltip(reference: Readonly<Ref<MaybeElement<any>>>, floating: Readonly<Ref<MaybeElement<HTMLElement>>>, interactive?: boolean, delay?: number, options?: UseFloatingOptions | undefined, offset?: number): ReturnType;
7
7
  export { useTooltip };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.10.12",
3
+ "version": "0.10.14",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "rimraf dist && vue-tsc && vite build",
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ variant === 'buttons' ? 'flex space-x-2' : 'btn-group',
5
+ ]"
6
+ >
7
+ <BaseActionItemButton
8
+ v-for="(primaryAction, i) in primaryActions"
9
+ :key="i"
10
+ :item="primaryAction"
11
+ size="sm"
12
+ />
13
+ <BaseMenu
14
+ v-if="secondaryActions.length"
15
+ :items="secondaryActions"
16
+ size="sm"
17
+ >
18
+ <template #button="{ open }">
19
+ <div
20
+ class="btn btn-sm flex items-center p-2 hover:border-slate-400"
21
+ :class="[open ? 'bg-slate-100' : '']"
22
+ >
23
+ <BaseIcon
24
+ icon="heroicons-outline:dots-horizontal"
25
+ class="h-4 w-4 text-slate-500"
26
+ />
27
+ </div>
28
+ </template>
29
+ </BaseMenu>
30
+ </div>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { ActionItem } from '@/types';
35
+ import { cloneDeep } from 'lodash';
36
+ import BaseActionItemButton from './BaseActionItemButton.vue';
37
+ import BaseMenu from './BaseMenu.vue';
38
+
39
+ interface PropsInterface {
40
+ actions: ActionItem[],
41
+ maxActions?: number,
42
+ compact?: boolean,
43
+ variant?: 'buttons' | 'button-group',
44
+ }
45
+
46
+ const props = withDefaults(defineProps<PropsInterface>(), {
47
+ maxActions: 3,
48
+ compact: false,
49
+ variant: 'buttons',
50
+ });
51
+
52
+ const maxActionsInternal = computed(() => {
53
+ if (props.compact) {
54
+ return 1;
55
+ }
56
+ return Math.max(1, props.maxActions);
57
+ });
58
+
59
+ const primaryActions = computed(() => {
60
+ if (!props.actions) {
61
+ return [];
62
+ }
63
+
64
+ return cloneDeep(props.actions).slice(0, maxActionsInternal.value);
65
+ });
66
+
67
+
68
+ const secondaryActions = computed(() => {
69
+ if (!props.actions) {
70
+ return [];
71
+ }
72
+
73
+ return props.actions.filter(
74
+ (a) => !primaryActions.value.map((a) => a.label).includes(a.label)
75
+ );
76
+ });
77
+ </script>
@@ -83,9 +83,33 @@ const componentProps = {
83
83
  ],
84
84
  checkableActions: [
85
85
  {
86
- label: "Delete all",
86
+ label: "Close",
87
+ icon: "mdi:check",
88
+ color: 'primary',
89
+ action: () => {
90
+ alert("Close!");
91
+ },
92
+ },
93
+ {
94
+ label: "Duplicate",
95
+ icon: "mdi:content-copy",
96
+ action: () => {
97
+ alert("Duplicate!");
98
+ },
99
+ },
100
+ {
101
+ label: "Edit",
102
+ icon: "mdi:pencil",
103
+ action: () => {
104
+ alert("Edit!");
105
+ },
106
+ },
107
+ {
108
+ label: "Delete",
109
+ color: 'danger',
110
+ icon: "mdi:trash-can",
87
111
  action: () => {
88
- alert("delete!");
112
+ alert("Delete!");
89
113
  },
90
114
  },
91
115
  ],
@@ -40,28 +40,12 @@
40
40
  {{ t('sui.deselect_all') }}
41
41
  </button>
42
42
  </div>
43
- <BaseMenu
43
+ <BaseActionButtons
44
44
  v-if="checkableActions?.length"
45
- :items="checkableActions"
46
- >
47
- <template #button="{ open }">
48
- <div
49
- class="flex pl-2 pr-4 items-center justify-center btn btn-sm"
50
- :class="[
51
- open ? 'ring-2 ring-primary-500 ring-offset-2' : false,
52
- ]"
53
- >
54
- <BaseIcon
55
- icon="heroicons-solid:dots-vertical"
56
- class="mr-2"
57
- />
58
-
59
- <span>
60
- {{ t('sui.bulk_actions') }}
61
- </span>
62
- </div>
63
- </template>
64
- </BaseMenu>
45
+ :actions="checkableActions"
46
+ :max-actions="2"
47
+ variant="button-group"
48
+ />
65
49
  </div>
66
50
  </div>
67
51
 
@@ -259,6 +243,7 @@ import { useInputSize } from '@/composables/inputSize';
259
243
  import BaseButton from './BaseButton.vue';
260
244
  import BaseDataTableTemplate from './BaseDataTableTemplate.vue';
261
245
  import { customKeyActions } from '@/services/table/customKeyActions';
246
+ import BaseActionButtons from './BaseActionButtons.vue';
262
247
 
263
248
  const http = config.http;
264
249
 
@@ -34,10 +34,13 @@ const attributes = [
34
34
  label: "Full Time",
35
35
  icon: "heroicons:briefcase-solid",
36
36
  tooltip: "40h a week",
37
+ to: '/articles'
37
38
  },
38
39
  {
39
40
  label: "Remote",
40
41
  icon: "heroicons:map-pin-solid",
42
+ tooltip: "Anywhere",
43
+ to: '/articles'
41
44
  },
42
45
  ];
43
46
 
@@ -48,16 +48,23 @@
48
48
  :visible="!!attribute.tooltip"
49
49
  :text="attribute.tooltip"
50
50
  dark
51
+ :delay="400"
51
52
  >
52
- <BaseIcon
53
- v-if="attribute.icon"
54
- :icon="attribute.icon"
55
- class="h-4 w-4 shrink-0 text-slate-600"
56
- aria-hidden="true"
57
- />
58
- <span class="text-sm text-slate-600">
59
- {{ attribute.label }}
60
- </span>
53
+ <component
54
+ :is="attribute.to ? 'router-link' : 'div'"
55
+ :to="attribute.to"
56
+ class="flex items-center gap-1.5"
57
+ >
58
+ <BaseIcon
59
+ v-if="attribute.icon"
60
+ :icon="attribute.icon"
61
+ class="h-4 w-4 shrink-0 text-slate-600"
62
+ aria-hidden="true"
63
+ />
64
+ <span class="text-sm text-slate-600">
65
+ {{ attribute.label }}
66
+ </span>
67
+ </component>
61
68
  </BaseTooltip>
62
69
  </div>
63
70
  </div>
@@ -66,34 +73,16 @@
66
73
  class="mt-3 lg:mt-0 mb-2 lg:mb-0"
67
74
  >
68
75
  <div
69
- class="flex gap-2"
70
76
  :class="{
71
77
  'lg:mt-0 lg:ml-4': !compactLayout,
72
78
  }"
73
79
  >
74
- <BaseActionItemButton
75
- v-for="(primaryAction, i) in primaryActions"
76
- :key="i"
77
- :item="primaryAction"
78
- size="sm"
80
+ <BaseActionButtons
81
+ v-if="actions"
82
+ :actions="actions"
83
+ :max-actions="maxActions"
84
+ :compact="compactLayout"
79
85
  />
80
- <BaseMenu
81
- v-if="secondaryActions.length"
82
- :items="secondaryActions"
83
- size="sm"
84
- >
85
- <template #button="{ open }">
86
- <div
87
- class="btn btn-sm flex items-center rounded-full p-2 hover:border-slate-400"
88
- :class="[open ? 'bg-slate-100' : '']"
89
- >
90
- <BaseIcon
91
- icon="heroicons-outline:dots-horizontal"
92
- class="h-4 w-4 text-slate-500"
93
- />
94
- </div>
95
- </template>
96
- </BaseMenu>
97
86
  </div>
98
87
  </div>
99
88
  </div>
@@ -104,11 +93,10 @@
104
93
  import { Breadcrumb, ActionItem } from '@/types';
105
94
  import { useResizeObserver } from '@vueuse/core';
106
95
  import { BaseBreadcrumbs, BaseIcon } from '..';
107
- import BaseActionItemButton from './BaseActionItemButton.vue';
108
96
  import BaseBadge from './BaseBadge.vue';
109
- import BaseMenu from './BaseMenu.vue';
110
- import { cloneDeep } from 'lodash';
111
97
  import BaseTooltip from './BaseTooltip.vue';
98
+ import BaseActionButtons from './BaseActionButtons.vue';
99
+ import { RouteRecordRaw } from 'vue-router';
112
100
 
113
101
  type BaseBadgeProps = InstanceType<typeof BaseBadge>["$props"] & {
114
102
  label: string;
@@ -118,7 +106,7 @@ const props = withDefaults(
118
106
  defineProps<{
119
107
  title: string;
120
108
  subtitle?: string;
121
- attributes?: { icon?: string; label: string; tooltip?: string }[];
109
+ attributes?: { icon?: string; label: string; tooltip?: string, to?: RouteRecordRaw }[];
122
110
  actions?: ActionItem[];
123
111
  badge?: BaseBadgeProps;
124
112
  layout?: 'default' | 'compact';
@@ -150,46 +138,4 @@ const compactLayout = computed(() => {
150
138
  return width.value < 500;
151
139
  });
152
140
 
153
- const maxActionsInternal = computed(() => {
154
- if (compactLayout.value) {
155
- return 1;
156
- }
157
- return Math.max(1, props.maxActions);
158
- });
159
-
160
- const primaryActions = computed(() => {
161
- if (!props.actions) {
162
- return [];
163
- }
164
-
165
- return cloneDeep(props.actions)
166
- .sort(sortByColor(false))
167
- .slice(0, maxActionsInternal.value)
168
- .sort(sortByColor(true));
169
- });
170
-
171
- function sortByColor(reverse = false) {
172
- const sortingArr = ['secondary', 'primary'];
173
-
174
- return (a: ActionItem, b: ActionItem) => {
175
- if (!reverse) {
176
- return (
177
- sortingArr.indexOf(b.color ?? '') - sortingArr.indexOf(a.color ?? '')
178
- );
179
- }
180
- return (
181
- sortingArr.indexOf(a.color ?? '') - sortingArr.indexOf(b.color ?? '')
182
- );
183
- };
184
- }
185
-
186
- const secondaryActions = computed(() => {
187
- if (!props.actions) {
188
- return [];
189
- }
190
-
191
- return props.actions.filter(
192
- (a) => !primaryActions.value.map((a) => a.label).includes(a.label)
193
- );
194
- });
195
141
  </script>
@@ -6,6 +6,7 @@
6
6
  }"
7
7
  :visible="collapsed"
8
8
  :interactive="hasItems"
9
+ :offset="hasItems ? 0 : 6"
9
10
  >
10
11
  <template #default>
11
12
  <BaseActionItem
@@ -34,7 +35,7 @@
34
35
  >
35
36
  <div
36
37
  v-if="hasItems"
37
- class="bg-white px-4 py-3 shadow-lg ring-1 ring-black ring-opacity-10 rounded-md"
38
+ class="bg-white shadow-lg py-2 ring-1 ring-black ring-opacity-10 rounded-r-md w-[180px]"
38
39
  >
39
40
  <div
40
41
  v-for="subItem in item.actions"
@@ -42,20 +43,22 @@
42
43
  >
43
44
  <BaseActionItem
44
45
  :item="subItem"
45
- class="flex gap-1 items-center justify-start"
46
+ class="flex gap-1 items-center px-4 py-1.5 hover:bg-slate-100"
46
47
  >
47
48
  <template #default="{ active }">
48
- <div
49
- class="text-sm text-slate-600 hover:text-slate-950"
50
- :class="{ 'font-medium': active }"
51
- >
52
- {{ subItem.label }}
49
+ <div class="flex justify-between gap-2 items-center w-full">
50
+ <div
51
+ class="text-sm text-slate-600 hover:text-slate-950"
52
+ :class="{ 'font-medium': active }"
53
+ >
54
+ {{ subItem.label }}
55
+ </div>
56
+ <BaseCounter
57
+ v-if="subItem.count"
58
+ :count="subItem.count"
59
+ size="sm"
60
+ />
53
61
  </div>
54
- <BaseCounter
55
- v-if="subItem.count"
56
- :count="subItem.count"
57
- size="xs"
58
- />
59
62
  </template>
60
63
  </BaseActionItem>
61
64
  </div>
@@ -108,7 +111,6 @@ import BaseActionItem from './BaseActionItem.vue';
108
111
  import BaseNavbarSideItemContent from './BaseNavbarSideItemContent.vue';
109
112
  import BaseCounter from './BaseCounter.vue';
110
113
  import BaseTooltip from './BaseTooltip.vue';
111
- import { flip, shift } from '@floating-ui/vue';
112
114
 
113
115
  const router = useRouter();
114
116
 
@@ -54,8 +54,14 @@ const props = withDefaults(defineProps<{
54
54
  text?: string | null | undefined;
55
55
  class?: string[] | string | null | undefined;
56
56
  floatingOptions?: UseFloatingOptions,
57
+ /**
58
+ * Whether the tooltip content is interactive or not.
59
+ * When true, hovering the tooltip content will keep it visible.
60
+ */
57
61
  interactive?: boolean,
62
+ delay?: number,
58
63
  dark?: boolean,
64
+ offset?: number,
59
65
  }>(), {
60
66
  visible: true,
61
67
  text: null,
@@ -65,8 +71,10 @@ const props = withDefaults(defineProps<{
65
71
  placement: 'top-start',
66
72
  };
67
73
  },
68
- interactive: false,
74
+ interactive: true,
75
+ delay: 0,
69
76
  dark: false,
77
+ offset: 6,
70
78
  });
71
79
 
72
80
  const targetRef = ref<HTMLElement | null>(null);
@@ -75,7 +83,7 @@ const targetInternal = computed(() => unrefElement(targetRef));
75
83
 
76
84
  const tooltipRef = ref<HTMLElement | null>(null)
77
85
 
78
- const { floatingStyles, showTooltip } = useTooltip(targetInternal, tooltipRef, props.interactive, props.floatingOptions);
86
+ const { floatingStyles, showTooltip } = useTooltip(targetInternal, tooltipRef, props.interactive, props.delay, props.floatingOptions, props.offset);
79
87
 
80
88
  const classInternal = computed(() => {
81
89
  return [
@@ -1,3 +1,4 @@
1
+ import BaseActionButtons from './BaseActionButtons.vue';
1
2
  import BaseActionItem from './BaseActionItem.vue';
2
3
  import BaseAddressForm from './BaseAddressForm.vue';
3
4
  import BaseAlert from './BaseAlert.vue';
@@ -108,6 +109,7 @@ import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
108
109
  import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
109
110
 
110
111
  export {
112
+ BaseActionButtons,
111
113
  BaseActionItem,
112
114
  BaseAddressForm,
113
115
  BaseAlert,