sprintify-ui 0.0.26 → 0.0.27

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.
@@ -39,7 +39,35 @@ declare const _default: import("vue").DefineComponent<{
39
39
  default: boolean;
40
40
  type: BooleanConstructor;
41
41
  };
42
- }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
42
+ iconLeft: {
43
+ default: undefined;
44
+ type: StringConstructor;
45
+ };
46
+ iconRight: {
47
+ default: undefined;
48
+ type: StringConstructor;
49
+ };
50
+ prefix: {
51
+ default: undefined;
52
+ type: StringConstructor;
53
+ };
54
+ suffix: {
55
+ default: undefined;
56
+ type: StringConstructor;
57
+ };
58
+ hasError: {
59
+ default: boolean;
60
+ type: BooleanConstructor;
61
+ };
62
+ min: {
63
+ default: undefined;
64
+ type: NumberConstructor;
65
+ };
66
+ max: {
67
+ default: undefined;
68
+ type: NumberConstructor;
69
+ };
70
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "focus" | "blur")[], "update:modelValue" | "focus" | "blur", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
43
71
  modelValue: {
44
72
  default: string;
45
73
  type: PropType<string | number | null>;
@@ -79,7 +107,37 @@ declare const _default: import("vue").DefineComponent<{
79
107
  default: boolean;
80
108
  type: BooleanConstructor;
81
109
  };
110
+ iconLeft: {
111
+ default: undefined;
112
+ type: StringConstructor;
113
+ };
114
+ iconRight: {
115
+ default: undefined;
116
+ type: StringConstructor;
117
+ };
118
+ prefix: {
119
+ default: undefined;
120
+ type: StringConstructor;
121
+ };
122
+ suffix: {
123
+ default: undefined;
124
+ type: StringConstructor;
125
+ };
126
+ hasError: {
127
+ default: boolean;
128
+ type: BooleanConstructor;
129
+ };
130
+ min: {
131
+ default: undefined;
132
+ type: NumberConstructor;
133
+ };
134
+ max: {
135
+ default: undefined;
136
+ type: NumberConstructor;
137
+ };
82
138
  }>> & {
139
+ onFocus?: ((...args: any[]) => any) | undefined;
140
+ onBlur?: ((...args: any[]) => any) | undefined;
83
141
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
84
142
  }, {
85
143
  required: boolean;
@@ -89,7 +147,14 @@ declare const _default: import("vue").DefineComponent<{
89
147
  modelValue: string | number | null;
90
148
  placeholder: string;
91
149
  disabled: boolean;
150
+ min: number;
151
+ max: number;
92
152
  autocomplete: boolean;
93
153
  preventSubmit: boolean;
154
+ iconLeft: string;
155
+ iconRight: string;
156
+ prefix: string;
157
+ suffix: string;
158
+ hasError: boolean;
94
159
  }>;
95
160
  export default _default;
@@ -0,0 +1,133 @@
1
+ import { PropType } from 'vue';
2
+ declare const _default: import("vue").DefineComponent<{
3
+ /**
4
+ * The value of the input. Can be a number or null.
5
+ * 0.1 = 10%
6
+ * 0.5 = 50%
7
+ * 1 = 100%
8
+ */
9
+ modelValue: {
10
+ default: undefined;
11
+ type: PropType<string | number | null>;
12
+ };
13
+ /**
14
+ * The step of the input. Can be a number or null.
15
+ */
16
+ step: {
17
+ default: number;
18
+ type: NumberConstructor;
19
+ };
20
+ /**
21
+ * Prevents submit when pressing 'Enter' while the input is focused.
22
+ */
23
+ preventSubmit: {
24
+ default: boolean;
25
+ type: BooleanConstructor;
26
+ };
27
+ name: {
28
+ default: undefined;
29
+ type: StringConstructor;
30
+ };
31
+ placeholder: {
32
+ default: string;
33
+ type: StringConstructor;
34
+ };
35
+ disabled: {
36
+ default: boolean;
37
+ type: BooleanConstructor;
38
+ };
39
+ required: {
40
+ default: boolean;
41
+ type: BooleanConstructor;
42
+ };
43
+ icon: {
44
+ default: undefined;
45
+ type: StringConstructor;
46
+ };
47
+ hasError: {
48
+ default: boolean;
49
+ type: BooleanConstructor;
50
+ };
51
+ min: {
52
+ default: undefined;
53
+ type: NumberConstructor;
54
+ };
55
+ max: {
56
+ default: undefined;
57
+ type: NumberConstructor;
58
+ };
59
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "focus" | "blur")[], "update:modelValue" | "focus" | "blur", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
60
+ /**
61
+ * The value of the input. Can be a number or null.
62
+ * 0.1 = 10%
63
+ * 0.5 = 50%
64
+ * 1 = 100%
65
+ */
66
+ modelValue: {
67
+ default: undefined;
68
+ type: PropType<string | number | null>;
69
+ };
70
+ /**
71
+ * The step of the input. Can be a number or null.
72
+ */
73
+ step: {
74
+ default: number;
75
+ type: NumberConstructor;
76
+ };
77
+ /**
78
+ * Prevents submit when pressing 'Enter' while the input is focused.
79
+ */
80
+ preventSubmit: {
81
+ default: boolean;
82
+ type: BooleanConstructor;
83
+ };
84
+ name: {
85
+ default: undefined;
86
+ type: StringConstructor;
87
+ };
88
+ placeholder: {
89
+ default: string;
90
+ type: StringConstructor;
91
+ };
92
+ disabled: {
93
+ default: boolean;
94
+ type: BooleanConstructor;
95
+ };
96
+ required: {
97
+ default: boolean;
98
+ type: BooleanConstructor;
99
+ };
100
+ icon: {
101
+ default: undefined;
102
+ type: StringConstructor;
103
+ };
104
+ hasError: {
105
+ default: boolean;
106
+ type: BooleanConstructor;
107
+ };
108
+ min: {
109
+ default: undefined;
110
+ type: NumberConstructor;
111
+ };
112
+ max: {
113
+ default: undefined;
114
+ type: NumberConstructor;
115
+ };
116
+ }>> & {
117
+ onFocus?: ((...args: any[]) => any) | undefined;
118
+ onBlur?: ((...args: any[]) => any) | undefined;
119
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
120
+ }, {
121
+ required: boolean;
122
+ name: string;
123
+ step: number;
124
+ icon: string;
125
+ modelValue: string | number | null;
126
+ placeholder: string;
127
+ disabled: boolean;
128
+ min: number;
129
+ max: number;
130
+ preventSubmit: boolean;
131
+ hasError: boolean;
132
+ }>;
133
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "build-fast": "rimraf dist && vite build",
@@ -7,7 +7,6 @@ export default {
7
7
  required: true,
8
8
  type: 'text',
9
9
  name: 'name',
10
- class: 'w-full',
11
10
  },
12
11
  };
13
12
 
@@ -31,6 +30,39 @@ Demo.args = {
31
30
  placeholder: 'Enter your name',
32
31
  };
33
32
 
33
+ export const IconLeft = Template.bind({});
34
+ IconLeft.args = {
35
+ iconLeft: 'heroicons:phone-20-solid',
36
+ placeholder: 'Enter your phone',
37
+ };
38
+
39
+ export const IconRight = Template.bind({});
40
+ IconRight.args = {
41
+ iconRight: 'mdi:email-outline',
42
+ placeholder: 'Enter your email',
43
+ };
44
+
45
+ export const Prefix = Template.bind({});
46
+ Prefix.args = {
47
+ prefix: 'https://',
48
+ placeholder: 'website URL',
49
+ };
50
+
51
+ export const Suffix = Template.bind({});
52
+ Suffix.args = {
53
+ suffix: '%',
54
+ placeholder: 'Percentage',
55
+ };
56
+
57
+ export const All = Template.bind({});
58
+ All.args = {
59
+ iconLeft: 'heroicons:currency-dollar-20-solid',
60
+ prefix: 'Price',
61
+ iconRight: 'heroicons:document-magnifying-glass',
62
+ suffix: '$',
63
+ placeholder: 'Item price',
64
+ };
65
+
34
66
  export const Number = Template.bind({});
35
67
  Number.args = {
36
68
  type: 'number',
@@ -44,3 +76,11 @@ Disabled.args = {
44
76
  disabled: true,
45
77
  placeholder: 'Enter your name',
46
78
  };
79
+
80
+ export const Error = Template.bind({});
81
+ Error.args = {
82
+ hasError: true,
83
+ prefix: 'Price',
84
+ iconRight: 'heroicons:currency-dollar',
85
+ placeholder: 'Enter your name',
86
+ };
@@ -1,23 +1,72 @@
1
1
  <template>
2
- <input
3
- ref="input"
4
- :value="modelValue"
5
- :type="type"
6
- :name="name"
7
- :step="step"
8
- :disabled="disabled"
9
- :placeholder="placeholder"
10
- :required="required"
11
- class="rounded border-slate-300 disabled:cursor-not-allowed disabled:text-slate-300"
12
- :autocomplete="autocomplete ? 'on' : 'off'"
13
- @keydown.enter="onEnter"
14
- @input="$emit('update:modelValue', transformInputValue($event))"
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>