@lumx/core 4.4.1-alpha.1 → 4.4.1-alpha.2

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.
@@ -0,0 +1,11 @@
1
+ import { SetupOptions } from '../../../testing';
2
+ /**
3
+ * Mounts the component and returns common DOM elements / data needed in multiple tests further down.
4
+ */
5
+ export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
6
+ props: any;
7
+ tooltip: Element | null;
8
+ wrapper: Partial<import("../../../testing").SetupResult>;
9
+ };
10
+ declare const _default: (renderOptions: SetupOptions<any>) => void;
11
+ export default _default;
@@ -0,0 +1,10 @@
1
+ export declare const ARIA_LINK_MODES: readonly ["aria-describedby", "aria-labelledby"];
2
+ /**
3
+ * Arrow size (in pixel).
4
+ */
5
+ export declare const ARROW_SIZE = 8;
6
+ /**
7
+ * Make sure tooltip appear above popovers.
8
+ * Hardcoded as POPOVER_ZINDEX (9999) + 1.
9
+ */
10
+ export declare const TOOLTIP_ZINDEX = 10000;
@@ -0,0 +1,21 @@
1
+ export interface TooltipOpenManagerOptions {
2
+ /** Delay in millisecond to display the tooltip. */
3
+ delay?: number;
4
+ /** Callback to update the open state. */
5
+ onStateChange: (isOpen: boolean) => void;
6
+ }
7
+ export interface TooltipOpenManager {
8
+ /** Attach event listeners to the anchor element. */
9
+ attachAnchor(anchorElement: HTMLElement): void;
10
+ /** Attach event listeners to the popper element (for hover support). */
11
+ attachPopper(popperElement: HTMLElement | null): void;
12
+ /** Close the tooltip immediately (for escape key integration). */
13
+ close(): void;
14
+ /** Destroy the manager, clearing all timers and detaching events. */
15
+ destroy(): void;
16
+ }
17
+ /**
18
+ * Framework-agnostic open/close state machine for tooltip.
19
+ * Manages hover, touch, focus, timers, and escape key behavior.
20
+ */
21
+ export declare function createTooltipOpenManager(options: TooltipOpenManagerOptions): TooltipOpenManager;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Check if we are running in a true browser (not SSR and not jsdom test environment).
3
+ */
4
+ export declare const IS_BROWSER: boolean;
5
+ /**
6
+ * Optional global `window` instance (not defined when running SSR).
7
+ */
8
+ export declare const WINDOW: (Window & typeof globalThis) | undefined;
9
+ /**
10
+ * Optional global `document` instance (not defined when running SSR).
11
+ */
12
+ export declare const DOCUMENT: Document | undefined;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Check if we are running in a true browser (not SSR and not jsdom test environment).
3
+ */
4
+ const IS_BROWSER = typeof window !== 'undefined' && !window.navigator.userAgent.includes('jsdom');
5
+ /**
6
+ * Optional global `window` instance (not defined when running SSR).
7
+ */
8
+ const WINDOW = typeof window !== 'undefined' ? window : undefined;
9
+ /**
10
+ * Optional global `document` instance (not defined when running SSR).
11
+ */
12
+ const DOCUMENT = typeof document !== 'undefined' ? document : undefined;
13
+
14
+ export { DOCUMENT, IS_BROWSER, WINDOW };
@@ -2,3 +2,4 @@ export * from './keycodes';
2
2
  export * from './components';
3
3
  export * from './enums';
4
4
  export * from './className';
5
+ export * from './browser';
@@ -2,3 +2,4 @@ export { BACKSPACE_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESCAPE_KEY_CODE, LEF
2
2
  export { DIALOG_TRANSITION_DURATION, EXPANSION_PANEL_TRANSITION_DURATION, NOTIFICATION_TRANSITION_DURATION, SLIDESHOW_TRANSITION_DURATION, TOOLTIP_HOVER_DELAY, TOOLTIP_LONG_PRESS_DELAY } from './components/index.js';
3
3
  export { Alignment, AspectRatio, ColorPalette, ColorVariant, Emphasis, Kind, Orientation, REAL_SIZE_FOR_LUMX_SIZE, Size, Theme, Typography, TypographyCustom, TypographyInterface, TypographyTitleCustom, WhiteSpace } from './enums/index.js';
4
4
  export { VISUALLY_HIDDEN } from './className/index.js';
5
+ export { DOCUMENT, IS_BROWSER, WINDOW } from './browser/index.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared types and logic for ClickAway detection.
3
+ *
4
+ * ClickAway detects clicks outside a set of elements and triggers a callback.
5
+ * The core logic (event listening + target checking) is framework-agnostic.
6
+ * Framework-specific wrappers (React hook, Vue composable) and context providers
7
+ * (React context, Vue provide/inject) are implemented in each framework package.
8
+ */
9
+ import type { Falsy } from '@lumx/core/js/types';
10
+ /** Event types that trigger click away detection. */
11
+ export declare const CLICK_AWAY_EVENT_TYPES: readonly ["mousedown", "touchstart"];
12
+ /** Callback triggered when a click away is detected. */
13
+ export type ClickAwayCallback = EventListener | Falsy;
14
+ /**
15
+ * Check if the click event targets are outside all the given elements.
16
+ *
17
+ * @param targets - The event target elements (from `event.target` and `event.composedPath()`).
18
+ * @param elements - The elements considered "inside" the click away context.
19
+ * @returns `true` if the click is outside all elements (i.e. a click away).
20
+ */
21
+ export declare function isClickAway(targets: HTMLElement[], elements: HTMLElement[]): boolean;
22
+ /**
23
+ * Imperative setup for click away detection.
24
+ * Adds mousedown/touchstart listeners on `document` and calls the callback when a click
25
+ * occurs outside the elements returned by `getElements`.
26
+ *
27
+ * @param getElements - Getter returning the current list of elements considered "inside".
28
+ * @param callback - Callback to invoke on click away.
29
+ * @returns A teardown function that removes the event listeners.
30
+ */
31
+ export declare function setupClickAway(getElements: () => HTMLElement[], callback: ClickAwayCallback): (() => void) | undefined;
@@ -0,0 +1,25 @@
1
+ import type { Screen } from '@testing-library/dom';
2
+ import type { PortalInit } from '.';
3
+ export interface PortalTestOptions {
4
+ screen: Screen;
5
+ /**
6
+ * Render Portal with a child element (a div with `data-testid="portal-child"` containing "Hello from portal").
7
+ * Return the render result (must have a `container` property for wrapper queries and `unmount` for cleanup).
8
+ */
9
+ renderPortal(options: {
10
+ enabled?: boolean;
11
+ /** Wrap the Portal in a PortalProvider with this value */
12
+ portalInit?: PortalInit;
13
+ /** Wrap the Portal + PortalProvider in a div#wrapper */
14
+ wrapInDiv?: boolean;
15
+ }): {
16
+ container: Element;
17
+ unmount: () => void;
18
+ };
19
+ }
20
+ /**
21
+ * Shared Portal + PortalProvider tests.
22
+ * Framework-specific render logic is injected via `renderPortal`.
23
+ */
24
+ declare const _default: ({ screen, renderPortal }: PortalTestOptions) => void;
25
+ export default _default;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared types for Portal and PortalProvider.
3
+ *
4
+ * Portal renders children in a subtree outside the current DOM hierarchy.
5
+ * PortalProvider customizes where Portal children render.
6
+ *
7
+ * Unlike other core components, Portal has no shared render function
8
+ * since the implementation is entirely framework-specific
9
+ * (React's createPortal vs Vue's Teleport).
10
+ */
11
+ export type Container = DocumentFragment | Element | string;
12
+ /**
13
+ * Portal initializing function.
14
+ * If it does not provide a container, the Portal children will render in the standard component tree and not in a portal.
15
+ */
16
+ export type PortalInit = () => {
17
+ container?: Container;
18
+ teardown?: () => void;
19
+ };
20
+ export interface PortalProps {
21
+ enabled?: boolean;
22
+ }
23
+ export interface PortalProviderProps {
24
+ value: PortalInit;
25
+ }
@@ -0,0 +1,2 @@
1
+ /** Check if the focus is visible on the given element */
2
+ export declare const isFocusVisible: (element?: HTMLElement) => boolean | undefined;
@@ -0,0 +1,2 @@
1
+ /** Return true if the browser does not support pointer hover */
2
+ export declare const isHoverNotSupported: () => boolean;
@@ -1,4 +1,5 @@
1
1
  import { ColorVariant } from '../../../constants/enums/index.js';
2
+ import '../../../constants/browser/index.js';
2
3
  import { resolveColorWithVariants } from '../../../../_internal/DPnPEC08.js';
3
4
 
4
5
  /**
@@ -1,5 +1,6 @@
1
1
  import '../../../constants/enums/index.js';
2
2
  import { VISUALLY_HIDDEN } from '../../../constants/className/index.js';
3
+ import '../../../constants/browser/index.js';
3
4
 
4
5
  /**
5
6
  * Visually hidden class name.
@@ -0,0 +1,13 @@
1
+ export type Listener = {
2
+ enable(): void;
3
+ disable(): void;
4
+ };
5
+ /**
6
+ * Keep track of listeners, only the last registered listener gets activated at any point (previously registered
7
+ * listener are disabled).
8
+ * When a listener gets unregistered, the previously registered listener gets enabled again.
9
+ */
10
+ export declare function makeListenerTowerContext(): {
11
+ register(listener: Listener): void;
12
+ unregister(listener: Listener): void;
13
+ };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/lumapps/design-system/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@lumx/icons": "^4.4.1-alpha.1",
9
+ "@lumx/icons": "^4.4.1-alpha.2",
10
10
  "classnames": "^2.3.2",
11
11
  "focus-visible": "^5.0.2",
12
12
  "lodash": "4.17.23",
@@ -66,7 +66,7 @@
66
66
  "update-version-changelog": "yarn version-changelog ../../CHANGELOG.md"
67
67
  },
68
68
  "sideEffects": false,
69
- "version": "4.4.1-alpha.1",
69
+ "version": "4.4.1-alpha.2",
70
70
  "devDependencies": {
71
71
  "@rollup/plugin-typescript": "^12.3.0",
72
72
  "@testing-library/dom": "^10.4.1",
@@ -13,6 +13,13 @@ interface StoryDecorators {
13
13
  withNestedProps?: () => Decorator;
14
14
  /** Decorator wrapping story in a resizable box */
15
15
  withResizableBox?: (options?: Record<string, any>) => Decorator;
16
+ /** Decorator managing a local state for a value prop, updating it via onChange */
17
+ withValueOnChange?: (options?: {
18
+ valueProp?: string;
19
+ valueTransform?: (v: any) => any;
20
+ }) => Decorator;
21
+ /** Decorator forcing a minimum screen size for Chromatic snapshots */
22
+ withChromaticForceScreenSize?: () => Decorator;
16
23
  }
17
24
  /** A partial Storybook story object (args, argTypes, render, decorators, etc.) */
18
25
  type StoryOverride = Record<string, any>;