Giter VIP home page Giter VIP logo

svelte-french-toast's Introduction

Website · NPM Package

svelte-french-toast

Buttery smooth Svelte notifications.

svelte-french-toast is a Svelte port of Timo Lins’s react-hot-toast, a lightweight, customizable, and beautiful-by-default toast notification library.

Installation

Install the package with your favorite package manager:

npm install svelte-french-toast
pnpm install svelte-french-toast
yarn add svelte-french-toast

Basic usage

Mount a <Toaster /> at the top level of your app and use the toast API to display toasts.

<script>
	import toast, {Toaster} from 'svelte-french-toast'

	function handleClick() {
		toast.success('Hello, world!')
	}
</script>

<Toaster />
<button type="button" on:click={handleClick}>Toast</button>

For more usage examples, see the website.

Thanks

Thanks to the original author of React Hot Toast and its contributors.

MIT License

Copyright (c) 2020 Timo Lins

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

svelte-french-toast's People

Contributors

dependabot[bot] avatar kbrgl avatar marcuscemes avatar nickgraffis avatar thebjorn avatar thenbe avatar yiak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

svelte-french-toast's Issues

Using toast.promise with use:enhance

Hi! Forgive me if it seems like a basic quesiton, I'm still learning Svelte(kit).

I have a Form component with use:enhance attached, sending data to the +page.server.js with POST and returning new data. I wanted to somehow use toast.promise before and after the form submission, as per the svelte docs , with the form property as promise but I'm not quite sure how and where to implement it. Could you give me some pointers?

+page.server.js looks like this

import { fail } from '@sveltejs/kit'

export const actions = {
  default: async ({ request }) => {
    const form = await request.formData()
    const newGame = form.get('new-game')
    const newPlatform = form.get('new-platform')

    if (!newGame) {
      return fail(400, { newGame, missing: true })
    }
    return { success: true, newGame, newPlatform }
  }
}

+page.svelte

<script>
  import Form from '$lib/components/Form.svelte'
  import toast, { Toaster } from 'svelte-french-toast'
  export let data
  export let form
</script>

<Form />

{#if form?.success}
  <p>Added {form.newGame} on {form.newPlatform}</p>
{/if}

Form.svelte

<script>
  import { enhance } from '$app/forms'
  export let categories
</script>

<form method='POST' use:enhance>
  <input type='text' name='new-game'>
  <input type='text' name='new-platform'>
  <button type='submit'>Create</button>
</form>

Failed to resolve 'svelte-french-toast'

I added svelte-french-toast to my project with the pnpm install svelte-french-toast command. When I try to build the project I get this error:
🔴 ERROR | Failed to resolve 'svelte-french-toast' from './options.svelte' 🔴 ERROR | Cannot load file './index' from module 'svelte-french-toast'
I am using the Plasmo Framework for extension development using Svelte so that may be related. I am using "plasmo": "0.83.0" and "svelte": "4.2.0"

Global styles?

Can it be made possible to globally change the classes/styles applied to each part of the toaster? It would be preferential for app-wide theming to declare these things at a single point of authority rather than in every function call.

Offering the same props available to the toast() function to the toaster would be a good solution in my opinion.

WARNING: The following packages use a svelte resolve configuration in package.json that has conflicting results and is going to cause problems future

Hi,

whit last version I get warning:

WARNING: The following packages use a svelte resolve configuration in package.json that has conflicting results and is going to cause problems future

[email protected]

{
"name": "etlevsdrowtsv2",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build --base=./",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.1.0",
"@tsconfig/svelte": "^4.0.1",
"svelte": "^3.58.0",
"svelte-check": "^3.2.0",
"svelte-preprocess": "^5.0.3",
"tslib": "^2.5.0",
"typescript": "^5.0.4",
"vite": "^4.3.1"
},
"dependencies": {
"svelte-french-toast": "^1.0.3"
}
}

Update an existing toast?

Is there any way to get a reference to an existing toast if visible and update it directly?

If someone saves several times, I'd love to show some kind of feedback in the existing toast instead of showing 4 in a row of the same thing.

Toasts are appearing unstyled

I've been having some problems setting up svelte-french-toast in my application, which uses Svelte with Inertia and Webpack 5 (via Encore).

When I invoke a toast, there is no styling:

Screenshot from 2022-07-03 23-06-05

I'm using this code:

<script>
import { onMount } from 'svelte';
import toast, { Toaster } from 'svelte-french-toast';

onMount(() => {
    toast.success("Hello, world!");
})
</script>

<Toaster />

I'm not really sure how to go about debugging this further since this is my first project with Svelte. There are no errors in the console.

Add more comprehensive documentation + Discord?

The API surface isn’t very well documented outside of a few common use cases that are listed on the website. As this library grows, we need better docs.

We could either do Docusaurus or bake in docs in the current website.

Further, it might also be nice to have a Discord channel for this package. A server doesn't make sense since this isn’t a framework—perhaps we can integrate into one of the existing Svelte community Discord servers?

Getting 404 while using Toaster

I have no idea as to why this is occuring

SvelteKitError: Not found: /dashboard/Toaster.svelte
    at resolve (~\node_modules\@sveltejs\kit\src\runtime\server\respond.js:522:13)
    at resolve (~\node_modules\@sveltejs\kit\src\runtime\server\respond.js:322:5)
    at resolve (~\node_modules\@sveltejs\kit\src\exports\hooks\sequence.js:115:9)
    at routing (~\src\hooks.server.ts:96:25)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async cloudflare (~\src\hooks.server.ts:68:9)
    at async Module.respond (~\node_modules\@sveltejs\kit\src\runtime\server\respond.js:319:20)
    at async ~/node_modules/@sveltejs/kit/src/exports/vite/dev/index.js:524:22 {
  status: 404,
  text: 'Not Found'
}

Caught the error in client hooks

export const handleError: HandleClientError = ({ error, event }) => {}

Toast not being read by screen readers in Firefox

It doesn't seem like toast messages are being read in FF. I'm using the latest version of NVDA and when I show the toast it just says alert but if I do this in Chrome it works fine. I checked the demo on the website and that works fine in FF so I'm not sure if there is a difference in versions there. I'm running the latest version of French Toast and just installed it in a project.

A11y ARIA Role Warning

Hi :)

Lately, I noticed an a11y warning in my tests regarding svelte-french-toast: A11y: <div> with mouseenter, mouseleave handlers must have an ARIA role.
This warning comes from the <div> element in Toaster.svelte.
Maybe we should consider adding an alert aria role?

<div role="alert"
    class="toaster {containerClassName || ''}"
    style={containerStyle}
    on:mouseenter={handlers.startPause}
    on:mouseleave={handlers.endPause}
>
    {#each _toasts as toast (toast.id)}
	<ToastWrapper {toast} setHeight={(height) => handlers.updateHeight(toast.id, height)} />
    {/each}
</div>

Thanks in advance🙏

Update to Svelte 4

Just a reminder to update the peer dependency to Svelte 4 to avoid incompatibility issues with the latest version

Pass classes into toast

I'm not sure if I missed it, but it'd be great to be able to pass in classes to the toast call function, for example to use Tailwind to style it. Otherwise this is still a great library. Thanks a lot

eslint import/order parse errors

When I try to use this package with https://github.com/import-js/eslint-plugin-import I get the following error:

eslint . --fix

Checking formatting...
All matched files use Prettier code style!

Error while parsing /home/haseeb/projects/bookmarkey/gui/node_modules/svelte-french-toast/index.js
Line 2, column 9: Unexpected token
`parseForESLint` from parser `/home/haseeb/projects/bookmarkey/gui/node_modules/svelte-eslint-parser/lib/index.js` is invalid and will just be ignored

/home/haseeb/projects/bookmarkey/gui/src/routes/(unprotected)/(account)/login/+page.svelte
  3:20  error    Parse errors in imported module 'svelte-french-toast': parser.parse is not a function (undefined:undefined)  import/default
  3:20  warning  Parse errors in imported module 'svelte-french-toast': parser.parse is not a function (undefined:undefined)  import/no-named-as-default
  3:20  warning  Parse errors in imported module 'svelte-french-toast': parser.parse is not a function (undefined:undefined)  import/no-named-as-default-member

Where my eslint config file looks like:

module.exports = {
	root: true,
	parser: '@typescript-eslint/parser',
	parserOptions: {
		project: './tsconfig.json',
		extraFileExtensions: ['.svelte']
	},
	extends: [
		'eslint:recommended',
		'plugin:svelte/recommended',
		'plugin:@typescript-eslint/recommended',
		'prettier',
		'plugin:import/errors',
		'plugin:import/warnings',
		'plugin:import/typescript'
	],
	plugins: ['@typescript-eslint'],
	ignorePatterns: ['*.cjs', 'svelte-french-toast'],
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	],
	settings: {
		// 'import/ignore': ['svelte-french-toast'],
		'svelte3/typescript': () => require('typescript')
	},
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020
	},
	env: {
		browser: true,
		es2017: true,
		node: true
	}
};

Adding this line 'import/ignore': ['svelte-french-toast'], in settings fixes this issue by ignoring it I believe, https://github.com/import-js/eslint-plugin-import#importignore. Any ideas what is actually is causing the issue ? It seems the parser cannot parse the index file in this library.

Thanks

How to use `props` with a custom component in typescript?

Writing the following gives me an error on props:

toast(CustomToast, { props: { someProp: "⭐" } })

error:

Object literal may only specify known properties, and 'props' does not exist in type
'Partial<Pick<Toast, "id" | "icon" | "duration" | "ariaProps" | "className" | "style" | "position" | "iconTheme">>'.

I tried to extend the Toast type but it's a dead end because of the Pick modifier.

I might be missing something. 🤔

Toast position not working properly in electron

Hello. The positioning of the toast appears to malfunction inside electron.
I'm not sure if it's electron specific or rather the create-svelte-electron-app template.

I tried it on a repl and it works just fine, but using electron, the position seems to be stuck to the top-left. The toasts also don't stack. It would seem the inline styling is not getting applied to the elements.

I've created a blank project with the issue. If you clone it and try to run it, the problem should be apparent.
Here is the link

Incorporate promise results into toast

Can i provide a function to the success/error messages to incorporate the result/error of the promise?

toast.promise(
  myPromise,
  {
    loading: 'Loading',
    success: (data) => `Successfully saved ${data.name}`,
    error: (err) => `This just happened: ${err.toString()}`,
  }
)

Cannot convert undefined or null to object

Cannot convert undefined or null to object
TypeError: Cannot convert undefined or null to object
at Function.assign ()
at eval (/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-french-toast/components/ToastIcon.svelte:33:164)
at Object.$$render (/node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:1876:22)
at eval (/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-french-toast/components/ToastBar.svelte:57:91)
at Object.$$render (/node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:1876:22)
at eval (/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-french-toast/components/ToastWrapper.svelte:56:90)
at Object.$$render (/node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:1876:22)
at eval (/node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-french-toast/components/Toaster.svelte:50:101)
at Module.each (/node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:1842:16)
at Toaster.svelte:24:22

Request for Feature: More Granular Toast Positioning

First of all, thank you very much for this great component! :)

Currently, the svelte-french-toast library positions toasts with a default "fixed" positioning, which centers them relative to the entire screen. However, in some cases, it might be desirable to center the toasts relative to a specific section of the page, such as a content area in a two-column layout (sidebar - content).

Is this already somehow possible?

If not, here are two ideas for implementing it:

  1. Allow users to set the positioning of the toasts to either "fixed" or "absolute". This would give users the ability to control the centering of the toasts by placing the toaster in a specific place.

<Toaster position="absolute" />

  1. Allow users to specify an offset, such as "offset-left: 250px". This would give users the ability to fine-tune the positioning of the toasts to their liking.

<Toaster offsetLeft="250px"/>

RTL support?

the positions are invalid for RTL layouts. the bottom-left for example appear on the right side, and vice versa.

Here's a repl

Uncaught error when using custom elements in toast.promise()

Description

The loading property accepts a custom Svelte element, however success and error do not.

toast.promise(promise, {
    loading: Toast,
    success: Toast,
    error: "I failed!",
});

A custom success element will throw an error which is caught, and the failed state is rendered.

The following error is thrown (not visible in the REPL):

Uncaught (in promise) TypeError: Class constructors cannot be invoked without 'new'
    at resolveValue (types.js?v=72f77d3a:2:82)
    at toast.js?v=72f77d3a:43:21

which seems to map to this line:

): TValue => (isFunction(valOrFunction) ? valOrFunction(arg) : valOrFunction);

This may be due to the fact that success and error are calling resolveValue(), and loading isn't?

const id = toast.loading(msgs.loading, { ...opts, ...opts?.loading });
promise
.then((p) => {
toast.success(resolveValue(msgs.success, p), {

Reproduction

Svelte REPL

Cannot read properties of undefined (reading 'push')

Hi! When running the server, this bunch of error logs show up:

image

However, when I wrap <Toaster /> with an if browser from SvelteKit, the error stops happening:
image
browser is imported from '$app/environment'

Just opening the issue here in case there are some other people out there that are also experiencing this.

Thanks for this amazing library! We've been using for a few months now and it's been great.

How to pass Component into ToastBar?

Is ToastBar intended to be called separately, or is using Component in ToastBar an old API?

I have seen your blog post, which seems to suggest passing Component to ToastBar from Toaster, but from the current source it does not accepting a Component props:

export let reverseOrder = false;
export let position: ToastPosition = 'top-center';
export let toastOptions: ToastOptions | undefined = undefined;
export let gutter = 8;
export let containerStyle: string | undefined = undefined;
export let containerClassName: string | undefined = undefined;

If that is indeed an old API, how can I use custom component as the toast?

keep toast alive

I currently have the toaster element inside +layout.svelte, but as soon as i change the window location the toast dissapears, is there a way to fix that?

Is this maintained?

The toast messages look absolutely amazing! However, judging from the issues, I have a feeling it's no longer maintained. Especially this: #61 Is it maintained?

Publish type issue fix to npm

Hi @kbrgl ,
I see that the PR #25 to fix type issues for Promise style toast has been merged into master for some time but was not published to npm. Can you please publish this so we can use that feature especially for production builds that run remotely on github using containers? While one can fix the source file in node_modules locally, we can't do this in those remote builds

Are there any alternatives to dismiss notification for custom toasts?

Hi! I have a question about dismissing the notification. You have an example of 'Rich content' toast:
<span> Custom and <b>bold</b> <button on:click={() => toast_.dismiss(toast.id)}>Dismiss</button> </span>
and advice to use toast such this: toast(RichContent). But can I use RichContent component with my custom message property like this: toast()? Or are there any alternatives to have dismiss button (e.g. dismiss property in options object: true with default Icon like toast.error(message, { style: ..., position: ...., **dismiss: true,** });)
Thank you in advance

Disable hover pause behavior?

By default the notification seem to have functionality that allows them to stay on the screen while hovered. Is there a way to disable this? The reason is that I quickly found some edge cases where the notifications get stuck on the screen if the browser window loses focus, and I'm not sure it's easily fixable (because the mouseleave event probably doesn't trigger even when the window is activated again, unless you actually hover over the notification again)

I would rather not deal with this complexity, especially considering the notifications don't have a dismiss button by default, so end user might get into a situation where they don't understand why the notification stays on the screen.

Would it be possible to add something like pauseOnHover: boolean to disable the behavior and have the notifications always close at exactly the duration?

PS. Although a different issue, it would be nice to have a built-in "X" button to dismiss notifications, like svelte-notifications has.

TypeScript error when using a function in toast.promise()

I have some code that looks like this:

toast.promise(response, {
	loading: 'Saving...',
	success: 'Saved!',
	error: (e) => `Something went wrong: ${e}`
});

The code works, however I get the TS error:

Type '(e: any) => string' is not assignable to type 'Renderable'.ts(2322)

I tried typing this in various ways, but I can't figure out how to get it to work. For example both of these examples do not work either:

// Type '(e: any) => Renderable' is not assignable to type 'Renderable'.ts(2322)

// Ex 1
error: (e: any): Renderable => `Something went wrong: ${e}`

// Ex 2
error: (e: any) => {
	return `Something went wrong: ${e}` as Renderable;
}

Toast offset should update when toast updates

When a toast is modified, its height can change, which should update the toast offsets for all other toasts.

For example, in the below code the updated toast is stacked on top of another toast below.

toast.promise(promise, {
loading: 'Saving...',
success: `Settings saved! This message extends across multiple lines.`,
error: `Could not save. This message extends across multiple lines.`
});

Mouseleave event is never triggered on iOS after interacting with a toast that has a button

on:mouseleave={handlers.endPause}

This is an issue on iOS devices (that I've tested... iOS 16 and iPad OS)
When you click on a button (mouseenter) in a toast that has a rich content component (just like in the demo site dismiss btn), the subsequent toasts will be paused and never dismissed automatically.

In my app, I have to dispatch a custom event on dismiss to make sure subsequent toasts don't display forever
document.querySelector('.toaster')?.dispatchEvent(new CustomEvent('mouseleave'));

Can I use this awesome package in Sveltekit?

When I add this package to my Sveltekit project, some errors are encountered.

Internal server error: Failed to resolve entry for package "svelte-french-toast". The package may have incorrect main/module/exports specified in its package.json: No known conditions for "." specifier in "svelte-french-toast" package

toast reappears after navigation

Hi,

I use this library in my project.
In a page, click on a button calls save function as below:

export const save = async () => {
    if (newName === '') {
        toast.error('File name required.', {
            duration: 2000
        });
        return;
    }
    const res = await fetch(`/api/save`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            original: data.fileName,
            new: newName,
            content: data.content
        })
    });

    if (!res.ok) {
        const message = await res.text();
        toast.error(`Error occured: ${message}`, {
            duration: 2000
        });
        return;
    }

    toast.success('Saved.', {
        duration: 2000
    });

    data.fileName = newName;
    edited = false;
};

When I navigate to other page before the toast disappears, it reappears for a short time again.
How can I fix this?

EDIT: Format code

npm installs wrong version

Hey.
I have been trying to create a Rich Content toast and had troubles passing down props, like so:

toast(RichComponent, { props: { someProp: "⭐" } });

I got type errors saying that props does not exist in Partial<Pick<Toast, "id" | "icon" | "duration"... and in my project, RichComponent did show up inside the toast but someProp resolved as undefined.

I dived into the package dist folder and couldn't quite figure out what's wrong, so I cloned the entire repo and have built the package using npm run package. I then copied the newly created dist folder into my project, essentially overriding the one installed from npm, and...

CleanShot 2023-12-30 at 15 05 07@2x

... everything seems to work, except I am still getting type errors, but I can deal with those.

There are certainly some differences between the version I have built myself and the one coming from npm, unless I have done something incredibly stupid (which is likely)

Laggy scroll issue on chrome mobile

When using this library on android chrome mobile, the root wrapper <div class="toaster" /> is making any scroll anywhere on the website laggy: it feels like an fps drop, scroll is not as smooth and it is quite noticeable once you spotted it.
I am not sure why this happens and it might be a chrome mobile issue related to the wrapper being a position fixed div but it could be something else.

I made a quick hack fix by not displaying the container while it does not have any children. This should of course be done properly directly in the lib, but here is the fix FYI:

:global(.toaster) {
  display: none;
}
:global(.toaster:has(div)) {
  display: block;
}

LoaderIcon very large bundle size

When building my app using svelte-french-toast all my chunks in the final build are usually around 1-40kb max but there is this 1 chunk called "LoaderIcon" (presumably from svelte-french-toast) that is 400kb of javascript.

image

Deminified contents:
deminified.txt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.