简体   繁体   中英

@aws-amplify/ui-react how to customize UI if my project uses SASS?

I'm extending a Next.js (React) project that was built by someone else, which uses.scss files (SASS) for styling. This is the project in question https://github.com/codebushi/nextjs-starter-dimension

Now I'm adding an authentication flow to the project using @aws-amplify/ui-react . Everything works fine, but I want to customize the UI style. I've found in the documentation that I can do that through :root in globals.css, as so:

:root {
  --amplify-primary-color: #ff6347;
  --amplify-primary-tint: #ff7359;
  --amplify-primary-shade: #e0573e;
}

Documentation here: https://docs.amplify.aws/ui/customization/theming/q/framework/react

I know pretty much nothing about SASS except the basics. How would I do the equivalent of setting those variables in :root ?

Edit with more details

This is my next.config.js :

module.exports = {
  webpack: (config, { dev }) => {
    config.module.rules.push(
      {
        test: /\.scss$/,
        use: ['raw-loader', 'sass-loader']
      }
    )
    return config
  }
}

This is my authentication page where the Amplify elements are defined:

import { useState, useEffect } from 'react'
import { AuthState, onAuthUIStateChange } from '@aws-amplify/ui-components';
import { AmplifyAuthenticator, AmplifyAuthContainer, AmplifySignUp, AmplifySignIn, AmplifySignOut } from '@aws-amplify/ui-react';
import Router from 'next/router'

const Auth = (props) => {
  const [authState, setAuthState] = useState();
  const [user, setUser] = useState();

  useEffect(() => {
      return onAuthUIStateChange((nextAuthState, authData) => {
          setAuthState(nextAuthState);
          setUser(authData);
          //console.log(`authData: ${JSON.stringify(authData, null, 2)}`);
      });
  }, []);

  if (authState === AuthState.SignedIn && user) {
    Router.push('https://mywebsite')
    return <p>Redirecting...</p>
  }

  return (
    <AmplifyAuthContainer>
        <AmplifyAuthenticator usernameAlias="email">
          <AmplifySignUp
            slot="sign-up"
            usernameAlias="email"
            formFields={[
              {
                type: "email",
                label: "Email Address *",
                placeholder: "Enter your email address",
                inputProps: { required: true },
              },
              {
                type: "password",
                label: "Password *",
                placeholder: "Enter your password",
                inputProps: { required: true },
              },
            ]} 
          />
          <AmplifySignIn slot="sign-in" usernameAlias="email" />
        </AmplifyAuthenticator>
    </AmplifyAuthContainer>
  );
}

export default Auth;

As per the answer below from Sean W, I've already tried creating an _app.js with:

import '../styles/global.scss'

const App = ({ Component, pageProps }) => {
  return <Component {...pageProps} />
}

export default App;

with global.scss :

:root {
  --amplify-primary-color: #ff6347;
  --amplify-primary-tint: #ff7359;
  --amplify-primary-shade: #e0573e;
}

But the CSS variables don't seem to be replaced.

Include the styles in your pages. The easiest way is to create a new SCSS file and include it in a custom _app.js .

By default, Next supports SASS - you only need to install the sass npm package and likely do not need a custom next.config. This could be one of your problems.

file - global.scss -

:root{
  --amplify-primary-color: #ff6347;
  --amplify-primary-shade: #e0573e;
}

//scoped & redeclared to an element with id #__next
:root #__next {
  --amplify-primary-color: #ff6347;
  --amplify-primary-shade: #e0573e;
}

Amplify could also be setting setting styles after you have already defined them for the:root - if this is the case you will need to scope your custom styles to take precedence over the default Amplify CSS variables. To do this - redeclare them in a CSS rule that is more specific than :root like the example above - keeping order of precedence in mind

Amplify also lets you directly target components .

amplify-authenticator {
  --amplify-primary-color: #ff6347;
  background: var(--amplify-primary-color);
  padding: 5px;
}

// scoped & redeclared 
:root #__next amplify-sign-in{
  --amplify-primary-color: #ff6347;
}

The amplify elements that can be targeted are

  • amplify-authenticator
  • amplify-sign-in
  • amplify-confirm-sign-in
  • amplify-sign-up
  • amplify-confirm-sign-up
  • amplify-forgot-password
  • amplify-require-new-password
  • amplify-verify-contact
  • amplify-totp-setup

import your file - pages/_app.js

import 'path/to/global.scss';
const App = ({ Component, pageProps }) => <Component {...pageProps} />;
export default App;

Global variables (the equivalent of :root variables) can be created simply with this line.

$color = #c0ff33 !important;

The content can be anything that is available in css and partially sass. For large projects, creating a variables.scss file and including in it all these variable declarations can be truly helpful for changing multiple variables at once. To include this file, just do @import "./variables.scss" at the top of your file.

Hope this helps! Good luck in your sassy endeavors!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM