-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
627ae87
commit 8c000c6
Showing
29 changed files
with
898 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {PaginationComponent, PaginationNumberDirective} from '@agnos-ui/angular'; | ||
import {Component} from '@angular/core'; | ||
|
||
@Component({ | ||
standalone: true, | ||
imports: [PaginationComponent, PaginationNumberDirective], | ||
template: ` | ||
<p>The default look of the pagination:</p> | ||
<nav auPagination auCollectionSize="60"></nav> | ||
<p>Changing the slot displaying the page number to use letters instead:</p> | ||
<nav auPagination auCollectionSize="60"> | ||
<ng-template auPaginationNumber let-displayedPage="displayedPage"> | ||
{{ ['A', 'B', 'C', 'D', 'E', 'F'][displayedPage - 1] }} | ||
</ng-template> | ||
</nav> | ||
`, | ||
}) | ||
export default class SlotsContextComponent {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import {Component, ViewEncapsulation} from '@angular/core'; | ||
import {RatingReadonlyComponent, RatingReadonlyStarDirective} from './rating-readonly.component'; | ||
|
||
@Component({ | ||
standalone: true, | ||
imports: [RatingReadonlyComponent, RatingReadonlyStarDirective], | ||
encapsulation: ViewEncapsulation.None, | ||
template: ` | ||
<div>The readonly rating without slot:</div> | ||
<app-rating-readonly [rating]="7" [maxRating]="10" /> | ||
<div class="mt-2">Using a slot to customize the display:</div> | ||
<app-rating-readonly className="rating-custom" [rating]="7" [maxRating]="10"> | ||
<ng-template appRatingStar let-fill="fill" let-index="index"> | ||
<span class="star" [class.filled]="fill === 100" [class.bad]="index < 3">★</span> | ||
</ng-template> | ||
</app-rating-readonly> | ||
`, | ||
styles: "@import '@agnos-ui/common/samples/rating/custom.scss';", | ||
}) | ||
export default class SlotsHeadlessComponent {} |
65 changes: 65 additions & 0 deletions
65
angular/demo/src/app/samples/slots/rating-readonly.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import type {AdaptSlotContentProps, RatingWidget, SlotContent, StarContext} from '@agnos-ui/angular-headless'; | ||
import {BaseWidgetDirective, SlotDirective, auNumberAttribute, callWidgetFactory, createRating} from '@agnos-ui/angular-headless'; | ||
import type {AfterContentChecked} from '@angular/core'; | ||
import {ChangeDetectionStrategy, Component, ContentChild, Directive, Input, TemplateRef, inject} from '@angular/core'; | ||
|
||
/** | ||
* This directive allows the component to retrieve the slot template. | ||
*/ | ||
@Directive({selector: 'ng-template[appRatingStar]', standalone: true}) | ||
export class RatingReadonlyStarDirective { | ||
public templateRef = inject(TemplateRef<AdaptSlotContentProps<StarContext>>); | ||
static ngTemplateContextGuard(_dir: RatingReadonlyStarDirective, context: unknown): context is StarContext { | ||
return true; | ||
} | ||
} | ||
|
||
/** | ||
* To use the defined slotStar, we simply need to use the {@link SlotDirective} and give it the prop as input. | ||
* The auSlotProps is used to provide context to the slot. | ||
*/ | ||
@Component({ | ||
selector: 'app-rating-readonly', | ||
standalone: true, | ||
imports: [SlotDirective], | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
template: ` | ||
<div class="d-inline-flex au-rating" [class]="state().className"> | ||
@for (item of state().stars; track item) { | ||
<span class="au-rating-star"> | ||
<ng-template [auSlot]="state().slotStar" [auSlotProps]="item"></ng-template> | ||
</span> | ||
} | ||
</div> | ||
`, | ||
}) | ||
export class RatingReadonlyComponent extends BaseWidgetDirective<RatingWidget> implements AfterContentChecked { | ||
readonly _widget = callWidgetFactory({ | ||
factory: createRating, | ||
widgetName: 'rating', | ||
defaultConfig: { | ||
readonly: true, | ||
}, | ||
events: { | ||
onHover: () => {}, | ||
onLeave: () => {}, | ||
onRatingChange: () => {}, | ||
}, | ||
}); | ||
|
||
@Input() | ||
slotStar: SlotContent<AdaptSlotContentProps<StarContext>>; | ||
@ContentChild(RatingReadonlyStarDirective, {static: false}) slotStarFromContent: RatingReadonlyStarDirective | undefined; | ||
|
||
@Input({transform: auNumberAttribute}) rating: number | undefined; | ||
|
||
@Input({transform: auNumberAttribute}) maxRating: number | undefined; | ||
|
||
@Input() className: string; | ||
|
||
ngAfterContentChecked(): void { | ||
this._widget.patchSlots({ | ||
slotStar: this.slotStarFromContent?.templateRef, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {AlertComponent} from '@agnos-ui/angular'; | ||
import {Component} from '@angular/core'; | ||
|
||
@Component({ | ||
standalone: true, | ||
imports: [AlertComponent], | ||
template: ` | ||
<au-component auAlert auType="primary" [auDismissible]="false"> Label provided by slot </au-component> | ||
<au-component auAlert auType="secondary" [auDismissible]="false" auSlotDefault="Label provided by property" /> | ||
<au-component | ||
auAlert | ||
auType="info" | ||
[auDismissible]="false" | ||
auSlotDefault="When both prop and slot are provided, the prop's content will take precedence." | ||
> | ||
This content is ignored. | ||
</au-component> | ||
`, | ||
}) | ||
export default class SlotsUsageComponent {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
## Slots in Angular | ||
|
||
Angular applications usually handle slots using [content projection](https://angular.dev/guide/components/content-projection). | ||
We support this behavior, while going further. | ||
|
||
The AgnosUI Angular slots can be set using: | ||
|
||
- a simple `string` | ||
- a function `(props: Props) => string` | ||
- a [TemplateRef](https://angular.io/api/core/TemplateRef) | ||
- an Angular component | ||
- a `ComponentTemplate`, an AgnosUI utility allowing to use an Angular component without the host element |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,9 @@ | |
} | ||
pre { | ||
> code { | ||
white-space: pre-wrap; | ||
} | ||
// color: black; | ||
tab-size: 1rem; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,64 @@ | ||
# Slots | ||
|
||
## TODO | ||
## What are Slots ? | ||
|
||
To be done, issue #376 | ||
Slots are essentially placeholders within a component that can be filled with custom content. | ||
They provide a way to dynamically inject content into a component without affecting its original template. | ||
This makes it possible to create components that can be easily adapted to different scenarios without having to duplicate code or create a new component from scratch. | ||
|
||
## Why use them ? | ||
|
||
Slots facilitate the creation of more versatile and reusable components. | ||
They allow developers to design components with predefined structures while leaving room for variation in content. | ||
This separation of structure and content enhances code reusability and promotes a cleaner, more modular codebase. | ||
|
||
## AgnosUI Slot | ||
|
||
AgnosUI core widgets include slots as **properties** prefixed by _slot_ in their states. | ||
This allows to specifiy the projected content in multiple manners, like simple `string`, context-aware functions, standard slots or even fully-fledged components. | ||
|
||
To illustrate the basic usage, let's see in action how we can use a simple slot in the Bootstrap flavour of the **Alert** component: | ||
|
||
```sample | ||
{Slot Standard Usage:slots/usage:278} | ||
``` | ||
|
||
## Context | ||
|
||
Slots have access to a context, which for most cases is the widget state. | ||
It is possible however to extend the context, which enables powerful customization. Here is an example with the Bootstrap flavour of the **Pagination** component: | ||
|
||
```sample | ||
{Slot Context:slots/context:220} | ||
``` | ||
|
||
## Integration with Configuration | ||
|
||
As explained above, AgnosUI slots are inherently properties, thus benefit from the [Configuration](01-Configuration.md). | ||
For instance, we may configure the _slotStructure_ of the **Alert** to use a custom component, allowing to fully customize the widget. | ||
|
||
```sample | ||
{Slot Configuration:alert/icon:402} | ||
``` | ||
|
||
<!-- <framework-specific src="Slots.md"> --> | ||
|
||
## Headless Usage | ||
|
||
AgnosUI provides utilities to manage slots for each framework, as frameworks have differences in their implementations of slots / templates / snippets. | ||
To learn more about the specificies of each framework, go here: | ||
|
||
<p align="center"> | ||
<a href="../../angular/docs/Slots.md">Slots in Angular</a> | ||
<a href="../../react/docs/Slots.md">Slots in React</a> | ||
<a href="../../svelte/docs/Slots.md">Slots in Svelte</a> | ||
</p> | ||
<!-- </framework-specific> --> | ||
|
||
## Headless example | ||
|
||
You can check out the following example, re-writing the Bootstrap flavour of the **Rating** component as readonly: | ||
|
||
```sample | ||
{Slot Headless:slots/headless:148} | ||
``` |
Oops, something went wrong.