nuxt-hs-ui 2.12.7 → 4.0.0

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.
Files changed (131) hide show
  1. package/README.md +202 -14
  2. package/dist/module.d.mts +3 -4
  3. package/dist/module.json +9 -6
  4. package/dist/module.mjs +109 -99
  5. package/dist/runtime/assets/flatpickr-dark.css +1 -1
  6. package/dist/runtime/assets/main.css +1 -0
  7. package/dist/runtime/assets/tabulator-custom.css +1 -1
  8. package/dist/runtime/components/form/_select/hidden-item-toggle.vue +28 -0
  9. package/dist/runtime/components/form/_select/hidden-item-toggle.vue.d.ts +10 -0
  10. package/dist/runtime/components/form/_select/item-container.vue +63 -0
  11. package/dist/runtime/components/form/_select/item-container.vue.d.ts +19 -0
  12. package/dist/runtime/components/form/_select/item-label.vue +31 -0
  13. package/dist/runtime/components/form/_select/item-label.vue.d.ts +13 -0
  14. package/dist/runtime/components/form/_select/item-row.vue +62 -0
  15. package/dist/runtime/components/form/_select/item-row.vue.d.ts +34 -0
  16. package/dist/runtime/components/form/btn-line-loading.vue +62 -81
  17. package/dist/runtime/components/form/btn-line-loading.vue.d.ts +14 -0
  18. package/dist/runtime/components/form/btn.vue +411 -494
  19. package/dist/runtime/components/form/btn.vue.d.ts +0 -0
  20. package/dist/runtime/components/form/check-box.vue +200 -315
  21. package/dist/runtime/components/form/check-box.vue.d.ts +71 -0
  22. package/dist/runtime/components/form/check-list.vue +234 -364
  23. package/dist/runtime/components/form/check-list.vue.d.ts +99 -0
  24. package/dist/runtime/components/form/combo-box.vue +340 -0
  25. package/dist/runtime/components/form/combo-box.vue.d.ts +69 -0
  26. package/dist/runtime/components/form/datepicker.vue +717 -883
  27. package/dist/runtime/components/form/datepicker.vue.d.ts +122 -0
  28. package/dist/runtime/components/form/input-frame.vue +174 -258
  29. package/dist/runtime/components/form/input-frame.vue.d.ts +88 -0
  30. package/dist/runtime/components/form/radio.vue +451 -614
  31. package/dist/runtime/components/form/radio.vue.d.ts +62 -0
  32. package/dist/runtime/components/form/select-img-icon.vue +38 -53
  33. package/dist/runtime/components/form/select-img-icon.vue.d.ts +15 -0
  34. package/dist/runtime/components/form/select.vue +733 -579
  35. package/dist/runtime/components/form/select.vue.d.ts +63 -0
  36. package/dist/runtime/components/form/text-box.vue +266 -365
  37. package/dist/runtime/components/form/text-box.vue.d.ts +105 -0
  38. package/dist/runtime/components/form/textarea.vue +338 -421
  39. package/dist/runtime/components/form/textarea.vue.d.ts +98 -0
  40. package/dist/runtime/components/form/value-box.vue +512 -641
  41. package/dist/runtime/components/form/value-box.vue.d.ts +128 -0
  42. package/dist/runtime/components/interactive/alert.vue +49 -113
  43. package/dist/runtime/components/interactive/alert.vue.d.ts +30 -0
  44. package/dist/runtime/components/interactive/block-loading.vue +91 -119
  45. package/dist/runtime/components/interactive/block-loading.vue.d.ts +22 -0
  46. package/dist/runtime/components/interactive/dialog.vue +252 -407
  47. package/dist/runtime/components/interactive/dialog.vue.d.ts +3 -0
  48. package/dist/runtime/components/interactive/modal-bg.vue +72 -82
  49. package/dist/runtime/components/interactive/modal-bg.vue.d.ts +11 -0
  50. package/dist/runtime/components/interactive/modal.vue +121 -169
  51. package/dist/runtime/components/interactive/modal.vue.d.ts +38 -0
  52. package/dist/runtime/components/interactive/toast.vue +164 -206
  53. package/dist/runtime/components/interactive/toast.vue.d.ts +3 -0
  54. package/dist/runtime/components/interactive/window-loader.vue +61 -84
  55. package/dist/runtime/components/interactive/window-loader.vue.d.ts +3 -0
  56. package/dist/runtime/components/layout/accordion-down.vue +72 -0
  57. package/dist/runtime/components/layout/accordion-down.vue.d.ts +26 -0
  58. package/dist/runtime/components/layout/accordion.vue +47 -78
  59. package/dist/runtime/components/layout/accordion.vue.d.ts +22 -0
  60. package/dist/runtime/components/layout/aspect-box.vue +29 -58
  61. package/dist/runtime/components/layout/aspect-box.vue.d.ts +29 -0
  62. package/dist/runtime/components/layout/card-item.vue +148 -193
  63. package/dist/runtime/components/layout/card-item.vue.d.ts +0 -0
  64. package/dist/runtime/components/layout/card.vue +27 -42
  65. package/dist/runtime/components/layout/card.vue.d.ts +23 -0
  66. package/dist/runtime/components/layout/container.vue +25 -40
  67. package/dist/runtime/components/layout/container.vue.d.ts +35 -0
  68. package/dist/runtime/components/layout/divider-h.vue +30 -50
  69. package/dist/runtime/components/layout/divider-h.vue.d.ts +18 -0
  70. package/dist/runtime/components/misc/breadcrumb.vue +47 -95
  71. package/dist/runtime/components/misc/breadcrumb.vue.d.ts +22 -0
  72. package/dist/runtime/components/misc/tabulator.vue +122 -190
  73. package/dist/runtime/components/misc/tabulator.vue.d.ts +28 -0
  74. package/dist/runtime/components/misc/view-name-display.vue +53 -68
  75. package/dist/runtime/components/misc/view-name-display.vue.d.ts +14 -0
  76. package/dist/runtime/components/test.vue +13 -0
  77. package/dist/runtime/components/test.vue.d.ts +3 -0
  78. package/dist/runtime/composables/test.d.ts +8 -0
  79. package/dist/runtime/composables/test.js +12 -0
  80. package/dist/runtime/composables/use-hs-dialog.d.ts +3 -20
  81. package/dist/runtime/composables/use-hs-dialog.js +3 -9
  82. package/dist/runtime/composables/use-hs-is-mobile.d.ts +8 -2
  83. package/dist/runtime/composables/use-hs-is-mobile.js +43 -25
  84. package/dist/runtime/composables/use-hs-misc.d.ts +8 -38
  85. package/dist/runtime/composables/use-hs-misc.js +9 -61
  86. package/dist/runtime/composables/use-hs-modal.js +1 -3
  87. package/dist/runtime/composables/use-hs-multi-lang.d.ts +23 -40
  88. package/dist/runtime/composables/use-hs-multi-lang.js +30 -74
  89. package/dist/runtime/composables/use-hs-scroll-lock.d.ts +1 -1
  90. package/dist/runtime/composables/use-hs-scroll-lock.js +2 -1
  91. package/dist/runtime/composables/use-hs-toast.d.ts +2 -2
  92. package/dist/runtime/composables/use-hs-toast.js +12 -4
  93. package/dist/runtime/composables/use-pinia.d.ts +1 -0
  94. package/dist/runtime/composables/use-pinia.js +2 -0
  95. package/dist/runtime/plugin.d.ts +2 -0
  96. package/dist/runtime/plugin.js +4 -0
  97. package/dist/runtime/server/tsconfig.json +3 -3
  98. package/dist/runtime/types/dialog.d.ts +11 -20
  99. package/dist/runtime/types/dialog.js +2 -1
  100. package/dist/runtime/types/flatpickr/default.js +2 -23
  101. package/dist/runtime/types/flatpickr/ja.js +3 -37
  102. package/dist/runtime/types/toast.d.ts +1 -1
  103. package/dist/runtime/utils/dayjs.d.ts +8 -6
  104. package/dist/runtime/utils/dayjs.js +12 -5
  105. package/dist/runtime/utils/modal.d.ts +9 -28
  106. package/dist/runtime/utils/modal.js +7 -36
  107. package/dist/runtime/utils/multi-lang-object.d.ts +2 -2
  108. package/dist/runtime/utils/multi-lang-object.js +1 -5
  109. package/dist/runtime/utils/multi-lang.js +12 -22
  110. package/dist/runtime/utils/object.js +1 -1
  111. package/dist/runtime/utils/select-item.d.ts +3 -1
  112. package/dist/runtime/utils/stop-watch.js +6 -4
  113. package/dist/runtime/utils/string.js +4 -4
  114. package/dist/runtime/utils/tabulator.d.ts +1 -42
  115. package/dist/runtime/utils/tabulator.js +2 -99
  116. package/dist/runtime/utils/theme.d.ts +20 -20
  117. package/dist/runtime/utils/theme.js +180 -30
  118. package/dist/runtime/utils/tv.d.ts +1 -101
  119. package/dist/runtime/utils/tv.js +0 -22
  120. package/dist/types.d.mts +3 -1
  121. package/package.json +61 -119
  122. package/dist/module.cjs +0 -5
  123. package/dist/module.d.ts +0 -16
  124. package/dist/runtime/assets/vue-select.css +0 -1
  125. package/dist/runtime/components/misc/view-name-display-target.vue +0 -39
  126. package/dist/runtime/plugin/v-select.d.ts +0 -2
  127. package/dist/runtime/plugin/v-select.js +0 -5
  128. package/dist/runtime/style.css +0 -22
  129. package/dist/runtime/tailwind.css +0 -78
  130. package/dist/runtime/types/app.config.d.ts +0 -5
  131. package/dist/types.d.ts +0 -1
@@ -1,427 +1,338 @@
1
- <script setup lang="ts">
2
- /* ----------------------------------------------------------------------------
3
- // src\runtime\components\form\textarea.vue
4
- // ----------------------------------------------------------------------------
5
- // Textarea
6
- // TextareaTextarea
7
- ----------------------------------------------------------------------------- */
8
-
9
- // [ tailwind ]
10
- import { twMerge } from "tailwind-merge";
11
- // [ NUXT ]
12
- import { reactive, ref, watch, computed, useId, nextTick } from "#imports";
13
- // [ utils ]
14
- import type { ClassType } from "../../utils/class-style";
15
- import type { MultiLang } from "../../utils/multi-lang";
16
- // [ composables ]
17
- import { useHsFocus } from "../../composables/use-hs-focus";
18
- import { useHsMisc } from "../../composables/use-hs-misc";
19
- import { useHsMultiLang } from "../../composables/use-hs-multi-lang";
20
- // [ Components ]
21
- import InputFrame from "./input-frame.vue";
22
- // ----------------------------------------------------------------------------
23
- const hsFocus = useHsFocus();
24
- const hsMisc = useHsMisc();
25
- // ----------------------------------------------------------------------------
26
- // [ Props ]
27
- type Props = {
28
- // ----------------------------------------------------------------------------
29
- // Input 種類別
30
- rows?: number;
31
- maxRows?: number;
32
- maxLen?: number;
33
- autosize?: boolean;
34
- // ----------------------------------------------------------------------------
35
- data: string | null;
36
- diff?: string | null | undefined;
37
- tabindex?: string | undefined;
38
- // ----------------------------------------------------------------------------
39
- class?: ClassType;
40
- classHeader?: ClassType;
41
- classInput?: ClassType;
42
- // ----------------------------------------------------------------------------
43
- // 状態
44
- // focus?: boolean;
45
- focusColor?: string;
46
- // change?: boolean;
47
- changeColor?: string;
48
- error?: boolean;
49
- errorColor?: string;
50
- disabled?: boolean;
51
- disabledColor?: string;
52
- readonly?: boolean;
53
- headerless?: boolean;
54
- // ----------------------------------------------------------------------------
55
- // 表示
56
- label?: MultiLang;
57
- // 表示-副情報
58
- require?: boolean;
59
- requireText?: MultiLang;
60
- warn?: string;
61
- warnTimeOut?: number;
62
- // ----------------------------------------------------------------------------
63
- // 設定
64
- size?: "s" | "m" | "l";
65
- // ----------------------------------------------------------------------------
66
- uiText?: {
67
- rowsUnit: MultiLang;
68
- };
69
- };
70
- const props = withDefaults(defineProps<Props>(), {
71
- // ----------------------------------------------------------------------------
72
- // Input 種類別
73
- rows: 5,
74
- maxRows: 0,
75
- maxLen: 0,
76
- autosize: false,
77
- // ----------------------------------------------------------------------------
78
- diff: undefined,
79
- tabindex: undefined,
80
- // ----------------------------------------------------------------------------
81
- class: "",
82
- classHeader: "",
83
- classInput: "",
84
- // ----------------------------------------------------------------------------
85
- // 状態
86
- // focus: false,
87
- focusColor: "shadow-[inset_0px_0px_1px_2px_#0d8ee4]",
88
- // change: false,
89
- changeColor: "shadow-[inset_0px_0px_1px_2px_#fd9831be]",
90
- error: false,
91
- errorColor: "shadow-[inset_0px_0px_1px_2px_#d80000dc]",
92
- disabled: false,
93
- disabledColor: "",
94
- readonly: false,
95
- headerless: false,
96
- // ----------------------------------------------------------------------------
97
- // 表示
98
- label: "",
99
- // 表示-副情報
100
- require: false,
101
- requireText: () => ({ ja: "必須", en: "Required" }),
102
- warn: "",
103
- warnTimeOut: 3000,
104
- // ----------------------------------------------------------------------------
105
- // 設定
106
- size: "m",
107
- // ----------------------------------------------------------------------------
108
- uiText: () => {
109
- return {
110
- rowsUnit: { ja: "行", en: "Rows" },
111
- };
112
- },
113
- });
114
- // ----------------------------------------------------------------------------
115
- // [ emit ]
116
- type Emits = {
117
- ref: [element: HTMLElement];
118
- focus: [elm: HTMLElement];
119
- blur: [elm: HTMLElement];
120
- // ----------------------------
121
- "update:data": [value: string];
122
- "value-change": [after: string, before: string | null];
123
- // ----------------------------
124
- keydown: [event: KeyboardEvent];
125
- keyup: [event: KeyboardEvent];
126
- // ----------------------------
127
- };
128
- const emit = defineEmits<Emits>();
129
- // ----------------------------------------------------------------------------
130
-
131
- const multiLang = useHsMultiLang();
132
- const tx = multiLang.tx;
133
-
134
- // [ getCurrentInstance ]
135
-
136
- const uid = useId();
137
- // ----------------------------------------------------------------------------
138
-
139
- // [ reactive ]
140
- interface State {
141
- value: string;
142
- }
143
- const state = reactive<State>({
144
- value: "",
145
- });
146
-
147
- // ----------------------------------------------------------------------------
148
- watch(
149
- () => props.data,
150
- () => {
151
- setValue(props.data);
152
- }
153
- );
154
-
155
- const CutLen = (text: string, len: number, addWard = "") => {
156
- if (text === null) return "";
157
- if (len === 0) return text;
158
- return text.substring(0, len) + addWard;
159
- };
160
- const getCheckedText = (text: string) => {
161
- // 各行を配列の要素に分ける
162
- let ret = text;
163
- if (props.maxRows !== 0) {
164
- const lines = text.split("\n");
165
- let amari = "";
166
- // 入力行数が制限を超えた場合
167
- if (lines.length > props.maxRows) {
168
- const result = [];
169
- for (let i = 0; i < lines.length; i++) {
170
- if (i < props.maxRows) {
171
- result.push(lines[i]);
172
- } else {
173
- amari += lines[i].replace(/\n/g, "");
174
- }
175
- }
176
- ret = result.join("\n") + amari;
177
- }
178
- }
179
- if (props.maxLen !== 0 || ret.length > props.maxLen) {
180
- ret = CutLen(ret, props.maxLen, "");
181
- }
182
- return ret;
183
- };
184
-
185
- const setValue = (text: string | null) => {
186
- if (text === null) {
187
- state.value = "";
188
- return;
189
- }
190
- const lineCheckedText = getCheckedText(text);
191
- if (lineCheckedText === text) {
192
- state.value = text;
193
- } else {
194
- // 文字数のオーバーフロー確定
195
- // 親コンポーネントへの更新処理に移動
196
- updateValue(text);
197
- }
198
- };
199
- setValue(props.data);
200
-
201
- // 更新を親コンポーネントに伝える
202
- const updateValue = async (text: string | null) => {
203
- const before = props.data;
204
- let setText = "";
205
- if (text === null) {
206
- setText = "";
207
- } else {
208
- // 各行を配列の要素に分ける
209
- setText = getCheckedText(text);
210
- }
211
- state.value = setText;
212
- emit("update:data", setText);
213
- await nextTick();
214
- emit("value-change", setText, before);
215
- };
216
-
217
- // [ ref ]
218
- const inputElement = ref();
219
-
220
- const setRef = (elm: any) => {
221
- inputElement.value = elm;
222
- emit("ref", elm as HTMLInputElement);
223
- };
224
-
225
- /**
226
- * 強制focus
227
- */
228
- const elmFocus = () => {
229
- inputElement.value.focus();
230
- };
231
-
232
- // [ focus, blur ]
233
-
234
- interface FocusState {
235
- isActivate: boolean;
236
- isMmousedown: boolean;
237
- }
238
-
239
- const focusState = reactive<FocusState>({
240
- isActivate: false,
241
- isMmousedown: false,
242
- });
243
-
244
- /**
245
- * コントロールのFocus判定
246
- */
247
- const computedActivate = computed(() => {
248
- if (props.disabled === true) return false;
249
- if (props.readonly === true) return false;
250
- if (hsFocus.state.id !== uid) return false;
251
- if (focusState.isActivate) return true;
252
- if (focusState.isMmousedown) return true;
253
- return false;
254
- });
255
-
256
- /**
257
- * focus, blur イベント
258
- */
259
- watch(computedActivate, (value) => {
260
- if (value === true) {
261
- // クリックでの遷移の場合に
262
- // 一つ前のコントロールのblurイベントよりも早くfocusが発生しないようにする対策で10ミリ秒処理をずらす
263
- setTimeout(() => {
264
- emit("focus", inputElement.value);
265
- }, 10);
266
- } else {
267
- emit("blur", inputElement.value);
268
- }
269
- });
270
-
271
- const onMousedown = () => {
272
- focusState.isMmousedown = true;
273
- };
274
- const onMouseup = () => {
275
- elmFocus();
276
- focusState.isMmousedown = false;
277
- };
278
-
279
- const onFocus = () => {
280
- if (props.disabled === true) return;
281
- if (props.readonly === true) return;
282
- focusState.isActivate = true;
283
- hsFocus.state.id = uid;
284
- };
285
- const onBlur = () => {
286
- focusState.isActivate = false;
287
- };
288
-
289
- // [ baseClass ]
290
- const tabindex = computed(() => {
291
- if (props.disabled === true) return -1;
292
- if (props.readonly === true) return -1;
293
- return props.tabindex;
294
- });
295
-
296
- // 更新の有無確認
297
- const isChangeData = computed(() => {
298
- if (props.diff === undefined) return false;
299
- if (props.diff === null && props.data === "") return false;
300
- if (props.diff === "" && props.data === null) return false;
301
- if (props.diff !== props.data) return true;
302
- return false;
303
- });
304
- // ---------------------------------------------------------------------------------
305
- // ----------------------------------------------------------------------------
306
- const lenLabelClass = computed(() => {
307
- const last = props.maxLen - state.value.length;
308
- return [
309
- twMerge(
310
- "text-white bg-[#2fa412]",
311
- last < 6 ? "bg-[#fdc90d]" : "",
312
- last < 5 ? "bg-[#fd750d]" : "",
313
- last < 2 ? "bg-[#fa541d]" : ""
314
- ),
315
- ];
316
- });
317
- const rowLabelClass = computed(() => {
318
- const last = props.maxRows - state.value.split("\n").length;
319
- return [
320
- twMerge(
321
- "text-white bg-[#2fa412]",
322
- last < 9 ? "bg-[#fdc90d]" : "",
323
- last < 6 ? "bg-[#fd750d]" : "",
324
- last < 3 ? "bg-[#fa541d]" : ""
325
- ),
326
- ];
327
- });
328
-
329
- const textAreaFrameClass = computed(() => {
330
- return [
331
- twMerge(),
332
- //
333
- "bg-transparent",
334
- "flex flex-row items-center justify-center",
335
- "h-full w-full",
336
- ];
337
- });
338
- const textAreaClass = computed(() => {
339
- return [
340
- twMerge(
341
- //
342
- "flex-1",
343
- "!leading-[1.2em]",
344
- "bg-transparent",
345
- "mt-[1px]",
346
- "min-h-full min-w-full"
347
- ),
348
- ];
349
- });
350
-
351
- const _rows = computed(() => {
352
- if (!props.autosize) return props.rows;
353
- return Math.max(state.value.split("\n").length, props.rows);
354
- });
355
- </script>
356
-
357
- <template>
358
- <InputFrame
359
- :class="['h-auto', props.class]"
360
- :class-header="props.classHeader"
361
- :class-input="['flex-1', props.classInput]"
362
- :focus="computedActivate"
363
- :focus-color="props.focusColor"
364
- :change="isChangeData"
365
- :change-color="props.changeColor"
366
- :error="props.error"
367
- :error-color="props.errorColor"
368
- :disabled="props.disabled"
369
- :disabled-color="props.disabledColor"
370
- :readonly="props.readonly"
371
- :label="props.label"
372
- :require="props.require"
373
- :require-text="props.requireText"
374
- :warn="props.warn"
375
- :warn-time-out="props.warnTimeOut"
376
- :size="props.size"
377
- :headerless="props.headerless"
378
- @click="elmFocus"
379
- >
380
- <template v-if="$slots.label" #label>
381
- <slot name="label"></slot>
382
- </template>
383
- <template
384
- v-if="props.maxLen > 0 || props.maxRows > 0"
385
- #header-right="{ defaultClass }"
386
- >
387
- <div v-if="props.maxLen !== 0" :class="[defaultClass, lenLabelClass]">
388
- {{ state.value.length }} / {{ props.maxLen }}
389
- </div>
390
- <div v-if="props.maxRows !== 0" :class="[defaultClass, rowLabelClass]">
391
- {{ state.value.split("\n").length }} / {{ props.maxRows }}
392
- {{ tx(props.uiText.rowsUnit) }}
393
- </div>
394
- </template>
395
- <div
396
- class="nac-c-input-box"
397
- :class="[textAreaFrameClass, { isMobile: hsMisc.state.isMobile }]"
398
- >
399
- <textarea
400
- :ref="(e) => setRef(e)"
401
- v-model="state.value"
402
- type="text"
403
- :class="textAreaClass"
404
- :rows="_rows"
405
- :disabled="props.disabled || props.readonly"
406
- :tabindex="tabindex"
407
- @blur="onBlur()"
408
- @focus="onFocus()"
409
- @mousedown="onMousedown"
410
- @mouseup="onMouseup"
411
- @input="updateValue(state.value)"
412
- @keydown="(e: KeyboardEvent) => emit('keydown', e)"
413
- @keyup="(e: KeyboardEvent) => emit('keyup', e)"
414
- ></textarea>
415
- </div>
416
- </InputFrame>
417
- </template>
418
-
1
+ <script setup>
2
+ import { twMerge } from "tailwind-merge";
3
+ import { reactive, ref, watch, computed, useId, nextTick, onMounted } from "#imports";
4
+ import { Int } from "../../utils/number";
5
+ import { useHsFocus } from "../../composables/use-hs-focus";
6
+ import { useHsMultiLang } from "../../composables/use-hs-multi-lang";
7
+ import { useHsPinia } from "../../composables/use-pinia";
8
+ import { useHsIsMobile } from "../../composables/use-hs-is-mobile";
9
+ import { useHsMisc } from "../../composables/use-hs-misc";
10
+ import InputFrame from "./input-frame.vue";
11
+ const hsFocus = useHsFocus(useHsPinia());
12
+ const hsMisc = useHsMisc(useHsPinia());
13
+ const hsIsMobile = useHsIsMobile(useHsPinia());
14
+ onMounted(() => {
15
+ hsIsMobile.init();
16
+ });
17
+ const props = defineProps({
18
+ rows: { type: [Number, String], required: false, default: 3 },
19
+ maxRows: { type: Number, required: false, default: 0 },
20
+ maxLen: { type: Number, required: false, default: 0 },
21
+ autosize: { type: Boolean, required: false, default: false },
22
+ placeholder: { type: [String, Object], required: false, default: "" },
23
+ data: { type: [String, null], required: true },
24
+ diff: { type: null, required: false, default: void 0 },
25
+ tabindex: { type: null, required: false, default: void 0 },
26
+ class: { type: [String, Object, Array], required: false, default: "" },
27
+ classHeader: { type: [String, Object, Array], required: false, default: "" },
28
+ classInput: { type: [String, Object, Array], required: false, default: "" },
29
+ focusColor: { type: String, required: false, default: "shadow-[inset_0px_0px_1px_2px_#0d8ee4]" },
30
+ changeColor: { type: String, required: false, default: "shadow-[inset_0px_0px_1px_2px_#fd9831be]" },
31
+ error: { type: Boolean, required: false, default: false },
32
+ errorColor: { type: String, required: false, default: "shadow-[inset_0px_0px_1px_2px_#d80000dc]" },
33
+ disabled: { type: Boolean, required: false, default: false },
34
+ disabledColor: { type: String, required: false, default: "" },
35
+ readonly: { type: Boolean, required: false, default: false },
36
+ headerless: { type: Boolean, required: false, default: false },
37
+ label: { type: [String, Object], required: false, default: "" },
38
+ require: { type: Boolean, required: false, default: false },
39
+ requireText: { type: [String, Object], required: false, default: () => ({ ja: "\u5FC5\u9808", en: "Required" }) },
40
+ warn: { type: String, required: false, default: "" },
41
+ warnTimeOut: { type: Number, required: false, default: 3e3 },
42
+ size: { type: String, required: false, default: "m" },
43
+ uiText: { type: Object, required: false, default: () => {
44
+ return {
45
+ rowsUnit: { ja: "\u884C", en: "Rows" }
46
+ };
47
+ } }
48
+ });
49
+ const emit = defineEmits(["ref", "focus", "blur", "update:data", "value-change", "keydown", "keyup"]);
50
+ const slots = defineSlots();
51
+ const multiLang = useHsMultiLang(useHsPinia());
52
+ const tx = multiLang.tx;
53
+ const uid = useId();
54
+ const state = reactive({
55
+ value: ""
56
+ });
57
+ watch(
58
+ () => props.data,
59
+ () => {
60
+ setValue(props.data);
61
+ }
62
+ );
63
+ const CutLen = (text, len, addWard = "") => {
64
+ if (text === null) return "";
65
+ if (len === 0) return text;
66
+ return text.substring(0, len) + addWard;
67
+ };
68
+ const getCheckedText = (text) => {
69
+ let ret = text;
70
+ if (props.maxRows !== 0) {
71
+ const lines = text.split("\n");
72
+ let amari = "";
73
+ if (lines.length > props.maxRows) {
74
+ const result = [];
75
+ for (let i = 0; i < lines.length; i++) {
76
+ if (i < props.maxRows) {
77
+ result.push(lines[i]);
78
+ } else {
79
+ amari += lines[i]?.replace(/\n/g, "");
80
+ }
81
+ }
82
+ ret = result.join("\n") + amari;
83
+ }
84
+ }
85
+ if (props.maxLen !== 0 || ret.length > props.maxLen) {
86
+ ret = CutLen(ret, props.maxLen, "");
87
+ }
88
+ return ret;
89
+ };
90
+ const setValue = (text) => {
91
+ if (text === null) {
92
+ state.value = "";
93
+ return;
94
+ }
95
+ const lineCheckedText = getCheckedText(text);
96
+ if (lineCheckedText === text) {
97
+ state.value = text;
98
+ } else {
99
+ updateValue(text);
100
+ }
101
+ };
102
+ setValue(props.data);
103
+ const updateValue = async (text) => {
104
+ const before = props.data;
105
+ let setText = "";
106
+ if (text === null) {
107
+ setText = "";
108
+ } else {
109
+ setText = getCheckedText(text);
110
+ }
111
+ state.value = setText;
112
+ emit("update:data", setText);
113
+ await nextTick();
114
+ emit("value-change", setText, before);
115
+ };
116
+ const inputElement = ref();
117
+ defineExpose({ el: inputElement });
118
+ const setRef = (elm) => {
119
+ inputElement.value = elm;
120
+ emit("ref", elm);
121
+ };
122
+ const elmFocus = () => {
123
+ inputElement.value.focus();
124
+ };
125
+ const focusState = reactive({
126
+ isActivate: false,
127
+ isMmousedown: false
128
+ });
129
+ const computedActivate = computed(() => {
130
+ if (props.disabled === true) return false;
131
+ if (props.readonly === true) return false;
132
+ if (hsFocus.state.id !== uid) return false;
133
+ if (focusState.isActivate) return true;
134
+ if (focusState.isMmousedown) return true;
135
+ return false;
136
+ });
137
+ watch(computedActivate, (value) => {
138
+ if (value === true) {
139
+ setTimeout(() => {
140
+ emit("focus", inputElement.value);
141
+ }, 10);
142
+ } else {
143
+ emit("blur", inputElement.value);
144
+ }
145
+ });
146
+ const onMousedown = () => {
147
+ focusState.isMmousedown = true;
148
+ };
149
+ const onMouseup = () => {
150
+ elmFocus();
151
+ focusState.isMmousedown = false;
152
+ };
153
+ const onFocus = () => {
154
+ if (props.disabled === true) return;
155
+ if (props.readonly === true) return;
156
+ focusState.isActivate = true;
157
+ if (hsFocus.state.id !== uid) {
158
+ hsFocus.state.id = uid;
159
+ }
160
+ };
161
+ const onBlur = () => {
162
+ focusState.isActivate = false;
163
+ };
164
+ const tabindex = computed(() => {
165
+ if (props.disabled === true) return -1;
166
+ if (props.readonly === true) return -1;
167
+ return props.tabindex;
168
+ });
169
+ const isChangeData = computed(() => {
170
+ if (props.diff === void 0) return false;
171
+ if (props.diff === null && props.data === "") return false;
172
+ if (props.diff === "" && props.data === null) return false;
173
+ if (props.diff !== props.data) return true;
174
+ return false;
175
+ });
176
+ const lastLen = computed(() => {
177
+ return props.maxLen - state.value.length;
178
+ });
179
+ const lastRow = computed(() => {
180
+ return props.maxRows - state.value.split("\n").length;
181
+ });
182
+ const lenLabelClass = computed(() => {
183
+ return [
184
+ twMerge(
185
+ "text-white bg-[#2fa412]",
186
+ lastLen.value < 9 ? "bg-[#fdc90d]" : "",
187
+ lastLen.value < 6 ? "bg-[#fd750d]" : "",
188
+ lastLen.value < 3 ? "bg-[#fa541d]" : ""
189
+ )
190
+ ];
191
+ });
192
+ const rowLabelClass = computed(() => {
193
+ return [
194
+ twMerge(
195
+ "text-white bg-[#2fa412]",
196
+ lastRow.value < 6 ? "bg-[#fdc90d]" : "",
197
+ lastRow.value < 5 ? "bg-[#fd750d]" : "",
198
+ lastRow.value < 2 ? "bg-[#fa541d]" : ""
199
+ )
200
+ ];
201
+ });
202
+ const textAreaFrameClass = computed(() => {
203
+ return [
204
+ twMerge(),
205
+ //
206
+ "bg-transparent",
207
+ "flex flex-row items-center justify-center",
208
+ "h-full w-full"
209
+ ];
210
+ });
211
+ const textAreaClass = computed(() => {
212
+ return [
213
+ twMerge(
214
+ //
215
+ "flex-1",
216
+ "!leading-[1.2em]",
217
+ "bg-transparent",
218
+ "mt-[1px]",
219
+ "min-h-full min-w-full"
220
+ )
221
+ ];
222
+ });
223
+ const _rows = computed(() => {
224
+ if (!props.autosize) return props.rows;
225
+ const placeholder2 = tx(props.placeholder).value;
226
+ return Math.max(state.value.split("\n").length, placeholder2.split("\n").length, Int(props.rows));
227
+ });
228
+ const placeholder = computed(() => tx(props.placeholder).value);
229
+ </script>
230
+
231
+ <template>
232
+ <InputFrame
233
+ :class="['h-auto', props.class]"
234
+ :class-header="props.classHeader"
235
+ :class-input="['flex-1', props.classInput]"
236
+ :focus="computedActivate"
237
+ :focus-color="props.focusColor"
238
+ :change="isChangeData"
239
+ :change-color="props.changeColor"
240
+ :error="props.error"
241
+ :error-color="props.errorColor"
242
+ :disabled="props.disabled"
243
+ :disabled-color="props.disabledColor"
244
+ :readonly="props.readonly"
245
+ :label="props.label"
246
+ :require="props.require"
247
+ :require-text="props.requireText"
248
+ :warn="props.warn"
249
+ :warn-time-out="props.warnTimeOut"
250
+ :size="props.size"
251
+ :headerless="props.headerless"
252
+ @click="elmFocus"
253
+ >
254
+ <template #overlay="{ focus, change }">
255
+ <div
256
+ v-if="props.diff !== void 0 && change"
257
+ class="absolute inset-0 bg-red/30 transition-opacity flex items-start p-1 bg-dark/20"
258
+ :class="!focus && hsMisc.capsLockState ? 'opacity-100' : 'opacity-0 pointer-events-none select-none'"
259
+ >
260
+ <div class="flex">
261
+ <Btn
262
+ variant="outlined"
263
+ theme="error"
264
+ tabindex="-1"
265
+ size="xs"
266
+ class="bg-white flex-none"
267
+ @click="updateValue(props.diff)"
268
+ >
269
+ <i class="fa-solid fa-rotate-right"></i>
270
+ </Btn>
271
+ <div v-if="props.diff" class="px-1 truncate bg-white mx-1 flex items-center">{{ props.diff }}</div>
272
+ </div>
273
+ </div>
274
+ <template v-if="slots.overlay">
275
+ <slot name="overlay" :focus="focus" :change="change"></slot>
276
+ </template>
277
+ </template>
278
+ <template v-if="slots['left-icons']" #left-icons>
279
+ <slot name="left-icons" :disabled="disabled" />
280
+ </template>
281
+ <template v-if="slots['right-icons']" #right-icons>
282
+ <slot name="right-icons" :disabled="disabled" />
283
+ </template>
284
+ <template v-if="slots['label-prepend']" #label-prepend>
285
+ <slot name="label-prepend" />
286
+ </template>
287
+ <template v-if="slots['label-append']" #label-append>
288
+ <slot name="label-append" />
289
+ </template>
290
+ <template v-if="props.maxLen > 0 || props.maxRows > 0 || slots['header-right']" #header-right="{ defaultClass }">
291
+ <div v-if="props.maxLen !== 0 && lastLen < 15" :class="[defaultClass, lenLabelClass]">
292
+ {{ state.value.length }} / {{ props.maxLen }}
293
+ </div>
294
+ <div v-if="props.maxRows !== 0 && lastRow < 9" :class="[defaultClass, rowLabelClass]">
295
+ {{ state.value.split("\n").length }} / {{ props.maxRows }}
296
+ {{ tx(props.uiText.rowsUnit) }}
297
+ </div>
298
+ <slot name="header-right" />
299
+ </template>
300
+ <template #default="{ focus }">
301
+ <span
302
+ v-if="placeholder"
303
+ class="text-black/50 pointer-events-none select-none px-1 absolute inset-0 items-center transition-opacity truncate"
304
+ :class="focus || !!state.value ? 'opacity-0' : ''"
305
+ >
306
+ <div class="whitespace-pre-wrap w-full leading-[1.20em] mt-1">
307
+ {{ placeholder }}
308
+ </div>
309
+ </span>
310
+ <div class="nac-c-input-box" :class="[textAreaFrameClass, { isMobile: hsIsMobile.isMobile }]">
311
+ <textarea
312
+ :ref="(e) => setRef(e)"
313
+ v-model="state.value"
314
+ type="text"
315
+ :class="textAreaClass"
316
+ :rows="_rows"
317
+ :disabled="props.disabled || props.readonly"
318
+ :tabindex="tabindex"
319
+ @blur="onBlur()"
320
+ @focus="onFocus()"
321
+ @mousedown="onMousedown"
322
+ @mouseup="onMouseup"
323
+ @input="updateValue(state.value)"
324
+ @keydown="(e) => emit('keydown', e)"
325
+ @keyup="(e) => emit('keyup', e)"
326
+ ></textarea>
327
+ </div>
328
+ </template>
329
+ </InputFrame>
330
+ </template>
331
+
419
332
  <style scoped>
420
333
  @charset "UTF-8";
421
334
  .nac-c-input-box {
422
335
  padding: 4px 2px 4px 4px;
423
- /*スクロールバーの軌道*/
424
- /*スクロールバーの動く部分*/
425
336
  }
426
337
  .nac-c-input-box ::-webkit-scrollbar {
427
338
  width: 6px;
@@ -430,11 +341,17 @@ const _rows = computed(() => {
430
341
  cursor: pointer;
431
342
  background-color: transparent;
432
343
  }
344
+ .nac-c-input-box {
345
+ /*スクロールバーの軌道*/
346
+ }
433
347
  .nac-c-input-box ::-webkit-scrollbar-track {
434
348
  border-radius: 3px;
435
349
  margin-top: -3px;
436
350
  margin-bottom: 4px;
437
351
  }
352
+ .nac-c-input-box {
353
+ /*スクロールバーの動く部分*/
354
+ }
438
355
  .nac-c-input-box ::-webkit-scrollbar-thumb {
439
356
  border-radius: 3px;
440
357
  }
@@ -480,4 +397,4 @@ textarea {
480
397
  textarea[disabled]::-webkit-resizer {
481
398
  background: #f3f3f3;
482
399
  }
483
- </style>
400
+ </style>