create-nexwire 4.2.4 → 4.2.5
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/express/.vscode/extensions.json +6 -0
- package/express/.vscode/settings.json +37 -26
- package/express/biome.json +99 -66
- package/express/package.json +30 -28
- package/express/src/database/schema.ts +2 -2
- package/express/src/resources/src/components/Checkbox.vue +32 -29
- package/express/src/resources/src/components/Input.vue +243 -223
- package/express/src/resources/src/components/InputGroup.vue +147 -145
- package/express/src/resources/src/components/InputPasswordToggle.vue +229 -213
- package/express/src/resources/src/components/Modal.vue +71 -55
- package/express/src/resources/src/components/Refresh.vue +19 -0
- package/express/src/resources/src/helpers/assets.ts +51 -0
- package/express/src/resources/src/main.ts +3 -1
- package/express/src/resources/src/plugins/gum.ts +1 -1
- package/express/src/resources/src/stores/auth.ts +184 -164
- package/express/src/resources/vite.config.ts +9 -2
- package/express/src/storage/database/nexwire.sqlite +0 -0
- package/hono/.vscode/extensions.json +6 -0
- package/hono/.vscode/settings.json +37 -26
- package/hono/biome.json +25 -2
- package/hono/package.json +24 -22
- package/hono/src/database/schema.ts +2 -2
- package/hono/src/resources/src/components/Checkbox.vue +32 -29
- package/hono/src/resources/src/components/Input.vue +243 -234
- package/hono/src/resources/src/components/InputGroup.vue +147 -149
- package/hono/src/resources/src/components/InputPasswordToggle.vue +229 -222
- package/hono/src/resources/src/components/Modal.vue +71 -55
- package/hono/src/resources/src/components/Refresh.vue +19 -0
- package/hono/src/resources/src/helpers/assets.ts +51 -0
- package/hono/src/resources/src/main.ts +3 -1
- package/hono/src/resources/src/plugins/gum.ts +1 -1
- package/hono/src/resources/src/stores/auth.ts +184 -164
- package/hono/src/resources/vite.config.ts +9 -2
- package/hono/src/storage/database/nexwire.sqlite +0 -0
- package/package.json +1 -1
|
@@ -1,149 +1,147 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="topclass">
|
|
3
|
-
<div class="position-relative">
|
|
4
|
-
<label
|
|
5
|
-
:for="inputId"
|
|
6
|
-
class="text-capitalize d-flex align-items-center mb-1"
|
|
7
|
-
:class="{ 'd-none': !inputLabel }">
|
|
8
|
-
<div class="position-relative">
|
|
9
|
-
<span class="text-capitalize" v-html="inputLabel"></span>
|
|
10
|
-
<span
|
|
11
|
-
class="position-absolute text-danger rounded-circle bg-danger must"
|
|
12
|
-
:class="{ 'd-none': !props.must }"></span>
|
|
13
|
-
</div>
|
|
14
|
-
<div
|
|
15
|
-
:class="hoodClass"
|
|
16
|
-
style="font-size: 12px; margin-top: 0.15rem"
|
|
17
|
-
v-html="hoodHtml"></div>
|
|
18
|
-
</label>
|
|
19
|
-
<div class="input-group">
|
|
20
|
-
<div class="position-relative" :style="props.half ? 'width: 50%;' : 'width: 35%;'">
|
|
21
|
-
<input
|
|
22
|
-
ref="inputRef"
|
|
23
|
-
:id="inputId"
|
|
24
|
-
type="text"
|
|
25
|
-
class="form-control flex-grow-0 px-1 text-center rounded-0 rounded-start"
|
|
26
|
-
:maxlength="maxLengthAttr"
|
|
27
|
-
:value="props.modelValue"
|
|
28
|
-
v-bind="$attrs"
|
|
29
|
-
@input="updateModel" />
|
|
30
|
-
<div
|
|
31
|
-
class="position-absolute bottom-0 end-0 pe-1 text-secondary max"
|
|
32
|
-
:class="{ 'd-none': !max }">
|
|
33
|
-
{{ maxCounter }}
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
<input
|
|
37
|
-
type="text"
|
|
38
|
-
class="form-control text-center border-start second-input"
|
|
39
|
-
:style="props.half ? 'width: 50%;' : 'width: 62%;'"
|
|
40
|
-
:placeholder="placeholder1"
|
|
41
|
-
:value="props.calcdata"
|
|
42
|
-
readonly />
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
<div :id="`${inputId}Help`" class="form-text text-danger" :class="{ 'd-none': !props.err }">
|
|
46
|
-
{{ props.err }}
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</template>
|
|
50
|
-
|
|
51
|
-
<script setup lang="ts">
|
|
52
|
-
import { computed, nextTick, onMounted, ref, useAttrs } from "vue";
|
|
53
|
-
|
|
54
|
-
defineOptions({ name: "InputGroup", inheritAttrs: false });
|
|
55
|
-
|
|
56
|
-
type InputGroupCategory = "number" | "decimal" | "mobile" | string;
|
|
57
|
-
|
|
58
|
-
interface InputGroupProps {
|
|
59
|
-
focus?: boolean;
|
|
60
|
-
must?: boolean;
|
|
61
|
-
half?: boolean;
|
|
62
|
-
err?: string | boolean;
|
|
63
|
-
modelValue?: string | number;
|
|
64
|
-
category?: InputGroupCategory;
|
|
65
|
-
calcdata?: string | number;
|
|
66
|
-
hood?: string | number | boolean;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const $attrs = useAttrs();
|
|
70
|
-
const inputRef = ref<HTMLInputElement | null>(null);
|
|
71
|
-
const props = withDefaults(defineProps<InputGroupProps>(), {
|
|
72
|
-
err: false,
|
|
73
|
-
modelValue: "",
|
|
74
|
-
calcdata: ""
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const topclass = computed(() => ($attrs.topclass as string | undefined) || "mb-3");
|
|
78
|
-
const inputId = computed(() => ($attrs.id as string | undefined) || "");
|
|
79
|
-
const inputLabel = computed(() => ($attrs.label as string | undefined) || "");
|
|
80
|
-
const placeholder1 = computed(() => ($attrs.placeholder1 as string | undefined) || "");
|
|
81
|
-
|
|
82
|
-
const max = computed<number | null>(() => {
|
|
83
|
-
const raw = $attrs.maxlength as string | number | undefined;
|
|
84
|
-
return raw != null ? Number(raw) : null;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const maxLengthAttr = computed<number | undefined>(() => max.value ?? undefined);
|
|
88
|
-
const maxCounter = computed(() =>
|
|
89
|
-
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
props.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="topclass">
|
|
3
|
+
<div class="position-relative">
|
|
4
|
+
<label
|
|
5
|
+
:for="inputId"
|
|
6
|
+
class="text-capitalize d-flex align-items-center mb-1"
|
|
7
|
+
:class="{ 'd-none': !inputLabel }">
|
|
8
|
+
<div class="position-relative">
|
|
9
|
+
<span class="text-capitalize" v-html="inputLabel"></span>
|
|
10
|
+
<span
|
|
11
|
+
class="position-absolute text-danger rounded-circle bg-danger must"
|
|
12
|
+
:class="{ 'd-none': !props.must }"></span>
|
|
13
|
+
</div>
|
|
14
|
+
<div
|
|
15
|
+
:class="hoodClass"
|
|
16
|
+
style="font-size: 12px; margin-top: 0.15rem"
|
|
17
|
+
v-html="hoodHtml"></div>
|
|
18
|
+
</label>
|
|
19
|
+
<div class="input-group">
|
|
20
|
+
<div class="position-relative" :style="props.half ? 'width: 50%;' : 'width: 35%;'">
|
|
21
|
+
<input
|
|
22
|
+
ref="inputRef"
|
|
23
|
+
:id="inputId"
|
|
24
|
+
type="text"
|
|
25
|
+
class="form-control flex-grow-0 px-1 text-center rounded-0 rounded-start"
|
|
26
|
+
:maxlength="maxLengthAttr"
|
|
27
|
+
:value="props.modelValue"
|
|
28
|
+
v-bind="$attrs"
|
|
29
|
+
@input="updateModel" />
|
|
30
|
+
<div
|
|
31
|
+
class="position-absolute bottom-0 end-0 pe-1 text-secondary max"
|
|
32
|
+
:class="{ 'd-none': !max }">
|
|
33
|
+
{{ maxCounter }}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<input
|
|
37
|
+
type="text"
|
|
38
|
+
class="form-control text-center border-start second-input"
|
|
39
|
+
:style="props.half ? 'width: 50%;' : 'width: 62%;'"
|
|
40
|
+
:placeholder="placeholder1"
|
|
41
|
+
:value="props.calcdata"
|
|
42
|
+
readonly />
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div :id="`${inputId}Help`" class="form-text text-danger" :class="{ 'd-none': !props.err }">
|
|
46
|
+
{{ props.err }}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script setup lang="ts">
|
|
52
|
+
import { computed, nextTick, onMounted, ref, useAttrs } from "vue";
|
|
53
|
+
|
|
54
|
+
defineOptions({ name: "InputGroup", inheritAttrs: false });
|
|
55
|
+
|
|
56
|
+
type InputGroupCategory = "number" | "decimal" | "mobile" | string;
|
|
57
|
+
|
|
58
|
+
interface InputGroupProps {
|
|
59
|
+
focus?: boolean;
|
|
60
|
+
must?: boolean;
|
|
61
|
+
half?: boolean;
|
|
62
|
+
err?: string | boolean;
|
|
63
|
+
modelValue?: string | number;
|
|
64
|
+
category?: InputGroupCategory;
|
|
65
|
+
calcdata?: string | number;
|
|
66
|
+
hood?: string | number | boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const $attrs = useAttrs();
|
|
70
|
+
const inputRef = ref<HTMLInputElement | null>(null);
|
|
71
|
+
const props = withDefaults(defineProps<InputGroupProps>(), {
|
|
72
|
+
err: false,
|
|
73
|
+
modelValue: "",
|
|
74
|
+
calcdata: ""
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const topclass = computed(() => ($attrs.topclass as string | undefined) || "mb-3");
|
|
78
|
+
const inputId = computed(() => ($attrs.id as string | undefined) || "");
|
|
79
|
+
const inputLabel = computed(() => ($attrs.label as string | undefined) || "");
|
|
80
|
+
const placeholder1 = computed(() => ($attrs.placeholder1 as string | undefined) || "");
|
|
81
|
+
|
|
82
|
+
const max = computed<number | null>(() => {
|
|
83
|
+
const raw = $attrs.maxlength as string | number | undefined;
|
|
84
|
+
return raw != null ? Number(raw) : null;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const maxLengthAttr = computed<number | undefined>(() => max.value ?? undefined);
|
|
88
|
+
const maxCounter = computed(() => (max.value == null ? "" : max.value - String(props.modelValue).length));
|
|
89
|
+
|
|
90
|
+
const hoodHtml = computed(() => (props.hood === false || props.hood == null ? "" : String(props.hood)));
|
|
91
|
+
const hoodClass = computed(() => [
|
|
92
|
+
"text-uppercase w-50 text-end text-primary fw-semibold",
|
|
93
|
+
props.half ? "w-50" : "w-100",
|
|
94
|
+
!props.hood && "d-none"
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
const emit = defineEmits<(event: "update:modelValue", value: string | number) => void>();
|
|
98
|
+
|
|
99
|
+
const updateModel = (e: Event) => {
|
|
100
|
+
const target = e.target as HTMLInputElement;
|
|
101
|
+
|
|
102
|
+
if (props.category === "number") {
|
|
103
|
+
emit("update:modelValue", (target.value = target.value.replace(/[^\d]/gi, "")));
|
|
104
|
+
} else if (props.category === "decimal") {
|
|
105
|
+
let val = target.value;
|
|
106
|
+
val = val.replace(/[^0-9.]/g, "");
|
|
107
|
+
|
|
108
|
+
const parts = val.split(".");
|
|
109
|
+
if (parts.length > 2) {
|
|
110
|
+
val = `${parts[0]}.${parts.slice(1).join("")}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
emit("update:modelValue", (target.value = val));
|
|
114
|
+
} else if (props.category === "mobile") {
|
|
115
|
+
const digits = target.value.replace(/[^\d]/g, "");
|
|
116
|
+
let val = digits;
|
|
117
|
+
if (target.value.includes("+")) {
|
|
118
|
+
val = `+${digits}`;
|
|
119
|
+
}
|
|
120
|
+
emit("update:modelValue", (target.value = val));
|
|
121
|
+
} else {
|
|
122
|
+
emit("update:modelValue", target.value);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
onMounted(async () => {
|
|
127
|
+
const shouldFocus = props.focus !== false && props.focus !== undefined;
|
|
128
|
+
if (!shouldFocus) return;
|
|
129
|
+
|
|
130
|
+
await nextTick();
|
|
131
|
+
// preventScroll: focusing inside a modal must not scroll the modal/page
|
|
132
|
+
inputRef.value?.focus({ preventScroll: true });
|
|
133
|
+
});
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<style lang="scss" scoped>
|
|
137
|
+
.must {
|
|
138
|
+
width: 4px;
|
|
139
|
+
height: 4px;
|
|
140
|
+
margin-left: 2px;
|
|
141
|
+
margin-top: 5px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.max {
|
|
145
|
+
font-size: 0.6rem;
|
|
146
|
+
}
|
|
147
|
+
</style>
|