@mario_hahn/jumpy-ui 0.7.0 → 0.8.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 +34 -1
- package/dist/{chunk-KIZKZXWH.js → chunk-HQ4NWZ65.js} +21 -1
- package/dist/index.js +24 -12
- package/dist/theme.js +1 -1
- package/index.d.ts +2 -2
- package/package.json +1 -1
- package/theme.d.ts +2 -1
package/README.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @mario_hahn/jumpy-ui
|
|
2
2
|
|
|
3
|
+
## Sticky tables and selection
|
|
4
|
+
|
|
5
|
+
`JumpTable stickyHeader` fixes both the header and footer inside the scrollable
|
|
6
|
+
container. They use `--jumpy-cmp-table-backdrop-color` for a continuous background
|
|
7
|
+
behind the decorative cell surfaces. The default resolves to the opaque semantic
|
|
8
|
+
floating surface in each preset. Keep any custom backdrop override opaque.
|
|
9
|
+
|
|
10
|
+
`JumpTableCell` and `JumpTableHeaderCell` support `pinned="left"` or `pinned="right"`;
|
|
11
|
+
use `pinnedEdge` for the edge divider. Pinned cells use the same backdrop as the
|
|
12
|
+
sticky bands. Set the container's maximum height through `containerProps.style`.
|
|
13
|
+
|
|
14
|
+
Selection preserves normal text weight for table cells and list-item labels.
|
|
15
|
+
For deliberate emphasis, use `innerClasses.text.style.fontWeight` on a table cell
|
|
16
|
+
or `innerClasses.label.style.fontWeight` on a list item. Headers stay emphasized;
|
|
17
|
+
selection surfaces and accessibility attributes are independent of typography.
|
|
18
|
+
|
|
19
|
+
## Button sizes
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { JumpButton, JumpySize } from '@mario_hahn/jumpy-ui'
|
|
23
|
+
|
|
24
|
+
<JumpButton>Standard</JumpButton>
|
|
25
|
+
<JumpButton size={JumpySize.medium}>Compact</JumpButton>
|
|
26
|
+
<JumpButton size={JumpySize.largeXL}>Large</JumpButton>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`size` accepts a Jumpy sizing token, not a pixel number. The standard theme resolves
|
|
30
|
+
`medium` to 32px and `largeXL` to 48px. Omitting the prop preserves the existing
|
|
31
|
+
button layout (normally 40px). Explicit sizes adjust vertical padding; compact
|
|
32
|
+
buttons also use smaller typography, icons and horizontal padding. The token sets
|
|
33
|
+
a minimum height: content is never clipped when a very small token or larger
|
|
34
|
+
custom typography is used. Consumer `style` overrides retain precedence.
|
|
35
|
+
|
|
3
36
|
## Theme overrides
|
|
4
37
|
|
|
5
38
|
Use semantic colors for brand-wide changes and action overrides for individual
|
|
@@ -42,7 +75,7 @@ Jumpy Components als ein gemeinsames UI-Paket.
|
|
|
42
75
|
Starting with 0.5.0, Jumpy UI uses the public npmjs registry. No package token is required to install:
|
|
43
76
|
|
|
44
77
|
```bash
|
|
45
|
-
npm install @mario_hahn/jumpy-ui@^0.
|
|
78
|
+
npm install @mario_hahn/jumpy-ui@^0.8.0
|
|
46
79
|
```
|
|
47
80
|
|
|
48
81
|
The public npm package uses the `@mario_hahn` scope. Older GitHub Packages releases
|
|
@@ -23765,13 +23765,33 @@ var providerStyles = `
|
|
|
23765
23765
|
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] thead,
|
|
23766
23766
|
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] tfoot {
|
|
23767
23767
|
position: sticky;
|
|
23768
|
-
z-index
|
|
23768
|
+
/* Above pinned body cells (z-index 10), with a full-width opaque surface. */
|
|
23769
|
+
z-index: 20;
|
|
23770
|
+
/* The inset decorative cell surfaces are not an occluding backdrop. */
|
|
23771
|
+
background-color: var(--jumpy-cmp-table-backdrop-color);
|
|
23769
23772
|
}
|
|
23770
23773
|
|
|
23771
23774
|
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] thead {
|
|
23772
23775
|
top: 0;
|
|
23773
23776
|
}
|
|
23774
23777
|
|
|
23778
|
+
/* Table section backgrounds can be clipped to rounded cell boxes by the table
|
|
23779
|
+
painting algorithm. An independent layer also covers those outer corners. */
|
|
23780
|
+
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] thead::before,
|
|
23781
|
+
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] tfoot::before {
|
|
23782
|
+
content: '';
|
|
23783
|
+
position: absolute;
|
|
23784
|
+
inset: 0;
|
|
23785
|
+
z-index: -1;
|
|
23786
|
+
pointer-events: none;
|
|
23787
|
+
background-color: var(--jumpy-cmp-table-backdrop-color);
|
|
23788
|
+
}
|
|
23789
|
+
|
|
23790
|
+
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] :is(thead, tfoot) > [data-jumpy-component='table-row'] > :is([data-jumpy-component='table-cell'], [data-jumpy-component='table-header-cell']):is(:first-child, :last-child) {
|
|
23791
|
+
/* Only the decorative surface is rounded; sticky backdrops are rectangular. */
|
|
23792
|
+
border-radius: 0;
|
|
23793
|
+
}
|
|
23794
|
+
|
|
23775
23795
|
[data-jumpy-theme='true'] [data-jumpy-slot='table-container'][data-sticky-header='true'] tfoot {
|
|
23776
23796
|
bottom: 0;
|
|
23777
23797
|
}
|
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
textStyleValue,
|
|
29
29
|
themeToCSSVariables,
|
|
30
30
|
useJumpyTheme
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-HQ4NWZ65.js";
|
|
32
32
|
import {
|
|
33
33
|
cn
|
|
34
34
|
} from "./chunk-3DBKYKP2.js";
|
|
@@ -680,7 +680,6 @@ function JumpListItem({ as, children, className = "", selected = false, disabled
|
|
|
680
680
|
const isDisabled = disabled || readOnly;
|
|
681
681
|
const bodyMedium = textStyleValue(theme, JumpyTextStyle.bodyMedium);
|
|
682
682
|
const bodySmall = textStyleValue(theme, JumpyTextStyle.bodySmall);
|
|
683
|
-
const bodyMediumEmphasized = textStyleValue(theme, JumpyTextStyle.bodyMediumEmphasized);
|
|
684
683
|
const iconSize = sizeValue(theme, JumpySize.small2XS);
|
|
685
684
|
const handleExpandedChange = () => {
|
|
686
685
|
const nextCollapsed = !isNestedCollapsed;
|
|
@@ -750,7 +749,7 @@ function JumpListItem({ as, children, className = "", selected = false, disabled
|
|
|
750
749
|
resolvedSelector ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "selector", "aria-hidden": props.role === "option" || props.role === "treeitem" ? "true" : void 0, className: innerClasses.selector?.className, style: { display: "inline-flex", pointerEvents: "none", color: "var(--jumpy-list-item-icon-color, var(--jumpy-list-item-default-icon))", ...innerClasses.selector?.style || {} }, children: resolvedSelector }) : null,
|
|
751
750
|
resolvedLeading ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "leading", "aria-hidden": "true", className: innerClasses.leading?.className, style: { display: "inline-flex", width: iconSize, height: iconSize, color: "var(--jumpy-list-item-icon-color, var(--jumpy-list-item-default-icon))", ...innerClasses.leading?.style || {} }, children: resolvedLeading }) : null,
|
|
752
751
|
/* @__PURE__ */ jsxs("span", { style: { display: "grid", minWidth: 0 }, children: [
|
|
753
|
-
/* @__PURE__ */ jsx("span", { "data-jumpy-slot": "label", "data-truncate": truncateTexts ? "true" : void 0, "data-text": typeof children === "string" ? children : void 0, className: innerClasses.label?.className, style: { minWidth: 0, maxWidth: "100%", overflowWrap: "anywhere", wordBreak: "break-word", fontWeight:
|
|
752
|
+
/* @__PURE__ */ jsx("span", { "data-jumpy-slot": "label", "data-truncate": truncateTexts ? "true" : void 0, "data-text": typeof children === "string" ? children : void 0, className: innerClasses.label?.className, style: { minWidth: 0, maxWidth: "100%", overflowWrap: "anywhere", wordBreak: "break-word", fontWeight: bodyMedium.fontWeight, ...innerClasses.label?.style || {} }, children }),
|
|
754
753
|
resolvedDescription ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "description", className: innerClasses.description?.className, style: { color: selected ? theme.listItem.active.default.subtext : theme.listItem.inactive.default.subtext, fontSize: bodySmall.fontSize, lineHeight: bodySmall.lineHeight, ...innerClasses.description?.style || {} }, children: resolvedDescription }) : null
|
|
755
754
|
] }),
|
|
756
755
|
resolvedMetadata ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "metadata", className: innerClasses.metadata?.className, style: { color: selected ? theme.listItem.active.default.subtext : theme.listItem.inactive.default.subtext, whiteSpace: "nowrap", fontSize: bodySmall.fontSize, lineHeight: bodySmall.lineHeight, ...innerClasses.metadata?.style || {} }, children: resolvedMetadata }) : null,
|
|
@@ -1770,7 +1769,7 @@ function JumpTableCell({ as, children, selected = false, disabled = false, align
|
|
|
1770
1769
|
/* @__PURE__ */ jsxs("span", { "data-jumpy-slot": "table-cell-inner", "data-align": resolvedAlign, className: innerClasses.inner?.className, style: innerClasses.inner?.style, children: [
|
|
1771
1770
|
cellLeading ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "table-cell-leading", className: innerClasses.leading?.className, style: innerClasses.leading?.style, children: cellLeading }) : null,
|
|
1772
1771
|
/* @__PURE__ */ jsxs("span", { "data-jumpy-slot": "table-cell-content", className: innerClasses.content?.className, style: innerClasses.content?.style, children: [
|
|
1773
|
-
/* @__PURE__ */ jsx("span", { "data-jumpy-slot": "table-cell-text", className: innerClasses.text?.className, style: tableCellTextStyle(theme,
|
|
1772
|
+
/* @__PURE__ */ jsx("span", { "data-jumpy-slot": "table-cell-text", className: innerClasses.text?.className, style: tableCellTextStyle(theme, false, innerClasses.text?.style), children }),
|
|
1774
1773
|
cellDescription ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "table-cell-description", className: innerClasses.description?.className, style: tableCellTextStyle(theme, false, innerClasses.description?.style), children: cellDescription }) : null
|
|
1775
1774
|
] }),
|
|
1776
1775
|
cellTrailing ? /* @__PURE__ */ jsx("span", { "data-jumpy-slot": "table-cell-trailing", className: innerClasses.trailing?.className, style: innerClasses.trailing?.style, children: cellTrailing }) : null
|
|
@@ -3044,11 +3043,14 @@ function JumpLoader({ label = "Jumpy UI wird geladen", fullScreen = false, class
|
|
|
3044
3043
|
/* @__PURE__ */ jsx(JumpCard, { className: cn("px-10 py-9", decorativeBackground && "relative z-10"), children: content })
|
|
3045
3044
|
] });
|
|
3046
3045
|
}
|
|
3047
|
-
function JumpButton({ as, variant = "primary", status = "regular", className = "", isLoading = false, disabled, elevated = false, slots, leadingIcon, trailingIcon, children, ...props }) {
|
|
3046
|
+
function JumpButton({ as, size: size2, variant = "primary", status = "regular", className = "", isLoading = false, disabled, elevated = false, slots, leadingIcon, trailingIcon, children, ...props }) {
|
|
3048
3047
|
const theme = useJumpyTheme();
|
|
3049
3048
|
const variantStyles = getButtonVariantStyles(theme, variant, status);
|
|
3050
|
-
const
|
|
3051
|
-
|
|
3049
|
+
const height = sizeValue(theme, size2 ?? JumpySize.large);
|
|
3050
|
+
if (!Number.isFinite(height) || height < 0) throw new Error(`Invalid JumpButton size token: ${size2}`);
|
|
3051
|
+
const compact = height < sizeValue(theme, JumpySize.large);
|
|
3052
|
+
const textStyle = textStyleValue(theme, compact ? JumpyTextStyle.bodySmallEmphasized : JumpyTextStyle.bodyMediumEmphasized);
|
|
3053
|
+
const iconSize = sizeValue(theme, compact ? JumpySize.small3XS : JumpySize.small2XS);
|
|
3052
3054
|
const [pressed, setPressed] = useState(false);
|
|
3053
3055
|
const leading = slots?.leading ?? leadingIcon;
|
|
3054
3056
|
const trailing = slots?.trailing ?? trailingIcon;
|
|
@@ -3057,6 +3059,15 @@ function JumpButton({ as, variant = "primary", status = "regular", className = "
|
|
|
3057
3059
|
const isDisabled = disabled || isLoading;
|
|
3058
3060
|
const spacing = getButtonSpacing(theme, variant, Boolean(leading), Boolean(trailing));
|
|
3059
3061
|
const hasBorder = variant === "secondary" || variant === "tertiary";
|
|
3062
|
+
if (size2 !== void 0) {
|
|
3063
|
+
const border = hasBorder ? borderWidthValue(theme, JumpyBorderWidth.small) : 0;
|
|
3064
|
+
const contentHeight = Math.max(textStyle.fontSize * textStyle.lineHeight, leading || trailing ? iconSize : 0);
|
|
3065
|
+
spacing.paddingTop = spacing.paddingBottom = Math.max(0, (height - contentHeight - border * 2) / 2);
|
|
3066
|
+
if (compact) {
|
|
3067
|
+
spacing.gap = spacingValue(theme, JumpySpacing.small3XS);
|
|
3068
|
+
spacing.paddingLeft = spacing.paddingRight = spacingValue(theme, variant === "borderless" ? JumpySpacing.zero : JumpySpacing.medium);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3060
3071
|
const content = /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", flexDirection: "row", alignItems: "center", justifyContent: "center", gap: spacing.gap, whiteSpace: "nowrap" }, children: [
|
|
3061
3072
|
leading ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex shrink-0 items-center justify-center", style: { width: iconSize, height: iconSize, lineHeight: 0, fontSize: iconSize }, children: leading }) : null,
|
|
3062
3073
|
/* @__PURE__ */ jsx("span", { children }),
|
|
@@ -3072,6 +3083,7 @@ function JumpButton({ as, variant = "primary", status = "regular", className = "
|
|
|
3072
3083
|
"data-status": status,
|
|
3073
3084
|
"data-elevated": elevated ? "true" : "false",
|
|
3074
3085
|
"data-loading": isLoading ? "true" : "false",
|
|
3086
|
+
"data-size": size2,
|
|
3075
3087
|
"data-pressed": pressed ? "true" : "false",
|
|
3076
3088
|
"aria-busy": isLoading || void 0,
|
|
3077
3089
|
"aria-disabled": !isButton && isDisabled ? true : props["aria-disabled"],
|
|
@@ -3098,7 +3110,7 @@ function JumpButton({ as, variant = "primary", status = "regular", className = "
|
|
|
3098
3110
|
display: "inline-flex",
|
|
3099
3111
|
alignItems: "center",
|
|
3100
3112
|
justifyContent: "center",
|
|
3101
|
-
minHeight:
|
|
3113
|
+
minHeight: height,
|
|
3102
3114
|
appearance: "none",
|
|
3103
3115
|
WebkitAppearance: "none",
|
|
3104
3116
|
boxSizing: "border-box",
|
|
@@ -3107,11 +3119,11 @@ function JumpButton({ as, variant = "primary", status = "regular", className = "
|
|
|
3107
3119
|
paddingTop: spacing.paddingTop,
|
|
3108
3120
|
paddingBottom: spacing.paddingBottom,
|
|
3109
3121
|
borderRadius: radiusValue(theme, JumpyRadius.small),
|
|
3110
|
-
letterSpacing:
|
|
3122
|
+
letterSpacing: textStyle.letterSpacing,
|
|
3111
3123
|
fontFamily: theme.fontFamily.familyBase,
|
|
3112
|
-
fontSize:
|
|
3113
|
-
lineHeight:
|
|
3114
|
-
fontWeight:
|
|
3124
|
+
fontSize: textStyle.fontSize,
|
|
3125
|
+
lineHeight: textStyle.lineHeight,
|
|
3126
|
+
fontWeight: textStyle.fontWeight,
|
|
3115
3127
|
opacity: isDisabled ? opacityValue(theme, JumpyOpacity.medium) : opacityValue(theme, JumpyOpacity.solid),
|
|
3116
3128
|
borderWidth: hasBorder ? borderWidthValue(theme, JumpyBorderWidth.small) : 0,
|
|
3117
3129
|
borderStyle: hasBorder ? "solid" : "none",
|
package/dist/theme.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLAttributes, InputHTMLAttributes, ReactNode, Ref, TdHTMLAttributes, TextareaHTMLAttributes, ThHTMLAttributes } from 'react'
|
|
2
|
-
export type { JumpyTheme } from './theme.js'
|
|
2
|
+
export type { JumpyTheme, JumpySizeToken } from './theme.js'
|
|
3
3
|
type ElementTag = keyof HTMLElementTagNameMap
|
|
4
4
|
type JumpResponsiveValue<T> = T | { small?: T; medium?: T; large?: T; xLarge?: T }
|
|
5
5
|
type JumpGridSpacing = number | string | [row: number | string, column: number | string]
|
|
@@ -128,7 +128,7 @@ export type JumpDialogInnerPart = 'illustration' | 'body' | 'icon' | 'title' | '
|
|
|
128
128
|
export type JumpDialogInnerClasses = Partial<Record<JumpDialogInnerPart, { className?: string; style?: import('react').CSSProperties }>>
|
|
129
129
|
export declare function JumpDialog(props: HTMLAttributes<HTMLElement> & { as?: ElementTag; visible?: boolean; onVisibleChange?: (visible: boolean) => void; title?: ReactNode; description?: ReactNode; footer?: ReactNode; disableBackdropClick?: boolean; disableContentScroll?: boolean; fullScreen?: boolean; overlayProps?: HTMLAttributes<HTMLDivElement>; slots?: { illustration?: ReactNode; icon?: ReactNode; title?: ReactNode; description?: ReactNode; footer?: ReactNode }; innerClasses?: JumpDialogInnerClasses; children?: ReactNode }): ReactNode
|
|
130
130
|
export declare function JumpLoader(props: { label?: string; fullScreen?: boolean; className?: string; decorativeBackground?: boolean }): ReactNode
|
|
131
|
-
export declare function JumpButton(props: JumpPolymorphicButtonAttributes & { as?: ElementTag; variant?: 'primary' | 'secondary' | 'tertiary' | 'borderless'; status?: 'regular' | 'alarm'; isLoading?: boolean; elevated?: boolean; slots?: JumpButtonSlots; leadingIcon?: ReactNode; trailingIcon?: ReactNode }): ReactNode
|
|
131
|
+
export declare function JumpButton(props: JumpPolymorphicButtonAttributes & { as?: ElementTag; size?: import('./theme.js').JumpySizeToken; variant?: 'primary' | 'secondary' | 'tertiary' | 'borderless'; status?: 'regular' | 'alarm'; isLoading?: boolean; elevated?: boolean; slots?: JumpButtonSlots; leadingIcon?: ReactNode; trailingIcon?: ReactNode }): ReactNode
|
|
132
132
|
export declare function JumpIconButton(props: JumpPolymorphicButtonAttributes & { as?: ElementTag; variant?: 'primary' | 'secondary' | 'tertiary' | 'borderless'; status?: 'regular' | 'alarm'; alternateHover?: boolean; elevated?: boolean }): ReactNode
|
|
133
133
|
export declare function JumpLinkButton(props: AnchorHTMLAttributes<HTMLAnchorElement> & { href: string; variant?: 'primary' | 'secondary' | 'tertiary' | 'borderless'; status?: 'regular' | 'alarm'; leadingIcon?: ReactNode; trailingIcon?: ReactNode }): ReactNode
|
|
134
134
|
export declare const JumpInput: import('react').ForwardRefExoticComponent<InputHTMLAttributes<HTMLInputElement> & { status?: JumpInputStatus } & import('react').RefAttributes<HTMLInputElement>>
|
package/package.json
CHANGED
package/theme.d.ts
CHANGED
|
@@ -19,7 +19,8 @@ export type JumpyTheme = {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export declare const JumpySpacing: Record<string, string>
|
|
22
|
-
export
|
|
22
|
+
export type JumpySizeToken = 'none' | 'small5XS' | 'small4XS' | 'small3XS' | 'small2XS' | 'smallXS' | 'small' | 'medium' | 'large' | 'largeXL' | 'large2XL' | 'large3XL' | 'large4XL' | 'large5XL' | 'large6XL' | 'large7XL' | 'large8XL'
|
|
23
|
+
export declare const JumpySize: { readonly [Key in JumpySizeToken]: Key }
|
|
23
24
|
export declare const JumpyRadius: Record<string, string>
|
|
24
25
|
export declare const JumpyOpacity: Record<string, string>
|
|
25
26
|
export declare const JumpyBorderWidth: Record<string, string>
|