@txstate-mws/svelte-components 0.0.67 → 1.0.3
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/README.md +39 -4
- package/{dist/ts/actions/a11y.d.ts → actions/buttonify.d.ts} +0 -0
- package/{dist/actions/a11y.js → actions/buttonify.js} +1 -6
- package/{dist/ts/actions → actions}/glue.d.ts +2 -2
- package/{dist/actions → actions}/glue.js +9 -16
- package/actions/index.d.ts +7 -0
- package/actions/index.js +7 -0
- package/actions/offset.d.ts +15 -0
- package/actions/offset.js +35 -0
- package/{dist/ts/actions → actions}/portal.d.ts +0 -0
- package/actions/portal.js +13 -0
- package/{dist/ts/actions → actions}/resize.d.ts +6 -2
- package/actions/resize.js +45 -0
- package/{dist/ts/actions → actions}/sticky.d.ts +2 -2
- package/{dist/actions → actions}/sticky.js +10 -18
- package/{dist/ts/actions → actions}/stickyfixed.d.ts +7 -7
- package/{dist/actions → actions}/stickyfixed.js +19 -28
- package/{dist/components → components}/CollapsingTable.svelte +13 -14
- package/components/CollapsingTable.svelte.d.ts +59 -0
- package/{dist/ts/components → components}/ConditionalWrapper.svelte +6 -7
- package/components/ConditionalWrapper.svelte.d.ts +23 -0
- package/{dist/components → components}/FocusLock.svelte +21 -19
- package/components/FocusLock.svelte.d.ts +26 -0
- package/components/Modal.svelte +53 -0
- package/components/Modal.svelte.d.ts +27 -0
- package/{dist/components → components}/PopupMenu.svelte +28 -30
- package/components/PopupMenu.svelte.d.ts +44 -0
- package/{dist/ts/components → components}/ScreenReaderOnly.svelte +4 -5
- package/components/ScreenReaderOnly.svelte.d.ts +20 -0
- package/{dist/ts/components → components}/index.d.ts +0 -0
- package/components/index.js +6 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +47 -68
- package/{dist/ts/types → types}/CollapsingTable.d.ts +0 -0
- package/{dist/ts/tests/Actions/Actions.stories.d.ts → types/CollapsingTable.js} +0 -0
- package/{dist/ts/types → types}/PopupMenu.d.ts +0 -0
- package/{dist/ts/tests/CollapsingTable/CollapsingTable.stories.d.ts → types/PopupMenu.js} +0 -0
- package/types/index.d.ts +2 -0
- package/types/index.js +2 -0
- package/{dist/ts/lib → util}/bodyoffset.d.ts +2 -1
- package/{dist/lib → util}/bodyoffset.js +10 -14
- package/util/index.d.ts +3 -0
- package/util/index.js +3 -0
- package/{dist/ts/lib → util}/repositioned.d.ts +1 -2
- package/{dist/lib → util}/repositioned.js +14 -24
- package/{dist/ts/lib → util}/util.d.ts +0 -0
- package/util/util.js +10 -0
- package/LICENSE +0 -21
- package/dist/actions/a11y.js.map +0 -1
- package/dist/actions/glue.js.map +0 -1
- package/dist/actions/index.js +0 -20
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/offset.js +0 -35
- package/dist/actions/offset.js.map +0 -1
- package/dist/actions/portal.js +0 -23
- package/dist/actions/portal.js.map +0 -1
- package/dist/actions/resize.js +0 -48
- package/dist/actions/resize.js.map +0 -1
- package/dist/actions/sticky.js.map +0 -1
- package/dist/actions/stickyfixed.js.map +0 -1
- package/dist/components/ConditionalWrapper.svelte +0 -38
- package/dist/components/Modal.svelte +0 -44
- package/dist/components/ScreenReaderOnly.svelte +0 -26
- package/dist/components/index.js +0 -19
- package/dist/components/index.js.map +0 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +0 -1
- package/dist/lib/bodyoffset.js.map +0 -1
- package/dist/lib/deepstore.js +0 -80
- package/dist/lib/deepstore.js.map +0 -1
- package/dist/lib/derivedstore.js +0 -53
- package/dist/lib/derivedstore.js.map +0 -1
- package/dist/lib/index.js +0 -20
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/repositioned.js.map +0 -1
- package/dist/lib/safestore.js +0 -16
- package/dist/lib/safestore.js.map +0 -1
- package/dist/lib/substore.js +0 -46
- package/dist/lib/substore.js.map +0 -1
- package/dist/lib/util.js +0 -16
- package/dist/lib/util.js.map +0 -1
- package/dist/ts/actions/index.d.ts +0 -7
- package/dist/ts/actions/offset.d.ts +0 -15
- package/dist/ts/components/CollapsingTable.svelte +0 -147
- package/dist/ts/components/FocusLock.svelte +0 -100
- package/dist/ts/components/Modal.svelte +0 -45
- package/dist/ts/components/PopupMenu.svelte +0 -278
- package/dist/ts/index.d.ts +0 -4
- package/dist/ts/lib/deepstore.d.ts +0 -42
- package/dist/ts/lib/derivedstore.d.ts +0 -16
- package/dist/ts/lib/index.d.ts +0 -7
- package/dist/ts/lib/safestore.d.ts +0 -4
- package/dist/ts/lib/substore.d.ts +0 -23
- package/dist/ts/tests/Actions/Offset.svelte +0 -34
- package/dist/ts/tests/Actions/Resize.svelte +0 -31
- package/dist/ts/tests/Actions/Sticky.svelte +0 -65
- package/dist/ts/tests/CollapsingTable/CollapsingTable.test.d.ts +0 -1
- package/dist/ts/tests/CollapsingTable/CollapsingTableTest.svelte +0 -36
- package/dist/ts/tests/Modal/Modal.stories.d.ts +0 -1
- package/dist/ts/tests/Modal/Modal.test.d.ts +0 -1
- package/dist/ts/tests/Modal/ModalTest.svelte +0 -58
- package/dist/ts/tests/PopupMenu/PopupMenu.stories.d.ts +0 -1
- package/dist/ts/tests/PopupMenu/PopupMenu.test.d.ts +0 -1
- package/dist/ts/tests/PopupMenu/PopupMenuBody.svelte +0 -34
- package/dist/ts/tests/PopupMenu/PopupMenuButtonIsParent.svelte +0 -36
- package/dist/ts/tests/PopupMenu/PopupMenuComplex.svelte +0 -34
- package/dist/ts/tests/PopupMenu/PopupMenuSimple.svelte +0 -30
- package/dist/ts/tests/stores/deepstore.test.d.ts +0 -1
- package/dist/ts/types/index.d.ts +0 -2
- package/dist/types/CollapsingTable.js +0 -3
- package/dist/types/CollapsingTable.js.map +0 -1
- package/dist/types/PopupMenu.js +0 -3
- package/dist/types/PopupMenu.js.map +0 -1
- package/dist/types/index.js +0 -15
- package/dist/types/index.js.map +0 -1
- package/docs/CollapsingTable.md +0 -80
- package/docs/actions.md +0 -10
- package/esm/index.js +0 -1
- package/esm/package.json +0 -3
package/README.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
|
-
# svelte
|
|
2
|
-
A set of generically useful components for svelte.
|
|
1
|
+
# create-svelte
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
|
4
|
+
|
|
5
|
+
## Creating a project
|
|
6
|
+
|
|
7
|
+
If you're seeing this, you've probably already done this step. Congrats!
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# create a new project in the current directory
|
|
11
|
+
npm init svelte@next
|
|
12
|
+
|
|
13
|
+
# create a new project in my-app
|
|
14
|
+
npm init svelte@next my-app
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> Note: the `@next` is temporary
|
|
18
|
+
|
|
19
|
+
## Developing
|
|
20
|
+
|
|
21
|
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm run dev
|
|
25
|
+
|
|
26
|
+
# or start the server and open the app in a new browser tab
|
|
27
|
+
npm run dev -- --open
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Building
|
|
31
|
+
|
|
32
|
+
To create a production version of your app:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
You can preview the production build with `npm run preview`.
|
|
39
|
+
|
|
40
|
+
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment.
|
|
File without changes
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buttonify = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Turns any HTML element into an accessible button that responds to keyboard events and has
|
|
6
3
|
* role="button" and the tabindex attribute set. You are still responsible for making sure it has
|
|
7
4
|
* readable content or a good label.
|
|
8
5
|
*/
|
|
9
|
-
function buttonify(node) {
|
|
6
|
+
export function buttonify(node) {
|
|
10
7
|
function keydown(e) {
|
|
11
8
|
if (e.key === 'Enter') {
|
|
12
9
|
if (!e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey) {
|
|
@@ -27,5 +24,3 @@ function buttonify(node) {
|
|
|
27
24
|
}
|
|
28
25
|
};
|
|
29
26
|
}
|
|
30
|
-
exports.buttonify = buttonify;
|
|
31
|
-
//# sourceMappingURL=a11y.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SettableSubject } from '
|
|
1
|
+
import type { SettableSubject } from '@txstate-mws/svelte-store';
|
|
2
2
|
export declare type GlueAlignOpts = 'auto' | 'bottomleft' | 'bottomright' | 'topleft' | 'topright';
|
|
3
3
|
export interface GlueArgs<T extends GlueAlignStore = GlueAlignStore> {
|
|
4
4
|
target: HTMLElement;
|
|
@@ -12,5 +12,5 @@ export interface GlueAlignStore {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function glue(el: HTMLElement, { target, align, cover, store }: GlueArgs): {
|
|
14
14
|
update({ target: utarget, align: ualign, cover: ucover, store: ustore }: GlueArgs): void;
|
|
15
|
-
destroy()
|
|
15
|
+
destroy: () => void;
|
|
16
16
|
};
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.glue = void 0;
|
|
4
|
-
const lib_1 = require("../lib");
|
|
1
|
+
import { sharedOffsetParent, targetOffset, watchForPositionChangeInContainer } from '../util/index.js';
|
|
5
2
|
let setBodyRelative = false;
|
|
6
|
-
function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
3
|
+
export function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
7
4
|
if (!setBodyRelative) {
|
|
8
5
|
setBodyRelative = true;
|
|
9
6
|
document.body.style.position = 'relative';
|
|
10
7
|
}
|
|
11
8
|
let halign;
|
|
12
9
|
let valign;
|
|
13
|
-
let sharedOffset =
|
|
10
|
+
let sharedOffset = sharedOffsetParent(el, target);
|
|
14
11
|
function reposition(offset) {
|
|
15
12
|
if (!target || !sharedOffset || !(el.offsetParent instanceof HTMLElement))
|
|
16
13
|
return;
|
|
17
14
|
let autoalign = align;
|
|
18
|
-
const parentoffset = el.offsetParent === sharedOffset && target !== sharedOffset ? { top: 0, left: 0, bottom: 0, right: 0 } :
|
|
15
|
+
const parentoffset = el.offsetParent === sharedOffset && target !== sharedOffset ? { top: 0, left: 0, bottom: 0, right: 0 } : targetOffset(el.offsetParent, sharedOffset);
|
|
19
16
|
if (align === 'auto') {
|
|
20
17
|
const rect = target.getBoundingClientRect();
|
|
21
18
|
const leftright = window.innerWidth - rect.right > rect.left ? 'left' : 'right';
|
|
@@ -63,27 +60,23 @@ function glue(el, { target, align = 'auto', cover = false, store }) {
|
|
|
63
60
|
valign = 'top';
|
|
64
61
|
halign = 'right';
|
|
65
62
|
}
|
|
66
|
-
store
|
|
63
|
+
store?.update(v => ({ ...v, valign, halign }));
|
|
67
64
|
}
|
|
68
|
-
const { destroy, update } =
|
|
65
|
+
const { destroy, update } = watchForPositionChangeInContainer(target, sharedOffset, reposition);
|
|
69
66
|
return {
|
|
70
67
|
update({ target: utarget, align: ualign = 'auto', cover: ucover = false, store: ustore }) {
|
|
71
68
|
align = ualign;
|
|
72
69
|
cover = ucover;
|
|
73
70
|
if (ustore && ustore !== store) {
|
|
74
|
-
ustore.update(v => (
|
|
71
|
+
ustore.update(v => ({ ...v, valign, halign }));
|
|
75
72
|
store = ustore;
|
|
76
73
|
}
|
|
77
74
|
if (target !== utarget) {
|
|
78
|
-
sharedOffset =
|
|
75
|
+
sharedOffset = sharedOffsetParent(el, utarget);
|
|
79
76
|
target = utarget;
|
|
80
77
|
update(target, sharedOffset, reposition);
|
|
81
78
|
}
|
|
82
79
|
},
|
|
83
|
-
destroy
|
|
84
|
-
destroy();
|
|
85
|
-
}
|
|
80
|
+
destroy
|
|
86
81
|
};
|
|
87
82
|
}
|
|
88
|
-
exports.glue = glue;
|
|
89
|
-
//# sourceMappingURL=glue.js.map
|
package/actions/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Store } from '@txstate-mws/svelte-store';
|
|
2
|
+
import type { WritableSubject } from '@txstate-mws/svelte-store';
|
|
3
|
+
import type { ElementOffsets } from '../util/index.js';
|
|
4
|
+
interface OffsetConfig<T extends ElementOffsets = ElementOffsets> {
|
|
5
|
+
debounce?: boolean | number;
|
|
6
|
+
store?: WritableSubject<T>;
|
|
7
|
+
}
|
|
8
|
+
export declare class OffsetStore extends Store<ElementOffsets> {
|
|
9
|
+
constructor(initialState?: ElementOffsets);
|
|
10
|
+
}
|
|
11
|
+
export declare function offset(el: HTMLElement, config?: OffsetConfig): {
|
|
12
|
+
update(newConfig?: OffsetConfig): void;
|
|
13
|
+
destroy: () => void;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Store } from '@txstate-mws/svelte-store';
|
|
2
|
+
import { debounced, watchForPositionChange } from '../util/index.js';
|
|
3
|
+
export class OffsetStore extends Store {
|
|
4
|
+
constructor(initialState) {
|
|
5
|
+
super(initialState ?? { top: 0, right: 0, bottom: 0, left: 0 });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function offset(el, config) {
|
|
9
|
+
if (config?.debounce === true)
|
|
10
|
+
config.debounce = 100;
|
|
11
|
+
let lastOffset = {};
|
|
12
|
+
function lookforoffsetchange(current) {
|
|
13
|
+
lastOffset = current;
|
|
14
|
+
if (config?.store)
|
|
15
|
+
config.store.update(v => ({ ...v, ...current }));
|
|
16
|
+
el.dispatchEvent(new CustomEvent('offset', { detail: current }));
|
|
17
|
+
}
|
|
18
|
+
let resolvedchange = config?.debounce ? debounced(lookforoffsetchange, config.debounce) : lookforoffsetchange;
|
|
19
|
+
const { destroy, update } = watchForPositionChange(el, resolvedchange);
|
|
20
|
+
return {
|
|
21
|
+
update(newConfig) {
|
|
22
|
+
if (newConfig?.debounce === true)
|
|
23
|
+
newConfig.debounce = 100;
|
|
24
|
+
if (newConfig?.store !== config?.store) {
|
|
25
|
+
newConfig?.store?.update(v => ({ ...v, ...lastOffset }));
|
|
26
|
+
}
|
|
27
|
+
if (newConfig?.debounce !== config?.debounce) {
|
|
28
|
+
resolvedchange = newConfig?.debounce ? debounced(lookforoffsetchange, newConfig.debounce) : lookforoffsetchange;
|
|
29
|
+
update(el, resolvedchange);
|
|
30
|
+
}
|
|
31
|
+
config = newConfig;
|
|
32
|
+
},
|
|
33
|
+
destroy
|
|
34
|
+
};
|
|
35
|
+
}
|
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Store } from '@txstate-mws/svelte-store';
|
|
2
|
+
import type { SettableSubject } from '@txstate-mws/svelte-store';
|
|
2
3
|
export interface ElementSize {
|
|
3
4
|
clientWidth?: number;
|
|
4
5
|
clientHeight?: number;
|
|
@@ -9,8 +10,11 @@ interface ResizeConfig {
|
|
|
9
10
|
debounce?: boolean | number;
|
|
10
11
|
store?: SettableSubject<ElementSize>;
|
|
11
12
|
}
|
|
13
|
+
export declare class ResizeStore extends Store<ElementSize> {
|
|
14
|
+
constructor(initialState?: ElementSize);
|
|
15
|
+
}
|
|
12
16
|
export declare function resize(el: HTMLElement, config?: ResizeConfig): void | {
|
|
13
|
-
update(newConfig?: ResizeConfig
|
|
17
|
+
update(newConfig?: ResizeConfig): void;
|
|
14
18
|
destroy(): void;
|
|
15
19
|
};
|
|
16
20
|
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { equal } from 'txstate-utils';
|
|
2
|
+
import { Store } from '@txstate-mws/svelte-store';
|
|
3
|
+
import { debounced } from '../util/index.js';
|
|
4
|
+
export class ResizeStore extends Store {
|
|
5
|
+
constructor(initialState) {
|
|
6
|
+
super(initialState ?? { clientWidth: 1024, clientHeight: 1024, offsetWidth: 1024, offsetHeight: 1024 });
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function resize(el, config) {
|
|
10
|
+
if (config?.debounce === true)
|
|
11
|
+
config.debounce = 100;
|
|
12
|
+
let lastSize = {};
|
|
13
|
+
function watch() {
|
|
14
|
+
const current = { clientWidth: el.clientWidth, clientHeight: el.clientHeight, offsetWidth: el.offsetWidth, offsetHeight: el.offsetHeight };
|
|
15
|
+
if (!equal(lastSize, current)) {
|
|
16
|
+
lastSize = current;
|
|
17
|
+
if (config?.store)
|
|
18
|
+
config.store.set(current);
|
|
19
|
+
el.dispatchEvent(new CustomEvent('resize', { detail: current }));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (!ResizeObserver)
|
|
23
|
+
return watch(); // support SSR
|
|
24
|
+
let observer = new ResizeObserver(config?.debounce ? debounced(watch, config.debounce) : watch);
|
|
25
|
+
observer.observe(el);
|
|
26
|
+
watch();
|
|
27
|
+
return {
|
|
28
|
+
update(newConfig) {
|
|
29
|
+
if (newConfig?.debounce === true)
|
|
30
|
+
newConfig.debounce = 100;
|
|
31
|
+
if (newConfig?.store !== config?.store) {
|
|
32
|
+
newConfig?.store?.set(lastSize);
|
|
33
|
+
}
|
|
34
|
+
if (!!newConfig?.debounce !== !!config?.debounce) {
|
|
35
|
+
observer.disconnect();
|
|
36
|
+
observer = new ResizeObserver(newConfig?.debounce ? debounced(watch, newConfig.debounce) : watch);
|
|
37
|
+
observer.observe(el);
|
|
38
|
+
}
|
|
39
|
+
config = newConfig;
|
|
40
|
+
},
|
|
41
|
+
destroy() {
|
|
42
|
+
observer.disconnect();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SettableSubject } from '
|
|
1
|
+
import type { SettableSubject } from '@txstate-mws/svelte-store';
|
|
2
2
|
export interface StickyArgs<T extends StickyStore = StickyStore> {
|
|
3
3
|
target?: HTMLElement;
|
|
4
4
|
store?: SettableSubject<T>;
|
|
@@ -28,6 +28,6 @@ export interface StickyStore {
|
|
|
28
28
|
* fragile if your markup/CSS situation is very complex.
|
|
29
29
|
*/
|
|
30
30
|
export declare function sticky(el: HTMLElement, config?: StickyArgs): {
|
|
31
|
-
update: (newConfig?: StickyArgs
|
|
31
|
+
update: (newConfig?: StickyArgs) => void;
|
|
32
32
|
destroy: () => void;
|
|
33
33
|
};
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sticky = void 0;
|
|
4
|
-
const lib_1 = require("../lib");
|
|
1
|
+
import { bodyOffset, watchForPositionChange } from '../util/index.js';
|
|
5
2
|
let scrolled = false;
|
|
6
3
|
/**
|
|
7
4
|
* A robust implementation of stickyness based on `transform: translateY()`. Only use when
|
|
@@ -23,19 +20,18 @@ let scrolled = false;
|
|
|
23
20
|
* and therefore animates better than this. However, it has a lot more work to do and is more
|
|
24
21
|
* fragile if your markup/CSS situation is very complex.
|
|
25
22
|
*/
|
|
26
|
-
function sticky(el, config) {
|
|
23
|
+
export function sticky(el, config) {
|
|
27
24
|
let floating;
|
|
28
25
|
let translateY;
|
|
29
26
|
let scrollstart = Number.MAX_SAFE_INTEGER;
|
|
30
27
|
let scrollend = Number.MAX_SAFE_INTEGER;
|
|
31
28
|
function recalc(scroll) {
|
|
32
|
-
var _a;
|
|
33
29
|
const newTranslateY = Math.max(Math.min(scroll, scrollend) - scrollstart, 0);
|
|
34
30
|
if (newTranslateY !== translateY) {
|
|
35
31
|
el.style.transform = `translateY(${newTranslateY}px)`;
|
|
36
32
|
translateY = newTranslateY;
|
|
37
33
|
floating = scroll >= scrollstart;
|
|
38
|
-
|
|
34
|
+
config?.store?.update(v => ({ ...v, translateY, floating }));
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
37
|
function onscroll(e) {
|
|
@@ -55,29 +51,27 @@ function sticky(el, config) {
|
|
|
55
51
|
}
|
|
56
52
|
let lastOffsetParent = el.offsetParent;
|
|
57
53
|
function onpositionchange(offset) {
|
|
58
|
-
var _a;
|
|
59
54
|
const offsetParent = el.offsetParent;
|
|
60
55
|
if (!(offsetParent instanceof HTMLElement))
|
|
61
56
|
return;
|
|
62
57
|
if (lastOffsetParent !== offsetParent) {
|
|
63
|
-
offset[0] =
|
|
58
|
+
offset[0] = bodyOffset(offsetParent);
|
|
64
59
|
update(offsetParent, onpositionchange);
|
|
65
60
|
lastOffsetParent = offsetParent;
|
|
66
61
|
}
|
|
67
62
|
scrollstart = offset[0].top + el.offsetTop;
|
|
68
|
-
const containeroffset =
|
|
69
|
-
scrollend = Math.max(scrollstart, containeroffset.top + (
|
|
63
|
+
const containeroffset = config?.target ? offset[1] : offset[0];
|
|
64
|
+
scrollend = Math.max(scrollstart, containeroffset.top + (config?.target ?? offsetParent).clientHeight - el.offsetHeight);
|
|
70
65
|
recalc(window.scrollY);
|
|
71
66
|
}
|
|
72
|
-
const { destroy, update } =
|
|
67
|
+
const { destroy, update } = watchForPositionChange([el.offsetParent, config?.target], onpositionchange);
|
|
73
68
|
window.addEventListener('scroll', onscroll, { passive: true });
|
|
74
69
|
window.addEventListener('wheel', onwheel, { passive: false });
|
|
75
70
|
function stickyUpdate(newConfig) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
(_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.store) === null || _a === void 0 ? void 0 : _a.update(v => (Object.assign(Object.assign({}, v), { translateY, floating })));
|
|
71
|
+
if (newConfig?.store !== config?.store)
|
|
72
|
+
newConfig?.store?.update(v => ({ ...v, translateY, floating }));
|
|
79
73
|
config = newConfig;
|
|
80
|
-
update([el.offsetParent, config
|
|
74
|
+
update([el.offsetParent, config?.target], onpositionchange);
|
|
81
75
|
}
|
|
82
76
|
function stickyDestroy() {
|
|
83
77
|
window.removeEventListener('scroll', onscroll);
|
|
@@ -89,5 +83,3 @@ function sticky(el, config) {
|
|
|
89
83
|
destroy: stickyDestroy
|
|
90
84
|
};
|
|
91
85
|
}
|
|
92
|
-
exports.sticky = sticky;
|
|
93
|
-
//# sourceMappingURL=sticky.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { StickyArgs } from './sticky';
|
|
1
|
+
import type { StickyArgs } from './sticky.js';
|
|
2
2
|
/**
|
|
3
|
-
* An implementation of stickyness based on `
|
|
3
|
+
* An implementation of stickyness based on `positon: fixed`. Only use when
|
|
4
4
|
* `position: sticky` won't work for you. If `position: sticky` does work for you, use it,
|
|
5
5
|
* it performs better.
|
|
6
6
|
*
|
|
@@ -10,16 +10,16 @@ import { StickyArgs } from './sticky';
|
|
|
10
10
|
* 3) it always stays within the boundaries of the closest parent element that has a `position`
|
|
11
11
|
* * use:sticky accepts a `target` element as a parameter, defining the bounding container
|
|
12
12
|
*
|
|
13
|
-
* Note that this implementation
|
|
14
|
-
* work like cloning the element you place it on, placing the cloned element next
|
|
15
|
-
* setting widths to match between them, watching for mutations to keep them
|
|
16
|
-
* this work may get foiled if you have a complex html/css/js situation.
|
|
13
|
+
* Note that this implementation gets great animation performance at the cost of extra complexity.
|
|
14
|
+
* It does a lot of work like cloning the element you place it on, placing the cloned element next
|
|
15
|
+
* to yours in the DOM, setting widths to match between them, watching for mutations to keep them
|
|
16
|
+
* in sync, etc. Some of this work may get foiled if you have a complex html/css/js situation.
|
|
17
17
|
*
|
|
18
18
|
* You may also want to try use:sticky. It is based on setting `transform: translateY()` as appropriate,
|
|
19
19
|
* and is less fragile than this. However, it cannot do its work before the scroll on mobile, only after,
|
|
20
20
|
* so it will visually lag a bit on mobile.
|
|
21
21
|
*/
|
|
22
22
|
export declare function stickyfixed(el: HTMLElement, config?: StickyArgs): {
|
|
23
|
-
update: (newConfig?: StickyArgs
|
|
23
|
+
update: (newConfig?: StickyArgs) => void;
|
|
24
24
|
destroy: () => void;
|
|
25
25
|
};
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.stickyfixed = void 0;
|
|
4
|
-
const lib_1 = require("../lib");
|
|
1
|
+
import { bodyOffset, watchForPositionChange } from '../util/index.js';
|
|
5
2
|
/**
|
|
6
|
-
* An implementation of stickyness based on `
|
|
3
|
+
* An implementation of stickyness based on `positon: fixed`. Only use when
|
|
7
4
|
* `position: sticky` won't work for you. If `position: sticky` does work for you, use it,
|
|
8
5
|
* it performs better.
|
|
9
6
|
*
|
|
@@ -13,16 +10,16 @@ const lib_1 = require("../lib");
|
|
|
13
10
|
* 3) it always stays within the boundaries of the closest parent element that has a `position`
|
|
14
11
|
* * use:sticky accepts a `target` element as a parameter, defining the bounding container
|
|
15
12
|
*
|
|
16
|
-
* Note that this implementation
|
|
17
|
-
* work like cloning the element you place it on, placing the cloned element next
|
|
18
|
-
* setting widths to match between them, watching for mutations to keep them
|
|
19
|
-
* this work may get foiled if you have a complex html/css/js situation.
|
|
13
|
+
* Note that this implementation gets great animation performance at the cost of extra complexity.
|
|
14
|
+
* It does a lot of work like cloning the element you place it on, placing the cloned element next
|
|
15
|
+
* to yours in the DOM, setting widths to match between them, watching for mutations to keep them
|
|
16
|
+
* in sync, etc. Some of this work may get foiled if you have a complex html/css/js situation.
|
|
20
17
|
*
|
|
21
18
|
* You may also want to try use:sticky. It is based on setting `transform: translateY()` as appropriate,
|
|
22
19
|
* and is less fragile than this. However, it cannot do its work before the scroll on mobile, only after,
|
|
23
20
|
* so it will visually lag a bit on mobile.
|
|
24
21
|
*/
|
|
25
|
-
function stickyfixed(el, config) {
|
|
22
|
+
export function stickyfixed(el, config) {
|
|
26
23
|
let floating;
|
|
27
24
|
let translateY;
|
|
28
25
|
let scrollstart = Number.MAX_SAFE_INTEGER;
|
|
@@ -32,10 +29,9 @@ function stickyfixed(el, config) {
|
|
|
32
29
|
let left;
|
|
33
30
|
let top = 0;
|
|
34
31
|
function generatespacer(mutations) {
|
|
35
|
-
|
|
36
|
-
if (mutations === null || mutations === void 0 ? void 0 : mutations.every(m => m.attributeName === 'style'))
|
|
32
|
+
if (mutations?.every(m => m.attributeName === 'style'))
|
|
37
33
|
return;
|
|
38
|
-
spacer
|
|
34
|
+
spacer?.remove();
|
|
39
35
|
spacer = el.cloneNode(true);
|
|
40
36
|
spacer.setAttribute('aria-hidden', 'true');
|
|
41
37
|
spacer.style.position = '';
|
|
@@ -46,7 +42,7 @@ function stickyfixed(el, config) {
|
|
|
46
42
|
for (const td of tds)
|
|
47
43
|
td.style.width = '';
|
|
48
44
|
if (floating)
|
|
49
|
-
|
|
45
|
+
el.parentElement?.insertBefore(spacer, el);
|
|
50
46
|
}
|
|
51
47
|
const mutationobserver = new MutationObserver(generatespacer);
|
|
52
48
|
mutationobserver.observe(el, {
|
|
@@ -85,14 +81,13 @@ function stickyfixed(el, config) {
|
|
|
85
81
|
}
|
|
86
82
|
const resizeobserver = new ResizeObserver(adjustwidths);
|
|
87
83
|
function recalc(scroll) {
|
|
88
|
-
var _a, _b;
|
|
89
84
|
const newTranslateY = Math.max(Math.min(scroll - 1, scrollend) - scrollstart, 0);
|
|
90
85
|
const newFloating = newTranslateY > 0;
|
|
91
86
|
const newTop = Math.max(Math.min(scrollend - scroll, 0), -2 * elheight);
|
|
92
87
|
if (newFloating !== floating) {
|
|
93
88
|
floating = newFloating;
|
|
94
89
|
if (floating) {
|
|
95
|
-
|
|
90
|
+
el.parentElement?.insertBefore(spacer, el);
|
|
96
91
|
el.style.position = 'fixed';
|
|
97
92
|
el.style.top = `${Math.min(scrollend - scroll, 0)}px`;
|
|
98
93
|
el.style.left = `${left}px`;
|
|
@@ -109,7 +104,7 @@ function stickyfixed(el, config) {
|
|
|
109
104
|
}
|
|
110
105
|
if (newTranslateY !== translateY) {
|
|
111
106
|
translateY = newTranslateY;
|
|
112
|
-
|
|
107
|
+
config?.store?.update(v => ({ ...v, translateY, floating }));
|
|
113
108
|
}
|
|
114
109
|
if (top !== newTop) {
|
|
115
110
|
top = newTop;
|
|
@@ -122,12 +117,11 @@ function stickyfixed(el, config) {
|
|
|
122
117
|
}
|
|
123
118
|
let lastOffsetParent = el.offsetParent;
|
|
124
119
|
function onpositionchange(offset) {
|
|
125
|
-
var _a, _b;
|
|
126
120
|
const offsetParent = el.offsetParent;
|
|
127
121
|
if (!(offsetParent instanceof HTMLElement))
|
|
128
122
|
return;
|
|
129
123
|
if (lastOffsetParent !== offsetParent) {
|
|
130
|
-
offset[0] =
|
|
124
|
+
offset[0] = bodyOffset(offsetParent);
|
|
131
125
|
update(offsetParent, onpositionchange);
|
|
132
126
|
lastOffsetParent = offsetParent;
|
|
133
127
|
}
|
|
@@ -138,18 +132,17 @@ function stickyfixed(el, config) {
|
|
|
138
132
|
if (el.tagName === 'TR') {
|
|
139
133
|
scrollstart -= borderspacing;
|
|
140
134
|
}
|
|
141
|
-
const containeroffset =
|
|
142
|
-
scrollend = Math.max(scrollstart, containeroffset.top + (
|
|
135
|
+
const containeroffset = config?.target ? offset[1] ?? offset[0] : offset[0];
|
|
136
|
+
scrollend = Math.max(scrollstart, containeroffset.top + (config?.target ?? offsetParent).clientHeight - el.offsetHeight);
|
|
143
137
|
recalc(window.scrollY);
|
|
144
138
|
}
|
|
145
|
-
const { destroy, update } =
|
|
139
|
+
const { destroy, update } = watchForPositionChange([el.offsetParent, config?.target], onpositionchange);
|
|
146
140
|
window.addEventListener('scroll', onscroll, { passive: true });
|
|
147
141
|
function stickyUpdate(newConfig) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
(_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.store) === null || _a === void 0 ? void 0 : _a.update(v => (Object.assign(Object.assign({}, v), { translateY, floating })));
|
|
142
|
+
if (newConfig?.store !== config?.store)
|
|
143
|
+
newConfig?.store?.update(v => ({ ...v, translateY, floating }));
|
|
151
144
|
config = newConfig;
|
|
152
|
-
update([el.offsetParent, config
|
|
145
|
+
update([el.offsetParent, config?.target], onpositionchange);
|
|
153
146
|
}
|
|
154
147
|
function stickyDestroy() {
|
|
155
148
|
resizeobserver.disconnect();
|
|
@@ -162,5 +155,3 @@ function stickyfixed(el, config) {
|
|
|
162
155
|
destroy: stickyDestroy
|
|
163
156
|
};
|
|
164
157
|
}
|
|
165
|
-
exports.stickyfixed = stickyfixed;
|
|
166
|
-
//# sourceMappingURL=stickyfixed.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { DeepStore, classes } from '../lib';
|
|
1
|
+
<script >import { Store } from '@txstate-mws/svelte-store';
|
|
3
2
|
import { derived } from 'svelte/store';
|
|
3
|
+
import { classes } from '../util';
|
|
4
4
|
import DefaultPopupMenu from './PopupMenu.svelte';
|
|
5
5
|
import ScreenReaderOnly from './ScreenReaderOnly.svelte';
|
|
6
6
|
export let tableClass = '';
|
|
@@ -22,8 +22,8 @@ let columns;
|
|
|
22
22
|
let width = 320;
|
|
23
23
|
let selected;
|
|
24
24
|
let identifyingkeys = [];
|
|
25
|
-
$: firstrow =
|
|
26
|
-
$: columns = config
|
|
25
|
+
$: firstrow = items?.[0] ?? {};
|
|
26
|
+
$: columns = config ?? Object.keys(firstrow).map(key => ({ key }));
|
|
27
27
|
function reactToColumns(columns) {
|
|
28
28
|
if (!columns.some(c => c.neverhide)) {
|
|
29
29
|
columns[0].neverhide = true;
|
|
@@ -40,36 +40,35 @@ function reactToColumns(columns) {
|
|
|
40
40
|
return sortedcolumns;
|
|
41
41
|
}
|
|
42
42
|
$: sortedcolumns = reactToColumns(columns);
|
|
43
|
-
$: itemkeys = items.map(item =>
|
|
44
|
-
const state = new
|
|
43
|
+
$: itemkeys = items.map(item => item.id ?? item._id ?? identifyingkeys.map(k => item[k]).join('.'));
|
|
44
|
+
const state = new Store({
|
|
45
45
|
keepcolumns: [],
|
|
46
46
|
hiddencolumns: [],
|
|
47
47
|
dropdowncolumn: undefined
|
|
48
48
|
});
|
|
49
49
|
const menuitems = derived(state, obj => obj.hiddencolumns.map(c => ({ value: c.key, label: c.title })));
|
|
50
50
|
function react(..._) {
|
|
51
|
-
|
|
52
|
-
const selectedcol = (_a = sortedcolumns.find(c => c.key === (selected === null || selected === void 0 ? void 0 : selected.value))) !== null && _a !== void 0 ? _a : columns[1];
|
|
51
|
+
const selectedcol = sortedcolumns.find(c => c.key === selected?.value) ?? columns[1];
|
|
53
52
|
const keepcolumns = [];
|
|
54
53
|
const hiddencolumns = [];
|
|
55
|
-
let used = sortedcolumns.filter(c => c.neverhide || c === selectedcol).reduce((sum, col) =>
|
|
54
|
+
let used = sortedcolumns.filter(c => c.neverhide || c === selectedcol).reduce((sum, col) => sum + (col.width ?? defaultCellWidth), 0);
|
|
56
55
|
for (const col of sortedcolumns) {
|
|
57
|
-
if (col.neverhide || col === selectedcol || used + (
|
|
56
|
+
if (col.neverhide || col === selectedcol || used + (col.width ?? defaultCellWidth) < width) {
|
|
58
57
|
keepcolumns.push(col);
|
|
59
58
|
if (col !== selectedcol && !col.neverhide)
|
|
60
|
-
used +=
|
|
59
|
+
used += col.width ?? defaultCellWidth;
|
|
61
60
|
}
|
|
62
61
|
else
|
|
63
62
|
hiddencolumns.push(col);
|
|
64
63
|
}
|
|
65
64
|
for (const col of keepcolumns) {
|
|
66
|
-
col.widthPercent = 100 * (
|
|
65
|
+
col.widthPercent = 100 * (col.width ?? defaultCellWidth) / used;
|
|
67
66
|
}
|
|
68
67
|
const dropdowncolumn = hiddencolumns.length ? keepcolumns[keepcolumns.length - 1] : undefined;
|
|
69
68
|
state.set({ keepcolumns, hiddencolumns, dropdowncolumn });
|
|
70
69
|
}
|
|
71
70
|
$: react(width, selected);
|
|
72
|
-
|
|
71
|
+
const headers = [];
|
|
73
72
|
$: menubuttonelement = headers[$state.keepcolumns.length - 1];
|
|
74
73
|
</script>
|
|
75
74
|
|
|
@@ -113,7 +112,7 @@ $: menubuttonelement = headers[$state.keepcolumns.length - 1];
|
|
|
113
112
|
</table>
|
|
114
113
|
</div>
|
|
115
114
|
{#if $menuitems.length > 0}
|
|
116
|
-
<svelte:component this={PopupMenu} {menuContainerClass} {menuClass} {menuItemClass} {menuItemHilitedClass} items={$menuitems} buttonelement={menubuttonelement}
|
|
115
|
+
<svelte:component this={PopupMenu} {menuContainerClass} {menuClass} {menuItemClass} {menuItemHilitedClass} items={$menuitems} buttonelement={menubuttonelement} on:change={e => { selected = e.detail }}></svelte:component>
|
|
117
116
|
{/if}
|
|
118
117
|
|
|
119
118
|
<style>
|