@txstate-mws/svelte-components 1.0.2 → 1.1.1
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 +33 -14
- package/{dist/ts/actions → actions}/buttonify.d.ts +0 -0
- package/{dist/actions → actions}/buttonify.js +1 -6
- package/{dist/ts/actions → actions}/glue.d.ts +1 -1
- package/{dist/actions → actions}/glue.js +8 -13
- 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 +57 -0
- package/{dist/ts/actions → actions}/sticky.d.ts +2 -2
- package/{dist/actions → actions}/sticky.js +11 -19
- package/{dist/ts/actions → actions}/stickyfixed.d.ts +2 -2
- package/{dist/actions → actions}/stickyfixed.js +15 -24
- package/components/Card.svelte +23 -0
- package/components/Card.svelte.d.ts +18 -0
- package/components/CardLayout.svelte +197 -0
- package/components/CardLayout.svelte.d.ts +21 -0
- package/{dist/components → components}/CollapsingTable.svelte +12 -13
- 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 +11 -9
- package/components/FocusLock.svelte.d.ts +26 -0
- package/{dist/components → components}/Modal.svelte +5 -4
- package/components/Modal.svelte.d.ts +27 -0
- package/components/MultiSelect.svelte +179 -0
- package/components/MultiSelect.svelte.d.ts +35 -0
- package/{dist/components → components}/PopupMenu.svelte +29 -24
- package/components/PopupMenu.svelte.d.ts +45 -0
- package/{dist/components → components}/ScreenReaderOnly.svelte +1 -1
- package/components/ScreenReaderOnly.svelte.d.ts +20 -0
- package/{dist/ts/components → components}/index.d.ts +3 -0
- package/components/index.js +9 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +47 -77
- package/types/CardLayout.d.ts +14 -0
- package/types/CardLayout.js +1 -0
- 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 +3 -0
- package/types/index.js +3 -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 +13 -24
- package/util/util.d.ts +5 -0
- package/util/util.js +33 -0
- package/LICENSE +0 -21
- package/dist/actions/buttonify.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 -19
- 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/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/activestore.js +0 -123
- package/dist/lib/activestore.js.map +0 -1
- package/dist/lib/bodyoffset.js.map +0 -1
- package/dist/lib/convertedstore.js +0 -41
- package/dist/lib/convertedstore.js.map +0 -1
- package/dist/lib/derivedstore.js +0 -65
- package/dist/lib/derivedstore.js.map +0 -1
- package/dist/lib/index.js +0 -22
- 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/store.js +0 -27
- package/dist/lib/store.js.map +0 -1
- package/dist/lib/substore.js +0 -47
- 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 -101
- package/dist/ts/components/Modal.svelte +0 -54
- package/dist/ts/components/PopupMenu.svelte +0 -279
- package/dist/ts/components/ScreenReaderOnly.svelte +0 -26
- package/dist/ts/index.d.ts +0 -4
- package/dist/ts/lib/activestore.d.ts +0 -60
- package/dist/ts/lib/convertedstore.d.ts +0 -16
- package/dist/ts/lib/derivedstore.d.ts +0 -23
- package/dist/ts/lib/index.d.ts +0 -9
- package/dist/ts/lib/safestore.d.ts +0 -4
- package/dist/ts/lib/store.d.ts +0 -16
- package/dist/ts/lib/substore.d.ts +0 -24
- package/dist/ts/lib/util.d.ts +0 -2
- 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 -36
- 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 -79
- package/docs/ConditionalWrapper.md +0 -35
- package/docs/Modal.md +0 -63
- package/docs/PopupMenu.md +0 -31
- package/docs/ScreenReaderOnly.md +0 -10
- package/docs/actions.md +0 -84
- package/docs/stores.md +0 -203
- package/esm/index.js +0 -1
- package/esm/package.json +0 -3
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<script >import { onDestroy, tick, setContext, onMount } from 'svelte';
|
|
2
|
+
import { writable } from 'svelte/store';
|
|
3
|
+
import { browser } from '$app/env';
|
|
4
|
+
import { resize } from '../actions';
|
|
5
|
+
import { CARDLAYOUT } from '../types';
|
|
6
|
+
export let maxwidth = 500;
|
|
7
|
+
export let preserveorder = false;
|
|
8
|
+
export let gutter = 10;
|
|
9
|
+
export let className = '';
|
|
10
|
+
const blocks = [];
|
|
11
|
+
const gutterstore = writable(gutter);
|
|
12
|
+
let defaultOrder = 0;
|
|
13
|
+
setContext(CARDLAYOUT, {
|
|
14
|
+
registerBlock: (block) => {
|
|
15
|
+
blocks.push(block);
|
|
16
|
+
hardrecalc();
|
|
17
|
+
onDestroy(() => {
|
|
18
|
+
blocks.splice(blocks.indexOf(block), 1);
|
|
19
|
+
hardrecalc();
|
|
20
|
+
});
|
|
21
|
+
block.order = writable(defaultOrder++);
|
|
22
|
+
block.linebreak = writable(false);
|
|
23
|
+
const cols = savecolumns || Math.ceil(1024 / maxwidth);
|
|
24
|
+
block.width = writable(`calc(${100.0 / cols}% - ${gutter * (cols - 1) / cols}px)`);
|
|
25
|
+
return block;
|
|
26
|
+
},
|
|
27
|
+
recalculate: () => {
|
|
28
|
+
hardrecalc();
|
|
29
|
+
},
|
|
30
|
+
gutter: gutterstore
|
|
31
|
+
});
|
|
32
|
+
$: gutterstore.set(gutter);
|
|
33
|
+
let layoutelement;
|
|
34
|
+
let cycle1 = 0;
|
|
35
|
+
let cycle2 = 0;
|
|
36
|
+
function detectcycle(w) {
|
|
37
|
+
if (cycle1 === 0 && Math.abs(w - cycle2) > 5) {
|
|
38
|
+
cycle1 = w;
|
|
39
|
+
}
|
|
40
|
+
else if (cycle2 === 0 && Math.abs(w - cycle1) > 5) {
|
|
41
|
+
cycle2 = w;
|
|
42
|
+
}
|
|
43
|
+
else if (w === cycle1 || w === cycle2) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
cycle1 = 0;
|
|
48
|
+
cycle2 = 0;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
let savecolumns = 0;
|
|
53
|
+
let optimal;
|
|
54
|
+
let fullheight = 0;
|
|
55
|
+
let hardrequired = false;
|
|
56
|
+
async function recalculate(realw) {
|
|
57
|
+
const columns = Math.ceil(realw / maxwidth);
|
|
58
|
+
const guttereach = gutter * (columns - 1) / columns;
|
|
59
|
+
const cycling = detectcycle(realw);
|
|
60
|
+
if (columns !== savecolumns) {
|
|
61
|
+
for (const block of blocks)
|
|
62
|
+
block.width.set(`calc(${100.0 / columns}% - ${guttereach}px`);
|
|
63
|
+
await tick();
|
|
64
|
+
}
|
|
65
|
+
// collect all the card heights at this new column width
|
|
66
|
+
for (const block of blocks)
|
|
67
|
+
block.height = block.element?.offsetHeight ?? 200;
|
|
68
|
+
if (columns !== savecolumns || hardrequired) { // only do real work if number of columns has changed, recalculate triggers on resize
|
|
69
|
+
if (preserveorder) {
|
|
70
|
+
optimal = [blocks];
|
|
71
|
+
if (columns > 1) {
|
|
72
|
+
const totalheight = blocks.reduce((totalheight, block) => totalheight + block.height + gutter, 0);
|
|
73
|
+
const tallestblock = Math.max(...blocks.map(b => b.height));
|
|
74
|
+
const minheight = Math.max(totalheight / columns, tallestblock);
|
|
75
|
+
let shortestoverall = totalheight;
|
|
76
|
+
// 2d packing problem is NP-hard so this is an O(n) heuristic
|
|
77
|
+
// optimal configuration would be if each column is `minheight` so start there
|
|
78
|
+
// then relax it in increments and see if the overall height shrinks
|
|
79
|
+
const increment = Math.max(1, Math.floor(Math.min(minheight, tallestblock) * 0.05));
|
|
80
|
+
for (let colmaxheight = minheight; colmaxheight < minheight + tallestblock + gutter; colmaxheight += increment) {
|
|
81
|
+
let colheight = 0;
|
|
82
|
+
let colidx = 0;
|
|
83
|
+
let tallestcol = 0;
|
|
84
|
+
let tallestcolidx = 0;
|
|
85
|
+
const arrangement = [];
|
|
86
|
+
for (const block of blocks) {
|
|
87
|
+
if (colheight + block.height > colmaxheight && colidx < columns - 1) {
|
|
88
|
+
if (colheight > tallestcol) {
|
|
89
|
+
tallestcol = colheight;
|
|
90
|
+
tallestcolidx = colidx;
|
|
91
|
+
}
|
|
92
|
+
colidx++;
|
|
93
|
+
colheight = 0;
|
|
94
|
+
}
|
|
95
|
+
if (!arrangement[colidx])
|
|
96
|
+
arrangement[colidx] = [];
|
|
97
|
+
arrangement[colidx].push(block);
|
|
98
|
+
colheight += block.height + gutter;
|
|
99
|
+
}
|
|
100
|
+
if (colheight > tallestcol) {
|
|
101
|
+
tallestcol = colheight;
|
|
102
|
+
tallestcolidx = colidx;
|
|
103
|
+
}
|
|
104
|
+
if (tallestcol < shortestoverall) {
|
|
105
|
+
shortestoverall = tallestcol;
|
|
106
|
+
optimal = arrangement;
|
|
107
|
+
}
|
|
108
|
+
// if leftmost column is tallest, increasing the allowable height can never make the overall height shorter
|
|
109
|
+
if (tallestcolidx === 0)
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
optimal = [];
|
|
116
|
+
const heights = Array.apply(null, Array(columns)).map((_) => 0); // initializes heights to an array of zeroes
|
|
117
|
+
// begin sorting blocks into columns
|
|
118
|
+
for (const block of blocks) {
|
|
119
|
+
// find the column with the smallest current height
|
|
120
|
+
const colidx = heights.reduce((acc, curr, curridx) => curr < heights[acc] ? curridx : acc, 0);
|
|
121
|
+
// record the height we are adding to the chosen column
|
|
122
|
+
heights[colidx] += block.height + gutter;
|
|
123
|
+
// move the current card to the chosen column
|
|
124
|
+
if (!optimal[colidx])
|
|
125
|
+
optimal[colidx] = [];
|
|
126
|
+
optimal[colidx].push(block);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// we created the optimal arrangement, now move the block elements to
|
|
130
|
+
// reflect it
|
|
131
|
+
let order = 0;
|
|
132
|
+
for (let i = 0; i < optimal.length; i++) {
|
|
133
|
+
for (let j = 0; j < optimal[i].length; j++) {
|
|
134
|
+
const block = optimal[i][j];
|
|
135
|
+
block.order.set(order++);
|
|
136
|
+
block.linebreak.set(j === optimal[i].length - 1 && i < optimal.length - 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
savecolumns = columns;
|
|
140
|
+
hardrequired = false;
|
|
141
|
+
}
|
|
142
|
+
// re-adjust container height
|
|
143
|
+
const saveheight = fullheight;
|
|
144
|
+
fullheight = 0;
|
|
145
|
+
for (let i = 0; i < optimal.length; i++) {
|
|
146
|
+
let top = 0;
|
|
147
|
+
for (const block of optimal[i]) {
|
|
148
|
+
top += block.height + gutter;
|
|
149
|
+
}
|
|
150
|
+
fullheight = Math.max(fullheight, top);
|
|
151
|
+
}
|
|
152
|
+
if (cycling && saveheight < fullheight)
|
|
153
|
+
fullheight = saveheight;
|
|
154
|
+
}
|
|
155
|
+
let savewidth = 0;
|
|
156
|
+
let timer = 0;
|
|
157
|
+
function triggerrecalc(width) {
|
|
158
|
+
if (width === savewidth && !hardrequired)
|
|
159
|
+
return;
|
|
160
|
+
cancelAnimationFrame(timer);
|
|
161
|
+
timer = requestAnimationFrame(() => {
|
|
162
|
+
recalculate(width);
|
|
163
|
+
savewidth = width;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function hardrecalc() {
|
|
167
|
+
if (!layoutelement)
|
|
168
|
+
return;
|
|
169
|
+
hardrequired = true;
|
|
170
|
+
cycle1 = 0;
|
|
171
|
+
cycle2 = 0;
|
|
172
|
+
triggerrecalc(layoutelement.clientWidth);
|
|
173
|
+
}
|
|
174
|
+
function onResize(e) {
|
|
175
|
+
triggerrecalc(e.detail.clientWidth);
|
|
176
|
+
}
|
|
177
|
+
onMount(() => triggerrecalc(layoutelement.clientWidth));
|
|
178
|
+
</script>
|
|
179
|
+
|
|
180
|
+
<ul class="cardlayout {className}" class:ssr={!browser} style:height={browser ? `${fullheight + gutter}px` : undefined} bind:this={layoutelement} use:resize on:resize={onResize}>
|
|
181
|
+
<slot></slot>
|
|
182
|
+
</ul>
|
|
183
|
+
|
|
184
|
+
<style>
|
|
185
|
+
.cardlayout {
|
|
186
|
+
list-style: none;
|
|
187
|
+
padding: 0;
|
|
188
|
+
margin: 0;
|
|
189
|
+
display: flex;
|
|
190
|
+
flex-wrap: wrap;
|
|
191
|
+
flex-direction: column;
|
|
192
|
+
align-content: space-between;
|
|
193
|
+
}
|
|
194
|
+
.cardlayout.ssr {
|
|
195
|
+
flex-direction: row;
|
|
196
|
+
}
|
|
197
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
maxwidth?: number;
|
|
5
|
+
preserveorder?: boolean;
|
|
6
|
+
gutter?: number;
|
|
7
|
+
className?: string;
|
|
8
|
+
};
|
|
9
|
+
events: {
|
|
10
|
+
[evt: string]: CustomEvent<any>;
|
|
11
|
+
};
|
|
12
|
+
slots: {
|
|
13
|
+
default: {};
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare type CardLayoutProps = typeof __propDef.props;
|
|
17
|
+
export declare type CardLayoutEvents = typeof __propDef.events;
|
|
18
|
+
export declare type CardLayoutSlots = typeof __propDef.slots;
|
|
19
|
+
export default class CardLayout extends SvelteComponentTyped<CardLayoutProps, CardLayoutEvents, CardLayoutSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { Store, 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,7 +40,7 @@ function reactToColumns(columns) {
|
|
|
40
40
|
return sortedcolumns;
|
|
41
41
|
}
|
|
42
42
|
$: sortedcolumns = reactToColumns(columns);
|
|
43
|
-
$: itemkeys = items.map(item =>
|
|
43
|
+
$: itemkeys = items.map(item => item.id ?? item._id ?? identifyingkeys.map(k => item[k]).join('.'));
|
|
44
44
|
const state = new Store({
|
|
45
45
|
keepcolumns: [],
|
|
46
46
|
hiddencolumns: [],
|
|
@@ -48,28 +48,27 @@ const state = new Store({
|
|
|
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} on:change={e => selected = e.detail}></svelte:component>
|
|
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>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { CollapsingTableColumn } from '../types';
|
|
3
|
+
import DefaultPopupMenu from './PopupMenu.svelte';
|
|
4
|
+
declare const __propDef: {
|
|
5
|
+
props: {
|
|
6
|
+
tableClass?: string;
|
|
7
|
+
bodyRowClass?: string;
|
|
8
|
+
bodyCellClass?: string;
|
|
9
|
+
headerRowClass?: string;
|
|
10
|
+
headerCellClass?: string;
|
|
11
|
+
menuContainerClass?: string;
|
|
12
|
+
menuClass?: string;
|
|
13
|
+
menuItemClass?: string;
|
|
14
|
+
menuItemHilitedClass?: string;
|
|
15
|
+
items: any[];
|
|
16
|
+
config?: CollapsingTableColumn[] | undefined;
|
|
17
|
+
defaultCellWidth?: number;
|
|
18
|
+
PopupMenu?: typeof DefaultPopupMenu;
|
|
19
|
+
slots?: Record<string, boolean>;
|
|
20
|
+
stickyheader?: boolean;
|
|
21
|
+
};
|
|
22
|
+
events: {
|
|
23
|
+
[evt: string]: CustomEvent<any>;
|
|
24
|
+
};
|
|
25
|
+
slots: {
|
|
26
|
+
headercell: {
|
|
27
|
+
column: CollapsingTableColumn & {
|
|
28
|
+
widthPercent?: number;
|
|
29
|
+
};
|
|
30
|
+
key: string;
|
|
31
|
+
title: string;
|
|
32
|
+
item: any;
|
|
33
|
+
value: any;
|
|
34
|
+
};
|
|
35
|
+
dropicon: {
|
|
36
|
+
column: CollapsingTableColumn & {
|
|
37
|
+
widthPercent?: number;
|
|
38
|
+
};
|
|
39
|
+
item: any;
|
|
40
|
+
value: any;
|
|
41
|
+
};
|
|
42
|
+
default: {
|
|
43
|
+
key: string;
|
|
44
|
+
value: any;
|
|
45
|
+
item: any;
|
|
46
|
+
};
|
|
47
|
+
footer: {
|
|
48
|
+
item: any;
|
|
49
|
+
key: any;
|
|
50
|
+
value: any;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare type CollapsingTableProps = typeof __propDef.props;
|
|
55
|
+
export declare type CollapsingTableEvents = typeof __propDef.events;
|
|
56
|
+
export declare type CollapsingTableSlots = typeof __propDef.slots;
|
|
57
|
+
export default class CollapsingTable extends SvelteComponentTyped<CollapsingTableProps, CollapsingTableEvents, CollapsingTableSlots> {
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
<script
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
$: passthrough = (({ condition, component, a, span, element, ...passthrough }) => passthrough)($$props)
|
|
1
|
+
<script >export let condition;
|
|
2
|
+
export let component = undefined;
|
|
3
|
+
export let a = false;
|
|
4
|
+
export let span = false;
|
|
5
|
+
export let element = undefined;
|
|
6
|
+
$: passthrough = (({ condition, component, a, span, element, ...passthrough }) => passthrough)($$props);
|
|
8
7
|
</script>
|
|
9
8
|
|
|
10
9
|
{#if condition || (typeof condition === 'undefined' && component)}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
[x: string]: any;
|
|
5
|
+
condition: boolean | undefined;
|
|
6
|
+
component?: Function | undefined;
|
|
7
|
+
a?: boolean;
|
|
8
|
+
span?: boolean;
|
|
9
|
+
element?: HTMLElement | undefined;
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {
|
|
15
|
+
default: {};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare type ConditionalWrapperProps = typeof __propDef.props;
|
|
19
|
+
export declare type ConditionalWrapperEvents = typeof __propDef.events;
|
|
20
|
+
export declare type ConditionalWrapperSlots = typeof __propDef.slots;
|
|
21
|
+
export default class ConditionalWrapper extends SvelteComponentTyped<ConditionalWrapperProps, ConditionalWrapperEvents, ConditionalWrapperSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<script context="module">const FocusLockStack = [];
|
|
1
|
+
<script context="module" >const FocusLockStack = [];
|
|
2
2
|
</script>
|
|
3
3
|
|
|
4
|
-
<script>export let returnfocusto = undefined;
|
|
4
|
+
<script >export let returnfocusto = undefined;
|
|
5
5
|
export let initialfocus = undefined;
|
|
6
6
|
export let hidefocus = true;
|
|
7
|
-
export let hidefocuslabel =
|
|
7
|
+
export let hidefocuslabel = 'focus is above modal dialog, start tabbing';
|
|
8
8
|
export let escapable = true;
|
|
9
9
|
let className = '';
|
|
10
10
|
export { className as class };
|
|
@@ -32,6 +32,8 @@ onMount(async () => {
|
|
|
32
32
|
returnfocusto = document.querySelector(':focus');
|
|
33
33
|
}
|
|
34
34
|
await sleep(1); // sapper resets focus on page load, so we'll wait a millisecond in case our modal is on screen at load
|
|
35
|
+
if (!lockelement)
|
|
36
|
+
return; // in case we already unmounted
|
|
35
37
|
if (initialfocus) {
|
|
36
38
|
const focusEl = lockelement.querySelector(initialfocus);
|
|
37
39
|
if (focusEl instanceof HTMLElement)
|
|
@@ -40,7 +42,7 @@ onMount(async () => {
|
|
|
40
42
|
else {
|
|
41
43
|
setInitialFocus();
|
|
42
44
|
}
|
|
43
|
-
setTimeout(() => listenforescape = true, 0);
|
|
45
|
+
setTimeout(() => { listenforescape = true; }, 0);
|
|
44
46
|
});
|
|
45
47
|
onDestroy(async () => {
|
|
46
48
|
const wasactive = active;
|
|
@@ -55,25 +57,25 @@ onDestroy(async () => {
|
|
|
55
57
|
prevFocusLock.unpause();
|
|
56
58
|
});
|
|
57
59
|
const setInitialFocus = () => {
|
|
58
|
-
const firstfocus = tabbable(lockelement)[0];
|
|
60
|
+
const firstfocus = lockelement ? tabbable(lockelement)[0] : undefined;
|
|
59
61
|
if (firstfocus && firstfocus.focus) {
|
|
60
62
|
firstfocus.focus();
|
|
61
63
|
}
|
|
62
64
|
};
|
|
63
65
|
const setLastFocus = () => {
|
|
64
|
-
const lastfocus = tabbable(lockelement).slice(-1)[0];
|
|
66
|
+
const lastfocus = lockelement ? tabbable(lockelement).slice(-1)[0] : undefined;
|
|
65
67
|
if (lastfocus && lastfocus.focus) {
|
|
66
68
|
lastfocus.focus();
|
|
67
69
|
}
|
|
68
70
|
};
|
|
69
71
|
const keydown = (e) => {
|
|
70
|
-
if (active && e.key ===
|
|
72
|
+
if (active && e.key === 'Escape' && escapable) {
|
|
71
73
|
e.preventDefault();
|
|
72
74
|
dispatch('escape');
|
|
73
75
|
}
|
|
74
76
|
};
|
|
75
77
|
const focusin = (e) => {
|
|
76
|
-
if (active && e.target instanceof HTMLElement && !
|
|
78
|
+
if (active && e.target instanceof HTMLElement && !lockelement?.contains(e.target)) {
|
|
77
79
|
if (e.target === abovelockelement)
|
|
78
80
|
setLastFocus();
|
|
79
81
|
else
|
|
@@ -91,7 +93,7 @@ const windowclick = (_) => {
|
|
|
91
93
|
<div class={className} role="alertdialog" aria-modal="true" on:click|stopPropagation on:keydown|stopPropagation={keydown} on:focusin={focusin}>
|
|
92
94
|
<div bind:this={abovelockelement} tabindex="0"></div>
|
|
93
95
|
<div bind:this={lockelement} on:keydown={keydown}>
|
|
94
|
-
{#if hidefocus}<div class="hiddenfocus" use:buttonify on:blur={() =>{ hidefocus = false }} on:click={() => escapable && dispatch('escape')}><ScreenReaderOnly>{hidefocuslabel}{#if escapable}, click to escape or use escape key at any time{/if}</ScreenReaderOnly></div>{/if}
|
|
96
|
+
{#if hidefocus}<div class="hiddenfocus" use:buttonify on:blur={() => { hidefocus = false }} on:click={() => escapable && dispatch('escape')}><ScreenReaderOnly>{hidefocuslabel}{#if escapable}, click to escape or use escape key at any time{/if}</ScreenReaderOnly></div>{/if}
|
|
95
97
|
<slot></slot>
|
|
96
98
|
</div>
|
|
97
99
|
<div tabindex="0"></div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
returnfocusto?: HTMLElement | null | undefined;
|
|
5
|
+
initialfocus?: string | undefined;
|
|
6
|
+
hidefocus?: boolean;
|
|
7
|
+
hidefocuslabel?: string;
|
|
8
|
+
escapable?: boolean;
|
|
9
|
+
class?: string;
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
click: MouseEvent;
|
|
13
|
+
escape: CustomEvent<any>;
|
|
14
|
+
} & {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {
|
|
18
|
+
default: {};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare type FocusLockProps = typeof __propDef.props;
|
|
22
|
+
export declare type FocusLockEvents = typeof __propDef.events;
|
|
23
|
+
export declare type FocusLockSlots = typeof __propDef.slots;
|
|
24
|
+
export default class FocusLock extends SvelteComponentTyped<FocusLockProps, FocusLockEvents, FocusLockSlots> {
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
<script>export let escapable = true;
|
|
1
|
+
<script >export let escapable = true;
|
|
2
2
|
export let hidefocus = true;
|
|
3
3
|
export let hidefocuslabel = undefined;
|
|
4
4
|
export let returnfocusto = undefined;
|
|
5
5
|
export let initialfocus = undefined;
|
|
6
6
|
export let containerClass = '';
|
|
7
7
|
export let opaque = false;
|
|
8
|
-
|
|
8
|
+
export let usePortal = undefined;
|
|
9
9
|
import { createEventDispatcher, onMount } from 'svelte';
|
|
10
|
+
import FocusLock from './FocusLock.svelte';
|
|
10
11
|
import { portal } from '../actions';
|
|
11
12
|
const dispatch = createEventDispatcher();
|
|
12
13
|
const endmodal = () => {
|
|
@@ -22,7 +23,7 @@ onMount(() => {
|
|
|
22
23
|
});
|
|
23
24
|
</script>
|
|
24
25
|
|
|
25
|
-
<div use:portal class="modal-backdrop" class:opaque on:click|stopPropagation|preventDefault={() => escapable && endmodal()}>
|
|
26
|
+
<div use:portal={usePortal} class="modal-backdrop" class:opaque on:click|stopPropagation|preventDefault={() => escapable && endmodal()}>
|
|
26
27
|
<FocusLock class="modal-container {containerClass}" {escapable} on:escape {hidefocus} {hidefocuslabel} {returnfocusto} {initialfocus}>
|
|
27
28
|
<slot></slot>
|
|
28
29
|
</FocusLock>
|
|
@@ -36,7 +37,7 @@ onMount(() => {
|
|
|
36
37
|
width: 100vw;
|
|
37
38
|
height: 100vh;
|
|
38
39
|
background-color: var(--modal-bg, rgba(0, 0, 0, 0.7));
|
|
39
|
-
z-index:
|
|
40
|
+
z-index: 2147483000;
|
|
40
41
|
display: flex;
|
|
41
42
|
justify-content: center;
|
|
42
43
|
align-items: center
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
escapable?: boolean;
|
|
5
|
+
hidefocus?: boolean;
|
|
6
|
+
hidefocuslabel?: string | undefined;
|
|
7
|
+
returnfocusto?: HTMLElement | undefined;
|
|
8
|
+
initialfocus?: string | undefined;
|
|
9
|
+
containerClass?: string;
|
|
10
|
+
opaque?: boolean;
|
|
11
|
+
usePortal?: HTMLElement | undefined;
|
|
12
|
+
};
|
|
13
|
+
events: {
|
|
14
|
+
escape: CustomEvent<any>;
|
|
15
|
+
} & {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
};
|
|
18
|
+
slots: {
|
|
19
|
+
default: {};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare type ModalProps = typeof __propDef.props;
|
|
23
|
+
export declare type ModalEvents = typeof __propDef.events;
|
|
24
|
+
export declare type ModalSlots = typeof __propDef.slots;
|
|
25
|
+
export default class Modal extends SvelteComponentTyped<ModalProps, ModalEvents, ModalSlots> {
|
|
26
|
+
}
|
|
27
|
+
export {};
|