svelte-tiler 0.1.0 → 0.2.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/context.d.ts +13 -8
- package/dist/context.js +34 -19
- package/dist/debug.svelte +11 -0
- package/dist/debug.svelte.d.ts +8 -0
- package/dist/dnd.d.ts +1 -0
- package/dist/dnd.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/model.d.ts +18 -1
- package/dist/model.js +32 -1
- package/dist/panel.svelte.d.ts +1 -1
- package/dist/render.svelte +2 -2
- package/dist/render.svelte.d.ts +1 -1
- package/dist/tiles/leaf.svelte +2 -0
- package/dist/tiles/leaf.svelte.d.ts +1 -0
- package/dist/tiles/split.svelte +22 -9
- package/dist/tiles/split.svelte.d.ts +2 -2
- package/dist/tiles/tabs.svelte +33 -44
- package/dist/tiles/tabs.svelte.d.ts +8 -8
- package/package.json +3 -3
package/dist/context.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DndContext } from './shared/dnd.svelte.ts';
|
|
2
|
-
import type { Tile, TileComponent, Tiles, TileType } from './model.
|
|
2
|
+
import type { Tile, TileComponent, TileInsertData, Tiles, TileType } from './model.js';
|
|
3
3
|
export declare const getTilerContext: () => TilerContext, setTilerContext: (context: TilerContext) => TilerContext;
|
|
4
4
|
export interface TileDefinition<T extends TileType> {
|
|
5
5
|
default: TileComponent<T>;
|
|
6
6
|
onRemoveChild: (ctx: TilerContext, tile: Tiles[T], index: number) => void;
|
|
7
|
+
onInsert: (ctx: TilerContext, tile: Tiles[T], index: number, data: TileInsertData<T>) => void;
|
|
7
8
|
onClear: (ctx: TilerContext, tile: Tiles[T]) => void;
|
|
8
9
|
}
|
|
9
10
|
export type TileDefinitions = {
|
|
@@ -21,20 +22,21 @@ export declare class TilerContext {
|
|
|
21
22
|
protected definitions: TileDefinitions;
|
|
22
23
|
protected effects: TileEffects;
|
|
23
24
|
protected updateRootFn: ((tile: Tile) => void) | undefined;
|
|
24
|
-
protected
|
|
25
|
-
protected
|
|
25
|
+
protected registry: FinalizationRegistry<string>;
|
|
26
|
+
protected tiles: Map<string, WeakRef<Tile>>;
|
|
27
|
+
protected parents: WeakMap<Tile, Tile>;
|
|
26
28
|
readonly dnd: DndContext<Tile>;
|
|
27
29
|
constructor(options: TilerContextOptions);
|
|
28
|
-
registerTile(tile: Tile, parent: Tile | ((tile: Tile) => void)):
|
|
29
|
-
getTileEffect(tile: Tile): ((tile: import("./model.
|
|
30
|
+
registerTile(tile: Tile, parent: Tile | ((tile: Tile) => void)): void;
|
|
31
|
+
getTileEffect(tile: Tile): ((tile: import("./model.js").TileBase<"leaf"> & {
|
|
30
32
|
name: string;
|
|
31
|
-
}) => void | (() => void)) | ((tile: import("./model.
|
|
33
|
+
}) => void | (() => void)) | ((tile: import("./model.js").TileBase<"split"> & {
|
|
32
34
|
constraints: Array<import("./shared/constraints.ts").Constraint[]>;
|
|
33
35
|
weights: number[];
|
|
34
36
|
direction: import("./shared/spatial.ts").Direction;
|
|
35
37
|
resizer?: string;
|
|
36
38
|
gapPx: number;
|
|
37
|
-
}) => void | (() => void)) | ((tile: import("./model.
|
|
39
|
+
}) => void | (() => void)) | ((tile: import("./model.js").TileBase<"tabs"> & {
|
|
38
40
|
titles: string[];
|
|
39
41
|
selectedTab: number;
|
|
40
42
|
headersDirection: import("./tiles/tabs.svelte.ts").HeadersDirection;
|
|
@@ -43,7 +45,10 @@ export declare class TilerContext {
|
|
|
43
45
|
empty?: string;
|
|
44
46
|
}) => void | (() => void)) | undefined;
|
|
45
47
|
getTileComponent(tile: Tile): TileComponent<"leaf"> | TileComponent<"split"> | TileComponent<"tabs">;
|
|
46
|
-
|
|
48
|
+
replace(tile: Tile | undefined, replace: Tile): void;
|
|
49
|
+
replaceTile(tileId: string | undefined, replace: Tile): void;
|
|
50
|
+
insertInto<T extends TileType>(tile: Tiles[T], index: number, data: TileInsertData<T>): void;
|
|
51
|
+
insertIntoTile<T extends TileType>(tileId: string, type: T, index: number, data: TileInsertData<T>): void;
|
|
47
52
|
removeChildFrom(tile: Tile, index: number): void;
|
|
48
53
|
removeChildFromTile(tileId: string, index: number): void;
|
|
49
54
|
remove(tile: Tile): void;
|
package/dist/context.js
CHANGED
|
@@ -5,8 +5,11 @@ export class TilerContext {
|
|
|
5
5
|
definitions;
|
|
6
6
|
effects;
|
|
7
7
|
updateRootFn;
|
|
8
|
+
registry = new FinalizationRegistry((id) => {
|
|
9
|
+
this.tiles.delete(id);
|
|
10
|
+
});
|
|
8
11
|
tiles = new Map();
|
|
9
|
-
parents = new
|
|
12
|
+
parents = new WeakMap();
|
|
10
13
|
dnd;
|
|
11
14
|
constructor(options) {
|
|
12
15
|
this.definitions = options.definitions;
|
|
@@ -14,18 +17,15 @@ export class TilerContext {
|
|
|
14
17
|
this.effects = options.effects ?? {};
|
|
15
18
|
}
|
|
16
19
|
registerTile(tile, parent) {
|
|
17
|
-
|
|
18
|
-
this.
|
|
20
|
+
this.tiles.set(tile.id, new WeakRef(tile));
|
|
21
|
+
this.registry.register(tile, tile.id);
|
|
19
22
|
if (typeof parent === 'function') {
|
|
23
|
+
this.parents.delete(tile);
|
|
20
24
|
this.updateRootFn = parent;
|
|
21
25
|
}
|
|
22
26
|
else {
|
|
23
|
-
this.parents.set(
|
|
27
|
+
this.parents.set(tile, parent);
|
|
24
28
|
}
|
|
25
|
-
return () => {
|
|
26
|
-
this.tiles.delete(id);
|
|
27
|
-
this.parents.delete(id);
|
|
28
|
-
};
|
|
29
29
|
}
|
|
30
30
|
getTileEffect(tile) {
|
|
31
31
|
return this.effects[tile.type];
|
|
@@ -33,18 +33,33 @@ export class TilerContext {
|
|
|
33
33
|
getTileComponent(tile) {
|
|
34
34
|
return this.definitions[tile.type].default;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
replace(tile, replace) {
|
|
37
|
+
if (tile) {
|
|
38
|
+
const parent = this.parents.get(tile);
|
|
39
|
+
if (parent) {
|
|
40
|
+
const index = parent.children.findIndex((c) => c.id === tile.id);
|
|
41
|
+
if (index < 0) {
|
|
42
|
+
throw new Error(`Invalid parent for "${tile.id}" tile`);
|
|
43
|
+
}
|
|
44
|
+
parent.children[index] = replace;
|
|
45
|
+
return;
|
|
42
46
|
}
|
|
43
|
-
parent.children[index] = replace;
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
this.updateRootFn?.(replace);
|
|
49
|
+
}
|
|
50
|
+
replaceTile(tileId, replace) {
|
|
51
|
+
const tile = tileId && this.getTileById(tileId);
|
|
52
|
+
this.replace(tile || undefined, replace);
|
|
53
|
+
}
|
|
54
|
+
insertInto(tile, index, data) {
|
|
55
|
+
this.definitions[tile.type].onInsert(this, tile, index, data);
|
|
56
|
+
}
|
|
57
|
+
insertIntoTile(tileId, type, index, data) {
|
|
58
|
+
const tile = this.getTileById(tileId);
|
|
59
|
+
if (tile.type !== type) {
|
|
60
|
+
throw new Error(`Tile type mismatch: expected "${type}", but got "${tile.type}"`);
|
|
47
61
|
}
|
|
62
|
+
this.insertInto(tile, index, data);
|
|
48
63
|
}
|
|
49
64
|
removeChildFrom(tile, index) {
|
|
50
65
|
this.definitions[tile.type].onRemoveChild(this, tile, index);
|
|
@@ -53,7 +68,7 @@ export class TilerContext {
|
|
|
53
68
|
this.removeChildFrom(this.getTileById(tileId), index);
|
|
54
69
|
}
|
|
55
70
|
remove(tile) {
|
|
56
|
-
const parent = this.parents.get(tile
|
|
71
|
+
const parent = this.parents.get(tile);
|
|
57
72
|
if (parent === undefined) {
|
|
58
73
|
this.definitions[tile.type].onClear(this, tile);
|
|
59
74
|
return;
|
|
@@ -68,7 +83,7 @@ export class TilerContext {
|
|
|
68
83
|
this.remove(this.getTileById(tileId));
|
|
69
84
|
}
|
|
70
85
|
getTileById(tileId) {
|
|
71
|
-
const tile = this.tiles.get(tileId);
|
|
86
|
+
const tile = this.tiles.get(tileId)?.deref();
|
|
72
87
|
if (tile === undefined) {
|
|
73
88
|
throw new Error(`Unable to find tile with "${tileId}" id`);
|
|
74
89
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Tile } from './model.js';
|
|
3
|
+
import Self from './debug.svelte';
|
|
4
|
+
|
|
5
|
+
const { tile, level = 0 }: { tile: Tile; level?: number } = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div style="padding-left: {level * 12}px;">{tile.type} ({tile.id})</div>
|
|
9
|
+
{#each tile.children as c (c.id)}
|
|
10
|
+
<Self tile={c} level={level + 1} />
|
|
11
|
+
{/each}
|
package/dist/dnd.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class TileDropTarget<T extends Tile> extends Droppable<Tile, T> {
|
|
|
5
5
|
readonly tileId: string;
|
|
6
6
|
protected tilerCtx: TilerContext;
|
|
7
7
|
constructor(ctx: TilerContext, tileId: string);
|
|
8
|
+
getTargetTileId(): string | undefined;
|
|
8
9
|
protected isOwnChild(d: Draggable): d is TileDragSource;
|
|
9
10
|
}
|
|
10
11
|
export interface TileDragSourceOptions extends DraggableOptions<Tile> {
|
package/dist/dnd.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './context.ts';
|
|
2
|
-
export * from './model.
|
|
2
|
+
export * from './model.js';
|
|
3
3
|
export * from './dnd.ts';
|
|
4
4
|
export { default as Panel } from './panel.svelte';
|
|
5
5
|
export { default as Tiler } from './tiler.svelte';
|
|
6
|
+
export { default as Debug } from './debug.svelte';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./context.js";
|
|
2
|
-
export * from
|
|
2
|
+
export * from './model.js';
|
|
3
3
|
export * from "./dnd.js";
|
|
4
4
|
export { default as Panel } from './panel.svelte';
|
|
5
5
|
export { default as Tiler } from './tiler.svelte';
|
|
6
|
+
export { default as Debug } from './debug.svelte';
|
package/dist/model.d.ts
CHANGED
|
@@ -11,10 +11,27 @@ export type Tiles = {
|
|
|
11
11
|
[T in TileType]: TileBase<T> & TileRegistry[T];
|
|
12
12
|
};
|
|
13
13
|
export type Tile = Tiles[TileType];
|
|
14
|
+
export interface TileInsertRequirements {
|
|
15
|
+
}
|
|
16
|
+
type WithOnlyRequired<T, K extends keyof T> = Required<Pick<T, K>> & Partial<Omit<T, K>>;
|
|
17
|
+
export type TileInsertData<T extends TileType> = WithOnlyRequired<Tiles[T], (T extends keyof TileInsertRequirements ? TileInsertRequirements[T] & keyof Tiles[T] : never) | 'children'>;
|
|
14
18
|
export type TileProps<T extends TileType> = {
|
|
15
19
|
tile: Tiles[T];
|
|
16
20
|
parent: Tile | undefined;
|
|
17
21
|
index: number;
|
|
18
22
|
child: Snippet<[number]>;
|
|
19
23
|
};
|
|
20
|
-
export type TileComponent<T extends TileType> = Component<TileProps<T>, {}, 'tile'
|
|
24
|
+
export type TileComponent<T extends TileType> = Component<TileProps<T>, {}, 'tile'>;
|
|
25
|
+
export type TileArrayProperties<T extends TileType> = {
|
|
26
|
+
[K in keyof Tiles[T] as Tiles[T][K] extends Array<any> ? K : never]: Tiles[T][K];
|
|
27
|
+
};
|
|
28
|
+
export type TileArrayProperty<T extends TileType> = keyof TileArrayProperties<T>;
|
|
29
|
+
/**
|
|
30
|
+
* @returns Returns the insertion position taking into account removed duplicates
|
|
31
|
+
*/
|
|
32
|
+
export declare function insertWithDeduplication<T extends TileType>(tile: Tiles[T], i: number, arrays: {
|
|
33
|
+
[K in Exclude<TileArrayProperty<T>, 'children'>]?: Tiles[T][K & keyof Tiles[T]];
|
|
34
|
+
} & {
|
|
35
|
+
children: Tile[];
|
|
36
|
+
}): number;
|
|
37
|
+
export {};
|
package/dist/model.js
CHANGED
|
@@ -1 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @returns Returns the insertion position taking into account removed duplicates
|
|
3
|
+
*/
|
|
4
|
+
export function insertWithDeduplication(tile, i, arrays) {
|
|
5
|
+
const newIds = new Set(arrays.children.map((c) => c.id));
|
|
6
|
+
let write = 0;
|
|
7
|
+
let shift = 0;
|
|
8
|
+
const c = tile.children;
|
|
9
|
+
const l = c.length;
|
|
10
|
+
const keys = Object.keys(arrays);
|
|
11
|
+
const tileArrays = keys.map((arr) => tile[arr]);
|
|
12
|
+
for (let read = 0; read < l; read++) {
|
|
13
|
+
if (!newIds.has(c[read].id)) {
|
|
14
|
+
for (const arr of tileArrays) {
|
|
15
|
+
// @ts-expect-error ignore
|
|
16
|
+
arr[write] = arr[read];
|
|
17
|
+
}
|
|
18
|
+
write++;
|
|
19
|
+
}
|
|
20
|
+
else if (read < i) {
|
|
21
|
+
shift++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
i -= shift;
|
|
25
|
+
for (const key of keys) {
|
|
26
|
+
// @ts-expect-error ignore
|
|
27
|
+
tile[key].length = write;
|
|
28
|
+
// @ts-expect-error ignore
|
|
29
|
+
tile[key].splice(i, 0, ...arrays[key]);
|
|
30
|
+
}
|
|
31
|
+
return i;
|
|
32
|
+
}
|
package/dist/panel.svelte.d.ts
CHANGED
package/dist/render.svelte
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
{#snippet child(index: number)}
|
|
26
|
-
<Self
|
|
26
|
+
<Self parent={tile} bind:tile={tile.children[index]} {index} />
|
|
27
27
|
{/snippet}
|
|
28
28
|
|
|
29
|
-
<TileComponent
|
|
29
|
+
<TileComponent {parent} bind:tile={tile as never} {index} {child} />
|
package/dist/render.svelte.d.ts
CHANGED
package/dist/tiles/leaf.svelte
CHANGED
|
@@ -12,6 +12,7 @@ type LeafContext<N extends string = string> = Registry<N, Snippet<[Tiles['leaf']
|
|
|
12
12
|
export declare function setup<N extends string>(leafs: LeafContext<N>): (name: N) => Tiles["leaf"];
|
|
13
13
|
export declare function onRemoveChild(): void;
|
|
14
14
|
export declare function onClear(): void;
|
|
15
|
+
export declare function onInsert(): void;
|
|
15
16
|
declare const Leaf: import("svelte").Component<TileProps<"leaf">, {}, "tile">;
|
|
16
17
|
type Leaf = ReturnType<typeof Leaf>;
|
|
17
18
|
export default Leaf;
|
package/dist/tiles/split.svelte
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
} from '../shared/constraints.js';
|
|
11
11
|
import type { Direction } from '../shared/spatial.js';
|
|
12
12
|
import { almostEqual } from '../shared/math.js';
|
|
13
|
-
import
|
|
13
|
+
import {
|
|
14
|
+
insertWithDeduplication,
|
|
15
|
+
type Tile,
|
|
16
|
+
type TileInsertData,
|
|
17
|
+
type TileProps,
|
|
18
|
+
type Tiles,
|
|
19
|
+
} from '../model.js';
|
|
14
20
|
import type { TilerContext } from '../context.js';
|
|
15
21
|
import { TileDropTarget } from '../dnd.js';
|
|
16
22
|
|
|
@@ -89,10 +95,10 @@
|
|
|
89
95
|
if (
|
|
90
96
|
!droppable ||
|
|
91
97
|
(droppable instanceof TileDropTarget &&
|
|
92
|
-
tile.
|
|
98
|
+
tile.id !== droppable.getTargetTileId())
|
|
93
99
|
) {
|
|
94
100
|
tick().then(() => {
|
|
95
|
-
ctx.
|
|
101
|
+
ctx.replace(tile, tile.children[1 - i]);
|
|
96
102
|
});
|
|
97
103
|
return;
|
|
98
104
|
}
|
|
@@ -108,14 +114,21 @@
|
|
|
108
114
|
|
|
109
115
|
export function onClear(_ctx: TilerContext, _tile: Tiles['split']) {}
|
|
110
116
|
|
|
111
|
-
export function
|
|
112
|
-
|
|
117
|
+
export function onInsert(
|
|
118
|
+
_ctx: TilerContext,
|
|
119
|
+
tile: Tiles['split'],
|
|
113
120
|
index: number,
|
|
114
|
-
{
|
|
121
|
+
{
|
|
122
|
+
children,
|
|
123
|
+
constraints = children.map(() => []),
|
|
124
|
+
weights = children.map(() => 1),
|
|
125
|
+
}: TileInsertData<'split'>
|
|
115
126
|
) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
127
|
+
insertWithDeduplication<'split'>(tile, index, {
|
|
128
|
+
children,
|
|
129
|
+
constraints,
|
|
130
|
+
weights,
|
|
131
|
+
});
|
|
119
132
|
}
|
|
120
133
|
</script>
|
|
121
134
|
|
|
@@ -3,7 +3,7 @@ import type { Registry } from '../shared/registry.js';
|
|
|
3
3
|
import { Draggable } from '../shared/dnd.svelte.js';
|
|
4
4
|
import { type Constraint } from '../shared/constraints.js';
|
|
5
5
|
import type { Direction } from '../shared/spatial.js';
|
|
6
|
-
import type
|
|
6
|
+
import { type Tile, type TileInsertData, type TileProps, type Tiles } from '../model.js';
|
|
7
7
|
import type { TilerContext } from '../context.js';
|
|
8
8
|
declare module '../model.js' {
|
|
9
9
|
interface TileRegistry {
|
|
@@ -36,7 +36,7 @@ type SplitContext<R extends string = string> = {
|
|
|
36
36
|
export declare function setup<R extends string>(ctx: SplitContext<R>): (options: SplitOptions<R>) => Tiles["split"];
|
|
37
37
|
export declare function onRemoveChild(ctx: TilerContext, tile: Tiles['split'], i: number): void;
|
|
38
38
|
export declare function onClear(_ctx: TilerContext, _tile: Tiles['split']): void;
|
|
39
|
-
export declare function
|
|
39
|
+
export declare function onInsert(_ctx: TilerContext, tile: Tiles['split'], index: number, { children, constraints, weights, }: TileInsertData<'split'>): void;
|
|
40
40
|
declare const Split: import("svelte").Component<TileProps<"split">, {}, "tile">;
|
|
41
41
|
type Split = ReturnType<typeof Split>;
|
|
42
42
|
export default Split;
|
package/dist/tiles/tabs.svelte
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
import type { Draggable } from '../shared/dnd.svelte.js';
|
|
5
5
|
import type { Registry } from '../shared/registry.js';
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
insertWithDeduplication,
|
|
8
|
+
type Tile,
|
|
9
|
+
type Tiles,
|
|
10
|
+
} from '../model.js';
|
|
7
11
|
import type { TilerContext } from '../context.js';
|
|
8
12
|
|
|
9
13
|
export type HeadersDirection = Direction | 'none';
|
|
@@ -19,6 +23,9 @@
|
|
|
19
23
|
empty?: string;
|
|
20
24
|
};
|
|
21
25
|
}
|
|
26
|
+
interface TileInsertRequirements {
|
|
27
|
+
tabs: 'titles';
|
|
28
|
+
}
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
export interface TabsOptions<
|
|
@@ -70,7 +77,7 @@
|
|
|
70
77
|
E extends string = string,
|
|
71
78
|
A extends string = string,
|
|
72
79
|
> {
|
|
73
|
-
|
|
80
|
+
applySplit?: (options: SplitOptions) => void;
|
|
74
81
|
actions?: Registry<A, Snippet<[Tiles['tabs']]> | undefined>;
|
|
75
82
|
headers?: Registry<
|
|
76
83
|
H,
|
|
@@ -112,38 +119,16 @@
|
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
|
|
115
|
-
export function
|
|
122
|
+
export function onInsert(
|
|
123
|
+
_ctx: TilerContext,
|
|
116
124
|
tile: Tiles['tabs'],
|
|
117
125
|
i: number,
|
|
118
|
-
|
|
119
|
-
titles,
|
|
120
|
-
children,
|
|
121
|
-
}: {
|
|
122
|
-
titles: string[];
|
|
123
|
-
children: Tile[];
|
|
124
|
-
}
|
|
126
|
+
data: TileInsertData<'tabs'>
|
|
125
127
|
) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const t = tile.titles;
|
|
131
|
-
const l = t.length;
|
|
132
|
-
for (let read = 0; read < l; read++) {
|
|
133
|
-
if (!newIds.has(c[read].id)) {
|
|
134
|
-
t[write] = t[read];
|
|
135
|
-
c[write] = c[read];
|
|
136
|
-
write++;
|
|
137
|
-
} else if (read < i) {
|
|
138
|
-
shift++;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
c.length = write;
|
|
142
|
-
t.length = write;
|
|
143
|
-
i -= shift;
|
|
144
|
-
tile.children.splice(i, 0, ...children);
|
|
145
|
-
tile.titles.splice(i, 0, ...titles);
|
|
146
|
-
tile.selectedTab = i;
|
|
128
|
+
tile.selectedTab = insertWithDeduplication<'tabs'>(tile, i, {
|
|
129
|
+
titles: data.titles,
|
|
130
|
+
children: data.children,
|
|
131
|
+
});
|
|
147
132
|
}
|
|
148
133
|
</script>
|
|
149
134
|
|
|
@@ -154,14 +139,10 @@
|
|
|
154
139
|
type EdgePart,
|
|
155
140
|
} from '../shared/spatial.js';
|
|
156
141
|
import { getTilerContext } from '../context.js';
|
|
157
|
-
import type { TileProps } from '../model.js';
|
|
142
|
+
import type { TileInsertData, TileProps } from '../model.js';
|
|
158
143
|
import { TileDragSource, TileDropTarget } from '../dnd.js';
|
|
159
144
|
|
|
160
|
-
let {
|
|
161
|
-
tile = $bindable(),
|
|
162
|
-
parent = $bindable(),
|
|
163
|
-
child,
|
|
164
|
-
}: TileProps<'tabs'> = $props();
|
|
145
|
+
let { tile = $bindable(), parent, child }: TileProps<'tabs'> = $props();
|
|
165
146
|
|
|
166
147
|
const ctx = getTilerContext();
|
|
167
148
|
const tabsCtx = getContext<TabsContext | undefined>(TABS_CONTEXT_KEY);
|
|
@@ -177,7 +158,7 @@
|
|
|
177
158
|
const empty = $derived(
|
|
178
159
|
(tile.empty !== undefined && tabsCtx?.empty?.get(tile.empty)) || undefined
|
|
179
160
|
);
|
|
180
|
-
const edgeRatio = $derived(tabsCtx?.
|
|
161
|
+
const edgeRatio = $derived(tabsCtx?.applySplit ? 0.1 : 0);
|
|
181
162
|
|
|
182
163
|
class TabsTileDropTarget extends TileDropTarget<Tiles['tabs']> {
|
|
183
164
|
accepts(d: Draggable<Tile>): d is Draggable<Tiles['tabs']> {
|
|
@@ -196,7 +177,7 @@
|
|
|
196
177
|
|
|
197
178
|
class SimpleTabsDropTarget extends TabsTileDropTarget {
|
|
198
179
|
protected onDrop(tabs: Tiles['tabs']): void {
|
|
199
|
-
|
|
180
|
+
ctx.insertInto<'tabs'>(tile, tile.children.length, tabs);
|
|
200
181
|
}
|
|
201
182
|
}
|
|
202
183
|
|
|
@@ -241,21 +222,29 @@
|
|
|
241
222
|
) {
|
|
242
223
|
i++;
|
|
243
224
|
}
|
|
244
|
-
|
|
225
|
+
ctx.insertInto<'tabs'>(tile, i, tabs);
|
|
245
226
|
}
|
|
246
227
|
}
|
|
247
228
|
|
|
248
229
|
class SegmentedContentDropTarget extends SegmentedTabsTileDropTarget {
|
|
230
|
+
get isCenter() {
|
|
231
|
+
return this.hpart === 'center' && this.vpart === 'center';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
getTargetTileId(): string | undefined {
|
|
235
|
+
return this.isCenter ? tile.id : parent?.id;
|
|
236
|
+
}
|
|
237
|
+
|
|
249
238
|
protected onDrop(tabs: Tiles['tabs'], d: Draggable): void {
|
|
250
239
|
const id = tabs.children[0].id;
|
|
251
|
-
if (this.
|
|
240
|
+
if (this.isCenter) {
|
|
252
241
|
let i = tile.children.findIndex((t) => t.id === id);
|
|
253
242
|
if (i < 0 && this.isOwnChild(d)) {
|
|
254
243
|
i = d.childIndex;
|
|
255
244
|
}
|
|
256
|
-
|
|
257
|
-
} else if (tabsCtx?.
|
|
258
|
-
|
|
245
|
+
ctx.insertInto<'tabs'>(tile, i < 0 ? tile.children.length : i, tabs);
|
|
246
|
+
} else if (tabsCtx?.applySplit) {
|
|
247
|
+
tabsCtx.applySplit({
|
|
259
248
|
parent,
|
|
260
249
|
type:
|
|
261
250
|
this.hpart === 'start' || this.hpart === 'end' ? 'row' : 'column',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Snippet } from 'svelte';
|
|
2
2
|
import type { Draggable } from '../shared/dnd.svelte.js';
|
|
3
3
|
import type { Registry } from '../shared/registry.js';
|
|
4
|
-
import type
|
|
4
|
+
import { type Tile, type Tiles } from '../model.js';
|
|
5
5
|
import type { TilerContext } from '../context.js';
|
|
6
6
|
export type HeadersDirection = Direction | 'none';
|
|
7
7
|
declare module '../model.js' {
|
|
@@ -15,6 +15,9 @@ declare module '../model.js' {
|
|
|
15
15
|
empty?: string;
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
+
interface TileInsertRequirements {
|
|
19
|
+
tabs: 'titles';
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
export interface TabsOptions<H extends string, E extends string, A extends string> {
|
|
20
23
|
tabs: [string, Tile][];
|
|
@@ -34,7 +37,7 @@ interface SplitOptions {
|
|
|
34
37
|
adjacent: Tiles['tabs'];
|
|
35
38
|
}
|
|
36
39
|
interface TabsContext<H extends string = string, E extends string = string, A extends string = string> {
|
|
37
|
-
|
|
40
|
+
applySplit?: (options: SplitOptions) => void;
|
|
38
41
|
actions?: Registry<A, Snippet<[Tiles['tabs']]> | undefined>;
|
|
39
42
|
headers?: Registry<H, Snippet<[Tiles['tabs'], number, Draggable<Tile>]> | undefined>;
|
|
40
43
|
empty?: Registry<E, Snippet<[Tiles['tabs']]> | undefined>;
|
|
@@ -42,12 +45,9 @@ interface TabsContext<H extends string = string, E extends string = string, A ex
|
|
|
42
45
|
export declare function setup<H extends string, E extends string, A extends string>(ctx: TabsContext<H, E, A>): (options: TabsOptions<H, E, A>) => Tiles["tabs"];
|
|
43
46
|
export declare function onRemoveChild(ctx: TilerContext, tile: Tiles['tabs'], i: number): void;
|
|
44
47
|
export declare function onClear(_ctx: TilerContext, tile: Tiles['tabs']): void;
|
|
45
|
-
export declare function
|
|
46
|
-
titles: string[];
|
|
47
|
-
children: Tile[];
|
|
48
|
-
}): void;
|
|
48
|
+
export declare function onInsert(_ctx: TilerContext, tile: Tiles['tabs'], i: number, data: TileInsertData<'tabs'>): void;
|
|
49
49
|
import { type Direction } from '../shared/spatial.js';
|
|
50
|
-
import type { TileProps } from '../model.js';
|
|
51
|
-
declare const Tabs: import("svelte").Component<TileProps<"tabs">, {}, "tile"
|
|
50
|
+
import type { TileInsertData, TileProps } from '../model.js';
|
|
51
|
+
declare const Tabs: import("svelte").Component<TileProps<"tabs">, {}, "tile">;
|
|
52
52
|
type Tabs = ReturnType<typeof Tabs>;
|
|
53
53
|
export default Tabs;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-tiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A small, unstyled library for building tiling user interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/x0k/svelte-tiler#readme",
|
|
@@ -61,14 +61,14 @@
|
|
|
61
61
|
"eslint": "^9.39.2",
|
|
62
62
|
"eslint-config-prettier": "^10.1.8",
|
|
63
63
|
"eslint-plugin-svelte": "^3.14.0",
|
|
64
|
-
"globals": "^17.
|
|
64
|
+
"globals": "^17.2.0",
|
|
65
65
|
"marked": "^17.0.1",
|
|
66
66
|
"playwright": "^1.58.0",
|
|
67
67
|
"prettier": "^3.8.1",
|
|
68
68
|
"prettier-plugin-svelte": "^3.4.1",
|
|
69
69
|
"publint": "^0.3.17",
|
|
70
70
|
"shiki": "^3.21.0",
|
|
71
|
-
"svelte": "^5.
|
|
71
|
+
"svelte": "^5.49.1",
|
|
72
72
|
"svelte-check": "^4.3.5",
|
|
73
73
|
"typescript": "^5.9.3",
|
|
74
74
|
"typescript-eslint": "^8.54.0",
|