@7365admin1/layer-common 3.2.2-staging.147 → 3.2.2-staging.148

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.
@@ -10,12 +10,17 @@
10
10
  <v-row no-gutters>
11
11
  <v-col v-if="value || readOnly" cols="12">
12
12
  <v-row no-gutters>
13
+ <!-- The strip is one control split in two: the file name, and the
14
+ cross that clears it. `rounded=""` on the read-only card was
15
+ not "no radius" - Vuetify's `useRounded` treats an empty string
16
+ as `true` and adds `.rounded`, i.e. its own 4px. The design's
17
+ radius is stated here instead, on both ends. -->
13
18
  <v-card
14
19
  variant="outlined"
15
20
  border="thin"
16
- class="px-4 text-caption font-weight-medium"
17
- :rounded="readOnly ? '' : '0 s'"
18
- height="36"
21
+ class="btn-input-file__name"
22
+ :class="{ 'btn-input-file__name--solo': readOnly }"
23
+ height="40"
19
24
  @click="emit('click:view')"
20
25
  >
21
26
  <v-row no-gutters class="fill-height" align="center">
@@ -26,24 +31,28 @@
26
31
  v-if="!readOnly"
27
32
  variant="outlined"
28
33
  border="s-0 thin"
29
- rounded="0 e"
30
- class="px-4 d-inline"
31
- height="36"
34
+ class="btn-input-file__clear"
35
+ height="40"
32
36
  @click="emit('click:close')"
33
37
  >
34
38
  <v-row no-gutters class="fill-height" align="center">
35
- <v-icon size="small"> mdi-close </v-icon>
39
+ <v-icon size="18"> mdi-close </v-icon>
36
40
  </v-row>
37
41
  </v-card>
38
42
  </v-row>
39
43
  </v-col>
40
44
 
41
45
  <v-col v-else cols="12">
46
+ <!-- This arm is the `v-else` of `v-if="value || readOnly"`, so
47
+ `value` is always falsy by the time it renders: the old
48
+ `:prepend-icon="value ? '' : ..."` had an arm that could never be
49
+ taken, and the icon is unconditional. `screen-btn-ghost` is the
50
+ design's 40px bordered button while keeping Vuetify's `loading`
51
+ spinner, which the upload needs and `AppButton` does not have. -->
42
52
  <v-btn
43
- variant="outlined"
44
- border="thin"
45
- class="text-none"
46
- :prepend-icon="value ? '' : 'mdi-tray-arrow-up'"
53
+ variant="flat"
54
+ class="text-none screen-btn-ghost"
55
+ prepend-icon="mdi-tray-arrow-up"
47
56
  :disabled="loading"
48
57
  :loading="loading"
49
58
  @click="selectAttachment"
@@ -137,3 +146,36 @@ const errorMessage = computed(() => {
137
146
  return null;
138
147
  });
139
148
  </script>
149
+
150
+ <style scoped>
151
+ /* The design's control box on the attachment strip: 40px, `--r-inner` on the
152
+ outer corners only (the two cards butt together), a `--line` edge and the
153
+ 13.5px/500 cell type - not Vuetify's `text-caption` scale and 4px radius.
154
+ `:deep` because the box being styled is the `v-card` root Vuetify renders. */
155
+ .btn-input-file__name,
156
+ .btn-input-file__clear {
157
+ font-family: var(--font-sans);
158
+ font-size: var(--fs-cell);
159
+ font-weight: var(--fw-cell);
160
+ color: var(--text2);
161
+ border-color: var(--border);
162
+ }
163
+
164
+ .btn-input-file__name {
165
+ padding-inline: 14px;
166
+ border-start-start-radius: var(--r-inner);
167
+ border-end-start-radius: var(--r-inner);
168
+ }
169
+
170
+ /* Read-only: there is no cross beside it, so it is a single rounded box. */
171
+ .btn-input-file__name--solo {
172
+ border-radius: var(--r-inner);
173
+ }
174
+
175
+ .btn-input-file__clear {
176
+ display: inline;
177
+ padding-inline: 12px;
178
+ border-start-end-radius: var(--r-inner);
179
+ border-end-end-radius: var(--r-inner);
180
+ }
181
+ </style>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="d-flex flex-column">
3
- <v-text-field v-bind="$attrs" ref="datePickerRef" :model-value="dateFormattedReadOnly" autocomplete="off"
3
+ <v-text-field v-bind="$attrs" class="filter-field" ref="datePickerRef" :model-value="dateFormattedReadOnly" autocomplete="off"
4
4
  :placeholder="placeholder" :rules="rules" style="z-index: 10" @click="openDatePicker" @click:clear.stop="clearDate">
5
5
  <template #append-inner>
6
6
  <v-icon icon="mdi-calendar" @click.stop="openDatePicker" />
@@ -2,6 +2,7 @@
2
2
  <div class="d-flex flex-column">
3
3
  <v-text-field
4
4
  v-bind="$attrs"
5
+ class="filter-field"
5
6
  ref="dateTimePickerRef"
6
7
  :model-value="dateTimeFormattedReadOnly"
7
8
  autocomplete="off"
@@ -22,7 +22,7 @@
22
22
  <template v-else>
23
23
  <v-file-upload v-model="uploadFiles" density="compact" @update:model-value="handleUpdateValue"
24
24
  :loading="processing" :disabled="processing" :height="height" :title="title" :accept="accept"
25
- :name="`upload_images`" class="text-caption w-100" clearable :multiple="multiple">
25
+ :name="`upload_images`" class="w-100 file-v2__drop" clearable :multiple="multiple">
26
26
  <template #item="{ props: itemProps, file }">
27
27
  <v-file-upload-item v-bind="itemProps" lines="one" nav @click="handleClickItem(file)">
28
28
  <template #prepend>
@@ -30,8 +30,19 @@
30
30
  </template>
31
31
 
32
32
  <!-- delete button NOT shown in view mode -->
33
- <template #clear="{ props: clearProps }">
34
- <v-btn v-if="!viewMode" color="primary" @click.stop="handleRemove(file)"></v-btn>
33
+ <!-- This button had NO icon and NO label, so it drew as an empty
34
+ slab, and `color="primary"` filled that slab with the design's
35
+ FOREGROUND token (the link ink) rather than a fill. It is the
36
+ remove control for one attached file: a plain close glyph. -->
37
+ <template #clear>
38
+ <v-btn
39
+ v-if="!viewMode"
40
+ icon="mdi-close"
41
+ variant="text"
42
+ size="small"
43
+ aria-label="Remove file"
44
+ @click.stop="handleRemove(file)"
45
+ />
35
46
  </template>
36
47
  </v-file-upload-item>
37
48
  </template>
@@ -39,7 +50,7 @@
39
50
  </template>
40
51
 
41
52
  <v-row no-gutters class="w-100" v-if="errorMessage">
42
- <p class="text-error w-100 text-center text-subtitle-2">{{ errorMessage }}</p>
53
+ <p class="text-error w-100 text-center file-v2__error">{{ errorMessage }}</p>
43
54
  </v-row>
44
55
 
45
56
  <ImageCarousel v-model="showImageCarousel" :files="idsArray" :active-file-id="activeImageId" />
@@ -224,12 +235,34 @@ async function downloadFile(id: string, filename: string) {
224
235
 
225
236
 
226
237
  <style scoped>
238
+ /* The drop zone on the design's surface: `--r-inner`, a `--border` edge and the
239
+ 13.5px cell type, instead of Vuetify's 4px radius and `text-caption` scale.
240
+ `:deep` because every box below is rendered by `v-file-upload`. */
241
+ .file-v2__drop {
242
+ font-family: var(--font-sans);
243
+ font-size: var(--fs-cell);
244
+ border-radius: var(--r-inner);
245
+ border-color: var(--border);
246
+ }
247
+
248
+ .file-v2__drop :deep(.v-file-upload-item) {
249
+ border-radius: var(--r-inner);
250
+ }
251
+
227
252
  * :deep(.v-file-upload-title) {
228
- font-size: 1rem;
229
- font-weight: 500;
253
+ font-family: var(--font-sans);
254
+ font-size: var(--fs-card-title);
255
+ font-weight: var(--fw-card-title);
256
+ color: var(--text);
230
257
  }
231
258
 
232
259
  * :deep(.v-file-upload-items) {
233
260
  min-width: 100%;
234
261
  }
262
+
263
+ .file-v2__error {
264
+ font-family: var(--font-sans);
265
+ font-size: var(--fs-cell);
266
+ font-weight: var(--fw-cell);
267
+ }
235
268
  </style>
@@ -8,7 +8,7 @@
8
8
  item-title="dial_code"
9
9
  item-value="code"
10
10
  hide-details
11
- class="px-0"
11
+ class="px-0 filter-field"
12
12
  :density="density"
13
13
  style="max-width: 110px"
14
14
  :rules="[...props.rules]"
@@ -31,6 +31,7 @@
31
31
 
32
32
  <v-mask-input
33
33
  v-model="input"
34
+ class="filter-field"
34
35
  :mask="currentMask"
35
36
  :rules="[...props.rules, validatePhone]"
36
37
  ref="maskRef"
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <v-text-field
3
3
  v-model.trim="model"
4
+ class="filter-field"
4
5
  :rules="rules"
5
6
  :maxlength="maxlength"
6
7
  :placeholder="placeholder"
@@ -113,6 +113,7 @@ const modifyDatePart = (
113
113
  <template>
114
114
  <v-text-field
115
115
  ref="inputRef"
116
+ class="filter-field"
116
117
  v-model="dateValue"
117
118
  placeholder="MM/DD/YYYY"
118
119
  @input="formatDate"
@@ -102,6 +102,7 @@ const restoreCursor = () => {
102
102
  ref="inputRef"
103
103
  v-model="formattedValue"
104
104
  v-bind="attrs"
105
+ class="filter-field"
105
106
  type="text"
106
107
  @keydown="handleKeyDown"
107
108
  >
@@ -2,6 +2,7 @@
2
2
  <v-text-field
3
3
  id="_password"
4
4
  v-model="password"
5
+ class="filter-field"
5
6
  placeholder="Password"
6
7
  :type="showPassword ? 'text' : 'password'"
7
8
  :append-inner-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <v-text-field
3
3
  v-model="model"
4
+ class="filter-field"
4
5
  :rules="rules"
5
6
  :maxlength="maxlength"
6
7
  :placeholder="placeholder"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "3.2.2-staging.147",
5
+ "version": "3.2.2-staging.148",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",