Skip to content

Commit

Permalink
Merge pull request #102 from sadeghbarati/sonner-v1.7.0
Browse files Browse the repository at this point in the history
feat: add sonner 1.7.0 features
  • Loading branch information
xiaoluoboding authored Nov 21, 2024
2 parents 8dd0b3e + 26cc191 commit 0f456eb
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 206 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"license": "MIT",
"devDependencies": {
"@iconify/json": "^2.2.172",
"@microsoft/api-extractor": "^7.47.10",
"@microsoft/api-extractor": "^7.47.11",
"@nuxt/devtools": "^1.6.0",
"@nuxt/kit": "^3.13.2",
"@nuxt/module-builder": "^0.8.4",
Expand All @@ -62,7 +62,7 @@
"@types/node": "^18.19.8",
"@unocss/reset": "^0.63.4",
"@vitejs/plugin-vue": "^5.1.4",
"@vue/tsconfig": "^0.5.1",
"@vue/tsconfig": "^0.6.0",
"@vueuse/core": "^11.1.0",
"@vueuse/head": "^2.0.0",
"clean-css": "^5.3.3",
Expand All @@ -72,9 +72,9 @@
"unocss": "^0.63.4",
"unplugin-icons": "^0.19.3",
"unplugin-vue-components": "^0.27.4",
"vite": "^5.4.9",
"vite": "^5.4.11",
"vue": "^3.5.12",
"vue-sonner": "^1.2.4",
"vue-tsc": "^2.1.6"
"vue-tsc": "^2.1.10"
}
}
221 changes: 116 additions & 105 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

57 changes: 30 additions & 27 deletions src/packages/Toast.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
if (!isAction(toast.action!)) return;
if (event.defaultPrevented) return;
toast.action.onClick?.(event);
if (event.defaultPrevented) return;
deleteToast();
}
"
Expand All @@ -167,7 +168,7 @@
<script lang="ts" setup>
import './styles.css'
import { computed, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import { computed, onBeforeUnmount, onMounted, onUnmounted, ref, watch, watchEffect } from 'vue'
import { type HeightT, type ToastProps, type ToastT, isAction } from './types'
import { useIsDocumentHidden } from './hooks'
Expand All @@ -189,8 +190,10 @@ const mounted = ref(false)
const removed = ref(false)
const swiping = ref(false)
const swipeOut = ref(false)
const swiped = ref(false)
const offsetBeforeRemove = ref(0)
const initialHeight = ref(0)
const remainingTime = ref(props.toast.duration || props.duration || TOAST_LIFETIME)
const dragStartTime = ref<Date | null>(null)
const toastRef = ref<HTMLLIElement | null>(null)
const isFront = computed(() => props.index === 0)
Expand All @@ -213,7 +216,6 @@ const duration = computed(
)
const closeTimerStartTimeRef = ref(0)
const offset = ref(0)
const lastCloseTimerStartTimeRef = ref(0)
const pointerStartRef = ref<{ x: number; y: number } | null>(null)
const coords = computed(() => props.position.split('-'))
Expand All @@ -238,6 +240,10 @@ const isDocumentHidden = useIsDocumentHidden()
const invert = computed(() => props.toast.invert || props.invert)
const disabled = computed(() => toastType.value === 'loading')
const offset = computed(() => {
return heightIndex.value * props.gap! + toastsHeightBefore.value || 0
})
onMounted(() => {
if (!mounted.value) return
Expand All @@ -250,6 +256,7 @@ onMounted(() => {
initialHeight.value = newHeight
let newHeightArr
const alreadyExists = props.heights.find(
(height) => height.toastId === props.toast.id
)
Expand Down Expand Up @@ -290,7 +297,7 @@ function deleteToast() {
function handleCloseToast() {
if (disabled.value || !dismissible.value) {
return
return {}
}
deleteToast()
Expand All @@ -309,7 +316,7 @@ function onPointerDown(event: PointerEvent) {
}
function onPointerUp() {
if (swipeOut.value) return
if (swipeOut.value || !dismissible) return;
pointerStartRef.value = null
const swipeAmount = Number(
Expand All @@ -327,6 +334,7 @@ function onPointerUp() {
props.toast.onDismiss?.(props.toast)
deleteToast()
swipeOut.value = true
swiped.value = false
return
}
Expand All @@ -338,25 +346,20 @@ function onPointerMove(event: PointerEvent) {
if (!pointerStartRef.value || !dismissible.value) return
const yPosition = event.clientY - pointerStartRef.value.y
const xPosition = event.clientX - pointerStartRef.value.x
const clamp = coords.value[0] === 'top' ? Math.min : Math.max
const clampedY = clamp(0, yPosition)
const swipeStartThreshold = event.pointerType === 'touch' ? 10 : 2
const isAllowedToSwipe = Math.abs(clampedY) > swipeStartThreshold
if (isAllowedToSwipe) {
toastRef.value?.style.setProperty('--swipe-amount', `${yPosition}px`)
} else if (Math.abs(xPosition) > swipeStartThreshold) {
// User is swiping in wrong direction so we disable swipe gesture
// for the current pointer down interaction
pointerStartRef.value = null
// @ts-expect-error
const isHighlighted = window.getSelection()?.toString().length > 0;
const swipeAmount = y.value === 'top' ? Math.min(0, yPosition) : Math.max(0, yPosition);
if (Math.abs(swipeAmount) > 0) {
swiped.value = true;
}
}
watchEffect(() => {
offset.value = heightIndex.value * props?.gap! + toastsHeightBefore.value
})
if (isHighlighted) return;
toastRef.value?.style.setProperty('--swipe-amount', `${swipeAmount}px`);
}
watchEffect((onInvalidate) => {
if (
Expand All @@ -367,29 +370,28 @@ watchEffect((onInvalidate) => {
return
}
let timeoutId: ReturnType<typeof setTimeout>
let remainingTime = duration.value
// Pause the timer on each hover
const pauseTimer = () => {
if (lastCloseTimerStartTimeRef.value < closeTimerStartTimeRef.value) {
// Get the elapsed time since the timer started
const elapsedTime = new Date().getTime() - closeTimerStartTimeRef.value
remainingTime = remainingTime - elapsedTime
remainingTime.value = remainingTime.value - elapsedTime
}
lastCloseTimerStartTimeRef.value = new Date().getTime()
}
const startTimer = () => {
if (remainingTime === Infinity) return
if (remainingTime.value === Infinity) return
closeTimerStartTimeRef.value = new Date().getTime()
// Let the toast know it has started
timeoutId = setTimeout(() => {
props.toast.onAutoClose?.(props.toast)
deleteToast()
}, remainingTime)
}, remainingTime.value)
}
if (
Expand Down Expand Up @@ -417,6 +419,8 @@ watch(
)
onMounted(() => {
mounted.value = true
if (toastRef.value) {
const height = toastRef.value.getBoundingClientRect().height
// Add toast height tot heights array after the toast is mounted
Expand All @@ -428,10 +432,9 @@ onMounted(() => {
]
emit('update:heights', newHeights)
}
mounted.value = true
})
onUnmounted(() => {
onBeforeUnmount(() => {
if (toastRef.value) {
const newHeights = props.heights.filter(
(height) => height.toastId !== props.toast.id
Expand Down
26 changes: 21 additions & 5 deletions src/packages/Toaster.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<!-- Remove item from normal navigation flow, only available via hotkey -->
<section :aria-label="`${containerAriaLabel} ${hotkeyLabel}`" :tabIndex="-1">
<section :aria-label="`${containerAriaLabel} ${hotkeyLabel}`" :tabIndex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false">
<template v-for="(pos, index) in possiblePositions" :key="pos">
<ol
ref="listRef"
Expand All @@ -12,6 +12,7 @@
:data-rich-colors="richColors"
:data-y-position="pos.split('-')[0]"
:data-x-position="pos.split('-')[1]"
:data-lifted="expanded && toasts.length > 1 && !expand"
:style="
{
'--front-toast-height': `${heights[0]?.height}px`,
Expand Down Expand Up @@ -272,7 +273,7 @@ function onPointerDown(event: PointerEvent) {
if (isNotDismissible) return
}
interacting.value = false
interacting.value = true
}
watchEffect((onInvalidate) => {
Expand Down Expand Up @@ -331,15 +332,30 @@ watch(
if (typeof window === 'undefined') return
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', ({ matches }) => {
const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
try {
// Chrome & Firefox
darkMediaQuery.addEventListener('change', ({ matches }) => {
if (matches) {
actualTheme.value = 'dark'
} else {
actualTheme.value = 'light'
}
})
} catch(error) {
darkMediaQuery.addListener(({ matches }) => {
try {
if (matches) {
actualTheme.value = 'dark'
} else {
actualTheme.value = 'light'
}
} catch (e) {
console.error(e);
}
});
}
}
)
Expand Down
18 changes: 10 additions & 8 deletions src/packages/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type {

let toastsCounter = 0

type titleT = (() => string | Component) | string | Component;

class Observer {
subscribers: Array<(toast: ExternalToast | ToastToDismiss) => void>
toasts: Array<ToastT | ToastToDismiss>
Expand Down Expand Up @@ -40,7 +42,7 @@ class Observer {

create = (
data: ExternalToast & {
message?: string | Component
message?: titleT
type?: ToastTypes
promise?: PromiseT
}
Expand Down Expand Up @@ -90,27 +92,27 @@ class Observer {
return id
}

message = (message: string | Component, data?: ExternalToast) => {
message = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, message, type: 'default' })
}

error = (message: string | Component, data?: ExternalToast) => {
error = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, type: 'error', message })
}

success = (message: string | Component, data?: ExternalToast) => {
success = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, type: 'success', message })
}

info = (message: string | Component, data?: ExternalToast) => {
info = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, type: 'info', message })
}

warning = (message: string | Component, data?: ExternalToast) => {
warning = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, type: 'warning', message })
}

loading = (message: string | Component, data?: ExternalToast) => {
loading = (message: titleT, data?: ExternalToast) => {
return this.create({ ...data, type: 'loading', message })
}

Expand Down Expand Up @@ -229,7 +231,7 @@ class Observer {
export const ToastState = new Observer()

// bind this to the toast function
function toastFunction(message: string | Component, data?: ExternalToast) {
function toastFunction(message: titleT, data?: ExternalToast) {
const id = data?.id || toastsCounter++

ToastState.create({
Expand Down
Loading

0 comments on commit 0f456eb

Please sign in to comment.