kettanaito / atomic-layout Goto Github PK
View Code? Open in Web Editor NEWBuild declarative, responsive layouts in React using CSS Grid.
Home Page: https://redd.gitbook.io/atomic-layout
License: MIT License
Build declarative, responsive layouts in React using CSS Grid.
Home Page: https://redd.gitbook.io/atomic-layout
License: MIT License
I suggest to make template
and its derived props optional for Composition
component.
As I continue on the marvelous road of learning CSS Grid, I find a lot of scenarios when using templateCols
and/or templateRows
is sufficient to create a layout. I wouldn't limit the functionality of CSS Grid by artificially forcing template-areas
prop.
Composition
component can render without template-*
props being provided.Composition
component can still render with template-*
props being provided.template-*
props are not provided, the children of Composition
are usual React components.template-*
props are provided, the children of Composition
is a function that accepts generated area components and renders React component.template
and its derived props optional.template
props are provided, expose function as a children of Composition
componentNeed to handle conditional grid areas.
Consider:
const templateMobile = `
'text'
`
const templateTablet = `
'text subtext'
`
<Layout
template={templateMobile}
templateSm={templateTablet}>
{({ Text, Subtext }) => (...)}
</Layout>
Using this example the Layout
will throw when trying to render Subtext
on mobile (subtext
area is not preset in the template, therefore, its component is not created).
const Placeholder = () => null
template
to know the fullest list of areas, and create them all, no matter the screen size.parseTemplateString
composite function into smaller pure functionsGracefully handle components that are not included in the current grid template(s)
For example, when using atomic-layout as a top level routing component, not all components will be included in the template, which means that each has to be checked to see if it's defined before it can be used.
<Composition template={router.gridTemplate || `notFound`}>
{({ Page1, Page2, NotFound }) => (
<>
{Page1 && (
<Page1>
<Page1Component />
</Page1>
)}
{Page2 && (
<Page2>
<Page2Component />
</Page2>
)}
{NotFound && (
<NotFound>
<NotFoundComponent />
</NotFound>
)}
</>
)}
</Composition>
This could more cleanly be describe with a hash of components (indexed by template area)
<Composition template={router.gridTemplate || `notFound`} components={{
'page1': Page1Component,
'page2': Page2Component,
'notFound': NotFoundComponent,
}} />
or by using a more generic Area wrapper
<Composition template={router.gridTemplate || `notFound`}>
<Area name='page1'>
<Page1Component />
</Area>
<Area name='page2'>
<Page2Component />
</Area>
<Area name='notFound'>
<NotFoundComponent />
</Area>
</Composition>
Suggest to move the order of bundle-size reporting in the CircleCI pipeline.
To receive the build size status faster, without waiting for all the tests to run.
.circleci/config.yml
I suggest to allow long (2+ words) breakpoint names.
At the moment only one word breakpoint names are expected in the prop name parsing algorithm. Having custom breakpoint names is essential for DX.
Straightforward. CI is a must.
Should create a template for pull request.
To improve developer experience and make the contribution process smooth.
Syntax Error: Unexpected character 'โ' (7:0)
8.9.4
6.1.0
0.3.4
10.13.5
16.3.2
Steps to reproduce the behavior:
See the card example
I also tried https://styled-css-grid.js.org/ I like their api better (the cell approach), but it does not seem to support break points.
Other than that your project looks great! ๐ Good step at making css grid more developer friendly.
I suggest to find some sensible way of handling unknown prop aliases.
I would like to reduce the size of propAliases
by excluding the aliases which output properties are identical to the alias itself (i.e. margin
, padding
, height
, width
). This would decrease the library size even more.
Need to add test cases for prop aliases functionality.
To ensure all prop aliases are assigned properly in the generated CSS properties.
Need to add the support for component
prop to grid area components.
At the moment all grid areas will render <div>
elements. That may not be the desired layout in some cases. For example, sometimes passing a presentational component as the component
prop may simplify the layout declaration:
import React from 'react'
import ArticleHeader from './ArticleHeader'
const template = `
'header'
`
const Article = () => (
<Layout template={template}>
{({ Header }) => (
<React.Fragment>
<Header component={ArticleHeader} />
</React.Fragment>
)}
</Layout>
)
export default Article
Maybe it's worth looking into optimizing "react-responsive" package built-in into the library.
react-responsive
takes almost a half of the library's bundle size. It's always good to ship a smaller package, that evaluates and runs faster.
If react-responsive
allows es/src imports, those can be included and processed via library's webpack. This can improve the bundle size via tree shaking, for example, as Atomic layout doesn't utilize all features of react-responsive
.
Alternatively, can do a PoC to include a custom responsive utility, covering only the required aspects.
<Only/>
is a React component that renders its children responsively, depending on the breakpoint props specified to it.Layout.configure()
).atomic-layout/examples/only/OnlyExample.jsx
Lines 9 to 32 in 4c7ca5d
Enforcing all area components behave like flex results into broken layouts by default.
0.3.8
Flex behavior doesn't interfere with the existing layouts.
flex
).flex-direction: column
by default. However, this, most likely, will not eliminate the issue.Currently, a bell areas are not wrapped in MediaQuery properly, as their shouldAlwaysRender
flag returns true
.
This is most likely an issue with reduceAreas
function.
Bell area is an area that is present on the very left breakpoint, then is not present in the middle breakpoint, and present again on the very right breakpoint. This is an example:
const templateMobile = `
'header actions'
`
const templateMobile = `
'header'
`
const templateDesktop = `
'header actions'
`
In the example above, <Actions/>
is a bell area.
reduceAreas
functionality to properly compose bell areas.reduceAreas
functionality to cover bell areasAllow string values to be passed for spacial props (i.e.height
, width
).
To allow to set vw
and px
in case of necessity for that properties. By default, numbers passed to spacial properties represent rem
units.
Error handling must be refined and improved where necessary.
Having meaningful and helpful error messages is a must.
Layout.configure()
After introducing a postinstall
hook, installing of a library attempts to build it immediately afterward. Since the end consumer may not have a proper tools to build, this attempt is rather ridiculous.
npm install atomic-layout
Library is built only after it is being cloned. Alternatively, remove this logic completely, and provide a comment in the contribution guidelines that a developer must first build the library.
I suggest to extend a breakpoint params to include more properties rather than just from
and to
.
This will allow to craft completely custom breakpoints, i.e. the ones dependant on the screen resolution or device orientation.
from
to minWidth
and to
to maxWidth
.I suggest to consider behavior support for template declarations that do not have a preceding breakpoint name (i.e. templateDown
or templateOnly
).
Current RegExp won't match the template prop names enlisted above. There must be a way to use explicit behaviors even for breakpoint-less template declarations, especially since there is a defaultBreakpointName
param, which excludes the necessity of specifying breakpoint name every time.
Layout is broken when using custom breakpoints.
When provided custom breakpoints via Layout.configure()
, there is no logic which sets a breakpoint as the default one.
Currently xs
is a fallback value for the cases when no breakpoint is specified. However, when such breakpoint name doesn't exist, breakpoint
becomes undefined
, causing a hell of errors.
0.3.1
Steps to reproduce the behavior:
Layout.configure()
There must be a logic to define and use the default breakpoint.
Need to increase code coverage up to 100%.
To have our code covered with tests, of course. And also because 99% coverage is simply unacceptable.
Need to allow custom breakpoints to be used with the Atomic layout.
Having custom breakpoints grants additional flexibility and customization when using Atomi layout.
For example, at the moment Bootstrap's grid breakpoints are used as default breakpoints. This influences the way responsive props are written:
<Layout gutterMd={2} gutterLg={3} />
With custom breakpoints, developers can strive toward explicit semantics dictated by their projects:
<Layout gutterTablet={2} gutterDesktop={3} />
I suggest to list default breakpoints' values as explicit unit strings.
Right now it will take the defaultUnit
. So if you set default unit to rem,
numeric values in default breakpoint definitions use rem
as their suffix.
Need to enhance integration tests assertion to also test for grid-area
property value and area component position on the screen.
When grid-area
assignment is broken, grid areas will still be visible, but positioned in the unexpected part of the layout. That is a falsy positive test result, which must be avoided.
Need to provide proper error handling and error messages.
Right now any error results into broken client build. That is unacceptable.
Layout.configure()
without optionsdefaultBreakpointName
to the name of non-existing breakpointComposition.props.template
Composition.props.template
(not wrapped in quotes).
as the grid area name (#5)Need to base the logic of utils/getAreaParams
function to handle any scenarios of breakpoints (using min/maxHeight, min/maxWidth, resolution, orientation, etc.).
To have a single source of truth for area component media query props composition.
getAreaParams
function.Branch: https://github.com/kettanaito/atomic-layout/tree/28-generic-breakpoint-concatenation
Lack of indentation in template breaks the Composition component
Not working
const template = `
top
bottom
`
Working
const template = `
top
bottom
`
Hard coded white space removal
You dont need to append whitespace to template string
Self-descriptive.
Need to consider Element Queries non-standard feature.
That is a brand new look at the components and their responsive behavior. I believe that in the conjuncture with the traditional media queries this could allow to create immersive responsive experiences.
See the Element Query API proposal.
Add integration tests for SSR of the components rendered using Atomic layout.
SSR support is a crucial part of any implementation. Since we use react-responsive
for conditional areas rendering, I believe that SSR should be supported out of the box. The tests are needed regardless.
ReactDOMServer.renderToString(<Component/>)
Assert the output, or use a snapshot to assert it.
Suggest to consider React Native support.
Because creating layouts in RN is a hell.
<Composition templateCols={undefined} />
will output
grid-template-columns: undefined;
not checking for undefined values
css attributes for props with undefined or null values should not be output
Need to setup and write integration tests.
Atomic layout contributes to the end layout (UI) of the application. Its contribution needs to be tested to ensure it works as expected.
<Composition/>
)I suggest to make generated area components to have display: flex
by default.
This will allow to control their children behavior using the flexbox prop aliases without explicitly setting its display, or having to nest composition/box just for alignment matter.
display: flex
on the generated area component.flex
inline: true
, inline-flex
Deploy lib to npm without minification
Because errors are not reported correctly and we cannot easily make use of internal functions.
Remove minification build step for npm publish
Conduct a check and add tests to ensure behavior:down
areas are working properly.
parsePropName('templateDown')
doesn't return proper parsed prop object.
Because of the current RegExp.
Returns prop name template
and down
as a behavior.
I suggest to introduce a memoization logic for parseTemplates
function call.
template-*
prop values due to computation process is memoizedmemoize
function, or similar.memoize
function.Suggest to add lint-staged
package.
To have hooks on the files added to the commit only.
Current "up" behavior is broken. Consider this composition:
const templateXs = `A B C`
const templateMd = `A B`
<Composition template={templateXs} templateMd={templateMd} />
The composition for sm
breakpoint will render empty component, which is not correct.
This is most likely related to the changed parsing API.
0.3.0
Default "up" behavior is working properly. That implies that the most left provided value is persistent through the breakpoints, unless met more specific right value overwriting it.
Need to handle .
character which is supported by CSS Grid spec.
In order to cover feature which is in spec, in case it needs to be handled from React side.
grid-template-areas
. There is a fair chance that we need not to handle it in any way. If that is a placeholder to achieve different gutter (gap) between different grid areas, this can be done via explicit spacing props (margin/padding) assigned directly to area components as props.<Placeholder/>
component at its place.Need to provide an interface which will allow a developer to set a default measurement unit of his preference.
At the moment the default measurement unit is rem
. While that bears the most sense when building layouts to me, others can share different opinions and have different project requirements. It's not a good idea to force any behavior in general.
defaultUnit
property to the options Object passed to the library.Box and Composition components (as well as generated React components) behave very simiarly, they can use a generic component in their render.
Reusing functionality is good.
Need to parse string values of minWidth
and maxWidth
of a breakpoint.
It's allowed to use string values (i.e. 25vw
), which needs to be handled properly during the breakpoint boundaries subtraction.
parseFloat()
?I propose to establishing a support for different CSS-in-JS libraries to help developers take benefits of Atomic Layout using their favorite styling solution.
To enable such support it has been decided to convert the library to a monorepo that consist of the following parts:
@atomic-layout/core
, responsible for media queries calculation, areas parsing, parametric components generation without attachment to any specific styling/rendering solution)@atomic-layout/emotion
)All rendering libraries would list @atomic-layout/core
as a dependency and utilize functions and types the core library exports.
To use Atomic Layout with another styling solution (implying that such solution is supported) import the respective @atomic-layout/X
package and use it with the same API described in the documentation:
import React from 'react'
import { Composition } from '@atomic-layout/emotion'
const MyComponent = () => (
<Composition templateCols="250px 1fr">
<span>Emotion support</span>
<span>Example</span>
</Composition>
)
Need to focus on improving contributor experience.
To create a clear process of contributing to Atomic layout, in order to get more contributors and make the contribution process as pleasing as it gets <3
pre-commit
hookpre-push
hookA declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.