@hraness/design-kit 0.35.2 → 0.35.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hraness/design-kit",
3
- "version": "0.35.2",
3
+ "version": "0.35.3",
4
4
  "description": "React components and CSS for Hraness apps and product sites: application shells, marketing sections, charts, themes, effects, and syntax highlighting. Built on @hraness/ui.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,7 +6,7 @@
6
6
  "name": "@hraness/design-kit",
7
7
  "path": ".",
8
8
  "visibility": "public",
9
- "version": "0.35.2"
9
+ "version": "0.35.3"
10
10
  }
11
11
  ],
12
12
  "contract": "hraness.portfolio-inventory/v1",
@@ -229,73 +229,84 @@ export function ModeShowcase<S extends string, M extends string, O extends strin
229
229
  return (
230
230
  <figure
231
231
  aria-label={label?.(surface) ?? `Illustration of ${surface.label.toLowerCase()}`}
232
- className={joinMockupClasses("hkm-showcase", className)}
232
+ className={joinMockupClasses("hkm-showcase", "hkm-modes", className)}
233
233
  data-hkm-theme={theme}
234
234
  data-nosnippet=""
235
235
  >
236
- <div className="hkm-showcase-controls">
237
- {surfaces.length > 1 ? (
238
- <div aria-label="Surface" className="hkm-tabs" role="tablist">
239
- {surfaces.map((entry) => (
240
- <button
241
- aria-controls={`${id}-panel`}
242
- aria-selected={entry.id === surface.id}
243
- className="hkm-tab"
244
- id={`${id}-tab-${entry.id}`}
245
- key={entry.id}
246
- onClick={() => setSurfaceId(entry.id)}
247
- onKeyDown={onTabKey}
248
- ref={(element) => {
249
- if (element === null) tabs.current.delete(entry.id);
250
- else tabs.current.set(entry.id, element);
251
- }}
252
- role="tab"
253
- tabIndex={entry.id === surface.id ? 0 : -1}
254
- type="button"
255
- >
256
- {entry.label}
257
- </button>
258
- ))}
259
- </div>
260
- ) : null}
261
- <div className="hkm-showcase-settings">
262
- <div className="hkm-showcase-row">
263
- <span className="hkm-showcase-label" id={`${id}-mode`}>{modeLabel}</span>
264
- <div aria-labelledby={`${id}-mode`} className="hkm-segmented" role="group">
265
- {modes.map((entry) => (
266
- <button aria-pressed={entry.id === mode} key={entry.id} onClick={() => chooseMode(entry.id)} type="button">
267
- {entry.label}
268
- </button>
269
- ))}
270
- </div>
271
- </div>
272
- {options === undefined ? null : (
273
- <div className="hkm-showcase-row">
274
- <span className="hkm-showcase-label" id={`${id}-option`}>{optionLabel}</span>
275
- <div aria-labelledby={`${id}-option`} className="hkm-segmented" role="group">
276
- {options.map((entry) => (
277
- <button aria-pressed={entry.id === option} disabled={optionInactive} key={entry.id} onClick={() => chooseOption(entry.id)} type="button">
278
- {entry.label}
279
- </button>
280
- ))}
281
- </div>
282
- </div>
283
- )}
236
+ {surfaces.length > 1 ? (
237
+ <div aria-label="Surface" className="hkm-tabs hkm-folder-tabs" role="tablist">
238
+ {surfaces.map((entry) => (
239
+ <button
240
+ aria-controls={`${id}-panel`}
241
+ aria-selected={entry.id === surface.id}
242
+ className="hkm-tab"
243
+ id={`${id}-tab-${entry.id}`}
244
+ key={entry.id}
245
+ onClick={() => setSurfaceId(entry.id)}
246
+ onKeyDown={onTabKey}
247
+ ref={(element) => {
248
+ if (element === null) tabs.current.delete(entry.id);
249
+ else tabs.current.set(entry.id, element);
250
+ }}
251
+ role="tab"
252
+ tabIndex={entry.id === surface.id ? 0 : -1}
253
+ type="button"
254
+ >
255
+ {entry.label}
256
+ </button>
257
+ ))}
284
258
  </div>
285
- {hint === "" ? null : <p className="hkm-showcase-hint">{hint}</p>}
286
- </div>
259
+ ) : null}
287
260
  <div
288
261
  aria-labelledby={surfaces.length > 1 ? `${id}-tab-${surface.id}` : undefined}
289
- className="hkm-showcase-stage"
290
- data-hkm-animated={animated ? "" : undefined}
291
- data-hkm-from={animated ? previousMode : undefined}
262
+ className="hkm-showcase-stage hkm-mode-panel"
292
263
  id={`${id}-panel`}
293
264
  role={surfaces.length > 1 ? "tabpanel" : undefined}
294
265
  style={{ "--hkm-page-height": `${height}px` } as CSSProperties}
295
266
  >
296
- <FitToWidth minWidth={minWidth}>
297
- {surface.render({ animated, mode, option, previousMode, theme })}
298
- </FitToWidth>
267
+ <div className="hkm-showcase-controls">
268
+ <div className="hkm-showcase-settings">
269
+ <div className="hkm-showcase-row">
270
+ <span className="hkm-showcase-label" id={`${id}-mode`}>{modeLabel}</span>
271
+ <div aria-labelledby={`${id}-mode`} className="hkm-segmented" role="group">
272
+ {modes.map((entry) => (
273
+ <button aria-pressed={entry.id === mode} key={entry.id} onClick={() => chooseMode(entry.id)} type="button">
274
+ {entry.label}
275
+ </button>
276
+ ))}
277
+ </div>
278
+ </div>
279
+ {options === undefined ? null : (
280
+ <div className="hkm-showcase-row">
281
+ <span className="hkm-showcase-label" id={`${id}-option`}>{optionLabel}</span>
282
+ <div aria-labelledby={`${id}-option`} className="hkm-segmented" role="group">
283
+ {options.map((entry) => (
284
+ <button aria-pressed={entry.id === option} disabled={optionInactive} key={entry.id} onClick={() => chooseOption(entry.id)} type="button">
285
+ {entry.label}
286
+ </button>
287
+ ))}
288
+ </div>
289
+ </div>
290
+ )}
291
+ </div>
292
+ {hint === "" ? null : <p className="hkm-showcase-hint">{hint}</p>}
293
+ </div>
294
+ <div className="hkm-mode-stage">
295
+ {surfaces.map((entry) => (
296
+ <div
297
+ aria-hidden={entry.id !== surface.id}
298
+ className="hkm-mode-surface"
299
+ data-hkm-animated={entry.id === surface.id && animated ? "" : undefined}
300
+ data-hkm-from={entry.id === surface.id && animated ? previousMode : undefined}
301
+ inert={entry.id !== surface.id}
302
+ key={entry.id}
303
+ >
304
+ <FitToWidth minWidth={minWidth}>
305
+ {entry.render({ animated: entry.id === surface.id && animated, mode, option, previousMode, theme })}
306
+ </FitToWidth>
307
+ </div>
308
+ ))}
309
+ </div>
299
310
  </div>
300
311
  {!hasStatus && captionText === undefined ? null : (
301
312
  <figcaption className="hkm-showcase-caption">
@@ -367,7 +378,7 @@ export function StepThrough({
367
378
  return (
368
379
  <figure aria-label={`Illustration: ${label.toLowerCase()}`} className={joinMockupClasses("hkm-showcase", "hkm-steps", className)} data-hkm-theme={theme} data-nosnippet="">
369
380
  <div className="hkm-showcase-controls">
370
- <div aria-label={label} className="hkm-tabs hkm-step-tabs" role="tablist">
381
+ <div aria-label={label} className="hkm-tabs hkm-folder-tabs hkm-step-tabs" role="tablist">
371
382
  {steps.map((entry, position) => (
372
383
  <button
373
384
  aria-controls={`${id}-panel-${entry.id}`}
package/src/mockups.css CHANGED
@@ -2503,14 +2503,22 @@
2503
2503
  }
2504
2504
  }
2505
2505
 
2506
- /* Folder tabs share an edge with the stable-height walkthrough stage. */
2507
- .hkm-showcase.hkm-steps { gap: 0; }
2506
+ /* Folder tabs share an edge with each showcase panel. */
2507
+ .hkm-showcase:is(.hkm-steps, .hkm-modes) { gap: 0; }
2508
2508
  .hkm-showcase.hkm-steps .hkm-showcase-controls { padding: 0; border: 0; border-radius: 0; background: transparent; }
2509
- .hkm-showcase.hkm-steps .hkm-step-tabs { gap: 6px; margin: 0; padding: 0; border: 0; position: relative; z-index: 1; }
2510
- .hkm-showcase.hkm-steps .hkm-tab { min-block-size: 48px; padding: 12px 18px; border: 1px solid var(--hkm-sc-line); border-block-end: 0; border-radius: 12px 12px 0 0; background: var(--hkm-sc-field); color: var(--hkm-sc-muted); }
2511
- .hkm-showcase.hkm-steps .hkm-tab[aria-selected="true"] { background: var(--hkm-sc-bg); color: var(--hkm-sc-fg); }
2512
- .hkm-showcase.hkm-steps .hkm-tab:hover { color: var(--hkm-sc-fg); }
2509
+ .hkm-showcase .hkm-folder-tabs { gap: 6px; margin: 0; padding: 0; border: 0; position: relative; z-index: 1; }
2510
+ .hkm-showcase .hkm-folder-tabs .hkm-tab { min-block-size: 48px; padding: 12px 18px; border: 1px solid var(--hkm-sc-line); border-block-end: 0; border-radius: 12px 12px 0 0; background: var(--hkm-sc-field); color: var(--hkm-sc-muted); }
2511
+ .hkm-showcase .hkm-folder-tabs .hkm-tab[aria-selected="true"] { background: var(--hkm-sc-bg); color: var(--hkm-sc-fg); }
2512
+ .hkm-showcase .hkm-folder-tabs .hkm-tab:hover { color: var(--hkm-sc-fg); }
2513
2513
  .hkm-showcase.hkm-steps .hkm-step-stage { display: grid; border: 1px solid var(--hkm-sc-line); border-radius: 0 12px 12px 12px; background: var(--hkm-sc-bg); margin-block-start: -1px; overflow: clip; }
2514
+ .hkm-showcase.hkm-modes .hkm-mode-panel { border: 1px solid var(--hkm-sc-line); border-radius: 12px; background: var(--hkm-sc-bg); overflow: clip; }
2515
+ .hkm-showcase.hkm-modes .hkm-folder-tabs + .hkm-mode-panel { border-start-start-radius: 0; margin-block-start: -1px; }
2516
+ .hkm-showcase.hkm-modes .hkm-showcase-controls { border: 0; border-block-end: 1px solid var(--hkm-sc-line); border-radius: 0; }
2517
+ .hkm-mode-stage { display: grid; min-inline-size: 0; }
2518
+ .hkm-mode-surface { grid-area: 1 / 1; min-inline-size: 0; align-self: start; }
2519
+ .hkm-mode-surface[aria-hidden="true"] { visibility: hidden; pointer-events: none; }
2520
+ .hkm-showcase.hkm-modes .hkm-mode-surface > .hkm-fit > .hkm-fit-inner > .hkm-root,
2521
+ .hkm-showcase.hkm-modes .hkm-mode-surface > .hkm-fit > .hkm-fit-inner > .hkm-root > .hkm-window { border: 0; border-radius: 0; box-shadow: none; }
2514
2522
  .hkm-step-panel { grid-area: 1 / 1; min-inline-size: 0; align-self: start; }
2515
2523
  .hkm-step-panel[aria-hidden="true"] { visibility: hidden; pointer-events: none; }
2516
2524
  .hkm-showcase.hkm-steps .hkm-step-panel .hkm-root { border-start-start-radius: 0; border-start-end-radius: 0; box-shadow: none; }
@@ -2520,7 +2528,7 @@
2520
2528
  .hkm-showcase.hkm-steps .hkm-step-button:disabled { color: var(--hkm-sc-muted); background: transparent; }
2521
2529
  .hkm-showcase.hkm-steps .hkm-step-button[data-hkm-primary]:disabled { background: var(--hkm-sc-field); }
2522
2530
  .hkm-showcase.hkm-steps .hkm-step-announcement { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
2523
- .hkm-showcase.hkm-steps .hkm-showcase-caption { margin-block-start: 1rem; }
2531
+ .hkm-showcase:is(.hkm-steps, .hkm-modes) .hkm-showcase-caption { margin-block-start: 1rem; }
2524
2532
 
2525
2533
  /* ---------------------------------------------------------------- */
2526
2534
  /* Motion */