Skip to content

Commit 3be6fb4

Browse files
authored
2.3.0 (#47)
* Core - Remove lightningcss bug workaround * Core - Implement `avoidDuplicates` * Notifications - Add duplicate animation, add aria-atomic everywhere * Core - Refactor `useVisibilityChange` * Core - Expose `isStreamPaused` * Notifications - Implement `NotificationProgress` * Core, NotivueKeyboard - Cleanup * Notifications - Fix `--nv-accent` fallback value computation * Demo - Add new controls, cleanup * Pkg - Edit verify script, bump v2.3.0 * Tests - Add NotivueProgress to Notifications test file * Core - Add singular named import aliases to any exported CSS file * Demo - Add duplicate effect to custom notifications * Tests, Notifications - Add duplicate class test * Tests - Add `avoidDuplicates` tests * Tests - Up tests deps * Demo - Up deps
1 parent fdac118 commit 3be6fb4

40 files changed

+462
-171
lines changed

demo/app.vue

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ watch(
3939
:item="item as NotivueItem<FriendRequestNotificationProps>"
4040
/>
4141

42-
<NotivueSwipe v-else :item="item" :disabled="!state.enableSwipe">
42+
<NotivueSwipe v-else :item :disabled="!state.enableSwipe">
4343
<UploadNotification
4444
v-if="item.props.isUploadNotifiation"
4545
:item="item as NotivueItem<UploadNotificationProps>"
@@ -52,10 +52,12 @@ watch(
5252

5353
<Notification
5454
v-else
55-
:item="item"
55+
:item
5656
:theme="{ ...themes[state.theme], '--nv-y-align-has-title': 'flex-start' }"
5757
:icons="state.outlinedIcons ? outlinedIcons : undefined"
58-
/>
58+
>
59+
<NotificationProgress :item v-if="state.hasProgress" />
60+
</Notification>
5961
</NotivueSwipe>
6062
</Notivue>
6163
</NotivueKeyboard>

demo/assets/style.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
-moz-osx-font-smoothing: grayscale;
4141
-webkit-text-size-adjust: 100%;
4242
--app-font-family: 'PT Sans Narrow', Avenir, Helvetica, Arial, sans-serif;
43-
--nav-height: 260px;
43+
--nav-height: 280px;
4444
--royal-blue: #438bff;
4545
--focus-ring: 0px 0px 0px 2px #fff, 0px 0px 0px 4px var(--royal-blue);
4646
--focus-ring-xl: 0px 0px 0px 2px #fff, 0px 0px 0px 5px var(--royal-blue);

demo/components/custom-notifications/FriendRequestNotification.vue

+30-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ const { elementsTabIndex } = useNotivueKeyboard()
1515
</script>
1616

1717
<template>
18-
<div class="Notification">
18+
<div
19+
:key="item.duplicates"
20+
:class="[
21+
'Notification',
22+
{
23+
Duplicate_Anim: item.duplicates > 0,
24+
},
25+
]"
26+
>
1927
<div class="Avatar">
2028
<img :src="item.props.profilePicture" alt="profile" class="Picture" />
2129
<span class="OnlineDot" />
@@ -30,14 +38,14 @@ const { elementsTabIndex } = useNotivueKeyboard()
3038
</div>
3139
<nav class="Buttons">
3240
<button
33-
role="button"
41+
type="button"
3442
@click="item.clear"
3543
class="Button ButtonReverse"
3644
:tabIndex="elementsTabIndex"
3745
>
3846
Deny
3947
</button>
40-
<button role="button" @click="item.clear" class="Button" :tabIndex="elementsTabIndex">
48+
<button type="button" @click="item.clear" class="Button" :tabIndex="elementsTabIndex">
4149
Accept
4250
</button>
4351
</nav>
@@ -169,4 +177,23 @@ const { elementsTabIndex } = useNotivueKeyboard()
169177
opacity: 1;
170178
}
171179
}
180+
181+
.Duplicate_Anim {
182+
animation: Duplicate_KF 350ms cubic-bezier(0.16, 1, 0.3, 1);
183+
}
184+
185+
@keyframes Duplicate_KF {
186+
0% {
187+
transform: scale(1);
188+
}
189+
190+
50% {
191+
transform: scale(1.05);
192+
box-shadow: 0 0 0 3px var(--royal-blue);
193+
}
194+
195+
100% {
196+
transform: scale(1);
197+
}
198+
}
172199
</style>

demo/components/custom-notifications/SimpleNotification.vue

+30-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,15 @@ defineProps<{
1111
</script>
1212

1313
<template>
14-
<div class="Notification">
14+
<div
15+
:key="item.duplicates"
16+
:class="[
17+
'Notification',
18+
{
19+
Duplicate_Anim: item.duplicates > 0,
20+
},
21+
]"
22+
>
1523
<p :role="item.ariaRole" :aria-live="item.ariaLive">
1624
{{ item.message }}
1725
</p>
@@ -64,4 +72,25 @@ defineProps<{
6472
height: 1.25rem;
6573
}
6674
}
75+
76+
.Duplicate_Anim {
77+
animation: Duplicate_KF 300ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
78+
}
79+
80+
@keyframes Duplicate_KF {
81+
0% {
82+
transform: scale(1);
83+
opacity: 1;
84+
}
85+
86+
50% {
87+
transform: scale(1.035);
88+
opacity: 0.8;
89+
}
90+
91+
100% {
92+
transform: scale(1);
93+
opacity: 1;
94+
}
95+
}
6796
</style>

demo/components/nav/Nav.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ nav {
5252
z-index: 9999;
5353
bottom: 0;
5454
left: 0;
55-
height: 260px;
55+
height: var(--nav-height);
5656
position: fixed;
5757
overflow: hidden;
5858

demo/components/nav/NavNotificationsCustomization.vue

+17-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function clearAllAndPushOne() {
66
push.success(messages.value.success)
77
}
88
9-
async function toggleRenderTitles() {
9+
function toggleRenderTitles() {
1010
actions.toggleRenderTitles()
1111
clearAllAndPushOne()
1212
}
@@ -15,34 +15,34 @@ function toggleRTL() {
1515
actions.toggleRTL()
1616
clearAllAndPushOne()
1717
}
18+
19+
function toggleProgress() {
20+
actions.toggleProgress()
21+
clearAllAndPushOne()
22+
}
23+
24+
const btnProps = {
25+
class: 'ButtonBase SwitchButton',
26+
role: 'switch',
27+
}
1828
</script>
1929

2030
<template>
2131
<div class="Controls">
22-
<button
23-
class="ButtonBase SwitchButton"
24-
role="switch"
25-
:aria-checked="state.renderTitles"
26-
@click="toggleRenderTitles"
27-
>
32+
<button v-bind="btnProps" :aria-checked="state.hasProgress" @click="toggleProgress">
33+
Progress
34+
</button>
35+
<button v-bind="btnProps" :aria-checked="state.renderTitles" @click="toggleRenderTitles">
2836
Titles
2937
</button>
3038
<button
31-
class="ButtonBase SwitchButton"
32-
role="switch"
39+
v-bind="btnProps"
3340
:aria-checked="state.outlinedIcons"
3441
@click="actions.toggleOutlinedIcons"
3542
>
3643
Outlined
3744
</button>
38-
<button
39-
class="ButtonBase SwitchButton"
40-
role="switch"
41-
:aria-checked="state.rtl"
42-
@click="toggleRTL"
43-
>
44-
RTL
45-
</button>
45+
<button v-bind="btnProps" :aria-checked="state.rtl" @click="toggleRTL">RTL</button>
4646
</div>
4747
</template>
4848

@@ -53,4 +53,3 @@ function toggleRTL() {
5353
grid-auto-flow: row;
5454
}
5555
</style>
56-
utils/store

demo/components/nav/NavNotivueConfig.vue

+22-43
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ function togglePauseOnHover() {
77
config.update((prevConf) => ({
88
pauseOnHover: !prevConf.pauseOnHover,
99
}))
10-
11-
push.info({
12-
title: `Pause on hover ${config.pauseOnHover.value ? 'enabled' : 'disabled'}`,
13-
message: config.pauseOnHover.value
14-
? 'Notifications will be paused on hover.'
15-
: 'Notifications will not be paused on hover.',
16-
})
1710
}
1811
1912
function toggleRtlIfNeeded() {
@@ -26,13 +19,6 @@ function togglePauseOnTouch() {
2619
config.update((prevConf) => ({
2720
pauseOnTouch: !prevConf.pauseOnTouch,
2821
}))
29-
30-
push.info({
31-
title: `Pause on touch ${config.pauseOnTouch.value ? 'enabled' : 'disabled'}`,
32-
message: config.pauseOnTouch.value
33-
? 'Notifications will be paused on touch.'
34-
: 'Notifications will not be paused on touch.',
35-
})
3622
}
3723
3824
function toggleQueue() {
@@ -43,6 +29,14 @@ function toggleQueue() {
4329
}))
4430
}
4531
32+
function toggleNoDupes() {
33+
config.update((prevConf) => ({
34+
avoidDuplicates: !prevConf.avoidDuplicates,
35+
}))
36+
37+
if (config.avoidDuplicates.value) state.hasProgress = true
38+
}
39+
4640
const enqueuedLength = computed(() => queue.value.length)
4741
const isEnqueueDisabled = computed(() => config.limit.value === Infinity)
4842
const isSwipeDisabled = computed(() => !config.pauseOnHover.value)
@@ -71,14 +65,18 @@ watch(
7165
watch(config.limit, () => {
7266
toggleRtlIfNeeded()
7367
})
68+
69+
const btnProps = {
70+
class: 'ButtonBase SwitchButton',
71+
role: 'switch',
72+
}
7473
</script>
7574

7675
<template>
7776
<div class="Controls">
7877
<button
7978
v-if="isMobile()"
80-
class="ButtonBase SwitchButton"
81-
role="switch"
79+
v-bind="btnProps"
8280
:aria-checked="config.pauseOnTouch.value"
8381
@click="togglePauseOnTouch"
8482
>
@@ -87,27 +85,28 @@ watch(config.limit, () => {
8785

8886
<button
8987
v-else
90-
class="ButtonBase SwitchButton"
91-
role="switch"
88+
v-bind="btnProps"
9289
:aria-checked="config.pauseOnHover.value"
9390
@click="togglePauseOnHover"
9491
>
9592
Pause on Hover
9693
</button>
9794

9895
<button
99-
class="ButtonBase SwitchButton"
96+
v-bind="btnProps"
10097
:disabled="isSwipeDisabled"
101-
role="switch"
10298
:aria-checked="state.enableSwipe"
10399
@click="actions.toggleSwipe"
104100
>
105101
Clear on Swipe
106102
</button>
107103

104+
<button v-bind="btnProps" :aria-checked="config.avoidDuplicates.value" @click="toggleNoDupes">
105+
No Duplicates
106+
</button>
107+
108108
<button
109-
class="ButtonBase SwitchButton ButtonTooltip"
110-
role="switch"
109+
v-bind="btnProps"
111110
:aria-checked="config.enqueue.value"
112111
@click="toggleQueue"
113112
:disabled="isEnqueueDisabled"
@@ -138,6 +137,7 @@ watch(config.limit, () => {
138137
text-align: center;
139138
display: flex;
140139
justify-items: center;
140+
padding-right: 1rem;
141141
142142
-webkit-appearance: none;
143143
appearance: none;
@@ -148,30 +148,9 @@ watch(config.limit, () => {
148148
background-size: auto 1rem;
149149
}
150150
151-
.ButtonTooltip {
152-
width: 100%;
153-
}
154-
155151
hr {
156152
margin: 0.25rem 0;
157153
border: 0;
158154
border-bottom: 1px solid var(--divider-color);
159155
}
160156
</style>
161-
162-
<style>
163-
.v-popper__wrapper {
164-
max-width: 160px;
165-
}
166-
167-
.v-popper__inner {
168-
background: var(--button-bg-color) !important;
169-
color: var(--button-color) !important;
170-
font-size: 0.825rem !important;
171-
line-height: 1.35;
172-
}
173-
174-
.v-popper__arrow-outer {
175-
border-color: var(--button-bg-color) !important;
176-
}
177-
</style>

demo/components/nav/NavNotivuePosition.vue

+7-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ const isFullWidth = computed(() => state.maxWidth === '100%')
1818
function setPosition(position: Position) {
1919
config.update({ position })
2020
}
21+
22+
const btnProps = {
23+
class: 'ButtonBase SwitchButton Switch',
24+
role: 'switch',
25+
}
2126
</script>
2227

2328
<template>
@@ -35,17 +40,11 @@ function setPosition(position: Position) {
3540
<IconsArrowIcon :rotate="position.rotate" />
3641
</div>
3742

38-
<button
39-
class="ButtonBase SwitchButton Switch"
40-
role="switch"
41-
:aria-checked="isFullWidth"
42-
@click="actions.setFullWidth"
43-
>
43+
<button v-bind="btnProps" :aria-checked="isFullWidth" @click="actions.setFullWidth">
4444
Full Width
4545
</button>
4646
<button
47-
class="ButtonBase SwitchButton Switch"
48-
role="switch"
47+
v-bind="btnProps"
4948
:aria-checked="state.centerOnMobile"
5049
@click="actions.toggleCenterOnMobile"
5150
:disabled="config.position.value.endsWith('center')"

demo/nuxt.config.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@ export default defineNuxtConfig({
2828
transformer: 'lightningcss',
2929
},
3030
},
31-
css: ['assets/style.css', 'notivue/notifications.css', 'notivue/animations.css'],
31+
css: [
32+
'assets/style.css',
33+
'notivue/notifications.css',
34+
'notivue/notifications-progress.css',
35+
'notivue/animations.css',
36+
],
3237
})

0 commit comments

Comments
 (0)