@antify/ui 2.2.16 → 2.3.1

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.
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ computed,
4
+ } from 'vue';
5
+ import {
6
+ State,
7
+ } from '../enums/State.enum';
8
+
9
+ const props = withDefaults(defineProps<{
10
+ /**
11
+ * Represent the value in percentage
12
+ * Should be a number from 0 to 100
13
+ */
14
+ progress: number | null;
15
+ /**
16
+ * Takes string with height and the unit e.g. '16px' or '1rem'
17
+ */
18
+ height: string;
19
+ /**
20
+ * Takes tailwind class for background color e.g. 'bg-primary-500'
21
+ */
22
+ color?: string;
23
+ }>(),{
24
+ color: 'bg-primary-500',
25
+ });
26
+
27
+ const progressWidth = computed(() => {
28
+ if (!props.progress || props.progress <= 0) {
29
+ return '0%';
30
+ } else if (props.progress && props.progress <= 100) {
31
+ return `${props.progress}%`;
32
+ } else {
33
+ return '100%';
34
+ }
35
+ });
36
+ </script>
37
+
38
+ <template>
39
+ <div
40
+ class="relative bg-base-100 w-full rounded-md"
41
+ :style="{ height: height }"
42
+ >
43
+ <div
44
+ class="absolute rounded-md"
45
+ :class="color"
46
+ :style="{ width: progressWidth, height: height }"
47
+ />
48
+ </div>
49
+ </template>
@@ -0,0 +1,7 @@
1
+ import AntProgress from '../AntProgress.vue';
2
+ import { type Meta, type StoryObj } from '@storybook/vue3';
3
+ declare const meta: Meta<typeof AntProgress>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AntProgress>;
6
+ export declare const Docs: Story;
7
+ export declare const Summary: Story;
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ module.exports = exports.Summary = exports.Docs = void 0;
7
+ var _AntProgress = _interopRequireDefault(require("../AntProgress.vue"));
8
+ var _AntButton = _interopRequireDefault(require("../buttons/AntButton.vue"));
9
+ var _Size = require("../../enums/Size.enum");
10
+ var _vue = require("vue");
11
+ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const meta = {
14
+ title: "Components/Progress",
15
+ component: _AntProgress.default,
16
+ parameters: {
17
+ controls: {
18
+ sort: "requiredFirst"
19
+ }
20
+ },
21
+ argTypes: {
22
+ color: {
23
+ control: {
24
+ type: "text"
25
+ },
26
+ description: 'Use tailwind class to change background color e.g. "bg-primary-500"'
27
+ }
28
+ }
29
+ };
30
+ module.exports = meta;
31
+ const Docs = exports.Docs = {
32
+ render: args => ({
33
+ components: {
34
+ AntProgress: _AntProgress.default,
35
+ AntButton: _AntButton.default
36
+ },
37
+ setup() {
38
+ const progress = (0, _vue.ref)(0);
39
+ const increase = () => {
40
+ if (progress.value === 100) {
41
+ return;
42
+ }
43
+ progress.value += 10;
44
+ };
45
+ const decrease = () => {
46
+ if (progress.value === null || progress.value === 0) {
47
+ return;
48
+ }
49
+ progress.value -= 10;
50
+ };
51
+ const onClickStart = () => {
52
+ progress.value = 0;
53
+ const interval = setInterval(() => {
54
+ if (progress.value < 100) {
55
+ progress.value += 5;
56
+ } else {
57
+ clearInterval(interval);
58
+ }
59
+ }, 100);
60
+ };
61
+ return {
62
+ args,
63
+ faPlus: _freeSolidSvgIcons.faPlus,
64
+ faMinus: _freeSolidSvgIcons.faMinus,
65
+ Size: _Size.Size,
66
+ progress,
67
+ decrease,
68
+ increase,
69
+ onClickStart
70
+ };
71
+ },
72
+ template: `
73
+ <div class="dashed p-2 flex h-[50vh] flex-col gap-2.5">
74
+ <AntProgress v-bind="args" :progress="progress"/>
75
+
76
+ <div class="flex gap-2.5 items-center">
77
+ <AntButton
78
+ :icon-left="faMinus"
79
+ :size="Size.md"
80
+ :disabled="progress <= 0"
81
+ @click="decrease"
82
+ />
83
+
84
+ <div>
85
+ {{progress}}%
86
+ </div>
87
+
88
+ <AntButton
89
+ :icon-left="faPlus"
90
+ :size="Size.md"
91
+ :disabled="progress >= 100"
92
+ @click="increase"
93
+ />
94
+
95
+ <AntButton
96
+ :size="Size.md"
97
+ @click="onClickStart"
98
+ >
99
+ Start
100
+ </AntButton>
101
+ </div>
102
+ </div>
103
+ `
104
+ }),
105
+ args: {
106
+ height: "8px"
107
+ }
108
+ };
109
+ const Summary = exports.Summary = {
110
+ parameters: {
111
+ chromatic: {
112
+ disableSnapshot: false
113
+ }
114
+ },
115
+ render: args => ({
116
+ components: {
117
+ AntProgress: _AntProgress.default,
118
+ AntButton: _AntButton.default
119
+ },
120
+ setup() {
121
+ const progress1 = (0, _vue.ref)(50);
122
+ const progress2 = (0, _vue.ref)(50);
123
+ const progress3 = (0, _vue.ref)(50);
124
+ const progress = [progress1, progress2, progress3];
125
+ const increase = number => {
126
+ const progressItem = progress[number - 1];
127
+ if (progressItem.value < 100) {
128
+ progressItem.value += 10;
129
+ }
130
+ };
131
+ const decrease = number => {
132
+ const progressItem = progress[number - 1];
133
+ if (progressItem.value < 100) {
134
+ progressItem.value -= 10;
135
+ }
136
+ };
137
+ const onClickStart = number => {
138
+ const progressItem = progress[number - 1];
139
+ progressItem.value = 0;
140
+ const interval = setInterval(() => {
141
+ if (progressItem.value < 100) {
142
+ progressItem.value += 5;
143
+ } else {
144
+ clearInterval(interval);
145
+ }
146
+ }, 100);
147
+ };
148
+ return {
149
+ args,
150
+ faPlus: _freeSolidSvgIcons.faPlus,
151
+ faMinus: _freeSolidSvgIcons.faMinus,
152
+ Size: _Size.Size,
153
+ progress1,
154
+ progress2,
155
+ progress3,
156
+ decrease,
157
+ increase,
158
+ onClickStart
159
+ };
160
+ },
161
+ template: `
162
+ <div class="flex flex-col gap-2.5">
163
+ <div class="flex flex-col gap-2.5">
164
+ <AntProgress v-bind="args" :progress="progress1" height="8px"/>
165
+
166
+ <div class="flex gap-2.5 items-center">
167
+ <AntButton
168
+ :icon-left="faMinus"
169
+ :size="Size.md"
170
+ :disabled="progress1 <= 0"
171
+ @click="decrease(1)"
172
+ />
173
+
174
+ <div>
175
+ {{progress1}}%
176
+ </div>
177
+
178
+ <AntButton
179
+ :icon-left="faPlus"
180
+ :size="Size.md"
181
+ :disabled="progress1 >= 100"
182
+ @click="increase(1)"
183
+ />
184
+
185
+ <AntButton
186
+ :size="Size.md"
187
+ @click="onClickStart(1)"
188
+ >
189
+ Start
190
+ </AntButton>
191
+ </div>
192
+ </div>
193
+
194
+ <div class="flex flex-col gap-2.5">
195
+ <AntProgress v-bind="args" :progress="progress2" height="12px" color="bg-secondary-500"/>
196
+
197
+ <div class="flex gap-2.5 items-center">
198
+ <AntButton
199
+ :icon-left="faMinus"
200
+ :size="Size.md"
201
+ :disabled="progress2 <= 0"
202
+ @click="decrease(2)"
203
+ />
204
+
205
+ <div>
206
+ {{progress2}}%
207
+ </div>
208
+
209
+ <AntButton
210
+ :icon-left="faPlus"
211
+ :size="Size.md"
212
+ :disabled="progress2 >= 100"
213
+ @click="increase(2)"
214
+ />
215
+
216
+ <AntButton
217
+ :size="Size.md"
218
+ @click="onClickStart(2)"
219
+ >
220
+ Start
221
+ </AntButton>
222
+ </div>
223
+ </div>
224
+
225
+ <div class="flex flex-col gap-2.5">
226
+ <AntProgress v-bind="args" :progress="progress3" height="18px" color="bg-amber-500"/>
227
+
228
+ <div class="flex gap-2.5 items-center">
229
+ <AntButton
230
+ :icon-left="faMinus"
231
+ :size="Size.md"
232
+ :disabled="progress3 <= 0"
233
+ @click="decrease(3)"
234
+ />
235
+
236
+ <div>
237
+ {{progress3}}%
238
+ </div>
239
+
240
+ <AntButton
241
+ :icon-left="faPlus"
242
+ :size="Size.md"
243
+ :disabled="progress3 >= 100"
244
+ @click="increase(3)"
245
+ />
246
+
247
+ <AntButton
248
+ :size="Size.md"
249
+ @click="onClickStart(3)"
250
+ >
251
+ Start
252
+ </AntButton>
253
+ </div>
254
+ </div>
255
+ </div>
256
+ `
257
+ }),
258
+ args: {}
259
+ };
@@ -0,0 +1,263 @@
1
+ import AntProgress from "../AntProgress.vue";
2
+ import AntButton from "../buttons/AntButton.vue";
3
+ import {
4
+ Size
5
+ } from "../../enums/Size.enum.mjs";
6
+ import {
7
+ ref
8
+ } from "vue";
9
+ import {
10
+ faMinus,
11
+ faPlus
12
+ } from "@fortawesome/free-solid-svg-icons";
13
+ const meta = {
14
+ title: "Components/Progress",
15
+ component: AntProgress,
16
+ parameters: {
17
+ controls: {
18
+ sort: "requiredFirst"
19
+ }
20
+ },
21
+ argTypes: {
22
+ color: {
23
+ control: {
24
+ type: "text"
25
+ },
26
+ description: 'Use tailwind class to change background color e.g. "bg-primary-500"'
27
+ }
28
+ }
29
+ };
30
+ export default meta;
31
+ export const Docs = {
32
+ render: (args) => ({
33
+ components: {
34
+ AntProgress,
35
+ AntButton
36
+ },
37
+ setup() {
38
+ const progress = ref(0);
39
+ const increase = () => {
40
+ if (progress.value === 100) {
41
+ return;
42
+ }
43
+ progress.value += 10;
44
+ };
45
+ const decrease = () => {
46
+ if (progress.value === null || progress.value === 0) {
47
+ return;
48
+ }
49
+ progress.value -= 10;
50
+ };
51
+ const onClickStart = () => {
52
+ progress.value = 0;
53
+ const interval = setInterval(() => {
54
+ if (progress.value < 100) {
55
+ progress.value += 5;
56
+ } else {
57
+ clearInterval(interval);
58
+ }
59
+ }, 100);
60
+ };
61
+ return {
62
+ args,
63
+ faPlus,
64
+ faMinus,
65
+ Size,
66
+ progress,
67
+ decrease,
68
+ increase,
69
+ onClickStart
70
+ };
71
+ },
72
+ template: `
73
+ <div class="dashed p-2 flex h-[50vh] flex-col gap-2.5">
74
+ <AntProgress v-bind="args" :progress="progress"/>
75
+
76
+ <div class="flex gap-2.5 items-center">
77
+ <AntButton
78
+ :icon-left="faMinus"
79
+ :size="Size.md"
80
+ :disabled="progress <= 0"
81
+ @click="decrease"
82
+ />
83
+
84
+ <div>
85
+ {{progress}}%
86
+ </div>
87
+
88
+ <AntButton
89
+ :icon-left="faPlus"
90
+ :size="Size.md"
91
+ :disabled="progress >= 100"
92
+ @click="increase"
93
+ />
94
+
95
+ <AntButton
96
+ :size="Size.md"
97
+ @click="onClickStart"
98
+ >
99
+ Start
100
+ </AntButton>
101
+ </div>
102
+ </div>
103
+ `
104
+ }),
105
+ args: {
106
+ height: "8px"
107
+ }
108
+ };
109
+ export const Summary = {
110
+ parameters: {
111
+ chromatic: {
112
+ disableSnapshot: false
113
+ }
114
+ },
115
+ render: (args) => ({
116
+ components: {
117
+ AntProgress,
118
+ AntButton
119
+ },
120
+ setup() {
121
+ const progress1 = ref(50);
122
+ const progress2 = ref(50);
123
+ const progress3 = ref(50);
124
+ const progress = [
125
+ progress1,
126
+ progress2,
127
+ progress3
128
+ ];
129
+ const increase = (number) => {
130
+ const progressItem = progress[number - 1];
131
+ if (progressItem.value < 100) {
132
+ progressItem.value += 10;
133
+ }
134
+ };
135
+ const decrease = (number) => {
136
+ const progressItem = progress[number - 1];
137
+ if (progressItem.value < 100) {
138
+ progressItem.value -= 10;
139
+ }
140
+ };
141
+ const onClickStart = (number) => {
142
+ const progressItem = progress[number - 1];
143
+ progressItem.value = 0;
144
+ const interval = setInterval(() => {
145
+ if (progressItem.value < 100) {
146
+ progressItem.value += 5;
147
+ } else {
148
+ clearInterval(interval);
149
+ }
150
+ }, 100);
151
+ };
152
+ return {
153
+ args,
154
+ faPlus,
155
+ faMinus,
156
+ Size,
157
+ progress1,
158
+ progress2,
159
+ progress3,
160
+ decrease,
161
+ increase,
162
+ onClickStart
163
+ };
164
+ },
165
+ template: `
166
+ <div class="flex flex-col gap-2.5">
167
+ <div class="flex flex-col gap-2.5">
168
+ <AntProgress v-bind="args" :progress="progress1" height="8px"/>
169
+
170
+ <div class="flex gap-2.5 items-center">
171
+ <AntButton
172
+ :icon-left="faMinus"
173
+ :size="Size.md"
174
+ :disabled="progress1 <= 0"
175
+ @click="decrease(1)"
176
+ />
177
+
178
+ <div>
179
+ {{progress1}}%
180
+ </div>
181
+
182
+ <AntButton
183
+ :icon-left="faPlus"
184
+ :size="Size.md"
185
+ :disabled="progress1 >= 100"
186
+ @click="increase(1)"
187
+ />
188
+
189
+ <AntButton
190
+ :size="Size.md"
191
+ @click="onClickStart(1)"
192
+ >
193
+ Start
194
+ </AntButton>
195
+ </div>
196
+ </div>
197
+
198
+ <div class="flex flex-col gap-2.5">
199
+ <AntProgress v-bind="args" :progress="progress2" height="12px" color="bg-secondary-500"/>
200
+
201
+ <div class="flex gap-2.5 items-center">
202
+ <AntButton
203
+ :icon-left="faMinus"
204
+ :size="Size.md"
205
+ :disabled="progress2 <= 0"
206
+ @click="decrease(2)"
207
+ />
208
+
209
+ <div>
210
+ {{progress2}}%
211
+ </div>
212
+
213
+ <AntButton
214
+ :icon-left="faPlus"
215
+ :size="Size.md"
216
+ :disabled="progress2 >= 100"
217
+ @click="increase(2)"
218
+ />
219
+
220
+ <AntButton
221
+ :size="Size.md"
222
+ @click="onClickStart(2)"
223
+ >
224
+ Start
225
+ </AntButton>
226
+ </div>
227
+ </div>
228
+
229
+ <div class="flex flex-col gap-2.5">
230
+ <AntProgress v-bind="args" :progress="progress3" height="18px" color="bg-amber-500"/>
231
+
232
+ <div class="flex gap-2.5 items-center">
233
+ <AntButton
234
+ :icon-left="faMinus"
235
+ :size="Size.md"
236
+ :disabled="progress3 <= 0"
237
+ @click="decrease(3)"
238
+ />
239
+
240
+ <div>
241
+ {{progress3}}%
242
+ </div>
243
+
244
+ <AntButton
245
+ :icon-left="faPlus"
246
+ :size="Size.md"
247
+ :disabled="progress3 >= 100"
248
+ @click="increase(3)"
249
+ />
250
+
251
+ <AntButton
252
+ :size="Size.md"
253
+ @click="onClickStart(3)"
254
+ >
255
+ Start
256
+ </AntButton>
257
+ </div>
258
+ </div>
259
+ </div>
260
+ `
261
+ }),
262
+ args: {}
263
+ };
@@ -38,6 +38,7 @@ import AntTagInput from './inputs/AntTagInput.vue';
38
38
  import AntTextarea from './inputs/AntTextarea.vue';
39
39
  import AntTextInput from './inputs/AntTextInput.vue';
40
40
  import AntUnitInput from './inputs/AntUnitInput.vue';
41
+ import AntImageInput from './inputs/AntImageInput.vue';
41
42
  import AntNavLeftLayout from './layouts/AntNavLeftLayout.vue';
42
43
  import AntNavbar from './navbar/AntNavbar.vue';
43
44
  import AntNavbarItem from './navbar/AntNavbarItem.vue';
@@ -63,4 +64,4 @@ import AntTag from './AntTag.vue';
63
64
  import AntToast from './AntToast.vue';
64
65
  import AntToaster from './AntToaster.vue';
65
66
  import AntTooltip from './AntTooltip.vue';
66
- export { AntActionButton, AntButton, AntCreateButton, AntDeleteButton, AntDuplicateButton, AntEditButton, AntSaveAndNewButton, AntSaveButton, AntCrud, AntCrudDetail, AntCrudDetailActions, AntCrudDetailNav, AntCrudTableFilter, AntCrudTableNav, AntDeleteDialog, AntDialog, AntField, AntFormGroup, AntFormGroupLabel, AntBaseInput, AntSelectMenu, AntInputDescription, AntInputLabel, AntInputLimiter, AntCheckbox, AntCheckboxGroup, AntDateInput, AntNumberInput, AntPasswordInput, AntRadio, AntRadioGroup, AntRangeSlider, AntSearch, AntSelect, AntSwitch, AntSwitcher, AntTagInput, AntTextarea, AntTextInput, AntUnitInput, AntNavLeftLayout, AntNavbar, AntNavbarItem, AntTable, AntTabs, AntTransitionCollapseHeight, AntAccordion, AntAccordionItem, AntAlert, AntCard, AntContent, AntDropdown, AntIcon, AntKeycap, AntListGroup, AntListGroupItem, AntModal, AntPagination, AntPopover, AntSkeleton, AntSpinner, AntTag, AntToast, AntToaster, AntTooltip, };
67
+ export { AntActionButton, AntButton, AntCreateButton, AntDeleteButton, AntDuplicateButton, AntEditButton, AntSaveAndNewButton, AntSaveButton, AntCrud, AntCrudDetail, AntCrudDetailActions, AntCrudDetailNav, AntCrudTableFilter, AntCrudTableNav, AntDeleteDialog, AntDialog, AntField, AntFormGroup, AntFormGroupLabel, AntBaseInput, AntSelectMenu, AntInputDescription, AntInputLabel, AntInputLimiter, AntCheckbox, AntCheckboxGroup, AntDateInput, AntNumberInput, AntPasswordInput, AntRadio, AntRadioGroup, AntRangeSlider, AntSearch, AntSelect, AntSwitch, AntSwitcher, AntTagInput, AntTextarea, AntTextInput, AntUnitInput, AntImageInput, AntNavLeftLayout, AntNavbar, AntNavbarItem, AntTable, AntTabs, AntTransitionCollapseHeight, AntAccordion, AntAccordionItem, AntAlert, AntCard, AntContent, AntDropdown, AntIcon, AntKeycap, AntListGroup, AntListGroupItem, AntModal, AntPagination, AntPopover, AntSkeleton, AntSpinner, AntTag, AntToast, AntToaster, AntTooltip, };
@@ -171,6 +171,12 @@ Object.defineProperty(exports, "AntIcon", {
171
171
  return _AntIcon.default;
172
172
  }
173
173
  });
174
+ Object.defineProperty(exports, "AntImageInput", {
175
+ enumerable: true,
176
+ get: function () {
177
+ return _AntImageInput.default;
178
+ }
179
+ });
174
180
  Object.defineProperty(exports, "AntInputDescription", {
175
181
  enumerable: true,
176
182
  get: function () {
@@ -433,6 +439,7 @@ var _AntTagInput = _interopRequireDefault(require("./inputs/AntTagInput.vue"));
433
439
  var _AntTextarea = _interopRequireDefault(require("./inputs/AntTextarea.vue"));
434
440
  var _AntTextInput = _interopRequireDefault(require("./inputs/AntTextInput.vue"));
435
441
  var _AntUnitInput = _interopRequireDefault(require("./inputs/AntUnitInput.vue"));
442
+ var _AntImageInput = _interopRequireDefault(require("./inputs/AntImageInput.vue"));
436
443
  var _AntNavLeftLayout = _interopRequireDefault(require("./layouts/AntNavLeftLayout.vue"));
437
444
  var _AntNavbar = _interopRequireDefault(require("./navbar/AntNavbar.vue"));
438
445
  var _AntNavbarItem = _interopRequireDefault(require("./navbar/AntNavbarItem.vue"));
@@ -38,6 +38,7 @@ import AntTagInput from "./inputs/AntTagInput.vue";
38
38
  import AntTextarea from "./inputs/AntTextarea.vue";
39
39
  import AntTextInput from "./inputs/AntTextInput.vue";
40
40
  import AntUnitInput from "./inputs/AntUnitInput.vue";
41
+ import AntImageInput from "./inputs/AntImageInput.vue";
41
42
  import AntNavLeftLayout from "./layouts/AntNavLeftLayout.vue";
42
43
  import AntNavbar from "./navbar/AntNavbar.vue";
43
44
  import AntNavbarItem from "./navbar/AntNavbarItem.vue";
@@ -104,6 +105,7 @@ export {
104
105
  AntTextarea,
105
106
  AntTextInput,
106
107
  AntUnitInput,
108
+ AntImageInput,
107
109
  AntNavLeftLayout,
108
110
  AntNavbar,
109
111
  AntNavbarItem,
@@ -0,0 +1,199 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ computed,
4
+ onMounted,
5
+ ref,
6
+ } from 'vue';
7
+ import AntField from '../forms/AntField.vue';
8
+ import {
9
+ Size,
10
+ } from '../../enums/Size.enum';
11
+ import {
12
+ InputState, State,
13
+ } from '../../enums';
14
+ import {
15
+ useVModel,
16
+ } from '@vueuse/core';
17
+ import {
18
+ handleEnumValidation,
19
+ } from '../../handler';
20
+ import {
21
+ faImage, faMultiply, faUpload,
22
+ } from '@fortawesome/free-solid-svg-icons';
23
+ import AntIcon from '../AntIcon.vue';
24
+ import {
25
+ IconSize,
26
+ } from '../__types';
27
+ import AntButton from '../buttons/AntButton.vue';
28
+ import AntSpinner from '../AntSpinner.vue';
29
+ import AntInputDescription from './Elements/AntInputDescription.vue';
30
+ import AntSkeleton from '../AntSkeleton.vue';
31
+
32
+ defineOptions({
33
+ inheritAttrs: false,
34
+ });
35
+
36
+ const props = withDefaults(defineProps<{
37
+ modelValue: string | null;
38
+ loading?: boolean;
39
+ label?: string;
40
+ placeholder?: string;
41
+ description?: string;
42
+ size?: Size;
43
+ state?: InputState;
44
+ disabled?: boolean;
45
+ skeleton?: boolean;
46
+ wrapperClass?: string | Record<string, boolean>;
47
+ messages?: string[];
48
+ expanded?: boolean;
49
+ }>(), {
50
+ state: InputState.base,
51
+ disabled: false,
52
+ skeleton: false,
53
+ size: Size.md,
54
+ messages: () => [],
55
+ expanded: true,
56
+ loading: false,
57
+ });
58
+ const emit = defineEmits([
59
+ 'update:modelValue',
60
+ 'validate',
61
+ ]);
62
+ const _modelValue = useVModel(props, 'modelValue', emit);
63
+ const descriptionFontSize = computed(() => {
64
+ if (props.size === Size.xs2 || props.size === Size.xs) {
65
+ return Size.xs;
66
+ }
67
+
68
+ return Size.sm;
69
+ });
70
+ const fileInput = ref<HTMLInputElement | null>(null);
71
+
72
+ const openFileDialog = () => {
73
+ fileInput.value?.click();
74
+ };
75
+
76
+ const handleFileChange = (event: Event) => {
77
+ const target = event.target as HTMLInputElement;
78
+ const file = target.files?.[0];
79
+ if (file) {
80
+ const reader = new FileReader();
81
+ reader.onload = () => {
82
+ emit('update:modelValue', reader.result as string);
83
+ };
84
+ reader.readAsDataURL(file);
85
+ }
86
+ };
87
+
88
+ onMounted(() => {
89
+ handleEnumValidation(props.state, InputState, 'state');
90
+ handleEnumValidation(props.size, Size, 'size');
91
+ });
92
+ </script>
93
+
94
+ <template>
95
+ <AntField
96
+ :label="label"
97
+ :size="size"
98
+ :skeleton="skeleton"
99
+ :state="state"
100
+ :messages="messages"
101
+ :expanded="expanded"
102
+ >
103
+ <div
104
+ class="flex gap-2.5 w-full"
105
+ :class="{'cursor-pointer': !disabled && !skeleton}"
106
+ >
107
+ <div>
108
+ <div class="h-[70px] w-[70px] bg-gray-100 rounded-full overflow-hidden flex items-center justify-center relative">
109
+ <img
110
+ v-if="_modelValue && !skeleton"
111
+ :src="_modelValue"
112
+ alt="Image"
113
+ class="h-full w-full object-cover"
114
+ >
115
+
116
+ <AntIcon
117
+ v-else
118
+ class="text-base-300"
119
+ :size="IconSize.xl3"
120
+ :icon="faImage"
121
+ />
122
+
123
+ <div
124
+ v-if="loading"
125
+ class="absolute flex items-center justify-center inset-0 bg-base-600/50 rounded-full"
126
+ >
127
+ <AntSpinner
128
+ :state="State.primary"
129
+ />
130
+ </div>
131
+
132
+ <AntSkeleton
133
+ v-if="skeleton"
134
+ absolute
135
+ rounded-full
136
+ />
137
+ </div>
138
+ </div>
139
+
140
+ <div class="flex flex-col gap-2.5 w-full">
141
+ <div class="flex items-center relative w-full justify-between">
142
+ <input
143
+ v-if="!disabled && !skeleton"
144
+ ref="fileInput"
145
+ type="file"
146
+ accept="image/*"
147
+ class="hidden"
148
+ @change="handleFileChange"
149
+ >
150
+
151
+ <span class="text-sm text-for-white-bg-font relative">
152
+ Upload Image
153
+
154
+ <AntSkeleton
155
+ v-if="skeleton"
156
+ absolute
157
+ rounded
158
+ />
159
+ </span>
160
+
161
+ <AntButton
162
+ v-if="_modelValue"
163
+ :size="Size.lg"
164
+ :icon-left="faMultiply"
165
+ :skeleton="skeleton"
166
+ :disabled="disabled"
167
+ @click.prevent="() => _modelValue = null"
168
+ >
169
+ <template #tooltip-content>
170
+ Remove image
171
+ </template>
172
+ </AntButton>
173
+
174
+ <AntButton
175
+ v-else
176
+ :size="Size.lg"
177
+ :icon-left="faUpload"
178
+ :skeleton="skeleton"
179
+ :disabled="disabled"
180
+ @click="openFileDialog"
181
+ >
182
+ <template #tooltip-content>
183
+ Upload image
184
+ </template>
185
+ </AntButton>
186
+ </div>
187
+
188
+ <AntInputDescription
189
+ v-if="description"
190
+ :skeleton="skeleton"
191
+ :size="descriptionFontSize"
192
+ :state="state"
193
+ >
194
+ {{ description }}
195
+ </AntInputDescription>
196
+ </div>
197
+ </div>
198
+ </AntField>
199
+ </template>
@@ -0,0 +1,10 @@
1
+ import { type Meta, type StoryObj } from '@storybook/vue3';
2
+ import AntImageInput from '../AntImageInput.vue';
3
+ declare const meta: Meta<typeof AntImageInput>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AntImageInput>;
6
+ export declare const Docs: Story;
7
+ export declare const Empty: Story;
8
+ export declare const Skeleton: Story;
9
+ export declare const Disabled: Story;
10
+ export declare const Summary: Story;
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ module.exports = exports.Summary = exports.Skeleton = exports.Empty = exports.Docs = exports.Disabled = void 0;
7
+ var _Size = require("../../../enums/Size.enum");
8
+ var _AntImageInput = _interopRequireDefault(require("../AntImageInput.vue"));
9
+ var _enums = require("../../../enums");
10
+ var _AntFormGroupLabel = _interopRequireDefault(require("../../forms/AntFormGroupLabel.vue"));
11
+ var _AntFormGroup = _interopRequireDefault(require("../../forms/AntFormGroup.vue"));
12
+ var _vue = require("vue");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ const meta = {
15
+ title: "Inputs/Image Input",
16
+ component: _AntImageInput.default,
17
+ parameters: {
18
+ controls: {
19
+ sort: "requiredFirst"
20
+ }
21
+ },
22
+ argTypes: {
23
+ modelValue: {
24
+ table: {
25
+ type: {
26
+ summary: "string|null"
27
+ }
28
+ }
29
+ },
30
+ state: {
31
+ control: {
32
+ type: "select"
33
+ },
34
+ options: Object.values(_enums.InputState)
35
+ },
36
+ size: {
37
+ control: {
38
+ type: "select"
39
+ },
40
+ options: Object.values(_Size.Size)
41
+ },
42
+ placeholder: {
43
+ table: {
44
+ defaultValue: {
45
+ summary: "this.label"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ };
51
+ module.exports = meta;
52
+ const Docs = exports.Docs = {
53
+ render: args => ({
54
+ components: {
55
+ AntImageInput: _AntImageInput.default
56
+ },
57
+ setup() {
58
+ return {
59
+ args
60
+ };
61
+ },
62
+ template: `
63
+ <AntImageInput
64
+ v-bind="args"
65
+ v-model="args.modelValue"
66
+ />`
67
+ }),
68
+ args: {
69
+ modelValue: "/avatar.jpg",
70
+ label: "Label",
71
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
72
+ }
73
+ };
74
+ const Empty = exports.Empty = {
75
+ render: Docs.render,
76
+ args: {
77
+ ...Docs.args,
78
+ modelValue: null
79
+ }
80
+ };
81
+ const Skeleton = exports.Skeleton = {
82
+ render: Docs.render,
83
+ args: {
84
+ ...Docs.args,
85
+ skeleton: true
86
+ }
87
+ };
88
+ const Disabled = exports.Disabled = {
89
+ render: Docs.render,
90
+ args: {
91
+ ...Docs.args,
92
+ disabled: true
93
+ }
94
+ };
95
+ const Summary = exports.Summary = {
96
+ parameters: {
97
+ chromatic: {
98
+ disableSnapshot: false
99
+ }
100
+ },
101
+ render: () => ({
102
+ components: {
103
+ AntFormGroupLabel: _AntFormGroupLabel.default,
104
+ AntImageInput: _AntImageInput.default,
105
+ AntFormGroup: _AntFormGroup.default,
106
+ ref: _vue.ref
107
+ },
108
+ setup() {
109
+ const valuedModelValue = (0, _vue.ref)("/avatar.jpg");
110
+ const emptyModelValue = (0, _vue.ref)(null);
111
+ return {
112
+ valuedModelValue,
113
+ emptyModelValue
114
+ };
115
+ },
116
+ template: `
117
+ <AntFormGroup>
118
+ <AntFormGroupLabel>Default</AntFormGroupLabel>
119
+ <AntImageInput
120
+ v-model="valuedModelValue"
121
+ label="Label"
122
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
123
+ />
124
+ <AntFormGroupLabel>Empty</AntFormGroupLabel>
125
+ <AntImageInput
126
+ v-model="emptyModelValue"
127
+ label="Label"
128
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
129
+ />
130
+ <AntFormGroupLabel>Disabled</AntFormGroupLabel>
131
+ <AntImageInput
132
+ v-model="valuedModelValue"
133
+ label="Label"
134
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
135
+ />
136
+ </AntFormGroup>
137
+ `
138
+ })
139
+ };
@@ -0,0 +1,138 @@
1
+ import {
2
+ Size
3
+ } from "../../../enums/Size.enum.mjs";
4
+ import AntImageInput from "../AntImageInput.vue";
5
+ import {
6
+ InputState
7
+ } from "../../../enums/index.mjs";
8
+ import AntFormGroupLabel from "../../forms/AntFormGroupLabel.vue";
9
+ import AntFormGroup from "../../forms/AntFormGroup.vue";
10
+ import {
11
+ ref
12
+ } from "vue";
13
+ const meta = {
14
+ title: "Inputs/Image Input",
15
+ component: AntImageInput,
16
+ parameters: {
17
+ controls: {
18
+ sort: "requiredFirst"
19
+ }
20
+ },
21
+ argTypes: {
22
+ modelValue: {
23
+ table: {
24
+ type: {
25
+ summary: "string|null"
26
+ }
27
+ }
28
+ },
29
+ state: {
30
+ control: {
31
+ type: "select"
32
+ },
33
+ options: Object.values(InputState)
34
+ },
35
+ size: {
36
+ control: {
37
+ type: "select"
38
+ },
39
+ options: Object.values(Size)
40
+ },
41
+ placeholder: {
42
+ table: {
43
+ defaultValue: {
44
+ summary: "this.label"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ };
50
+ export default meta;
51
+ export const Docs = {
52
+ render: (args) => ({
53
+ components: {
54
+ AntImageInput
55
+ },
56
+ setup() {
57
+ return {
58
+ args
59
+ };
60
+ },
61
+ template: `
62
+ <AntImageInput
63
+ v-bind="args"
64
+ v-model="args.modelValue"
65
+ />`
66
+ }),
67
+ args: {
68
+ modelValue: "/avatar.jpg",
69
+ label: "Label",
70
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
71
+ }
72
+ };
73
+ export const Empty = {
74
+ render: Docs.render,
75
+ args: {
76
+ ...Docs.args,
77
+ modelValue: null
78
+ }
79
+ };
80
+ export const Skeleton = {
81
+ render: Docs.render,
82
+ args: {
83
+ ...Docs.args,
84
+ skeleton: true
85
+ }
86
+ };
87
+ export const Disabled = {
88
+ render: Docs.render,
89
+ args: {
90
+ ...Docs.args,
91
+ disabled: true
92
+ }
93
+ };
94
+ export const Summary = {
95
+ parameters: {
96
+ chromatic: {
97
+ disableSnapshot: false
98
+ }
99
+ },
100
+ render: () => ({
101
+ components: {
102
+ AntFormGroupLabel,
103
+ AntImageInput,
104
+ AntFormGroup,
105
+ ref
106
+ },
107
+ setup() {
108
+ const valuedModelValue = ref("/avatar.jpg");
109
+ const emptyModelValue = ref(null);
110
+ return {
111
+ valuedModelValue,
112
+ emptyModelValue
113
+ };
114
+ },
115
+ template: `
116
+ <AntFormGroup>
117
+ <AntFormGroupLabel>Default</AntFormGroupLabel>
118
+ <AntImageInput
119
+ v-model="valuedModelValue"
120
+ label="Label"
121
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
122
+ />
123
+ <AntFormGroupLabel>Empty</AntFormGroupLabel>
124
+ <AntImageInput
125
+ v-model="emptyModelValue"
126
+ label="Label"
127
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
128
+ />
129
+ <AntFormGroupLabel>Disabled</AntFormGroupLabel>
130
+ <AntImageInput
131
+ v-model="valuedModelValue"
132
+ label="Label"
133
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
134
+ />
135
+ </AntFormGroup>
136
+ `
137
+ })
138
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antify/ui",
3
- "version": "2.2.16",
3
+ "version": "2.3.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {