sprintify-ui 0.0.19 → 0.0.21

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 (54) hide show
  1. package/dist/sprintify-ui.es.js +6877 -4264
  2. package/dist/types/src/components/BaseActionItem.vue.d.ts +121 -0
  3. package/dist/types/src/components/BaseAlert.vue.d.ts +3 -3
  4. package/dist/types/src/components/BaseAppDialogs.vue.d.ts +1 -1
  5. package/dist/types/src/components/BaseBoolean.vue.d.ts +2 -2
  6. package/dist/types/src/components/BaseCounter.vue.d.ts +3 -3
  7. package/dist/types/src/components/BaseDialog.vue.d.ts +4 -4
  8. package/dist/types/src/components/BaseInput.vue.d.ts +1 -1
  9. package/dist/types/src/components/BaseLayoutNotificationDropdown.vue.d.ts +24 -0
  10. package/dist/types/src/components/BaseLayoutNotificationItem.vue.d.ts +14 -0
  11. package/dist/types/src/components/BaseLayoutSidebar.vue.d.ts +114 -0
  12. package/dist/types/src/components/BaseLayoutSidebarConfigurable.vue.d.ts +182 -0
  13. package/dist/types/src/components/BaseLayoutStacked.vue.d.ts +76 -0
  14. package/dist/types/src/components/BaseLayoutStackedConfigurable.vue.d.ts +182 -0
  15. package/dist/types/src/components/BaseMenu.vue.d.ts +17 -15
  16. package/dist/types/src/components/BaseMenuItem.vue.d.ts +5 -5
  17. package/dist/types/src/components/BaseNavbar.vue.d.ts +20 -1
  18. package/dist/types/src/components/BaseNavbarItem.vue.d.ts +17 -71
  19. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +11 -2
  20. package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +26 -0
  21. package/dist/types/src/components/BaseNavbarSideItemContent.vue.d.ts +50 -0
  22. package/dist/types/src/components/BaseSwitch.vue.d.ts +3 -3
  23. package/dist/types/src/components/BaseSystemAlert.vue.d.ts +8 -8
  24. package/dist/types/src/components/BaseTableColumn.vue.d.ts +1 -1
  25. package/dist/types/src/components/index.d.ts +6 -1
  26. package/dist/types/src/index.d.ts +12 -0
  27. package/dist/types/src/types/Notification.d.ts +8 -0
  28. package/dist/types/src/types/types.d.ts +9 -0
  29. package/package.json +6 -3
  30. package/src/components/BaseActionItem.vue +68 -0
  31. package/src/components/{HasMany.stories.js → BaseHasMany.stories.js} +0 -0
  32. package/src/components/BaseLayoutNotificationDropdown.vue +101 -0
  33. package/src/components/BaseLayoutNotificationItem.vue +58 -0
  34. package/src/components/BaseLayoutSidebar.vue +199 -0
  35. package/src/components/BaseLayoutSidebarConfigurable.stories.js +129 -0
  36. package/src/components/BaseLayoutSidebarConfigurable.vue +118 -0
  37. package/src/components/BaseLayoutStacked.vue +52 -0
  38. package/src/components/BaseLayoutStackedConfigurable.stories.js +110 -0
  39. package/src/components/BaseLayoutStackedConfigurable.vue +129 -0
  40. package/src/components/BaseMediaItem.vue +7 -7
  41. package/src/components/BaseMediaLibrary.vue +3 -3
  42. package/src/components/BaseMediaPreview.vue +1 -1
  43. package/src/components/BaseMenu.vue +12 -4
  44. package/src/components/BaseNavbar.stories.js +18 -14
  45. package/src/components/BaseNavbar.vue +19 -3
  46. package/src/components/BaseNavbarItem.vue +17 -43
  47. package/src/components/BaseNavbarItemContent.vue +36 -16
  48. package/src/components/BaseNavbarSideItem.vue +42 -0
  49. package/src/components/BaseNavbarSideItemContent.vue +77 -0
  50. package/src/components/index.ts +11 -0
  51. package/src/lang/en.json +3 -0
  52. package/src/lang/fr.json +3 -0
  53. package/src/types/Notification.ts +10 -0
  54. package/src/types/types.ts +11 -0
@@ -0,0 +1,129 @@
1
+ import BaseContainer from './BaseContainer.vue';
2
+ import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
3
+
4
+ export default {
5
+ title: 'Layout/BaseLayoutSidebarConfigurable',
6
+ component: BaseLayoutSidebarConfigurable,
7
+ parameters: {
8
+ layout: 'fullscreen',
9
+ },
10
+ args: {
11
+ user: {
12
+ email: 'jane@witify.io',
13
+ first_name: 'Jane',
14
+ last_name: 'Doe',
15
+ full_name: 'Jane Doe',
16
+ avatar_url:
17
+ 'https://images.unsplash.com/photo-1494790108377-be9c29b29330??auto=format&fit=crop&w=200&h=200&q=80&g=face',
18
+ },
19
+ menu: [
20
+ {
21
+ title: 'General',
22
+ actions: [
23
+ {
24
+ label: 'Dashboard',
25
+ to: '/',
26
+ icon: 'heroicons-home',
27
+ },
28
+ {
29
+ label: 'Articles',
30
+ to: '/articles',
31
+ icon: 'heroicons:document-text',
32
+ },
33
+ {
34
+ label: 'Users',
35
+ to: '/users',
36
+ icon: 'heroicons:users',
37
+ },
38
+ ],
39
+ },
40
+ {
41
+ title: 'Settings',
42
+ actions: [
43
+ {
44
+ label: 'Account',
45
+ to: '/account',
46
+ icon: 'heroicons:cog',
47
+ },
48
+ {
49
+ label: 'Logout',
50
+ action: logout,
51
+ icon: 'heroicons:arrow-left-on-rectangle',
52
+ },
53
+ ],
54
+ },
55
+ ],
56
+ userMenu: [
57
+ {
58
+ label: 'Dashboard',
59
+ to: '/',
60
+ icon: 'heroicons-home',
61
+ },
62
+ {
63
+ label: 'Settings',
64
+ to: '/account',
65
+ icon: 'heroicons:cog',
66
+ },
67
+ {
68
+ label: 'Logout',
69
+ action: logout,
70
+ icon: 'heroicons:arrow-left-on-rectangle',
71
+ },
72
+ ],
73
+ notifications: {
74
+ footerTo: '/',
75
+ footerLabel: 'See all notifications',
76
+ items: [
77
+ {
78
+ id: '1',
79
+ text: 'You have a new message',
80
+ to: '/',
81
+ created_at: '2022-01-01T00:00:00',
82
+ },
83
+ {
84
+ id: '2',
85
+ text: 'Your inbox is now full. Please empty your inbox before it goes bang.',
86
+ to: '/',
87
+ created_at: '2022-01-01T00:00:00',
88
+ },
89
+ ],
90
+ },
91
+ },
92
+ };
93
+
94
+ async function logout() {
95
+ alert('logout');
96
+ }
97
+
98
+ const Template = (args) => ({
99
+ components: {
100
+ BaseContainer,
101
+ BaseLayoutSidebarConfigurable,
102
+ },
103
+ setup() {
104
+ return { args };
105
+ },
106
+ template: `
107
+ <BaseLayoutSidebarConfigurable v-bind="args">
108
+ <div class="py-16">
109
+ <BaseContainer size="3xl">
110
+ <p v-for="i in 20" class="mb-1">
111
+ Amet occaecat enim pariatur incididunt enim laborum enim. Duis cillum in in excepteur sit excepteur laboris consectetur magna. Commodo proident labore commodo duis veniam do nisi irure ipsum officia excepteur non. Nisi cillum mollit tempor ut.
112
+ </p>
113
+ </BaseContainer>
114
+ </div>
115
+ </BaseLayoutSidebarConfigurable>
116
+ `,
117
+ });
118
+
119
+ export const Light = Template.bind({});
120
+ Light.args = {
121
+ dark: false,
122
+ logoUrl: 'https://sprintify.witify.io/img/logo/logo-side.svg',
123
+ };
124
+
125
+ export const Dark = Template.bind({});
126
+ Dark.args = {
127
+ dark: true,
128
+ logoUrl: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
129
+ };
@@ -0,0 +1,118 @@
1
+ <template>
2
+ <BaseLayoutSidebar :app-name="appName" :logo-url="logoUrl" :dark="dark">
3
+ <template #menu>
4
+ <div class="px-3 py-6">
5
+ <div class="space-y-8">
6
+ <div v-for="section in actionSections" :key="section.title">
7
+ <h2
8
+ v-if="section.title"
9
+ class="mb-3 pl-3 text-xs font-semibold uppercase tracking-widest"
10
+ :class="dark ? 'text-slate-400' : 'text-slate-500'"
11
+ >
12
+ {{ section.title }}
13
+ </h2>
14
+ <div>
15
+ <div class="space-y-1">
16
+ <BaseNavbarSideItem
17
+ v-for="item in section.actions"
18
+ :key="item.label"
19
+ :item="item"
20
+ :dark="dark"
21
+ />
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <template #navbar>
30
+ <div class="flex flex-1 justify-between px-4">
31
+ <div class="flex flex-1">
32
+ <!-- Good spot for search bar... -->
33
+ </div>
34
+
35
+ <div class="ml-4 flex items-center md:ml-6">
36
+ <!-- Notification dropdown -->
37
+ <BaseLayoutNotificationDropdown
38
+ v-if="notifications"
39
+ :notifications-config="notifications"
40
+ class="mr-1 sm:mr-2"
41
+ ></BaseLayoutNotificationDropdown>
42
+
43
+ <!-- Profile dropdown -->
44
+ <div class="relative ml-3 mr-3">
45
+ <BaseMenu :items="userMenu">
46
+ <template #button="{ open }">
47
+ <div class="flex" :class="[open ? '' : '']">
48
+ <BaseAvatar :user="user" show-details />
49
+ </div>
50
+ </template>
51
+ </BaseMenu>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <template #default>
58
+ <slot />
59
+ </template>
60
+ </BaseLayoutSidebar>
61
+ </template>
62
+
63
+ <script setup lang="ts">
64
+ import { User } from '@/types/User';
65
+ import { PropType } from 'vue';
66
+ import { ActionItem, ActionSection, NotificationsConfig } from '../types/types';
67
+ import BaseAvatar from './BaseAvatar.vue';
68
+ import BaseLayoutNotificationDropdown from './BaseLayoutNotificationDropdown.vue';
69
+ import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
70
+ import BaseMenu from './BaseMenu.vue';
71
+ import BaseNavbarSideItem from './BaseNavbarSideItem.vue';
72
+
73
+ const props = defineProps({
74
+ appName: {
75
+ default: '',
76
+ type: String,
77
+ },
78
+ logoUrl: {
79
+ default: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
80
+ type: String,
81
+ },
82
+ menu: {
83
+ required: true,
84
+ type: Array as PropType<ActionItem[] | ActionSection[]>,
85
+ },
86
+ userMenu: {
87
+ required: true,
88
+ type: Array as PropType<ActionItem[]>,
89
+ },
90
+ user: {
91
+ required: true,
92
+ type: Object as PropType<User>,
93
+ },
94
+ notifications: {
95
+ default: undefined,
96
+ type: Object as PropType<NotificationsConfig>,
97
+ },
98
+ dark: {
99
+ default: false,
100
+ type: Boolean,
101
+ },
102
+ });
103
+
104
+ const actionSections = computed((): ActionSection[] => {
105
+ const isActionSections = props.menu.length > 0 && 'actions' in props.menu[0];
106
+
107
+ if (isActionSections) {
108
+ return props.menu as ActionSection[];
109
+ }
110
+
111
+ return [
112
+ {
113
+ title: '',
114
+ actions: props.menu as ActionItem[],
115
+ },
116
+ ];
117
+ });
118
+ </script>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="sticky top-0 z-20 w-full shadow-sm">
3
+ <BaseSystemAlert
4
+ v-for="systemAlert in systemAlerts"
5
+ :key="systemAlert.id"
6
+ :color="systemAlert.color"
7
+ :to="systemAlert.to"
8
+ :action="systemAlert.action"
9
+ :closable="systemAlert.closable"
10
+ @close="systemAlertStore.remove(systemAlert)"
11
+ >
12
+ {{ systemAlert.message }}
13
+ </BaseSystemAlert>
14
+
15
+ <BaseNavbar :dark="dark">
16
+ <template #navbar>
17
+ <slot name="navbar" />
18
+ </template>
19
+
20
+ <template #mobile>
21
+ <slot name="mobile" />
22
+ </template>
23
+ </BaseNavbar>
24
+ </div>
25
+
26
+ <div>
27
+ <slot />
28
+ </div>
29
+ </template>
30
+
31
+ <script lang="ts" setup>
32
+ import { useSystemAlertStore } from '../stores/systemAlerts';
33
+ import BaseNavbar from './BaseNavbar.vue';
34
+ import BaseSystemAlert from './BaseSystemAlert.vue';
35
+
36
+ defineProps({
37
+ dark: {
38
+ default: false,
39
+ type: Boolean,
40
+ },
41
+ });
42
+
43
+ /**
44
+ * System Alerts
45
+ */
46
+
47
+ const systemAlertStore = useSystemAlertStore();
48
+
49
+ const systemAlerts = computed(() => {
50
+ return systemAlertStore.systemAlerts;
51
+ });
52
+ </script>
@@ -0,0 +1,110 @@
1
+ import BaseContainer from './BaseContainer.vue';
2
+ import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
3
+
4
+ export default {
5
+ title: 'Layout/BaseLayoutStackedConfigurable',
6
+ component: BaseLayoutStackedConfigurable,
7
+ parameters: {
8
+ layout: 'fullscreen',
9
+ },
10
+ args: {
11
+ appName: 'Sprintify',
12
+ user: {
13
+ email: 'jane@witify.io',
14
+ first_name: 'Jane',
15
+ last_name: 'Doe',
16
+ full_name: 'Jane Doe',
17
+ avatar_url:
18
+ 'https://images.unsplash.com/photo-1494790108377-be9c29b29330??auto=format&fit=crop&w=200&h=200&q=80&g=face',
19
+ },
20
+ menu: [
21
+ {
22
+ label: 'Products',
23
+ to: '/',
24
+ count: 234,
25
+ type: 'RouterLink',
26
+ },
27
+ {
28
+ label: 'Users',
29
+ to: '/setup',
30
+ },
31
+ {
32
+ label: 'Account',
33
+ to: '/settings',
34
+ icon: 'heroicons:cog',
35
+ },
36
+ ],
37
+ userMenu: [
38
+ {
39
+ label: 'Dashboard',
40
+ to: '/',
41
+ icon: 'heroicons-home',
42
+ },
43
+ {
44
+ label: 'Settings',
45
+ to: '/account',
46
+ icon: 'heroicons:cog',
47
+ },
48
+ {
49
+ label: 'Logout',
50
+ action: logout,
51
+ icon: 'heroicons:arrow-left-on-rectangle',
52
+ },
53
+ ],
54
+ notifications: {
55
+ footerTo: '/',
56
+ footerLabel: 'See all notifications',
57
+ items: [
58
+ {
59
+ id: '1',
60
+ text: 'You have a new message',
61
+ to: '/',
62
+ created_at: '2022-12-08T19:16:10Z',
63
+ },
64
+ {
65
+ id: '2',
66
+ text: 'Your inbox is now full. Please empty your inbox before it goes bang.',
67
+ to: '/',
68
+ created_at: '2022-01-01T00:00:00',
69
+ },
70
+ ],
71
+ },
72
+ },
73
+ };
74
+
75
+ async function logout() {
76
+ alert('logout');
77
+ }
78
+
79
+ const Template = (args) => ({
80
+ components: {
81
+ BaseLayoutStackedConfigurable,
82
+ BaseContainer,
83
+ },
84
+ setup() {
85
+ return { args };
86
+ },
87
+ template: `
88
+ <BaseLayoutStackedConfigurable v-bind="args">
89
+ <div class="py-16">
90
+ <BaseContainer size="3xl">
91
+ <p v-for="i in 20" class="mb-1">
92
+ Amet occaecat enim pariatur incididunt enim laborum enim. Duis cillum in in excepteur sit excepteur laboris consectetur magna. Commodo proident labore commodo duis veniam do nisi irure ipsum officia excepteur non. Nisi cillum mollit tempor ut.
93
+ </p>
94
+ </BaseContainer>
95
+ </div>
96
+ </BaseLayoutStackedConfigurable>
97
+ `,
98
+ });
99
+
100
+ export const Light = Template.bind({});
101
+ Light.args = {
102
+ dark: false,
103
+ logoUrl: 'https://sprintify.witify.io/img/logo/logo-side.svg',
104
+ };
105
+
106
+ export const Dark = Template.bind({});
107
+ Dark.args = {
108
+ dark: true,
109
+ logoUrl: 'https://sprintify.witify.io/img/logo/logo-side-dark.svg',
110
+ };
@@ -0,0 +1,129 @@
1
+ <template>
2
+ <BaseLayoutStacked :dark="dark">
3
+ <template #navbar>
4
+ <div class="flex h-16 justify-between">
5
+ <!-- Left -->
6
+
7
+ <div class="flex justify-center">
8
+ <!-- Logo -->
9
+ <router-link to="/" class="flex flex-shrink-0 items-center p-2 pl-0">
10
+ <img class="block h-8 w-auto" :src="logoUrl" :alt="appName" />
11
+ </router-link>
12
+
13
+ <!-- Links (desktop) -->
14
+ <div class="ml-10 hidden space-x-4 md:flex">
15
+ <BaseNavbarItem
16
+ v-for="item in menu"
17
+ :key="item.label"
18
+ :item="item"
19
+ :dark="dark"
20
+ />
21
+ </div>
22
+ </div>
23
+
24
+ <!-- Right -->
25
+ <div class="flex items-center md:ml-6">
26
+ <!-- Notification dropdown -->
27
+ <BaseLayoutNotificationDropdown
28
+ v-if="notifications"
29
+ class="mr-4 md:mr-5"
30
+ :dark="dark"
31
+ :notifications-config="notifications"
32
+ ></BaseLayoutNotificationDropdown>
33
+
34
+ <!-- Profile dropdown -->
35
+ <BaseMenu menu-class="w-52" class="hidden md:block" :items="userMenu">
36
+ <template #button="{ open }">
37
+ <div class="flex rounded-full" :class="[open ? '' : '']">
38
+ <BaseAvatar :class="dark ? 'text-white' : ''" :user="user" />
39
+ </div>
40
+ </template>
41
+ </BaseMenu>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <template #mobile>
47
+ <!-- Links mobile -->
48
+ <div class="space-y-1 p-2 pt-0">
49
+ <BaseNavbarSideItem
50
+ v-for="item in menu"
51
+ :key="item.label"
52
+ :item="item"
53
+ :dark="dark"
54
+ />
55
+ </div>
56
+
57
+ <hr
58
+ class="mb-4 mt-2"
59
+ :class="[dark ? 'border-slate-700' : 'border-slate-200']"
60
+ />
61
+
62
+ <!-- Profile links -->
63
+ <div class="p-2 pb-6">
64
+ <BaseAvatar
65
+ :user="user"
66
+ show-details
67
+ size="base"
68
+ class="px-3"
69
+ :class="dark ? 'text-white' : ''"
70
+ />
71
+ <div class="mt-4 space-y-1">
72
+ <BaseNavbarSideItem
73
+ v-for="item in userMenu"
74
+ :key="item.label"
75
+ :item="item"
76
+ :dark="dark"
77
+ />
78
+ </div>
79
+ </div>
80
+ </template>
81
+
82
+ <template #default>
83
+ <slot name="default" />
84
+ </template>
85
+ </BaseLayoutStacked>
86
+ </template>
87
+
88
+ <script lang="ts" setup>
89
+ import { User } from '@/types/User';
90
+ import { PropType } from 'vue';
91
+ import { ActionItem, NotificationsConfig } from '../types/types';
92
+ import BaseAvatar from './BaseAvatar.vue';
93
+ import BaseLayoutStacked from './BaseLayoutStacked.vue';
94
+ import BaseMenu from './BaseMenu.vue';
95
+ import BaseNavbarItem from './BaseNavbarItem.vue';
96
+ import BaseNavbarSideItem from './BaseNavbarSideItem.vue';
97
+ import BaseLayoutNotificationDropdown from './BaseLayoutNotificationDropdown.vue';
98
+
99
+ defineProps({
100
+ appName: {
101
+ default: '',
102
+ type: String,
103
+ },
104
+ logoUrl: {
105
+ default: 'https://sprintify.witify.io/img/logo/logo-side.svg',
106
+ type: String,
107
+ },
108
+ menu: {
109
+ required: true,
110
+ type: Array as PropType<ActionItem[]>,
111
+ },
112
+ userMenu: {
113
+ required: true,
114
+ type: Array as PropType<ActionItem[]>,
115
+ },
116
+ user: {
117
+ required: true,
118
+ type: Object as PropType<User>,
119
+ },
120
+ notifications: {
121
+ default: undefined,
122
+ type: Object as PropType<NotificationsConfig>,
123
+ },
124
+ dark: {
125
+ default: false,
126
+ type: Boolean,
127
+ },
128
+ });
129
+ </script>
@@ -1,28 +1,28 @@
1
1
  <template>
2
- <div class="rounded border border-slate-300 bg-white shadow">
2
+ <div class="rounded bg-white shadow">
3
3
  <div class="relative flex">
4
4
  <div class="shrink-0">
5
- <BaseMediaPreview class="h-14 w-14 rounded-l" :media="media" />
5
+ <BaseMediaPreview class="h-12 w-12 rounded-l" :media="media" />
6
6
  </div>
7
7
  <component
8
8
  :is="url ? 'a' : 'p'"
9
9
  :href="url"
10
10
  target="_blank"
11
- class="grow overflow-hidden px-3 pt-3"
11
+ class="flex grow items-center overflow-hidden px-3"
12
12
  >
13
13
  <div class="text-left leading-tight">
14
- <p class="grow truncate text-sm font-medium">
14
+ <p class="mb-px grow truncate text-[13px] font-medium">
15
15
  {{ name }}
16
16
  </p>
17
- <p class="shrink-0 text-[10px] font-medium text-slate-400">
17
+ <p class="shrink-0 text-[10px] text-slate-400">
18
18
  {{ size }}
19
19
  </p>
20
20
  </div>
21
21
  </component>
22
- <div v-if="showRemove" class="shrink-0 p-2">
22
+ <div v-if="showRemove" class="shrink-0 p-0.5">
23
23
  <button
24
24
  type="button"
25
- class="rounded-full bg-slate-400 p-1 text-white hover:bg-slate-500"
25
+ class="rounded-full bg-white p-1 text-slate-400 hover:bg-slate-100"
26
26
  @click="$emit('remove')"
27
27
  >
28
28
  <BaseIcon icon="heroicons:x-mark-20-solid" class="h-4 w-4"></BaseIcon>
@@ -22,16 +22,16 @@
22
22
  <div
23
23
  class="rounded border border-dashed p-6 duration-150"
24
24
  :class="[
25
- baseFileUploaderProps.dragging ? 'bg-blue-100' : 'bg-slate-100',
25
+ baseFileUploaderProps.dragging ? 'bg-blue-100' : 'bg-white',
26
26
  baseFileUploaderProps.disabled
27
27
  ? 'cursor-not-allowed border-slate-300'
28
- : 'border-slate-300 hover:bg-slate-50',
28
+ : 'border-slate-300 hover:bg-slate-100',
29
29
  ]"
30
30
  >
31
31
  <div :class="[baseFileUploaderProps.disabled ? 'opacity-30' : '']">
32
32
  <BaseIcon
33
33
  icon="heroicons:arrow-up-on-square"
34
- class="mx-auto mb-3 h-6 w-6 text-primary-500"
34
+ class="mx-auto mb-3 h-6 w-6 text-slate-500"
35
35
  />
36
36
  <div class="text-center">
37
37
  <p class="mb-0 text-sm font-medium leading-tight">
@@ -20,7 +20,7 @@
20
20
  />
21
21
  <div
22
22
  v-else
23
- class="flex h-full w-full items-center justify-center bg-slate-200"
23
+ class="flex h-full w-full items-center justify-center bg-slate-100"
24
24
  >
25
25
  <BaseIcon
26
26
  v-if="extension == 'pdf'"
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <Menu v-slot="{ open }" as="div" class="relative text-left">
2
+ <Menu
3
+ v-slot="{ open }"
4
+ as="div"
5
+ class="text-left"
6
+ :class="[position == 'custom' ? 'static' : 'relative']"
7
+ >
3
8
  <div>
4
9
  <MenuButton class="flex">
5
10
  <slot name="button" :open="open" />
@@ -18,7 +23,7 @@
18
23
  :class="[menuClass, menuPositionClass]"
19
24
  class="absolute z-menu mt-2 rounded-md bg-white p-1 shadow-lg ring-1 ring-black ring-opacity-10 focus:outline-none"
20
25
  >
21
- <slot name="items">
26
+ <slot name="items" :items="items">
22
27
  <template v-for="item in items" :key="item.label + 'link'">
23
28
  <div v-if="item.line" class="my-1 -mx-1 flex h-px bg-gray-200" />
24
29
 
@@ -95,15 +100,18 @@ const props = defineProps({
95
100
  },
96
101
  menuClass: {
97
102
  default: 'w-48',
98
- type: String,
103
+ type: [String, Array, Object],
99
104
  },
100
105
  position: {
101
106
  default: 'bottom-left',
102
- type: String as PropType<'bottom-left' | 'bottom-right'>,
107
+ type: String as PropType<'bottom-left' | 'bottom-right' | 'custom'>,
103
108
  },
104
109
  });
105
110
 
106
111
  const menuPositionClass = computed(() => {
112
+ if (props.position == 'custom') {
113
+ return '';
114
+ }
107
115
  if (props.position == 'bottom-left') {
108
116
  return 'origin-top-right right-0';
109
117
  }