npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-ambient

v1.0.2

Published

Dead-simple solution for changing the background dynamically based on the most prominent content.

Downloads

6

Readme

react-ambient

Dead-simple solution for changing the background dynamically based on the most prominent content.

See the demo

Quick Start

1 Install

npm i --save react-ambient

2 Add provider

import { AmbientProvider } from 'react-ambient';

function AppLayout() {
  return (
    <AmbientProvider>
      <YourPageView />
    </AmbientProvider>
  );
}

3 Add sections

import { useAmbient } from 'react-ambient';

function Section({ backgroundContent, children }) {
  const [props, { renderBackground }] = useAmbient();

  return (
    <section {...props}>
      {renderBackground(backgroundContent)}
      {children}
    </section>
  );
}

function YourPageView() {
  return (
    <main>
      <Section backgroundContent={<FancyBackground />}>
        <p>Section content</p>
      </Section>
      <Section backgroundContent={<AdvertisingVideo />}>
        <p>Section content</p>
      </Section>
    </main>
  );
}

4 That's it!

You can find full typings for all exported tools in the docs. Or you can view another example in the Storybook.

Usage Tips

Getting started is easy, but there's a bit more to making a page with dynamic backgrounds than just changing the background.

Reacting to the active content globally

You probably want to change some aspects of the current visible content based on the active background. For example, if one of your backgrounds is dark and the other is light, you want content to be visible with good contrast against both while the user scrolls and transitions between them. How can that be done?

Good news, I thought of that! The trick is, each content component which you call useAmbient from can pass its own free-form user data. This data will be available to every content component when they render. Once you it clicks, you'll find it's quite easy to share global data to all content components based on which one is active:

// suppose we pass a 'color' prop to each section, indicating what its foreground color should be,
// and a 'background' prop, which tells what its background should be. as conscientious developers
// we have made sure there's a good contrast between these colors.
function Section({ color, background }) {
  // notice we're pulling out `activeData` from the return values
  const [props, { activeData, renderBackground }] = useAmbient({
    // let's pass our section's foreground color to `data` - now all sections
    // will know the foreground color of this section when it's the active one.
    data: { color },
  });

  return (
    // by pulling the color value from activeData, we are using the color
    // as specified by the currently active section, which presumably will
    // have the best contrast with the currently active background.
    <section {...props} style={{ color: activeData && activeData.color }}>
      {/* (just assume we have a ColorBackground component that renders a solid color here) */}
      {renderBackground(<ColorBackground background={background} />)}
      <p>Some content</p>
    </section>
  );
}

So in each <Section> we render (in this example), we're passing the foreground color to data - and when it renders, the activeData will have the appropriate foreground color, even if the rendered section isn't the one with the active background.

This feature can be used for more than just foreground color though. Put whatever data you want in there!

Changing the transition animation

This library ships with a pretty reasonable fade transition by default, but maybe you want something fancier - or nothing at all. That's easy to do, just pass a WrapperComponent to useAmbient:

import { Scale } from '@material-ui/core';

function Section() {
  const [props, { renderBackground }] = useAmbient({
    WrapperComponent: Scale,
    getWrapperProps: ({ active }) => ({ in: active }),
  });

  return (
    <section {...props}>
      {renderBackground(<BackgroundImage />)}
      Some content
    </section>
  );
}

In this example we're using the Scale transition component from material-ui. Neat!

If you don't want a transition at all, you can pass null.

Of course, if you've got your own component, it probably takes specific props to control the animation. That's where getWrapperProps comes in. Pass a function here which takes the current ambient state ({ active: boolean; activeData: D; activeKey: string; }, where D is the shape of whatever data you provide to useAmbient), and returns the props for your component.