ampproject / ampproject/amp-react-prototype

Prototype AmpLayout component

Open
#36 0 comments 0 reactions 0 assignees View on GitHub
TBD
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.