@ntmats/hc-ui 0.11.0 → 0.12.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.
package/dist/index.d.ts CHANGED
@@ -97,7 +97,14 @@ export declare const IconButton: ForwardRefExoticComponent<IconButtonProps & Ref
97
97
  interface ChipBaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {
98
98
  /** Toggle state for filters; omit for a plain action chip. */
99
99
  selected?: boolean;
100
+ /** Decorative icon before the label (18px at `md`); its side of the pill gets a little less room than text. */
100
101
  icon?: ReactNode;
102
+ /**
103
+ * Round picture before the label, concentric with the pill's start: 24px at `md` and `sm`, 18px at
104
+ * `xs` (a character, a player). Pass an `img` (or an `AvatarView`); the chip sizes and rounds it.
105
+ * Decorative: the label names the chip. Takes the place of `icon` when both are given.
106
+ */
107
+ avatar?: ReactNode;
101
108
  /**
102
109
  * `md` (default): 36px, 13px text (HCUI `chip`). `sm`: 36px, 12px text and 12px padding (HCUI's
103
110
  * desktop filter pills and sort trigger). `xs`: 26px, 11px text, muted fill without ring (HCUI's
package/dist/index.js CHANGED
@@ -156,18 +156,18 @@ var glyph = (size, d) => /* @__PURE__ */ jsx("svg", { width: size, height: size,
156
156
  var CHEVRON_DOWN = "M6 9L12 15L18 9";
157
157
  var XMARK = "M6.75827 17.2426L12.0009 12M17.2435 6.75736L12.0009 12M12.0009 12L6.75827 6.75736M12.0009 12L17.2435 17.2426";
158
158
  var visible = (node) => node !== void 0 && node !== null && node !== false && node !== "";
159
- var Chip = forwardRef(function Chip2({ selected, icon, size = "md", variant = "outline", applied = false, count, badge, badgePlacement = "inline", informative = false, chevron, onClear, clearLabel, type = "button", className, children, ...props }, ref) {
159
+ var Chip = forwardRef(function Chip2({ selected, icon, avatar, size = "md", variant = "outline", applied = false, count, badge, badgePlacement = "inline", informative = false, chevron, onClear, clearLabel, type = "button", className, children, ...props }, ref) {
160
160
  const popup = props["aria-haspopup"];
161
161
  const withChevron = chevron ?? (popup !== void 0 && popup !== false && popup !== "false");
162
162
  const look = {
163
163
  "data-size": size === "md" ? void 0 : size,
164
164
  "data-variant": variant === "outline" ? void 0 : variant,
165
165
  "data-applied": applied || void 0,
166
- "data-icon-only": icon && !visible(children) || void 0,
166
+ "data-icon-only": icon && !avatar && !visible(children) || void 0,
167
167
  "data-informative": informative || void 0
168
168
  };
169
169
  const content = /* @__PURE__ */ jsxs(Fragment2, { children: [
170
- icon && /* @__PURE__ */ jsx("span", { className: "hc-ui-chip__icon", "aria-hidden": "true", children: icon }),
170
+ avatar ? /* @__PURE__ */ jsx("span", { className: "hc-ui-chip__avatar", "aria-hidden": "true", children: avatar }) : icon && /* @__PURE__ */ jsx("span", { className: "hc-ui-chip__icon", "aria-hidden": "true", children: icon }),
171
171
  children,
172
172
  visible(count) && /* @__PURE__ */ jsx("span", { className: "hc-ui-chip__count", children: count }),
173
173
  visible(badge) && /* @__PURE__ */ jsx("span", { className: "hc-ui-chip__badge", "data-placement": badgePlacement === "corner" ? "corner" : void 0, children: badge }),
package/dist/styles.css CHANGED
@@ -64,7 +64,8 @@
64
64
  min-width: var(--hc-segmented-option-min-width, 0);
65
65
  min-height: 38px;
66
66
  margin: 0;
67
- padding: 0 var(--hc-space-3);
67
+ /* Text gets the pill's room (as Chip); an icon before the label, a little less. */
68
+ padding: 0 var(--hc-space-4);
68
69
  color: var(--hc-color-text-secondary);
69
70
  font-family: var(--hc-font-body);
70
71
  font-size: var(--hc-font-size-sm);
@@ -84,7 +85,8 @@
84
85
  box-shadow var(--hc-transition-fast), font-weight 220ms var(--hc-ease-standard);
85
86
  }
86
87
 
87
- [data-hc-ds] .hc-ui-segmented[data-density='compact'] .hc-ui-segmented__option { min-height: 32px; }
88
+ [data-hc-ds] .hc-ui-segmented[data-density='compact'] .hc-ui-segmented__option { min-height: 32px; padding: 0 14px; }
89
+ [data-hc-ds] .hc-ui-segmented:not([data-labels='hidden']) .hc-ui-segmented__option:has(> .hc-ui-segmented__icon + .hc-ui-segmented__label) { padding-inline-start: var(--hc-space-3); }
88
90
 
89
91
  [data-hc-ds] .hc-ui-segmented[data-labels='hidden'] .hc-ui-segmented__option {
90
92
  width: 40px;
@@ -216,9 +218,11 @@
216
218
 
217
219
  /* Button — HCUI btn-base / btn-primary / btn-outline / btn-danger / btn-lg. */
218
220
  [data-hc-ds] .hc-ui-button {
221
+ --hc-button-pad: var(--hc-space-5);
222
+ --hc-button-pad-icon: var(--hc-space-4);
219
223
  gap: var(--hc-space-2);
220
224
  min-height: var(--hc-control-height-md);
221
- padding: 0 var(--hc-space-5);
225
+ padding: 0 var(--hc-button-pad);
222
226
  color: var(--hc-color-text-primary);
223
227
  background-color: var(--hc-color-bg-muted);
224
228
  font-size: var(--hc-font-size-md);
@@ -237,8 +241,11 @@
237
241
  [data-hc-ds] .hc-ui-button:is([data-variant='secondary'], [data-variant='outline'], [data-variant='ghost'])[data-tone='danger'] { color: var(--hc-color-danger); }
238
242
  /* An open popup trigger: the 1.5px ring in the text color, as Chip (HCUI's Importar, Entrar and Convidar). */
239
243
  [data-hc-ds] .hc-ui-button:is([data-variant='secondary'], [data-variant='outline'], [data-variant='ghost'])[aria-haspopup]:not([aria-haspopup='false'])[aria-expanded='true'] { box-shadow: inset 0 0 0 1.5px var(--hc-color-text-primary); }
240
- [data-hc-ds] .hc-ui-button[data-size='sm'] { min-height: var(--hc-control-height-chip); padding: 0 var(--hc-space-4); font-size: var(--hc-font-size-sm); }
241
- [data-hc-ds] .hc-ui-button[data-size='lg'] { min-height: var(--hc-control-height-lg); padding: 0 var(--hc-space-6); font-size: var(--hc-font-size-base); }
244
+ [data-hc-ds] .hc-ui-button[data-size='sm'] { --hc-button-pad: var(--hc-space-4); --hc-button-pad-icon: var(--hc-space-3); min-height: var(--hc-control-height-chip); font-size: var(--hc-font-size-sm); }
245
+ [data-hc-ds] .hc-ui-button[data-size='lg'] { --hc-button-pad: var(--hc-space-6); --hc-button-pad-icon: var(--hc-space-5); min-height: var(--hc-control-height-lg); font-size: var(--hc-font-size-base); }
246
+ /* An icon (or the spinner) at a side takes a little less room than text (Material 3: 16 and 24 at 40). */
247
+ [data-hc-ds] .hc-ui-button:has(> :is(.hc-ui-button__icon, .hc-ui-button__spinner):first-child) { padding-inline-start: var(--hc-button-pad-icon); }
248
+ [data-hc-ds] .hc-ui-button:has(> .hc-ui-button__icon:last-child) { padding-inline-end: var(--hc-button-pad-icon); }
242
249
  [data-hc-ds] .hc-ui-button[data-full-width] { width: 100%; }
243
250
  [data-hc-ds] .hc-ui-button:disabled { opacity: 0.4; cursor: default; }
244
251
  [data-hc-ds] .hc-ui-button { max-width: 100%; }
@@ -297,11 +304,21 @@
297
304
  [data-hc-ds] .hc-ui-icon-button:disabled { opacity: 0.4; cursor: default; }
298
305
 
299
306
  /* Chip — HCUI chip / chip-active. */
307
+ /*
308
+ * Side space of a pill (Chip, Button, SegmentedControl): text needs more room than an icon or an
309
+ * avatar, because the round end eats into the text and a glyph is already round. A side with text
310
+ * gets about half the height (Material 3: 16/32 and 24/40; eBay Playbook: 16/32 and 20/40); a side
311
+ * that starts or ends with an icon gets a little less; an avatar sits concentric with the end.
312
+ */
300
313
  [data-hc-ds] .hc-ui-chip {
314
+ --hc-chip-pad: 16px;
315
+ --hc-chip-pad-icon: 12px;
316
+ --hc-chip-pad-avatar: 6px;
317
+ --hc-chip-avatar: 24px;
301
318
  flex: 0 0 auto;
302
319
  gap: 6px;
303
320
  min-height: var(--hc-control-height-chip);
304
- padding: 0 14px;
321
+ padding: 0 var(--hc-chip-pad);
305
322
  color: var(--hc-color-text-primary);
306
323
  background-color: var(--hc-color-bg-surface);
307
324
  box-shadow: inset 0 0 0 1px var(--hc-color-border-strong);
@@ -335,16 +352,33 @@
335
352
  font-variant-numeric: tabular-nums;
336
353
  }
337
354
  [data-hc-ds] .hc-ui-chip__chevron { display: inline-flex; flex: 0 0 auto; }
355
+ /* An icon or avatar at the start, a chevron or an inline badge at the end: less room on that side. */
356
+ [data-hc-ds] .hc-ui-chip:not([data-icon-only]):has(> .hc-ui-chip__icon:first-child) { padding-inline-start: var(--hc-chip-pad-icon); }
357
+ [data-hc-ds] .hc-ui-chip:not([data-icon-only]):has(> .hc-ui-chip__avatar:first-child) { padding-inline-start: var(--hc-chip-pad-avatar); }
358
+ [data-hc-ds] .hc-ui-chip:has(> :is(.hc-ui-chip__chevron, .hc-ui-chip__badge:not([data-placement='corner'])):last-child) { padding-inline-end: var(--hc-chip-pad-icon); }
359
+ /* Avatar: a round picture concentric with the pill's start (24px at 36px, 18px at 26px). */
360
+ [data-hc-ds] .hc-ui-chip__avatar {
361
+ display: inline-flex;
362
+ flex: 0 0 auto;
363
+ width: var(--hc-chip-avatar);
364
+ height: var(--hc-chip-avatar);
365
+ overflow: hidden;
366
+ border-radius: var(--hc-radius-full);
367
+ }
368
+ [data-hc-ds] .hc-ui-chip__avatar > :is(img, svg, .hc-ui-avatar) { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
338
369
  [data-hc-ds] .hc-ui-chip__chevron svg { display: block; }
339
370
  /* Applied filter, or the trigger of an open popup: a 1.5px ring (the selected fill below wins). */
340
371
  [data-hc-ds] .hc-ui-chip:is([data-applied], [aria-expanded='true']):not([aria-pressed='true'], [aria-checked='true'], [data-selected]) { box-shadow: inset 0 0 0 1.5px var(--hc-color-text-primary); }
341
372
  /* Line height `normal`, as HCUI's filter pills: on 2x screens 18px moves the text by half a pixel. */
342
- [data-hc-ds] .hc-ui-chip[data-size='sm'] { padding: 0 var(--hc-space-3); font-size: var(--hc-font-size-xs); line-height: normal; }
373
+ [data-hc-ds] .hc-ui-chip[data-size='sm'] { --hc-chip-pad: 14px; --hc-chip-pad-icon: 10px; font-size: var(--hc-font-size-xs); line-height: normal; }
343
374
  [data-hc-ds] .hc-ui-chip[data-size='xs'] {
344
375
  gap: var(--hc-space-1);
376
+ --hc-chip-pad: 10px;
377
+ --hc-chip-pad-icon: 7px;
378
+ --hc-chip-pad-avatar: 4px;
379
+ --hc-chip-avatar: 18px;
345
380
  min-height: 26px;
346
381
  height: 26px;
347
- padding: 0 var(--hc-space-2);
348
382
  background-color: var(--hc-color-bg-muted);
349
383
  box-shadow: none;
350
384
  font-size: var(--hc-font-size-2xs);
@@ -352,8 +386,9 @@
352
386
  [data-hc-ds] .hc-ui-chip[data-size='xs']:is([data-applied], [aria-expanded='true']):not([aria-pressed='true'], [aria-checked='true'], [data-selected]) { box-shadow: inset 0 0 0 1.5px var(--hc-color-text-primary); }
353
387
  /* Quiet: HCUI's rule filter pills, lighter until applied. */
354
388
  [data-hc-ds] .hc-ui-chip[data-variant='quiet'] {
389
+ --hc-chip-pad: 15px;
390
+ --hc-chip-pad-icon: 11px;
355
391
  gap: 5px;
356
- padding: 0 13px;
357
392
  color: var(--hc-color-text-secondary);
358
393
  box-shadow: inset 0 0 0 1px var(--hc-color-border);
359
394
  font-weight: 560;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ntmats/hc-ui",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "Shared HCUI/Arena React presentation primitives.",
6
6
  "license": "UNLICENSED",