@shwfed/nuxt 0.11.36 → 0.11.37

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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
3
  "configKey": "shwfed",
4
- "version": "0.11.36",
4
+ "version": "0.11.37",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -172,6 +172,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
172
172
  }[] | undefined;
173
173
  maxCount?: string | undefined;
174
174
  template?: string | undefined;
175
+ templateName?: readonly {
176
+ locale: "en" | "ja" | "ko" | "zh";
177
+ message: string;
178
+ }[] | undefined;
175
179
  style?: string | undefined;
176
180
  initialValue?: string | undefined;
177
181
  hidden?: string | undefined;
@@ -361,6 +365,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
361
365
  }[] | undefined;
362
366
  maxCount?: string | undefined;
363
367
  template?: string | undefined;
368
+ templateName?: readonly {
369
+ locale: "en" | "ja" | "ko" | "zh";
370
+ message: string;
371
+ }[] | undefined;
364
372
  style?: string | undefined;
365
373
  initialValue?: string | undefined;
366
374
  hidden?: string | undefined;
@@ -172,6 +172,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
172
172
  }[] | undefined;
173
173
  maxCount?: string | undefined;
174
174
  template?: string | undefined;
175
+ templateName?: readonly {
176
+ locale: "en" | "ja" | "ko" | "zh";
177
+ message: string;
178
+ }[] | undefined;
175
179
  style?: string | undefined;
176
180
  initialValue?: string | undefined;
177
181
  hidden?: string | undefined;
@@ -361,6 +365,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
361
365
  }[] | undefined;
362
366
  maxCount?: string | undefined;
363
367
  template?: string | undefined;
368
+ templateName?: readonly {
369
+ locale: "en" | "ja" | "ko" | "zh";
370
+ message: string;
371
+ }[] | undefined;
364
372
  style?: string | undefined;
365
373
  initialValue?: string | undefined;
366
374
  hidden?: string | undefined;
@@ -4,10 +4,10 @@ import { computed, ref, useAttrs, useSlots } from "vue";
4
4
  import {
5
5
  Dialog,
6
6
  DialogClose,
7
- DialogContent,
8
7
  DialogDescription,
9
8
  DialogFooter,
10
9
  DialogHeader,
10
+ DialogScrollContent,
11
11
  DialogTitle,
12
12
  DialogTrigger
13
13
  } from "./ui/dialog";
@@ -39,7 +39,7 @@ const isDesktop = useMediaQuery(props.breakpoint);
39
39
  const desktopComponents = {
40
40
  Root: Dialog,
41
41
  Trigger: DialogTrigger,
42
- Content: DialogContent,
42
+ Content: DialogScrollContent,
43
43
  Header: DialogHeader,
44
44
  Title: DialogTitle,
45
45
  Description: DialogDescription,
@@ -13,7 +13,7 @@ import {
13
13
  ButtonsStyleC
14
14
  } from "../buttons/schema";
15
15
  import { Checkbox } from "../checkbox";
16
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../dialog";
16
+ import { Dialog, DialogDescription, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "../dialog";
17
17
  import { IconPicker } from "../icon-picker";
18
18
  import { Input } from "../input";
19
19
  import Locale from "../locale/Locale.vue";
@@ -848,7 +848,7 @@ function confirmChanges() {
848
848
  :open="open"
849
849
  @update:open="open = $event"
850
850
  >
851
- <DialogContent class="flex h-[min(40rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[72rem] sm:max-w-[72rem]">
851
+ <DialogScrollContent class="flex h-[min(40rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[72rem] sm:max-w-[72rem]">
852
852
  <DialogHeader class="gap-1 border-b border-zinc-200 px-6 py-5">
853
853
  <div class="flex items-center gap-3">
854
854
  <DialogTitle class="text-xl font-semibold text-zinc-800">
@@ -1382,7 +1382,7 @@ function confirmChanges() {
1382
1382
  </Button>
1383
1383
  </div>
1384
1384
  </DialogFooter>
1385
- </DialogContent>
1385
+ </DialogScrollContent>
1386
1386
  </Dialog>
1387
1387
  </template>
1388
1388
 
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
2
  import { useForwardPropsEmits } from "reka-ui";
3
- import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "../dialog";
3
+ import { Dialog, DialogDescription, DialogHeader, DialogScrollContent, DialogTitle } from "../dialog";
4
4
  import Command from "./Command.vue";
5
5
  const props = defineProps({
6
6
  open: { type: Boolean, required: false },
@@ -18,7 +18,7 @@ const forwarded = useForwardPropsEmits(props, emits);
18
18
  v-slot="slotProps"
19
19
  v-bind="forwarded"
20
20
  >
21
- <DialogContent
21
+ <DialogScrollContent
22
22
  :show-close-button="false"
23
23
  class="overflow-hidden p-0"
24
24
  >
@@ -29,6 +29,6 @@ const forwarded = useForwardPropsEmits(props, emits);
29
29
  <Command>
30
30
  <slot v-bind="slotProps" />
31
31
  </Command>
32
- </DialogContent>
32
+ </DialogScrollContent>
33
33
  </Dialog>
34
34
  </template>
@@ -2,10 +2,11 @@ import type { DialogContentProps } from 'reka-ui';
2
2
  import type { HTMLAttributes } from 'vue';
3
3
  type __VLS_Props = DialogContentProps & {
4
4
  class?: HTMLAttributes['class'];
5
+ showCloseButton?: boolean;
5
6
  };
6
- declare var __VLS_22: {};
7
+ declare var __VLS_23: {};
7
8
  type __VLS_Slots = {} & {
8
- default?: (props: typeof __VLS_22) => any;
9
+ default?: (props: typeof __VLS_23) => any;
9
10
  };
10
11
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
12
  escapeKeyDown: (event: KeyboardEvent) => any;
@@ -14,6 +15,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
14
15
  interactOutside: (event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any;
15
16
  openAutoFocus: (event: Event) => any;
16
17
  closeAutoFocus: (event: Event) => any;
18
+ "after-close": () => any;
17
19
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
20
  onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
19
21
  onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
@@ -21,7 +23,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
21
23
  onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
22
24
  onOpenAutoFocus?: ((event: Event) => any) | undefined;
23
25
  onCloseAutoFocus?: ((event: Event) => any) | undefined;
24
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ "onAfter-close"?: (() => any) | undefined;
27
+ }>, {
28
+ showCloseButton: boolean;
29
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
30
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
26
31
  declare const _default: typeof __VLS_export;
27
32
  export default _default;
@@ -1,6 +1,13 @@
1
1
  <script setup>
2
- import { Icon } from "@iconify/vue";
3
2
  import { reactiveOmit } from "@vueuse/core";
3
+ import { Icon } from "@iconify/vue";
4
+ import {
5
+ computed,
6
+ onBeforeUnmount,
7
+ shallowRef,
8
+ useAttrs,
9
+ watchEffect
10
+ } from "vue";
4
11
  import {
5
12
  DialogClose,
6
13
  DialogContent,
@@ -17,11 +24,158 @@ const props = defineProps({
17
24
  disableOutsidePointerEvents: { type: Boolean, required: false },
18
25
  asChild: { type: Boolean, required: false },
19
26
  as: { type: null, required: false },
20
- class: { type: null, required: false }
27
+ class: { type: null, required: false },
28
+ showCloseButton: { type: Boolean, required: false, default: true }
29
+ });
30
+ const emit = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus", "after-close"]);
31
+ const attrs = useAttrs();
32
+ const delegatedProps = reactiveOmit(props, "class", "showCloseButton");
33
+ const forwarded = useForwardPropsEmits(delegatedProps, emit);
34
+ const contentElement = shallowRef(null);
35
+ let closeFallbackTimer;
36
+ let hasEmittedAfterClose = false;
37
+ function isClosedContentTarget(target) {
38
+ return target instanceof HTMLElement && target.dataset.state === "closed";
39
+ }
40
+ function isPointerDownOutsideEvent(event) {
41
+ if (!("detail" in event) || typeof event.detail !== "object" || event.detail === null) {
42
+ return false;
43
+ }
44
+ if (!("originalEvent" in event.detail)) {
45
+ return false;
46
+ }
47
+ return event.detail.originalEvent instanceof MouseEvent;
48
+ }
49
+ function clearCloseFallbackTimer() {
50
+ if (closeFallbackTimer === void 0) {
51
+ return;
52
+ }
53
+ window.clearTimeout(closeFallbackTimer);
54
+ closeFallbackTimer = void 0;
55
+ }
56
+ function emitAfterClose() {
57
+ if (hasEmittedAfterClose) {
58
+ return;
59
+ }
60
+ hasEmittedAfterClose = true;
61
+ clearCloseFallbackTimer();
62
+ emit("after-close");
63
+ }
64
+ function parseDurationMs(value) {
65
+ const normalizedValue = value.trim();
66
+ if (normalizedValue.endsWith("ms")) {
67
+ const duration = Number.parseFloat(normalizedValue.slice(0, -2));
68
+ return Number.isFinite(duration) ? duration : 0;
69
+ }
70
+ if (normalizedValue.endsWith("s")) {
71
+ const duration = Number.parseFloat(normalizedValue.slice(0, -1));
72
+ return Number.isFinite(duration) ? duration * 1e3 : 0;
73
+ }
74
+ return 0;
75
+ }
76
+ function getLongestMotionMs(element) {
77
+ const style = window.getComputedStyle(element);
78
+ const animationDurations = style.animationDuration.split(",");
79
+ const animationDelays = style.animationDelay.split(",");
80
+ const transitionDurations = style.transitionDuration.split(",");
81
+ const transitionDelays = style.transitionDelay.split(",");
82
+ let longestMotionMs = 0;
83
+ for (const [index, durationValue] of animationDurations.entries()) {
84
+ const durationMs = parseDurationMs(durationValue);
85
+ const delayMs = parseDurationMs(animationDelays[index] ?? animationDelays[0] ?? "0s");
86
+ longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
87
+ }
88
+ for (const [index, durationValue] of transitionDurations.entries()) {
89
+ const durationMs = parseDurationMs(durationValue);
90
+ const delayMs = parseDurationMs(transitionDelays[index] ?? transitionDelays[0] ?? "0s");
91
+ longestMotionMs = Math.max(longestMotionMs, durationMs + delayMs);
92
+ }
93
+ return longestMotionMs;
94
+ }
95
+ function syncCloseFallback() {
96
+ const element = contentElement.value;
97
+ clearCloseFallbackTimer();
98
+ if (!element) {
99
+ return;
100
+ }
101
+ if (element.dataset.state !== "closed") {
102
+ hasEmittedAfterClose = false;
103
+ return;
104
+ }
105
+ const motionMs = getLongestMotionMs(element);
106
+ closeFallbackTimer = window.setTimeout(() => {
107
+ emitAfterClose();
108
+ }, motionMs > 0 ? motionMs : 0);
109
+ }
110
+ function handleCloseMotionEnd(event) {
111
+ if (hasEmittedAfterClose || event.target !== event.currentTarget || !isClosedContentTarget(event.currentTarget)) {
112
+ return;
113
+ }
114
+ emitAfterClose();
115
+ }
116
+ function setContentElement(target) {
117
+ if (target instanceof HTMLElement) {
118
+ contentElement.value = target;
119
+ syncCloseFallback();
120
+ return;
121
+ }
122
+ if (target && "$el" in target && target.$el instanceof HTMLElement) {
123
+ contentElement.value = target.$el;
124
+ syncCloseFallback();
125
+ return;
126
+ }
127
+ contentElement.value = null;
128
+ clearCloseFallbackTimer();
129
+ }
130
+ function callEventHandlers(eventHandler, event) {
131
+ if (typeof eventHandler === "function") {
132
+ eventHandler(event);
133
+ return;
134
+ }
135
+ if (!Array.isArray(eventHandler)) {
136
+ return;
137
+ }
138
+ for (const handler of eventHandler) {
139
+ if (typeof handler === "function") {
140
+ handler(event);
141
+ }
142
+ }
143
+ }
144
+ function handlePointerDownOutside(event) {
145
+ if (isPointerDownOutsideEvent(event) && event.detail.originalEvent.target instanceof HTMLElement) {
146
+ const target = event.detail.originalEvent.target;
147
+ if (event.detail.originalEvent.offsetX > target.clientWidth || event.detail.originalEvent.offsetY > target.clientHeight) {
148
+ event.preventDefault();
149
+ }
150
+ }
151
+ callEventHandlers(Reflect.get(forwarded, "onPointerDownOutside"), event);
152
+ callEventHandlers(Reflect.get(attrs, "onPointerDownOutside"), event);
153
+ }
154
+ const contentBindings = computed(() => ({
155
+ ...attrs,
156
+ ...forwarded,
157
+ onPointerDownOutside: handlePointerDownOutside
158
+ }));
159
+ watchEffect((onCleanup) => {
160
+ const element = contentElement.value;
161
+ if (!element) {
162
+ return;
163
+ }
164
+ const observer = new MutationObserver(() => {
165
+ syncCloseFallback();
166
+ });
167
+ observer.observe(element, {
168
+ attributes: true,
169
+ attributeFilter: ["data-state"]
170
+ });
171
+ syncCloseFallback();
172
+ onCleanup(() => {
173
+ observer.disconnect();
174
+ });
175
+ });
176
+ onBeforeUnmount(() => {
177
+ clearCloseFallbackTimer();
21
178
  });
22
- const emits = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus"]);
23
- const delegatedProps = reactiveOmit(props, "class");
24
- const forwarded = useForwardPropsEmits(delegatedProps, emits);
25
179
  </script>
26
180
 
27
181
  <template>
@@ -30,25 +184,24 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
30
184
  class="fixed inset-0 z-50 grid place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
31
185
  >
32
186
  <DialogContent
187
+ :ref="setContentElement"
188
+ data-slot="dialog-content"
33
189
  :class="
34
190
  cn(
35
191
  'relative z-50 grid w-full max-w-lg my-8 gap-4 border border-zinc-200 bg-white p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
36
192
  props.class
37
193
  )
38
194
  "
39
- v-bind="{ ...$attrs, ...forwarded }"
40
- @pointer-down-outside="(event) => {
41
- const originalEvent = event.detail.originalEvent;
42
- const target = originalEvent.target;
43
- if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
44
- event.preventDefault();
45
- }
46
- }"
195
+ v-bind="contentBindings"
196
+ @animationend="handleCloseMotionEnd"
197
+ @transitionend="handleCloseMotionEnd"
47
198
  >
48
199
  <slot />
49
200
 
50
201
  <DialogClose
51
- class="absolute top-4 right-4 p-0.5 transition-colors rounded-md hover:bg-zinc-100"
202
+ v-if="showCloseButton"
203
+ data-slot="dialog-close"
204
+ class="data-[state=open]:bg-zinc-100 data-[state=open]:text-zinc-700 absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
52
205
  >
53
206
  <Icon icon="fluent:dismiss-20-filled" />
54
207
  <span class="sr-only">Close</span>
@@ -2,10 +2,11 @@ import type { DialogContentProps } from 'reka-ui';
2
2
  import type { HTMLAttributes } from 'vue';
3
3
  type __VLS_Props = DialogContentProps & {
4
4
  class?: HTMLAttributes['class'];
5
+ showCloseButton?: boolean;
5
6
  };
6
- declare var __VLS_22: {};
7
+ declare var __VLS_23: {};
7
8
  type __VLS_Slots = {} & {
8
- default?: (props: typeof __VLS_22) => any;
9
+ default?: (props: typeof __VLS_23) => any;
9
10
  };
10
11
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
12
  escapeKeyDown: (event: KeyboardEvent) => any;
@@ -14,6 +15,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
14
15
  interactOutside: (event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any;
15
16
  openAutoFocus: (event: Event) => any;
16
17
  closeAutoFocus: (event: Event) => any;
18
+ "after-close": () => any;
17
19
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
20
  onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
19
21
  onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
@@ -21,7 +23,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
21
23
  onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
22
24
  onOpenAutoFocus?: ((event: Event) => any) | undefined;
23
25
  onCloseAutoFocus?: ((event: Event) => any) | undefined;
24
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ "onAfter-close"?: (() => any) | undefined;
27
+ }>, {
28
+ showCloseButton: boolean;
29
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
30
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
26
31
  declare const _default: typeof __VLS_export;
27
32
  export default _default;
@@ -166,6 +166,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
166
166
  }[] | undefined;
167
167
  maxCount?: string | undefined;
168
168
  template?: string | undefined;
169
+ templateName?: readonly {
170
+ locale: "en" | "ja" | "ko" | "zh";
171
+ message: string;
172
+ }[] | undefined;
169
173
  style?: string | undefined;
170
174
  initialValue?: string | undefined;
171
175
  hidden?: string | undefined;
@@ -354,6 +358,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
354
358
  }[] | undefined;
355
359
  maxCount?: string | undefined;
356
360
  template?: string | undefined;
361
+ templateName?: readonly {
362
+ locale: "en" | "ja" | "ko" | "zh";
363
+ message: string;
364
+ }[] | undefined;
357
365
  style?: string | undefined;
358
366
  initialValue?: string | undefined;
359
367
  hidden?: string | undefined;
@@ -538,6 +546,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
538
546
  }[] | undefined;
539
547
  maxCount?: string | undefined;
540
548
  template?: string | undefined;
549
+ templateName?: readonly {
550
+ locale: "en" | "ja" | "ko" | "zh";
551
+ message: string;
552
+ }[] | undefined;
541
553
  style?: string | undefined;
542
554
  initialValue?: string | undefined;
543
555
  hidden?: string | undefined;
@@ -724,6 +736,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
724
736
  }[] | undefined;
725
737
  maxCount?: string | undefined;
726
738
  template?: string | undefined;
739
+ templateName?: readonly {
740
+ locale: "en" | "ja" | "ko" | "zh";
741
+ message: string;
742
+ }[] | undefined;
727
743
  style?: string | undefined;
728
744
  initialValue?: string | undefined;
729
745
  hidden?: string | undefined;
@@ -226,6 +226,24 @@ function getFileIcon(filename) {
226
226
  const ext = filename.split(".").pop()?.toLowerCase() ?? "";
227
227
  return FILE_EXTENSION_ICONS[ext] ?? "vscode-icons:default-file";
228
228
  }
229
+ const MIME_TO_ICON = {
230
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "vscode-icons:file-type-excel",
231
+ "application/vnd.ms-excel": "vscode-icons:file-type-excel",
232
+ "application/pdf": "vscode-icons:file-type-pdf2",
233
+ "application/msword": "vscode-icons:file-type-word",
234
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "vscode-icons:file-type-word",
235
+ "application/vnd.ms-powerpoint": "vscode-icons:file-type-powerpoint",
236
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "vscode-icons:file-type-powerpoint",
237
+ "application/x-zip-compressed": "vscode-icons:file-type-zip",
238
+ "application/zip": "vscode-icons:file-type-zip",
239
+ "image/png": "vscode-icons:file-type-image",
240
+ "image/jpg": "vscode-icons:file-type-image",
241
+ "image/jpeg": "vscode-icons:file-type-image"
242
+ };
243
+ function getUploadTemplateIcon(field) {
244
+ const first = field.accept?.[0];
245
+ return (first && MIME_TO_ICON[first]) ?? "fluent:arrow-download-20-regular";
246
+ }
229
247
  function getUploadAcceptString(field) {
230
248
  if (!field.accept || field.accept.length === 0) {
231
249
  return void 0;
@@ -678,19 +696,6 @@ export {
678
696
  >*</sup>
679
697
  </span>
680
698
  </p>
681
- <button
682
- v-if="field.template"
683
- type="button"
684
- class="inline-flex items-center gap-1 self-start text-sm text-[--el-color-primary] hover:underline disabled:opacity-50"
685
- :disabled="templateDownloading[field.id]"
686
- @click="handleTemplateDownload(field)"
687
- >
688
- <Icon
689
- :icon="templateDownloading[field.id] ? 'svg-spinners:ring-resize' : 'fluent:arrow-download-20-regular'"
690
- class="text-base"
691
- />
692
- {{ t("upload-download-template") }}
693
- </button>
694
699
  <label
695
700
  v-if="getUploadFiles(field).length < getUploadMaxCount(field)"
696
701
  :class="[
@@ -704,6 +709,19 @@ export {
704
709
  :icon="field.icon ?? 'fluent:cloud-arrow-up-20-regular'"
705
710
  class="text-4xl text-zinc-400"
706
711
  />
712
+ <button
713
+ v-if="field.template"
714
+ type="button"
715
+ class="inline-flex items-center gap-1.5 rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-600 transition-colors hover:border-[--el-color-primary] hover:text-[--el-color-primary] disabled:opacity-50"
716
+ :disabled="templateDownloading[field.id]"
717
+ @click.prevent.stop="handleTemplateDownload(field)"
718
+ >
719
+ <Icon
720
+ :icon="templateDownloading[field.id] ? 'svg-spinners:ring-resize' : getUploadTemplateIcon(field)"
721
+ class="text-base"
722
+ />
723
+ {{ getLocalizedText(field.templateName, locale) ?? t("upload-download-template") }}
724
+ </button>
707
725
  <p
708
726
  v-if="field.description"
709
727
  class="text-sm text-zinc-600"
@@ -166,6 +166,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
166
166
  }[] | undefined;
167
167
  maxCount?: string | undefined;
168
168
  template?: string | undefined;
169
+ templateName?: readonly {
170
+ locale: "en" | "ja" | "ko" | "zh";
171
+ message: string;
172
+ }[] | undefined;
169
173
  style?: string | undefined;
170
174
  initialValue?: string | undefined;
171
175
  hidden?: string | undefined;
@@ -354,6 +358,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
354
358
  }[] | undefined;
355
359
  maxCount?: string | undefined;
356
360
  template?: string | undefined;
361
+ templateName?: readonly {
362
+ locale: "en" | "ja" | "ko" | "zh";
363
+ message: string;
364
+ }[] | undefined;
357
365
  style?: string | undefined;
358
366
  initialValue?: string | undefined;
359
367
  hidden?: string | undefined;
@@ -538,6 +546,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
538
546
  }[] | undefined;
539
547
  maxCount?: string | undefined;
540
548
  template?: string | undefined;
549
+ templateName?: readonly {
550
+ locale: "en" | "ja" | "ko" | "zh";
551
+ message: string;
552
+ }[] | undefined;
541
553
  style?: string | undefined;
542
554
  initialValue?: string | undefined;
543
555
  hidden?: string | undefined;
@@ -724,6 +736,10 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
724
736
  }[] | undefined;
725
737
  maxCount?: string | undefined;
726
738
  template?: string | undefined;
739
+ templateName?: readonly {
740
+ locale: "en" | "ja" | "ko" | "zh";
741
+ message: string;
742
+ }[] | undefined;
727
743
  style?: string | undefined;
728
744
  initialValue?: string | undefined;
729
745
  hidden?: string | undefined;
@@ -218,6 +218,15 @@ export declare const UploadFieldC: z.ZodObject<{
218
218
  }, z.core.$strip>>>>;
219
219
  maxCount: z.ZodOptional<z.ZodString>;
220
220
  template: z.ZodOptional<z.ZodString>;
221
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
222
+ locale: z.ZodEnum<{
223
+ en: "en";
224
+ ja: "ja";
225
+ ko: "ko";
226
+ zh: "zh";
227
+ }>;
228
+ message: z.ZodString;
229
+ }, z.core.$strip>>>>;
221
230
  style: z.ZodOptional<z.ZodString>;
222
231
  initialValue: z.ZodOptional<z.ZodString>;
223
232
  hidden: z.ZodOptional<z.ZodString>;
@@ -439,6 +448,15 @@ export declare const FieldC: z.ZodDiscriminatedUnion<[z.ZodObject<{
439
448
  }, z.core.$strip>>>>;
440
449
  maxCount: z.ZodOptional<z.ZodString>;
441
450
  template: z.ZodOptional<z.ZodString>;
451
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
452
+ locale: z.ZodEnum<{
453
+ en: "en";
454
+ ja: "ja";
455
+ ko: "ko";
456
+ zh: "zh";
457
+ }>;
458
+ message: z.ZodString;
459
+ }, z.core.$strip>>>>;
442
460
  style: z.ZodOptional<z.ZodString>;
443
461
  initialValue: z.ZodOptional<z.ZodString>;
444
462
  hidden: z.ZodOptional<z.ZodString>;
@@ -674,6 +692,15 @@ export declare const FieldsBodyC: z.ZodReadonly<z.ZodObject<{
674
692
  }, z.core.$strip>>>>;
675
693
  maxCount: z.ZodOptional<z.ZodString>;
676
694
  template: z.ZodOptional<z.ZodString>;
695
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
696
+ locale: z.ZodEnum<{
697
+ en: "en";
698
+ ja: "ja";
699
+ ko: "ko";
700
+ zh: "zh";
701
+ }>;
702
+ message: z.ZodString;
703
+ }, z.core.$strip>>>>;
677
704
  style: z.ZodOptional<z.ZodString>;
678
705
  initialValue: z.ZodOptional<z.ZodString>;
679
706
  hidden: z.ZodOptional<z.ZodString>;
@@ -903,6 +930,15 @@ export declare const FieldsBodyInputC: z.ZodReadonly<z.ZodObject<{
903
930
  }, z.core.$strip>>>>;
904
931
  maxCount: z.ZodOptional<z.ZodString>;
905
932
  template: z.ZodOptional<z.ZodString>;
933
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
934
+ locale: z.ZodEnum<{
935
+ en: "en";
936
+ ja: "ja";
937
+ ko: "ko";
938
+ zh: "zh";
939
+ }>;
940
+ message: z.ZodString;
941
+ }, z.core.$strip>>>>;
906
942
  style: z.ZodOptional<z.ZodString>;
907
943
  initialValue: z.ZodOptional<z.ZodString>;
908
944
  hidden: z.ZodOptional<z.ZodString>;
@@ -1132,6 +1168,15 @@ export declare const FieldsConfigC: z.ZodReadonly<z.ZodObject<{
1132
1168
  }, z.core.$strip>>>>;
1133
1169
  maxCount: z.ZodOptional<z.ZodString>;
1134
1170
  template: z.ZodOptional<z.ZodString>;
1171
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
1172
+ locale: z.ZodEnum<{
1173
+ en: "en";
1174
+ ja: "ja";
1175
+ ko: "ko";
1176
+ zh: "zh";
1177
+ }>;
1178
+ message: z.ZodString;
1179
+ }, z.core.$strip>>>>;
1135
1180
  style: z.ZodOptional<z.ZodString>;
1136
1181
  initialValue: z.ZodOptional<z.ZodString>;
1137
1182
  hidden: z.ZodOptional<z.ZodString>;
@@ -1363,6 +1408,15 @@ export declare const FieldsConfigInputC: z.ZodReadonly<z.ZodObject<{
1363
1408
  }, z.core.$strip>>>>;
1364
1409
  maxCount: z.ZodOptional<z.ZodString>;
1365
1410
  template: z.ZodOptional<z.ZodString>;
1411
+ templateName: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
1412
+ locale: z.ZodEnum<{
1413
+ en: "en";
1414
+ ja: "ja";
1415
+ ko: "ko";
1416
+ zh: "zh";
1417
+ }>;
1418
+ message: z.ZodString;
1419
+ }, z.core.$strip>>>>;
1366
1420
  style: z.ZodOptional<z.ZodString>;
1367
1421
  initialValue: z.ZodOptional<z.ZodString>;
1368
1422
  hidden: z.ZodOptional<z.ZodString>;
@@ -134,6 +134,7 @@ export const UploadFieldC = z.object({
134
134
  description: localeC.optional().describe("\u4E0A\u4F20\u533A\u57DF\u7684\u63D0\u793A\u6587\u672C\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C\uFF0C\u66FF\u6362\u9ED8\u8BA4\u7684\u300C\u70B9\u51FB\u6216\u62D6\u62FD\u5230\u6B64\u5904\u4E0A\u4F20\u300D"),
135
135
  maxCount: expressionC(["int", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE\u6574\u6570\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u9650\u5236\u6700\u5927\u53EF\u4E0A\u4F20\u6587\u4EF6\u6570\u91CF\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
136
136
  template: expressionC(["File", "dyn"]).optional().describe('\u8FD4\u56DE File \u7684 CEL \u8868\u8FBE\u5F0F\uFF08\u5982 http.post("/url").file()\uFF09\uFF0C\u914D\u7F6E\u540E\u5728\u4E0A\u4F20\u533A\u57DF\u663E\u793A\u300C\u4E0B\u8F7D\u6A21\u677F\u300D\u6309\u94AE'),
137
+ templateName: localeC.optional().describe("\u4E0B\u8F7D\u6A21\u677F\u6309\u94AE\u7684\u672C\u5730\u5316\u663E\u793A\u6587\u672C\uFF0C\u7559\u7A7A\u65F6\u663E\u793A\u9ED8\u8BA4\u6587\u672C\u300C\u4E0B\u8F7D\u6A21\u677F\u300D"),
137
138
  style: z.string().optional().describe("CSS \u6837\u5F0F\u5BF9\u8C61\u8868\u8FBE\u5F0F\uFF0C\u63A7\u5236\u5B57\u6BB5\u7684\u5E03\u5C40\u4E0E\u5916\u89C2"),
138
139
  initialValue: expressionC(["list(dyn)", "dyn"], inheritedFieldContext).optional().describe("\u8FD4\u56DE\u6570\u7EC4\u7684 CEL \u8868\u8FBE\u5F0F\uFF0C\u5728\u5B57\u6BB5\u9996\u6B21\u521D\u59CB\u5316\u4E14 path \u4E0D\u5B58\u5728\u65F6\u5199\u5165\u521D\u59CB\u503C\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
139
140
  hidden: expressionC(["bool", "dyn"], inheritedFieldContext).optional().describe("\u4E3A true \u65F6\uFF0C\u9690\u85CF\u8FD9\u4E2A\u5B57\u6BB5\uFF0C\u53EF\u4F7F\u7528 form\u3001row\u3001index \u548C id \u53D8\u91CF"),
@@ -167,6 +167,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
167
167
  }[] | undefined;
168
168
  maxCount?: string | undefined;
169
169
  template?: string | undefined;
170
+ templateName?: readonly {
171
+ locale: "en" | "ja" | "ko" | "zh";
172
+ message: string;
173
+ }[] | undefined;
170
174
  style?: string | undefined;
171
175
  initialValue?: string | undefined;
172
176
  hidden?: string | undefined;
@@ -351,6 +355,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
351
355
  }[] | undefined;
352
356
  maxCount?: string | undefined;
353
357
  template?: string | undefined;
358
+ templateName?: readonly {
359
+ locale: "en" | "ja" | "ko" | "zh";
360
+ message: string;
361
+ }[] | undefined;
354
362
  style?: string | undefined;
355
363
  initialValue?: string | undefined;
356
364
  hidden?: string | undefined;
@@ -23,10 +23,10 @@ import { cn } from "../../../utils/cn";
23
23
  import { Button } from "../button";
24
24
  import {
25
25
  Dialog,
26
- DialogContent,
27
26
  DialogDescription,
28
27
  DialogFooter,
29
28
  DialogHeader,
29
+ DialogScrollContent,
30
30
  DialogTitle
31
31
  } from "../dialog";
32
32
  import {
@@ -908,6 +908,22 @@ function updateSelectedUploadDescription(value) {
908
908
  };
909
909
  });
910
910
  }
911
+ function updateSelectedUploadTemplateName(value) {
912
+ const selected = selectedField.value;
913
+ if (!selected || selected.field.type !== "upload") {
914
+ return;
915
+ }
916
+ clearFieldError(selected.draftId, "templateName");
917
+ updateDraftField(selected.draftId, (field) => {
918
+ if (field.type !== "upload") {
919
+ return field;
920
+ }
921
+ return {
922
+ ...field,
923
+ templateName: value
924
+ };
925
+ });
926
+ }
911
927
  function updateSelectedUploadMaxCount(value) {
912
928
  const selected = selectedField.value;
913
929
  if (!selected || selected.field.type !== "upload") {
@@ -1451,7 +1467,7 @@ function confirmChanges() {
1451
1467
  :open="open"
1452
1468
  @update:open="handleOpenChange"
1453
1469
  >
1454
- <DialogContent
1470
+ <DialogScrollContent
1455
1471
  class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
1456
1472
  :show-close-button="true"
1457
1473
  >
@@ -2335,6 +2351,17 @@ function confirmChanges() {
2335
2351
  {{ validationErrors[getFieldErrorKey(selectedField.draftId, "template")] }}
2336
2352
  </p>
2337
2353
  </label>
2354
+
2355
+ <div class="flex flex-col gap-2 md:col-span-2">
2356
+ <span class="text-xs font-medium text-zinc-500">
2357
+ {{ t("field-upload-template-name") }}
2358
+ </span>
2359
+ <Locale
2360
+ data-slot="fields-configurator-field-upload-template-name-locale"
2361
+ :model-value="selectedField.field.templateName"
2362
+ @update:model-value="updateSelectedUploadTemplateName"
2363
+ />
2364
+ </div>
2338
2365
  </section>
2339
2366
 
2340
2367
  <section
@@ -2515,7 +2542,7 @@ function confirmChanges() {
2515
2542
  </Button>
2516
2543
  </div>
2517
2544
  </DialogFooter>
2518
- </DialogContent>
2545
+ </DialogScrollContent>
2519
2546
  </Dialog>
2520
2547
  </template>
2521
2548
 
@@ -2621,6 +2648,7 @@ function confirmChanges() {
2621
2648
  "field-upload-max-count-placeholder": "例如 5",
2622
2649
  "field-upload-template": "下载模板表达式",
2623
2650
  "field-upload-template-placeholder": "例如 http.post(\"/api/v1/example/download_template\").file()",
2651
+ "field-upload-template-name": "下载模板按钮名称",
2624
2652
  "field-validation": "校验规则",
2625
2653
  "field-validation-description": "字段失焦时按顺序执行,命中第一个失败规则后停止。",
2626
2654
  "add-validation-rule": "新增规则",
@@ -2740,6 +2768,7 @@ function confirmChanges() {
2740
2768
  "field-upload-max-count-placeholder": "例: 5",
2741
2769
  "field-upload-template": "テンプレートダウンロード式",
2742
2770
  "field-upload-template-placeholder": "例: http.post(\"/api/v1/example/download_template\").file()",
2771
+ "field-upload-template-name": "テンプレートボタン名",
2743
2772
  "field-validation": "検証ルール",
2744
2773
  "field-validation-description": "フォーカスを外したときに順番に評価し、最初の失敗で停止します。",
2745
2774
  "add-validation-rule": "ルールを追加",
@@ -2859,6 +2888,7 @@ function confirmChanges() {
2859
2888
  "field-upload-max-count-placeholder": "For example 5",
2860
2889
  "field-upload-template": "Template download expression",
2861
2890
  "field-upload-template-placeholder": "e.g. http.post(\"/api/v1/example/download_template\").file()",
2891
+ "field-upload-template-name": "Template button name",
2862
2892
  "field-validation": "Validation rules",
2863
2893
  "field-validation-description": "Rules run on blur in order and stop at the first failure.",
2864
2894
  "add-validation-rule": "Add rule",
@@ -167,6 +167,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
167
167
  }[] | undefined;
168
168
  maxCount?: string | undefined;
169
169
  template?: string | undefined;
170
+ templateName?: readonly {
171
+ locale: "en" | "ja" | "ko" | "zh";
172
+ message: string;
173
+ }[] | undefined;
170
174
  style?: string | undefined;
171
175
  initialValue?: string | undefined;
172
176
  hidden?: string | undefined;
@@ -351,6 +355,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
351
355
  }[] | undefined;
352
356
  maxCount?: string | undefined;
353
357
  template?: string | undefined;
358
+ templateName?: readonly {
359
+ locale: "en" | "ja" | "ko" | "zh";
360
+ message: string;
361
+ }[] | undefined;
354
362
  style?: string | undefined;
355
363
  initialValue?: string | undefined;
356
364
  hidden?: string | undefined;
@@ -7,10 +7,10 @@ import { cn } from "../../../utils/cn";
7
7
  import { Button } from "../button";
8
8
  import {
9
9
  Dialog,
10
- DialogContent,
11
10
  DialogDescription,
12
11
  DialogFooter,
13
12
  DialogHeader,
13
+ DialogScrollContent,
14
14
  DialogTitle
15
15
  } from "../dialog";
16
16
  import { ExpressionEditor } from "../expression-editor";
@@ -258,7 +258,7 @@ watch(normalizedSearch, async () => {
258
258
  :open="open"
259
259
  @update:open="open = $event"
260
260
  >
261
- <DialogContent
261
+ <DialogScrollContent
262
262
  data-slot="menu-tabs-configurator-dialog"
263
263
  class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
264
264
  >
@@ -419,7 +419,7 @@ watch(normalizedSearch, async () => {
419
419
  {{ t("confirm") }}
420
420
  </Button>
421
421
  </DialogFooter>
422
- </DialogContent>
422
+ </DialogScrollContent>
423
423
  </Dialog>
424
424
  </template>
425
425
 
@@ -13,10 +13,10 @@ import { Button } from "../button";
13
13
  import { Checkbox } from "../checkbox";
14
14
  import {
15
15
  Dialog,
16
- DialogContent,
17
16
  DialogDescription,
18
17
  DialogFooter,
19
18
  DialogHeader,
19
+ DialogScrollContent,
20
20
  DialogTitle
21
21
  } from "../dialog";
22
22
  import { Input } from "../input";
@@ -1625,7 +1625,7 @@ function confirmChanges() {
1625
1625
  :open="open"
1626
1626
  @update:open="handleOpenChange"
1627
1627
  >
1628
- <DialogContent
1628
+ <DialogScrollContent
1629
1629
  class="flex h-[min(42rem,calc(100vh-4rem))] w-[calc(100%-2rem)] max-h-[calc(100vh-4rem)] max-w-[calc(100%-2rem)] flex-col overflow-hidden p-0 sm:w-[80vw] sm:max-w-[80vw]"
1630
1630
  :show-close-button="true"
1631
1631
  @pointer-down-outside="(event) => event.preventDefault()"
@@ -2437,7 +2437,7 @@ function confirmChanges() {
2437
2437
  </Button>
2438
2438
  </div>
2439
2439
  </DialogFooter>
2440
- </DialogContent>
2440
+ </DialogScrollContent>
2441
2441
  </Dialog>
2442
2442
  </template>
2443
2443
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
- "version": "0.11.36",
3
+ "version": "0.11.37",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",