sprintify-ui 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/dist/sprintify-ui.es.js +5911 -3760
- package/dist/style.css +1 -1
- package/dist/tailwindcss/index.js +1 -2
- package/dist/types/src/components/BaseCharacterCounter.vue.d.ts +143 -0
- package/dist/types/src/components/BaseHasMany.vue.d.ts +277 -0
- package/dist/types/src/components/BaseInput.vue.d.ts +39 -5
- package/dist/types/src/components/BaseLoadingCover.vue.d.ts +72 -0
- package/dist/types/src/components/{BaseMediaLibraryItem.vue.d.ts → BaseMediaItem.vue.d.ts} +26 -4
- package/dist/types/src/components/BaseMediaLibrary.vue.d.ts +23 -15
- package/dist/types/src/components/BaseMediaPreview.vue.d.ts +97 -0
- package/dist/types/src/components/BaseModalCenter.vue.d.ts +8 -8
- package/dist/types/src/components/BaseModalSide.vue.d.ts +8 -8
- package/dist/types/src/components/BasePagination.vue.d.ts +105 -13
- package/dist/types/src/components/BaseSelect.vue.d.ts +130 -26
- package/dist/types/src/components/BaseSideNavigationItem.vue.d.ts +20 -1
- package/dist/types/src/components/BaseSwitch.vue.d.ts +15 -8
- package/dist/types/src/components/BaseTabItem.vue.d.ts +45 -4
- package/dist/types/src/components/BaseTagAutocomplete.vue.d.ts +25 -17
- package/dist/types/src/components/BaseTagAutocompleteFetch.vue.d.ts +37 -21
- package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +175 -21
- package/dist/types/src/components/index.d.ts +30 -1
- package/dist/types/src/index.d.ts +4 -0
- package/package.json +1 -1
- package/src/components/BaseAppDialogs.vue +2 -2
- package/src/components/BaseAppNotifications.vue +1 -1
- package/src/components/BaseAutocomplete.vue +16 -18
- package/src/components/BaseBelongsTo.vue +1 -0
- package/src/components/BaseCharacterCounter.stories.js +30 -0
- package/src/components/BaseCharacterCounter.vue +60 -0
- package/src/components/BaseClipboard.vue +1 -1
- package/src/components/BaseDataIterator.stories.js +2 -2
- package/src/components/BaseDataIterator.vue +32 -38
- package/src/components/BaseDataTable.stories.js +2 -2
- package/src/components/BaseFileUploader.vue +4 -0
- package/src/components/BaseHasMany.vue +92 -0
- package/src/components/BaseInput.stories.js +46 -0
- package/src/components/BaseInput.vue +10 -2
- package/src/components/BaseInputLabel.stories.js +31 -0
- package/src/components/BaseInputLabel.vue +1 -1
- package/src/components/BaseLoadingCover.stories.js +55 -0
- package/src/components/BaseLoadingCover.vue +19 -1
- package/src/components/BaseMediaItem.stories.js +41 -0
- package/src/components/BaseMediaItem.vue +71 -0
- package/src/components/BaseMediaLibrary.stories.js +80 -0
- package/src/components/BaseMediaLibrary.vue +67 -68
- package/src/components/BaseMediaPreview.stories.js +72 -0
- package/src/components/BaseMediaPreview.vue +90 -0
- package/src/components/BaseMenu.stories.js +125 -0
- package/src/components/BaseMenu.vue +1 -1
- package/src/components/BaseModalCenter.stories.js +61 -0
- package/src/components/BaseModalCenter.vue +2 -2
- package/src/components/BaseModalSide.stories.js +55 -0
- package/src/components/BaseModalSide.vue +2 -2
- package/src/components/BaseNavbar.stories.js +150 -0
- package/src/components/BaseNavbar.vue +3 -0
- package/src/components/BaseNavbarItem.vue +1 -0
- package/src/components/BaseNavbarItemContent.vue +3 -0
- package/src/components/BasePagination.stories.js +32 -0
- package/src/components/BasePagination.vue +126 -40
- package/src/components/BasePanel.stories.js +56 -0
- package/src/components/BasePassword.stories.js +36 -0
- package/src/components/BasePassword.vue +11 -5
- package/src/components/BaseProcessRing.stories.js +27 -0
- package/src/components/BaseReadMore.stories.js +30 -0
- package/src/components/BaseReadMore.vue +1 -1
- package/src/components/BaseSelect.stories.js +67 -0
- package/src/components/BaseSelect.vue +144 -44
- package/src/components/BaseSideNavigation.stories.js +55 -0
- package/src/components/BaseSideNavigation.vue +7 -2
- package/src/components/BaseSideNavigationItem.vue +21 -5
- package/src/components/BaseSkeleton.stories.js +36 -0
- package/src/components/BaseSwitch.stories.js +101 -0
- package/src/components/BaseSwitch.vue +90 -12
- package/src/components/BaseSystemAlert.stories.js +63 -0
- package/src/components/BaseTabItem.vue +29 -6
- package/src/components/BaseTable.vue +2 -2
- package/src/components/BaseTabs.stories.js +54 -0
- package/src/components/BaseTabs.vue +3 -3
- package/src/components/BaseTagAutocomplete.stories.js +129 -0
- package/src/components/BaseTagAutocomplete.vue +155 -57
- package/src/components/BaseTagAutocompleteFetch.stories.js +130 -0
- package/src/components/BaseTagAutocompleteFetch.vue +36 -25
- package/src/components/BaseTextarea.stories.js +35 -0
- package/src/components/BaseTextarea.vue +1 -1
- package/src/components/BaseTextareaAutoresize.stories.js +49 -0
- package/src/components/BaseTextareaAutoresize.vue +83 -87
- package/src/components/HasMany.stories.js +135 -0
- package/src/components/index.ts +58 -0
- package/src/lang/en.json +2 -1
- package/src/lang/fr.json +2 -1
- package/dist/types/src/components/BasePaginationSimple.vue.d.ts +0 -25
- package/dist/types/src/components/BaseWordCount.vue.d.ts +0 -31
- package/src/components/BaseMediaLibraryItem.vue +0 -92
- package/src/components/BasePaginationSimple.vue +0 -60
- package/src/components/BaseWordCount.vue +0 -36
|
@@ -1,59 +1,159 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<select
|
|
3
|
-
|
|
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
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
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 {
|
|
19
|
-
import { get } from 'lodash';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
|
3
|
-
<
|
|
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
|
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<router-link
|
|
2
|
+
<router-link
|
|
3
|
+
v-slot="{ href, navigate, isActive, isExactActive }"
|
|
4
|
+
:to="to"
|
|
5
|
+
custom
|
|
6
|
+
>
|
|
3
7
|
<a
|
|
4
8
|
:href="disabled ? undefined : href"
|
|
5
9
|
:disabled="disabled"
|
|
6
|
-
class="flex items-center
|
|
10
|
+
class="group relative flex items-center px-3 py-1"
|
|
7
11
|
:class="[
|
|
8
|
-
isActive
|
|
9
|
-
? '
|
|
10
|
-
: 'text-slate-600 hover:
|
|
12
|
+
(activeStrategy == 'default' ? isActive : isExactActive)
|
|
13
|
+
? 'font-semibold text-blue-600'
|
|
14
|
+
: 'text-slate-600 hover:text-slate-900',
|
|
11
15
|
disabled ? 'cursor-not-allowed opacity-60' : '',
|
|
12
16
|
]"
|
|
13
17
|
@click.prevent="onClick(navigate)"
|
|
14
18
|
>
|
|
19
|
+
<div
|
|
20
|
+
class="absolute left-0 top-0 h-full"
|
|
21
|
+
:class="[
|
|
22
|
+
(activeStrategy == 'default' ? isActive : isExactActive)
|
|
23
|
+
? 'w-[2px] bg-blue-600'
|
|
24
|
+
: 'group-hover:w-px group-hover:bg-slate-700',
|
|
25
|
+
]"
|
|
26
|
+
></div>
|
|
15
27
|
<slot />
|
|
16
28
|
</a>
|
|
17
29
|
</router-link>
|
|
@@ -30,6 +42,10 @@ const props = defineProps({
|
|
|
30
42
|
default: false,
|
|
31
43
|
type: Boolean,
|
|
32
44
|
},
|
|
45
|
+
activeStrategy: {
|
|
46
|
+
default: 'default',
|
|
47
|
+
type: String as PropType<'default' | 'exact'>,
|
|
48
|
+
},
|
|
33
49
|
});
|
|
34
50
|
|
|
35
51
|
const onClick = (navigate: () => void) => {
|
|
@@ -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
|
|
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
|
-
:
|
|
16
|
-
|
|
17
|
-
|
|
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 == '
|
|
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 == '
|
|
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 == '
|
|
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 == '
|
|
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 = {};
|