Name: radium-constraints
Owner: Formidable
Description: Constraint-based layout system for React components.
Created: 2016-03-10 06:07:29.0
Updated: 2017-11-14 01:46:22.0
Pushed: 2016-06-30 04:43:44.0
Homepage: null
Size: 457
Language: JavaScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Radium Constraints introduces the power of constraint-based layout to React. Declare simple relationships between your visual components and let the constraint solver generate the optimum layout.
Radium Constraints handles DOM and SVG elements and is the perfect alternative to manual layout when building SVG data visualizations. Radium Constraints is the bedrock for exciting new enhancements to Victory.
This library is still incubating and is not yet ready for production use. See the roadmap for what's left to do before 1.0.0.
First, ensure all components using Radium Constraints are wrapped in the top-level <ConstraintLayout>
component:
rt ConstraintLayout from "radium-constraints";
straintLayout>
.other components
nstraintLayout>
Next, add a <Superview>
component. A <Superview>
is a collection of “subviews” whose layouts relate to each other and their parent. A <Superview>
typically encapsulates one large visual component, like a single chart.
Superviews require the following props:
name
: for identification. We'll remove this requirement in future versions.container
which element the superview should use as a container (i.e. div
for DOM and g
for SVG).width
: the initial width of the superview.height
: the initial height of the superview.style
(optional) custom styles to apply to the container node.Here's how to set up a <Superview>
:
rt ConstraintLayout, { Superview } from "radium-constraints";
straintLayout>
uperview
name="tutorial"
container="div"
width={400}
height={500}
style={{
background: "red"
}}
...subview components
Superview>
nstraintLayout>
Finally, add subviews to your <Superview>
! You can create subviews in two ways. The first, AutoDOM
and AutoSVG
, automatically map the bounding box of the subview to the appropriate DOM styles/SVG attributes. AutoDOM uses the bounding box to absolutely position the element. AutoSVG
maps the bounding box to attributes like x, y, x1, y1, cx, cy, r
, etc. on a per-element basis.
If you need more control over the usage of the bounding box in components, you can create a custom subview using the <Subview>
higher-order component. <Subview>
provides layout props (width, height, top, left, bottom, right) that you can map to DOM attributes or style
props.
Both of these methods use <Subview>
under the covers, and they require the same props:
name
: the name of the subview. Allows other subviews to constrain themselves to this subview.intrinsicWidth
: the minimum width of the component before application of constraints.intrinsicHeight
: the minimum height of the component before application of constraints.constraints
: a set of constraints for this subview.Building constraints uses a fluent DSL in the style of Chai assertions. Some constraint examples:
hese two constraints center the subview in the <Superview>.
train.subview("demo").centerX.to.equal.superview.centerX
train.subview("demo").centerY.to.equal.superview.centerY
his prevents this subview from overlapping with
nother subview named "other".
train.subview("demo").left
o.be.greaterThanOrEqualTo.subview("other").right
his prevents this subview from overflowing
he superview's right edge.
train.subview("demo").right
o.be.lessThanOrEqualTo.superview.right
Here's an example of a custom component using <Subview>
:
s Rectangle extends Component {
atic propTypes = {
layout: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number
})
nder() {
return (
<div style={{
position: "absolute",
top: this.props.layout.top || 0,
left: this.props.layout.left || 0
width: this.props.layout.width || 0,
height: this.props.layout.height || 0
}}
>
<p>Demo time!</p>
</div>
);
rt default Subview()(Rectangle);
Here's how to use AutoDOM
components:
rt ConstraintLayout, { Superview, AutoDOM } from "radium-constraints";
straintLayout>
uperview
name="tutorial"
container="div"
width={400}
height={500}
style={{
background: "red"
}}
<AutoDOM.div
name="tutorialSubview"
intrinsicWidth={50}
intrinsicHeight={50}
constraints={[
constrain.subview("tutorialSubview").centerX
.to.equal.superview.centerX,
constrain.subview("tutorialSubview").centerY
.to.equal.superview.centerY
]}
>
This is a subview
</AutoDOM.div>
Superview>
nstraintLayout>
When using AutoSVG
components, make sure to pass “g” instead of “div” to the <Superview>
's container
prop.
You can add automatic layout animation to any Subview
or AutoSVG
/AutoDOM
components! The animation system works with both <Motion>
from react-motion
and <VictoryAnimation>
from victory-core
. To create Victory-animated versions of AutoDOM
components, for example, you'd do the following:
rt { animateDOM } from "radium-constraints";
rt { VictoryAnimation } from "victory-core";
t VictoryAnimationAutoDOM = animateDOM({
imatorClass: VictoryAnimation,
imatorProps: (layout) => ({
data: {
width: layout.width,
height: layout.height,
top: layout.top,
right: layout.right,
bottom: layout.bottom,
left: layout.left
}
ater, in render()
toryAnimationAutoDOM.p
me="victory-animation-note"
yle={{...styles.box, fontSize: "16px", border: 0}}
trinsicWidth={300}
trinsicHeight={45}
nstraints={this.state.dynamicConstraints}
is is a subview animated by VictoryAnimation!!!!!!
ctoryAnimationAutoDOM.p>
When different constraints enter either the top-level or component-level constraints
prop, the new animated component automatically tweens between the previous and newly calculated layout, diffing/removing/adding constraints behind the scenes.
If you're using the Subview
higher-order component, you can pass an object with animatorClass
and animatorProps
to the first curried argument of Subview
like so:
rt default Subview({
imatorClass: VictoryAnimation,
imatorProps: (layout) => ({
data: {
width: layout.width,
height: layout.height,
top: layout.top,
right: layout.right,
bottom: layout.bottom,
left: layout.left
}
omeCustomComponent);
There are more complex examples on the demo page. Check out the code in app.jsx.
npm install
and then ./node_modules/.bin/builder run hot
will load a webpack dev server at localhost:3000.If you want to type builder
instead of
./node_modules/.bin/builder
, please update your shell to include
./node_modules/.bin
in PATH
like:
rt PATH="${PATH}:./node_modules/.bin"
React Constraints uses an asynchronous layout engine running on a pool of WebWorkers. This prevents layout calculations from bogging down the main thread and allows the library to be a good citizen in any page/app. Therefore, browsers using this library must support WebWorkers.
Resolving and incrementally adding/removing constraints are cheap enough to run in 60fps for most cases. However, the initial layout calculations on first load are the most expensive, and you may notice a slight delay in layout (although this does not block the main thread). We're working on a build tool that will pre-calculate initial layouts and feed them into your components to prevent this.
This library's browser support aligns with React's browser support minus IE 8 and 9 (neither support Web Workers). The library requires a Promise polyfill for non-ES6 environments.
In order of priority:
path
elements in AutoSVG.constrain
Begins a constraint builder chain.
subview(name)
Chooses a subview by name to pick attributes from.
superview
Chooses the superview to pick attributes from.
to
and be
No-op methods. Use with lessThanOrEqualTo
and greaterThanOrEqualTo
for legibility.
equal
Declare that the subview or superview attribute on the left will equal the subview or superview attribute on the right.
lessThanOrEqualTo
and greaterThanOrEqualTo
Declare that the subview or superview attribute on the left will be greater than/less than or equal to the subview or superview attribute on the right.
width
, height
, top
, left
, bottom
, right
, centerX
, centerY
The constrainable attributes of a subview or superview. Call these methods on superview
or subview(name)
to complete one side of a constraint relationship.
constant
Declare that the subview or superview attribute on the left will equal a constant number (no relation to another subview/superview).
plus
, minus
, times
Modifies an attribute by a constant. Call these methods on attributes of superview
or subview
, like superview.left.plus(10)
.
withPriority(priority)
Declare the priority of this constraint. Accepts 1000, 750, and 250 as values. Use at the end of the entire chain.
train.subview("demo").bottom
o.equal.superview.top.plus(10)
ithPriority(1000);
train.subview("demo").bottom.constant(20);
train.subview("demo").right
o.be.lessThanOrEqualTo.superview.right