@sbc-connect/nuxt-base 0.1.16 → 0.1.18

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @sbc-connect/nuxt-base
2
2
 
3
+ ## 0.1.18
4
+
5
+ ### Patch Changes
6
+
7
+ - [#64](https://github.com/bcgov/connect-nuxt/pull/64) [`291b7dd`](https://github.com/bcgov/connect-nuxt/commit/291b7dd9147dfe465efaabca645ff5cef23d2a66) Thanks [@deetz99](https://github.com/deetz99)! - Create ConnectTombstone component. issue: bcgov/entity#29341
8
+
9
+ - [#62](https://github.com/bcgov/connect-nuxt/pull/62) [`6ff25af`](https://github.com/bcgov/connect-nuxt/commit/6ff25af994b1099582f632825e1c280a518ff59a) Thanks [@deetz99](https://github.com/deetz99)! - Create ConnectContactDisplay component. issue: bcgov/entity#29341
10
+
11
+ ## 0.1.17
12
+
13
+ ### Patch Changes
14
+
15
+ - [#60](https://github.com/bcgov/connect-nuxt/pull/60) [`b77b067`](https://github.com/bcgov/connect-nuxt/commit/b77b067c07962f79396064f14da87dd25a89a4d1) Thanks [@deetz99](https://github.com/deetz99)! - Update modal title font size, set floating labels to neutral instead of neutral-highlighted. issue: bcgov/entity#29341
16
+
3
17
  ## 0.1.16
4
18
 
5
19
  ### Patch Changes
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import type { ConnectContactItem } from '#imports'
3
+
4
+ const props = defineProps<{
5
+ contact: ConnectContactItem | ConnectContactItem[]
6
+ hours?: string
7
+ }>()
8
+
9
+ const iconMap = {
10
+ email: 'i-mdi-email',
11
+ phone: 'i-mdi-phone',
12
+ fax: 'i-mdi-fax'
13
+ }
14
+
15
+ const isMultipleContacts = computed(() => Array.isArray(props.contact))
16
+ const normalizedContact = computed(() => {
17
+ return isMultipleContacts.value ? props.contact as ConnectContactItem[] : [props.contact as ConnectContactItem]
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <div class="space-y-5">
23
+ <ul
24
+ v-if="isMultipleContacts"
25
+ class="space-y-1"
26
+ :aria-label="$t('connect.label.contactInformation')"
27
+ >
28
+ <li v-for="item in normalizedContact" :key="item.value">
29
+ <span class="inline-flex items-center gap-1">
30
+ <UIcon :name="iconMap[item.type]" class="mr-2 size-4 text-blue-350" />
31
+ {{ item.title }}
32
+ <span v-if="item.type === 'fax'">{{ item.value }}</span>
33
+ <a
34
+ v-else
35
+ class="text-primary underline"
36
+ :href="item.href"
37
+ :target="item.type === 'email' ? '_blank' : undefined"
38
+ >
39
+ {{ item.value }}
40
+ </a>
41
+ </span>
42
+ </li>
43
+ </ul>
44
+
45
+ <div v-else-if="normalizedContact[0]">
46
+ <span class="inline-flex items-center gap-1">
47
+ <UIcon :name="iconMap[normalizedContact[0].type]" class="mr-2 size-4 text-blue-350" />
48
+ {{ normalizedContact[0].title }}
49
+ <a
50
+ class="text-primary underline"
51
+ :href="normalizedContact[0].href"
52
+ :target="normalizedContact[0].type === 'email' ? '_blank' : undefined"
53
+ >
54
+ {{ normalizedContact[0].value }}
55
+ </a>
56
+ </span>
57
+ </div>
58
+
59
+ <p v-if="hours">
60
+ <strong class="text-neutral-highlighted">{{ $t('connect.label.hoursOfOperation') }}</strong>
61
+ <br>
62
+ {{ hours }}
63
+ </p>
64
+ </div>
65
+ </template>
@@ -19,7 +19,7 @@ defineEmits<{ close: [] }>()
19
19
  >
20
20
  <template #content>
21
21
  <div class="p-10 flex flex-col gap-6">
22
- <div class="flex flex-col gap-6 text-left">
22
+ <div class="flex flex-col gap-6 text-left text-2xl">
23
23
  <h2>
24
24
  {{ title }}
25
25
  </h2>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import type { ConnectTombstoneItem } from '#imports'
3
+
4
+ defineProps<ConnectTombstoneItem>()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="flex space-x-1">
9
+ <UIcon
10
+ v-if="icon"
11
+ v-bind="icon"
12
+ :class="itemClass || 'mt-1 text-primary'"
13
+ />
14
+ <UBadge
15
+ v-if="badge"
16
+ v-bind="badge"
17
+ :class="itemClass || 'px-3'"
18
+ />
19
+ <ULink
20
+ v-else-if="link"
21
+ v-bind="link"
22
+ :class="itemClass || 'mt-[2px] text-sm text-primary underline'"
23
+ >
24
+ {{ link.label }}
25
+ </ULink>
26
+ <component
27
+ :is="vNode"
28
+ v-else-if="vNode"
29
+ />
30
+ <p
31
+ v-else-if="text"
32
+ :class="itemClass || 'mt-[2px] text-sm'"
33
+ >
34
+ {{ text }}
35
+ </p>
36
+ </div>
37
+ </template>
@@ -0,0 +1,123 @@
1
+ <script setup lang="ts">
2
+ import type { ButtonProps } from '@nuxt/ui'
3
+
4
+ const props = defineProps<{ stateKey: string }>()
5
+
6
+ const { tombstone } = useConnectTombstone(props.stateKey)
7
+
8
+ async function handleButtonAction(button: ButtonProps, event: MouseEvent) {
9
+ button.loading = true
10
+ if (button.onClick) {
11
+ if (Array.isArray(button.onClick)) {
12
+ await Promise.all(button.onClick.map(fn => fn(event)))
13
+ } else if (button.onClick) {
14
+ await button.onClick(event)
15
+ }
16
+ }
17
+ button.loading = false
18
+ }
19
+ </script>
20
+
21
+ <template>
22
+ <div class="bg-white py-8 px-2 sm:px-4">
23
+ <div class="app-inner-container">
24
+ <div
25
+ v-if="tombstone.loading"
26
+ class="flex flex-col gap-2 *:space-y-2 sm:flex-row"
27
+ >
28
+ <slot name="loading">
29
+ <div class="grow">
30
+ <USkeleton class="h-9 w-[400px] rounded" />
31
+ <USkeleton class="h-5 w-[250px] rounded" />
32
+ <USkeleton class="h-5 w-[200px] rounded" />
33
+ <USkeleton class="h-5 w-[150px] rounded" />
34
+ </div>
35
+ <div>
36
+ <USkeleton class="h-5 w-[300px] rounded" />
37
+ <USkeleton class="h-5 w-[300px] rounded" />
38
+ <USkeleton class="h-5 w-[300px] rounded" />
39
+ <USkeleton class="h-5 w-[300px] rounded" />
40
+ </div>
41
+ </slot>
42
+ </div>
43
+ <div
44
+ v-else
45
+ class="flex flex-col gap-2 sm:flex-row"
46
+ >
47
+ <div class="grow space-y-4">
48
+ <div>
49
+ <slot name="title">
50
+ <component
51
+ :is="tombstone.title.as"
52
+ class="text-[1.375rem] font-bold text-neutral-highlighted"
53
+ >
54
+ {{ tombstone.title.text }}
55
+ </component>
56
+ </slot>
57
+ <slot name="subtitles">
58
+ <div
59
+ v-if="tombstone.subtitles.length"
60
+ class="flex divide-x divide-gray-500"
61
+ >
62
+ <ConnectTombstoneItem
63
+ v-for="subtitle, i in tombstone.subtitles"
64
+ :key="'subtitle-' + i"
65
+ v-bind="subtitle"
66
+ class="px-2"
67
+ :class="i === 0 ? 'pl-0' : ''"
68
+ />
69
+ </div>
70
+ </slot>
71
+ </div>
72
+ <div class="space-y-1">
73
+ <slot name="details">
74
+ <div class="flex space-x-2">
75
+ <div
76
+ v-for="detail, i in tombstone.details"
77
+ :key="'detail-' + i"
78
+ >
79
+ <ConnectTombstoneItem v-bind="detail" />
80
+ </div>
81
+ </div>
82
+ </slot>
83
+ <slot name="buttons">
84
+ <div
85
+ v-if="tombstone.bottomButtons.length"
86
+ class="flex flex-wrap gap-2"
87
+ >
88
+ <template v-for="btn in tombstone.bottomButtons" :key="btn.button?.label || btn.vNode?.key">
89
+ <component :is="btn.vNode" v-if="btn.vNode" />
90
+ <UButton
91
+ v-else-if="btn.button"
92
+ v-bind="{
93
+ ...btn.button,
94
+ onClick(event) {
95
+ handleButtonAction(btn.button!, event)
96
+ },
97
+ }"
98
+ />
99
+ </template>
100
+ </div>
101
+ </slot>
102
+ </div>
103
+ </div>
104
+ <slot name="sideDetails">
105
+ <dl class="space-y-1 text-sm">
106
+ <div
107
+ v-for="detail in tombstone.sideDetails"
108
+ :key="detail.label"
109
+ class="flex flex-row flex-wrap gap-2"
110
+ >
111
+ <dt class="font-bold text-neutral-highlighted">
112
+ {{ detail.label }}:
113
+ </dt>
114
+ <dd>
115
+ {{ detail.value }}
116
+ </dd>
117
+ </div>
118
+ </dl>
119
+ </slot>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </template>
@@ -0,0 +1,22 @@
1
+ export const useConnectTombstone = (stateKey: string, initialState?: Partial<ConnectTombstoneState>) => {
2
+ function createInitialState(): ConnectTombstoneState {
3
+ const baseState: ConnectTombstoneState = {
4
+ loading: false,
5
+ title: {} as ConnectTombstoneTitle,
6
+ subtitles: [],
7
+ details: [],
8
+ sideDetails: [],
9
+ bottomButtons: []
10
+ }
11
+
12
+ return { ...baseState, ...initialState }
13
+ }
14
+
15
+ const tombstone = useState<ConnectTombstoneState>(stateKey, () => createInitialState())
16
+
17
+ function $reset() {
18
+ tombstone.value = createInitialState()
19
+ }
20
+
21
+ return { tombstone, $reset }
22
+ }
@@ -0,0 +1,6 @@
1
+ export interface ConnectContactItem {
2
+ type: 'email' | 'phone' | 'fax'
3
+ title: string
4
+ value: string
5
+ href?: string
6
+ }
@@ -0,0 +1,39 @@
1
+ import type { ButtonProps, IconProps, BadgeProps, LinkProps } from '@nuxt/ui'
2
+ import type { VNode } from 'vue'
3
+
4
+ export interface ConnectTombstoneSideDetail {
5
+ label: string
6
+ value: string
7
+ }
8
+
9
+ export interface ConnectTombstoneTitle {
10
+ text: string
11
+ as: 'span' | 'p' | 'div' | 'h1' | 'h2' | 'h3' | 'h4'
12
+ }
13
+
14
+ export interface ConnectTombstoneLink extends LinkProps {
15
+ label?: string
16
+ }
17
+
18
+ export interface ConnectTombstoneItem {
19
+ text?: string
20
+ itemClass?: string
21
+ icon?: IconProps
22
+ badge?: BadgeProps
23
+ link?: ConnectTombstoneLink
24
+ vNode?: VNode
25
+ }
26
+
27
+ export type ConnectTombstoneBtn = {
28
+ button?: ButtonProps
29
+ vNode?: VNode
30
+ }
31
+
32
+ export interface ConnectTombstoneState {
33
+ loading: boolean
34
+ title: ConnectTombstoneTitle
35
+ subtitles: ConnectTombstoneItem[]
36
+ details: ConnectTombstoneItem[]
37
+ sideDetails: ConnectTombstoneSideDetail[]
38
+ bottomButtons: ConnectTombstoneBtn[]
39
+ }
@@ -21,12 +21,14 @@ export default {
21
21
  appVersion: 'App Version',
22
22
  bcApp: 'A BC Online Application',
23
23
  bcGovLogo: 'Government of British Columbia Logo',
24
+ contactInformation: 'Contact Information',
24
25
  copyright: 'Copyright',
25
26
  disclaimer: 'Disclaimer',
26
27
  fees: 'Fees',
27
28
  goBack: 'Go Back',
28
29
  goHome: 'Go Home',
29
30
  home: 'Home',
31
+ hoursOfOperation: 'Hours of Operation',
30
32
  localeSelect: 'Select a Language, current language: English',
31
33
  privacy: 'Privacy',
32
34
  releaseNotes: 'Release Notes',
@@ -269,11 +269,11 @@ body {
269
269
 
270
270
  /* floating labels */
271
271
  .floating-label-input {
272
- @apply pointer-events-none absolute left-0 top-3 text-neutral-highlighted transition-all motion-reduce:transition-none duration-200 text-xs font-medium px-2.5 peer-focus:top-3 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-1/2 -translate-y-1/2 peer-focus:text-primary peer-aria-invalid:text-error;
272
+ @apply pointer-events-none absolute left-0 top-3 text-neutral transition-all motion-reduce:transition-none duration-200 text-xs font-medium px-2.5 peer-focus:top-3 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-1/2 -translate-y-1/2 peer-focus:text-primary peer-aria-invalid:text-error;
273
273
  }
274
274
 
275
275
  .floating-label-textarea {
276
- @apply pointer-events-none absolute left-0 top-1 text-neutral-highlighted text-xs font-medium px-2.5 transition-all duration-200 peer-focus:top-1 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-2.5 peer-focus:translate-none peer-focus:text-primary peer-aria-invalid:text-error;
276
+ @apply pointer-events-none absolute left-0 top-1 text-neutral text-xs font-medium px-2.5 transition-all duration-200 peer-focus:top-1 peer-focus:text-xs peer-placeholder-shown:text-sm peer-placeholder-shown:top-2.5 peer-focus:translate-none peer-focus:text-primary peer-aria-invalid:text-error;
277
277
  }
278
278
  }
279
279
 
package/nuxt.config.ts CHANGED
@@ -120,6 +120,10 @@ export default defineNuxtConfig({
120
120
  }
121
121
  },
122
122
 
123
+ typescript: {
124
+ includeWorkspace: true // fixes auto imports in tests
125
+ },
126
+
123
127
  runtimeConfig: {
124
128
  public: {
125
129
  // Should in alphabetical order
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sbc-connect/nuxt-base",
3
3
  "type": "module",
4
- "version": "0.1.16",
4
+ "version": "0.1.18",
5
5
  "repository": "github:bcgov/connect-nuxt",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "./nuxt.config.ts",