Skip to content

Commit 9babafd

Browse files
authored
2.4.0 (#50)
* Core - Rename NKeys to NType, move Notivue utils to core * Notivue - Fine-tine `pauseOnTabChange: false` behavior * Notivue - Remove unnecessary ResizeObsever repositioning call * Core - Move `isTopAlign` out of `createConfig` * Core - Rename `createWatchers`, remove repositioning watcher, get unwatchers * Core - Add counters, fine-tune repositioning watcher * Core - Add `useNotivueInstance` * Demo - Add NavActions, instance controls * Core, Notifications - Add new type aliases * Dev - Disable minification, nuxt devtools * Notivue - Rename attributes * Core - Sort imports in main entry file * Pkg - Add exports.js, verify-exports.js * Demo - Edit duplicate control behavior * Core - Cleanup useless code in `createStore` * Pkg - Edit README * Core - Update config tests * Tests - Fix import tests * Pkg - Edit README, nuxt/README * Core - Restore triggerRef on queue add/edit methods * Core - Use interfaces, edit some comments * Core - Add Intellisense description to `useNotivueInstance` * Notivue, NotivueKeyboard - Force unmount when not running * Tests - Add instance tests * Tests - Imrpove instance tests nomenclatures * Demo - Move limit select above enqueue control * Notivue - Rename window focus events * Pkg - Bump 2.4.0 * Astro - Make push more readable * Astro - Prefer createdAt istead of counter for event id * Core, Notivue - Fix some typos
1 parent b824d90 commit 9babafd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+810
-328
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ cypress/screenshots
1919

2020
.nuxt
2121
pnpm-lock.yaml
22+
23+
astro-dev

README.md

-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ _Built-in announcements, reduced-motion and keyboard support_
4848
**💫 Nuxt and Astro modules**
4949
_Built-in Nuxt and Astro ad-hoc modules_
5050

51-
**📜 Complete yet friendly documentation**
52-
_You're covered with a plain-language [documentation](https://notivuedocs.netlify.app/)_
53-
5451
<br />
5552

5653
## Installation

demo/components/nav/Nav.vue

+51-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,42 @@
1+
<script setup lang="ts">
2+
import { useNotivueInstance } from 'notivue'
3+
4+
const { isRunning } = useNotivueInstance()
5+
6+
let shouldDisplayNotice = ref(false)
7+
8+
let timeout: number
9+
10+
watch(isRunning, (newVal) => {
11+
window.clearTimeout(timeout)
12+
13+
shouldDisplayNotice.value = true
14+
15+
if (newVal) {
16+
window.setTimeout(() => {
17+
shouldDisplayNotice.value = false
18+
}, 3000)
19+
}
20+
})
21+
</script>
22+
123
<template>
24+
<div
25+
class="Notice"
26+
v-if="shouldDisplayNotice"
27+
:style="{ backgroundColor: isRunning ? '#399b76' : '#d2463c' }"
28+
aria-live="assertive"
29+
role="alert"
30+
dir="ltr"
31+
>
32+
<template v-if="isRunning">
33+
Notivue is now running again. This will be dismissed shortly.</template
34+
>
35+
<template v-else>
36+
Notivue instance has been stopped. Restart it to create notifications.
37+
</template>
38+
</div>
39+
240
<nav dir="ltr">
341
<div class="Container">
442
<SharedButtonGroup name="Position">
@@ -28,18 +66,25 @@
2866
</SharedButtonGroup>
2967

3068
<SharedButtonGroup name="Actions">
31-
<SharedButton @click="push.clearAll()" text="Dismiss All">
32-
<IconsDismissIcon />
33-
</SharedButton>
34-
<SharedButton @click="push.destroyAll()" text="Destroy All">
35-
<IconsDestroyIcon />
36-
</SharedButton>
69+
<NavActions />
3770
</SharedButtonGroup>
3871
</div>
3972
</nav>
4073
</template>
4174

4275
<style scoped>
76+
.Notice {
77+
position: fixed;
78+
bottom: var(--nav-height);
79+
width: 100%;
80+
color: #fff;
81+
padding: 0.25rem 2rem;
82+
text-align: center;
83+
font-size: 0.925rem;
84+
line-height: normal;
85+
z-index: 1000;
86+
}
87+
4388
nav {
4489
padding: 1rem 1.25rem 1.25rem 1.25rem;
4590
background-color: var(--nav-bg-color);

demo/components/nav/NavActions.vue

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
const { entries } = useNotifications()
3+
4+
const { isRunning, startInstance, stopInstance } = useNotivueInstance()
5+
</script>
6+
7+
<template>
8+
<SharedButton
9+
@click="push.clearAll()"
10+
text="Dismiss All"
11+
:isDisabled="entries.length === 0"
12+
:key="entries.length"
13+
>
14+
<IconsDismissIcon />
15+
</SharedButton>
16+
<SharedButton
17+
@click="push.destroyAll()"
18+
text="Destroy All"
19+
:isDisabled="entries.length === 0"
20+
:key="entries.length"
21+
>
22+
<IconsDestroyIcon />
23+
</SharedButton>
24+
25+
<SharedButton @click="startInstance()" text="Start Instance" :isDisabled="isRunning">
26+
<IconsSuccessIcon />
27+
</SharedButton>
28+
<SharedButton @click="stopInstance()" text="Stop Instance" :isDisabled="!isRunning">
29+
<IconsWarnIcon :isWarn="false" />
30+
</SharedButton>
31+
</template>

demo/components/nav/NavNotivueConfig.vue

+13-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
const config = useNotivue()
33
const { queue } = useNotifications()
4-
const { state, actions } = useStore()
4+
const { state, actions, messages } = useStore()
55
66
function togglePauseOnHover() {
77
config.update((prevConf) => ({
@@ -30,11 +30,15 @@ function toggleQueue() {
3030
}
3131
3232
function toggleNoDupes() {
33+
push.destroyAll()
34+
3335
config.update((prevConf) => ({
3436
avoidDuplicates: !prevConf.avoidDuplicates,
3537
}))
3638
3739
if (config.avoidDuplicates.value) state.hasProgress = true
40+
41+
push.success(messages.value.success)
3842
}
3943
4044
const enqueuedLength = computed(() => queue.value.length)
@@ -105,6 +109,14 @@ const btnProps = {
105109
No Duplicates
106110
</button>
107111

112+
<select class="ButtonBase Select" v-model="config.limit.value" aria-label="Limit">
113+
<option selected :value="Infinity">No Limit</option>
114+
<option :value="1">Limit - 1</option>
115+
<option :value="3">Limit - 3</option>
116+
<option :value="5">Limit - 5</option>
117+
<option :value="10">Limit - 10</option>
118+
</select>
119+
108120
<button
109121
v-bind="btnProps"
110122
:aria-checked="config.enqueue.value"
@@ -113,16 +125,6 @@ const btnProps = {
113125
>
114126
Enqueue ({{ enqueuedLength }})
115127
</button>
116-
117-
<hr />
118-
119-
<select class="ButtonBase Select" v-model="config.limit.value" aria-label="Limit">
120-
<option selected :value="Infinity">No Limit</option>
121-
<option :value="1">Limit - 1</option>
122-
<option :value="3">Limit - 3</option>
123-
<option :value="5">Limit - 5</option>
124-
<option :value="10">Limit - 10</option>
125-
</select>
126128
</div>
127129
</template>
128130

@@ -147,10 +149,4 @@ const btnProps = {
147149
background-repeat: no-repeat;
148150
background-size: auto 1rem;
149151
}
150-
151-
hr {
152-
margin: 0.25rem 0;
153-
border: 0;
154-
border-bottom: 1px solid var(--divider-color);
155-
}
156152
</style>

demo/components/nav/NavPushBuiltIn.vue

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script setup lang="ts">
2-
const { state } = useStore()
3-
const { messages } = useStore()
2+
const { state, messages } = useStore()
43
54
async function asyncRefMessagePush() {
65
const initialMessage = ref(state.rtl ? 'جاري تحميل الملفات...' : 'Preparing to upload files...')

demo/components/shared/Button.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
const props = defineProps<{
33
text: string
4+
isDisabled?: boolean
45
}>()
56
67
const emit = defineEmits<{
@@ -9,7 +10,7 @@ const emit = defineEmits<{
910
</script>
1011

1112
<template>
12-
<button @click="emit('click')" class="ButtonBase" role="button">
13+
<button @click="emit('click')" class="ButtonBase" role="button" :disabled="isDisabled">
1314
<slot />
1415
<span>{{ props.text }}</span>
1516
</button>

demo/nuxt.config.ts

+9
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import { getHead } from './utils/head'
33
export default defineNuxtConfig({
44
modules: ['notivue/nuxt'],
55
ssr: true,
6+
devtools: {
7+
enabled: false,
8+
},
69
experimental: {
710
componentIslands: true,
811
},
912
notivue: {
1013
// addPlugin: true,
14+
// startOnCreation: true,
1115
notifications: {
1216
global: {
1317
// duration: Infinity,
@@ -21,7 +25,12 @@ export default defineNuxtConfig({
2125
head: getHead(),
2226
},
2327
vite: {
28+
esbuild: {
29+
minifyIdentifiers: !import.meta.env.DEV,
30+
minifySyntax: !import.meta.env.DEV,
31+
},
2432
build: {
33+
minify: import.meta.env.DEV ? false : 'esbuild',
2534
cssMinify: 'lightningcss',
2635
},
2736
css: {

packages/notivue/Notifications/icons/index.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { markRaw as raw, type SVGAttributes } from 'vue'
22

3-
import { NotificationTypeKeys as NKeys } from '@/core/constants'
3+
import { NotificationTypeKeys as NType } from '@/core/constants'
44

55
import SuccessIcon from './SuccessIcon.vue'
66
import ErrorIcon from './ErrorIcon.vue'
@@ -34,23 +34,23 @@ export const featherProps: SVGAttributes = {
3434
}
3535

3636
export const filledIcons: NotivueIcons = {
37-
[NKeys.SUCCESS]: raw(SuccessIcon),
38-
[NKeys.ERROR]: raw(ErrorIcon),
39-
[NKeys.INFO]: raw(InfoIcon),
40-
[NKeys.WARNING]: raw(ErrorIcon),
41-
[NKeys.PROMISE]: raw(PromiseIcon),
42-
[NKeys.PROMISE_RESOLVE]: raw(SuccessIcon),
43-
[NKeys.PROMISE_REJECT]: raw(ErrorIcon),
37+
[NType.SUCCESS]: raw(SuccessIcon),
38+
[NType.ERROR]: raw(ErrorIcon),
39+
[NType.INFO]: raw(InfoIcon),
40+
[NType.WARNING]: raw(ErrorIcon),
41+
[NType.PROMISE]: raw(PromiseIcon),
42+
[NType.PROMISE_RESOLVE]: raw(SuccessIcon),
43+
[NType.PROMISE_REJECT]: raw(ErrorIcon),
4444
close: raw(CloseIcon),
4545
}
4646

4747
export const outlinedIcons: NotivueIcons = {
48-
[NKeys.SUCCESS]: raw(SuccessOutlineIcon),
49-
[NKeys.ERROR]: raw(ErrorOutlineIcon),
50-
[NKeys.INFO]: raw(InfoOutlineIcon),
51-
[NKeys.WARNING]: raw(ErrorOutlineIcon),
52-
[NKeys.PROMISE]: raw(PromiseIcon),
53-
[NKeys.PROMISE_RESOLVE]: raw(SuccessOutlineIcon),
54-
[NKeys.PROMISE_REJECT]: raw(ErrorOutlineIcon),
48+
[NType.SUCCESS]: raw(SuccessOutlineIcon),
49+
[NType.ERROR]: raw(ErrorOutlineIcon),
50+
[NType.INFO]: raw(InfoOutlineIcon),
51+
[NType.WARNING]: raw(ErrorOutlineIcon),
52+
[NType.PROMISE]: raw(PromiseIcon),
53+
[NType.PROMISE_RESOLVE]: raw(SuccessOutlineIcon),
54+
[NType.PROMISE_REJECT]: raw(ErrorOutlineIcon),
5555
close: raw(CloseIcon),
5656
}

packages/notivue/Notifications/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ type ThemeVars =
6969
| WarningColorsVars
7070
| InfoColorsVars
7171
| PromiseColorsVars
72+
73+
// New v2.4.0 aliases
74+
75+
export type NotificationProps = NotificationsProps

packages/notivue/Notivue/Notivue.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<script setup lang="ts">
2+
import { useNotivueInstance } from '@/core/useStore'
23
import { DEFAULT_PROPS } from './constants'
4+
35
import { NotivueClientOnly } from '@/shared/ClientOnly'
46
57
import NotivueImpl from './NotivueImpl.vue'
@@ -8,12 +10,14 @@ import type { NotivueComponentSlot, NotivueProps } from 'notivue'
810
911
const props = withDefaults(defineProps<NotivueProps>(), DEFAULT_PROPS)
1012
13+
const { isRunning } = useNotivueInstance()
14+
1115
defineSlots<NotivueComponentSlot>()
1216
</script>
1317

1418
<template>
1519
<NotivueClientOnly>
16-
<NotivueImpl v-bind="props" v-slot="item">
20+
<NotivueImpl v-bind="props" v-slot="item" v-if="isRunning">
1721
<slot v-bind="item" />
1822
</NotivueImpl>
1923
</NotivueClientOnly>

packages/notivue/Notivue/NotivueImpl.vue

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import { Teleport } from 'vue'
44
import AriaLive from './AriaLive.vue'
55
66
import { useStore } from '@/core/useStore'
7+
import { getSlotItem } from '@/core/utils'
8+
79
import { useMouseEvents } from './composables/useMouseEvents'
810
import { useTouchEvents } from './composables/useTouchEvents'
911
import { useNotivueStyles } from './composables/useNotivueStyles'
1012
import { useRepositioning } from './composables/useRepositioning'
1113
import { useWindowFocus } from './composables/useWindowFocus'
1214
import { useReducedMotion } from './composables/useReducedMotion'
13-
import { getSlotItem, getAriaLabel } from './utils'
15+
16+
import { getAriaLabel } from './utils'
1417
import { DEFAULT_PROPS } from './constants'
1518
1619
import type { NotivueProps, NotivueComponentSlot } from 'notivue'
@@ -43,22 +46,22 @@ useRepositioning()
4346
>
4447
<!-- List Container -->
4548
<ol
46-
v-if="items.length > 0"
49+
v-if="items.entries.value.length > 0"
4750
v-bind="{ ...mouseEvents, ...touchEvents, ...elements.rootAttrs.value }"
48-
:data-notivue-align="config.isTopAlign.value ? 'top' : 'bottom'"
51+
:data-notivue-align="config.position.value.split('-')[0]"
4952
:aria-label="props.listAriaLabel"
5053
:ref="elements.root"
5154
:class="props.class"
5255
:style="{ ...styles.list, ...props.styles?.list }"
5356
>
5457
<!-- List Item -->
5558
<li
56-
v-for="(item, index) in items.entries.value"
59+
v-for="(item, i) in items.entries.value"
5760
tabindex="-1"
5861
:key="item.id"
59-
:data-notivue-id="item.id"
62+
:data-notivue-item="item.id"
6063
:aria-setsize="items.length"
61-
:aria-posinset="index + 1"
64+
:aria-posinset="i + 1"
6265
:ref="elements.items"
6366
:style="{
6467
...styles.listItem,

0 commit comments

Comments
 (0)