@sbc-connect/nuxt-base 0.1.28 → 0.2.0
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 +16 -0
- package/app/app.config.ts +6 -0
- package/app/components/Connect/Input.vue +36 -4
- package/app/components/Connect/InputDate.vue +107 -0
- package/app/components/Connect/Layout/Sidebar.vue +38 -0
- package/app/components/Connect/Tombstone/index.vue +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @sbc-connect/nuxt-base
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#101](https://github.com/bcgov/connect-nuxt/pull/101) [`033f6c6`](https://github.com/bcgov/connect-nuxt/commit/033f6c624fbf953f1d7cf491c876cc9b58619b22) Thanks [@cameron-eyds](https://github.com/cameron-eyds)! - Implements dynamic slots/props while supporting explicit props
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#97](https://github.com/bcgov/connect-nuxt/pull/97) [`09323e1`](https://github.com/bcgov/connect-nuxt/commit/09323e1fcaff9a2738528c8161288c1d4bcd0677) Thanks [@deetz99](https://github.com/deetz99)! - feat: ConnectInputDate component
|
|
12
|
+
|
|
13
|
+
## 0.1.29
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#95](https://github.com/bcgov/connect-nuxt/pull/95) [`a0724ac`](https://github.com/bcgov/connect-nuxt/commit/a0724ac5fdf44296e822942b0eea6be3bb313fcb) Thanks [@kialj876](https://github.com/kialj876)! - Add firebase.json for CI build, update examples sidebar
|
|
18
|
+
|
|
3
19
|
## 0.1.28
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/app/app.config.ts
CHANGED
|
@@ -80,6 +80,9 @@ export default defineAppConfig({
|
|
|
80
80
|
class: 'ring ring-inset ring-primary text-primary hover:bg-primary/10 active:bg-primary/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-primary'
|
|
81
81
|
}
|
|
82
82
|
],
|
|
83
|
+
slots: {
|
|
84
|
+
base: 'cursor-pointer'
|
|
85
|
+
},
|
|
83
86
|
variants: {
|
|
84
87
|
size: {
|
|
85
88
|
sm: {
|
|
@@ -275,6 +278,9 @@ export default defineAppConfig({
|
|
|
275
278
|
upload: 'i-mdi-upload'
|
|
276
279
|
},
|
|
277
280
|
input: {
|
|
281
|
+
slots: {
|
|
282
|
+
trailingIcon: 'text-neutral group-has-[div>input[aria-invalid=true]]:text-error group-focus-within:text-primary'
|
|
283
|
+
},
|
|
278
284
|
variants: {
|
|
279
285
|
size: {
|
|
280
286
|
bcGov: {
|
|
@@ -1,21 +1,42 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
2
|
+
import type { InputProps } from '@nuxt/ui'
|
|
3
3
|
|
|
4
|
-
defineProps<{
|
|
4
|
+
const props = defineProps<{
|
|
5
5
|
id: string
|
|
6
6
|
label: string
|
|
7
7
|
mask?: string
|
|
8
|
+
disabled?: boolean
|
|
9
|
+
autoFocus?: boolean
|
|
8
10
|
}>()
|
|
11
|
+
|
|
12
|
+
const model = defineModel<string | number | bigint | null | undefined>({ required: true })
|
|
13
|
+
|
|
14
|
+
// Inject props
|
|
15
|
+
const injectedProps = inject<InputProps>(
|
|
16
|
+
`UInput-props${props.id ? `-${props.id}` : ''}`,
|
|
17
|
+
{} as InputProps
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
// Inject slots
|
|
21
|
+
const injectedSlots = inject<{ [key: string]: VNode }>(
|
|
22
|
+
`UInput-slots${props.id ? `-${props.id}` : ''}`,
|
|
23
|
+
{}
|
|
24
|
+
)
|
|
9
25
|
</script>
|
|
10
26
|
|
|
11
27
|
<template>
|
|
12
28
|
<UInput
|
|
13
|
-
|
|
29
|
+
v-bind="{
|
|
30
|
+
id,
|
|
31
|
+
disabled,
|
|
32
|
+
autoFocus,
|
|
33
|
+
...injectedProps, // injected props will default when provided
|
|
34
|
+
}"
|
|
14
35
|
v-model.trim="model"
|
|
15
36
|
v-maska="mask"
|
|
37
|
+
class="w-full grow"
|
|
16
38
|
:data-testid="id"
|
|
17
39
|
placeholder=" "
|
|
18
|
-
class="w-full grow"
|
|
19
40
|
>
|
|
20
41
|
<label
|
|
21
42
|
:for="id"
|
|
@@ -23,5 +44,16 @@ defineProps<{
|
|
|
23
44
|
>
|
|
24
45
|
{{ label }}
|
|
25
46
|
</label>
|
|
47
|
+
|
|
48
|
+
<!-- Render injected slots -->
|
|
49
|
+
<template
|
|
50
|
+
v-for="(comp, name) in injectedSlots"
|
|
51
|
+
#[name]
|
|
52
|
+
:key="name"
|
|
53
|
+
>
|
|
54
|
+
<component
|
|
55
|
+
:is="comp"
|
|
56
|
+
/>
|
|
57
|
+
</template>
|
|
26
58
|
</UInput>
|
|
27
59
|
</template>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
// https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/
|
|
4
|
+
// https://whatsock.com/Templates/Datepickers/Basic,%20Auto%20Open/index.htm
|
|
5
|
+
import type { ConnectInput, UCalendar } from '#components'
|
|
6
|
+
import { CalendarDate } from '@internationalized/date'
|
|
7
|
+
import { DateTime } from 'luxon'
|
|
8
|
+
|
|
9
|
+
// FUTURE: update props as needed (min/max/disabled days)
|
|
10
|
+
defineProps<{
|
|
11
|
+
label: string
|
|
12
|
+
id: string
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
blur: []
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const externalModel = defineModel<string | null | undefined>({ required: true })
|
|
20
|
+
|
|
21
|
+
const localModel = computed({
|
|
22
|
+
get() {
|
|
23
|
+
if (externalModel.value) {
|
|
24
|
+
const dt = DateTime.fromISO(externalModel.value, { zone: 'America/Vancouver' })
|
|
25
|
+
if (dt.isValid) {
|
|
26
|
+
return new CalendarDate(dt.year, dt.month, dt.day)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined
|
|
30
|
+
},
|
|
31
|
+
set(v) {
|
|
32
|
+
if (v) {
|
|
33
|
+
externalModel.value = DateTime.fromObject({
|
|
34
|
+
year: v.year,
|
|
35
|
+
month: v.month,
|
|
36
|
+
day: v.day
|
|
37
|
+
}).toISODate()
|
|
38
|
+
} else {
|
|
39
|
+
externalModel.value = null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const open = ref(false)
|
|
45
|
+
const calendarRef = useTemplateRef('calendar-ref')
|
|
46
|
+
const inputRef = useTemplateRef<InstanceType<typeof ConnectInput>>('input-ref')
|
|
47
|
+
|
|
48
|
+
function focusCalendar() {
|
|
49
|
+
const button = (calendarRef.value as any).$el.querySelector('button')
|
|
50
|
+
if (button) {
|
|
51
|
+
(button as HTMLButtonElement).focus()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function focusInput() {
|
|
56
|
+
const input = (inputRef.value as any).$el.querySelector('input')
|
|
57
|
+
if (input) {
|
|
58
|
+
(input as HTMLInputElement).focus()
|
|
59
|
+
}
|
|
60
|
+
open.value = false
|
|
61
|
+
emit('blur')
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<UPopover
|
|
67
|
+
v-model:open="open"
|
|
68
|
+
:content="{
|
|
69
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
70
|
+
onEscapeKeyDown: () => {
|
|
71
|
+
focusInput()
|
|
72
|
+
},
|
|
73
|
+
side: 'bottom',
|
|
74
|
+
align: 'start',
|
|
75
|
+
}"
|
|
76
|
+
@update:open="(v) => {
|
|
77
|
+
if (!v) {
|
|
78
|
+
$emit('blur')
|
|
79
|
+
}
|
|
80
|
+
}"
|
|
81
|
+
>
|
|
82
|
+
<template #default>
|
|
83
|
+
<div class="w-full group">
|
|
84
|
+
<ConnectInput
|
|
85
|
+
:id
|
|
86
|
+
ref="input-ref"
|
|
87
|
+
v-model="externalModel"
|
|
88
|
+
:label
|
|
89
|
+
mask="####-##-##"
|
|
90
|
+
trailing-icon="i-mdi-calendar"
|
|
91
|
+
@focus="open = true"
|
|
92
|
+
@click.stop="open = true"
|
|
93
|
+
@keydown.down.prevent="focusCalendar"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</template>
|
|
97
|
+
|
|
98
|
+
<template #content>
|
|
99
|
+
<UCalendar
|
|
100
|
+
ref="calendar-ref"
|
|
101
|
+
v-model="localModel"
|
|
102
|
+
class="p-2"
|
|
103
|
+
@update:model-value="focusInput"
|
|
104
|
+
/>
|
|
105
|
+
</template>
|
|
106
|
+
</UPopover>
|
|
107
|
+
</template>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { NavigationMenuItem } from '@nuxt/ui'
|
|
3
|
+
|
|
4
|
+
defineProps<{ items: NavigationMenuItem[] }>()
|
|
5
|
+
|
|
6
|
+
const showSideMenu = ref(true)
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div class="flex gap-4 my-10 relative">
|
|
11
|
+
<UButton
|
|
12
|
+
class="absolute z-1 -top-8"
|
|
13
|
+
color="neutral"
|
|
14
|
+
size="xs"
|
|
15
|
+
:icon="showSideMenu ? 'i-mdi-minus' : 'i-mdi-plus'"
|
|
16
|
+
data-testid="connect-sidebar-toggle-btn"
|
|
17
|
+
@click="showSideMenu = !showSideMenu"
|
|
18
|
+
/>
|
|
19
|
+
<ConnectTransitionCollapse>
|
|
20
|
+
<div v-if="showSideMenu">
|
|
21
|
+
<UNavigationMenu
|
|
22
|
+
collapsible
|
|
23
|
+
:items
|
|
24
|
+
orientation="vertical"
|
|
25
|
+
class="text-neutral-highlighted"
|
|
26
|
+
variant="pill"
|
|
27
|
+
:ui="{
|
|
28
|
+
label: 'text-base',
|
|
29
|
+
link: 'cursor-pointer',
|
|
30
|
+
linkLabel: 'text-neutral-highlighted',
|
|
31
|
+
root: 'bg-white rounded p-3',
|
|
32
|
+
}"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</ConnectTransitionCollapse>
|
|
36
|
+
<slot />
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
@@ -19,7 +19,7 @@ async function handleButtonAction(button: ButtonProps, event: MouseEvent) {
|
|
|
19
19
|
</script>
|
|
20
20
|
|
|
21
21
|
<template>
|
|
22
|
-
<div class="bg-white py-8 px-2 sm:px-4">
|
|
22
|
+
<div class="bg-white py-8 px-2 sm:px-4" data-testid="connect-tombstone-wrapper">
|
|
23
23
|
<div class="app-inner-container">
|
|
24
24
|
<div
|
|
25
25
|
v-if="tombstone.loading"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sbc-connect/nuxt-base",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"repository": "github:bcgov/connect-nuxt",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
@@ -14,11 +14,13 @@
|
|
|
14
14
|
"dompurify": "^3.3.0",
|
|
15
15
|
"es-toolkit": "^1.41.0",
|
|
16
16
|
"launchdarkly-vue-client-sdk": "^2.4.1",
|
|
17
|
+
"luxon": "^3.7.2",
|
|
17
18
|
"maska": "^3.2.0",
|
|
18
19
|
"zod": "^4.1.12"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
22
|
"@axe-core/playwright": "4.11.0",
|
|
23
|
+
"@types/luxon": "^3.7.1",
|
|
22
24
|
"@vitest/coverage-v8": "3.2.4",
|
|
23
25
|
"dotenv": "17.2.3",
|
|
24
26
|
"nuxt": "4.1.3",
|