@sbc-connect/nuxt-base 0.0.0-test-ld-20260520212549
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/.env.example +11 -0
- package/CHANGELOG.md +338 -0
- package/LICENSE +28 -0
- package/README.md +55 -0
- package/app/app.config.ts +441 -0
- package/app/app.vue +18 -0
- package/app/assets/css/connect-base-layout.css +13 -0
- package/app/assets/css/connect-base-tw.css +303 -0
- package/app/components/Connect/Address/Display.vue +84 -0
- package/app/components/Connect/BCGovLogo.vue +42 -0
- package/app/components/Connect/Breadcrumb.vue +68 -0
- package/app/components/Connect/ButtonControl/Buttons.vue +28 -0
- package/app/components/Connect/ButtonControl/Index.vue +66 -0
- package/app/components/Connect/ButtonControl/Wrapper.vue +18 -0
- package/app/components/Connect/Contact/Display.vue +65 -0
- package/app/components/Connect/FloatingLabel.vue +67 -0
- package/app/components/Connect/Footer.vue +99 -0
- package/app/components/Connect/Header/LogoHomeLink.vue +20 -0
- package/app/components/Connect/Header/WhatsNew.vue +36 -0
- package/app/components/Connect/Header/Wrapper.vue +14 -0
- package/app/components/Connect/Header/index.vue +17 -0
- package/app/components/Connect/I18n/Helper.vue +40 -0
- package/app/components/Connect/Input.vue +69 -0
- package/app/components/Connect/InputDate.vue +104 -0
- package/app/components/Connect/Layout/Index.vue +25 -0
- package/app/components/Connect/Layout/Sidebar.vue +38 -0
- package/app/components/Connect/LocaleSelect.vue +37 -0
- package/app/components/Connect/Modal/Error.vue +76 -0
- package/app/components/Connect/Modal/index.vue +51 -0
- package/app/components/Connect/PageSection.vue +57 -0
- package/app/components/Connect/Select.vue +28 -0
- package/app/components/Connect/Slideover/WhatsNew.vue +61 -0
- package/app/components/Connect/Spinner.vue +91 -0
- package/app/components/Connect/SystemBanner.vue +53 -0
- package/app/components/Connect/Textarea.vue +27 -0
- package/app/components/Connect/Tombstone/Item.vue +51 -0
- package/app/components/Connect/Tombstone/index.vue +123 -0
- package/app/components/Connect/Transition/Collapse.vue +39 -0
- package/app/components/Connect/Transition/Fade.vue +31 -0
- package/app/components/HelloWorld/Index.vue +14 -0
- package/app/composables/useConnectButtonControl.ts +146 -0
- package/app/composables/useConnectLaunchDarkly.ts +173 -0
- package/app/composables/useConnectModal.ts +13 -0
- package/app/composables/useConnectTombstone.ts +25 -0
- package/app/coverage/app/app.config.ts.html +1408 -0
- package/app/coverage/app/app.vue.html +139 -0
- package/app/coverage/app/components/Connect/Address/Display.vue.html +337 -0
- package/app/coverage/app/components/Connect/Address/index.html +116 -0
- package/app/coverage/app/components/Connect/BCGovLogo.vue.html +211 -0
- package/app/coverage/app/components/Connect/Breadcrumb.vue.html +289 -0
- package/app/coverage/app/components/Connect/ButtonControl/Buttons.vue.html +166 -0
- package/app/coverage/app/components/Connect/ButtonControl/Index.vue.html +283 -0
- package/app/coverage/app/components/Connect/ButtonControl/Wrapper.vue.html +139 -0
- package/app/coverage/app/components/Connect/ButtonControl/index.html +146 -0
- package/app/coverage/app/components/Connect/Contact/Display.vue.html +280 -0
- package/app/coverage/app/components/Connect/Contact/index.html +116 -0
- package/app/coverage/app/components/Connect/FloatingLabel.vue.html +286 -0
- package/app/coverage/app/components/Connect/Footer.vue.html +382 -0
- package/app/coverage/app/components/Connect/Header/LogoHomeLink.vue.html +145 -0
- package/app/coverage/app/components/Connect/Header/WhatsNew.vue.html +193 -0
- package/app/coverage/app/components/Connect/Header/Wrapper.vue.html +127 -0
- package/app/coverage/app/components/Connect/Header/index.html +161 -0
- package/app/coverage/app/components/Connect/Header/index.vue.html +136 -0
- package/app/coverage/app/components/Connect/I18n/Helper.vue.html +205 -0
- package/app/coverage/app/components/Connect/I18n/index.html +116 -0
- package/app/coverage/app/components/Connect/Input.vue.html +262 -0
- package/app/coverage/app/components/Connect/InputDate.vue.html +406 -0
- package/app/coverage/app/components/Connect/Layout/Index.vue.html +160 -0
- package/app/coverage/app/components/Connect/Layout/Sidebar.vue.html +199 -0
- package/app/coverage/app/components/Connect/Layout/index.html +131 -0
- package/app/coverage/app/components/Connect/LocaleSelect.vue.html +196 -0
- package/app/coverage/app/components/Connect/Modal/Error.vue.html +313 -0
- package/app/coverage/app/components/Connect/Modal/index.html +131 -0
- package/app/coverage/app/components/Connect/Modal/index.vue.html +238 -0
- package/app/coverage/app/components/Connect/PageSection.vue.html +256 -0
- package/app/coverage/app/components/Connect/Select.vue.html +169 -0
- package/app/coverage/app/components/Connect/Slideover/WhatsNew.vue.html +268 -0
- package/app/coverage/app/components/Connect/Slideover/index.html +116 -0
- package/app/coverage/app/components/Connect/Spinner.vue.html +358 -0
- package/app/coverage/app/components/Connect/SystemBanner.vue.html +244 -0
- package/app/coverage/app/components/Connect/Textarea.vue.html +160 -0
- package/app/coverage/app/components/Connect/Tombstone/Item.vue.html +238 -0
- package/app/coverage/app/components/Connect/Tombstone/index.html +131 -0
- package/app/coverage/app/components/Connect/Tombstone/index.vue.html +454 -0
- package/app/coverage/app/components/Connect/Transition/Collapse.vue.html +202 -0
- package/app/coverage/app/components/Connect/Transition/Fade.vue.html +178 -0
- package/app/coverage/app/components/Connect/Transition/index.html +131 -0
- package/app/coverage/app/components/Connect/index.html +281 -0
- package/app/coverage/app/components/HelloWorld/Index.vue.html +127 -0
- package/app/coverage/app/components/HelloWorld/index.html +116 -0
- package/app/coverage/app/composables/index.html +161 -0
- package/app/coverage/app/composables/useConnectButtonControl.ts.html +523 -0
- package/app/coverage/app/composables/useConnectLaunchDarkly.ts.html +595 -0
- package/app/coverage/app/composables/useConnectModal.ts.html +124 -0
- package/app/coverage/app/composables/useConnectTombstone.ts.html +160 -0
- package/app/coverage/app/error.vue.html +247 -0
- package/app/coverage/app/index.html +146 -0
- package/app/coverage/app/interfaces/connect-address.ts.html +121 -0
- package/app/coverage/app/interfaces/connect-breadcrumb.ts.html +100 -0
- package/app/coverage/app/interfaces/connect-button-control.ts.html +151 -0
- package/app/coverage/app/interfaces/connect-contact-item.ts.html +103 -0
- package/app/coverage/app/interfaces/connect-modal.ts.html +100 -0
- package/app/coverage/app/interfaces/connect-tombstone.ts.html +208 -0
- package/app/coverage/app/interfaces/connect-whatsnew.ts.html +127 -0
- package/app/coverage/app/interfaces/index.html +206 -0
- package/app/coverage/app/layouts/ConnectBase.vue.html +100 -0
- package/app/coverage/app/layouts/index.html +116 -0
- package/app/coverage/app/plugins/index.html +146 -0
- package/app/coverage/app/plugins/maska.client.ts.html +115 -0
- package/app/coverage/app/plugins/sanitize.client.ts.html +151 -0
- package/app/coverage/app/plugins/whats-new.client.ts.html +220 -0
- package/app/coverage/app/types/dates.ts.html +136 -0
- package/app/coverage/app/types/index.html +116 -0
- package/app/coverage/app/utils/appendUrlParam.ts.html +97 -0
- package/app/coverage/app/utils/getErrorMessage.ts.html +211 -0
- package/app/coverage/app/utils/getErrorStatus.ts.html +196 -0
- package/app/coverage/app/utils/index.html +191 -0
- package/app/coverage/app/utils/logFetchError.ts.html +193 -0
- package/app/coverage/app/utils/parseSpecialCharacters.ts.html +160 -0
- package/app/coverage/app/utils/setBreadcrumbs.ts.html +100 -0
- package/app/coverage/base.css +224 -0
- package/app/coverage/block-navigation.js +87 -0
- package/app/coverage/clover.xml +2094 -0
- package/app/coverage/coverage-final.json +58 -0
- package/app/coverage/favicon.png +0 -0
- package/app/coverage/index.html +386 -0
- package/app/coverage/prettify.css +1 -0
- package/app/coverage/prettify.js +2 -0
- package/app/coverage/sort-arrow-sprite.png +0 -0
- package/app/coverage/sorter.js +210 -0
- package/app/error.vue +54 -0
- package/app/interfaces/connect-address.ts +12 -0
- package/app/interfaces/connect-breadcrumb.ts +5 -0
- package/app/interfaces/connect-button-control.ts +23 -0
- package/app/interfaces/connect-contact-item.ts +6 -0
- package/app/interfaces/connect-modal.ts +5 -0
- package/app/interfaces/connect-tombstone.ts +41 -0
- package/app/interfaces/connect-whatsnew.ts +14 -0
- package/app/layouts/ConnectBase.vue +5 -0
- package/app/plugins/maska.client.ts +10 -0
- package/app/plugins/sanitize.client.ts +22 -0
- package/app/plugins/whats-new.client.ts +45 -0
- package/app/spa-loading-template.html +61 -0
- package/app/types/base-app-config.d.ts +15 -0
- package/app/types/base-directives.d.ts +7 -0
- package/app/types/base-page-meta.d.ts +8 -0
- package/app/types/dates.ts +17 -0
- package/app/utils/appendUrlParam.ts +4 -0
- package/app/utils/getErrorMessage.ts +42 -0
- package/app/utils/getErrorStatus.ts +37 -0
- package/app/utils/logFetchError.ts +36 -0
- package/app/utils/parseSpecialCharacters.ts +25 -0
- package/app/utils/setBreadcrumbs.ts +7 -0
- package/firebase.json +34 -0
- package/i18n/locales/en-CA.ts +70 -0
- package/i18n/locales/fr-CA.ts +96 -0
- package/nuxt.config.ts +147 -0
- package/package.json +49 -0
- package/public/BCGovLogo/gov_bc_logo_horiz_en.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_horiz_fr.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_vert_en.png +0 -0
- package/public/BCGovLogo/gov_bc_logo_vert_fr.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/fonts/BCSans/BCSans-Bold.woff +0 -0
- package/public/fonts/BCSans/BCSans-Bold.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-BoldItalic.woff +0 -0
- package/public/fonts/BCSans/BCSans-BoldItalic.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-Italic.woff +0 -0
- package/public/fonts/BCSans/BCSans-Italic.woff2 +0 -0
- package/public/fonts/BCSans/BCSans-Regular.woff +0 -0
- package/public/fonts/BCSans/BCSans-Regular.woff2 +0 -0
- package/public/fonts/BCSans/LICENSE_OFL.txt +94 -0
- package/test-results/.last-run.json +7 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/error-context.md +135 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/test-failed-1.png +0 -0
- package/test-results/error-page-404-Error-vue-D-1eb51-cted-visuals-with-404-error-Desktop-Chrome/trace.zip +0 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/error-context.md +135 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/test-failed-1.png +0 -0
- package/test-results/error-page-500-Error-vue-D-8c2cf-cted-visuals-with-500-error-Desktop-Chrome/trace.zip +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const isSmallScreen = useMediaQuery('(max-width: 640px)')
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
title: string
|
|
6
|
+
description: string
|
|
7
|
+
dismissible: boolean
|
|
8
|
+
buttons?: ConnectModalButton[]
|
|
9
|
+
}>()
|
|
10
|
+
defineEmits<{ close: [] }>()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<UModal
|
|
15
|
+
overlay
|
|
16
|
+
:title
|
|
17
|
+
:description
|
|
18
|
+
:dismissible
|
|
19
|
+
>
|
|
20
|
+
<template #content>
|
|
21
|
+
<div class="p-10 flex flex-col gap-6">
|
|
22
|
+
<div class="flex flex-col gap-6 text-left">
|
|
23
|
+
<h2 class="text-2xl">
|
|
24
|
+
{{ title }}
|
|
25
|
+
</h2>
|
|
26
|
+
<p class="-mt-2">
|
|
27
|
+
{{ description }}
|
|
28
|
+
</p>
|
|
29
|
+
</div>
|
|
30
|
+
<div v-if="buttons && buttons.length" class="flex flex-wrap items-center justify-center gap-4">
|
|
31
|
+
<template
|
|
32
|
+
v-for="button in buttons"
|
|
33
|
+
:key="button.label"
|
|
34
|
+
>
|
|
35
|
+
<UButton
|
|
36
|
+
v-if="button.shouldClose"
|
|
37
|
+
v-bind="button"
|
|
38
|
+
:block="isSmallScreen"
|
|
39
|
+
@click="$emit('close')"
|
|
40
|
+
/>
|
|
41
|
+
<UButton
|
|
42
|
+
v-else
|
|
43
|
+
v-bind="button"
|
|
44
|
+
:block="isSmallScreen"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
</UModal>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { ButtonProps } from '#ui/types'
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
heading?: {
|
|
6
|
+
label?: string
|
|
7
|
+
labelClass?: string
|
|
8
|
+
level?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
|
|
9
|
+
icon?: string
|
|
10
|
+
iconClass?: string
|
|
11
|
+
ui?: string
|
|
12
|
+
}
|
|
13
|
+
uiBody?: string
|
|
14
|
+
actions?: ButtonProps[]
|
|
15
|
+
}>()
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<UCard
|
|
20
|
+
as="section"
|
|
21
|
+
class="w-full"
|
|
22
|
+
variant="outline"
|
|
23
|
+
:ui="{
|
|
24
|
+
header: heading?.ui ?? 'bg-shade-secondary px-4 py-4 sm:px-4 rounded-t-md',
|
|
25
|
+
body: uiBody ?? 'p-0 sm:p-0',
|
|
26
|
+
footer: 'p-0 sm:p-0',
|
|
27
|
+
}"
|
|
28
|
+
>
|
|
29
|
+
<template v-if="heading?.label || $slots.header" #header>
|
|
30
|
+
<slot name="header">
|
|
31
|
+
<div class="flex items-center justify-between gap-2.5">
|
|
32
|
+
<component :is="heading?.level || 'h2'">
|
|
33
|
+
<div class="flex items-center gap-2.5">
|
|
34
|
+
<UIcon
|
|
35
|
+
v-if="heading?.icon"
|
|
36
|
+
:name="heading.icon"
|
|
37
|
+
:class="heading?.iconClass || 'size-6 shrink-0 text-primary'"
|
|
38
|
+
/>
|
|
39
|
+
<span :class="heading?.labelClass || 'font-semibold text-neutral-highlighted text-base'">
|
|
40
|
+
{{ heading?.label }}
|
|
41
|
+
</span>
|
|
42
|
+
</div>
|
|
43
|
+
</component>
|
|
44
|
+
|
|
45
|
+
<div class="flex items-center gap-2.5">
|
|
46
|
+
<UButton
|
|
47
|
+
v-for="(action, i) in actions"
|
|
48
|
+
:key="i"
|
|
49
|
+
v-bind="action"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</slot>
|
|
54
|
+
</template>
|
|
55
|
+
<slot />
|
|
56
|
+
</UCard>
|
|
57
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
id: string
|
|
4
|
+
label: string
|
|
5
|
+
}>()
|
|
6
|
+
|
|
7
|
+
defineEmits<{
|
|
8
|
+
change: []
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
const labelId = props.id + '-label'
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<ConnectFloatingLabel
|
|
16
|
+
:id="labelId"
|
|
17
|
+
:label
|
|
18
|
+
variant="select"
|
|
19
|
+
>
|
|
20
|
+
<USelect
|
|
21
|
+
:id
|
|
22
|
+
:data-testid="id"
|
|
23
|
+
:aria-labelledby="labelId"
|
|
24
|
+
v-bind="$attrs"
|
|
25
|
+
@change="$emit('change')"
|
|
26
|
+
/>
|
|
27
|
+
</ConnectFloatingLabel>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const { $sanitize } = useNuxtApp()
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
items: ConnectWhatsNewItem[]
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<USlideover
|
|
11
|
+
:title="$t('connect.label.whatsNewSlideover')"
|
|
12
|
+
:description="$t('connect.text.whatsNewSlideoverDescription')"
|
|
13
|
+
:overlay="false"
|
|
14
|
+
:close="{
|
|
15
|
+
color: 'neutral',
|
|
16
|
+
variant: 'ghost',
|
|
17
|
+
class: 'cursor-pointer hover:bg-shade/50 focus-visible:bg-transparent focus-visible:ring-2 rounded-full',
|
|
18
|
+
}"
|
|
19
|
+
:ui="{
|
|
20
|
+
header: 'bg-brand-inverted',
|
|
21
|
+
title: 'text-brand',
|
|
22
|
+
body: 'flex-1 overflow-y-auto p-0 sm:p-0',
|
|
23
|
+
description: 'sr-only',
|
|
24
|
+
}"
|
|
25
|
+
>
|
|
26
|
+
<template #body>
|
|
27
|
+
<div class="overflow-y-auto text-neutral">
|
|
28
|
+
<div class="flex-1">
|
|
29
|
+
<ol v-if="items.length">
|
|
30
|
+
<li
|
|
31
|
+
v-for="item, i in items"
|
|
32
|
+
:key="i"
|
|
33
|
+
class="flex flex-col border-b border-gray-500 p-4 last:border-0"
|
|
34
|
+
>
|
|
35
|
+
<h3 class="text-lg font-bold">
|
|
36
|
+
{{ item.title }}
|
|
37
|
+
</h3>
|
|
38
|
+
<time class="text-sm">{{ item.date }}</time>
|
|
39
|
+
<!-- eslint-disable vue/no-v-html -->
|
|
40
|
+
<div
|
|
41
|
+
class="pt-3 vhtml"
|
|
42
|
+
v-html="$sanitize(item.description)"
|
|
43
|
+
/>
|
|
44
|
+
</li>
|
|
45
|
+
</ol>
|
|
46
|
+
<div v-else class="flex justify-center py-10">
|
|
47
|
+
<span>{{ $t('connect.text.whatsNewSlideoverEmpty') }}</span>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
</USlideover>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<!-- must style globally for vhtml style to work -->
|
|
56
|
+
<style>
|
|
57
|
+
.vhtml a {
|
|
58
|
+
color: var(--ui-mark);
|
|
59
|
+
text-decoration: underline;
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const {
|
|
3
|
+
fullscreen = false,
|
|
4
|
+
size = 75
|
|
5
|
+
} = defineProps<{
|
|
6
|
+
fullscreen?: boolean
|
|
7
|
+
size?: number
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const spinnerStyle = computed(() => ({
|
|
11
|
+
'--spinner-size': `${size}px`,
|
|
12
|
+
'--spinner-margin': `${size / -2}px`
|
|
13
|
+
}))
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<!-- eslint-disable tailwindcss/no-custom-classname -->
|
|
18
|
+
<Teleport v-if="fullscreen" to="body">
|
|
19
|
+
<div class="fixed inset-0 z-[999] h-screen w-screen bg-gray-100 opacity-50" />
|
|
20
|
+
<svg
|
|
21
|
+
class="spinner fixed"
|
|
22
|
+
viewBox="0 0 50 50"
|
|
23
|
+
:style="spinnerStyle"
|
|
24
|
+
>
|
|
25
|
+
<circle
|
|
26
|
+
class="path"
|
|
27
|
+
cx="25"
|
|
28
|
+
cy="25"
|
|
29
|
+
r="20"
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke-width="5"
|
|
32
|
+
/>
|
|
33
|
+
</svg>
|
|
34
|
+
</Teleport>
|
|
35
|
+
<svg
|
|
36
|
+
v-else
|
|
37
|
+
class="spinner absolute"
|
|
38
|
+
viewBox="0 0 50 50"
|
|
39
|
+
:style="spinnerStyle"
|
|
40
|
+
>
|
|
41
|
+
<circle
|
|
42
|
+
class="path"
|
|
43
|
+
cx="25"
|
|
44
|
+
cy="25"
|
|
45
|
+
r="20"
|
|
46
|
+
fill="none"
|
|
47
|
+
stroke-width="5"
|
|
48
|
+
/>
|
|
49
|
+
</svg>
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
<style scoped>
|
|
53
|
+
.spinner {
|
|
54
|
+
animation: rotate 1.5s linear infinite;
|
|
55
|
+
z-index: 10000;
|
|
56
|
+
top: 50%;
|
|
57
|
+
left: 50%;
|
|
58
|
+
margin-top: var(--spinner-margin, -37.5px);
|
|
59
|
+
margin-left: var(--spinner-margin, -37.5px);
|
|
60
|
+
width: var(--spinner-size, 75px);
|
|
61
|
+
height: var(--spinner-size, 75px);
|
|
62
|
+
transform-origin: 50% 50%;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.spinner .path {
|
|
66
|
+
stroke: #1669bb;
|
|
67
|
+
stroke-linecap: round;
|
|
68
|
+
animation: dash 1.25s ease-in-out infinite;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@keyframes rotate {
|
|
72
|
+
100% {
|
|
73
|
+
transform: rotate(360deg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@keyframes dash {
|
|
78
|
+
0% {
|
|
79
|
+
stroke-dasharray: 1, 150;
|
|
80
|
+
stroke-dashoffset: 0;
|
|
81
|
+
}
|
|
82
|
+
50% {
|
|
83
|
+
stroke-dasharray: 90, 150;
|
|
84
|
+
stroke-dashoffset: -35;
|
|
85
|
+
}
|
|
86
|
+
100% {
|
|
87
|
+
stroke-dasharray: 90, 150;
|
|
88
|
+
stroke-dashoffset: -124;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const ld = useConnectLaunchDarkly()
|
|
3
|
+
const { $sanitize } = useNuxtApp()
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
dismissible = false,
|
|
7
|
+
icon = 'i-mdi-information'
|
|
8
|
+
} = defineProps<{
|
|
9
|
+
dismissible?: boolean
|
|
10
|
+
icon?: string
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const close = ref(false)
|
|
14
|
+
const message = ref('')
|
|
15
|
+
onMounted(async () => {
|
|
16
|
+
message.value = $sanitize(await ld.getStoredFlag('banner-text', '', 'await'))
|
|
17
|
+
})
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div id="connect-system-banner" class="bg-brand-inverted px-2 sm:px-4">
|
|
22
|
+
<UAlert
|
|
23
|
+
v-show="!!message && !close"
|
|
24
|
+
class="py-0"
|
|
25
|
+
:description="message"
|
|
26
|
+
:close="dismissible"
|
|
27
|
+
close-icon="i-mdi-close"
|
|
28
|
+
:ui="{
|
|
29
|
+
root: 'rounded-none bg-brand-inverted px-0 sm:px-0 app-inner-container',
|
|
30
|
+
wrapper: 'bg-brand-inverted',
|
|
31
|
+
close: 'mt-2 text-neutral-highlighted',
|
|
32
|
+
}"
|
|
33
|
+
@update:open="close = true"
|
|
34
|
+
>
|
|
35
|
+
<!-- dismissible ? { class: 'pr-2 text-neutral-highlighted' } : null -->
|
|
36
|
+
<template #description>
|
|
37
|
+
<div class="flex gap-2 items-center py-2">
|
|
38
|
+
<UIcon class="size-7 shrink-0 text-neutral-highlighted self-start" :name="icon" />
|
|
39
|
+
<!-- eslint-disable vue/no-v-html tailwindcss/no-custom-classname -->
|
|
40
|
+
<p class="vhtml text-neutral-highlighted" v-html="message" />
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
</UAlert>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<!-- must style globally for vhtml style to work -->
|
|
48
|
+
<style>
|
|
49
|
+
.vhtml > a {
|
|
50
|
+
color: var(--ui-neutral-highlighted);
|
|
51
|
+
text-decoration: underline;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { TextareaProps } from '@nuxt/ui'
|
|
3
|
+
|
|
4
|
+
const model = defineModel<Exclude<TextareaProps['modelValue'], null>>({ required: true })
|
|
5
|
+
|
|
6
|
+
defineProps<{
|
|
7
|
+
id: string
|
|
8
|
+
label: string
|
|
9
|
+
}>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<UTextarea
|
|
14
|
+
:id
|
|
15
|
+
v-model.trim="model"
|
|
16
|
+
:data-testid="id"
|
|
17
|
+
placeholder=" "
|
|
18
|
+
class="w-full grow"
|
|
19
|
+
>
|
|
20
|
+
<label
|
|
21
|
+
class="floating-label-textarea bg-shade w-[96%] flex-1 pt-1 -mt-1"
|
|
22
|
+
:for="id"
|
|
23
|
+
>
|
|
24
|
+
{{ label }}
|
|
25
|
+
</label>
|
|
26
|
+
</UTextarea>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { IconProps, BadgeProps, LinkProps } from '@nuxt/ui'
|
|
3
|
+
import type { VNode } from 'vue'
|
|
4
|
+
|
|
5
|
+
interface ConnectTombstoneLink extends LinkProps {
|
|
6
|
+
label?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// cant use imported interface here as it causes vue compiler to break when extended
|
|
10
|
+
// must also update connect-tombstone interface if changing these props
|
|
11
|
+
defineProps<{
|
|
12
|
+
text?: string
|
|
13
|
+
itemClass?: string
|
|
14
|
+
icon?: IconProps
|
|
15
|
+
badge?: BadgeProps
|
|
16
|
+
link?: ConnectTombstoneLink
|
|
17
|
+
vNode?: VNode
|
|
18
|
+
}>()
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<div class="flex space-x-1">
|
|
23
|
+
<UIcon
|
|
24
|
+
v-if="icon"
|
|
25
|
+
v-bind="icon"
|
|
26
|
+
:class="itemClass || 'mt-1 text-primary'"
|
|
27
|
+
/>
|
|
28
|
+
<UBadge
|
|
29
|
+
v-if="badge"
|
|
30
|
+
v-bind="badge"
|
|
31
|
+
:class="itemClass || 'px-3'"
|
|
32
|
+
/>
|
|
33
|
+
<ULink
|
|
34
|
+
v-else-if="link"
|
|
35
|
+
v-bind="link"
|
|
36
|
+
:class="itemClass || 'mt-[2px] text-sm text-primary underline'"
|
|
37
|
+
>
|
|
38
|
+
{{ link.label }}
|
|
39
|
+
</ULink>
|
|
40
|
+
<component
|
|
41
|
+
:is="vNode"
|
|
42
|
+
v-else-if="vNode"
|
|
43
|
+
/>
|
|
44
|
+
<p
|
|
45
|
+
v-else-if="text"
|
|
46
|
+
:class="itemClass || 'mt-[2px] text-sm'"
|
|
47
|
+
>
|
|
48
|
+
{{ text }}
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
</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" data-testid="connect-tombstone-wrapper">
|
|
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,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Transition name="collapse">
|
|
3
|
+
<slot />
|
|
4
|
+
</Transition>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<style>
|
|
8
|
+
.collapse-enter-active,
|
|
9
|
+
.collapse-leave-active {
|
|
10
|
+
transition: max-height 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
|
11
|
+
}
|
|
12
|
+
.collapse-enter-from,
|
|
13
|
+
.collapse-leave-to {
|
|
14
|
+
max-height: 0;
|
|
15
|
+
opacity: 0;
|
|
16
|
+
}
|
|
17
|
+
.collapse-enter-to,
|
|
18
|
+
.collapse-leave-from {
|
|
19
|
+
max-height: 1000px;
|
|
20
|
+
opacity: 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@media (prefers-reduced-motion) {
|
|
24
|
+
.collapse-enter-active,
|
|
25
|
+
.collapse-leave-active {
|
|
26
|
+
transition: max-height 0s ease-out, opacity 0s ease-out;
|
|
27
|
+
}
|
|
28
|
+
.collapse-enter-from,
|
|
29
|
+
.collapse-leave-to {
|
|
30
|
+
max-height: 0;
|
|
31
|
+
opacity: 0;
|
|
32
|
+
}
|
|
33
|
+
.collapse-enter-to,
|
|
34
|
+
.collapse-leave-from {
|
|
35
|
+
max-height: 1000px;
|
|
36
|
+
opacity: 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Transition name="fade">
|
|
3
|
+
<slot />
|
|
4
|
+
</Transition>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<style>
|
|
8
|
+
.fade-enter-active {
|
|
9
|
+
transition: opacity 0.3s ease-in-out;
|
|
10
|
+
}
|
|
11
|
+
.fade-leave-active {
|
|
12
|
+
transition: opacity 0s ease-in-out;
|
|
13
|
+
}
|
|
14
|
+
.fade-enter-from,
|
|
15
|
+
.fade-leave-to {
|
|
16
|
+
opacity: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media (prefers-reduced-motion) {
|
|
20
|
+
.fade-enter-active {
|
|
21
|
+
transition: opacity 0s ease-in-out;
|
|
22
|
+
}
|
|
23
|
+
.fade-leave-active {
|
|
24
|
+
transition: opacity 0s ease-in-out;
|
|
25
|
+
}
|
|
26
|
+
.fade-enter-from,
|
|
27
|
+
.fade-leave-to {
|
|
28
|
+
opacity: 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const { myLayer } = useAppConfig()
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div class="bg-primary">
|
|
7
|
+
Should have bg-primary
|
|
8
|
+
<h1>Hello World!</h1>
|
|
9
|
+
<pre>{{ myLayer }}</pre>
|
|
10
|
+
<p class="text-gray-900">
|
|
11
|
+
Hello World text base should be gray-900 test
|
|
12
|
+
</p>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|