npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@studiohyperdrive/ngx-layout

v18.4.2

Published

A lightweight customizable approach for common and complex layouts in Angular.

Downloads

373

Readme

Angular Tools: NgxLayout (@studiohyperdrive/ngx-layout)

ngx-layout is a collection of Angular components related to layout.

Installation

Install the package first:

npm install @studiohyperdrive/ngx-layout

Versioning and build information

This package will follow a semver-like format, major.minor.patch, in which:

  • major: Follows the Angular major version
  • minor: Introduces new features and (potential) breaking changes
  • patch: Introduces bugfixes and minor non-breaking changes

For more information about the build process, authors, contributions and issues, we refer to the ngx-tools repository.

Concept

ngx-layout is a package to help facilitate common layout use-cases.

Currently the package provides a configurable layout component which can be used to render components in a grid based on provided templates. This approach is ideal for use-cases such as a custom configurable dashboard. We also provide a fully accessible accordion component and an accessible displayContent approach to handle loading, error and offline flows.

Implementation

Accessibility

With all the packages of Studio Hyperdrive we aim to provide components and implementations that are WCAG/WAI-ARIA compliant. This means that rather than making this optional to the implementation, we enforce it throughout the packages.

Where custom input is needed to make the implementation accessible, a Accessibility chapter can be found for each implementation.

Drag and drop

Drag and drop is a common and well known pattern for end users, but often ends up being inaccessible for users that prefer or need to use a keyboard for interacting with the interface. On top of that, for visually impaired users, it becomes difficult to understand how to use this pattern.

Within this package we use Angular CDK Drag and Drop, but further enhance to make it accessible for keyboard users and users using screen readers. We already provide several measures for this functionality, but further input from the developer is required.

Concept

To make the drag and drop pattern accessible for keyboard users, we allow the items in the drag and drop container to be moved using keyboard interactions. By tabbing to the item and pressing Enter or Space, we can select an element and then move it using the Arrow keys. Once the item is in the correct place, we can deselect the element by pressing the Enter or Space key again.

For users with assistive technologies, such as screenreaders, we provide use the CDK LiveAnnouncer that will announce each change in the drag and drop container. This will announce select events, deselect events and move events. ngx-layout provides a set of default messages for a select amount of languages, but offers the ability to overwrite these with your own messages when needed.

Implementation

In order to make the drag and drop accessible for every user, you need to provide an implementation of the NgxAccessibleDragAndDropAbstractService. This service requires you to provide the current language of your application by implementing the currentLanguage method. This can be either a string or an Observable string.

If you wish to overwrite the default message record with your own, you can do that by providing the customMessages property. This is however optional, if not provided, the default language options will be provided.

You can provide your service in the following manner:

providers: [
    provideNgxDragAndDropService(DragAndDropService),
]
Setup

Components

Accordion

The ngx-accordion provides a easy to use WCAG/ARIA compliant implementation for an accordion. Its implementation exists of a NgxAccordionComponent and a NgxAccordionItemComponent component. Both can be imported simultaneously by importing NgxAccordion.

Implementation

Using the NgxAccordionComponent as a container for our accordion items (NgxAccordionItemComponent), we are able to provide correct keyboard navigation for end users. Therefore it is important to always warp your items in the container component.

We use content projection to pass the header and the content of each accordion item, by using the headerTmpl and contentTmpl ng-templates. Both templates allow for fetching the open state of the accordion, by using the $implicit outlet context.

In the example below you can find a simple implementation of the accordion.

import { NgxAccordion } from '@ngx/layout';

@Component({
	...
	standalone: true,
	imports: [NgxAccordion],
})
<ngx-accordion>
	@for (item of testData; track $index) {
	<ngx-accordion-item>
		<ng-template #headerTmpl let-isOpen> {{item.title}} {{isOpen}} </ng-template>

		<ng-template #contentTmpl> {{item.content}} </ng-template>
	</ngx-accordion-item>
	}
</ngx-accordion>
Extra configuration

The NgxAccordionComponent allows for opening a set of accordion items from the start. This is useful for when you want to open the first item, or specific items in the accordion. By using the open property you can either open all items, the first item, a specific item or a set of specific items by passing all, first, the index of an item or an array of indexes respectively.

An individual NgxAccordionItemComponent can also be disabled by providing the disabled property. Once disabled, an item's open or closed state cannot be altered by the user. To allow an item to be open from the start and not closeable by the end-user, the open property of the NgxAccordionComponent will ignore the disabled state of the individual items.

Styling

The accordion implementation provides several classes we can use to target elements in the accordion. Internally the NgxAccordionItemComponent uses the details HTML element.

| Class | | | --------------------- | ------------------------------------------------- | | ngx-accordion | A class set to the NgxAccordionComponent. | | ngx-accordion-item | A class set to the NgxAccordionItemComponent. | | ngx-accordion-content | A class set to the content of the accordion item. | | ngx-accordion-header | A class set to the header of the accordion item. |

Configurable layout

The configurable layout provides the ability to render components in a grid depending on a provided two dimensional array of keys and corresponding items with a provided template. The combination exists of an ngx-configurable-layout and an ngx-configurable-layout-item.

Setup

By using content projection, we render our components inside of a ngx-configurable-layout-item. Each item requires a key as an input, which will be used to match the provided component with the two dimensional array we provide to the ngx-configurable-layout component.

This means that the order of rendering is now no longer depended on how you provide the components in the template, but by the two dimensional array provided to the ngx-configurable-layout component. This significantly streamlines the process and allows you to easily refactor existing flows. In the chapters below we'll explain how to provide the two dimensional array to the component.

In order to provide an accessible experience for end-users, the earlier mentioned NgxDragAndDropService needs to be provided.

Accessibility

Currently, default texts have been provided for the following languages: Dutch (nl), English (en), French (fr), German (de), Spanish (es),Portuguese (pt), Turkish (tr), and Kurdish (ku).

In order to further customize the messages for end users with assistive technologies, we can pass several configuration items to the ngx-configurable-layout and ngx-configurable-layout-item.

By passing an itemLabel and a rowLabel we can define specific names for the rows and the items within the rows of the ngx-configurable-layout. By default, these are item and list; but you can change these to your own preference.

The ngx-configurable-layout-item also has an optional label property which can be used to overwrite both the default and the layout defined label for the item.

Static

Earlier we mentioned that the layout is build up using a provided two dimensional array. Depending on whether you want this layout to be static or editable, we provide the array in a different fashion.

When making a static layout, the layout itself can not be readjusted on the spot by the end user. A good use-case for this could be a dashboard that comes with a predefined set of layouts the user can pick from.

When the layoutType of the ngx-configurable-layout is set to static, the two dimensional array needs to provided through a keys input. This input takes a two dimensional array of key strings that match the ones presented in the template.

Below is a simple example for a static configurable layout.

import { NgxConfigurableLayoutComponent, NgxConfigurableLayoutItemComponent } from '@studiohyperdrive/ngx-layout';

@Component({
	...,
	standalone: true,
	imports: [NgxConfigurableLayoutComponent, NgxConfigurableLayoutItemComponent],
	...
})
<ngx-configurable-layout
	layoutType="static"
	[keys]="[['second-item', 'first-item'], ['third-item']]"
>
	<ngx-configurable-layout-item key="first-item">
		<p>This is the second item in the DOM.</p>
	</ngx-configurable-layout-item>

	<ngx-configurable-layout-item key="second-item">
		<p>This is the first item in the DOM.</p>
	</ngx-configurable-layout-item>

	<ngx-configurable-layout-item key="third-item">
		<p>This is the third item in the DOM.</p>
	</ngx-configurable-layout-item>
</ngx-configurable-layout>
Editable

Unlike with the static layout, the editable layout allows the user to readjust on the spot by the end user. This means that the end user can toggle items and ,when enabled, reorder these items through drag and drop. A use-case that fits this approach is a fully configurable dashboard, where an end user can pick and choose which items they wish to see.

When setting the layoutType to editable, the two dimensional array is provided by attaching a FormControl to the ngx-configurable-layout. Unlike with the keys input, the control expects an object with a key and an isActive property. The latter will be used to let the end user toggle items within the view.

As long as the showInactive property is set to false, the inactive items will not be shown in the view. By setting it to true, the inactive items become visible, including a toggle that gets attached to all the items in the view. This toggle allows the items in the view be toggled on and off.

If you for some reason do not wish to make an item in the list toggable, you can set individual items in the control as disabled. You can do this by simply setting the disabled property of the item in the two dimensional array to true. This will prevent the toggle from being shown and the corresponding item will receive the class ngx-layout-item-disabled.

By default, the toggle is represented by a default html checkbox in the top right corner of the item. This checkbox has the ngx-layout-item-toggle class. This toggle however can be overwritten by using the custom checkboxTmpl template.

Below is a simple example for an editable configurable layout.

import { NgxConfigurableLayoutComponent, NgxConfigurableLayoutItemComponent,NgxConfigurableLayoutGrid } from '@studiohyperdrive/ngx-layout';

@Component({
	...,
	standalone: true,
	imports: [NgxConfigurableLayoutComponent, NgxConfigurableLayoutItemComponent],
	...
})

...

public readonly control: FormControl<NgxConfigurableLayoutGrid> = new FormControl([[{key: 'second-item', isActive: true}, {key: 'first-item', isActive: false}, ]])
<ngx-configurable-layout layoutType="editable" [formControl]="control">
	<ngx-configurable-layout-item key="first-item">
		<p>
			This is the second item in the DOM. It will only be visible when the showInactive
			property is set to true.
		</p>
	</ngx-configurable-layout-item>

	<ngx-configurable-layout-item key="second-item">
		<p>This is the first item in the DOM.</p>
	</ngx-configurable-layout-item>

	<ng-template #checkboxTmpl let-control>
		This is an optional custom checkboxTmpl!

		<input type="checkbox" [formControl]="control" class="my-custom-checkbox" />
	</ng-template>
</ngx-configurable-layout>
Drag and drop

ngx-configurable-layout provides drag and drop through the Angular CDK implementation. By default, the drag and drop functionality is disabled, and can be enabled through allowDragAndDrop.

By default, the package uses the demo styling provided by the Angular CDK team. This can be overwritten by custom styling, using the classes provided in the section Styling.

When allowDragAndDrop is enabled, we can pass a dropPredicate. This function is bound to the layout component and will allow you to determine whether dropping an element in a specific spot is allowed by returning true or false. For more information on the predicate, we refer to the CDK Drag and Drop documentation.

Item size

To determine how much space an item takes up in the grid, we use the itemSize input.

By using the option fill, which is the default option, the components will be sized to maximize filling up the grid.

By using the option fit-content, the size of the components themselves will define how much space they take up.

By using the option equal, all items in the entire grid will take up an equal amount of space. This also applies to the height of the elements, but this will require you to set the height of your items to height:100% for this to take effect.

Gaps

In order to create spacing between items in the layout, ngx-configurable-layout provides two inputs, columnGap and rowGap.

Both properties expect a CSS based amount (in px, rem, %, etc.) and are both optional. This is the preferred way of adding spacing between your items, as using margins can sometimes create unexpected results due to the CSS Grid based implementation.

Styling

By default, ngx-configurable-layout always provides minimal styling. Several classes are provided to further style the grid as needed.

| Class | | | ------------------------------ | --------------------------------------------------------------------------- | | ngx-layout-grid | The overarching grid container used by the ngx-configurable-layout | | ngx-layout-row | A row in the ngx-configurable-layout | | ngx-layout-item | A cell in the ngx-configurable-layout | | ngx-layout-drag-placeholder | A class to style the custom placeholder used when drag and drop is enabled. | | ngx-layout-item-toggle | A class to style the default checkbox used in editable layouts. | | ngx-layout-item-inactive | A class to style the inactive items used in editable layouts. | | ngx-layout-item-disabled | A class to style the disabled items used in editable layouts. | | ngx-layout-grid-inactive-shown | A class given to the container when the inactive items are being shown. |

Directives

NgxDisplayContentDirective

The *displayContent directive provides the ability to hide parts of the template based on a loading, error and/or offline status and optionally replace those by default components provided in the application.

Setup

In order for the directive to function correctly, some base configuration has to be provided. For each status, we can provide a fallback component we wish to render when each of these statuses are true. These components should implement the NgxDisplayContentComponent abstract.

Each component is optional and can be overwritten by a custom template where the directive is used.

providers: [
	provideNgxDisplayContentConfiguration({
		components: {
			loading: DisplayContentLoadingComponent,
			error: DisplayContentErrorComponent,
			offline: DisplayContentOfflineComponent,
		},
	}),
];

Due to the fact that these components are optional, we might provide a loading state to the directive and not have a loading component to show. By default, the directive will then render the initial template. To override this behavior the configuration allows a property hideWhenNoTemplateProvided to be set to true, which will hide the initial template instead.

By default, we need to provide the offline condition to the directive ourself in order to display the offline fallback. Because this status, unlike the error and the loading status, is based on a single input; we've provided the ability to automatically listen to the the online status of the application, using the NgxOnlineService provided in this package. Setting listenToOnlineStatus to true will automatically handle the offline status.

providers: [
	provideNgxDisplayContentConfiguration({
		hideWhenNoTemplateProvided: true,
		listenToOnlineStatus: true,
		components: {
			loading: DisplayContentLoadingComponent,
			error: DisplayContentErrorComponent,
			offline: DisplayContentOfflineComponent,
		},
	}),
];

Implementation

Once the initial configuration is provided, we can use the *displayContent directive. This directive is a structural directive and requires an object with the status as an input. The directive has 3 potential statuses to listen to, being offline, loading and error. These statuses are checked in the earlier mentioned order.

As an example, if the application is offline and we automatically listen to the online status, the offline fallback will be shown first; even if the loading status is currently set to true. Once the application is back online, then the loading fallback will be shown. Only then, if the loading status is false, will a potential error fallback be shown based on the error condition.

<!-- This will not render the provided div, but the provided loading fallback instead -->
<div *displayContent="{loading: true}">Hello! This content will be rendered when</div>

<!-- This will render the provided div -->
<div *displayContent="{loading: false}">Hello! This content will be rendered when</div>

Override configuration

In certain cases we wish to override the default components we've provided or we wish to provide extra information to the default components. We can use this by providing additional configuration to the *displayContent directive.

Each implementation of the NgxDisplayContentComponent comes with a any-typed data Input. We can pass this data to the component by providing this in the configuration object.

<!-- This will not render the provided div, but the provided error fallback including the provided data-->
<div *displayContent="{error: true}; condition: {error: {data: 'This is the error'}}">
	Hello! This content will be rendered when
</div>

Sometimes, we do not wish to use the default component at all, and want to provide a custom template instead. We can also do this by providing a template in the override configuration.

<ng-template #errorTmpl> This is our custom error template! </ng-template>

<!-- This will not render the provided div nor the provided fallback component, but will render the errorTmpl above.-->
<div *displayContent="{error: true}; condition: {error: {template: errorTmpl}}">
	Hello! This content will be rendered when
</div>

Accessibility

In order to provide a WCAG/ARIA compliant implementation, the *displayContent directive automatically sets the aria-live and aria-busy labels when needed.

By default, the aria-live label gets set to polite. You can overwrite this setting using the ariaLive property in the override configuration.

<div *displayContent="{loading: true}; ariaLive:'assertive' ">Hello world!</div>

If multiple items in a parent have this directive or if the parent already has an aria-live label set, the label with the highest importance gets used. The ranking is assertive, polite and off respectively.

Services

NgxOnlineService

ngx-layout provides a root service NgxOnlineService that offers a SSR friendly approach to the online status of the application. Listening to the online$ Observable will provide you with a simple true or false based on the current status.