@cosmicdrift/kumiko-renderer-web 0.229.0 → 0.230.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": "@cosmicdrift/kumiko-renderer-web",
3
- "version": "0.229.0",
3
+ "version": "0.230.0",
4
4
  "description": "Web-platform bindings for @cosmicdrift/kumiko-renderer. HTML default-primitives, browser history-based navigation, EventSource-backed live events, and a one-call createKumikoApp that mounts the whole stack via react-dom.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -16,9 +16,9 @@
16
16
  "./styles.css": "./src/styles.css"
17
17
  },
18
18
  "dependencies": {
19
- "@cosmicdrift/kumiko-dispatcher-live": "0.229.0",
20
- "@cosmicdrift/kumiko-headless": "0.229.0",
21
- "@cosmicdrift/kumiko-renderer": "0.229.0",
19
+ "@cosmicdrift/kumiko-dispatcher-live": "0.230.0",
20
+ "@cosmicdrift/kumiko-headless": "0.230.0",
21
+ "@cosmicdrift/kumiko-renderer": "0.230.0",
22
22
  "@radix-ui/react-dialog": "^1.1.15",
23
23
  "@radix-ui/react-dropdown-menu": "^2.1.16",
24
24
  "@radix-ui/react-label": "^2.1.8",
@@ -64,7 +64,7 @@
64
64
  "@types/react-dom": "^19.2.3",
65
65
  "jsdom": "^29.1.1",
66
66
  "tailwindcss": "^4.3.0",
67
- "@cosmicdrift/kumiko-locale-de": "0.229.0"
67
+ "@cosmicdrift/kumiko-locale-de": "0.230.0"
68
68
  },
69
69
  "repository": {
70
70
  "type": "git",
@@ -1203,8 +1203,9 @@ describe("Form", () => {
1203
1203
  );
1204
1204
  const actionsFooter = screen.getByTestId("form-actions");
1205
1205
  expect(actionsFooter.className).toContain("max-sm:fixed");
1206
+ expect(actionsFooter.className).toContain("flex-wrap");
1206
1207
  const contentContainer = actionsFooter.previousElementSibling as HTMLElement;
1207
- expect(contentContainer.className).toContain("max-sm:pb-24");
1208
+ expect(contentContainer.className).toContain("max-sm:pb-32");
1208
1209
  });
1209
1210
 
1210
1211
  test("ohne stickyActions: Footer bleibt im normalen Dokumentfluss", () => {
@@ -1215,8 +1216,12 @@ describe("Form", () => {
1215
1216
  );
1216
1217
  const actionsFooter = screen.getByTestId("form-actions");
1217
1218
  expect(actionsFooter.className).not.toContain("max-sm:fixed");
1219
+ // Shared cardFooter constant — this asserts the wrap fix (fw#2528) on the
1220
+ // plain (non-sticky) footer, which also covers Section/Card since they
1221
+ // render the same constant.
1222
+ expect(actionsFooter.className).toContain("flex-wrap");
1218
1223
  const contentContainer = actionsFooter.previousElementSibling as HTMLElement;
1219
- expect(contentContainer.className).not.toContain("max-sm:pb-24");
1224
+ expect(contentContainer.className).not.toContain("max-sm:pb-32");
1220
1225
  });
1221
1226
  });
1222
1227
 
@@ -1,8 +1,15 @@
1
1
  // Shared `fill`-prop wiring for the sidebar-based app shells
2
2
  // (DefaultAppShell, WorkspaceShell) — both wrap the same vendored
3
3
  // shadcn sidebar and need identical viewport-fit classes.
4
+ //
5
+ // min-w-0 on the inset is unconditional (not fill-gated): vendored
6
+ // SidebarInset is `flex-1` with no min-width override, so a flex row child
7
+ // never shrinks below its content's intrinsic width by default. Wide screen
8
+ // content (e.g. a table with many columns) then grows the inset — and with
9
+ // it the whole sidebar row and the page — past the viewport instead of
10
+ // scrolling inside the inset's own `main` (which already has overflow-auto).
4
11
  export const fillClasses = (fill?: boolean) => ({
5
12
  provider: fill === true ? { className: "h-svh" } : {},
6
- inset: fill === true ? "min-h-0" : undefined,
13
+ inset: fill === true ? "min-h-0 min-w-0" : "min-w-0",
7
14
  main: fill === true ? "min-h-0 flex-1 overflow-auto" : "flex-1 overflow-auto",
8
15
  });
@@ -127,7 +127,8 @@ const cardSurface = cva(
127
127
  defaultVariants: { radius: "xl" },
128
128
  },
129
129
  );
130
- const cardFooter = "flex items-center justify-end gap-2 px-[var(--card-padding)] py-4";
130
+ // Wraps instead of running off-screen when the row outgrows its container (fw#2528).
131
+ const cardFooter = "flex flex-wrap items-center justify-end gap-2 px-[var(--card-padding)] py-4";
131
132
  const cardFooterBorder = "border-t bg-muted/30";
132
133
 
133
134
  // ---- Button (vendored shadcn ui/button) ----
@@ -717,11 +718,14 @@ function DefaultDataTable({
717
718
  {hasTableActions && (
718
719
  <TableHead
719
720
  data-testid="column-actions"
720
- // sticky right-0 + bg-muted (= header tone) so the action
721
- // column stays at the right edge during horizontal scroll.
722
- // No border-l: a permanent divider looks heavy; the sticky
723
- // bg already sets the column apart during scroll anyway.
724
- className="sticky right-0 z-10 w-px bg-muted text-right text-muted-foreground"
721
+ // From md: sticky right-0 + bg-muted (= header tone) so the
722
+ // action column stays at the right edge during horizontal
723
+ // scroll on wider screens. Below md, actions scroll in
724
+ // normal flow sticky there would pin the column over the
725
+ // preceding data column instead of the (already narrow)
726
+ // page edge. No border-l: a permanent divider looks heavy;
727
+ // the sticky bg already sets the column apart during scroll.
728
+ className="w-px text-right text-muted-foreground md:sticky md:right-0 md:z-10 md:bg-muted"
725
729
  aria-label="Actions"
726
730
  />
727
731
  )}
@@ -766,10 +770,13 @@ function DefaultDataTable({
766
770
  {hasTableActions && (
767
771
  <TableCell
768
772
  data-testid={getCellTestId?.(row, "actions") ?? `cell-${row.id}-actions`}
769
- // Sticky-right so the actions stay visible on the right
770
- // edge during horizontal scroll. bg-background sets the
771
- // column apart during scroll no border-l (divider too heavy).
772
- className="sticky right-0 z-10 bg-background text-right"
773
+ // From md: sticky-right so the actions stay visible on the
774
+ // right edge during horizontal scroll. Below md, actions
775
+ // scroll with the row like any other cell sticky there
776
+ // would hide the neighboring data column on narrow
777
+ // viewports. bg-background sets the column apart during
778
+ // scroll — no border-l (divider too heavy).
779
+ className="text-right md:sticky md:right-0 md:z-10 md:bg-background"
773
780
  // Action-cell events must not trigger the row click/activation
774
781
  // (typically "Open Detail" — the user wanted the action,
775
782
  // not navigation). We stopPropagation for mouse and
@@ -1699,9 +1706,10 @@ function DefaultForm({
1699
1706
  "[&>section:not(:first-child)]:border-t",
1700
1707
  "[&>:not(section)]:px-6 [&>:not(section)]:py-3",
1701
1708
  "[&>:not(section):first-child]:pt-6 [&>:not(section):last-child]:pb-6",
1702
- // ponytail: fixed footer height is a guess (button row + safe-area) —
1703
- // widen if a wizard step's last field ever renders visibly clipped.
1704
- stickyActions === true && "max-sm:pb-24",
1709
+ // ponytail: fixed footer height is a guess (two wrapped button rows +
1710
+ // safe-area, fw#2528) — widen further if a wizard step's last field
1711
+ // ever renders visibly clipped under three or more wrapped rows.
1712
+ stickyActions === true && "max-sm:pb-32",
1705
1713
  )}
1706
1714
  >
1707
1715
  <InsideFormContext.Provider value={true}>{children}</InsideFormContext.Provider>
@@ -13,7 +13,7 @@ import { DrawerSheetContent } from "./sheet-parts";
13
13
  // equivalent classes are inlined here rather than growing the vendored
14
14
  // SheetFooter's own default className with panel-specific styling.
15
15
  const DRAWER_FOOTER_CLASS =
16
- "flex-row items-center justify-end border-t bg-background px-[var(--card-padding)] py-4";
16
+ "flex-row flex-wrap items-center justify-end border-t bg-background px-[var(--card-padding)] py-4";
17
17
 
18
18
  export type DrawerProps = {
19
19
  readonly open: boolean;