ampproject / ampproject/amp-react-prototype
Prototype AmpLayout component
- Dominant language
- JavaScript
- Stars
- 36
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
See #35 for context.
`AmpLayout` component would provide the following features:
- Define a child component's layout using AMP rules (`layout`, `width`, `height`, etc);
- Show placeholder until the child component is loaded;
- Show loading indicator until the child component is loaded.
To implement these features The `AmpLayout` component would:
1. Wrap the "child" component into another DOM element and use it to implement main UI rules.
2. Modify the "child" component's inline `style` to achieve the right layout. For instance, with the responsive layout the wrapper component, as well as placeholder, loading indicator, etc - should all be styled with `position:absolute; inset: 0; width: 100%; height: 100%`.
There could be several possible composition styles.
#### /1/ A static [higher order component](https://reactjs.org/docs/higher-order-components.html):
```
const AmpCarouselWithLayout = withLayout(AmpCarousel, {options});
```
Main drawback: all components have to have “WithLayout” pair.
#### /2/ JSX: Child component with cloning of `children[0]`:
```jsx
...
```
Implementation:
```jsx
const child = props.children[0];
const decoratedChild = preact.cloneElement(
child,
{
style: {
// Preserve other styles:
...child.props.style,
// Make the child component take all available space:
position: 'absolute',
inset: 0,
width: '100%',
height: '100%'
}
}
);
```
Question: any negative consequences of cloning?
#### /3/ JSX: wrapper with `type` property:
```
...
```
Implementation is very similar to the cloning case, but avoids the cloning:
```jsx
const decoratedChild = preact.createElement(
props.type,
{
...props,
style: {
// Preserve other styles:
...props.style,
// Make the child component take all available space:
position: 'absolute',
inset: 0,
width: '100%',
height: '100%'
}
}
);
```
Main drawback: we lose some type information by combining two components into one.
#### /4/ CSS approach:
We use a global stylesheet like this:
```
.amp-with-layout > * {
position: absolute !important;
inset: 0 !important;
width: 100% !important;
height: 100% !important;
}
```
Main drawback: the global stylesheet is a global singleton side-effect and as such we'd have to correctly support server-side rendering, documents, shadow roots, embeds. We'd likely have to deal with FOUC.
Contributor guide
Assessment
This issue has not been assessed yet.