@flytedan/flytebot-design-system 0.47.0 → 0.48.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flytedan/flytebot-design-system",
3
- "version": "0.47.0",
3
+ "version": "0.48.0",
4
4
  "description": "flytedesk Design System — shared component library, tokens, and business-logic kits for flytedesk apps.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -791,6 +791,13 @@
791
791
  border-radius: var(--r-lg);
792
792
  box-shadow: var(--e-1);
793
793
  overflow: hidden;
794
+ /* MP-271: column flex so a card stretched taller than its own content (CardGrid's
795
+ equal-height rows — a row's shorter cards stretch to match the tallest) still keeps its
796
+ footer pinned to the bottom rather than leaving a gap above it. flex-direction: column on
797
+ a `<div>`/`<a>`/`<button>` all behave identically, so this holds regardless of which
798
+ element Card renders as (see `interactive` in Card.tsx). */
799
+ display: flex;
800
+ flex-direction: column;
794
801
  }
795
802
  .fd-card-flat {
796
803
  box-shadow: none;
@@ -809,6 +816,49 @@
809
816
  border-color: var(--border-strong);
810
817
  transform: translateY(-1px);
811
818
  }
819
+ /* MP-271: a real interactive card (Card rendered as <a> or <button> — `href`/`onClick`).
820
+ Reset the native element's own look (button chrome, link underline/colour) so it reads as
821
+ the same card either way, then add hover/press states that only ever touch box-shadow and
822
+ border-color — never `transform` or a size-affecting property — so nothing jumps or
823
+ reflows on press (MP-271 AC). A `:focus-visible` rule of its own IS needed, restated after
824
+ `:hover`/`:active` below: without it, the global `button:focus-visible`/`a:focus-visible`
825
+ rule (styles/foundations.css, specificity 0,1,1) loses to `.fd-card-interactive:hover`
826
+ (0,2,0) whenever a card is both keyboard-focused and still under the pointer — a real,
827
+ reachable state (tab to a card, and the mouse that was already resting on it never moved)
828
+ — which would hide the focus ring entirely. Same fix Button.tsx's own `:focus-visible`
829
+ rule already uses for the identical reason (see components.css's own comment on
830
+ `.fd-btn-icon-solid:focus-visible`). */
831
+ .fd-card-interactive {
832
+ display: block;
833
+ width: 100%;
834
+ text-align: left;
835
+ color: inherit;
836
+ text-decoration: none;
837
+ font: inherit;
838
+ cursor: pointer;
839
+ transition: box-shadow var(--dur-base) var(--ease), border-color var(--dur-base) var(--ease);
840
+ }
841
+ .fd-card-interactive:hover {
842
+ box-shadow: var(--e-2);
843
+ border-color: var(--border-strong);
844
+ }
845
+ .fd-card-interactive:active {
846
+ box-shadow: var(--e-1);
847
+ border-color: var(--border-strong);
848
+ }
849
+ .fd-card-interactive:focus-visible {
850
+ box-shadow: var(--focus-ring);
851
+ }
852
+ /* MP-271: the draft/placeholder variant — dashed instead of solid, using the same
853
+ `--border-strong` token an emphatic-but-still-neutral border already uses elsewhere
854
+ (Card's own `:hover` above), so light, dark and `[data-contrast="high"]` (tokens/
855
+ appearance.css: high contrast promotes `--border` to `--border-strong` itself) all
856
+ resolve a correct, themed dash with no new colour token. */
857
+ .fd-card-draft {
858
+ border-style: dashed;
859
+ border-color: var(--border-strong);
860
+ box-shadow: none;
861
+ }
812
862
  /* The header degrades in two steps as the action slot needs more room than is left:
813
863
  first the title gives up ITS OWN spare width (ordinary flex-shrink) down to
814
864
  fd-card-head-title's min-width; once even that doesn't leave enough room for the
@@ -839,6 +889,9 @@
839
889
  }
840
890
  .fd-card-body {
841
891
  padding: 18px;
892
+ /* MP-271: lets the body absorb any extra height CardGrid's equal-height stretch adds,
893
+ keeping `fd-card-foot` pinned to the bottom instead of leaving a gap above it. */
894
+ flex: 1 1 auto;
842
895
  }
843
896
  .fd-card-foot {
844
897
  display: flex;
@@ -3360,6 +3413,23 @@
3360
3413
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 175px), 1fr));
3361
3414
  gap: 16px;
3362
3415
  }
3416
+ /* MP-271 — CardGrid (src/components/layout/CardGrid.tsx). `auto-fill` rather than
3417
+ `fd-grid-stats`'s own `auto-fit` above on purpose: a dashboard of Cards should keep a
3418
+ consistent card width as the count changes, not stretch a lone card to fill the whole row
3419
+ the way a handful of stat tiles usefully do. `--card-grid-min` is set inline per instance
3420
+ (CardGrid's `minCardWidth` prop, default 280px); `1fr` is what lets the last, partial row's
3421
+ cards still share the leftover width evenly rather than sitting at a fixed size with a gap
3422
+ down one side. Gap is deliberately NOT set here — CardGrid applies one of the existing
3423
+ `fd-gap-*` utility classes above alongside this one, so a "medium gap" stays one token
3424
+ shared with every other flex/grid consumer of the spacing scale, not a second grid-only
3425
+ value. Equal-height rows need no explicit rule: `align-items: stretch` is Grid's own
3426
+ default, restated below only so it can't silently regress if that default is ever
3427
+ overridden elsewhere for `.fd-card-grid`'s selector specifically. */
3428
+ .fd-card-grid {
3429
+ display: grid;
3430
+ grid-template-columns: repeat(auto-fill, minmax(var(--card-grid-min, 280px), 1fr));
3431
+ align-items: stretch;
3432
+ }
3363
3433
  @media (max-width: 640px) {
3364
3434
  .fd-grid-stats {
3365
3435
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));