@indielayer/ui 1.12.0 → 1.12.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.
@@ -111,6 +111,7 @@ const linkTab = ref(null)
111
111
  v-model="tab"
112
112
  class="pb-10"
113
113
  variant="block"
114
+ :full-width="false"
114
115
  ghost
115
116
  >
116
117
  <x-tab value="a" label="Tab A">
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { ref } from 'vue'
3
- import { useNotifications, type UploadFile } from '@indielayer/ui'
3
+ import { useNotifications, XUpload, type UploadFile } from '@indielayer/ui'
4
4
 
5
5
  const notifications = useNotifications()
6
6
 
@@ -72,29 +72,38 @@ function onSubmit(isValid: boolean) {
72
72
  notifications?.success('Valid! Submitted.')
73
73
  }
74
74
 
75
+ const uploadRef = ref<InstanceType<typeof XUpload>>()
76
+
77
+ function reset() {
78
+ uploadRef.value?.reset()
79
+ previewImg.value = undefined
80
+ }
81
+
75
82
  const action = 'https://run.mocky.io/v3/6904ae0b-3cfa-4ae1-bbf2-243a4dd32a3c'
76
83
  </script>
77
84
 
78
85
  <template>
79
86
  <div >
80
87
  <x-form @submit="onSubmit">
81
- <div class="grid md:grid-cols-2 gap-2">
82
- <x-upload
83
- v-model="imageFiles"
84
-
85
- :action="action"
86
- method="POST"
87
- :with-credentials="false"
88
- :rules="[rules.isValidUpload]"
89
-
90
- placeholder="Upload game title cover image"
91
- max-file-size="2000000"
92
- label="Cover Image"
93
- tooltip="Title cover image should be 16:9 aspect ratio and max 2MB"
94
- helper="Title cover image should be 16:9 aspect ratio and max 2MB"
95
- @upload="onUploadComplete"
96
- @change="onChangeImage"
97
- />
88
+ <div class="grid md:grid-cols-2 gap-2 mb-4">
89
+ <div>
90
+ <x-upload
91
+ ref="uploadRef"
92
+ v-model="imageFiles"
93
+ :action="action"
94
+ method="POST"
95
+ :with-credentials="false"
96
+ :rules="[rules.isValidUpload]"
97
+ placeholder="Upload game title cover image"
98
+ max-file-size="2000000"
99
+ label="Cover Image"
100
+ tooltip="Title cover image should be 16:9 aspect ratio and max 2MB"
101
+ helper="Title cover image should be 16:9 aspect ratio and max 2MB"
102
+ @upload="onUploadComplete"
103
+ @change="onChangeImage"
104
+ />
105
+ <x-button size="sm" outlined ghost @click="reset">Reset input</x-button>
106
+ </div>
98
107
  <x-upload
99
108
  v-model="jsonFile"
100
109
  placeholder="Upload your json file"
@@ -105,6 +114,7 @@ const action = 'https://run.mocky.io/v3/6904ae0b-3cfa-4ae1-bbf2-243a4dd32a3c'
105
114
  @change="onChangeJSON"
106
115
  />
107
116
  </div>
117
+ <x-divider class="my-4"/>
108
118
  <x-button type="submit">Submit</x-button>
109
119
  </x-form>
110
120
  <div v-if="previewImg">
@@ -78,10 +78,7 @@ const x = { key: 0 }, ee = ["xs", "sm", "md", "lg", "xl", "full"], oe = ["top",
78
78
  u.value = e, c.value = e, A(), document.body.style.paddingRight = "", document.body.style.overflow = "auto";
79
79
  }
80
80
  typeof window < "u" && G(document, "keydown", W);
81
- const R = (e) => [".v-popper__popper", ".x-datepicker"].some((n) => {
82
- if (typeof n == "string")
83
- return Array.from(window.document.querySelectorAll(n)).some((f) => f === e.target || e.composedPath().includes(f));
84
- });
81
+ const R = (e) => [".v-popper__popper", ".x-datepicker"].some((n) => typeof n == "string" ? Array.from(window.document.querySelectorAll(n)).some((f) => f === e.target || e.composedPath().includes(f)) : !1);
85
82
  function W(e) {
86
83
  e.key === "Escape" && !R(e) && c.value && !d.persistent && p();
87
84
  }
@@ -1,8 +1,8 @@
1
1
  const i = {
2
2
  classes: {
3
3
  wrapper: ({ props: t, data: s }) => {
4
- const e = ["py-2 transition-colors duration-150 ease-in-out whitespace-nowrap text-center"];
5
- return s.variant === "block" && e.push("px-8"), t.size === "xs" ? e.push("text-xs") : t.size === "sm" ? e.push("text-sm") : t.size === "lg" ? e.push("text-lg") : t.size === "xl" && e.push("text-xl"), e;
4
+ const e = ["transition-colors duration-150 ease-in-out whitespace-nowrap text-center"];
5
+ return s.variant === "line" && e.push("py-2"), s.variant === "block" && e.push("py-1.5 px-8"), t.size === "xs" ? e.push("text-xs") : t.size === "sm" ? e.push("text-sm") : t.size === "lg" ? e.push("text-lg") : t.size === "xl" && e.push("text-xl"), e;
6
6
  },
7
7
  content: "flex items-center justify-center",
8
8
  label: "font-medium",
@@ -3,7 +3,7 @@ const o = {
3
3
  wrapper: "",
4
4
  scroller: ({ props: t }) => {
5
5
  const r = [""];
6
- return t.fullWidth || r.push("!w-fit"), t.variant === "block" && r.push("rounded-md"), t.variant === "block" && !t.ghost && r.push("bg-secondary-100 dark:bg-secondary-800 p-1"), r;
6
+ return t.fullWidth || r.push("!w-fit"), t.variant === "block" && r.push("rounded-lg"), t.variant === "block" && !t.ghost && r.push("bg-secondary-100 dark:bg-secondary-800 p-1"), r;
7
7
  },
8
8
  list: ({ props: t }) => {
9
9
  const r = ["flex min-w-full w-fit"];
@@ -21,6 +21,10 @@ declare const uploadProps: {
21
21
  default: string;
22
22
  };
23
23
  withCredentials: BooleanConstructor;
24
+ fileFormDataName: {
25
+ type: StringConstructor;
26
+ default: string;
27
+ };
24
28
  modelValue: {
25
29
  readonly type: PropType<string | number | boolean | object | any[] | undefined>;
26
30
  readonly default: undefined;
@@ -80,6 +84,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<im
80
84
  default: string;
81
85
  };
82
86
  withCredentials: BooleanConstructor;
87
+ fileFormDataName: {
88
+ type: StringConstructor;
89
+ default: string;
90
+ };
83
91
  modelValue: {
84
92
  readonly type: PropType<string | number | boolean | object | any[] | undefined>;
85
93
  readonly default: undefined;
@@ -132,6 +140,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<im
132
140
  default: string;
133
141
  };
134
142
  withCredentials: BooleanConstructor;
143
+ fileFormDataName: {
144
+ type: StringConstructor;
145
+ default: string;
146
+ };
135
147
  modelValue: {
136
148
  readonly type: PropType<string | number | boolean | object | any[] | undefined>;
137
149
  readonly default: undefined;
@@ -178,6 +190,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<im
178
190
  multiple: boolean;
179
191
  method: "POST" | "PUT";
180
192
  withCredentials: boolean;
193
+ fileFormDataName: string;
181
194
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, {
182
195
  box?(_: {
183
196
  isOver: boolean;
@@ -1,20 +1,20 @@
1
- import { defineComponent as te, ref as y, computed as oe, watch as ne, openBlock as d, createElementBlock as f, normalizeClass as b, unref as s, createVNode as x, normalizeStyle as se, withCtx as ie, createElementVNode as l, mergeProps as ae, toHandlers as le, renderSlot as k, toDisplayString as _, createBlock as g, createCommentVNode as w, Fragment as de, renderList as ce } from "vue";
1
+ import { defineComponent as te, ref as b, computed as oe, watch as ne, openBlock as d, createElementBlock as v, normalizeClass as x, unref as a, createVNode as k, normalizeStyle as se, withCtx as ae, createElementVNode as l, mergeProps as ie, toHandlers as le, renderSlot as S, toDisplayString as _, createBlock as g, createCommentVNode as w, Fragment as de, renderList as ce } from "vue";
2
2
  import { useDropZone as ue } from "../../node_modules/.pnpm/@vueuse_core@11.1.0_vue@3.5.10_typescript@5.2.2_/node_modules/@vueuse/core/index.js";
3
- import { useCommon as pe } from "../../composables/useCommon.js";
4
- import { useInteractive as U } from "../../composables/useInteractive.js";
5
- import { useInputtable as I } from "../../composables/useInputtable.js";
6
- import { useTheme as me } from "../../composables/useTheme.js";
7
- import { uploadIcon as fe, fileIcon as ge, closeIcon as he } from "../../common/icons.js";
8
- import ve from "../label/Label.vue.js";
9
- import O from "../inputFooter/InputFooter.vue.js";
3
+ import { useCommon as me } from "../../composables/useCommon.js";
4
+ import { useInteractive as O } from "../../composables/useInteractive.js";
5
+ import { useInputtable as V } from "../../composables/useInputtable.js";
6
+ import { useTheme as pe } from "../../composables/useTheme.js";
7
+ import { uploadIcon as fe, fileIcon as ve, closeIcon as ge } from "../../common/icons.js";
8
+ import he from "../label/Label.vue.js";
9
+ import L from "../inputFooter/InputFooter.vue.js";
10
10
  import ye from "../progress/Progress.vue.js";
11
- import S from "../icon/Icon.vue.js";
12
- const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = { class: "text-secondary-500 dark:text-secondary-400" }, ke = { class: "flex items-center" }, _e = ["src"], we = { class: "truncate flex-1 pr-2" }, Se = { class: "font-medium truncate" }, Ie = { class: "text-xs text-secondary-500" }, $e = ["onClick"], Ve = {
13
- ...pe.validators(),
11
+ import I from "../icon/Icon.vue.js";
12
+ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = { class: "text-secondary-500 dark:text-secondary-400" }, ke = { class: "flex items-center" }, Se = ["src"], _e = { class: "truncate flex-1 pr-2" }, we = { class: "font-medium truncate" }, Ie = { class: "text-xs text-secondary-500" }, Ve = ["onClick"], $e = {
13
+ ...me.validators(),
14
14
  variant: ["box"]
15
- }, Ce = {
16
- ...U.props(),
17
- ...I.props(),
15
+ }, Ne = {
16
+ ...O.props(),
17
+ ...V.props(),
18
18
  placeholder: String,
19
19
  accept: String,
20
20
  multiple: Boolean,
@@ -32,20 +32,24 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
32
32
  type: String,
33
33
  default: "POST"
34
34
  },
35
- withCredentials: Boolean
36
- }, Ee = {
35
+ withCredentials: Boolean,
36
+ fileFormDataName: {
37
+ type: String,
38
+ default: "file"
39
+ }
40
+ }, Ce = {
37
41
  name: "XUpload",
38
- validators: Ve
39
- }, Fe = /* @__PURE__ */ te({
40
- ...Ee,
41
- props: Ce,
42
- emits: [...I.emits(), "upload", "remove"],
43
- setup(j, { expose: D, emit: q }) {
44
- const o = j, u = q, $ = y(null), p = oe(() => !!o.action), i = y([]);
45
- ne(i, (e) => {
42
+ validators: $e
43
+ }, Te = /* @__PURE__ */ te({
44
+ ...Ce,
45
+ props: Ne,
46
+ emits: [...V.emits(), "upload", "remove"],
47
+ setup(j, { expose: F, emit: U }) {
48
+ const o = j, u = U, p = b(null), f = oe(() => !!o.action), s = b([]);
49
+ ne(s, (e) => {
46
50
  u("update:modelValue", e);
47
51
  }, { deep: !0, immediate: !0 });
48
- const { focus: V, blur: P } = U($);
52
+ const { focus: $, blur: q } = O(p);
49
53
  function h(e) {
50
54
  if (!e)
51
55
  return !1;
@@ -66,34 +70,34 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
66
70
  }
67
71
  return !0;
68
72
  }
69
- function T(e) {
73
+ function P(e) {
70
74
  const r = e.target.files;
71
75
  h(r) && u("change", e);
72
76
  }
73
- function F(e) {
77
+ function T(e) {
74
78
  const r = e.target.files;
75
- h(r) && (N(r), o.validateOnInput && !K.value && v(i.value), u("input", e));
79
+ h(r) && (E(r), o.validateOnInput && !D.value && y(s.value), u("input", e));
76
80
  }
77
- const C = y(null);
81
+ const N = b(null);
78
82
  function M(e) {
79
- h(e) && N(e);
83
+ h(e) && E(e);
80
84
  }
81
- const { isOverDropZone: E } = ue(C, {
85
+ const { isOverDropZone: C } = ue(N, {
82
86
  onDrop: M,
83
87
  multiple: o.multiple,
84
88
  preventDefaultForUnhandled: !1
85
89
  });
86
- function N(e) {
87
- i.value = e ? Array.from(e).map((t) => ({
90
+ function E(e) {
91
+ s.value = e ? Array.from(e).map((t) => ({
88
92
  file: t,
89
- completed: !p.value,
90
- progress: p.value ? 0 : 100,
93
+ completed: !f.value,
94
+ progress: f.value ? 0 : 100,
91
95
  error: ""
92
- })) : [], p.value && W();
96
+ })) : [], f.value && W();
93
97
  }
94
98
  function Z(e) {
95
- const t = i.value.findIndex((r) => r.file === e);
96
- t !== -1 && (u("remove", i.value[t]), i.value.splice(t, 1));
99
+ const t = s.value.findIndex((r) => r.file === e);
100
+ t !== -1 && (u("remove", s.value[t]), s.value.splice(t, 1));
97
101
  }
98
102
  function B(e) {
99
103
  const t = ["jpg", "jpeg", "png", "gif", "webp", "svg"];
@@ -111,15 +115,15 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
111
115
  r(new Error("No action provided"));
112
116
  else {
113
117
  const n = new XMLHttpRequest(), c = new FormData();
114
- c.append("file", e.file), n.open(o.method, o.action, !0), o.headers && typeof o.headers == "object" && Object.keys(o.headers).forEach((a) => {
115
- n.setRequestHeader(a, o.headers[a]);
116
- }), n.upload.addEventListener("progress", (a) => {
117
- if (a.lengthComputable) {
118
- const L = a.loaded / a.total * 100;
119
- e.progress = L, console.log(`Upload progress: ${L}%`);
118
+ c.append(o.fileFormDataName, e.file), n.open(o.method, o.action, !0), o.headers && typeof o.headers == "object" && Object.keys(o.headers).forEach((i) => {
119
+ n.setRequestHeader(i, o.headers[i]);
120
+ }), n.upload.addEventListener("progress", (i) => {
121
+ if (i.lengthComputable) {
122
+ const re = i.loaded / i.total * 100;
123
+ e.progress = re;
120
124
  }
121
125
  }), n.addEventListener("load", () => {
122
- if (n.status === 200) {
126
+ if (n.status >= 200 && n.status < 300) {
123
127
  e.completed = !0;
124
128
  try {
125
129
  e.response = JSON.parse(n.responseText);
@@ -128,8 +132,8 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
128
132
  }
129
133
  t(n.responseText);
130
134
  } else {
131
- const a = `Upload failed. Status: ${n.status}`;
132
- e.error = a, r(new Error(a));
135
+ const i = `Upload failed. Status: ${n.status}`;
136
+ e.error = i, r(new Error(i));
133
137
  }
134
138
  }), n.addEventListener("error", () => {
135
139
  e.error = "An error occurred during the upload.", r(new Error("An error occurred during the upload."));
@@ -138,46 +142,48 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
138
142
  });
139
143
  }
140
144
  async function W() {
141
- if (!o.action && !i.value)
145
+ if (!o.action && !s.value)
142
146
  return;
143
147
  const e = [];
144
- for (let t = 0; t < i.value.length; t++)
145
- e.push(H(i.value[t]));
146
- await Promise.all(e), v(i.value);
148
+ for (let t = 0; t < s.value.length; t++)
149
+ e.push(H(s.value[t]));
150
+ await Promise.all(e), y(s.value);
151
+ }
152
+ function X() {
153
+ m.value = "", D.value = !0, s.value = [], p.value && (p.value.value = "");
147
154
  }
148
155
  const {
149
156
  errorInternal: m,
150
- hideFooterInternal: X,
151
- isInsideForm: G,
152
- inputListeners: J,
153
- isFirstValidation: K,
154
- reset: Q,
155
- validate: v,
156
- setError: Y
157
- } = I(o, { focus: V, emit: u }), { styles: ee, classes: R, className: re } = me("Upload", {}, o);
158
- return D({ focus: V, blur: P, reset: Q, validate: v, setError: Y }), (e, t) => (d(), f("div", {
159
- class: b([
160
- s(re),
161
- s(R).wrapper
157
+ hideFooterInternal: G,
158
+ isInsideForm: J,
159
+ inputListeners: K,
160
+ isFirstValidation: D,
161
+ validate: y,
162
+ setError: Q
163
+ } = V(o, { focus: $, emit: u }), { styles: Y, classes: R, className: ee } = pe("Upload", {}, o);
164
+ return F({ focus: $, blur: q, reset: X, validate: y, setError: Q }), (e, t) => (d(), v("div", {
165
+ class: x([
166
+ a(ee),
167
+ a(R).wrapper
162
168
  ])
163
169
  }, [
164
- x(ve, {
165
- style: se(s(ee)),
170
+ k(he, {
171
+ style: se(a(Y)),
166
172
  disabled: e.disabled,
167
173
  required: e.required,
168
- "is-inside-form": s(G),
174
+ "is-inside-form": a(J),
169
175
  label: e.label,
170
176
  tooltip: e.tooltip
171
177
  }, {
172
- default: ie(() => [
173
- l("input", ae({
178
+ default: ae(() => [
179
+ l("input", ie({
174
180
  id: e.id,
175
181
  ref_key: "elRef",
176
- ref: $,
182
+ ref: p,
177
183
  type: "file",
178
184
  class: [
179
185
  "sr-only",
180
- s(R).input
186
+ a(R).input
181
187
  ],
182
188
  disabled: e.disabled,
183
189
  name: e.name,
@@ -185,53 +191,53 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
185
191
  multiple: e.multiple,
186
192
  readonly: e.readonly
187
193
  }, le({
188
- ...s(J),
189
- input: F,
190
- change: T
194
+ ...a(K),
195
+ input: T,
196
+ change: P
191
197
  }, !0)), null, 16, be),
192
- k(e.$slots, "box", { isOver: s(E) }, () => [
198
+ S(e.$slots, "box", { isOver: a(C) }, () => [
193
199
  l("div", {
194
200
  ref_key: "dropZoneRef",
195
- ref: C,
196
- class: b(["border border-dashed rounded-md flex items-center justify-center gap-2 p-4 cursor-pointer transition-colors duration-500 hover:border-primary-500 dark:hover:border-primary-400", {
197
- "border-primary-500 dark:border-primary-400": s(E)
201
+ ref: N,
202
+ class: x(["border border-dashed rounded-md flex items-center justify-center gap-2 p-4 cursor-pointer transition-colors duration-500 hover:border-primary-500 dark:hover:border-primary-400", {
203
+ "border-primary-500 dark:border-primary-400": a(C)
198
204
  }])
199
205
  }, [
200
- x(S, { icon: s(fe) }, null, 8, ["icon"]),
206
+ k(I, { icon: a(fe) }, null, 8, ["icon"]),
201
207
  l("span", xe, _(e.placeholder), 1),
202
208
  t[0] || (t[0] = l("span", { class: "text-xs text-secondary-400 dark:text-secondary-500" }, "or drag and drop", -1))
203
209
  ], 2)
204
210
  ]),
205
- s(X) ? w("", !0) : (d(), g(O, {
211
+ a(G) ? w("", !0) : (d(), g(L, {
206
212
  key: 0,
207
- error: s(m),
213
+ error: a(m),
208
214
  helper: e.helper
209
215
  }, null, 8, ["error", "helper"]))
210
216
  ]),
211
217
  _: 3
212
218
  }, 8, ["style", "disabled", "required", "is-inside-form", "label", "tooltip"]),
213
- k(e.$slots, "files", { files: i.value }, () => [
214
- (d(!0), f(de, null, ce(i.value, (r, n) => (d(), f("div", {
219
+ S(e.$slots, "files", { files: s.value }, () => [
220
+ (d(!0), v(de, null, ce(s.value, (r, n) => (d(), v("div", {
215
221
  key: n,
216
222
  class: "border rounded-md p-2 bg-secondary-100 my-2"
217
223
  }, [
218
224
  l("div", ke, [
219
225
  l("div", {
220
- class: b(["rounded-md w-9 h-9 flex items-center justify-center mr-2 border", {
226
+ class: x(["rounded-md w-9 h-9 flex items-center justify-center mr-2 border", {
221
227
  "p-2 bg-white": !B(r.file)
222
228
  }])
223
229
  }, [
224
- B(r.file) ? (d(), f("img", {
230
+ B(r.file) ? (d(), v("img", {
225
231
  key: 0,
226
232
  src: z(r.file),
227
233
  class: "w-full h-full object-cover rounded-md"
228
- }, null, 8, _e)) : (d(), g(S, {
234
+ }, null, 8, Se)) : (d(), g(I, {
229
235
  key: 1,
230
- icon: s(ge)
236
+ icon: a(ve)
231
237
  }, null, 8, ["icon"]))
232
238
  ], 2),
233
- l("div", we, [
234
- l("div", Se, _(r.file.name), 1),
239
+ l("div", _e, [
240
+ l("div", we, _(r.file.name), 1),
235
241
  l("div", Ie, _(A(r.file.size)), 1)
236
242
  ]),
237
243
  l("button", {
@@ -239,18 +245,18 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
239
245
  class: "shrink-0",
240
246
  onClick: (c) => Z(r.file)
241
247
  }, [
242
- k(e.$slots, "removeIcon", {}, () => [
243
- x(S, { icon: s(he) }, null, 8, ["icon"])
248
+ S(e.$slots, "removeIcon", {}, () => [
249
+ k(I, { icon: a(ge) }, null, 8, ["icon"])
244
250
  ])
245
- ], 8, $e)
251
+ ], 8, Ve)
246
252
  ]),
247
- p.value ? (d(), g(ye, {
253
+ f.value ? (d(), g(ye, {
248
254
  key: 0,
249
255
  percentage: r.progress,
250
256
  class: "mt-1",
251
257
  color: r.error ? "warning" : "success"
252
258
  }, null, 8, ["percentage", "color"])) : w("", !0),
253
- r.error ? (d(), g(O, {
259
+ r.error ? (d(), g(L, {
254
260
  key: 1,
255
261
  error: r.error
256
262
  }, null, 8, ["error"])) : w("", !0)
@@ -260,5 +266,5 @@ const be = ["id", "disabled", "name", "accept", "multiple", "readonly"], xe = {
260
266
  }
261
267
  });
262
268
  export {
263
- Fe as default
269
+ Te as default
264
270
  };