maverick-wave 3.9.0 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,8 @@
8
8
  "Bash(git ls-remote:*)",
9
9
  "Bash(npm outdated:*)",
10
10
  "Bash(npm update:*)",
11
- "Bash(npm audit:*)"
11
+ "Bash(npm audit:*)",
12
+ "Bash(npx prettier *)"
12
13
  ]
13
14
  }
14
15
  }
@@ -44,14 +44,14 @@ Load the one you need - do not read them all up front.
44
44
  ```html
45
45
  <link
46
46
  rel="stylesheet"
47
- href="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.css"
47
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@3.10.0/maverick-wave.min.css"
48
48
  />
49
49
  <link
50
50
  rel="stylesheet"
51
51
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"
52
52
  />
53
53
  ...
54
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.js"></script>
54
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@3.10.0/maverick-wave.min.js"></script>
55
55
  ```
56
56
 
57
57
  Pin the version. The JS file is optional and only for server-rendered/static pages -
@@ -114,6 +114,8 @@ bundled. Load it yourself or override the token.
114
114
  | Gallery dot | `mw-active` |
115
115
  | Stepper indicator / label / connector / step | `mw-active`, `mw-done` |
116
116
  | Checkbox list item (`li`) | `mw-selected` |
117
+ | Kanban composer (open) | `mw-active` |
118
+ | Kanban ticket being edited | `mw-kanban-editing` |
117
119
  | Modal overlay | `mw-modal-open` |
118
120
  | Alert, after dismissal | `mw-alert-closed` (`display: none`) |
119
121
  | Field wrapper in error | `mw-field-has-error` |
@@ -154,9 +156,10 @@ Everything below is documented in `references/components.md` unless marked other
154
156
  `mw-item-list` family
155
157
 
156
158
  **Data & status** `mw-table` (+ `subtle`, `sticky-head`, `cards`, `compact`,
157
- `hover`, responsive wrappers) · `mw-tag` / `mw-tags` · `mw-info` /
158
- `mw-info-mini` / `mw-info-counter` · `mw-progress-bar` · `mw-rating` ·
159
- `mw-meta-header` · `mw-stepper` · `mw-timeline-big` / `mw-timeline-simple`
159
+ `hover`, responsive wrappers) · `mw-kanban` (+ `plain`, `compact`) · `mw-tag` /
160
+ `mw-tags` · `mw-info` / `mw-info-mini` / `mw-info-counter` · `mw-progress-bar` ·
161
+ `mw-rating` · `mw-meta-header` · `mw-stepper` · `mw-timeline-big` /
162
+ `mw-timeline-simple`
160
163
 
161
164
  **Feedback** `mw-alert` · `mw-toast-stack` · `mw-empty-state` ·
162
165
  `mw-spinner-border` / `mw-spinner-dots` / `mw-spinner-dual-ring` · `mw-skeleton`
@@ -15,7 +15,7 @@ wired up by hand.
15
15
 
16
16
  <link
17
17
  rel="stylesheet"
18
- href="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.css"
18
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@3.10.0/maverick-wave.min.css"
19
19
  />
20
20
  <link
21
21
  rel="stylesheet"
@@ -332,7 +332,7 @@ wired up by hand.
332
332
  <div class="mw-modal-backdrop" onclick="closeModal('demo')"></div>
333
333
  </div>
334
334
 
335
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.js"></script>
335
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@3.10.0/maverick-wave.min.js"></script>
336
336
  <script>
337
337
  // The only thing the shipped script does not cover: opening a modal.
338
338
  // Closing works through .mw-modal-close, the backdrop is wired above.
@@ -96,8 +96,9 @@ Row of equally treated buttons, centered by default.
96
96
  `-secondary`, `-success`, `-warning`, `-danger`, `-info`.
97
97
  - A card does not clip its content, so a tooltip or dropdown inside it can reach
98
98
  outside. The exception is `mw-card-ribbon`: that banner has to be cut off at
99
- the edge, so a card containing one switches to `overflow: hidden` and clips
100
- everything else too.
99
+ the edge, so a card with one as its **direct child** switches to
100
+ `overflow: hidden` and clips everything else too. A ribbon deeper inside - on
101
+ a card nested in another card - does not make the outer one clip.
101
102
 
102
103
  ```html
103
104
  <div class="mw-card">
@@ -365,6 +366,150 @@ Shapes: `mw-skeleton-title`, `-text`, `-circle`, `-rect` (+ `-rect-sm`,
365
366
  </div>
366
367
  ```
367
368
 
369
+ ## Kanban
370
+
371
+ A board is a grid of equally wide lanes; a ticket is a plain `mw-card` with
372
+ `mw-kanban-card` on top. Everything except the counters and the composer is CSS.
373
+
374
+ ```html
375
+ <div class="mw-kanban" style="--mw-kanban-column-min-height: 390px">
376
+ <div class="mw-kanban-column">
377
+ <div class="mw-kanban-column-header">
378
+ <h5 class="mw-kanban-title">In Progress</h5>
379
+ <span class="mw-kanban-count">2</span>
380
+ <button
381
+ type="button"
382
+ class="mw-btn mw-btn-secondary mw-btn-sm mw-kanban-add"
383
+ aria-label="Add ticket to In Progress"
384
+ >
385
+ <i class="fas fa-plus"></i>
386
+ </button>
387
+ </div>
388
+
389
+ <div class="mw-kanban-column-body">
390
+ <article class="mw-card mw-kanban-card">
391
+ <div class="mw-card-ribbon mw-card-addon-danger">High</div>
392
+ <p class="mw-kanban-card-title">Sticky table header jitters</p>
393
+ <p class="mw-kanban-card-text">
394
+ On Safari the header shifts by a pixel.
395
+ </p>
396
+ <div class="mw-kanban-card-footer">
397
+ <span class="mw-kanban-card-id">MW-102</span>
398
+ <div class="mw-kanban-card-actions">
399
+ <div class="mw-avatar mw-avatar-xs mw-avatar-initials">jd</div>
400
+ <button
401
+ type="button"
402
+ class="mw-kanban-action"
403
+ aria-label="Move MW-102 one lane left"
404
+ >
405
+ <i class="fas fa-chevron-left"></i>
406
+ </button>
407
+ <button
408
+ type="button"
409
+ class="mw-kanban-action"
410
+ aria-label="Move MW-102 one lane right"
411
+ >
412
+ <i class="fas fa-chevron-right"></i>
413
+ </button>
414
+ <button
415
+ type="button"
416
+ class="mw-kanban-action"
417
+ aria-label="Edit MW-102"
418
+ >
419
+ <i class="fas fa-pen"></i>
420
+ </button>
421
+ <button
422
+ type="button"
423
+ class="mw-kanban-action mw-kanban-action-danger"
424
+ aria-label="Delete MW-102"
425
+ >
426
+ <i class="fas fa-trash"></i>
427
+ </button>
428
+ </div>
429
+ </div>
430
+ </article>
431
+
432
+ <div class="mw-kanban-empty">No tickets</div>
433
+ </div>
434
+ </div>
435
+ ...
436
+ </div>
437
+ ```
438
+
439
+ | Class | Role |
440
+ | ------------------------- | ---------------------------------------------------------------------------------------- |
441
+ | `mw-kanban` | Board. Grid, one column per lane, same width for all of them |
442
+ | `mw-kanban-plain` | Board without its own surface or padding - for a board that already sits on a panel |
443
+ | `mw-kanban-compact` | Tighter padding, description clamped to 2 lines instead of 4, lane floor 90px |
444
+ | `mw-kanban-column` | Lane: dashed border, flex column |
445
+ | `mw-kanban-column-header` | Title + counter + add button in one row |
446
+ | `mw-kanban-title` | Lane title, uppercase, truncates |
447
+ | `mw-kanban-count` | Ticket counter pill |
448
+ | `mw-kanban-add` | Sits **on** `mw-btn` - only trims it to the header line height |
449
+ | `mw-kanban-column-body` | Ticket stack; fills the lane so the empty state stays centred |
450
+ | `mw-kanban-card` | Ticket. Needs `mw-card` next to it |
451
+ | `mw-kanban-card-title` | Ticket title |
452
+ | `mw-kanban-card-text` | Description, clamped to 4 lines (2 on a compact board) |
453
+ | `mw-kanban-card-footer` | Rule + key on the left, avatar and actions on the right |
454
+ | `mw-kanban-card-id` | Ticket key, monospaced so equal-length keys line up across cards |
455
+ | `mw-kanban-card-actions` | Right-hand group; resets the avatar margin |
456
+ | `mw-kanban-action` | 26px square icon button (32px below `md`), `mw-kanban-action-danger` turns the hover red |
457
+ | `mw-kanban-empty` | Placeholder; hides itself as soon as the lane holds a ticket or an open composer |
458
+ | `mw-kanban-card-in` | One-shot entry animation for a freshly created ticket |
459
+
460
+ - **Priority is the regular `mw-card-ribbon`** and brings its own colour through
461
+ `mw-card-addon-danger|warning|info`. It has to be a **direct child** of the
462
+ card - that is what reserves the space next to the title. No ribbon means no
463
+ priority; there is no separate priority class.
464
+ - Lanes are as tall as the fullest one, with `--mw-kanban-column-min-height` as
465
+ the floor (120px, 90px compact). Raise it per board so a board that starts out
466
+ empty still reads as a board.
467
+ - Board surface and lane border are `--mw-kanban-background` and
468
+ `--mw-kanban-lane-border` - set them on the board, or drop the surface with
469
+ `mw-kanban-plain`.
470
+ - Responsive: below `lg` the lanes reflow into two columns, below `sm` into one.
471
+ - The actions are ordinary buttons - which of them exist is your decision. Give
472
+ every one an `aria-label` naming the ticket; the icon alone has no accessible
473
+ name.
474
+
475
+ ### Composer
476
+
477
+ The inline form for creating and editing a ticket. One per board, moved into the
478
+ lane it is needed in.
479
+
480
+ ```html
481
+ <form class="mw-kanban-composer mw-active">
482
+ <input type="text" class="mw-input mw-input-sm mw-kanban-composer-title" />
483
+ <textarea class="mw-textarea mw-kanban-composer-text" rows="2"></textarea>
484
+ <div class="mw-kanban-composer-row">
485
+ <select class="mw-select mw-select-sm mw-kanban-composer-priority">
486
+ ...
487
+ </select>
488
+ <select class="mw-select mw-select-sm mw-kanban-composer-assignee">
489
+ ...
490
+ </select>
491
+ </div>
492
+ <div class="mw-kanban-composer-actions">
493
+ <button type="button" class="mw-btn mw-btn-outline mw-btn-sm">
494
+ Cancel
495
+ </button>
496
+ <button type="submit" class="mw-btn mw-btn-primary mw-btn-sm">Save</button>
497
+ </div>
498
+ </form>
499
+ ```
500
+
501
+ - **`mw-kanban-composer` is `display: none` until it also carries `mw-active`.**
502
+ Rendering it conditionally is not enough - the class has to be there too, or
503
+ the form stays invisible.
504
+ - `mw-kanban-composer-row` puts priority and assignee side by side and stacks
505
+ them once the lane gets too narrow; `mw-kanban-composer-actions` is the button
506
+ row and gives its buttons the same 80px floor as a modal footer.
507
+ - The `-title`, `-text`, `-priority`, `-assignee` and `-cancel` classes carry no
508
+ styling of their own beyond a min-height on the textarea - they are the hooks
509
+ the shipped JS queries. In a SPA you bind the controls yourself and can drop
510
+ them.
511
+ - `mw-kanban-editing` hides the ticket the composer is currently replacing.
512
+
368
513
  ## Tags
369
514
 
370
515
  Two forms, picked by count - see also the pitfall list in `SKILL.md`.
@@ -25,23 +25,24 @@ classes are the entire contract.
25
25
 
26
26
  ## Behaviour inventory
27
27
 
28
- | Behaviour | What the shipped JS does | What to do instead |
29
- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
30
- | Accordion | Toggles `active` on `mw-accordion-header` and the following `mw-accordion-content` | `[class.active]="isOpen()"` on both elements |
31
- | Tabs | `data-tab` → panel `id`; sets `active` on nav item and panel | Track the selected index/key, bind `active` on both; drop `data-tab` |
32
- | Modal | Click on `mw-modal-close` removes `mw-modal-open` from the overlay | `[class.mw-modal-open]="isOpen()"`; backdrop click closes. Opening is not in the script at all (the showcase has its own `openModal`) |
33
- | Mobile nav | Toggles `open` on `mw-menu-btn` and `mw-navbar`, closes on anchor click | One signal, bound to both; reset it on navigation end |
34
- | Scroll spy | Sets `active` on `mw-navbar-link` from the scroll position | Router-based: `routerLinkActive="active"` |
35
- | Theme toggle | `localStorage['mw-theme']`, toggles `mw-theme-light` on `<body>` and `active` on the toggle | A theme service - see `examples/angular-services.md` |
36
- | Progress bar | `IntersectionObserver` sets `width` from `data-value` | Bind `[style.width.%]="value()"` on `mw-progress-fill` |
37
- | Slider | On `input`, sets `--value` (track fill) and `data-value` (badge text) | Bind `[style.--value.%]` and `[attr.data-value]` |
38
- | Alerts | Close button adds `mw-alert-closed` (`display: none`) | Remove the alert from the list/signal |
39
- | Checkbox lists | Adds `mw-selected` to the `li`, emits a `checkboxToggle` event, exposes `window.toggleCheckbox` | `[class.mw-selected]="item.checked"` |
40
- | Gallery | Generates the dots, moves the track, swipe handling, writes `mw-gallery-desc` | Render dots in the template, bind the track transform and `mw-active` on the current dot |
41
- | Image slider | Toggles `active` on the overlay image and the control button with the matching `data-index` | Bind `active` from the selected index |
42
- | Localhost indicator | On a local hostname, prepends `mw-localhost-indicator-pulse` to the header when it carries `mw-localhost-indicator-activated` | Render the element conditionally |
43
- | Header login button | Swaps the FontAwesome lock icon | Bind the icon class |
44
- | Color swatches | Showcase-only (prints computed hex values) | Not needed |
28
+ | Behaviour | What the shipped JS does | What to do instead |
29
+ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
+ | Accordion | Toggles `active` on `mw-accordion-header` and the following `mw-accordion-content` | `[class.active]="isOpen()"` on both elements |
31
+ | Tabs | `data-tab` → panel `id`; sets `active` on nav item and panel | Track the selected index/key, bind `active` on both; drop `data-tab` |
32
+ | Modal | Click on `mw-modal-close` removes `mw-modal-open` from the overlay | `[class.mw-modal-open]="isOpen()"`; backdrop click closes. Opening is not in the script at all (the showcase has its own `openModal`) |
33
+ | Mobile nav | Toggles `open` on `mw-menu-btn` and `mw-navbar`, closes on anchor click | One signal, bound to both; reset it on navigation end |
34
+ | Scroll spy | Sets `active` on `mw-navbar-link` from the scroll position | Router-based: `routerLinkActive="active"` |
35
+ | Theme toggle | `localStorage['mw-theme']`, toggles `mw-theme-light` on `<body>` and `active` on the toggle | A theme service - see `examples/angular-services.md` |
36
+ | Progress bar | `IntersectionObserver` sets `width` from `data-value` | Bind `[style.width.%]="value()"` on `mw-progress-fill` |
37
+ | Slider | On `input`, sets `--value` (track fill) and `data-value` (badge text) | Bind `[style.--value.%]` and `[attr.data-value]` |
38
+ | Alerts | Close button adds `mw-alert-closed` (`display: none`) | Remove the alert from the list/signal |
39
+ | Checkbox lists | Adds `mw-selected` to the `li`, emits a `checkboxToggle` event, exposes `window.toggleCheckbox` | `[class.mw-selected]="item.checked"` |
40
+ | Gallery | Generates the dots, moves the track, swipe handling, writes `mw-gallery-desc` | Render dots in the template, bind the track transform and `mw-active` on the current dot |
41
+ | Image slider | Toggles `active` on the overlay image and the control button with the matching `data-index` | Bind `active` from the selected index |
42
+ | Kanban board | Counts the tickets per lane, moves a card between lanes (`data-kanban-move`), clones `mw-kanban-card-template` on save, derives the next key from `data-kanban-prefix`, toggles `mw-active` on the composer | Keep the tickets in a signal/store and render the lanes from it; `mw-active` on the composer, `mw-kanban-editing` on the ticket it replaces. Neither the `<template>` nor the `mw-kanban-composer-*` hook classes are needed |
43
+ | Localhost indicator | On a local hostname, prepends `mw-localhost-indicator-pulse` to the header when it carries `mw-localhost-indicator-activated` | Render the element conditionally |
44
+ | Header login button | Swaps the FontAwesome lock icon | Bind the icon class |
45
+ | Color swatches | Showcase-only (prints computed hex values) | Not needed |
45
46
 
46
47
  ## What works without any JavaScript
47
48
 
@@ -49,7 +50,8 @@ Pure CSS, nothing to wire up: hover and focus states, the card lift, tooltips
49
50
  (`data-tooltip`), `mw-rating` (via `data-rating`), the responsive table card
50
51
  view (`data-label`), all grids and utilities, the body scroll lock while a modal
51
52
  is open (`body:has(.mw-modal-open)`), toast entry animations, the sticky table
52
- header, `prefers-reduced-motion` handling.
53
+ header, the kanban empty-lane placeholder (hidden via `:has()` as soon as the
54
+ lane holds a ticket), `prefers-reduced-motion` handling.
53
55
 
54
56
  ## When you do keep the shipped JS
55
57
 
@@ -60,6 +60,7 @@ a palette switch meant setting 41 variables.
60
60
  | `--mw-card-img-height` | Per-card image height (default `210px`; `mw-card-lg`/`-xl` set it to 340px/480px) |
61
61
  | `--mw-card-addon-color` | Background of `mw-card-badge` / `mw-card-ribbon`; the `mw-card-addon-*` classes set it, override it for a custom colour |
62
62
  | `--mw-table-scroll-height` | Per-table height cap for `mw-table-responsive-scroll` |
63
+ | `--mw-kanban-background`, `--mw-kanban-lane-border`, `--mw-kanban-column-min-height` | Per-board surface, lane border and lane floor (120px, 90px on `mw-kanban-compact`) |
63
64
  | `--mw-internal-theme-mode` | Read-only: what `$mw-theme-mode` was compiled to |
64
65
 
65
66
  Two rules that prevent most colour bugs:
package/CHANGELOG.md CHANGED
@@ -6,6 +6,8 @@ Patch releases are only for test purposes - here I only document major and minor
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ <<<<<<< HEAD
10
+ <<<<<<< HEAD
9
11
  <<<<<<< HEAD
10
12
  <<<<<<< HEAD
11
13
  <<<<<<< HEAD
@@ -13,6 +15,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
15
  =======
14
16
  ||||||| 0be20d9
15
17
  =======
18
+ ||||||| da0294d
19
+ =======
20
+ ||||||| 15e4c7d
21
+ =======
22
+ ## [3.11.0] - 2026-08-12
23
+
24
+ ### Fixed
25
+
26
+ - footer color
27
+
28
+ >>>>>>> main
29
+ ## [3.10.0] - 2026-08-10
30
+
31
+ ### Added
32
+
33
+ - kanban board
34
+
35
+ >>>>>>> main
16
36
  ## [3.9.0] - 2026-08-07
17
37
 
18
38
  ### Fixed
package/index.html CHANGED
@@ -382,6 +382,7 @@
382
382
  <a href="#page-header" class="mw-section-btn">Page Header</a>
383
383
  <a href="#meta-info" class="mw-section-btn">Meta Info</a>
384
384
  <a href="#tables" class="mw-section-btn">Tables</a>
385
+ <a href="#kanban" class="mw-section-btn">Kanban</a>
385
386
  <a href="#pagination" class="mw-section-btn">Pagination</a>
386
387
  <a href="#timelines" class="mw-section-btn">Timelines</a>
387
388
  <a href="#gallery" class="mw-section-btn">Image Gallery</a>
@@ -407,6 +408,11 @@
407
408
  @@include('./src/partials/tables-container.html')
408
409
  </div>
409
410
 
411
+ <!-- Kanban container -->
412
+ <div id="kanban">
413
+ @@include('./src/partials/kanban-container.html')
414
+ </div>
415
+
410
416
  <!-- Pagination container -->
411
417
  <div id="pagination">
412
418
  @@include('./src/partials/pagination-container.html')