vueless 0.0.50 → 0.0.52
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/adatper.locale/locales/en.js +2 -0
- package/composable.breakpoint/index.js +93 -0
- package/index.js +9 -0
- package/package.json +4 -6
- package/service.ui/index.js +1 -0
- package/ui.button/composables/attrs.composable.js +9 -2
- package/ui.button-link/composables/attrs.composable.js +23 -3
- package/ui.button-toggle/configs/default.config.js +1 -0
- package/ui.container-card/composable/attrs.composable.js +2 -2
- package/ui.container-card/index.vue +3 -6
- package/ui.container-modal/composables/attrs.composable.js +5 -8
- package/ui.container-modal-confirm/composable/attrs.composable.js +55 -5
- package/ui.container-page/composables/attrs.composable.js +3 -3
- package/ui.container-page/index.vue +4 -6
- package/ui.form-calendar/configs/default.config.js +21 -21
- package/ui.form-color-picker/composables/attrs.composable.js +2 -9
- package/ui.form-date-picker/configs/default.config.js +1 -1
- package/ui.form-date-picker-range/configs/default.config.js +16 -16
- package/ui.form-date-picker-range/index.vue +3 -4
- package/ui.form-input/configs/default.config.js +2 -2
- package/ui.form-radio-card/composables/attrs.composable.js +2 -2
- package/ui.form-radio-card/index.vue +6 -10
- package/ui.form-select/configs/default.config.js +2 -2
- package/ui.form-textarea/configs/default.config.js +1 -1
- package/ui.loader-rendering/composables/useLoaderRendering.js +19 -0
- package/ui.loader-rendering/index.vue +15 -16
- package/ui.navigation-pagination/configs/default.config.js +2 -2
- package/ui.notify/Docs.mdx +84 -0
- package/ui.notify/composables/attrs.composable.js +30 -0
- package/ui.notify/configs/default.config.js +47 -0
- package/ui.notify/constants/index.js +19 -0
- package/ui.notify/index.stories.js +77 -0
- package/ui.notify/index.vue +196 -214
- package/ui.notify/services/index.js +65 -63
- package/ui.other-loader-top/composables/useLoaderTop.js +57 -0
- package/ui.other-loader-top/index.vue +12 -13
- package/ui.text-alert/composables/attrs.composable.js +1 -1
- package/web-types.json +21 -16
- package/ui.loader-rendering/store/index.js +0 -17
- package/ui.notify/index.sto_ries.js +0 -102
- package/ui.other-loader-top/store/index.js +0 -59
- package/ui.viewport/index.vue +0 -78
- package/ui.viewport/store/index.js +0 -47
|
@@ -2,23 +2,23 @@ export default /*tw*/ {
|
|
|
2
2
|
input: "",
|
|
3
3
|
inputActive: {
|
|
4
4
|
block: {
|
|
5
|
-
base: "ring-4 ring-
|
|
5
|
+
base: "ring-4 ring-brand-600/[.15] border-brand-500 hover:border-brand-500",
|
|
6
6
|
},
|
|
7
7
|
},
|
|
8
|
-
buttonWrapper: "flex h-full rounded-lg focus-within:ring-4 focus-within:ring-
|
|
8
|
+
buttonWrapper: "flex h-full rounded-lg focus-within:ring-4 focus-within:ring-brand-600/[.15] max-md:justify-between",
|
|
9
9
|
button: `
|
|
10
10
|
shrink-0 grow rounded-none border-0 bg-zinc-100 py-2 text-base font-medium text-gray-900 shadow-none
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
hover:bg-zinc-200 hover:ring-brand-600/[.15] focus:border-0 focus:bg-zinc-200 focus:ring-0 focus:ring-brand-600/[.15]
|
|
12
|
+
active:bg-zinc-200 disabled:cursor-not-allowed
|
|
13
13
|
`,
|
|
14
|
-
buttonActive: "border-0 hover:bg-zinc-200 ring-0 ring-
|
|
15
|
-
buttonWrapperActive: "ring-4 ring-
|
|
14
|
+
buttonActive: "border-0 hover:bg-zinc-200 ring-0 ring-brand-600/[.15] bg-zinc-200",
|
|
15
|
+
buttonWrapperActive: "ring-4 ring-brand-600/[.15]",
|
|
16
16
|
shiftRangeButton: `
|
|
17
17
|
focus:bg-bg-zinc-200 flex items-center border-0 bg-zinc-100 py-[0.71875rem] shadow-none
|
|
18
|
-
hover:bg-zinc-200 hover:ring-
|
|
18
|
+
hover:bg-zinc-200 hover:ring-brand-600/[.15] focus:border-0 focus:ring-0 focus:ring-brand-600/[.15] active:bg-zinc-200
|
|
19
19
|
disabled:cursor-not-allowed last:rounded-l-none last:rounded-r-lg first:rounded-l-lg first:rounded-r-none
|
|
20
20
|
`,
|
|
21
|
-
menu: "absolute z-40 mt-2 w-80 overflow-hidden rounded-lg border border-
|
|
21
|
+
menu: "absolute z-40 mt-2 w-80 overflow-hidden rounded-lg border border-brand-300 bg-white p-2 shadow focus:outline-none",
|
|
22
22
|
menuTransition: {
|
|
23
23
|
enterFromClass: "opacity-0 scale-95",
|
|
24
24
|
enterActiveClass: "transition transform ease-out duration-100",
|
|
@@ -30,8 +30,8 @@ export default /*tw*/ {
|
|
|
30
30
|
periodsRow: "mb-1 flex min-w-64 gap-1",
|
|
31
31
|
periodButton: `
|
|
32
32
|
flex h-[3.125rem] w-full cursor-pointer flex-col items-center justify-center rounded-lg bg-zinc-100
|
|
33
|
-
px-1.5 py-2.5 text-center text-xs font-medium text-
|
|
34
|
-
[&_span]:block [&_span]:font-normal [&_span]:text-
|
|
33
|
+
px-1.5 py-2.5 text-center text-xs font-medium text-brand-900 hover:bg-brand-200
|
|
34
|
+
[&_span]:block [&_span]:font-normal [&_span]:text-brand-500
|
|
35
35
|
`,
|
|
36
36
|
periodButtonActive: "bg-zinc-200",
|
|
37
37
|
rangeSwitchWrapper: "mb-2.5 mt-4 flex items-center justify-between py-2",
|
|
@@ -46,7 +46,7 @@ export default /*tw*/ {
|
|
|
46
46
|
periodDateYearList: "grid grid-cols-3 grid-rows-1 gap-0.5",
|
|
47
47
|
periodDateQuarterList: "",
|
|
48
48
|
periodDate: `
|
|
49
|
-
cursor-pointer block w-full rounded-lg py-3 text-center text-sm font-medium text-gray-900 hover:rounded-lg hover:bg-
|
|
49
|
+
cursor-pointer block w-full rounded-lg py-3 text-center text-sm font-medium text-gray-900 hover:rounded-lg hover:bg-brand-50
|
|
50
50
|
disabled:opacity-50 disabled:cursor-not-allowed
|
|
51
51
|
`,
|
|
52
52
|
periodDateActive: "bg-zinc-100",
|
|
@@ -58,7 +58,7 @@ export default /*tw*/ {
|
|
|
58
58
|
description: "hidden",
|
|
59
59
|
},
|
|
60
60
|
input: {
|
|
61
|
-
base: "text-sm border-
|
|
61
|
+
base: "text-sm border-brand-100 px-4 py-2.5",
|
|
62
62
|
variants: {
|
|
63
63
|
size: {
|
|
64
64
|
md: "pt-2.5 pb-2.5",
|
|
@@ -72,7 +72,7 @@ export default /*tw*/ {
|
|
|
72
72
|
dayViewWrapper: "p-0 w-full",
|
|
73
73
|
monthViewWrapper: "p-0 w-full",
|
|
74
74
|
yearViewWrapper: "p-0 w-full",
|
|
75
|
-
dayViewSwitchLabel: "font-medium text-
|
|
75
|
+
dayViewSwitchLabel: "font-medium text-brand-900",
|
|
76
76
|
nextPrevButton: "p-0 py-2 hover:bg-transparent",
|
|
77
77
|
navigation: "px-0 w-full",
|
|
78
78
|
nextIcon: {
|
|
@@ -88,12 +88,12 @@ export default /*tw*/ {
|
|
|
88
88
|
},
|
|
89
89
|
},
|
|
90
90
|
day: "font-medium w-full h-10 text-sm mb-0.5",
|
|
91
|
-
currentDay: "text-white bg-
|
|
91
|
+
currentDay: "text-white bg-brand-900 hover:bg-brand-900 hover:text-white",
|
|
92
92
|
weekDay: "text-sm size-10",
|
|
93
93
|
month: "font-medium",
|
|
94
|
-
selectedMonth: "bg-zinc-100 text-
|
|
94
|
+
selectedMonth: "bg-zinc-100 text-brand-900 hover:text-white",
|
|
95
95
|
year: "font-medium",
|
|
96
|
-
selectedYear: "bg-zinc-100 text-
|
|
96
|
+
selectedYear: "bg-zinc-100 text-brand-900 hover:text-white",
|
|
97
97
|
},
|
|
98
98
|
i18n: {
|
|
99
99
|
lastThirtyDays: "Last 30 days <span> and 2 next two weeks </span>",
|
|
@@ -179,7 +179,6 @@
|
|
|
179
179
|
|
|
180
180
|
<script setup>
|
|
181
181
|
import { computed, watch, ref, nextTick } from "vue";
|
|
182
|
-
import { useStore } from "vuex";
|
|
183
182
|
import { merge } from "lodash-es";
|
|
184
183
|
|
|
185
184
|
import UIcon from "../ui.image-icon";
|
|
@@ -227,6 +226,7 @@ import {
|
|
|
227
226
|
import { wrongDateFormat, wrongMonthNumber, wrongDayNumber } from "./services/validation.service";
|
|
228
227
|
import useAttrs from "./composables/attrs.composable";
|
|
229
228
|
import { useLocale } from "../composable.locale";
|
|
229
|
+
import useBreakpoint from "../composable.breakpoint";
|
|
230
230
|
|
|
231
231
|
import defaultConfig from "./configs/default.config";
|
|
232
232
|
import {
|
|
@@ -385,7 +385,6 @@ const {
|
|
|
385
385
|
rangeInputWrapperAttrs,
|
|
386
386
|
inputRangeErrorAttrs,
|
|
387
387
|
} = useAttrs(props, { isShownMenu });
|
|
388
|
-
const store = useStore();
|
|
389
388
|
const { tm } = useLocale();
|
|
390
389
|
|
|
391
390
|
const calendarValue = ref(props.modelValue);
|
|
@@ -413,7 +412,7 @@ const localValue = computed({
|
|
|
413
412
|
},
|
|
414
413
|
});
|
|
415
414
|
|
|
416
|
-
const
|
|
415
|
+
const { isMobileBreakpoint } = useBreakpoint();
|
|
417
416
|
const rangeInputName = computed(() => `rangeInput-${props.id}`);
|
|
418
417
|
const currentLocale = computed(() => merge(tm("UDatePickerRange"), props.config.i18n));
|
|
419
418
|
|
|
@@ -560,7 +559,7 @@ const userFormatDate = computed(() => {
|
|
|
560
559
|
title = `${fromTitle} – ${toTitle}`;
|
|
561
560
|
}
|
|
562
561
|
|
|
563
|
-
if (
|
|
562
|
+
if (isMobileBreakpoint.value && !isPeriod.value.month && isVariant.value.button) {
|
|
564
563
|
const startDay = String(from.getDate()).padStart(2, "0");
|
|
565
564
|
const endDay = String(to?.getDate())?.padStart(2, "0");
|
|
566
565
|
const startMonth = String(from.getMonth()).padStart(2, "0");
|
|
@@ -10,8 +10,8 @@ export default /*tw*/ {
|
|
|
10
10
|
base: `
|
|
11
11
|
rounded-lg border border-solid border-gray-300 bg-white !opacity-100 relative flex
|
|
12
12
|
transition duration-100 ease-in-out
|
|
13
|
-
hover:border-gray-400 hover:focus-within:border-
|
|
14
|
-
focus-within:border-
|
|
13
|
+
hover:border-gray-400 hover:focus-within:border-brand-500
|
|
14
|
+
focus-within:border-brand-500 focus-within:ring-4 focus-within:ring-brand-600/[.15]
|
|
15
15
|
`,
|
|
16
16
|
variants: {
|
|
17
17
|
disabled: {
|
|
@@ -5,7 +5,7 @@ import defaultConfig from "../configs/default.config";
|
|
|
5
5
|
import { computed } from "vue";
|
|
6
6
|
|
|
7
7
|
export function useAttrs(props) {
|
|
8
|
-
const { config, getAttrs
|
|
8
|
+
const { config, getAttrs } = useUI(defaultConfig, () => props.config);
|
|
9
9
|
const { radio } = config.value;
|
|
10
10
|
|
|
11
11
|
const cvaRadio = cva({
|
|
@@ -14,7 +14,7 @@ export function useAttrs(props) {
|
|
|
14
14
|
compoundVariants: radio.compoundVariants,
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
const radioClasses = computed(() =>
|
|
17
|
+
const radioClasses = computed(() => cvaRadio({ color: props.color }));
|
|
18
18
|
|
|
19
19
|
const wrapperAttrsRaw = getAttrs("wrapper");
|
|
20
20
|
const itemsAttrs = getAttrs("items");
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
|
|
26
26
|
<script setup>
|
|
27
27
|
import { computed } from "vue";
|
|
28
|
-
import { useStore } from "vuex";
|
|
29
28
|
|
|
30
29
|
import UIcon from "../ui.image-icon";
|
|
31
30
|
import URadio from "../ui.form-radio";
|
|
@@ -34,12 +33,11 @@ import UIService, { getRandomId } from "../service.ui";
|
|
|
34
33
|
import defaultConfig from "./configs/default.config";
|
|
35
34
|
import { URadioCard } from "./constants";
|
|
36
35
|
import { useAttrs } from "./composables/attrs.composable";
|
|
36
|
+
import useBreakpoint from "../composable.breakpoint";
|
|
37
37
|
|
|
38
38
|
/* Should be a string for correct web-types gen */
|
|
39
39
|
defineOptions({ name: "URadioCard", inheritAttrs: false });
|
|
40
40
|
|
|
41
|
-
const store = useStore();
|
|
42
|
-
|
|
43
41
|
const props = defineProps({
|
|
44
42
|
/**
|
|
45
43
|
* Set radio card name.
|
|
@@ -126,9 +124,7 @@ const emit = defineEmits(["update:modelValue"]);
|
|
|
126
124
|
|
|
127
125
|
const { radioAttrs, iconAttrs, wrapperAttrs, labelAttrs, itemsAttrs } = useAttrs(props);
|
|
128
126
|
|
|
129
|
-
const
|
|
130
|
-
return store.getters["breakpoint/isMobileDevice"];
|
|
131
|
-
});
|
|
127
|
+
const { isMobileBreakpoint } = useBreakpoint();
|
|
132
128
|
|
|
133
129
|
const selectedItem = computed({
|
|
134
130
|
get: () => props.modelValue,
|
|
@@ -137,10 +133,10 @@ const selectedItem = computed({
|
|
|
137
133
|
|
|
138
134
|
const gridColsClass = computed(() => {
|
|
139
135
|
return {
|
|
140
|
-
"grid-cols-1":
|
|
141
|
-
"grid-cols-2": props.gridCols === 2 &&
|
|
142
|
-
"grid-cols-3": props.gridCols === 3 &&
|
|
143
|
-
"grid-cols-4": props.gridCols === 4 &&
|
|
136
|
+
"grid-cols-1": isMobileBreakpoint.value,
|
|
137
|
+
"grid-cols-2": props.gridCols === 2 && isMobileBreakpoint.value,
|
|
138
|
+
"grid-cols-3": props.gridCols === 3 && isMobileBreakpoint.value,
|
|
139
|
+
"grid-cols-4": props.gridCols === 4 && isMobileBreakpoint.value,
|
|
144
140
|
};
|
|
145
141
|
});
|
|
146
142
|
</script>
|
|
@@ -4,8 +4,8 @@ export default /*tw*/ {
|
|
|
4
4
|
base: `
|
|
5
5
|
pb-2 pt-2 flex flex-row-reverse justify-between w-full min-h-full box-border relative
|
|
6
6
|
rounded-lg border border-gray-300 bg-white
|
|
7
|
-
hover:border-gray-400 hover:transition hover:duration-100 hover:ease-in-out hover:focus-within:border-
|
|
8
|
-
focus-within:border-
|
|
7
|
+
hover:border-gray-400 hover:transition hover:duration-100 hover:ease-in-out hover:focus-within:border-brand-500
|
|
8
|
+
focus-within:border-brand-500 focus-within:ring-4 focus-within:ring-brand-600/[.15] focus-within:outline-none
|
|
9
9
|
`,
|
|
10
10
|
variants: {
|
|
11
11
|
error: {
|
|
@@ -21,7 +21,7 @@ export default /*tw*/ {
|
|
|
21
21
|
true: "cursor-not-allowed border-none focus-within:ring-0 bg-gray-100",
|
|
22
22
|
},
|
|
23
23
|
readonly: {
|
|
24
|
-
true: "ring-0 border-gray-300 focus-within:ring-0 focus-within:border-
|
|
24
|
+
true: "ring-0 border-gray-300 focus-within:ring-0 focus-within:border-brand-300",
|
|
25
25
|
},
|
|
26
26
|
size: {
|
|
27
27
|
sm: "pb-2 pr-4 pt-6",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readonly, ref } from "vue";
|
|
2
|
+
|
|
3
|
+
const isRenderingPage = ref(true);
|
|
4
|
+
|
|
5
|
+
function setRenderingStarted() {
|
|
6
|
+
isRenderingPage.value = true;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function setRenderingFinished() {
|
|
10
|
+
isRenderingPage.value = false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default function useLoaderRendering() {
|
|
14
|
+
return {
|
|
15
|
+
isRenderingPage: readonly(isRenderingPage),
|
|
16
|
+
setRenderingStarted,
|
|
17
|
+
setRenderingFinished,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -9,27 +9,26 @@
|
|
|
9
9
|
</transition>
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
|
-
<script>
|
|
13
|
-
import {
|
|
12
|
+
<script setup>
|
|
13
|
+
import { computed } from "vue";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
name: "ULoaderRendering",
|
|
15
|
+
import useLoaderRendering from "./composables/useLoaderRendering";
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
/* Should be a string for correct web-types gen */
|
|
18
|
+
defineOptions({ name: "ULoaderRendering", inheritAttrs: false });
|
|
19
|
+
|
|
20
|
+
const props = defineProps({
|
|
21
|
+
loading: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: false,
|
|
23
24
|
},
|
|
25
|
+
});
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
...mapState("loader", ["isRenderingPage"]),
|
|
27
|
+
const { isRenderingPage } = useLoaderRendering();
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
32
|
-
};
|
|
29
|
+
const showLoader = computed(() => {
|
|
30
|
+
return props.loading || isRenderingPage.value;
|
|
31
|
+
});
|
|
33
32
|
</script>
|
|
34
33
|
|
|
35
34
|
<style lang="postcss" scoped>
|
|
@@ -5,8 +5,8 @@ export default /*tw*/ {
|
|
|
5
5
|
navigationButton: "size-full rounded font-normal disabled:hover:bg-transparent",
|
|
6
6
|
pageButton: "size-full rounded font-normal disabled:hover:bg-transparent",
|
|
7
7
|
pageButtonActive: `
|
|
8
|
-
rounded !bg-
|
|
9
|
-
hover:!text-
|
|
8
|
+
rounded !bg-brand-900/15
|
|
9
|
+
hover:!text-brand-900 !hover:bg-brand-900/15 disabled:hover:bg-brand-900/15
|
|
10
10
|
focus:outline-none
|
|
11
11
|
`,
|
|
12
12
|
defaultVariants: {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source, Markdown } from "@storybook/blocks";
|
|
2
|
+
import { getSource } from "../service.storybook";
|
|
3
|
+
|
|
4
|
+
import * as stories from "./index.stories";
|
|
5
|
+
import defaultConfig from "./configs/default.config?raw"
|
|
6
|
+
|
|
7
|
+
<Meta of={stories} />
|
|
8
|
+
<Title of={stories} />
|
|
9
|
+
<Subtitle of={stories} />
|
|
10
|
+
<Description of={stories} />
|
|
11
|
+
<Primary of={stories} />
|
|
12
|
+
<Controls of={stories.Default} />
|
|
13
|
+
<Stories of={stories} />
|
|
14
|
+
|
|
15
|
+
## **Default config**
|
|
16
|
+
<Source code={getSource(defaultConfig)} language="jsx" dark />
|
|
17
|
+
|
|
18
|
+
## Trigger notifications
|
|
19
|
+
You can trigger notification using *notify* method. Use *notifySuccess, notifyWarning, notifyError* methods to trigger notification of specific type.
|
|
20
|
+
|
|
21
|
+
<Source code={`
|
|
22
|
+
import {
|
|
23
|
+
notify,
|
|
24
|
+
notifySuccess,
|
|
25
|
+
notifyWarning,
|
|
26
|
+
notifyError,
|
|
27
|
+
} from "vueless";
|
|
28
|
+
|
|
29
|
+
notify({
|
|
30
|
+
type: "success" // success, warning, error
|
|
31
|
+
title: "" // Some label
|
|
32
|
+
text: "" // Some text content
|
|
33
|
+
duration: 1000 // Duration in milliseconds
|
|
34
|
+
delayDuplicates: false // Delay notifications with same text
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const durationInMilliseconds = 1000;
|
|
38
|
+
|
|
39
|
+
notifySuccess("Some success text", durationInMilliseconds);
|
|
40
|
+
notifyWarning("Some warning text", durationInMilliseconds);
|
|
41
|
+
notifyError("Some error text", durationInMilliseconds);
|
|
42
|
+
`} language="jsx" dark />
|
|
43
|
+
|
|
44
|
+
## Clear active notifications
|
|
45
|
+
Use *clearAllNotifications* method to clear all active notifications.
|
|
46
|
+
|
|
47
|
+
<Source code={`
|
|
48
|
+
import { clearAllNotifications, notifySuccess } from "vueless";
|
|
49
|
+
|
|
50
|
+
const durationInMilliseconds = 1000;
|
|
51
|
+
notifySuccess("Some success text", durationInMilliseconds);
|
|
52
|
+
|
|
53
|
+
clearAllNotifications();
|
|
54
|
+
`} language="jsx" dark />
|
|
55
|
+
|
|
56
|
+
## Trigger notifications
|
|
57
|
+
You can create delayed notification which you can trigger any time later.
|
|
58
|
+
|
|
59
|
+
<Source code={`
|
|
60
|
+
import { setDelayedNotify, getDelayedNotify } from "vueless";
|
|
61
|
+
|
|
62
|
+
setDelayedNotify({
|
|
63
|
+
type: "success" // success, warning, error
|
|
64
|
+
title: "" // Some label
|
|
65
|
+
text: "" // Some text content
|
|
66
|
+
duration: 1000 // Duration in milliseconds
|
|
67
|
+
delayDuplicates: false // Delay notifications with same text
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
setTimeout(getDelayedNotify, 10_000);
|
|
71
|
+
`} language="jsx" dark />
|
|
72
|
+
|
|
73
|
+
## Place notification relatively to navigation elements
|
|
74
|
+
Provide *positionClasses* key for UNotify config to take navigation elements offset into account.
|
|
75
|
+
By default, it will be looking for UNotifyPage and UNotifyAside classes.
|
|
76
|
+
|
|
77
|
+
<Source code={`
|
|
78
|
+
const notifyConfig = {
|
|
79
|
+
positionClasses: {
|
|
80
|
+
page: "UNotifyPage",
|
|
81
|
+
aside: "UNotifyAside",
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
`} language="jsx" dark />
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import useUI from "../../composable.ui";
|
|
2
|
+
|
|
3
|
+
import defaultConfig from "../configs/default.config";
|
|
4
|
+
|
|
5
|
+
export function useAttrs(props) {
|
|
6
|
+
const { config, getAttrs } = useUI(defaultConfig, () => props.config);
|
|
7
|
+
|
|
8
|
+
const wrapperAttrs = getAttrs("wrapper");
|
|
9
|
+
const bodyAttrs = getAttrs("body");
|
|
10
|
+
const contentAttrs = getAttrs("content");
|
|
11
|
+
const labelAttrs = getAttrs("label");
|
|
12
|
+
const descriptionAttrs = getAttrs("description");
|
|
13
|
+
const iconSuccessAttrs = getAttrs("iconSuccess");
|
|
14
|
+
const iconWarningAttrs = getAttrs("iconWarning");
|
|
15
|
+
const iconErrorAttrs = getAttrs("iconError");
|
|
16
|
+
const iconCloseAttrs = getAttrs("iconClose");
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
config,
|
|
20
|
+
wrapperAttrs,
|
|
21
|
+
bodyAttrs,
|
|
22
|
+
contentAttrs,
|
|
23
|
+
labelAttrs,
|
|
24
|
+
descriptionAttrs,
|
|
25
|
+
iconSuccessAttrs,
|
|
26
|
+
iconWarningAttrs,
|
|
27
|
+
iconCloseAttrs,
|
|
28
|
+
iconErrorAttrs,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export default /*tw*/ {
|
|
2
|
+
wrapper: "absolute overflow-visible md:w-[22rem]",
|
|
3
|
+
body: `
|
|
4
|
+
mb-3 flex w-fit items-center justify-center gap-3 rounded-2xl bg-gray-900/90
|
|
5
|
+
p-4 shadow-[0_4px_16px_rgba(17,24,39,0.5)] backdrop-blur-md md:shadow-[0_0px_12px_rgba(0,0,0,0.25)]
|
|
6
|
+
`,
|
|
7
|
+
bodySuccess: "bg-[radial-gradient(100.16%_500.78%_at_0%_50%,rgba(74,222,128,0.1)_2.17%,transparent)]",
|
|
8
|
+
bodyWarning: "bg-[radial-gradient(100.16%_500.78%_at_0%_50%,rgba(251,146,60,0.2)_2.17%,transparent)]",
|
|
9
|
+
bodyError: "bg-[radial-gradient(100.16%_500.78%_at_0%_50%,rgba(251,113,133,0.2)_2.17%,transparent)]",
|
|
10
|
+
content: "w-full flex flex-col max-w-full px-3 text-sm text-gray-200",
|
|
11
|
+
label: "mb-1 font-medium",
|
|
12
|
+
description: "break-words font-normal leading-5",
|
|
13
|
+
iconSuccess: "",
|
|
14
|
+
iconSuccessName: "check_circle",
|
|
15
|
+
iconWarning: "",
|
|
16
|
+
iconWarningName: "warning",
|
|
17
|
+
iconError: "",
|
|
18
|
+
iconErrorName: "error",
|
|
19
|
+
iconClose: "",
|
|
20
|
+
iconCloseName: "close",
|
|
21
|
+
transitionGroup: {
|
|
22
|
+
moveClass: "transition-all duration-500",
|
|
23
|
+
enterActiveClass: "transition-all duration-500",
|
|
24
|
+
leaveActiveClass: "transition-all duration-500 absolute",
|
|
25
|
+
enterFromClass: "opacity-0",
|
|
26
|
+
leaveToClass: "opacity-0",
|
|
27
|
+
},
|
|
28
|
+
duration: {
|
|
29
|
+
short: 4000,
|
|
30
|
+
medium: 8000,
|
|
31
|
+
long: 12000,
|
|
32
|
+
},
|
|
33
|
+
i18n: {
|
|
34
|
+
success: "Operation successful.",
|
|
35
|
+
warning: "Operation warning.",
|
|
36
|
+
error: "Operation error.",
|
|
37
|
+
},
|
|
38
|
+
positionClasses: {
|
|
39
|
+
page: "UNotifyPage",
|
|
40
|
+
aside: "UNotifyAside",
|
|
41
|
+
},
|
|
42
|
+
defaultVariants: {
|
|
43
|
+
xPosition: "center",
|
|
44
|
+
yPosition: "top",
|
|
45
|
+
vHtml: false,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*
|
|
2
|
+
This const is needed to prevent the issue in script setup:
|
|
3
|
+
`defineProps` is referencing locally declared variables. (vue/valid-define-props)
|
|
4
|
+
*/
|
|
5
|
+
export const UNotify = "UNotify";
|
|
6
|
+
|
|
7
|
+
export const NOTIFY_TYPE = {
|
|
8
|
+
success: "success",
|
|
9
|
+
warning: "warning",
|
|
10
|
+
error: "error",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const POSITION = {
|
|
14
|
+
left: "left",
|
|
15
|
+
right: "right",
|
|
16
|
+
top: "top",
|
|
17
|
+
bottom: "bottom",
|
|
18
|
+
center: "center",
|
|
19
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { notify } from "../ui.notify/services";
|
|
2
|
+
|
|
3
|
+
import UNotify from "../ui.notify";
|
|
4
|
+
import UButton from "../ui.button";
|
|
5
|
+
|
|
6
|
+
import { getArgTypes } from "../service.storybook";
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
title: "Other / Notify",
|
|
10
|
+
component: UNotify,
|
|
11
|
+
args: {
|
|
12
|
+
type: "success",
|
|
13
|
+
label: "",
|
|
14
|
+
text: "",
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
...getArgTypes(UNotify.name),
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const DefaultTemplate = (args) => ({
|
|
22
|
+
components: { UNotify, UButton },
|
|
23
|
+
setup() {
|
|
24
|
+
return { args };
|
|
25
|
+
},
|
|
26
|
+
template: `
|
|
27
|
+
<div>
|
|
28
|
+
<UNotify v-bind="args" />
|
|
29
|
+
|
|
30
|
+
<UButton label="show notify" @click="onClick"/>
|
|
31
|
+
</div>
|
|
32
|
+
`,
|
|
33
|
+
|
|
34
|
+
methods: {
|
|
35
|
+
onClick() {
|
|
36
|
+
const settings = {
|
|
37
|
+
type: "success",
|
|
38
|
+
label: "Some label",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
notify(settings);
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const TypesTemplate = (args) => ({
|
|
47
|
+
components: { UNotify, UButton },
|
|
48
|
+
setup() {
|
|
49
|
+
return { args };
|
|
50
|
+
},
|
|
51
|
+
template: `
|
|
52
|
+
<div class="flex gap-4">
|
|
53
|
+
<UNotify />
|
|
54
|
+
|
|
55
|
+
<UButton label="Success" @click="onClick('success')"/>
|
|
56
|
+
<UButton label="Warning" @click="onClick('warning')"/>
|
|
57
|
+
<UButton label="Error" @click="onClick('error')"/>
|
|
58
|
+
</div>
|
|
59
|
+
`,
|
|
60
|
+
|
|
61
|
+
methods: {
|
|
62
|
+
onClick(type) {
|
|
63
|
+
const settings = { type };
|
|
64
|
+
|
|
65
|
+
notify(settings);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const Default = DefaultTemplate.bind({});
|
|
71
|
+
Default.args = {};
|
|
72
|
+
|
|
73
|
+
export const position = DefaultTemplate.bind({});
|
|
74
|
+
position.args = { xPosition: "right", yPosition: "bottom" };
|
|
75
|
+
|
|
76
|
+
export const types = TypesTemplate.bind({});
|
|
77
|
+
types.args = {};
|