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-expand

v2.9.0

Published

Simple element expand state controlling

Downloads

40

Readme

React Expand

codecov Build Status npm

Component for controlling expand state of each elements on page.

Usage

Somewhere in code

<ExpandController>
    <SomeComponent/>
</ExpandController>

Controlling expand state

import * as React from "react";

export class SomeComponent extends React.Component {
    ...
    public static readonly contextTypes = ExpandControllerContextTypes;
    public readonly context: ExpandContext;
    ...

    public componentDidMount() {
        this.context.changeExpandState("custom-expand-string", false, { someData: "data" })();
    }

    public componentWillUnmount() {
        console.log(this.context.getState("custom-expand-string")); // {someData: "data"}
    }

    public render(): JSX.Element {
        return (
            <React.Fragment>
                <button
                    onClick={this.context.changeExpandState("custom-expand-string")}
                    // Highly recommended use data attribute 
                    // for elements outside controlled element
                    data-expand="custom-expand-string"
                />
                <div
                    // In this case expand state changing on click button 
                    // and click on zone without data attribute "custom-expand-string"
                    className={this.context.isExpanded("custom-expand-string") ? "visible" : "hidden"}
                    data-expand="custom-expand-string"
                >
                    <button onClick={this.context.changeExpandState("custom-expand-string")} />
                </div>
                <div
                    // In this case expand state changing only on click button
                    data-expand-keep="more-custom-expand-string"
                >
                    <button onClick={this.context.changeExpandState("more-custom-expand-string")} />
                </div>
            </React.Fragment>
        );
    }
}

Migration from 1.x.x to 2.x.x

Short overview

| v1.x.x | v2.x.x | |---------------------- |------------------------------------------------------------------------------------------ | | < Collapse /> | < ExpandControl /> as controlElement < ControlledExpandElement /> as < Collapse /> | | < Header /> | tabId -> expandId | | < Tab /> | tabId -> expandId | | < Popup /> | < ControlledExpandElement /> as < Popup /> | | < ModalOpenButton /> | < ExpandControl staticState={true} /> as < ModalOpenButton /> | | < ModalCloseButton /> | < ExpandControl staticState={false}/> as < ModalCloseButton /> |

Collapse

Collapse component is depricated. Use ExpandControl and ControlledExpandElement instead

OLD
<Collapse 
    controlElement={({state: boolean, onClick: () => void}) => <i className={state ? "open": "closed"} onClick={onClick}/>} 
    defaultOpened
    {...HTMLDivElementProps}
>
      ...
</Collapse>
NEW
<ExpandControl 
    {...HTMLButtonElementProps} 
    expandId="collapse-id" 
    activeClassName="is-active"
    state={{myData: true}}
    activeOnMount
>
    ...
</ExpandControl>
<ControlledExpandElement 
    {...HTMLDivElementProps} 
    expandId="collapse-id"
    closeOnOutside
>
      ...
</ControlledExpandElement>

Tabs

Prop tabId is depricated. Use expandId instead

OLD
<TabsController>
   <Header activeClassName="is-active" tabId="tab_1" {...HTMLDivElementProps} >
     ...
   </Header>
   <Header tabId="tab_2" {...HTMLDivElementProps} >
     ...
   </Header>
   <Tab activeClassName="is-active" tabId="tab_1" {...HTMLDivElementProps} >
     ...
   </Tab>
   <Tab tabId="tab_2" {...HTMLDivElementProps}>
     ...
   </Tab>
</TabsController>
NEW
<TabsController>
   <Header activeClassName="is-active" expandId="tab_1" {...HTMLDivElementProps} >
     ...
   </Header>
   <Header expandId="tab_2" {...HTMLDivElementProps} >
     ...
   </Header>
   <Tab activeClassName="is-active" expandId="tab_1" {...HTMLDivElementProps} >
     ...
   </Tab>
   <Tab expandId="tab_2" {...HTMLDivElementProps}>
     ...
   </Tab>
</TabsController>

Popup

Popup component is depricated. Use ExpandControl and ControlledExpandElement instead

OLD
<PopupControl popupId="popup-id" triggerEvent={TriggerEvents.hover}>
    // Single component
    ...
</PopupControl>
<Popup popupId="popup-id" {...HTMLDivElementProps}>
    ...
</Popup>
NEW
<ExpandControl 
    {...HTMLButtonElementProps} 
    expandId="popup-id" 
    triggerEvent="hover" // or "click"
    activeClassName="is-active"
>
    ...
</ExpandControl>
<ControlledExpandElement 
    {...HTMLDivElementProps} 
    expandId="popup-id" 
    closeOnOutside
>
      ...
</ControlledExpandElement>

Modal

ModalOpenButton and ModalCloseButton components is depricated. Use ExpandControl instead

OLD
<ModalOpenButton modalId="some-id" {...HTMLButtonElementProps}/>
<Modal modalId="some-id" defaultOpened closeOnOutside {...HTMLDivElementProps}>
    ...
    <ModalCloseButton {...HTMLButtonElementProps}/>
</Modal>
NEW
<ExpandControl expandId="some-id" staticState={true} {...HTMLButtonElementProps}/>
<Modal modalId="some-id" defaultOpened closeOnOutside {...HTMLDivElementProps}>
    ...
    <ExpandControl expandId="some-id" staticState={false} {...HTMLButtonElementProps}/>
</Modal>
<ExpandControl expandId="some-id" staticState={false} {...HTMLButtonElementProps}/> // close button actualy can be outside modal

Presets

NOTE: You must provide context to child nodes with <ExpandController>

HashListener

// will expand element with expandId 'expandElementId1' and 'expandElementId2'
// when href will be 'somepath/#expandElementId2/anotherPathIfYouWant/#expandElementId1'
<HashListener onHashExpanded={(expandId: string) => console.log(expandId)}>
    <ControlledExpandElement expandId="expandElementId1"/>
    <ControlledExpandElement expandId="expandElementId2"/>
</HashListener>

HashControl

// same as html link, except activeClassName, that binds when element with
// href, that contains expand keys, is active
<HashControl 
    {...HTMLAnchorProps}
    activeClassName="active" 
    href="somepath/#expandElementId2/anotherPathIfYouWant/#expandElementId1"
 >
   ...
</HashControl>

Tabs

<TabsController defaultOpened="tab_2">
   <Header activeClassName="is-active" expandId="tab_1" {...HTMLDivElementProps} > // Click on header to activate according tab
     ...
   </Header>
   <Header expandId="tab_2" {...HTMLDivElementProps} >
     ...
   </Header>
   <Tab activeClassName="is-active" expandId="tab_1" {...HTMLDivElementProps} >
     ...
   </Tab>
   <Tab expandId="tab_2" {...HTMLDivElementProps}>
     ...
   </Tab>
</TabsController>

Modal

<ExpandControl expandId="some-id" staticState={true} {...HTMLButtonElementProps}/>
<Modal modalId="some-id" defaultOpened closeOnOutside {...HTMLDivElementProps}>
    ...
    <ExpandControl expandId="some-id" staticState={false} {...HTMLButtonElementProps}/>
</Modal>
<ExpandControl expandId="some-id" staticState={false} {...HTMLButtonElementProps}/>

Expand

<ExpandControl 
    {...HTMLButtonElementProps} 
    expandId="some-expand-id" 
    triggerEvent="hover"
    activeClassName="is-active"
    staticState={true}
>
    show
</ExpandControl>
<ExpandControl 
    {...HTMLButtonElementProps} 
    expandId="some-expand-id" 
    triggerEvent="hover"
    activeClassName="is-active"
    staticState={false}
>
    hide
</ExpandControl>
<ExpandControl 
    {...HTMLButtonElementProps} 
    expandId="some-expand-id" 
    triggerEvent="click"
    activeClassName="is-active"
    activeOnMount
>
    hide
</ExpandControl>
<ControlledExpandElement 
    {...HTMLDivElementProps} 
    expandId="some-expand-id"
>
      ...
</ControlledExpandElement>

Slider

<SliderController autoPlay autoPlayDelay={5000}>
    <Slide disableDrag {...HTMLDivElementProps}>
        ...
    </Slide>
    // Slide that will be displayed on mount
    <Slide initial {...HTMLDivElementProps}>
        ...
    </Slide>
    <Slide dragSensitive={500} {...HTMLDivElementProps}>
        ...
    </Slide>
    <Dots {...HTMLButtonElementProps}/>
</SliderController>
<SliderController>
    <SlideButton drection={Direction.prev} {...HTMLButtonElementProps}>
        ...
    </SlideButton>
    // will render [[some banner 1, some banner 2, some banner 3], [some banner 4, some banner 5, some banner 6], [some banner 7]]
    <SlideGroup groupSize={3}>
        <span>some banner 1</span>
        <span>some banner 2</span>
        <span>some banner 3</span>
        <span>some banner 4</span>
        <span>some banner 5</span>
        <span>some banner 6</span>
        <span>some banner 7</span>
    </SlideGroup>
    <SlideButton direction={Direction.next} {...HTMLButtonElementProps}>
        ...
    </SlideButton>
    <Dots activeClassName="active" {...HTMLButtonElementProps}>
        ...
    </Dots>
</SliderController>

Server-side render

Because ReactDOM.createPortal does not support SSR, you must modify code for correct work of <Modal/> component

Client side

export class Layout extends React.Component {
    public render(): React.ReactNode {
        return (
            <ExpandController>
                <Modal modalId="some-id" defaultOpened>
                    ...
                </Modal>
            </ExpandController>
        );
    }    
}

Server side

app.get("*", (request, response) => {
    ReactDOMServer.renderToNodeStream(
        <html {...htmlAttrs} data-version={version}>
            <body className={StaticContainer.childrenLength ? Modal.defaultProps.activeBodyClassName : ""}>
                <div id="app">
                    <Layout />
                </div>
                <div id={ModalContainer.containerId}>
                    {StaticContainer.renderStatic()}
                </div>
            </body>
        </html>
    ).pipe(response);
})

You also can use <StaticContainer/> and <OuterContextPorvider/> in your needs.