@rxap/directives
Version:
This package provides a set of Angular directives to simplify common tasks such as setting background images, confirming clicks, making elements contenteditable, and more. It includes directives for handling UI interactions, applying styles, and managing
642 lines (527 loc) • 22.4 kB
HTML
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>angular-directives</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="../images/favicon.ico">
<link rel="stylesheet" href="../styles/style.css">
<link rel="stylesheet" href="../styles/dark.css">
</head>
<body>
<script>
// Blocking script to avoid flickering dark mode
// Dark mode toggle button
var useDark = window.matchMedia('(prefers-color-scheme: dark)');
var darkModeState = useDark.matches;
var $darkModeToggleSwitchers = document.querySelectorAll('.dark-mode-switch input');
var $darkModeToggles = document.querySelectorAll('.dark-mode-switch');
var darkModeStateLocal = localStorage.getItem('compodoc_darkmode-state');
function checkToggle(check) {
for (var i = 0; i < $darkModeToggleSwitchers.length; i++) {
$darkModeToggleSwitchers[i].checked = check;
}
}
function toggleDarkMode(state) {
if (window.localStorage) {
localStorage.setItem('compodoc_darkmode-state', state);
}
checkToggle(state);
const hasClass = document.body.classList.contains('dark');
if (state) {
for (var i = 0; i < $darkModeToggles.length; i++) {
$darkModeToggles[i].classList.add('dark');
}
if (!hasClass) {
document.body.classList.add('dark');
}
} else {
for (var i = 0; i < $darkModeToggles.length; i++) {
$darkModeToggles[i].classList.remove('dark');
}
if (hasClass) {
document.body.classList.remove('dark');
}
}
}
useDark.addEventListener('change', function (evt) {
toggleDarkMode(evt.matches);
});
if (darkModeStateLocal) {
darkModeState = darkModeStateLocal === 'true';
}
toggleDarkMode(darkModeState);
</script>
<div class="navbar navbar-default navbar-fixed-top d-md-none p-0">
<div class="d-flex">
<a href="../" class="navbar-brand">angular-directives</a>
<button type="button" class="btn btn-default btn-menu ion-ios-menu" id="btn-menu"></button>
</div>
</div>
<div class="xs-menu menu" id="mobile-menu">
<div id="book-search-input" role="search"><input type="text" placeholder="Type to search"></div> <compodoc-menu></compodoc-menu>
</div>
<div class="container-fluid main">
<div class="row main">
<div class="d-none d-md-block menu">
<compodoc-menu mode="normal"></compodoc-menu>
</div>
<!-- START CONTENT -->
<div class="content directive">
<div class="content-data">
<ol class="breadcrumb">
<li class="breadcrumb-item">Directives</li>
<li class="breadcrumb-item" >BackgroundImageDirective</li>
</ol>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a href="#info"
class="nav-link"
class="nav-link active"
role="tab" id="info-tab" data-bs-toggle="tab" data-link="info">Info</a>
</li>
<li class="nav-item">
<a href="#source"
class="nav-link"
role="tab" id="source-tab" data-bs-toggle="tab" data-link="source">Source</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade active in" id="info">
<p class="comment">
<h3>File</h3>
</p>
<p class="comment">
<code>src/lib/background-image.directive.ts</code>
</p>
<p class="comment">
<h3>Implements</h3>
</p>
<p class="comment">
<code>OnChanges</code>
<code>OnInit</code>
</p>
<section data-compodoc="block-metadata">
<h3>Metadata</h3>
<table class="table table-sm table-hover metadata">
<tbody>
<tr>
<td class="col-md-3">Selector</td>
<td class="col-md-9"><code>[rxapBackgroundImage]</code></td>
</tr>
<tr>
<td class="col-md-3">Standalone</td>
<td class="col-md-9"><code>true</code></td>
</tr>
</tbody>
</table>
</section>
<section data-compodoc="block-index">
<h3 id="index">Index</h3>
<table class="table table-sm table-bordered index-table">
<tbody>
<tr>
<td class="col-md-4">
<h6><b>Inputs</b></h6>
</td>
</tr>
<tr>
<td class="col-md-4">
<ul class="index-list">
<li>
<a href="#placeholderImageUrl" >placeholderImageUrl</a>
</li>
<li>
<a href="#position" >position</a>
</li>
<li>
<a href="#repeat" >repeat</a>
</li>
<li>
<a href="#rxapBackgroundImage" >rxapBackgroundImage</a>
</li>
<li>
<a href="#size" >size</a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</section>
<section data-compodoc="block-constructor">
<h3 id="constructor">Constructor</h3>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<code>constructor(host: ElementRef, renderer: Renderer2, imageLoader: ImageLoaderService)</code>
</td>
</tr>
<tr>
<td class="col-md-4">
<div class="io-line">Defined in <a href="" data-line="70" class="link-to-prism">src/lib/background-image.directive.ts:70</a></div>
</td>
</tr>
<tr>
<td class="col-md-4">
<div>
<b>Parameters :</b>
<table class="params">
<thead>
<tr>
<td>Name</td>
<td>Type</td>
<td>Optional</td>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>
<code>ElementRef</code>
</td>
<td>
No
</td>
</tr>
<tr>
<td>renderer</td>
<td>
<code>Renderer2</code>
</td>
<td>
No
</td>
</tr>
<tr>
<td>imageLoader</td>
<td>
<code>ImageLoaderService</code>
</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</section>
<section data-compodoc="block-inputs">
<h3 id="inputs">Inputs</h3>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<a name="placeholderImageUrl"></a>
<b>placeholderImageUrl</b>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Type : </i> <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string" target="_blank" >string</a></code>
</td>
</tr>
<tr>
<td class="col-md-2" colspan="2">
<div class="io-line">Defined in <a href="" data-line="61" class="link-to-prism">src/lib/background-image.directive.ts:61</a></div>
</td>
</tr>
</tbody>
</table>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<a name="position"></a>
<b>position</b>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Type : </i> <code><a href="../miscellaneous/typealiases.html#BackgroundPosition" target="_self" >BackgroundPosition</a></code>
</td>
</tr>
<tr>
<td class="col-md-2" colspan="2">
<div class="io-line">Defined in <a href="" data-line="70" class="link-to-prism">src/lib/background-image.directive.ts:70</a></div>
</td>
</tr>
</tbody>
</table>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<a name="repeat"></a>
<b>repeat</b>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Type : </i> <code><a href="../miscellaneous/typealiases.html#BackgroundRepeat" target="_self" >BackgroundRepeat</a></code>
</td>
</tr>
<tr>
<td class="col-md-2" colspan="2">
<div class="io-line">Defined in <a href="" data-line="67" class="link-to-prism">src/lib/background-image.directive.ts:67</a></div>
</td>
</tr>
</tbody>
</table>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<a name="rxapBackgroundImage"></a>
<b>rxapBackgroundImage</b>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Type : </i> <code>string | null | undefined</code>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Default value : </i><code>null</code>
</td>
</tr>
<tr>
<td class="col-md-2" colspan="2">
<div class="io-line">Defined in <a href="" data-line="58" class="link-to-prism">src/lib/background-image.directive.ts:58</a></div>
</td>
</tr>
</tbody>
</table>
<table class="table table-sm table-bordered">
<tbody>
<tr>
<td class="col-md-4">
<a name="size"></a>
<b>size</b>
</td>
</tr>
<tr>
<td class="col-md-4">
<i>Type : </i> <code><a href="../miscellaneous/typealiases.html#BackgroundSize" target="_self" >BackgroundSize</a></code>
</td>
</tr>
<tr>
<td class="col-md-2" colspan="2">
<div class="io-line">Defined in <a href="" data-line="64" class="link-to-prism">src/lib/background-image.directive.ts:64</a></div>
</td>
</tr>
</tbody>
</table>
</section>
</div>
<div class="tab-pane fade tab-source-code" id="source">
<pre class="line-numbers compodoc-sourcecode"><code class="language-typescript">import {
Directive,
ElementRef,
Inject,
Input,
isDevMode,
OnChanges,
OnInit,
Renderer2,
SimpleChanges,
} from '@angular/core';
import { ImageLoaderService } from '@rxap/services';
export enum GlobalStyleOptions {
INITIAL = 'initial',
INHERIT = 'inherit',
}
// TODO : complete description
// https://www.w3schools.com/cssref/css3_pr_background-size.asp
export enum BackgroundSizeOptions {
AUTO = 'auto',
COVER = 'cover',
CONTAIN = 'contain',
}
export type BackgroundSize =
| GlobalStyleOptions
| BackgroundSizeOptions
| string;
// TODO : complete options and description
// https://www.w3schools.com/cssref/pr_background-repeat.asp
export enum BackgroundRepeatOptions {
NO_REPEAT = 'no-repeat',
}
export type BackgroundRepeat = GlobalStyleOptions | BackgroundRepeatOptions;
// TODO : complete options and description
// https://www.w3schools.com/cssref/pr_background-position.asp
export enum BackgroundPositionOptions {
CENTER = 'center',
CENTER_CENTER = 'center center',
}
export type BackgroundPosition =
| GlobalStyleOptions
| BackgroundPositionOptions
| string;
@Directive({
selector: '[rxapBackgroundImage]',
standalone: true,
})
export class BackgroundImageDirective implements OnChanges, OnInit {
@Input('rxapBackgroundImage')
public imageUrl: string | null | undefined = null;
@Input()
public placeholderImageUrl!: string;
@Input()
public size?: BackgroundSize;
@Input()
public repeat?: BackgroundRepeat;
@Input()
public position?: BackgroundPosition;
// TODO : add inputs for all 'background-*' styles
constructor(
@Inject(ElementRef)
private readonly host: ElementRef,
@Inject(Renderer2)
private readonly renderer: Renderer2,
@Inject(ImageLoaderService)
private readonly imageLoader: ImageLoaderService,
) {
}
public ngOnInit() {
if (this.size) {
this.sizeChange(this.size);
}
if (this.position) {
this.positionChange(this.position);
}
if (this.repeat) {
this.repeatChange(this.repeat);
}
}
public ngOnChanges(changes: SimpleChanges) {
for (const propertyKey of Object.keys(changes)) {
switch (propertyKey) {
case 'imageUrl':
if (changes['imageUrl'].currentValue) {
this.imageUrlChange(changes['imageUrl'].currentValue);
}
break;
case 'size':
this.sizeChange(changes['size'].currentValue);
break;
case 'repeat':
this.repeatChange(changes['repeat'].currentValue);
break;
case 'position':
this.positionChange(changes['position'].currentValue);
break;
}
}
}
private repeatChange(repeat: string): void {
this.renderer.setStyle(
this.host.nativeElement,
'background-repeat',
repeat,
);
}
private positionChange(position: string): void {
this.renderer.setStyle(
this.host.nativeElement,
'background-position',
position,
);
}
private sizeChange(size: string): void {
this.renderer.setStyle(this.host.nativeElement, 'background-size', size);
}
private async imageUrlChange(imageUrl: string): Promise<void> {
if (this.placeholderImageUrl) {
this.renderer.setStyle(
this.host.nativeElement,
'background-image',
`url("${ this.placeholderImageUrl }")`,
);
}
if (imageUrl) {
await this.imageLoader.load(imageUrl);
this.renderer.setStyle(
this.host.nativeElement,
'background-image',
`url("${ imageUrl }")`,
);
} else {
if (isDevMode()) {
console.warn('background image url is not defined');
}
}
}
}
</code></pre>
</div>
</div>
</div><div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
<!-- END CONTENT -->
</div>
</div>
<label class="dark-mode-switch">
<input type="checkbox">
<span class="slider">
<svg class="slider-icon" viewBox="0 0 24 24" fill="none" height="20" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" width="20" xmlns="http://www.w3.org/2000/svg">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"></path>
</svg>
</span>
</label>
<script>
var COMPODOC_CURRENT_PAGE_DEPTH = 1;
var COMPODOC_CURRENT_PAGE_CONTEXT = 'directive';
var COMPODOC_CURRENT_PAGE_URL = 'BackgroundImageDirective.html';
var MAX_SEARCH_RESULTS = 15;
</script>
<script>
$darkModeToggleSwitchers = document.querySelectorAll('.dark-mode-switch input');
checkToggle(darkModeState);
if ($darkModeToggleSwitchers.length > 0) {
for (var i = 0; i < $darkModeToggleSwitchers.length; i++) {
$darkModeToggleSwitchers[i].addEventListener('change', function (event) {
darkModeState = !darkModeState;
toggleDarkMode(darkModeState);
});
}
}
</script>
<script src="../js/libs/custom-elements.min.js"></script>
<script src="../js/libs/lit-html.js"></script>
<script src="../js/menu-wc.js" defer></script>
<script nomodule src="../js/menu-wc_es5.js" defer></script>
<script src="../js/libs/bootstrap-native.js"></script>
<script src="../js/libs/es6-shim.min.js"></script>
<script src="../js/libs/EventDispatcher.js"></script>
<script src="../js/libs/promise.min.js"></script>
<script src="../js/libs/zepto.min.js"></script>
<script src="../js/compodoc.js"></script>
<script src="../js/tabs.js"></script>
<script src="../js/menu.js"></script>
<script src="../js/libs/clipboard.min.js"></script>
<script src="../js/libs/prism.js"></script>
<script src="../js/sourceCode.js"></script>
<script src="../js/search/search.js"></script>
<script src="../js/search/lunr.min.js"></script>
<script src="../js/search/search-lunr.js"></script>
<script src="../js/search/search_index.js"></script>
<script src="../js/lazy-load-graphs.js"></script>
</body>
</html>