index.tsx
:
import React from 'react';
import styled from 'styled-components';
enum Area {
header = 'header',
main = 'main',
footer = 'footer'
}
const Layout = styled.div`
display: grid;
min-height: 100vh;
grid-template-areas:
'${Area.header}'
'${Area.main}'
'${Area.footer}';
grid-template-rows: auto 1fr auto;
`;
type ItemProps = {
area: Area;
};
const Item = styled.div<ItemProps>`
grid-area: ${({ area }) => area};
`;
const App = () => (
<Layout>
<Item area={Area.header}>Header</Item>
<Item area={Area.main}>My content...</Item>
<Item area={Area.footer}>Footer</Item>
</Layout>
);
layout.component.ts
:
import { Component, Input } from '@angular/core';
export enum Area {
header = 'header',
main = 'main',
footer = 'footer'
}
@Component({
selector: 'app-layout',
template: `<div><ng-content></ng-content></div>`,
styleUrls: ['./layout.style.less'] // needs to use the same values as Area enum
})
export class LayoutComponent {}
@Component({
selector: 'app-item',
template: `<div [style.grid-area]="area"><ng-content></ng-content></div>`
})
export class ItemComponent {
@Input() area!: Area; // usage is not really type checked
}
layout.style.less
:
div {
display: grid;
min-height: 100vh;
grid-template-areas:
'header'
'main'
'footer';
grid-template-rows: auto 1fr auto;
}
Next step: register your component in some module.
app.component.ts
:
import { Component } from '@angular/core';
import { Area } from './layout/layout.component';
@Component({
selector: 'app-root',
templateUrl: './app.template.html'
})
export class AppComponent {
Area = Area;
}
app.template.html
:
<app-layout>
<app-item area="{{ Area.header }}">Header</app-item>
<app-item area="{{ Area.main }}">My content...</app-item>
<app-item area="{{ Area.footer }}">Footer</app-item>
</app-layout>