Skip to content

Instantly share code, notes, and snippets.

@isaacplmann
Last active September 4, 2018 13:04
Show Gist options
  • Save isaacplmann/66b4442c387cae43a5c0deab7853ef59 to your computer and use it in GitHub Desktop.
Save isaacplmann/66b4442c387cae43a5c0deab7853ef59 to your computer and use it in GitHub Desktop.
A Render Prop by Any Other Name: Angular
@Component({
selector: 'theme-provider',
template: `
<ngx-data-provider key="theme" [data]="{ theme: theme, setTheme: setTheme }">
<ng-content></ng-content>
</ngx-data-provider>`,
})
export class ThemeProvider {
setTheme = theme => this.theme = theme;
theme = 'dark';
}
@Component({
selector: 'accordion-button',
template: `
<ngx-data-consumer key="theme">
<ng-template let-theme="theme">
<button
[class]="'accordion accordion-' + theme + ' ' + (isOpen ? 'open' : 'closed')"
/>
</ng-template>
</ngx-data-consumer>
`
})
export class AccordionButton {
@Input() isOpen;
}
<theme-provider>
...
...
<accordion-button
getButtonProps="{isOpen: openIndexes.includes(index)}"
>
{{item.title}} {{openIndexes.includes(index) ? 'πŸ‘‡' : 'πŸ‘ˆ'}}
</accordion-button>
...
...
</theme-provider>
<accordion>
<ng-template let-openIndexes="openIndexes" let-getButtonProps="getButtonProps">
<div>
<accordion-item *ngFor="let item of items; let index=index">
<accordion-button
getButtonProps="{isOpen: openIndexes.includes(index)}"
>
{{item.title}} {{openIndexes.includes(index) ? 'πŸ‘‡' : 'πŸ‘ˆ'}}
</accordion-button>
<accordion-contents [isOpen]="openIndexes.includes(index)">
{{item.contents}}
</accordion-contents>
</accordion-item>
</div>
</ng-template>
</accordion>
import {
preventClose, // prevents the state from having all open indexes closed
single, // allows only one open index at a time
combineReducers, // accepts any number of reducers and calls each of them in turn
} from './reducers';
// composes the Accordion into a component that uses the logic for a Tabs UI
@Component({
selector: "tabs",
template: `
<accordion [stateReducer]="stateReducer" ...>
</accordion>
`
})
export class TabsComponent {
...
stateReducer: AccordionStateReducer = combineReducers(single, preventClose);
}
// usage:
<tabs>
<ng-template let-openIndexes="openIndexes" let-getButtonProps="getButtonProps">
<div>
<tab-buttons>
...
</tab-buttons>
<tab-items>
...
</tab-items>
</div>
</ng-template>
</tabs>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment