sprintify-ui 0.0.10 → 0.0.12

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 (103) hide show
  1. package/dist/sprintify-ui.es.js +5174 -6624
  2. package/dist/style.css +1 -1
  3. package/dist/tailwindcss/index.js +23 -0
  4. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +0 -1
  5. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +0 -1
  6. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +13 -3
  7. package/dist/types/src/components/BaseCharacterCounter.vue.d.ts +143 -0
  8. package/dist/types/src/components/BaseDataTable.vue.d.ts +95 -64
  9. package/dist/types/src/components/BaseDialog.vue.d.ts +8 -8
  10. package/dist/types/src/components/BaseFilePicker.vue.d.ts +3 -3
  11. package/dist/types/src/components/BaseInput.vue.d.ts +39 -5
  12. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +84 -12
  13. package/dist/types/src/components/BaseMenuItem.vue.d.ts +4 -4
  14. package/dist/types/src/components/BaseModalCenter.vue.d.ts +8 -8
  15. package/dist/types/src/components/BaseModalSide.vue.d.ts +8 -8
  16. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +4 -4
  17. package/dist/types/src/components/BasePagination.vue.d.ts +105 -13
  18. package/dist/types/src/components/BasePaginationSimple.vue.d.ts +2 -2
  19. package/dist/types/src/components/BaseSelect.vue.d.ts +130 -26
  20. package/dist/types/src/components/BaseSwitch.vue.d.ts +15 -8
  21. package/dist/types/src/components/BaseTabItem.vue.d.ts +26 -4
  22. package/dist/types/src/components/BaseTableColumn.vue.d.ts +4 -4
  23. package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +175 -21
  24. package/dist/types/src/components/index.d.ts +24 -1
  25. package/dist/types/src/index.d.ts +4 -0
  26. package/dist/types/src/svg/BaseEmptyState.vue.d.ts +2 -0
  27. package/dist/types/src/{components/BaseSpinner.vue.d.ts → svg/BaseSpinnerLarge.vue.d.ts} +0 -0
  28. package/dist/types/src/svg/BaseSpinnerSmall.vue.d.ts +44 -0
  29. package/dist/types/src/types/types.d.ts +1 -1
  30. package/package.json +4 -2
  31. package/src/components/BaseAutocomplete.stories.js +7 -4
  32. package/src/components/BaseAutocomplete.vue +44 -15
  33. package/src/components/BaseAutocompleteFetch.stories.js +6 -3
  34. package/src/components/BaseAutocompleteFetch.vue +8 -3
  35. package/src/components/BaseBelongsTo.stories.js +9 -4
  36. package/src/components/BaseBelongsTo.vue +1 -0
  37. package/src/components/BaseCard.vue +1 -1
  38. package/src/components/BaseCharacterCounter.stories.js +30 -0
  39. package/src/components/BaseCharacterCounter.vue +60 -0
  40. package/src/components/BaseDataIterator.stories.js +102 -3
  41. package/src/components/BaseDataIterator.vue +75 -49
  42. package/src/components/BaseDataTable.stories.js +149 -2
  43. package/src/components/BaseDataTable.vue +34 -28
  44. package/src/components/BaseDataTableToggleColumns.vue +1 -1
  45. package/src/components/BaseDateSelect.vue +6 -2
  46. package/src/components/BaseDescriptionListItem.vue +40 -4
  47. package/src/components/BaseDialog.stories.js +51 -0
  48. package/src/components/BaseDialog.vue +13 -7
  49. package/src/components/BaseFilePicker.stories.js +51 -0
  50. package/src/components/BaseFilePicker.vue +6 -6
  51. package/src/components/BaseFileUploader.stories.js +80 -0
  52. package/src/components/BaseFileUploader.vue +16 -3
  53. package/src/components/BaseInput.stories.js +46 -0
  54. package/src/components/BaseInput.vue +10 -2
  55. package/src/components/BaseInputLabel.stories.js +31 -0
  56. package/src/components/BaseInputLabel.vue +1 -1
  57. package/src/components/BaseLoadingCover.stories.js +55 -0
  58. package/src/components/BaseLoadingCover.vue +27 -17
  59. package/src/components/BaseMenu.stories.js +125 -0
  60. package/src/components/BaseModalCenter.stories.js +61 -0
  61. package/src/components/BaseModalCenter.vue +2 -2
  62. package/src/components/BaseModalSide.stories.js +55 -0
  63. package/src/components/BaseModalSide.vue +2 -2
  64. package/src/components/BaseNavbar.stories.js +150 -0
  65. package/src/components/BaseNavbar.vue +3 -0
  66. package/src/components/BaseNavbarItem.vue +1 -0
  67. package/src/components/BaseNavbarItemContent.vue +3 -0
  68. package/src/components/BasePagination.stories.js +32 -0
  69. package/src/components/BasePagination.vue +126 -40
  70. package/src/components/BasePaginationSimple.vue +3 -3
  71. package/src/components/BasePanel.stories.js +56 -0
  72. package/src/components/BasePassword.stories.js +36 -0
  73. package/src/components/BasePassword.vue +11 -5
  74. package/src/components/BaseProcessRing.stories.js +27 -0
  75. package/src/components/BaseReadMore.stories.js +30 -0
  76. package/src/components/BaseReadMore.vue +1 -1
  77. package/src/components/BaseSelect.stories.js +67 -0
  78. package/src/components/BaseSelect.vue +144 -44
  79. package/src/components/BaseSideNavigation.stories.js +55 -0
  80. package/src/components/BaseSideNavigation.vue +7 -2
  81. package/src/components/BaseSideNavigationItem.vue +11 -3
  82. package/src/components/BaseSkeleton.stories.js +36 -0
  83. package/src/components/BaseSwitch.stories.js +101 -0
  84. package/src/components/BaseSwitch.vue +90 -12
  85. package/src/components/BaseSystemAlert.stories.js +63 -0
  86. package/src/components/BaseTabItem.vue +19 -6
  87. package/src/components/BaseTable.vue +42 -29
  88. package/src/components/BaseTableColumn.vue +2 -2
  89. package/src/components/BaseTabs.stories.js +54 -0
  90. package/src/components/BaseTabs.vue +3 -3
  91. package/src/components/BaseTextarea.stories.js +35 -0
  92. package/src/components/BaseTextarea.vue +1 -1
  93. package/src/components/BaseTextareaAutoresize.stories.js +49 -0
  94. package/src/components/BaseTextareaAutoresize.vue +83 -87
  95. package/src/components/index.ts +46 -0
  96. package/src/lang/en.json +1 -0
  97. package/src/lang/fr.json +1 -0
  98. package/src/svg/BaseEmptyState.vue +34 -0
  99. package/src/{components/BaseSpinner.vue → svg/BaseSpinnerLarge.vue} +0 -0
  100. package/src/svg/BaseSpinnerSmall.vue +9 -0
  101. package/src/types/types.ts +1 -1
  102. package/dist/types/src/components/BaseWordCount.vue.d.ts +0 -31
  103. package/src/components/BaseWordCount.vue +0 -36
@@ -1,59 +1,159 @@
1
1
  <template>
2
2
  <select
3
- :value="modelValue"
3
+ ref="select"
4
+ :value="modelValueInternal"
4
5
  :name="name"
5
6
  :disabled="disabled"
6
7
  :required="required"
7
- class="rounded"
8
+ class="rounded border border-slate-300 disabled:cursor-not-allowed disabled:text-slate-300 disabled:opacity-100"
9
+ :class="[!modelValue && required ? 'text-slate-400' : '']"
8
10
  @change="onChange($event)"
9
11
  >
10
- <option v-if="required" selected disabled hidden value="">
11
- {{ placeholder ? placeholder : $t('sui.select_an_option') }}
12
- </option>
12
+ <template v-if="required">
13
+ <option disabled hidden :value="EMPTY_VALUE_INTERNAL">
14
+ {{ placeholder ? placeholder : $t('sui.select_an_option') }}
15
+ </option>
16
+ </template>
17
+ <template v-else>
18
+ <option :value="EMPTY_VALUE_INTERNAL">
19
+ {{ placeholder ? placeholder : $t('sui.select_an_option') }}
20
+ </option>
21
+ </template>
13
22
  <slot />
14
23
  </select>
15
24
  </template>
16
25
 
17
- <script lang="ts">
18
- import { defineComponent, PropType } from 'vue';
19
- import { get } from 'lodash';
20
-
21
- export default defineComponent({
22
- props: {
23
- modelValue: {
24
- default: null,
25
- type: [String, Number, null] as PropType<string | number | null>,
26
- },
27
- name: {
28
- default: undefined,
29
- type: String,
30
- },
31
- placeholder: {
32
- default: '',
33
- type: String,
34
- },
35
- disabled: {
36
- default: false,
37
- type: Boolean,
38
- },
39
- required: {
40
- default: false,
41
- type: Boolean,
42
- },
26
+ <script lang="ts" setup>
27
+ import { PropType, Ref } from 'vue';
28
+ import { get, isEqual } from 'lodash';
29
+ import { useMounted } from '@vueuse/core';
30
+
31
+ type Option = string | number | null;
32
+
33
+ const EMPTY_VALUE_INTERNAL = '';
34
+ const EMPTY_VALUE_EXTERNAL = null;
35
+
36
+ const props = defineProps({
37
+ modelValue: {
38
+ default: undefined,
39
+ type: [String, Number, null, undefined] as PropType<Option>,
40
+ },
41
+ name: {
42
+ default: undefined,
43
+ type: String,
43
44
  },
44
- emits: ['update:modelValue'],
45
- methods: {
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- onChange(event: Event): any {
48
- if (event === null) {
49
- this.$emit('update:modelValue', null);
50
- }
51
- const value = get(event, 'target.value', null);
52
- if (value === null) {
53
- this.$emit('update:modelValue', null);
54
- }
55
- this.$emit('update:modelValue', value);
56
- },
45
+ placeholder: {
46
+ default: '',
47
+ type: String,
57
48
  },
49
+ disabled: {
50
+ default: false,
51
+ type: Boolean,
52
+ },
53
+ required: {
54
+ default: false,
55
+ type: Boolean,
56
+ },
57
+ });
58
+
59
+ const mounted = useMounted();
60
+ const select = ref(null) as Ref<HTMLSelectElement | null>;
61
+
62
+ const emit = defineEmits(['update:modelValue']);
63
+
64
+ function isEmptyExternal(value: string | number | null | undefined) {
65
+ if (value === undefined || value === EMPTY_VALUE_EXTERNAL) {
66
+ return true;
67
+ }
68
+
69
+ return false;
70
+ }
71
+
72
+ function isEmptyInternal(value: string | number | null | undefined) {
73
+ if (value === undefined || value === EMPTY_VALUE_INTERNAL) {
74
+ return true;
75
+ }
76
+
77
+ return false;
78
+ }
79
+
80
+ /**
81
+ * Transform to external empty NULL
82
+ * to internal empty ''.
83
+ */
84
+ const modelValueInternal = computed(() => {
85
+ if (isEmptyExternal(props.modelValue)) {
86
+ return EMPTY_VALUE_INTERNAL;
87
+ }
88
+
89
+ if (!validModelValue()) {
90
+ return EMPTY_VALUE_INTERNAL;
91
+ }
92
+
93
+ return props.modelValue;
58
94
  });
95
+
96
+ /**
97
+ * Checks if the current modelValue is valid
98
+ */
99
+ function validModelValue(): boolean {
100
+ if (props.modelValue === EMPTY_VALUE_EXTERNAL) {
101
+ return true;
102
+ }
103
+
104
+ const options = [...(select.value?.options ?? [])];
105
+ return options.findIndex((o) => isEqual(o.value, props.modelValue)) != -1;
106
+ }
107
+
108
+ /**
109
+ * This watcher is used to update the parent value
110
+ * if the given modelValue should be empty.
111
+ */
112
+ watch(
113
+ () => props.modelValue,
114
+ () => validateAndFixModelVale()
115
+ );
116
+
117
+ /**
118
+ * Re-trigger the same validation on mounted
119
+ */
120
+ onMounted(() => {
121
+ validateAndFixModelVale();
122
+ });
123
+
124
+ /**
125
+ * Validate the current Model Value. Transform to external empty if :
126
+ * 1. is internal empty
127
+ * 2. is in the current options
128
+ */
129
+ function validateAndFixModelVale() {
130
+ if (!mounted.value) {
131
+ return;
132
+ }
133
+ if (isEmptyInternal(props.modelValue)) {
134
+ emit('update:modelValue', EMPTY_VALUE_EXTERNAL);
135
+ } else if (!validModelValue()) {
136
+ emit('update:modelValue', EMPTY_VALUE_EXTERNAL);
137
+ }
138
+ }
139
+
140
+ /**
141
+ *
142
+ * Emit change while mutating internal empty value ''
143
+ * to external empty value NULL.
144
+ */
145
+ function onChange(event: Event) {
146
+ if (event === null) {
147
+ emit('update:modelValue', EMPTY_VALUE_EXTERNAL);
148
+ }
149
+
150
+ const value = get(event, 'target.value', null);
151
+
152
+ if (isEmptyExternal(value)) {
153
+ emit('update:modelValue', EMPTY_VALUE_EXTERNAL);
154
+ return;
155
+ }
156
+
157
+ emit('update:modelValue', value);
158
+ }
59
159
  </script>
@@ -0,0 +1,55 @@
1
+ import BaseSideNavigation from './BaseSideNavigation.vue';
2
+ import BaseSideNavigationItem from './BaseSideNavigationItem.vue';
3
+ import BaseContainer from './BaseContainer.vue';
4
+ import BaseCard from './BaseCard.vue';
5
+ import BaseCardRow from './BaseCardRow.vue';
6
+
7
+ export default {
8
+ title: 'Layout/BaseSideNavigation',
9
+ component: BaseSideNavigation,
10
+ args: {},
11
+ };
12
+
13
+ const Template = (args) => ({
14
+ components: {
15
+ BaseSideNavigation,
16
+ BaseSideNavigationItem,
17
+ BaseContainer,
18
+ BaseCard,
19
+ BaseCardRow,
20
+ },
21
+ setup() {
22
+ return { args };
23
+ },
24
+ template: `
25
+ <div class="bg-slate-100 py-10">
26
+ <BaseContainer>
27
+ <div class="md:flex">
28
+ <div class="shrink-0 mb-6 md:mb-0" style="margin-right: 2rem; width: 200px;">
29
+ <BaseSideNavigation v-bind="args">
30
+ <BaseSideNavigationItem to="/">
31
+ Home
32
+ </BaseSideNavigationItem>
33
+ <BaseSideNavigationItem to="/setup">
34
+ Setup
35
+ </BaseSideNavigationItem>
36
+ <BaseSideNavigationItem to="/settings">
37
+ Settings
38
+ </BaseSideNavigationItem>
39
+ </BaseSideNavigation>
40
+ </div>
41
+ <div class="grow">
42
+ <BaseCard>
43
+ <BaseCardRow>
44
+ {{ $route.path }}
45
+ </BaseCardRow>
46
+ </BaseCard>
47
+ </div>
48
+ </div>
49
+ </BaseContainer>
50
+ </div>
51
+ `,
52
+ });
53
+
54
+ export const Demo = Template.bind({});
55
+ Demo.args = {};
@@ -1,6 +1,11 @@
1
1
  <template>
2
- <nav class="space-y-1" aria-label="Sidebar">
3
- <slot />
2
+ <nav aria-label="Sidebar" class="relative">
3
+ <div class="absolute bottom-0 left-0 h-full w-px bg-slate-300" />
4
+ <div class="relative overflow-x-auto overflow-y-hidden">
5
+ <div class="space-y-2">
6
+ <slot />
7
+ </div>
8
+ </div>
4
9
  </nav>
5
10
  </template>
6
11
 
@@ -3,15 +3,23 @@
3
3
  <a
4
4
  :href="disabled ? undefined : href"
5
5
  :disabled="disabled"
6
- class="flex items-center rounded-md px-3 py-2 text-sm font-medium"
6
+ class="group relative flex items-center px-3 py-1"
7
7
  :class="[
8
8
  isActive
9
- ? 'bg-slate-300 bg-opacity-60 text-black'
10
- : 'text-slate-600 hover:bg-slate-200 hover:bg-opacity-70 hover:text-slate-900',
9
+ ? 'font-semibold text-blue-600'
10
+ : 'text-slate-600 hover:text-slate-900',
11
11
  disabled ? 'cursor-not-allowed opacity-60' : '',
12
12
  ]"
13
13
  @click.prevent="onClick(navigate)"
14
14
  >
15
+ <div
16
+ class="absolute left-0 top-0 h-full"
17
+ :class="[
18
+ isActive
19
+ ? 'w-[2px] bg-blue-600'
20
+ : 'group-hover:w-px group-hover:bg-slate-700',
21
+ ]"
22
+ ></div>
15
23
  <slot />
16
24
  </a>
17
25
  </router-link>
@@ -0,0 +1,36 @@
1
+ import BaseSkeleton from './BaseSkeleton.vue';
2
+ import BaseContainer from './BaseContainer.vue';
3
+
4
+ export default {
5
+ title: 'Components/BaseSkeleton',
6
+ component: BaseSkeleton,
7
+ args: {},
8
+ };
9
+
10
+ const Template = (args) => ({
11
+ components: {
12
+ BaseSkeleton,
13
+ BaseContainer,
14
+ },
15
+ setup() {
16
+ return { args };
17
+ },
18
+ template: `
19
+ <BaseContainer size="xl">
20
+ <div class="flex space-x-5">
21
+ <div class="shrink-0">
22
+ <BaseSkeleton class="h-16 rounded-full w-16" v-bind="args"></BaseSkeleton>
23
+ </div>
24
+ <div class="grow">
25
+ <BaseSkeleton class="w-52 h-8 mb-3" v-bind="args"></BaseSkeleton>
26
+ <BaseSkeleton class="w-full h-4 mb-1" v-bind="args"></BaseSkeleton>
27
+ <BaseSkeleton class="w-full h-4 mb-1" v-bind="args"></BaseSkeleton>
28
+ <BaseSkeleton class="w-full h-4 mb-1" v-bind="args"></BaseSkeleton>
29
+ </div>
30
+ </div>
31
+ </BaseContainer>
32
+ `,
33
+ });
34
+
35
+ export const Demo = Template.bind({});
36
+ Demo.args = {};
@@ -0,0 +1,101 @@
1
+ import BaseSwitch from './BaseSwitch.vue';
2
+ import BaseContainer from './BaseContainer.vue';
3
+
4
+ export default {
5
+ title: 'Form/BaseSwitch',
6
+ component: BaseSwitch,
7
+ args: {},
8
+ argTypes: {
9
+ color: {
10
+ control: { type: 'select' },
11
+ options: [
12
+ 'primary',
13
+ 'success',
14
+ 'info',
15
+ 'warning',
16
+ 'danger',
17
+ 'light',
18
+ 'dark',
19
+ ],
20
+ },
21
+ size: {
22
+ control: { type: 'select' },
23
+ options: ['xs', 'sm', 'base', 'lg', 'xl'],
24
+ },
25
+ },
26
+ };
27
+
28
+ const Template = (args) => ({
29
+ components: {
30
+ BaseSwitch,
31
+ BaseContainer,
32
+ },
33
+ setup() {
34
+ const value = ref(true);
35
+ return { args, value };
36
+ },
37
+ template: `
38
+ <BaseSwitch v-model="value" v-bind="args">
39
+ <span class="text-slate-600">Label</span>
40
+ </BaseSwitch>
41
+ `,
42
+ });
43
+
44
+ export const Demo = Template.bind({});
45
+ Demo.args = {};
46
+
47
+ const colors = [
48
+ 'primary',
49
+ 'info',
50
+ 'success',
51
+ 'warning',
52
+ 'danger',
53
+ 'light',
54
+ 'dark',
55
+ ];
56
+
57
+ const Colors = (args) => ({
58
+ components: {
59
+ BaseSwitch,
60
+ BaseContainer,
61
+ },
62
+ setup() {
63
+ const value = ref(true);
64
+ return { args, value, colors };
65
+ },
66
+ template: `
67
+ <div v-for="color in colors" class="mb-1">
68
+ <p class="text-xs text-slate-600 leading-tight mb-1">{{ color }}</p>
69
+ <BaseSwitch v-model="value" :color="color">
70
+ <span class="text-slate-600">Label</span>
71
+ </BaseSwitch>
72
+ </div>
73
+ `,
74
+ });
75
+
76
+ export const AllColors = Colors.bind({});
77
+ AllColors.args = {};
78
+
79
+ const sizes = ['xs', 'sm', 'base', 'lg', 'xl'];
80
+
81
+ const Sizes = (args) => ({
82
+ components: {
83
+ BaseSwitch,
84
+ BaseContainer,
85
+ },
86
+ setup() {
87
+ const value = ref(true);
88
+ return { args, value, sizes };
89
+ },
90
+ template: `
91
+ <div v-for="size in sizes" class="mb-1">
92
+ <p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
93
+ <BaseSwitch v-model="value" :size="size">
94
+ <span class="text-slate-600">Label</span>
95
+ </BaseSwitch>
96
+ </div>
97
+ `,
98
+ });
99
+
100
+ export const AllSizes = Sizes.bind({});
101
+ AllSizes.args = {};
@@ -5,17 +5,23 @@
5
5
  :model-value="modelValue"
6
6
  :class="[
7
7
  modelValue ? bg : 'bg-slate-200',
8
- 'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 ',
8
+ 'relative inline-flex shrink-0 cursor-pointer items-center rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 ',
9
9
  focus,
10
10
  ]"
11
+ :style="{
12
+ width: width + 'px',
13
+ height: height + 'px',
14
+ }"
11
15
  @update:model-value="update"
12
16
  >
13
17
  <span
14
18
  aria-hidden="true"
15
- :class="[
16
- modelValue ? 'translate-x-5' : 'translate-x-0',
17
- 'pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
18
- ]"
19
+ :style="{
20
+ height: sizePx + 'px',
21
+ width: sizePx + 'px',
22
+ transform: `translateX(${translateX}px)`,
23
+ }"
24
+ class="pointer-events-none inline-block rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"
19
25
  />
20
26
  </Switch>
21
27
  <SwitchLabel v-if="$slots.default" class="cursor-pointer">
@@ -27,7 +33,7 @@
27
33
 
28
34
  <script lang="ts">
29
35
  import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue';
30
- import { defineComponent } from 'vue';
36
+ import { defineComponent, PropType } from 'vue';
31
37
 
32
38
  export default defineComponent({
33
39
  components: {
@@ -43,11 +49,13 @@ export default defineComponent({
43
49
  },
44
50
  color: {
45
51
  default: 'primary',
46
- type: String,
52
+ type: String as PropType<
53
+ 'primary' | 'info' | 'danger' | 'warning' | 'success' | 'dark' | 'light'
54
+ >,
47
55
  },
48
56
  size: {
49
57
  default: 'base',
50
- type: String,
58
+ type: String as PropType<'xs' | 'sm' | 'base' | 'lg' | 'xl'>,
51
59
  },
52
60
  },
53
61
  emits: ['update:modelValue'],
@@ -56,26 +64,96 @@ export default defineComponent({
56
64
  if (this.color == 'primary') {
57
65
  return 'bg-primary-500';
58
66
  }
59
- if (this.color == 'red') {
67
+ if (this.color == 'info') {
68
+ return 'bg-blue-500';
69
+ }
70
+ if (this.color == 'danger') {
60
71
  return 'bg-red-500';
61
72
  }
62
- if (this.color == 'green') {
73
+ if (this.color == 'warning') {
74
+ return 'bg-yellow-500';
75
+ }
76
+ if (this.color == 'success') {
63
77
  return 'bg-green-500';
64
78
  }
79
+ if (this.color == 'light') {
80
+ return 'bg-slate-500';
81
+ }
65
82
  return 'bg-slate-900';
66
83
  },
67
84
  focus() {
68
85
  if (this.color == 'primary') {
69
86
  return 'focus:ring-primary-500';
70
87
  }
71
- if (this.color == 'red') {
88
+ if (this.color == 'info') {
89
+ return 'focus:ring-blue-500';
90
+ }
91
+ if (this.color == 'danger') {
72
92
  return 'focus:ring-red-500';
73
93
  }
74
- if (this.color == 'green') {
94
+ if (this.color == 'warning') {
95
+ return 'focus:ring-yellow-500';
96
+ }
97
+ if (this.color == 'success') {
75
98
  return 'focus:ring-green-500';
76
99
  }
100
+ if (this.color == 'light') {
101
+ return 'focus:ring-slate-500';
102
+ }
77
103
  return 'focus:ring-slate-900';
78
104
  },
105
+ sizePx() {
106
+ if (this.size == 'xs') {
107
+ return 12;
108
+ }
109
+ if (this.size == 'sm') {
110
+ return 16;
111
+ }
112
+ if (this.size == 'base') {
113
+ return 20;
114
+ }
115
+ if (this.size == 'lg') {
116
+ return 24;
117
+ }
118
+ if (this.size == 'xl') {
119
+ return 32;
120
+ }
121
+ return 16;
122
+ },
123
+ padding() {
124
+ if (this.size == 'xs') {
125
+ return 2;
126
+ }
127
+ if (this.size == 'sm') {
128
+ return 2.5;
129
+ }
130
+ if (this.size == 'base') {
131
+ return 3;
132
+ }
133
+ if (this.size == 'lg') {
134
+ return 3;
135
+ }
136
+ if (this.size == 'xl') {
137
+ return 4;
138
+ }
139
+ return 2;
140
+ },
141
+ height() {
142
+ return this.sizePx + 2 * this.padding;
143
+ },
144
+ distance() {
145
+ return 2 * this.sizePx;
146
+ },
147
+ width() {
148
+ return this.distance + 2 * this.padding;
149
+ },
150
+ translateX() {
151
+ if (this.modelValue) {
152
+ return this.padding + this.distance - this.sizePx;
153
+ }
154
+
155
+ return this.padding;
156
+ },
79
157
  },
80
158
  methods: {
81
159
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -0,0 +1,63 @@
1
+ import BaseSystemAlert from './BaseSystemAlert.vue';
2
+
3
+ export default {
4
+ title: 'Layout/BaseSystemAlert',
5
+ component: BaseSystemAlert,
6
+ args: {
7
+ to: 'https://google.com',
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
+ BaseSystemAlert,
20
+ },
21
+ setup() {
22
+ function onClose() {
23
+ alert('close');
24
+ }
25
+
26
+ return { args, onClose };
27
+ },
28
+ template: `
29
+ <BaseSystemAlert v-bind="args" @close="onClose">
30
+ Tempor nisi ut ea sit pariatur aute irure magna id id ullamco cupidatat enim.
31
+ </BaseSystemAlert>
32
+ `,
33
+ });
34
+
35
+ export const Demo = Template.bind({});
36
+ Demo.args = {};
37
+
38
+ export const Closable = Template.bind({});
39
+ Closable.args = {
40
+ closable: true,
41
+ };
42
+
43
+ const colors = ['info', 'success', 'warning', 'danger'];
44
+
45
+ const Colors = (args) => ({
46
+ components: {
47
+ BaseSystemAlert,
48
+ },
49
+ setup() {
50
+ return { args, colors };
51
+ },
52
+ template: `
53
+ <div v-for="color in colors" class="mb-1">
54
+ <p class="text-xs text-slate-600 leading-tight mb-1">{{ color }}</p>
55
+ <BaseSystemAlert v-bind="args" :color="color">
56
+ Tempor nisi ut ea sit pariatur aute irure magna id id ullamco cupidatat enim.
57
+ </BaseSystemAlert>
58
+ </div>
59
+ `,
60
+ });
61
+
62
+ export const AllColors = Colors.bind({});
63
+ AllColors.args = {};
@@ -1,17 +1,26 @@
1
1
  <template>
2
2
  <li role="presentation">
3
- <router-link v-slot="{ href, navigate, isExactActive }" :to="to" custom>
3
+ <router-link v-slot="{ href, navigate, isActive }" :to="to" custom>
4
4
  <a
5
5
  :href="href"
6
- class="relative inline-block whitespace-nowrap rounded-t-lg border-b-[2px] p-4 font-medium"
6
+ class="group relative inline-block rounded-t-lg px-2 py-3 font-medium"
7
7
  :class="[
8
- isExactActive
9
- ? 'border-blue-600 text-blue-600'
10
- : 'border-transparent hover:border-slate-300 hover:text-slate-600',
8
+ isActive ? 'text-blue-600' : 'text-slate-600 hover:text-slate-900',
9
+ disabled ? 'cursor-not-allowed opacity-60' : '',
11
10
  ]"
12
11
  @click="navigate"
13
12
  >
14
- <slot />
13
+ <div
14
+ class="absolute left-0 bottom-0 w-full"
15
+ :class="[
16
+ isActive
17
+ ? 'h-[2px] bg-blue-600'
18
+ : 'group-hover:h-px group-hover:bg-slate-700',
19
+ ]"
20
+ ></div>
21
+ <div class="whitespace-nowrap">
22
+ <slot />
23
+ </div>
15
24
  </a>
16
25
  </router-link>
17
26
  </li>
@@ -26,5 +35,9 @@ defineProps({
26
35
  required: true,
27
36
  type: [Object, String] as PropType<RouteLocationRaw>,
28
37
  },
38
+ disabled: {
39
+ default: false,
40
+ type: Boolean,
41
+ },
29
42
  });
30
43
  </script>