@mario_hahn/jumpy-ui 0.12.0 → 0.13.1

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.
Files changed (40) hide show
  1. package/README.md +13 -1
  2. package/dist/{chunk-3PHOJLCH.js → chunk-XX3RYGLI.js} +31 -12
  3. package/dist/index.js +85 -9
  4. package/dist/theme.js +1 -1
  5. package/index.d.ts +3 -2
  6. package/package.json +1 -1
  7. package/tokens/android/tokens/src/main/kotlin/com/mariohahn/jumpy/tokens/defaultDark/Tokens.kt +1200 -4
  8. package/tokens/android/tokens/src/main/kotlin/com/mariohahn/jumpy/tokens/defaultLight/Tokens.kt +1200 -4
  9. package/tokens/android/tokens/src/main/kotlin/com/mariohahn/jumpy/tokens/jumpyDark/Tokens.kt +1200 -4
  10. package/tokens/android/tokens/src/main/kotlin/com/mariohahn/jumpy/tokens/jumpyLight/Tokens.kt +1200 -4
  11. package/tokens/ios/Sources/JumpyTokensDefault/Tokens.xcassets/actionsPrimaryRegularDisabledBorder.colorset/Contents.json +6 -6
  12. package/tokens/ios/Sources/JumpyTokensDefault/Tokens.xcassets/actionsPrimaryRegularDisabledSurface.colorset/Contents.json +6 -6
  13. package/tokens/ios/Sources/JumpyTokensDefault/Tokens.xcassets/actionsPrimaryRegularDisabledSurfaceAlternate.colorset/Contents.json +6 -6
  14. package/tokens/ios/Sources/JumpyTokensJumpy/Tokens.xcassets/actionsPrimaryRegularDisabledBorder.colorset/Contents.json +6 -6
  15. package/tokens/ios/Sources/JumpyTokensJumpy/Tokens.xcassets/actionsPrimaryRegularDisabledSurface.colorset/Contents.json +6 -6
  16. package/tokens/ios/Sources/JumpyTokensJumpy/Tokens.xcassets/actionsPrimaryRegularDisabledSurfaceAlternate.colorset/Contents.json +6 -6
  17. package/tokens/web/css/default-dark/variables.css +3 -3
  18. package/tokens/web/css/default-light/variables.css +3 -3
  19. package/tokens/web/css/jumpy-dark/variables.css +3 -3
  20. package/tokens/web/css/jumpy-light/variables.css +3 -3
  21. package/tokens/web/js/default-dark/variables.cjs +3 -3
  22. package/tokens/web/js/default-dark/variables.js +3 -3
  23. package/tokens/web/js/default-light/variables.cjs +3 -3
  24. package/tokens/web/js/default-light/variables.js +3 -3
  25. package/tokens/web/js/jumpy-dark/variables.cjs +3 -3
  26. package/tokens/web/js/jumpy-dark/variables.js +3 -3
  27. package/tokens/web/js/jumpy-light/variables.cjs +3 -3
  28. package/tokens/web/js/jumpy-light/variables.js +3 -3
  29. package/tokens/web/json/default-dark/flat-variables.json +3 -3
  30. package/tokens/web/json/default-dark/nested-variables.json +3 -3
  31. package/tokens/web/json/default-dark/variables.json +3 -3
  32. package/tokens/web/json/default-light/flat-variables.json +3 -3
  33. package/tokens/web/json/default-light/nested-variables.json +3 -3
  34. package/tokens/web/json/default-light/variables.json +3 -3
  35. package/tokens/web/json/jumpy-dark/flat-variables.json +3 -3
  36. package/tokens/web/json/jumpy-dark/nested-variables.json +3 -3
  37. package/tokens/web/json/jumpy-dark/variables.json +3 -3
  38. package/tokens/web/json/jumpy-light/flat-variables.json +3 -3
  39. package/tokens/web/json/jumpy-light/nested-variables.json +3 -3
  40. package/tokens/web/json/jumpy-light/variables.json +3 -3
package/README.md CHANGED
@@ -9,6 +9,13 @@ keeps its dimensions when replacing an icon; adding a new slot may widen a butto
9
9
  that had none. Loading disables activation and sets `aria-busy`. The SVG animation
10
10
  works without a Tailwind source scan in the consumer.
11
11
 
12
+ ### Disabled visibility (0.13.1)
13
+
14
+ Regular primary disabled buttons use a visible neutral surface on page and card
15
+ backgrounds (`#D1D1D1` Light, `#4D4D4D` Dark). The surface, alternate surface and
16
+ border tokens agree across Web/Android/iOS. `JumpButton` uses these tokens without
17
+ an additional opacity reduction, including during loading.
18
+
12
19
  ## Preset migration (0.10.0)
13
20
 
14
21
  Available presets are now `default-light`, `default-dark`, `jumpy-light` and
@@ -211,7 +218,7 @@ Jumpy Components als ein gemeinsames UI-Paket.
211
218
  Starting with 0.5.0, Jumpy UI uses the public npmjs registry. No package token is required to install:
212
219
 
213
220
  ```bash
214
- npm install @mario_hahn/jumpy-ui@^0.12.0
221
+ npm install @mario_hahn/jumpy-ui@^0.13.0
215
222
  ```
216
223
 
217
224
  The public npm package uses the `@mario_hahn` scope. Older GitHub Packages releases
@@ -333,6 +340,11 @@ import { JumpAppShell, JumpSideMenu, JumpSideMenuItem, JumpTabBar, JumpTabBarIte
333
340
  stays visible and the rest go into a "More actions" menu. Desktop shows labelled
334
341
  buttons beside the large title, otherwise in the top bar. Prefer it over `trailing`
335
342
  for ordinary actions; keep `trailing` for custom content such as an avatar.
343
+ - `topBar.back` (0.13.0+): `{ label, href, as: Link }` for detail pages ("up" to the
344
+ parent). Mobile: "‹ label" replaces the menu button; desktop: link above the large
345
+ title or in the top bar. Returns through history when the previous entry is that
346
+ parent, otherwise follows `href` (deep links stay in the app). Keep the browser's own
347
+ back (button, Safari edge swipe) working: every page change needs a history entry.
336
348
  - `JumpTopBar` and `JumpTabBar` also work standalone. Both are sticky and include
337
349
  safe-area insets. `JumpTabBarItem` accepts `as` (e.g. Next `Link`), `href`, `icon`,
338
350
  numeric or custom `badge` and `selected` (`aria-current="page"`).
@@ -1455,11 +1455,11 @@ var variables_default = {
1455
1455
  "text": "#FFFFFF"
1456
1456
  },
1457
1457
  "disabled": {
1458
- "border": "#242A2F",
1458
+ "border": "#4D4D4DFF",
1459
1459
  "icon": "#B8C0C4",
1460
1460
  "surface": {
1461
- "$value": "#242A2F",
1462
- "alternate": "#1A1A1AFF"
1461
+ "$value": "#4D4D4DFF",
1462
+ "alternate": "#4D4D4DFF"
1463
1463
  },
1464
1464
  "text": "#B8C0C4"
1465
1465
  },
@@ -3565,11 +3565,11 @@ var variables_default2 = {
3565
3565
  "text": "#FFFFFFFF"
3566
3566
  },
3567
3567
  "disabled": {
3568
- "border": "#F4F7F5",
3568
+ "border": "#D1D1D1FF",
3569
3569
  "icon": "#575B5E",
3570
3570
  "surface": {
3571
- "$value": "#F4F7F5",
3572
- "alternate": "#F6F6F6FF"
3571
+ "$value": "#D1D1D1FF",
3572
+ "alternate": "#D1D1D1FF"
3573
3573
  },
3574
3574
  "text": "#575B5E"
3575
3575
  },
@@ -5675,11 +5675,11 @@ var variables_default3 = {
5675
5675
  "text": "#FFFFFF"
5676
5676
  },
5677
5677
  "disabled": {
5678
- "border": "#151934",
5678
+ "border": "#4D4D4DFF",
5679
5679
  "icon": "#A5ADBF",
5680
5680
  "surface": {
5681
- "$value": "#151934",
5682
- "alternate": "#1A1A1AFF"
5681
+ "$value": "#4D4D4DFF",
5682
+ "alternate": "#4D4D4DFF"
5683
5683
  },
5684
5684
  "text": "#A5ADBF"
5685
5685
  },
@@ -7785,11 +7785,11 @@ var variables_default4 = {
7785
7785
  "text": "#FFFFFF"
7786
7786
  },
7787
7787
  "disabled": {
7788
- "border": "#F4F7F5",
7788
+ "border": "#D1D1D1FF",
7789
7789
  "icon": "#575B5E",
7790
7790
  "surface": {
7791
- "$value": "#F4F7F5",
7792
- "alternate": "#F6F6F6FF"
7791
+ "$value": "#D1D1D1FF",
7792
+ "alternate": "#D1D1D1FF"
7793
7793
  },
7794
7794
  "text": "#575B5E"
7795
7795
  },
@@ -11904,6 +11904,25 @@ var providerStyles = `
11904
11904
  backdrop-filter: none;
11905
11905
  }
11906
11906
 
11907
+ [data-jumpy-theme='true'] [data-jumpy-slot='app-shell-back'] {
11908
+ display: inline-flex;
11909
+ -webkit-tap-highlight-color: transparent;
11910
+ }
11911
+
11912
+ /* Only the label truncates; the chevron keeps its size. */
11913
+ [data-jumpy-theme='true'] [data-jumpy-slot='app-shell-back'] > svg {
11914
+ flex: none;
11915
+ }
11916
+
11917
+ [data-jumpy-theme='true'] [data-jumpy-slot='app-shell-back']:hover {
11918
+ color: var(--jumpy-interactive-active-regular-hover-text);
11919
+ }
11920
+
11921
+ [data-jumpy-theme='true'] [data-jumpy-slot='app-shell-back']:focus-visible {
11922
+ outline: var(--jumpy-spacing-outline-medium) solid var(--jumpy-interactive-inactive-regular-focus-focus-ring);
11923
+ outline-offset: var(--jumpy-spacing-outline-small);
11924
+ }
11925
+
11907
11926
  [data-jumpy-theme='true'] [data-jumpy-component='tab-bar-item'] {
11908
11927
  transition: background-color var(--jumpy-animation-duration-xsmall) var(--jumpy-animation-easing-drift), color var(--jumpy-animation-duration-xsmall) var(--jumpy-animation-easing-drift);
11909
11928
  -webkit-tap-highlight-color: transparent;
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  textStyleValue,
29
29
  themeToCSSVariables,
30
30
  useJumpyTheme
31
- } from "./chunk-3PHOJLCH.js";
31
+ } from "./chunk-XX3RYGLI.js";
32
32
  import {
33
33
  cn
34
34
  } from "./chunk-3DBKYKP2.js";
@@ -2408,14 +2408,14 @@ function JumpSheet({ visible = false, onVisibleChange, position = "right", title
2408
2408
  footer ? /* @__PURE__ */ jsx2("div", { style: { padding: spacingValue(theme, JumpySpacing.large), borderTop: `${borderWidthValue(theme, JumpyBorderWidth.small)}px solid ${theme.color.borderSubtle}` }, children: footer }) : null
2409
2409
  ] }) });
2410
2410
  }
2411
- function JumpyNavigationIcon({ type }) {
2411
+ function JumpyNavigationIcon({ type, size: size2 = 24 }) {
2412
2412
  const paths = {
2413
2413
  menu: "M4 6h16M4 12h16M4 18h16",
2414
2414
  close: "M6 6l12 12M18 6 6 18",
2415
2415
  back: "M15 18l-6-6 6-6",
2416
2416
  more: "M5 12h.01M12 12h.01M19 12h.01"
2417
2417
  };
2418
- return /* @__PURE__ */ jsx2("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: type === "more" ? 3 : 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", "data-jumpy-stroke-icon": "true", style: { display: "block" }, children: /* @__PURE__ */ jsx2("path", { d: paths[type] }) });
2418
+ return /* @__PURE__ */ jsx2("svg", { width: size2, height: size2, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: type === "more" ? 3 : 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", "data-jumpy-stroke-icon": "true", style: { display: "block" }, children: /* @__PURE__ */ jsx2("path", { d: paths[type] }) });
2419
2419
  }
2420
2420
  function JumpTopBar({ leading, onMenu, onBack, menuOpen = false, title, subtitle, trailing, sticky = true, titleAlign = "start", titleHidden = false, ariaLabels = {}, className = "", ...props }) {
2421
2421
  const theme = useJumpyTheme();
@@ -2455,7 +2455,7 @@ function JumpTopBar({ leading, onMenu, onBack, menuOpen = false, title, subtitle
2455
2455
  ...props.style || {}
2456
2456
  },
2457
2457
  children: [
2458
- leadingNode ? /* @__PURE__ */ jsx2("span", { "data-jumpy-slot": "top-bar-leading", "data-leading": leadingType, style: { marginLeft: -spacingValue(theme, JumpySpacing.smallXS) }, children: leadingNode }) : null,
2458
+ leadingNode ? /* @__PURE__ */ jsx2("span", { "data-jumpy-slot": "top-bar-leading", "data-leading": leadingType, style: { minWidth: 0, maxWidth: "100%", marginLeft: -spacingValue(theme, JumpySpacing.smallXS) }, children: leadingNode }) : null,
2459
2459
  /* @__PURE__ */ jsxs2("span", { "data-jumpy-slot": "top-bar-title", "aria-hidden": titleHidden || void 0, style: titleAlign === "center" ? {
2460
2460
  display: "flex",
2461
2461
  flexDirection: "column",
@@ -2558,6 +2558,71 @@ function JumpTabBarItem({ as, icon, badge, selected = false, children, className
2558
2558
  }
2559
2559
  );
2560
2560
  }
2561
+ var jumpyLocations = { current: null, previous: null };
2562
+ function jumpyNormalizeUrl(url) {
2563
+ const resolved = new URL(url, window.location.href);
2564
+ const path = resolved.pathname.length > 1 ? resolved.pathname.replace(/\/+$/, "") : resolved.pathname;
2565
+ return `${resolved.origin}${path}${resolved.search === "?" ? "" : resolved.search}`;
2566
+ }
2567
+ function jumpyPreviousEntryIs(href) {
2568
+ const target = jumpyNormalizeUrl(href);
2569
+ const navigation = window.navigation;
2570
+ if (navigation && typeof navigation.entries === "function" && navigation.currentEntry) {
2571
+ if (!navigation.canGoBack) return false;
2572
+ const previous = navigation.entries()[navigation.currentEntry.index - 1];
2573
+ return Boolean(previous?.url) && jumpyNormalizeUrl(previous.url) === target;
2574
+ }
2575
+ return Boolean(jumpyLocations.previous) && jumpyNormalizeUrl(jumpyLocations.previous) === target && window.history.length > 1;
2576
+ }
2577
+ function JumpyAppShellBack({ back, variant, ariaLabels }) {
2578
+ const theme = useJumpyTheme();
2579
+ const Component = back.as || (back.href ? "a" : "button");
2580
+ const textStyle = textStyleValue(theme, variant === "inline" ? JumpyTextStyle.bodySmallEmphasized : JumpyTextStyle.bodyMedium);
2581
+ const accessibleName = ariaLabels.backTo ? ariaLabels.backTo(back.label) : `Back to ${back.label}`;
2582
+ function handleClick(event) {
2583
+ back.onClick?.(event);
2584
+ if (event.defaultPrevented || !back.href || back.history === false) return;
2585
+ if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
2586
+ if (!jumpyPreviousEntryIs(back.href)) return;
2587
+ event.preventDefault();
2588
+ window.history.back();
2589
+ }
2590
+ return /* @__PURE__ */ jsxs2(
2591
+ Component,
2592
+ {
2593
+ href: back.href,
2594
+ type: Component === "button" ? "button" : void 0,
2595
+ "aria-label": accessibleName,
2596
+ "data-jumpy-slot": "app-shell-back",
2597
+ "data-variant": variant,
2598
+ onClick: handleClick,
2599
+ style: {
2600
+ boxSizing: "border-box",
2601
+ alignItems: "center",
2602
+ gap: spacingValue(theme, JumpySpacing.small4XS),
2603
+ maxWidth: "100%",
2604
+ minWidth: 0,
2605
+ minHeight: variant === "inline" ? void 0 : sizeValue(theme, JumpySize.largeXL),
2606
+ margin: variant === "inline" ? `0 0 ${spacingValue(theme, JumpySpacing.small3XS)}px ${-spacingValue(theme, JumpySpacing.small3XS)}px` : 0,
2607
+ padding: variant === "inline" ? 0 : `0 ${spacingValue(theme, JumpySpacing.smallXS)}px 0 0`,
2608
+ border: 0,
2609
+ borderRadius: radiusValue(theme, JumpyRadius.small),
2610
+ background: "transparent",
2611
+ color: "var(--jumpy-interactive-active-regular-default-text)",
2612
+ textDecoration: "none",
2613
+ cursor: "pointer",
2614
+ fontFamily: theme.fontFamily.familyBase,
2615
+ fontSize: textStyle.fontSize,
2616
+ lineHeight: textStyle.lineHeight,
2617
+ fontWeight: textStyle.fontWeight
2618
+ },
2619
+ children: [
2620
+ /* @__PURE__ */ jsx2(JumpyNavigationIcon, { type: "back", size: variant === "inline" ? 18 : 24 }),
2621
+ /* @__PURE__ */ jsx2("span", { style: { minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: back.label })
2622
+ ]
2623
+ }
2624
+ );
2625
+ }
2561
2626
  function JumpyAppShellActions({ actions, variant, ariaLabels }) {
2562
2627
  const theme = useJumpyTheme();
2563
2628
  if (!actions.length) return null;
@@ -2591,12 +2656,19 @@ function JumpAppShell({ brand, navigation, sidebarFooter, topBar, tabBar, hideTa
2591
2656
  const showDrawer = isOpen || drawerMounted;
2592
2657
  const closing = drawerMounted && !isOpen;
2593
2658
  const wasShown = useRef2(showDrawer);
2594
- const { desktop: topBarDesktop = false, leading, largeTitle = false, actions = [], ...topBarProps } = topBar || {};
2659
+ const { desktop: topBarDesktop = false, leading, largeTitle = false, actions = [], back, ...topBarProps } = topBar || {};
2595
2660
  const showLargeTitle = largeTitle && Boolean(topBarProps.title);
2596
- const topBarOnDesktop = topBarDesktop || actions.length > 0 && !showLargeTitle;
2661
+ const hasBack = Boolean(back?.label);
2662
+ const topBarOnDesktop = topBarDesktop || !showLargeTitle && (actions.length > 0 || hasBack);
2597
2663
  const largeTitleRef = useRef2(null);
2598
2664
  const [largeTitleCovered, setLargeTitleCovered] = useState2(false);
2599
- const resolvedLeading = leading ?? (navigation ? "menu" : void 0);
2665
+ const resolvedLeading = hasBack ? /* @__PURE__ */ jsx2(JumpyAppShellBack, { back, variant: "bar", ariaLabels }) : leading ?? (navigation ? "menu" : void 0);
2666
+ useEffect2(() => {
2667
+ const href = window.location.href;
2668
+ if (jumpyLocations.current === href) return;
2669
+ jumpyLocations.previous = jumpyLocations.current;
2670
+ jumpyLocations.current = href;
2671
+ });
2600
2672
  const shell = `[data-jumpy-app-shell="${shellId}"]`;
2601
2673
  const width = typeof sidebarWidth === "number" ? `${sidebarWidth}px` : sidebarWidth;
2602
2674
  function setOpen(next) {
@@ -2655,11 +2727,13 @@ ${shell} { grid-template-columns: minmax(0, 1fr); }
2655
2727
  ${shell} > [data-jumpy-slot='app-shell-sidebar'] { display: none; }
2656
2728
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='compact'] { display: inline-flex; }
2657
2729
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: none; }
2730
+ ${shell} [data-jumpy-slot='app-shell-back'][data-variant='inline'] { display: none; }
2658
2731
  @media (min-width: ${breakpoint}px) {
2659
2732
  ${shell} { grid-template-columns: ${width} minmax(0, 1fr); }
2660
2733
  ${shell} > [data-jumpy-slot='app-shell-sidebar'] { display: flex; }
2661
2734
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='compact'] { display: none; }
2662
2735
  ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: inline-flex; }
2736
+ ${shell} [data-jumpy-slot='app-shell-back'][data-variant='inline'] { display: flex; width: fit-content; }
2663
2737
  ${shell} > [data-jumpy-slot='app-shell-body'] > [data-jumpy-component='tab-bar'] { display: none; }
2664
2738
  ${shell} > [data-jumpy-slot='app-shell-body'] > [data-jumpy-component='top-bar'][data-mobile-only='true'] { display: none; }
2665
2739
  ${shell} > [data-jumpy-slot='app-shell-body'] > [data-jumpy-component='top-bar'] > [data-leading='menu'] { display: none; }
@@ -2674,7 +2748,7 @@ ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: n
2674
2748
  onMenu: () => setOpen(true),
2675
2749
  title: topBarProps.title ?? brand,
2676
2750
  subtitle: showLargeTitle ? void 0 : topBarProps.subtitle,
2677
- titleAlign: showLargeTitle ? "center" : topBarProps.titleAlign,
2751
+ titleAlign: showLargeTitle || hasBack ? "center" : topBarProps.titleAlign,
2678
2752
  titleHidden: showLargeTitle ? !largeTitleCovered : topBarProps.titleHidden,
2679
2753
  "data-large-title": showLargeTitle ? "true" : void 0,
2680
2754
  trailing: actions.length || topBarProps.trailing ? /* @__PURE__ */ jsxs2(Fragment, { children: [
@@ -2731,6 +2805,7 @@ ${shell} [data-jumpy-slot='app-shell-actions'][data-variant='full'] { display: n
2731
2805
  /* @__PURE__ */ jsxs2("main", { "data-jumpy-slot": "app-shell-content", style: { flex: 1, minWidth: 0 }, children: [
2732
2806
  showLargeTitle ? /* @__PURE__ */ jsx2("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__ */ jsxs2("div", { style: { display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: spacingValue(theme, JumpySpacing.large), flexWrap: "wrap" }, children: [
2733
2807
  /* @__PURE__ */ jsxs2("div", { style: { minWidth: 0 }, children: [
2808
+ hasBack ? /* @__PURE__ */ jsx2(JumpyAppShellBack, { back, variant: "inline", ariaLabels }) : null,
2734
2809
  /* @__PURE__ */ jsx2("h1", { ref: largeTitleRef, style: { margin: 0, ...textStyleValue(theme, JumpyTextStyle.displaySmallEmphasized), overflowWrap: "anywhere" }, children: topBarProps.title }),
2735
2810
  topBarProps.subtitle ? /* @__PURE__ */ jsx2("p", { style: { margin: `${spacingValue(theme, JumpySpacing.small4XS)}px 0 0`, color: "var(--jumpy-color-text-secondary)", ...textStyleValue(theme, JumpyTextStyle.bodyMedium) }, children: topBarProps.subtitle }) : null
2736
2811
  ] }),
@@ -3881,7 +3956,8 @@ function JumpButton({ as, size: size2, variant = "primary", status = "regular",
3881
3956
  fontSize: textStyle.fontSize,
3882
3957
  lineHeight: textStyle.lineHeight,
3883
3958
  fontWeight: textStyle.fontWeight,
3884
- opacity: isDisabled ? opacityValue(theme, JumpyOpacity.medium) : opacityValue(theme, JumpyOpacity.solid),
3959
+ // Primary regular disabled tokens already encode the subdued appearance.
3960
+ opacity: isDisabled && !(variant === "primary" && status === "regular") ? opacityValue(theme, JumpyOpacity.medium) : opacityValue(theme, JumpyOpacity.solid),
3885
3961
  borderWidth: hasBorder ? borderWidthValue(theme, JumpyBorderWidth.small) : 0,
3886
3962
  borderStyle: hasBorder ? "solid" : "none",
3887
3963
  ...variantStyles,
package/dist/theme.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  textStyleValue,
29
29
  themeToCSSVariables,
30
30
  useJumpyTheme
31
- } from "./chunk-3PHOJLCH.js";
31
+ } from "./chunk-XX3RYGLI.js";
32
32
  export {
33
33
  JumpyAnimation,
34
34
  JumpyAnimationDelay,
package/index.d.ts CHANGED
@@ -117,8 +117,9 @@ export declare function JumpTabBar(props: HTMLAttributes<HTMLElement> & { childr
117
117
  export type JumpTabBarItemProps = { as?: ElementType; href?: string; icon?: ReactNode; badge?: ReactNode | number; selected?: boolean; children: ReactNode; className?: string; style?: CSSProperties } & Record<string, unknown>
118
118
  export declare function JumpTabBarItem(props: JumpTabBarItemProps): ReactNode
119
119
  export type JumpAppShellAction = { id?: string; label: string; icon: ReactNode; onClick?: (event: import('react').MouseEvent<HTMLElement>) => void; href?: string; variant?: 'primary' | 'secondary' | 'tertiary' | 'borderless'; disabled?: boolean }
120
- export type JumpAppShellTopBar = Omit<JumpTopBarProps, 'onMenu' | 'menuOpen'> & { desktop?: boolean; largeTitle?: boolean; actions?: JumpAppShellAction[] }
121
- export declare function JumpAppShell(props: HTMLAttributes<HTMLDivElement> & { brand?: ReactNode; navigation?: ReactNode; sidebarFooter?: ReactNode; topBar?: JumpAppShellTopBar | null; tabBar?: ReactNode; hideTabBar?: boolean; breakpoint?: number; sidebarWidth?: number | string; navigationOpen?: boolean; defaultNavigationOpen?: boolean; onNavigationOpenChange?: (open: boolean) => void; ariaLabels?: { navigation?: string; openNavigation?: string; closeNavigation?: string; back?: string; moreActions?: string }; children?: ReactNode }): ReactNode
120
+ export type JumpAppShellBack = { label: string; href?: string; as?: ElementType; onClick?: (event: import('react').MouseEvent<HTMLElement>) => void; history?: boolean }
121
+ export type JumpAppShellTopBar = Omit<JumpTopBarProps, 'onMenu' | 'menuOpen'> & { desktop?: boolean; largeTitle?: boolean; actions?: JumpAppShellAction[]; back?: JumpAppShellBack }
122
+ export declare function JumpAppShell(props: HTMLAttributes<HTMLDivElement> & { brand?: ReactNode; navigation?: ReactNode; sidebarFooter?: ReactNode; topBar?: JumpAppShellTopBar | null; tabBar?: ReactNode; hideTabBar?: boolean; breakpoint?: number; sidebarWidth?: number | string; navigationOpen?: boolean; defaultNavigationOpen?: boolean; onNavigationOpenChange?: (open: boolean) => void; ariaLabels?: { navigation?: string; openNavigation?: string; closeNavigation?: string; back?: string; backTo?: (label: string) => string; moreActions?: string }; children?: ReactNode }): ReactNode
122
123
  export declare function JumpSectionHeader(props: HTMLAttributes<HTMLElement> & { as?: ElementTag; variant?: 'regular' | 'prominent'; description?: ReactNode; children: ReactNode }): ReactNode
123
124
  export declare function JumpSectionFooter(props: HTMLAttributes<HTMLElement> & { as?: ElementTag; children: ReactNode }): ReactNode
124
125
  export declare function JumpTag(props: HTMLAttributes<HTMLSpanElement> & { size?: 'small' | 'medium'; status?: 'regular' | 'positive' | 'warning' | 'alarm'; disabled?: boolean; children: ReactNode }): ReactNode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mario_hahn/jumpy-ui",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {