sprintify-ui 0.2.26 → 0.2.28

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 (44) hide show
  1. package/dist/sprintify-ui.es.js +3985 -3991
  2. package/dist/style.css +1 -1
  3. package/dist/types/src/components/BaseStatistic.vue.d.ts +0 -1
  4. package/dist/types/src/components/BaseToast.vue.d.ts +20 -0
  5. package/dist/types/src/stories/PageShow.vue.d.ts +2 -0
  6. package/dist/types/src/types/TimelineItem.d.ts +1 -2
  7. package/package.json +1 -1
  8. package/src/assets/form.css +1 -1
  9. package/src/components/BaseActionItemButton.vue +3 -1
  10. package/src/components/BaseAlert.vue +20 -20
  11. package/src/components/BaseAppDialogs.vue +6 -7
  12. package/src/components/BaseAppNotifications.vue +11 -47
  13. package/src/components/BaseAvatar.vue +1 -1
  14. package/src/components/BaseBreadcrumbs.vue +3 -3
  15. package/src/components/BaseDataIterator.vue +2 -2
  16. package/src/components/BaseDataIteratorSectionModal.vue +2 -2
  17. package/src/components/BaseDataTable.stories.js +2 -144
  18. package/src/components/BaseDataTable.vue +1 -1
  19. package/src/components/BaseDialog.vue +9 -9
  20. package/src/components/BaseGantt.vue +1 -1
  21. package/src/components/BaseHeader.vue +13 -19
  22. package/src/components/BaseIconPicker.vue +1 -1
  23. package/src/components/BaseInputLabel.vue +2 -2
  24. package/src/components/BaseModalCenter.vue +11 -17
  25. package/src/components/BaseModalSide.vue +11 -17
  26. package/src/components/BaseNavbarSideItem.vue +1 -1
  27. package/src/components/BasePanel.vue +1 -1
  28. package/src/components/BaseRichText.vue +17 -1
  29. package/src/components/BaseShortcut.vue +1 -1
  30. package/src/components/BaseSideNavigation.stories.js +6 -1
  31. package/src/components/BaseSideNavigationItem.vue +1 -1
  32. package/src/components/BaseStatistic.vue +11 -14
  33. package/src/components/BaseTabItem.vue +18 -17
  34. package/src/components/BaseTable.vue +14 -18
  35. package/src/components/BaseTextareaAutoresize.vue +1 -1
  36. package/src/components/BaseTimeline.vue +1 -1
  37. package/src/components/BaseTimelineItem.vue +20 -30
  38. package/src/components/BaseToast.stories.js +50 -0
  39. package/src/components/BaseToast.vue +44 -0
  40. package/src/stories/List.stories.js +132 -0
  41. package/src/stories/PageShow.vue +424 -0
  42. package/src/stories/Show.stories.js +22 -0
  43. package/src/types/TimelineItem.ts +1 -2
  44. package/src/utils/colors.ts +10 -0
@@ -101,27 +101,33 @@ function updateChange(value: string | null): string | null {
101
101
  .ql-toolbar.ql-snow {
102
102
  @apply rounded-t border-slate-300 font-sans;
103
103
  }
104
+
104
105
  .ql-container.ql-snow {
105
106
  @apply rounded-b border-slate-300 font-sans;
106
107
  }
108
+
107
109
  .ql-container {
108
110
  @apply font-sans;
109
111
  }
112
+
110
113
  &.error {
114
+
111
115
  & .ql-toolbar.ql-snow,
112
116
  & .ql-container.ql-snow {
113
117
  @apply border-red-500;
114
118
  }
115
119
  }
120
+
116
121
  .ql-tooltip {
117
122
  @apply z-menu;
118
123
  }
124
+
119
125
  .ql-container {
120
126
  @apply text-slate-900;
121
127
  }
122
128
 
123
129
  .ql-editor.ql-blank::before {
124
- @apply text-base text-slate-400;
130
+ @apply text-base text-slate-400 font-light not-italic;
125
131
  }
126
132
 
127
133
  /** Style Prose */
@@ -129,24 +135,31 @@ function updateChange(value: string | null): string | null {
129
135
  h1 {
130
136
  @apply mt-0 mb-8 text-4xl font-bold leading-snug tracking-normal;
131
137
  }
138
+
132
139
  h2 {
133
140
  @apply mt-6 mb-4 text-3xl font-bold leading-snug tracking-normal;
134
141
  }
142
+
135
143
  h3 {
136
144
  @apply mt-5 mb-3 text-2xl font-bold leading-snug tracking-normal;
137
145
  }
146
+
138
147
  h4 {
139
148
  @apply mt-4 mb-2 text-xl font-bold leading-snug tracking-normal;
140
149
  }
150
+
141
151
  p {
142
152
  @apply my-5 text-base leading-relaxed;
153
+
143
154
  &:first-child {
144
155
  @apply mt-0;
145
156
  }
146
157
  }
158
+
147
159
  ol,
148
160
  ul {
149
161
  padding-left: 2rem;
162
+
150
163
  li {
151
164
  @apply my-2 text-base leading-relaxed;
152
165
  padding-left: 0.5rem;
@@ -160,13 +173,16 @@ function updateChange(value: string | null): string | null {
160
173
  }
161
174
  }
162
175
  }
176
+
163
177
  blockquote {
164
178
  @apply my-5 text-base;
165
179
  }
180
+
166
181
  pre {
167
182
  @apply my-5 p-4 text-sm;
168
183
  }
169
184
  }
185
+
170
186
  h1,
171
187
  h2,
172
188
  h3,
@@ -25,7 +25,7 @@
25
25
  <!-- Description -->
26
26
  <div
27
27
  v-if="description"
28
- class="mt-1 mb-3 whitespace-pre-line text-sm text-slate-500 line-clamp-2"
28
+ class="mt-1 mb-3 whitespace-pre-line text-sm font-light text-slate-500 line-clamp-2"
29
29
  >
30
30
  {{ description }}
31
31
  </div>
@@ -32,7 +32,12 @@ const Template = (args) => ({
32
32
  <BaseSideNavigationItem to="/" v-slot="{active}">
33
33
  <div class="flex items-center">
34
34
  <span class="mr-1">Home</span>
35
- <BaseCounter :size="['lg', 'md'].includes(args.size) ? 'sm' : 'xs'" :color="active ? 'primary' : 'light'" :count="1"></BaseCounter>
35
+ <BaseCounter
36
+ class="shrink-0"
37
+ :size="['lg', 'md'].includes(args.size) ? 'sm' : 'xs'"
38
+ :color="active ? 'primary' : 'light'"
39
+ :count="1">
40
+ </BaseCounter>
36
41
  </div>
37
42
  </BaseSideNavigationItem>
38
43
  <BaseSideNavigationItem to="/setup">
@@ -83,7 +83,7 @@ const sizeClassOuter = computed(() => {
83
83
  const sizeClassInner = computed(() => {
84
84
  switch (size.value) {
85
85
  case 'xs':
86
- return 'text-xs px-3 py-0.5 font-normal';
86
+ return 'text-xs px-3 py-0.5 font-light';
87
87
  case 'sm':
88
88
  return 'text-sm px-4 py-0.5 font-normal';
89
89
  case 'md':
@@ -5,7 +5,7 @@
5
5
  >
6
6
  <section>
7
7
  <!-- Label -->
8
- <header class="mb-0.5 text-base font-medium">
8
+ <header class="mb-1 text-base font-medium">
9
9
  {{ label }}
10
10
  </header>
11
11
  <!-- Content -->
@@ -13,29 +13,29 @@
13
13
  class="flex"
14
14
  :class="[centerClass]"
15
15
  >
16
- <div class="text-3xl font-bold leading-tight">
16
+ <div class="text-3xl font-semibold leading-tight">
17
17
  {{ primaryValue }}
18
18
  </div>
19
19
 
20
20
  <div
21
21
  v-if="secondaryValue"
22
- class="ml-1 flex rounded-md px-1 text-lg font-bold"
22
+ class="ml-2 flex rounded-full px-1.5"
23
23
  :class="[backgroundClass, textClass, centerClass]"
24
24
  >
25
25
  <!-- Icon trend -->
26
26
  <div v-if="trend">
27
27
  <BaseIcon
28
28
  :icon="icon"
29
- :class="iconClass"
29
+ class="w-4 h-4"
30
30
  />
31
31
  </div>
32
- <div class="text-lg">
32
+ <div class="text-sm font-medium">
33
33
  {{ secondaryValue }}
34
34
  </div>
35
35
  </div>
36
36
  </div>
37
37
  <!-- Caption -->
38
- <footer class="text-base text-slate-500">
38
+ <footer class="text-sm text-slate-500 font-light">
39
39
  {{ caption }}
40
40
  </footer>
41
41
  </section>
@@ -73,24 +73,21 @@ export default defineComponent({
73
73
  computed: {
74
74
  backgroundClass(): string {
75
75
  if (this.trend == 'up') {
76
- return 'bg-green-50';
76
+ return 'bg-green-100 border border-green-300';
77
77
  }
78
78
  if (this.trend == 'down') {
79
- return 'bg-red-50';
79
+ return 'bg-red-100 border border-red-300';
80
80
  }
81
81
  return '';
82
82
  },
83
83
  textClass(): string {
84
84
  if (this.trend == 'up') {
85
- return 'text-green-700';
85
+ return 'text-green-800';
86
86
  }
87
87
  if (this.trend == 'down') {
88
- return 'text-red-700';
88
+ return 'text-red-800';
89
89
  }
90
- return 'text-slate-400';
91
- },
92
- iconClass(): string {
93
- return 'w-5 h-5';
90
+ return 'text-slate-900';
94
91
  },
95
92
  icon(): string {
96
93
  if (this.trend == 'up') {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <li>
2
+ <li class="[&:first-child_a]:pl-0 [&:last-child_a]:pr-0">
3
3
  <RouterLink
4
4
  v-slot="{ href, navigate, isActive, isExactActive }"
5
5
  :to="to"
@@ -18,19 +18,20 @@
18
18
  ]"
19
19
  @click.prevent="onClick(navigate)"
20
20
  >
21
- <div
22
- class="relative flex"
23
- :class="sizeClassInner"
24
- >
21
+ <div class="relative flex py-1">
25
22
  <div
26
- class="absolute left-0 bottom-0 w-full"
23
+ v-if="isActiveInternal(isActive, isExactActive)"
24
+ class="absolute left-0 bottom-0 w-full h-[2px] bg-primary-600"
25
+ />
26
+ <div
27
+ class="whitespace-nowrap rounded-md"
27
28
  :class="[
28
29
  isActiveInternal(isActive, isExactActive)
29
- ? 'h-[2px] bg-primary-600'
30
- : 'group-hover:h-px group-hover:bg-slate-700',
30
+ ? 'group-hover:bg-primary-100'
31
+ : 'group-hover:bg-slate-200',
32
+ sizeClassInner
31
33
  ]"
32
- />
33
- <div class="whitespace-nowrap">
34
+ >
34
35
  <slot :active="isActiveInternal(isActive, isExactActive)" />
35
36
  </div>
36
37
  </div>
@@ -73,24 +74,24 @@ const sizeClassOuter = computed(() => {
73
74
  case 'xs':
74
75
  return 'px-1';
75
76
  case 'sm':
76
- return 'px-2';
77
+ return 'px-1.5';
77
78
  case 'md':
78
- return 'px-2.5';
79
+ return 'px-2';
79
80
  case 'lg':
80
- return 'px-3';
81
+ return 'px-2';
81
82
  }
82
83
  });
83
84
 
84
85
  const sizeClassInner = computed(() => {
85
86
  switch (size.value) {
86
87
  case 'xs':
87
- return 'text-xs py-2 px-1 font-normal';
88
+ return 'text-xs py-1 px-1 font-light';
88
89
  case 'sm':
89
- return 'text-sm py-2.5 px-1 font-normal';
90
+ return 'text-sm py-1 px-2 font-normal';
90
91
  case 'md':
91
- return 'text-sm py-4 px-1 font-normal';
92
+ return 'text-sm py-1.5 px-2 font-normal';
92
93
  case 'lg':
93
- return 'text-base py-4 px-1 font-normal';
94
+ return 'text-base py-1.5 px-3 font-normal';
94
95
  }
95
96
  });
96
97
  </script>
@@ -88,23 +88,19 @@
88
88
  ]"
89
89
  >
90
90
  <svg
91
- viewBox="0 0 24 24"
91
+ viewBox="0 0 20 20"
92
92
  class="absolute top-1/2 h-5 w-5 -translate-y-1/2"
93
93
  >
94
- <g transform="translate(0 -3)">
95
- <path
96
- :opacity="!isAsc ? '0.5' : '1'"
97
- fill="currentColor"
98
- d="M8.71 12.29L11.3 9.7a.996.996 0 0 1 1.41 0l2.59 2.59c.63.63.18 1.71-.71 1.71H9.41c-.89 0-1.33-1.08-.7-1.71z"
99
- ></path>
100
- </g>
101
- <g transform="translate(0 3)">
102
- <path
103
- :opacity="isAsc ? '0.5' : '1'"
104
- fill="currentColor"
105
- d="m8.71 11.71l2.59 2.59c.39.39 1.02.39 1.41 0l2.59-2.59c.63-.63.18-1.71-.71-1.71H9.41c-.89 0-1.33 1.08-.7 1.71z"
106
- ></path>
107
- </g>
94
+ <path
95
+ :opacity="!isAsc ? '0.5' : '1'"
96
+ fill="currentColor"
97
+ d="M9.116 4.823a1.25 1.25 0 0 1 1.768 0l2.646 2.647a.75.75 0 0 1-1.06 1.06l-2.47-2.47-2.47 2.47a.75.75 0 1 1-1.06-1.06l2.646-2.647Z"
98
+ ></path>
99
+ <path
100
+ :opacity="isAsc ? '0.5' : '1'"
101
+ fill="currentColor"
102
+ d="M9.116 15.177a1.25 1.25 0 0 0 1.768 0l2.646-2.647a.75.75 0 0 0-1.06-1.06l-2.47 2.47-2.47-2.47a.75.75 0 0 0-1.06 1.06l2.646 2.647Z"
103
+ ></path>
108
104
  </svg>
109
105
  </div>
110
106
  </button>
@@ -180,7 +176,7 @@
180
176
  scoped
181
177
  name="default"
182
178
  tag="td"
183
- class="bg-white text-sm"
179
+ class="bg-white text-sm font-light"
184
180
  :class="[
185
181
  borderBottomClasses(index, row),
186
182
  column.clickable ? 'cursor-pointer' : '',
@@ -831,7 +827,7 @@ function zIndex(th: boolean) {
831
827
  function detailsStyles(th: boolean): any {
832
828
  if (props.detailed) {
833
829
  return {
834
- zIndex: zIndex(th),
830
+ zIndex: zIndex(th) + 1,
835
831
  position: 'sticky',
836
832
  left: 0,
837
833
  width: DETAIL_ROW_WIDTH + 'px',
@@ -845,7 +841,7 @@ function detailsStyles(th: boolean): any {
845
841
  function checkStyles(th: boolean): any {
846
842
  if (props.checkable) {
847
843
  return {
848
- zIndex: zIndex(th),
844
+ zIndex: zIndex(th) + 1,
849
845
  position: 'sticky',
850
846
  left: props.detailed ? DETAIL_ROW_WIDTH + 'px' : 0,
851
847
  width: CHECK_ROW_WIDTH + 'px',
@@ -40,7 +40,7 @@ import { twMerge } from 'tailwind-merge';
40
40
  import { PropType } from 'vue';
41
41
 
42
42
  const BASE_TEXTAREA_CLASSES =
43
- 'py-2 px-3 font-normal text-base disabled:cursor-not-allowed disabled:text-slate-300 font-sans rounded leading-normal tracking-normal border';
43
+ 'py-2 px-3 font-normal text-base disabled:cursor-not-allowed disabled:text-slate-300 font-sans rounded leading-normal tracking-normal border placeholder:text-slate-400 placeholder:font-light';
44
44
 
45
45
  const BASE_GRID_AREA = '1 / 1 / 2 / 2';
46
46
 
@@ -11,7 +11,7 @@
11
11
  <div class="relative pb-8">
12
12
  <span
13
13
  v-if="index != items.length - 1"
14
- class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-slate-200"
14
+ class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-slate-300"
15
15
  aria-hidden="true"
16
16
  />
17
17
  <BaseTimelineItem :item="item" />
@@ -3,12 +3,12 @@
3
3
  <div>
4
4
  <span
5
5
  :class="[
6
- iconBackgroundClass,
7
- 'flex h-8 w-8 items-center justify-center rounded-full ring-8 ring-white',
6
+ 'flex h-8 w-8 items-center justify-center rounded-full',
8
7
  ]"
8
+ :style="colorStyle"
9
9
  >
10
10
  <BaseIcon
11
- class="h-5 w-5 text-white"
11
+ class="h-5 w-5"
12
12
  aria-hidden="true"
13
13
  :icon="item.icon"
14
14
  />
@@ -19,19 +19,19 @@
19
19
  :class="{ 'pt-1.5': !item.description }"
20
20
  >
21
21
  <div>
22
- <p class="text-sm leading-tight text-slate-600">
22
+ <p class="text-sm leading-tight text-slate-900">
23
23
  {{ item.title }}
24
24
  </p>
25
25
  <p
26
26
  v-if="item.description"
27
- class="mt-1 text-xs leading-tight text-slate-500"
27
+ class="mt-1 text-xs leading-tight text-slate-500 font-light"
28
28
  >
29
29
  {{ item.description }}
30
30
  </p>
31
31
  </div>
32
32
  <div
33
33
  v-if="item.date"
34
- class="whitespace-nowrap text-right text-sm text-slate-500"
34
+ class="whitespace-nowrap text-right text-xs text-slate-500 font-light"
35
35
  >
36
36
  <time :datetime="item.date">{{ item.date }}</time>
37
37
  </div>
@@ -41,9 +41,9 @@
41
41
 
42
42
  <script lang="ts" setup>
43
43
  import { TimelineItem } from '../types/TimelineItem';
44
- import { Color } from '../types/Color';
45
44
  import { PropType } from 'vue';
46
45
  import { Icon as BaseIcon } from '@iconify/vue';
46
+ import { getColorConfig } from '@/utils/colors';
47
47
 
48
48
  const props = defineProps({
49
49
  item: {
@@ -52,28 +52,18 @@ const props = defineProps({
52
52
  },
53
53
  });
54
54
 
55
- const iconBackgroundClass = computed((): string => {
56
- if (props.item.color == Color.primary) {
57
- return 'bg-primary-600';
58
- }
59
- if (props.item.color == Color.danger) {
60
- return 'bg-red-600';
61
- }
62
- if (props.item.color == Color.warning) {
63
- return 'bg-yellow-600';
64
- }
65
- if (props.item.color == Color.info) {
66
- return 'bg-blue-500';
67
- }
68
- if (props.item.color == Color.grey) {
69
- return 'bg-slate-500';
70
- }
71
- if (props.item.color == Color.black) {
72
- return 'bg-slate-900';
73
- }
74
- if (props.item.color == Color.success) {
75
- return 'bg-green-500';
76
- }
77
- return 'bg-slate-500';
55
+ const colorStyle = computed((): Record<string, string> => {
56
+ const config = getColorConfig(props.item.color ?? 'gray', false);
57
+
58
+ const styles: Record<string, string> = {
59
+ backgroundColor: config.backgroundColor,
60
+ color: config.textColor,
61
+ borderColor: config.borderColor,
62
+ borderWidth: '1px',
63
+ borderStyle: 'solid',
64
+ };
65
+
66
+ return styles;
78
67
  });
68
+
79
69
  </script>
@@ -0,0 +1,50 @@
1
+ import BaseToast from './BaseToast.vue';
2
+
3
+ export default {
4
+ title: 'Components/BaseToast',
5
+ component: BaseToast,
6
+ args: {
7
+ text: 'Successfully saved',
8
+ },
9
+ argTypes: {
10
+ color: {
11
+ control: { type: 'select' },
12
+ options: ['success', 'info', 'warning', 'danger'],
13
+ },
14
+ },
15
+ };
16
+
17
+ const Template = (args) => ({
18
+ components: {
19
+ BaseToast,
20
+ },
21
+ setup() {
22
+ return { args };
23
+ },
24
+ template: `
25
+ <BaseToast v-bind="args" @close="onClose"></BaseToast>
26
+ `,
27
+ });
28
+
29
+ export const Demo = Template.bind({});
30
+ Demo.args = {};
31
+
32
+ const colors = ['info', 'success', 'warning', 'danger'];
33
+
34
+ const Colors = (args) => ({
35
+ components: {
36
+ BaseToast,
37
+ },
38
+ setup() {
39
+ return { args, colors };
40
+ },
41
+ template: `
42
+ <div v-for="color in colors" class="mb-1">
43
+ <p class="text-xs text-slate-600 leading-tight mb-1">{{ color }}</p>
44
+ <BaseToast v-bind="args" :color="color"></BaseToast>
45
+ </div>
46
+ `,
47
+ });
48
+
49
+ export const AllColors = Colors.bind({});
50
+ AllColors.args = {};
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <div class="flex justify-center">
3
+ <div class="inline-flex items-center max-w-sm overflow-hidden rounded bg-slate-700 shadow-xl py-3 px-3">
4
+ <BaseIcon
5
+ :icon="icon"
6
+ class="w-5 h-5 mr-2.5 shrink-0"
7
+ :class="colorClass"
8
+ />
9
+
10
+ <p class="text-sm leading-snug text-white font-light line-clamp-4">
11
+ {{ text }}
12
+ </p>
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <script lang="ts" setup>
18
+ const props = defineProps<{
19
+ text: string;
20
+ color: string;
21
+ }>();
22
+
23
+ const colorClass = computed(() => {
24
+ if (props.color == 'warning') {
25
+ return 'text-yellow-500';
26
+ } else if (props.color == 'danger') {
27
+ return 'text-red-500';
28
+ } else if (props.color == 'success') {
29
+ return 'text-green-500';
30
+ }
31
+ return 'text-blue-500';
32
+ });
33
+
34
+ const icon = computed(() => {
35
+ if (props.color == 'warning') {
36
+ return 'heroicons-solid:exclamation';
37
+ } else if (props.color == 'danger') {
38
+ return 'heroicons-solid:exclamation-circle';
39
+ } else if (props.color == 'success') {
40
+ return 'heroicons-solid:check-circle';
41
+ }
42
+ return 'heroicons-solid:information-circle';
43
+ });
44
+ </script>
@@ -0,0 +1,132 @@
1
+ import BaseHeader from '../components/BaseHeader.vue';
2
+ import BaseTabs from '../components/BaseTabs.vue';
3
+ import BaseTabItem from '../components/BaseTabItem.vue';
4
+ import BaseDataTable from '../components/BaseDataTable.vue';
5
+ import BaseTableColumn from '../components/BaseTableColumn.vue';
6
+ import BaseBoolean from '../components/BaseBoolean.vue';
7
+ import BaseSelect from '../components/BaseSelect.vue';
8
+ import BaseBadge from '../components/BaseBadge.vue';
9
+ import BaseCounter from '../components/BaseCounter.vue';
10
+ import BaseAppNotifications from '../components/BaseAppNotifications.vue';
11
+ import BaseAppDialogs from '../components/BaseAppDialogs.vue';
12
+ import BaseContainer from '../components/BaseContainer.vue';
13
+ import { DateTime } from 'luxon';
14
+ import { templateDataTable } from '../../.storybook/utils';
15
+
16
+ export default {
17
+ title: 'Pages/List',
18
+ component: BaseDataTable,
19
+ parameters: {
20
+ layout: 'fullscreen',
21
+ },
22
+ argTypes: {
23
+ layout: {
24
+ control: { type: 'select' },
25
+ options: ['default', 'compact'],
26
+ },
27
+ size: {
28
+ control: { type: 'select' },
29
+ options: ['sm', 'md'],
30
+ }
31
+ },
32
+ args: {
33
+ url: 'https://effettandem.com/api/content/articles',
34
+ urlQuery: {
35
+ per_page: 10,
36
+ },
37
+ historyMode: false,
38
+ detailed: true,
39
+ searchable: true,
40
+ checkable: true,
41
+ layout: 'compact',
42
+ size: 'sm',
43
+ showUrl() {
44
+ return '/';
45
+ },
46
+ editUrl() {
47
+ return '/';
48
+ },
49
+ deleteUrl() {
50
+ return '/';
51
+ },
52
+ actions: [
53
+ {
54
+ label: 'Export',
55
+ icon: 'heroicons:arrow-down-tray',
56
+ action: () => alert('export!'),
57
+ },
58
+ { line: true },
59
+ {
60
+ label: 'Delete all',
61
+ icon: 'heroicons:trash',
62
+ action: () => alert('Delete All!'),
63
+ color: 'danger',
64
+ },
65
+ ],
66
+ checkableActions: [
67
+ {
68
+ label: 'Delete all',
69
+ action: () => {
70
+ alert('delete!');
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ };
76
+
77
+ const templateComponents = {
78
+ BaseHeader,
79
+ BaseTabs,
80
+ BaseTabItem,
81
+ BaseDataTable,
82
+ BaseTableColumn,
83
+ BaseBoolean,
84
+ BaseSelect,
85
+ BaseBadge,
86
+ BaseAppNotifications,
87
+ BaseAppDialogs,
88
+ BaseCounter,
89
+ BaseContainer,
90
+ };
91
+
92
+ const template = `
93
+ <div class="bg-slate-100 py-6">
94
+ <BaseContainer>
95
+ <BaseHeader
96
+ title="Articles"
97
+ :actions="[
98
+ {label: 'New article', icon: 'heroicons:plus', action: () => alert('new article!'), color: 'primary'},
99
+ {label: 'Export', icon: 'heroicons:arrow-down-tray', action: () => alert('export!')},
100
+ {label: 'Import', icon: 'heroicons:arrow-up-tray', action: () => alert('import!')},
101
+ ]"
102
+ :breadcrumbs="[{label: 'Home', to: '/'}, {label: 'Articles', to: '/articles'}]"
103
+ class="mb-1"
104
+ ></BaseHeader>
105
+
106
+ <BaseTabs class="mb-4" size="sm">
107
+ <BaseTabItem to="/">All</BaseTabItem>
108
+ <BaseTabItem to="/settings">Videos <BaseCounter :count="4"></BaseCounter></BaseTabItem>
109
+ <BaseTabItem to="/setup">Articles</BaseTabItem>
110
+ </BaseTabs>
111
+
112
+ ${templateDataTable}
113
+
114
+ <BaseAppNotifications></BaseAppNotifications>
115
+ <BaseAppDialogs></BaseAppDialogs>
116
+ </BaseContainer>
117
+ </div>
118
+ `;
119
+
120
+ const Template = (args) => ({
121
+ components: templateComponents,
122
+ template: template,
123
+ setup() {
124
+ function onCellClick(row) {
125
+ alert('Cell click: ' + row.id);
126
+ }
127
+
128
+ return { args, onCellClick, DateTime };
129
+ },
130
+ });
131
+
132
+ export const Demo = Template.bind({});