@mario_hahn/jumpy-ui 0.14.2 → 0.15.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/README.md CHANGED
@@ -162,7 +162,15 @@ behind the decorative cell surfaces. The default resolves to the opaque semantic
162
162
  card surface in each preset. Normal cell decorations are transparent; selected
163
163
  and hovered cells use their semantic interaction surfaces. The scroll container
164
164
  and pinned cells share the same backdrop. Keep any custom backdrop override opaque.
165
- Use `showHorizontalBorders` for explicit row separators in all columns.
165
+ Use `showHorizontalBorders` for explicit row separators in all columns. Separators lie
166
+ between rows: the last body row has none, unless a `JumpTableFooter` follows (the footer
167
+ draws its own top border).
168
+
169
+ `surface="card"` (default) paints the backdrop box described above, right inside a
170
+ `JumpCard`. On a plain page use `<JumpTable surface="none">`: no card box, square corners
171
+ or inset rows. Sticky headers and pinned cells still need an opaque backdrop, so it falls
172
+ back to the page canvas (`--jumpy-color-surface-canvas`); if the page uses another
173
+ background, set `--jumpy-cmp-table-backdrop-color` to it.
166
174
 
167
175
  `JumpTableCell` and `JumpTableHeaderCell` support `pinned="left"` or `pinned="right"`;
168
176
  use `pinnedEdge` for the edge divider. Pinned cells use the same backdrop as the
@@ -18,7 +18,7 @@ import {
18
18
  textStyleValue,
19
19
  themeToCSSVariables,
20
20
  useJumpyTheme
21
- } from "./chunk-2XOYK2JS.js";
21
+ } from "./chunk-YAOAIT3N.js";
22
22
  import {
23
23
  cn
24
24
  } from "./chunk-3DBKYKP2.js";
@@ -1696,10 +1696,10 @@ function JumpSnackbarProvider({ children, position = "bottom-center", maxSnackba
1696
1696
  /* @__PURE__ */ jsx("div", { ...props, "data-jumpy-component": "snackbar-provider", className: cn(className), style: { position: "fixed", zIndex: 1100, left: position.endsWith("start") ? horizontalOffset : position.endsWith("end") ? "auto" : "50%", right: position.endsWith("end") ? horizontalOffset : "auto", top: top ? verticalOffset : "auto", bottom: top ? "auto" : verticalOffset, transform: position.endsWith("center") ? "translateX(-50%)" : void 0, display: "flex", flexDirection: "column", alignItems: align, gap: spacingValue(theme, JumpySpacing.smallXS), width: "min(487px, calc(100vw - 32px))", maxWidth: "50vw", pointerEvents: "none", ...props.style || {} }, children: snackbars.map((snackbar) => snackbar.isData ? /* @__PURE__ */ jsx(JumpBanner, { floating: true, status: snackbar.content.status || "info", title: snackbar.content.title, actions: snackbar.content.slots?.actions, style: { width: "100%", pointerEvents: "auto", boxShadow: theme.shadow.positiveLarge }, children: snackbar.content.description }, snackbar.id) : /* @__PURE__ */ jsx("div", { "data-jumpy-component": "snackbar", style: { width: "100%", pointerEvents: "auto", borderRadius: radiusValue(theme, JumpyRadius.small), boxShadow: theme.shadow.positiveLarge }, children: snackbar.content }, snackbar.id)) })
1697
1697
  ] });
1698
1698
  }
1699
- function JumpTable({ children, showHorizontalBorders = false, disabled = false, stickyHeader = false, density = "regular", containerProps, innerClasses = {}, className = "", ...props }) {
1699
+ function JumpTable({ children, showHorizontalBorders = false, disabled = false, stickyHeader = false, density = "regular", surface = "card", containerProps, innerClasses = {}, className = "", ...props }) {
1700
1700
  const { className: containerClassName, style: containerStyle, ...restContainerProps } = containerProps || {};
1701
1701
  const contextValue = { showHorizontalBorders, disabled };
1702
- return /* @__PURE__ */ jsx(JumpyTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { "data-jumpy-slot": "table-wrapper", className: innerClasses.wrapper?.className, style: innerClasses.wrapper?.style, children: /* @__PURE__ */ jsx("div", { ...restContainerProps, "data-jumpy-slot": "table-container", "data-sticky-header": stickyHeader ? "true" : "false", className: cn(containerClassName), style: containerStyle, children: /* @__PURE__ */ jsx("table", { ...props, "data-jumpy-component": "table", "data-horizontal-borders": showHorizontalBorders ? "true" : "false", "data-density": density === "condensed" ? "condensed" : void 0, "data-disabled": disabled ? "true" : void 0, role: props.role || "grid", className: cn(className), children }) }) }) });
1702
+ return /* @__PURE__ */ jsx(JumpyTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { "data-jumpy-slot": "table-wrapper", "data-surface": surface === "none" ? "none" : void 0, className: innerClasses.wrapper?.className, style: innerClasses.wrapper?.style, children: /* @__PURE__ */ jsx("div", { ...restContainerProps, "data-jumpy-slot": "table-container", "data-sticky-header": stickyHeader ? "true" : "false", className: cn(containerClassName), style: containerStyle, children: /* @__PURE__ */ jsx("table", { ...props, "data-jumpy-component": "table", "data-horizontal-borders": showHorizontalBorders ? "true" : "false", "data-density": density === "condensed" ? "condensed" : void 0, "data-disabled": disabled ? "true" : void 0, role: props.role || "grid", className: cn(className), children }) }) }) });
1703
1703
  }
1704
1704
  function JumpTableHead({ as, children, className = "", ...props }) {
1705
1705
  const Component = as || "thead";
@@ -2401,7 +2401,8 @@ ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='compact'] { display
2401
2401
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: none; }
2402
2402
  ${shell} [data-jumpy-slot='app-shell-back'][data-variant='inline'] { display: none; }
2403
2403
  @media (min-width: ${breakpoint}px) {
2404
- ${shell} { grid-template-columns: ${width} minmax(0, 1fr); }
2404
+ ${shell} { grid-template-columns: ${width} minmax(0, 1fr); }${topBarOnDesktop ? "" : `
2405
+ ${shell} { --jumpy-app-shell-large-title-padding-top: ${spacingValue(theme, JumpySpacing.large2XL)}px; }`}
2405
2406
  ${shell} > [data-jumpy-slot='app-shell-sidebar'] { display: flex; }
2406
2407
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='compact'] { display: none; }
2407
2408
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: inline-flex; }
@@ -2476,7 +2477,7 @@ ${shell} [data-jumpy-slot='app-shell-back'][data-variant='inline'] { display: no
2476
2477
  /* @__PURE__ */ jsxs("div", { "data-jumpy-slot": "app-shell-body", style: { display: "flex", flexDirection: "column", minWidth: 0, minHeight: "100dvh" }, children: [
2477
2478
  topBar !== null ? topBarNode : null,
2478
2479
  /* @__PURE__ */ jsxs("main", { "data-jumpy-slot": "app-shell-content", style: { flex: 1, minWidth: 0 }, children: [
2479
- showLargeTitle ? /* @__PURE__ */ jsx("div", { "data-jumpy-slot": "app-shell-large-title", style: { padding: `${spacingValue(theme, JumpySpacing.smallXS)}px calc(var(--jumpy-app-shell-gutter, ${spacingValue(theme, JumpySpacing.large)}px) + env(safe-area-inset-right, 0px)) 0 calc(var(--jumpy-app-shell-gutter, ${spacingValue(theme, JumpySpacing.large)}px) + env(safe-area-inset-left, 0px))` }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: spacingValue(theme, JumpySpacing.large), flexWrap: "wrap" }, children: [
2480
+ showLargeTitle ? /* @__PURE__ */ jsx("div", { "data-jumpy-slot": "app-shell-large-title", style: { padding: `var(--jumpy-app-shell-large-title-padding-top, ${spacingValue(theme, JumpySpacing.smallXS)}px) calc(var(--jumpy-app-shell-gutter, ${spacingValue(theme, JumpySpacing.large)}px) + env(safe-area-inset-right, 0px)) 0 calc(var(--jumpy-app-shell-gutter, ${spacingValue(theme, JumpySpacing.large)}px) + env(safe-area-inset-left, 0px))` }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: spacingValue(theme, JumpySpacing.large), flexWrap: "wrap" }, children: [
2480
2481
  /* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
2481
2482
  hasBack ? /* @__PURE__ */ jsx(JumpyAppShellBack, { back, variant: "inline", ariaLabels }) : null,
2482
2483
  /* @__PURE__ */ jsx("h1", { ref: largeTitleRef, style: { margin: 0, ...textStyleValue(theme, JumpyTextStyle.displaySmallEmphasized), overflowWrap: "anywhere" }, children: topBarProps.title }),
@@ -3803,11 +3804,18 @@ function JumpLinkButton({ href, variant = "borderless", status = "regular", clas
3803
3804
  }
3804
3805
  );
3805
3806
  }
3807
+ function nativeColorScheme(theme) {
3808
+ const match = /^#([0-9a-f]{6})/i.exec(String(theme.color?.surfaceField || ""));
3809
+ if (!match) return void 0;
3810
+ const [r, g, b] = [0, 2, 4].map((index) => parseInt(match[1].slice(index, index + 2), 16) / 255);
3811
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b < 0.4 ? "dark" : "light";
3812
+ }
3806
3813
  var JumpInput = forwardRef(function JumpInput2({ className = "", ...props }, ref) {
3807
3814
  const theme = useJumpyTheme();
3808
3815
  const fieldContext = useContext(JumpyFieldContext);
3809
3816
  const inputOffset = fieldContext?.hasLabel ? spacingValue(theme, JumpySpacing.large) : spacingValue(theme, JumpySpacing.zero);
3810
3817
  const inputMinHeight = fieldContext ? void 0 : sizeValue(theme, JumpySize.largeXL) - spacingValue(theme, JumpySpacing.small3XS) * 2;
3818
+ const spinShift = props.type === "number" && inputOffset ? Math.max(0, (inputOffset - spacingValue(theme, JumpySpacing.small3XS) / 2) / 2) : 0;
3811
3819
  const inputElement = /* @__PURE__ */ jsx(
3812
3820
  "input",
3813
3821
  {
@@ -3818,7 +3826,9 @@ var JumpInput = forwardRef(function JumpInput2({ className = "", ...props }, ref
3818
3826
  style: {
3819
3827
  ...getFieldInputStyles(theme, props.disabled),
3820
3828
  minHeight: inputMinHeight,
3821
- marginTop: inputOffset,
3829
+ marginTop: inputOffset - spinShift,
3830
+ ...spinShift ? { paddingTop: spinShift, "--jumpy-input-spin-shift": `${-spinShift}px` } : {},
3831
+ colorScheme: props.type === "number" ? nativeColorScheme(theme) : void 0,
3822
3832
  ...props.style || {}
3823
3833
  }
3824
3834
  }
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  JumpField,
3
3
  JumpyFieldContext
4
- } from "./chunk-SXBPGNRO.js";
4
+ } from "./chunk-K4DXYTVW.js";
5
5
  import {
6
6
  JumpySpacing,
7
7
  spacingValue,
8
8
  useJumpyTheme
9
- } from "./chunk-2XOYK2JS.js";
9
+ } from "./chunk-YAOAIT3N.js";
10
10
 
11
11
  // editor.js
12
12
  import { useContext, useRef as useRef2, useState as useState2 } from "react";
@@ -14496,6 +14496,10 @@ var providerStyles = `
14496
14496
  color: var(--jumpy-cmp-base-input-value-color);
14497
14497
  }
14498
14498
 
14499
+ [data-jumpy-theme='true'] [data-jumpy-component='input'][type='number']::-webkit-inner-spin-button {
14500
+ transform: translateY(var(--jumpy-input-spin-shift, 0px));
14501
+ }
14502
+
14499
14503
  [data-jumpy-theme='true'] [data-jumpy-component='input'][type='search']::-webkit-search-cancel-button {
14500
14504
  -webkit-appearance: none;
14501
14505
  appearance: none;
@@ -14699,6 +14703,15 @@ var providerStyles = `
14699
14703
  width: 100%;
14700
14704
  }
14701
14705
 
14706
+ /* surface="none": no card box. Sticky headers and pinned cells still need an opaque backdrop, so it falls back to the page canvas. */
14707
+ [data-jumpy-theme='true'] [data-jumpy-slot='table-wrapper'][data-surface='none'] {
14708
+ --jumpy-cmp-table-backdrop-color: var(--jumpy-color-surface-canvas);
14709
+ }
14710
+
14711
+ [data-jumpy-theme='true'] [data-jumpy-slot='table-wrapper'][data-surface='none'] > [data-jumpy-slot='table-container'] {
14712
+ background-color: transparent;
14713
+ }
14714
+
14702
14715
  [data-jumpy-theme='true'] [data-jumpy-slot='table-container'] {
14703
14716
  display: block;
14704
14717
  position: relative;
@@ -14844,6 +14857,11 @@ var providerStyles = `
14844
14857
  display: none;
14845
14858
  }
14846
14859
 
14860
+ /* Row separators lie between rows: the last body row has none unless a footer follows (it draws its own top border). */
14861
+ [data-jumpy-theme='true'] [data-jumpy-component='table'] > [data-jumpy-component='table-body']:last-child > [data-jumpy-component='table-row']:last-child > [data-jumpy-component='table-cell']::before {
14862
+ display: none;
14863
+ }
14864
+
14847
14865
  [data-jumpy-theme='true'] [data-jumpy-component='table-cell']:first-child::before,
14848
14866
  [data-jumpy-theme='true'] [data-jumpy-component='table-header-cell']:first-child::before {
14849
14867
  inset-inline-start: var(--jumpy-spacing-size-4xsmall);
@@ -74,7 +74,7 @@ import {
74
74
  getSortOrder,
75
75
  isRowFullySelected,
76
76
  useJumpSnackbar
77
- } from "./chunk-SXBPGNRO.js";
77
+ } from "./chunk-K4DXYTVW.js";
78
78
  import {
79
79
  JumpyAnimation,
80
80
  JumpyAnimationDelay,
@@ -105,7 +105,7 @@ import {
105
105
  textStyleValue,
106
106
  themeToCSSVariables,
107
107
  useJumpyTheme
108
- } from "./chunk-2XOYK2JS.js";
108
+ } from "./chunk-YAOAIT3N.js";
109
109
  import "./chunk-3DBKYKP2.js";
110
110
  import {
111
111
  jumpyThemeInventory
package/dist/editor.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import {
3
3
  JumpTokenInput
4
- } from "./chunk-NPUCW4NM.js";
5
- import "./chunk-SXBPGNRO.js";
6
- import "./chunk-2XOYK2JS.js";
4
+ } from "./chunk-NK6N6UY5.js";
5
+ import "./chunk-K4DXYTVW.js";
6
+ import "./chunk-YAOAIT3N.js";
7
7
  import "./chunk-3DBKYKP2.js";
8
8
  import "./chunk-XDTVYUWG.js";
9
9
  export {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  JumpTokenInput
4
- } from "./chunk-NPUCW4NM.js";
4
+ } from "./chunk-NK6N6UY5.js";
5
5
  import {
6
6
  BrandMark,
7
7
  JumpAppShell,
@@ -77,7 +77,7 @@ import {
77
77
  getSortOrder,
78
78
  isRowFullySelected,
79
79
  useJumpSnackbar
80
- } from "./chunk-SXBPGNRO.js";
80
+ } from "./chunk-K4DXYTVW.js";
81
81
  import {
82
82
  JumpyAnimation,
83
83
  JumpyAnimationDelay,
@@ -108,7 +108,7 @@ import {
108
108
  textStyleValue,
109
109
  themeToCSSVariables,
110
110
  useJumpyTheme
111
- } from "./chunk-2XOYK2JS.js";
111
+ } from "./chunk-YAOAIT3N.js";
112
112
  import "./chunk-3DBKYKP2.js";
113
113
  import {
114
114
  jumpyThemeInventory
package/dist/theme.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  textStyleValue,
31
31
  themeToCSSVariables,
32
32
  useJumpyTheme
33
- } from "./chunk-2XOYK2JS.js";
33
+ } from "./chunk-YAOAIT3N.js";
34
34
  export {
35
35
  JumpyAnimation,
36
36
  JumpyAnimationDelay,
package/index.d.ts CHANGED
@@ -104,7 +104,7 @@ export declare function getRowCheckboxProps(row: JumpSelectableRow, disabled?: b
104
104
  export declare function getHeaderCheckboxProps(table: JumpSelectableTable, disabled?: boolean): JumpSelectionCheckboxProps
105
105
  export type JumpTableInnerClasses = { wrapper?: { className?: string; style?: import('react').CSSProperties } }
106
106
  export type JumpTableCellInnerClasses = Partial<Record<'inner' | 'leading' | 'content' | 'text' | 'description' | 'trailing' | 'label' | 'labelText' | 'sortButton' | 'sortIndicator', { className?: string; style?: import('react').CSSProperties }>>
107
- export declare function JumpTable(props: HTMLAttributes<HTMLTableElement> & { ref?: Ref<HTMLTableElement>; showHorizontalBorders?: boolean; disabled?: boolean; stickyHeader?: boolean; density?: 'default' | 'regular' | 'condensed'; containerProps?: HTMLAttributes<HTMLDivElement> & { ref?: Ref<HTMLDivElement> }; innerClasses?: JumpTableInnerClasses; children?: ReactNode }): ReactNode
107
+ export declare function JumpTable(props: HTMLAttributes<HTMLTableElement> & { ref?: Ref<HTMLTableElement>; showHorizontalBorders?: boolean; disabled?: boolean; stickyHeader?: boolean; density?: 'default' | 'regular' | 'condensed'; surface?: 'card' | 'none'; containerProps?: HTMLAttributes<HTMLDivElement> & { ref?: Ref<HTMLDivElement> }; innerClasses?: JumpTableInnerClasses; children?: ReactNode }): ReactNode
108
108
  export declare function JumpTableHead(props: HTMLAttributes<HTMLTableSectionElement> & { as?: ElementTag; ref?: Ref<HTMLTableSectionElement>; children?: ReactNode }): ReactNode
109
109
  export declare function JumpTableBody(props: HTMLAttributes<HTMLTableSectionElement> & { as?: ElementTag; ref?: Ref<HTMLTableSectionElement>; children?: ReactNode }): ReactNode
110
110
  export declare function JumpTableFooter(props: HTMLAttributes<HTMLTableSectionElement> & { as?: ElementTag; ref?: Ref<HTMLTableSectionElement>; children?: ReactNode }): ReactNode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mario_hahn/jumpy-ui",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": ["**/*.css"],