Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Usage />
<Types />
<Position v-model:position="position" />
<ClosePosition v-model:closeButtonPosition="closeButtonPosition" />
<Expand v-model:expand="expand" />
<Theming @setTheme="(newTheme: Theme) => (theme = newTheme)" />
<Styling />
Expand All @@ -28,6 +29,7 @@
:expand="expand"
:rich-colors="richColors"
:close-button="closeButton"
:close-button-position="closeButtonPosition"
:theme="theme"
/>
</div>
Expand All @@ -37,13 +39,14 @@
import { ref } from 'vue'
// import { toggleDarkmode, isDark } from '~/composables/useDarkmode'
import { Toaster } from '@/packages'
import type { Position, Theme } from '@/packages/types'
import type { CloseButtonPosition, Position, Theme } from '@/packages/types'
import { useSEOHeader } from '~/composables/useSEOHeader'

useSEOHeader()

const expand = ref(false)
const position = ref<Position>('bottom-right')
const closeButtonPosition = ref<CloseButtonPosition>('top-left')
const richColors = ref(false)
const closeButton = ref(false)
const theme = ref<Theme>('light')
Expand Down
90 changes: 90 additions & 0 deletions app/components/ClosePosition.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<template>
<div class="types">
<h1 class="text-lg font-semibold my-2">Close Button Position</h1>
<p class="text-base my-3">
You can customize the position of the close button, If you haven't
set the position, it defaults to
<code class="text-xs !bg-neutral-200/66 p-1 mx-1 rounded-md">
top-left
</code>
.
</p>
<div class="mb-4 flex gap-3 overflow-auto">
<button
v-for="position in positions"
:key="position"
class="btn-default"
:class="{
'bg-neutral-200/50 border-neutral-400/50': props.closeButtonPosition === position
}"
@click="() => handleChangePosition(position)"
>
{{ position }}
</button>
</div>
<div class="code-block relative group">
<Highlight
language="javascript"
className="rounded-md text-xs"
:autodetect="false"
:code="renderedCode"
/>
<button
aria-label="Copy code"
title="Copy code"
class="absolute right-2 top-2 btn-border p-1 hidden group-hover:block"
@click="handleCopyCode"
>
<CheckIcon v-if="showCheckIcon" />
<CopyIcon v-else />
</button>
</div>
</div>
</template>

<script lang="ts" setup>
import type { PropType } from 'vue'
import { ref, computed, watch } from 'vue'

import { toast, useVueSonner } from '@/packages'
import type { CloseButtonPosition } from '@/packages/types'
import { useCopyCode } from '~/composables/useCopyCode'
import CopyIcon from '~/components/icons/CopyIcon.vue'
import CheckIcon from '~/components/icons/CheckIcon.vue'

const props = defineProps({
closeButtonPosition: String as PropType<CloseButtonPosition>
})

const emit = defineEmits<{
(e: 'update:closeButtonPosition', position: CloseButtonPosition): void
}>()

const positions = [
'top-left',
'top-right',
'bottom-left',
'bottom-right'
] as const

const renderedCode = computed(() => {
return `<Toaster closeButton="true" closeButtonPosition="${props.closeButtonPosition}" />`
})
const showCheckIcon = ref(false)

const handleChangePosition = (activePosition: CloseButtonPosition) => {
toast.dismiss()
emit('update:closeButtonPosition', activePosition)

toast('Event has been created', {
description: 'Monday, January 3rd at 6:00pm',
closeButton: true,
closeButtonPosition: 'bottom-right'
})
}

const handleCopyCode = async () => {
await useCopyCode({ code: renderedCode.value, checkIconRef: showCheckIcon })
toast('Copied to your clipboard!!!')
}
</script>
17 changes: 0 additions & 17 deletions app/components/Others.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,6 @@ const allTypes = [
emit('setRichColors', true)
}
},
{
name: 'Close Button',
snippet: `toast('Event has been created', {
description: 'Monday, January 3rd at 6:00pm',
})

// ...

<Toaster closeButton />
`,
action: () => {
toast('Event has been created', {
description: 'Monday, January 3rd at 6:00pm'
})
emit('setCloseButton')
}
},
{
name: 'Headless',
snippet: `import { markRaw } from 'vue'
Expand Down
2 changes: 2 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ declare module 'vue' {
'Carbon:cafe': typeof import('~icons/carbon/cafe')['default']
'Carbon:logoTwitter': typeof import('~icons/carbon/logo-twitter')['default']
CheckIcon: typeof import('./app/components/icons/CheckIcon.vue')['default']
ClosePosition: typeof import('./app/components/ClosePosition.vue')['default']
copy: typeof import('./app/components/Position copy.vue')['default']
CopyIcon: typeof import('./app/components/icons/CopyIcon.vue')['default']
Expand: typeof import('./app/components/Expand.vue')['default']
Footer: typeof import('./app/components/Footer.vue')['default']
Expand Down
3 changes: 2 additions & 1 deletion src/packages/Toast.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
:aria-label="closeButtonAriaLabel || 'Close toast'"
:data-disabled="disabled"
data-close-button="true"
:data-close-button-position="closeButtonPosition"
:class="cn(classes?.closeButton, toast?.classes?.closeButton)"
@click="handleCloseToast"
>
Expand Down Expand Up @@ -484,4 +485,4 @@ function handleDragEnd() {
swipeDirection.value = null;
pointerStartRef.value = null;
}
</script>
</script>
49 changes: 39 additions & 10 deletions src/packages/Toaster.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
:closeButton="toastOptions?.closeButton ?? closeButton"
:interacting="interacting"
:position="pos"
:closeButtonPosition="toastOptions?.closeButtonPosition ?? closeButtonPosition"
:style="toastOptions?.style"
:unstyled="toastOptions?.unstyled"
:classes="toastOptions?.classes"
Expand Down Expand Up @@ -163,6 +164,7 @@ defineOptions({
const props = withDefaults(defineProps<ToasterProps>(), {
invert: false,
position: 'bottom-right',
closeButtonPosition: 'top-left',
hotkey: () => ['altKey', 'KeyT'],
expand: false,
closeButton: false,
Expand Down Expand Up @@ -489,9 +491,6 @@ html[dir='ltr'],
--toast-svg-margin-end: 0px;
--toast-button-margin-start: auto;
--toast-button-margin-end: 0;
--toast-close-button-start: 0;
--toast-close-button-end: unset;
--toast-close-button-transform: translate(-35%, -35%);
}

html[dir='rtl'],
Expand All @@ -502,9 +501,6 @@ html[dir='rtl'],
--toast-svg-margin-end: -1px;
--toast-button-margin-start: 0;
--toast-button-margin-end: auto;
--toast-close-button-start: unset;
--toast-close-button-end: 0;
--toast-close-button-transform: translate(35%, -35%);
}

[data-sonner-toaster] {
Expand Down Expand Up @@ -699,11 +695,44 @@ html[dir='rtl'],
background: rgba(255, 255, 255, 0.3);
}

[data-sonner-toaster] [data-close-button-position='top-left'] {
--toast-close-button-left: 0;
--toast-close-button-right: unset;
--toast-close-button-top: 0;
--toast-close-button-bottom: unset;
--toast-close-button-transform: translate(-35%, -35%);
}

[data-sonner-toaster] [data-close-button-position='top-right'] {
--toast-close-button-left: unset;
--toast-close-button-right: 0;
--toast-close-button-top: 0;
--toast-close-button-bottom: unset;
--toast-close-button-transform: translate(35%, -35%);
}

[data-sonner-toaster] [data-close-button-position='bottom-left'] {
--toast-close-button-left: 0;
--toast-close-button-right: unset;
--toast-close-button-top: unset;
--toast-close-button-bottom: 0;
--toast-close-button-transform: translate(-35%, 35%);
}

[data-sonner-toaster] [data-close-button-position='bottom-right'] {
--toast-close-button-left: unset;
--toast-close-button-right: 0;
--toast-close-button-top: unset;
--toast-close-button-bottom: 0;
--toast-close-button-transform: translate(35%, 35%);
}

[data-sonner-toast][data-styled='true'] [data-close-button] {
position: absolute;
left: var(--toast-close-button-start);
right: var(--toast-close-button-end);
top: 0;
left: var(--toast-close-button-left);
right: var(--toast-close-button-right);
top: var(--toast-close-button-top);
bottom: var(--toast-close-button-bottom);
height: 20px;
width: 20px;
display: flex;
Expand Down Expand Up @@ -1205,4 +1234,4 @@ html[dir='rtl'],
opacity: 0;
transform: scale(0.8) translate(-50%, -50%);
}
</style>
</style>
6 changes: 6 additions & 0 deletions src/packages/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export interface ToastT<T extends Component = Component> {
classes?: ToastClasses
descriptionClass?: string
position?: Position
closeButtonPosition?: CloseButtonPosition
testId?: string
}

Expand All @@ -112,6 +113,8 @@ export type Position =
| 'top-center'
| 'bottom-center'

export type CloseButtonPosition = Exclude<Position, 'top-center' | 'bottom-center'>

export interface HeightT {
height: number
toastId: number | string
Expand All @@ -130,6 +133,7 @@ export interface ToastOptions {
classes?: ToastClasses
closeButtonAriaLabel?: string
toasterId?: string
closeButtonPosition?: CloseButtonPosition
}

type Offset =
Expand All @@ -147,6 +151,7 @@ export interface ToasterProps {
invert?: boolean
theme?: Theme
position?: Position
closeButtonPosition?: CloseButtonPosition
hotkey?: string[]
richColors?: boolean
expand?: boolean
Expand Down Expand Up @@ -177,6 +182,7 @@ export interface ToastProps {
heights: HeightT[]
gap?: number
position: Position
closeButtonPosition?: CloseButtonPosition
visibleToasts: number
expandByDefault: boolean
closeButton: boolean
Expand Down
Loading