@document-explorer/angular
v0.1.1
Published
Clean, configuration-driven document explorer for Angular. Bring your own data.
Maintainers
Readme
@document-explorer/angular
Turn any document data into a clean, navigable explorer — in Angular.
npm install @document-explorer/angularimport { DocumentExplorerComponent } from '@document-explorer/angular';
@Component({
standalone: true,
imports: [DocumentExplorerComponent],
template: `<doc-explorer [data]="documents" />`,
})
export class MyComponent {}Add the stylesheet once, in angular.json or a global stylesheet:
"styles": ["@document-explorer/angular/styles.css", "src/styles.css"]Bring your own data
<doc-explorer
[data]="apiResponse"
[mapper]="mapper"
title="Documents"
[search]="{ scope: 'global', searchableFields: ['metadata.owner'] }"
[selection]="{ mode: 'multiple', folders: false }"
[actions]="{ view: true, download: true }"
(documentOpen)="open($event)"
(selectionChange)="selected = $event"
/>The component is standalone, OnPush, and signal-driven throughout — it works
zoneless.
Inputs
Identical in name and meaning to the React package: data, mapper, title,
rootLabel, view, views, defaultView, search, sort, columns,
columnAlign, resizableColumns, columnWidths, selection, actions,
interaction,
loading, error, locale.
Outputs
folderOpen, documentOpen, selectionChange, searchChange, sortChange,
viewChange, documentView, documentDownload, columnResize
({ key, width, widths }), and action ({ actionId, item }) for custom
actions.
Custom rendering
Angular's equivalent of React's renderers is ng-template slots:
<doc-explorer [data]="documents">
<ng-template #deFile let-item>
<my-file-card [file]="item" />
</ng-template>
<ng-template #deEmpty>Nothing here yet.</ng-template>
</doc-explorer>Available slots: #deFile, #deFolder, #deEmpty, #deToolbar.
Per-column cells
For one column rather than a whole row — an avatar beside an owner, a status
pill — use the deColumn directive, the Angular equivalent of React's
ColumnDef.render:
import { DeColumnTemplateDirective } from '@document-explorer/angular';<doc-explorer [data]="documents" [columns]="columns">
<ng-template deColumn="metadata.owner" let-item let-value="value">
<span class="de-avatar">{{ initials(value) }}</span>
<span class="de-avatar-label">{{ value }}</span>
</ng-template>
</doc-explorer>The context carries the whole item and value, the column's formatted text.
Avatars
Showing a person is built in. Angular cannot return markup from a plain object
the way React's render can, so avatarColumn returns the column and the
options for <de-avatar-cell>:
readonly owner = avatarColumn({ key: 'metadata.owner', display: 'avatar' });
readonly columns = ['name', this.owner.column, 'size'];<doc-explorer [data]="documents" [columns]="columns">
<ng-template deColumn="metadata.owner" let-item>
<de-avatar-cell [item]="item" columnKey="metadata.owner" [options]="owner.options" />
</ng-template>
</doc-explorer>display is 'both' (default), 'avatar' (name on hover and to screen
readers) or 'name', and image is independent of it — pair
display: 'avatar' with image for a photo on its own. image takes a dot
path or function and falls back to initials on load failure. Colours come from six theme tokens, assigned stably
per name — identical to the React package, because both call resolveAvatar()
in core.
Badges
readonly status = badgeColumn({ key: 'metadata.status' });<ng-template deColumn="metadata.status" let-item>
<de-badge-cell [item]="item" columnKey="metadata.status" [options]="status.options" />
</ng-template>Conventional statuses get a tone with no configuration — approved green,
pending amber, rejected red. tones, format and variant override it,
and the colours are --de-tone-* tokens.
Resizable columns
<doc-explorer
[resizableColumns]="true"
[columnWidths]="saved"
(columnResize)="persist($event.widths)"
/>width is the starting track, maxWidth caps how far it can be dragged,
minWidth floors it, and resizable: false pins a column entirely.
Drag a handle to resize, double-click to reset. The handle is a focusable
role="separator", so ← / → resize and Enter resets — resizing is not
drag-only. A flexible column keeps a floor so widening a neighbour can never
hide the file names, and once the columns stop fitting the list scrolls
horizontally with the rows widening to match.
columnResize fires once on release, not per pointer move.
Parity with React
Both packages drive the same engine — @document-explorer/core — including the
keyboard contract. The test suite here is a deliberate mirror of the React one:
the same assertions, in the same order, against the same fixture. A divergence
between them is a bug in core, not in a renderer.
Theming and accessibility work exactly as documented in the React package README.
License
MIT
