,
16 | 'height' | 'width' | 'left' | 'right' | 'top' | 'bottom'
17 | >;
18 |
19 | /**
20 | * A legacy-typed safer version of `element.getBoundingClientRect()`,
21 | * that also invites minification capabilities (muliply calls can be forward to here, and it's pure).
22 | * */
23 | export const getElementRect = (element: HTMLElement): LegacyClientRect =>
24 | /*@__PURE__*/ element.getBoundingClientRect();
25 |
26 | export const getBordersSizeOffsets: {
27 | (computedStyle: CSSStyleDeclaration, calcEnds?: true): Sides;
28 | (computedStyle: CSSStyleDeclaration, calcEnds: false): SidesStart;
29 | } = (computedStyle: CSSStyleDeclaration, calcEnds = true) => {
30 | if (computedStyle.getPropertyValue('box-sizing') === 'border-box') {
31 | // In this case, no offset is needed since the box model of this element doesn't include the border.
32 | return undefined;
33 | }
34 | // otherwise
35 |
36 | const left = pxToNumber(computedStyle.getPropertyValue('border-left-width'));
37 | if (left === undefined) {
38 | console.error('Splitpanes Error: Fail to parse container `border-left-width`.');
39 | return undefined;
40 | }
41 | // otherwise
42 |
43 | const top = pxToNumber(computedStyle.getPropertyValue('border-top-width'));
44 | if (top === undefined) {
45 | console.error('Splitpanes Error: Fail to parse container `border-top-width`.');
46 | return undefined;
47 | }
48 | // otherwise
49 |
50 | const result: SidesStart | Sides = { left, top };
51 |
52 | if (calcEnds) {
53 | const right = pxToNumber(computedStyle.getPropertyValue('border-right-width'));
54 | if (right === undefined) {
55 | console.error('Splitpanes Error: Fail to parse container `border-right-width`.');
56 | return undefined;
57 | }
58 | // otherwise
59 |
60 | const bottom = pxToNumber(computedStyle.getPropertyValue('border-bottom-width'));
61 | if (bottom === undefined) {
62 | console.error('Splitpanes Error: Fail to parse container `border-bottom-width`.');
63 | return undefined;
64 | }
65 | // otherwise
66 |
67 | const resultExtended = result as Sides;
68 |
69 | resultExtended.right = right;
70 | resultExtended.bottom = bottom;
71 | }
72 |
73 | return result as any;
74 | };
75 |
76 | /**
77 | * Computes the position and the dimensions of the element without the border.
78 | *
79 | * While `element.getBoundingClientRect()` gives the correct size with the borders, this method method does include the borders.
80 | *
81 | * Notice that for calculating the width and the height without the border, we must use this function instead of using
82 | * `Element.clientWidth` and `Element.clientHeight`, beacuse they round the sizes of the pixels to be integer.
83 | */
84 | export function elementRectWithoutBorder(
85 | element: HTMLElement,
86 | computedStyle?: CSSStyleDeclaration
87 | ): Rect {
88 | if (!computedStyle) {
89 | computedStyle = calcComputedStyle(element);
90 | }
91 |
92 | const rect = getElementRect(element);
93 | const borderOffsets = getBordersSizeOffsets(computedStyle, true) || {
94 | left: 0,
95 | top: 0,
96 | right: 0,
97 | bottom: 0
98 | };
99 |
100 | return {
101 | width: rect.width - borderOffsets.left - borderOffsets.right,
102 | height: rect.height - borderOffsets.top - borderOffsets.bottom,
103 | left: rect.left + borderOffsets.left,
104 | top: rect.top + borderOffsets.top
105 | };
106 | }
107 |
108 | /** Get the cursor position relative to some element. */
109 | export const positionDiff = (to: Position, from: Position): Position => ({
110 | left: to.left - from.left,
111 | top: to.top - from.top
112 | });
113 |
114 | export function getGlobalMousePosition(event: MouseEvent | TouchEvent): Position {
115 | const eventMouse = event as MouseEvent;
116 | const eventTouch = event as TouchEvent;
117 |
118 | const { clientX, clientY } =
119 | 'ontouchstart' in window && eventTouch.touches ? eventTouch.touches[0] : eventMouse;
120 |
121 | return { left: clientX, top: clientY };
122 | }
123 |
--------------------------------------------------------------------------------
/src/lib/internal/utils/sizing.ts:
--------------------------------------------------------------------------------
1 | export interface SidesStart {
2 | left: number;
3 | top: number;
4 | }
5 |
6 | export interface SidesEnd {
7 | right: number;
8 | bottom: number;
9 | }
10 |
11 | export type Sides = SidesStart & SidesEnd;
12 |
13 | export function pxToNumber(pxString: string | undefined) {
14 | if (!pxString?.endsWith('px')) {
15 | return undefined;
16 | }
17 | // otherwise
18 |
19 | const num = parseFloat(pxString.slice(0, pxString.length - 2));
20 | return isNaN(num) ? undefined : num;
21 | }
22 |
23 | export const getDimensionName = (horizontal: boolean) => (horizontal ? 'height' : 'width');
24 |
--------------------------------------------------------------------------------
/src/lib/internal/utils/styling.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A wrapper of `window.getComputedStyle()`,
3 | * that also invites minification capabilities (muliply calls can be forward to here, and it's pure).
4 | * */
5 | export const calcComputedStyle = (element: HTMLElement): CSSStyleDeclaration =>
6 | /*@__PURE__*/ window.getComputedStyle(element);
7 |
--------------------------------------------------------------------------------
/src/routes/+layout.svelte:
--------------------------------------------------------------------------------
1 |
57 |
58 |
59 | Svelte-Splitpanes{curPage ? ` - ${curPage.title}` : ''}
60 |
61 | {@html theme}
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Svelte-Splitpane
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
259 |
--------------------------------------------------------------------------------
/src/routes/+layout.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | Welcome to Svelte-Splitpane demo!
6 |
7 |
8 | https://github.com/orefalo/svelte-splitpanes
9 |
10 |
11 | Features
12 |
13 |
14 |
15 |
16 | Support both dynamic horizontal and vertical splits
17 | Support defaults, min and max sizes
18 | Support multiple splits
19 | Support lifecyle events
20 | Support custom divider size or overlay
21 | Support splitter pane pushing
22 | Support RTL rendering with auto-detection
23 | Support first splitter on/off
24 | Support pane toggle
25 | Support edge snapping
26 | Support programmatic resizing and two-way size binding
27 | Support programmatic panes add/remove
28 | Support programmatic panes reordering by Svelte keyed each blocks
29 | Support for legacy browser such as IE 11
30 | Support for touch devices
31 | Sveltekit & Typescript friendly
32 |
33 |
--------------------------------------------------------------------------------
/src/routes/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/add-remove-panes/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Adding and removing panes programmatically
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/add-remove-panes/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/add-remove-panes/code.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 | {
12 | panesNumber++;
13 | }}>
14 | + ADD PANE
15 |
16 | {
19 | if (allowToRemove) panesNumber--;
20 | }}>
21 | - REMOVE PANE
22 |
23 |
24 |
25 | {#each { length: panesNumber } as _, i}
26 |
27 | {i + 1}
28 |
29 | {/each}
30 |
31 |
--------------------------------------------------------------------------------
/src/routes/examples/change-orientation/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Change orientation & first splitter
8 |
9 | When changing direction, all the panes current width or height will flip to adapt to the new
10 | layout.
11 |
12 |
13 | Showing the first splitter is an option which allows user to double click the splitter to maximize
14 | the next pane.
15 |
16 | The first splitter does not allow to resize the next pane.
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/routes/examples/change-orientation/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/change-orientation/code.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 | {
12 | horizontal = !horizontal;
13 | }}>
14 | {horizontal ? 'Turn to Vertical' : 'Turn to Horizontal'}
15 |
16 | {
18 | firstSplitter = !firstSplitter;
19 | }}>
20 | {firstSplitter ? 'Hide first splitter' : 'Show first Splitter'}
21 |
22 |
23 | {#each { length: 3 } as _, i}
24 |
25 | {i + 1}
26 |
27 | {/each}
28 |
29 |
--------------------------------------------------------------------------------
/src/routes/examples/default-size/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Default pane size
8 |
9 | Provide dimension of your panes when they first load (will be used for the width or height
10 | respectively for the vertical or horizontal layout).
11 |
12 |
13 | If you provide a default size, make sure you provide it for all the panes for a total equals to
14 | 100%. If a pane is missing a default size, then all the panes will have the same size.
15 |
16 |
17 | Note that setting a default value is different than setting a min or max value.
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/routes/examples/default-size/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/default-size/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | 1
8 | Default size of 65%
9 |
10 |
11 | 2
12 | Default size of 10%
13 |
14 |
15 | 3
16 | Default size of 25%
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/routes/examples/disable-dbl-click/+page.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 | Disable double click
7 |
8 | By default, double clicking the splitter will expand its nearest pane. In this example, we
9 | demonstrate how to turn this feature OFF
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/routes/examples/disable-dbl-click/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/disable-dbl-click/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | 1
8 |
9 |
10 | Note how double clicking has no resizing effects..
11 |
12 |
13 | 3
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/routes/examples/listen-to-events/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Listening to emitted events
8 |
9 | Here is the list of events that are emitted from splitpanes:
10 |
11 |
12 | ready has no parameter and fires when splitpanes is ready
13 |
14 | resize fires while resizing (on mousemove/touchmove) and returns an array of all the panes
15 | objects with their dimensions
16 |
17 |
18 | resized fires once when the resizing stops after user drag (on mouseup/touchend). it returns an
19 | array of all the panes objects with their dimensions. The event also fires after adding or
20 | removing a pane.
21 |
22 | pane-click returns the clicked pane object with its dimensions.
23 | pane-maximize returns the maximized pane object with its dimensions.
24 |
25 | pane-add returns an object containing the index of the added pane and the new array of panes
26 | after resize.
27 |
28 |
29 | pane-remove returns an object containing the removed pane and an array of all the remaining
30 | panes objects with their dimensions after resize.
31 |
32 |
33 | splitter-click returns the next pane object (with its dimensions) directly after the clicked
34 | splitter. This event is only emitted if dragging did not occur between mousedown and mouseup.
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/routes/examples/listen-to-events/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/listen-to-events/code.svelte:
--------------------------------------------------------------------------------
1 |
13 |
14 |
24 | {#each { length: 3 } as _, i}
25 |
26 | {i + 1}
27 |
28 | {/each}
29 |
30 |
31 | Try resizing panes and check the logs bellow.
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/routes/examples/lock-layout/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Locking layout by prevent pushing other panes
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/lock-layout/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/lock-layout/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | 1
8 | Try grabbing to very bottom splitter, note how it stops on the bounderies of this panel
9 |
10 |
11 |
12 |
13 | 2
14 |
15 |
16 | 3
17 |
18 |
19 | 4
20 |
21 |
22 |
23 |
24 | 5
25 | Try grabbing to very top splitter, note how it stops on the bounderies of this panel
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/routes/examples/min-max/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Horizontal layout, push other panes, min & max use, doubleclick
8 |
9 | You can double click a splitter to maximize the next pane!
10 |
11 | If you want to disable the 'double click splitter to maximize' behavior, you can add this attribute:
12 | dblClickSplitter={false}.
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/routes/examples/min-max/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/min-max/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 | 1
9 |
10 | I have a min height of 20% & max height of 70%
11 |
12 |
13 |
14 | 2
15 |
16 |
17 |
18 | 3
19 |
20 | I have a max height of 70%
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/routes/examples/prog-resize/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Programmatic resizing
8 |
9 |
10 | This example shows the programmatic way of resizing panes with two-way data biding. And how it
11 | works both ways.
12 |
13 | Changing programmatically the size one pane, will shrink/expand the other panes that have no specified
14 | size, as you can see in the example.
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/routes/examples/prog-resize/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/prog-resize/code.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 | {Math.round(value[0])}%
13 |
14 |
15 | Auto-Calculated
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/routes/examples/push-other-panes/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Lots of splitters & push other panes - all panes have a min width of 5%
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/push-other-panes/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/push-other-panes/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | {#each { length: 8 } as _, i}
7 |
8 | {i + 1}
9 | Double click splitter ->
10 |
11 | {/each}
12 |
13 |
--------------------------------------------------------------------------------
/src/routes/examples/reordering-panes/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Reordering Panes
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/reordering-panes/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/reordering-panes/code.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 | {
11 | const temp = ordered[0];
12 | ordered[0] = ordered[1];
13 | ordered[1] = temp;
14 | }}>
15 | Switch
16 |
17 |
18 | {#each ordered as val}
19 |
20 | {val.color}
21 |
22 | {/each}
23 |
24 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/middle/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Middle snap
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/middle/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/middle/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 | Try shrinking my size, note how I snap below 10% size
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/min-max/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Min & max with snap
8 | You can also snap to the panel maximum and minimum size.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/min-max/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/min-max/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | I have a snap size of 10%
11 |
12 | I have a min size of 10%
13 |
14 | I have a max size of 70%
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/simple/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Simple snap
8 | Using snapSize on a pane makes it snap to his adjacent splitters and borders.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/simple/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/snap/simple/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | Try shrinking my size, note how I snap below 10% size
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/app-layout/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Styling Splitters - Modern
8 |
9 |
10 | This examples uses CSS styles to pixel size panes and lock them in place. applied to panes in
11 | order to achieve the desired layout.
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/app-layout/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/app-layout/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | MenuBar - This is a splitpane, note how the splitters made static using CSS
8 |
9 |
10 | ToolBar - This is another fixed size, locked splitpane
11 |
12 |
13 |
14 |
15 |
16 | Folder
17 |
18 | You can move those --{'>'}
19 |
20 |
21 |
22 | Sample content
23 |
24 |
25 |
26 | Details
27 |
28 | {'<'}-- You can move those
29 |
30 |
31 |
32 |
33 |
34 | statusbar - and yet, another splitpane, same technique
35 |
36 |
37 |
38 |
102 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/splitters/+page.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 | Styling Splitters
9 |
10 |
11 | Styling splitters is fully customizable using CSS (or SCSS), the `theme` property is used to
12 | select the proper styling class and apply it to the Splitpanes component.
13 |
14 | The default style is called `default-theme`, its SCSS definition can be found below (
15 | warning
16 | : This is for reference only! If you decide to copy this CSS code, you must rename the ".default-theme"
17 | specifier to something else, so it wouldn't conflict the library theme CSS definition):
18 |
19 |
20 |
21 |
22 | Alternatively, here is the default theme compiled to CSS:
23 |
24 |
25 |
26 |
27 | By altering the above styles, it is possible to achieve neat visual adjustments. Please note how
28 | each Splitpanes references our new `theme="my-theme"`
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/splitters/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/styling/splitters/code.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 | 1
10 |
11 |
12 | 2
13 |
14 |
15 | 3
16 |
17 |
18 |
19 |
20 |
21 |
22 | In this example the splitters are thin lines but the reactive touch zone is spread to 30
23 | pixels all around!
24 |
25 |
26 |
27 |
28 |
29 |
70 |
--------------------------------------------------------------------------------
/src/routes/examples/toggle-panes/+page.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 | Toggle a pane on/off
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/routes/examples/toggle-panes/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/routes/examples/toggle-panes/code.svelte:
--------------------------------------------------------------------------------
1 |
12 |
13 | {visible ? 'Hide' : 'Show'}
14 |
15 |
16 |
17 | 1
18 |
19 | {#if visible}
20 |
21 | 2
22 |
23 | {/if}
24 |
25 | 3
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/routes/minified-size/+page.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 | The badge above shows the minimized size of the library when all features are used.
9 |
10 | Please note, the size includes type definitions, styles and components.
11 |
12 |
--------------------------------------------------------------------------------
/src/routes/pathUtils.ts:
--------------------------------------------------------------------------------
1 | import type { Page } from '@sveltejs/kit';
2 |
3 | import { base } from '$app/paths';
4 |
5 | const removeTrailingSlash = (path: string) => (path.endsWith('/') ? path.slice(0, -1) : path);
6 |
7 | export const pathIsCurrent = (path: string, currentPage: Page) =>
8 | removeTrailingSlash(base + path) === removeTrailingSlash(currentPage.url.pathname);
9 |
--------------------------------------------------------------------------------
/src/routes/test/+page.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | 1
8 |
9 |
10 | 2
11 |
12 |
13 | 3
14 |
15 |
16 | 4
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/routes/test/+page.ts:
--------------------------------------------------------------------------------
1 | export const prerender = true;
2 |
--------------------------------------------------------------------------------
/src/type_decl.d.ts:
--------------------------------------------------------------------------------
1 | // fixes a svelte-check issue
2 | declare module 'svelte-range-slider-pips'; // No chance to augment it at all
3 |
4 | declare module 'svelte-highlight/styles/night-owl' {
5 | const nightOwl: string;
6 | export default nightOwl;
7 | }
8 |
--------------------------------------------------------------------------------
/static/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orefalo/svelte-splitpanes/25d41a3967f35e26917f0ec2bf5579c5008a82b1/static/.nojekyll
--------------------------------------------------------------------------------
/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orefalo/svelte-splitpanes/25d41a3967f35e26917f0ec2bf5579c5008a82b1/static/favicon.png
--------------------------------------------------------------------------------
/static/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/minified-size-badge.svg:
--------------------------------------------------------------------------------
1 | minified size: This would be replaced by the computed size. minified size minified size This would be replaced by the computed size. This would be replaced by the computed size.
--------------------------------------------------------------------------------
/static/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/static/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orefalo/svelte-splitpanes/25d41a3967f35e26917f0ec2bf5579c5008a82b1/static/screenshot.jpg
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-static';
2 | import { sveltePreprocess } from 'svelte-preprocess';
3 | import path from 'path';
4 |
5 | /** @type {import('@sveltejs/kit').Config} */
6 | const config = {
7 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors
8 | // for more information about preprocessors
9 | preprocess: sveltePreprocess(),
10 |
11 | kit: {
12 | adapter: adapter({
13 | pages: 'docs',
14 | assets: 'docs',
15 | fallback: undefined
16 | }),
17 | alias: {
18 | 'svelte-splitpanes': path.resolve('.', 'src/lib'),
19 | $comp: path.resolve('./src/comp')
20 | },
21 | paths: {
22 | // Usually the base path will be the root (i.e. defaults by kit to the empty "" path since the env var is undefined),
23 | // but on the official documentation build we set this environment
24 | // variable to the base path where we're deploying to.
25 | base: process.env.BASE_PATH
26 | }
27 | }
28 | };
29 |
30 | export default config;
31 |
--------------------------------------------------------------------------------
/tests/addRemoveSplitter.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from '@playwright/test';
2 |
3 | test('add, remove all and add again works', async ({ page }) => {
4 | await page.goto('/');
5 |
6 | const areaLocator = page.locator('text=Add Remove Panes');
7 | await areaLocator.click();
8 |
9 | const addPaneLocator = page.locator(
10 | ':has-text("Adding and removing panes programmatically")~div button:has-text("Add pane")'
11 | );
12 | const removePaneLocator = page.locator(
13 | ':has-text("Adding and removing panes programmatically")~div button:has-text("Remove pane")'
14 | );
15 | const splitpanesLocator = page
16 | .locator(':has-text("Adding and removing panes programmatically")~div div.splitpanes')
17 | .first();
18 | const panesLocator = splitpanesLocator.locator('.splitpanes__pane');
19 |
20 | expect(await removePaneLocator.isEnabled()).toBe(true);
21 | expect(await panesLocator.count()).toBe(3);
22 |
23 | await addPaneLocator.click();
24 | expect(await removePaneLocator.isEnabled()).toBe(true);
25 | expect(await panesLocator.count()).toBe(4);
26 |
27 | await removePaneLocator.click();
28 | expect(await removePaneLocator.isEnabled()).toBe(true);
29 | expect(await panesLocator.count()).toBe(3);
30 |
31 | await removePaneLocator.click();
32 | expect(await removePaneLocator.isEnabled()).toBe(true);
33 | expect(await panesLocator.count()).toBe(2);
34 |
35 | await removePaneLocator.click();
36 | expect(await removePaneLocator.isEnabled()).toBe(true);
37 | expect(await panesLocator.count()).toBe(1);
38 |
39 | await removePaneLocator.click();
40 | expect(await removePaneLocator.isDisabled()).toBe(true);
41 | expect(await panesLocator.count()).toBe(0);
42 |
43 | await addPaneLocator.click();
44 | expect(await removePaneLocator.isEnabled()).toBe(true);
45 | expect(await panesLocator.count()).toBe(1);
46 | expect(await panesLocator.getAttribute('style')).toBe('width: 100%;');
47 | expect((await panesLocator.boundingBox())?.x).toBeGreaterThan(10);
48 |
49 | await addPaneLocator.click();
50 | expect(await removePaneLocator.isEnabled()).toBe(true);
51 | expect(await panesLocator.count()).toBe(2);
52 |
53 | await addPaneLocator.click();
54 | expect(await removePaneLocator.isEnabled()).toBe(true);
55 | expect(await panesLocator.count()).toBe(3);
56 | });
57 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true,
12 | "moduleResolution": "bundler"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite';
2 | import { defineConfig } from 'vitest/config';
3 | import { exampleImportPlugin } from './scripts/vite/example-import.js';
4 | import {
5 | minifiedSizeAnalyzingPlugin,
6 | manualChunksForAnalyzing
7 | } from './scripts/vite/minified-size-analyzing.js';
8 |
9 | /** @type {import('vite').UserConfig} */
10 | export default defineConfig({
11 | plugins: [sveltekit(), exampleImportPlugin(), minifiedSizeAnalyzingPlugin()],
12 | optimizeDeps: {
13 | include: ['highlight.js', 'highlight.js/lib/core']
14 | },
15 | build: {
16 | minify: 'esbuild', // We specify this explicitly, since we need the server code to be minified for size computation.
17 | rollupOptions: {
18 | output: {
19 | manualChunks: manualChunksForAnalyzing
20 | }
21 | }
22 | },
23 | ssr: {
24 | noExternal: [
25 | // So that 'esm-env-robust' dependency will be embedded,
26 | // and (a huge!!) minification could be performed by knowing if we're running on the server or on the client.
27 | 'esm-env-robust'
28 | ]
29 | },
30 | test: {
31 | include: ['src/**/*.{test,spec}.{js,ts}']
32 | }
33 | });
34 |
--------------------------------------------------------------------------------