@apliteni/apliteni-ui 0.116.0 → 0.118.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.
@@ -2,7 +2,7 @@ import { button, esc } from './index.js';
2
2
  import { dropdown, wireDropdown } from './dropdown.js';
3
3
  import { filterChipText, filterChipName, filterChipUnset, filterChipItems, focusNextStop } from '../logic/filter-bar.js';
4
4
 
5
- export function filterBar({ filters = [], label = 'Filters', clearLabel = 'Clear all', disabled = false, busy = false } = {}) {
5
+ export function filterBar({ filters = [], label = 'Filters', clearLabel = 'Clear all', clearVariant = 'ghost', disabled = false, busy = false } = {}) {
6
6
  return `<fieldset class="ui-filter-bar" data-filter-bar${disabled || busy ? ' disabled' : ''}${busy ? ' aria-busy="true"' : ''}>`
7
7
  + `<legend class="ui-filter-bar__legend">${esc(label)}</legend>`
8
8
  + filters.map(filter => `<fieldset class="ui-filter-bar__chip" data-filter-id="${esc(filter.id)}"${filter.disabled ? ' disabled' : ''}>`
@@ -17,11 +17,10 @@ export function filterBar({ filters = [], label = 'Filters', clearLabel = 'Clear
17
17
  // row is the only thing in it, and it reads as a bar that has been turned
18
18
  // off rather than one with no filters on it. It is the kit's own `one-page`
19
19
  // rule — a control with no action to offer is not shown. It returns with
20
- // the first chip, in the bordered skin rather than the ghost one, because a
21
- // live action beside two chips has to read as live.
20
+ // the first chip, as a quiet text action.
22
21
  // why: docs/components.md#a-filter-row-holds-its-panels
23
22
  + (filters.length
24
- ? `<span data-filter-clear>${button({ label: clearLabel, size: 'sm', variant: 'ghost' })}</span>`
23
+ ? `<span data-filter-clear>${button({ label: clearLabel, size: 'sm', variant: clearVariant })}</span>`
25
24
  : '')
26
25
  + '</fieldset>';
27
26
  }
@@ -1,5 +1,5 @@
1
1
  /* ============================================================================
2
- * Button — .ui-btn (variants: primary / secondary / ghost / danger)
2
+ * Button — .ui-btn (variants: primary / secondary / ghost / danger / link)
3
3
  * (sizes: xs / sm / md / lg, [icon], [disabled], [aria-busy])
4
4
  * ========================================================================== */
5
5
 
@@ -70,6 +70,22 @@
70
70
  color: var(--strong);
71
71
  }
72
72
 
73
+ .ui-btn--link {
74
+ background: transparent;
75
+ border-color: transparent;
76
+ color: var(--accent);
77
+ padding-inline: 0;
78
+ }
79
+ .ui-btn--link .ui-btn__label-slot { overflow: visible; }
80
+ .ui-btn--link[aria-busy="true"] .ui-btn__label-slot { overflow: hidden; }
81
+ .ui-btn--link .ui-btn__label { text-decoration: underline; text-underline-offset: 0.2em; }
82
+ .ui-btn.ui-btn--link:hover {
83
+ background: transparent;
84
+ border-color: transparent;
85
+ color: var(--strong);
86
+ text-decoration: underline;
87
+ }
88
+
73
89
  .ui-btn--danger { color: var(--text); }
74
90
  .ui-btn--danger:hover, .ui-btn--danger:focus-visible {
75
91
  color: var(--pink);
@@ -112,6 +128,12 @@
112
128
  border-color: transparent;
113
129
  /* muted-ink: state — unavailable control */ color: var(--disabled-ink-bare);
114
130
  }
131
+ .ui-btn--link:disabled,
132
+ .ui-btn--link[aria-disabled="true"] {
133
+ background: transparent;
134
+ border-color: transparent;
135
+ /* muted-ink: state — unavailable link action */ color: var(--disabled-ink-bare);
136
+ }
115
137
  /* With no box, the ink is read on whatever is behind it, so the ghost takes an ink
116
138
  set for the dullest ground: in dark 7.49 / 6.31 / 7.00 / 5.44 on --bg / --surface /
117
139
  --surface-2 / --surface-3, in light 5.85 / 6.50 / 5.49 / 5.70. The enabled ghost now uses body
@@ -161,6 +183,13 @@
161
183
  border-color: transparent;
162
184
  color: var(--text);
163
185
  }
186
+ .ui-btn[aria-busy="true"].ui-btn--link,
187
+ .ui-btn[aria-busy="true"].ui-btn--link:hover,
188
+ .ui-btn[aria-busy="true"].ui-btn--link:active {
189
+ background: transparent; /* code-bg: inherit — busy paint retains the button's containing gap. */
190
+ border-color: transparent;
191
+ color: var(--accent);
192
+ }
164
193
  .ui-btn[aria-busy="true"].ui-btn--danger,
165
194
  .ui-btn[aria-busy="true"].ui-btn--danger:hover,
166
195
  .ui-btn[aria-busy="true"].ui-btn--danger:active {
@@ -40,6 +40,11 @@
40
40
  .ui-card--pad-sm { padding: var(--space-5) var(--space-6); }
41
41
  .ui-card--pad-lg { padding: var(--space-8) var(--space-10); }
42
42
 
43
+ /* A card framing one content-width block ends where the block ends — a 359px table sat in
44
+ a 1232px card (#504) — and is capped, so a wider block still fills the room and scrolls.
45
+ why: docs/foundations.md#spacing-and-rhythm */
46
+ .ui-card--fit { width: fit-content; max-width: 100%; }
47
+
43
48
  /* An accent-tinted card, e.g. a highlighted plan / success surface. The accent edge is
44
49
  the card's own hairline re-coloured: an inset ring over it would draw two. #295
45
50
  The strength is --card-tint, per theme: light mixes down from white, so a tint that
@@ -10,6 +10,7 @@
10
10
  .ui-pager {
11
11
  display: flex;
12
12
  flex-wrap: wrap;
13
+ justify-content: flex-end;
13
14
  align-items: center;
14
15
  gap: var(--space-3) var(--space-4);
15
16
  font-size: var(--text-sm);
@@ -113,7 +114,8 @@
113
114
  `margin-top: 16px` for this, which is --space-4; the number moves to the scale
114
115
  with it rather than travelling as a literal.
115
116
  why: docs/foundations.md#spacing-and-rhythm */
116
- .ui-table + .ui-pager { margin-top: var(--space-4); }
117
+ .ui-table + .ui-pager,
118
+ .ui-table-scroll + .ui-pager { margin-top: var(--space-4); }
117
119
 
118
120
  /* A step given an `href` is an anchor, and a host stylesheet's `a:link` is
119
121
  (0,1,1) — which outranks `.ui-btn--ghost` at (0,1,0) and paints the enabled
@@ -8,6 +8,11 @@
8
8
  border-collapse: collapse;
9
9
  font-size: var(--text-base);
10
10
  }
11
+ /* Fit cards keep short tables close to their labels. Other cards keep full-width tables. */
12
+ :where(.ui-card--fit) .ui-table {
13
+ width: auto;
14
+ max-width: 100%;
15
+ }
11
16
  .ui-table th {
12
17
  text-align: left;
13
18
  /* rank: label */
@@ -280,6 +285,10 @@
280
285
  width: calc(100% + 2 * var(--space-3));
281
286
  margin-inline: calc(-1 * var(--space-3));
282
287
  }
288
+ .ui-card--fit > :where(.ui-table--dense, .ui-table--zebra) {
289
+ width: auto;
290
+ max-width: calc(100% + 2 * var(--space-3));
291
+ }
283
292
  /* A scroll wrapper owns the bleed for a nested dense table: 4px of focus
284
293
  clearance plus the 12px end-cell inset. */
285
294
  .ui-card > .ui-table-scroll:has(> .ui-table--dense) {
@@ -391,6 +400,8 @@ a.ui-identity:hover { text-decoration: underline; }
391
400
  under it, so whatever the cut lets out is painted over that column. A child's ring
392
401
  needs 3px and the cell's padding is 12px, so the room comes from the padding.
393
402
  why: docs/components.md#dense-financial-tables, #500, #513 */
403
+ /* A percentage can stretch an intrinsic table beyond its content. */
404
+ .ui-card--fit .ui-table--pinned .ui-table__identity { width: 1px; }
394
405
  .ui-table--pinned .ui-table__identity {
395
406
  width: 1%;
396
407
  max-width: var(--ui-table-identity-max);