@wallarm-org/design-system 1.23.3-rc-fix-remote-shell-breadcrumb-transition.2 → 1.24.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/dist/components/RemoteShell/NavPanelContent.d.ts +0 -5
- package/dist/components/RemoteShell/NavPanelContent.js +4 -6
- package/dist/components/RemoteShell/RemoteShellPanel.js +4 -10
- package/dist/components/RemoteShell/model/useDrillTransition.d.ts +1 -3
- package/dist/components/RemoteShell/model/useDrillTransition.js +11 -17
- package/dist/components/SplashScreen/SplashScreen.js +17 -5
- package/dist/components/SplashScreen/index.d.ts +1 -1
- package/dist/components/SplashScreen/lib.d.ts +1 -1
- package/dist/components/SplashScreen/lib.js +7 -2
- package/dist/components/SplashScreen/types.d.ts +2 -1
- package/dist/components/SplashScreen/useContentHeight.d.ts +13 -0
- package/dist/components/SplashScreen/useContentHeight.js +33 -0
- package/dist/components/SplashScreen/useSplashPhase.d.ts +1 -1
- package/dist/components/SplashScreen/useSplashPhase.js +8 -2
- package/dist/metadata/components.json +11 -1
- package/package.json +1 -1
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
|
-
import type { NavStackEntry } from './model';
|
|
3
|
-
interface NavigationSnapshot {
|
|
4
|
-
navStack: NavStackEntry[];
|
|
5
|
-
}
|
|
6
2
|
interface NavPanelContentProps {
|
|
7
3
|
level: number;
|
|
8
|
-
navigationSnapshot?: NavigationSnapshot;
|
|
9
4
|
}
|
|
10
5
|
export declare const NavPanelContent: FC<NavPanelContentProps>;
|
|
11
6
|
export {};
|
|
@@ -4,12 +4,10 @@ import { Text } from "../Text/index.js";
|
|
|
4
4
|
import { HeaderActions } from "./HeaderActions.js";
|
|
5
5
|
import { findDrillNode, useRemoteShellContext } from "./model/index.js";
|
|
6
6
|
import { NavItemsList } from "./NavItemsList.js";
|
|
7
|
-
const NavPanelContent = ({ level: rawLevel
|
|
8
|
-
const { config, navStack
|
|
9
|
-
const navStack = navigationSnapshot?.navStack ?? currentNavStack;
|
|
7
|
+
const NavPanelContent = ({ level: rawLevel })=>{
|
|
8
|
+
const { config, navStack, effectiveActiveItemId, navigate, drillInto, goBack } = useRemoteShellContext();
|
|
10
9
|
const level = Math.min(rawLevel, navStack.length - 1);
|
|
11
10
|
const entry = navStack[level];
|
|
12
|
-
const activeItemId = entry.activeItemId;
|
|
13
11
|
const hasHeaderActions = !!config.headerActions?.length;
|
|
14
12
|
if (0 === level) return /*#__PURE__*/ jsxs(Fragment, {
|
|
15
13
|
children: [
|
|
@@ -30,7 +28,7 @@ const NavPanelContent = ({ level: rawLevel, navigationSnapshot })=>{
|
|
|
30
28
|
}),
|
|
31
29
|
/*#__PURE__*/ jsx(NavItemsList, {
|
|
32
30
|
items: config.items,
|
|
33
|
-
activeItemId:
|
|
31
|
+
activeItemId: effectiveActiveItemId,
|
|
34
32
|
onNavigate: navigate,
|
|
35
33
|
onDrillClick: drillInto
|
|
36
34
|
})
|
|
@@ -56,7 +54,7 @@ const NavPanelContent = ({ level: rawLevel, navigationSnapshot })=>{
|
|
|
56
54
|
}),
|
|
57
55
|
/*#__PURE__*/ jsx(NavItemsList, {
|
|
58
56
|
items: entry.items,
|
|
59
|
-
activeItemId:
|
|
57
|
+
activeItemId: effectiveActiveItemId,
|
|
60
58
|
onNavigate: navigate,
|
|
61
59
|
onDrillClick: drillInto
|
|
62
60
|
})
|
|
@@ -7,8 +7,8 @@ import { DRILL_ANIMATION_DURATION, DRILL_ANIMATION_EASING, useDrillTransition }
|
|
|
7
7
|
import { NavPanelContent } from "./NavPanelContent.js";
|
|
8
8
|
const RemoteShellPanel = ({ ref, className, resizable, isLoading, loaderCount = 6, ...props })=>{
|
|
9
9
|
const testId = useTestId('panel');
|
|
10
|
-
const { config, drillLevel
|
|
11
|
-
const { transition, clearTransition } = useDrillTransition(drillLevel
|
|
10
|
+
const { config, drillLevel } = useRemoteShellContext();
|
|
11
|
+
const { transition, clearTransition } = useDrillTransition(drillLevel);
|
|
12
12
|
if (isLoading) return /*#__PURE__*/ jsx("div", {
|
|
13
13
|
...props,
|
|
14
14
|
ref: ref,
|
|
@@ -53,10 +53,7 @@ const RemoteShellPanel = ({ ref, className, resizable, isLoading, loaderCount =
|
|
|
53
53
|
animation: `${isForward ? 'ds-nav-blur-out' : 'ds-nav-blur-in'} ${timing}`
|
|
54
54
|
},
|
|
55
55
|
children: /*#__PURE__*/ jsx(NavPanelContent, {
|
|
56
|
-
level: isForward ? transition.fromLevel : drillLevel
|
|
57
|
-
navigationSnapshot: isForward ? {
|
|
58
|
-
navStack: transition.fromNavStack
|
|
59
|
-
} : void 0
|
|
56
|
+
level: isForward ? transition.fromLevel : drillLevel
|
|
60
57
|
})
|
|
61
58
|
}),
|
|
62
59
|
/*#__PURE__*/ jsx("div", {
|
|
@@ -65,10 +62,7 @@ const RemoteShellPanel = ({ ref, className, resizable, isLoading, loaderCount =
|
|
|
65
62
|
animation: `${isForward ? 'ds-nav-blur-in' : 'ds-nav-blur-out'} ${timing}`
|
|
66
63
|
},
|
|
67
64
|
children: /*#__PURE__*/ jsx(NavPanelContent, {
|
|
68
|
-
level: isForward ? drillLevel : transition.fromLevel
|
|
69
|
-
navigationSnapshot: isForward ? void 0 : {
|
|
70
|
-
navStack: transition.fromNavStack
|
|
71
|
-
}
|
|
65
|
+
level: isForward ? drillLevel : transition.fromLevel
|
|
72
66
|
})
|
|
73
67
|
})
|
|
74
68
|
]
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import type { NavStackEntry } from './types';
|
|
2
1
|
export declare const DRILL_ANIMATION_DURATION = "220ms";
|
|
3
2
|
export declare const DRILL_ANIMATION_EASING = "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
4
3
|
export interface DrillTransition {
|
|
5
4
|
fromLevel: number;
|
|
6
5
|
direction: 'forward' | 'backward';
|
|
7
|
-
fromNavStack: NavStackEntry[];
|
|
8
6
|
}
|
|
9
|
-
export declare const useDrillTransition: (drillLevel: number
|
|
7
|
+
export declare const useDrillTransition: (drillLevel: number) => {
|
|
10
8
|
transition: DrillTransition | null;
|
|
11
9
|
clearTransition: () => void;
|
|
12
10
|
};
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { useLayoutEffect, useRef, useState } from "react";
|
|
2
2
|
const DRILL_ANIMATION_DURATION = '220ms';
|
|
3
3
|
const DRILL_ANIMATION_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';
|
|
4
|
-
const useDrillTransition = (drillLevel
|
|
5
|
-
const
|
|
6
|
-
drillLevel,
|
|
7
|
-
navStack
|
|
8
|
-
});
|
|
4
|
+
const useDrillTransition = (drillLevel)=>{
|
|
5
|
+
const prevLevelRef = useRef(drillLevel);
|
|
9
6
|
const [transition, setTransition] = useState(null);
|
|
10
7
|
useLayoutEffect(()=>{
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
navStack
|
|
20
|
-
};
|
|
8
|
+
const prev = prevLevelRef.current;
|
|
9
|
+
if (prev !== drillLevel) {
|
|
10
|
+
setTransition({
|
|
11
|
+
fromLevel: prev,
|
|
12
|
+
direction: drillLevel > prev ? 'forward' : 'backward'
|
|
13
|
+
});
|
|
14
|
+
prevLevelRef.current = drillLevel;
|
|
15
|
+
}
|
|
21
16
|
}, [
|
|
22
|
-
drillLevel
|
|
23
|
-
navStack
|
|
17
|
+
drillLevel
|
|
24
18
|
]);
|
|
25
19
|
const clearTransition = ()=>setTransition(null);
|
|
26
20
|
return {
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
2
3
|
import { cn } from "../../utils/cn.js";
|
|
3
4
|
import { Logo } from "../Logo/index.js";
|
|
4
5
|
import { Progress } from "../Progress/index.js";
|
|
5
6
|
import { splashContainerVariants, splashContentVariants, splashLogoVariants, splashProgressVariants } from "./classes.js";
|
|
6
7
|
import { SPLASH_PHASES, getContainerStyle } from "./lib.js";
|
|
8
|
+
import { useContentHeight } from "./useContentHeight.js";
|
|
7
9
|
import { useSplashPhase } from "./useSplashPhase.js";
|
|
8
|
-
const SplashScreen = ({ ref, visible = true, shrinkTarget, className, children, ...props })=>{
|
|
9
|
-
const { phase, childrenRevealed, handleContainerTransitionEnd, handleContentTransitionEnd } = useSplashPhase(visible, shrinkTarget);
|
|
10
|
+
const SplashScreen = ({ ref, visible = true, shrinkTarget, className, children, onPhaseChange, ...props })=>{
|
|
11
|
+
const { phase, childrenRevealed, handleContainerTransitionEnd, handleContentTransitionEnd } = useSplashPhase(visible, shrinkTarget, onPhaseChange);
|
|
12
|
+
const contentRef = useRef(null);
|
|
13
|
+
const isLocked = 'settled' !== phase;
|
|
14
|
+
const shouldMeasure = Boolean(children && shrinkTarget && void 0 === shrinkTarget.height);
|
|
15
|
+
const measuredHeight = useContentHeight(contentRef, shouldMeasure, isLocked);
|
|
10
16
|
if ('exited' === phase) return null;
|
|
11
17
|
const containerPhase = phase;
|
|
12
18
|
const contentPhase = phase;
|
|
13
19
|
const showContent = SPLASH_PHASES[contentPhase] || 'shrinking' === phase;
|
|
14
20
|
const effectiveContentPhase = 'shrinking' === phase ? 'content-fading' : contentPhase;
|
|
21
|
+
const shouldShowChildren = children && shrinkTarget;
|
|
22
|
+
const isChildrenVisible = 'shrinking' === phase || 'settled' === phase;
|
|
15
23
|
return /*#__PURE__*/ jsxs("div", {
|
|
16
24
|
...props,
|
|
17
25
|
"data-slot": "splash-screen",
|
|
@@ -19,7 +27,7 @@ const SplashScreen = ({ ref, visible = true, shrinkTarget, className, children,
|
|
|
19
27
|
className: cn(splashContainerVariants({
|
|
20
28
|
phase: containerPhase
|
|
21
29
|
}), className),
|
|
22
|
-
style: getContainerStyle(phase, shrinkTarget),
|
|
30
|
+
style: getContainerStyle(phase, shrinkTarget, measuredHeight),
|
|
23
31
|
onTransitionEnd: handleContainerTransitionEnd,
|
|
24
32
|
children: [
|
|
25
33
|
showContent && /*#__PURE__*/ jsxs("div", {
|
|
@@ -41,8 +49,12 @@ const SplashScreen = ({ ref, visible = true, shrinkTarget, className, children,
|
|
|
41
49
|
})
|
|
42
50
|
]
|
|
43
51
|
}),
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
shouldShowChildren && /*#__PURE__*/ jsx("div", {
|
|
53
|
+
ref: contentRef,
|
|
54
|
+
className: cn('absolute h-auto w-full transition-opacity duration-300', !isChildrenVisible && 'invisible pointer-events-none opacity-0', 'shrinking' === phase && 'visible pointer-events-none', 'shrinking' === phase && (childrenRevealed ? 'opacity-100' : 'opacity-0'), 'settled' === phase && 'visible pointer-events-auto opacity-100', 'settled' === phase && 'transition-[height,opacity] duration-200'),
|
|
55
|
+
style: shrinkTarget ? {
|
|
56
|
+
width: shrinkTarget.width
|
|
57
|
+
} : void 0,
|
|
46
58
|
children: children
|
|
47
59
|
})
|
|
48
60
|
]
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { SplashScreen } from './SplashScreen';
|
|
2
|
-
export type { SplashScreenProps, SplashScreenShrinkTarget } from './types';
|
|
2
|
+
export type { PhaseType, SplashScreenProps, SplashScreenShrinkTarget } from './types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { CSSProperties } from 'react';
|
|
2
2
|
import type { ContentPhase, PhaseType, SplashScreenShrinkTarget } from './types';
|
|
3
3
|
export declare const SPLASH_PHASES: Record<ContentPhase, boolean>;
|
|
4
|
-
export declare function getContainerStyle(phase: PhaseType, shrinkTarget?: SplashScreenShrinkTarget): CSSProperties | undefined;
|
|
4
|
+
export declare function getContainerStyle(phase: PhaseType, shrinkTarget?: SplashScreenShrinkTarget, measuredHeight?: number): CSSProperties | undefined;
|
|
@@ -4,9 +4,10 @@ const SPLASH_PHASES = {
|
|
|
4
4
|
'content-fading': true,
|
|
5
5
|
exiting: true
|
|
6
6
|
};
|
|
7
|
-
function getContainerStyle(phase, shrinkTarget) {
|
|
7
|
+
function getContainerStyle(phase, shrinkTarget, measuredHeight) {
|
|
8
8
|
if (!shrinkTarget) return;
|
|
9
|
-
const { width, height, borderRadius = 0 } = shrinkTarget;
|
|
9
|
+
const { width, height: targetHeight, borderRadius = 0 } = shrinkTarget;
|
|
10
|
+
const height = measuredHeight ?? targetHeight;
|
|
10
11
|
switch(phase){
|
|
11
12
|
case 'enter-start':
|
|
12
13
|
case 'entered':
|
|
@@ -19,6 +20,10 @@ function getContainerStyle(phase, shrinkTarget) {
|
|
|
19
20
|
transition: 'clip-path 500ms ease-in-out'
|
|
20
21
|
};
|
|
21
22
|
case 'shrinking':
|
|
23
|
+
if (void 0 === height) return {
|
|
24
|
+
clipPath: `inset(0 0 round ${borderRadius}px)`,
|
|
25
|
+
transition: 'clip-path 500ms ease-in-out'
|
|
26
|
+
};
|
|
22
27
|
return {
|
|
23
28
|
clipPath: `inset(calc(50% - ${height / 2}px) calc(50% - ${width / 2}px) round ${borderRadius}px)`,
|
|
24
29
|
transition: 'clip-path 500ms ease-in-out'
|
|
@@ -3,7 +3,7 @@ export type ContentPhase = 'enter-start' | 'entered' | 'content-fading' | 'exiti
|
|
|
3
3
|
export type PhaseType = ContentPhase | 'shrinking' | 'settled' | 'exited';
|
|
4
4
|
export interface SplashScreenShrinkTarget {
|
|
5
5
|
width: number;
|
|
6
|
-
height
|
|
6
|
+
height?: number;
|
|
7
7
|
borderRadius?: number;
|
|
8
8
|
}
|
|
9
9
|
export interface SplashScreenProps extends HTMLAttributes<HTMLDivElement> {
|
|
@@ -11,4 +11,5 @@ export interface SplashScreenProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
11
11
|
visible?: boolean;
|
|
12
12
|
shrinkTarget?: SplashScreenShrinkTarget;
|
|
13
13
|
children?: ReactNode;
|
|
14
|
+
onPhaseChange?: (phase: PhaseType) => void;
|
|
14
15
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Measures the height of an element with ResizeObserver, with optional locking
|
|
4
|
+
* during animations to prevent mid-animation jumps.
|
|
5
|
+
*
|
|
6
|
+
* When locked=true, stores the first measured height and ignores subsequent
|
|
7
|
+
* updates until locked becomes false. This prevents viewport/content resizes
|
|
8
|
+
* from disrupting the shrink animation.
|
|
9
|
+
*
|
|
10
|
+
* The measured height is capped by viewport height minus a margin to ensure
|
|
11
|
+
* content fits on small screens.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useContentHeight: (elementRef: RefObject<HTMLElement | null>, enabled: boolean, locked: boolean) => number | undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
const useContentHeight = (elementRef, enabled, locked)=>{
|
|
3
|
+
const [height, setHeight] = useState(void 0);
|
|
4
|
+
const lockedHeightRef = useRef(void 0);
|
|
5
|
+
useEffect(()=>{
|
|
6
|
+
if (!enabled || !elementRef.current) return;
|
|
7
|
+
const updateHeight = ()=>{
|
|
8
|
+
if (locked && void 0 !== lockedHeightRef.current) return;
|
|
9
|
+
if (elementRef.current) {
|
|
10
|
+
const measured = elementRef.current.offsetHeight;
|
|
11
|
+
const maxHeight = window.innerHeight - 40;
|
|
12
|
+
const newHeight = Math.min(measured, maxHeight);
|
|
13
|
+
setHeight(newHeight);
|
|
14
|
+
if (locked) lockedHeightRef.current = newHeight;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const observer = new ResizeObserver(updateHeight);
|
|
18
|
+
observer.observe(elementRef.current);
|
|
19
|
+
updateHeight();
|
|
20
|
+
return ()=>observer.disconnect();
|
|
21
|
+
}, [
|
|
22
|
+
elementRef,
|
|
23
|
+
enabled,
|
|
24
|
+
locked
|
|
25
|
+
]);
|
|
26
|
+
useEffect(()=>{
|
|
27
|
+
if (!locked) lockedHeightRef.current = void 0;
|
|
28
|
+
}, [
|
|
29
|
+
locked
|
|
30
|
+
]);
|
|
31
|
+
return height;
|
|
32
|
+
};
|
|
33
|
+
export { useContentHeight };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TransitionEvent } from 'react';
|
|
2
2
|
import type { PhaseType, SplashScreenShrinkTarget } from './types';
|
|
3
|
-
export declare const useSplashPhase: (visible: boolean, shrinkTarget?: SplashScreenShrinkTarget) => {
|
|
3
|
+
export declare const useSplashPhase: (visible: boolean, shrinkTarget?: SplashScreenShrinkTarget, onPhaseChange?: (phase: PhaseType) => void) => {
|
|
4
4
|
phase: PhaseType;
|
|
5
5
|
childrenRevealed: boolean;
|
|
6
6
|
handleContainerTransitionEnd: (e: TransitionEvent<HTMLDivElement>) => void;
|
|
@@ -9,7 +9,7 @@ const doubleRaf = (callback)=>{
|
|
|
9
9
|
cancelAnimationFrame(id2);
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
-
const useSplashPhase = (visible, shrinkTarget)=>{
|
|
12
|
+
const useSplashPhase = (visible, shrinkTarget, onPhaseChange)=>{
|
|
13
13
|
const shrinkTargetRef = useRef(shrinkTarget);
|
|
14
14
|
shrinkTargetRef.current = shrinkTarget;
|
|
15
15
|
const [phase, setPhase] = useState(()=>visible ? 'enter-start' : shrinkTarget ? 'settled' : 'exited');
|
|
@@ -35,7 +35,7 @@ const useSplashPhase = (visible, shrinkTarget)=>{
|
|
|
35
35
|
]);
|
|
36
36
|
useEffect(()=>{
|
|
37
37
|
if ('content-fading' === phase && !contentShownRef.current) return doubleRaf(()=>setPhase('shrinking'));
|
|
38
|
-
if ('
|
|
38
|
+
if ('shrinking' === phase) return doubleRaf(()=>setChildrenRevealed(true));
|
|
39
39
|
}, [
|
|
40
40
|
phase
|
|
41
41
|
]);
|
|
@@ -48,6 +48,12 @@ const useSplashPhase = (visible, shrinkTarget)=>{
|
|
|
48
48
|
if ('exiting' === phase) setPhase('exited');
|
|
49
49
|
else if ('content-fading' === phase) setPhase('shrinking');
|
|
50
50
|
};
|
|
51
|
+
useEffect(()=>{
|
|
52
|
+
onPhaseChange?.(phase);
|
|
53
|
+
}, [
|
|
54
|
+
phase,
|
|
55
|
+
onPhaseChange
|
|
56
|
+
]);
|
|
51
57
|
return {
|
|
52
58
|
phase,
|
|
53
59
|
childrenRevealed,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.23.2",
|
|
3
|
-
"generatedAt": "2026-09-
|
|
3
|
+
"generatedAt": "2026-09-27T21:57:31.353Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -33057,6 +33057,11 @@
|
|
|
33057
33057
|
"name": "FutureDate",
|
|
33058
33058
|
"code": "() => (\n <FormatDateTime value={new Date(Date.now() + 5 * 60 * 1000)} format='relative' />\n)",
|
|
33059
33059
|
"description": "A timestamp five minutes ahead reads `Just now` rather than counting forwards — the\ncomponent absorbs clock skew between a browser and a server instead of showing it."
|
|
33060
|
+
},
|
|
33061
|
+
{
|
|
33062
|
+
"name": "DateOrderAndHourCycle",
|
|
33063
|
+
"code": "() => (\n <VStack gap={24} align='start'>\n <VStack gap={12} align='start'>\n <span className='sb-annotation'>Day-first, 24-hour (default)</span>\n <DateFormatProvider order='day-first' hourCycle={24}>\n <VStack gap={8} align='start'>\n <FormatDateTime value='2026-02-11T14:32:07' format='date' />\n <FormatDateTime value='2026-02-11T14:32:07' format='datetime' />\n <FormatDateTime value={subDays(now, 200)} format='relative' />\n </VStack>\n </DateFormatProvider>\n </VStack>\n\n <VStack gap={12} align='start'>\n <span className='sb-annotation'>Month-first, 12-hour</span>\n <DateFormatProvider order='month-first' hourCycle={12}>\n <VStack gap={8} align='start'>\n <FormatDateTime value='2026-02-11T14:32:07' format='date' />\n <FormatDateTime value='2026-02-11T14:32:07' format='datetime' />\n <FormatDateTime value={subDays(now, 200)} format='relative' />\n </VStack>\n </DateFormatProvider>\n </VStack>\n\n <VStack gap={12} align='start'>\n <span className='sb-annotation'>Day-first, 12-hour</span>\n <DateFormatProvider order='day-first' hourCycle={12}>\n <VStack gap={8} align='start'>\n <FormatDateTime value='2026-02-11T14:32:07' format='date' />\n <FormatDateTime value='2026-02-11T14:32:07' format='datetime' />\n <FormatDateTime value={subDays(now, 200)} format='relative' />\n </VStack>\n </DateFormatProvider>\n </VStack>\n\n <VStack gap={12} align='start'>\n <span className='sb-annotation'>Month-first, 24-hour</span>\n <DateFormatProvider order='month-first' hourCycle={24}>\n <VStack gap={8} align='start'>\n <FormatDateTime value='2026-02-11T14:32:07' format='date' />\n <FormatDateTime value='2026-02-11T14:32:07' format='datetime' />\n <FormatDateTime value={subDays(now, 200)} format='relative' />\n </VStack>\n </DateFormatProvider>\n </VStack>\n </VStack>\n)",
|
|
33064
|
+
"description": "The component respects the app's date order from `DateFormatProvider`. Day-first (the\ndefault) prints \"11 Feb, 2026\"; month-first prints \"Feb 11, 2026\". Both hour cycles\nare shown: 24-hour and 12-hour with AM/PM."
|
|
33060
33065
|
}
|
|
33061
33066
|
]
|
|
33062
33067
|
},
|
|
@@ -80231,6 +80236,11 @@
|
|
|
80231
80236
|
"name": "ShrinkToCard",
|
|
80232
80237
|
"code": "() => {\n const [visible, setVisible] = useState(true);\n\n useEffect(() => {\n if (!visible) return;\n\n const timer = window.setTimeout(() => {\n setVisible(false);\n }, 2000);\n\n return () => window.clearTimeout(timer);\n }, [visible]);\n\n return (\n <div className='relative h-screen w-screen'>\n <AnimatedBackground />\n\n <div className='absolute inset-0 flex items-center justify-center'>\n <SplashScreen\n visible={visible}\n shrinkTarget={{ width: 480, height: 600, borderRadius: 12 }}\n className='bg-bg-page-bg shadow-lg'\n >\n <div className='flex h-full flex-col items-center justify-center gap-4 p-8'>\n <h2 className='text-lg font-semibold text-text-primary'>Welcome</h2>\n <p className='text-center text-sm text-text-secondary'>\n Content revealed after splash animation.\n </p>\n <Button type='button' onClick={() => setVisible(true)}>\n Replay\n </Button>\n </div>\n </SplashScreen>\n </div>\n </div>\n );\n}",
|
|
80233
80238
|
"description": "With a `shrinkTarget` it morphs into that box and reveals its children inside — the entrance becomes the first view, typically a sign-in card."
|
|
80239
|
+
},
|
|
80240
|
+
{
|
|
80241
|
+
"name": "MeasuredHeight",
|
|
80242
|
+
"code": "() => {\n const [visible, setVisible] = useState(true);\n\n useEffect(() => {\n if (!visible) return;\n\n const timer = window.setTimeout(() => {\n setVisible(false);\n }, 2000);\n\n return () => window.clearTimeout(timer);\n }, [visible]);\n\n const handleSignIn = () => {\n setVisible(true);\n };\n\n return (\n <div className='relative h-screen w-screen'>\n <AnimatedBackground />\n\n <div className='absolute inset-0 flex items-center justify-center'>\n <SplashScreen\n visible={visible}\n shrinkTarget={{ width: 480, borderRadius: 12 }}\n className='bg-bg-page-bg shadow-lg'\n >\n <div className='flex h-full w-full flex-col items-center justify-center gap-16 p-24'>\n <Text size='xl'>Sign In</Text>\n <div className='flex w-full flex-col gap-12'>\n <Input placeholder='Email' />\n <Input placeholder='Password' type='password' />\n </div>\n <Button variant='primary' color='brand' className='w-full' onClick={handleSignIn}>\n Sign In\n </Button>\n </div>\n </SplashScreen>\n </div>\n </div>\n );\n}",
|
|
80243
|
+
"description": "The splash can measure its own content height when `shrinkTarget.height` is omitted — the animation shrinks to fit whatever you put inside, no hardcoded constant needed."
|
|
80234
80244
|
}
|
|
80235
80245
|
]
|
|
80236
80246
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wallarm-org/design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "Core design system library with React components and Storybook documentation",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|