sprintify-ui 0.0.26 → 0.0.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.
- package/dist/sprintify-ui.es.js +2204 -2121
- package/dist/types/src/components/BaseBadge.vue.d.ts +46 -8
- package/dist/types/src/components/BaseInput.vue.d.ts +66 -1
- package/dist/types/src/components/BaseInputPercent.vue.d.ts +133 -0
- package/package.json +1 -1
- package/src/components/BaseBadge.stories.js +52 -7
- package/src/components/BaseBadge.vue +51 -0
- package/src/components/BaseInput.stories.js +41 -1
- package/src/components/BaseInput.vue +104 -15
- package/src/components/BaseInputPercent.stories.js +43 -0
- package/src/components/BaseInputPercent.vue +116 -0
- package/src/components/BaseModalCenter.stories.js +4 -2
- package/src/components/BaseModalCenter.vue +1 -1
- package/src/components/BaseModalSide.stories.js +4 -2
|
@@ -1,23 +1,72 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
<div class="inline-flex rounded border" :class="borderColor">
|
|
3
|
+
<div
|
|
4
|
+
v-if="iconLeft"
|
|
5
|
+
class="flex shrink-0 items-center justify-center rounded-l border-r px-3 transition-colors"
|
|
6
|
+
:class="[borderColor, backgroundColor, textColor]"
|
|
7
|
+
>
|
|
8
|
+
<BaseIcon :icon="iconLeft" />
|
|
9
|
+
</div>
|
|
10
|
+
<div
|
|
11
|
+
v-if="prefix"
|
|
12
|
+
class="flex shrink-0 items-center justify-center border-r px-4 transition-colors"
|
|
13
|
+
:class="[
|
|
14
|
+
iconLeft ? '' : 'rounded-l',
|
|
15
|
+
borderColor,
|
|
16
|
+
backgroundColor,
|
|
17
|
+
textColor,
|
|
18
|
+
]"
|
|
19
|
+
>
|
|
20
|
+
{{ prefix }}
|
|
21
|
+
</div>
|
|
22
|
+
<input
|
|
23
|
+
ref="input"
|
|
24
|
+
:value="modelValue"
|
|
25
|
+
:type="type"
|
|
26
|
+
:name="name"
|
|
27
|
+
:step="step"
|
|
28
|
+
:min="min"
|
|
29
|
+
:max="max"
|
|
30
|
+
:disabled="disabled"
|
|
31
|
+
:placeholder="placeholder"
|
|
32
|
+
:required="required"
|
|
33
|
+
class="w-full border-none bg-transparent outline-none focus:z-[1] focus:ring-2 focus:ring-primary-600 focus:ring-offset-1 disabled:cursor-not-allowed disabled:text-slate-300"
|
|
34
|
+
:class="{
|
|
35
|
+
'rounded-l': !iconLeft && !prefix,
|
|
36
|
+
'rounded-r': !iconRight && !suffix,
|
|
37
|
+
}"
|
|
38
|
+
:autocomplete="autocomplete ? 'on' : 'off'"
|
|
39
|
+
@keydown.enter="onEnter"
|
|
40
|
+
@input="$emit('update:modelValue', transformInputValue($event))"
|
|
41
|
+
@focus="$emit('focus', $event)"
|
|
42
|
+
@blur="$emit('blur', $event)"
|
|
43
|
+
/>
|
|
44
|
+
<div
|
|
45
|
+
v-if="suffix"
|
|
46
|
+
class="flex shrink-0 items-center justify-center border-l px-4 transition-colors"
|
|
47
|
+
:class="[
|
|
48
|
+
iconRight ? '' : 'rounded-r',
|
|
49
|
+
borderColor,
|
|
50
|
+
backgroundColor,
|
|
51
|
+
textColor,
|
|
52
|
+
]"
|
|
53
|
+
>
|
|
54
|
+
{{ suffix }}
|
|
55
|
+
</div>
|
|
56
|
+
<div
|
|
57
|
+
v-if="iconRight"
|
|
58
|
+
class="flex shrink-0 items-center justify-center rounded-r border-l px-3 transition-colors"
|
|
59
|
+
:class="[borderColor, backgroundColor, textColor]"
|
|
60
|
+
>
|
|
61
|
+
<BaseIcon :icon="iconRight" />
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
16
64
|
</template>
|
|
17
65
|
|
|
18
66
|
<script lang="ts" setup>
|
|
19
67
|
import { get, isNumber, isString, trim } from 'lodash';
|
|
20
68
|
import { PropType } from 'vue';
|
|
69
|
+
import { BaseIcon } from './index';
|
|
21
70
|
|
|
22
71
|
const props = defineProps({
|
|
23
72
|
modelValue: {
|
|
@@ -59,9 +108,37 @@ const props = defineProps({
|
|
|
59
108
|
default: false,
|
|
60
109
|
type: Boolean,
|
|
61
110
|
},
|
|
111
|
+
iconLeft: {
|
|
112
|
+
default: undefined,
|
|
113
|
+
type: String,
|
|
114
|
+
},
|
|
115
|
+
iconRight: {
|
|
116
|
+
default: undefined,
|
|
117
|
+
type: String,
|
|
118
|
+
},
|
|
119
|
+
prefix: {
|
|
120
|
+
default: undefined,
|
|
121
|
+
type: String,
|
|
122
|
+
},
|
|
123
|
+
suffix: {
|
|
124
|
+
default: undefined,
|
|
125
|
+
type: String,
|
|
126
|
+
},
|
|
127
|
+
hasError: {
|
|
128
|
+
default: false,
|
|
129
|
+
type: Boolean,
|
|
130
|
+
},
|
|
131
|
+
min: {
|
|
132
|
+
default: undefined,
|
|
133
|
+
type: Number,
|
|
134
|
+
},
|
|
135
|
+
max: {
|
|
136
|
+
default: undefined,
|
|
137
|
+
type: Number,
|
|
138
|
+
},
|
|
62
139
|
});
|
|
63
140
|
|
|
64
|
-
defineEmits(['update:modelValue']);
|
|
141
|
+
defineEmits(['update:modelValue', 'focus', 'blur']);
|
|
65
142
|
|
|
66
143
|
function transformInputValue(event: Event | null): string | null {
|
|
67
144
|
if (event === null) {
|
|
@@ -87,4 +164,16 @@ function onEnter(e: Event) {
|
|
|
87
164
|
return;
|
|
88
165
|
}
|
|
89
166
|
}
|
|
167
|
+
|
|
168
|
+
const borderColor = computed(() => {
|
|
169
|
+
return props.hasError ? 'border-red-500' : 'border-slate-300';
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const backgroundColor = computed(() => {
|
|
173
|
+
return props.hasError ? 'bg-red-100' : 'bg-slate-100';
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const textColor = computed(() => {
|
|
177
|
+
return props.hasError ? 'text-red-800' : 'text-slate-600';
|
|
178
|
+
});
|
|
90
179
|
</script>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import BaseInputPercent from './BaseInputPercent.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Form/BaseInputPercent',
|
|
5
|
+
component: BaseInputPercent,
|
|
6
|
+
args: {
|
|
7
|
+
required: true,
|
|
8
|
+
name: 'rebate',
|
|
9
|
+
placeholder: 'Enter rebate, eg: 50%',
|
|
10
|
+
step: 0.1,
|
|
11
|
+
min: 0,
|
|
12
|
+
max: 100,
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const Template = (args) => ({
|
|
17
|
+
components: {
|
|
18
|
+
BaseInputPercent,
|
|
19
|
+
},
|
|
20
|
+
setup() {
|
|
21
|
+
const value = ref(null);
|
|
22
|
+
return { args, value };
|
|
23
|
+
},
|
|
24
|
+
template: `
|
|
25
|
+
<form @submit.prevent="" class="border-none">
|
|
26
|
+
<BaseInputPercent v-model="value" v-bind="args" class="w-full"></BaseInputPercent>
|
|
27
|
+
</form>
|
|
28
|
+
<pre class="mt-4 bg-slate-800 font-light text-xs p-3 rounded text-white">{{ value }}</pre>
|
|
29
|
+
`,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const Demo = Template.bind({});
|
|
33
|
+
Demo.args = {};
|
|
34
|
+
|
|
35
|
+
export const Disabled = Template.bind({});
|
|
36
|
+
Disabled.args = {
|
|
37
|
+
disabled: true,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const Error = Template.bind({});
|
|
41
|
+
Error.args = {
|
|
42
|
+
hasError: true,
|
|
43
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<BaseInput
|
|
3
|
+
:model-value="value"
|
|
4
|
+
suffix="%"
|
|
5
|
+
type="number"
|
|
6
|
+
:prevent-submit="preventSubmit"
|
|
7
|
+
:name="name"
|
|
8
|
+
:step="step"
|
|
9
|
+
:placeholder="placeholder"
|
|
10
|
+
:disabled="disabled"
|
|
11
|
+
:icon-left="icon"
|
|
12
|
+
:has-error="hasError"
|
|
13
|
+
:min="min"
|
|
14
|
+
:max="max"
|
|
15
|
+
@update:model-value="onUpdate"
|
|
16
|
+
></BaseInput>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script lang="ts" setup>
|
|
20
|
+
import { round } from 'lodash';
|
|
21
|
+
import { PropType } from 'vue';
|
|
22
|
+
import { BaseInput } from '.';
|
|
23
|
+
|
|
24
|
+
const props = defineProps({
|
|
25
|
+
/**
|
|
26
|
+
* The value of the input. Can be a number or null.
|
|
27
|
+
* 0.1 = 10%
|
|
28
|
+
* 0.5 = 50%
|
|
29
|
+
* 1 = 100%
|
|
30
|
+
*/
|
|
31
|
+
modelValue: {
|
|
32
|
+
default: undefined,
|
|
33
|
+
type: [Number, String, null] as PropType<number | string | null>,
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* The step of the input. Can be a number or null.
|
|
37
|
+
*/
|
|
38
|
+
step: {
|
|
39
|
+
default: 1,
|
|
40
|
+
type: Number,
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Prevents submit when pressing 'Enter' while the input is focused.
|
|
44
|
+
*/
|
|
45
|
+
preventSubmit: {
|
|
46
|
+
default: false,
|
|
47
|
+
type: Boolean,
|
|
48
|
+
},
|
|
49
|
+
name: {
|
|
50
|
+
default: undefined,
|
|
51
|
+
type: String,
|
|
52
|
+
},
|
|
53
|
+
placeholder: {
|
|
54
|
+
default: '',
|
|
55
|
+
type: String,
|
|
56
|
+
},
|
|
57
|
+
disabled: {
|
|
58
|
+
default: false,
|
|
59
|
+
type: Boolean,
|
|
60
|
+
},
|
|
61
|
+
required: {
|
|
62
|
+
default: false,
|
|
63
|
+
type: Boolean,
|
|
64
|
+
},
|
|
65
|
+
icon: {
|
|
66
|
+
default: undefined,
|
|
67
|
+
type: String,
|
|
68
|
+
},
|
|
69
|
+
hasError: {
|
|
70
|
+
default: false,
|
|
71
|
+
type: Boolean,
|
|
72
|
+
},
|
|
73
|
+
min: {
|
|
74
|
+
default: undefined,
|
|
75
|
+
type: Number,
|
|
76
|
+
},
|
|
77
|
+
max: {
|
|
78
|
+
default: undefined,
|
|
79
|
+
type: Number,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const emit = defineEmits(['update:modelValue', 'focus', 'blur']);
|
|
84
|
+
|
|
85
|
+
const precision = computed(() => {
|
|
86
|
+
if (props.step === undefined) return 0;
|
|
87
|
+
if (props.step === 0) return 0;
|
|
88
|
+
const parts = props.step.toString().split('.');
|
|
89
|
+
if (parts.length === 1) return 0;
|
|
90
|
+
return parts[1].length;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const value = computed(() => {
|
|
94
|
+
if (props.modelValue === undefined) return null;
|
|
95
|
+
if (props.modelValue === null) return null;
|
|
96
|
+
if (props.modelValue === '') return null;
|
|
97
|
+
|
|
98
|
+
const valueToNumber = parseFloat(props.modelValue as string);
|
|
99
|
+
if (Number.isNaN(valueToNumber)) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return round(valueToNumber * 100, precision.value);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
function onUpdate(value: string | number | null) {
|
|
107
|
+
const valueToNumber = parseFloat(value as string);
|
|
108
|
+
|
|
109
|
+
if (Number.isNaN(valueToNumber)) {
|
|
110
|
+
emit('update:modelValue', null);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
emit('update:modelValue', round(valueToNumber / 100, precision.value + 2));
|
|
115
|
+
}
|
|
116
|
+
</script>
|
|
@@ -32,9 +32,11 @@ const Template = (args) => ({
|
|
|
32
32
|
<BaseModalCenter v-model="show" v-bind="args">
|
|
33
33
|
<template #default="{close}">
|
|
34
34
|
<div class="p-8">
|
|
35
|
-
<
|
|
35
|
+
<h2 class="font-semibold text-lg mb-6">This is a center modal</h2>
|
|
36
36
|
|
|
37
|
-
<
|
|
37
|
+
<p v-for="i in 10" :key="i" class="mb-3 text-slate-600">Ipsum magna irure aliquip aute adipisicing Lorem non commodo amet. Est labore dolor laboris sint est magna quis fugiat id cillum deserunt cupidatat veniam. Exercitation dolore consequat labore deserunt laboris id. In laborum ea irure amet esse commodo et deserunt do officia et. Nulla incididunt est laboris pariatur ad duis ad reprehenderit voluptate. Tempor consectetur magna eiusmod incididunt.</p>
|
|
38
|
+
|
|
39
|
+
<button @click="close" class="btn mt-4">Close</button>
|
|
38
40
|
</div>
|
|
39
41
|
</template>
|
|
40
42
|
</BaseModalCenter>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
63
|
<button
|
|
64
|
-
class="right
|
|
64
|
+
class="right fixed top-2 right-2 flex h-16 w-16 items-center justify-center rounded-full hover:bg-black hover:bg-opacity-20"
|
|
65
65
|
type="button"
|
|
66
66
|
@click="modal.close()"
|
|
67
67
|
>
|
|
@@ -26,9 +26,11 @@ const Template = (args) => ({
|
|
|
26
26
|
<BaseModalSide v-model="show" v-bind="args">
|
|
27
27
|
<template #default="{close}">
|
|
28
28
|
<div class="p-8">
|
|
29
|
-
<
|
|
29
|
+
<h2 class="font-semibold text-lg mb-6">This is a center modal</h2>
|
|
30
30
|
|
|
31
|
-
<
|
|
31
|
+
<p v-for="i in 10" :key="i" class="mb-3 text-slate-600">Ipsum magna irure aliquip aute adipisicing Lorem non commodo amet. Est labore dolor laboris sint est magna quis fugiat id cillum deserunt cupidatat veniam. Exercitation dolore consequat labore deserunt laboris id. In laborum ea irure amet esse commodo et deserunt do officia et. Nulla incididunt est laboris pariatur ad duis ad reprehenderit voluptate. Tempor consectetur magna eiusmod incididunt.</p>
|
|
32
|
+
|
|
33
|
+
<button @click="close" class="btn mt-4">Close</button>
|
|
32
34
|
</div>
|
|
33
35
|
</template>
|
|
34
36
|
</BaseModalSide>
|