@7365admin1/layer-common 3.2.2-staging.125 → 3.2.2-staging.127

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.
@@ -6,6 +6,9 @@
6
6
  accept="image/*"
7
7
  :prepend-icon="prependIcon"
8
8
  :loading="isFileUploading"
9
+ variant="outlined"
10
+ density="comfortable"
11
+ class="filter-field"
9
12
  hide-details
10
13
  chips
11
14
  multiple
@@ -16,7 +19,16 @@
16
19
  >
17
20
  <template v-slot:append v-if="hasLabel">
18
21
  <slot name="append">
19
- <v-btn color="primary" height="50px" @click="openCameraDialog">
22
+ <!-- `color="primary"` on a `v-btn` is the design's FOREGROUND token,
23
+ so this drew accent-on-accent; the fill is `primary-button`, which
24
+ is what `.screen-btn-primary` states. `height="50px"` was also
25
+ 10px taller than the design's 40px button. -->
26
+ <v-btn
27
+ class="text-none screen-btn-primary"
28
+ variant="flat"
29
+ aria-label="Take a picture"
30
+ @click="openCameraDialog"
31
+ >
20
32
  <v-icon>mdi-camera</v-icon>
21
33
  </v-btn>
22
34
  </slot>
@@ -32,64 +44,69 @@
32
44
  persistent
33
45
  @after-enter="startCamera"
34
46
  >
35
- <v-container
36
- class="d-flex justify-center"
37
- max-height="90vh"
38
- width="800"
39
- max-width="800"
40
- >
41
- <v-card elevation="2" class="d-flex flex-column align-center pa-2">
42
- <v-toolbar>
43
- <v-card-title class="text-h5">Take a Picture</v-card-title>
44
- <v-spacer></v-spacer>
45
- <v-btn
46
- color="grey-darken-1"
47
- icon="mdi-close"
48
- @click="closeCameraDialog"
49
- ></v-btn>
50
- </v-toolbar>
51
-
52
- <div
53
- id="reader"
54
- class="d-flex justify-center align-center"
55
- style="
56
- position: relative;
57
- width: 500px;
58
- min-width: 400px;
59
- height: 400px;
60
- "
47
+ <!-- Was a `v-container` wrapping a factory 4px `v-card` with a bare
48
+ `v-toolbar` across the top - Vuetify paints that toolbar from its own
49
+ `surface`, a grey slab visibly lighter than the card on dark. The
50
+ design's modal is the card itself: 16px radius on `--card`, a
51
+ `v-card-title` row, and the borderless 32px close. -->
52
+ <v-card class="screen-modal d-flex flex-column align-center">
53
+ <v-card-title class="d-flex align-center w-100">
54
+ Take a Picture
55
+ <v-spacer />
56
+ <v-btn
57
+ variant="text"
58
+ icon="mdi-close"
59
+ class="screen-modal__close"
60
+ aria-label="Close camera"
61
+ @click="closeCameraDialog"
62
+ />
63
+ </v-card-title>
64
+
65
+ <div
66
+ id="reader"
67
+ class="d-flex justify-center align-center"
68
+ style="
69
+ position: relative;
70
+ width: 500px;
71
+ min-width: 400px;
72
+ height: 400px;
73
+ "
74
+ >
75
+ <video
76
+ ref="video"
77
+ style="flex: 1; height: 400px; min-width: 300px"
78
+ class="video-shutter"
79
+ autoplay
80
+ ></video>
81
+ <canvas
82
+ ref="canvas"
83
+ style="flex: 1; height: 400px; min-width: 300px; display: none"
84
+ ></canvas>
85
+ </div>
86
+
87
+ <!-- Was a two-column `v-row` of Vuetify `primary` / `secondary` icon
88
+ buttons - `secondary` is not a design token at all, and `primary` is
89
+ the foreground one. The design's icon button is the 36px bordered
90
+ square, and the capture action is the primary of the pair, so it
91
+ sits on the shared modal footer in the primary's place. -->
92
+ <div class="screen-modal__footer w-100">
93
+ <v-btn
94
+ class="text-none screen-btn-ghost"
95
+ variant="outlined"
96
+ aria-label="Switch camera"
97
+ @click="switchCamera"
98
+ >
99
+ <v-icon>mdi-camera-switch</v-icon>
100
+ </v-btn>
101
+ <v-btn
102
+ class="text-none screen-btn-primary"
103
+ variant="flat"
104
+ @click="captureImageFromCamera"
61
105
  >
62
- <video
63
- ref="video"
64
- style="flex: 1; height: 400px; min-width: 300px"
65
- class="video-shutter"
66
- autoplay
67
- ></video>
68
- <canvas
69
- ref="canvas"
70
- style="flex: 1; height: 400px; min-width: 300px; display: none"
71
- ></canvas>
72
- </div>
73
-
74
- <v-row align="center" justify="center">
75
- <v-col cols="6">
76
- <v-btn color="primary" icon class="mt-4" @click="switchCamera">
77
- <v-icon>mdi-camera-switch</v-icon>
78
- </v-btn>
79
- </v-col>
80
- <v-col cols="6">
81
- <v-btn
82
- color="secondary"
83
- icon
84
- class="mt-4"
85
- @click="captureImageFromCamera"
86
- >
87
- <v-icon large>mdi-camera-outline</v-icon>
88
- </v-btn>
89
- </v-col>
90
- </v-row>
91
- </v-card>
92
- </v-container>
106
+ <v-icon>mdi-camera-outline</v-icon>
107
+ </v-btn>
108
+ </div>
109
+ </v-card>
93
110
  </v-dialog>
94
111
  </div>
95
112
 
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <v-row no-gutters class="mb-6">
3
3
  <v-col cols="12">
4
- <div class="text-subtitle-2 font-weight-bold mb-3">
4
+ <div class="photo-upload__title mb-3">
5
5
  {{ title }}
6
- <span v-if="required" class="text-error">*</span>
6
+ <span v-if="required" class="photo-upload__req">*</span>
7
7
  </div>
8
8
 
9
9
  <v-sheet
@@ -17,13 +17,13 @@
17
17
  <v-icon
18
18
  :icon="uploading ? 'mdi-loading mdi-spin' : 'mdi-camera-plus-outline'"
19
19
  size="56"
20
- :color="uploading ? 'grey' : 'primary'"
21
20
  class="mb-3"
21
+ :class="uploading ? 'photo-upload__icon--wait' : 'photo-upload__icon'"
22
22
  />
23
- <div class="text-body-1 font-weight-medium mb-1">
23
+ <div class="photo-upload__lead mb-1">
24
24
  {{ uploading ? "Uploading Photo..." : "Add Photo" }}
25
25
  </div>
26
- <div class="text-caption text-medium-emphasis">
26
+ <div class="photo-upload__hint">
27
27
  {{ uploading ? "Please wait" : "Take a photo or upload from device" }}
28
28
  </div>
29
29
  </v-sheet>
@@ -50,8 +50,8 @@
50
50
  icon="mdi-close"
51
51
  size="x-small"
52
52
  variant="tonal"
53
- color="error"
54
- class="delete-btn"
53
+ aria-label="Remove photo"
54
+ class="delete-btn photo-upload__remove"
55
55
  @click.stop="removePhoto(index)"
56
56
  style="position: absolute; top: -8px; right: -8px"
57
57
  />
@@ -60,11 +60,13 @@
60
60
  </v-row>
61
61
 
62
62
  <v-dialog v-model="showPhotoPreview" max-width="900">
63
- <v-card>
63
+ <v-card class="screen-modal">
64
64
  <v-card-actions class="pa-2 justify-end">
65
65
  <v-btn
66
66
  icon="mdi-close"
67
67
  variant="text"
68
+ class="screen-modal__close"
69
+ aria-label="Close photo preview"
68
70
  @click="showPhotoPreview = false"
69
71
  />
70
72
  </v-card-actions>
@@ -75,46 +77,47 @@
75
77
  </v-dialog>
76
78
 
77
79
  <v-dialog v-model="photoOptionsDialog" max-width="420">
78
- <v-card>
79
- <v-card-title class="d-flex align-center pa-4">
80
- <span class="text-h6 font-weight-bold">Add Photo</span>
80
+ <v-card class="screen-modal">
81
+ <!-- `text-h6` is 20px/500 Roboto; the design's modal heading is the
82
+ `v-card-title` row's own size and weight. -->
83
+ <v-card-title class="d-flex align-center">
84
+ Add Photo
81
85
  <v-spacer />
82
86
  <v-btn
83
87
  icon="mdi-close"
84
88
  variant="text"
85
- size="small"
89
+ class="screen-modal__close"
90
+ aria-label="Close"
86
91
  @click="photoOptionsDialog = false"
87
92
  />
88
93
  </v-card-title>
89
94
 
90
- <v-divider />
91
-
92
- <v-card-text class="pa-4">
95
+ <v-card-text class="screen-modal__body">
93
96
  <v-list class="pa-0" bg-color="transparent">
94
97
  <v-list-item class="rounded-lg mb-2" @click="openCameraFromOptions">
95
98
  <template v-slot:prepend>
96
- <v-avatar color="primary" variant="tonal" size="48">
97
- <v-icon icon="mdi-camera" color="primary" />
99
+ <v-avatar variant="flat" size="48" class="photo-upload__avatar">
100
+ <v-icon icon="mdi-camera" />
98
101
  </v-avatar>
99
102
  </template>
100
- <v-list-item-title class="font-weight-medium mb-1">
103
+ <v-list-item-title class="photo-upload__lead mb-1">
101
104
  Take a Photo
102
105
  </v-list-item-title>
103
- <v-list-item-subtitle class="text-caption">
106
+ <v-list-item-subtitle class="photo-upload__hint">
104
107
  Use device camera to capture an image
105
108
  </v-list-item-subtitle>
106
109
  </v-list-item>
107
110
 
108
111
  <v-list-item class="rounded-lg" @click="triggerFileInput">
109
112
  <template v-slot:prepend>
110
- <v-avatar color="primary" variant="tonal" size="48">
111
- <v-icon icon="mdi-upload" color="primary" />
113
+ <v-avatar variant="flat" size="48" class="photo-upload__avatar">
114
+ <v-icon icon="mdi-upload" />
112
115
  </v-avatar>
113
116
  </template>
114
- <v-list-item-title class="font-weight-medium mb-1">
117
+ <v-list-item-title class="photo-upload__lead mb-1">
115
118
  Upload a Photo
116
119
  </v-list-item-title>
117
- <v-list-item-subtitle class="text-caption">
120
+ <v-list-item-subtitle class="photo-upload__hint">
118
121
  Select an image from your device
119
122
  </v-list-item-subtitle>
120
123
  </v-list-item>
@@ -124,17 +127,22 @@
124
127
  </v-dialog>
125
128
 
126
129
  <v-dialog v-model="showCameraDialog" max-width="720">
127
- <v-card>
128
- <v-toolbar density="compact">
129
- <v-toolbar-title class="text-subtitle-1 font-weight-medium">
130
- Camera
131
- </v-toolbar-title>
130
+ <!-- Was a bare `v-toolbar`, which Vuetify paints from its own `surface` -
131
+ a grey slab across the top of the card, lighter than the card on the
132
+ dark theme. -->
133
+ <v-card class="screen-modal">
134
+ <v-card-title class="d-flex align-center">
135
+ Camera
132
136
  <v-spacer />
133
- <v-btn icon @click="closeCameraDialog">
134
- <v-icon>mdi-close</v-icon>
135
- </v-btn>
136
- </v-toolbar>
137
- <v-card-text>
137
+ <v-btn
138
+ icon="mdi-close"
139
+ variant="text"
140
+ class="screen-modal__close"
141
+ aria-label="Close camera"
142
+ @click="closeCameraDialog"
143
+ />
144
+ </v-card-title>
145
+ <v-card-text class="screen-modal__body">
138
146
  <div class="d-flex flex-column align-center">
139
147
  <div style="width: 100%; max-width: 640px">
140
148
  <video
@@ -146,33 +154,32 @@
146
154
  />
147
155
  </div>
148
156
  <canvas ref="canvasRef" style="display: none"></canvas>
149
- <div class="text-caption grey--text mt-2">
157
+ <div class="screen-hint mt-2">
150
158
  Tip: Allow camera permissions to use this feature.
151
159
  </div>
152
160
  </div>
153
161
  </v-card-text>
154
- <v-card-actions>
162
+ <!-- Was a `v-card-actions` holding a plain text CANCEL and a 56px
163
+ `color="black"` bar forced to `rounded-0` - black is neither theme's
164
+ accent and reads as a hole in the dark modal. This is the design's
165
+ shared modal footer: ghost secondary, then the primary. -->
166
+ <div class="screen-modal__footer">
155
167
  <v-btn
156
- text
168
+ class="text-none screen-btn-ghost"
169
+ variant="outlined"
157
170
  @click="closeCameraDialog"
158
- class="text-none font-weight-medium"
159
171
  >
160
- CANCEL
172
+ Cancel
161
173
  </v-btn>
162
- <v-spacer />
163
174
  <v-btn
164
- block
175
+ class="text-none screen-btn-primary"
165
176
  variant="flat"
166
- color="black"
167
- class="text-none font-weight-bold rounded-0"
168
- height="56"
169
- size="large"
170
177
  @click="capturePhoto"
171
178
  >
172
179
  <v-icon class="mr-2">mdi-camera</v-icon>
173
- CAPTURE
180
+ Capture
174
181
  </v-btn>
175
- </v-card-actions>
182
+ </div>
176
183
  </v-card>
177
184
  </v-dialog>
178
185
 
@@ -393,13 +400,68 @@ onBeforeUnmount(() => {
393
400
  </script>
394
401
 
395
402
  <style scoped>
403
+ /* Was `rgb(var(--v-theme-primary))`, i.e. the design's FOREGROUND token used
404
+ as a rule and a wash. `--accent-strong` is the accent's fill form, which is
405
+ what a hover state on a drop zone is. */
396
406
  .upload-area {
397
407
  &:hover:not(.upload-disabled) {
398
- border-color: rgb(var(--v-theme-primary)) !important;
399
- background-color: rgba(var(--v-theme-primary), 0.04);
408
+ border-color: var(--accent-strong) !important;
409
+ background-color: var(--accent-soft);
400
410
  }
401
411
  }
402
412
 
413
+ /* The section title was `text-subtitle-2 font-weight-bold` and the two leads
414
+ `text-body-1 font-weight-medium` - Vuetify Roboto at Vuetify's sizes. These
415
+ take the design's card-title and cell type. */
416
+ .photo-upload__title {
417
+ font-family: var(--font-sans);
418
+ font-size: var(--fs-card-title);
419
+ font-weight: var(--fw-card-title);
420
+ color: var(--text);
421
+ }
422
+
423
+ .photo-upload__req {
424
+ color: var(--err);
425
+ }
426
+
427
+ .photo-upload__lead {
428
+ font-family: var(--font-sans);
429
+ font-size: 13.5px;
430
+ font-weight: 600;
431
+ color: var(--text);
432
+ }
433
+
434
+ /* Was `text-caption text-medium-emphasis` / `grey--text`, Vuetify's 60% alpha.
435
+ `--muted` is the design's sub-line and follows the theme. */
436
+ .photo-upload__hint {
437
+ font-family: var(--font-sans);
438
+ font-size: 12px;
439
+ color: var(--muted);
440
+ }
441
+
442
+ /* The drop-zone glyph was `color="primary"`, the FOREGROUND token; the
443
+ accent's ink form is the one held at >= 4.5:1 on the card. */
444
+ .photo-upload__icon {
445
+ color: var(--accent-text);
446
+ }
447
+
448
+ .photo-upload__icon--wait {
449
+ color: var(--muted);
450
+ }
451
+
452
+ /* The two option tiles were `v-avatar color="primary" variant="tonal"` with a
453
+ `primary` glyph inside - accent on accent. */
454
+ .photo-upload__avatar {
455
+ background: var(--accent-soft);
456
+ color: var(--accent-text);
457
+ }
458
+
459
+ /* `color="error"` is Vuetify's palette red, not the theme's `--err`. */
460
+ .photo-upload__remove {
461
+ background: var(--err-bg);
462
+ color: var(--err);
463
+ }
464
+
403
465
  .upload-disabled {
404
466
  cursor: not-allowed !important;
405
467
  opacity: 0.6;
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.125",
5
+ "version": "3.2.2-staging.127",
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.",