question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add slot name to `amplify-toast`

See original GitHub issue

Is your feature request related to a problem? Please describe. I’d like to add custom style to toast notification. I’ve seen other issue about this, like #5604 #6167 #2834

Describe the solution you’d like Fully customize toast notification via slot as other ui components do.

I think it’s matter of few lines in this file: https://github.com/aws-amplify/amplify-js/blob/3642e6af455ee1848c1cc743a7a503e96baefa41/packages/amplify-ui-components/src/components/amplify-toast/amplify-toast.tsx

render() {
    return (
      <slot name="toast-notification">
        <div class="toast">
          <amplify-icon class="toast-icon" name="warning" />
          {this.message ? <span>{this.message}</span> : null}
          <slot />
          <button class="toast-close" onClick={this.handleClose} />
        </div>
      </slot name="toast-notification">
    );
  }

Could you consider a PR?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:19
  • Comments:16 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
Luke-Daviescommented, Mar 14, 2021

You can now prevent the default toast from showing using the hideToast prop on AmplifyAuthenticator.

See this simple example from #7129 for how to implement your own notification/alert component in react (typescript):

import React, { useState, useEffect } from 'react';
import { Hub, HubCallback } from '@aws-amplify/core';
import {
  AmplifyAuthenticator,
} from '@aws-amplify/ui-react';
import {
 UI_AUTH_CHANNEL, TOAST_AUTH_ERROR_EVENT
} from '@aws-amplify/ui-components';

const MyAuth: React.FC = ({ children }) => {

  const [alertMessage, setAlertMessage] = useState('');

  const handleToastErrors: HubCallback = ({ payload }) => {
    if (payload.event === TOAST_AUTH_ERROR_EVENT && payload.message) {
      setAlertMessage(payload.message);
    }
  };

  useEffect(() => {
    Hub.listen(UI_AUTH_CHANNEL, handleToastErrors);
    return () => Hub.remove(UI_AUTH_CHANNEL, handleToastErrors);
  });

  return (
    <>
      {alertMessage && (<div>{alertMessage}</div>)}
      <AmplifyAuthenticator hideToast>
        // ...........
      </AmplifyAuthenticator>
    </>
  );
}

You can just replace <div>{alertMessage}</div> with your own component, using your own styles etc (for example a modal).

For anyone wondering why this ended up as a prop instead of a slot as suggested at the top of this issue; a slot approach was investigated (#7601) but the implementation would have required making trade-offs that the prop approach simply avoids.

4reactions
1443658commented, Dec 23, 2020

I have solved the problem.

It should listen to UI Auth instead of auth channel, then check whether the res.payload.event is ToastAuthError. It would literally captured all events related to authorization including case that no actual auth request is sent.

Here is the code :

Hub.listen("UI Auth", (res) => {  //Listen to UI Auth channel
      if (res?.payload?.event === 'ToastAuthError') {
        let errorMsg = res?.payload?.message
          ? res.payload.message
          : null;

        switch (res.payload.message?.trim()) {
          case "Custom auth lambda trigger is not configured for the user pool.":
            errorMsg = "Password cannot be empty";
            break;
           .......  // The rest is the same

On hiding the default Toast, I’ve changed to use interval to loop on it instead of just once, so that it is still safe to set a shorter waiting time (Not sure whether it has significant improvement though).

  const hideToast = () => {
    const target: HTMLElement = document.getElementsByTagName("amplify-authenticator")[0];
    if (target?.shadowRoot?.children) {
      let el!: HTMLElement;

      let interval = setInterval(function () {
        el = target!.shadowRoot!.children[0] as HTMLElement;
        if (el.tagName.toLocaleLowerCase() === "amplify-toast") {
          el.style.display = "none";
          clearInterval(interval);
        }
      }, 1);  // delay time = 1
    }
  }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Add slot name to `amplify-toast` - - Bountysource
Add slot name to `amplify -toast` ... I'd like to add custom style to toast notification. I've seen other issue about this, like...
Read more >
Figma-to-Code (React) - Component slots - AWS Amplify Docs
Add component slots to Amplify-generated Figma-to-code components. Use this to support nested components or collections in React code. - AWS Amplify Docs.
Read more >
amplify-js
AWS Amplify provides a declarative and easy-to-use interface across different categories of cloud operations. AWS Amplify goes well with any JavaScript based ...
Read more >
Change auth state from custom component while using @aws ...
I am trying to integrate Amplify Auth with a React application. ... slot={props.slot}> <h4>Login</h4> <p>Need an account?
Read more >
Introducing Component Slots for Figma-to-React code in ...
Add a Slot · By default, your slot will inherit the name of the Frame you selected · You'll be prompted to confirm...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found