@classic-homes/data-panel-core

中文文档
0.1.3发布于 2026/10/16TypeScriptESM + CJS零依赖近 30 天下载 1765

Core utilities and types for DataPanel components

原始使用文档
文档目录10 节
  1. Installation
  2. Quick Start
  3. API Reference
  4. Types
  5. Constants
  6. Drag Utilities
  7. Constraint Utilities
  8. Persistence Utilities
  9. Usage with React/Svelte
  10. License

@classic-homes/data-panel-core

Core utilities and types for DataPanel components. This package provides shared functionality for building flexible, draggable, resizable panels across React and Svelte implementations.

Installation

npm install @classic-homes/data-panel-core

Quick Start

import {
  // Types
  type PanelMode,
  type PanelEdge,
  type DataPanelState,

  // Default values
  DEFAULT_PANEL_STATE,
  DEFAULT_CONSTRAINTS,

  // Utilities
  constrainSize,
  constrainPosition,
  loadPanelState,
  savePanelState,
} from '@classic-homes/data-panel-core';

// Load persisted state
const persisted = loadPanelState('my-panel');
const state = mergeWithDefaults(persisted);

// Constrain panel size
const size = constrainSize({ width: 500, height: 600 }, { minWidth: 300, maxWidth: 800 });

API Reference

Types

Panel Configuration Types

type PanelMode = 'pinned' | 'detached';
type PanelEdge = 'left' | 'right' | 'top' | 'bottom';
type PanelVariant = 'full' | 'card';
type ResizeHandle =
  | 'top'
  | 'right'
  | 'bottom'
  | 'left'
  | 'top-left'
  | 'top-right'
  | 'bottom-left'
  | 'bottom-right';

State Types

interface Position {
  x: number;
  y: number;
}

interface Size {
  width: number;
  height: number;
}

interface PanelConstraints {
  minWidth?: number;
  maxWidth?: number;
  minHeight?: number;
  maxHeight?: number;
}

interface DataPanelState {
  mode: PanelMode;
  variant: PanelVariant;
  edge: PanelEdge;
  isExpanded: boolean;
  detachedPosition: Position;
  detachedSize: Size;
  pinnedSize: number;
  cardSnapIndex: number;
}

Interaction State Types

interface DragState {
  isDragging: boolean;
  startPosition: Position;
  startPanelPosition: Position;
  currentPosition: Position;
}

interface ResizeState {
  isResizing: boolean;
  handle: ResizeHandle | null;
  startPosition: Position;
  startSize: Size;
  startPanelPosition: Position;
}

interface PinnedDragState {
  isDragging: boolean;
  hasDetached: boolean;
  startPosition: Position;
  currentPosition: Position;
  edge: PanelEdge;
  pinnedSize: number;
}

Constants

Default Values

import {
  DEFAULT_PANEL_STATE, // Default DataPanelState
  DEFAULT_CONSTRAINTS, // Default PanelConstraints
  DEFAULT_CARD_CONFIG, // Default CardConfig
  DEFAULT_SNAP_POINTS, // Default snap points { peek: 0.25, half: 0.5, full: 1.0 }
} from '@classic-homes/data-panel-core';

Card Mode Constants

import {
  CARD_HEADER_HEIGHT, // 72 - Height of collapsed card header
  CARD_EXPANDED_RATIO, // 0.85 - Max height as ratio of viewport
  CARD_MIN_WIDTH, // 280 - Minimum card width
} from '@classic-homes/data-panel-core';

Drag Utilities

State Initialization

// Create initial drag state
const dragState = createDragState();

// Create initial resize state
const resizeState = createResizeState();

// Create pinned drag-to-detach state
const pinnedDragState = createPinnedDragState();

Pointer Handling

// Get position from any pointer event type
const position = getPointerPosition(event); // MouseEvent | PointerEvent | TouchEvent

// Calculate new panel position during drag
const newPosition = calculateDragPosition(dragState, currentPointer);

// Calculate new size and position during resize
const { position, size } = calculateResize(resizeState, currentPointer);

Resize Handles

// Get cursor style for a resize handle
const cursor = getResizeCursor('top-left'); // 'nwse-resize'

// Get the resize handle for a pinned panel edge
const handle = getPinnedResizeHandle('right'); // 'left'

// Get all handles for detached mode
const handles = getDetachedResizeHandles(); // ['top', 'right', 'bottom', 'left', ...]

// Check if pointer is near a resize handle
const nearHandle = isNearResizeHandle(mousePos, panelRect, threshold);

Pinned Drag-to-Detach

// Calculate distance dragged away from edge
const distance = calculateDetachDistance(startPos, currentPos, 'right');

// Calculate rubber-band pull offset
const offset = calculatePullOffset(distance, threshold, maxPull);

// Get new position when detaching
const newPos = calculateDetachedPositionFromPinned(
  pointerPos,
  pinnedSize,
  detachedSize,
  edge,
  viewportWidth,
  viewportHeight
);

// Get CSS transform for pull effect
const transform = getPinnedPullTransform(pullOffset, 'right'); // 'translateX(-10px)'

Constraint Utilities

Value Clamping

// Clamp a value between min and max
const clamped = clamp(value, min, max);

// Constrain size to min/max bounds
const size = constrainSize({ width: 1000, height: 1000 }, constraints);

// Constrain position within viewport
const pos = constrainPosition(position, size, viewportWidth, viewportHeight, padding);

// Combined size and position constraint during resize.
// Pass the active handle so left/top edges keep the opposite edge anchored
// when the size is clamped (omit it to leave position unadjusted).
const { position, size } = constrainResize(newPos, newSize, constraints, vw, vh, handle);

Pinned Panel Constraints

// Constrain width for horizontal edges (left/right)
const width = constrainPinnedWidth(width, constraints, viewportWidth, maxRatio);

// Constrain height for vertical edges (top/bottom)
const height = constrainPinnedHeight(height, constraints, viewportHeight, maxRatio);

Edge Detection

// Check if position should snap to an edge
const { shouldSnap, edge, distance } = detectEdgeSnap(
  position,
  size,
  viewportWidth,
  viewportHeight,
  threshold
);

// Edge type helpers
const isHoriz = isHorizontalEdge('left'); // true
const isVert = isVerticalEdge('top'); // true

Position Styles

// Get CSS styles for pinned panel
const styles = getPinnedPositionStyles('right', 400);
// { top: '0', right: '0', bottom: '0', width: '400px', height: '100%' }

// Get CSS styles for detached panel
const styles = getDetachedPositionStyles({ x: 100, y: 200 }, { width: 400, height: 500 });
// { top: '200px', left: '100px', width: '400px', height: '500px' }

// Get centered initial position
const pos = getInitialDetachedPosition(size, viewportWidth, viewportHeight);

Card Mode Utilities

// Calculate snap point height in pixels
const height = getSnapPointHeight(0.5, viewportHeight, headerHeight);

// Get CSS styles for card mode
const styles = getCardPositionStyles(0.5, viewportWidth, viewportHeight, cardConfig);

// Find nearest snap point to current height
const index = findNearestSnapIndex(currentHeight, viewportHeight, snapPoints);

// Determine snap based on swipe velocity
const index = getSnapIndexFromVelocity(currentIndex, velocity, snapPoints, threshold);

// Calculate drag velocity
const velocity = calculateDragVelocity(startY, endY, startTime, endTime);

// Check if card should be dismissed
const dismiss = shouldDismissCard(currentHeight, viewportHeight, threshold);

// Get labels for snap points
const labels = getSnapPointLabels([0.25, 0.5, 1.0]); // ['Peek', 'Half', 'Full']

Persistence Utilities

// Load state from localStorage
const state = loadPanelState('my-panel-key');

// Save state to localStorage
savePanelState('my-panel-key', panelState);

// Clear persisted state
clearPanelState('my-panel-key');

// Merge persisted state with defaults
const fullState = mergeWithDefaults(persisted, customDefaults);

// Create debounced save function
const debouncedSave = createDebouncedSave('my-panel-key', 300);
debouncedSave(state); // Saves after 300ms of inactivity

Usage with React/Svelte

This package is framework-agnostic and provides the core logic for DataPanel components. Use with:

  • @classic-homes/react - React DataPanel component
  • @classic-homes/svelte - Svelte DataPanel component

Both implementations use this package internally for consistent behavior.

License

MIT

版本与发布记录

@classic-homes/data-panel-core 共发布 10 个版本,首次发布于 2026/02/04;过去 12 个月发布了 10 个版本。

版本发布日期距今
0.1.3latest2026/10/1624 天前
0.1.22026/10/081 个月前
0.1.12026/08/182 个月前
0.1.02026/08/152 个月前
0.0.72026/08/142 个月前
0.0.62026/07/173 个月前

关于 @classic-homes/data-panel-core 的常见问题

@classic-homes/data-panel-core 是什么?

Core utilities and types for DataPanel components

如何安装 @classic-homes/data-panel-core?

在项目目录运行 npm install @classic-homes/data-panel-core,或使用 pnpm add / yarn add / bun add。

@classic-homes/data-panel-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@classic-homes/data-panel-core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@classic-homes/data-panel-core 可以商用吗?

@classic-homes/data-panel-core 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@classic-homes/data-panel-core 的下载量有多少?

根据 npm 官方下载统计,@classic-homes/data-panel-core 在 2026/10/10 – 2026/11/08 这 30 天内被下载 1,765 次,日均约 59 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@classic-homes/data-panel-core 还在维护吗?

最新版本 0.1.3 发布于 2026/10/16(24 天前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/02/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。