Coder Social home page Coder Social logo

okonet / react-container-dimensions Goto Github PK

View Code? Open in Web Editor NEW
231.0 5.0 30.0 155 KB

Wrapper component that detects element resize and passes new dimensions down the tree. Based on https://github.com/wnr/element-resize-detector

License: MIT License

JavaScript 100.00%

react-container-dimensions's Introduction

react-container-dimensions Build Status npm version

Wrapper component that detects parent (container) element resize and passes new dimensions down the tree. Based on element-resize-detector.

npm install --save react-container-dimensions

It is especially useful when you create components with dimensions that change over time and you want to explicitely pass the container dimensions to the children. For example, SVG visualization needs to be updated in order to fit into container.

It uses getBoundingClientRect() and passes values for all top, right, bottom, left, width, height CSs attributes down the tree.

Usage

  • Wrap your existing components. Children component will recieve top, right, bottom, left, width, height as props.
<ContainerDimensions>
    <MyComponent/>
</ContainerDimensions>    
  • Use a function to pass width or height explicitely or do some calculation. Function callback will be called with an object { width: number, height: number } as an argument and it expects the output to be a React Component or an element.
<ContainerDimensions>
    { ({ height }) => <MyComponent height={height}/> }
</ContainerDimensions>    

How is it different from [similar_component_here]

It does not create a new element in the DOM but relies on the parentNode which must be present. So, basically, it acts as a middleware to pass the dimensions of your styled component to your children components. This makes it very easy to integrate with your existing code base.

For example, if your parent container has display: flex, only adjacent children will be affected by this rule. This means if your children rely on flex CSS property, you can't wrap it in a div anymore since this will break the flexbox flow.

So this won't work anymore:

<div style="display: flex">
    <div>
        <div style="flex: 1">...</div>
    </div>
</div>

react-container-dimensions doesn't change the resulting HTML markup, so it remains:

<div style="display: flex">
    <div style="flex: 1">...</div>
</div>

Example

Let's say you want your SVG visualization to always fit into the container. In order for SVG to scale elements properly it is required that width and height attributes are properly set on the svg element. Imagine the following example

Before (static)

It's hard to keep dimensions of the container and the SVG in sync. Especially, when you want your content to be resplonsive (or dynamic).

export const myVis = () => (
    <div className="myStyles">
        <svg width={600} height={400}>
            {/* SVG contents */}
        </svg>  
    <div>
)

After (dynamic)

This will resize and re-render the SVG each time the div dimensions are changed. For instance, when you change CSS for .myStyles.

import ContainerDimensions from 'react-container-dimensions'

export const myVis = () => (
    <div className="myStyles">
        <ContainerDimensions>
            { ({ width, height }) => 
                <svg width={width} height={height}>
                    {/* SVG contents */}
                </svg>  
            }
        </ContainerDimensions>
    <div>
)

Other similar projects:

and a few others...

react-container-dimensions's People

Contributors

andreypopp avatar cecigarcia avatar d-tucker avatar franklixuefei avatar greenkeeper[bot] avatar idan avatar okonet avatar tarikhuber avatar valentinh avatar zvictor 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

react-container-dimensions's Issues

An in-range update of babel-cli is breaking the build 🚨

Version 6.24.1 of babel-cli just got published.

Branch Build failing 🚨
Dependency babel-cli
Current Version 6.24.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As babel-cli is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • dependency-ci Dependencies checked Details

  • continuous-integration/travis-ci/push The Travis CI build failed Details

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Initial values

Thank you for this very handy project! I have just made a PR to add it to Recharts (http://recharts.org), but there is a minor thing that makes them sort of incompatible.

React-container-dimensions is always sending its initial state (width and height set to zero) to the children components on the first render, and therefore Recharts prints multiple warns saying that it can't render the charts in these conditions.

Can we send others values, other than zeros, to the children? What about having a third parameter hasInitiated, or send null as first values?

Link to the PR: recharts/recharts#105

Width and height are initially zero on Apple iPad Safari

ContainerDimensions returns zero for width and height for the first rendering. It works fine in all desktop browsers. After updating the state it works fine again.

<div css={mainContentStyle}>
  <main css={mainStyle}>
    <div css={someStyle}>
      <Button />
    </div>
<ContainerDimensions>
      {({width, height}) => {
        console.log(width, height);
        return (
          <Renderer width={width} height={height}>
            {scene}
          </Renderer>
        );
      }}
    </ContainerDimensions>
  </main>
</div>

My css looks like this

export const mainContentStyle = css({
  display: 'flex',
  flex: 1,
  
});

export const mainStyle = css({
  display: 'flex',
  flex: 1,
  order: 2,
  overflow: 'hidden',
  height: '100%',
  backgroundColor: threejsWrapperGray
});

_reactDom2.default.findDOMNode is not a function

Hey everyone,

I'm trying to use the react-container-dimensions package with @kadira/storyshots testing approach (an addition to the storybook), however launching the tests results in this error:

_reactDom2.default.findDOMNode is not a function
at ContainerDimensions.componentDidMount (...\node_modules\react-container-dimensions\lib\index.js:69:50)

Meanwhile all the components that do not use the package render successfully.

It feels like a configuration issue. Does anyone have an idea how to fix it?

Calling onResize callback after the component is unmounted

Despite the elementResizeDetector listener is uninstalled before the ContainerDimensions component gets unmounted, I got this warning:

"Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
Please check the code for the ContainerDimensions component."

I only get this warning in a particular scenario where the ContainerDimensions component is rendered in a tab menu component, but I can't figure out why this case is so particular.

I temporarily fix it by adding an instance variable set to true before the onResize callback is called in componentDidMount lifecycle method, set to false in componentWillUnmount and checked before calling setState in the onResize callback.

I suppose it's not a problem with this library itself but with the element-resize-detector library. I hope you could sort it out anyway.

Test logic in `calls onResize when parent has been resized` gives false positive

In looking at the test below, if I make a few modifications which should presumable break the test, it still passes. I've removed the logic that I believe is representing the resize, but it still passes the test.

Original Test (passing)

    it('calls onResize when parent has been resized', (done) => {
        spy(ContainerDimensions.prototype, 'onResize')
        const wrapper = mount(
            <div ref="node" id="node" style={{ width: 10 }}>
                <ContainerDimensions>
                    <MyComponent />
                </ContainerDimensions>
            </div>
        , { attachTo: document.body })
        const el = wrapper.render()
        el.css('width', 10)
        setTimeout(() => {
            el.css('width', 100) // Triggering onResize event
            expect(ContainerDimensions.prototype.onResize.calledTwice).to.be.true
            ContainerDimensions.prototype.onResize.restore()
            done()
        }, 10)
    })

Modified Test (still passing, but how?)

    it('calls onResize when parent has been resized', (done) => {
        spy(ContainerDimensions.prototype, 'onResize')
        const wrapper = mount(
            <div ref="node" id="node" style={{ width: 10 }}>
                <ContainerDimensions>
                    <MyComponent />
                </ContainerDimensions>
            </div>
        , { attachTo: document.body })
        // =========================================================
        // const el = wrapper.render()
        // el.css('width', 10)
        // =========================================================
        setTimeout(() => {
            // =====================================================
            // el.css('width', 100) // Triggering onResize event
            // =====================================================
            expect(ContainerDimensions.prototype.onResize.calledTwice).to.be.true
            ContainerDimensions.prototype.onResize.restore()
            done()
        }, 10)
    })

[Typescript] index.d.ts is not published

When I looked at the files under node_modules/react-container-dimensions, index.d.ts is not there. Probably this is related to how you publish the package? Could you help me look into this?

Resize not reported for particular case where listener element is in flex layout

Please see this Plunker. It is based on one of your examples, but partially replicates the UI of a component in an app my team is developing.

Note how the reported width stays the same after resizing the window. However, if the display style of the first div is changed to block, the reported width changes with each resize. Also, if you instead remove the div with the explicitly specified size (or, just remove the size), the reported width changes with each resize.

Is this a bug, or is it a case your package is not designed to handle?

element-resize-detector not removed correctly on componentWillUnmount

I'm using this library in a react-router application and I have issues when using several detectors in different routes. On the first route, resize events are sent but when I go on a new route, then the library don't send the dimensions anymore.

After a bit of investigations, I found that the element-resize-detector needs to be uninstall on componentWillUnmount since it is instantiated on each componentDidMount. (See https://github.com/wnr/element-resize-detector#uninstallelement).

This block should be replaced by:

 componentWillUnmount() {
    this.elementResizeDetector.uninstall(this.parentNode)
}

Then, everything works properly in React Router...

Do you want me to submit a Pull Request for this?

An in-range update of lint-staged is breaking the build 🚨

Version 4.2.0 of lint-staged just got published.

Branch Build failing 🚨
Dependency lint-staged
Current Version 4.1.3
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As lint-staged is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v4.2.0

4.2.0 (2017-09-15)

Features

  • Print friendlier error if config is missing (#281) (30fa594)
Commits

The new version differs by 8 commits.

  • 30fa594 feat: Print friendlier error if config is missing (#281)
  • 0077644 chore: Cleanup package.json (#250)
  • 7abe23f ci: Disable email notifications from Travis CI
  • c9d0849 docs: Use emojis in the Readme
  • e976a3c docs: Add screenshot with the animated gif (#276)
  • 92e586b docs: Reformat code blocks
  • 9b0282a docs: Use diff formatting for code
  • 33da9b3 ci: Whitelist build branches to avoid duplicate builds (#269)

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

An in-range update of mocha is breaking the build 🚨

Version 3.4.0 of mocha just got published.

Branch Build failing 🚨
Dependency mocha
Current Version 3.3.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As mocha is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Release Notes v3.4.0

Mocha is now moving to a quicker release schedule: when non-breaking changes are merged, a release should happen that week.

This week's highlights:

  • allowUncaught added to commandline as --allow-uncaught (and bugfixed)
  • warning-related Node flags

🎉 Enhancements

🐛 Fixes

🔩 Other

Commits

The new version differs by 9 commits0.

  • 7554b31 Add Changelog for v3.4.0
  • 9f7f7ed Add --trace-warnings flag
  • 92561c8 Add --no-warnings flag
  • ceee976 lint test/integration/fixtures/simple-reporter.js
  • dcfc094 Revert "use semistandard directly"
  • 93392dd no special case for macOS running Karma locally
  • 4d1d91d --allow-uncaught cli option
  • fb1e083 fix allowUncaught in browser
  • 4ed3fc5 Add license report and scan status

false

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

When print it's not pass the correct width

I try to print the svg chart, but since the width of ContainerDimensions doesn't pass the width of print port (it still use the screen width), the svg chart won't be printed correctly. Is there any way that we can work around for the problem?

An in-range update of enzyme is breaking the build 🚨

Version 2.8.1 of enzyme just got published.

Branch Build failing 🚨
Dependency enzyme
Current Version 2.8.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As enzyme is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • dependency-ci Dependencies checked Details

  • continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 33 commits .

  • 8ab9528 v2.8.1
  • 75d1390 Merge pull request #876 from kentcdodds/pr/support-15.5
  • 21f6e7a [Tests] create-react-class should be a static dev dependency.
  • 4464a17 [Tests] move helpers in to test/_helpers dir
  • 22f368f address final comments
  • cc78489 Update error message in react-compat
  • b48e551 Change condition in performBatchedUpdates to a version check
  • 2f957af REACT155 constant is now true for react 15.5 or above
  • f5f6001 Update ReactWrapperComponent to use prop-types package
  • 3ff9832 Update karma cofig to be compatible with [email protected]
  • ec7bbc5 Lint
  • 270ee7f Remove unnecessary tests
  • d6badda Fix import
  • edeb99c Remove dependency on create-react-class
  • b0e2fac Extract batchedUpdates to a function

There are 33 commits in total. See the full diff.

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

React router props not passed to wrapped component

I'm rendering a component in a react router route and when I wrap this component with ContainerDimensions, the props that are normally passed via the props by react router don't reached my component. Do you think it would be possible for ContainerDimensions to pass all the props it receives to its children?

Otherwise, have you ever deal with ContainerDimensions inside a Route?

Here's what I do:

<Route path="/" component={MyComponent}/>

When I export export default MyComponent in my MyComponent.js file, the props contains this:
image

While if I export this from my component:

export default () => (
  <ContainerDimensions>
    <MyComponent/>
  </ContainerDimensions>
)

then I get these props:
image

Thus, I would like to merge this two objects.

What is the best way of getting updated top and left values?

Hi there!

I am making a X/Y control pad thingy where the user can drag an object around within a confined space. I use this module to provide the control pad with the bounds that constraints the objects. This works well when at the top of the page, but as soon as one scrolls, the top and/or left values fetched using getBoundingClientRect() will no longer be true.

I could solve this by composing <ControlDimensions> with another scroll detecting component, but I would first just like to check here if it would be within the scope of the module to support my scenario?

Emits warning about prop 'initiated'

When creating this component with any types of children, the following warning message is emitted to the browser console:

Warning: Received `true` for a non-boolean attribute `initiated`.

If you want to write it to the DOM, pass a string instead: initiated="true" or initiated={value.toString()}.
    in div (created by ContainerDimensions)
    in ContainerDimensions (created by Card)
    in div (created by Card)
    in div (created by Card)
     ... etc etc etc ...

I cannot find any way to stop the warning message from being sent to the console.

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

getBoundingClientRect takes `transform: scale` into account

If some parent element has a transform: scale applied then getBoundingClientRect will take it into account and return actual sizes. This might be undesirable in some situations so probably offsetWidth and offsetHeight are better options but they won't work with SVG elements AFAIK.

Adding a Debounce

I can't seem to see a way to add a debounce, would you be interested in a PR for that? I have a project with a page with multiple graphs, would be useful for lower power machines.

Container height always zero

I am trying to use react-container-dimensions, but the height is always coming through as zero.

    renderChart() {
        return (
            <div className="candleChart">
                <ContainerDimensions>
                    {({width, height}) =>
                        <CandleStickStockScaleChart width={width} height={height}/>
                    }
                </ContainerDimensions>
            </div>
        );
    }
.candleChart {
    width: 100%;
    height: 50%;
}
CandleStickStockScaleChart.render() - height(0) width(1786.949951171875)
CandleStickStockScaleChart.jsx:151:8

Any ideas?

Fails with react-test-renderer

Is there a way to make react-container-dimensions work with react-test-renderer? I'm trying to write some snapshot tests with jest-snapshot and getting the following failure:

     Invariant Violation: getNodeFromInstance: Invalid argument.
      at invariant (node_modules/fbjs/lib/invariant.js:38:15)
      at Object.getNodeFromInstance (node_modules/react-dom/lib/ReactDOMComponentTree.js:155:77)
      at Object.findDOMNode (node_modules/react-dom/lib/findDOMNode.js:49:41)
      at ContainerDimensions.componentDidMount (node_modules/react-container-dimensions/lib/index.js:69:50)
      ...

If the two are not compatible, is there a recommended workaround?

Size calculated is slightly different with size rendered in the browser

I have noticed a variance between the size calculated by the library and the actual size rendered in the browser. More precisely, the calculated size tends to be slightly larger than the size visually rendered. This difference may be attributed to rounding operations, and while it might be considered minor, it could potentially result in unforeseen outcomes for my specific use case.

The logged size in the console reads as follows: Width: 796.90625, Height: 797

Comparatively, the actual rendered size is:
image

container updates slow down d3-force convergence

Thanks for this easy to use component. It has completely solved my sizing issues, but has created a new problem that I'm not sure how to resolve. Apologizes if I should post this elsewhere, or if it is due to my novice react+js skills.

Without the ContainerDimension component, my react-d3-graph renders quickly and correctly, but with weird dimensions. When I add the ContainerDimension, the size of the graph is correct but the graph renders very slowly and does not converge on the layouts I saw before.

I suspect this is because ContainerDimension slows the rendering down and the force simulation decays too quickly. It seems that the Container resizing is only triggered a handful of times though.

Do you have any ideas on how to use ContainerDimension without slowing down the graph layout algorithm?

Thank you,

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.