Initial commit: kanban-elements-ui library
Angular 19 component library for kanban boards: - kb-board: main board with toolbar, swimlanes, and pipeline view - kb-column: columns with WIP limits, collapse, and drag reorder - kb-card: draggable cards with labels, assignees, and priorities - kb-swimlane: horizontal grouping with collapsible rows - kb-toolbar: search, sort, filter, and view toggle - kb-quick-add: inline card creation - kb-wip-indicator: WIP limit status display - kb-card-def / kb-column-header-def: custom template directives Includes signal-based services (board, drag, filter), SCSS design tokens with dark mode, and full TypeScript type definitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
87
src/components/kb-toolbar/kb-toolbar.component.html
Normal file
87
src/components/kb-toolbar/kb-toolbar.component.html
Normal file
@@ -0,0 +1,87 @@
|
||||
<div class="kb-toolbar">
|
||||
@if (searchable()) {
|
||||
<div class="kb-toolbar__search">
|
||||
<span class="kb-toolbar__search-icon">
|
||||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="7" cy="7" r="4.5"/><path d="M10.5 10.5L14 14"/></svg>
|
||||
</span>
|
||||
<input
|
||||
class="kb-toolbar__search-input"
|
||||
type="text"
|
||||
placeholder="Search cards..."
|
||||
[value]="searchTerm()"
|
||||
(input)="onSearchInput($event)"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="kb-toolbar__actions">
|
||||
<!-- Sort dropdown -->
|
||||
<div class="kb-toolbar__sort">
|
||||
<button
|
||||
class="kb-toolbar__btn"
|
||||
type="button"
|
||||
(click)="toggleSortMenu()"
|
||||
[title]="currentSort() ? 'Sort: ' + currentSort()!.field + ' ' + currentSort()!.direction : 'Sort cards'"
|
||||
>
|
||||
<span class="kb-toolbar__btn-icon">
|
||||
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M3 4h10v1.5H3V4zm0 3.25h7v1.5H3v-1.5zm0 3.25h4v1.5H3v-1.5z"/></svg>
|
||||
Sort
|
||||
</span>
|
||||
</button>
|
||||
@if (showSortMenu()) {
|
||||
<div class="kb-toolbar__sort-menu">
|
||||
@for (opt of sortOptions; track opt.field) {
|
||||
<button
|
||||
class="kb-toolbar__sort-option"
|
||||
[class.kb-toolbar__sort-option--active]="currentSort()?.field === opt.field"
|
||||
type="button"
|
||||
(click)="onSort(opt.field)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
@if (currentSort()?.field === opt.field) {
|
||||
<span class="kb-toolbar__sort-dir">
|
||||
@if (currentSort()!.direction === 'asc') {
|
||||
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M8 3.5l4.5 5H3.5L8 3.5z"/></svg>
|
||||
} @else {
|
||||
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M8 12.5L3.5 7.5h9L8 12.5z"/></svg>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (filterCount() > 0) {
|
||||
<span class="kb-toolbar__filter-badge">{{ filterCount() }}</span>
|
||||
}
|
||||
|
||||
@if (showViewToggle()) {
|
||||
<button
|
||||
class="kb-toolbar__btn"
|
||||
[class.kb-toolbar__btn--active]="viewMode() === 'board'"
|
||||
type="button"
|
||||
title="Board view"
|
||||
(click)="viewMode() !== 'board' && toggleView()"
|
||||
>
|
||||
<span class="kb-toolbar__btn-icon">
|
||||
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 3h3v10H2V3zm4.5 0h3v10h-3V3zm4.5 0h3v10h-3V3z"/></svg>
|
||||
Board
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="kb-toolbar__btn"
|
||||
[class.kb-toolbar__btn--active]="viewMode() === 'pipeline'"
|
||||
type="button"
|
||||
title="Pipeline view"
|
||||
(click)="viewMode() !== 'pipeline' && toggleView()"
|
||||
>
|
||||
<span class="kb-toolbar__btn-icon">
|
||||
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M1 7.25h3.5v1.5H1v-1.5zm5 0h3.5v1.5H6v-1.5zm5 0h3.5v1.5H11v-1.5zM4.5 7.5l1.5 .5-1.5.5v-1zm5 0l1.5.5-1.5.5v-1z"/></svg>
|
||||
Pipeline
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user