@synopackageland/ui 0.20.2 → 0.20.4
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/CHANGELOG.md +26 -0
- package/LICENSES/ux-foundation.md +83 -0
- package/LICENSES/ux-grid-baserow.md +35 -0
- package/LICENSES/ux-grid-teable.md +48 -0
- package/README.md +3 -0
- package/dist/cli.js +0 -0
- package/dist/components/app/app-layout/AppLayout.vue.d.ts +31 -4
- package/dist/components/app/app-root/AppRoot.vue.d.ts +9 -0
- package/dist/components/app/aside-panel/AsidePanel.vue.d.ts +69 -0
- package/dist/components/app/aside-panel/asidePreference.d.ts +28 -0
- package/dist/components/composite/adaptive-panel/AdaptivePanel.vue.d.ts +61 -0
- package/dist/components/composite/connection-topology/ConnectionTopology.vue.d.ts +1 -1
- package/dist/components/composite/data-grid/DataGrid.vue.d.ts +3 -2
- package/dist/components/composite/data-grid/viewState.d.ts +2 -2
- package/dist/components/composite/file-picker/FilePicker.vue.d.ts +1 -1
- package/dist/components/composite/mention-list/MentionList.vue.d.ts +2 -2
- package/dist/components/composite/overflow-toolbar/OverflowToolbar.vue.d.ts +2 -2
- package/dist/components/composite/record-panel/RecordPanel.vue.d.ts +77 -0
- package/dist/components/composite/record-panel/recordPanelWidth.d.ts +54 -0
- package/dist/components/composite/summary-card/SummaryCard.vue.d.ts +1 -1
- package/dist/components/composite/tag-editor/TagEditor.vue.d.ts +2 -2
- package/dist/components/composite/tree-view/TreeView.vue.d.ts +1 -1
- package/dist/components/composite/wizard/Wizard.vue.d.ts +2 -2
- package/dist/components/composite/wizard/WizardDialog.vue.d.ts +2 -2
- package/dist/components/containers/card/Card.vue.d.ts +1 -1
- package/dist/components/containers/card/CardField.vue.d.ts +26 -0
- package/dist/components/containers/card-grid/CardCover.vue.d.ts +16 -0
- package/dist/components/containers/card-grid/CardGrid.vue.d.ts +1 -1
- package/dist/components/containers/card-grid/VirtualCardGrid.vue.d.ts +71 -0
- package/dist/components/containers/expandable-item/ExpandableItem.vue.d.ts +1 -1
- package/dist/components/containers/fieldset/Fieldset.vue.d.ts +1 -1
- package/dist/components/containers/list-detail/ListDetail.vue.d.ts +1 -1
- package/dist/components/containers/split-pane/SplitPane.vue.d.ts +1 -1
- package/dist/components/feedback/notification/Notification.vue.d.ts +1 -1
- package/dist/components/feedback/notification/NotificationProvider.vue.d.ts +1 -1
- package/dist/components/primitives/breadcrumb/Breadcrumb.vue.d.ts +2 -2
- package/dist/components/primitives/context-menu/ContextMenu.vue.d.ts +3 -0
- package/dist/components/primitives/context-menu/ContextMenuItems.vue.d.ts +4 -5
- package/dist/components/primitives/dialog/Dialog.vue.d.ts +2 -2
- package/dist/components/primitives/dropdown-menu/DropdownMenu.vue.d.ts +4 -0
- package/dist/components/primitives/dropdown-menu/DropdownMenuItems.vue.d.ts +6 -3
- package/dist/components/primitives/popover/Popover.vue.d.ts +10 -2
- package/dist/components/primitives/popover/floating.d.ts +27 -0
- package/dist/components/primitives/popover/overlay.d.ts +36 -0
- package/dist/components/primitives/segment-control/SegmentControl.vue.d.ts +4 -1
- package/dist/components/primitives/segment-control/context.d.ts +3 -0
- package/dist/components/primitives/select/Select.vue.d.ts +4 -0
- package/dist/components/primitives/select/internal/ComboboxField.vue.d.ts +1 -0
- package/dist/components/primitives/select/internal/types.d.ts +2 -0
- package/dist/components/primitives/skeleton/SectionSkeleton.vue.d.ts +25 -4
- package/dist/components/primitives/skeleton/Skeleton.vue.d.ts +3 -0
- package/dist/components/primitives/tag/Tag.vue.d.ts +2 -2
- package/dist/components/primitives/toast/ToastProvider.vue.d.ts +0 -2
- package/dist/components/primitives/toast/toast.d.ts +21 -1
- package/dist/components/primitives/tooltip/Tooltip.vue.d.ts +8 -3
- package/dist/components/primitives/tooltip/tooltipStyle.d.ts +11 -1
- package/dist/composables/backDismiss.d.ts +19 -0
- package/dist/composables/phone.d.ts +8 -0
- package/dist/composables/softKeyboard.d.ts +26 -4
- package/dist/composables/visualViewport.d.ts +31 -0
- package/dist/dnd/autoScroll.d.ts +57 -0
- package/dist/dnd/dragKit.d.ts +111 -0
- package/dist/dnd/index.d.ts +4 -0
- package/dist/dnd/layout.d.ts +57 -0
- package/dist/dnd/vue.d.ts +16 -0
- package/dist/feedback/StatusSlot.vue.d.ts +24 -0
- package/dist/feedback/showAfter.d.ts +15 -0
- package/dist/feedback/stackMotion.d.ts +13 -0
- package/dist/feedback/timing.d.ts +23 -0
- package/dist/grid/cells/draw.d.ts +57 -0
- package/dist/grid/cells/images.d.ts +5 -0
- package/dist/grid/cells/index.d.ts +7 -0
- package/dist/grid/cells/number.d.ts +5 -0
- package/dist/grid/cells/registry.d.ts +56 -0
- package/dist/grid/cells/renderers.d.ts +8 -0
- package/dist/grid/cells/status.d.ts +6 -0
- package/dist/grid/cells/types.d.ts +200 -0
- package/dist/grid/cells/use.d.ts +7 -0
- package/dist/grid/clipboard/copy.d.ts +17 -0
- package/dist/grid/clipboard/index.d.ts +4 -0
- package/dist/grid/clipboard/proposal.d.ts +35 -0
- package/dist/grid/clipboard/tsv.d.ts +14 -0
- package/dist/grid/clipboard/write.d.ts +21 -0
- package/dist/grid/contracts.d.ts +200 -0
- package/dist/grid/edit/cell-status.d.ts +33 -0
- package/dist/grid/edit/edit-session.d.ts +97 -0
- package/dist/grid/edit/use-grid-edit.d.ts +48 -0
- package/dist/grid/focus/editor-style.d.ts +67 -0
- package/dist/grid/host/GridHost.vue.d.ts +137 -0
- package/dist/grid/host/controller.d.ts +219 -0
- package/dist/grid/host/dom.d.ts +10 -0
- package/dist/grid/index.d.ts +8 -0
- package/dist/grid/range/block.d.ts +30 -0
- package/dist/grid/range/fill.d.ts +27 -0
- package/dist/grid/range/index.d.ts +2 -0
- package/dist/grid/theme.d.ts +61 -0
- package/dist/grid-core/auto-scroll.d.ts +67 -0
- package/dist/grid-core/column-resize.d.ts +43 -0
- package/dist/grid-core/config.d.ts +39 -0
- package/dist/grid-core/coordinate.d.ts +64 -0
- package/dist/grid-core/drag.d.ts +46 -0
- package/dist/grid-core/freeze.d.ts +11 -0
- package/dist/grid-core/index.d.ts +17 -0
- package/dist/grid-core/keyboard.d.ts +34 -0
- package/dist/grid-core/keys.d.ts +38 -0
- package/dist/grid-core/lru.d.ts +10 -0
- package/dist/grid-core/range.d.ts +28 -0
- package/dist/grid-core/region.d.ts +73 -0
- package/dist/grid-core/renderer/base.d.ts +92 -0
- package/dist/grid-core/renderer/layout.d.ts +129 -0
- package/dist/grid-core/selection-controller.d.ts +62 -0
- package/dist/grid-core/selection.d.ts +35 -0
- package/dist/grid-core/theme.d.ts +81 -0
- package/dist/grid-core/types.d.ts +178 -0
- package/dist/grid.js +6173 -0
- package/dist/i18n/text.d.ts +6 -0
- package/dist/index.d.ts +32 -2
- package/dist/index.js +17662 -13637
- package/dist/interaction/editSession.d.ts +49 -0
- package/dist/interaction/focus.d.ts +28 -0
- package/dist/interaction/gesture.d.ts +49 -0
- package/dist/interaction/ime.d.ts +55 -0
- package/dist/interaction/index.d.ts +6 -0
- package/dist/interaction/outside.d.ts +40 -0
- package/dist/interaction/vue.d.ts +21 -0
- package/dist/json-ai-prompt.md +1 -1
- package/dist/json-preview/preview.js +8529 -7812
- package/dist/json.js +10 -10
- package/dist/lib/adaptiveLayout.d.ts +32 -2
- package/dist/lib/deviceViewport.d.ts +2 -1
- package/dist/lib/motion.d.ts +12 -0
- package/dist/reka-runtime.json +1 -1
- package/dist/theme.css +1 -1
- package/dist/themes/dsm7-embedded-theme.css +1 -1
- package/dist/themes/dsm7-embedded.css +1 -1
- package/dist/themes/dsm7.css +1 -1
- package/dist/virtual/cardHeight.d.ts +39 -0
- package/dist/virtual/galleryColumns.d.ts +11 -0
- package/dist/virtual/layoutMotion.d.ts +30 -0
- package/docs/adaptive-layout.md +137 -16
- package/docs/callout.md +22 -1
- package/docs/list-detail.md +54 -0
- package/docs/mobile-native.md +214 -0
- package/docs/release-checks.md +23 -0
- package/docs/theme-hooks.md +28 -7
- package/docs/ux-foundation.md +133 -0
- package/docs/ux-grid.md +217 -0
- package/package.json +94 -3
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GridCellRange } from './block';
|
|
2
|
+
export type GridFillDirection = 'down' | 'up';
|
|
3
|
+
/**
|
|
4
|
+
* A finished fill-handle drag. The grid never writes data: the caller reads
|
|
5
|
+
* `source`, builds the values (for example with `fillSeries`), writes `target`
|
|
6
|
+
* as one undoable change and saves in the background.
|
|
7
|
+
*/
|
|
8
|
+
export interface GridFillRequest {
|
|
9
|
+
/** The selected block the drag started from. */
|
|
10
|
+
source: GridCellRange;
|
|
11
|
+
/** The new rows only, same columns as `source`. */
|
|
12
|
+
target: GridCellRange;
|
|
13
|
+
direction: GridFillDirection;
|
|
14
|
+
}
|
|
15
|
+
/** The fill for a drag that ends on `targetRow`; null when the pointer is still inside the source rows. */
|
|
16
|
+
export declare const planFill: (source: GridCellRange, targetRow: number, rowCount: number) => GridFillRequest | null;
|
|
17
|
+
/** Source and target together: the selection after a fill. */
|
|
18
|
+
export declare const filledRange: (fill: GridFillRequest) => GridCellRange;
|
|
19
|
+
export type GridFillValue = string | number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Values for one column of a fill, in target row order (top to bottom).
|
|
22
|
+
* `source` is the column's source values, top to bottom. With two or more
|
|
23
|
+
* numbers that are not all equal, the steps between them repeat (1, 2 → 3, 4;
|
|
24
|
+
* a date passed as epoch milliseconds steps the same way). Anything else
|
|
25
|
+
* repeats the source block. An upward fill mirrors both rules.
|
|
26
|
+
*/
|
|
27
|
+
export declare const fillSeries: (source: readonly GridFillValue[], count: number, direction?: GridFillDirection) => GridFillValue[];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { GridCellMetrics, GridChipTone } from './cells/types';
|
|
2
|
+
export interface GridChipColors {
|
|
3
|
+
fill: string;
|
|
4
|
+
color: string;
|
|
5
|
+
}
|
|
6
|
+
export interface GridCellTheme {
|
|
7
|
+
text: string;
|
|
8
|
+
textMuted: string;
|
|
9
|
+
link: string;
|
|
10
|
+
danger: string;
|
|
11
|
+
/** Saving dot. */
|
|
12
|
+
pending: string;
|
|
13
|
+
/** Ring drawn around the saving dot so it reads on any fill. */
|
|
14
|
+
surface: string;
|
|
15
|
+
checkboxOn: string;
|
|
16
|
+
checkboxMark: string;
|
|
17
|
+
checkboxOff: string;
|
|
18
|
+
ratingOn: string;
|
|
19
|
+
ratingOff: string;
|
|
20
|
+
progressTrack: string;
|
|
21
|
+
progressFill: string;
|
|
22
|
+
buttonFill: string;
|
|
23
|
+
buttonText: string;
|
|
24
|
+
buttonBorder: string;
|
|
25
|
+
avatarFill: string;
|
|
26
|
+
avatarText: string;
|
|
27
|
+
badgeFill: string;
|
|
28
|
+
badgeText: string;
|
|
29
|
+
chips: Record<GridChipTone, GridChipColors>;
|
|
30
|
+
/** 'light' or 'dark', for caches keyed by theme. */
|
|
31
|
+
themeKey: string;
|
|
32
|
+
}
|
|
33
|
+
type GridCellColorKey = Exclude<keyof GridCellTheme, 'chips' | 'themeKey'>;
|
|
34
|
+
/** Which token feeds each colour. */
|
|
35
|
+
export declare const GRID_CELL_TOKENS: Record<GridCellColorKey, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Chip tones use the badge token pairs, which have dark values. The scale
|
|
38
|
+
* names are aliases of the matching tone (blue = info, green = success,
|
|
39
|
+
* orange = warning, red = danger, gray = neutral).
|
|
40
|
+
*/
|
|
41
|
+
export declare const GRID_CHIP_TOKENS: Record<GridChipTone, {
|
|
42
|
+
fill: string;
|
|
43
|
+
color: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** DSM 7 light values, used only where a token is missing (tests, a page without theme.css). */
|
|
46
|
+
export declare const defaultGridCellTheme: GridCellTheme;
|
|
47
|
+
/** Resolved colour of a token, or empty/undefined when the token is not set. */
|
|
48
|
+
export type GridCellTokenSource = (token: string) => string | undefined;
|
|
49
|
+
export declare const createGridCellTheme: (source: GridCellTokenSource, overrides?: Partial<GridCellTheme>) => GridCellTheme;
|
|
50
|
+
/**
|
|
51
|
+
* Cell colours in effect on `el`, each resolved to `rgb()`/`rgba()` through a
|
|
52
|
+
* hidden probe so canvas never sees `var()` or `color-mix()`. Call again after
|
|
53
|
+
* the app switches theme (alongside the host's `refreshTheme`).
|
|
54
|
+
*/
|
|
55
|
+
export declare const readGridCellTheme: (el: Element, overrides?: Partial<GridCellTheme>) => GridCellTheme;
|
|
56
|
+
/**
|
|
57
|
+
* Sizes for a row height: chips and avatars leave 4 px above and below (20 px
|
|
58
|
+
* in a 28 px row, 16 px in a 24 px row), icons stay 16 px down to 24 px rows.
|
|
59
|
+
*/
|
|
60
|
+
export declare const gridCellMetrics: (rowHeight: number, fontSize?: number, chipFontSize?: number) => GridCellMetrics;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DragRegionType, IPosition, IScrollDirection } from './types';
|
|
2
|
+
/** Edge zone in px. */
|
|
3
|
+
export declare const AUTO_SCROLL_THRESHOLD = 30;
|
|
4
|
+
/** Top speed in px per ms (2000 px/s). */
|
|
5
|
+
export declare const AUTO_SCROLL_MAX_PX_PER_MS = 2;
|
|
6
|
+
/** Time from rest to top speed in ms. */
|
|
7
|
+
export declare const AUTO_SCROLL_MS_TO_FULL_SPEED = 1200;
|
|
8
|
+
export interface IAutoScrollBounds {
|
|
9
|
+
containerWidth: number;
|
|
10
|
+
containerHeight: number;
|
|
11
|
+
/** Row header plus frozen columns; pointers over frozen columns do not scroll, so they stay targets. */
|
|
12
|
+
freezeRegionWidth: number;
|
|
13
|
+
/** Row header width. */
|
|
14
|
+
columnInitSize: number;
|
|
15
|
+
/** Column header height. */
|
|
16
|
+
rowInitSize: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Scroll direction for a pointer at `position` (relative to the grid's
|
|
20
|
+
* top-left). Right/bottom: within 30 px of the edge or beyond it. Left/top:
|
|
21
|
+
* within 30 px past the frozen columns / header, over the row header or header,
|
|
22
|
+
* or beyond the grid. Teable stops when the pointer passes over the header or
|
|
23
|
+
* leaves the grid on the left or top; we keep scrolling there.
|
|
24
|
+
* `dragType` limits a row drag to y and a column drag to x.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getAutoScrollDirection: (position: IPosition, bounds: IAutoScrollBounds, dragType?: DragRegionType, threshold?: number) => [IScrollDirection, IScrollDirection];
|
|
27
|
+
/**
|
|
28
|
+
* One frame of Teable's ramp: `speed = min(1, speed + dt/1200)`, then
|
|
29
|
+
* `px = speed · dt · 2`. Teable floors `px` every frame; with `carry` the
|
|
30
|
+
* fractional part moves to the next frame instead, so the distance does not
|
|
31
|
+
* depend on the refresh rate.
|
|
32
|
+
*/
|
|
33
|
+
export declare const autoScrollStep: (speed: number, dt: number, carry?: number) => {
|
|
34
|
+
speed: number;
|
|
35
|
+
motion: number;
|
|
36
|
+
carry: number;
|
|
37
|
+
};
|
|
38
|
+
export interface IAutoScrollerOptions {
|
|
39
|
+
getBounds: () => IAutoScrollBounds;
|
|
40
|
+
scrollBy: (deltaX: number, deltaY: number) => void;
|
|
41
|
+
/** After each scroll; re-derive the selection head from the last pointer here. */
|
|
42
|
+
onTick?: (deltaX: number, deltaY: number) => void;
|
|
43
|
+
/** Default true. False floors each frame exactly as Teable does. */
|
|
44
|
+
carryFraction?: boolean;
|
|
45
|
+
requestFrame?: (callback: (time: number) => void) => number;
|
|
46
|
+
cancelFrame?: (id: number) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Edge auto-scroll while drag-selecting, filling or dragging. Call `update`
|
|
50
|
+
* on every pointer move and `stop` on release or cancel. The speed ramps from
|
|
51
|
+
* 0 while the pointer stays in a zone and resets when it leaves all zones.
|
|
52
|
+
*/
|
|
53
|
+
export declare class AutoScroller {
|
|
54
|
+
direction: [IScrollDirection, IScrollDirection];
|
|
55
|
+
private speed;
|
|
56
|
+
private carry;
|
|
57
|
+
private lastTime;
|
|
58
|
+
private frameId;
|
|
59
|
+
private readonly options;
|
|
60
|
+
constructor(options: IAutoScrollerOptions);
|
|
61
|
+
get isRunning(): boolean;
|
|
62
|
+
update(position: IPosition, dragType?: DragRegionType): void;
|
|
63
|
+
stop(): void;
|
|
64
|
+
private readonly processFrame;
|
|
65
|
+
private request;
|
|
66
|
+
private cancel;
|
|
67
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CoordinateManager } from './coordinate';
|
|
2
|
+
import { IColumnResizeState, IMouseState, IScrollState } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* The column a resize zone belongs to. The zone straddles a column edge; its
|
|
5
|
+
* left half belongs to the previous column.
|
|
6
|
+
*/
|
|
7
|
+
export declare const resolveResizeColumnIndex: (coordInstance: CoordinateManager, scrollLeft: number, x: number, columnIndex: number) => number;
|
|
8
|
+
export interface IColumnResizeControllerOptions {
|
|
9
|
+
coordInstance: () => CoordinateManager;
|
|
10
|
+
scrollState: () => Pick<IScrollState, 'scrollLeft'>;
|
|
11
|
+
/** Minimum width, per column if a function. Default 100 px (Teable). */
|
|
12
|
+
minWidth?: number | ((columnIndex: number) => number);
|
|
13
|
+
/** Every width change while dragging, and the restored width on cancel. */
|
|
14
|
+
onResize?: (width: number, columnIndex: number) => void;
|
|
15
|
+
onChange?: (state: IColumnResizeState, hoveredIndex: number) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Column resize as a state machine: hover a resize zone → press (`start`) →
|
|
19
|
+
* live width on every move → release (`end`) or Esc (`cancel`, restores the
|
|
20
|
+
* width at the press). The width follows the pointer from the press point, so
|
|
21
|
+
* hitting the minimum and coming back does not drift.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ColumnResizeController {
|
|
24
|
+
state: IColumnResizeState;
|
|
25
|
+
hoveredIndex: number;
|
|
26
|
+
private pressed;
|
|
27
|
+
private readonly options;
|
|
28
|
+
constructor(options: IColumnResizeControllerOptions);
|
|
29
|
+
get isResizing(): boolean;
|
|
30
|
+
private emit;
|
|
31
|
+
private minWidth;
|
|
32
|
+
/** On pointerdown; returns false unless the pointer is on a resize zone. */
|
|
33
|
+
start(mouseState: Pick<IMouseState, 'type' | 'columnIndex' | 'x'>): boolean;
|
|
34
|
+
/** On pointermove: resizes while pressed, otherwise tracks which edge is hovered. */
|
|
35
|
+
move(mouseState: Pick<IMouseState, 'type' | 'columnIndex' | 'x'>): void;
|
|
36
|
+
/** On pointerup; returns the final width and column, or null when not resizing. */
|
|
37
|
+
end(): {
|
|
38
|
+
width: number;
|
|
39
|
+
columnIndex: number;
|
|
40
|
+
} | null;
|
|
41
|
+
/** Esc while resizing: puts the width back. */
|
|
42
|
+
cancel(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { RegionType, IColumnFreezeState, IColumnResizeState, IDragState, IMouseState, IScrollState } from './types';
|
|
2
|
+
/** Geometry constants in CSS pixels. Row and header heights are defaults; the host passes its density's values to the coordinate manager. */
|
|
3
|
+
export declare const GRID_DEFAULT: {
|
|
4
|
+
readonly rowHeight: 32;
|
|
5
|
+
readonly rowHeadWidth: 70;
|
|
6
|
+
readonly rowHeadIconPaddingTop: 8;
|
|
7
|
+
readonly groupHeaderHeight: 48;
|
|
8
|
+
readonly columnWidth: 150;
|
|
9
|
+
readonly columnHeadHeight: 32;
|
|
10
|
+
readonly columnHeadMenuSize: 12;
|
|
11
|
+
readonly columnHeadMenuClickableSize: 20;
|
|
12
|
+
readonly columnHeadPadding: 8;
|
|
13
|
+
readonly columnAppendBtnWidth: 100;
|
|
14
|
+
readonly columnResizeHandlerWidth: 5;
|
|
15
|
+
readonly columnResizeHandlerPaddingTop: 4;
|
|
16
|
+
readonly columnFreezeHandlerWidth: 8;
|
|
17
|
+
readonly columnFreezeHandlerHeight: 30;
|
|
18
|
+
/** Teable's hard-coded minimum while resizing. */
|
|
19
|
+
readonly columnMinWidth: 100;
|
|
20
|
+
readonly cellHorizontalPadding: 8;
|
|
21
|
+
readonly cellVerticalPaddingXS: 3;
|
|
22
|
+
readonly cellVerticalPaddingSM: 6;
|
|
23
|
+
readonly cellVerticalPaddingMD: 10;
|
|
24
|
+
readonly cellVerticalPaddingLG: 16;
|
|
25
|
+
readonly cellTextLineHeight: 22;
|
|
26
|
+
readonly fillHandlerSize: 5;
|
|
27
|
+
readonly fillHandlerPadding: 8;
|
|
28
|
+
readonly scrollBuffer: 100;
|
|
29
|
+
readonly cellScrollBuffer: 16;
|
|
30
|
+
/** Pointer travel before a header or row drag starts. */
|
|
31
|
+
readonly dragThreshold: 5;
|
|
32
|
+
};
|
|
33
|
+
export declare const DEFAULT_MOUSE_STATE: IMouseState;
|
|
34
|
+
export declare const DEFAULT_SCROLL_STATE: IScrollState;
|
|
35
|
+
export declare const DEFAULT_COLUMN_RESIZE_STATE: IColumnResizeState;
|
|
36
|
+
export declare const DEFAULT_DRAG_STATE: IDragState;
|
|
37
|
+
export declare const DEFAULT_FREEZE_COLUMN_STATE: IColumnFreezeState;
|
|
38
|
+
/** Regions that count as hovering a row, for the row tint. */
|
|
39
|
+
export declare const ROW_RELATED_REGIONS: ReadonlySet<RegionType>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ItemType, ICellMetaData, ICellMetaDataMap, ICoordinate, IIndicesMap } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Row and column geometry by arithmetic. Offsets are prefix sums computed
|
|
4
|
+
* lazily up to the furthest index asked for and cached; finding the index at
|
|
5
|
+
* an offset is a binary search over the cached part, or an exponential search
|
|
6
|
+
* past it, so hit-testing never reads the DOM.
|
|
7
|
+
*
|
|
8
|
+
* Offsets include `rowInitSize` (header height) and `columnInitSize` (row
|
|
9
|
+
* header width). Change sizes through `refreshRowDimensions` /
|
|
10
|
+
* `refreshColumnDimensions` so the cache is cleared.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CoordinateManager {
|
|
13
|
+
protected defaultRowHeight: number;
|
|
14
|
+
protected defaultColumnWidth: number;
|
|
15
|
+
pureRowCount: number;
|
|
16
|
+
rowCount: number;
|
|
17
|
+
columnCount: number;
|
|
18
|
+
private _containerWidth;
|
|
19
|
+
private _containerHeight;
|
|
20
|
+
rowHeightMap: IIndicesMap;
|
|
21
|
+
columnWidthMap: IIndicesMap;
|
|
22
|
+
rowInitSize: number;
|
|
23
|
+
columnInitSize: number;
|
|
24
|
+
lastRowIndex: number;
|
|
25
|
+
lastColumnIndex: number;
|
|
26
|
+
rowMetaDataMap: ICellMetaDataMap;
|
|
27
|
+
columnMetaDataMap: ICellMetaDataMap;
|
|
28
|
+
private _freezeColumnCount;
|
|
29
|
+
constructor({ rowHeight, columnWidth, rowCount, pureRowCount, columnCount, containerWidth, containerHeight, rowInitSize, columnInitSize, rowHeightMap, columnWidthMap, freezeColumnCount, }: ICoordinate);
|
|
30
|
+
/** Width of the row header plus the frozen columns. */
|
|
31
|
+
get freezeRegionWidth(): number;
|
|
32
|
+
get freezeColumnCount(): number;
|
|
33
|
+
set freezeColumnCount(count: number);
|
|
34
|
+
get containerWidth(): number;
|
|
35
|
+
set containerWidth(width: number);
|
|
36
|
+
get containerHeight(): number;
|
|
37
|
+
set containerHeight(height: number);
|
|
38
|
+
get columnWidth(): number;
|
|
39
|
+
set columnWidth(width: number);
|
|
40
|
+
get rowHeight(): number;
|
|
41
|
+
set rowHeight(height: number);
|
|
42
|
+
get totalWidth(): number;
|
|
43
|
+
get totalHeight(): number;
|
|
44
|
+
getRowHeight(index: number): number;
|
|
45
|
+
getColumnWidth(index: number): number;
|
|
46
|
+
/** Offset and size of one row or column, extending the prefix-sum cache up to `index` when needed. */
|
|
47
|
+
getCellMetaData(index: number, itemType: ItemType): ICellMetaData;
|
|
48
|
+
private findNearestCellIndexLinear;
|
|
49
|
+
private findNearestCellIndexBinary;
|
|
50
|
+
/** Index of the row or column that contains `offset` (in content coordinates, headers included). */
|
|
51
|
+
findNearestCellIndex(offset: number, itemType: ItemType): number;
|
|
52
|
+
getRowStartIndex(scrollTop: number): number;
|
|
53
|
+
getRowStopIndex(startIndex: number, scrollTop: number): number;
|
|
54
|
+
getColumnStartIndex(scrollLeft: number): number;
|
|
55
|
+
getColumnStopIndex(startIndex: number, scrollLeft: number): number;
|
|
56
|
+
getRowOffset(rowIndex: number): number;
|
|
57
|
+
getColumnOffset(columnIndex: number): number;
|
|
58
|
+
/** Column x on screen: frozen columns ignore horizontal scroll. */
|
|
59
|
+
getColumnRelativeOffset(columnIndex: number, scrollLeft: number): number;
|
|
60
|
+
refreshColumnDimensions({ columnCount, columnInitSize, columnWidthMap }: Pick<ICoordinate, 'columnCount' | 'columnInitSize' | 'columnWidthMap'>): void;
|
|
61
|
+
refreshRowDimensions({ rowCount, pureRowCount, rowInitSize, rowHeightMap, rowHeight }: Pick<ICoordinate, 'rowCount' | 'pureRowCount' | 'rowInitSize' | 'rowHeightMap'> & {
|
|
62
|
+
rowHeight?: number;
|
|
63
|
+
}): void;
|
|
64
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CoordinateManager } from './coordinate';
|
|
2
|
+
import { CombinedSelection } from './selection';
|
|
3
|
+
import { DragRegionType, DraggableType, IDragState, IMouseState, IPosition, IRange, IScrollState } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Drop index for a pointer: the hovered column (row) when the pointer is on its
|
|
6
|
+
* leading half, the next one otherwise. The index is where the dragged items
|
|
7
|
+
* land, counted before they are removed.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getDropTargetIndex: (coordInstance: CoordinateManager, position: IPosition, scrollState: Pick<IScrollState, "scrollLeft" | "scrollTop">, dragType: DragRegionType) => number;
|
|
10
|
+
export interface IDragControllerOptions {
|
|
11
|
+
coordInstance: () => CoordinateManager;
|
|
12
|
+
scrollState: () => Pick<IScrollState, 'scrollLeft' | 'scrollTop'>;
|
|
13
|
+
selection: () => CombinedSelection;
|
|
14
|
+
draggable?: DraggableType;
|
|
15
|
+
/** Pointer travel before a press becomes a drag. */
|
|
16
|
+
threshold?: number;
|
|
17
|
+
onChange?: (state: IDragState) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Column-header and row-handle drag as a state machine:
|
|
21
|
+
* idle → pressed (`start`) → dragging (after 5 px along the drag axis) → drop
|
|
22
|
+
* (`end`) or cancel (`cancel`, for Esc). A press that never passes the
|
|
23
|
+
* threshold is a click. Dragging a header or row inside the current
|
|
24
|
+
* column/row selection drags the whole selection.
|
|
25
|
+
*/
|
|
26
|
+
export declare class DragController {
|
|
27
|
+
state: IDragState;
|
|
28
|
+
private startPosition;
|
|
29
|
+
private readonly options;
|
|
30
|
+
constructor(options: IDragControllerOptions);
|
|
31
|
+
private setState;
|
|
32
|
+
/** On pointerdown. Returns the drag type and ranges when the press can start a drag. */
|
|
33
|
+
start(mouseState: Pick<IMouseState, 'type' | 'rowIndex' | 'columnIndex' | 'x' | 'y'>): {
|
|
34
|
+
type: DragRegionType;
|
|
35
|
+
ranges: IRange[];
|
|
36
|
+
} | null;
|
|
37
|
+
/** On pointermove. Flips to dragging once the pointer has moved the threshold along the drag axis. */
|
|
38
|
+
move(position: IPosition): void;
|
|
39
|
+
/**
|
|
40
|
+
* On pointerup. Calls `onDrop` with the dragged ranges and the drop index
|
|
41
|
+
* unless the drop lands inside the dragged block; always resets.
|
|
42
|
+
*/
|
|
43
|
+
end(position: IPosition, onDrop?: (ranges: IRange[], dropIndex: number) => void): void;
|
|
44
|
+
/** Esc while pressed or dragging: nothing moves. */
|
|
45
|
+
cancel(): void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Width the scrolling columns keep at least; frozen columns that would take more stop freezing. */
|
|
2
|
+
export declare const MIN_FREEZE_SCROLLABLE_WIDTH = 240;
|
|
3
|
+
export interface IFreezeColumnLimitOptions {
|
|
4
|
+
containerWidth: number;
|
|
5
|
+
columnInitSize: number;
|
|
6
|
+
columnCount: number;
|
|
7
|
+
getColumnWidth: (index: number) => number;
|
|
8
|
+
minScrollableWidth?: number;
|
|
9
|
+
}
|
|
10
|
+
/** How many leading columns can stay frozen in this width (0 on a phone with a wide first column). */
|
|
11
|
+
export declare const getMaxFreezeColumnCount: ({ containerWidth, columnInitSize, columnCount, getColumnWidth, minScrollableWidth, }: IFreezeColumnLimitOptions) => number;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './config';
|
|
3
|
+
export * from './range';
|
|
4
|
+
export * from './lru';
|
|
5
|
+
export * from './coordinate';
|
|
6
|
+
export * from './selection';
|
|
7
|
+
export * from './selection-controller';
|
|
8
|
+
export * from './keyboard';
|
|
9
|
+
export * from './region';
|
|
10
|
+
export * from './auto-scroll';
|
|
11
|
+
export * from './drag';
|
|
12
|
+
export * from './column-resize';
|
|
13
|
+
export * from './freeze';
|
|
14
|
+
export * from './keys';
|
|
15
|
+
export * from './theme';
|
|
16
|
+
export * from './renderer/base';
|
|
17
|
+
export * from './renderer/layout';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CombinedSelection } from './selection';
|
|
2
|
+
import { ICellItem } from './types';
|
|
3
|
+
export type IArrowDirection = 'up' | 'down' | 'left' | 'right';
|
|
4
|
+
export interface IGridBounds {
|
|
5
|
+
/** Data rows. */
|
|
6
|
+
pureRowCount: number;
|
|
7
|
+
columnCount: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ISelectionMove {
|
|
10
|
+
selection: CombinedSelection;
|
|
11
|
+
/** The new active cell, or undefined when it stays (Shift extends the range only). */
|
|
12
|
+
activeCell?: ICellItem;
|
|
13
|
+
/** The cell to scroll into view. */
|
|
14
|
+
scrollTo: ICellItem;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Arrow keys on a cell selection. Plain arrows move by one; `jump` (Cmd/Ctrl)
|
|
18
|
+
* goes to the edge; `expand` (Shift) keeps the anchor and moves the head.
|
|
19
|
+
*/
|
|
20
|
+
export declare const moveSelection: (selection: CombinedSelection, direction: IArrowDirection, modifiers: {
|
|
21
|
+
expand?: boolean;
|
|
22
|
+
jump?: boolean;
|
|
23
|
+
}, bounds: IGridBounds) => ISelectionMove;
|
|
24
|
+
/** Tab / Shift+Tab: one cell right or left from the anchor, collapsing any range. The host commits an open editor first. */
|
|
25
|
+
export declare const tabSelection: (selection: CombinedSelection, backward: boolean, bounds: IGridBounds) => Required<ISelectionMove>;
|
|
26
|
+
/** Cmd/Ctrl+A: every cell. The active cell stays. */
|
|
27
|
+
export declare const selectAllCells: (selection: CombinedSelection, bounds: IGridBounds) => CombinedSelection;
|
|
28
|
+
/**
|
|
29
|
+
* Enter while editing: the cell to select after commit, one row down unless
|
|
30
|
+
* `stay` is set. A column selection commits on its first row.
|
|
31
|
+
*/
|
|
32
|
+
export declare const enterCommitSelection: (selection: CombinedSelection, bounds: IGridBounds, stay?: boolean) => Required<ISelectionMove>;
|
|
33
|
+
/** PageUp/PageDown scroll distance: one viewport below the header. */
|
|
34
|
+
export declare const pageScrollDelta: (containerHeight: number, rowInitSize: number) => number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** keyCode values (the `ts-keycode-enum` names Teable uses). */
|
|
2
|
+
export declare const KeyCode: {
|
|
3
|
+
readonly Space: 32;
|
|
4
|
+
readonly Digit0: 48;
|
|
5
|
+
readonly Digit9: 57;
|
|
6
|
+
readonly A: 65;
|
|
7
|
+
readonly Z: 90;
|
|
8
|
+
readonly Numpad0: 96;
|
|
9
|
+
readonly Numpad9: 105;
|
|
10
|
+
readonly Multiply: 106;
|
|
11
|
+
readonly Divide: 111;
|
|
12
|
+
readonly Equals: 61;
|
|
13
|
+
readonly Minus: 173;
|
|
14
|
+
readonly SemiColon: 186;
|
|
15
|
+
readonly Tilde: 192;
|
|
16
|
+
readonly OpenBracket: 219;
|
|
17
|
+
readonly Quote: 222;
|
|
18
|
+
/** Sent while an input method is composing. */
|
|
19
|
+
readonly Ime: 229;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The first-key test and the composition guard are shared with editors outside
|
|
23
|
+
* the grid, so they live in the interaction core (also ported from Teable).
|
|
24
|
+
* Ask `guard.ownsKey(event)` before handling Enter, Esc or Tab; ask
|
|
25
|
+
* `isComposingKey(event)` before arrows.
|
|
26
|
+
*/
|
|
27
|
+
export { COMPOSITION_END_GRACE_MS, createCompositionGuard, isComposingKey, isPrintableKey, type CompositionGuard } from '../interaction/ime';
|
|
28
|
+
export declare const isNumberKey: (keyCode: number) => boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether a paste should go to the grid's selection handler. While editing, a
|
|
31
|
+
* visible input, textarea or contenteditable keeps the native paste; the
|
|
32
|
+
* hidden focus owner forwards it.
|
|
33
|
+
*/
|
|
34
|
+
export declare const shouldForwardPasteToGrid: ({ isEditing, eventTarget, hiddenFocusEl }: {
|
|
35
|
+
isEditing: boolean;
|
|
36
|
+
eventTarget: EventTarget | null;
|
|
37
|
+
hiddenFocusEl: HTMLElement | null;
|
|
38
|
+
}) => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Least-recently-used map with a fixed size, on Map's insertion order. */
|
|
2
|
+
export declare class LruCache<K, V> {
|
|
3
|
+
private readonly map;
|
|
4
|
+
readonly max: number;
|
|
5
|
+
constructor(max: number);
|
|
6
|
+
get size(): number;
|
|
7
|
+
get(key: K): V | undefined;
|
|
8
|
+
set(key: K, value: V): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ICellItem, IRange } from './types';
|
|
2
|
+
import { CombinedSelection } from './selection';
|
|
3
|
+
/** Whether `num` lies between `start` and `end`, both inclusive, in either order. */
|
|
4
|
+
export declare const inRange: (num: number, start: number, end: number) => boolean;
|
|
5
|
+
/** Whether a `[start, end]` run lies entirely inside one of `ranges`. */
|
|
6
|
+
export declare const isRangeWithinRanges: (checkedRange: IRange, ranges: IRange[]) => boolean;
|
|
7
|
+
/** Every index covered by the runs, in order. */
|
|
8
|
+
export declare const flatRanges: (ranges: IRange[]) => number[];
|
|
9
|
+
export declare const isPointInsideRectangle: (checkPoint: [number, number], startPoint: [number, number], endPoint: [number, number]) => boolean;
|
|
10
|
+
/** Sorts runs and merges the ones that overlap or touch. */
|
|
11
|
+
export declare const serializedRanges: (ranges: IRange[]) => IRange[];
|
|
12
|
+
/**
|
|
13
|
+
* Toggles `newRange` in `ranges`: a run equal to it is removed, a run that
|
|
14
|
+
* contains or overlaps it loses that part, otherwise it is added.
|
|
15
|
+
*/
|
|
16
|
+
export declare const mixRanges: (ranges: IRange[], newRange: IRange) => IRange[];
|
|
17
|
+
/** The bottom-right `[column, row]` of a cell selection, or null for other kinds. */
|
|
18
|
+
export declare const calculateMaxRange: (selection: CombinedSelection) => ICellItem | null;
|
|
19
|
+
export declare const checkIfRowOrCellActive: (activeCell: ICellItem | null, rowIndex: number, columnIndex: number) => {
|
|
20
|
+
isRowActive: boolean;
|
|
21
|
+
isCellActive: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare const checkIfRowOrCellSelected: (selection: CombinedSelection, rowIndex: number, columnIndex: number) => {
|
|
24
|
+
isRowSelected: boolean;
|
|
25
|
+
isCellSelected: boolean;
|
|
26
|
+
};
|
|
27
|
+
/** Element-wise equality of two lists of ranges (replaces lodash `isEqual` for this shape). */
|
|
28
|
+
export declare const rangesEqual: (a: readonly IRange[], b: readonly IRange[]) => boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CoordinateManager } from './coordinate';
|
|
2
|
+
import { CombinedSelection } from './selection';
|
|
3
|
+
import { IGridTheme } from './theme';
|
|
4
|
+
import { RegionType, IActiveCellBound, ICellItem, IColumnResizeState, IDragState, IGridColumn, ILinearRow, IMouseState, IPosition, IRectangle, IRegionPosition, IRowControlItem, IScrollState } from './types';
|
|
5
|
+
type IRowControlTheme = Pick<IGridTheme, 'iconSizeXS' | 'iconSizeMD'>;
|
|
6
|
+
export declare const getRowControlExtraWidth: (theme: IRowControlTheme, rowControlPaddingX: number | undefined) => number;
|
|
7
|
+
export declare const getRowControlLayoutWidth: (width: number, theme: IRowControlTheme, rowControlPaddingX: number | undefined) => number;
|
|
8
|
+
/** Centre x of the `rowControlIndex`-th control in a row header `width` wide. */
|
|
9
|
+
export declare const getRowControlOffsetX: (width: number, theme: IRowControlTheme, rowControlPaddingX: number | undefined, rowControlCount: number, rowControlIndex: number) => number;
|
|
10
|
+
export declare const getRowControlCheckboxOffsetX: ({ width, theme, rowControls, rowControlPaddingX }: {
|
|
11
|
+
width: number;
|
|
12
|
+
theme: IRowControlTheme;
|
|
13
|
+
rowControls: IRowControlItem[];
|
|
14
|
+
rowControlPaddingX?: number;
|
|
15
|
+
}) => number;
|
|
16
|
+
/**
|
|
17
|
+
* Row and column under a point relative to the grid's top-left corner, by
|
|
18
|
+
* arithmetic only. Row -1 = column header; column -1 = row header; column -2 =
|
|
19
|
+
* the append-column button; -Infinity = above or left of the grid.
|
|
20
|
+
*/
|
|
21
|
+
export declare const getPosition: (coordInstance: CoordinateManager, scrollState: Pick<IScrollState, "scrollLeft" | "scrollTop">, point: IPosition) => IRegionPosition;
|
|
22
|
+
/** Whether the point is past the last row or the append column (excluding a footer band between `containerHeight` and `height`). */
|
|
23
|
+
export declare const isPositionOutOfBounds: (coordInstance: CoordinateManager, scrollState: Pick<IScrollState, "scrollLeft" | "scrollTop">, point: IPosition, height?: number) => boolean;
|
|
24
|
+
export interface IRegionContext {
|
|
25
|
+
coordInstance: CoordinateManager;
|
|
26
|
+
scrollState: Pick<IScrollState, 'scrollLeft' | 'scrollTop'>;
|
|
27
|
+
theme: Pick<IGridTheme, 'iconSizeXS' | 'iconSizeMD'>;
|
|
28
|
+
columns: IGridColumn[];
|
|
29
|
+
selection: CombinedSelection;
|
|
30
|
+
isSelecting: boolean;
|
|
31
|
+
dragState: Pick<IDragState, 'isDragging'>;
|
|
32
|
+
columnResizeState: Pick<IColumnResizeState, 'columnIndex'>;
|
|
33
|
+
rowControls: IRowControlItem[];
|
|
34
|
+
rowControlPaddingX?: number;
|
|
35
|
+
activeCell: ICellItem | null;
|
|
36
|
+
activeCellBound: IActiveCellBound | null;
|
|
37
|
+
isFreezing?: boolean;
|
|
38
|
+
isColumnFreezable?: boolean;
|
|
39
|
+
isColumnResizable?: boolean;
|
|
40
|
+
isColumnAppendEnable?: boolean;
|
|
41
|
+
isColumnHeaderMenuVisible?: boolean;
|
|
42
|
+
isMultiSelectionEnable?: boolean;
|
|
43
|
+
/** Shows and hit-tests the fill handle. */
|
|
44
|
+
isFillEnabled?: boolean;
|
|
45
|
+
getLinearRow?: (index: number) => ILinearRow;
|
|
46
|
+
real2RowIndex?: (index: number) => number;
|
|
47
|
+
}
|
|
48
|
+
interface ICheckRegionProps extends IRegionContext {
|
|
49
|
+
position: IRegionPosition;
|
|
50
|
+
isOutOfBounds: boolean;
|
|
51
|
+
getLinearRow: (index: number) => ILinearRow;
|
|
52
|
+
real2RowIndex: (index: number) => number;
|
|
53
|
+
}
|
|
54
|
+
export interface IRegionData extends IRectangle {
|
|
55
|
+
type: RegionType;
|
|
56
|
+
rowIndex?: number;
|
|
57
|
+
columnIndex?: number;
|
|
58
|
+
isOutOfBounds?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare const BLANK_REGION_DATA: IRegionData;
|
|
61
|
+
/**
|
|
62
|
+
* What is under the pointer. Checks run in priority order and the first match
|
|
63
|
+
* wins: an ongoing freeze, the fill handle, the active cell, out of bounds, an
|
|
64
|
+
* ongoing selection, resize or drag, the freeze handle, the append column, the
|
|
65
|
+
* corner checkbox, the append row, the row header, a group header, a cell, a
|
|
66
|
+
* column header.
|
|
67
|
+
*/
|
|
68
|
+
export declare const getRegionData: (props: ICheckRegionProps) => IRegionData;
|
|
69
|
+
/** Full mouse state for a point: position, region type and the region's own row/column when it reports one. */
|
|
70
|
+
export declare const getMouseState: (context: IRegionContext, point: IPosition, height?: number) => IMouseState & {
|
|
71
|
+
region: IRegionData;
|
|
72
|
+
};
|
|
73
|
+
export {};
|