@usssa/component-library 1.0.0-alpha.204 → 1.0.0-alpha.205

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Component Library v1.0.0-alpha.204
1
+ # Component Library v1.0.0-alpha.205
2
2
 
3
3
  **This library provides custom UI components for USSSA applications**
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usssa/component-library",
3
- "version": "1.0.0-alpha.204",
3
+ "version": "1.0.0-alpha.205",
4
4
  "description": "A Quasar component library project",
5
5
  "productName": "Quasar component library App",
6
6
  "author": "Engineering Team <engineering@usssa.com>",
@@ -1,6 +1,9 @@
1
1
  <script setup>
2
2
  import { ref } from "vue";
3
- import { UAvatar, UExpansionStd, UTableStd, useScreenType } from "src/components";
3
+ import UAvatar from "./UAvatar.vue";
4
+ import UExpansionStd from "./UExpansionStd.vue";
5
+ import UTableStd from "./UTableStd.vue";
6
+ import { useScreenType } from "../../composables/useScreenType";
4
7
 
5
8
  const emit = defineEmits(["onCustomSort", "onLoadMore"]);
6
9
 
@@ -0,0 +1,441 @@
1
+ <script setup>
2
+ import { ref } from "vue";
3
+ import UAvatar from "./UAvatar.vue";
4
+ import UBtnStd from "./UBtnStd.vue";
5
+ import { useScreenType } from "../../composables/useScreenType";
6
+
7
+ const body = defineModel("body", {
8
+ type: Object,
9
+ default: () => ({
10
+ team1: {
11
+ avatar: { type: "initials", value: "", name: "" },
12
+ teamName: "Team Name",
13
+ record: "In-Class Record (10-6-1)",
14
+ link: {
15
+ url: "",
16
+ color: "neutral",
17
+ ariaLabel: "",
18
+ onClick: () => {},
19
+ },
20
+ score: "",
21
+ },
22
+ team2: {
23
+ avatar: { type: "initials", value: "", name: "" },
24
+ teamName: "Team Name",
25
+ record: "In-Class Record (10-6-1)",
26
+ link: {
27
+ url: "",
28
+ color: "neutral",
29
+ ariaLabel: "",
30
+ onClick: () => {},
31
+ },
32
+ score: "",
33
+ },
34
+ viewMatchup: {
35
+ color: "primary",
36
+ size: "sm",
37
+ label: "View Matchup",
38
+ onClick: () => {},
39
+ },
40
+ }),
41
+ });
42
+
43
+ const direction = defineModel("direction", {
44
+ default: "horizontal",
45
+ type: String,
46
+ });
47
+
48
+ const gameState = defineModel("gameState", {
49
+ default: "notStarted",
50
+ type: String,
51
+ });
52
+
53
+ const header = defineModel("header", {
54
+ type: Object,
55
+ default: () => ({
56
+ primary: {
57
+ iconClass: "",
58
+ iconColor: "",
59
+ text: "",
60
+ customClass: "",
61
+ },
62
+ secondary: {
63
+ iconClass: "",
64
+ iconColor: "",
65
+ text: "",
66
+ badge: "",
67
+ alignBadge: "",
68
+ customClass: "",
69
+ },
70
+ }),
71
+ });
72
+
73
+ const props = defineProps({
74
+ dataTestId: {
75
+ type: String,
76
+ default: "game-object-card",
77
+ },
78
+ fieldLocation: {
79
+ type: String,
80
+ default: "",
81
+ },
82
+ });
83
+
84
+ const $screen = useScreenType();
85
+
86
+ const vsLogo = ref("/icons/VS.svg");
87
+ // const versesLogo = ref("/icons/verses.svg"); TODO: Will uncomment when Figma design for completed state is completed
88
+
89
+ const getChipCustomClass = (badge) => {
90
+ const isNotStarted = gameState.value === "notStarted" ? true : false;
91
+ if (badge === "REPLAY") {
92
+ return "replay-watch-chip";
93
+ }
94
+
95
+ if (badge === "WATCH LIVE") {
96
+ return isNotStarted ? "completed-replay-watch-chip" : "replay-watch-chip";
97
+ }
98
+
99
+ return "replay-watch-chip";
100
+ };
101
+
102
+ function isEmpty(obj) {
103
+ const emptyRegex = /^\s*$/;
104
+ return Object.values(obj).every((value) => {
105
+ return value == null || (typeof value === "string" && emptyRegex.test(value));
106
+ });
107
+ }
108
+ </script>
109
+
110
+ <template>
111
+ <q-card
112
+ :class="[
113
+ 'u-game-object-std ',
114
+ $screen.isMobile || direction === 'vertical' ? 'vertical-view' : 'full-width',
115
+ ]"
116
+ :dataTestId="dataTestId"
117
+ >
118
+ <!-- Header -->
119
+ <q-card-section
120
+ :class="[
121
+ 'row',
122
+ !$screen.isMobile && direction === 'horizontal' ? 'nowrap' : 'wrap',
123
+ 'u-game-object-std-header justify-between q-mb-xxs',
124
+ ]"
125
+ >
126
+ <!-- two section -->
127
+
128
+ <!-- Header primary section -->
129
+ <div class="header-primary-section flex items-center no-wrap">
130
+ <q-icon
131
+ v-if="header.primary.iconClass"
132
+ :class="['q-mr-xs icon-secondary-opacity', header.primary.iconClass]"
133
+ :iconColor="header.primary.iconColor"
134
+ size="1rem"
135
+ />
136
+ <span class="text-caption-md title-text">{{ header.primary.text }}</span>
137
+ </div>
138
+
139
+ <!-- Header secondary section -->
140
+ <div
141
+ v-if="!isEmpty(header.secondary)"
142
+ class="header-secondary-section flex items-center"
143
+ :style="{
144
+ width:
145
+ !$screen.isMobile && direction === 'horizontal'
146
+ ? 'auto'
147
+ : !header.secondary.badge && !header.secondary.iconClass
148
+ ? 'auto'
149
+ : '100%',
150
+ justifyContent:
151
+ !$screen.isMobile && direction === 'horizontal' ? 'unset' : 'space-between',
152
+ }"
153
+ >
154
+ <!-- Left Badge -->
155
+ <template
156
+ v-if="
157
+ header.secondary.badge &&
158
+ header.secondary.alignBadge === 'left' &&
159
+ (!$screen.isMobile || direction != 'vertical')
160
+ "
161
+ >
162
+ <q-chip
163
+ icon="circle"
164
+ :class="[
165
+ 'secondary-section-chip',
166
+ 'text-overline-xs',
167
+ !$screen.isMobile && direction === 'horizontal' ? 'q-mr-xs' : 'hidden',
168
+ getChipCustomClass(header.secondary.badge),
169
+ ]"
170
+ style="margin: 0 0.5rem 0px 0px !important"
171
+ >
172
+ {{ header.secondary.badge }}</q-chip
173
+ >
174
+ </template>
175
+ <!-- Left Badge -->
176
+
177
+ <div class="secondary-sub-section flex items-center">
178
+ <q-icon
179
+ v-if="header.secondary.iconClass"
180
+ :class="['q-mr-xs icon-secondary-opacity', header.secondary.iconClass]"
181
+ :iconColor="header.secondary.iconColor"
182
+ size="1rem"
183
+ />
184
+ <span class="text-caption-md title-text">{{ header.secondary.text }}</span>
185
+ </div>
186
+
187
+ <!-- Right Badge -->
188
+ <template
189
+ v-if="
190
+ header.secondary.badge &&
191
+ (header.secondary.alignBadge === 'right' ||
192
+ (header.secondary.alignBadge === 'left' &&
193
+ ($screen.isMobile || direction === 'vertical')))
194
+ "
195
+ >
196
+ <q-chip
197
+ :class="[
198
+ 'secondary-section-chip',
199
+ 'text-overline-xs',
200
+ getChipCustomClass(header.secondary.badge),
201
+ ]"
202
+ icon="circle"
203
+ style="margin: 0 0 0 0.5rem !important"
204
+ >
205
+ {{ header.secondary.badge }}</q-chip
206
+ >
207
+ </template>
208
+ <!-- Right Badge -->
209
+ </div>
210
+ </q-card-section>
211
+ <!-- Header -->
212
+
213
+ <!-- Body -->
214
+ <q-card-section class="u-game-object-std-body">
215
+ <div class="team-stats-section row q-mb-ba">
216
+ <!-- Team 1 -->
217
+ <div class="flex justify-between items-center no-wrap">
218
+ <div class="team-stats">
219
+ <div
220
+ v-if="typeof body.team1.avatar === 'object'"
221
+ class="flex item-center justify-center"
222
+ >
223
+ <UAvatar
224
+ v-if="body.team1.avatar?.type === 'initials'"
225
+ :name="`${body.team1.avatar?.value}`"
226
+ :size="body.team1.avatar?.size"
227
+ />
228
+ <UAvatar
229
+ v-else-if="body.team1.avatar?.type === 'image'"
230
+ :image="`${body.team1.avatar?.value}`"
231
+ :name="body.team1.avatar?.name ?? body.team1.avatar?.value"
232
+ :size="body.team1.avatar?.size"
233
+ />
234
+ </div>
235
+ <div>
236
+ <div class="flex items-center no-wrap">
237
+ <span class="text-caption-lg q-mr-xs" :style="{ wordBreak: 'break-word' }"
238
+ >{{ body.team1.teamName }}
239
+ </span>
240
+ <q-icon
241
+ class="fa-kit-duotone fa-share cursor-pointer icon-secondary-opacity"
242
+ :aria-label="body.team1.link.ariaLabel"
243
+ :color="body.team1.link.color"
244
+ size="1rem"
245
+ tabindex="1"
246
+ @click="body.team1.link.onClick"
247
+ />
248
+ </div>
249
+ <span class="text-body-xxs text-description">{{ body.team1.record }}</span>
250
+ </div>
251
+ </div>
252
+
253
+ <div class="flex item-center justify-center full-height q-ml-xs">
254
+ <span class="text-caption-lg">
255
+ {{ body.team1.score }}
256
+ </span>
257
+ </div>
258
+ </div>
259
+ <!-- Team 1 -->
260
+
261
+ <div class="logo-section">
262
+ <q-img class="vs-logo" alt="vs logo" :src="`${vsLogo}`" />
263
+ </div>
264
+
265
+ <!-- Team 2 -->
266
+ <div
267
+ class="flex justify-between items-center no-wrap"
268
+ :style="{
269
+ flexDirection:
270
+ !$screen.isMobile && direction === 'horizontal' ? 'unset' : 'row-reverse',
271
+ }"
272
+ >
273
+ <div class="flex item-center justify-center full-height">
274
+ <span
275
+ class="text-caption-lg"
276
+ :style="{
277
+ marginLeft:
278
+ !$screen.isMobile && direction === 'horizontal' ? '0' : '0.5rem',
279
+ }"
280
+ >
281
+ {{ body.team2.score }}
282
+ </span>
283
+ </div>
284
+ <div class="team-stats2">
285
+ <div
286
+ v-if="typeof body.team2.avatar === 'object'"
287
+ class="flex item-center justify-center"
288
+ :style="{
289
+ marginLeft:
290
+ !$screen.isMobile && direction === 'horizontal' ? '0.5rem' : '',
291
+ }"
292
+ >
293
+ <UAvatar
294
+ v-if="body.team2.avatar?.type === 'initials'"
295
+ :name="`${body.team2.avatar?.value}`"
296
+ :size="body.team2.avatar?.size"
297
+ />
298
+ <UAvatar
299
+ v-else-if="body.team2.avatar?.type === 'image'"
300
+ :image="`${body.team2.avatar?.value}`"
301
+ :name="body.team2.avatar?.name ?? body.team2.avatar?.value"
302
+ :size="body.team2.avatar?.size"
303
+ />
304
+ </div>
305
+ <div>
306
+ <div class="flex items-center no-wrap">
307
+ <span class="text-caption-lg q-mr-xs" :style="{ wordBreak: 'break-word' }"
308
+ >{{ body.team2.teamName }}
309
+ </span>
310
+ <q-icon
311
+ class="fa-kit-duotone fa-share cursor-pointer icon-secondary-opacity"
312
+ :aria-label="body.team2.link.ariaLabel"
313
+ :color="body.team2.link.color"
314
+ size="1rem"
315
+ tabindex="1"
316
+ @click="body.team2.link.onClick"
317
+ />
318
+ </div>
319
+ <span class="text-body-xxs text-description">{{ body.team2.record }}</span>
320
+ </div>
321
+ </div>
322
+ </div>
323
+ <!-- Team 2 -->
324
+ </div>
325
+
326
+ <!-- action -->
327
+ <div class="row flex items-center justify-between">
328
+ <div
329
+ v-if="fieldLocation"
330
+ :class="[
331
+ 'flex items-center',
332
+ 'field-location',
333
+ 'no-wrap',
334
+ !$screen.isMobile && direction === 'horizontal' ? '' : 'q-mb-ba',
335
+ ]"
336
+ >
337
+ <q-icon
338
+ class="fa-kit-duotone fa-field-location q-mr-xxs icon-secondary-opacity"
339
+ size="ba"
340
+ />
341
+ <span class="text-body-sm">{{ fieldLocation }}</span>
342
+ </div>
343
+
344
+ <UBtnStd
345
+ :class="[!$screen.isMobile && direction === 'horizontal' ? '' : 'full-width']"
346
+ :color="body.viewMatchup.color"
347
+ :label="body.viewMatchup.label"
348
+ :outline="true"
349
+ :size="body.viewMatchup.size"
350
+ @on-click="body.viewMatchup.onClick"
351
+ />
352
+ </div>
353
+ </q-card-section>
354
+ <!-- Body -->
355
+ </q-card>
356
+ </template>
357
+
358
+ <style lang="sass">
359
+ .u-game-object-std
360
+ border-radius: $xs
361
+ box-shadow: none
362
+ background: $neutral-3
363
+ padding: $xxs
364
+
365
+ .u-game-object-std-header
366
+ padding: $xxs $xs
367
+ background: inherit
368
+ min-height: $lg
369
+ align-items: center
370
+
371
+ .title-text
372
+ word-break: break-word
373
+ overflow-wrap: break-word
374
+
375
+ .u-game-object-std-body
376
+ padding: $sm
377
+ background: white
378
+ border-radius: $xxs !important
379
+
380
+ .secondary-section-chip
381
+ border: none !important
382
+ padding: $xxs
383
+ .q-icon
384
+ font-size: $xs
385
+ margin-right: $xxs
386
+
387
+ .replay-watch-chip
388
+ background-color: #FCEDEE
389
+ .q-icon
390
+ color: #CE2129 !important
391
+ .q-chip__content
392
+ color: #CE2129
393
+
394
+ .completed-replay-watch-chip
395
+ background-color: $pink-1
396
+ .q-icon
397
+ color: $pink-7
398
+ .q-chip__content
399
+ color: $pink-7
400
+
401
+ .u-game-object-std-body
402
+ .team-stats-section
403
+ display: grid
404
+ grid-template-columns: 1fr auto 1fr
405
+
406
+ .team-stats
407
+ width: 100%
408
+ display: flex
409
+ align-items: center
410
+ gap: $xs
411
+
412
+ .team-stats2
413
+ display: flex
414
+ align-items: center
415
+ gap: $xs
416
+
417
+ .logo-section
418
+ display: flex
419
+ align-items: center
420
+ justify-content: center
421
+ margin: 0 $ba
422
+ .vs-logo
423
+ width: 2.8rem
424
+ height: $md
425
+
426
+ .u-game-object-std.vertical-view
427
+ max-width: 20.125rem
428
+
429
+ .u-game-object-std-header
430
+ gap: $xs
431
+
432
+ .u-game-object-std-body
433
+ .team-stats-section
434
+ display: flex !important
435
+ flex-direction: column !important
436
+ gap: $ba
437
+ .logo-section
438
+ align-items: start
439
+ justify-content: unset
440
+ margin: 0
441
+ </style>
@@ -13,7 +13,9 @@ import UDate from './core/UDate.vue'
13
13
  import UDialogStd from './core/UDialogStd.vue'
14
14
  import UDrawer from './core/UDrawer/UDrawer.vue'
15
15
  import UExpansionStd from './core/UExpansionStd.vue'
16
+ import UExpansionTableStd from './core/UExpansionTableStd.vue'
16
17
  import UFilter from './core/UFilter.vue'
18
+ import UGameObject from './core/UGameObject.vue'
17
19
  import UInnerLoader from './core/UInnerLoader.vue'
18
20
  import UInputAddressLookup from './core/UInputAddressLookup.vue'
19
21
  import UInputPhoneStd from './core/UInputPhoneStd.vue'
@@ -61,7 +63,9 @@ export {
61
63
  UDialogStd,
62
64
  UDrawer,
63
65
  UExpansionStd,
66
+ UExpansionTableStd,
64
67
  UFilter,
68
+ UGameObject,
65
69
  UInnerLoader,
66
70
  UInputAddressLookup,
67
71
  UInputPhoneStd,